Aleksmorshen commited on
Commit
7d11f3c
·
verified ·
1 Parent(s): e777fe7

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +361 -0
app.py ADDED
@@ -0,0 +1,361 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import sqlite3
4
+ import random
5
+ import string
6
+ from datetime import datetime, timedelta
7
+ import pytz
8
+
9
+ # Подключение к базе данных SQLite3
10
+ conn = sqlite3.connect('auth_system.db', check_same_thread=False)
11
+ c = conn.cursor()
12
+
13
+ # Создание таблиц, если они не существуют
14
+ c.execute('''
15
+ CREATE TABLE IF NOT EXISTS users (
16
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
17
+ username TEXT NOT NULL UNIQUE,
18
+ token TEXT NOT NULL
19
+ )
20
+ ''')
21
+ conn.commit()
22
+
23
+ c.execute('''
24
+ CREATE TABLE IF NOT EXISTS products (
25
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
26
+ name TEXT NOT NULL,
27
+ description TEXT,
28
+ purchase_price REAL NOT NULL,
29
+ sale_price REAL NOT NULL,
30
+ quantity_in_stock INTEGER NOT NULL DEFAULT 0,
31
+ user_id INTEGER NOT NULL,
32
+ FOREIGN KEY(user_id) REFERENCES users(id)
33
+ )
34
+ ''')
35
+ conn.commit()
36
+
37
+ c.execute('''
38
+ CREATE TABLE IF NOT EXISTS cart (
39
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
40
+ product_id INTEGER NOT NULL,
41
+ quantity INTEGER NOT NULL,
42
+ UNIQUE(product_id)
43
+ )
44
+ ''')
45
+ conn.commit()
46
+
47
+ c.execute('''
48
+ CREATE TABLE IF NOT EXISTS sales (
49
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
50
+ product_id INTEGER NOT NULL,
51
+ quantity INTEGER NOT NULL,
52
+ sale_date DATE NOT NULL,
53
+ FOREIGN KEY(product_id) REFERENCES products(id)
54
+ )
55
+ ''')
56
+ conn.commit()
57
+
58
+ # Функция для генерации случайного 13-значного токена
59
+ def generate_token():
60
+ return ''.join(random.choices(string.ascii_letters + string.digits, k=13))
61
+
62
+ # Функция для получения идентификатора пользователя по токену
63
+ def get_user_id_by_token(token):
64
+ c.execute("SELECT id FROM users WHERE token=?", (token,))
65
+ user = c.fetchone()
66
+ return user[0] if user else None
67
+
68
+ # Функция для получения товаров из корзины
69
+ def get_cart_summary(user_id):
70
+ c.execute('''
71
+ SELECT p.name, c.quantity, p.sale_price, c.quantity * p.sale_price
72
+ FROM cart c
73
+ JOIN products p ON c.product_id = p.id
74
+ WHERE p.user_id = ?
75
+ ''', (user_id,))
76
+ items = c.fetchall()
77
+ total_quantity = sum(item[1] for item in items)
78
+ total_price = sum(item[3] for item in items)
79
+ return items, total_quantity, total_price
80
+
81
+ # Функция для добавления продажи в отчет
82
+ def record_sales():
83
+ c.execute('''
84
+ SELECT product_id, quantity FROM cart
85
+ ''')
86
+ cart_items = c.fetchall()
87
+ for product_id, quantity in cart_items:
88
+ c.execute('''
89
+ INSERT INTO sales (product_id, quantity, sale_date)
90
+ VALUES (?, ?, ?)
91
+ ''', (product_id, quantity, datetime.now(pytz.timezone('Asia/Bishkek')).strftime('%Y-%m-%d %H:%M:%S')))
92
+ c.execute('DELETE FROM cart')
93
+ conn.commit()
94
+
95
+ # Функция для генерации отчета за месяц
96
+ def generate_monthly_report():
97
+ start_date = (datetime.now().replace(day=1)).strftime('%Y-%m-%d')
98
+ end_date = (datetime.now() + timedelta(days=31)).replace(day=1).strftime('%Y-%m-%d')
99
+
100
+ c.execute('''
101
+ SELECT p.name, SUM(s.quantity) AS total_quantity, p.sale_price, SUM(s.quantity) * p.sale_price AS total_sales,
102
+ SUM(s.quantity) * (p.sale_price - p.purchase_price) AS profit
103
+ FROM sales s
104
+ JOIN products p ON s.product_id = p.id
105
+ WHERE s.sale_date BETWEEN ? AND ?
106
+ GROUP BY p.id
107
+ ''', (start_date, end_date))
108
+ sales_data = c.fetchall()
109
+
110
+ # Расчёт общей суммы продаж и прибыли
111
+ total_sales = sum(item[3] for item in sales_data)
112
+ total_profit = sum(item[4] for item in sales_data)
113
+
114
+ return sales_data, total_sales, total_profit
115
+
116
+ # Функция для получения всех сделок
117
+ def get_all_sales():
118
+ c.execute('''
119
+ SELECT s.id, p.name, s.quantity, s.sale_date
120
+ FROM sales s
121
+ JOIN products p ON s.product_id = p.id
122
+ ORDER BY s.sale_date DESC
123
+ ''')
124
+ sales_data = c.fetchall()
125
+ return sales_data
126
+
127
+ # Страница регистрации
128
+ def register():
129
+ st.title('Регистрация')
130
+ username = st.text_input("Введите ваше имя пользователя")
131
+ admin_password = st.text_input("Введите пароль администратора", type="password")
132
+
133
+ if st.button("Зарегистрироваться"):
134
+ if admin_password == "1234":
135
+ token = generate_token()
136
+ try:
137
+ c.execute("INSERT INTO users (username, token) VALUES (?, ?)", (username, token))
138
+ conn.commit()
139
+ st.success(f"Регистрация успешна! Ваш токен: {token}")
140
+ except sqlite3.IntegrityError:
141
+ st.error("Это имя пользователя уже занято. Попробуйте другое.")
142
+ else:
143
+ st.error("Неверный пароль администратора!")
144
+
145
+ # Страница авторизации
146
+ def login():
147
+ st.title('Авторизация')
148
+ token_input = st.text_input("Введите ваш токен")
149
+
150
+ if st.button("Войти"):
151
+ user_id = get_user_id_by_token(token_input)
152
+ if user_id:
153
+ st.session_state.logged_in = True # Устанавливаем состояние авторизации
154
+ st.session_state.username = token_input
155
+ st.session_state.user_id = user_id
156
+ st.success("Добро пожаловать!")
157
+ else:
158
+ st.error("Неверный токен!")
159
+
160
+ # Форма добавления товара
161
+ def add_product():
162
+ st.title("Добавление товара")
163
+ product_name = st.text_input("Название товара").strip().lower() # Преобразование в нижний регистр
164
+ product_description = st.text_area("Описание товара")
165
+ purchase_price = st.number_input("Приходная цена", min_value=0.0, step=0.01) # Запрос приходной цены
166
+ sale_price = st.number_input("Отпускная цена", min_value=0.0, step=0.01) # Запрос отпускной цены
167
+ product_quantity = st.number_input("Количество на складе", min_value=0, step=1)
168
+
169
+ if st.button("Добавить товар"):
170
+ if product_name and sale_price:
171
+ c.execute("INSERT INTO products (name, description, purchase_price, sale_price, quantity_in_stock, user_id) VALUES (?, ?, ?, ?, ?, ?)",
172
+ (product_name, product_description, purchase_price, sale_price, product_quantity, st.session_state.user_id))
173
+ conn.commit()
174
+ st.success("Товар успешно добавлен!")
175
+ else:
176
+ st.error("Пожалуйста, введите все обязательные данные.")
177
+
178
+ # Форма редактирования и удаления товара
179
+ def edit_products():
180
+ st.title("Редактирование товара")
181
+ products = c.execute("SELECT id, name, description, purchase_price, sale_price, quantity_in_stock FROM products WHERE user_id=?",
182
+ (st.session_state.user_id,)).fetchall()
183
+
184
+ if products:
185
+ product_names = [p[1] for p in products]
186
+ product_id = st.selectbox("Выберите товар", product_names)
187
+ product = next(p for p in products if p[1] == product_id)
188
+
189
+ new_name = st.text_input("Новое название товара", product[1])
190
+ new_description = st.text_area("Новое описание товара", product[2])
191
+ new_purchase_price = st.number_input("Новая приходная цена", min_value=0.0, step=0.01, value=product[3])
192
+ new_sale_price = st.number_input("Новая отпускная цена", min_value=0.0, step=0.01, value=product[4])
193
+ new_quantity_in_stock = st.number_input("Новое количество на складе", min_value=0, step=1, value=product[5])
194
+
195
+ if st.button("Сохранить изменения"):
196
+ c.execute("UPDATE products SET name=?, description=?, purchase_price=?, sale_price=?, quantity_in_stock=? WHERE id=?",
197
+ (new_name, new_description, new_purchase_price, new_sale_price, new_quantity_in_stock, product[0]))
198
+ conn.commit()
199
+ st.success("Изменения успешно сохранены!")
200
+
201
+ if st.button("Удалить товар"):
202
+ c.execute("DELETE FROM products WHERE id=?", (product[0],))
203
+ c.execute("DELETE FROM cart WHERE product_id=?", (product[0],)) # Удаляем товар из корзины, если он там есть
204
+ conn.commit()
205
+ st.success("Товар успешно удалён!")
206
+ else:
207
+ st.info("Нет товаров для редактирования.")
208
+
209
+ # Форма для добавления и удаления товара в корзину с поиском
210
+ def add_to_cart():
211
+ st.title("Отпуск товара")
212
+
213
+ search_term = st.text_input("Поиск товара").strip().lower() # Преобразуем ввод в нижний регистр
214
+
215
+ # Поиск товаров по ключевому слову (без учета регистра)
216
+ c.execute("SELECT id, name, sale_price, quantity_in_stock FROM products WHERE user_id=? AND LOWER(name) LIKE ?",
217
+ (st.session_state.user_id, f"%{search_term}%"))
218
+ products = c.fetchall()
219
+
220
+ if products:
221
+ product_list = []
222
+ for product in products:
223
+ cols = st.columns(4)
224
+ with cols[0]:
225
+ st.write(product[1]) # Название товара
226
+
227
+ with cols[1]:
228
+ quantity = st.number_input(f"Количество для '{product[1]}'", min_value=1, max_value=product[3], key=f"quantity_{product[0]}")
229
+
230
+ with cols[2]:
231
+ add_button = st.button(f"Добавить в корзину", key=f"add_{product[0]}")
232
+
233
+ if add_button:
234
+ if quantity <= product[3]:
235
+ # Обработка добавления товара в корзину
236
+ c.execute('''
237
+ INSERT INTO cart (product_id, quantity)
238
+ VALUES (?, ?)
239
+ ON CONFLICT(product_id)
240
+ DO UPDATE SET quantity = quantity + excluded.quantity
241
+ ''', (product[0], quantity))
242
+
243
+ # Уменьшаем количество на складе
244
+ c.execute("UPDATE products SET quantity_in_stock = quantity_in_stock - ? WHERE id=?",
245
+ (quantity, product[0]))
246
+ conn.commit()
247
+ st.success(f"Товар '{product[1]}' успешно добавлен в корзину!")
248
+ else:
249
+ st.error(f"Недостаточное количество товара '{product[1]}' на складе!")
250
+
251
+ with cols[3]:
252
+ remove_button = st.button(f"Удалить из корзины", key=f"remove_{product[0]}")
253
+
254
+ if remove_button:
255
+ if quantity > 0:
256
+ # Обработка удаления товара из корзины
257
+ current_quantity = c.execute("SELECT quantity FROM cart WHERE product_id=?", (product[0],)).fetchone()
258
+ if current_quantity:
259
+ new_quantity = current_quantity[0] - quantity
260
+ if new_quantity > 0:
261
+ c.execute('''
262
+ INSERT INTO cart (product_id, quantity)
263
+ VALUES (?, ?)
264
+ ON CONFLICT(product_id)
265
+ DO UPDATE SET quantity = excluded.quantity
266
+ ''', (product[0], new_quantity))
267
+ else:
268
+ c.execute("DELETE FROM cart WHERE product_id=?", (product[0],))
269
+
270
+ # Увеличиваем количество на складе
271
+ c.execute("UPDATE products SET quantity_in_stock = quantity_in_stock + ? WHERE id=?",
272
+ (quantity, product[0]))
273
+ conn.commit()
274
+ st.success(f"Товар '{product[1]}' успешно удалён из корзины!")
275
+ else:
276
+ st.error(f"Товар '{product[1]}' не найден в корзине.")
277
+ else:
278
+ st.error(f"Введите количество для удаления товара '{product[1]}'.")
279
+
280
+ # Отображение состояния корзины
281
+ st.subheader("Состояние корзины")
282
+ items, total_quantity, total_price = get_cart_summary(st.session_state.user_id)
283
+
284
+ if items:
285
+ # Создание DataFrame для таблицы
286
+ df = pd.DataFrame(items, columns=["Название", "Количество", "Цена за единицу", "Итого"])
287
+ st.dataframe(df.style.format({"Цена за единицу": "{:.2f}", "Итого": "{:.2f}"}), use_container_width=True)
288
+
289
+ st.write(f"Общее количество: {total_quantity}, Общая стоимость: {total_price:.2f}")
290
+
291
+ # Добавляем кнопку "Пробить" для оформления продажи
292
+ if st.button("Пробить"):
293
+ record_sales()
294
+ st.success("Корзина успешно пробита! Все товары добавлены в отчет и корзина очищена.")
295
+
296
+ # Кнопка для отображения сделок
297
+ if st.button("Сделки"):
298
+ sales_data = get_all_sales()
299
+ if sales_data:
300
+ df_sales = pd.DataFrame(sales_data, columns=["ID", "Название товара", "Количество", "Дата и время"])
301
+ st.dataframe(df_sales.style.format({"Дата и время": lambda x: pd.to_datetime(x).strftime('%d-%m-%Y %H:%M:%S')}), use_container_width=True)
302
+ else:
303
+ st.info("Нет сделок для отображения.")
304
+ else:
305
+ st.info("Корзина пуста.")
306
+
307
+ # Страница отчета о продажах за месяц
308
+ def monthly_report():
309
+ st.title("Отчет о продажах за месяц")
310
+ sales_data, total_sales, total_profit = generate_monthly_report()
311
+ if sales_data:
312
+ # Создание DataFrame ��ля отчета
313
+ df = pd.DataFrame(sales_data, columns=["Название", "Общее количество", "Отпускная цена", "Общие продажи", "Прибыль"])
314
+ st.write(f"**Отчет за {datetime.now().strftime('%B %Y')}**")
315
+ st.dataframe(df.style.format({"Отпускная цена": "{:.2f}", "Общие продажи": "{:.2f}", "Прибыль": "{:.2f}"}), use_container_width=True)
316
+
317
+ st.write(f"**Общая сумма продаж**: {total_sales:.2f}")
318
+ st.write(f"**Общая сумма прибыли**: {total_profit:.2f}")
319
+
320
+ # Кнопка для отображения сделок
321
+ if st.button("Сделки"):
322
+ sales_data = get_all_sales()
323
+ if sales_data:
324
+ df_sales = pd.DataFrame(sales_data, columns=["ID", "Название товара", "Количество", "Дата и время"])
325
+ st.dataframe(df_sales.style.format({"Дата и время": lambda x: pd.to_datetime(x).strftime('%d-%m-%Y %H:%M:%S')}), use_container_width=True)
326
+ else:
327
+ st.info("Нет сделок для отображения.")
328
+ else:
329
+ st.info("Нет данных о продажах за этот месяц.")
330
+
331
+ # Главная функция приложения
332
+ def main():
333
+ if 'logged_in' not in st.session_state:
334
+ st.session_state.logged_in = False
335
+
336
+ if st.session_state.logged_in:
337
+ st.sidebar.title(f"Привет, {st.session_state.username}!")
338
+ option = st.sidebar.selectbox("Выберите действие", ["Добавить товар", "Отпуск товара", "Редактировать товары", "Отчет за месяц", "Выйти"])
339
+
340
+ if option == "Добавить товар":
341
+ add_product()
342
+ elif option == "Отпуск товара":
343
+ add_to_cart()
344
+ elif option == "Редактировать товары":
345
+ edit_products()
346
+ elif option == "Отчет за месяц":
347
+ monthly_report()
348
+ elif option == "Выйти":
349
+ st.session_state.logged_in = False
350
+ st.session_state.username = None
351
+ st.session_state.user_id = None
352
+ st.success("Вы вышли из системы!")
353
+ else:
354
+ page = st.sidebar.selectbox("Выберите страницу", ["Регистрация", "Авторизация"])
355
+ if page == "Регистрация":
356
+ register()
357
+ elif page == "Авторизация":
358
+ login()
359
+
360
+ if __name__ == "__main__":
361
+ main()