test_payment_chase.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. """催缴纳入规则与金额口径"""
  2. from datetime import date
  3. from decimal import Decimal
  4. import unittest
  5. from app.services.payment_chase import (
  6. chase_period_money,
  7. is_chase_candidate,
  8. parse_due_date_ymd,
  9. )
  10. class TestChase(unittest.TestCase):
  11. def test_chase_paid_only_counts_yjf(self):
  12. """已缴 = 仅 yjf;欠缴 = 应缴 − 已缴"""
  13. paid, arrears = chase_period_money(
  14. due_amount=Decimal("1000"),
  15. transfers=[
  16. {
  17. "transferAmount": Decimal("300"),
  18. "payStatus": "dfj",
  19. "transferTime": "2026-04-01 10:00:00",
  20. },
  21. {
  22. "transferAmount": Decimal("200"),
  23. "payStatus": "jfqrz",
  24. "transferTime": "2026-04-02 10:00:00",
  25. },
  26. {
  27. "transferAmount": Decimal("100"),
  28. "payStatus": "yjf",
  29. "transferTime": "2026-04-03 10:00:00",
  30. },
  31. ],
  32. )
  33. self.assertEqual(paid, Decimal("100"))
  34. self.assertEqual(arrears, Decimal("900"))
  35. def test_chase_dfj_only_still_has_arrears(self):
  36. paid, arrears = chase_period_money(
  37. due_amount=Decimal("500"),
  38. transfers=[
  39. {
  40. "transferAmount": Decimal("500"),
  41. "payStatus": "dfj",
  42. "transferTime": "2026-04-01 10:00:00",
  43. }
  44. ],
  45. )
  46. self.assertEqual(paid, Decimal("0"))
  47. self.assertEqual(arrears, Decimal("500"))
  48. self.assertTrue(
  49. is_chase_candidate(
  50. due_date=date(2026, 9, 1),
  51. today=date(2026, 10, 9),
  52. arrears=arrears,
  53. )
  54. )
  55. def test_overdue(self):
  56. self.assertTrue(
  57. is_chase_candidate(
  58. due_date=date(2026, 9, 1),
  59. today=date(2026, 10, 9),
  60. arrears=Decimal("100"),
  61. )
  62. )
  63. def test_within_30(self):
  64. self.assertTrue(
  65. is_chase_candidate(
  66. due_date=date(2026, 11, 1),
  67. today=date(2026, 10, 9),
  68. arrears=Decimal("100"),
  69. )
  70. )
  71. def test_beyond_30(self):
  72. self.assertFalse(
  73. is_chase_candidate(
  74. due_date=date(2026, 11, 10),
  75. today=date(2026, 10, 9),
  76. arrears=Decimal("100"),
  77. )
  78. )
  79. def test_zero_arrears(self):
  80. self.assertFalse(
  81. is_chase_candidate(
  82. due_date=date(2026, 9, 1),
  83. today=date(2026, 10, 9),
  84. arrears=Decimal("0"),
  85. )
  86. )
  87. def test_parse_due_date(self):
  88. self.assertEqual(parse_due_date_ymd("20261009"), date(2026, 10, 9))
  89. self.assertEqual(parse_due_date_ymd("2026-10-09"), date(2026, 10, 9))
  90. def test_parse_due_date_rejects_suffixes_and_mixed_separators(self):
  91. for raw in (
  92. "20261009extra",
  93. "2026-10-09 12:00:00",
  94. "2026-1009",
  95. "202610-09",
  96. " 20261009",
  97. "2026-10-09 ",
  98. ):
  99. with self.subTest(raw=raw):
  100. self.assertIsNone(parse_due_date_ymd(raw))
  101. if __name__ == "__main__":
  102. unittest.main()