test_pl_plan_archive_stop_service.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. plan_product_id="pp1",
  59. inbound_qty=Decimal("30"),
  60. inbound_price=Decimal("100"),
  61. )
  62. ],
  63. PlPlanDelivery: [
  64. _FakeRow(id="d1", customer_name="外部客户有限公司"),
  65. _FakeRow(id="d2", customer_name=internal_name),
  66. ],
  67. PlPlanDeliveryProduct: [
  68. _FakeRow(
  69. delivery_id="d2",
  70. plan_product_id="pp1",
  71. outbound_qty=Decimal("12"),
  72. outbound_price=Decimal("120"),
  73. )
  74. ],
  75. }
  76. )
  77. lines = list(
  78. iter_stop_archive_inventory_lines(db, tenant_no="t1", plan_id="p1")
  79. )
  80. assert lines == [
  81. ("pp1", Decimal("30"), "outbound", Decimal("100")),
  82. ("pp1", Decimal("12"), "inbound", Decimal("120")),
  83. ]
  84. def test_archive_stop_product_item_schema_aliases():
  85. item = PlanArchiveStopProductItem.model_validate(
  86. {
  87. "id": "row1",
  88. "inboundQty": "8",
  89. "inboundPrice": "99.5",
  90. }
  91. )
  92. assert item.inbound_qty == Decimal("8")
  93. assert item.inbound_price == Decimal("99.5")
  94. load_block = PlanArchiveLoadBlock.model_validate(
  95. {
  96. "stopId": "load1",
  97. "products": [{"id": "row1", "inboundQty": 1}],
  98. }
  99. )
  100. assert load_block.stop_id == "load1"
  101. assert load_block.products[0].id == "row1"
  102. delivery_block = PlanArchiveDeliveryBlock.model_validate(
  103. {
  104. "stopId": "d1",
  105. "products": [{"id": "row2", "outboundQty": 2}],
  106. }
  107. )
  108. assert delivery_block.stop_id == "d1"
  109. assert delivery_block.products[0].outbound_qty == Decimal("2")