After Graduate Update

This commit is contained in:
Daniel 2025-11-26 19:31:33 +03:00
parent b92a91ab37
commit c6917dd85e
69 changed files with 7540 additions and 0 deletions

344
ressult/gui/orders_panel.py Normal file
View file

@ -0,0 +1,344 @@
# gui/orders_panel.py
"""
Панель управления заказами и продажами
"""
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QTableWidget, QTableWidgetItem, QPushButton,
QHeaderView, QMessageBox, QDateEdit, QComboBox,
QLineEdit, QFormLayout, QDialog, QDoubleSpinBox)
from PyQt6.QtCore import Qt, QDate
from PyQt6.QtGui import QFont
import requests
class OrderForm(QDialog):
"""Форма для добавления/редактирования заказа"""
order_saved = pyqtSignal()
def __init__(self, parent=None, order_data=None, auth=None, partners=None):
super().__init__(parent)
self.order_data = order_data
self.auth = auth
self.partners = partners or []
self.setup_ui()
def setup_ui(self):
self.setWindowTitle("Добавить заказ" if not self.order_data else "Редактировать заказ")
self.setModal(True)
self.resize(400, 300)
layout = QVBoxLayout()
# Форма ввода данных
form_layout = QFormLayout()
# Выбор партнера
self.partner_combo = QComboBox()
self.partner_combo.addItem("Выберите партнера", None)
for partner in self.partners:
self.partner_combo.addItem(partner['company_name'], partner['partner_id'])
form_layout.addRow("Партнер*:", self.partner_combo)
# Название продукта
self.product_name = QLineEdit()
self.product_name.setPlaceholderText("Введите название продукта")
form_layout.addRow("Продукт*:", self.product_name)
# Количество
self.quantity = QDoubleSpinBox()
self.quantity.setRange(0.01, 100000.0)
self.quantity.setDecimals(2)
form_layout.addRow("Количество*:", self.quantity)
# Дата продажи
self.sale_date = QDateEdit()
self.sale_date.setDate(QDate.currentDate())
self.sale_date.setCalendarPopup(True)
form_layout.addRow("Дата продажи*:", self.sale_date)
layout.addLayout(form_layout)
# Кнопки
buttons_layout = QHBoxLayout()
self.save_button = QPushButton("Сохранить")
self.save_button.clicked.connect(self.save_order)
self.save_button.setStyleSheet("""
QPushButton {
background-color: #28a745;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
font-weight: bold;
}
QPushButton:hover {
background-color: #218838;
}
""")
self.cancel_button = QPushButton("Отмена")
self.cancel_button.clicked.connect(self.reject)
buttons_layout.addWidget(self.save_button)
buttons_layout.addWidget(self.cancel_button)
buttons_layout.addStretch()
layout.addLayout(buttons_layout)
self.setLayout(layout)
# Если редактирование, заполняем форму
if self.order_data:
self.fill_form()
def fill_form(self):
"""Заполнение формы данными заказа"""
data = self.order_data
# Устанавливаем партнера
partner_index = self.partner_combo.findData(data.get('partner_id'))
if partner_index >= 0:
self.partner_combo.setCurrentIndex(partner_index)
self.product_name.setText(data.get('product_name', ''))
self.quantity.setValue(float(data.get('quantity', 0)))
# Устанавливаем дату
sale_date = data.get('sale_date')
if sale_date:
date = QDate.fromString(sale_date, 'yyyy-MM-dd')
if date.isValid():
self.sale_date.setDate(date)
def validate_form(self):
"""Валидация данных формы"""
errors = []
if not self.partner_combo.currentData():
errors.append("Выберите партнера")
if not self.product_name.text().strip():
errors.append("Введите название продукта")
if self.quantity.value() <= 0:
errors.append("Количество должно быть больше 0")
return errors
def save_order(self):
"""Сохранение заказа"""
errors = self.validate_form()
if errors:
QMessageBox.warning(self, "Ошибка валидации", "\n".join(errors))
return
order_data = {
'partner_id': self.partner_combo.currentData(),
'product_name': self.product_name.text().strip(),
'quantity': self.quantity.value(),
'sale_date': self.sale_date.date().toString('yyyy-MM-dd')
}
try:
if self.order_data:
# Обновление существующего заказа
response = requests.put(
f"http://localhost:8000/api/v1/sales/{self.order_data['sale_id']}",
json=order_data,
auth=self.auth,
timeout=10
)
else:
# Создание нового заказа
response = requests.post(
"http://localhost:8000/api/v1/sales",
json=order_data,
auth=self.auth,
timeout=10
)
if response.status_code == 200:
self.order_saved.emit()
QMessageBox.information(self, "Успех", "Заказ успешно сохранен")
self.accept()
elif response.status_code == 401:
QMessageBox.warning(self, "Ошибка авторизации", "Сессия истекла. Пожалуйста, войдите снова.")
else:
error_msg = response.json().get('detail', 'Неизвестная ошибка')
QMessageBox.warning(self, "Ошибка", f"Не удалось сохранить заказ: {error_msg}")
except requests.exceptions.ConnectionError:
QMessageBox.critical(self, "Ошибка", "Не удалось подключиться к серверу")
except Exception as e:
QMessageBox.critical(self, "Ошибка", f"Ошибка подключения: {str(e)}")
class OrdersPanel(QWidget):
"""Панель управления заказами"""
def __init__(self, auth=None):
super().__init__()
self.auth = auth
self.partners = []
self.setup_ui()
self.load_partners()
self.load_orders()
def setup_ui(self):
"""Настройка интерфейса панели заказов"""
layout = QVBoxLayout()
layout.setContentsMargins(10, 10, 10, 10)
layout.setSpacing(10)
# Заголовок
title = QLabel("Управление заказами")
title.setFont(QFont("Arial", 16, QFont.Weight.Bold))
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(title)
# Панель управления
control_layout = QHBoxLayout()
self.add_button = QPushButton("Добавить заказ")
self.add_button.clicked.connect(self.show_add_order_form)
self.add_button.setStyleSheet("""
QPushButton {
background-color: #007acc;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
font-weight: bold;
}
QPushButton:hover {
background-color: #005a9e;
}
""")
self.refresh_button = QPushButton("Обновить")
self.refresh_button.clicked.connect(self.load_orders)
control_layout.addWidget(self.add_button)
control_layout.addWidget(self.refresh_button)
control_layout.addStretch()
layout.addLayout(control_layout)
# Таблица заказов
self.orders_table = QTableWidget()
self.orders_table.setColumnCount(6)
self.orders_table.setHorizontalHeaderLabels([
"ID", "Партнер", "Продукт", "Количество", "Дата", "Действия"
])
self.orders_table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
self.orders_table.setStyleSheet("""
QTableWidget {
border: 1px solid #ddd;
border-radius: 4px;
background-color: white;
}
QTableWidget::item {
padding: 8px;
}
""")
layout.addWidget(self.orders_table)
self.setLayout(layout)
def load_partners(self):
"""Загрузка списка партнеров"""
try:
response = requests.get(
"http://localhost:8000/api/v1/partners",
auth=self.auth,
timeout=10
)
if response.status_code == 200:
self.partners = response.json()
except:
self.partners = []
def load_orders(self):
"""Загрузка списка заказов"""
try:
response = requests.get(
"http://localhost:8000/api/v1/sales",
auth=self.auth,
timeout=10
)
if response.status_code == 200:
orders = response.json()
self.display_orders(orders)
elif response.status_code == 401:
QMessageBox.warning(self, "Ошибка авторизации", "Сессия истекла")
except Exception as e:
QMessageBox.warning(self, "Ошибка", f"Не удалось загрузить заказы: {str(e)}")
def display_orders(self, orders):
"""Отображение заказов в таблице"""
self.orders_table.setRowCount(len(orders))
for row, order in enumerate(orders):
self.orders_table.setItem(row, 0, QTableWidgetItem(str(order.get('sale_id', ''))))
self.orders_table.setItem(row, 1, QTableWidgetItem(order.get('company_name', 'Неизвестно')))
self.orders_table.setItem(row, 2, QTableWidgetItem(order.get('product_name', '')))
self.orders_table.setItem(row, 3, QTableWidgetItem(str(order.get('quantity', ''))))
self.orders_table.setItem(row, 4, QTableWidgetItem(order.get('sale_date', '')))
# Кнопки действий
actions_widget = QWidget()
actions_layout = QHBoxLayout(actions_widget)
actions_layout.setContentsMargins(4, 4, 4, 4)
actions_layout.setSpacing(4)
delete_button = QPushButton("Удалить")
delete_button.setStyleSheet("""
QPushButton {
background-color: #dc3545;
color: white;
border: none;
padding: 4px 8px;
border-radius: 3px;
font-size: 11px;
}
QPushButton:hover {
background-color: #c82333;
}
""")
delete_button.clicked.connect(lambda checked, o=order: self.delete_order(o))
actions_layout.addWidget(delete_button)
actions_layout.addStretch()
self.orders_table.setCellWidget(row, 5, actions_widget)
def show_add_order_form(self):
"""Открытие формы добавления заказа"""
form = OrderForm(self, auth=self.auth, partners=self.partners)
form.order_saved.connect(self.load_orders)
form.exec()
def delete_order(self, order):
"""Удаление заказа"""
reply = QMessageBox.question(
self,
"Подтверждение удаления",
f"Вы уверены, что хотите удалить заказ #{order.get('sale_id')}?",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
QMessageBox.StandardButton.No
)
if reply == QMessageBox.StandardButton.Yes:
try:
response = requests.delete(
f"http://localhost:8000/api/v1/sales/{order['sale_id']}",
auth=self.auth,
timeout=10
)
if response.status_code == 200:
self.load_orders()
elif response.status_code == 401:
QMessageBox.warning(self, "Ошибка авторизации", "Сессия истекла")
except Exception as e:
QMessageBox.warning(self, "Ошибка", f"Не удалось удалить заказ: {str(e)}")