fix: Applicant-Wise Loan Security Exposure report
This commit is contained in:
parent
d3634f6dac
commit
7976d12ed0
@ -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": [
|
||||||
|
|
||||||
|
]
|
||||||
|
};
|
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -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
|
@ -15,6 +15,7 @@ def execute(filters=None):
|
|||||||
def get_columns(filters):
|
def get_columns(filters):
|
||||||
columns = [
|
columns = [
|
||||||
{"label": _("Loan"), "fieldname": "loan", "fieldtype": "Link", "options": "Loan", "width": 160},
|
{"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 Type"), "fieldname": "applicant_type", "options": "DocType", "width": 100},
|
||||||
{"label": _("Applicant Name"), "fieldname": "applicant_name", "fieldtype": "Dynamic Link", "options": "applicant_type", "width": 150},
|
{"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},
|
{"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",
|
loan_details = frappe.get_all("Loan",
|
||||||
fields=["name as loan", "applicant_type", "applicant as applicant_name", "loan_type",
|
fields=["name as loan", "applicant_type", "applicant as applicant_name", "loan_type",
|
||||||
"disbursed_amount", "rate_of_interest", "total_payment", "total_principal_paid",
|
"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")})
|
filters={"status": ("!=", "Closed")})
|
||||||
|
|
||||||
loan_list = [d.loan for d in loan_details]
|
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())
|
current_month_start = get_first_day(getdate())
|
||||||
|
|
||||||
interest_accruals = frappe.get_all("Loan Interest Accrual",
|
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)})
|
filters={"loan": ("in", loans)})
|
||||||
|
|
||||||
for entry in interest_accruals:
|
for entry in interest_accruals:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user