722 lines
29 KiB
Python
722 lines
29 KiB
Python
from flask import Flask, render_template, request, redirect, url_for, flash, jsonify
|
||
import sqlite3
|
||
import os
|
||
import pandas as pd
|
||
from datetime import datetime
|
||
from database import get_db_connection, calculate_order_total, calculate_discount, get_discount_description, \
|
||
calculate_discount_for_new_order, get_db, create_tables
|
||
from import_data import import_data_from_files
|
||
|
||
app = Flask(__name__)
|
||
app.secret_key = 'kancelyary_secret_key_2026'
|
||
app.config['TEMPLATES_AUTO_RELOAD'] = True
|
||
app.config['DATABASE'] = 'partners.db'
|
||
|
||
|
||
# Функция для сохранения данных в Excel (опционально)
|
||
def save_to_excel():
|
||
"""Сохраняет все данные из БД в Excel файлы"""
|
||
try:
|
||
if not os.path.exists('data'):
|
||
os.makedirs('data')
|
||
|
||
with get_db() as conn:
|
||
product_types = conn.execute('SELECT * FROM product_types').fetchall()
|
||
if product_types:
|
||
df_types = pd.DataFrame([dict(pt) for pt in product_types])
|
||
df_types.to_excel('data/Product_types_import.xlsx', index=False)
|
||
|
||
partners = conn.execute('SELECT * FROM partners').fetchall()
|
||
if partners:
|
||
df_partners = pd.DataFrame([dict(p) for p in partners])
|
||
df_partners.to_excel('data/Partners_import.xlsx', index=False)
|
||
|
||
products = conn.execute('SELECT * FROM products').fetchall()
|
||
if products:
|
||
df_products = pd.DataFrame([dict(p) for p in products])
|
||
df_products.to_excel('data/Products_import.xlsx', index=False)
|
||
|
||
orders = conn.execute('SELECT * FROM orders').fetchall()
|
||
if orders:
|
||
df_orders = pd.DataFrame([dict(o) for o in orders])
|
||
df_orders.to_excel('data/Orders_import.xlsx', index=False)
|
||
|
||
order_items = conn.execute('SELECT * FROM order_items').fetchall()
|
||
if order_items:
|
||
df_items = pd.DataFrame([dict(oi) for oi in order_items])
|
||
df_items.to_excel('data/Order_items_import.xlsx', index=False)
|
||
|
||
print("✅ Данные сохранены в Excel файлы")
|
||
return True
|
||
except Exception as e:
|
||
print(f"❌ Ошибка при сохранении в Excel: {e}")
|
||
return False
|
||
|
||
|
||
# Главная страница - список заказов с сортировкой
|
||
@app.route('/')
|
||
def index():
|
||
sort_by = request.args.get('sort', 'date_desc')
|
||
partner_filter = request.args.get('partner', None)
|
||
|
||
try:
|
||
with get_db() as conn:
|
||
if partner_filter:
|
||
query = f'''
|
||
SELECT o.*, p.name as partner_name, p.id as partner_id
|
||
FROM orders o
|
||
JOIN partners p ON o.partner_id = p.id
|
||
WHERE o.partner_id = {partner_filter}
|
||
'''
|
||
else:
|
||
query = '''
|
||
SELECT o.*, p.name as partner_name, p.id as partner_id
|
||
FROM orders o
|
||
JOIN partners p ON o.partner_id = p.id
|
||
'''
|
||
|
||
if sort_by == 'amount_desc':
|
||
query += '''
|
||
LEFT JOIN order_items oi ON o.id = oi.order_id
|
||
GROUP BY o.id
|
||
ORDER BY COALESCE(SUM(oi.quantity * oi.price_at_order), 0) * 1.1 DESC
|
||
'''
|
||
elif sort_by == 'date_desc':
|
||
query += ' ORDER BY o.order_date DESC'
|
||
elif sort_by == 'partner':
|
||
query += ' ORDER BY p.name, o.order_date DESC'
|
||
else:
|
||
query += ' ORDER BY o.order_date DESC'
|
||
|
||
orders = conn.execute(query).fetchall()
|
||
|
||
orders_with_discount = []
|
||
for order in orders:
|
||
try:
|
||
items_count = conn.execute('''
|
||
SELECT COUNT(*) as count FROM order_items WHERE order_id = ?
|
||
''', (order['id'],)).fetchone()['count']
|
||
|
||
subtotal_without_markup = conn.execute('''
|
||
SELECT COALESCE(SUM(quantity * price_at_order), 0) as total
|
||
FROM order_items WHERE order_id = ?
|
||
''', (order['id'],)).fetchone()['total']
|
||
|
||
subtotal_with_markup = subtotal_without_markup * 1.1
|
||
discount_percent = order['discount_percent'] if order['discount_percent'] else 0
|
||
discount_amount = subtotal_with_markup * discount_percent / 100
|
||
total = subtotal_with_markup - discount_amount
|
||
|
||
order_dict = {
|
||
'order_id': order['id'],
|
||
'partner_id': order['partner_id'],
|
||
'partner_name': order['partner_name'],
|
||
'order_date': order['order_date'],
|
||
'notes': order['notes'] if order['notes'] else '',
|
||
'items_count': items_count,
|
||
'subtotal_without_markup': round(subtotal_without_markup, 2),
|
||
'subtotal_with_markup': round(subtotal_with_markup, 2),
|
||
'discount_percent': discount_percent,
|
||
'discount_desc': get_discount_description(discount_percent),
|
||
'discount_amount': round(discount_amount, 2),
|
||
'total': round(total, 2)
|
||
}
|
||
|
||
orders_with_discount.append(order_dict)
|
||
|
||
except Exception as e:
|
||
print(f"Ошибка при обработке заказа {order['id']}: {e}")
|
||
orders_with_discount.append({
|
||
'order_id': order['id'],
|
||
'partner_id': order['partner_id'],
|
||
'partner_name': order['partner_name'],
|
||
'order_date': order['order_date'],
|
||
'notes': '',
|
||
'items_count': 0,
|
||
'subtotal_without_markup': 0,
|
||
'subtotal_with_markup': 0,
|
||
'discount_percent': 0,
|
||
'discount_desc': '0%',
|
||
'discount_amount': 0,
|
||
'total': 0
|
||
})
|
||
|
||
return render_template('index.html', orders=orders_with_discount, current_sort=sort_by)
|
||
|
||
except Exception as e:
|
||
print(f"Критическая ошибка в index: {e}")
|
||
return render_template('index.html', orders=[], current_sort='date_desc')
|
||
|
||
|
||
# Страница товаров
|
||
@app.route('/products')
|
||
def products():
|
||
try:
|
||
with get_db() as conn:
|
||
products_rows = conn.execute('''
|
||
SELECT p.*, pt.type_name as product_type_name
|
||
FROM products p
|
||
JOIN product_types pt ON p.product_type_id = pt.id
|
||
ORDER BY p.product_name
|
||
''').fetchall()
|
||
|
||
products_list = []
|
||
for row in products_rows:
|
||
products_list.append({
|
||
'id': row['id'],
|
||
'product_type_id': row['product_type_id'],
|
||
'product_name': row['product_name'],
|
||
'article': row['article'],
|
||
'min_partner_price': row['min_partner_price'],
|
||
'product_type_name': row['product_type_name']
|
||
})
|
||
|
||
product_types_rows = conn.execute('SELECT * FROM product_types ORDER BY type_name').fetchall()
|
||
product_types = []
|
||
for row in product_types_rows:
|
||
product_types.append({
|
||
'id': row['id'],
|
||
'type_name': row['type_name'],
|
||
'description': row['description']
|
||
})
|
||
|
||
partners_rows = conn.execute('SELECT id, name FROM partners ORDER BY name').fetchall()
|
||
partners = []
|
||
for row in partners_rows:
|
||
partners.append({
|
||
'id': row['id'],
|
||
'name': row['name']
|
||
})
|
||
|
||
today = datetime.now().strftime('%Y-%m-%d')
|
||
|
||
return render_template('products.html', products=products_list, product_types=product_types,
|
||
partners=partners, today=today)
|
||
except Exception as e:
|
||
print(f"Ошибка на странице товаров: {e}")
|
||
flash('Ошибка при загрузке страницы', 'error')
|
||
return redirect(url_for('index'))
|
||
|
||
|
||
# Страница партнеров
|
||
@app.route('/partners')
|
||
def partners():
|
||
try:
|
||
with get_db() as conn:
|
||
partners_rows = conn.execute('''
|
||
SELECT p.*,
|
||
COUNT(DISTINCT o.id) as orders_count,
|
||
COALESCE(SUM(oi.quantity * oi.price_at_order), 0) as total_purchases
|
||
FROM partners p
|
||
LEFT JOIN orders o ON p.id = o.partner_id
|
||
LEFT JOIN order_items oi ON o.id = oi.order_id
|
||
GROUP BY p.id
|
||
ORDER BY p.name
|
||
''').fetchall()
|
||
|
||
partners_with_stats = []
|
||
for partner in partners_rows:
|
||
partner_dict = {
|
||
'id': partner['id'],
|
||
'name': partner['name'],
|
||
'director': partner['director'],
|
||
'email': partner['email'],
|
||
'phone': partner['phone'],
|
||
'legal_address': partner['legal_address'],
|
||
'inn': partner['inn'],
|
||
'orders_count': partner['orders_count'],
|
||
'total_purchases': partner['total_purchases']
|
||
}
|
||
discount_percent = calculate_discount(partner['total_purchases'] or 0)
|
||
discount_desc = get_discount_description(discount_percent)
|
||
partner_dict['discount_percent'] = discount_percent
|
||
partner_dict['discount_desc'] = discount_desc
|
||
partners_with_stats.append(partner_dict)
|
||
|
||
return render_template('partners.html', partners=partners_with_stats)
|
||
except Exception as e:
|
||
print(f"Ошибка на странице партнеров: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
flash('Ошибка при загрузке страницы', 'error')
|
||
return redirect(url_for('index'))
|
||
|
||
|
||
# Добавление заказа
|
||
@app.route('/add_order', methods=['GET', 'POST'])
|
||
def add_order():
|
||
if request.method == 'POST':
|
||
try:
|
||
partner_id = request.form['partner_id']
|
||
order_date = request.form['order_date']
|
||
notes = request.form.get('notes', '')
|
||
|
||
products = request.form.getlist('product_id[]')
|
||
quantities = request.form.getlist('quantity[]')
|
||
prices = request.form.getlist('price[]')
|
||
|
||
with get_db() as conn:
|
||
# Проверка (товары всегда есть в наличии, но проверяем что они существуют)
|
||
for i in range(len(products)):
|
||
if products[i] and quantities[i]:
|
||
product_id = int(products[i])
|
||
quantity = int(quantities[i])
|
||
|
||
if quantity <= 0:
|
||
flash(f'Количество должно быть положительным для позиции {i + 1}', 'warning')
|
||
return redirect(url_for('add_order'))
|
||
|
||
product = conn.execute('SELECT * FROM products WHERE id = ?',
|
||
(product_id,)).fetchone()
|
||
if not product:
|
||
flash(f'Товар с ID {product_id} не найден', 'error')
|
||
return redirect(url_for('add_order'))
|
||
|
||
# Рассчитываем сумму текущего заказа (без добавочной стоимости)
|
||
current_order_amount_without_markup = 0
|
||
for i in range(len(products)):
|
||
if products[i] and quantities[i] and prices[i]:
|
||
quantity = int(quantities[i])
|
||
price = float(prices[i])
|
||
current_order_amount_without_markup += quantity * price
|
||
|
||
# Рассчитываем скидку на основе предыдущих заказов
|
||
discount_percent = calculate_discount_for_new_order(partner_id, order_date,
|
||
current_order_amount_without_markup)
|
||
|
||
# Создаем заказ
|
||
cursor = conn.cursor()
|
||
cursor.execute('''
|
||
INSERT INTO orders (partner_id, order_date, notes, discount_percent)
|
||
VALUES (?, ?, ?, ?)
|
||
''', (partner_id, order_date, notes, discount_percent))
|
||
|
||
order_id = cursor.lastrowid
|
||
|
||
# Добавляем позиции
|
||
items_added = 0
|
||
for i in range(len(products)):
|
||
if products[i] and quantities[i] and prices[i]:
|
||
product_id = int(products[i])
|
||
quantity = int(quantities[i])
|
||
price = float(prices[i])
|
||
|
||
cursor.execute('''
|
||
INSERT INTO order_items (order_id, product_id, quantity, price_at_order)
|
||
VALUES (?, ?, ?, ?)
|
||
''', (order_id, product_id, quantity, price))
|
||
|
||
items_added += 1
|
||
|
||
save_to_excel()
|
||
|
||
if items_added > 0:
|
||
flash(f'Заказ успешно создан! Добавлено {items_added} позиций', 'success')
|
||
|
||
return redirect(url_for('index'))
|
||
|
||
except Exception as e:
|
||
print(f"Ошибка при создании заказа: {e}")
|
||
flash(f'Ошибка при создании заказа: {str(e)}', 'error')
|
||
return redirect(url_for('add_order'))
|
||
|
||
# GET запрос
|
||
try:
|
||
with get_db() as conn:
|
||
partners_rows = conn.execute('SELECT * FROM partners ORDER BY name').fetchall()
|
||
partners = []
|
||
for row in partners_rows:
|
||
partners.append({
|
||
'id': row['id'],
|
||
'name': row['name'],
|
||
'director': row['director'],
|
||
'email': row['email'],
|
||
'phone': row['phone'],
|
||
'legal_address': row['legal_address'],
|
||
'inn': row['inn']
|
||
})
|
||
|
||
products_rows = conn.execute('''
|
||
SELECT p.*, pt.type_name
|
||
FROM products p
|
||
JOIN product_types pt ON p.product_type_id = pt.id
|
||
ORDER BY p.product_name
|
||
''').fetchall()
|
||
|
||
products = []
|
||
for row in products_rows:
|
||
products.append({
|
||
'id': row['id'],
|
||
'product_type_id': row['product_type_id'],
|
||
'product_name': row['product_name'],
|
||
'article': row['article'],
|
||
'min_partner_price': row['min_partner_price'],
|
||
'type_name': row['type_name']
|
||
})
|
||
|
||
today = datetime.now().strftime('%Y-%m-%d')
|
||
|
||
return render_template('add_order.html', partners=partners, products=products, today=today)
|
||
except Exception as e:
|
||
print(f"Ошибка при загрузке формы: {e}")
|
||
flash('Ошибка при загрузке формы', 'error')
|
||
return redirect(url_for('index'))
|
||
|
||
|
||
# Редактирование заказа (УБРАН МАРШРУТ УДАЛЕНИЯ)
|
||
@app.route('/edit_order/<int:order_id>', methods=['GET', 'POST'])
|
||
def edit_order(order_id):
|
||
if request.method == 'POST':
|
||
try:
|
||
order_date = request.form['order_date']
|
||
notes = request.form.get('notes', '')
|
||
|
||
with get_db() as conn:
|
||
old_items = conn.execute('SELECT product_id, quantity FROM order_items WHERE order_id = ?',
|
||
(order_id,)).fetchall()
|
||
|
||
products = request.form.getlist('product_id[]')
|
||
quantities = request.form.getlist('quantity[]')
|
||
prices = request.form.getlist('price[]')
|
||
|
||
has_new_items = any(p and p.strip() for p in products)
|
||
|
||
if has_new_items:
|
||
conn.execute('DELETE FROM order_items WHERE order_id = ?', (order_id,))
|
||
|
||
items_added = 0
|
||
new_order_amount_without_markup = 0
|
||
|
||
for i in range(len(products)):
|
||
if products[i] and products[i].strip():
|
||
product_id = int(products[i])
|
||
quantity = int(quantities[i]) if quantities[i] and quantities[i].strip() else 1
|
||
price = float(prices[i]) if prices[i] and prices[i].strip() else 0
|
||
|
||
conn.execute('''
|
||
INSERT INTO order_items (order_id, product_id, quantity, price_at_order)
|
||
VALUES (?, ?, ?, ?)
|
||
''', (order_id, product_id, quantity, price))
|
||
|
||
new_order_amount_without_markup += quantity * price
|
||
items_added += 1
|
||
|
||
order_info = conn.execute('SELECT partner_id FROM orders WHERE id = ?', (order_id,)).fetchone()
|
||
partner_id = order_info['partner_id']
|
||
|
||
discount_percent = calculate_discount_for_new_order(partner_id, order_date,
|
||
new_order_amount_without_markup, order_id)
|
||
|
||
conn.execute('''
|
||
UPDATE orders
|
||
SET order_date = ?, notes = ?, discount_percent = ?
|
||
WHERE id = ?
|
||
''', (order_date, notes, discount_percent, order_id))
|
||
else:
|
||
items_added = len(old_items)
|
||
conn.execute('''
|
||
UPDATE orders
|
||
SET order_date = ?, notes = ?
|
||
WHERE id = ?
|
||
''', (order_date, notes, order_id))
|
||
|
||
save_to_excel()
|
||
|
||
flash(f'Заказ обновлен! {items_added} позиций', 'success')
|
||
return redirect(url_for('index'))
|
||
|
||
except Exception as e:
|
||
print(f"Ошибка при редактировании заказа: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
flash(f'Ошибка: {str(e)}', 'error')
|
||
return redirect(url_for('edit_order', order_id=order_id))
|
||
|
||
try:
|
||
with get_db() as conn:
|
||
order_row = conn.execute('SELECT * FROM orders WHERE id = ?', (order_id,)).fetchone()
|
||
if not order_row:
|
||
return redirect(url_for('index'))
|
||
|
||
order = {
|
||
'id': order_row['id'],
|
||
'partner_id': order_row['partner_id'],
|
||
'order_date': order_row['order_date'],
|
||
'notes': order_row['notes']
|
||
}
|
||
|
||
items_rows = conn.execute('''
|
||
SELECT oi.*, p.product_name, p.article
|
||
FROM order_items oi
|
||
JOIN products p ON oi.product_id = p.id
|
||
WHERE oi.order_id = ?
|
||
''', (order_id,)).fetchall()
|
||
|
||
items = []
|
||
for row in items_rows:
|
||
items.append({
|
||
'id': row['id'],
|
||
'order_id': row['order_id'],
|
||
'product_id': row['product_id'],
|
||
'quantity': row['quantity'],
|
||
'price_at_order': row['price_at_order'],
|
||
'product_name': row['product_name'],
|
||
'article': row['article']
|
||
})
|
||
|
||
products_rows = conn.execute('''
|
||
SELECT p.*, pt.type_name
|
||
FROM products p
|
||
JOIN product_types pt ON p.product_type_id = pt.id
|
||
ORDER BY p.product_name
|
||
''').fetchall()
|
||
|
||
products = []
|
||
for row in products_rows:
|
||
products.append({
|
||
'id': row['id'],
|
||
'product_type_id': row['product_type_id'],
|
||
'product_name': row['product_name'],
|
||
'article': row['article'],
|
||
'min_partner_price': row['min_partner_price'],
|
||
'type_name': row['type_name']
|
||
})
|
||
|
||
return render_template('edit_order.html', order=order, items=items, products=products)
|
||
except Exception as e:
|
||
print(f"Ошибка при загрузке заказа: {e}")
|
||
flash('Ошибка при загрузке заказа', 'error')
|
||
return redirect(url_for('index'))
|
||
|
||
|
||
# Добавление партнера
|
||
@app.route('/add_partner', methods=['GET', 'POST'])
|
||
def add_partner():
|
||
if request.method == 'POST':
|
||
try:
|
||
name = request.form['name']
|
||
director = request.form.get('director', '')
|
||
email = request.form['email']
|
||
phone = request.form.get('phone', '')
|
||
legal_address = request.form.get('legal_address', '')
|
||
inn = request.form.get('inn', '')
|
||
|
||
with get_db() as conn:
|
||
conn.execute('''
|
||
INSERT INTO partners (name, director, email, phone, legal_address, inn)
|
||
VALUES (?, ?, ?, ?, ?, ?)
|
||
''', (name, director, email, phone, legal_address, inn))
|
||
|
||
save_to_excel()
|
||
|
||
flash('Партнер успешно добавлен!', 'success')
|
||
return redirect(url_for('partners'))
|
||
|
||
except sqlite3.IntegrityError:
|
||
flash('Партнер с таким ИНН уже существует', 'error')
|
||
return redirect(url_for('add_partner'))
|
||
except Exception as e:
|
||
print(f"Ошибка при добавлении партнера: {e}")
|
||
flash(f'Ошибка: {str(e)}', 'error')
|
||
return redirect(url_for('add_partner'))
|
||
|
||
return render_template('add_partner.html')
|
||
|
||
|
||
# Редактирование партнера (УБРАН МАРШРУТ УДАЛЕНИЯ)
|
||
@app.route('/edit_partner/<int:partner_id>', methods=['GET', 'POST'])
|
||
def edit_partner(partner_id):
|
||
if request.method == 'POST':
|
||
try:
|
||
name = request.form['name']
|
||
director = request.form.get('director', '')
|
||
email = request.form['email']
|
||
phone = request.form.get('phone', '')
|
||
legal_address = request.form.get('legal_address', '')
|
||
inn = request.form.get('inn', '')
|
||
|
||
with get_db() as conn:
|
||
existing = conn.execute(
|
||
'SELECT id FROM partners WHERE inn = ? AND id != ?',
|
||
(inn, partner_id)
|
||
).fetchone()
|
||
|
||
if existing:
|
||
flash('Партнер с таким ИНН уже существует', 'error')
|
||
return redirect(url_for('edit_partner', partner_id=partner_id))
|
||
|
||
conn.execute('''
|
||
UPDATE partners
|
||
SET name = ?, director = ?, email = ?, phone = ?,
|
||
legal_address = ?, inn = ?
|
||
WHERE id = ?
|
||
''', (name, director, email, phone, legal_address, inn, partner_id))
|
||
|
||
save_to_excel()
|
||
|
||
flash('Данные партнера обновлены!', 'success')
|
||
return redirect(url_for('partners'))
|
||
|
||
except Exception as e:
|
||
print(f"Ошибка при редактировании партнера: {e}")
|
||
flash(f'Ошибка: {str(e)}', 'error')
|
||
return redirect(url_for('edit_partner', partner_id=partner_id))
|
||
|
||
try:
|
||
with get_db() as conn:
|
||
partner_row = conn.execute('SELECT * FROM partners WHERE id = ?', (partner_id,)).fetchone()
|
||
|
||
if not partner_row:
|
||
flash('Партнер не найден', 'error')
|
||
return redirect(url_for('partners'))
|
||
|
||
partner = {
|
||
'id': partner_row['id'],
|
||
'name': partner_row['name'],
|
||
'director': partner_row['director'],
|
||
'email': partner_row['email'],
|
||
'phone': partner_row['phone'],
|
||
'legal_address': partner_row['legal_address'],
|
||
'inn': partner_row['inn']
|
||
}
|
||
|
||
return render_template('edit_partner.html', partner=partner)
|
||
except Exception as e:
|
||
print(f"Ошибка при загрузке партнера: {e}")
|
||
flash('Ошибка при загрузке данных', 'error')
|
||
return redirect(url_for('partners'))
|
||
|
||
|
||
# API для работы с товарами (УБРАН МАРШРУТ УДАЛЕНИЯ ТОВАРА)
|
||
@app.route('/api/product/<int:product_id>', methods=['GET'])
|
||
def api_get_product(product_id):
|
||
try:
|
||
with get_db() as conn:
|
||
product = conn.execute('SELECT * FROM products WHERE id = ?', (product_id,)).fetchone()
|
||
if product:
|
||
return jsonify(dict(product))
|
||
return jsonify({'error': 'Product not found'}), 404
|
||
except Exception as e:
|
||
return jsonify({'error': str(e)}), 500
|
||
|
||
|
||
@app.route('/api/product', methods=['POST'])
|
||
def api_add_product():
|
||
data = request.json
|
||
|
||
try:
|
||
with get_db() as conn:
|
||
cursor = conn.cursor()
|
||
cursor.execute('''
|
||
INSERT INTO products (product_type_id, product_name, article, min_partner_price)
|
||
VALUES (?, ?, ?, ?)
|
||
''', (
|
||
data['product_type_id'],
|
||
data['product_name'],
|
||
data['article'],
|
||
data['min_partner_price']
|
||
))
|
||
|
||
product_id = cursor.lastrowid
|
||
save_to_excel()
|
||
|
||
return jsonify({'success': True, 'product_id': product_id})
|
||
except Exception as e:
|
||
return jsonify({'success': False, 'error': str(e)}), 400
|
||
|
||
|
||
@app.route('/api/product/<int:product_id>', methods=['PUT'])
|
||
def api_update_product(product_id):
|
||
data = request.json
|
||
|
||
try:
|
||
with get_db() as conn:
|
||
conn.execute('''
|
||
UPDATE products
|
||
SET product_type_id = ?, product_name = ?, article = ?,
|
||
min_partner_price = ?
|
||
WHERE id = ?
|
||
''', (
|
||
data['product_type_id'],
|
||
data['product_name'],
|
||
data['article'],
|
||
data['min_partner_price'],
|
||
product_id
|
||
))
|
||
|
||
save_to_excel()
|
||
|
||
return jsonify({'success': True})
|
||
except Exception as e:
|
||
return jsonify({'success': False, 'error': str(e)}), 400
|
||
|
||
|
||
@app.route('/api/product_type', methods=['POST'])
|
||
def api_add_product_type():
|
||
data = request.json
|
||
|
||
try:
|
||
with get_db() as conn:
|
||
cursor = conn.cursor()
|
||
cursor.execute('''
|
||
INSERT INTO product_types (type_name, description)
|
||
VALUES (?, ?)
|
||
''', (
|
||
data['type_name'],
|
||
data.get('description', '')
|
||
))
|
||
|
||
type_id = cursor.lastrowid
|
||
save_to_excel()
|
||
|
||
return jsonify({'success': True, 'type_id': type_id})
|
||
except Exception as e:
|
||
return jsonify({'success': False, 'error': str(e)}), 400
|
||
|
||
|
||
@app.route('/api/order', methods=['POST'])
|
||
def api_create_order():
|
||
data = request.json
|
||
|
||
try:
|
||
with get_db() as conn:
|
||
for item in data['items']:
|
||
product = conn.execute('SELECT * FROM products WHERE id = ?',
|
||
(item['product_id'],)).fetchone()
|
||
if not product:
|
||
return jsonify({'success': False, 'error': 'Товар не найден'}), 400
|
||
|
||
order_amount_without_markup = sum(item['quantity'] * item['price'] for item in data['items'])
|
||
|
||
discount_percent = calculate_discount_for_new_order(data['partner_id'], data['order_date'],
|
||
order_amount_without_markup)
|
||
|
||
cursor = conn.cursor()
|
||
cursor.execute('''
|
||
INSERT INTO orders (partner_id, order_date, notes, discount_percent)
|
||
VALUES (?, ?, ?, ?)
|
||
''', (data['partner_id'], data['order_date'], data.get('notes', ''), discount_percent))
|
||
|
||
order_id = cursor.lastrowid
|
||
|
||
for item in data['items']:
|
||
cursor.execute('''
|
||
INSERT INTO order_items (order_id, product_id, quantity, price_at_order)
|
||
VALUES (?, ?, ?, ?)
|
||
''', (order_id, item['product_id'], item['quantity'], item['price']))
|
||
|
||
save_to_excel()
|
||
|
||
return jsonify({'success': True, 'order_id': order_id})
|
||
except Exception as e:
|
||
return jsonify({'success': False, 'error': str(e)}), 400
|
||
|
||
@app.route('/test_partner')
|
||
def test_partner():
|
||
"""Страница для ручного тестирования добавления партнера"""
|
||
return render_template('manual_partner_test.html')
|
||
|
||
if __name__ == '__main__':
|
||
if not os.path.exists('data'):
|
||
os.makedirs('data')
|
||
app.run(debug=True) |