widget.py login_window main_window cart_window product_detail_dialog.py product_detail.ui product_card_widget.py product_card.ui cart_manager.py db_connection.py ui_login_window.py ui_main_window.py ui_cart_window.py ui_product_detail.py ui_product_card.py order_history_window.py --------------------------------------------------------------------- widget.py # This Python file uses the following encoding: utf-8 import sys from PySide6.QtWidgets import QApplication from PySide6.QtGui import QIcon from login_window import LoginWindow from main_window import MainWindow if __name__ == "__main__": app = QApplication(sys.argv) app.setWindowIcon(QIcon("assets/111.ico")) login_window = LoginWindow() if login_window.exec() == LoginWindow.Accepted: current_user = login_window.get_current_user() main_window = MainWindow(current_user) main_window.setWindowTitle(f"Каталог продукции - {current_user['full_name']}") main_window.show() sys.exit(app.exec()) else: sys.exit(0) --------------------------------------------------------------------- db_connection.py # This Python file uses the following encoding: utf-8 import mysql.connector from mysql.connector import Error DB_CONFIG = { 'host': '192.168.50.51', 'port': 3306, 'user': 'web', 'password': 'QWEasdzxc_1', 'database': 'cafeteria' } def get_connection(): try: connection = mysql.connector.connect(**DB_CONFIG) if connection.is_connected(): return connection except Error: return None def execute_query(query, params=None): connection = get_connection() if not connection: return None try: cursor = connection.cursor(dictionary=True) if params: cursor.execute(query, params) else: cursor.execute(query) results = cursor.fetchall() cursor.close() connection.close() return results except Error: if connection: connection.close() return None def execute_update(query, params=None): connection = get_connection() if not connection: return None try: cursor = connection.cursor() if params: cursor.execute(query, params) else: cursor.execute(query) connection.commit() last_id = cursor.lastrowid affected_rows = cursor.rowcount cursor.close() connection.close() return last_id if last_id > 0 else affected_rows except Error: if connection: connection.rollback() connection.close() return None --------------------------------------------------------------------- login_window.py # This Python file uses the following encoding: utf-8 from PySide6.QtWidgets import QDialog, QMessageBox from PySide6.QtCore import Qt from ui_login_window import Ui_LoginWindow from db_connection import execute_query class LoginWindow(QDialog): def __init__(self): super().__init__() self.ui = Ui_LoginWindow() self.ui.setupUi(self) self.current_user = None self.ui.login_button.clicked.connect(self.attempt_login) self.ui.password_line_edit.returnPressed.connect(self.attempt_login) self.ui.username_line_edit.returnPressed.connect(self.ui.password_line_edit.setFocus) self.ui.username_line_edit.setFocus() def attempt_login(self): username = self.ui.username_line_edit.text().strip() password = self.ui.password_line_edit.text() if not username or not password: QMessageBox.warning(self, "Ошибка входа", "Введите логин и пароль") return query = """ SELECT e.id, a.login, e.surname, e.name, e.patronymic, e.role_id FROM autorization a JOIN employers e ON a.employer_id = e.id WHERE a.login = %s AND a.password = %s """ results = execute_query(query, (username, password)) if not results: QMessageBox.critical(self, "Ошибка входа", "Неверный логин или пароль") self.ui.password_line_edit.clear() self.ui.password_line_edit.setFocus() return user = results[0] user['full_name'] = f"{user['surname']} {user['name']}" if user.get('patronymic'): user['full_name'] += f" {user['patronymic']}" self.current_user = user self.accept() def get_current_user(self): return self.current_user --------------------------------------------------------------------- main_window.py # This Python file uses the following encoding: utf-8 from PySide6.QtWidgets import QMainWindow from PySide6.QtCore import Qt from ui_main_window import Ui_MainWindow from db_connection import execute_query from cart_manager import CartManager from product_detail_dialog import ProductDetailDialog class MainWindow(QMainWindow): def __init__(self, current_user=None): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.current_user = current_user self.cart_manager = CartManager() self.all_products = [] self.product_detail_dialog = None self.ui.search_line_edit.textChanged.connect(self.apply_filters) self.ui.category_combo_box.currentIndexChanged.connect(self.apply_filters) self.ui.sort_combo_box.currentIndexChanged.connect(self.apply_filters) self.ui.cart_button.clicked.connect(self.open_cart) self.ui.history_button.clicked.connect(self.open_order_history) self.load_categories() self.load_products() self.apply_filters() def load_categories(self): query = "SELECT id, value FROM product_types WHERE is_visible = 1 ORDER BY value" categories = execute_query(query) if categories: for category in categories: self.ui.category_combo_box.addItem(category['value'], category['id']) def load_products(self): query = """ SELECT p.*, pt.value as type_name, pwt.value as weight_type, (SELECT pp.image FROM product_photos pp WHERE pp.product_id = p.id ORDER BY pp.order_value LIMIT 1) as image_data FROM products p LEFT JOIN product_types pt ON p.type_id = pt.id LEFT JOIN product_weight_types pwt ON p.weight_type_id = pwt.id WHERE p.is_visible = 1 AND p.available_count > 0 ORDER BY p.name """ self.all_products = execute_query(query) or [] def apply_filters(self): search_text = self.ui.search_line_edit.text().lower() selected_category = self.ui.category_combo_box.currentData() sort_index = self.ui.sort_combo_box.currentIndex() filtered_products = self.all_products.copy() if search_text: filtered_products = [p for p in filtered_products if search_text in p['name'].lower() or (p['description'] and search_text in p['description'].lower()) or (p.get('type_name') and search_text in p['type_name'].lower())] if selected_category is not None: filtered_products = [p for p in filtered_products if p['type_id'] == selected_category] if sort_index == 1: filtered_products.sort(key=lambda p: float(p['cost'])) elif sort_index == 2: filtered_products.sort(key=lambda p: float(p['cost']), reverse=True) self.display_products(filtered_products) def display_products(self, products): layout = self.ui.products_grid_layout while layout.count(): item = layout.takeAt(0) if item.widget(): item.widget().deleteLater() columns = 4 for index, product in enumerate(products): row = index // columns col = index % columns product_card = self.create_product_card(product) layout.addWidget(product_card, row, col) def create_product_card(self, product): from product_card_widget import ProductCardWidget card = ProductCardWidget(product, self) card.get_add_button().clicked.connect(lambda: self.add_to_cart(product['id'])) image_label = card.get_image_label() image_label.mousePressEvent = lambda event: self.show_product_detail(product['id']) return card def add_to_cart(self, product_id): self.cart_manager.add_item(product_id, 1) def show_product_detail(self, product_id): if self.product_detail_dialog and self.product_detail_dialog.isVisible(): self.product_detail_dialog.close() self.product_detail_dialog = ProductDetailDialog(product_id, self) self.product_detail_dialog.show() def open_cart(self): from cart_window import CartWindow self.cart_window = CartWindow(self.current_user) self.cart_window.show() self.hide() def open_order_history(self): from order_history_window import OrderHistoryWindow self.order_history_window = OrderHistoryWindow(self.current_user) self.order_history_window.show() self.hide() --------------------------------------------------------------------- cart_manager.py # This Python file uses the following encoding: utf-8 from db_connection import execute_query class CartManager: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super(CartManager, cls).__new__(cls) cls._instance.cart_items = {} return cls._instance def add_item(self, product_id, quantity=1): if product_id in self.cart_items: self.cart_items[product_id] += quantity else: self.cart_items[product_id] = quantity def remove_item(self, product_id): if product_id in self.cart_items: del self.cart_items[product_id] def update_quantity(self, product_id, quantity): if quantity <= 0: self.remove_item(product_id) else: self.cart_items[product_id] = quantity def get_cart_items(self): if not self.cart_items: return [] product_ids = list(self.cart_items.keys()) placeholders = ','.join(['%s'] * len(product_ids)) query = f""" SELECT p.*, pt.value as type_name FROM products p LEFT JOIN product_types pt ON p.type_id = pt.id WHERE p.id IN ({placeholders}) """ products = execute_query(query, product_ids) if not products: return [] for product in products: product['quantity'] = self.cart_items[product['id']] product['subtotal'] = float(product['cost']) * product['quantity'] return products def get_total(self): items = self.get_cart_items() return sum(item['subtotal'] for item in items) def clear_cart(self): self.cart_items = {} def get_item_count(self): return sum(self.cart_items.values()) --------------------------------------------------------------------- product_card_widget.py # This Python file uses the following encoding: utf-8 from PySide6.QtWidgets import QFrame from PySide6.QtCore import Qt from PySide6.QtGui import QPixmap from ui_product_card import Ui_ProductCard class ProductCardWidget(QFrame): def __init__(self, product, parent=None): super().__init__(parent) self.ui = Ui_ProductCard() self.ui.setupUi(self) self.product = product self.setup_card() def setup_card(self): self.ui.name_label.setText(self.product['name']) description = self.product.get('description', '') if description and len(description) > 50: description = description[:50] + '...' self.ui.description_label.setText(description) self.ui.price_label.setText(f"Цена: {float(self.product['cost']):.2f} руб.") weight = self.product.get('weight_value', '') weight_type = self.product.get('weight_type', '') self.ui.weight_label.setText(f"Вес: {weight} {weight_type}") self.load_image() def load_image(self): if self.product.get('image_data'): pixmap = QPixmap() if pixmap.loadFromData(self.product['image_data']): self.ui.image_label.setPixmap(pixmap.scaled(240, 150, Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.ui.image_label.setText("") return def get_add_button(self): return self.ui.add_button def get_image_label(self): return self.ui.image_label --------------------------------------------------------------------- cart_window.py # This Python file uses the following encoding: utf-8 from PySide6.QtWidgets import QMainWindow, QTableWidgetItem, QPushButton, QSpinBox, QMessageBox from PySide6.QtCore import Qt from ui_cart_window import Ui_CartWindow from db_connection import execute_query, execute_update from cart_manager import CartManager class CartWindow(QMainWindow): def __init__(self, current_user=None): super().__init__() self.ui = Ui_CartWindow() self.ui.setupUi(self) self.current_user = current_user self.cart_manager = CartManager() self.pay_types = [] self.order_types = [] self.ui.no_client_checkbox.stateChanged.connect(self.toggle_client_selection) self.ui.create_order_button.clicked.connect(self.create_order) self.ui.back_button.clicked.connect(self.go_back) self.load_pay_types() self.load_order_types() self.load_clients() self.load_cart_items() def load_pay_types(self): query = "SELECT id, value FROM pay_types" self.pay_types = execute_query(query) or [] self.ui.payment_type_combo_box.clear() for pt in self.pay_types: self.ui.payment_type_combo_box.addItem(pt['value'], pt['id']) def load_order_types(self): query = "SELECT id, value FROM order_types" self.order_types = execute_query(query) or [] def load_clients(self): query = "SELECT phone_number, name, bonus_count FROM clients ORDER BY name" clients = execute_query(query) if clients: for client in clients: name = client['name'] or 'Без имени' display_text = f"{name} ({client['phone_number']})" self.ui.client_combo_box.addItem(display_text, client['phone_number']) def toggle_client_selection(self, state): self.ui.client_combo_box.setEnabled(state == Qt.Unchecked) def load_cart_items(self): items = self.cart_manager.get_cart_items() self.ui.cart_table_widget.setRowCount(len(items)) for row, item in enumerate(items): name_item = QTableWidgetItem(item['name']) name_item.setFlags(name_item.flags() & ~Qt.ItemIsEditable) self.ui.cart_table_widget.setItem(row, 0, name_item) price_item = QTableWidgetItem(f"{float(item['cost']):.2f}") price_item.setFlags(price_item.flags() & ~Qt.ItemIsEditable) self.ui.cart_table_widget.setItem(row, 1, price_item) quantity_spinbox = QSpinBox() quantity_spinbox.setMinimum(1) quantity_spinbox.setMaximum(999) quantity_spinbox.setValue(item['quantity']) quantity_spinbox.valueChanged.connect(lambda value, product_id=item['id']: self.update_quantity(product_id, value)) self.ui.cart_table_widget.setCellWidget(row, 2, quantity_spinbox) subtotal_item = QTableWidgetItem(f"{item['subtotal']:.2f}") subtotal_item.setFlags(subtotal_item.flags() & ~Qt.ItemIsEditable) self.ui.cart_table_widget.setItem(row, 3, subtotal_item) remove_button = QPushButton("Исключить") remove_button.clicked.connect(lambda checked, product_id=item['id']: self.remove_item(product_id)) self.ui.cart_table_widget.setCellWidget(row, 4, remove_button) self.calculate_totals() def update_quantity(self, product_id, quantity): self.cart_manager.update_quantity(product_id, quantity) self.load_cart_items() def remove_item(self, product_id): self.cart_manager.remove_item(product_id) self.load_cart_items() def calculate_totals(self): total = self.cart_manager.get_total() self.ui.total_label.setText(f"Стоимость корзины: {total:.2f} руб.") def get_order_type_id(self): if self.ui.in_cafe_radio_button.isChecked(): type_value = "В заведении" elif self.ui.takeaway_radio_button.isChecked(): type_value = "На вынос" else: type_value = "Доставка курьером" for ot in self.order_types: if ot['value'] == type_value: return ot['id'] return 1 def get_next_order_number(self): query = "SELECT COALESCE(MAX(order_number), 0) + 1 as next_num FROM orders WHERE DATE(date_create) = CURDATE()" result = execute_query(query) return result[0]['next_num'] if result else 1 def create_order(self): if self.cart_manager.get_item_count() == 0: QMessageBox.warning(self, "Ошибка", "Корзина пуста.") return reply = QMessageBox.question(self, "Подтверждение", "Оформить заказ?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply != QMessageBox.Yes: return client_phone = None if self.ui.no_client_checkbox.isChecked() else self.ui.client_combo_box.currentData() pay_id = self.ui.payment_type_combo_box.currentData() type_id = self.get_order_type_id() total_cost = self.cart_manager.get_total() order_number = self.get_next_order_number() employer_id = self.current_user['id'] if self.current_user else 1 order_query = """ INSERT INTO orders (order_number, date_create, type_id, employer_id, total_cost, pay_id) VALUES (%s, NOW(), %s, %s, %s, %s) """ order_id = execute_update(order_query, (order_number, type_id, employer_id, total_cost, pay_id)) if not order_id: QMessageBox.critical(self, "Ошибка", "Не удалось создать заказ.") return items = self.cart_manager.get_cart_items() for item in items: item_query = "INSERT INTO order_shopcase (order_id, product_id, current_count) VALUES (%s, %s, %s)" execute_update(item_query, (order_id, item['id'], item['quantity'])) if client_phone: link_query = "INSERT INTO clients_orders (client_number, order_id) VALUES (%s, %s)" execute_update(link_query, (client_phone, order_id)) QMessageBox.information(self, "Успех", f"Заказ #{order_number} оформлен!") self.cart_manager.clear_cart() self.go_back() def go_back(self): from main_window import MainWindow self.main_window = MainWindow(self.current_user) self.main_window.show() self.close() --------------------------------------------------------------------- product_detail_dialog.py # This Python file uses the following encoding: utf-8 from PySide6.QtWidgets import QDialog from PySide6.QtGui import QPixmap from PySide6.QtCore import Qt from ui_product_detail import Ui_ProductDetailDialog from db_connection import execute_query class ProductDetailDialog(QDialog): def __init__(self, product_id, parent=None): super().__init__(parent) self.ui = Ui_ProductDetailDialog() self.ui.setupUi(self) self.product_id = product_id self.ui.close_button.clicked.connect(self.close) self.load_product_details() def load_product_details(self): query = """ SELECT p.*, pt.value as type_name, pwt.value as weight_type FROM products p LEFT JOIN product_types pt ON p.type_id = pt.id LEFT JOIN product_weight_types pwt ON p.weight_type_id = pwt.id WHERE p.id = %s """ results = execute_query(query, (self.product_id,)) if not results: self.ui.name_label.setText("Продукт не найден") return product = results[0] photo_query = "SELECT image FROM product_photos WHERE product_id = %s ORDER BY order_value LIMIT 1" photos = execute_query(photo_query, (self.product_id,)) if photos and photos[0].get('image'): pixmap = QPixmap() if pixmap.loadFromData(photos[0]['image']): self.ui.image_label.setPixmap(pixmap.scaled(400, 300, Qt.KeepAspectRatio, Qt.SmoothTransformation)) self.ui.image_label.setText("") self.ui.name_label.setText(product['name']) self.ui.category_label.setText(f"Категория: {product.get('type_name', 'Не указана')}") self.ui.description_label.setText(product.get('description', 'Описание отсутствует')) self.ui.price_label.setText(f"Цена: {float(product['cost']):.2f} руб.") weight = product.get('weight_value', '') weight_type = product.get('weight_type', '') self.ui.weight_label.setText(f"Вес: {weight} {weight_type}") available = product.get('available_count', 0) > 0 availability_text = "В наличии" if available else "Недоступно" availability_color = "green" if available else "red" self.ui.availability_label.setText(f"Доступность: {availability_text}") self.ui.availability_label.setStyleSheet(f"color: {availability_color}; font-weight: bold;") --------------------------------------------------------------------- order_history_window.py # This Python file uses the following encoding: utf-8 from PySide6.QtWidgets import QMainWindow, QTableWidgetItem, QHeaderView from PySide6.QtCore import Qt from ui_order_history_window import Ui_OrderHistoryWindow from db_connection import execute_query class OrderHistoryWindow(QMainWindow): def __init__(self, current_user=None): super().__init__() self.ui = Ui_OrderHistoryWindow() self.ui.setupUi(self) self.current_user = current_user self.ui.refresh_button.clicked.connect(self.load_orders) self.ui.back_button.clicked.connect(self.go_back) self.ui.orders_table_widget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.load_orders() def load_orders(self): query = """ SELECT o.id, o.order_number, o.date_create, o.total_cost, ot.value as order_type, pt.value as pay_type, CONCAT(e.surname, ' ', e.name) as employer_name, (SELECT c.name FROM clients_orders co JOIN clients c ON co.client_number = c.phone_number WHERE co.order_id = o.id LIMIT 1) as client_name FROM orders o LEFT JOIN order_types ot ON o.type_id = ot.id LEFT JOIN pay_types pt ON o.pay_id = pt.id LEFT JOIN employers e ON o.employer_id = e.id ORDER BY o.date_create DESC """ orders = execute_query(query) or [] self.ui.orders_table_widget.setRowCount(len(orders)) for row, order in enumerate(orders): order_num_item = QTableWidgetItem(str(order['order_number'])) order_num_item.setFlags(order_num_item.flags() & ~Qt.ItemIsEditable) self.ui.orders_table_widget.setItem(row, 0, order_num_item) date_str = order['date_create'].strftime('%d.%m.%Y %H:%M') if order['date_create'] else '' date_item = QTableWidgetItem(date_str) date_item.setFlags(date_item.flags() & ~Qt.ItemIsEditable) self.ui.orders_table_widget.setItem(row, 1, date_item) type_item = QTableWidgetItem(order.get('order_type', '')) type_item.setFlags(type_item.flags() & ~Qt.ItemIsEditable) self.ui.orders_table_widget.setItem(row, 2, type_item) employee_item = QTableWidgetItem(order.get('employer_name', '')) employee_item.setFlags(employee_item.flags() & ~Qt.ItemIsEditable) self.ui.orders_table_widget.setItem(row, 3, employee_item) cost_item = QTableWidgetItem(f"{float(order['total_cost']):.2f} руб.") cost_item.setFlags(cost_item.flags() & ~Qt.ItemIsEditable) self.ui.orders_table_widget.setItem(row, 4, cost_item) pay_item = QTableWidgetItem(order.get('pay_type', '')) pay_item.setFlags(pay_item.flags() & ~Qt.ItemIsEditable) self.ui.orders_table_widget.setItem(row, 5, pay_item) client_item = QTableWidgetItem(order.get('client_name', 'Без клиента') or 'Без клиента') client_item.setFlags(client_item.flags() & ~Qt.ItemIsEditable) self.ui.orders_table_widget.setItem(row, 6, client_item) self.ui.total_orders_label.setText(f"Всего заказов: {len(orders)}") def go_back(self): from main_window import MainWindow self.main_window = MainWindow(self.current_user) self.main_window.show() self.close() ---------------------------------------------------------------------