From e838a85327efa593f3c500666ef95066978d8a58 Mon Sep 17 00:00:00 2001 From: Nikhil Vangumalla Date: Tue, 13 Jul 2021 14:24:08 +0530 Subject: [PATCH 1/2] Don't create payment split for reset loan's transaction_refund event --- src/rush/payments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rush/payments.py b/src/rush/payments.py index 446f5997..e0588317 100644 --- a/src/rush/payments.py +++ b/src/rush/payments.py @@ -376,6 +376,7 @@ def transaction_refund_event( amount=refund_amount, debit_book_str=m2p_pool_account, ) + create_payment_split(session, event) if not skip_limit_assignment: limit_assignment_event( @@ -389,7 +390,6 @@ def transaction_refund_event( credit_book_str=f"{user_loan.loan_id}/loan/refund_off_balance/l", # Couldn't find anything relevant. amount=Decimal(event.amount), ) - create_payment_split(session, event) # slide_payment_to_emis(user_loan, event) From f9b1c8677babc2c6a689102c785fda3f1b51d2d1 Mon Sep 17 00:00:00 2001 From: Nikhil Vangumalla Date: Wed, 14 Jul 2021 15:57:34 +0530 Subject: [PATCH 2/2] Do not adjust payment in unbilled account for term loans --- src/rush/accrue_financial_charges.py | 1 + src/rush/ledger_events.py | 13 +- src/test/test_reset_card.py | 230 +++++++++++++++++++++++++++ 3 files changed, 238 insertions(+), 6 deletions(-) diff --git a/src/rush/accrue_financial_charges.py b/src/rush/accrue_financial_charges.py index 0eeb1ded..51366d9f 100644 --- a/src/rush/accrue_financial_charges.py +++ b/src/rush/accrue_financial_charges.py @@ -355,6 +355,7 @@ def reverse_incorrect_late_charges( ) .one_or_none() ) + bill = user_loan.convert_to_bill_class(bill) if fee.fee_status == "UNPAID": # Remove from min. But only what's remaining. Rest doesn't matter. diff --git a/src/rush/ledger_events.py b/src/rush/ledger_events.py index 447bf3a4..203a537a 100644 --- a/src/rush/ledger_events.py +++ b/src/rush/ledger_events.py @@ -154,7 +154,7 @@ def add_max_amount_event( def _adjust_bill( session: Session, - bill: LoanData, + bill: BaseBill, amount_to_adjust_in_this_bill: Decimal, event_id: int, debit_acc_str: str, @@ -182,11 +182,12 @@ def adjust_for_receivable(payment_to_adjust_from: Decimal, to_acc: str, from_acc to_acc=debit_acc_str, from_acc=f"{bill.id}/bill/interest_receivable/a", ) - remaining_amount = adjust_for_receivable( - remaining_amount, - to_acc=debit_acc_str, - from_acc=f"{bill.id}/bill/unbilled/a", - ) + if not bill.user_loan.sub_product_type == "tenure_loan": + remaining_amount = adjust_for_receivable( + remaining_amount, + to_acc=debit_acc_str, + from_acc=f"{bill.id}/bill/unbilled/a", + ) remaining_amount = adjust_for_receivable( remaining_amount, to_acc=debit_acc_str, diff --git a/src/test/test_reset_card.py b/src/test/test_reset_card.py index 27e5c0e4..296ee474 100644 --- a/src/test/test_reset_card.py +++ b/src/test/test_reset_card.py @@ -1174,3 +1174,233 @@ def test_reset_card_versions(session: Session) -> None: v2 = ResetCardV2(session=session) assert is_reset_loan(v2) is True assert is_reset_product_type(v2.product_type) is True + + +def test_payment_not_adjusted_to_unbilled(session: Session) -> None: + create_lenders(session=session) + create_products(session=session) + create_user(session=session) + + user_product = create_user_product_mapping( + session=session, user_id=6, product_type="term_loan_reset" + ) + create_loan(session=session, user_product=user_product, lender_id=1756833) + user_loan = get_user_product( + session=session, user_id=user_product.user_id, card_type="term_loan_reset" + ) + assert isinstance(user_loan, ResetCard) == True + + fee = create_loan_fee( + session=session, + user_loan=user_loan, + post_date=parse_date("2021-08-01 00:00:00"), + gross_amount=Decimal("100"), + include_gst_from_gross_amount=False, + fee_name="reset_joining_fees", + ) + + payment_date = parse_date("2021-08-01") + amount = fee.gross_amount + payment_request_id = "dummy_reset_fee_1" + payment_request_data( + session=session, + type="reset_joining_fees", + payment_request_amount=amount, + user_id=user_product.user_id, + payment_request_id=payment_request_id, + ) + payment_requests_data = pay_payment_request( + session=session, payment_request_id=payment_request_id, payment_date=payment_date + ) + payment_received( + session=session, + user_loan=user_loan, + payment_request_data=payment_requests_data, + ) + settle_payment_in_bank( + session=session, + payment_request_id=payment_request_id, + gateway_expenses=payment_requests_data.payment_execution_charges, + gross_payment_amount=payment_requests_data.payment_request_amount, + settlement_date=payment_requests_data.payment_received_in_bank_date, + user_loan=user_loan, + ) + payment_ledger_event = ( + session.query(LedgerTriggerEvent) + .filter( + LedgerTriggerEvent.name == "payment_received", + LedgerTriggerEvent.extra_details["payment_request_id"].astext == payment_request_id, + ) + .first() + ) + assert payment_ledger_event.amount == amount + + session.flush() + + loan_creation_data = {"date_str": "2021-08-01", "user_product_id": user_product.id} + + # create loan + loan = create_test_term_loan(session=session, **loan_creation_data) + + _, rc_cash_balance = get_account_balance_from_str( + session=session, book_string=f"12345/redcarpet/rc_cash/a" + ) + assert rc_cash_balance == Decimal("-10000") + + assert loan.product_type == "term_loan_reset" + assert loan.amortization_date == parse_date("2021-08-01").date() + + loan_data = session.query(LoanData).filter(LoanData.loan_id == user_loan.loan_id).one() + + assert loan_data.bill_start_date == parse_date("2021-08-01").date() + assert loan_data.bill_close_date == parse_date("2022-07-01").date() + + _, principal_receivable = get_account_balance_from_str( + session=session, book_string=f"{loan_data.id}/bill/principal_receivable/a" + ) + assert principal_receivable == Decimal("10000") + + all_emis = user_loan.get_loan_schedule() + + assert len(all_emis) == 12 + assert all_emis[0].due_date == parse_date("2021-08-01").date() + assert all_emis[0].emi_number == 1 + assert all_emis[0].interest_due == Decimal("300.67") + assert all_emis[0].total_due_amount == Decimal("1134") + + assert all_emis[-1].due_date == parse_date("2022-07-01").date() + assert all_emis[-1].emi_number == 12 + assert all_emis[-1].interest_due == Decimal("300.67") + assert all_emis[-1].total_due_amount == Decimal("1134") + + interest_left_to_accrue = get_interest_left_to_accrue(session, user_loan) + assert interest_left_to_accrue == Decimal("3608.04") + + create_card_swipe( + session=session, + user_loan=user_loan, + txn_time=parse_date("2021-08-01 11:22:11"), + amount=Decimal(1000), + description="Flipkart.com", + txn_ref_no="dummy_txn_ref_no_2", + trace_no="123456", + ) + session.flush() + _, loan_lender_payable = get_account_balance_from_str( + session=session, book_string=f"{user_loan.loan_id}/loan/lender_payable/l" + ) + assert loan_lender_payable == Decimal("882.50") + + payment_date = parse_date("2021-08-25") + amount = Decimal(1134) + payment_request_id = "dummy_reset_fee_2" + payment_request_data( + session=session, + type="collection", + payment_request_amount=amount, + user_id=user_product.user_id, + payment_request_id=payment_request_id, + ) + payment_requests_data = pay_payment_request( + session=session, payment_request_id=payment_request_id, payment_date=payment_date + ) + payment_received( + session=session, + user_loan=user_loan, + payment_request_data=payment_requests_data, + ) + settle_payment_in_bank( + session=session, + payment_request_id=payment_request_id, + gateway_expenses=payment_requests_data.payment_execution_charges, + gross_payment_amount=payment_requests_data.payment_request_amount, + settlement_date=payment_requests_data.payment_received_in_bank_date, + user_loan=user_loan, + ) + + payment_ledger_event = ( + session.query(LedgerTriggerEvent) + .filter( + LedgerTriggerEvent.name == "payment_received", + LedgerTriggerEvent.extra_details["payment_request_id"].astext == payment_request_id, + ) + .first() + ) + assert payment_ledger_event.amount == amount + + _, principal_receivable = get_account_balance_from_str( + session=session, book_string=f"{loan_data.id}/bill/principal_receivable/a" + ) + assert principal_receivable == Decimal(8866) + + _, unbilled = get_account_balance_from_str( + session=session, book_string=f"{loan_data.id}/bill/unbilled/a" + ) + assert unbilled == Decimal(1000) + + create_card_swipe( + session=session, + user_loan=user_loan, + txn_time=parse_date("2021-08-26 11:22:11"), + amount=Decimal(1000), + description="Flipkart.com", + txn_ref_no="dummy_txn_ref_no_3", + trace_no="123456", + ) + + _, unbilled = get_account_balance_from_str( + session=session, book_string=f"{loan_data.id}/bill/unbilled/a" + ) + assert unbilled == Decimal(2000) + + payment_date = parse_date("2021-08-25") + amount = Decimal(9866) + payment_request_id = "dummy_reset_fee_3" + payment_request_data( + session=session, + type="collection", + payment_request_amount=amount, + user_id=user_product.user_id, + payment_request_id=payment_request_id, + ) + payment_requests_data = pay_payment_request( + session=session, payment_request_id=payment_request_id, payment_date=payment_date + ) + payment_received( + session=session, + user_loan=user_loan, + payment_request_data=payment_requests_data, + ) + settle_payment_in_bank( + session=session, + payment_request_id=payment_request_id, + gateway_expenses=payment_requests_data.payment_execution_charges, + gross_payment_amount=payment_requests_data.payment_request_amount, + settlement_date=payment_requests_data.payment_received_in_bank_date, + user_loan=user_loan, + ) + + payment_ledger_event = ( + session.query(LedgerTriggerEvent) + .filter( + LedgerTriggerEvent.name == "payment_received", + LedgerTriggerEvent.extra_details["payment_request_id"].astext == payment_request_id, + ) + .first() + ) + assert payment_ledger_event.amount == amount + + _, principal_receivable = get_account_balance_from_str( + session=session, book_string=f"{loan_data.id}/bill/principal_receivable/a" + ) + assert principal_receivable == Decimal(0) + + _, unbilled = get_account_balance_from_str( + session=session, book_string=f"{loan_data.id}/bill/unbilled/a" + ) + assert unbilled == Decimal(2000) + + _, early_close_balance = get_account_balance_from_str( + session=session, book_string=f"{loan.loan_id}/loan/early_close_fee/r" + ) + assert early_close_balance == Decimal("847.46")