diff --git a/inventory-backend/app/services/inbound/product_service.py b/inventory-backend/app/services/inbound/product_service.py index 0d73767..a724542 100644 --- a/inventory-backend/app/services/inbound/product_service.py +++ b/inventory-backend/app/services/inbound/product_service.py @@ -410,7 +410,7 @@ class ProductInboundService: sql = text(""" SELECT child_id, dosage FROM bom_table - WHERE bom_no = :bom_no AND version = :version AND is_enabled = true + WHERE bom_no = :bom_no AND version = :version """) bom_lines = db.session.execute(sql, {'bom_no': bom_no, 'version': bom_version}).fetchall() diff --git a/inventory-backend/app/services/inbound/semi_service.py b/inventory-backend/app/services/inbound/semi_service.py index 89a83e8..e4462c5 100644 --- a/inventory-backend/app/services/inbound/semi_service.py +++ b/inventory-backend/app/services/inbound/semi_service.py @@ -458,45 +458,47 @@ class SemiInboundService: @staticmethod def calculate_bom_cost(bom_no, bom_version): """ - 【防崩修正版】查询物理字段:采购的税前价 / 半成品和成品的 manual_cost(映射后的单件成本) + 根据 BOM 编号和版本计算原材料总成本 + 遍历 BOM 子件,使用原生 SQL 查物理表 bom_table,取每个子件在采购、半成品、成品三个表中的最高单价,乘以用量后累加 """ - from app.models.bom import bom_table # 假设这可能是 SQLAlchemy 表对象或类 from app.models.inbound.buy import StockBuy from app.models.inbound.semi import StockSemi from app.models.inbound.product import StockProduct - from sqlalchemy import func - + from sqlalchemy import func, text try: - # 兼容你的表名 - bom_lines = db.session.execute( - text("SELECT child_id, dosage FROM bom_table WHERE bom_no = :bom_no AND version = :version"), - {'bom_no': bom_no, 'version': bom_version} - ).fetchall() - + # 使用原生 SQL 精准查询 bom_table,避免模型映射错误 + sql = text(""" + SELECT child_id, dosage + FROM bom_table + WHERE bom_no = :bom_no AND version = :version + """) + bom_lines = db.session.execute(sql, {'bom_no': bom_no, 'version': bom_version}).fetchall() + total_cost = 0.0 for line in bom_lines: - component_base_id = line[0] - usage_qty = float(line[1] or 1.0) - - # 查采购表最高价 + component_base_id = line[0] # child_id + usage_qty = float(line[1] or 1.0) # dosage + + # 1. 查采购表最高价 (不含税) buy_price = db.session.query(func.max(StockBuy.pre_tax_unit_price)).filter( StockBuy.base_id == component_base_id ).scalar() or 0.0 - - # 查半成品表最高价 (直接查 manual_cost,因为它存的就是单件成本) + + # 2. 查半成品表最高价 (单件成本映射存在 manual_cost 里了) semi_price = db.session.query(func.max(StockSemi.manual_cost)).filter( StockSemi.base_id == component_base_id ).scalar() or 0.0 - - # 查成品表最高价 + + # 3. 查成品表最高价 (同样存储在 manual_cost 字段里) product_price = db.session.query(func.max(StockProduct.manual_cost)).filter( StockProduct.base_id == component_base_id ).scalar() or 0.0 - - max_price = max(buy_price, semi_price, product_price) + + # 4. 取三个表中的最大值,乘以用量 (dosage) + max_price = max(float(buy_price), float(semi_price), float(product_price)) total_cost += max_price * usage_qty - + return round(total_cost, 2) except Exception as e: traceback.print_exc() - raise e \ No newline at end of file + raise e