This commit is contained in:
user_3d 2025-10-25 09:05:20 +05:00 committed by user_3d
commit 1d2620e0bf
9 changed files with 120 additions and 108 deletions

View file

@ -3,5 +3,5 @@
<component name="Black"> <component name="Black">
<option name="sdkName" value="Python 3.11 (mmmm6)" /> <option name="sdkName" value="Python 3.11 (mmmm6)" />
</component> </component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (venv)" project-jdk-type="Python SDK" /> <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (venv) (2)" project-jdk-type="Python SDK" />
</project> </project>

View file

@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4"> <module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" /> <content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.11 (venv)" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.11 (venv) (2)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>

View file

@ -2,5 +2,6 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" /> <mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component> </component>
</project> </project>

213
main.py
View file

@ -2,71 +2,72 @@ import sqlite3
import pandas as pd import pandas as pd
import os import os
import sys import sys
import openpyxl
"potapov andrey"
def create_tables(db_connection): def create_tables(db_connection):
"""Создает все необходимые таблицы в базе данных""" # Функция создает структуру таблиц в базе данных
cursor = db_connection.cursor() cursor = db_connection.cursor()
# Создание таблиц и индексов
cursor.executescript(''' cursor.executescript('''
CREATE TABLE IF NOT EXISTS PartnerType ( CREATE TABLE IF NOT EXISTS PartnerType (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
type_name VARCHAR(100) NOT NULL UNIQUE type_name VARCHAR(100) NOT NULL UNIQUE
); );
CREATE TABLE IF NOT EXISTS Partner ( CREATE TABLE IF NOT EXISTS Partner (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
partner_type_id INTEGER REFERENCES PartnerType(id), partner_type_id INTEGER REFERENCES PartnerType(id),
name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL,
director VARCHAR(255), director VARCHAR(255),
email VARCHAR(255), email VARCHAR(255),
phone VARCHAR(50), phone VARCHAR(50),
legal_address TEXT, legal_address TEXT,
inn VARCHAR(20) UNIQUE, inn VARCHAR(20) UNIQUE,
rating DECIMAL(3,2) DEFAULT 0.0, rating DECIMAL(3,2) DEFAULT 0.0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
); );
CREATE TABLE IF NOT EXISTS ProductType ( CREATE TABLE IF NOT EXISTS ProductType (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
type_name VARCHAR(100) NOT NULL UNIQUE, type_name VARCHAR(100) NOT NULL UNIQUE,
coefficient DECIMAL(5,2) NOT NULL DEFAULT 1.0 coefficient DECIMAL(5,2) NOT NULL DEFAULT 1.0
); );
CREATE TABLE IF NOT EXISTS Product ( CREATE TABLE IF NOT EXISTS Product (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
product_type_id INTEGER REFERENCES ProductType(id), product_type_id INTEGER REFERENCES ProductType(id),
product_name VARCHAR(255) NOT NULL, product_name VARCHAR(255) NOT NULL,
article VARCHAR(100) UNIQUE NOT NULL, article VARCHAR(100) UNIQUE NOT NULL,
min_partner_price DECIMAL(15,2) NOT NULL, min_partner_price DECIMAL(15,2) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
); );
CREATE TABLE IF NOT EXISTS Sale ( CREATE TABLE IF NOT EXISTS Sale (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
product_id INTEGER REFERENCES Product(id), product_id INTEGER REFERENCES Product(id),
partner_id INTEGER REFERENCES Partner(id), partner_id INTEGER REFERENCES Partner(id),
quantity INTEGER NOT NULL CHECK (quantity > 0), quantity INTEGER NOT NULL CHECK (quantity > 0),
sale_date DATE NOT NULL, sale_date DATE NOT NULL,
sale_price DECIMAL(15,2) NOT NULL, sale_price DECIMAL(15,2) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP 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);
''')
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() db_connection.commit()
print("✅ Таблицы успешно созданы") print("✅ Таблицы успешно созданы")
def calculate_discount(total_quantity): def calculate_discount(total_quantity):
"""Рассчитывает скидку на основе общего количества проданной продукции""" # Функция рассчитывает скидку на основе объема продаж
if total_quantity >= 300000: if total_quantity >= 300000:
return 15, '15% (более 300000 ед.)' return 15, '15% (более 300000 ед.)'
elif total_quantity >= 50000: elif total_quantity >= 50000:
@ -78,28 +79,29 @@ def calculate_discount(total_quantity):
def get_partners(db_path='partners.db', sort_by='rating', ascending=False): def get_partners(db_path='partners.db', sort_by='rating', ascending=False):
"""Получает данные о партнерах с возможностью сортировки""" # Функция получает данные о партнерах из базы данных
try: try:
conn = sqlite3.connect(db_path) conn = sqlite3.connect(db_path)
# Здесь прописан SQL-запрос для выборки данных о партнерах
query = """ query = """
SELECT SELECT
pt.type_name AS "Тип партнера", pt.type_name AS "Тип партнера",
p.name AS "Наименование партнера", p.name AS "Наименование партнера",
p.director AS "Директор", p.director AS "Директор",
p.email AS "Электронная почта", p.email AS "Электронная почта",
p.phone AS "Телефон", p.phone AS "Телефон",
p.legal_address AS "Юридический адрес", p.legal_address AS "Юридический адрес",
p.inn AS "ИНН", p.inn AS "ИНН",
p.rating AS "Рейтинг", p.rating AS "Рейтинг",
p.created_at AS "Дата создания", p.created_at AS "Дата создания",
COALESCE(SUM(s.quantity), 0) as total_quantity COALESCE(SUM(s.quantity), 0) as total_quantity
FROM Partner p FROM Partner p
JOIN PartnerType pt ON p.partner_type_id = pt.id JOIN PartnerType pt ON p.partner_type_id = pt.id
LEFT JOIN Sale s ON p.id = s.partner_id LEFT JOIN Sale s ON p.id = s.partner_id
GROUP BY p.id GROUP BY p.id
""" """
# Добавляем сортировку # Применяем нужную сортировку и лимитируем количество записей
if sort_by == 'discount': if sort_by == 'discount':
query += " ORDER BY total_quantity" query += " ORDER BY total_quantity"
elif sort_by == 'rating': elif sort_by == 'rating':
@ -132,26 +134,27 @@ 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'): def get_sales_history(db_path='partners.db', limit=50, sort_by='date_desc'):
"""Получает историю реализации продукции с разными вариантами сортировки""" # Функция получает историю продаж
try: try:
conn = sqlite3.connect(db_path) conn = sqlite3.connect(db_path)
# Здесь прописан SQL-запрос для выборки истории продаж
query = """ query = """
SELECT SELECT
s.sale_date AS "Дата продажи", s.sale_date AS "Дата продажи",
p.name AS "Партнер", p.name AS "Партнер",
pr.product_name AS "Продукция", pr.product_name AS "Продукция",
pr.article AS "Артикул", pr.article AS "Артикул",
s.quantity AS "Количество", s.quantity AS "Количество",
s.sale_price AS "Цена за единицу", s.sale_price AS "Цена за единицу",
(s.quantity * s.sale_price) AS "Общая сумма", (s.quantity * s.sale_price) AS "Общая сумма",
pt.type_name AS "Тип продукции" pt.type_name AS "Тип продукции"
FROM Sale s FROM Sale s
JOIN Partner p ON s.partner_id = p.id JOIN Partner p ON s.partner_id = p.id
JOIN Product pr ON s.product_id = pr.id JOIN Product pr ON s.product_id = pr.id
JOIN ProductType pt ON pr.product_type_id = pt.id JOIN ProductType pt ON pr.product_type_id = pt.id
""" """
# Добавляем сортировку по дате # Применяем сортировку и ограничение числа записей
if sort_by == 'date_desc': if sort_by == 'date_desc':
query += " ORDER BY s.sale_date DESC, s.created_at DESC" query += " ORDER BY s.sale_date DESC, s.created_at DESC"
elif sort_by == 'date_asc': elif sort_by == 'date_asc':
@ -172,12 +175,13 @@ def get_sales_history(db_path='partners.db', limit=50, sort_by='date_desc'):
print(f"❌ Ошибка при получении истории продаж: {e}") print(f"❌ Ошибка при получении истории продаж: {e}")
return None return None
def print_partner_cards(partners_df): def print_partner_cards(partners_df):
"""Выводит карточки партнеров в красивом формате""" # Функция выводит информацию о партнерах в красивой форме
if partners_df is None or partners_df.empty: if partners_df is None or partners_df.empty:
print("📭 Нет данных о партнерах") print("📭 Нет данных о партнерах")
return return
# Красивый вывод карточек партнеров
for index, row in partners_df.iterrows(): for index, row in partners_df.iterrows():
print("╔" + "═" * 69 + "╗") print("╔" + "═" * 69 + "╗")
print(f"║ {'КАРТОЧКА ПАРТНЕРА':^67} ║") print(f"║ {'КАРТОЧКА ПАРТНЕРА':^67} ║")
@ -198,6 +202,7 @@ def print_partner_cards(partners_df):
address = address[:57] + "..." address = address[:57] + "..."
address_text = f"Адрес: {address}" address_text = f"Адрес: {address}"
# Информация о партнере
print(f"║ {type_text:<67} ║") print(f"║ {type_text:<67} ║")
print(f"║ {name_text:<67} ║") print(f"║ {name_text:<67} ║")
print(f"║ {director_text:<67} ║") print(f"║ {director_text:<67} ║")
@ -215,11 +220,11 @@ def print_partner_cards(partners_df):
def print_sales_cards(sales_df): def print_sales_cards(sales_df):
"""Выводит карточки истории реализации в виде таблицы""" # Функция выводит историю продаж в табличном представлении
if sales_df is None or sales_df.empty: if sales_df is None or sales_df.empty:
print("📭 Нет данных о продажах") print("📭 Нет данных о продажах")
return return
# Рамка таблицы
print("╔" + "═" * 147 + "╗") print("╔" + "═" * 147 + "╗")
print(f"║ {'ИСТОРИЯ РЕАЛИЗАЦИИ ПРОДУКЦИИ':^145} ║") print(f"║ {'ИСТОРИЯ РЕАЛИЗАЦИИ ПРОДУКЦИИ':^145} ║")
print("╠" + "═" * 147 + "╣") print("╠" + "═" * 147 + "╣")
@ -231,7 +236,7 @@ def print_sales_cards(sales_df):
)) ))
print("╠" + "═" * 147 + "╣") print("╠" + "═" * 147 + "╣")
# Данные таблицы # Вывод данных о продажах
for index, row in sales_df.iterrows(): for index, row in sales_df.iterrows():
date = str(row['Дата продажи'])[:10] date = str(row['Дата продажи'])[:10]
partner = row['Партнер'] partner = row['Партнер']
@ -241,16 +246,20 @@ def print_sales_cards(sales_df):
price = f"{row['Цена за единицу']:,.2f}" price = f"{row['Цена за единицу']:,.2f}"
total = 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(
f"║ {date} ║ {partner.ljust(16)} ║ {product.ljust(57)} ║ {article.ljust(8)} ║ {quantity.ljust(8)} ║ {price.ljust(10)} ║ {total.ljust(18)} ║")
print("╚" + "═" * 147 + "╝") print("╚" + "═" * 147 + "╝")
# Закрывающая рамка таблицы
# Итоги # Итоги
total_quantity = sales_df['Количество'].sum() total_quantity = sales_df['Количество'].sum()
total_amount = sales_df['Общая сумма'].sum() total_amount = sales_df['Общая сумма'].sum()
print(f"📊 ИТОГО: {len(sales_df)} продаж, {total_quantity:,} единиц, общая сумма: {total_amount:,.2f} руб.") print(f"📊 ИТОГО: {len(sales_df)} продаж, {total_quantity:,} единиц, общая сумма: {total_amount:,.2f} руб.")
def simple_choice(options): def simple_choice(options):
"""Упрощенная функция выбора""" # Простая функция выбора пункта меню
print("\n" + "=" * 50) print("\n" + "=" * 50)
print("ВЫБЕРИТЕ ОПЦИЮ:") print("ВЫБЕРИТЕ ОПЦИЮ:")
print("=" * 50) print("=" * 50)
@ -273,7 +282,7 @@ def simple_choice(options):
def check_database(): def check_database():
"""Проверяет загруженные данные в базе""" # Проверяет наличие данных в базе
conn = sqlite3.connect('partners.db') conn = sqlite3.connect('partners.db')
try: try:
cursor = conn.cursor() cursor = conn.cursor()
@ -288,7 +297,7 @@ def check_database():
def load_data_from_files(): def load_data_from_files():
"""Загружает данные из Excel файлов в базу данных""" # Загружает данные из Excel-файлов в базу данных
conn = sqlite3.connect('partners.db') conn = sqlite3.connect('partners.db')
cursor = conn.cursor() cursor = conn.cursor()
@ -314,8 +323,8 @@ def load_data_from_files():
partner_type_id = cursor.fetchone()[0] partner_type_id = cursor.fetchone()[0]
cursor.execute("""INSERT OR IGNORE INTO Partner cursor.execute("""INSERT OR IGNORE INTO Partner
(partner_type_id, name, director, email, phone, legal_address, inn, rating) (partner_type_id, name, director, email, phone, legal_address, inn, rating)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
(partner_type_id, row['Наименование партнера'], row['Директор'], (partner_type_id, row['Наименование партнера'], row['Директор'],
row['Электронная почта партнера'], row['Телефон партнера'], row['Электронная почта партнера'], row['Телефон партнера'],
row['Юридический адрес партнера'], row['ИНН'], row['Рейтинг']) row['Юридический адрес партнера'], row['ИНН'], row['Рейтинг'])
@ -337,8 +346,8 @@ def load_data_from_files():
product_type_id = cursor.fetchone()[0] product_type_id = cursor.fetchone()[0]
cursor.execute("""INSERT OR IGNORE INTO Product cursor.execute("""INSERT OR IGNORE INTO Product
(product_type_id, product_name, article, min_partner_price) (product_type_id, product_name, article, min_partner_price)
VALUES (?, ?, ?, ?)""", VALUES (?, ?, ?, ?)""",
(product_type_id, row['Наименование продукции'], (product_type_id, row['Наименование продукции'],
row['Артикул'], row['Минимальная стоимость для партнера']) row['Артикул'], row['Минимальная стоимость для партнера'])
) )
@ -375,8 +384,8 @@ def load_data_from_files():
# Вставляем продажу # Вставляем продажу
cursor.execute("""INSERT INTO Sale cursor.execute("""INSERT INTO Sale
(product_id, partner_id, quantity, sale_date, sale_price) (product_id, partner_id, quantity, sale_date, sale_price)
VALUES (?, ?, ?, ?, ?)""", VALUES (?, ?, ?, ?, ?)""",
(product_id, partner_id, row['Количество продукции'], sale_date, sale_price) (product_id, partner_id, row['Количество продукции'], sale_date, sale_price)
) )
loaded_sales += 1 loaded_sales += 1
@ -393,7 +402,7 @@ def load_data_from_files():
def display_menu(): def display_menu():
"""Главное меню программы""" # Основное меню программы
menu_options = [ menu_options = [
'КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)', 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по рейтингу)',
'КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам)', 'КАРТОЧКИ ПАРТНЕРОВ (сортировка по скидкам)',
@ -440,5 +449,7 @@ def display_menu():
break break
# Главная точка запуска программы
if __name__ == "__main__": if __name__ == "__main__":
display_menu() display_menu()

Binary file not shown.

View file

@ -35,7 +35,7 @@ deactivate () {
# unset irrelevant variables # unset irrelevant variables
deactivate nondestructive deactivate nondestructive
VIRTUAL_ENV=/home/user_3d/PycharmProjects/mmmm/venv VIRTUAL_ENV=/home/user_3d/mmmm/venv
export VIRTUAL_ENV export VIRTUAL_ENV
_OLD_VIRTUAL_PATH="$PATH" _OLD_VIRTUAL_PATH="$PATH"

View file

@ -8,7 +8,7 @@ alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PA
# Unset irrelevant variables. # Unset irrelevant variables.
deactivate nondestructive deactivate nondestructive
setenv VIRTUAL_ENV /home/user_3d/PycharmProjects/mmmm/venv setenv VIRTUAL_ENV /home/user_3d/mmmm/venv
set _OLD_VIRTUAL_PATH="$PATH" set _OLD_VIRTUAL_PATH="$PATH"
setenv PATH "$VIRTUAL_ENV/"bin":$PATH" setenv PATH "$VIRTUAL_ENV/"bin":$PATH"

View file

@ -33,7 +33,7 @@ end
# Unset irrelevant variables. # Unset irrelevant variables.
deactivate nondestructive deactivate nondestructive
set -gx VIRTUAL_ENV /home/user_3d/PycharmProjects/mmmm/venv set -gx VIRTUAL_ENV /home/user_3d/mmmm/venv
set -gx _OLD_VIRTUAL_PATH $PATH set -gx _OLD_VIRTUAL_PATH $PATH
set -gx PATH "$VIRTUAL_ENV/"bin $PATH set -gx PATH "$VIRTUAL_ENV/"bin $PATH

View file

@ -2,4 +2,4 @@ home = /usr/bin
include-system-site-packages = false include-system-site-packages = false
version = 3.11.13 version = 3.11.13
executable = /usr/bin/python3.11 executable = /usr/bin/python3.11
command = /usr/bin/python -m venv /home/user_3d/PycharmProjects/mmmm/venv command = /usr/bin/python -m venv /home/user_3d/mmmm/venv