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
+
+
+ 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)