test_pl_dibang_plan_quantity.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. """地磅月计划量运输联动累加/回减单元测试"""
  2. from decimal import Decimal
  3. from unittest.mock import MagicMock, patch
  4. import pytest
  5. from app.models.db_models import DbInboundOutbound, DbPurchasePlan
  6. from app.models.pl_models import PlTransportDbLink
  7. from app.services.pl_dibang_bridge_service import (
  8. _apply_plan_quantity_delta,
  9. _resolve_link_contributed_qty,
  10. revoke_regeneratable_dibang_for_transport,
  11. )
  12. def test_apply_plan_quantity_delta_accumulates():
  13. db_plan = DbPurchasePlan(planned_quantity=30.0)
  14. _apply_plan_quantity_delta(db_plan, 31, user_id="u1")
  15. assert db_plan.planned_quantity == 61.0
  16. assert db_plan.update_by == "u1"
  17. def test_apply_plan_quantity_delta_never_below_zero():
  18. db_plan = DbPurchasePlan(planned_quantity=30.0)
  19. _apply_plan_quantity_delta(db_plan, -50, user_id="u1")
  20. assert db_plan.planned_quantity == 0.0
  21. def test_resolve_link_contributed_qty_prefers_link_field():
  22. link = PlTransportDbLink(contributed_qty=Decimal("30"))
  23. inventory = DbInboundOutbound(quantity=Decimal("99"))
  24. assert _resolve_link_contributed_qty(link, inventory) == 30.0
  25. def test_resolve_link_contributed_qty_falls_back_to_inventory():
  26. link = PlTransportDbLink(contributed_qty=None)
  27. inventory = DbInboundOutbound(quantity=Decimal("31"))
  28. assert _resolve_link_contributed_qty(link, inventory) == 31.0
  29. def test_resolve_link_contributed_qty_zero_when_missing():
  30. link = PlTransportDbLink(contributed_qty=None)
  31. assert _resolve_link_contributed_qty(link, None) == 0.0
  32. @patch("app.services.pl_dibang_bridge_service._inventory_has_weighing_slip", return_value=False)
  33. def test_revoke_subtracts_plan_quantity_on_cancel(_mock_weighing):
  34. db_plan = DbPurchasePlan(id="plan-1", tenant_no="t1", planned_quantity=61.0, del_flag=0)
  35. inventory = DbInboundOutbound(
  36. id="inv-1",
  37. tenant_no="t1",
  38. del_flag=0,
  39. status="待入库",
  40. quantity=Decimal("30"),
  41. batch_no="CRKDH0000001",
  42. )
  43. link = PlTransportDbLink(
  44. id="link-1",
  45. tenant_no="t1",
  46. transport_id="tr-1",
  47. db_inventory_id="inv-1",
  48. db_purchase_plan_id="plan-1",
  49. contributed_qty=Decimal("30"),
  50. del_flag=0,
  51. )
  52. db = MagicMock()
  53. link_query = MagicMock()
  54. link_query.filter.return_value.all.return_value = [link]
  55. inv_query = MagicMock()
  56. inv_query.filter.return_value.first.return_value = inventory
  57. plan_query = MagicMock()
  58. plan_query.filter.return_value.first.return_value = db_plan
  59. def query_router(model):
  60. if model is PlTransportDbLink:
  61. return link_query
  62. if model is DbInboundOutbound:
  63. return inv_query
  64. if model is DbPurchasePlan:
  65. return plan_query
  66. return MagicMock()
  67. db.query.side_effect = query_router
  68. revoke_regeneratable_dibang_for_transport(
  69. db,
  70. tenant_no="t1",
  71. transport_id="tr-1",
  72. user_id="u1",
  73. )
  74. assert db_plan.planned_quantity == 31.0
  75. assert inventory.del_flag == 1
  76. assert link.del_flag == 1
  77. @patch("app.services.pl_dibang_bridge_service._inventory_has_weighing_slip", return_value=True)
  78. def test_revoke_blocks_when_weighing_exists(_mock_weighing):
  79. inventory = DbInboundOutbound(
  80. id="inv-1",
  81. tenant_no="t1",
  82. del_flag=0,
  83. status="待入库",
  84. batch_no="CRKDH0000001",
  85. )
  86. link = PlTransportDbLink(
  87. id="link-1",
  88. tenant_no="t1",
  89. transport_id="tr-1",
  90. db_inventory_id="inv-1",
  91. db_purchase_plan_id="plan-1",
  92. contributed_qty=Decimal("30"),
  93. del_flag=0,
  94. )
  95. db = MagicMock()
  96. link_query = MagicMock()
  97. link_query.filter.return_value.all.return_value = [link]
  98. inv_query = MagicMock()
  99. inv_query.filter.return_value.first.return_value = inventory
  100. db.query.side_effect = lambda model: link_query if model is PlTransportDbLink else inv_query
  101. with pytest.raises(ValueError, match="已关联地磅"):
  102. revoke_regeneratable_dibang_for_transport(
  103. db,
  104. tenant_no="t1",
  105. transport_id="tr-1",
  106. user_id="u1",
  107. )
  108. assert inventory.del_flag == 0
  109. assert link.del_flag == 0