"""运输计划多段:内部客户地磅默认值与数量平衡校验""" from decimal import Decimal from app.services.pl_internal_customer import INTERNAL_CUSTOMER_NAMES from app.services.pl_plan_stop_rules import ( normalize_stop_dibang_fields, resolve_stop_dibang_defaults, warn_qty_imbalance, ) def test_internal_shanxia_load_outbound(): name = "安庆市山峡化工有限公司" assert name in INTERNAL_CUSTOMER_NAMES assert resolve_stop_dibang_defaults(name, "load") == (True, "outbound") def test_internal_shanxia_delivery_inbound(): name = "安庆市山峡化工有限公司" assert resolve_stop_dibang_defaults(name, "delivery") == (True, "inbound") def test_internal_yundong_load_outbound(): name = "安徽云栋化工有限公司" assert resolve_stop_dibang_defaults(name, "load") == (True, "outbound") def test_internal_yundong_delivery_inbound(): name = "安徽云栋化工有限公司" assert resolve_stop_dibang_defaults(name, "delivery") == (True, "inbound") def test_external_customer_no_dibang(): assert resolve_stop_dibang_defaults("外部客户有限公司", "load") == (False, "none") assert resolve_stop_dibang_defaults("外部客户有限公司", "delivery") == (False, "none") def test_delivery_defaults_use_delivery_customer(): """送货段地磅默认以本段客户是否为内部客户为准。""" internal = "安庆市山峡化工有限公司" assert resolve_stop_dibang_defaults(internal, "delivery") == (True, "inbound") assert resolve_stop_dibang_defaults("外部客户有限公司", "delivery") == (False, "none") def test_normalize_stop_dibang_fields_repairs_none_direction(): gen, direction = normalize_stop_dibang_fields( "安庆市山峡化工有限公司", "delivery", 1, "none", ) assert gen == 1 assert direction == "inbound" def test_normalize_respects_explicit_uncheck_for_internal_customer(): """内部客户显式传 0(如可选车皖H21522 取消勾选)时须保留,不得用默认值强制回 1。""" gen, direction = normalize_stop_dibang_fields( "安庆市山峡化工有限公司", "load", 0, "none", ) assert gen == 0 assert direction == "none" def test_normalize_respects_explicit_uncheck_for_internal_delivery(): gen, direction = normalize_stop_dibang_fields( "安徽云栋化工有限公司", "delivery", 0, "inbound", ) assert gen == 0 assert direction == "none" def test_normalize_forces_off_for_external_even_when_checked(): gen, direction = normalize_stop_dibang_fields( "外部客户有限公司", "load", 1, "outbound", ) assert gen == 0 assert direction == "none" def test_normalize_keeps_explicit_check_for_internal(): gen, direction = normalize_stop_dibang_fields( "安庆市山峡化工有限公司", "load", 1, "outbound", ) assert gen == 1 assert direction == "outbound" def test_external_empty_name_no_dibang(): assert resolve_stop_dibang_defaults(None, "load") == (False, "none") assert resolve_stop_dibang_defaults(" ", "delivery") == (False, "none") def test_warn_qty_balanced_returns_empty(): plan = [{"quantity": Decimal("30")}] load = [{"plan_qty": Decimal("30")}] delivery = [{"plan_qty": Decimal("30")}] assert warn_qty_imbalance(plan, load, delivery) == [] def test_warn_qty_uses_plan_qty_on_plan_products(): plan = [{"plan_qty": Decimal("28")}] load = [{"plan_qty": Decimal("28")}] delivery = [{"plan_qty": Decimal("28")}] assert warn_qty_imbalance(plan, load, delivery) == [] def test_warn_qty_load_vs_delivery_imbalance(): plan = [{"quantity": Decimal("28")}] load = [{"plan_qty": Decimal("30")}] delivery = [{"plan_qty": Decimal("28")}] warnings = warn_qty_imbalance(plan, load, delivery) assert warnings == [ "装货合计(30)与送货合计(28)不一致,请核对", ] def test_warn_qty_delivery_vs_load_imbalance(): plan = [{"quantity": Decimal("30")}] load = [{"plan_qty": Decimal("30")}] delivery = [{"plan_qty": Decimal("25")}] warnings = warn_qty_imbalance(plan, load, delivery) assert warnings == [ "装货合计(30)与送货合计(25)不一致,请核对", ] def test_warn_qty_load_delivery_decimal_imbalance(): plan = [{"quantity": Decimal("30")}] load = [{"plan_qty": Decimal("30")}] delivery = [{"plan_qty": Decimal("30.31")}] warnings = warn_qty_imbalance(plan, load, delivery) assert warnings == [ "装货合计(30)与送货合计(30.31)不一致,请核对", ] def test_warn_qty_multi_stop_30_equals_10_15_5_balanced(): """验收场景:计划 30 = 送货 10+15+5,装货 30。""" plan = [{"quantity": Decimal("30")}] load = [{"plan_qty": Decimal("30")}] delivery = [ {"plan_qty": Decimal("10")}, {"plan_qty": Decimal("15")}, {"plan_qty": Decimal("5")}, ] assert warn_qty_imbalance(plan, load, delivery) == [] def test_warn_qty_sums_multiple_rows_balanced_across_stops(): plan = [{"quantity": Decimal("10")}, {"quantity": Decimal("20")}] load = [{"plan_qty": Decimal("10")}, {"plan_qty": Decimal("15")}] delivery = [{"plan_qty": Decimal("25")}] assert warn_qty_imbalance(plan, load, delivery) == [] def test_warn_qty_sums_multiple_rows_imbalanced_across_stops(): plan = [{"quantity": Decimal("10")}, {"quantity": Decimal("20")}] load = [{"plan_qty": Decimal("10")}, {"plan_qty": Decimal("15")}] delivery = [{"plan_qty": Decimal("24")}] warnings = warn_qty_imbalance(plan, load, delivery) assert warnings == [ "装货合计(25)与送货合计(24)不一致,请核对", ]