test_pl_plan_archive_stop_service.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. from decimal import Decimal
  2. from app.schemas.pl.plan import (
  3. PlanArchiveDeliveryBlock,
  4. PlanArchiveLoadBlock,
  5. PlanArchiveStopProductItem,
  6. )
  7. from app.services.pl_plan_archive_stop_service import (
  8. iter_stop_archive_inventory_lines,
  9. sum_delivery_outbound_qty,
  10. )
  11. class _FakeRow:
  12. def __init__(self, **kwargs):
  13. for key, value in kwargs.items():
  14. setattr(self, key, value)
  15. class _FakeQuery:
  16. def __init__(self, rows):
  17. self._rows = rows
  18. def filter(self, *args, **kwargs):
  19. return self
  20. def first(self):
  21. return self._rows[0] if self._rows else None
  22. def all(self):
  23. return self._rows
  24. def order_by(self, *args, **kwargs):
  25. return self
  26. class _FakeDb:
  27. def __init__(self, mapping):
  28. self._mapping = mapping
  29. def query(self, model):
  30. return _FakeQuery(self._mapping.get(model, []))
  31. def test_sum_delivery_outbound_qty():
  32. from app.models.pl_models import PlPlanDeliveryProduct
  33. db = _FakeDb(
  34. {
  35. PlPlanDeliveryProduct: [
  36. _FakeRow(outbound_qty=Decimal("10")),
  37. _FakeRow(outbound_qty=Decimal("5.5")),
  38. _FakeRow(outbound_qty=None),
  39. ]
  40. }
  41. )
  42. total = sum_delivery_outbound_qty(db, tenant_no="t1", plan_id="p1")
  43. assert total == Decimal("15.5")
  44. def test_iter_stop_archive_inventory_lines_internal_load_outbound_and_delivery_inbound():
  45. from app.models.pl_models import (
  46. PlPlanDelivery,
  47. PlPlanDeliveryProduct,
  48. PlPlanLoad,
  49. PlPlanLoadProduct,
  50. )
  51. from app.services.pl_internal_customer import INTERNAL_CUSTOMER_NAMES
  52. internal_name = next(iter(INTERNAL_CUSTOMER_NAMES))
  53. db = _FakeDb(
  54. {
  55. PlPlanLoad: [_FakeRow(id="load1", customer_name=internal_name)],
  56. PlPlanLoadProduct: [
  57. _FakeRow(
  58. id="load-item",
  59. plan_product_id="pp1",
  60. inbound_qty=Decimal("30"),
  61. inbound_price=Decimal("100"),
  62. )
  63. ],
  64. PlPlanDelivery: [
  65. _FakeRow(id="d1", customer_name="外部客户有限公司"),
  66. _FakeRow(id="d2", customer_name=internal_name),
  67. ],
  68. PlPlanDeliveryProduct: [
  69. _FakeRow(
  70. id="d2-item",
  71. delivery_id="d2",
  72. plan_product_id="pp1",
  73. outbound_qty=Decimal("12"),
  74. outbound_price=Decimal("120"),
  75. )
  76. ],
  77. }
  78. )
  79. lines = list(
  80. iter_stop_archive_inventory_lines(db, tenant_no="t1", plan_id="p1")
  81. )
  82. assert lines == [
  83. ("pp1", Decimal("30"), "outbound", Decimal("100"), "load", "load-item"),
  84. ("pp1", Decimal("12"), "inbound", Decimal("120"), "delivery", "d2-item"),
  85. ]
  86. def test_archive_stop_product_item_schema_aliases():
  87. item = PlanArchiveStopProductItem.model_validate(
  88. {
  89. "id": "row1",
  90. "inboundQty": "8",
  91. "inboundPrice": "99.5",
  92. }
  93. )
  94. assert item.inbound_qty == Decimal("8")
  95. assert item.inbound_price == Decimal("99.5")
  96. load_block = PlanArchiveLoadBlock.model_validate(
  97. {
  98. "stopId": "load1",
  99. "products": [{"id": "row1", "inboundQty": 1}],
  100. }
  101. )
  102. assert load_block.stop_id == "load1"
  103. assert load_block.products[0].id == "row1"
  104. delivery_block = PlanArchiveDeliveryBlock.model_validate(
  105. {
  106. "stopId": "d1",
  107. "products": [{"id": "row2", "outboundQty": 2}],
  108. }
  109. )
  110. assert delivery_block.stop_id == "d1"
  111. assert delivery_block.products[0].outbound_qty == Decimal("2")