test_sample_payment_progress.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. """样本缴费进度:状态码与已缴/待缴汇总"""
  2. from decimal import Decimal
  3. import unittest
  4. from app.services.sample_payment_progress import (
  5. compute_sample_payment_progress,
  6. )
  7. class TestSamplePaymentProgress(unittest.TestCase):
  8. def test_pending_when_no_transfers(self):
  9. r = compute_sample_payment_progress(
  10. schedules=[
  11. {"scheduleStatus": "open", "dueAmount": Decimal("1000")},
  12. ],
  13. transfers=[],
  14. )
  15. self.assertEqual(r["progressStatus"], "dfj")
  16. self.assertEqual(r["paidAmount"], Decimal("0"))
  17. self.assertEqual(r["dueRemainAmount"], Decimal("1000"))
  18. self.assertEqual(r["clearedScheduleCount"], 0)
  19. self.assertEqual(r["activeScheduleCount"], 1)
  20. self.assertTrue(r["canConfirm"])
  21. def test_confirming_does_not_set_progress_status(self):
  22. """付款确认中不再作为样本缴费进度;有 yjf 则部分已缴,仍不可再提交确认。"""
  23. r = compute_sample_payment_progress(
  24. schedules=[
  25. {"id": "s1", "scheduleStatus": "open", "dueAmount": Decimal("1000")},
  26. ],
  27. transfers=[
  28. {"scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("200")},
  29. {"scheduleId": "s1", "payStatus": "jfqrz", "transferAmount": Decimal("100")},
  30. ],
  31. )
  32. self.assertEqual(r["progressStatus"], "bfyj")
  33. self.assertEqual(r["paidAmount"], Decimal("200"))
  34. self.assertFalse(r["canConfirm"])
  35. def test_confirming_only_stays_pending(self):
  36. """仅有付款确认中、尚无 yjf 时,缴费进度仍为待缴费。"""
  37. r = compute_sample_payment_progress(
  38. schedules=[
  39. {"id": "s1", "scheduleStatus": "open", "dueAmount": Decimal("1000")},
  40. ],
  41. transfers=[
  42. {"scheduleId": "s1", "payStatus": "jfqrz", "transferAmount": Decimal("100")},
  43. ],
  44. )
  45. self.assertEqual(r["progressStatus"], "dfj")
  46. self.assertEqual(r["paidAmount"], Decimal("0"))
  47. self.assertFalse(r["canConfirm"])
  48. def test_partial_paid(self):
  49. r = compute_sample_payment_progress(
  50. schedules=[
  51. {"id": "s1", "scheduleStatus": "cleared", "dueAmount": Decimal("500")},
  52. {"id": "s2", "scheduleStatus": "open", "dueAmount": Decimal("500")},
  53. ],
  54. transfers=[
  55. {"scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("500")},
  56. ],
  57. )
  58. self.assertEqual(r["progressStatus"], "bfyj")
  59. self.assertEqual(r["clearedScheduleCount"], 1)
  60. self.assertEqual(r["activeScheduleCount"], 2)
  61. self.assertTrue(r["canConfirm"])
  62. def test_open_schedule_is_cleared_when_confirmed_paid_covers_due(self):
  63. """财务已确认实缴覆盖应缴时,即使批次仍是 open,也按已缴清计。"""
  64. r = compute_sample_payment_progress(
  65. schedules=[
  66. {
  67. "id": "s1",
  68. "scheduleStatus": "open",
  69. "dueAmount": Decimal("22880.00"),
  70. },
  71. ],
  72. transfers=[
  73. {
  74. "scheduleId": "s1",
  75. "payStatus": "yjf",
  76. "transferAmount": Decimal("22880.00"),
  77. },
  78. ],
  79. )
  80. self.assertEqual(r["progressStatus"], "yjq")
  81. self.assertEqual(r["clearedScheduleCount"], 1)
  82. self.assertEqual(r["activeScheduleCount"], 1)
  83. self.assertEqual(r["dueRemainAmount"], Decimal("0"))
  84. self.assertFalse(r["canConfirm"])
  85. def test_partial_confirmed_on_open_schedule_stays_partial(self):
  86. r = compute_sample_payment_progress(
  87. schedules=[
  88. {"id": "s1", "scheduleStatus": "open", "dueAmount": Decimal("100")},
  89. ],
  90. transfers=[
  91. {"scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("20")},
  92. ],
  93. )
  94. self.assertEqual(r["progressStatus"], "bfyj")
  95. self.assertEqual(r["clearedScheduleCount"], 0)
  96. self.assertEqual(r["activeScheduleCount"], 1)
  97. def test_all_cleared(self):
  98. r = compute_sample_payment_progress(
  99. schedules=[
  100. {"id": "s1", "scheduleStatus": "cleared", "dueAmount": Decimal("500")},
  101. {"id": "s2", "scheduleStatus": "void", "dueAmount": Decimal("500")},
  102. ],
  103. transfers=[
  104. {"scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("500")},
  105. ],
  106. )
  107. self.assertEqual(r["progressStatus"], "yjq")
  108. self.assertEqual(r["activeScheduleCount"], 1)
  109. self.assertEqual(r["clearedScheduleCount"], 1)
  110. self.assertFalse(r["canConfirm"])
  111. self.assertEqual(r["dueRemainAmount"], Decimal("0"))
  112. def test_void_schedules_ignored(self):
  113. r = compute_sample_payment_progress(
  114. schedules=[
  115. {"scheduleStatus": "void", "dueAmount": Decimal("9999")},
  116. {"scheduleStatus": "open", "dueAmount": Decimal("100")},
  117. ],
  118. transfers=[],
  119. )
  120. self.assertEqual(r["activeScheduleCount"], 1)
  121. self.assertEqual(r["dueRemainAmount"], Decimal("100"))
  122. if __name__ == "__main__":
  123. unittest.main()