fix: Loan disbursement amount validation check
diff --git a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
index bfdc8b4..f58b989 100644
--- a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
+++ b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
@@ -17,6 +17,7 @@
def validate(self):
self.set_missing_values()
+ self.validate_disbursal_amount()
def on_submit(self):
self.set_status_and_amounts()
@@ -40,57 +41,21 @@
if not self.bank_account and self.applicant_type == "Customer":
self.bank_account = frappe.db.get_value("Customer", self.applicant, "default_bank_account")
- def set_status_and_amounts(self, cancel=0):
+ def validate_disbursal_amount(self):
+ possible_disbursal_amount = get_disbursal_amount(self.against_loan)
+ if self.disbursed_amount > possible_disbursal_amount:
+ frappe.throw(_("Disbursed Amount cannot be greater than {0}").format(possible_disbursal_amount))
+
+ def set_status_and_amounts(self, cancel=0):
loan_details = frappe.get_all("Loan",
fields = ["loan_amount", "disbursed_amount", "total_payment", "total_principal_paid", "total_interest_payable",
"status", "is_term_loan", "is_secured_loan"], filters= { "name": self.against_loan })[0]
if cancel:
- disbursed_amount = loan_details.disbursed_amount - self.disbursed_amount
- total_payment = loan_details.total_payment
-
- if loan_details.disbursed_amount > loan_details.loan_amount:
- topup_amount = loan_details.disbursed_amount - loan_details.loan_amount
- if topup_amount > self.disbursed_amount:
- topup_amount = self.disbursed_amount
-
- total_payment = total_payment - topup_amount
-
- if disbursed_amount == 0:
- status = "Sanctioned"
- elif disbursed_amount >= loan_details.loan_amount:
- status = "Disbursed"
- else:
- status = "Partially Disbursed"
+ disbursed_amount, status, total_payment = self.get_values_on_cancel(loan_details)
else:
- disbursed_amount = self.disbursed_amount + loan_details.disbursed_amount
- total_payment = loan_details.total_payment
-
- possible_disbursal_amount = get_disbursal_amount(self.against_loan)
-
- if self.disbursed_amount > possible_disbursal_amount:
- frappe.throw(_("Disbursed Amount cannot be greater than {0}").format(possible_disbursal_amount))
-
- if loan_details.status == "Disbursed" and not loan_details.is_term_loan:
- process_loan_interest_accrual_for_demand_loans(posting_date=add_days(self.disbursement_date, -1),
- loan=self.against_loan, accrual_type="Disbursement")
-
- if disbursed_amount > loan_details.loan_amount:
- topup_amount = disbursed_amount - loan_details.loan_amount
-
- if topup_amount < 0:
- topup_amount = 0
-
- if topup_amount > self.disbursed_amount:
- topup_amount = self.disbursed_amount
-
- total_payment = total_payment + topup_amount
-
- if flt(disbursed_amount) >= loan_details.loan_amount:
- status = "Disbursed"
- else:
- status = "Partially Disbursed"
+ disbursed_amount, status, total_payment = self.get_values_on_submit(loan_details)
frappe.db.set_value("Loan", self.against_loan, {
"disbursement_date": self.disbursement_date,
@@ -99,6 +64,54 @@
"total_payment": total_payment
})
+ def get_values_on_cancel(self, loan_details):
+ disbursed_amount = loan_details.disbursed_amount - self.disbursed_amount
+ total_payment = loan_details.total_payment
+
+ if loan_details.disbursed_amount > loan_details.loan_amount:
+ topup_amount = loan_details.disbursed_amount - loan_details.loan_amount
+ if topup_amount > self.disbursed_amount:
+ topup_amount = self.disbursed_amount
+
+ total_payment = total_payment - topup_amount
+
+ if disbursed_amount == 0:
+ status = "Sanctioned"
+ total_payment = loan_details.loan_amount
+ elif disbursed_amount >= loan_details.loan_amount:
+ status = "Disbursed"
+ else:
+ status = "Partially Disbursed"
+
+ return disbursed_amount, status, total_payment
+
+ def get_values_on_submit(self, loan_details):
+ disbursed_amount = self.disbursed_amount + loan_details.disbursed_amount
+ total_payment = loan_details.total_payment
+
+ if loan_details.status == "Disbursed" and not loan_details.is_term_loan:
+ process_loan_interest_accrual_for_demand_loans(posting_date=add_days(self.disbursement_date, -1),
+ loan=self.against_loan, accrual_type="Disbursement")
+
+ if disbursed_amount > loan_details.loan_amount:
+ topup_amount = disbursed_amount - loan_details.loan_amount
+
+ if topup_amount < 0:
+ topup_amount = 0
+
+ if topup_amount > self.disbursed_amount:
+ topup_amount = self.disbursed_amount
+
+ total_payment = total_payment + topup_amount
+
+ if flt(disbursed_amount) >= loan_details.loan_amount:
+ status = "Disbursed"
+ else:
+ status = "Partially Disbursed"
+ total_payment = disbursed_amount
+
+ return disbursed_amount, status, total_payment
+
def make_gl_entries(self, cancel=0, adv_adj=0):
gle_map = []
loan_details = frappe.get_doc("Loan", self.against_loan)
@@ -155,7 +168,8 @@
pledged_securities = get_pledged_security_qty(loan)
for security, qty in pledged_securities.items():
- security_value += (loan_security_price_map.get(security) * qty * hair_cut_map.get(security))/100
+ after_haircut_percentage = 100 - hair_cut_map.get(security)
+ security_value += (loan_security_price_map.get(security) * qty * after_haircut_percentage)/100
return security_value
@@ -173,7 +187,8 @@
pending_principal_amount = flt(loan_details.total_payment) - flt(loan_details.total_interest_payable) \
- flt(loan_details.total_principal_paid)
else:
- pending_principal_amount = flt(loan_details.disbursed_amount)
+ pending_principal_amount = flt(loan_details.disbursed_amount) - flt(loan_details.total_interest_payable) \
+ - flt(loan_details.total_principal_paid)
security_value = 0.0
if loan_details.is_secured_loan:
diff --git a/erpnext/loan_management/doctype/loan_security/loan_security.json b/erpnext/loan_management/doctype/loan_security/loan_security.json
index 1d0bb30..c698601 100644
--- a/erpnext/loan_management/doctype/loan_security/loan_security.json
+++ b/erpnext/loan_management/doctype/loan_security/loan_security.json
@@ -25,6 +25,7 @@
},
{
"fetch_from": "loan_security_type.haircut",
+ "fetch_if_empty": 1,
"fieldname": "haircut",
"fieldtype": "Percent",
"label": "Haircut %"
@@ -64,8 +65,9 @@
"reqd": 1
}
],
+ "index_web_pages_for_search": 1,
"links": [],
- "modified": "2020-04-29 13:21:26.043492",
+ "modified": "2020-10-26 07:34:48.601766",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan Security",