Merge pull request #24456 from deepeshgarg007/ltv_in_report
fix: Add loan to value field in Loan Interest Report
This commit is contained in:
commit
befe32cbe1
@ -26,6 +26,7 @@ def get_columns(filters):
|
||||
{"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 @@ def get_data(filters):
|
||||
|
||||
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_data(filters):
|
||||
|
||||
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 @@ def get_applicant_wise_total_loan_security_qty(filters, loan_security_details):
|
||||
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
|
@ -6,6 +6,8 @@ import frappe
|
||||
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 @@ def get_columns(filters):
|
||||
{"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 @@ def get_active_loan_details(filters):
|
||||
|
||||
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 @@ def get_active_loan_details(filters):
|
||||
"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 @@ def get_interest_accruals(loans):
|
||||
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))
|
||||
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
|
@ -24,6 +24,7 @@ def get_columns(filters):
|
||||
{"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 @@ def get_data(filters):
|
||||
|
||||
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
|
||||
})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user