After Graduate Update
This commit is contained in:
parent
b92a91ab37
commit
c6917dd85e
69 changed files with 7540 additions and 0 deletions
344
ressult/gui/orders_panel.py
Normal file
344
ressult/gui/orders_panel.py
Normal 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)}")
|
||||
Loading…
Add table
Add a link
Reference in a new issue