fix: Applicant-Wise Loan Security Exposure report

This commit is contained in:
Deepesh Garg 2021-01-16 18:10:01 +05:30
parent d3634f6dac
commit 7976d12ed0
5 changed files with 153 additions and 2 deletions

View File

@ -0,0 +1,9 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
/* eslint-disable */
frappe.query_reports["Applicant-Wise Loan Security Exposure"] = {
"filters": [
]
};

View File

@ -0,0 +1,29 @@
{
"add_total_row": 0,
"columns": [],
"creation": "2021-01-15 23:48:38.913514",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [],
"idx": 0,
"is_standard": "Yes",
"modified": "2021-01-15 23:48:38.913514",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Applicant-Wise Loan Security Exposure",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "Loan Security",
"report_name": "Applicant-Wise Loan Security Exposure",
"report_type": "Script Report",
"roles": [
{
"role": "System Manager"
},
{
"role": "Loan Manager"
}
]
}

View File

@ -0,0 +1,112 @@
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import get_datetime, flt
from six import iteritems
def execute(filters=None):
columns = get_columns(filters)
data = get_data(filters)
return columns, data
def get_columns(filters):
columns = [
{"label": _("Applicant Type"), "fieldname": "applicant_type", "options": "DocType", "width": 100},
{"label": _("Applicant Name"), "fieldname": "applicant_name", "fieldtype": "Dynamic Link", "options": "applicant_type", "width": 150},
{"label": _("Loan Security"), "fieldname": "loan_security", "fieldtype": "Link", "options": "Loan Security", "width": 160},
{"label": _("Loan Security Code"), "fieldname": "loan_security_code", "fieldtype": "Data", "width": 100},
{"label": _("Loan Security Name"), "fieldname": "loan_security_name", "fieldtype": "Data", "width": 150},
{"label": _("Haircut"), "fieldname": "haircut", "fieldtype": "Percent", "width": 100},
{"label": _("Loan Security Type"), "fieldname": "loan_security_type", "fieldtype": "Link", "options": "Loan Security Type", "width": 120},
{"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": _("Current Value"), "fieldname": "current_value", "fieldtype": "Currency", "options": "Currency", "width": 100},
{"label": _("% Of Applicant Portfolio"), "fieldname": "portfolio_percent", "fieldtype": "Percentage", "width": 100}
]
return columns
def get_data(filters):
data = []
loan_security_details = get_loan_security_details(filters)
pledge_values, total_value_map, applicant_type_map = get_applicant_wise_total_loan_security_qty(loan_security_details)
for key, qty in iteritems(pledge_values):
row = {}
current_value = flt(qty * loan_security_details.get(key[1])['latest_price'])
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,
'portfolio_percent': current_value * 100 / total_value_map.get(key[0])
})
data.append(row)
return data
def get_loan_security_details(filters):
update_time = get_datetime()
security_detail_map = {}
loan_security_price_map = frappe._dict(frappe.db.sql("""
SELECT loan_security, loan_security_price
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))
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_detail_map.setdefault(security.loan_security, security)
return security_detail_map
def get_applicant_wise_total_loan_security_qty(loan_security_details):
current_pledges = {}
total_value_map = {}
applicant_type_map = {}
applicant_wise_unpledges = {}
unpledges = frappe.db.sql("""
SELECT up.applicant, u.loan_security, sum(u.qty) as qty
FROM `tabLoan Security Unpledge` up, `tabUnpledge` u
WHERE u.parent = up.name
AND up.status = 'Approved'
GROUP BY up.applicant, u.loan_security
""", as_dict=1)
for unpledge in unpledges:
applicant_wise_unpledges.setdefault((unpledge.applicant, unpledge.loan_security), unpledge.qty)
pledges = frappe.db.sql("""
SELECT lp.applicant_type, lp.applicant, p.loan_security, sum(p.qty) as qty
FROM `tabLoan Security Pledge` lp, `tabPledge`p
WHERE p.parent = lp.name
AND lp.status = 'Pledged'
GROUP BY lp.applicant, p.loan_security
""", as_dict=1)
for security in pledges:
current_pledges.setdefault((security.applicant, security.loan_security), security.qty)
total_value_map.setdefault(security.applicant, 0.0)
applicant_type_map.setdefault(security.applicant, security.applicant_type)
current_pledges[(security.applicant, security.loan_security)] -= \
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']
return current_pledges, total_value_map, applicant_type_map

View File

@ -15,6 +15,7 @@ def execute(filters=None):
def get_columns(filters):
columns = [
{"label": _("Loan"), "fieldname": "loan", "fieldtype": "Link", "options": "Loan", "width": 160},
{"label": _("Status"), "fieldname": "status", "fieldtype": "Data", "width": 160},
{"label": _("Applicant Type"), "fieldname": "applicant_type", "options": "DocType", "width": 100},
{"label": _("Applicant Name"), "fieldname": "applicant_name", "fieldtype": "Dynamic Link", "options": "applicant_type", "width": 150},
{"label": _("Loan Type"), "fieldname": "loan_type", "fieldtype": "Link", "options": "Loan Type", "width": 100},
@ -37,7 +38,7 @@ def get_active_loan_details(filters):
loan_details = frappe.get_all("Loan",
fields=["name as loan", "applicant_type", "applicant as applicant_name", "loan_type",
"disbursed_amount", "rate_of_interest", "total_payment", "total_principal_paid",
"total_interest_payable", "written_off_amount"],
"total_interest_payable", "written_off_amount", "status"],
filters={"status": ("!=", "Closed")})
loan_list = [d.loan for d in loan_details]
@ -70,7 +71,7 @@ def get_interest_accruals(loans):
current_month_start = get_first_day(getdate())
interest_accruals = frappe.get_all("Loan Interest Accrual",
fields=["loan", "interest_amount", "posting_date", "penalty"],
fields=["loan", "interest_amount", "posting_date", "penalty_amount"],
filters={"loan": ("in", loans)})
for entry in interest_accruals: