fix: Employee loan test case and other fixes
This commit is contained in:
parent
f7e216e285
commit
af27d61bee
@ -311,7 +311,7 @@ scheduler_events = {
|
|||||||
"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms",
|
"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms",
|
||||||
"erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry.process_expired_allocation",
|
"erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry.process_expired_allocation",
|
||||||
"erpnext.hr.utils.generate_leave_encashment",
|
"erpnext.hr.utils.generate_leave_encashment",
|
||||||
"erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall.check_for_ltv_shortfall",
|
"erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall.create_process_loan_security_shortfall",
|
||||||
"erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual.process_loan_interest_accrual_for_term_loans"
|
"erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual.process_loan_interest_accrual_for_term_loans"
|
||||||
],
|
],
|
||||||
"monthly_long": [
|
"monthly_long": [
|
||||||
|
@ -13,7 +13,7 @@ from erpnext.hr.doctype.salary_slip.test_salary_slip import get_salary_component
|
|||||||
make_earning_salary_component, make_deduction_salary_component
|
make_earning_salary_component, make_deduction_salary_component
|
||||||
from erpnext.hr.doctype.salary_structure.test_salary_structure import make_salary_structure
|
from erpnext.hr.doctype.salary_structure.test_salary_structure import make_salary_structure
|
||||||
from erpnext.loan_management.doctype.loan.test_loan import create_loan, make_loan_disbursement_entry
|
from erpnext.loan_management.doctype.loan.test_loan import create_loan, make_loan_disbursement_entry
|
||||||
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import make_accrual_interest_entry_for_term_loans
|
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_term_loans
|
||||||
|
|
||||||
class TestPayrollEntry(unittest.TestCase):
|
class TestPayrollEntry(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -81,7 +81,7 @@ class TestPayrollEntry(unittest.TestCase):
|
|||||||
|
|
||||||
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=add_months(nowdate(), -1))
|
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=add_months(nowdate(), -1))
|
||||||
|
|
||||||
make_accrual_interest_entry_for_term_loans(posting_date=nowdate())
|
process_loan_interest_accrual_for_term_loans(posting_date=nowdate())
|
||||||
|
|
||||||
|
|
||||||
dates = get_start_end_dates('Monthly', nowdate())
|
dates = get_start_end_dates('Monthly', nowdate())
|
||||||
|
@ -755,30 +755,43 @@ class SalarySlip(TransactionBase):
|
|||||||
d.amount = self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0]
|
d.amount = self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0]
|
||||||
|
|
||||||
def set_loan_repayment(self):
|
def set_loan_repayment(self):
|
||||||
self.set('loans', [])
|
|
||||||
self.total_loan_repayment = 0
|
self.total_loan_repayment = 0
|
||||||
self.total_interest_amount = 0
|
self.total_interest_amount = 0
|
||||||
self.total_principal_amount = 0
|
self.total_principal_amount = 0
|
||||||
|
|
||||||
for loan in self.get_loan_details():
|
if not self.get('loans'):
|
||||||
|
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")
|
||||||
|
|
||||||
total_payment = amounts['interest_amount'] + amounts['payable_principal_amount']
|
if amounts['interest_amount'] or amounts['payable_principal_amount']:
|
||||||
|
self.append('loans', {
|
||||||
|
'loan': loan.name,
|
||||||
|
'total_payment': amounts['interest_amount'] + amounts['payable_principal_amount'],
|
||||||
|
'interest_amount': amounts['interest_amount'],
|
||||||
|
'principal_amount': amounts['payable_principal_amount'],
|
||||||
|
'loan_account': loan.loan_account,
|
||||||
|
'interest_income_account': loan.interest_income_account
|
||||||
|
})
|
||||||
|
|
||||||
if total_payment:
|
for payment in self.get('loans'):
|
||||||
self.append('loans', {
|
amounts = calculate_amounts(payment.loan, self.posting_date, "Regular Payment")
|
||||||
'loan': loan.name,
|
|
||||||
'total_payment': total_payment,
|
|
||||||
'interest_amount': amounts['interest_amount'],
|
|
||||||
'principal_amount': amounts['payable_principal_amount'],
|
|
||||||
'loan_account': loan.loan_account,
|
|
||||||
'interest_income_account': loan.interest_income_account
|
|
||||||
})
|
|
||||||
|
|
||||||
self.total_loan_repayment += total_payment
|
if payment.interest_amount > amounts['interest_amount']:
|
||||||
self.total_interest_amount += amounts['interest_amount']
|
frappe.throw(_("""Row {0}: Paid Interest amount {1} is greater than pending interest amount {2}
|
||||||
self.total_principal_amount += amounts['payable_principal_amount']
|
against loan {3}""").format(payment.idx, frappe.bold(payment.interest_amount),
|
||||||
|
frappe.bold(amounts['interest_amount']), frappe.bold(payment.loan)))
|
||||||
|
|
||||||
|
if payment.principal_amount > amounts['payable_principal_amount']:
|
||||||
|
frappe.throw(_("""Row {0}: Paid Principal amount {1} is greater than pending principal amount {2}
|
||||||
|
against loan {3}""").format(payment.idx, frappe.bold(payment.principal_amount),
|
||||||
|
frappe.bold(amounts['payable_principal_amount']), frappe.bold(payment.loan)))
|
||||||
|
|
||||||
|
payment.total_payment = payment.interest_amount + payment.principal_amount
|
||||||
|
self.total_interest_amount += payment.interest_amount
|
||||||
|
self.total_principal_amount += payment.principal_amount
|
||||||
|
|
||||||
|
self.total_loan_repayment = self.total_interest_amount + self.total_principal_amount
|
||||||
|
|
||||||
def get_loan_details(self):
|
def get_loan_details(self):
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
|
|
||||||
def test_loan_repayment_salary_slip(self):
|
def test_loan_repayment_salary_slip(self):
|
||||||
from erpnext.loan_management.doctype.loan.test_loan import create_loan_type, create_loan, make_loan_disbursement_entry, create_loan_accounts
|
from erpnext.loan_management.doctype.loan.test_loan import create_loan_type, create_loan, make_loan_disbursement_entry, create_loan_accounts
|
||||||
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import make_accrual_interest_entry_for_term_loans
|
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_term_loans
|
||||||
|
|
||||||
applicant = make_employee("test_loanemployee@salary.com", company="_Test Company")
|
applicant = make_employee("test_loanemployee@salary.com", company="_Test Company")
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
|
|
||||||
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=add_months(nowdate(), -1))
|
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=add_months(nowdate(), -1))
|
||||||
|
|
||||||
make_accrual_interest_entry_for_term_loans(posting_date=nowdate())
|
process_loan_interest_accrual_for_term_loans(posting_date=nowdate())
|
||||||
|
|
||||||
ss = make_employee_salary_slip("test_loanemployee@salary.com", "Monthly")
|
ss = make_employee_salary_slip("test_loanemployee@salary.com", "Monthly")
|
||||||
ss.submit()
|
ss.submit()
|
||||||
|
@ -12,9 +12,8 @@ from erpnext.selling.doctype.customer.test_customer import get_customer_dict
|
|||||||
from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee
|
from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee
|
||||||
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import (process_loan_interest_accrual_for_demand_loans,
|
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import (process_loan_interest_accrual_for_demand_loans,
|
||||||
process_loan_interest_accrual_for_term_loans)
|
process_loan_interest_accrual_for_term_loans)
|
||||||
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import (make_accrual_interest_entry_for_term_loans, days_in_year)
|
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_year
|
||||||
|
from erpnext.loan_management.doctype.process_loan_security_shortfall.process_loan_security_shortfall import create_process_loan_security_shortfall
|
||||||
from erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall import check_for_ltv_shortfall
|
|
||||||
|
|
||||||
class TestLoan(unittest.TestCase):
|
class TestLoan(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -298,7 +297,7 @@ class TestLoan(unittest.TestCase):
|
|||||||
frappe.db.sql(""" UPDATE `tabLoan Security Price` SET loan_security_price = 100
|
frappe.db.sql(""" UPDATE `tabLoan Security Price` SET loan_security_price = 100
|
||||||
where loan_security='Test Security 2'""")
|
where loan_security='Test Security 2'""")
|
||||||
|
|
||||||
check_for_ltv_shortfall()
|
create_process_loan_security_shortfall()
|
||||||
loan_security_shortfall = frappe.get_doc("Loan Security Shortfall", {"loan": loan.name})
|
loan_security_shortfall = frappe.get_doc("Loan Security Shortfall", {"loan": loan.name})
|
||||||
self.assertTrue(loan_security_shortfall)
|
self.assertTrue(loan_security_shortfall)
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ from frappe.utils import (nowdate, add_days, get_datetime, get_first_day, get_la
|
|||||||
from erpnext.loan_management.doctype.loan.test_loan import (create_loan_type, create_loan_security_pledge, create_repayment_entry,
|
from erpnext.loan_management.doctype.loan.test_loan import (create_loan_type, create_loan_security_pledge, create_repayment_entry,
|
||||||
make_loan_disbursement_entry, create_loan_accounts, create_loan_security_type, create_loan_security, create_demand_loan, create_loan_security_price)
|
make_loan_disbursement_entry, create_loan_accounts, create_loan_security_type, create_loan_security, create_demand_loan, create_loan_security_price)
|
||||||
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
|
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
|
||||||
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import (make_accrual_interest_entry_for_term_loans, days_in_year)
|
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_year
|
||||||
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
|
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
|
||||||
|
|
||||||
class TestLoanDisbursement(unittest.TestCase):
|
class TestLoanDisbursement(unittest.TestCase):
|
||||||
|
@ -94,7 +94,7 @@ def calculate_accrual_amount_for_demand_loans(loan, posting_date, process_loan_i
|
|||||||
'applicant_type': loan.applicant_type,
|
'applicant_type': loan.applicant_type,
|
||||||
'applicant': loan.applicant,
|
'applicant': loan.applicant,
|
||||||
'interest_income_account': loan.interest_income_account,
|
'interest_income_account': loan.interest_income_account,
|
||||||
'loan_account': loan.loan_acccount,
|
'loan_account': loan.loan_account,
|
||||||
'pending_principal_amount': pending_principal_amount,
|
'pending_principal_amount': pending_principal_amount,
|
||||||
'interest_amount': payable_interest,
|
'interest_amount': payable_interest,
|
||||||
'process_loan_interest': process_loan_interest,
|
'process_loan_interest': process_loan_interest,
|
||||||
@ -137,7 +137,7 @@ def make_accrual_interest_entry_for_term_loans(posting_date, process_loan_intere
|
|||||||
'applicant_type': loan.applicant_type,
|
'applicant_type': loan.applicant_type,
|
||||||
'applicant': loan.applicant,
|
'applicant': loan.applicant,
|
||||||
'interest_income_account': loan.interest_income_account,
|
'interest_income_account': loan.interest_income_account,
|
||||||
'loan_account': loan.loan_acccount,
|
'loan_account': loan.loan_account,
|
||||||
'interest_amount': loan.interest_amount,
|
'interest_amount': loan.interest_amount,
|
||||||
'payable_principal': loan.principal_amount,
|
'payable_principal': loan.principal_amount,
|
||||||
'process_loan_interest': process_loan_interest,
|
'process_loan_interest': process_loan_interest,
|
||||||
|
@ -8,7 +8,7 @@ from frappe.utils import (nowdate, add_days, get_datetime, get_first_day, get_la
|
|||||||
from erpnext.loan_management.doctype.loan.test_loan import (create_loan_type, create_loan_security_pledge, create_loan_security_price,
|
from erpnext.loan_management.doctype.loan.test_loan import (create_loan_type, create_loan_security_pledge, create_loan_security_price,
|
||||||
make_loan_disbursement_entry, create_loan_accounts, create_loan_security_type, create_loan_security, create_demand_loan)
|
make_loan_disbursement_entry, create_loan_accounts, create_loan_security_type, create_loan_security, create_demand_loan)
|
||||||
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
|
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
|
||||||
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import (make_accrual_interest_entry_for_term_loans, days_in_year)
|
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_years
|
||||||
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
|
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
|
||||||
|
|
||||||
class TestLoanInterestAccrual(unittest.TestCase):
|
class TestLoanInterestAccrual(unittest.TestCase):
|
||||||
|
@ -210,7 +210,7 @@ class LoanRepayment(AccountsController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if gle_map:
|
if gle_map:
|
||||||
make_gl_entries(gle_map, cancel=cancel, adv_adj=adv_adj)
|
make_gl_entries(gle_map, cancel=cancel, adv_adj=adv_adj, merge_entries=False)
|
||||||
|
|
||||||
def create_repayment_entry(loan, applicant, company, posting_date, loan_type,
|
def create_repayment_entry(loan, applicant, company, posting_date, loan_type,
|
||||||
payment_type, interest_payable, payable_principal_amount, amount_paid, penalty_amount=None):
|
payment_type, interest_payable, payable_principal_amount, amount_paid, penalty_amount=None):
|
||||||
@ -223,7 +223,7 @@ def create_repayment_entry(loan, applicant, company, posting_date, loan_type,
|
|||||||
"posting_date": posting_date,
|
"posting_date": posting_date,
|
||||||
"applicant": applicant,
|
"applicant": applicant,
|
||||||
"penalty_amount": penalty_amount,
|
"penalty_amount": penalty_amount,
|
||||||
"interets_payable": interest_payable,
|
"interst_payable": interest_payable,
|
||||||
"payable_principal_amount": payable_principal_amount,
|
"payable_principal_amount": payable_principal_amount,
|
||||||
"amount_paid": amount_paid,
|
"amount_paid": amount_paid,
|
||||||
"loan_type": loan_type
|
"loan_type": loan_type
|
||||||
@ -236,7 +236,8 @@ def get_accrued_interest_entries(against_loan):
|
|||||||
fields=["name", "interest_amount", "posting_date", "payable_principal_amount"],
|
fields=["name", "interest_amount", "posting_date", "payable_principal_amount"],
|
||||||
filters = {
|
filters = {
|
||||||
"loan": against_loan,
|
"loan": against_loan,
|
||||||
"is_paid": 0
|
"is_paid": 0,
|
||||||
|
"docstatus": 1
|
||||||
}, order_by="posting_date")
|
}, order_by="posting_date")
|
||||||
|
|
||||||
return accrued_interest_entries
|
return accrued_interest_entries
|
||||||
@ -272,7 +273,9 @@ def get_amounts(amounts, against_loan, posting_date, payment_type):
|
|||||||
total_pending_interest += entry.interest_amount
|
total_pending_interest += entry.interest_amount
|
||||||
payable_principal_amount += entry.payable_principal_amount
|
payable_principal_amount += entry.payable_principal_amount
|
||||||
|
|
||||||
pending_accrual_entries.setdefault(entry.name, entry.interest_amount)
|
pending_accrual_entries.setdefault(entry.name,
|
||||||
|
flt(entry.interest_amount) + flt(entry.payable_principal_amount))
|
||||||
|
|
||||||
final_due_date = due_date
|
final_due_date = due_date
|
||||||
|
|
||||||
pending_principal_amount = against_loan_doc.total_payment - against_loan_doc.total_principal_paid - against_loan_doc.total_interest_payable
|
pending_principal_amount = against_loan_doc.total_payment - against_loan_doc.total_principal_paid - against_loan_doc.total_interest_payable
|
||||||
|
@ -37,17 +37,10 @@ def add_security(loan):
|
|||||||
|
|
||||||
return loan_security_pledge.as_dict()
|
return loan_security_pledge.as_dict()
|
||||||
|
|
||||||
def check_for_ltv_shortfall(process_loan_security_shortfall=None):
|
def check_for_ltv_shortfall(process_loan_security_shortfall):
|
||||||
|
|
||||||
update_time = get_datetime()
|
update_time = get_datetime()
|
||||||
|
|
||||||
if not process_loan_security_shortfall:
|
|
||||||
process = frappe.new_doc("Process Loan Security Shortfall")
|
|
||||||
process.update_time = update_time
|
|
||||||
process.submit()
|
|
||||||
|
|
||||||
process_loan_security_shortfall = process.name
|
|
||||||
|
|
||||||
loan_security_price_map = frappe._dict(frappe.get_all("Loan Security Price",
|
loan_security_price_map = frappe._dict(frappe.get_all("Loan Security Price",
|
||||||
fields=["loan_security", "loan_security_price"],
|
fields=["loan_security", "loan_security_price"],
|
||||||
filters = {
|
filters = {
|
||||||
|
@ -19,3 +19,6 @@ class LoanType(Document):
|
|||||||
frappe.throw(_("Account {0} does not belong to company {1}").format(frappe.bold(self.get(fieldname)),
|
frappe.throw(_("Account {0} does not belong to company {1}").format(frappe.bold(self.get(fieldname)),
|
||||||
frappe.bold(self.company)))
|
frappe.bold(self.company)))
|
||||||
|
|
||||||
|
if self.get('loan_account') == self.get('payment_account'):
|
||||||
|
frappe.throw(_('Loan Account and Payment Account cannot be same'))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user