"""样本缴费进度:状态码与已缴/待缴汇总""" from decimal import Decimal import unittest from app.services.sample_payment_progress import ( compute_sample_payment_progress, ) class TestSamplePaymentProgress(unittest.TestCase): def test_pending_when_no_transfers(self): r = compute_sample_payment_progress( schedules=[ {"scheduleStatus": "open", "dueAmount": Decimal("1000")}, ], transfers=[], ) self.assertEqual(r["progressStatus"], "dfj") self.assertEqual(r["paidAmount"], Decimal("0")) self.assertEqual(r["dueRemainAmount"], Decimal("1000")) self.assertEqual(r["clearedScheduleCount"], 0) self.assertEqual(r["activeScheduleCount"], 1) self.assertTrue(r["canConfirm"]) def test_confirming_does_not_set_progress_status(self): """付款确认中不再作为样本缴费进度;有 yjf 则部分已缴,仍不可再提交确认。""" r = compute_sample_payment_progress( schedules=[ {"id": "s1", "scheduleStatus": "open", "dueAmount": Decimal("1000")}, ], transfers=[ {"scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("200")}, {"scheduleId": "s1", "payStatus": "jfqrz", "transferAmount": Decimal("100")}, ], ) self.assertEqual(r["progressStatus"], "bfyj") self.assertEqual(r["paidAmount"], Decimal("200")) self.assertFalse(r["canConfirm"]) def test_confirming_only_stays_pending(self): """仅有付款确认中、尚无 yjf 时,缴费进度仍为待缴费。""" r = compute_sample_payment_progress( schedules=[ {"id": "s1", "scheduleStatus": "open", "dueAmount": Decimal("1000")}, ], transfers=[ {"scheduleId": "s1", "payStatus": "jfqrz", "transferAmount": Decimal("100")}, ], ) self.assertEqual(r["progressStatus"], "dfj") self.assertEqual(r["paidAmount"], Decimal("0")) self.assertFalse(r["canConfirm"]) def test_partial_paid(self): r = compute_sample_payment_progress( schedules=[ {"id": "s1", "scheduleStatus": "cleared", "dueAmount": Decimal("500")}, {"id": "s2", "scheduleStatus": "open", "dueAmount": Decimal("500")}, ], transfers=[ {"scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("500")}, ], ) self.assertEqual(r["progressStatus"], "bfyj") self.assertEqual(r["clearedScheduleCount"], 1) self.assertEqual(r["activeScheduleCount"], 2) self.assertTrue(r["canConfirm"]) def test_open_schedule_is_cleared_when_confirmed_paid_covers_due(self): """财务已确认实缴覆盖应缴时,即使批次仍是 open,也按已缴清计。""" r = compute_sample_payment_progress( schedules=[ { "id": "s1", "scheduleStatus": "open", "dueAmount": Decimal("22880.00"), }, ], transfers=[ { "scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("22880.00"), }, ], ) self.assertEqual(r["progressStatus"], "yjq") self.assertEqual(r["clearedScheduleCount"], 1) self.assertEqual(r["activeScheduleCount"], 1) self.assertEqual(r["dueRemainAmount"], Decimal("0")) self.assertFalse(r["canConfirm"]) def test_partial_confirmed_on_open_schedule_stays_partial(self): r = compute_sample_payment_progress( schedules=[ {"id": "s1", "scheduleStatus": "open", "dueAmount": Decimal("100")}, ], transfers=[ {"scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("20")}, ], ) self.assertEqual(r["progressStatus"], "bfyj") self.assertEqual(r["clearedScheduleCount"], 0) self.assertEqual(r["activeScheduleCount"], 1) def test_all_cleared(self): r = compute_sample_payment_progress( schedules=[ {"id": "s1", "scheduleStatus": "cleared", "dueAmount": Decimal("500")}, {"id": "s2", "scheduleStatus": "void", "dueAmount": Decimal("500")}, ], transfers=[ {"scheduleId": "s1", "payStatus": "yjf", "transferAmount": Decimal("500")}, ], ) self.assertEqual(r["progressStatus"], "yjq") self.assertEqual(r["activeScheduleCount"], 1) self.assertEqual(r["clearedScheduleCount"], 1) self.assertFalse(r["canConfirm"]) self.assertEqual(r["dueRemainAmount"], Decimal("0")) def test_void_schedules_ignored(self): r = compute_sample_payment_progress( schedules=[ {"scheduleStatus": "void", "dueAmount": Decimal("9999")}, {"scheduleStatus": "open", "dueAmount": Decimal("100")}, ], transfers=[], ) self.assertEqual(r["activeScheduleCount"], 1) self.assertEqual(r["dueRemainAmount"], Decimal("100")) if __name__ == "__main__": unittest.main()