120 lines
3.3 KiB
Python
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)
|
|
)
|