This commit is contained in:
2026-04-09 23:15:56 +08:00
parent dccd9bd81d
commit cd9b244bc8
7 changed files with 153 additions and 28 deletions
+3 -7
View File
@@ -36,7 +36,7 @@ async def _calculate_material_cost_map(db_session: AsyncSession, product_ids: Li
ProductMaterial.finished_product_id,
func.coalesce(
func.sum(
Product.cost_price * ProductMaterial.quantity * (1 + ProductMaterial.loss_rate)
Product.cost_price * ProductMaterial.quantity
),
0
)
@@ -186,7 +186,7 @@ async def get_product_bom(
items: List[ProductMaterialItemResponse] = []
total_material_cost = 0.0
for bom, material in bom_result.all():
line_cost = float(material.cost_price or 0) * float(bom.quantity) * (1 + float(bom.loss_rate or 0))
line_cost = float(material.cost_price or 0) * float(bom.quantity)
total_material_cost += line_cost
items.append(
ProductMaterialItemResponse(
@@ -194,7 +194,6 @@ async def get_product_bom(
material_sku=material.sku,
material_name=material.name,
quantity=round(float(bom.quantity), 4),
loss_rate=round(float(bom.loss_rate or 0), 4),
unit_cost=round(float(material.cost_price or 0), 4),
line_cost=round(float(line_cost), 4),
)
@@ -246,15 +245,12 @@ async def replace_product_bom(
for item in payload.items:
if item.quantity <= 0:
raise HTTPException(status_code=400, detail="物料数量必须大于0")
if item.loss_rate < 0:
raise HTTPException(status_code=400, detail="损耗率不能为负数")
raise HTTPException(status_code=400, detail="物料数量必须大于 0")
db_session.add(
ProductMaterial(
finished_product_id=product_id,
material_product_id=item.material_id,
quantity=item.quantity,
loss_rate=item.loss_rate,
)
)
+22 -9
View File
@@ -38,6 +38,10 @@ router = APIRouter(prefix="/purchase-orders", tags=["采购订单"])
def _build_purchase_order_response(order: PurchaseOrder, supplier_name: str) -> PurchaseOrderResponse:
# 检查字段是否存在,避免数据库中没有这些字段时的错误
received_date = getattr(order, 'received_date', None)
paid_date = getattr(order, 'paid_date', None)
return PurchaseOrderResponse(
id=order.id,
order_no=order.order_no,
@@ -49,8 +53,8 @@ def _build_purchase_order_response(order: PurchaseOrder, supplier_name: str) ->
paid_amount=order.paid_amount,
remark=order.remark,
created_at=order.created_at,
received_date=order.received_date,
paid_date=order.paid_date
received_date=received_date,
paid_date=paid_date
)
@@ -81,6 +85,10 @@ async def _build_purchase_order_detail(
.order_by(PurchaseOrderItem.id.asc())
)
item_rows = item_result.all()
# 检查字段是否存在,避免数据库中没有这些字段时的错误
received_date = getattr(order, 'received_date', None)
paid_date = getattr(order, 'paid_date', None)
return PurchaseOrderDetailResponse(
id=order.id,
order_no=order.order_no,
@@ -93,8 +101,8 @@ async def _build_purchase_order_detail(
paid_amount=order.paid_amount,
remark=order.remark,
created_at=order.created_at,
received_date=order.received_date,
paid_date=order.paid_date,
received_date=received_date,
paid_date=paid_date,
items=[
PurchaseOrderItemResponse(
id=item.id,
@@ -218,8 +226,10 @@ async def create_purchase_order(
await db_session.commit()
await db_session.refresh(order)
supplier = await db_session.execute(select(Supplier).where(Supplier.id == order.supplier_id))
supplier = supplier.scalar_one()
supplier_result = await db_session.execute(select(Supplier).where(Supplier.id == order.supplier_id))
supplier = supplier_result.scalar_one_or_none()
if not supplier:
raise HTTPException(status_code=404, detail="供应商不存在")
return _build_purchase_order_response(order, supplier.name)
@@ -313,9 +323,10 @@ async def update_purchase_order_status(
# 更新状态和对应时间
order.status = new_status
if new_status == "received":
# 检查字段是否存在,避免数据库中没有这些字段时的错误
if hasattr(order, 'received_date') and new_status == "received":
order.received_date = func.now()
elif new_status == "paid":
elif hasattr(order, 'paid_date') and new_status == "paid":
order.paid_date = func.now()
await db_session.commit()
@@ -407,7 +418,9 @@ async def receive_purchase_order(
any_received = any((item.received_quantity or 0) > 0 for item in item_map.values())
if all_received:
order.status = "received"
order.received_date = func.now()
# 检查字段是否存在,避免数据库中没有这些字段时的错误
if hasattr(order, 'received_date'):
order.received_date = func.now()
elif any_received:
order.status = "partial_received"
@@ -39,7 +39,6 @@ class ProductResponse(BaseModel):
class ProductMaterialItemUpdate(BaseModel):
material_id: int
quantity: float
loss_rate: float = 0
class ProductBOMUpdate(BaseModel):
@@ -51,7 +50,6 @@ class ProductMaterialItemResponse(BaseModel):
material_sku: str
material_name: str
quantity: float
loss_rate: float
unit_cost: float
line_cost: float