test_pl_calendar_customer_names.py 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. """日历名称只查询已授权计划引用的客户,简称缺失时显示全称。"""
  2. from types import SimpleNamespace as NS
  3. from sqlalchemy import create_engine, text
  4. from sqlalchemy.orm import Session
  5. from app.services.pl_calendar_customer_names import attach_calendar_routes
  6. def test_short_names_full_names_stop_order_and_tenant_isolation():
  7. engine = create_engine("sqlite://")
  8. with engine.begin() as conn:
  9. conn.execute(text("CREATE TABLE crm_customer (id TEXT, customer_name TEXT, short_name TEXT, tenant_no TEXT, del_flag INTEGER)"))
  10. conn.execute(text("INSERT INTO crm_customer VALUES (:id, :name, :short, :tenant, :deleted)"), [
  11. dict(id="load", name="山峡化工有限公司", short=" 山峡 ", tenant="t1", deleted=0),
  12. dict(id="full", name="永恒有限公司", short=" ", tenant="t1", deleted=0),
  13. dict(id="other", name="其他租户", short="不应泄漏", tenant="t2", deleted=0),
  14. dict(id="deleted", name="已删除", short="不应显示", tenant="t1", deleted=1),
  15. dict(id="unused", name="无关客户", short="无关", tenant="t1", deleted=0),
  16. ])
  17. plan = NS(load=NS(customer_id="load", customer_name="山峡旧全称"), deliveries=[
  18. NS(seq=3, customer_id="deleted", customer_name="删除前全称"),
  19. NS(seq=1, customer_id="full", customer_name="永恒旧全称"),
  20. NS(seq=2, customer_id="other", customer_name="计划留存全称"),
  21. ])
  22. with Session(engine) as db:
  23. attach_calendar_routes(db, tenant_no="t1", plans=[plan])
  24. assert plan.calendar_route == "山峡 → 永恒有限公司 → 计划留存全称 → 删除前全称"
  25. assert plan.load.calendar_customer_name == "山峡"
  26. assert [stop.calendar_customer_name for stop in plan.deliveries] == ["删除前全称", "永恒有限公司", "计划留存全称"]
  27. assert plan.load.customer_name == "山峡旧全称"
  28. def test_legacy_plan_and_address_fallback_without_customer_ids():
  29. class NoQuery:
  30. def query(self, *args):
  31. raise AssertionError("没有客户 ID 时不应查询客户表")
  32. plans = [
  33. NS(supplier_name="装货全称", customer_name="送货全称"),
  34. NS(load=NS(address="装货地址"), deliveries=[NS(seq=1, address="送货地址")]),
  35. NS(),
  36. ]
  37. attach_calendar_routes(NoQuery(), tenant_no="t1", plans=plans)
  38. assert [p.calendar_route for p in plans] == ["装货全称 → 送货全称", "装货地址 → 送货地址", "去向待定"]
  39. def test_load_name_without_id_does_not_get_replaced_by_supplier():
  40. class SupplierQuery:
  41. def filter(self, *args):
  42. return self
  43. def all(self):
  44. return [NS(id="supplier", short_name="供方简称", customer_name="供方全称")]
  45. class SupplierDb:
  46. def query(self, *args):
  47. return SupplierQuery()
  48. plan = NS(supplier_id="supplier", supplier_name="供方全称", load=NS(customer_name="实际装货站点"))
  49. attach_calendar_routes(SupplierDb(), tenant_no="t1", plans=[plan])
  50. assert plan.calendar_route == "实际装货站点"
  51. def test_read_schemas_serialize_calendar_stop_names():
  52. from app.schemas.pl.plan import PlanLoadRead, PlanDeliveryRead
  53. class NoQuery:
  54. def query(self, *args):
  55. raise AssertionError("无关联客户不查询")
  56. fields = dict(planId="p1", tenantNo="t1", createTime="2026-10-25T00:00:00", updateTime="2026-10-25T00:00:00")
  57. load = PlanLoadRead.model_validate(dict(id="load", customerName="装货全称", **fields))
  58. delivery = PlanDeliveryRead.model_validate(dict(id="delivery", customerName="送货全称", **fields))
  59. attach_calendar_routes(NoQuery(), tenant_no="t1", plans=[NS(load=load, deliveries=[delivery])])
  60. assert load.model_dump(by_alias=True)["calendarCustomerName"] == "装货全称"
  61. assert delivery.model_dump(by_alias=True)["calendarCustomerName"] == "送货全称"