Merge pull request #24703 from deepeshgarg007/loan_test_precision_fix_new
fix: Precision fixes in loans
This commit is contained in:
commit
3dd0e49525
@ -201,7 +201,9 @@ def request_loan_closure(loan, posting_date=None):
|
|||||||
write_off_limit = frappe.get_value('Loan Type', loan_type, 'write_off_amount')
|
write_off_limit = frappe.get_value('Loan Type', loan_type, 'write_off_amount')
|
||||||
|
|
||||||
# checking greater than 0 as there may be some minor precision error
|
# checking greater than 0 as there may be some minor precision error
|
||||||
if pending_amount < write_off_limit:
|
if not pending_amount:
|
||||||
|
frappe.db.set_value('Loan', loan, 'status', 'Loan Closure Requested')
|
||||||
|
elif pending_amount < write_off_limit:
|
||||||
# Auto create loan write off and update status as loan closure requested
|
# Auto create loan write off and update status as loan closure requested
|
||||||
write_off = make_loan_write_off(loan)
|
write_off = make_loan_write_off(loan)
|
||||||
write_off.submit()
|
write_off.submit()
|
||||||
|
@ -547,7 +547,7 @@ class TestLoan(unittest.TestCase):
|
|||||||
|
|
||||||
# 30 days - grace period
|
# 30 days - grace period
|
||||||
penalty_days = 30 - 4
|
penalty_days = 30 - 4
|
||||||
penalty_applicable_amount = flt(amounts['interest_amount']/2, 2)
|
penalty_applicable_amount = flt(amounts['interest_amount']/2)
|
||||||
penalty_amount = flt((((penalty_applicable_amount * 25) / 100) * penalty_days), 2)
|
penalty_amount = flt((((penalty_applicable_amount * 25) / 100) * penalty_days), 2)
|
||||||
process = process_loan_interest_accrual_for_demand_loans(posting_date = '2019-11-30')
|
process = process_loan_interest_accrual_for_demand_loans(posting_date = '2019-11-30')
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ def get_proposed_pledge(securities):
|
|||||||
security.qty = cint(security.amount/security.loan_security_price)
|
security.qty = cint(security.amount/security.loan_security_price)
|
||||||
|
|
||||||
security.amount = security.qty * security.loan_security_price
|
security.amount = security.qty * security.loan_security_price
|
||||||
security.post_haircut_amount = security.amount - (security.amount * security.haircut/100)
|
security.post_haircut_amount = cint(security.amount - (security.amount * security.haircut/100))
|
||||||
|
|
||||||
maximum_loan_amount += security.post_haircut_amount
|
maximum_loan_amount += security.post_haircut_amount
|
||||||
|
|
||||||
|
@ -246,7 +246,5 @@ def get_per_day_interest(principal_amount, rate_of_interest, posting_date=None):
|
|||||||
if not posting_date:
|
if not posting_date:
|
||||||
posting_date = getdate()
|
posting_date = getdate()
|
||||||
|
|
||||||
precision = cint(frappe.db.get_default("currency_precision")) or 2
|
return flt((principal_amount * rate_of_interest) / (days_in_year(get_datetime(posting_date).year) * 100))
|
||||||
|
|
||||||
return flt((principal_amount * rate_of_interest) / (days_in_year(get_datetime(posting_date).year) * 100), precision)
|
|
||||||
|
|
||||||
|
@ -81,8 +81,8 @@ class LoanRepayment(AccountsController):
|
|||||||
last_accrual_date = get_last_accrual_date(self.against_loan)
|
last_accrual_date = get_last_accrual_date(self.against_loan)
|
||||||
|
|
||||||
# get posting date upto which interest has to be accrued
|
# get posting date upto which interest has to be accrued
|
||||||
per_day_interest = flt(get_per_day_interest(self.pending_principal_amount,
|
per_day_interest = get_per_day_interest(self.pending_principal_amount,
|
||||||
self.rate_of_interest, self.posting_date), 2)
|
self.rate_of_interest, self.posting_date)
|
||||||
|
|
||||||
no_of_days = flt(flt(self.total_interest_paid - self.interest_payable,
|
no_of_days = flt(flt(self.total_interest_paid - self.interest_payable,
|
||||||
precision)/per_day_interest, 0) - 1
|
precision)/per_day_interest, 0) - 1
|
||||||
@ -105,8 +105,6 @@ class LoanRepayment(AccountsController):
|
|||||||
})
|
})
|
||||||
|
|
||||||
def update_paid_amount(self):
|
def update_paid_amount(self):
|
||||||
precision = cint(frappe.db.get_default("currency_precision")) or 2
|
|
||||||
|
|
||||||
loan = frappe.get_doc("Loan", self.against_loan)
|
loan = frappe.get_doc("Loan", self.against_loan)
|
||||||
|
|
||||||
for payment in self.repayment_details:
|
for payment in self.repayment_details:
|
||||||
@ -114,7 +112,7 @@ class LoanRepayment(AccountsController):
|
|||||||
SET paid_principal_amount = `paid_principal_amount` + %s,
|
SET paid_principal_amount = `paid_principal_amount` + %s,
|
||||||
paid_interest_amount = `paid_interest_amount` + %s
|
paid_interest_amount = `paid_interest_amount` + %s
|
||||||
WHERE name = %s""",
|
WHERE name = %s""",
|
||||||
(flt(payment.paid_principal_amount, precision), flt(payment.paid_interest_amount, precision), payment.loan_interest_accrual))
|
(flt(payment.paid_principal_amount), flt(payment.paid_interest_amount), payment.loan_interest_accrual))
|
||||||
|
|
||||||
frappe.db.sql(""" UPDATE `tabLoan` SET total_amount_paid = %s, total_principal_paid = %s
|
frappe.db.sql(""" UPDATE `tabLoan` SET total_amount_paid = %s, total_principal_paid = %s
|
||||||
WHERE name = %s """, (loan.total_amount_paid + self.amount_paid,
|
WHERE name = %s """, (loan.total_amount_paid + self.amount_paid,
|
||||||
@ -148,8 +146,6 @@ class LoanRepayment(AccountsController):
|
|||||||
frappe.db.set_value("Loan", self.against_loan, "status", "Disbursed")
|
frappe.db.set_value("Loan", self.against_loan, "status", "Disbursed")
|
||||||
|
|
||||||
def allocate_amounts(self, repayment_details):
|
def allocate_amounts(self, repayment_details):
|
||||||
precision = cint(frappe.db.get_default("currency_precision")) or 2
|
|
||||||
|
|
||||||
self.set('repayment_details', [])
|
self.set('repayment_details', [])
|
||||||
self.principal_amount_paid = 0
|
self.principal_amount_paid = 0
|
||||||
total_interest_paid = 0
|
total_interest_paid = 0
|
||||||
@ -185,21 +181,18 @@ class LoanRepayment(AccountsController):
|
|||||||
# no of days for which to accrue interest
|
# no of days for which to accrue interest
|
||||||
# Interest can only be accrued for an entire day and not partial
|
# Interest can only be accrued for an entire day and not partial
|
||||||
if interest_paid > repayment_details['unaccrued_interest']:
|
if interest_paid > repayment_details['unaccrued_interest']:
|
||||||
per_day_interest = flt(get_per_day_interest(self.pending_principal_amount,
|
|
||||||
self.rate_of_interest, self.posting_date), precision)
|
|
||||||
interest_paid -= repayment_details['unaccrued_interest']
|
interest_paid -= repayment_details['unaccrued_interest']
|
||||||
total_interest_paid += repayment_details['unaccrued_interest']
|
total_interest_paid += repayment_details['unaccrued_interest']
|
||||||
else:
|
else:
|
||||||
# get no of days for which interest can be paid
|
# get no of days for which interest can be paid
|
||||||
per_day_interest = flt(get_per_day_interest(self.pending_principal_amount,
|
per_day_interest = get_per_day_interest(self.pending_principal_amount,
|
||||||
self.rate_of_interest, self.posting_date), precision)
|
self.rate_of_interest, self.posting_date)
|
||||||
|
|
||||||
no_of_days = cint(interest_paid/per_day_interest)
|
no_of_days = cint(interest_paid/per_day_interest)
|
||||||
total_interest_paid += no_of_days * per_day_interest
|
total_interest_paid += no_of_days * per_day_interest
|
||||||
interest_paid -= no_of_days * per_day_interest
|
interest_paid -= no_of_days * per_day_interest
|
||||||
|
|
||||||
self.total_interest_paid = total_interest_paid
|
self.total_interest_paid = total_interest_paid
|
||||||
|
|
||||||
if interest_paid:
|
if interest_paid:
|
||||||
self.principal_amount_paid += interest_paid
|
self.principal_amount_paid += interest_paid
|
||||||
|
|
||||||
@ -369,7 +362,7 @@ def get_amounts(amounts, against_loan, posting_date):
|
|||||||
if pending_days > 0:
|
if pending_days > 0:
|
||||||
principal_amount = flt(pending_principal_amount, precision)
|
principal_amount = flt(pending_principal_amount, precision)
|
||||||
per_day_interest = get_per_day_interest(principal_amount, loan_type_details.rate_of_interest, posting_date)
|
per_day_interest = get_per_day_interest(principal_amount, loan_type_details.rate_of_interest, posting_date)
|
||||||
unaccrued_interest += (pending_days * flt(per_day_interest, precision))
|
unaccrued_interest += (pending_days * per_day_interest)
|
||||||
|
|
||||||
amounts["pending_principal_amount"] = flt(pending_principal_amount, precision)
|
amounts["pending_principal_amount"] = flt(pending_principal_amount, precision)
|
||||||
amounts["payable_principal_amount"] = flt(payable_principal_amount, precision)
|
amounts["payable_principal_amount"] = flt(payable_principal_amount, precision)
|
||||||
|
@ -76,7 +76,7 @@ def get_company_wise_loan_security_details(filters, loan_security_details):
|
|||||||
if qty:
|
if qty:
|
||||||
security_wise_map[key[1]]['applicant_count'] += 1
|
security_wise_map[key[1]]['applicant_count'] += 1
|
||||||
|
|
||||||
total_portfolio_value += flt(qty * loan_security_details.get(key[1])['latest_price'])
|
total_portfolio_value += flt(qty * loan_security_details.get(key[1], {}).get('latest_price', 0))
|
||||||
|
|
||||||
return security_wise_map, total_portfolio_value
|
return security_wise_map, total_portfolio_value
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user