262 lines
9.5 KiB
Python
262 lines
9.5 KiB
Python
from flask import Flask, render_template, send_from_directory, request, redirect, url_for, flash
|
||
import sqlite3
|
||
import os
|
||
from datetime import datetime
|
||
|
||
app = Flask(__name__)
|
||
app.secret_key = 'my_secret_key_12345'
|
||
|
||
def get_db_connection():
|
||
conn = sqlite3.connect('partners.db')
|
||
conn.row_factory = sqlite3.Row
|
||
return conn
|
||
def calculate_discount(total_quantity):
|
||
"""Рассчитывает скидку на основе общего количества проданной продукции"""
|
||
if total_quantity >= 300000:
|
||
return 15, '15% (более 300000 ед.)'
|
||
elif total_quantity >= 50000:
|
||
return 10, '10% (50000-300000 ед.)'
|
||
elif total_quantity >= 10000:
|
||
return 5, '5% (10000-50000 ед.)'
|
||
else:
|
||
return 0, '0% (до 10000 ед.)'
|
||
@app.route('/')
|
||
def index():
|
||
conn = get_db_connection()
|
||
|
||
partners = conn.execute('''
|
||
SELECT p.*, pt.type_name as partner_type_name,
|
||
COALESCE(SUM(s.quantity), 0) as total_quantity,
|
||
COALESCE(SUM(s.quantity * s.sale_price), 0) as total_sales
|
||
FROM Partner p
|
||
LEFT JOIN PartnerType pt ON p.partner_type_id = pt.id
|
||
LEFT JOIN Sale s ON p.id = s.partner_id
|
||
GROUP BY p.id
|
||
ORDER BY total_quantity DESC
|
||
''').fetchall()
|
||
|
||
partners_with_discount = []
|
||
for partner in partners:
|
||
total_quantity = partner['total_quantity'] or 0
|
||
discount_percent, discount_text = calculate_discount(total_quantity)
|
||
|
||
partner_dict = dict(partner)
|
||
partner_dict['total_quantity'] = total_quantity
|
||
partner_dict['total_sales'] = partner['total_sales'] or 0
|
||
partner_dict['discount_percent'] = discount_percent
|
||
partner_dict['discount_text'] = discount_text
|
||
|
||
partners_with_discount.append(partner_dict)
|
||
|
||
conn.close()
|
||
return render_template('index.html', partners=partners_with_discount)
|
||
|
||
|
||
@app.route('/add_sale/<int:partner_id>', methods=['GET', 'POST'])
|
||
def add_sale(partner_id):
|
||
if request.method == 'POST':
|
||
try:
|
||
product_id = request.form['product_id']
|
||
quantity = request.form['quantity']
|
||
sale_price = request.form['sale_price']
|
||
sale_date = request.form['sale_date']
|
||
|
||
conn = get_db_connection()
|
||
conn.execute('''
|
||
INSERT INTO Sale (product_id, partner_id, quantity, sale_price, sale_date)
|
||
VALUES (?, ?, ?, ?, ?)
|
||
''', (product_id, partner_id, quantity, sale_price, sale_date))
|
||
|
||
conn.commit()
|
||
conn.close()
|
||
|
||
flash('Продажа успешно добавлена!', 'success')
|
||
return redirect(url_for('sales_history', partner_id=partner_id))
|
||
|
||
except Exception as e:
|
||
flash(f'Ошибка при добавлении продажи: {str(e)}', 'error')
|
||
return redirect(url_for('add_sale', partner_id=partner_id))
|
||
|
||
# GET запрос - показываем форму
|
||
conn = get_db_connection()
|
||
|
||
partner = conn.execute('''
|
||
SELECT p.*, pt.type_name as partner_type_name
|
||
FROM Partner p
|
||
LEFT JOIN PartnerType pt ON p.partner_type_id = pt.id
|
||
WHERE p.id = ?
|
||
''', (partner_id,)).fetchone()
|
||
|
||
products = conn.execute('''
|
||
SELECT p.*, pt.type_name as product_type_name
|
||
FROM Product p
|
||
LEFT JOIN ProductType pt ON p.product_type_id = pt.id
|
||
ORDER BY p.product_name
|
||
''').fetchall()
|
||
|
||
conn.close()
|
||
|
||
if not partner:
|
||
flash('Партнер не найден', 'error')
|
||
return redirect(url_for('index'))
|
||
|
||
today = datetime.now().strftime('%Y-%m-%d')
|
||
|
||
return render_template('add_sale.html', partner=partner, products=products, today=today)
|
||
|
||
|
||
@app.route('/edit_partner/<int:partner_id>', methods=['GET', 'POST'])
|
||
def edit_partner(partner_id):
|
||
conn = get_db_connection()
|
||
|
||
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', '')
|
||
partner_type_id = request.form['partner_type_id']
|
||
rating = request.form.get('rating', 0.0)
|
||
|
||
# Проверяем уникальность ИНН (исключая текущего партнера)
|
||
if inn:
|
||
existing = conn.execute(
|
||
'SELECT id FROM Partner WHERE inn = ? AND id != ?',
|
||
(inn, partner_id)
|
||
).fetchone()
|
||
if existing:
|
||
flash('Партнер с таким ИНН уже существует', 'error')
|
||
conn.close()
|
||
return redirect(url_for('edit_partner', partner_id=partner_id))
|
||
|
||
# Обновляем данные партнера
|
||
conn.execute('''
|
||
UPDATE Partner
|
||
SET name = ?, director = ?, email = ?, phone = ?,
|
||
legal_address = ?, inn = ?, partner_type_id = ?, rating = ?
|
||
WHERE id = ?
|
||
''', (name, director, email, phone, legal_address, inn, partner_type_id, rating, partner_id))
|
||
|
||
conn.commit()
|
||
conn.close()
|
||
|
||
flash('Данные партнера успешно обновлены!', 'success')
|
||
return redirect(url_for('index'))
|
||
|
||
except Exception as e:
|
||
flash(f'Ошибка при обновлении данных: {str(e)}', 'error')
|
||
conn.close()
|
||
return redirect(url_for('edit_partner', partner_id=partner_id))
|
||
|
||
# GET запрос - показываем форму редактирования
|
||
partner = conn.execute('''
|
||
SELECT p.*, pt.type_name as partner_type_name
|
||
FROM Partner p
|
||
LEFT JOIN PartnerType pt ON p.partner_type_id = pt.id
|
||
WHERE p.id = ?
|
||
''', (partner_id,)).fetchone()
|
||
|
||
partner_types = conn.execute('SELECT * FROM PartnerType ORDER BY type_name').fetchall()
|
||
conn.close()
|
||
|
||
if not partner:
|
||
flash('Партнер не найден', 'error')
|
||
return redirect(url_for('index'))
|
||
|
||
return render_template('edit_partner.html', partner=partner, partner_types=partner_types)
|
||
@app.route('/add_partner', methods=['GET', 'POST'])
|
||
def add_partner():
|
||
if request.method == 'POST':
|
||
# Получаем данные из формы
|
||
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', '')
|
||
partner_type_id = request.form['partner_type_id']
|
||
rating = request.form.get('rating', 0.0)
|
||
|
||
try:
|
||
conn = get_db_connection()
|
||
conn.execute('''
|
||
INSERT INTO Partner (name, director, email, phone, legal_address, inn, partner_type_id, rating)
|
||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||
''', (name, director, email, phone, legal_address, inn, partner_type_id, rating))
|
||
|
||
conn.commit()
|
||
conn.close()
|
||
|
||
flash('Партнер успешно добавлен!', 'success')
|
||
return redirect(url_for('index'))
|
||
|
||
except Exception as e:
|
||
flash(f'Ошибка при добавлении партнера: {str(e)}', 'error')
|
||
return redirect(url_for('add_partner'))
|
||
|
||
# GET запрос - показываем форму
|
||
conn = get_db_connection()
|
||
partner_types = conn.execute('SELECT * FROM PartnerType').fetchall()
|
||
conn.close()
|
||
|
||
return render_template('add_partner.html', partner_types=partner_types)
|
||
@app.route('/sales_history/<int:partner_id>')
|
||
def sales_history(partner_id):
|
||
conn = get_db_connection()
|
||
|
||
partner = conn.execute('''
|
||
SELECT p.*, pt.type_name as partner_type_name
|
||
FROM Partner p
|
||
LEFT JOIN PartnerType pt ON p.partner_type_id = pt.id
|
||
WHERE p.id = ?
|
||
''', (partner_id,)).fetchone()
|
||
|
||
# Получаем историю продаж (исправлено: product_name вместо name)
|
||
sales = conn.execute('''
|
||
SELECT
|
||
s.*,
|
||
pr.product_name as product_name,
|
||
pr.article as product_article,
|
||
pt.type_name as product_type_name
|
||
FROM Sale s
|
||
LEFT JOIN Product pr ON s.product_id = pr.id
|
||
LEFT JOIN ProductType pt ON pr.product_type_id = pt.id
|
||
WHERE s.partner_id = ?
|
||
ORDER BY s.sale_date DESC, s.created_at DESC
|
||
''', (partner_id,)).fetchall()
|
||
|
||
# Считаем общую статистику
|
||
total_stats = conn.execute('''
|
||
SELECT
|
||
COUNT(*) as total_sales,
|
||
SUM(s.quantity) as total_quantity,
|
||
SUM(s.quantity * s.sale_price) as total_amount,
|
||
AVG(s.sale_price) as avg_price
|
||
FROM Sale s
|
||
WHERE s.partner_id = ?
|
||
''', (partner_id,)).fetchone()
|
||
|
||
conn.close()
|
||
|
||
return render_template('sales_history.html',
|
||
partner=partner,
|
||
sales=sales,
|
||
total_stats=total_stats)
|
||
|
||
|
||
@app.route('/favicon.ico')
|
||
def favicon():
|
||
return send_from_directory(os.path.join(app.root_path, 'static'),
|
||
'favicon.ico', mimetype='image/vnd.microsoft.icon')
|
||
|
||
|
||
@app.route('/static/<path:filename>')
|
||
def static_files(filename):
|
||
return send_from_directory(app.root_path + '/static', filename)
|
||
|
||
|
||
if __name__ == '__main__':
|
||
app.run(debug=True)
|