Files
shanxia2.0/backend/app/services/db/product_helpers.py
T
2026-08-06 09:58:20 +08:00

77 lines
2.3 KiB
Python

"""地磅模块 — CRM 产品解析与快照写入。"""
from __future__ import annotations
from dataclasses import dataclass
from fastapi import HTTPException, status
from sqlalchemy.orm import Session
from app.crud.crm.product import get_product
@dataclass(frozen=True)
class ProductSnapshot:
product_id: str
product_name: str
specification: str | None
def resolve_crm_product(
db: Session,
tenant_no: str,
product_id: str,
*,
require_on_shelf: bool = True,
) -> ProductSnapshot:
"""校验 CRM 产品并返回名称/规格快照。新建单据 product_id 必填。
require_on_shelf=False 用于运输计划联动地磅等历史单据场景:
合同/计划中的产品可能已下架,但仍允许按主数据快照继续业务。
"""
pid = (product_id or "").strip()
if not pid:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="请选择 CRM 产品",
)
row = get_product(db, pid)
if row is None or row.tenant_no != tenant_no:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="产品不存在或不可用",
)
if require_on_shelf and row.status != "on":
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="产品已下架,请重新选择",
)
name = (row.product_name or "").strip()
if not name:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="产品名称无效",
)
model = (row.model or "").strip() or None
return ProductSnapshot(product_id=row.id, product_name=name, specification=model)
def apply_product_snapshot_to_plan(plan, snapshot: ProductSnapshot) -> None:
plan.product_id = snapshot.product_id
plan.product = snapshot.product_name
plan.specification = snapshot.specification
def apply_product_snapshot_to_inventory(row, snapshot: ProductSnapshot) -> None:
row.product_id = snapshot.product_id
row.product = snapshot.product_name
row.specification = snapshot.specification
def apply_product_snapshot_to_weighing(row, snapshot: ProductSnapshot) -> None:
row.product_id = snapshot.product_id
row.cargo_name = snapshot.product_name
row.specification = snapshot.specification