demo_diana/read.txt

772 lines
44 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Файл с партнерами: 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()
###1 def calculate_discount(total_quantity):
"""Рассчитывает скидку на основе общего количества проданной продукции
Args:
total_quantity (int): общее количество проданной продукции
Returns:
tuple: кортеж содержащий:
- discount_percent (int): процент скидки
- discount_description (str): текстовое описание скидки
Discount tiers:
- 15%: при объеме продаж от 300000 единиц
- 10%: при объеме продаж от 50000 до 300000 единиц
- 5%: при объеме продаж от 10000 до 50000 единиц
- 0%: при объеме продаж менее 10000 единиц
"""
###2 def get_partners(db_path='partners.db', sort_by='rating', ascending=False):
"""Получает данные о партнерах из базы данных с возможностью сортировки и расчета скидок
Args:
db_path (str): путь к файлу базы данных SQLite. По умолчанию 'partners.db'
sort_by (str): поле для сортировки. Допустимые значения:
- 'rating': по рейтингу (по умолчанию)
- 'discount': по общему количеству продаж (для расчета скидки)
- 'name': по наименованию партнера
- 'type': по типу партнера и наименованию
ascending (bool): направление сортировки.
- False: по убыванию (по умолчанию)
- True: по возрастанию
Returns:
pandas.DataFrame или None: DataFrame с данными партнеров или None в случае ошибки
Структура возвращаемого DataFrame:
- Тип партнера
- Наименование партнера
- Директор
- Электронная почта
- Телефон
- Юридический адрес
- ИНН
- Рейтинг
- Дата создания
- total_quantity: общее количество продаж (скрытое поле)
- Скидка: процент скидки на основе total_quantity
- Текст_скидки: текстовое описание скидки
Raises:
sqlite3.Error: ошибки работы с базой данных
Exception: другие возможные ошибки
Example:
>>> df = get_partners(sort_by='discount', ascending=True)
>>> df = get_partners('my_database.db', sort_by='name')
"""
### 3 def get_sales_history(db_path='partners.db', limit=50, sort_by='date_desc'):
"""Получает историю реализации продукции с разными вариантами сортировки
Args:
db_path (str): путь к файлу базы данных SQLite. По умолчанию 'partners.db'
limit (int): ограничение количества возвращаемых записей. По умолчанию 50
sort_by (str): критерий сортировки данных. Допустимые значения:
- 'date_desc': по дате продажи (новые сверху, по умолчанию)
- 'date_asc': по дате продажи (старые сверху)
- 'quantity_desc': по количеству (по убыванию)
- 'amount_desc': по общей сумме (по убыванию)
Returns:
pandas.DataFrame или None: DataFrame с историей продаж или None в случае ошибки
Структура возвращаемого DataFrame:
- Дата продажи: дата осуществления продажи
- Партнер: наименование партнера
- Продукция: название продукции
- Артикул: артикул продукции
- Количество: количество проданных единиц
- Цена за единицу: цена за одну единицу продукции
- Общая сумма: общая сумма продажи (рассчитывается как количество × цена)
- Тип продукции: категория продукции
Raises:
Exception: ошибки при выполнении запроса к базе данных
Example:
>>> # Получить последние 50 продаж
>>> df = get_sales_history()
>>> # Получить 100 самых крупных продаж по сумме
>>> df = get_sales_history(limit=100, sort_by='amount_desc')
>>> # Получить историю продаж в хронологическом порядке
>>> df = get_sales_history(sort_by='date_asc', limit=200)
"""
###4 def print_partner_cards(partners_df):
"""Выводит карточки партнеров в красивом формате с рамкой
Args:
partners_df (pandas.DataFrame): DataFrame с данными партнеров, полученный из функции get_partners()
Returns:
None: функция выполняет только вывод в консоль
Формат вывода:
Каждая карточка партнера оформлена в виде рамки с следующими полями:
- Тип партнера
- Наименование партнера
- Директор
- Рейтинг
- Общее количество проданных единиц (форматированное с разделителями тысяч)
- Размер и описание скидки
- Электронная почта
- Телефон
- ИНН
- Юридический адрес (обрезается до 60 символов если слишком длинный)
Особенности:
- Если передан пустой DataFrame или None, выводится сообщение об отсутствии данных
- Адрес автоматически обрезается если превышает 60 символов
- Числовые значения количества форматируются с разделителями тысяч
- Между карточками добавляются пустые строки для лучшей читаемости
Example:
>>> partners_data = get_partners()
>>> print_partner_cards(partners_data)
╔═══════════════════════════════════════════════════════════════════════╗
║ КАРТОЧКА ПАРТНЕРА ║
╠═══════════════════════════════════════════════════════════════════════╣
║ Тип: Поставщик ║
║ Наименование: ООО "Ромашка" ║
║ Директор: Иванов Иван Иванович ║
║ Рейтинг: 4.8 ║
║ Продано единиц: 150,000 ║
║ Скидка: 10% (50000-300000 ед.) ║
║ ║
║ Контакты: info@romashka.ru ║
║ Телефон: +7 (495) 123-45-67 ║
║ ║
║ ИНН: 7712345678 ║
║ Адрес: г. Москва, ул. Ленина, д. 1, офис 25 ║
╚═══════════════════════════════════════════════════════════════════════╝
"""
###5 def print_sales_cards(sales_df):
"""Выводит историю реализации продукции в виде форматированной таблицы с рамкой
Args:
sales_df (pandas.DataFrame): DataFrame с данными о продажах, полученный из функции get_sales_history()
Returns:
None: функция выполняет только вывод в консоль
Формат вывода:
Таблица с рамкой содержит следующие колонки:
- Дата: дата продажи (обрезается до 10 символов)
- Партнер: наименование партнера (максимум 16 символов)
- Продукция: название продукции (максимум 57 символов)
- Артикул: артикул продукции (максимум 8 символов)
- Кол-во: количество проданных единиц (форматируется с разделителями тысяч)
- Цена: цена за единицу (форматируется с двумя decimal places)
- Сумма: общая сумма продажи (форматируется с двумя decimal places)
Особенности:
- Если передан пустой DataFrame или None, выводится сообщение об отсутствии данных
- Все числовые значения форматируются с разделителями тысяч и двумя знаками после запятой
- В конце таблицы выводятся итоговые показатели:
* Количество продаж
* Общее количество проданных единиц
* Общая сумма всех продаж
- Ширина таблицы фиксирована (147 символов) для сохранения форматирования
Example:
>>> sales_data = get_sales_history(limit=10)
>>> print_sales_cards(sales_data)
╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ ИСТОРИЯ РЕАЛИЗАЦИИ ПРОДУКЦИИ ║
╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ Дата Партнер Продукция Арт Кол-во Цена Сумма ║
╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ 2024-01-15 ║ ООО "Ромашка" ║ Процессор Intel Core i7-13700K ║ A123 ║ 150 ║ 25,000.00 ║ 3,750,000.00 ║
║ 2024-01-14 ║ ИП Петров ║ Монитор Samsung Odyssey G7 27" ║ B456 ║ 50 ║ 35,000.00 ║ 1,750,000.00 ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
📊 ИТОГО: 2 продаж, 200 единиц, общая сумма: 5,500,000.00 руб.
"""
###6 def check_database():
"""Упрощенная функция выбора опции из списка с валидацией ввода
Args:
options (list): список строк с доступными опциями для выбора
Returns:
str: выбранная опция из списка options
Особенности:
- Выводит пронумерованный список опций в красивом формате
- Запрашивает ввод пользователя с валидацией
- Обрабатывает некорректный ввод и повторяет запрос
- Обрабатывает прерывание программы (Ctrl+C) с graceful shutdown
- Поддерживает ввод только цифровых значений в допустимом диапазоне
Raises:
SystemExit: при прерывании программы пользователем (KeyboardInterrupt)
Example:
>>> options = ["Показать всех партнеров", "История продаж", "Выход"]
>>> choice = simple_choice(options)
==================================================
ВЫБЕРИТЕ ОПЦИЮ:
==================================================
1. Показать всех партнеров
2. История продаж
3. Выход
Введите номер (1-3): 2
>>> print(choice)
"История продаж"
Обработка ошибок:
- Некорректный ввод (не цифры): повторный запрос
- Число вне диапазона: повторный запрос
- Прерывание (Ctrl+C): graceful exit программы
- EOF (Ctrl+D в Unix): обрабатывается как некорректный ввод
"""
"""Проверяет загруженные данные в базе данных и выводит статистику по таблицам
Функция подключается к SQLite базе данных и подсчитывает количество записей
в каждой из основных таблиц системы для проверки целостности данных.
Args:
None: использует фиксированный путь к базе данных 'partners.db'
Returns:
None: функция выполняет только вывод статистики в консоль
Проверяемые таблицы:
- PartnerType: типы партнеров (поставщики, клиенты и т.д.)
- Partner: основные данные о партнерах
- ProductType: категории продукции
- Product: данные о продукции
- Sale: история продаж
Особенности:
- Автоматически закрывает соединение с базой данных используя try-finally
- Выводит результаты в читаемом формате с эмодзи для наглядности
- Не обрабатывает ошибки явно - предполагается что база данных существует
и доступна для чтения
Example:
>>> check_database()
🔍 Проверка загруженных данных:
PartnerType: 3 записей
Partner: 15 записей
ProductType: 5 записей
Product: 25 записей
Sale: 150 записей
Note:
Для работы функции требуется существование файла 'partners.db' и всех
указанных таблиц в базе данных. В случае отсутствия таблиц может
возникнуть исключение sqlite3.OperationalError.
"""
###7 def load_data_from_files():
"""Загружает данные из Excel файлов в базу данных SQLite
Функция выполняет полную загрузку данных из четырех Excel файлов в соответствующие таблицы базы данных.
Процесс загрузки состоит из пяти этапов, выполняемых последовательно с проверкой целостности данных.
Args:
None: имена файлов запрашиваются у пользователя через интерактивный ввод
Returns:
None: функция выполняет операции с базой данных и выводит результаты в консоль
Процесс загрузки:
1. 📊 Типы партнеров - из файла партнеров извлекаются уникальные типы
2. 👥 Партнеры - загрузка основных данных о партнерах с привязкой к типам
3. 📦 Типы продукции - загрузка категорий продукции с коэффициентами
4. 🏷️ Продукты - загрузка данных о продукции с привязкой к типам
5. 💰 Продажи - загрузка истории продаж с валидацией связей и преобразованием дат
Требуемые файлы:
- Файл с партнерами: содержит данные о партнерах и их типах
- Файл с типами продукции: содержит категории продукции и коэффициенты
- Файл с продуктами: содержит данные о продукции с привязкой к типам
- Файл с продажами: содержит историю продаж с ссылками на партнеров и продукты
Особенности:
- Использует INSERT OR IGNORE для избежания дублирования записей
- Выполняет проверку существования связанных записей перед вставкой продаж
- Преобразует даты в стандартный SQL формат (YYYY-MM-DD)
- Автоматически рассчитывает цену продажи на основе минимальной партнерской цены
- В случае ошибки выполняет откат транзакции (rollback)
- После успешной загрузки вызывает check_database() для отображения статистики
Обработка ошибок:
- Отлавливает и выводит подробные сообщения об ошибках
- Продолжает загрузку при отсутствии некоторых продуктов/партнеров с предупреждениями
- Подсчитывает и выводит количество успешно загруженных продаж
Example:
>>> load_data_from_files()
📁 Введите имена файлов:
Файл с партнерами: partners.xlsx
Файл с типами продукции: product_types.xlsx
Файл с продуктами: products.xlsx
Файл с продажами: sales.xlsx
1. 📊 Загрузка типов партнеров...
2. 👥 Загрузка партнеров...
3. 📦 Загрузка типов продукции...
4. 🏷️ Загрузка продуктов...
5. 💰 Загрузка продаж...
✅ Данные успешно загружены! Загружено 150 продаж
Note:
Для работы функции требуются файлы в формате Excel (.xlsx) с определенной структурой колонок,
соответствующих ожидаемым названиям в коде.
"""
###8 def display_menu():
"""Главное меню программы для управления базой данных партнеров и продаж
Функция предоставляет интерактивный интерфейс для работы с системой управления партнерами.
Реализует основной цикл программы с возможностью выбора различных операций.
Args:
None: все параметры задаются внутри функции или запрашиваются у пользователя
Returns:
None: функция выполняется до выбора опции выхода
Основные функции меню:
1. КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу) - отображение партнеров, отсортированных по рейтингу
2. КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам) - отображение партнеров, отсортированных по уровню скидки
3. ИСТОРИЯ РЕАЛИЗАЦИИ - просмотр последних 50 записей о продажах
4. ЗАПОЛНЕНИЕ БД из файлов - полная переинициализация базы данных с загрузкой из Excel файлов
5. ВЫХОД - завершение работы программы
Особенности работы:
- Использует simple_choice() для интерактивного выбора опций
- Бесконечный цикл до выбора опции выхода
- При выборе загрузки данных удаляет существующую базу и создает новую
- Автоматически создает необходимые таблицы при инициализации базы
- Обеспечивает единообразное форматирование вывода для всех опций
Flow программы:
while True:
Показать меню опций
Получить выбор пользователя
Выполнить соответствующую функцию
Если выбран ВЫХОД - прервать цикл
Example:
==================================================
ВЫБЕРИТЕ ОПЦИЮ:
==================================================
1. КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)
2. КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам)
3. ИСТОРИЯ РЕАЛИЗАЦИИ
4. ЗАПОЛНЕНИЕ БД из файлов
5. ВЫХОД
Введите номер (1-5): 1
🎯 КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)
══════════════════════════════════════════════════════════════════════
[вывод карточек партнеров...]
Dependencies:
- simple_choice(): для выбора опций меню
- get_partners(): для получения данных партнеров
- print_partner_cards(): для форматированного вывода партнеров
- get_sales_history(): для получения истории продаж
- print_sales_cards(): для форматированного вывода продаж
- create_tables(): для создания структуры базы данных
- load_data_from_files(): для загрузки данных из файлов
"""