Преглед изворни кода

feat(pl): wire stockRole into plan list, export, and facets

Co-authored-by: Cursor <cursoragent@cursor.com>
wuzilong пре 3 недеља
родитељ
комит
c4ee338c3a
1 измењених фајлова са 41 додато и 3 уклоњено
  1. 41 3
      backend/app/api/pl/plan.py

+ 41 - 3
backend/app/api/pl/plan.py

@@ -75,6 +75,7 @@ from app.schemas.pl.plan import (
 )
 from app.services.pl.plan_column_facet_context import strip_plan_facet_self_params
 from app.services.pl_plan_contract_gap import (
+    apply_contract_gap_keyword_filter,
     apply_contract_gap_type_filter,
     list_plan_contract_gaps,
     plan_has_contract_gap_exists,
@@ -132,6 +133,7 @@ from app.services.pl_plan_stop_service import (
 )
 from app.services.pl_customer_stop_pref_service import safe_upsert_prefs_from_plan_stops
 from app.services.pl.plan_list_filters import (
+    apply_stock_role_filter,
     build_plan_column_filters,
     parse_single_stop_kind,
     parse_stop_customer_keywords,
@@ -532,13 +534,18 @@ def _build_plan_facet_base_query(
         PlPlan.tenant_no == tenant_no,
         PlPlan.del_flag == 0,
     )
+    contract_gap_only = _truthy_param(
+        _param_get(params, "contractGapOnly", "contract_gap_only")
+    )
 
     q_kw = (_param_get(params, "q") or "")
     if isinstance(q_kw, str):
         q_kw = q_kw.strip()
     else:
         q_kw = str(q_kw).strip() if q_kw else ""
-    if q_kw:
+    if contract_gap_only:
+        query = apply_contract_gap_keyword_filter(query, tenant_no, q_kw)
+    elif q_kw:
         q_lower = q_kw.lower()
         query = query.filter(
             or_(
@@ -562,7 +569,7 @@ def _build_plan_facet_base_query(
     if _truthy_param(has_hazard):
         query = query.filter(plan_has_hazard_product_exists(tenant_no))
 
-    if _truthy_param(_param_get(params, "contractGapOnly", "contract_gap_only")):
+    if contract_gap_only:
         query = query.filter(
             PlPlan.follow_status != "cancelled",
             plan_has_contract_gap_exists(tenant_no),
@@ -573,7 +580,11 @@ def _build_plan_facet_base_query(
         query = apply_contract_gap_type_filter(query, tenant_no, str(gap_type))
 
     customer_keyword = _param_get(params, "customerKeyword", "customer_keyword")
-    if customer_keyword and str(customer_keyword).strip():
+    if contract_gap_only:
+        query = apply_contract_gap_keyword_filter(
+            query, tenant_no, str(customer_keyword or ""), include_plan_no=False
+        )
+    elif customer_keyword and str(customer_keyword).strip():
         kw = str(customer_keyword).strip()
         kw_lower = kw.lower()
         query = query.filter(
@@ -587,6 +598,14 @@ def _build_plan_facet_base_query(
     if column_filters:
         query = query.filter(*column_filters)
 
+    stock_role = _param_get(params, "stockRole", "stock_role")
+    try:
+        query = apply_stock_role_filter(
+            query, stock_role=stock_role, tenant_no=tenant_no
+        )
+    except ValueError as exc:
+        raise HTTPException(status_code=400, detail=str(exc)) from exc
+
     query = apply_pl_scope(query, PlPlan, user, db, tenant_no)
     return query
 
@@ -795,6 +814,11 @@ def list_plans(
         alias="includeArrangeCopyFlags",
         description="1=计算复制给司机/现场/磅单标志(运输计划列表需要;默认关闭)",
     ),
+    stock_role: Optional[str] = Query(
+        default=None,
+        alias="stockRole",
+        description="inbound=送货段山峡/云栋;outbound=装货段山峡/云栋",
+    ),
     page: int = Query(default=1, ge=1),
     page_size: int = Query(default=20, ge=1, le=500, alias="pageSize"),
     db: Session = Depends(get_db),
@@ -858,6 +882,13 @@ def list_plans(
     if column_filters:
         query = query.filter(*column_filters)
 
+    try:
+        query = apply_stock_role_filter(
+            query, stock_role=stock_role, tenant_no=tenant_no
+        )
+    except ValueError as exc:
+        raise HTTPException(status_code=400, detail=str(exc)) from exc
+
     query = apply_pl_scope(query, PlPlan, user, db, tenant_no)
 
     # 统计总数
@@ -1167,6 +1198,7 @@ class PlanExportBody(BaseModel):
     has_hazard_product: Optional[int] = Field(default=None, alias="hasHazardProduct")
     cert_upload_status: Optional[str] = Field(default=None, alias="certUploadStatus")
     hazard_cert_ready: Optional[int] = Field(default=None, alias="hazardCertReady")
+    stock_role: Optional[str] = Field(default=None, alias="stockRole")
     ids: Optional[List[str]] = None
     columns: Optional[List[str]] = None
     export_format: Optional[str] = Field(
@@ -1214,6 +1246,12 @@ def export_plans(
         )
         if column_filters:
             query = query.filter(*column_filters)
+        try:
+            query = apply_stock_role_filter(
+                query, stock_role=body.stock_role, tenant_no=tenant_no
+            )
+        except ValueError as exc:
+            raise HTTPException(status_code=400, detail=str(exc)) from exc
         if body.ids:
             query = query.filter(PlPlan.id.in_(body.ids))
         query = apply_pl_scope(query, PlPlan, user, db, tenant_no)