Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -5,6 +5,9 @@ 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)
|
|
@@ -91,11 +94,9 @@ def record_sales():
|
|
| 91 |
|
| 92 |
total_amount = 0.0
|
| 93 |
for product_id, quantity in cart_items:
|
| 94 |
-
# Получение цены за единицу товара
|
| 95 |
c.execute('SELECT sale_price FROM products WHERE id=?', (product_id,))
|
| 96 |
sale_price = c.fetchone()[0]
|
| 97 |
|
| 98 |
-
# Расчет общей суммы для этого товара
|
| 99 |
amount = quantity * sale_price
|
| 100 |
total_amount += amount
|
| 101 |
|
|
@@ -130,7 +131,6 @@ def generate_monthly_report(user_id):
|
|
| 130 |
|
| 131 |
return sales_data, total_sales, total_profit
|
| 132 |
|
| 133 |
-
|
| 134 |
# Функция для получения всех сделок
|
| 135 |
def get_all_sales(user_id):
|
| 136 |
c.execute('''
|
|
@@ -144,7 +144,6 @@ def get_all_sales(user_id):
|
|
| 144 |
sales_data = c.fetchall()
|
| 145 |
return sales_data
|
| 146 |
|
| 147 |
-
|
| 148 |
# Функция для получения всех подробностей сделок
|
| 149 |
def get_sale_details(sale_id):
|
| 150 |
c.execute('''
|
|
@@ -192,10 +191,10 @@ def login():
|
|
| 192 |
# Форма добавления товара
|
| 193 |
def add_product():
|
| 194 |
st.title("Добавление товара")
|
| 195 |
-
product_name = st.text_input("Название товара").strip().lower()
|
| 196 |
product_description = st.text_area("Описание товара")
|
| 197 |
-
purchase_price = st.number_input("Приходная цена", min_value=0.0, step=0.01)
|
| 198 |
-
sale_price = st.number_input("Отпускная цена", min_value=0.0, step=0.01)
|
| 199 |
product_quantity = st.number_input("Количество на складе", min_value=0, step=1)
|
| 200 |
|
| 201 |
if st.button("Добавить товар"):
|
|
@@ -243,9 +242,8 @@ def add_to_cart():
|
|
| 243 |
st.title("Отпуск товара")
|
| 244 |
products = c.execute("SELECT id, name, sale_price, quantity_in_stock FROM products WHERE user_id=?",
|
| 245 |
(st.session_state.user_id,)).fetchall()
|
| 246 |
-
search_term = st.text_input("Поиск товара").strip().lower()
|
| 247 |
|
| 248 |
-
# Поиск товаров по ключевому слову (без учета регистра)
|
| 249 |
c.execute("SELECT id, name, sale_price, quantity_in_stock FROM products WHERE user_id=? AND LOWER(name) LIKE ?",
|
| 250 |
(st.session_state.user_id, f"%{search_term}%"))
|
| 251 |
products = c.fetchall()
|
|
@@ -254,8 +252,8 @@ def add_to_cart():
|
|
| 254 |
for product in products:
|
| 255 |
cols = st.columns(4)
|
| 256 |
with cols[0]:
|
| 257 |
-
st.write(product[1])
|
| 258 |
-
st.write(f"**Отпускная цена**: {product[2]:.2f}")
|
| 259 |
st.write(f"**Остаток на складе**: {product[3]}")
|
| 260 |
|
| 261 |
with cols[1]:
|
|
@@ -266,15 +264,12 @@ def add_to_cart():
|
|
| 266 |
|
| 267 |
if add_button:
|
| 268 |
if quantity <= product[3]:
|
| 269 |
-
# Обработка добавления товара в корзину
|
| 270 |
c.execute('''
|
| 271 |
INSERT INTO cart (product_id, quantity)
|
| 272 |
VALUES (?, ?)
|
| 273 |
ON CONFLICT(product_id)
|
| 274 |
DO UPDATE SET quantity = quantity + excluded.quantity
|
| 275 |
''', (product[0], quantity))
|
| 276 |
-
|
| 277 |
-
# Уменьшаем количество на складе
|
| 278 |
c.execute("UPDATE products SET quantity_in_stock = quantity_in_stock - ? WHERE id=?",
|
| 279 |
(quantity, product[0]))
|
| 280 |
conn.commit()
|
|
@@ -287,7 +282,6 @@ def add_to_cart():
|
|
| 287 |
|
| 288 |
if remove_button:
|
| 289 |
if quantity > 0:
|
| 290 |
-
# Обработка удаления товара из корзины
|
| 291 |
current_quantity = c.execute("SELECT quantity FROM cart WHERE product_id=?", (product[0],)).fetchone()
|
| 292 |
if current_quantity:
|
| 293 |
new_quantity = current_quantity[0] - quantity
|
|
@@ -300,8 +294,6 @@ def add_to_cart():
|
|
| 300 |
''', (product[0], new_quantity))
|
| 301 |
else:
|
| 302 |
c.execute("DELETE FROM cart WHERE product_id=?", (product[0],))
|
| 303 |
-
|
| 304 |
-
# Увеличиваем количество на складе
|
| 305 |
c.execute("UPDATE products SET quantity_in_stock = quantity_in_stock + ? WHERE id=?",
|
| 306 |
(quantity, product[0]))
|
| 307 |
conn.commit()
|
|
@@ -311,18 +303,15 @@ def add_to_cart():
|
|
| 311 |
else:
|
| 312 |
st.error(f"Введите количество для удаления товара '{product[1]}'.")
|
| 313 |
|
| 314 |
-
# Отображение состояния корзины
|
| 315 |
st.subheader("Состояние корзины")
|
| 316 |
items, total_quantity, total_price = get_cart_summary(st.session_state.user_id)
|
| 317 |
|
| 318 |
if items:
|
| 319 |
-
# Создание DataFrame для таблицы
|
| 320 |
df = pd.DataFrame(items, columns=["Название", "Количество", "Цена за единицу", "Итого"])
|
| 321 |
st.dataframe(df.style.format({"Цена за единицу": "{:.2f}", "Итого": "{:.2f}"}), use_container_width=True)
|
| 322 |
|
| 323 |
st.write(f"Общее количество: {total_quantity}, Общая стоимость: {total_price:.2f}")
|
| 324 |
|
| 325 |
-
# Добавляем кнопку "Пробить" для оформления продажи
|
| 326 |
if st.button("Пробить"):
|
| 327 |
sales_details, sale_id, total_amount = record_sales()
|
| 328 |
if sales_details:
|
|
@@ -332,11 +321,9 @@ def add_to_cart():
|
|
| 332 |
st.write(f"**Общая сумма сделки:** {total_amount:.2f}")
|
| 333 |
st.success("Корзина успешно пробита! Все товары добавлены в отчет и корзина очищена.")
|
| 334 |
|
| 335 |
-
# Кнопка для отображения сделок
|
| 336 |
if st.button("Сделки"):
|
| 337 |
-
sales_data = get_all_sales()
|
| 338 |
if sales_data:
|
| 339 |
-
sale_ids = [sale[0] for sale in sales_data]
|
| 340 |
for sale_id, sale_date, total_amount in sales_data:
|
| 341 |
st.write(f"**Сделка ID:** {sale_id} ({sale_date}) - **Общая сумма:** {total_amount:.2f}")
|
| 342 |
sale_details = get_sale_details(sale_id)
|
|
@@ -355,7 +342,6 @@ def monthly_report():
|
|
| 355 |
st.title("Отчет о продажах за месяц")
|
| 356 |
sales_data, total_sales, total_profit = generate_monthly_report(st.session_state.user_id)
|
| 357 |
if sales_data:
|
| 358 |
-
# Создание DataFrame для отчета
|
| 359 |
df = pd.DataFrame(sales_data, columns=["Название", "Общее количество", "Отпускная цена", "Общие продажи", "Прибыль"])
|
| 360 |
st.write(f"**Отчет за {datetime.now().strftime('%B %Y')}**")
|
| 361 |
st.dataframe(df.style.format({"Отпускная цена": "{:.2f}", "Общие продажи": "{:.2f}", "Прибыль": "{:.2f}"}), use_container_width=True)
|
|
@@ -363,11 +349,9 @@ def monthly_report():
|
|
| 363 |
st.write(f"**Общая сумма продаж**: {total_sales:.2f}")
|
| 364 |
st.write(f"**Общая сумма прибыли**: {total_profit:.2f}")
|
| 365 |
|
| 366 |
-
# Кнопка для отображения сделок
|
| 367 |
if st.button("Сделки"):
|
| 368 |
sales_data = get_all_sales(st.session_state.user_id)
|
| 369 |
if sales_data:
|
| 370 |
-
sale_ids = [sale[0] for sale in sales_data]
|
| 371 |
for sale_id, sale_date, total_amount in sales_data:
|
| 372 |
st.write(f"**Сделка ID:** {sale_id} ({sale_date}) - **Общая сумма:** {total_amount:.2f}")
|
| 373 |
sale_details = get_sale_details(sale_id)
|
|
@@ -381,11 +365,36 @@ def monthly_report():
|
|
| 381 |
else:
|
| 382 |
st.info("Нет данных о продажах за этот месяц.")
|
| 383 |
|
| 384 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 385 |
def main():
|
| 386 |
if 'logged_in' not in st.session_state:
|
| 387 |
st.session_state.logged_in = False
|
| 388 |
|
|
|
|
| 389 |
if st.session_state.logged_in:
|
| 390 |
st.sidebar.title(f"Привет, {st.session_state.username}!")
|
| 391 |
option = st.sidebar.selectbox("Выберите действие", ["Добавить товар", "Отпуск товара", "Редактировать товары", "Отчет за месяц", "Выйти"])
|
|
@@ -411,4 +420,9 @@ def main():
|
|
| 411 |
login()
|
| 412 |
|
| 413 |
if __name__ == "__main__":
|
| 414 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
import string
|
| 6 |
from datetime import datetime, timedelta
|
| 7 |
import pytz
|
| 8 |
+
import time
|
| 9 |
+
import threading
|
| 10 |
+
from huggingface_hub import HfApi # импорт API для работы с Hugging Face
|
| 11 |
|
| 12 |
# Подключение к базе данных SQLite3
|
| 13 |
conn = sqlite3.connect('auth_system.db', check_same_thread=False)
|
|
|
|
| 94 |
|
| 95 |
total_amount = 0.0
|
| 96 |
for product_id, quantity in cart_items:
|
|
|
|
| 97 |
c.execute('SELECT sale_price FROM products WHERE id=?', (product_id,))
|
| 98 |
sale_price = c.fetchone()[0]
|
| 99 |
|
|
|
|
| 100 |
amount = quantity * sale_price
|
| 101 |
total_amount += amount
|
| 102 |
|
|
|
|
| 131 |
|
| 132 |
return sales_data, total_sales, total_profit
|
| 133 |
|
|
|
|
| 134 |
# Функция для получения всех сделок
|
| 135 |
def get_all_sales(user_id):
|
| 136 |
c.execute('''
|
|
|
|
| 144 |
sales_data = c.fetchall()
|
| 145 |
return sales_data
|
| 146 |
|
|
|
|
| 147 |
# Функция для получения всех подробностей сделок
|
| 148 |
def get_sale_details(sale_id):
|
| 149 |
c.execute('''
|
|
|
|
| 191 |
# Форма добавления товара
|
| 192 |
def add_product():
|
| 193 |
st.title("Добавление товара")
|
| 194 |
+
product_name = st.text_input("Название товара").strip().lower()
|
| 195 |
product_description = st.text_area("Описание товара")
|
| 196 |
+
purchase_price = st.number_input("Приходная цена", min_value=0.0, step=0.01)
|
| 197 |
+
sale_price = st.number_input("Отпускная цена", min_value=0.0, step=0.01)
|
| 198 |
product_quantity = st.number_input("Количество на складе", min_value=0, step=1)
|
| 199 |
|
| 200 |
if st.button("Добавить товар"):
|
|
|
|
| 242 |
st.title("Отпуск товара")
|
| 243 |
products = c.execute("SELECT id, name, sale_price, quantity_in_stock FROM products WHERE user_id=?",
|
| 244 |
(st.session_state.user_id,)).fetchall()
|
| 245 |
+
search_term = st.text_input("Поиск товара").strip().lower()
|
| 246 |
|
|
|
|
| 247 |
c.execute("SELECT id, name, sale_price, quantity_in_stock FROM products WHERE user_id=? AND LOWER(name) LIKE ?",
|
| 248 |
(st.session_state.user_id, f"%{search_term}%"))
|
| 249 |
products = c.fetchall()
|
|
|
|
| 252 |
for product in products:
|
| 253 |
cols = st.columns(4)
|
| 254 |
with cols[0]:
|
| 255 |
+
st.write(product[1])
|
| 256 |
+
st.write(f"**Отпускная цена**: {product[2]:.2f}")
|
| 257 |
st.write(f"**Остаток на складе**: {product[3]}")
|
| 258 |
|
| 259 |
with cols[1]:
|
|
|
|
| 264 |
|
| 265 |
if add_button:
|
| 266 |
if quantity <= product[3]:
|
|
|
|
| 267 |
c.execute('''
|
| 268 |
INSERT INTO cart (product_id, quantity)
|
| 269 |
VALUES (?, ?)
|
| 270 |
ON CONFLICT(product_id)
|
| 271 |
DO UPDATE SET quantity = quantity + excluded.quantity
|
| 272 |
''', (product[0], quantity))
|
|
|
|
|
|
|
| 273 |
c.execute("UPDATE products SET quantity_in_stock = quantity_in_stock - ? WHERE id=?",
|
| 274 |
(quantity, product[0]))
|
| 275 |
conn.commit()
|
|
|
|
| 282 |
|
| 283 |
if remove_button:
|
| 284 |
if quantity > 0:
|
|
|
|
| 285 |
current_quantity = c.execute("SELECT quantity FROM cart WHERE product_id=?", (product[0],)).fetchone()
|
| 286 |
if current_quantity:
|
| 287 |
new_quantity = current_quantity[0] - quantity
|
|
|
|
| 294 |
''', (product[0], new_quantity))
|
| 295 |
else:
|
| 296 |
c.execute("DELETE FROM cart WHERE product_id=?", (product[0],))
|
|
|
|
|
|
|
| 297 |
c.execute("UPDATE products SET quantity_in_stock = quantity_in_stock + ? WHERE id=?",
|
| 298 |
(quantity, product[0]))
|
| 299 |
conn.commit()
|
|
|
|
| 303 |
else:
|
| 304 |
st.error(f"Введите количество для удаления товара '{product[1]}'.")
|
| 305 |
|
|
|
|
| 306 |
st.subheader("Состояние корзины")
|
| 307 |
items, total_quantity, total_price = get_cart_summary(st.session_state.user_id)
|
| 308 |
|
| 309 |
if items:
|
|
|
|
| 310 |
df = pd.DataFrame(items, columns=["Название", "Количество", "Цена за единицу", "Итого"])
|
| 311 |
st.dataframe(df.style.format({"Цена за единицу": "{:.2f}", "Итого": "{:.2f}"}), use_container_width=True)
|
| 312 |
|
| 313 |
st.write(f"Общее количество: {total_quantity}, Общая стоимость: {total_price:.2f}")
|
| 314 |
|
|
|
|
| 315 |
if st.button("Пробить"):
|
| 316 |
sales_details, sale_id, total_amount = record_sales()
|
| 317 |
if sales_details:
|
|
|
|
| 321 |
st.write(f"**Общая сумма сделки:** {total_amount:.2f}")
|
| 322 |
st.success("Корзина успешно пробита! Все товары добавлены в отчет и корзина очищена.")
|
| 323 |
|
|
|
|
| 324 |
if st.button("Сделки"):
|
| 325 |
+
sales_data = get_all_sales(st.session_state.user_id)
|
| 326 |
if sales_data:
|
|
|
|
| 327 |
for sale_id, sale_date, total_amount in sales_data:
|
| 328 |
st.write(f"**Сделка ID:** {sale_id} ({sale_date}) - **Общая сумма:** {total_amount:.2f}")
|
| 329 |
sale_details = get_sale_details(sale_id)
|
|
|
|
| 342 |
st.title("Отчет о продажах за месяц")
|
| 343 |
sales_data, total_sales, total_profit = generate_monthly_report(st.session_state.user_id)
|
| 344 |
if sales_data:
|
|
|
|
| 345 |
df = pd.DataFrame(sales_data, columns=["Название", "Общее количество", "Отпускная цена", "Общие продажи", "Прибыль"])
|
| 346 |
st.write(f"**Отчет за {datetime.now().strftime('%B %Y')}**")
|
| 347 |
st.dataframe(df.style.format({"Отпускная цена": "{:.2f}", "Общие продажи": "{:.2f}", "Прибыль": "{:.2f}"}), use_container_width=True)
|
|
|
|
| 349 |
st.write(f"**Общая сумма продаж**: {total_sales:.2f}")
|
| 350 |
st.write(f"**Общая сумма прибыли**: {total_profit:.2f}")
|
| 351 |
|
|
|
|
| 352 |
if st.button("Сделки"):
|
| 353 |
sales_data = get_all_sales(st.session_state.user_id)
|
| 354 |
if sales_data:
|
|
|
|
| 355 |
for sale_id, sale_date, total_amount in sales_data:
|
| 356 |
st.write(f"**Сделка ID:** {sale_id} ({sale_date}) - **Общая сумма:** {total_amount:.2f}")
|
| 357 |
sale_details = get_sale_details(sale_id)
|
|
|
|
| 365 |
else:
|
| 366 |
st.info("Нет данных о продажах за этот месяц.")
|
| 367 |
|
| 368 |
+
# --- Функционал резервного копирования базы данных на Hugging Face ---
|
| 369 |
+
hf_token = "YOUR_HF_TOKEN" # Замените на ваш Hugging Face токен
|
| 370 |
+
|
| 371 |
+
def upload_db_to_hf():
|
| 372 |
+
"""Загружает файл базы данных в репозиторий Hugging Face (repo_id: Testbase1/testsett)."""
|
| 373 |
+
try:
|
| 374 |
+
api = HfApi()
|
| 375 |
+
api.upload_file(
|
| 376 |
+
path_or_fileobj="auth_system.db",
|
| 377 |
+
path_in_repo="auth_system.db",
|
| 378 |
+
repo_id="Testbase1/testsett",
|
| 379 |
+
repo_type="dataset",
|
| 380 |
+
token=hf_token
|
| 381 |
+
)
|
| 382 |
+
print("Резервная копия базы данных успешно загружена на Hugging Face.")
|
| 383 |
+
except Exception as e:
|
| 384 |
+
print("Ошибка при загрузке резервной к��пии:", e)
|
| 385 |
+
|
| 386 |
+
def periodic_backup():
|
| 387 |
+
"""Запускает бесконечный цикл резервного копирования с интервалом в 1 час."""
|
| 388 |
+
while True:
|
| 389 |
+
upload_db_to_hf()
|
| 390 |
+
time.sleep(3600) # ожидание 1 час
|
| 391 |
+
|
| 392 |
+
# --- Главная функция приложения ---
|
| 393 |
def main():
|
| 394 |
if 'logged_in' not in st.session_state:
|
| 395 |
st.session_state.logged_in = False
|
| 396 |
|
| 397 |
+
st.sidebar.title("Навигация")
|
| 398 |
if st.session_state.logged_in:
|
| 399 |
st.sidebar.title(f"Привет, {st.session_state.username}!")
|
| 400 |
option = st.sidebar.selectbox("Выберите действие", ["Добавить товар", "Отпуск товара", "Редактировать товары", "Отчет за месяц", "Выйти"])
|
|
|
|
| 420 |
login()
|
| 421 |
|
| 422 |
if __name__ == "__main__":
|
| 423 |
+
# Глобально запускаем поток резервного копирования, если он ещё не запущен.
|
| 424 |
+
if not globals().get("backup_thread_started", False):
|
| 425 |
+
backup_thread = threading.Thread(target=periodic_backup, daemon=True)
|
| 426 |
+
backup_thread.start()
|
| 427 |
+
globals()["backup_thread_started"] = True
|
| 428 |
+
main()
|