diff --git a/inventory-backend/app/api/v1/inbound/stock.py b/inventory-backend/app/api/v1/inbound/stock.py index e2642e3..7486e9e 100644 --- a/inventory-backend/app/api/v1/inbound/stock.py +++ b/inventory-backend/app/api/v1/inbound/stock.py @@ -976,19 +976,21 @@ def export_stocktake(): if expected_qty > 0: # ★ 直接使用预加载的 base 关系,避免额外查询 material = stock.base + # ★ 安全提取批号/序列号:使用 getattr 降级链 + batch_sn = getattr(stock, 'batch_number', None) or getattr(stock, 'sn', None) or getattr(stock, 'serial_number', None) or '-' mat_info = { 'name': material.name if material else '-', 'sku': getattr(stock, 'sku', None) or '-', 'spec': getattr(material, 'spec_model', None) if material else '-', 'location': getattr(stock, 'warehouse_location', None) or '-', - 'batch_no': getattr(stock, 'batch_number', None) or '-' # ★ 批号字段 + 'batch_no': batch_sn } unscanned_items.append({ 'name': mat_info['name'], 'sku': mat_info['sku'], 'spec': mat_info['spec'], 'location': mat_info['location'], - 'batch_no': mat_info['batch_no'], # ★ 批号字段 + 'batch_no': mat_info['batch_no'], 'stock_qty': expected_qty, 'actual_qty': 0, 'diff_qty': -expected_qty, @@ -1007,19 +1009,21 @@ def export_stocktake(): if expected_qty > 0: # ★ 直接使用预加载的 base 关系,避免额外查询 material = stock.base + # ★ 安全提取批号/序列号:使用 getattr 降级链 + batch_sn = getattr(stock, 'batch_number', None) or getattr(stock, 'sn', None) or getattr(stock, 'serial_number', None) or '-' mat_info = { 'name': material.name if material else '-', 'sku': getattr(stock, 'sku', None) or '-', 'spec': getattr(material, 'spec_model', None) if material else '-', 'location': getattr(stock, 'warehouse_location', None) or '-', - 'batch_no': getattr(stock, 'batch_number', None) or '-' # ★ 批号字段 + 'batch_no': batch_sn } unscanned_items.append({ 'name': mat_info['name'], 'sku': mat_info['sku'], 'spec': mat_info['spec'], 'location': mat_info['location'], - 'batch_no': mat_info['batch_no'], # ★ 批号字段 + 'batch_no': mat_info['batch_no'], 'stock_qty': expected_qty, 'actual_qty': 0, 'diff_qty': -expected_qty, @@ -1040,19 +1044,21 @@ def export_stocktake(): if expected_qty > 0: # ★ 直接使用预加载的 base 关系,避免额外查询 material = stock.base + # ★ 安全提取批号/序列号:使用 getattr 降级链 (成品可能无此字段) + batch_sn = getattr(stock, 'batch_number', None) or getattr(stock, 'sn', None) or getattr(stock, 'serial_number', None) or '-' mat_info = { 'name': material.name if material else '-', 'sku': getattr(stock, 'sku', None) or '-', 'spec': getattr(material, 'spec_model', None) if material else '-', 'location': getattr(stock, 'warehouse_location', None) or '-', - 'batch_no': '-' # ★ 成品无批号字段 + 'batch_no': batch_sn } unscanned_items.append({ 'name': mat_info['name'], 'sku': mat_info['sku'], 'spec': mat_info['spec'], 'location': mat_info['location'], - 'batch_no': mat_info['batch_no'], # ★ 成品无批号字段 + 'batch_no': mat_info['batch_no'], 'stock_qty': expected_qty, 'actual_qty': 0, 'diff_qty': -expected_qty, @@ -1239,7 +1245,8 @@ def get_all_stocktake_items(): 'id': item.id, 'sku': item.sku or '', 'barcode': item.barcode or '', - 'batch_no': item.batch_number or '', # ★ 批号字段 + # ★ 安全提取批号/序列号:使用 getattr 降级 + 'batch_no': getattr(item, 'batch_number', None) or getattr(item, 'sn', None) or getattr(item, 'serial_number', None) or '', 'material_name': item.base.name if item.base else '', 'spec_model': item.base.spec_model if item.base else '', 'stock_qty': float(item.stock_quantity or 0), @@ -1264,7 +1271,8 @@ def get_all_stocktake_items(): 'id': item.id, 'sku': item.sku or '', 'barcode': item.barcode or '', - 'batch_no': item.batch_number or '', # ★ 批号字段 + # ★ 安全提取批号/序列号:使用 getattr 降级 + 'batch_no': getattr(item, 'batch_number', None) or getattr(item, 'sn', None) or getattr(item, 'serial_number', None) or '', 'material_name': item.base.name if item.base else '', 'spec_model': item.base.spec_model if item.base else '', 'stock_qty': float(item.stock_quantity or 0), @@ -1289,7 +1297,8 @@ def get_all_stocktake_items(): 'id': item.id, 'sku': item.sku or '', 'barcode': item.barcode or '', - 'batch_no': item.batch_number or '', # ★ 批号字段 (成品无此字段则为空) + # ★ 安全提取批号/序列号:使用 getattr 降级 (成品无此字段则为空) + 'batch_no': getattr(item, 'batch_number', None) or getattr(item, 'sn', None) or getattr(item, 'serial_number', None) or '', 'material_name': item.base.name if item.base else '', 'spec_model': item.base.spec_model if item.base else '', 'stock_qty': float(item.stock_quantity or 0),