Просмотр исходного кода

test(pl): expect dibang plate sync even after weighing

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 2 месяцев назад
Родитель
Сommit
cd64463c0a
1 измененных файлов с 181 добавлено и 1 удалено
  1. 181 1
      backend/tests/test_pl_dibang_upsert_on_arrange.py

+ 181 - 1
backend/tests/test_pl_dibang_upsert_on_arrange.py

@@ -5,7 +5,7 @@ from unittest.mock import MagicMock, patch
 
 import pytest
 
-from app.models.db_models import DbInboundOutbound, DbPurchasePlan
+from app.models.db_models import DbInboundOutbound, DbPurchasePlan, DbWeighingSlip
 from app.models.pl_models import (
     PlPlan,
     PlPlanDelivery,
@@ -278,3 +278,183 @@ def test_upsert_reuses_existing_inventory_id(
     assert results[0].db_inventory_id == "inv-1"
     assert results[0].batch_no == "CRKDH0000001"
     mock_create_inv.assert_not_called()
+
+
+@patch("app.services.pl_dibang_bridge_service._inventory_has_weighing_slip", return_value=True)
+@patch("app.services.pl_dibang_bridge_service.resolve_crm_product")
+def test_upsert_updates_inventory_and_weighing_plate_when_already_weighed(
+    mock_crm, _mock_weighing
+):
+    """已过磅:仍强制回写出入库与过磅单车牌;称重不动;出入库 id 不变。"""
+    mock_crm.return_value = MagicMock(
+        product_id="prod-1",
+        product_name="硫酸",
+        specification="98%",
+    )
+    plan = PlPlan(
+        id="plan-1",
+        plan_no="PO1",
+        plan_type="outbound",
+        plan_date=date(2026, 9, 1),
+        pickup_time=datetime(2026, 9, 1, 0, 0),
+        license_plate="皖HA7429",
+        tenant_no="t1",
+    )
+    transport = PlTransport(
+        id="tr-1", tenant_no="t1", license_plate="皖HA7429", del_flag=0
+    )
+    load = PlPlanLoad(
+        id="load-1",
+        plan_id="plan-1",
+        customer_name="山峡",
+        generate_dibang=1,
+        dibang_direction="outbound",
+        load_time=datetime(2026, 9, 1, 0, 0),
+        tenant_no="t1",
+        del_flag=0,
+    )
+    delivery = PlPlanDelivery(
+        id="del-1",
+        plan_id="plan-1",
+        customer_name="江峰",
+        seq=1,
+        generate_dibang=0,
+        tenant_no="t1",
+        del_flag=0,
+    )
+    stop_product = PlPlanLoadProduct(
+        id="lp-1",
+        load_id="load-1",
+        plan_product_id="pp-1",
+        product_id="prod-1",
+        product_name="硫酸",
+        model="98%",
+        unit="吨",
+        plan_qty=Decimal("22"),
+        tenant_no="t1",
+        del_flag=0,
+        order_num=1,
+    )
+    inventory = DbInboundOutbound(
+        id="2861",
+        tenant_no="t1",
+        date=date(2026, 9, 6),
+        partner_company="江峰",
+        business_type="出库",
+        product_id="prod-1",
+        product="硫酸",
+        specification="98%",
+        quantity=22.0,
+        batch_no="CRKDH0002488",
+        vehicle_no="皖H28926",
+        status="待出库",
+        purchase_plan_id="dbp-1",
+        plan_no="SX-1",
+        del_flag=0,
+    )
+    slip = DbWeighingSlip(
+        id="ws-1",
+        tenant_no="t1",
+        vehicle_no="皖H28926",
+        plan_no="SX-1",
+        cargo_name="硫酸",
+        specification="98%",
+        business_type="出库",
+        batch_no="CRKDH0002488",
+        supplier="",
+        consignee="江峰",
+        gross_weight=0.0,
+        tare_weight=18730.0,
+        net_weight=-18730.0,
+        inbound_outbound_id="2861",
+        purchase_plan_id="dbp-1",
+        is_voided=0,
+        del_flag=0,
+    )
+    link = PlTransportDbLink(
+        id="link-1",
+        tenant_no="t1",
+        plan_id="plan-1",
+        transport_id="tr-1",
+        plan_product_id="pp-1",
+        stop_type="load",
+        stop_id="load-1",
+        db_purchase_plan_id="dbp-1",
+        db_inventory_id="2861",
+        contributed_qty=Decimal("22"),
+        del_flag=0,
+    )
+    db = MagicMock()
+
+    def link_q(m):
+        filtered = MagicMock()
+        filtered.all.return_value = []
+        filtered.first.return_value = link
+        m.filter.return_value = filtered
+        return m
+
+    def load_q(m):
+        m.filter.return_value.first.return_value = load
+        return m
+
+    def delivery_q(m):
+        m.filter.return_value.first.return_value = delivery
+        m.filter.return_value.order_by.return_value.all.return_value = [delivery]
+        return m
+
+    def load_prod_q(m):
+        m.filter.return_value.order_by.return_value.all.return_value = [stop_product]
+        return m
+
+    def delivery_prod_q(m):
+        m.filter.return_value.order_by.return_value.all.return_value = []
+        return m
+
+    def inv_q(m):
+        m.filter.return_value.first.return_value = inventory
+        return m
+
+    def slip_q(m):
+        filtered = MagicMock()
+        filtered.all.return_value = [slip]
+        m.filter.return_value = filtered
+        return m
+
+    def db_plan_q(m):
+        filtered = MagicMock()
+        filtered.first.return_value = None
+        m.filter.return_value = filtered
+        return m
+
+    db.query.side_effect = _make_query_router(
+        {
+            PlTransportDbLink: link_q,
+            PlPlanLoad: load_q,
+            PlPlanDelivery: delivery_q,
+            PlPlanLoadProduct: load_prod_q,
+            PlPlanDeliveryProduct: delivery_prod_q,
+            DbInboundOutbound: inv_q,
+            DbWeighingSlip: slip_q,
+            DbPurchasePlan: db_plan_q,
+        }
+    )
+
+    results, warnings = upsert_stop_dibang_links(
+        db,
+        tenant_no="t1",
+        plan=plan,
+        transport=transport,
+        stop_options=[
+            StopDibangOption(stop_type="load", stop_id="load-1", generate_dibang=True),
+            StopDibangOption(stop_type="delivery", stop_id="del-1", generate_dibang=False),
+        ],
+        user_id="u1",
+        dept_id="d1",
+    )
+
+    assert results and results[0].db_inventory_id == "2861"
+    assert inventory.vehicle_no == "皖HA7429"
+    assert slip.vehicle_no == "皖HA7429"
+    assert slip.tare_weight == 18730.0
+    assert slip.net_weight == -18730.0
+    assert not any("未同步" in w for w in warnings)