diff --git a/lending/loan_management/doctype/loan/test_loan.py b/lending/loan_management/doctype/loan/test_loan.py index 64f84fda..f380f5c6 100644 --- a/lending/loan_management/doctype/loan/test_loan.py +++ b/lending/loan_management/doctype/loan/test_loan.py @@ -1333,16 +1333,28 @@ def test_npa_for_loc(self): loan.submit() - make_loan_disbursement_entry( + disbursement = make_loan_disbursement_entry( loan.name, loan.loan_amount, disbursement_date="2024-03-06", repayment_start_date="2024-04-05" ) + + # Test Limit Update + loan.load_from_db() + self.assertEqual(loan.utilized_limit_amount, 500000) + self.assertEqual(loan.available_limit_amount, 0) + process_daily_loan_demands(posting_date="2024-04-05", loan=loan.name) create_process_loan_classification(posting_date="2024-10-05", loan=loan.name) - repayment_entry = create_repayment_entry(loan.name, "2024-10-05", 47523) + repayment_entry = create_repayment_entry( + loan.name, "2024-10-05", 47523, loan_disbursement=disbursement.name + ) repayment_entry.submit() + loan.load_from_db() + self.assertEqual(loan.utilized_limit_amount, 500000 - repayment_entry.principal_amount_paid) + self.assertEqual(loan.available_limit_amount, repayment_entry.principal_amount_paid) + def test_shortfall_loan_close_limit(self): loan = create_loan( "_Test Customer 1", @@ -1902,13 +1914,16 @@ def create_loan_security_price(loan_security, loan_security_price, uom, from_dat ).insert(ignore_permissions=True) -def create_repayment_entry(loan, posting_date, paid_amount, repayment_type="Normal Repayment"): +def create_repayment_entry( + loan, posting_date, paid_amount, repayment_type="Normal Repayment", loan_disbursement=None +): lr = frappe.new_doc("Loan Repayment") lr.against_loan = loan lr.company = "_Test Company" lr.posting_date = posting_date or nowdate() lr.amount_paid = paid_amount lr.repayment_type = repayment_type + lr.loan_disbursement = loan_disbursement lr.insert(ignore_permissions=True) return lr diff --git a/lending/loan_management/doctype/loan_demand/loan_demand.json b/lending/loan_management/doctype/loan_demand/loan_demand.json index 4e1cdf17..820e5c9e 100644 --- a/lending/loan_management/doctype/loan_demand/loan_demand.json +++ b/lending/loan_management/doctype/loan_demand/loan_demand.json @@ -52,8 +52,7 @@ "fieldtype": "Select", "in_list_view": 1, "label": "Demand Type", - "options": "EMI\nPenalty\nNormal\nCharges\nBPI\nAdditional Interest", - "search_index": 1 + "options": "EMI\nPenalty\nNormal\nCharges\nBPI\nAdditional Interest" }, { "fieldname": "demand_amount", @@ -69,8 +68,7 @@ "no_copy": 1, "options": "Loan Demand", "print_hide": 1, - "read_only": 1, - "search_index": 1 + "read_only": 1 }, { "fieldname": "loan", @@ -116,8 +114,7 @@ "fieldname": "applicant_type", "fieldtype": "Link", "label": "Applicant Type", - "options": "DocType", - "search_index": 1 + "options": "DocType" }, { "fetch_from": "loan.applicant", @@ -137,8 +134,7 @@ "fieldname": "demand_subtype", "fieldtype": "Data", "in_list_view": 1, - "label": "Demand Subtype", - "search_index": 1 + "label": "Demand Subtype" }, { "fetch_from": "loan.company", @@ -234,7 +230,7 @@ "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2024-11-26 21:19:21.444155", + "modified": "2025-01-29 14:12:33.665969", "modified_by": "Administrator", "module": "Loan Management", "name": "Loan Demand", diff --git a/lending/loan_management/doctype/loan_repayment/loan_repayment.py b/lending/loan_management/doctype/loan_repayment/loan_repayment.py index 14587244..30183329 100644 --- a/lending/loan_management/doctype/loan_repayment/loan_repayment.py +++ b/lending/loan_management/doctype/loan_repayment/loan_repayment.py @@ -139,7 +139,6 @@ def on_submit(self): self.update_paid_amounts() self.update_demands() - self.update_limits() self.update_security_deposit_amount() update_installment_counts(self.against_loan, loan_disbursement=self.loan_disbursement) @@ -463,7 +462,6 @@ def on_cancel(self): self.check_future_accruals() self.mark_as_unpaid() self.update_demands(cancel=1) - self.update_limits(cancel=1) self.update_security_deposit_amount(cancel=1) frappe.db.set_value("Loan", self.against_loan, "days_past_due", self.days_past_due) @@ -767,6 +765,7 @@ def update_paid_amounts(self): if not self.flags.from_repost: self.reverse_future_accruals_and_demands(on_settlement_or_closure=True) + query = self.update_limits(query, loan) query.run() update_shortfall_status(self.against_loan, self.principal_amount_paid) @@ -876,16 +875,19 @@ def auto_close_loan(self): shortfall_amount = self.pending_principal_amount - self.principal_amount_paid if self.repayment_type in ("Interest Waiver", "Penalty Waiver", "Charges Waiver"): - total_payable = frappe.db.get_value( - "Loan Demand", - { - "loan": self.against_loan, - "docstatus": 1, - "outstanding_amount": (">", 0), - "demand_date": ("<=", self.posting_date), - }, - "sum(outstanding_amount)", - ) or 0 + total_payable = ( + frappe.db.get_value( + "Loan Demand", + { + "loan": self.against_loan, + "docstatus": 1, + "outstanding_amount": (">", 0), + "demand_date": ("<=", self.posting_date), + }, + "sum(outstanding_amount)", + ) + or 0 + ) else: total_payable = self.payable_amount @@ -962,6 +964,7 @@ def mark_as_unpaid(self): if flt(self.excess_amount) > 0: query = query.set(loan.excess_amount_paid, loan.excess_amount_paid - self.excess_amount) + query = self.update_limits(query, loan, cancel=1) query.run() def update_demands(self, cancel=0): @@ -989,21 +992,19 @@ def update_demands(self, cancel=0): loan_demand.name == payment.loan_demand ).run() - def update_limits(self, cancel=0): + def update_limits(self, query, loan, cancel=0): principal_amount_paid = self.principal_amount_paid if cancel: principal_amount_paid = -1 * flt(self.principal_amount_paid) - loan = frappe.qb.DocType("Loan") - if self.repayment_schedule_type == "Line of Credit": - frappe.qb.update(loan).set( - loan.available_limit_amount, loan.available_limit_amount + principal_amount_paid - ).set( - loan.utilized_limit_amount, loan.utilized_limit_amount - principal_amount_paid - ).where( - loan.name == self.against_loan - ).run() + query = ( + query.set(loan.available_limit_amount, loan.available_limit_amount + principal_amount_paid) + .set(loan.utilized_limit_amount, loan.utilized_limit_amount - principal_amount_paid) + .where(loan.name == self.against_loan) + ) + + return query def update_security_deposit_amount(self, cancel=0): if self.repayment_type == "Security Deposit Adjustment":