Skip to content

Commit

Permalink
feat: broken period interest calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
deepeshgarg007 committed Dec 11, 2023
1 parent a31b1cc commit a987b5f
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"clearance_date",
"column_break_8",
"disbursed_amount",
"broken_period_interest",
"accounting_dimensions_section",
"cost_center",
"charges_section",
Expand Down Expand Up @@ -279,12 +280,18 @@
"fieldtype": "Currency",
"label": "Current Disbursed Amount",
"read_only": 1
},
{
"fieldname": "broken_period_interest",
"fieldtype": "Currency",
"label": "Broken Period Interest",
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2023-12-07 10:43:07.860874",
"modified": "2023-12-10 18:58:36.390130",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan Disbursement",
Expand Down
125 changes: 45 additions & 80 deletions lending/loan_management/doctype/loan_disbursement/loan_disbursement.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ def get_schedule_details(self):
"repayment_method": self.repayment_method,
"repayment_start_date": self.repayment_start_date,
"repayment_periods": self.tenure,
"monthly_repayment_amount": self.monthly_repayment_amount,
"posting_date": self.disbursement_date,
"repayment_frequency": self.repayment_frequency,
"disbursed_amount": disbursed_amount,
Expand All @@ -79,7 +78,9 @@ def make_draft_schedule(self):
already_accrued_months = self.get_already_accrued_months()
self.tenure = loan_details.repayment_periods - already_accrued_months

frappe.get_doc(self.get_schedule_details()).insert()
schedule = frappe.get_doc(self.get_schedule_details()).insert()
self.monthly_repayment_amount = schedule.monthly_repayment_amount
self.broken_period_interest = schedule.broken_period_interest

def get_already_accrued_months(self):
already_accrued_months = 0
Expand Down Expand Up @@ -129,6 +130,9 @@ def update_draft_schedule(self):
schedule.update(self.get_schedule_details())
schedule.save()

self.broken_period_interest = schedule.broken_period_interest
self.monthly_repayment_amount = schedule.monthly_repayment_amount

def on_submit(self):
if self.is_term_loan:
self.update_current_repayment_schedule()
Expand Down Expand Up @@ -370,19 +374,17 @@ def get_values_on_submit(self, loan_details):

return disbursed_amount, status, total_payment

def make_gl_entries(self, cancel=0, adv_adj=0):
gle_map = []

gle_map.append(
def add_gl_entry(self, gl_entries, account, against_account, amount, remarks=None):
gl_entries.append(
self.get_gl_dict(
{
"account": self.loan_account,
"against": self.disbursement_account,
"debit": self.disbursed_amount,
"debit_in_account_currency": self.disbursed_amount,
"account": account,
"against": against_account,
"debit": amount,
"debit_in_account_currency": amount,
"against_voucher_type": "Loan",
"against_voucher": self.against_loan,
"remarks": _("Disbursement against loan:") + self.against_loan,
"remarks": remarks,
"cost_center": self.cost_center,
"party_type": self.applicant_type,
"party": self.applicant,
Expand All @@ -391,95 +393,58 @@ def make_gl_entries(self, cancel=0, adv_adj=0):
)
)

gle_map.append(
gl_entries.append(
self.get_gl_dict(
{
"account": self.disbursement_account,
"against": self.loan_account,
"credit": self.disbursed_amount,
"credit_in_account_currency": self.disbursed_amount,
"account": against_account,
"against": account,
"debit": -1 * amount,
"debit_in_account_currency": amount,
"against_voucher_type": "Loan",
"against_voucher": self.against_loan,
"remarks": _("Disbursement against loan:") + self.against_loan,
"remarks": remarks,
"cost_center": self.cost_center,
"posting_date": self.disbursement_date,
}
)
)

def make_gl_entries(self, cancel=0, adv_adj=0):
gle_map = []
remarks = _("Disbursement against loan:") + self.against_loan

self.add_gl_entry(
gle_map, self.loan_account, self.disbursement_account, self.disbursed_amount, remarks
)

if self.withhold_security_deposit:
security_deposit_account = frappe.db.get_value(
"Loan Product", self.loan_product, "security_deposit_account"
)
gle_map.append(
self.get_gl_dict(
{
"account": security_deposit_account,
"against": self.disbursement_account,
"credit": self.monthly_repayment_amount,
"credit_in_account_currency": self.monthly_repayment_amount,
"against_voucher_type": "Loan",
"against_voucher": self.against_loan,
"remarks": _("Disbursement against loan:") + self.against_loan,
"cost_center": self.cost_center,
"party_type": self.applicant_type,
"party": self.applicant,
"posting_date": self.disbursement_date,
}
)
)

gle_map.append(
self.get_gl_dict(
{
"account": self.disbursement_account,
"against": self.loan_account,
"credit": -1 * self.monthly_repayment_amount,
"credit_in_account_currency": -1 * self.monthly_repayment_amount,
"against_voucher_type": "Loan",
"against_voucher": self.against_loan,
"remarks": _("Disbursement against loan:") + self.against_loan,
"cost_center": self.cost_center,
"posting_date": self.disbursement_date,
}
)
self.add_gl_entry(
gle_map,
security_deposit_account,
self.disbursement_account,
-1 * self.monthly_repayment_amount,
remarks,
)

for charge in self.get("loan_disbursement_charges"):
gle_map.append(
self.get_gl_dict(
{
"account": charge.account,
"against": self.disbursement_account,
"credit": charge.amount,
"credit_in_account_currency": charge.amount,
"against_voucher_type": "Loan",
"against_voucher": self.against_loan,
"remarks": _("Disbursement against loan:") + self.against_loan,
"cost_center": self.cost_center,
"party_type": self.applicant_type,
"party": self.applicant,
"posting_date": self.disbursement_date,
}
)
if self.broken_period_interest:
broken_period_interest_account = frappe.db.get_value(
"Loan Product", self.loan_product, "broken_period_interest_recovery_account"
)

gle_map.append(
self.get_gl_dict(
{
"account": self.disbursement_account,
"against": self.loan_account,
"credit": -1 * charge.amount,
"credit_in_account_currency": -1 * charge.amount,
"against_voucher_type": "Loan",
"against_voucher": self.against_loan,
"remarks": _("Disbursement against loan:") + self.against_loan,
"cost_center": self.cost_center,
"posting_date": self.disbursement_date,
}
)
self.add_gl_entry(
gle_map,
broken_period_interest_account,
self.disbursement_account,
-1 * self.broken_period_interest,
remarks,
)

for charge in self.get("loan_disbursement_charges"):
self.add_gl_entry(gle_map, charge.account, self.disbursement_account, charge.amount, remarks)

if gle_map:
make_gl_entries(gle_map, cancel=cancel, adv_adj=adv_adj)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"rate_of_interest",
"posting_date",
"adjusted_interest",
"broken_period_interest",
"column_break_n6iy",
"loan_product",
"repayment_frequency",
Expand Down Expand Up @@ -188,12 +189,18 @@
"fieldtype": "Link",
"label": "Loan Disbursement",
"options": "Loan Disbursement"
},
{
"fieldname": "broken_period_interest",
"fieldtype": "Currency",
"label": "Broken Period Interest",
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2023-12-05 22:50:03.030846",
"modified": "2023-12-10 18:53:50.681242",
"modified_by": "Administrator",
"module": "Loan Management",
"name": "Loan Repayment Schedule",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def make_repayment_schedule(self):
self.repayment_schedule = []
payment_date = self.repayment_start_date
balance_amount = self.disbursed_amount or self.loan_amount
broken_period_interest_days = date_diff(add_months(payment_date, -1), self.posting_date)
broken_period_interest_days = date_diff(add_months(payment_date, -1), self.posting_date) + 1
carry_forward_interest = self.adjusted_interest
moratorium_interest = 0

Expand Down Expand Up @@ -140,7 +140,7 @@ def get_amounts(
additional_days,
carry_forward_interest=0,
):
days, months = self.get_days_and_months(payment_date, additional_days)
days, months = self.get_days_and_months(payment_date, additional_days, balance_amount)
interest_amount = flt(balance_amount * flt(self.rate_of_interest) * days / (months * 100))
principal_amount = self.monthly_repayment_amount - flt(interest_amount)
balance_amount = flt(balance_amount + interest_amount - self.monthly_repayment_amount)
Expand All @@ -155,7 +155,7 @@ def get_amounts(

return interest_amount, principal_amount, balance_amount, total_payment, days

def get_days_and_months(self, payment_date, additional_days):
def get_days_and_months(self, payment_date, additional_days, balance_amount):
months = 365
if self.repayment_frequency == "Monthly":
if self.repayment_schedule_type == "Monthly as per repayment start date":
Expand All @@ -173,7 +173,7 @@ def get_days_and_months(self, payment_date, additional_days):
additional_days = 0

if additional_days:
days += additional_days
self.add_broken_period_interest(balance_amount, additional_days, payment_date)
additional_days = 0
elif expected_payment_date == payment_date:
# using 30 days for calculating interest for all full months
Expand All @@ -182,7 +182,7 @@ def get_days_and_months(self, payment_date, additional_days):
days = date_diff(get_last_day(payment_date), payment_date)
else:
if payment_date == self.repayment_start_date:
days = date_diff(payment_date, self.posting_date) + 1
days = date_diff(payment_date, self.posting_date)
elif self.repayment_frequency == "Weekly":
days = 7
elif self.repayment_frequency == "Daily":
Expand All @@ -194,6 +194,17 @@ def get_days_and_months(self, payment_date, additional_days):

return days, months

def add_broken_period_interest(self, balance_amount, additional_days, payment_date):
interest_amount = flt(
balance_amount * flt(self.rate_of_interest) * additional_days / (365 * 100)
)
payment_date = add_months(payment_date, -1)
self.add_repayment_schedule_row(
payment_date, 0, interest_amount, interest_amount, balance_amount, additional_days
)

self.broken_period_interest = interest_amount

def add_repayment_schedule_row(
self, payment_date, principal_amount, interest_amount, total_payment, balance_loan_amount, days
):
Expand Down

0 comments on commit a987b5f

Please sign in to comment.