Skip to content

Commit

Permalink
fix: LOC loan fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
deepeshgarg007 committed Jan 11, 2024
1 parent 68c50ad commit 3a655bc
Show file tree
Hide file tree
Showing 13 changed files with 177 additions and 550 deletions.
3 changes: 2 additions & 1 deletion lending/loan_management/doctype/loan/loan.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ frappe.ui.form.on('Loan', {
},__('Create'));
}

if (["Sanctioned", "Partially Disbursed"].includes(frm.doc.status)) {
if (["Sanctioned", "Partially Disbursed", "Active"].includes(frm.doc.status)) {
frm.add_custom_button(__('Loan Disbursement'), function() {
frm.trigger("make_loan_disbursement");
},__('Create'));
Expand Down Expand Up @@ -134,6 +134,7 @@ frappe.ui.form.on('Loan', {
frm.doc.loan_amount - frm.doc.disbursed_amount : 0,
"as_dict": 1,
"repayment_frequency": frm.doc.repayment_frequency,
"is_term_loan": frm.doc.is_term_loan
},
method: "lending.loan_management.doctype.loan.loan.make_loan_disbursement",
callback: function (r) {
Expand Down
26 changes: 21 additions & 5 deletions lending/loan_management/doctype/loan/loan.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
"label": "Loan Details"
},
{
"depends_on": "eval:doc.repayment_schedule_type!=\"Line of Credit\"",
"fieldname": "loan_amount",
"fieldtype": "Currency",
"label": "Loan Amount",
Expand Down Expand Up @@ -404,13 +405,15 @@
"fieldname": "is_npa",
"fieldtype": "Check",
"label": "Is NPA",
"no_copy": 1,
"read_only": 1
},
{
"depends_on": "is_term_loan",
"fetch_from": "loan_product.repayment_schedule_type",
"fieldname": "repayment_schedule_type",
"fieldtype": "Data",
"hidden": 1,
"label": "Repayment Schedule Type",
"read_only": 1
},
Expand All @@ -428,12 +431,14 @@
"description": "Manually marked as NPA",
"fieldname": "manual_npa",
"fieldtype": "Check",
"label": "Manual NPA"
"label": "Manual NPA",
"no_copy": 1
},
{
"fieldname": "loan_restructure_count",
"fieldtype": "Int",
"label": "Loan Restructure Count",
"no_copy": 1,
"read_only": 1
},
{
Expand All @@ -444,12 +449,14 @@
"fieldname": "watch_period_end_date",
"fieldtype": "Date",
"label": "Watch Period End Date",
"no_copy": 1,
"read_only": 1
},
{
"fieldname": "tenure_post_restructure",
"fieldtype": "Int",
"label": "Tenure Post Restructure",
"no_copy": 1,
"read_only": 1
},
{
Expand Down Expand Up @@ -506,14 +513,17 @@
"label": "Moratorium Tenure"
},
{
"depends_on": "eval:doc.repayment_schedule_type == \"Line of Credit\"",
"fieldname": "loan_credit_limits_section",
"fieldtype": "Section Break",
"label": "Loan Credit Limits"
},
{
"fieldname": "limit_applicable_start",
"fieldtype": "Date",
"label": "Limit Applicable Start"
"label": "Limit Applicable Start",
"mandatory_depends_on": "eval: doc.repayment_schedule_type == \"Line of Credit\"",
"no_copy": 1
},
{
"fieldname": "column_break_foeo",
Expand All @@ -522,13 +532,17 @@
{
"fieldname": "limit_applicable_end",
"fieldtype": "Date",
"label": "Limit Applicable End"
"label": "Limit Applicable End",
"mandatory_depends_on": "eval: doc.repayment_schedule_type == \"Line of Credit\"",
"no_copy": 1
},
{
"allow_on_submit": 1,
"fieldname": "maximum_limit_amount",
"fieldtype": "Currency",
"label": "Maximum Limit Amount"
"label": "Maximum Limit Amount",
"mandatory_depends_on": "eval: doc.repayment_schedule_type == \"Line of Credit\"",
"no_copy": 1
},
{
"fetch_from": "loan_product.loan_category",
Expand All @@ -542,12 +556,14 @@
"fieldname": "available_limit_amount",
"fieldtype": "Currency",
"label": "Available Limit Amount",
"no_copy": 1,
"read_only": 1
},
{
"fieldname": "utilized_limit_amount",
"fieldtype": "Currency",
"label": "Utilized Limit Amount",
"no_copy": 1,
"read_only": 1
},
{
Expand All @@ -561,7 +577,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2024-01-07 21:43:54.755239",
"modified": "2024-01-11 16:49:57.074283",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan",
Expand Down
17 changes: 14 additions & 3 deletions lending/loan_management/doctype/loan/loan.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def validate(self):
self.set_cyclic_date()
self.set_default_charge_account()
self.set_available_limit_amount()
self.validate_repayment_terms()

# if self.is_term_loan and not self.is_new() and self.repayment_schedule_type != "Line of Credit":
# update_draft_schedule(
Expand Down Expand Up @@ -122,6 +123,11 @@ def set_default_charge_account(self):
def set_available_limit_amount(self):
self.available_limit_amount = self.maximum_limit_amount

def validate_repayment_terms(self):
if self.is_term_loan and self.repayment_schedule_type != "Line of Credit":
if not self.repayment_periods:
frappe.throw(_("Repayment periods is mandatory for term loans"))

def on_submit(self):
self.link_loan_security_pledge()
# Interest accrual for backdated term loans
Expand Down Expand Up @@ -221,15 +227,18 @@ def calculate_totals(self, on_insert=False):
self.db_set("total_payment", self.total_payment)

def set_loan_amount(self):
if self.repayment_schedule_type == "Line of Credit":
self.loan_amount = self.maximum_limit_amount

if self.loan_application and not self.loan_amount:
self.loan_amount = frappe.db.get_value("Loan Application", self.loan_application, "loan_amount")

def validate_loan_amount(self):
if self.maximum_loan_amount and self.loan_amount > self.maximum_loan_amount:
msg = _("Loan amount cannot be greater than {0}").format(self.maximum_loan_amount)
if self.maximum_limit_amount and self.loan_amount > self.maximum_limit_amount:
msg = _("Loan amount cannot be greater than {0}").format(self.maximum_limit_amount)
frappe.throw(msg)

if not self.loan_amount and self.repayment_schedule_type != "Line of Credit":
if not self.loan_amount:
frappe.throw(_("Loan amount is mandatory"))

def link_loan_security_pledge(self):
Expand Down Expand Up @@ -405,6 +414,7 @@ def make_loan_disbursement(
posting_date=None,
disbursement_date=None,
bank_account=None,
is_term_loan=None,
):
loan_doc = frappe.get_doc("Loan", loan)
disbursement_entry = frappe.new_doc("Loan Disbursement")
Expand All @@ -418,6 +428,7 @@ def make_loan_disbursement(
disbursement_entry.repayment_start_date = repayment_start_date
disbursement_entry.repayment_frequency = repayment_frequency
disbursement_entry.disbursed_amount = disbursement_amount
disbursement_entry.is_term_loan = is_term_loan

for charge in loan_doc.get("loan_charges"):
disbursement_entry.append(
Expand Down
1 change: 1 addition & 0 deletions lending/loan_management/doctype/loan/loan_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ frappe.listview_settings['Loan'] = {
"Draft": "red",
"Sanctioned": "blue",
"Disbursed": "orange",
"Active": "orange",
"Partially Disbursed": "yellow",
"Loan Closure Requested": "green",
"Closed": "green"
Expand Down
29 changes: 25 additions & 4 deletions lending/loan_management/doctype/loan_demand/loan_demand.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"field_order": [
"loan_demand_details_section",
"loan",
"loan_repayment_schedule",
"loan_disbursement",
"repayment_schedule_detail",
"applicant_type",
"applicant",
Expand All @@ -18,6 +20,7 @@
"column_break_qrjm",
"company",
"demand_date",
"disbursement_date",
"demand_amount",
"paid_amount",
"waived_amount",
Expand Down Expand Up @@ -116,10 +119,9 @@
},
{
"fieldname": "demand_subtype",
"fieldtype": "Select",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Demand Subtype",
"options": "Principal\nInterest\nPenalty\nCharges"
"label": "Demand Subtype"
},
{
"fetch_from": "loan.company",
Expand Down Expand Up @@ -151,12 +153,31 @@
"fieldtype": "Link",
"label": "Process Loan Demand",
"options": "Process Loan Demand"
},
{
"fieldname": "loan_repayment_schedule",
"fieldtype": "Link",
"label": "Loan Repayment Schedule",
"options": "Loan Repayment Schedule"
},
{
"fetch_from": ".",
"fieldname": "loan_disbursement",
"fieldtype": "Link",
"label": "Loan Disbursement",
"options": "Loan Disbursement"
},
{
"fetch_from": "loan_repayment_schedule.posting_date",
"fieldname": "disbursement_date",
"fieldtype": "Date",
"label": "Disbursement Date"
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2024-01-06 16:22:37.771957",
"modified": "2024-01-11 13:43:39.861311",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan Demand",
Expand Down
26 changes: 19 additions & 7 deletions lending/loan_management/doctype/loan_demand/loan_demand.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,19 @@ def make_loan_demand_for_term_loans(

open_loans = frappe.db.get_all("Loan", filters=filters, pluck="name")

loan_repayment_schedule_map = frappe._dict(
frappe.db.get_all(
"Loan Repayment Schedule",
filters={"docstatus": 1, "status": "Active", "loan": ("in", open_loans)},
fields=["name", "loan"],
as_list=1,
)
loan_repayment_schedules = frappe.db.get_all(
"Loan Repayment Schedule",
filters={"docstatus": 1, "status": "Active", "loan": ("in", open_loans)},
fields=["name", "loan", "loan_disbursement"],
)

loan_repayment_schedule_map = frappe._dict()
disbursement_map = frappe._dict()

for schedule in loan_repayment_schedules:
loan_repayment_schedule_map[schedule.name] = schedule.loan
disbursement_map[schedule.name] = schedule.loan_disbursement

repayment_schedules = loan_repayment_schedule_map.keys()

emi_rows = frappe.db.get_all(
Expand All @@ -125,6 +129,8 @@ def make_loan_demand_for_term_loans(
for row in emi_rows:
create_loan_demand(
loan_repayment_schedule_map.get(row.parent),
row.parent,
disbursement_map.get(row.parent),
row.payment_date,
"EMI",
"Interest",
Expand All @@ -134,6 +140,8 @@ def make_loan_demand_for_term_loans(
)
create_loan_demand(
loan_repayment_schedule_map.get(row.parent),
row.parent,
disbursement_map.get(row.parent),
row.payment_date,
"EMI",
"Principal",
Expand All @@ -145,6 +153,8 @@ def make_loan_demand_for_term_loans(

def create_loan_demand(
loan,
loan_repayment_schedule,
loan_disbursement,
posting_date,
demand_type,
demand_subtype,
Expand All @@ -156,6 +166,8 @@ def create_loan_demand(
if amount:
demand = frappe.new_doc("Loan Demand")
demand.loan = loan
demand.loan_repayment_schedule = loan_repayment_schedule
demand.loan_disbursement = loan_disbursement
demand.repayment_schedule_detail = repayment_schedule_detail
demand.demand_date = posting_date
demand.demand_type = demand_type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ frappe.ui.form.on('Loan Disbursement', {
return {
'filters': {
'docstatus': 1,
"status": ["in",["Sanctioned","Active"]],
"status": ["in",["Sanctioned","Active", "Partially Disbursed"]],
}
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
"applicant_type",
"loan_product",
"monthly_repayment_amount",
"tenure",
"column_break_4",
"company",
"applicant",
"repayment_schedule_type",
"repayment_frequency",
"repayment_method",
"tenure",
"repayment_start_date",
"is_term_loan",
"withhold_security_deposit",
Expand Down Expand Up @@ -247,7 +247,8 @@
"fieldname": "repayment_schedule_type",
"fieldtype": "Data",
"hidden": 1,
"label": "Repayment Schedule Type"
"label": "Repayment Schedule Type",
"read_only": 1
},
{
"fetch_from": "against_loan.repayment_start_date",
Expand Down Expand Up @@ -294,7 +295,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2023-12-29 20:32:10.687328",
"modified": "2024-01-10 20:01:44.186607",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan Disbursement",
Expand Down
Loading

0 comments on commit 3a655bc

Please sign in to comment.