160 lines
6.8 KiB
Python
160 lines
6.8 KiB
Python
# gui/material_calculator.py
|
||
"""
|
||
Калькулятор материалов для производства
|
||
Соответствует модулю 4 ТЗ
|
||
"""
|
||
from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel,
|
||
QLineEdit, QPushButton, QMessageBox, QFormLayout,
|
||
QDoubleSpinBox, QSpinBox)
|
||
from PyQt6.QtCore import Qt
|
||
import requests
|
||
import math
|
||
|
||
class MaterialCalculatorWindow(QDialog):
|
||
def __init__(self, parent=None, auth=None):
|
||
super().__init__(parent)
|
||
self.auth = auth # Сохраняем auth, даже если не используется
|
||
self.setup_ui()
|
||
|
||
def setup_ui(self):
|
||
self.setWindowTitle("Калькулятор материалов для производства")
|
||
self.setModal(True)
|
||
self.resize(400, 300)
|
||
|
||
layout = QVBoxLayout()
|
||
|
||
# Заголовок
|
||
title = QLabel("Расчет количества материала")
|
||
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||
title.setStyleSheet("font-size: 16px; font-weight: bold; margin: 10px;")
|
||
layout.addWidget(title)
|
||
|
||
# Форма ввода параметров
|
||
form_layout = QFormLayout()
|
||
|
||
self.product_type_id = QSpinBox()
|
||
self.product_type_id.setRange(1, 100)
|
||
form_layout.addRow("ID типа продукции:", self.product_type_id)
|
||
|
||
self.material_type_id = QSpinBox()
|
||
self.material_type_id.setRange(1, 100)
|
||
form_layout.addRow("ID типа материала:", self.material_type_id)
|
||
|
||
self.quantity = QSpinBox()
|
||
self.quantity.setRange(1, 1000000)
|
||
form_layout.addRow("Количество продукции:", self.quantity)
|
||
|
||
self.param1 = QDoubleSpinBox()
|
||
self.param1.setRange(0.1, 1000.0)
|
||
self.param1.setDecimals(2)
|
||
form_layout.addRow("Параметр продукции 1:", self.param1)
|
||
|
||
self.param2 = QDoubleSpinBox()
|
||
self.param2.setRange(0.1, 1000.0)
|
||
self.param2.setDecimals(2)
|
||
form_layout.addRow("Параметр продукции 2:", self.param2)
|
||
|
||
self.product_coeff = QDoubleSpinBox()
|
||
self.product_coeff.setRange(0.1, 10.0)
|
||
self.product_coeff.setDecimals(3)
|
||
self.product_coeff.setValue(1.0)
|
||
form_layout.addRow("Коэффициент типа продукции:", self.product_coeff)
|
||
|
||
self.defect_percent = QDoubleSpinBox()
|
||
self.defect_percent.setRange(0.0, 50.0)
|
||
self.defect_percent.setDecimals(1)
|
||
self.defect_percent.setSuffix("%")
|
||
form_layout.addRow("Процент брака материала:", self.defect_percent)
|
||
|
||
layout.addLayout(form_layout)
|
||
|
||
# Результат
|
||
self.result_label = QLabel()
|
||
self.result_label.setStyleSheet("font-weight: bold; color: #007acc; margin: 10px;")
|
||
self.result_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||
layout.addWidget(self.result_label)
|
||
|
||
# Кнопки
|
||
buttons_layout = QHBoxLayout()
|
||
|
||
self.calculate_button = QPushButton("Рассчитать")
|
||
self.calculate_button.clicked.connect(self.calculate_material)
|
||
self.calculate_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.close_button = QPushButton("Закрыть")
|
||
self.close_button.clicked.connect(self.accept)
|
||
|
||
buttons_layout.addWidget(self.calculate_button)
|
||
buttons_layout.addStretch()
|
||
buttons_layout.addWidget(self.close_button)
|
||
|
||
layout.addLayout(buttons_layout)
|
||
|
||
self.setLayout(layout)
|
||
|
||
def calculate_material(self):
|
||
"""Расчет количества материала с обработкой ошибок"""
|
||
try:
|
||
# Проверяем валидность входных данных
|
||
if (self.param1.value() <= 0 or self.param2.value() <= 0 or
|
||
self.product_coeff.value() <= 0 or self.defect_percent.value() < 0):
|
||
self.result_label.setText("Ошибка: неверные параметры")
|
||
self.result_label.setStyleSheet("color: red; font-weight: bold;")
|
||
return
|
||
|
||
# Создаем данные для расчета
|
||
calculation_data = {
|
||
'product_type_id': self.product_type_id.value(),
|
||
'material_type_id': self.material_type_id.value(),
|
||
'quantity': self.quantity.value(),
|
||
'param1': self.param1.value(),
|
||
'param2': self.param2.value(),
|
||
'product_coeff': self.product_coeff.value(),
|
||
'defect_percent': self.defect_percent.value()
|
||
}
|
||
|
||
# Локальный расчет (без API)
|
||
material_quantity = self.calculate_locally(calculation_data)
|
||
|
||
if material_quantity >= 0:
|
||
self.result_label.setText(
|
||
f"Необходимое количество материала: {material_quantity} единиц"
|
||
)
|
||
self.result_label.setStyleSheet("color: #007acc; font-weight: bold;")
|
||
else:
|
||
self.result_label.setText("Ошибка: неверные параметры расчета")
|
||
self.result_label.setStyleSheet("color: red; font-weight: bold;")
|
||
|
||
except Exception as e:
|
||
self.result_label.setText(f"Ошибка расчета: {str(e)}")
|
||
self.result_label.setStyleSheet("color: red; font-weight: bold;")
|
||
|
||
def calculate_locally(self, data):
|
||
"""Локальный расчет материалов"""
|
||
try:
|
||
import math
|
||
|
||
# Расчет количества материала на одну единицу продукции
|
||
material_per_unit = data['param1'] * data['param2'] * data['product_coeff']
|
||
|
||
# Расчет общего количества материала с учетом брака
|
||
total_material = material_per_unit * data['quantity']
|
||
total_material_with_defect = total_material * (1 + data['defect_percent'] / 100)
|
||
|
||
# Округление до целого числа в большую сторону
|
||
return math.ceil(total_material_with_defect)
|
||
|
||
except:
|
||
return -1
|