Skip to content

Commit

Permalink
chore: complete remaining things
Browse files Browse the repository at this point in the history
  • Loading branch information
anandbaburajan committed Oct 25, 2023
1 parent 077713b commit e8b81b0
Show file tree
Hide file tree
Showing 30 changed files with 680 additions and 253 deletions.
39 changes: 24 additions & 15 deletions lending/loan_management/doctype/loan/loan.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import frappe
from frappe import _
from frappe.query_builder import Order
from frappe.query_builder.functions import Sum
from frappe.utils import (
add_days,
cint,
Expand Down Expand Up @@ -223,23 +224,31 @@ def validate_loan_amount(self):

def link_loan_security_assignment(self):
if self.is_secured_loan and self.loan_application:
maximum_loan_value = frappe.db.get_value(
"Loan Security Assignment",
{"loan_application": self.loan_application, "status": "Requested"},
"sum(maximum_loan_value)",
)

if maximum_loan_value:
frappe.db.sql(
"""
UPDATE `tabLoan Security Assignment`
SET loan = %s, pledge_time = %s, status = 'Pledged'
WHERE status = 'Requested' and loan_application = %s
""",
(self.name, now_datetime(), self.loan_application),
lsa = frappe.qb.DocType("Loan Security Assignment")
lsalad = frappe.qb.DocType("Loan Security Assignment Loan Application Detail")

lsa_and_maximum_loan_value = (
frappe.qb.from_(lsa)
.inner_join(lsalad)
.on(lsalad.parent == lsa.name)
.select(lsa.name, Sum(lsa.maximum_loan_value))
.where(lsa.status == "Requested")
.where(lsalad.loan_application == self.loan_application)
).run()

if lsa_and_maximum_loan_value:
lsa = frappe.get_doc("Loan Security Assignment", lsa_and_maximum_loan_value[0][0])
lsa.append(
"allocated_loans",
{
"loan": self.name,
},
)
lsa.pledge_time = now_datetime()
lsa.status = "Pledged"
lsa.save()

self.db_set("maximum_loan_amount", maximum_loan_value)
self.db_set("maximum_loan_amount", lsa_and_maximum_loan_value[0][1])

def accrue_loan_interest(self):
from lending.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import (
Expand Down
65 changes: 23 additions & 42 deletions lending/loan_management/doctype/loan/test_loan.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
request_loan_closure,
unpledge_security,
)
from lending.loan_management.doctype.loan_application.loan_application import create_pledge
from lending.loan_management.doctype.loan_application.loan_application import (
create_loan_security_assignment_from_loan_application,
)
from lending.loan_management.doctype.loan_disbursement.loan_disbursement import (
get_disbursal_amount,
)
Expand Down Expand Up @@ -174,7 +176,7 @@ def test_loan_with_security(self):
loan_application = create_loan_application(
"_Test Company", self.applicant2, "Stock Loan", pledge, "Repay Over Number of Periods", 12
)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_loan_with_security(
self.applicant2, "Stock Loan", "Repay Over Number of Periods", 12, loan_application
Expand All @@ -188,7 +190,7 @@ def test_loan_disbursement(self):
"_Test Company", self.applicant2, "Stock Loan", pledge, "Repay Over Number of Periods", 12
)

create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_loan_with_security(
self.applicant2, "Stock Loan", "Repay Over Number of Periods", 12, loan_application
Expand Down Expand Up @@ -250,7 +252,7 @@ def test_sanctioned_amount_limit(self):
loan_application = create_loan_application(
"_Test Company", self.applicant3, "Demand Loan", pledge
)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)
loan = create_demand_loan(
self.applicant3, "Demand Loan", loan_application, posting_date="2019-10-01"
)
Expand All @@ -268,7 +270,7 @@ def test_regular_loan_repayment(self):
loan_application = create_loan_application(
"_Test Company", self.applicant2, "Demand Loan", pledge
)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_demand_loan(
self.applicant2, "Demand Loan", loan_application, posting_date="2019-10-01"
Expand Down Expand Up @@ -328,8 +330,7 @@ def test_loan_closure(self):
loan_application = create_loan_application(
"_Test Company", self.applicant2, "Demand Loan", pledge
)
create_pledge(loan_application)

create_loan_security_assignment_from_loan_application(loan_application)
loan = create_demand_loan(
self.applicant2, "Demand Loan", loan_application, posting_date="2019-10-01"
)
Expand Down Expand Up @@ -383,7 +384,7 @@ def test_loan_repayment_for_term_loan(self):
loan_application = create_loan_application(
"_Test Company", self.applicant2, "Stock Loan", pledges, "Repay Over Number of Periods", 12
)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_loan_with_security(
self.applicant2,
Expand Down Expand Up @@ -428,7 +429,7 @@ def test_security_shortfall(self):
"_Test Company", self.applicant2, "Stock Loan", pledges, "Repay Over Number of Periods", 12
)

create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_loan_with_security(
self.applicant2, "Stock Loan", "Repay Over Number of Periods", 12, loan_application
Expand Down Expand Up @@ -466,7 +467,7 @@ def test_loan_security_release(self):
loan_application = create_loan_application(
"_Test Company", self.applicant2, "Demand Loan", pledge
)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_demand_loan(
self.applicant2, "Demand Loan", loan_application, posting_date="2019-10-01"
Expand Down Expand Up @@ -526,7 +527,7 @@ def test_partial_loan_security_release(self):
loan_application = create_loan_application(
"_Test Company", self.applicant2, "Demand Loan", pledge
)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_demand_loan(
self.applicant2, "Demand Loan", loan_application, posting_date="2019-10-01"
Expand Down Expand Up @@ -562,7 +563,7 @@ def test_sanctioned_loan_security_release(self):
loan_application = create_loan_application(
"_Test Company", self.applicant2, "Demand Loan", pledge
)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_demand_loan(
self.applicant2, "Demand Loan", loan_application, posting_date="2019-10-01"
Expand Down Expand Up @@ -591,7 +592,7 @@ def test_disbursal_check_with_shortfall(self):
"_Test Company", self.applicant2, "Stock Loan", pledges, "Repay Over Number of Periods", 12
)

create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_loan_with_security(
self.applicant2, "Stock Loan", "Repay Over Number of Periods", 12, loan_application
Expand Down Expand Up @@ -630,7 +631,7 @@ def test_disbursal_check_without_shortfall(self):
"_Test Company", self.applicant2, "Stock Loan", pledges, "Repay Over Number of Periods", 12
)

create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_loan_with_security(
self.applicant2, "Stock Loan", "Repay Over Number of Periods", 12, loan_application
Expand All @@ -648,7 +649,7 @@ def test_pending_loan_amount_after_closure_request(self):
loan_application = create_loan_application(
"_Test Company", self.applicant2, "Demand Loan", pledge
)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_demand_loan(
self.applicant2, "Demand Loan", loan_application, posting_date="2019-10-01"
Expand Down Expand Up @@ -698,7 +699,7 @@ def test_partial_unaccrued_interest_payment(self):
loan_application = create_loan_application(
"_Test Company", self.applicant2, "Demand Loan", pledge
)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_demand_loan(
self.applicant2, "Demand Loan", loan_application, posting_date="2019-10-01"
Expand Down Expand Up @@ -761,7 +762,7 @@ def test_loan_write_off_limit(self):
loan_application = create_loan_application(
"_Test Company", self.applicant2, "Demand Loan", pledge
)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_demand_loan(
self.applicant2, "Demand Loan", loan_application, posting_date="2019-10-01"
Expand Down Expand Up @@ -813,7 +814,7 @@ def test_loan_repayment_against_partially_disbursed_loan(self):
loan_application = create_loan_application(
"_Test Company", self.applicant2, "Demand Loan", pledge
)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_demand_loan(
self.applicant2, "Demand Loan", loan_application, posting_date="2019-10-01"
Expand All @@ -838,7 +839,7 @@ def test_loan_amount_write_off(self):
loan_application = create_loan_application(
"_Test Company", self.applicant2, "Demand Loan", pledge
)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)

loan = create_demand_loan(
self.applicant2, "Demand Loan", loan_application, posting_date="2019-10-01"
Expand Down Expand Up @@ -950,7 +951,7 @@ def create_loan_scenario_for_penalty(doc):
pledge = [{"loan_security": "Test Security 1", "qty": 4000.00}]

loan_application = create_loan_application("_Test Company", doc.applicant2, "Demand Loan", pledge)
create_pledge(loan_application)
create_loan_security_assignment_from_loan_application(loan_application)
loan = create_demand_loan(
doc.applicant2, "Demand Loan", loan_application, posting_date="2019-10-01"
)
Expand Down Expand Up @@ -1126,7 +1127,7 @@ def create_loan_security():
{
"doctype": "Loan Security",
"loan_security_type": "Stock",
"loan_security_code": "532779",
"loan_security_code": "Test Security 1",
"loan_security_name": "Test Security 1",
"unit_of_measure": "Nos",
"haircut": 50.00,
Expand All @@ -1138,34 +1139,14 @@ def create_loan_security():
{
"doctype": "Loan Security",
"loan_security_type": "Stock",
"loan_security_code": "531335",
"loan_security_code": "Test Security 2",
"loan_security_name": "Test Security 2",
"unit_of_measure": "Nos",
"haircut": 50.00,
}
).insert(ignore_permissions=True)


def create_loan_security_assignment(applicant, pledges, loan_application=None, loan=None):

lsp = frappe.new_doc("Loan Security Assignment")
lsp.applicant_type = "Customer"
lsp.applicant = applicant
lsp.company = "_Test Company"
lsp.loan_application = loan_application

if loan:
lsp.loan = loan

for pledge in pledges:
lsp.append("securities", {"loan_security": pledge["loan_security"], "qty": pledge["qty"]})

lsp.save()
lsp.submit()

return lsp


def make_loan_disbursement_entry(loan, amount, disbursement_date=None):

loan_disbursement_entry = frappe.get_doc(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@
lending.common.setup_filters("Loan Application");

frappe.ui.form.on('Loan Application', {
onload: function(frm) {
frm.set_query("loan_security", "proposed_pledges", function() {
return {
"filters": {
"status": "Pending Hypothecation",
}
};
});
},

setup: function(frm) {
frm.make_methods = {
'Loan': function() { frm.trigger('create_loan') },
'Loan Security Assignment': function() { frm.trigger('create_loan_security_assignment') },
'Loan Security Assignment': function() { frm.trigger('create_loan_security_assignment_from_loan_application') },
}
},
refresh: function(frm) {
Expand Down Expand Up @@ -39,13 +48,9 @@ frappe.ui.form.on('Loan Application', {
if (frm.doc.status == "Approved") {

if (frm.doc.is_secured_loan) {
frappe.db.get_value("Loan Security Assignment", {"loan_application": frm.doc.name, "docstatus": 1}, "name", (r) => {
if (Object.keys(r).length === 0) {
frm.add_custom_button(__('Loan Security Assignment'), function() {
frm.trigger('create_loan_security_assignment');
},__('Create'))
}
});
frm.add_custom_button(__('Loan Security Assignment'), function() {
frm.trigger('create_loan_security_assignment_from_loan_application');
},__('Create'))
}

frappe.db.get_value("Loan", {"loan_application": frm.doc.name, "docstatus": 1}, "name", (r) => {
Expand All @@ -69,14 +74,14 @@ frappe.ui.form.on('Loan Application', {
frm: frm
});
},
create_loan_security_assignment: function(frm) {
create_loan_security_assignment_from_loan_application: function(frm) {

if(!frm.doc.is_secured_loan) {
frappe.throw(__("Loan Security Assignment can only be created for secured loans"));
}

frappe.call({
method: "lending.loan_management.doctype.loan_application.loan_application.create_pledge",
method: "lending.loan_management.doctype.loan_application.loan_application.create_loan_security_assignment_from_loan_application",
args: {
loan_application: frm.doc.name
},
Expand All @@ -95,14 +100,8 @@ frappe.ui.form.on('Loan Application', {

calculate_amounts: function(frm, cdt, cdn) {
let row = locals[cdt][cdn];
if (row.qty) {
frappe.model.set_value(cdt, cdn, 'amount', row.qty * row.loan_security_price);
frappe.model.set_value(cdt, cdn, 'post_haircut_amount', cint(row.amount - (row.amount * row.haircut/100)));
} else if (row.amount) {
frappe.model.set_value(cdt, cdn, 'qty', cint(row.amount / row.loan_security_price));
frappe.model.set_value(cdt, cdn, 'amount', row.qty * row.loan_security_price);
frappe.model.set_value(cdt, cdn, 'post_haircut_amount', cint(row.amount - (row.amount * row.haircut/100)));
}
frappe.model.set_value(cdt, cdn, 'amount', row.qty * row.loan_security_price);
frappe.model.set_value(cdt, cdn, 'post_haircut_amount', cint(row.amount - (row.amount * row.haircut/100)));

let maximum_amount = 0;

Expand Down Expand Up @@ -134,11 +133,11 @@ frappe.ui.form.on("Proposed Pledge", {
}
},

amount: function(frm, cdt, cdn) {
qty: function(frm, cdt, cdn) {
frm.events.calculate_amounts(frm, cdt, cdn);
},

qty: function(frm, cdt, cdn) {
loan_security_price: function(frm, cdt, cdn) {
frm.events.calculate_amounts(frm, cdt, cdn);
},
})
Loading

0 comments on commit e8b81b0

Please sign in to comment.