"""催缴纳入规则与金额口径""" from datetime import date from decimal import Decimal import unittest from app.services.payment_chase import ( chase_period_money, is_chase_candidate, parse_due_date_ymd, ) class TestChase(unittest.TestCase): def test_chase_paid_only_counts_yjf(self): """已缴 = 仅 yjf;欠缴 = 应缴 − 已缴""" paid, arrears = chase_period_money( due_amount=Decimal("1000"), transfers=[ { "transferAmount": Decimal("300"), "payStatus": "dfj", "transferTime": "2026-04-01 10:00:00", }, { "transferAmount": Decimal("200"), "payStatus": "jfqrz", "transferTime": "2026-04-02 10:00:00", }, { "transferAmount": Decimal("100"), "payStatus": "yjf", "transferTime": "2026-04-03 10:00:00", }, ], ) self.assertEqual(paid, Decimal("100")) self.assertEqual(arrears, Decimal("900")) def test_chase_dfj_only_still_has_arrears(self): paid, arrears = chase_period_money( due_amount=Decimal("500"), transfers=[ { "transferAmount": Decimal("500"), "payStatus": "dfj", "transferTime": "2026-04-01 10:00:00", } ], ) self.assertEqual(paid, Decimal("0")) self.assertEqual(arrears, Decimal("500")) self.assertTrue( is_chase_candidate( due_date=date(2026, 9, 1), today=date(2026, 10, 9), arrears=arrears, ) ) def test_overdue(self): self.assertTrue( is_chase_candidate( due_date=date(2026, 9, 1), today=date(2026, 10, 9), arrears=Decimal("100"), ) ) def test_within_30(self): self.assertTrue( is_chase_candidate( due_date=date(2026, 11, 1), today=date(2026, 10, 9), arrears=Decimal("100"), ) ) def test_beyond_30(self): self.assertFalse( is_chase_candidate( due_date=date(2026, 11, 10), today=date(2026, 10, 9), arrears=Decimal("100"), ) ) def test_zero_arrears(self): self.assertFalse( is_chase_candidate( due_date=date(2026, 9, 1), today=date(2026, 10, 9), arrears=Decimal("0"), ) ) def test_parse_due_date(self): self.assertEqual(parse_due_date_ymd("20261009"), date(2026, 10, 9)) self.assertEqual(parse_due_date_ymd("2026-10-09"), date(2026, 10, 9)) def test_parse_due_date_rejects_suffixes_and_mixed_separators(self): for raw in ( "20261009extra", "2026-10-09 12:00:00", "2026-1009", "202610-09", " 20261009", "2026-10-09 ", ): with self.subTest(raw=raw): self.assertIsNone(parse_due_date_ymd(raw)) if __name__ == "__main__": unittest.main()