from PyQt6.QtWidgets import ( QLabel, QLineEdit, QComboBox, QPushButton, QMessageBox, QHBoxLayout, QVBoxLayout, QFormLayout, QTableWidget, QTableWidgetItem, QSpinBox, QGroupBox, QFrame ) from PyQt6.QtCore import Qt from base import BaseWindow from data import USERS, PRODUCTS, ORDERS, STATUS_OPTIONS class LoginWindow(BaseWindow): def _setup_ui(self): layout = QVBoxLayout() form = QFormLayout() self.login_edit = QLineEdit() self.pass_edit = QLineEdit() self.pass_edit.setEchoMode(QLineEdit.EchoMode.Password) self.role_combo = QComboBox() self.role_combo.addItems(['Покупатель', 'Кассир']) form.addRow('Логин:', self.login_edit) form.addRow('Пароль:', self.pass_edit) form.addRow('Роль:', self.role_combo) self.login_btn = QPushButton('Войти в систему') self.login_btn.clicked.connect(self.try_login) layout.addLayout(form) layout.addWidget(self.login_btn) self.setLayout(layout) def try_login(self): username = self.login_edit.text().strip() password = self.pass_edit.text() role = self.role_combo.currentText() if username not in USERS: QMessageBox.critical(self, 'Ошибка', 'Пользователь не найден') return user = USERS[username] if password != user['password']: QMessageBox.critical(self, 'Ошибка', 'Неправильный пароль') return if role != user['role']: QMessageBox.critical(self, 'Ошибка', 'Выбранная роль не совпадает с ролью пользователя') return if role == 'Покупатель': self._composer.render_request.emit("Покупатель") else: self._composer.render_request.emit("Кассир") class CustomerWindow(BaseWindow): def _setup_ui(self): main_layout = QVBoxLayout() top_layout = QHBoxLayout() left_box = QVBoxLayout() self.table = QTableWidget(len(PRODUCTS), 3) self.table.setHorizontalHeaderLabels([ 'Товар', 'Тип животного', 'Цена' ]) self.table.setSelectionBehavior( self.table.SelectionBehavior.SelectRows ) self.table.setEditTriggers(self.table.EditTrigger.NoEditTriggers) for row, p in enumerate(PRODUCTS): self.table.setItem(row, 0, QTableWidgetItem(p['name'])) self.table.setItem(row, 1, QTableWidgetItem(p['animal'])) self.table.setItem(row, 2, QTableWidgetItem(f"{p['price']} р.")) left_box.addWidget(self.table) self.select_btn = QPushButton('Выбрать товар') self.select_btn.clicked.connect(self.select_product) left_box.addWidget(self.select_btn) top_layout.addLayout(left_box, 2) # Правая колонка: расчёт стоимости right_group = QGroupBox('Расчёт стоимости') right_layout = QFormLayout() self.price_edit = QLineEdit() self.price_edit.setReadOnly(True) self.quantity_spin = QSpinBox() self.quantity_spin.setRange(1, 1000) self.quantity_spin.setValue(1) self.calc_btn = QPushButton('Рассчитать стоимость') self.calc_btn.setStyleSheet('background-color: #4CAF50; color: white;') self.calc_btn.clicked.connect(self.calculate_sum) self.sum_label = QLabel('0 р.') self.sum_label.setFrameShape(QFrame.Shape.Box) self.sum_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.add_btn = QPushButton('Добавить в заказ') self.add_btn.setStyleSheet('background-color: #4CAF50; color: white;') self.add_btn.clicked.connect(self.add_to_order) right_layout.addRow('Цена за единицу:', self.price_edit) right_layout.addRow('Количество:', self.quantity_spin) right_layout.addRow(self.calc_btn) right_layout.addRow('Сумма:', self.sum_label) right_layout.addRow(self.add_btn) right_group.setLayout(right_layout) top_layout.addWidget(right_group, 1) main_layout.addLayout(top_layout) # Внизу: закрыть self.close_btn = QPushButton('Закрыть') self.close_btn.clicked.connect(self.close) main_layout.addWidget(self.close_btn, alignment=Qt.AlignmentFlag.AlignRight) self.setLayout(main_layout) # Внутренний список заказа (простой) self.current_order = [] def select_product(self): selected = self.table.currentRow() if selected < 0: QMessageBox.warning(self, 'Ошибка', 'Не выбран товар') return price_item = self.table.item(selected, 2).text() # Из строки "500 р." выделим число price_number = ''.join(ch for ch in price_item if ch.isdigit()) self.price_edit.setText(price_number) def calculate_sum(self): price_text = self.price_edit.text().strip() if not price_text.isdigit(): QMessageBox.warning(self, 'Ошибка', 'Сначала выберите товар') return price = int(price_text) qty = self.quantity_spin.value() total = price * qty self.sum_label.setText(f"{total} р.") def add_to_order(self): sum_text = self.sum_label.text() if sum_text.startswith('0') or sum_text == '0 р.': QMessageBox.warning(self, 'Ошибка', 'Нужно рассчитать сумму перед добавлением') return # Для простоты — добавляем запись в список и показываем сообщение self.current_order.append({'sum': sum_text}) QMessageBox.information(self, 'Добавлено', f'Добавлено в заказ: {sum_text}') class CashierWindow(BaseWindow): def _setup_ui(self): main_layout = QVBoxLayout() self.orders_table = QTableWidget(len(ORDERS), 4) self.orders_table.setHorizontalHeaderLabels([ '№ заказа', 'Покупатель', 'Сумма', 'Статус' ]) self.orders_table.setSelectionBehavior( self.orders_table.SelectionBehavior.SelectRows ) self.orders_table.setEditTriggers( self.orders_table.EditTrigger.NoEditTriggers ) for row, o in enumerate(ORDERS): self.orders_table.setItem(row, 0, QTableWidgetItem(o['id'])) self.orders_table.setItem(row, 1, QTableWidgetItem(o['customer'])) self.orders_table.setItem(row, 2, QTableWidgetItem(o['sum'])) self.orders_table.setItem(row, 3, QTableWidgetItem(o['status'])) main_layout.addWidget(self.orders_table) ctrl_layout = QHBoxLayout() self.status_combo = QComboBox() self.status_combo.addItems(STATUS_OPTIONS) self.change_btn = QPushButton('Изменить статус') self.change_btn.clicked.connect(self.change_status) ctrl_layout.addWidget(QLabel('Новый статус:')) ctrl_layout.addWidget(self.status_combo) ctrl_layout.addWidget(self.change_btn) main_layout.addLayout(ctrl_layout) self.setLayout(main_layout) self.setFixedSize(450, 200) def change_status(self): selected = self.orders_table.currentRow() if selected < 0: QMessageBox.critical(self, 'Ошибка', 'Не выбрана строка') return new_status = self.status_combo.currentText() self.orders_table.setItem(selected, 3, QTableWidgetItem(new_status)) QMessageBox.information(self, 'Готово', 'Статус обновлён')