fix: Unsecured loan status update
This commit is contained in:
parent
1a5f0da6ca
commit
dcae9ba86e
@ -178,20 +178,19 @@ def get_total_pledged_security_value(loan):
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_disbursal_amount(loan, on_current_security_price=0):
|
||||
from erpnext.loan_management.doctype.loan_repayment.loan_repayment import (
|
||||
get_pending_principal_amount,
|
||||
)
|
||||
|
||||
loan_details = frappe.get_value("Loan", loan, ["loan_amount", "disbursed_amount", "total_payment",
|
||||
"total_principal_paid", "total_interest_payable", "status", "is_term_loan", "is_secured_loan",
|
||||
"maximum_loan_amount"], as_dict=1)
|
||||
"maximum_loan_amount", "written_off_amount"], as_dict=1)
|
||||
|
||||
if loan_details.is_secured_loan and frappe.get_all('Loan Security Shortfall', filters={'loan': loan,
|
||||
'status': 'Pending'}):
|
||||
return 0
|
||||
|
||||
if loan_details.status == 'Disbursed':
|
||||
pending_principal_amount = flt(loan_details.total_payment) - flt(loan_details.total_interest_payable) \
|
||||
- flt(loan_details.total_principal_paid)
|
||||
else:
|
||||
pending_principal_amount = flt(loan_details.disbursed_amount) - flt(loan_details.total_interest_payable) \
|
||||
- flt(loan_details.total_principal_paid)
|
||||
pending_principal_amount = get_pending_principal_amount(loan_details)
|
||||
|
||||
security_value = 0.0
|
||||
if loan_details.is_secured_loan and on_current_security_price:
|
||||
|
@ -117,7 +117,10 @@ class LoanInterestAccrual(AccountsController):
|
||||
# rate of interest is 13.5 then first loan interest accural will be on '01-10-2019'
|
||||
# which means interest will be accrued for 30 days which should be equal to 11095.89
|
||||
def calculate_accrual_amount_for_demand_loans(loan, posting_date, process_loan_interest, accrual_type):
|
||||
from erpnext.loan_management.doctype.loan_repayment.loan_repayment import calculate_amounts
|
||||
from erpnext.loan_management.doctype.loan_repayment.loan_repayment import (
|
||||
calculate_amounts,
|
||||
get_pending_principal_amount,
|
||||
)
|
||||
|
||||
no_of_days = get_no_of_days_for_interest_accural(loan, posting_date)
|
||||
precision = cint(frappe.db.get_default("currency_precision")) or 2
|
||||
@ -125,12 +128,7 @@ def calculate_accrual_amount_for_demand_loans(loan, posting_date, process_loan_i
|
||||
if no_of_days <= 0:
|
||||
return
|
||||
|
||||
if loan.status == 'Disbursed':
|
||||
pending_principal_amount = flt(loan.total_payment) - flt(loan.total_interest_payable) \
|
||||
- flt(loan.total_principal_paid) - flt(loan.written_off_amount)
|
||||
else:
|
||||
pending_principal_amount = flt(loan.disbursed_amount) - flt(loan.total_interest_payable) \
|
||||
- flt(loan.total_principal_paid) - flt(loan.written_off_amount)
|
||||
pending_principal_amount = get_pending_principal_amount(loan)
|
||||
|
||||
interest_per_day = get_per_day_interest(pending_principal_amount, loan.rate_of_interest, posting_date)
|
||||
payable_interest = interest_per_day * no_of_days
|
||||
@ -168,7 +166,7 @@ def make_accrual_interest_entry_for_demand_loans(posting_date, process_loan_inte
|
||||
|
||||
if not open_loans:
|
||||
open_loans = frappe.get_all("Loan",
|
||||
fields=["name", "total_payment", "total_amount_paid", "loan_account", "interest_income_account",
|
||||
fields=["name", "total_payment", "total_amount_paid", "loan_account", "interest_income_account", "loan_amount",
|
||||
"is_term_loan", "status", "disbursement_date", "disbursed_amount", "applicant_type", "applicant",
|
||||
"rate_of_interest", "total_interest_payable", "written_off_amount", "total_principal_paid", "repayment_start_date"],
|
||||
filters=query_filters)
|
||||
@ -225,7 +223,8 @@ def get_term_loans(date, term_loan=None, loan_type=None):
|
||||
AND l.is_term_loan =1
|
||||
AND rs.payment_date <= %s
|
||||
AND rs.is_accrued=0 {0}
|
||||
AND l.status = 'Disbursed'""".format(condition), (getdate(date)), as_dict=1)
|
||||
AND l.status = 'Disbursed'
|
||||
ORDER BY rs.payment_date""".format(condition), (getdate(date)), as_dict=1)
|
||||
|
||||
return term_loans
|
||||
|
||||
|
@ -126,7 +126,18 @@ class LoanRepayment(AccountsController):
|
||||
})
|
||||
|
||||
def update_paid_amount(self):
|
||||
loan = frappe.get_doc("Loan", self.against_loan)
|
||||
loan = frappe.get_value("Loan", self.against_loan, ['total_amount_paid', 'total_principal_paid',
|
||||
'status', 'is_secured_loan', 'total_payment', 'loan_amount', 'total_interest_payable',
|
||||
'written_off_amount'], as_dict=1)
|
||||
|
||||
loan.update({
|
||||
'total_amount_paid': loan.total_amount_paid + self.amount_paid,
|
||||
'total_principal_paid': loan.total_principal_paid + self.principal_amount_paid
|
||||
})
|
||||
|
||||
pending_principal_amount = get_pending_principal_amount(loan)
|
||||
if not loan.is_secured_loan and pending_principal_amount < 0:
|
||||
loan.update({'status': 'Loan Closure Requested'})
|
||||
|
||||
for payment in self.repayment_details:
|
||||
frappe.db.sql(""" UPDATE `tabLoan Interest Accrual`
|
||||
@ -135,17 +146,31 @@ class LoanRepayment(AccountsController):
|
||||
WHERE name = %s""",
|
||||
(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
|
||||
WHERE name = %s """, (loan.total_amount_paid + self.amount_paid,
|
||||
loan.total_principal_paid + self.principal_amount_paid, self.against_loan))
|
||||
frappe.db.sql(""" UPDATE `tabLoan`
|
||||
SET total_amount_paid = %s, total_principal_paid = %s, status = %s
|
||||
WHERE name = %s """, (loan.total_amount_paid, loan.total_principal_paid, loan.status,
|
||||
self.against_loan))
|
||||
|
||||
update_shortfall_status(self.against_loan, self.principal_amount_paid)
|
||||
|
||||
def mark_as_unpaid(self):
|
||||
loan = frappe.get_doc("Loan", self.against_loan)
|
||||
loan = frappe.get_value("Loan", self.against_loan, ['total_amount_paid', 'total_principal_paid',
|
||||
'status', 'is_secured_loan', 'total_payment', 'loan_amount', 'total_interest_payable',
|
||||
'written_off_amount'], as_dict=1)
|
||||
|
||||
no_of_repayments = len(self.repayment_details)
|
||||
|
||||
loan.update({
|
||||
'total_amount_paid': loan.total_amount_paid - self.amount_paid,
|
||||
'total_principal_paid': loan.total_principal_paid - self.principal_amount_paid
|
||||
})
|
||||
|
||||
if loan.status == 'Loan Closure Requested':
|
||||
if loan.disbursed_amount >= loan.loan_amount:
|
||||
loan['status'] = 'Disbursed'
|
||||
else:
|
||||
loan['status'] = 'Partially Disbursed'
|
||||
|
||||
for payment in self.repayment_details:
|
||||
frappe.db.sql(""" UPDATE `tabLoan Interest Accrual`
|
||||
SET paid_principal_amount = `paid_principal_amount` - %s,
|
||||
@ -159,12 +184,9 @@ class LoanRepayment(AccountsController):
|
||||
lia_doc = frappe.get_doc('Loan Interest Accrual', payment.loan_interest_accrual)
|
||||
lia_doc.cancel()
|
||||
|
||||
frappe.db.sql(""" UPDATE `tabLoan` SET total_amount_paid = %s, total_principal_paid = %s
|
||||
WHERE name = %s """, (loan.total_amount_paid - self.amount_paid,
|
||||
loan.total_principal_paid - self.principal_amount_paid, self.against_loan))
|
||||
|
||||
if loan.status == "Loan Closure Requested":
|
||||
frappe.db.set_value("Loan", self.against_loan, "status", "Disbursed")
|
||||
frappe.db.sql(""" UPDATE `tabLoan`
|
||||
SET total_amount_paid = %s, total_principal_paid = %s, status = %s
|
||||
WHERE name = %s """, (loan.total_amount_paid, loan.total_principal_paid, loan.status, self.against_loan))
|
||||
|
||||
def update_repayment_schedule(self):
|
||||
if self.is_term_loan and self.principal_amount_paid > self.payable_principal_amount:
|
||||
@ -431,12 +453,7 @@ def regenerate_repayment_schedule(loan):
|
||||
|
||||
loan_doc.save()
|
||||
|
||||
if loan_doc.status in ('Disbursed', 'Loan Closure Requested', 'Closed'):
|
||||
balance_amount = loan_doc.total_payment - loan_doc.total_principal_paid \
|
||||
- loan_doc.total_interest_payable - loan_doc.written_off_amount
|
||||
else:
|
||||
balance_amount = loan_doc.disbursed_amount - loan_doc.total_principal_paid \
|
||||
- loan_doc.total_interest_payable - loan_doc.written_off_amount
|
||||
balance_amount = get_pending_principal_amount(loan_doc)
|
||||
|
||||
monthly_repayment_amount = get_monthly_repayment_amount(loan_doc.loan_amount,
|
||||
loan_doc.rate_of_interest, loan_doc.repayment_periods)
|
||||
@ -464,6 +481,16 @@ def regenerate_repayment_schedule(loan):
|
||||
|
||||
loan_doc.save()
|
||||
|
||||
def get_pending_principal_amount(loan):
|
||||
if loan.status in ('Disbursed', 'Closed') or loan.disbursed_amount >= loan.loan_amount:
|
||||
pending_principal_amount = flt(loan.total_payment) - flt(loan.total_principal_paid) \
|
||||
- flt(loan.total_interest_payable) - flt(loan.written_off_amount)
|
||||
else:
|
||||
pending_principal_amount = flt(loan.disbursed_amount) - flt(loan.total_principal_paid) \
|
||||
- flt(loan.total_interest_payable) - flt(loan.written_off_amount)
|
||||
|
||||
return pending_principal_amount
|
||||
|
||||
# This function returns the amounts that are payable at the time of loan repayment based on posting date
|
||||
# So it pulls all the unpaid Loan Interest Accrual Entries and calculates the penalty if applicable
|
||||
|
||||
@ -511,12 +538,7 @@ def get_amounts(amounts, against_loan, posting_date):
|
||||
if due_date and not final_due_date:
|
||||
final_due_date = add_days(due_date, loan_type_details.grace_period_in_days)
|
||||
|
||||
if against_loan_doc.status in ('Disbursed', 'Loan Closure Requested', 'Closed'):
|
||||
pending_principal_amount = against_loan_doc.total_payment - against_loan_doc.total_principal_paid \
|
||||
- against_loan_doc.total_interest_payable - against_loan_doc.written_off_amount
|
||||
else:
|
||||
pending_principal_amount = against_loan_doc.disbursed_amount - against_loan_doc.total_principal_paid \
|
||||
- against_loan_doc.total_interest_payable - against_loan_doc.written_off_amount
|
||||
pending_principal_amount = get_pending_principal_amount(against_loan_doc)
|
||||
|
||||
unaccrued_interest = 0
|
||||
if due_date:
|
||||
|
@ -30,6 +30,9 @@ class LoanSecurityUnpledge(Document):
|
||||
d.idx, frappe.bold(d.loan_security)))
|
||||
|
||||
def validate_unpledge_qty(self):
|
||||
from erpnext.loan_management.doctype.loan_repayment.loan_repayment import (
|
||||
get_pending_principal_amount,
|
||||
)
|
||||
from erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall import (
|
||||
get_ltv_ratio,
|
||||
)
|
||||
@ -46,15 +49,10 @@ class LoanSecurityUnpledge(Document):
|
||||
"valid_upto": (">=", get_datetime())
|
||||
}, as_list=1))
|
||||
|
||||
loan_details = frappe.get_value("Loan", self.loan, ['total_payment', 'total_principal_paid',
|
||||
loan_details = frappe.get_value("Loan", self.loan, ['total_payment', 'total_principal_paid', 'loan_amount',
|
||||
'total_interest_payable', 'written_off_amount', 'disbursed_amount', 'status'], as_dict=1)
|
||||
|
||||
if loan_details.status == 'Disbursed':
|
||||
pending_principal_amount = flt(loan_details.total_payment) - flt(loan_details.total_interest_payable) \
|
||||
- flt(loan_details.total_principal_paid) - flt(loan_details.written_off_amount)
|
||||
else:
|
||||
pending_principal_amount = flt(loan_details.disbursed_amount) - flt(loan_details.total_interest_payable) \
|
||||
- flt(loan_details.total_principal_paid) - flt(loan_details.written_off_amount)
|
||||
pending_principal_amount = get_pending_principal_amount(loan_details)
|
||||
|
||||
security_value = 0
|
||||
unpledge_qty_map = {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user