# app/models/inbound/product.py from app.extensions import db import json class StockProduct(db.Model): """ 成品入库库存表 对应数据库表: stock_product """ __tablename__ = 'stock_product' id = db.Column(db.Integer, primary_key=True) base_id = db.Column(db.Integer, db.ForeignKey('material_base.id'), nullable=False) # 身份标识 sku = db.Column(db.String(100)) production_date = db.Column(db.Date) barcode = db.Column(db.String(100)) serial_number = db.Column(db.String(100)) # 数量 in_quantity = db.Column(db.Numeric(19, 4), default=0) stock_quantity = db.Column(db.Numeric(19, 4), default=0) available_quantity = db.Column(db.Numeric(19, 4), default=0) # 状态与位置 status = db.Column(db.String(50)) warehouse_location = db.Column(db.String(100)) # 生产与成本 bom_code = db.Column('bom_id', db.String(100)) bom_version = db.Column(db.String(50)) work_order_code = db.Column('work_order_id', db.String(100)) raw_material_cost = db.Column(db.Numeric(19, 4), default=0) manual_cost = db.Column(db.Numeric(19, 4), default=0) production_manager = db.Column('producer_name', db.String(100)) production_time_range = db.Column(db.String(255)) # 质量与检测 (均为 JSON 存储) quality_status = db.Column(db.String(50)) quality_report_link = db.Column(db.Text) # 质量报告 inspection_report_link = db.Column(db.Text) # 检测报告(旧字段升级为JSON) # [新增] 成品实拍图 (JSON 存储) product_photo = db.Column(db.Text) detail_link = db.Column(db.Text) remark = db.Column(db.Text) # 销售相关 sale_price = db.Column(db.Numeric(19, 4), default=0) order_id = db.Column(db.String(100)) # 全局打印流水号 global_print_id = db.Column(db.Integer) # 关系定义 material = db.relationship('MaterialBase', back_populates='stock_products') def to_dict(self): raw_val = float(self.raw_material_cost or 0) man_val = float(self.manual_cost or 0) unit_total = raw_val + man_val # 辅助解析函数 def parse_img_list(json_str): if not json_str: return [] try: if not json_str.startswith('['): return [json_str] # 兼容旧数据单链接 return json.loads(json_str) except: return [] return { 'id': self.id, 'base_id': self.base_id, 'material_name': self.material.name if self.material else '', 'spec_model': self.material.spec_model if self.material else '', 'category': self.material.category if self.material else '', 'unit': self.material.unit if self.material else '', 'material_type': self.material.material_type if self.material else '', 'sku': self.sku, 'inbound_date': self.production_date.strftime('%Y-%m-%d') if self.production_date else '', 'barcode': self.barcode, 'serial_number': self.serial_number, 'warehouse_loc': self.warehouse_location, 'status': self.status, 'in_quantity': float(self.in_quantity or 0), 'qty_inbound': float(self.in_quantity or 0), 'stock_quantity': float(self.stock_quantity or 0), 'qty_stock': float(self.stock_quantity or 0), 'available_quantity': float(self.available_quantity or 0), 'qty_available': float(self.available_quantity or 0), 'bom_code': self.bom_code, 'bom_version': self.bom_version, 'work_order_code': self.work_order_code, 'raw_material_cost': raw_val, 'manual_cost': man_val, 'unit_total_cost': unit_total, 'production_manager': self.production_manager, 'production_time_range': self.production_time_range, 'production_start_time': self.production_time_range.split(' ~ ')[ 0] if self.production_time_range and ' ~ ' in self.production_time_range else '', 'production_end_time': self.production_time_range.split(' ~ ')[ 1] if self.production_time_range and ' ~ ' in self.production_time_range else '', 'quality_status': self.quality_status, # [核心修改] 三个图片/链接字段全部解析为数组 'product_photo': parse_img_list(self.product_photo), 'quality_report_link': parse_img_list(self.quality_report_link), 'inspection_report_link': parse_img_list(self.inspection_report_link), 'detail_link': self.detail_link, 'remark': self.remark, 'sale_price': float(self.sale_price or 0), 'order_id': self.order_id, 'global_print_id': self.global_print_id, 'global_print_id_str': f"{self.global_print_id:010d}" if self.global_print_id else "" }