Загрузка данных
import tkinter as tk
from tkinter import messagebox
from bd import get_connection
SORT_OPTIONS = {
"Название": "name",
"Цена": "price",
"Категория": "category"
}
def set_icon(window):
try:
window.iconbitmap("Icon.ico")
except Exception:
pass
def add_logo(window):
try:
logo_img = tk.PhotoImage(file="logo.png")
logo_img = logo_img.subsample(4, 4)
label = tk.Label(window, image=logo_img, bg="white")
label.image = logo_img
label.pack(pady=(10, 0))
except Exception:
pass
def load_products(list_frame, search_text="", order_by="name"):
for widget in list_frame.winfo_children():
widget.destroy()
conn = get_connection()
cur = conn.cursor()
query = f"SELECT article, name, price, category, stock_qty FROM products WHERE name ILIKE %s ORDER BY {order_by}"
cur.execute(query, (f"%{search_text}%",))
products = cur.fetchall()
conn.close()
header = tk.Label(list_frame, text=f"{'Артикул':<10}{'Название':<20}{'Цена':<10}{'Категория':<18}{'Кол-во'}", bg="white", font=("Courier New", 10, "bold"))
header.pack(anchor="w")
for article, name, price, category, qty in products:
line = f"{article:<10}{name:<20}{str(price):<10}{category:<18}{qty}"
tk.Label(list_frame, text=line, bg="white", font=("Courier New", 10)).pack(anchor="w")
def open_add_product_window(list_frame):
win = tk.Toplevel()
win.title("Добавить товар")
win.configure(bg="white")
set_icon(win)
fields = {}
labels = ["Артикул", "Название", "Ед. изм.", "Цена", "Поставщик", "Производитель", "Категория", "Скидка", "Кол-во на складе"]
for i, label in enumerate(labels):
tk.Label(win, text=label, bg="white", font=("Times New Roman", 10)).grid(row=i, column=0, sticky="w", padx=10, pady=5)
entry = tk.Entry(win, font=("Times New Roman", 10))
entry.grid(row=i, column=1, padx=10, pady=5)
fields[label] = entry
def save():
if not fields["Артикул"].get() or not fields["Название"].get() or not fields["Цена"].get():
messagebox.showerror("Ошибка", "Заполните артикул, название и цену")
return
conn = get_connection()
cur = conn.cursor()
cur.execute(
"INSERT INTO products (article, name, unit, price, supplier, manufacturer, category, discount, stock_qty) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)",
(
fields["Артикул"].get(), fields["Название"].get(), fields["Ед. изм."].get(),
fields["Цена"].get(), fields["Поставщик"].get(), fields["Производитель"].get(),
fields["Категория"].get(), fields["Скидка"].get() or 0, fields["Кол-во на складе"].get() or 0
)
)
conn.commit()
conn.close()
win.destroy()
load_products(list_frame)
tk.Button(win, text="Сохранить", bg="#00FA9A", font=("Times New Roman", 10), command=save).grid(row=len(labels), column=0, columnspan=2, pady=15)
def open_delete_product_window(list_frame):
win = tk.Toplevel()
win.title("Удалить товар")
win.configure(bg="white")
set_icon(win)
tk.Label(win, text="Артикул товара", bg="white", font=("Times New Roman", 10)).pack(padx=10, pady=(10, 0))
article_entry = tk.Entry(win, font=("Times New Roman", 10))
article_entry.pack(padx=10, pady=5)
def delete():
if not article_entry.get():
messagebox.showerror("Ошибка", "Введите артикул")
return
conn = get_connection()
cur = conn.cursor()
cur.execute("DELETE FROM order_items WHERE product_article = %s", (article_entry.get(),))
cur.execute("DELETE FROM products WHERE article = %s", (article_entry.get(),))
conn.commit()
conn.close()
win.destroy()
load_products(list_frame)
tk.Button(win, text="Удалить", bg="#E24B4A", font=("Times New Roman", 10), command=delete).pack(pady=15)
def open_edit_product_window(list_frame):
win = tk.Toplevel()
win.title("Редактировать товар")
win.configure(bg="white")
set_icon(win)
tk.Label(win, text="Артикул товара", bg="white", font=("Times New Roman", 10)).grid(row=0, column=0, sticky="w", padx=10, pady=5)
article_entry = tk.Entry(win, font=("Times New Roman", 10))
article_entry.grid(row=0, column=1, padx=10, pady=5)
tk.Label(win, text="Новая цена", bg="white", font=("Times New Roman", 10)).grid(row=1, column=0, sticky="w", padx=10, pady=5)
price_entry = tk.Entry(win, font=("Times New Roman", 10))
price_entry.grid(row=1, column=1, padx=10, pady=5)
tk.Label(win, text="Новое кол-во на складе", bg="white", font=("Times New Roman", 10)).grid(row=2, column=0, sticky="w", padx=10, pady=5)
qty_entry = tk.Entry(win, font=("Times New Roman", 10))
qty_entry.grid(row=2, column=1, padx=10, pady=5)
def save():
if not article_entry.get():
messagebox.showerror("Ошибка", "Введите артикул")
return
conn = get_connection()
cur = conn.cursor()
cur.execute(
"UPDATE products SET price = %s, stock_qty = %s WHERE article = %s",
(price_entry.get(), qty_entry.get(), article_entry.get())
)
conn.commit()
conn.close()
win.destroy()
load_products(list_frame)
tk.Button(win, text="Сохранить", bg="#00FA9A", font=("Times New Roman", 10), command=save).grid(row=3, column=0, columnspan=2, pady=15)
def load_orders(list_frame):
for widget in list_frame.winfo_children():
widget.destroy()
conn = get_connection()
cur = conn.cursor()
cur.execute("""
SELECT o.id, u.full_name, o.order_date, o.delivery_date, o.status
FROM orders o
JOIN users u ON u.id = o.client_id
ORDER BY o.id
""")
orders = cur.fetchall()
conn.close()
header = tk.Label(list_frame, text=f"{'№':<5}{'Клиент':<28}{'Дата заказа':<14}{'Доставка':<14}{'Статус'}", bg="white", font=("Courier New", 10, "bold"))
header.pack(anchor="w")
for order_id, client, order_date, delivery_date, status in orders:
line = f"{order_id:<5}{client:<28}{str(order_date):<14}{str(delivery_date):<14}{status}"
tk.Label(list_frame, text=line, bg="white", font=("Courier New", 10)).pack(anchor="w")
def open_add_order_window(list_frame):
win = tk.Toplevel()
win.title("Добавить заказ")
win.configure(bg="white")
set_icon(win)
labels = ["ID клиента", "Дата заказа (ГГГГ-ММ-ДД)", "Дата доставки (ГГГГ-ММ-ДД)", "ID пункта выдачи", "Код получения", "Статус"]
fields = {}
for i, label in enumerate(labels):
tk.Label(win, text=label, bg="white", font=("Times New Roman", 10)).grid(row=i, column=0, sticky="w", padx=10, pady=5)
entry = tk.Entry(win, font=("Times New Roman", 10))
entry.grid(row=i, column=1, padx=10, pady=5)
fields[label] = entry
def save():
if not fields["ID клиента"].get() or not fields["Дата заказа (ГГГГ-ММ-ДД)"].get():
messagebox.showerror("Ошибка", "Заполните хотя бы ID клиента и дату заказа")
return
conn = get_connection()
cur = conn.cursor()
cur.execute(
"INSERT INTO orders (client_id, order_date, delivery_date, pickup_point_id, pickup_code, status) VALUES (%s,%s,%s,%s,%s,%s)",
(
fields["ID клиента"].get(),
fields["Дата заказа (ГГГГ-ММ-ДД)"].get(),
fields["Дата доставки (ГГГГ-ММ-ДД)"].get() or None,
fields["ID пункта выдачи"].get() or None,
fields["Код получения"].get() or None,
fields["Статус"].get() or "Новый"
)
)
conn.commit()
conn.close()
win.destroy()
load_orders(list_frame)
tk.Button(win, text="Сохранить", bg="#00FA9A", font=("Times New Roman", 10), command=save).grid(row=len(labels), column=0, columnspan=2, pady=15)
def open_edit_order_window(list_frame):
win = tk.Toplevel()
win.title("Изменить статус заказа")
win.configure(bg="white")
set_icon(win)
tk.Label(win, text="Номер заказа", bg="white", font=("Times New Roman", 10)).grid(row=0, column=0, sticky="w", padx=10, pady=5)
id_entry = tk.Entry(win, font=("Times New Roman", 10))
id_entry.grid(row=0, column=1, padx=10, pady=5)
tk.Label(win, text="Новый статус", bg="white", font=("Times New Roman", 10)).grid(row=1, column=0, sticky="w", padx=10, pady=5)
status_entry = tk.Entry(win, font=("Times New Roman", 10))
status_entry.grid(row=1, column=1, padx=10, pady=5)
def save():
if not id_entry.get() or not status_entry.get():
messagebox.showerror("Ошибка", "Заполните номер заказа и статус")
return
conn = get_connection()
cur = conn.cursor()
cur.execute("UPDATE orders SET status = %s WHERE id = %s", (status_entry.get(), id_entry.get()))
conn.commit()
conn.close()
win.destroy()
load_orders(list_frame)
tk.Button(win, text="Сохранить", bg="#00FA9A", font=("Times New Roman", 10), command=save).grid(row=2, column=0, columnspan=2, pady=15)
def open_delete_order_window(list_frame):
win = tk.Toplevel()
win.title("Удалить заказ")
win.configure(bg="white")
set_icon(win)
tk.Label(win, text="Номер заказа", bg="white", font=("Times New Roman", 10)).pack(padx=10, pady=(10, 0))
id_entry = tk.Entry(win, font=("Times New Roman", 10))
id_entry.pack(padx=10, pady=5)
def delete():
if not id_entry.get():
messagebox.showerror("Ошибка", "Введите номер заказа")
return
conn = get_connection()
cur = conn.cursor()
cur.execute("DELETE FROM order_items WHERE order_id = %s", (id_entry.get(),))
cur.execute("DELETE FROM orders WHERE id = %s", (id_entry.get(),))
conn.commit()
conn.close()
win.destroy()
load_orders(list_frame)
tk.Button(win, text="Удалить", bg="#E24B4A", font=("Times New Roman", 10), command=delete).pack(pady=15)
def open_orders_window(role):
win = tk.Toplevel()
win.title("Заказы")
win.configure(bg="white")
win.geometry("680x420")
set_icon(win)
list_frame = tk.Frame(win, bg="white")
if role == "Администратор":
actions = tk.Frame(win, bg="white")
actions.pack(fill="x", padx=10, pady=10)
tk.Button(actions, text="Добавить заказ", bg="#00FA9A", font=("Times New Roman", 10), command=lambda: open_add_order_window(list_frame)).pack(side="left", padx=(0, 10))
tk.Button(actions, text="Изменить статус", bg="#00FA9A", font=("Times New Roman", 10), command=lambda: open_edit_order_window(list_frame)).pack(side="left", padx=(0, 10))
tk.Button(actions, text="Удалить заказ", bg="#E24B4A", font=("Times New Roman", 10), command=lambda: open_delete_order_window(list_frame)).pack(side="left")
list_frame.pack(fill="both", expand=True, padx=10)
load_orders(list_frame)
def open_catalog(role, full_name):
login_window.destroy()
catalog = tk.Tk()
catalog.title(f"ООО Обувь — товары ({role})")
catalog.geometry("680x500")
catalog.configure(bg="white")
set_icon(catalog)
add_logo(catalog)
tk.Label(catalog, text=f"Вы вошли как: {full_name} ({role})", bg="white", font=("Times New Roman", 12)).pack(pady=10)
list_frame = tk.Frame(catalog, bg="white")
if role in ("Менеджер", "Администратор"):
controls = tk.Frame(catalog, bg="white")
controls.pack(fill="x", padx=10, pady=(0, 5))
tk.Label(controls, text="Поиск:", bg="white", font=("Times New Roman", 10)).pack(side="left")
search_entry = tk.Entry(controls, font=("Times New Roman", 10))
search_entry.pack(side="left", padx=(5, 15))
sort_var = tk.StringVar(value="Название")
tk.Label(controls, text="Сортировка:", bg="white", font=("Times New Roman", 10)).pack(side="left")
sort_menu = tk.OptionMenu(controls, sort_var, *SORT_OPTIONS.keys())
sort_menu.pack(side="left", padx=(5, 15))
tk.Button(
controls, text="Применить", bg="#7FFF00", font=("Times New Roman", 10),
command=lambda: load_products(list_frame, search_entry.get(), SORT_OPTIONS[sort_var.get()])
).pack(side="left")
actions = tk.Frame(catalog, bg="white")
actions.pack(fill="x", padx=10, pady=(0, 10))
tk.Button(actions, text="Заказы", bg="#7FFF00", font=("Times New Roman", 10), command=lambda: open_orders_window(role)).pack(side="left", padx=(0, 10))
if role == "Администратор":
tk.Button(actions, text="Добавить товар", bg="#00FA9A", font=("Times New Roman", 10), command=lambda: open_add_product_window(list_frame)).pack(side="left", padx=(0, 10))
tk.Button(actions, text="Редактировать товар", bg="#00FA9A", font=("Times New Roman", 10), command=lambda: open_edit_product_window(list_frame)).pack(side="left", padx=(0, 10))
tk.Button(actions, text="Удалить товар", bg="#E24B4A", font=("Times New Roman", 10), command=lambda: open_delete_product_window(list_frame)).pack(side="left")
list_frame.pack(fill="both", expand=True, padx=10)
load_products(list_frame)
catalog.mainloop()
def check_login(login_entry, password_entry):
login = login_entry.get()
password = password_entry.get()
conn = get_connection()
cur = conn.cursor()
cur.execute("SELECT id, role, full_name FROM users WHERE login = %s AND password = %s", (login, password))
user = cur.fetchone()
conn.close()
if user:
open_catalog(user[1], user[2])
else:
messagebox.showerror("Ошибка", "Неверный логин или пароль")
login_window = tk.Tk()
login_window.title("ООО Обувь — вход")
login_window.geometry("300x320")
login_window.configure(bg="white")
set_icon(login_window)
add_logo(login_window)
tk.Label(login_window, text="Логин", bg="white", font=("Times New Roman", 11)).pack(pady=(15, 0))
login_entry = tk.Entry(login_window, font=("Times New Roman", 11))
login_entry.pack()
tk.Label(login_window, text="Пароль", bg="white", font=("Times New Roman", 11)).pack(pady=(10, 0))
password_entry = tk.Entry(login_window, show="*", font=("Times New Roman", 11))
password_entry.pack()
tk.Button(login_window, text="Войти", bg="#00FA9A", font=("Times New Roman", 11), command=lambda: check_login(login_entry, password_entry)).pack(pady=20)
tk.Button(login_window, text="Продолжить как гость", bg="white", font=("Times New Roman", 9, "underline"), relief="flat", command=lambda: open_catalog("Гость", "Гость")).pack()
login_window.mainloop()