diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..a377feb --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..d3ae896 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/salim_project.iml b/.idea/salim_project.iml new file mode 100644 index 0000000..b5ad51a --- /dev/null +++ b/.idea/salim_project.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..d3f6ff6 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1762572998835 + + + + \ No newline at end of file diff --git a/Material_type_import.xlsx b/Material_type_import.xlsx new file mode 100644 index 0000000..14bfbf6 Binary files /dev/null and b/Material_type_import.xlsx differ diff --git a/Partner_products_import.xlsx b/Partner_products_import.xlsx new file mode 100644 index 0000000..eb7b428 Binary files /dev/null and b/Partner_products_import.xlsx differ diff --git a/Partners_import.xlsx b/Partners_import.xlsx new file mode 100644 index 0000000..06dfb34 Binary files /dev/null and b/Partners_import.xlsx differ diff --git a/Product_type_import.xlsx b/Product_type_import.xlsx new file mode 100644 index 0000000..cff7530 Binary files /dev/null and b/Product_type_import.xlsx differ diff --git a/Products_import.xlsx b/Products_import.xlsx new file mode 100644 index 0000000..0ce83b6 Binary files /dev/null and b/Products_import.xlsx differ diff --git a/main.py b/main.py index caf0e66..fc9f7ae 100644 --- a/main.py +++ b/main.py @@ -438,3 +438,4 @@ def display_menu(): if __name__ == "__main__": display_menu() #frergrgrggr +#aaabla \ No newline at end of file diff --git a/main_flask.py b/main_flask.py new file mode 100644 index 0000000..f2b795a --- /dev/null +++ b/main_flask.py @@ -0,0 +1,261 @@ +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/', 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/', 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/') +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/') +def static_files(filename): + return send_from_directory(app.root_path + '/static', filename) + + +if __name__ == '__main__': + app.run(debug=True)