Aleksmorshen commited on
Commit
7acd1ea
·
verified ·
1 Parent(s): bb78c64

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +144 -108
app.py CHANGED
@@ -8,70 +8,116 @@ from datetime import datetime, timedelta
8
  import pytz
9
  import time
10
  import threading
11
- from huggingface_hub import HfApi # импорт API для работы с Hugging Face
12
 
13
- # Подключение к базе данных SQLite3
14
- conn = sqlite3.connect('auth_system.db', check_same_thread=False)
 
 
 
 
 
 
15
  c = conn.cursor()
16
 
17
- # Создание таблиц, если они не существуют
18
- c.execute('''
19
- CREATE TABLE IF NOT EXISTS users (
20
- id INTEGER PRIMARY KEY AUTOINCREMENT,
21
- username TEXT NOT NULL UNIQUE,
22
- token TEXT NOT NULL
23
- )
24
- ''')
25
- conn.commit()
26
-
27
- c.execute('''
28
- CREATE TABLE IF NOT EXISTS products (
29
- id INTEGER PRIMARY KEY AUTOINCREMENT,
30
- name TEXT NOT NULL,
31
- description TEXT,
32
- purchase_price REAL NOT NULL,
33
- sale_price REAL NOT NULL,
34
- quantity_in_stock INTEGER NOT NULL DEFAULT 0,
35
- user_id INTEGER NOT NULL,
36
- FOREIGN KEY(user_id) REFERENCES users(id)
37
- )
38
- ''')
39
- conn.commit()
40
-
41
- c.execute('''
42
- CREATE TABLE IF NOT EXISTS cart (
43
- id INTEGER PRIMARY KEY AUTOINCREMENT,
44
- product_id INTEGER NOT NULL,
45
- quantity INTEGER NOT NULL,
46
- UNIQUE(product_id)
47
- )
48
- ''')
49
- conn.commit()
50
-
51
- c.execute('''
52
- CREATE TABLE IF NOT EXISTS sales (
53
- id INTEGER PRIMARY KEY AUTOINCREMENT,
54
- sale_id TEXT NOT NULL,
55
- product_id INTEGER NOT NULL,
56
- quantity INTEGER NOT NULL,
57
- sale_date TIMESTAMP NOT NULL,
58
- total_amount REAL NOT NULL,
59
- FOREIGN KEY(product_id) REFERENCES products(id)
60
- )
61
- ''')
62
- conn.commit()
63
-
64
- # Функция для генерации случайного 13-значного токена
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  def generate_token():
66
  return ''.join(random.choices(string.ascii_letters + string.digits, k=13))
67
 
68
- # Функция для получения идентификатора пользователя по токену
69
  def get_user_id_by_token(token):
70
  c.execute("SELECT id FROM users WHERE token=?", (token,))
71
  user = c.fetchone()
72
  return user[0] if user else None
73
 
74
- # Функция для получения товаров из корзины
75
  def get_cart_summary(user_id):
76
  c.execute('''
77
  SELECT p.name, c.quantity, p.sale_price, c.quantity * p.sale_price
@@ -84,34 +130,32 @@ def get_cart_summary(user_id):
84
  total_price = sum(item[3] for item in items)
85
  return items, total_quantity, total_price
86
 
87
- # Функция для добавления продажи в отчет
88
  def record_sales():
89
  sales_details = []
90
- sale_id = ''.join(random.choices(string.ascii_letters + string.digits, k=8)) # Уникальный идентификатор сделки
91
  sale_date = datetime.now(pytz.timezone('Asia/Bishkek')).strftime('%Y-%m-%d %H:%M:%S')
92
-
93
  c.execute('SELECT product_id, quantity FROM cart')
94
  cart_items = c.fetchall()
95
-
96
  total_amount = 0.0
97
  for product_id, quantity in cart_items:
98
  c.execute('SELECT sale_price FROM products WHERE id=?', (product_id,))
99
  sale_price = c.fetchone()[0]
100
-
101
  amount = quantity * sale_price
102
  total_amount += amount
103
-
104
  c.execute('''
105
  INSERT INTO sales (sale_id, product_id, quantity, sale_date, total_amount)
106
  VALUES (?, ?, ?, ?, ?)
107
  ''', (sale_id, product_id, quantity, sale_date, amount))
108
  sales_details.append((product_id, quantity, amount, sale_date))
109
-
110
  c.execute('DELETE FROM cart')
111
  conn.commit()
112
  return sales_details, sale_id, total_amount
113
 
114
- # Функция для генерации отчета за месяц
115
  def generate_monthly_report(user_id):
116
  start_date = (datetime.now().replace(day=1)).strftime('%Y-%m-%d')
117
  end_date = (datetime.now() + timedelta(days=31)).replace(day=1).strftime('%Y-%m-%d')
@@ -124,15 +168,14 @@ def generate_monthly_report(user_id):
124
  WHERE s.sale_date BETWEEN ? AND ? AND p.user_id = ?
125
  GROUP BY p.id
126
  ''', (start_date, end_date, user_id))
127
-
128
  sales_data = c.fetchall()
129
 
130
  total_sales = sum(item[3] for item in sales_data)
131
  total_profit = sum(item[4] for item in sales_data)
132
-
133
  return sales_data, total_sales, total_profit
134
 
135
- # Функция для получения всех сделок
136
  def get_all_sales(user_id):
137
  c.execute('''
138
  SELECT DISTINCT sale_id, sale_date, SUM(total_amount) AS total_amount
@@ -145,7 +188,6 @@ def get_all_sales(user_id):
145
  sales_data = c.fetchall()
146
  return sales_data
147
 
148
- # Функция для получения всех подробностей сделок
149
  def get_sale_details(sale_id):
150
  c.execute('''
151
  SELECT p.name, s.quantity, p.sale_price, s.sale_date
@@ -156,7 +198,7 @@ def get_sale_details(sale_id):
156
  sale_details = c.fetchall()
157
  return sale_details
158
 
159
- # Страница регистрации
160
  def register():
161
  st.title('Регистрация')
162
  username = st.text_input("Введите ваше имя пользователя")
@@ -174,7 +216,6 @@ def register():
174
  else:
175
  st.error("Неверный пароль администратора!")
176
 
177
- # Страница авторизации
178
  def login():
179
  st.title('Авторизация')
180
  token_input = st.text_input("Введите ваш токен")
@@ -182,14 +223,13 @@ def login():
182
  if st.button("Войти"):
183
  user_id = get_user_id_by_token(token_input)
184
  if user_id:
185
- st.session_state.logged_in = True # Устанавливаем состояние авторизации
186
  st.session_state.username = token_input
187
  st.session_state.user_id = user_id
188
  st.success("Добро пожаловать!")
189
  else:
190
  st.error("Неверный токен!")
191
 
192
- # Форма добавления товара
193
  def add_product():
194
  st.title("Добавление товара")
195
  product_name = st.text_input("Название товара").strip().lower()
@@ -207,23 +247,22 @@ def add_product():
207
  else:
208
  st.error("Пожалуйста, введите все обязательные данные.")
209
 
210
- # Форма редактирования и удаления товара
211
  def edit_products():
212
  st.title("Редактирование товара")
213
  products = c.execute("SELECT id, name, description, purchase_price, sale_price, quantity_in_stock FROM products WHERE user_id=?",
214
  (st.session_state.user_id,)).fetchall()
215
-
216
  if products:
217
  product_names = [p[1] for p in products]
218
  product_id = st.selectbox("Выберите товар", product_names)
219
  product = next(p for p in products if p[1] == product_id)
220
-
221
  new_name = st.text_input("Новое название товара", product[1])
222
  new_description = st.text_area("Новое описание товара", product[2])
223
  new_purchase_price = st.number_input("Новая приходная цена", min_value=0.0, step=0.01, value=product[3])
224
  new_sale_price = st.number_input("Новая отпускная цена", min_value=0.0, step=0.01, value=product[4])
225
  new_quantity_in_stock = st.number_input("Новое количество на складе", min_value=0, step=1, value=product[5])
226
-
227
  if st.button("Сохранить изменения"):
228
  c.execute('''
229
  UPDATE products
@@ -238,7 +277,6 @@ def edit_products():
238
  conn.commit()
239
  st.success("Товар успешно удален!")
240
 
241
- # Форма отпуска товара
242
  def add_to_cart():
243
  st.title("Отпуск товара")
244
  products = c.execute("SELECT id, name, sale_price, quantity_in_stock FROM products WHERE user_id=?",
@@ -259,10 +297,10 @@ def add_to_cart():
259
 
260
  with cols[1]:
261
  quantity = st.number_input(f"Количество для '{product[1]}'", min_value=0, max_value=product[3], key=f"quantity_{product[0]}")
262
-
263
  with cols[2]:
264
  add_button = st.button(f"Добавить в корзину", key=f"add_{product[0]}")
265
-
266
  if add_button:
267
  if quantity <= product[3]:
268
  c.execute('''
@@ -280,7 +318,7 @@ def add_to_cart():
280
 
281
  with cols[3]:
282
  remove_button = st.button(f"Удалить из корзины", key=f"remove_{product[0]}")
283
-
284
  if remove_button:
285
  if quantity > 0:
286
  current_quantity = c.execute("SELECT quantity FROM cart WHERE product_id=?", (product[0],)).fetchone()
@@ -306,13 +344,13 @@ def add_to_cart():
306
 
307
  st.subheader("Состояние корзины")
308
  items, total_quantity, total_price = get_cart_summary(st.session_state.user_id)
309
-
310
  if items:
311
  df = pd.DataFrame(items, columns=["Название", "Количество", "Цена за единицу", "Итого"])
312
  st.dataframe(df.style.format({"Цена за единицу": "{:.2f}", "Итого": "{:.2f}"}), use_container_width=True)
313
-
314
  st.write(f"Общее количество: {total_quantity}, Общая стоимость: {total_price:.2f}")
315
-
316
  if st.button("Пробить"):
317
  sales_details, sale_id, total_amount = record_sales()
318
  if sales_details:
@@ -321,7 +359,7 @@ def add_to_cart():
321
  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)
322
  st.write(f"**Общая сумма сделки:** {total_amount:.2f}")
323
  st.success("Корзина успешно пробита! Все товары добавлены в отчет и корзина очищена.")
324
-
325
  if st.button("Сделки"):
326
  sales_data = get_all_sales(st.session_state.user_id)
327
  if sales_data:
@@ -338,7 +376,6 @@ def add_to_cart():
338
  else:
339
  st.info("Корзина пуста.")
340
 
341
- # Страница отчета о продажах за месяц
342
  def monthly_report():
343
  st.title("Отчет о продажах за месяц")
344
  sales_data, total_sales, total_profit = generate_monthly_report(st.session_state.user_id)
@@ -346,10 +383,10 @@ def monthly_report():
346
  df = pd.DataFrame(sales_data, columns=["Название", "Общее количество", "Отпускная цена", "Общие продажи", "Прибыль"])
347
  st.write(f"**Отчет за {datetime.now().strftime('%B %Y')}**")
348
  st.dataframe(df.style.format({"Отпускная цена": "{:.2f}", "Общие продажи": "{:.2f}", "Прибыль": "{:.2f}"}), use_container_width=True)
349
-
350
  st.write(f"**Общая сумма продаж**: {total_sales:.2f}")
351
  st.write(f"**Общая сумма прибыли**: {total_profit:.2f}")
352
-
353
  if st.button("Сделки"):
354
  sales_data = get_all_sales(st.session_state.user_id)
355
  if sales_data:
@@ -366,32 +403,30 @@ def monthly_report():
366
  else:
367
  st.info("Нет данных о продажах за этот месяц.")
368
 
369
- # --- Функционал резервного копирования базы данных на Hugging Face ---
370
- hf_token = os.getenv("HF_TOKEN") # Замените на ваш Hugging Face токен
 
 
 
 
 
 
 
 
 
 
 
 
371
 
372
- def upload_db_to_hf():
373
- """Загружает файл базы данных в репозиторий Hugging Face (repo_id: Testbase1/testsett)."""
374
  try:
375
- api = HfApi()
376
- api.upload_file(
377
- path_or_fileobj="auth_system.db",
378
- path_in_repo="auth_system.db",
379
- repo_id="Testbase1/testsett",
380
- repo_type="dataset",
381
- token=hf_token
382
- )
383
- print("Резервная копия базы данных успешно загружена на Hugging Face.")
384
- except Exception as e:
385
- print("Ошибка при загрузке резервной копии:", e)
386
 
387
- def periodic_backup():
388
- """Запускает бесконечный цикл резервного копирования с интервалом в 1 час."""
389
- while True:
390
- upload_db_to_hf()
391
- time.sleep(3600) # ожидание 1 час
392
 
393
- # --- Главная функция приложения ---
394
- def main():
395
  if 'logged_in' not in st.session_state:
396
  st.session_state.logged_in = False
397
 
@@ -421,9 +456,10 @@ def main():
421
  login()
422
 
423
  if __name__ == "__main__":
424
- # Глобально запускаем поток резервного копирования, если он ещё не запущен.
425
  if not globals().get("backup_thread_started", False):
426
  backup_thread = threading.Thread(target=periodic_backup, daemon=True)
427
  backup_thread.start()
428
  globals()["backup_thread_started"] = True
429
- main()
 
 
8
  import pytz
9
  import time
10
  import threading
11
+ from huggingface_hub import HfApi, hf_hub_download # Импорт API для работы с Hugging Face
12
 
13
+ # --- Настройки Hugging Face ---
14
+ REPO_ID = "Testbase1/testsett" # Замените на ваш репозиторий
15
+ DB_FILENAME = "auth_system.db"
16
+ HF_TOKEN_WRITE = os.getenv("HF_TOKEN") # Токен для записи (загрузки)
17
+ HF_TOKEN_READ = os.getenv("HF_TOKEN_READ") # Токен для чтения (скачивания)
18
+
19
+ # --- Подключение к базе данных SQLite3 ---
20
+ conn = sqlite3.connect(DB_FILENAME, check_same_thread=False)
21
  c = conn.cursor()
22
 
23
+ # --- Создание таблиц, если они не существуют ---
24
+ def create_tables():
25
+ c.execute('''
26
+ CREATE TABLE IF NOT EXISTS users (
27
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
28
+ username TEXT NOT NULL UNIQUE,
29
+ token TEXT NOT NULL
30
+ )
31
+ ''')
32
+ conn.commit()
33
+
34
+ c.execute('''
35
+ CREATE TABLE IF NOT EXISTS products (
36
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
37
+ name TEXT NOT NULL,
38
+ description TEXT,
39
+ purchase_price REAL NOT NULL,
40
+ sale_price REAL NOT NULL,
41
+ quantity_in_stock INTEGER NOT NULL DEFAULT 0,
42
+ user_id INTEGER NOT NULL,
43
+ FOREIGN KEY(user_id) REFERENCES users(id)
44
+ )
45
+ ''')
46
+ conn.commit()
47
+
48
+ c.execute('''
49
+ CREATE TABLE IF NOT EXISTS cart (
50
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
51
+ product_id INTEGER NOT NULL,
52
+ quantity INTEGER NOT NULL,
53
+ UNIQUE(product_id)
54
+ )
55
+ ''')
56
+ conn.commit()
57
+
58
+ c.execute('''
59
+ CREATE TABLE IF NOT EXISTS sales (
60
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
61
+ sale_id TEXT NOT NULL,
62
+ product_id INTEGER NOT NULL,
63
+ quantity INTEGER NOT NULL,
64
+ sale_date TIMESTAMP NOT NULL,
65
+ total_amount REAL NOT NULL,
66
+ FOREIGN KEY(product_id) REFERENCES products(id)
67
+ )
68
+ ''')
69
+ conn.commit()
70
+
71
+ # --- Функция для скачивания базы данных из Hugging Face ---
72
+ def download_db_from_hf():
73
+ """Скачивает файл базы данных из репозитория Hugging Face."""
74
+ try:
75
+ hf_hub_download(
76
+ repo_id=REPO_ID,
77
+ filename=DB_FILENAME,
78
+ repo_type="dataset",
79
+ token=HF_TOKEN_READ,
80
+ local_dir=".", # Текущая директория
81
+ local_dir_use_symlinks=False
82
+ )
83
+ print("База данных успешно скачана из Hugging Face.")
84
+ return True
85
+ except Exception as e:
86
+ print("Ошибка при скачивании базы данных:", e)
87
+ return False
88
+
89
+ # --- Функция для загрузки базы данных в Hugging Face ---
90
+ def upload_db_to_hf():
91
+ """Загружает файл базы данных в репозиторий Hugging Face."""
92
+ try:
93
+ api = HfApi()
94
+ api.upload_file(
95
+ path_or_fileobj=DB_FILENAME,
96
+ path_in_repo=DB_FILENAME,
97
+ repo_id=REPO_ID,
98
+ repo_type="dataset",
99
+ token=HF_TOKEN_WRITE
100
+ )
101
+ print("Резервная копия базы данных успешно загружена на Hugging Face.")
102
+ except Exception as e:
103
+ print("Ошибка при загрузке резервной копии:", e)
104
+
105
+ # --- Функция периодического резервного копирования ---
106
+ def periodic_backup():
107
+ """Запускает бесконечный цикл резервного копирования с интервалом в 1 час."""
108
+ while True:
109
+ upload_db_to_hf()
110
+ time.sleep(15) # ожидание 1 час
111
+
112
+ # --- Вспомогательные функции (генерация токена, получение ID пользователя и т.д.) ---
113
  def generate_token():
114
  return ''.join(random.choices(string.ascii_letters + string.digits, k=13))
115
 
 
116
  def get_user_id_by_token(token):
117
  c.execute("SELECT id FROM users WHERE token=?", (token,))
118
  user = c.fetchone()
119
  return user[0] if user else None
120
 
 
121
  def get_cart_summary(user_id):
122
  c.execute('''
123
  SELECT p.name, c.quantity, p.sale_price, c.quantity * p.sale_price
 
130
  total_price = sum(item[3] for item in items)
131
  return items, total_quantity, total_price
132
 
 
133
  def record_sales():
134
  sales_details = []
135
+ sale_id = ''.join(random.choices(string.ascii_letters + string.digits, k=8))
136
  sale_date = datetime.now(pytz.timezone('Asia/Bishkek')).strftime('%Y-%m-%d %H:%M:%S')
137
+
138
  c.execute('SELECT product_id, quantity FROM cart')
139
  cart_items = c.fetchall()
140
+
141
  total_amount = 0.0
142
  for product_id, quantity in cart_items:
143
  c.execute('SELECT sale_price FROM products WHERE id=?', (product_id,))
144
  sale_price = c.fetchone()[0]
145
+
146
  amount = quantity * sale_price
147
  total_amount += amount
148
+
149
  c.execute('''
150
  INSERT INTO sales (sale_id, product_id, quantity, sale_date, total_amount)
151
  VALUES (?, ?, ?, ?, ?)
152
  ''', (sale_id, product_id, quantity, sale_date, amount))
153
  sales_details.append((product_id, quantity, amount, sale_date))
154
+
155
  c.execute('DELETE FROM cart')
156
  conn.commit()
157
  return sales_details, sale_id, total_amount
158
 
 
159
  def generate_monthly_report(user_id):
160
  start_date = (datetime.now().replace(day=1)).strftime('%Y-%m-%d')
161
  end_date = (datetime.now() + timedelta(days=31)).replace(day=1).strftime('%Y-%m-%d')
 
168
  WHERE s.sale_date BETWEEN ? AND ? AND p.user_id = ?
169
  GROUP BY p.id
170
  ''', (start_date, end_date, user_id))
171
+
172
  sales_data = c.fetchall()
173
 
174
  total_sales = sum(item[3] for item in sales_data)
175
  total_profit = sum(item[4] for item in sales_data)
176
+
177
  return sales_data, total_sales, total_profit
178
 
 
179
  def get_all_sales(user_id):
180
  c.execute('''
181
  SELECT DISTINCT sale_id, sale_date, SUM(total_amount) AS total_amount
 
188
  sales_data = c.fetchall()
189
  return sales_data
190
 
 
191
  def get_sale_details(sale_id):
192
  c.execute('''
193
  SELECT p.name, s.quantity, p.sale_price, s.sale_date
 
198
  sale_details = c.fetchall()
199
  return sale_details
200
 
201
+ # --- Страницы приложения ---
202
  def register():
203
  st.title('Регистрация')
204
  username = st.text_input("Введите ваше имя пользователя")
 
216
  else:
217
  st.error("Неверный пароль администратора!")
218
 
 
219
  def login():
220
  st.title('Авторизация')
221
  token_input = st.text_input("Введите ваш токен")
 
223
  if st.button("Войти"):
224
  user_id = get_user_id_by_token(token_input)
225
  if user_id:
226
+ st.session_state.logged_in = True
227
  st.session_state.username = token_input
228
  st.session_state.user_id = user_id
229
  st.success("Добро пожаловать!")
230
  else:
231
  st.error("Неверный токен!")
232
 
 
233
  def add_product():
234
  st.title("Добавление товара")
235
  product_name = st.text_input("Название товара").strip().lower()
 
247
  else:
248
  st.error("Пожалуйста, введите все обязательные данные.")
249
 
 
250
  def edit_products():
251
  st.title("Редактирование товара")
252
  products = c.execute("SELECT id, name, description, purchase_price, sale_price, quantity_in_stock FROM products WHERE user_id=?",
253
  (st.session_state.user_id,)).fetchall()
254
+
255
  if products:
256
  product_names = [p[1] for p in products]
257
  product_id = st.selectbox("Выберите товар", product_names)
258
  product = next(p for p in products if p[1] == product_id)
259
+
260
  new_name = st.text_input("Новое название товара", product[1])
261
  new_description = st.text_area("Новое описание товара", product[2])
262
  new_purchase_price = st.number_input("Новая приходная цена", min_value=0.0, step=0.01, value=product[3])
263
  new_sale_price = st.number_input("Новая отпускная цена", min_value=0.0, step=0.01, value=product[4])
264
  new_quantity_in_stock = st.number_input("Новое количество на складе", min_value=0, step=1, value=product[5])
265
+
266
  if st.button("Сохранить изменения"):
267
  c.execute('''
268
  UPDATE products
 
277
  conn.commit()
278
  st.success("Товар успешно удален!")
279
 
 
280
  def add_to_cart():
281
  st.title("Отпуск товара")
282
  products = c.execute("SELECT id, name, sale_price, quantity_in_stock FROM products WHERE user_id=?",
 
297
 
298
  with cols[1]:
299
  quantity = st.number_input(f"Количество для '{product[1]}'", min_value=0, max_value=product[3], key=f"quantity_{product[0]}")
300
+
301
  with cols[2]:
302
  add_button = st.button(f"Добавить в корзину", key=f"add_{product[0]}")
303
+
304
  if add_button:
305
  if quantity <= product[3]:
306
  c.execute('''
 
318
 
319
  with cols[3]:
320
  remove_button = st.button(f"Удалить из корзины", key=f"remove_{product[0]}")
321
+
322
  if remove_button:
323
  if quantity > 0:
324
  current_quantity = c.execute("SELECT quantity FROM cart WHERE product_id=?", (product[0],)).fetchone()
 
344
 
345
  st.subheader("Состояние корзины")
346
  items, total_quantity, total_price = get_cart_summary(st.session_state.user_id)
347
+
348
  if items:
349
  df = pd.DataFrame(items, columns=["Название", "Количество", "Цена за единицу", "Итого"])
350
  st.dataframe(df.style.format({"Цена за единицу": "{:.2f}", "Итого": "{:.2f}"}), use_container_width=True)
351
+
352
  st.write(f"Общее количество: {total_quantity}, Общая стоимость: {total_price:.2f}")
353
+
354
  if st.button("Пробить"):
355
  sales_details, sale_id, total_amount = record_sales()
356
  if sales_details:
 
359
  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)
360
  st.write(f"**Общая сумма сделки:** {total_amount:.2f}")
361
  st.success("Корзина успешно пробита! Все товары добавлены в отчет и корзина очищена.")
362
+
363
  if st.button("Сделки"):
364
  sales_data = get_all_sales(st.session_state.user_id)
365
  if sales_data:
 
376
  else:
377
  st.info("Корзина пуста.")
378
 
 
379
  def monthly_report():
380
  st.title("Отчет о продажах за месяц")
381
  sales_data, total_sales, total_profit = generate_monthly_report(st.session_state.user_id)
 
383
  df = pd.DataFrame(sales_data, columns=["Название", "Общее количество", "Отпускная цена", "Общие продажи", "Прибыль"])
384
  st.write(f"**Отчет за {datetime.now().strftime('%B %Y')}**")
385
  st.dataframe(df.style.format({"Отпускная цена": "{:.2f}", "Общие продажи": "{:.2f}", "Прибыль": "{:.2f}"}), use_container_width=True)
386
+
387
  st.write(f"**Общая сумма продаж**: {total_sales:.2f}")
388
  st.write(f"**Общая сумма прибыли**: {total_profit:.2f}")
389
+
390
  if st.button("Сделки"):
391
  sales_data = get_all_sales(st.session_state.user_id)
392
  if sales_data:
 
403
  else:
404
  st.info("Нет данных о продажах за этот месяц.")
405
 
406
+ # --- Главная функция приложения ---
407
+ def main():
408
+ # 1. Проверяем, существует ли локальная база данных.
409
+ if not os.path.exists(DB_FILENAME):
410
+ st.warning("Локальная база данных не найдена. Попытка загрузки из Hugging Face...")
411
+ # 2. Пытаемся скачать базу данных из Hugging Face.
412
+ if download_db_from_hf():
413
+ st.success("База данных успешно загружена из Hugging Face!")
414
+ else:
415
+ st.error("Не удалось загрузить базу данных из Hugging Face. Будет создана новая пустая база данных.")
416
+ create_tables() # Создаем таблицы, если не удалось скачать
417
+
418
+ else:
419
+ st.info("Локальная база данных найдена.")
420
 
421
+ # Инициализация таблиц, если база данных только что создана или скачана без таблиц
 
422
  try:
423
+ c.execute("SELECT * FROM users LIMIT 1") # Проверяем, существует ли таблица users
424
+ except sqlite3.OperationalError:
425
+ st.info("Таблицы не найдены в базе данных. Создание таблиц...")
426
+ create_tables() # Создаем таблицы, если они не существуют
427
+ st.success("Таблицы успешно созданы!")
 
 
 
 
 
 
428
 
 
 
 
 
 
429
 
 
 
430
  if 'logged_in' not in st.session_state:
431
  st.session_state.logged_in = False
432
 
 
456
  login()
457
 
458
  if __name__ == "__main__":
459
+ # 3. Запускаем поток резервного копирования (если он еще не запущен).
460
  if not globals().get("backup_thread_started", False):
461
  backup_thread = threading.Thread(target=periodic_backup, daemon=True)
462
  backup_thread.start()
463
  globals()["backup_thread_started"] = True
464
+
465
+ main()