fix: Applicant-Wise Loan Security Exposure report
diff --git a/erpnext/loan_management/report/applicant_wise_loan_security_exposure/__init__.py b/erpnext/loan_management/report/applicant_wise_loan_security_exposure/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/loan_management/report/applicant_wise_loan_security_exposure/__init__.py
diff --git a/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.js b/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.js
new file mode 100644
index 0000000..e954a39
--- /dev/null
+++ b/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.js
@@ -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": [
+
+ ]
+};
diff --git a/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.json b/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.json
new file mode 100644
index 0000000..a778cd7
--- /dev/null
+++ b/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.json
@@ -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"
+ }
+ ]
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..6b7f3ad
--- /dev/null
+++ b/erpnext/loan_management/report/applicant_wise_loan_security_exposure/applicant_wise_loan_security_exposure.py
@@ -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
\ 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 e039fe8..e38770b 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
@@ -15,6 +15,7 @@
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 @@
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 @@
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: