diff --git a/erpnext/loan_management/doctype/loan/loan.json b/erpnext/loan_management/doctype/loan/loan.json index b613d22827..23996afd21 100644 --- a/erpnext/loan_management/doctype/loan/loan.json +++ b/erpnext/loan_management/doctype/loan/loan.json @@ -344,13 +344,14 @@ "fieldtype": "Currency", "label": "Written Off Amount", "no_copy": 1, - "options": "Company:company:default_currency" + "options": "Company:company:default_currency", + "read_only": 1 } ], "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2020-10-22 11:03:43.697394", + "modified": "2020-10-27 23:37:02.785940", "modified_by": "Administrator", "module": "Loan Management", "name": "Loan", diff --git a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py index f58b989a20..949e1412e2 100644 --- a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py +++ b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py @@ -77,7 +77,7 @@ class LoanDisbursement(AccountsController): if disbursed_amount == 0: status = "Sanctioned" - total_payment = loan_details.loan_amount + elif disbursed_amount >= loan_details.loan_amount: status = "Disbursed" else: @@ -89,7 +89,7 @@ class LoanDisbursement(AccountsController): disbursed_amount = self.disbursed_amount + loan_details.disbursed_amount total_payment = loan_details.total_payment - if loan_details.status == "Disbursed" and not loan_details.is_term_loan: + if loan_details.status in ("Disbursed", "Partially Disbursed") and not loan_details.is_term_loan: process_loan_interest_accrual_for_demand_loans(posting_date=add_days(self.disbursement_date, -1), loan=self.against_loan, accrual_type="Disbursement") @@ -108,7 +108,6 @@ class LoanDisbursement(AccountsController): status = "Disbursed" else: status = "Partially Disbursed" - total_payment = disbursed_amount return disbursed_amount, status, total_payment @@ -199,6 +198,9 @@ def get_disbursal_amount(loan): disbursal_amount = flt(security_value) - flt(pending_principal_amount) + if loan_details.is_term_loan and (disbursal_amount + loan_details.loan_amount) > loan_details.loan_amount: + disbursal_amount = loan_details.loan_amount - loan_details.disbursed_amount + return disbursal_amount diff --git a/erpnext/loan_management/doctype/loan_disbursement/test_loan_disbursement.py b/erpnext/loan_management/doctype/loan_disbursement/test_loan_disbursement.py index aaaeea8c4e..a8753877a6 100644 --- a/erpnext/loan_management/doctype/loan_disbursement/test_loan_disbursement.py +++ b/erpnext/loan_management/doctype/loan_disbursement/test_loan_disbursement.py @@ -69,6 +69,12 @@ class TestLoanDisbursement(unittest.TestCase): # After repayment loan disbursement entry should go through make_loan_disbursement_entry(loan.name, 500000, disbursement_date=add_days(last_date, 16)) + # check for disbursement accrual + loan_interest_accrual = frappe.db.get_value('Loan Interest Accrual', {'loan': loan.name, + 'accrual_type': 'Disbursement'}) + + self.assertTrue(loan_interest_accrual) + def test_loan_topup_with_additional_pledge(self): pledge = [{ "loan_security": "Test Security 1", diff --git a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py index 1fc41f9ea5..d0b957de56 100644 --- a/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py +++ b/erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py @@ -218,7 +218,7 @@ def get_no_of_days_for_interest_accural(loan, posting_date): def get_last_accural_date(loan): last_posting_date = frappe.db.sql(""" SELECT MAX(posting_date) from `tabLoan Interest Accrual` - WHERE loan = %s""", (loan)) + WHERE loan = %s and docstatus = 1""", (loan)) if last_posting_date[0][0]: # interest for last interest accrual date is already booked, so add 1 day diff --git a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py index c1e83d9305..63d388daf5 100644 --- a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py +++ b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py @@ -301,7 +301,8 @@ def get_accrued_interest_entries(against_loan): unpaid_accrued_entries = frappe.db.sql( """ SELECT name, posting_date, interest_amount - paid_interest_amount as interest_amount, - payable_principal_amount - paid_principal_amount as payable_principal_amount + payable_principal_amount - paid_principal_amount as payable_principal_amount, + accrual_type FROM `tabLoan Interest Accrual` WHERE @@ -342,7 +343,7 @@ def get_amounts(amounts, against_loan, posting_date): no_of_late_days = date_diff(posting_date, add_days(due_date, loan_type_details.grace_period_in_days)) - if no_of_late_days > 0 and (not against_loan_doc.repay_from_salary): + if no_of_late_days > 0 and (not against_loan_doc.repay_from_salary) and entry.accrual_type == 'Regular': penalty_amount += (entry.interest_amount * (loan_type_details.penalty_interest_rate / 100) * no_of_late_days)/365 total_pending_interest += entry.interest_amount @@ -353,7 +354,7 @@ def get_amounts(amounts, against_loan, posting_date): 'payable_principal_amount': flt(entry.payable_principal_amount, precision) }) - if not final_due_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'):