mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-25 07:54:46 +00:00
Merge pull request #32011 from deepeshgarg007/loan_write_off_salary_slip
fix: Loan Write-off for term loans
This commit is contained in:
@@ -734,6 +734,7 @@ def get_amounts(amounts, against_loan, posting_date):
|
|||||||
)
|
)
|
||||||
amounts["pending_accrual_entries"] = pending_accrual_entries
|
amounts["pending_accrual_entries"] = pending_accrual_entries
|
||||||
amounts["unaccrued_interest"] = flt(unaccrued_interest, precision)
|
amounts["unaccrued_interest"] = flt(unaccrued_interest, precision)
|
||||||
|
amounts["written_off_amount"] = flt(against_loan_doc.written_off_amount, precision)
|
||||||
|
|
||||||
if final_due_date:
|
if final_due_date:
|
||||||
amounts["due_date"] = final_due_date
|
amounts["due_date"] = final_due_date
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ def process_loan_interest_accrual_for_demand_loans(
|
|||||||
|
|
||||||
def process_loan_interest_accrual_for_term_loans(posting_date=None, loan_type=None, loan=None):
|
def process_loan_interest_accrual_for_term_loans(posting_date=None, loan_type=None, loan=None):
|
||||||
|
|
||||||
if not term_loan_accrual_pending(posting_date or nowdate()):
|
if not term_loan_accrual_pending(posting_date or nowdate(), loan=loan):
|
||||||
return
|
return
|
||||||
|
|
||||||
loan_process = frappe.new_doc("Process Loan Interest Accrual")
|
loan_process = frappe.new_doc("Process Loan Interest Accrual")
|
||||||
@@ -71,9 +71,12 @@ def process_loan_interest_accrual_for_term_loans(posting_date=None, loan_type=No
|
|||||||
return loan_process.name
|
return loan_process.name
|
||||||
|
|
||||||
|
|
||||||
def term_loan_accrual_pending(date):
|
def term_loan_accrual_pending(date, loan=None):
|
||||||
pending_accrual = frappe.db.get_value(
|
filters = {"payment_date": ("<=", date), "is_accrued": 0}
|
||||||
"Repayment Schedule", {"payment_date": ("<=", date), "is_accrued": 0}
|
|
||||||
)
|
if loan:
|
||||||
|
filters.update({"parent": loan})
|
||||||
|
|
||||||
|
pending_accrual = frappe.db.get_value("Repayment Schedule", filters)
|
||||||
|
|
||||||
return pending_accrual
|
return pending_accrual
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
"fieldname": "total_payment",
|
"fieldname": "total_payment",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Total Payment",
|
"label": "Paid Amount",
|
||||||
"options": "Company:company:default_currency"
|
"options": "Company:company:default_currency"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-01-31 14:50:14.823213",
|
"modified": "2022-08-29 08:50:39.030296",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Loan Management",
|
"module": "Loan Management",
|
||||||
"name": "Salary Slip Loan",
|
"name": "Salary Slip Loan",
|
||||||
@@ -96,6 +96,5 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": [],
|
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -330,13 +330,13 @@ class TestPayrollEntry(FrappeTestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
salary_slip = frappe.get_doc("Salary Slip", name)
|
salary_slip = frappe.get_doc("Salary Slip", name)
|
||||||
|
|
||||||
for row in salary_slip.loans:
|
for row in salary_slip.loans:
|
||||||
if row.loan == loan.name:
|
if row.loan == loan.name:
|
||||||
interest_amount = (280000 * 8.4) / (12 * 100)
|
interest_amount = (280000 * 8.4) / (12 * 100)
|
||||||
principal_amount = loan.monthly_repayment_amount - interest_amount
|
principal_amount = loan.monthly_repayment_amount - interest_amount
|
||||||
self.assertEqual(row.interest_amount, interest_amount)
|
self.assertEqual(row.interest_amount, interest_amount)
|
||||||
self.assertEqual(row.principal_amount, principal_amount)
|
self.assertEqual(row.principal_amount, principal_amount)
|
||||||
self.assertEqual(row.total_payment, interest_amount + principal_amount)
|
|
||||||
|
|
||||||
if salary_slip.docstatus == 0:
|
if salary_slip.docstatus == 0:
|
||||||
frappe.delete_doc("Salary Slip", name)
|
frappe.delete_doc("Salary Slip", name)
|
||||||
|
|||||||
@@ -377,7 +377,6 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "total_loan_repayment",
|
|
||||||
"fieldname": "loan_repayment",
|
"fieldname": "loan_repayment",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Loan Repayment"
|
"label": "Loan Repayment"
|
||||||
@@ -647,7 +646,7 @@
|
|||||||
"idx": 9,
|
"idx": 9,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-10-08 11:48:47.098248",
|
"modified": "2022-08-29 08:59:50.819986",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Payroll",
|
"module": "Payroll",
|
||||||
"name": "Salary Slip",
|
"name": "Salary Slip",
|
||||||
|
|||||||
@@ -1379,12 +1379,29 @@ class SalarySlip(TransactionBase):
|
|||||||
for loan in self.get_loan_details():
|
for loan in self.get_loan_details():
|
||||||
amounts = calculate_amounts(loan.name, self.posting_date, "Regular Payment")
|
amounts = calculate_amounts(loan.name, self.posting_date, "Regular Payment")
|
||||||
|
|
||||||
if amounts["interest_amount"] or amounts["payable_principal_amount"]:
|
if (amounts["interest_amount"] or amounts["payable_principal_amount"]) and (
|
||||||
|
amounts["payable_principal_amount"] + amounts["interest_amount"]
|
||||||
|
> amounts["written_off_amount"]
|
||||||
|
):
|
||||||
|
|
||||||
|
if amounts["interest_amount"] > amounts["written_off_amount"]:
|
||||||
|
amounts["interest_amount"] -= amounts["written_off_amount"]
|
||||||
|
amounts["written_off_amount"] = 0
|
||||||
|
else:
|
||||||
|
amounts["written_off_amount"] -= amounts["interest_amount"]
|
||||||
|
amounts["interest_amount"] = 0
|
||||||
|
|
||||||
|
if amounts["payable_principal_amount"] > amounts["written_off_amount"]:
|
||||||
|
amounts["payable_principal_amount"] -= amounts["written_off_amount"]
|
||||||
|
amounts["written_off_amount"] = 0
|
||||||
|
else:
|
||||||
|
amounts["written_off_amount"] -= amounts["payable_principal_amount"]
|
||||||
|
amounts["payable_principal_amount"] = 0
|
||||||
|
|
||||||
self.append(
|
self.append(
|
||||||
"loans",
|
"loans",
|
||||||
{
|
{
|
||||||
"loan": loan.name,
|
"loan": loan.name,
|
||||||
"total_payment": amounts["interest_amount"] + amounts["payable_principal_amount"],
|
|
||||||
"interest_amount": amounts["interest_amount"],
|
"interest_amount": amounts["interest_amount"],
|
||||||
"principal_amount": amounts["payable_principal_amount"],
|
"principal_amount": amounts["payable_principal_amount"],
|
||||||
"loan_account": loan.loan_account,
|
"loan_account": loan.loan_account,
|
||||||
@@ -1395,7 +1412,7 @@ class SalarySlip(TransactionBase):
|
|||||||
for payment in self.get("loans"):
|
for payment in self.get("loans"):
|
||||||
amounts = calculate_amounts(payment.loan, self.posting_date, "Regular Payment")
|
amounts = calculate_amounts(payment.loan, self.posting_date, "Regular Payment")
|
||||||
total_amount = amounts["interest_amount"] + amounts["payable_principal_amount"]
|
total_amount = amounts["interest_amount"] + amounts["payable_principal_amount"]
|
||||||
if payment.total_payment > total_amount:
|
if flt(payment.total_payment) > total_amount:
|
||||||
frappe.throw(
|
frappe.throw(
|
||||||
_(
|
_(
|
||||||
"""Row {0}: Paid amount {1} is greater than pending accrued amount {2} against loan {3}"""
|
"""Row {0}: Paid amount {1} is greater than pending accrued amount {2} against loan {3}"""
|
||||||
@@ -1407,10 +1424,10 @@ class SalarySlip(TransactionBase):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.total_interest_amount += payment.interest_amount
|
self.total_interest_amount += flt(payment.interest_amount)
|
||||||
self.total_principal_amount += payment.principal_amount
|
self.total_principal_amount += flt(payment.principal_amount)
|
||||||
|
|
||||||
self.total_loan_repayment += payment.total_payment
|
self.total_loan_repayment += flt(payment.total_payment)
|
||||||
|
|
||||||
def get_loan_details(self):
|
def get_loan_details(self):
|
||||||
loan_details = frappe.get_all(
|
loan_details = frappe.get_all(
|
||||||
@@ -1436,7 +1453,7 @@ class SalarySlip(TransactionBase):
|
|||||||
def make_loan_repayment_entry(self):
|
def make_loan_repayment_entry(self):
|
||||||
payroll_payable_account = get_payroll_payable_account(self.company, self.payroll_entry)
|
payroll_payable_account = get_payroll_payable_account(self.company, self.payroll_entry)
|
||||||
for loan in self.loans:
|
for loan in self.loans:
|
||||||
if loan.total_payment:
|
if flt(loan.total_payment) > 0:
|
||||||
repayment_entry = create_repayment_entry(
|
repayment_entry = create_repayment_entry(
|
||||||
loan.loan,
|
loan.loan,
|
||||||
self.employee,
|
self.employee,
|
||||||
|
|||||||
@@ -670,9 +670,10 @@ class TestSalarySlip(FrappeTestCase):
|
|||||||
ss = make_employee_salary_slip(
|
ss = make_employee_salary_slip(
|
||||||
"test_loan_repayment_salary_slip@salary.com", "Monthly", "Test Loan Repayment Salary Structure"
|
"test_loan_repayment_salary_slip@salary.com", "Monthly", "Test Loan Repayment Salary Structure"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ss.loans[0].total_payment = 592
|
||||||
ss.submit()
|
ss.submit()
|
||||||
|
|
||||||
self.assertEqual(ss.total_loan_repayment, 592)
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
ss.net_pay, (flt(ss.gross_pay) - (flt(ss.total_deduction) + flt(ss.total_loan_repayment)))
|
ss.net_pay, (flt(ss.gross_pay) - (flt(ss.total_deduction) + flt(ss.total_loan_repayment)))
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user