fix: Add loan to value field in Loan Interest Report
diff --git a/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.py b/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.py
index 6d7c3b7..f280402 100644
--- a/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.py
+++ b/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.py
@@ -26,6 +26,7 @@
{"label": _("Disabled"), "fieldname": "disabled", "fieldtype": "Check", "width": 80},
{"label": _("Total Qty"), "fieldname": "total_qty", "fieldtype": "Float", "width": 100},
{"label": _("Latest Price"), "fieldname": "latest_price", "fieldtype": "Currency", "options": "currency", "width": 100},
+ {"label": _("Price Valid Upto"), "fieldname": "price_valid_upto", "fieldtype": "Datetime", "width": 100},
{"label": _("Current Value"), "fieldname": "current_value", "fieldtype": "Currency", "options": "currency", "width": 100},
{"label": _("% Of Applicant Portfolio"), "fieldname": "portfolio_percent", "fieldtype": "Percentage", "width": 100},
{"label": _("Currency"), "fieldname": "currency", "fieldtype": "Currency", "options": "Currency", "hidden": 1, "width": 100},
@@ -43,13 +44,16 @@
for key, qty in iteritems(pledge_values):
row = {}
- current_value = flt(qty * loan_security_details.get(key[1])['latest_price'])
+ current_value = flt(qty * loan_security_details.get(key[1], {}).get('latest_price', 0))
+ valid_upto = loan_security_details.get(key[1], {}).get('valid_upto')
+
row.update(loan_security_details.get(key[1]))
row.update({
'applicant_type': applicant_type_map.get(key[0]),
'applicant_name': key[0],
'total_qty': qty,
'current_value': current_value,
+ 'price_valid_upto': valid_upto,
'portfolio_percent': flt(current_value * 100 / total_value_map.get(key[0]), 2),
'currency': currency
})
@@ -60,20 +64,30 @@
def get_loan_security_details(filters):
security_detail_map = {}
+ loan_security_price_map = {}
+ lsp_validity_map = {}
- loan_security_price_map = frappe._dict(frappe.db.sql("""
- SELECT loan_security, loan_security_price
+ loan_security_prices = frappe.db.sql("""
+ SELECT loan_security, loan_security_price, valid_upto
FROM `tabLoan Security Price` t1
WHERE valid_from >= (SELECT MAX(valid_from) FROM `tabLoan Security Price` t2
WHERE t1.loan_security = t2.loan_security)
- """, as_list=1))
+ """, as_dict=1)
+
+ for security in loan_security_prices:
+ loan_security_price_map.setdefault(security.loan_security, security.loan_security_price)
+ lsp_validity_map.setdefault(security.loan_security, security.valid_upto)
loan_security_details = frappe.get_all('Loan Security', fields=['name as loan_security',
'loan_security_code', 'loan_security_name', 'haircut', 'loan_security_type',
'disabled'])
for security in loan_security_details:
- security.update({'latest_price': flt(loan_security_price_map.get(security.loan_security))})
+ security.update({
+ 'latest_price': flt(loan_security_price_map.get(security.loan_security)),
+ 'valid_upto': lsp_validity_map.get(security.loan_security)
+ })
+
security_detail_map.setdefault(security.loan_security, security)
return security_detail_map
@@ -118,6 +132,6 @@
applicant_wise_unpledges.get((security.applicant, security.loan_security), 0.0)
total_value_map[security.applicant] += current_pledges.get((security.applicant, security.loan_security)) \
- * loan_security_details.get(security.loan_security)['latest_price']
+ * loan_security_details.get(security.loan_security, {}).get('latest_price', 0)
return current_pledges, total_value_map, applicant_type_map
\ No newline at end of file
diff --git a/erpnext/loan_management/report/loan_interest_report/loan_interest_report.py b/erpnext/loan_management/report/loan_interest_report/loan_interest_report.py
index aa0325e..2bfe6d3 100644
--- a/erpnext/loan_management/report/loan_interest_report/loan_interest_report.py
+++ b/erpnext/loan_management/report/loan_interest_report/loan_interest_report.py
@@ -6,6 +6,8 @@
import erpnext
from frappe import _
from frappe.utils import flt, getdate, add_days
+from erpnext.loan_management.report.applicant_wise_loan_security_exposure.applicant_wise_loan_security_exposure \
+ import get_loan_security_details
def execute(filters=None):
@@ -31,6 +33,7 @@
{"label": _("Undue Booked Interest"), "fieldname": "undue_interest", "fieldtype": "Currency", "options": "currency", "width": 120},
{"label": _("Interest %"), "fieldname": "rate_of_interest", "fieldtype": "Percent", "width": 100},
{"label": _("Penalty Interest %"), "fieldname": "penalty_interest", "fieldtype": "Percent", "width": 100},
+ {"label": _("Loan To Value Ratio"), "fieldname": "loan_to_value", "fieldtype": "Percent", "width": 100},
{"label": _("Currency"), "fieldname": "currency", "fieldtype": "Currency", "options": "Currency", "hidden": 1, "width": 100},
]
@@ -50,6 +53,9 @@
loan_list = [d.loan for d in loan_details]
+ current_pledges = get_loan_wise_pledges(filters)
+ loan_wise_security_value = get_loan_wise_security_value(filters, current_pledges)
+
sanctioned_amount_map = get_sanctioned_amount_map()
penal_interest_rate_map = get_penal_interest_rate_map()
payments = get_payments(loan_list)
@@ -67,12 +73,16 @@
"penalty": flt(accrual_map.get(loan.loan, {}).get("penalty")),
"penalty_interest": penal_interest_rate_map.get(loan.loan_type),
"undue_interest": flt(accrual_map.get(loan.loan, {}).get("undue_interest")),
+ "loan_to_value": 0.0,
"currency": currency
})
loan['total_outstanding'] = loan['principal_outstanding'] + loan['interest_outstanding'] \
+ loan['penalty']
+ if loan_wise_security_value.get(loan.loan):
+ loan['loan_to_value'] = (loan['principal_outstanding'] * 100) / loan_wise_security_value.get(loan.loan)
+
return loan_details
def get_sanctioned_amount_map():
@@ -121,4 +131,53 @@
return accrual_map
def get_penal_interest_rate_map():
- return frappe._dict(frappe.get_all("Loan Type", fields=["name", "penalty_interest_rate"], as_list=1))
\ No newline at end of file
+ return frappe._dict(frappe.get_all("Loan Type", fields=["name", "penalty_interest_rate"], as_list=1))
+
+def get_loan_wise_pledges(filters):
+ loan_wise_unpledges = {}
+ current_pledges = {}
+
+ conditions = ""
+
+ if filters.get('company'):
+ conditions = "AND company = %(company)s"
+
+ unpledges = frappe.db.sql("""
+ SELECT up.loan, u.loan_security, sum(u.qty) as qty
+ FROM `tabLoan Security Unpledge` up, `tabUnpledge` u
+ WHERE u.parent = up.name
+ AND up.status = 'Approved'
+ {conditions}
+ GROUP BY up.loan
+ """.format(conditions=conditions), filters, as_dict=1)
+
+ for unpledge in unpledges:
+ loan_wise_unpledges.setdefault((unpledge.loan, unpledge.loan_security), unpledge.qty)
+
+ pledges = frappe.db.sql("""
+ SELECT lp.loan, p.loan_security, sum(p.qty) as qty
+ FROM `tabLoan Security Pledge` lp, `tabPledge`p
+ WHERE p.parent = lp.name
+ AND lp.status = 'Pledged'
+ {conditions}
+ GROUP BY lp.loan
+ """.format(conditions=conditions), filters, as_dict=1)
+
+ for security in pledges:
+ current_pledges.setdefault((security.loan, security.loan_security), security.qty)
+ current_pledges[(security.loan, security.loan_security)] -= \
+ loan_wise_unpledges.get((security.loan, security.loan_security), 0.0)
+
+ return current_pledges
+
+def get_loan_wise_security_value(filters, current_pledges):
+ loan_security_details = get_loan_security_details(filters)
+ loan_wise_security_value = {}
+
+ for key in current_pledges:
+ qty = current_pledges.get(key)
+ loan_wise_security_value.setdefault(key[0], 0.0)
+ loan_wise_security_value[key[0]] += \
+ flt(qty * loan_security_details.get(key[1], {}).get('latest_price', 0))
+
+ return loan_wise_security_value
\ No newline at end of file
diff --git a/erpnext/loan_management/report/loan_security_exposure/loan_security_exposure.py b/erpnext/loan_management/report/loan_security_exposure/loan_security_exposure.py
index 3ef10c0..ff88052 100644
--- a/erpnext/loan_management/report/loan_security_exposure/loan_security_exposure.py
+++ b/erpnext/loan_management/report/loan_security_exposure/loan_security_exposure.py
@@ -24,6 +24,7 @@
{"label": _("Disabled"), "fieldname": "disabled", "fieldtype": "Check", "width": 80},
{"label": _("Total Qty"), "fieldname": "total_qty", "fieldtype": "Float", "width": 100},
{"label": _("Latest Price"), "fieldname": "latest_price", "fieldtype": "Currency", "options": "currency", "width": 100},
+ {"label": _("Price Valid Upto"), "fieldname": "price_valid_upto", "fieldtype": "Datetime", "width": 100},
{"label": _("Current Value"), "fieldname": "current_value", "fieldtype": "Currency", "options": "currency", "width": 100},
{"label": _("% Of Total Portfolio"), "fieldname": "portfolio_percent", "fieldtype": "Percentage", "width": 100},
{"label": _("Pledged Applicant Count"), "fieldname": "pledged_applicant_count", "fieldtype": "Percentage", "width": 100},
@@ -40,13 +41,16 @@
for security, value in iteritems(current_pledges):
row = {}
- current_value = flt(value['qty'] * loan_security_details.get(security)['latest_price'])
+ current_value = flt(value.get('qty', 0) * loan_security_details.get(security, {}).get('latest_price', 0))
+ valid_upto = loan_security_details.get(security, {}).get('valid_upto')
+
row.update(loan_security_details.get(security))
row.update({
- 'total_qty': value['qty'],
+ 'total_qty': value.get('qty'),
'current_value': current_value,
+ 'price_valid_upto': valid_upto,
'portfolio_percent': flt(current_value * 100 / total_portfolio_value, 2),
- 'pledged_applicant_count': value['applicant_count'],
+ 'pledged_applicant_count': value.get('applicant_count'),
'currency': currency
})