Files
shanxia2.0/backend/app/services/crm_supplier_hazard.py
T
2026-07-26 21:06:09 +08:00

120 lines
3.3 KiB
Python

"""CRM 供应商危化品经营能力判定"""
from __future__ import annotations
from typing import Any, Dict, Iterable, List, Optional, Tuple
from sqlalchemy.orm import Session
from app.crud.crm.product import get_product
from app.crud.crm.supplier_info import get_supplier_info
def product_allowed(
is_toxic,
is_explosive,
*,
allow_toxic,
allow_explosive,
) -> bool:
toxic = int(is_toxic or 0)
explosive = int(is_explosive or 0)
allow_t = int(allow_toxic or 0)
allow_e = int(allow_explosive or 0)
if not toxic and not explosive:
return True
if toxic and not explosive:
return bool(allow_t)
if explosive and not toxic:
return bool(allow_e)
return bool(allow_t) and bool(allow_e)
def get_supplier_hazard_flags(
db: Session,
supplier_id: Optional[str],
*,
tenant_no: str,
) -> Tuple[int, int]:
if not supplier_id:
return (0, 0)
row = get_supplier_info(db, supplier_id, tenant_no=tenant_no)
if not row:
return (0, 0)
return (
int(getattr(row, "allow_toxic", 0) or 0),
int(getattr(row, "allow_explosive", 0) or 0),
)
def enrich_products_with_hazard_flags(
db: Session,
items: List[Dict[str, Any]],
) -> None:
"""批量回填明细行 isToxic/isExplosive(来自产品主数据,供前端切换主体剔除)。"""
from app.models.crm_models import CrmProduct
pids = []
for item in items:
pid = item.get("productId") or item.get("product_id")
if pid:
pids.append(str(pid))
if not pids:
for item in items:
item.setdefault("isToxic", 0)
item.setdefault("isExplosive", 0)
return
rows = (
db.query(CrmProduct.id, CrmProduct.is_toxic, CrmProduct.is_explosive)
.filter(CrmProduct.id.in_(pids), CrmProduct.del_flag == 0)
.all()
)
flag_map = {
str(r.id): (int(r.is_toxic or 0), int(r.is_explosive or 0)) for r in rows
}
for item in items:
pid = item.get("productId") or item.get("product_id")
toxic, explosive = flag_map.get(str(pid) if pid else "", (0, 0))
item["isToxic"] = toxic
item["isExplosive"] = explosive
def assert_products_allowed_for_supplier(
db: Session,
*,
tenant_no: str,
supplier_id: Optional[str],
products: Iterable[Any],
) -> None:
allow_toxic, allow_explosive = get_supplier_hazard_flags(
db, supplier_id, tenant_no=tenant_no
)
blocked_names: List[str] = []
for item in products:
if not isinstance(item, dict):
continue
pid = item.get("productId") or item.get("product_id")
if not pid:
continue
prod = get_product(db, str(pid))
if not prod:
continue
is_toxic = int(getattr(prod, "is_toxic", 0) or 0)
is_explosive = int(getattr(prod, "is_explosive", 0) or 0)
if not product_allowed(
is_toxic,
is_explosive,
allow_toxic=allow_toxic,
allow_explosive=allow_explosive,
):
name = getattr(prod, "product_name", None) or str(pid)
blocked_names.append(str(name))
if blocked_names:
raise ValueError(
"当前主体不具备以下产品的危化品经营能力,请移除后重试:"
+ "、".join(blocked_names)
)