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
 		})