1223
This commit is contained in:
222
stock_dialog.py
Normal file
222
stock_dialog.py
Normal file
@@ -0,0 +1,222 @@
|
||||
"""
|
||||
库存管理模块 - 处理原料入库和库存查询
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
|
||||
QPushButton, QTableWidget, QTableWidgetItem, QHeaderView,
|
||||
QMessageBox, QInputDialog
|
||||
)
|
||||
from database import get_db_connection
|
||||
|
||||
|
||||
class StockInDialog(QDialog):
|
||||
"""独立原料入库管理"""
|
||||
|
||||
def __init__(self, db_path):
|
||||
super().__init__()
|
||||
self.db_path = db_path
|
||||
self.setWindowTitle("原料入库记录")
|
||||
self.resize(900, 600)
|
||||
|
||||
self.setup_ui()
|
||||
self.load_models()
|
||||
|
||||
def setup_ui(self):
|
||||
"""设置用户界面"""
|
||||
layout = QVBoxLayout(self)
|
||||
|
||||
# 搜索过滤区域
|
||||
filter_layout = QHBoxLayout()
|
||||
filter_layout.addWidget(QLabel("搜索型号/名称:"))
|
||||
self.search_input = QLineEdit()
|
||||
self.search_input.textChanged.connect(self.load_models)
|
||||
filter_layout.addWidget(self.search_input)
|
||||
|
||||
refresh_btn = QPushButton("刷新")
|
||||
refresh_btn.clicked.connect(self.load_models)
|
||||
filter_layout.addWidget(refresh_btn)
|
||||
|
||||
layout.addLayout(filter_layout)
|
||||
|
||||
# 数据表格
|
||||
headers = ["型号/名称", "颜色", "供应商", "单位", "当前剩余库存", "操作"]
|
||||
self.table = QTableWidget()
|
||||
self.table.setColumnCount(len(headers))
|
||||
self.table.setHorizontalHeaderLabels(headers)
|
||||
self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||
layout.addWidget(self.table)
|
||||
|
||||
def get_conn(self):
|
||||
"""获取数据库连接"""
|
||||
return get_db_connection(self.db_path)
|
||||
|
||||
def load_models(self):
|
||||
"""加载面料型号列表"""
|
||||
keyword = self.search_input.text().strip()
|
||||
try:
|
||||
with self.get_conn() as conn:
|
||||
# 查询面料基础信息
|
||||
query = "SELECT model, color, supplier, unit FROM fabrics"
|
||||
params = []
|
||||
if keyword:
|
||||
query += " WHERE model LIKE ? OR color LIKE ?"
|
||||
params = ["%" + keyword + "%", "%" + keyword + "%"]
|
||||
query += " ORDER BY timestamp DESC"
|
||||
cursor = conn.execute(query, params)
|
||||
rows = cursor.fetchall()
|
||||
|
||||
# 计算库存数量
|
||||
model_stock = {}
|
||||
|
||||
# 入库数量
|
||||
cursor_in = conn.execute("SELECT model, COALESCE(SUM(quantity), 0) FROM fabric_stock_in GROUP BY model")
|
||||
for model, quantity in cursor_in.fetchall():
|
||||
model_stock[model] = quantity or 0
|
||||
|
||||
# 消耗数量
|
||||
cursor_out = conn.execute("SELECT model, COALESCE(SUM(consume_quantity), 0) FROM fabric_consumption GROUP BY model")
|
||||
for model, quantity in cursor_out.fetchall():
|
||||
model_stock[model] = model_stock.get(model, 0) - (quantity or 0)
|
||||
|
||||
# 填充表格
|
||||
self.table.setRowCount(len(rows))
|
||||
for i, (model, color, supplier, unit) in enumerate(rows):
|
||||
self.table.setItem(i, 0, QTableWidgetItem(model or ""))
|
||||
self.table.setItem(i, 1, QTableWidgetItem(color or ""))
|
||||
self.table.setItem(i, 2, QTableWidgetItem(supplier or ""))
|
||||
self.table.setItem(i, 3, QTableWidgetItem(unit or "米"))
|
||||
|
||||
remaining = model_stock.get(model, 0)
|
||||
self.table.setItem(i, 4, QTableWidgetItem("{:.3f}".format(remaining)))
|
||||
|
||||
# 入库按钮
|
||||
btn = QPushButton("入库")
|
||||
btn.clicked.connect(lambda _, m=model, u=unit or "米": self.do_stock_in(m, u))
|
||||
self.table.setCellWidget(i, 5, btn)
|
||||
|
||||
except Exception as e:
|
||||
QMessageBox.critical(self, "错误", f"加载数据失败: {str(e)}")
|
||||
|
||||
def do_stock_in(self, model, unit):
|
||||
"""执行入库操作"""
|
||||
# 输入入库数量
|
||||
quantity, ok1 = QInputDialog.getDouble(
|
||||
self, "入库数量", f"【{model}】入库数量(单位:{unit}):",
|
||||
0, 0, 1000000, 3
|
||||
)
|
||||
if not ok1 or quantity <= 0:
|
||||
return
|
||||
|
||||
# 输入备注信息
|
||||
note, ok2 = QInputDialog.getText(
|
||||
self, "入库备注", "备注(供应商/批次/发票号等,可选):"
|
||||
)
|
||||
if not ok2:
|
||||
note = ""
|
||||
|
||||
try:
|
||||
with self.get_conn() as conn:
|
||||
# 插入入库记录
|
||||
conn.execute('''
|
||||
INSERT INTO fabric_stock_in (model, quantity, unit, purchase_date, note)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', (model, quantity, unit, datetime.now().strftime('%Y-%m-%d'), note))
|
||||
conn.commit()
|
||||
|
||||
QMessageBox.information(self, "成功", f"已入库 {model}:{quantity} {unit}")
|
||||
self.load_models()
|
||||
|
||||
except Exception as e:
|
||||
QMessageBox.critical(self, "错误", f"入库失败: {str(e)}")
|
||||
|
||||
|
||||
class StockQueryDialog(QDialog):
|
||||
"""库存查询对话框"""
|
||||
|
||||
def __init__(self, db_path):
|
||||
super().__init__()
|
||||
self.db_path = db_path
|
||||
self.setWindowTitle("库存查询")
|
||||
self.resize(1000, 700)
|
||||
|
||||
self.setup_ui()
|
||||
self.load_stock_data()
|
||||
|
||||
def setup_ui(self):
|
||||
"""设置用户界面"""
|
||||
layout = QVBoxLayout(self)
|
||||
|
||||
# 搜索区域
|
||||
search_layout = QHBoxLayout()
|
||||
search_layout.addWidget(QLabel("搜索:"))
|
||||
self.search_input = QLineEdit()
|
||||
self.search_input.textChanged.connect(self.load_stock_data)
|
||||
search_layout.addWidget(self.search_input)
|
||||
|
||||
refresh_btn = QPushButton("刷新")
|
||||
refresh_btn.clicked.connect(self.load_stock_data)
|
||||
search_layout.addWidget(refresh_btn)
|
||||
|
||||
layout.addLayout(search_layout)
|
||||
|
||||
# 库存表格
|
||||
headers = ["类目", "型号", "颜色", "供应商", "单位", "入库总量", "消耗总量", "剩余库存"]
|
||||
self.stock_table = QTableWidget()
|
||||
self.stock_table.setColumnCount(len(headers))
|
||||
self.stock_table.setHorizontalHeaderLabels(headers)
|
||||
self.stock_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||
layout.addWidget(self.stock_table)
|
||||
|
||||
def get_conn(self):
|
||||
"""获取数据库连接"""
|
||||
return get_db_connection(self.db_path)
|
||||
|
||||
def load_stock_data(self):
|
||||
"""加载库存数据"""
|
||||
keyword = self.search_input.text().strip()
|
||||
try:
|
||||
with self.get_conn() as conn:
|
||||
# 查询库存汇总数据
|
||||
query = """
|
||||
SELECT
|
||||
f.category,
|
||||
f.model,
|
||||
f.color,
|
||||
f.supplier,
|
||||
f.unit,
|
||||
COALESCE(SUM(si.quantity), 0) as total_in,
|
||||
COALESCE(SUM(fc.consume_quantity), 0) as total_out,
|
||||
COALESCE(SUM(si.quantity), 0) - COALESCE(SUM(fc.consume_quantity), 0) as remaining
|
||||
FROM fabrics f
|
||||
LEFT JOIN fabric_stock_in si ON f.model = si.model
|
||||
LEFT JOIN fabric_consumption fc ON f.model = fc.model
|
||||
"""
|
||||
|
||||
params = []
|
||||
if keyword:
|
||||
query += " WHERE f.model LIKE ? OR f.category LIKE ? OR f.color LIKE ?"
|
||||
params = [f"%{keyword}%", f"%{keyword}%", f"%{keyword}%"]
|
||||
|
||||
query += " GROUP BY f.model ORDER BY f.category, f.model"
|
||||
|
||||
cursor = conn.execute(query, params)
|
||||
rows = cursor.fetchall()
|
||||
|
||||
# 填充表格
|
||||
self.stock_table.setRowCount(len(rows))
|
||||
for i, row in enumerate(rows):
|
||||
category, model, color, supplier, unit, total_in, total_out, remaining = row
|
||||
|
||||
self.stock_table.setItem(i, 0, QTableWidgetItem(category or ""))
|
||||
self.stock_table.setItem(i, 1, QTableWidgetItem(model or ""))
|
||||
self.stock_table.setItem(i, 2, QTableWidgetItem(color or ""))
|
||||
self.stock_table.setItem(i, 3, QTableWidgetItem(supplier or ""))
|
||||
self.stock_table.setItem(i, 4, QTableWidgetItem(unit or "米"))
|
||||
self.stock_table.setItem(i, 5, QTableWidgetItem(f"{total_in:.3f}"))
|
||||
self.stock_table.setItem(i, 6, QTableWidgetItem(f"{total_out:.3f}"))
|
||||
self.stock_table.setItem(i, 7, QTableWidgetItem(f"{remaining:.3f}"))
|
||||
|
||||
except Exception as e:
|
||||
QMessageBox.critical(self, "错误", f"加载库存数据失败: {str(e)}")
|
||||
Reference in New Issue
Block a user