diff --git a/main.py b/main.py index 68cc85e..4cc45b2 100644 --- a/main.py +++ b/main.py @@ -1,322 +1,454 @@ import sqlite3 -import datetime import pandas as pd import os - +import sys +import openpyxl #Черепанова -if os.path.exists('partners.db'): - os.remove('partners.db') - print(f"База данных {'partners.db'} удалена") -else: - print(f"База данных {'partners.db'} не найдена, создаем новую") -conn = sqlite3.connect('partners.db') -cursor = conn.cursor() +def create_tables(db_connection): + cursor = db_connection.cursor() + + cursor.executescript(''' + CREATE TABLE IF NOT EXISTS PartnerType ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + type_name VARCHAR(100) NOT NULL UNIQUE + ); + + CREATE TABLE IF NOT EXISTS Partner ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + partner_type_id INTEGER REFERENCES PartnerType(id), + name VARCHAR(255) NOT NULL, + director VARCHAR(255), + email VARCHAR(255), + phone VARCHAR(50), + legal_address TEXT, + inn VARCHAR(20) UNIQUE, + rating DECIMAL(3,2) DEFAULT 0.0, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ); + + CREATE TABLE IF NOT EXISTS ProductType ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + type_name VARCHAR(100) NOT NULL UNIQUE, + coefficient DECIMAL(5,2) NOT NULL DEFAULT 1.0 + ); + + CREATE TABLE IF NOT EXISTS Product ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + product_type_id INTEGER REFERENCES ProductType(id), + product_name VARCHAR(255) NOT NULL, + article VARCHAR(100) UNIQUE NOT NULL, + min_partner_price DECIMAL(15,2) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ); + + CREATE TABLE IF NOT EXISTS Sale ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + product_id INTEGER REFERENCES Product(id), + partner_id INTEGER REFERENCES Partner(id), + quantity INTEGER NOT NULL CHECK (quantity > 0), + sale_date DATE NOT NULL, + sale_price DECIMAL(15,2) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ); + + CREATE INDEX IF NOT EXISTS idx_partner_type ON Partner(partner_type_id); + CREATE INDEX IF NOT EXISTS idx_partner_inn ON Partner(inn); + CREATE INDEX IF NOT EXISTS idx_product_type ON Product(product_type_id); + CREATE INDEX IF NOT EXISTS idx_product_article ON Product(article); + CREATE INDEX IF NOT EXISTS idx_sale_product ON Sale(product_id); + CREATE INDEX IF NOT EXISTS idx_sale_partner ON Sale(partner_id); + CREATE INDEX IF NOT EXISTS idx_sale_date ON Sale(sale_date); + ''') + + db_connection.commit() + print("✅ Таблицы успешно созданы") -# Создаем таблицы -cursor.executescript(''' -CREATE TABLE IF NOT EXISTS PartnerType ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - type_name VARCHAR(100) NOT NULL UNIQUE); - -CREATE TABLE IF NOT EXISTS Partner ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - partner_type_id INTEGER REFERENCES PartnerType(id), - name VARCHAR(255) NOT NULL, - director VARCHAR(255), - email VARCHAR(255), - phone VARCHAR(50), - legal_address TEXT, - inn VARCHAR(20) UNIQUE, - rating DECIMAL(3,2) DEFAULT 0.0, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -); -CREATE TABLE IF NOT EXISTS ProductType ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - type_name VARCHAR(100) NOT NULL UNIQUE, - coefficient DECIMAL(5,2) NOT NULL DEFAULT 1.0 -); -CREATE TABLE IF NOT EXISTS Product ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - product_type_id INTEGER REFERENCES ProductType(id), - product_name VARCHAR(255) NOT NULL, - article VARCHAR(100) UNIQUE NOT NULL, - min_partner_price DECIMAL(15,2) NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -); -CREATE TABLE IF NOT EXISTS Sale ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - product_id INTEGER REFERENCES Product(id), - partner_id INTEGER REFERENCES Partner(id), - quantity INTEGER NOT NULL CHECK (quantity > 0), - sale_date DATE NOT NULL, - sale_price DECIMAL(15,2) NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -); -CREATE INDEX IF NOT EXISTS idx_partner_type ON Partner(partner_type_id); -CREATE INDEX IF NOT EXISTS idx_partner_inn ON Partner(inn); -CREATE INDEX IF NOT EXISTS idx_product_type ON Product(product_type_id); -CREATE INDEX IF NOT EXISTS idx_product_article ON Product(article); -CREATE INDEX IF NOT EXISTS idx_sale_product ON Sale(product_id); -CREATE INDEX IF NOT EXISTS idx_sale_partner ON Sale(partner_id); -CREATE INDEX IF NOT EXISTS idx_sale_date ON Sale(sale_date); -''') -partner_types = [ - ('ЗАО',), - ('ООО',), - ('ПАО',), - ('ОАО',) -] -cursor.executemany('INSERT OR IGNORE INTO PartnerType (type_name) VALUES (?)', partner_types) - -partners = [ - (1, 'База Строитель', 'Иванова Александра Ивановна', 'aleksandraivanova@ml.ru', - '493 123 45 67', '652050, Кемеровская область, город Юрга, ул. Лесная, 15', '2222455179', 7), - (2, 'Паркет 29', 'Петров Василий Петрович', 'vppetrov@vl.ru', - '987 123 56 78', '164500, Архангельская область, город Северодвинск, ул. Строителей, 18', '3333888520', 7), - (3, 'Стройсервис', 'Соловьев Андрей Николаевич', 'ansolovev@st.ru', - '812 223 32 00', '188910, Ленинградская область, город Приморск, ул. Парковая, 21', '4440391035', 7), - (4, 'Ремонт и отделка', 'Воробьева Екатерина Валерьевна', 'ekaterina.vorobeva@ml.ru', - '444 222 33 11', '143960, Московская область, город Реутов, ул. Свободы, 51', '1111520857', 5), - (1, 'МонтажПро', 'Степанов Степан Сергеевич', 'stepanov@stepan.ru', - '912 888 33 33', '309500, Белгородская область, город Старый Оскол, ул. Рабочая, 122', '5552431140', 10) -] - -cursor.executemany(''' -INSERT OR IGNORE INTO Partner (partner_type_id, name, director, email, phone, legal_address, inn, rating) -VALUES (?, ?, ?, ?, ?, ?, ?, ?) -''', partners) - -# Заполняем типы продукции -product_types = [ - ('Ламинат', 2.35), - ('Массивная доска', 5.15), - ('Паркетная доска', 4.34), - ('Пробковое покрытие', 1.5) -] - -cursor.executemany('INSERT OR IGNORE INTO ProductType (type_name, coefficient) VALUES (?, ?)', product_types) - -products = [ - (3, 'Паркетная доска Ясень темный однополосная 14 мм', '8758385', 4456.90), - (3, 'Инженерная доска Дуб Французская елка однополосная 12 мм', '8858958', 7330.99), - (1, 'Ламинат Дуб дымчато-белый 33 класс 12 мм', '7750282', 1799.33), - (1, 'Ламинат Дуб серый 32 класс 8 мм с фаской', '7028748', 3890.41), - (4, 'Пробковое напольное клеевое покрытие 32 класс 4 мм', '5012543', 5450.59) -] - -cursor.executemany(''' -INSERT OR IGNORE INTO Product (product_type_id, product_name, article, min_partner_price) -VALUES (?, ?, ?, ?) -''', products) - -# Заполняем продажи -sales_data = [ - # Формат: (product_name, partner_name, quantity, sale_date) - ('Паркетная доска Ясень темный однополосная 14 мм', 'База Строитель', 15500, '2023-03-23'), - ('Ламинат Дуб дымчато-белый 33 класс 12 мм', 'База Строитель', 12350, '2023-12-18'), - ('Ламинат Дуб серый 32 класс 8 мм с фаской', 'База Строитель', 37400, '2024-06-07'), - ('Инженерная доска Дуб Французская елка однополосная 12 мм', 'Паркет 29', 35000, '2022-12-02'), - ('Пробковое напольное клеевое покрытие 32 класс 4 мм', 'Паркет 29', 1250, '2023-05-17'), - ('Ламинат Дуб дымчато-белый 33 класс 12 мм', 'Паркет 29', 1000, '2024-06-07'), - ('Паркетная доска Ясень темный однополосная 14 мм', 'Паркет 29', 7550, '2024-07-01'), - ('Паркетная доска Ясень темный однополосная 14 мм', 'Стройсервис', 7250, '2023-01-22'), - ('Инженерная доска Дуб Французская елка однополосная 12 мм', 'Стройсервис', 2500, '2024-07-05'), - ('Ламинат Дуб серый 32 класс 8 мм с фаской', 'Ремонт и отделка', 59050, '2023-03-20'), - ('Ламинат Дуб дымчато-белый 33 класс 12 мм', 'Ремонт и отделка', 37200, '2024-03-12'), - ('Пробковое напольное клеевое покрытие 32 класс 4 мм', 'Ремонт и отделка', 4500, '2024-05-14'), - ('Ламинат Дуб дымчато-белый 33 класс 12 мм', 'МонтажПро', 50000, '2023-09-19'), - ('Ламинат Дуб серый 32 класс 8 мм с фаской', 'МонтажПро', 670000, '2023-11-10'), - ('Паркетная доска Ясень темный однополосная 14 мм', 'МонтажПро', 35000, '2024-04-15'), - ('Инженерная доска Дуб Французская елка однополосная 12 мм', 'МонтажПро', 25000, '2024-06-12') -] +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 ед.)' -def get_ids(product_name, partner_name): - cursor.execute('SELECT id FROM Product WHERE product_name = ?', (product_name,)) - product_id = cursor.fetchone()[0] - - cursor.execute('SELECT id FROM Partner WHERE name = ?', (partner_name,)) - partner_id = cursor.fetchone()[0] - - cursor.execute('SELECT min_partner_price FROM Product WHERE product_name = ?', (product_name,)) - sale_price = cursor.fetchone()[0] - - return product_id, partner_id, sale_price - - -for sale in sales_data: - product_name, partner_name, quantity, sale_date = sale - try: - product_id, partner_id, sale_price = get_ids(product_name, partner_name) - cursor.execute(''' - INSERT INTO Sale (product_id, partner_id, quantity, sale_date, sale_price) - VALUES (?, ?, ?, ?, ?) - ''', (product_id, partner_id, quantity, sale_date, sale_price)) - except Exception as e: - print(f"Ошибка при добавлении продажи: {sale}, ошибка: {e}") - -# Сохраняем изменения -conn.commit() -def get_partners(db_path='partners.db', sort_by= 'rating', ascending =False): - try: - # Подключаемся к базе данных - conn = sqlite3. connect (db_path) - # SQL запрос для получения данных о партнерах - query = """SELECT - pt. type_name AS "Тип партнера", - p. name AS "Наименование партнера", - p.director AS "Директор", - p. email AS "Электронная почта", - p. phone AS "Телефон", - p. Legal_address AS "Юридический адрес", - p. inn AS "ИНН", - p.rating AS "Рейтинг", - p.created_at AS "Дата создания" - FROM Partner p - JOIN PartnerType pt ON p.partner_type_id = pt.id - """ - if sort_by == 'rating': - query += " ORDER BY p.rating" - elif sort_by == 'name': - query += " ORDER BY p.name" - elif sort_by == 'type': - query += " ORDER BY pt.type_name, p.name" - else: - query += " ORDER BY p.rating" - query += " DESC" if not ascending else " ASC" - df = pd.read_sql_query(query, conn) - # Закрываем соединение - conn.close() - return df - - except sqlite3.Error as e: - print(f"Ошибка базы данных: {e}") - return None - except Exception as e: - print(f"Общая ошибка: {e}") - return None - -def print_partners(partners_df): - """ФУНКЦИЯ для красивого вывода данных о партнерах""" - if partners_df is None or partners_df.empty: - print("Нет данных о партнерах") - return - - # Выводим данные в удобном формате - print("=" * 120) - print("{:<7} {:<20} {:<35} {:<20} {:<10}".format( - "Тип", "Наименование", "Директор","Телефон","Рейтинг" - )) - print("=" * 120) - - for _, row in partners_df.iterrows(): - print("{:<7} {:<20} {:<35} {:<20} {:<10}".format( - row['Тип партнера'] [:7], - row['Наименование партнера'] [:20], - row['Директор'] [:35], - row['Телефон'][:20], - row['Рейтинг'] - )) - print("=" * 120) - print(f"Всего партнеров: {len(partners_df)}") - - -def get_partners_with_stats(db_path='partners.db'): - """Функция для получения партнеров со статистикой продаж""" - +def get_partners(db_path='partners.db', sort_by='rating', ascending=False): try: conn = sqlite3.connect(db_path) query = """ - SELECT - pt.type_name AS "Тип партнера", - p.name AS "Наименование партнера", - p.director AS "Директор", - p.rating AS "Рейтинг", - COUNT (s.id) AS "Количество продаж", - SUM(COALESCE(s.quantity, 0)) AS "Общее количество товаров", - SUM(COALESCE(s.quantity * s.sale_price, 0)) AS "Общий объем продаж", - p.created_at AS "Дата регистрации" + SELECT + pt.type_name AS "Тип партнера", + p.name AS "Наименование партнера", + p.director AS "Директор", + p.email AS "Электронная почта", + p.phone AS "Телефон", + p.legal_address AS "Юридический адрес", + p.inn AS "ИНН", + p.rating AS "Рейтинг", + p.created_at AS "Дата создания", + COALESCE(SUM(s.quantity), 0) as total_quantity FROM Partner p 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 "Общий объем продаж" DESC""" + """ + + + if sort_by == 'discount': + query += " ORDER BY total_quantity" + elif sort_by == 'rating': + query += " ORDER BY p.rating" + elif sort_by == 'name': + query += " ORDER BY p.name" + elif sort_by == 'type': + query += " ORDER BY pt.type_name, p.name" + + elif sort_by == 'inn': + query += " ORDER BY p.inn" + + else: + query += " ORDER BY p.rating" + + query += " DESC" if not ascending else " ASC" df = pd.read_sql_query(query, conn) conn.close() + + + if not df.empty: + df['Скидка'] = df['total_quantity'].apply(lambda x: calculate_discount(x)[0]) + df['Текст_скидки'] = df['total_quantity'].apply(lambda x: calculate_discount(x)[1]) + return df + + except sqlite3.Error as e: + print(f"❌ Ошибка базы данных: {e}") + return None except Exception as e: - print(f"Общая ошибка: {e}") + print(f"❌ Общая ошибка: {e}") return None - # print("╔" + "═" * 69 + "╗") - # print(f"║ {'КАРТОЧКА ПАРТНЕРА':^67} ║") - # print("╠" + "═" * 69 + "╣") - # print("╚" + "═" * 69 + "╝") + +def get_sales_history(db_path='partners.db', limit=50, sort_by='date_desc'): + try: + conn = sqlite3.connect(db_path) + query = """ + SELECT + s.sale_date AS "Дата продажи", + p.name AS "Партнер", + pr.product_name AS "Продукция", + pr.article AS "Артикул", + s.quantity AS "Количество", + s.sale_price AS "Цена за единицу", + (s.quantity * s.sale_price) AS "Общая сумма", + pt.type_name AS "Тип продукции" + FROM Sale s + JOIN Partner p ON s.partner_id = p.id + JOIN Product pr ON s.product_id = pr.id + JOIN ProductType pt ON pr.product_type_id = pt.id + """ + + + if sort_by == 'date_desc': + query += " ORDER BY s.sale_date DESC, s.created_at DESC" + elif sort_by == 'date_asc': + query += " ORDER BY s.sale_date ASC, s.created_at ASC" + elif sort_by == 'quantity_desc': + query += " ORDER BY s.quantity DESC" + elif sort_by == 'amount_desc': + query += " ORDER BY (s.quantity * s.sale_price) DESC" + else: + query += " ORDER BY s.sale_date DESC, s.created_at DESC" + + query += " LIMIT ?" + + df = pd.read_sql_query(query, conn, params=(limit,)) + conn.close() + return df + except Exception as e: + print(f"❌ Ошибка при получении истории продаж: {e}") + return None def print_partner_cards(partners_df): - """ФУНКЦИЯ для вывода партнеров в виде карточек с выравниванием""" + if partners_df is None or partners_df.empty: - print("Нет данных о партнерах") + print("📭 Нет данных о партнерах") return for index, row in partners_df.iterrows(): - print("╔" + "═" * 70 + "╗") - print(f"║{'КАРТОЧКА ПАРТНЕРА':^70}║") - print("╠" + "═" * 70 + "╣") + print("╔" + "═" * 69 + "╗") + print(f"║ {'КАРТОЧКА ПАРТНЕРА':^67} ║") + print("╠" + "═" * 69 + "╣") - # Используем разные кавычки для избежания конфликта type_text = f"Тип: {row['Тип партнера']}" name_text = f"Наименование: {row['Наименование партнера']}" director_text = f"Директор: {row['Директор']}" rating_text = f"Рейтинг: {row['Рейтинг']}" + quantity_text = f"Продано единиц: {row['total_quantity']:,}" + discount_text = f"Скидка: {row['Текст_скидки']}" email_text = f"Контакты: {row['Электронная почта']}" phone_text = f"Телефон: {row['Телефон']}" inn_text = f"ИНН: {row['ИНН']}" - address_text = row['Юридический адрес'] - print(f"║{type_text:<70}║") - print(f"║{name_text:<70}║") - print(f"║{director_text:<70}║") - print(f"║{rating_text:<70}║") - print(f"║{'':<70}║") - print(f"║{email_text:<70}║") - print(f"║{phone_text:<70}║") - print(f"║{'':<70}║") - print(f"║{inn_text:<70}║") - print(f"║{address_text:<70}║") - print("╚" + "═" * 70 + "╝") + address = row['Юридический адрес'] + if len(address) > 60: + address = address[:57] + "..." + address_text = f"Адрес: {address}" + + print(f"║ {type_text:<67} ║") + print(f"║ {name_text:<67} ║") + print(f"║ {director_text:<67} ║") + print(f"║ {rating_text:<67} ║") + print(f"║ {quantity_text:<67} ║") + print(f"║ {discount_text:<67} ║") + print(f"║ {'':<67} ║") + print(f"║ {email_text:<67} ║") + print(f"║ {phone_text:<67} ║") + print(f"║ {'':<67} ║") + print(f"║ {inn_text:<67} ║") + print(f"║ {address_text:<67} ║") + print("╚" + "═" * 69 + "╝") print() + +def print_sales_cards(sales_df): + + if sales_df is None or sales_df.empty: + print("📭 Нет данных о продажах") + return + + print("╔" + "═" * 147 + "╗") + print(f"║ {'ИСТОРИЯ РЕАЛИЗАЦИИ ПРОДУКЦИИ':^145} ║") + print("╠" + "═" * 147 + "╣") + + + headers = ["Дата", "Партнер", "Продукция", "Артикул", "Кол-во", "Цена", "Сумма"] + print("║ {:<12} {:<18} {:<59} {:<3} {:>9} {:>8} {:>13} ║".format( + headers[0], headers[1], headers[2], headers[3], headers[4], headers[5], headers[6] + )) + print("╠" + "═" * 147 + "╣") + + + for index, row in sales_df.iterrows(): + date = str(row['Дата продажи'])[:10] + partner = row['Партнер'] + product = row['Продукция'] + article = str(row['Артикул']) + quantity = f"{row['Количество']:,}" + price = f"{row['Цена за единицу']:,.2f}" + total = f"{row['Общая сумма']:,.2f}" + + print(f"║ {date} ║ {partner.ljust(16)} ║ {product.ljust(57)} ║ {article.ljust(8)} ║ {quantity.ljust(8)} ║ {price.ljust(10)} ║ {total.ljust(18)} ║") + + print("╚" + "═" * 147 + "╝") + + + total_quantity = sales_df['Количество'].sum() + total_amount = sales_df['Общая сумма'].sum() + print(f"📊 ИТОГО: {len(sales_df)} продаж, {total_quantity:,} единиц, общая сумма: {total_amount:,.2f} руб.") +def simple_choice(options): + + print("\n" + "=" * 50) + print("ВЫБЕРИТЕ ОПЦИЮ:") + print("=" * 50) + for i, option in enumerate(options, 1): + print(f"{i}. {option}") + + while True: + try: + choice = input(f"\nВведите номер (1-{len(options)}): ").strip() + if choice.isdigit(): + choice_num = int(choice) + if 1 <= choice_num <= len(options): + return options[choice_num - 1] + print(f"❌ Пожалуйста, введите число от 1 до {len(options)}") + except (ValueError, EOFError): + print("❌ Неверный ввод. Попробуйте еще раз.") + except KeyboardInterrupt: + print("\n👋 Программа прервана пользователем.") + sys.exit(0) + + +def check_database(): + + conn = sqlite3.connect('partners.db') + try: + cursor = conn.cursor() + print("\n🔍 Проверка загруженных данных:") + tables = ['PartnerType', 'Partner', 'ProductType', 'Product', 'Sale'] + for table in tables: + cursor.execute(f"SELECT COUNT(*) FROM {table}") + count = cursor.fetchone()[0] + print(f" {table}: {count} записей") + finally: + conn.close() + + +def load_data_from_files(): + + conn = sqlite3.connect('partners.db') + cursor = conn.cursor() + + try: + + print("\n📁 Введите имена файлов:") + partners_file = input("Файл с партнерами: ") + product_type_file = input("Файл с типами продукции: ") + products_file = input("Файл с продуктами: ") + sales_file = input("Файл с продажами: ") + + # 1. Загрузка типов партнеров + print("\n1. 📊 Загрузка типов партнеров...") + partners_df = pd.read_excel(partners_file) + partner_types = partners_df['Тип партнера'].unique() + for partner_type in partner_types: + cursor.execute("INSERT OR IGNORE INTO PartnerType (type_name) VALUES (?)", (partner_type,)) + + # 2. Загрузка партнеров + print("2. 👥 Загрузка партнеров...") + for _, row in partners_df.iterrows(): + cursor.execute("SELECT id FROM PartnerType WHERE type_name = ?", (row['Тип партнера'],)) + partner_type_id = cursor.fetchone()[0] + + cursor.execute("""INSERT OR IGNORE INTO Partner + (partner_type_id, name, director, email, phone, legal_address, inn, rating) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", + (partner_type_id, row['Наименование партнера'], row['Директор'], + row['Электронная почта партнера'], row['Телефон партнера'], + row['Юридический адрес партнера'], row['ИНН'], row['Рейтинг']) + ) + + # 3. Загрузка типов продукции + print("3. 📦 Загрузка типов продукции...") + product_type_df = pd.read_excel(product_type_file) + for _, row in product_type_df.iterrows(): + cursor.execute("INSERT OR IGNORE INTO ProductType (type_name, coefficient) VALUES (?, ?)", + (row['Тип продукции'], row['Коэффициент типа продукции']) + ) + + # 4. Загрузка продуктов + print("4. 🏷️ Загрузка продуктов...") + products_df = pd.read_excel(products_file) + for _, row in products_df.iterrows(): + cursor.execute("SELECT id FROM ProductType WHERE type_name = ?", (row['Тип продукции'],)) + product_type_id = cursor.fetchone()[0] + + cursor.execute("""INSERT OR IGNORE INTO Product + (product_type_id, product_name, article, min_partner_price) + VALUES (?, ?, ?, ?)""", + (product_type_id, row['Наименование продукции'], + row['Артикул'], row['Минимальная стоимость для партнера']) + ) + + # 5. Загрузка продаж + print("5. 💰 Загрузка продаж...") + sales_df = pd.read_excel(sales_file) + loaded_sales = 0 + + for _, row in sales_df.iterrows(): + # Находим ID продукта + cursor.execute("SELECT id FROM Product WHERE product_name = ?", (row['Продукция'],)) + product_result = cursor.fetchone() + if not product_result: + print(f" ⚠️ Продукт не найден: {row['Продукция']}") + continue + product_id = product_result[0] + + # Находим ID партнера + cursor.execute("SELECT id FROM Partner WHERE name = ?", (row['Наименование партнера'],)) + partner_result = cursor.fetchone() + if not partner_result: + print(f" ⚠️ Партнер не найден: {row['Наименование партнера']}") + continue + partner_id = partner_result[0] + + # Получаем цену продажи + cursor.execute("SELECT min_partner_price FROM Product WHERE id = ?", (product_id,)) + min_price_result = cursor.fetchone() + sale_price = min_price_result[0] if min_price_result else 0 + + # Преобразуем дату + sale_date = pd.to_datetime(row['Дата продажи']).strftime('%Y-%m-%d') + + # Вставляем продажу + cursor.execute("""INSERT INTO Sale + (product_id, partner_id, quantity, sale_date, sale_price) + VALUES (?, ?, ?, ?, ?)""", + (product_id, partner_id, row['Количество продукции'], sale_date, sale_price) + ) + loaded_sales += 1 + + conn.commit() + print(f"✅ Данные успешно загружены! Загружено {loaded_sales} продаж") + check_database() + + except Exception as e: + print(f"❌ Ошибка при загрузке данных: {e}") + conn.rollback() + finally: + conn.close() + + +def display_menu(): + + menu_options = [ + 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)', + 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам)', + 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по ИНН)', + 'ИСТОРИЯ РЕАЛИЗАЦИИ', + 'ЗАПОЛНЕНИЕ БД из файлов', + 'ВЫХОД' + ] + + while True: + choice = simple_choice(menu_options) + + if choice == 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)': + print("\n🎯 КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)") + print("═" * 70) + partners = get_partners(sort_by='rating', ascending=False) + print_partner_cards(partners) + + elif choice == 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам)': + print("\n📊 КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам)") + print("═" * 70) + partners = get_partners(sort_by='discount', ascending=False) + print_partner_cards(partners) + + elif choice == 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по ИНН)': + print("\n🔢 КАРТОЧКИ ПАРТНЕРОВ (сортировка по ИНН)") + print("═" * 70) + partners = get_partners(sort_by='inn', ascending=True) + print_partner_cards(partners) + + elif choice == 'ИСТОРИЯ РЕАЛИЗАЦИИ': + print("\n📈 ИСТОРИЯ РЕАЛИЗАЦИИ ПРОДУКЦИИ") + print("═" * 70) + sales = get_sales_history(limit=50) + print_sales_cards(sales) + + elif choice == 'ЗАПОЛНЕНИЕ БД из файлов': + if os.path.exists('partners.db'): + os.remove('partners.db') + print("🗑️ База данных partners.db удалена") + else: + print("ℹ️ База данных partners.db не найдена, создаем новую") + + conn = sqlite3.connect('partners.db') + create_tables(conn) + conn.close() + load_data_from_files() + + elif choice == 'ВЫХОД': + print("\n👋 До свидания!") + break + + if __name__ == "__main__": - # Проверяем данные - print("Данные успешно добавлены в базу данных!") - print("\nКоличество записей в таблицах:") - tables = ['PartnerType', 'Partner', 'ProductType', 'Product', 'Sale'] - for table in tables: - cursor.execute(f'SELECT COUNT(*) FROM {table}') - count = cursor.fetchone()[0] - print(f"{table}: {count} записей") - conn.close() - - print("1. КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)") - print("=" * 70) - partners = get_partners(sort_by='rating', ascending=False) - print_partner_cards(partners) - - # print("\n3. Партнеры со статистикой продаж:") - # partners_stats = get_partners_with_stats() - # - # if partners_stats is not None: - # print(partners_stats.to_string(index=False)) - - # - # print("\n4. Полные данные о партнерах:") - # # Выводим полную информацию в табличном виде - # full_data = get_partners() - # if full_data is not None: - # print(full_data.to_string(index=False)) + display_menu()