Merge pull request #22143 from deepeshgarg007/loan_amount_precision_v13

fix: Precision in loan amount calculation 
diff --git a/erpnext/loan_management/desk_page/loan/loan.json b/erpnext/loan_management/desk_page/loan/loan.json
index d79860a..23671ea 100644
--- a/erpnext/loan_management/desk_page/loan/loan.json
+++ b/erpnext/loan_management/desk_page/loan/loan.json
@@ -23,7 +23,7 @@
   {
    "hidden": 0,
    "label": "Reports",
-   "links": "[\n    {\n        \"dependencies\": [\n            \"Loan Repayment\"\n        ],\n        \"doctype\": \"Loan Repayment\",\n        \"incomplete_dependencies\": [\n            \"Loan Repayment\"\n        ],\n        \"is_query_report\": true,\n        \"label\": \"Loan Repayment and Closure\",\n        \"name\": \"Loan Repayment and Closure\",\n        \"route\": \"#query-report/Loan Repayment and Closure\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Loan Security Pledge\"\n        ],\n        \"doctype\": \"Loan Security Pledge\",\n        \"incomplete_dependencies\": [\n            \"Loan Security Pledge\"\n        ],\n        \"is_query_report\": true,\n        \"label\": \"Loan Security Status\",\n        \"name\": \"Loan Security Status\",\n        \"route\": \"#query-report/Loan Security Status\",\n        \"type\": \"report\"\n    }\n]"
+   "links": "[\n    {\n        \"doctype\": \"Loan Repayment\",\n        \"is_query_report\": true,\n        \"label\": \"Loan Repayment and Closure\",\n        \"name\": \"Loan Repayment and Closure\",\n        \"route\": \"#query-report/Loan Repayment and Closure\",\n        \"type\": \"report\"\n    },\n    {\n        \"doctype\": \"Loan Security Pledge\",\n        \"is_query_report\": true,\n        \"label\": \"Loan Security Status\",\n        \"name\": \"Loan Security Status\",\n        \"route\": \"#query-report/Loan Security Status\",\n        \"type\": \"report\"\n    }\n]"
   }
  ],
  "category": "Modules",
@@ -38,7 +38,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Loan",
- "modified": "2020-05-28 13:37:42.017709",
+ "modified": "2020-06-07 19:42:14.947902",
  "modified_by": "Administrator",
  "module": "Loan Management",
  "name": "Loan",
diff --git a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
index c9e36a8..d44088b 100644
--- a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
+++ b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
@@ -27,6 +27,7 @@
 
 	def on_cancel(self):
 		self.make_gl_entries(cancel=1)
+		self.ignore_linked_doctypes = ['GL Entry']
 
 	def set_missing_values(self):
 		if not self.disbursement_date:
diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
index 094b9c6..e6ceb55 100644
--- a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
+++ b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
@@ -31,6 +31,7 @@
 			self.update_is_accrued()
 
 		self.make_gl_entries(cancel=1)
+		self.ignore_linked_doctypes = ['GL Entry']
 
 	def update_is_accrued(self):
 		frappe.db.set_value('Repayment Schedule', self.repayment_schedule_name, 'is_accrued', 0)
@@ -176,21 +177,23 @@
 	return term_loans
 
 def make_loan_interest_accrual_entry(args):
-		loan_interest_accrual = frappe.new_doc("Loan Interest Accrual")
-		loan_interest_accrual.loan = args.loan
-		loan_interest_accrual.applicant_type = args.applicant_type
-		loan_interest_accrual.applicant = args.applicant
-		loan_interest_accrual.interest_income_account = args.interest_income_account
-		loan_interest_accrual.loan_account = args.loan_account
-		loan_interest_accrual.pending_principal_amount = flt(args.pending_principal_amount, 2)
-		loan_interest_accrual.interest_amount = flt(args.interest_amount, 2)
-		loan_interest_accrual.posting_date = args.posting_date or nowdate()
-		loan_interest_accrual.process_loan_interest_accrual = args.process_loan_interest
-		loan_interest_accrual.repayment_schedule_name = args.repayment_schedule_name
-		loan_interest_accrual.payable_principal_amount = args.payable_principal
+	precision = cint(frappe.db.get_default("currency_precision")) or 2
 
-		loan_interest_accrual.save()
-		loan_interest_accrual.submit()
+	loan_interest_accrual = frappe.new_doc("Loan Interest Accrual")
+	loan_interest_accrual.loan = args.loan
+	loan_interest_accrual.applicant_type = args.applicant_type
+	loan_interest_accrual.applicant = args.applicant
+	loan_interest_accrual.interest_income_account = args.interest_income_account
+	loan_interest_accrual.loan_account = args.loan_account
+	loan_interest_accrual.pending_principal_amount = flt(args.pending_principal_amount, precision)
+	loan_interest_accrual.interest_amount = flt(args.interest_amount, precision)
+	loan_interest_accrual.posting_date = args.posting_date or nowdate()
+	loan_interest_accrual.process_loan_interest_accrual = args.process_loan_interest
+	loan_interest_accrual.repayment_schedule_name = args.repayment_schedule_name
+	loan_interest_accrual.payable_principal_amount = args.payable_principal
+
+	loan_interest_accrual.save()
+	loan_interest_accrual.submit()
 
 
 def get_no_of_days_for_interest_accural(loan, posting_date):
diff --git a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
index 2ab668a..c28994e 100644
--- a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
+++ b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
@@ -6,7 +6,7 @@
 import frappe, erpnext
 import json
 from frappe import _
-from frappe.utils import flt, getdate
+from frappe.utils import flt, getdate, cint
 from six import iteritems
 from frappe.model.document import Document
 from frappe.utils import date_diff, add_days, getdate, add_months, get_first_day, get_datetime
@@ -29,8 +29,11 @@
 	def on_cancel(self):
 		self.mark_as_unpaid()
 		self.make_gl_entries(cancel=1)
+		self.ignore_linked_doctypes = ['GL Entry']
 
 	def set_missing_values(self, amounts):
+		precision = cint(frappe.db.get_default("currency_precision")) or 2
+
 		if not self.posting_date:
 			self.posting_date = get_datetime()
 
@@ -38,24 +41,26 @@
 			self.cost_center = erpnext.get_default_cost_center(self.company)
 
 		if not self.interest_payable:
-			self.interest_payable = flt(amounts['interest_amount'], 2)
+			self.interest_payable = flt(amounts['interest_amount'], precision)
 
 		if not self.penalty_amount:
-			self.penalty_amount = flt(amounts['penalty_amount'], 2)
+			self.penalty_amount = flt(amounts['penalty_amount'], precision)
 
 		if not self.pending_principal_amount:
-			self.pending_principal_amount = flt(amounts['pending_principal_amount'], 2)
+			self.pending_principal_amount = flt(amounts['pending_principal_amount'], precision)
 
 		if not self.payable_principal_amount and self.is_term_loan:
-			self.payable_principal_amount = flt(amounts['payable_principal_amount'], 2)
+			self.payable_principal_amount = flt(amounts['payable_principal_amount'], precision)
 
 		if not self.payable_amount:
-			self.payable_amount = flt(amounts['payable_amount'], 2)
+			self.payable_amount = flt(amounts['payable_amount'], precision)
 
 		if amounts.get('due_date'):
 			self.due_date = amounts.get('due_date')
 
 	def validate_amount(self):
+		precision = cint(frappe.db.get_default("currency_precision")) or 2
+
 		if not self.amount_paid:
 			frappe.throw(_("Amount paid cannot be zero"))
 
@@ -63,11 +68,13 @@
 			msg = _("Paid amount cannot be less than {0}").format(self.penalty_amount)
 			frappe.throw(msg)
 
-		if self.payment_type == "Loan Closure" and flt(self.amount_paid, 2) < flt(self.payable_amount, 2):
+		if self.payment_type == "Loan Closure" and flt(self.amount_paid, precision) < flt(self.payable_amount, precision):
 			msg = _("Amount of {0} is required for Loan closure").format(self.payable_amount)
 			frappe.throw(msg)
 
 	def update_paid_amount(self):
+		precision = cint(frappe.db.get_default("currency_precision")) or 2
+
 		loan = frappe.get_doc("Loan", self.against_loan)
 
 		for payment in self.repayment_details:
@@ -75,9 +82,9 @@
 				SET paid_principal_amount = `paid_principal_amount` + %s,
 					paid_interest_amount = `paid_interest_amount` + %s
 				WHERE name = %s""",
-				(flt(payment.paid_principal_amount), flt(payment.paid_interest_amount), payment.loan_interest_accrual))
+				(flt(payment.paid_principal_amount, precision), flt(payment.paid_interest_amount, precision), payment.loan_interest_accrual))
 
-		if flt(loan.total_principal_paid + self.principal_amount_paid, 2) >= flt(loan.total_payment, 2):
+		if flt(loan.total_principal_paid + self.principal_amount_paid, precision) >= flt(loan.total_payment, precision):
 			if loan.is_secured_loan:
 				frappe.db.set_value("Loan", self.against_loan, "status", "Loan Closure Requested")
 			else:
@@ -253,6 +260,7 @@
 # So it pulls all the unpaid Loan Interest Accrual Entries and calculates the penalty if applicable
 
 def get_amounts(amounts, against_loan, posting_date, payment_type):
+	precision = cint(frappe.db.get_default("currency_precision")) or 2
 
 	against_loan_doc = frappe.get_doc("Loan", against_loan)
 	loan_type_details = frappe.get_doc("Loan Type", against_loan_doc.loan_type)
@@ -282,8 +290,8 @@
 		payable_principal_amount += entry.payable_principal_amount
 
 		pending_accrual_entries.setdefault(entry.name, {
-			'interest_amount': flt(entry.interest_amount),
-			'payable_principal_amount': flt(entry.payable_principal_amount)
+			'interest_amount': flt(entry.interest_amount, precision),
+			'payable_principal_amount': flt(entry.payable_principal_amount, precision)
 		})
 
 		if not final_due_date:
@@ -301,11 +309,11 @@
 		per_day_interest = (payable_principal_amount * (loan_type_details.rate_of_interest / 100))/365
 		total_pending_interest += (pending_days * per_day_interest)
 
-	amounts["pending_principal_amount"] = pending_principal_amount
-	amounts["payable_principal_amount"] = payable_principal_amount
-	amounts["interest_amount"] = total_pending_interest
-	amounts["penalty_amount"] = penalty_amount
-	amounts["payable_amount"] = payable_principal_amount + total_pending_interest + penalty_amount
+	amounts["pending_principal_amount"] = flt(pending_principal_amount, precision)
+	amounts["payable_principal_amount"] = flt(payable_principal_amount, precision)
+	amounts["interest_amount"] = flt(total_pending_interest, precision)
+	amounts["penalty_amount"] = flt(penalty_amount, precision)
+	amounts["payable_amount"] = flt(payable_principal_amount + total_pending_interest + penalty_amount, precision)
 	amounts["pending_accrual_entries"] = pending_accrual_entries
 
 	if final_due_date:
diff --git a/erpnext/loan_management/doctype/loan_type/loan_type.json b/erpnext/loan_management/doctype/loan_type/loan_type.json
index 51c5cb9..1dd3710 100644
--- a/erpnext/loan_management/doctype/loan_type/loan_type.json
+++ b/erpnext/loan_management/doctype/loan_type/loan_type.json
@@ -41,6 +41,7 @@
    "options": "Company:company:default_currency"
   },
   {
+   "default": "0",
    "fieldname": "rate_of_interest",
    "fieldtype": "Percent",
    "label": "Rate of Interest (%) Yearly",
@@ -143,7 +144,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-04-15 00:24:43.259963",
+ "modified": "2020-06-07 18:55:59.346292",
  "modified_by": "Administrator",
  "module": "Loan Management",
  "name": "Loan Type",
diff --git a/erpnext/loan_management/report/loan_security_status/loan_security_status.py b/erpnext/loan_management/report/loan_security_status/loan_security_status.py
index ea6a2ee6..1951855 100644
--- a/erpnext/loan_management/report/loan_security_status/loan_security_status.py
+++ b/erpnext/loan_management/report/loan_security_status/loan_security_status.py
@@ -76,7 +76,8 @@
 			"fieldtype": "Link",
 			"fieldname": "currency",
 			"options": "Currency",
-			"width": 50
+			"width": 50,
+			"hidden": 1
 		}
 	]
 
@@ -84,17 +85,13 @@
 
 def get_data(filters):
 
-	loan_security_price_map = frappe._dict(frappe.get_all("Loan Security",
-		fields=["name", "loan_security_price"], as_list=1
-	))
-
 	data = []
 	conditions = get_conditions(filters)
 
 	loan_security_pledges = frappe.db.sql("""
 		SELECT
 			p.name, p.applicant, p.loan, p.status, p.pledge_time,
-			c.loan_security, c.qty
+			c.loan_security, c.qty, c.loan_security_price, c.amount
 		FROM
 			`tabLoan Security Pledge` p, `tabPledge` c
 		WHERE
@@ -115,8 +112,8 @@
 		row["pledge_time"] = pledge.pledge_time
 		row["loan_security"] = pledge.loan_security
 		row["qty"] = pledge.qty
-		row["loan_security_price"] = loan_security_price_map.get(pledge.loan_security)
-		row["loan_security_value"] = row["loan_security_price"] * pledge.qty
+		row["loan_security_price"] = pledge.loan_security_price
+		row["loan_security_value"] = pledge.amount
 		row["currency"] = default_currency
 
 		data.append(row)