fix: handle missing repayment schedule in advance payment validation#1243
fix: handle missing repayment schedule in advance payment validation#1243Hemil-Sangani wants to merge 4 commits into
Conversation
WalkthroughThe PR updates validate_advance_payment to fail if no active monthly_repayment_amount is found, round monthly_repayment_amount and amount_paid to currency precision once, and perform the existing check that the rounded advance payment lies between one and two times the rounded EMI. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
f5ef3ae to
ab2244a
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lending/loan_management/doctype/loan_repayment/loan_repayment.py`:
- Around line 1727-1741: The code currently converts the DB result directly with
flt which turns None into 0 and leads to misleading validation; change the logic
in loan_repayment.py around the retrieval of "monthly_repayment_amount" so you
first read the raw value (e.g., raw_monthly = frappe.db.get_value("Loan
Repayment Schedule", filters, "monthly_repayment_amount")), check if raw_monthly
is None and if so raise a clear error with frappe.throw (e.g., "Loan Repayment
Schedule not found for selected criteria" or similar), and only then set
monthly_repayment_amount = flt(raw_monthly, precision) before performing the
amount_paid bounds check; reference the variables monthly_repayment_amount,
raw_monthly, filters, and amount_paid when making the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: dfe332c0-e012-4ad2-b4dc-7b72247009e8
📒 Files selected for processing (1)
lending/loan_management/doctype/loan_repayment/loan_repayment.py
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #1243 +/- ##
===========================================
- Coverage 76.45% 76.45% -0.01%
===========================================
Files 142 142
Lines 10241 10245 +4
===========================================
+ Hits 7830 7833 +3
- Misses 2411 2412 +1
🚀 New features to boost your workflow:
|
8d0446d to
7656808
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
lending/loan_management/doctype/loan_repayment/loan_repayment.py (2)
2368-2368:⚠️ Potential issue | 🟡 Minor | 💤 Low valuePrincipal Capitalization payment account mapping added.
Consistent with other capitalization types (Interest, Penalty, Charges) that also map to "loan_account", but not documented in the PR objectives.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lending/loan_management/doctype/loan_repayment/loan_repayment.py` at line 2368, The new mapping entry "Principal Capitalization": "loan_account" was added to the payment account map in loan_repayment.py but was not documented in the PR objectives; confirm this is intentional and either add/update the PR description/changelog to include this mapping or remove the entry if unintended. Locate the payment account mapping dictionary in loan_repayment.py (the mapping that currently contains "Principal Capitalization": "loan_account") and either (a) keep the mapping and add a brief inline comment explaining why "Principal Capitalization" maps to "loan_account" and update the PR description/changelog to mention the change, or (b) remove the mapping if it was added by mistake and revert to the prior set of capitalization types.
2039-2041:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdditional Principal Capitalization logic not documented in PR.
This guard prevents GL entries for Principal Capitalization during loan restructure when no sales invoices are present in repayment details. Like the change at lines 127-134, this Principal Capitalization functionality is not mentioned in the PR objectives.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lending/loan_management/doctype/loan_repayment/loan_repayment.py` around lines 2039 - 2041, The new conditional in loan_repayment.py (checking self.repayment_type == "Principal Capitalization" and self.loan_restructure and not any(d.sales_invoice for d in self.get("repayment_details"))) introduces undocumented behavior that suppresses GL entries for Principal Capitalization during restructures; update the code and PR by either removing or adjusting this guard to match intended business logic in the loan repayment flow, or if the guard is required, add an inline comment next to this conditional referencing the business rule and add a note to the PR description explaining why Principal Capitalization GL entries are suppressed when loan_restructure is true and no repayment_details have sales_invoice (refer to repayment_details and the use of any(d.sales_invoice for d in self.get("repayment_details")) for locating the check).
🧹 Nitpick comments (1)
lending/loan_management/doctype/loan_repayment/loan_repayment.py (1)
127-134: ⚡ Quick winClarify scope of the “Principal Capitalization” handling in this PR
- “Principal Capitalization” is already used across the lending flow (e.g., in
lending/loan_management/doctype/loan_adjustment_detail/loan_adjustment_detail.pyandlending/loan_management/doctype/loan_restructure/loan_restructure.pywhen creatingloan_repayment).- This PR further extends
loan_repayment.pyto (1) allowpayable_chargesforPrincipal Capitalizationduringloan_restructureand (2) add a GL-entry guard + mapPrincipal Capitalizationtoloan_account.- Please ensure this PR (or
#1240) explicitly calls out thesePrincipal Capitalizationbehavior changes, or confirm they should be tracked as a separate item.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lending/loan_management/doctype/loan_repayment/loan_repayment.py` around lines 127 - 134, The change now allows payable_charges for repayment_type "Principal Capitalization" when loan_restructure is true and adds GL-entry guard + maps "Principal Capitalization" to loan_account in loan_repayment.py; update the PR description and/or changelog and add an inline comment in loan_repayment.py near the repayment_type check (the block that references self.repayment_type, self.get("payable_charges"), and self.loan_restructure) to explicitly call out that Principal Capitalization behavior has been extended here (and mention the related behavior in loan_adjustment_detail and loan_restructure modules), or split this behavioral change into a separate PR/issue if it should be tracked independently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lending/loan_management/doctype/loan_repayment/loan_repayment.py`:
- Around line 1744-1752: Add a unit test in
lending/loan_management/doctype/loan_repayment/test_loan_repayment.py that
triggers the advance-payment code path where monthly_repayment_amount is missing
and asserts that the call raises the exact message "Cannot process Advance
Payment: No active Loan Repayment Schedule found for this loan" (use
frappe.raises or pytest.raises as used elsewhere); name it something like
test_advance_payment_no_active_schedule and set up a loan with no active
repayment schedule before calling the advance-payment routine. Also, consider
tightening the guard in loan_repayment.py by changing the check from "if not
monthly_repayment_amount:" to "if monthly_repayment_amount is None:" to avoid
false negatives for zero values.
---
Duplicate comments:
In `@lending/loan_management/doctype/loan_repayment/loan_repayment.py`:
- Line 2368: The new mapping entry "Principal Capitalization": "loan_account"
was added to the payment account map in loan_repayment.py but was not documented
in the PR objectives; confirm this is intentional and either add/update the PR
description/changelog to include this mapping or remove the entry if unintended.
Locate the payment account mapping dictionary in loan_repayment.py (the mapping
that currently contains "Principal Capitalization": "loan_account") and either
(a) keep the mapping and add a brief inline comment explaining why "Principal
Capitalization" maps to "loan_account" and update the PR description/changelog
to mention the change, or (b) remove the mapping if it was added by mistake and
revert to the prior set of capitalization types.
- Around line 2039-2041: The new conditional in loan_repayment.py (checking
self.repayment_type == "Principal Capitalization" and self.loan_restructure and
not any(d.sales_invoice for d in self.get("repayment_details"))) introduces
undocumented behavior that suppresses GL entries for Principal Capitalization
during restructures; update the code and PR by either removing or adjusting this
guard to match intended business logic in the loan repayment flow, or if the
guard is required, add an inline comment next to this conditional referencing
the business rule and add a note to the PR description explaining why Principal
Capitalization GL entries are suppressed when loan_restructure is true and no
repayment_details have sales_invoice (refer to repayment_details and the use of
any(d.sales_invoice for d in self.get("repayment_details")) for locating the
check).
---
Nitpick comments:
In `@lending/loan_management/doctype/loan_repayment/loan_repayment.py`:
- Around line 127-134: The change now allows payable_charges for repayment_type
"Principal Capitalization" when loan_restructure is true and adds GL-entry guard
+ maps "Principal Capitalization" to loan_account in loan_repayment.py; update
the PR description and/or changelog and add an inline comment in
loan_repayment.py near the repayment_type check (the block that references
self.repayment_type, self.get("payable_charges"), and self.loan_restructure) to
explicitly call out that Principal Capitalization behavior has been extended
here (and mention the related behavior in loan_adjustment_detail and
loan_restructure modules), or split this behavioral change into a separate
PR/issue if it should be tracked independently.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fa3712f0-8565-4d46-bf67-4a242381bc87
📒 Files selected for processing (1)
lending/loan_management/doctype/loan_repayment/loan_repayment.py
|
@Nihantra-Patel Sir, could you please review this when you get a chance? |
Description
Handles cases where no matching
Loan Repayment Scheduleexists during Advance Payment validation for term loans.frappe.db.get_value()returnsNonewhen no matching repayment schedule is found, which causes invalid numeric comparisons during validation.This change safely normalizes values using
flt()before comparison.Changes
monthly_repayment_amountwithflt()amount_paidusingflt()NoneTypecomparison issues during Advance Payment validationBefore
After
Closes #1240
Summary by CodeRabbit