import streamlit as st import pandas as pd import sqlite3 import random import string from datetime import datetime, timedelta import pytz # Подключение к базе данных SQLite3 conn = sqlite3.connect('auth_system.db', check_same_thread=False) c = conn.cursor() # Создание таблиц, если они не существуют c.execute(''' CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, token TEXT NOT NULL ) ''') conn.commit() c.execute(''' CREATE TABLE IF NOT EXISTS products ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, description TEXT, purchase_price REAL NOT NULL, sale_price REAL NOT NULL, quantity_in_stock INTEGER NOT NULL DEFAULT 0, user_id INTEGER NOT NULL, FOREIGN KEY(user_id) REFERENCES users(id) ) ''') conn.commit() c.execute(''' CREATE TABLE IF NOT EXISTS cart ( id INTEGER PRIMARY KEY AUTOINCREMENT, product_id INTEGER NOT NULL, quantity INTEGER NOT NULL, UNIQUE(product_id) ) ''') conn.commit() c.execute(''' CREATE TABLE IF NOT EXISTS sales ( id INTEGER PRIMARY KEY AUTOINCREMENT, sale_id TEXT NOT NULL, product_id INTEGER NOT NULL, quantity INTEGER NOT NULL, sale_date TIMESTAMP NOT NULL, total_amount REAL NOT NULL, FOREIGN KEY(product_id) REFERENCES products(id) ) ''') conn.commit() # Функция для генерации случайного 13-значного токена def generate_token(): return ''.join(random.choices(string.ascii_letters + string.digits, k=13)) # Функция для получения идентификатора пользователя по токену def get_user_id_by_token(token): c.execute("SELECT id FROM users WHERE token=?", (token,)) user = c.fetchone() return user[0] if user else None # Функция для получения товаров из корзины def get_cart_summary(user_id): c.execute(''' SELECT p.name, c.quantity, p.sale_price, c.quantity * p.sale_price FROM cart c JOIN products p ON c.product_id = p.id WHERE p.user_id = ? ''', (user_id,)) items = c.fetchall() total_quantity = sum(item[1] for item in items) total_price = sum(item[3] for item in items) return items, total_quantity, total_price # Функция для добавления продажи в отчет def record_sales(): sales_details = [] sale_id = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) # Уникальный идентификатор сделки sale_date = datetime.now(pytz.timezone('Asia/Bishkek')).strftime('%Y-%m-%d %H:%M:%S') c.execute('SELECT product_id, quantity FROM cart') cart_items = c.fetchall() total_amount = 0.0 for product_id, quantity in cart_items: # Получение цены за единицу товара c.execute('SELECT sale_price FROM products WHERE id=?', (product_id,)) sale_price = c.fetchone()[0] # Расчет общей суммы для этого товара amount = quantity * sale_price total_amount += amount c.execute(''' INSERT INTO sales (sale_id, product_id, quantity, sale_date, total_amount) VALUES (?, ?, ?, ?, ?) ''', (sale_id, product_id, quantity, sale_date, amount)) sales_details.append((product_id, quantity, amount, sale_date)) c.execute('DELETE FROM cart') conn.commit() return sales_details, sale_id, total_amount # Функция для генерации отчета за месяц def generate_monthly_report(): start_date = (datetime.now().replace(day=1)).strftime('%Y-%m-%d') end_date = (datetime.now() + timedelta(days=31)).replace(day=1).strftime('%Y-%m-%d') c.execute(''' SELECT p.name, SUM(s.quantity) AS total_quantity, p.sale_price, SUM(s.quantity) * p.sale_price AS total_sales, SUM(s.quantity) * (p.sale_price - p.purchase_price) AS profit FROM sales s JOIN products p ON s.product_id = p.id WHERE s.sale_date BETWEEN ? AND ? GROUP BY p.id ''', (start_date, end_date)) sales_data = c.fetchall() # Расчёт общей суммы продаж и прибыли total_sales = sum(item[3] for item in sales_data) total_profit = sum(item[4] for item in sales_data) return sales_data, total_sales, total_profit # Функция для получения всех сделок def get_all_sales(): c.execute(''' SELECT DISTINCT sale_id, sale_date, SUM(total_amount) AS total_amount FROM sales GROUP BY sale_id, sale_date ORDER BY sale_date DESC ''') sales_data = c.fetchall() return sales_data # Функция для получения всех подробностей сделок def get_sale_details(sale_id): c.execute(''' SELECT p.name, s.quantity, p.sale_price, s.sale_date FROM sales s JOIN products p ON s.product_id = p.id WHERE s.sale_id = ? ''', (sale_id,)) sale_details = c.fetchall() return sale_details # Страница регистрации def register(): st.title('Регистрация') username = st.text_input("Введите ваше имя пользователя") admin_password = st.text_input("Введите пароль администратора", type="password") if st.button("Зарегистрироваться"): if admin_password == "1234": token = generate_token() try: c.execute("INSERT INTO users (username, token) VALUES (?, ?)", (username, token)) conn.commit() st.success(f"Регистрация успешна! Ваш токен: {token}") except sqlite3.IntegrityError: st.error("Это имя пользователя уже занято. Попробуйте другое.") else: st.error("Неверный пароль администратора!") # Страница авторизации def login(): st.title('Авторизация') token_input = st.text_input("Введите ваш токен") if st.button("Войти"): user_id = get_user_id_by_token(token_input) if user_id: st.session_state.logged_in = True # Устанавливаем состояние авторизации st.session_state.username = token_input st.session_state.user_id = user_id st.success("Добро пожаловать!") else: st.error("Неверный токен!") # Форма добавления товара def add_product(): st.title("Добавление товара") product_name = st.text_input("Название товара").strip().lower() # Преобразование в нижний регистр product_description = st.text_area("Описание товара") purchase_price = st.number_input("Приходная цена", min_value=0.0, step=0.01) # Запрос приходной цены sale_price = st.number_input("Отпускная цена", min_value=0.0, step=0.01) # Запрос отпускной цены product_quantity = st.number_input("Количество на складе", min_value=0, step=1) if st.button("Добавить товар"): if product_name and sale_price: c.execute("INSERT INTO products (name, description, purchase_price, sale_price, quantity_in_stock, user_id) VALUES (?, ?, ?, ?, ?, ?)", (product_name, product_description, purchase_price, sale_price, product_quantity, st.session_state.user_id)) conn.commit() st.success("Товар успешно добавлен!") else: st.error("Пожалуйста, введите все обязательные данные.") # Форма редактирования и удаления товара def edit_products(): st.title("Редактирование товара") products = c.execute("SELECT id, name, description, purchase_price, sale_price, quantity_in_stock FROM products WHERE user_id=?", (st.session_state.user_id,)).fetchall() if products: product_names = [p[1] for p in products] product_id = st.selectbox("Выберите товар", product_names) product = next(p for p in products if p[1] == product_id) new_name = st.text_input("Новое название товара", product[1]) new_description = st.text_area("Новое описание товара", product[2]) new_purchase_price = st.number_input("Новая приходная цена", min_value=0.0, step=0.01, value=product[3]) new_sale_price = st.number_input("Новая отпускная цена", min_value=0.0, step=0.01, value=product[4]) new_quantity_in_stock = st.number_input("Новое количество на складе", min_value=0, step=1, value=product[5]) if st.button("Сохранить изменения"): c.execute(''' UPDATE products SET name = ?, description = ?, purchase_price = ?, sale_price = ?, quantity_in_stock = ? WHERE id = ? ''', (new_name, new_description, new_purchase_price, new_sale_price, new_quantity_in_stock, product[0])) conn.commit() st.success("Товар успешно обновлен!") if st.button("Удалить товар"): c.execute("DELETE FROM products WHERE id=?", (product[0],)) conn.commit() st.success("Товар успешно удален!") # Форма отпуска товара def add_to_cart(): st.title("Отпуск товара") products = c.execute("SELECT id, name, sale_price, quantity_in_stock FROM products WHERE user_id=?", (st.session_state.user_id,)).fetchall() if products: for product in products: cols = st.columns(4) with cols[0]: st.write(product[1]) # Название товара with cols[1]: quantity = st.number_input(f"Количество для '{product[1]}'", min_value=1, max_value=product[3], key=f"quantity_{product[0]}") with cols[2]: add_button = st.button(f"Добавить в корзину", key=f"add_{product[0]}") if add_button: if quantity <= product[3]: # Обработка добавления товара в корзину c.execute(''' INSERT INTO cart (product_id, quantity) VALUES (?, ?) ON CONFLICT(product_id) DO UPDATE SET quantity = quantity + excluded.quantity ''', (product[0], quantity)) # Уменьшаем количество на складе c.execute("UPDATE products SET quantity_in_stock = quantity_in_stock - ? WHERE id=?", (quantity, product[0])) conn.commit() st.success(f"Товар '{product[1]}' успешно добавлен в корзину!") else: st.error(f"Недостаточное количество товара '{product[1]}' на складе!") with cols[3]: remove_button = st.button(f"Удалить из корзины", key=f"remove_{product[0]}") if remove_button: if quantity > 0: # Обработка удаления товара из корзины current_quantity = c.execute("SELECT quantity FROM cart WHERE product_id=?", (product[0],)).fetchone() if current_quantity: new_quantity = current_quantity[0] - quantity if new_quantity > 0: c.execute(''' INSERT INTO cart (product_id, quantity) VALUES (?, ?) ON CONFLICT(product_id) DO UPDATE SET quantity = excluded.quantity ''', (product[0], new_quantity)) else: c.execute("DELETE FROM cart WHERE product_id=?", (product[0],)) # Увеличиваем количество на складе c.execute("UPDATE products SET quantity_in_stock = quantity_in_stock + ? WHERE id=?", (quantity, product[0])) conn.commit() st.success(f"Товар '{product[1]}' успешно удалён из корзины!") else: st.error(f"Товар '{product[1]}' не найден в корзине.") else: st.error(f"Введите количество для удаления товара '{product[1]}'.") # Отображение состояния корзины st.subheader("Состояние корзины") items, total_quantity, total_price = get_cart_summary(st.session_state.user_id) if items: # Создание DataFrame для таблицы df = pd.DataFrame(items, columns=["Название", "Количество", "Цена за единицу", "Итого"]) st.dataframe(df.style.format({"Цена за единицу": "{:.2f}", "Итого": "{:.2f}"}), use_container_width=True) st.write(f"Общее количество: {total_quantity}, Общая стоимость: {total_price:.2f}") # Добавляем кнопку "Пробить" для оформления продажи if st.button("Пробить"): sales_details, sale_id, total_amount = record_sales() if sales_details: st.write("**Детали сделок:**") sale_details_df = pd.DataFrame(sales_details, columns=["ID товара", "Количество", "Сумма", "Дата и время"]) st.dataframe(sale_details_df.style.format({"Сумма": "{:.2f}", "Дата и время": lambda x: pd.to_datetime(x).strftime('%d-%m-%Y %H:%M:%S')}), use_container_width=True) st.write(f"**Общая сумма сделки:** {total_amount:.2f}") st.success("Корзина успешно пробита! Все товары добавлены в отчет и корзина очищена.") # Кнопка для отображения сделок if st.button("Сделки"): sales_data = get_all_sales() if sales_data: sale_ids = [sale[0] for sale in sales_data] for sale_id, sale_date, total_amount in sales_data: st.write(f"**Сделка ID:** {sale_id} ({sale_date}) - **Общая сумма:** {total_amount:.2f}") sale_details = get_sale_details(sale_id) if sale_details: df_sales = pd.DataFrame(sale_details, columns=["Название товара", "Количество", "Цена за единицу", "Дата и время"]) st.dataframe(df_sales.style.format({"Дата и время": lambda x: pd.to_datetime(x).strftime('%d-%m-%Y %H:%M:%S')}), use_container_width=True) else: st.info("Нет деталей для отображения.") else: st.info("Нет сделок для отображения.") else: st.info("Корзина пуста.") # Страница отчета о продажах за месяц def monthly_report(): st.title("Отчет о продажах за месяц") sales_data, total_sales, total_profit = generate_monthly_report() if sales_data: # Создание DataFrame для отчета df = pd.DataFrame(sales_data, columns=["Название", "Общее количество", "Отпускная цена", "Общие продажи", "Прибыль"]) st.write(f"**Отчет за {datetime.now().strftime('%B %Y')}**") st.dataframe(df.style.format({"Отпускная цена": "{:.2f}", "Общие продажи": "{:.2f}", "Прибыль": "{:.2f}"}), use_container_width=True) st.write(f"**Общая сумма продаж**: {total_sales:.2f}") st.write(f"**Общая сумма прибыли**: {total_profit:.2f}") # Кнопка для отображения сделок if st.button("Сделки"): sales_data = get_all_sales() if sales_data: sale_ids = [sale[0] for sale in sales_data] for sale_id, sale_date, total_amount in sales_data: st.write(f"**Сделка ID:** {sale_id} ({sale_date}) - **Общая сумма:** {total_amount:.2f}") sale_details = get_sale_details(sale_id) if sale_details: df_sales = pd.DataFrame(sale_details, columns=["Название товара", "Количество", "Цена за единицу", "Дата и время"]) st.dataframe(df_sales.style.format({"Дата и время": lambda x: pd.to_datetime(x).strftime('%d-%m-%Y %H:%M:%S')}), use_container_width=True) else: st.info("Нет деталей для отображения.") else: st.info("Нет сделок для отображения.") else: st.info("Нет данных о продажах за этот месяц.") # Главная функция приложения def main(): if 'logged_in' not in st.session_state: st.session_state.logged_in = False if st.session_state.logged_in: st.sidebar.title(f"Привет, {st.session_state.username}!") option = st.sidebar.selectbox("Выберите действие", ["Добавить товар", "Отпуск товара", "Редактировать товары", "Отчет за месяц", "Выйти"]) if option == "Добавить товар": add_product() elif option == "Отпуск товара": add_to_cart() elif option == "Редактировать товары": edit_products() elif option == "Отчет за месяц": monthly_report() elif option == "Выйти": st.session_state.logged_in = False st.session_state.username = None st.session_state.user_id = None st.success("Вы вышли из системы!") else: page = st.sidebar.selectbox("Выберите страницу", ["Регистрация", "Авторизация"]) if page == "Регистрация": register() elif page == "Авторизация": login() if __name__ == "__main__": main()