test_pl_plan_list_export.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. """运输计划列表导出:产品名称 / 品牌 / 别名。"""
  2. from types import SimpleNamespace
  3. from unittest.mock import MagicMock, patch
  4. from app.api.pl.plan import (
  5. PLAN_EXPORT_COLUMNS,
  6. _build_plan_list_export_rows,
  7. _format_plan_list_export_brand,
  8. _normalize_plan_export_columns,
  9. )
  10. from app.utils.excel_export import filter_export_columns
  11. def test_normalize_plan_export_columns_maps_list_props():
  12. assert _normalize_plan_export_columns(
  13. ["productBrand", "productAlias", "productName", "planNo"]
  14. ) == ["brandName", "aliasName", "productName", "planNo"]
  15. assert _normalize_plan_export_columns(None) is None
  16. def test_format_plan_list_export_brand_only_required():
  17. required = SimpleNamespace(brand_mode="required", brand_name="君正")
  18. any_mode = SimpleNamespace(brand_mode="any", brand_name="君正")
  19. assert _format_plan_list_export_brand(required) == "君正"
  20. assert _format_plan_list_export_brand(any_mode) == ""
  21. def test_filter_export_columns_keeps_brand_alias_after_normalize():
  22. requested = _normalize_plan_export_columns(
  23. ["planNo", "productName", "productBrand", "productAlias"]
  24. )
  25. cols = filter_export_columns(PLAN_EXPORT_COLUMNS, requested)
  26. assert [c.field for c in cols] == ["planNo", "productName", "brandName", "aliasName"]
  27. def test_build_plan_list_export_rows_expands_products_with_crm_names():
  28. plan = SimpleNamespace(
  29. id="p1",
  30. plan_no="PL001",
  31. follow_status="arranged",
  32. plan_date="2026-10-11",
  33. plan_type="direct",
  34. supplier_name="供方",
  35. customer_name="需方",
  36. license_plate="皖A12345",
  37. driver_name="司机",
  38. transport_status="arranged",
  39. archive_status="pending",
  40. erp_entered=0,
  41. remark="",
  42. products=[],
  43. )
  44. # PlanWithProducts.model_validate needs a real-ish object; patch dump path instead.
  45. product = SimpleNamespace(
  46. id="pp1",
  47. plan_id="p1",
  48. product_id="prod1",
  49. product_name="甲醇别名",
  50. brand_mode="required",
  51. brand_name="君正",
  52. order_num=1,
  53. )
  54. db = MagicMock()
  55. query = MagicMock()
  56. db.query.return_value = query
  57. query.filter.return_value = query
  58. query.order_by.return_value = query
  59. query.all.return_value = [product]
  60. fake_dump = {
  61. "planNo": "PL001",
  62. "followStatus": "arranged",
  63. "planDate": "2026-10-11",
  64. "planType": "direct",
  65. "supplierName": "供方",
  66. "customerName": "需方",
  67. "licensePlate": "皖A12345",
  68. "driverName": "司机",
  69. "transportStatus": "arranged",
  70. "archiveStatus": "pending",
  71. "erpEntered": 0,
  72. "remark": "",
  73. "products": [{"id": "pp1"}],
  74. }
  75. with patch(
  76. "app.api.pl.plan.PlanWithProducts.model_validate",
  77. return_value=MagicMock(model_dump=MagicMock(return_value=dict(fake_dump))),
  78. ), patch(
  79. "app.api.pl.plan.collect_unique_delivery_date_strings",
  80. return_value=["2026-10-12"],
  81. ), patch(
  82. "app.api.pl.plan.load_crm_product_alias_maps",
  83. return_value=({"prod1": "甲醇"}, {"prod1": ["甲醇别名"]}),
  84. ):
  85. rows = _build_plan_list_export_rows(
  86. db,
  87. tenant_no="t1",
  88. plans=[plan],
  89. stops_by_plan={"p1": (None, [])},
  90. )
  91. assert len(rows) == 1
  92. assert rows[0]["planNo"] == "PL001"
  93. assert rows[0]["deliveryTimes"] == "2026-10-12"
  94. assert rows[0]["productName"] == "甲醇"
  95. assert rows[0]["brandName"] == "君正"
  96. assert rows[0]["aliasName"] == "甲醇别名"
  97. assert "products" not in rows[0]