Merge pull request #24252 from deepeshgarg007/partial_security_unpledge

fix: Partial loan security unpledging
This commit is contained in:
Deepesh Garg 2020-12-30 21:37:52 +05:30 committed by GitHub
commit f57089532a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 9 deletions

View File

@ -6,6 +6,7 @@ from __future__ import unicode_literals
import frappe, math, json
import erpnext
from frappe import _
from six import string_types
from frappe.utils import flt, rounded, add_months, nowdate, getdate, now_datetime
from erpnext.loan_management.doctype.loan_security_unpledge.loan_security_unpledge import get_pledged_security_qty
from erpnext.controllers.accounts_controller import AccountsController
@ -280,10 +281,13 @@ def make_loan_write_off(loan, company=None, posting_date=None, amount=0, as_dict
return write_off
@frappe.whitelist()
def unpledge_security(loan=None, loan_security_pledge=None, as_dict=0, save=0, submit=0, approve=0):
# if loan is passed it will be considered as full unpledge
def unpledge_security(loan=None, loan_security_pledge=None, security_map=None, as_dict=0, save=0, submit=0, approve=0):
# if no security_map is passed it will be considered as full unpledge
if security_map and isinstance(security_map, string_types):
security_map = json.loads(security_map)
if loan:
pledge_qty_map = get_pledged_security_qty(loan)
pledge_qty_map = security_map or get_pledged_security_qty(loan)
loan_doc = frappe.get_doc('Loan', loan)
unpledge_request = create_loan_security_unpledge(pledge_qty_map, loan_doc.name, loan_doc.company,
loan_doc.applicant_type, loan_doc.applicant)

View File

@ -325,6 +325,43 @@ class TestLoan(unittest.TestCase):
self.assertEquals(amounts['payable_principal_amount'], 0.0)
self.assertEqual(amounts['interest_amount'], 0)
def test_partial_loan_security_unpledge(self):
pledge = [{
"loan_security": "Test Security 1",
"qty": 2000.00
},
{
"loan_security": "Test Security 2",
"qty": 4000.00
}]
loan_application = create_loan_application('_Test Company', self.applicant2, 'Demand Loan', pledge)
create_pledge(loan_application)
loan = create_demand_loan(self.applicant2, "Demand Loan", loan_application, posting_date='2019-10-01')
loan.submit()
self.assertEquals(loan.loan_amount, 1000000)
first_date = '2019-10-01'
last_date = '2019-10-30'
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=first_date)
process_loan_interest_accrual_for_demand_loans(posting_date = last_date)
repayment_entry = create_repayment_entry(loan.name, self.applicant2, add_days(last_date, 5), 600000)
repayment_entry.submit()
unpledge_map = {'Test Security 2': 2000}
unpledge_request = unpledge_security(loan=loan.name, security_map = unpledge_map, save=1)
unpledge_request.submit()
unpledge_request.status = 'Approved'
unpledge_request.save()
unpledge_request.submit()
unpledge_request.load_from_db()
self.assertEqual(unpledge_request.docstatus, 1)
def test_disbursal_check_with_shortfall(self):
pledges = [{
"loan_security": "Test Security 2",

View File

@ -81,7 +81,6 @@ def check_for_ltv_shortfall(process_loan_security_shortfall):
process_loan_security_shortfall)
def create_loan_security_shortfall(loan, loan_amount, security_value, shortfall_amount, process_loan_security_shortfall):
existing_shortfall = frappe.db.get_value("Loan Security Shortfall", {"loan": loan, "status": "Pending"}, "name")
if existing_shortfall:

View File

@ -30,6 +30,8 @@ class LoanSecurityUnpledge(Document):
d.idx, frappe.bold(d.loan_security)))
def validate_unpledge_qty(self):
from erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall import get_ltv_ratio
pledge_qty_map = get_pledged_security_qty(self.loan)
ltv_ratio_map = frappe._dict(frappe.get_all("Loan Security Type",
@ -47,6 +49,8 @@ class LoanSecurityUnpledge(Document):
pending_principal_amount = flt(total_payment) - flt(interest_payable) - flt(principal_paid) - flt(written_off_amount)
security_value = 0
unpledge_qty_map = {}
ltv_ratio = 0
for security in self.securities:
pledged_qty = pledge_qty_map.get(security.loan_security, 0)
@ -57,13 +61,15 @@ class LoanSecurityUnpledge(Document):
msg += _("You are trying to unpledge more.")
frappe.throw(msg, title=_("Loan Security Unpledge Error"))
qty_after_unpledge = pledged_qty - security.qty
ltv_ratio = ltv_ratio_map.get(security.loan_security_type)
unpledge_qty_map.setdefault(security.loan_security, 0)
unpledge_qty_map[security.loan_security] += security.qty
current_price = loan_security_price_map.get(security.loan_security)
if not current_price:
frappe.throw(_("No valid Loan Security Price found for {0}").format(frappe.bold(security.loan_security)))
for security in pledge_qty_map:
if not ltv_ratio:
ltv_ratio = get_ltv_ratio(security)
qty_after_unpledge = pledge_qty_map.get(security, 0) - unpledge_qty_map.get(security, 0)
current_price = loan_security_price_map.get(security)
security_value += qty_after_unpledge * current_price
if not security_value and flt(pending_principal_amount, 2) > 0: