"""缴费模式切换校验""" import unittest from app.services.protocol_pay_mode_switch import validate_payment_details_for_save class TestValidatePaymentDetailsForSave(unittest.TestCase): def test_dj_single_dfj_full_contract(self): validate_payment_details_for_save( "dj", 10000, None, [{"payStatus": "dfj", "dueAmount": 10000}], ) def test_dj_allows_multiple_dfj_when_sum_matches(self): validate_payment_details_for_save( "dj", 10000, None, [ {"payStatus": "dfj", "dueAmount": 2000}, {"payStatus": "dfj", "dueAmount": 8000}, ], ) def test_dj_rejects_multiple_dfj_wrong_sum(self): with self.assertRaises(ValueError) as ctx: validate_payment_details_for_save( "dj", 10000, None, [ {"payStatus": "dfj", "dueAmount": 2000}, {"payStatus": "dfj", "dueAmount": 7000}, ], ) self.assertIn("之和应为", str(ctx.exception)) def test_dj_partial_paid_remaining(self): validate_payment_details_for_save( "dj", 10000, None, [ {"payStatus": "yjf", "dueAmount": 2000}, {"payStatus": "dfj", "dueAmount": 8000}, ], ) def test_dj_partial_paid_wrong_remaining(self): with self.assertRaises(ValueError): validate_payment_details_for_save( "dj", 10000, None, [ {"payStatus": "yjf", "dueAmount": 2000}, {"payStatus": "dfj", "dueAmount": 10000}, ], ) def test_djfq_same_as_fq(self): validate_payment_details_for_save( "djfq", 41000, 4, [ {"payStatus": "dfj", "installmentNo": 1, "dueAmount": 29360}, {"payStatus": "dfj", "installmentNo": 2, "dueAmount": 3880}, {"payStatus": "dfj", "installmentNo": 3, "dueAmount": 3880}, {"payStatus": "dfj", "installmentNo": 4, "dueAmount": 3880}, ], installment_ratios=[29360, 3880, 3880, 3880], ) def test_fq_count_mismatch(self): with self.assertRaises(ValueError): validate_payment_details_for_save( "fq", 6000, 6, [{"payStatus": "dfj", "dueAmount": 6000}], ) def test_fq_partial_paid_valid(self): validate_payment_details_for_save( "fq", 10000, 4, [ {"payStatus": "yjf", "installmentNo": 1, "dueAmount": 2500}, {"payStatus": "yjf", "installmentNo": 2, "dueAmount": 2500}, {"payStatus": "dfj", "installmentNo": 3, "dueAmount": 2500}, {"payStatus": "dfj", "installmentNo": 4, "dueAmount": 2500}, ], ) def test_fq_jfqrz_rejected(self): with self.assertRaises(ValueError): validate_payment_details_for_save( "fq", 6000, 2, [ {"payStatus": "jfqrz", "dueAmount": 3000}, {"payStatus": "dfj", "dueAmount": 3000}, ], ) def test_dj_ytf_allowed(self): """已退费为终态,保存协议单时不应阻断。""" validate_payment_details_for_save( "dj", 10000, None, [{"payStatus": "ytf", "dueAmount": 10000}], ) def test_fq_ytf_allowed(self): validate_payment_details_for_save( "fq", 6000, 2, [ {"payStatus": "ytf", "installmentNo": 1, "dueAmount": 3000}, {"payStatus": "dfj", "installmentNo": 2, "dueAmount": 3000}, ], ) def test_blocking_status_rejected(self): with self.assertRaises(ValueError): validate_payment_details_for_save( "dj", 10000, None, [{"payStatus": "jfqrz", "dueAmount": 10000}], ) def test_tfqrz_blocking_rejected(self): with self.assertRaises(ValueError): validate_payment_details_for_save( "dj", 10000, None, [{"payStatus": "tfqrz", "dueAmount": 10000}], ) if __name__ == "__main__": unittest.main()