diff --git a/main.py b/main.py index 7581501..3eebe64 100644 --- a/main.py +++ b/main.py @@ -4,12 +4,8 @@ import os import sys import openpyxl -#kmujytgf -#uhliu - def create_tables(db_connection): - # Функция создает структуру таблиц в базе данных cursor = db_connection.cursor() cursor.executescript(''' @@ -37,7 +33,7 @@ def create_tables(db_connection): coefficient DECIMAL(5,2) NOT NULL DEFAULT 1.0 ); - CREATE TABLE IF NOT EXISTS Product (df = pd.read_sql_query(query, conn, params=(limit,)) + CREATE TABLE IF NOT EXISTS Product ( id INTEGER PRIMARY KEY AUTOINCREMENT, product_type_id INTEGER REFERENCES ProductType(id), product_name VARCHAR(255) NOT NULL, @@ -46,7 +42,7 @@ def create_tables(db_connection): created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); - CREATE TABLE IF NOT EXISTS Sale (df = pd.read_sql_query(query, conn, params=(limit,)) + CREATE TABLE IF NOT EXISTS Sale ( id INTEGER PRIMARY KEY AUTOINCREMENT, product_id INTEGER REFERENCES Product(id), partner_id INTEGER REFERENCES Partner(id), @@ -70,7 +66,6 @@ def create_tables(db_connection): def calculate_discount(total_quantity): - # Функция рассчитывает скидку на основе объема продаж if total_quantity >= 300000: return 15, '15% (более 300000 ед.)' elif total_quantity >= 50000: @@ -82,7 +77,6 @@ def calculate_discount(total_quantity): def get_partners(db_path='partners.db', sort_by='rating', ascending=False): - # Функция получает данные о партнерах из базы данных try: conn = sqlite3.connect(db_path) query = """ @@ -103,7 +97,6 @@ def get_partners(db_path='partners.db', sort_by='rating', ascending=False): GROUP BY p.id """ - # Добавляем сортировку if sort_by == 'discount': query += " ORDER BY total_quantity" elif sort_by == 'rating': @@ -120,7 +113,6 @@ def get_partners(db_path='partners.db', sort_by='rating', ascending=False): 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]) @@ -136,7 +128,6 @@ def get_partners(db_path='partners.db', sort_by='rating', ascending=False): def get_sales_history(db_path='partners.db', limit=50, sort_by='date_desc'): - # Функция получает историю продаж try: conn = sqlite3.connect(db_path) query = """ @@ -155,7 +146,6 @@ def get_sales_history(db_path='partners.db', limit=50, sort_by='date_desc'): 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': @@ -177,7 +167,6 @@ def get_sales_history(db_path='partners.db', limit=50, sort_by='date_desc'): return None def print_partner_cards(partners_df): - # Функция выводит информацию о партнерах в красивой форме if partners_df is None or partners_df.empty: print("📭 Нет данных о партнерах") return @@ -219,7 +208,6 @@ def print_partner_cards(partners_df): def print_sales_cards(sales_df): - # Функция выводит историю продаж в табличном представлении if sales_df is None or sales_df.empty: print("📭 Нет данных о продажах") return @@ -254,7 +242,6 @@ def print_sales_cards(sales_df): 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) @@ -277,7 +264,6 @@ def simple_choice(options): def check_database(): - # Проверяет наличие данных в базе conn = sqlite3.connect('partners.db') try: cursor = conn.cursor() @@ -292,7 +278,6 @@ def check_database(): def load_data_from_files(): - # Загружает данные из Excel-файлов в базу данных conn = sqlite3.connect('partners.db') cursor = conn.cursor() @@ -353,7 +338,6 @@ def load_data_from_files(): 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: @@ -361,7 +345,6 @@ def load_data_from_files(): continue product_id = product_result[0] - # Находим ID партнера cursor.execute("SELECT id FROM Partner WHERE name = ?", (row['Наименование партнера'],)) partner_result = cursor.fetchone() if not partner_result: @@ -369,15 +352,11 @@ def load_data_from_files(): 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 (?, ?, ?, ?, ?)""", @@ -397,7 +376,6 @@ def load_data_from_files(): def display_menu(): - # Основное меню программы menu_options = [ 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)', 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам)', @@ -445,4 +423,4 @@ def display_menu(): if __name__ == "__main__": - display_menu() + display_menu() \ No newline at end of file diff --git a/read.txt b/read.txt index fa15bf7..28d983e 100644 --- a/read.txt +++ b/read.txt @@ -1,390 +1,6 @@ Файл с партнерами: Partners_import.xlsx Файл с типами продукции: Product_type_import.xlsx Файл с продуктами: Products_import.xlsx -Файл с продажами: Partner_products_import.xlsx "" - - -# Импортируем библиотеку SQLite3 для взаимодействия с базами данных SQLite -import sqlite3 -# Подключаем библиотеку Pandas для обработки и анализа данных -import pandas as pd -# Подключаем модуль операционной системы Python для работы с файлами и путями -import os -# Подключаем модуль sys для взаимодействия с интерпретатором Python и системой -import sys -# Подключаем библиотеку OpenPyXL для чтения и записи файлов Excel формата .xlsx -import openpyxl - - -import sqlite3 -import pandas as pd -import os -import sys -import openpyxl """Создает все необходимые таблицы в базе данных""" - -# Функция создает структуру таблиц в базе данных -def create_tables(db_connection): -"Создает все необходимые таблицы в базе данных.""" - cursor = db_connection.cursor() - - # Создание таблиц и индексов - cursor.executescript(''' - ... - ''') # Здесь прописаны запросы на создание таблиц и индексов - - db_connection.commit() - print("✅ Таблицы успешно созданы") - - -# Функция рассчитывает скидку на основе объема продаж -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_partners(db_path='partners.db', sort_by='rating', ascending=False): - """Получает данные о партнерах с возможностью сортировки.""" - try: - conn = sqlite3.connect(db_path) - query = """ - ... - """ # Здесь прописан SQL-запрос для выборки данных о партнерах - - # Применяем нужную сортировку и лимитируем количество записей - 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" - 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}") - return None - - -# Функция получает историю продаж -def get_sales_history(db_path='partners.db', limit=50, sort_by='date_desc'): - """Получает историю реализации продукции с разными вариантами сортировки.""" - try: - conn = sqlite3.connect(db_path) - query = """ - ... - """ # Здесь прописан SQL-запрос для выборки истории продаж - - # Применяем сортировку и ограничение числа записей - 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("📭 Нет данных о партнерах") - return - - # Красивый вывод карточек партнеров - for index, row in partners_df.iterrows(): - # Оформление рамки вокруг карточки - print("╔" + "═" * 69 + "╗") - print(f"║ {'КАРТОЧКА ПАРТНЕРА':^67} ║") - print("╠" + "═" * 69 + "╣") - - # Информация о партнере - print(f"║ Тип: {row['Тип партнера']}{' ':<63}║") - print(f"║ Наименование: {row['Наименование партнера']}{' ':<50}║") - print(f"║ Директор: {row['Директор']}{' ':<61}║") - print(f"║ Рейтинг: {row['Рейтинг']}{' ':<63}║") - print(f"║ Продано единиц: {row['total_quantity']:,}{' ':<52}║") - print(f"║ Скидка: {row['Текст_скидки']}{' ':<58}║") - print(f"║ {' ':<67}║") - print(f"║ Электронная почта: {row['Электронная почта']}{' ':<45}║") - print(f"║ Телефон: {row['Телефон']}{' ':<61}║") - print(f"║ {' ':<67}║") - print(f"║ ИНН: {row['ИНН']}{' ':<63}║") - print(f"║ Адрес: {row['Юридический адрес']}{' ':<59}║") - 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)) - 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() - - -# Загружает данные из Excel-файлов в базу данных -def load_data_from_files(): - """Загружает данные из Excel файлов в базу данных.""" - conn = sqlite3.connect('partners.db') - cursor = conn.cursor() - - try: - # 1. Загрузка типов партнеров - print("\n1. 📊 Загрузка типов партнеров...") - partners_df = pd.read_excel(input("Файл с партнерами: ")) - 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(input("Файл с типами продукции: ")) - 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(input("Файл с продуктами: ")) - 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(input("Файл с продажами: ")) - 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() -Файл с партнерами: Partners_import.xlsx -Файл с типами продукции: Product_type_import.xlsx -Файл с продуктами: Products_import.xlsx Файл с продажами: Partner_products_import.xlsx - 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) - 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__": - display_menu()