mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-14 04:15:10 +00:00
fix(refactor): loan in HRMS (#20023)
* fix: update laon on salary slip submission and Cancelation * fix(refactor): Loan in HRMS * fix: Changes requested * Update loan.py Co-authored-by: Nabin Hait <nabinhait@gmail.com>
This commit is contained in:
committed by
Nabin Hait
parent
25fd2743a8
commit
fd68a682ca
@@ -9,7 +9,6 @@ from erpnext.controllers.accounts_controller import AccountsController
|
||||
from erpnext.accounts.utils import get_balance_on, get_account_currency
|
||||
from erpnext.accounts.party import get_party_account
|
||||
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
|
||||
from erpnext.hr.doctype.loan.loan import update_disbursement_status, update_total_amount_paid
|
||||
from erpnext.accounts.doctype.invoice_discounting.invoice_discounting import get_party_account_based_on_invoice_discounting
|
||||
|
||||
from six import string_types, iteritems
|
||||
@@ -606,8 +605,8 @@ class JournalEntry(AccountsController):
|
||||
for d in self.accounts:
|
||||
if d.reference_type=="Loan" and flt(d.debit) > 0:
|
||||
doc = frappe.get_doc("Loan", d.reference_name)
|
||||
update_disbursement_status(doc)
|
||||
update_total_amount_paid(doc)
|
||||
doc.update_total_amount_paid()
|
||||
doc.set_status()
|
||||
|
||||
def validate_expense_claim(self):
|
||||
for d in self.accounts:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@ class Loan(AccountsController):
|
||||
self.make_repayment_schedule()
|
||||
self.set_repayment_period()
|
||||
self.calculate_totals()
|
||||
self.set_status(from_validate=True)
|
||||
|
||||
def set_missing_fields(self):
|
||||
if not self.company:
|
||||
@@ -95,43 +96,57 @@ class Loan(AccountsController):
|
||||
self.total_payment = 0
|
||||
self.total_interest_payable = 0
|
||||
self.total_amount_paid = 0
|
||||
for data in self.repayment_schedule:
|
||||
self.total_payment += data.total_payment
|
||||
self.total_interest_payable +=data.interest_amount
|
||||
if data.paid:
|
||||
self.total_amount_paid += data.total_payment
|
||||
for schedule in self.repayment_schedule:
|
||||
self.total_payment += schedule.total_payment
|
||||
self.total_interest_payable +=schedule.interest_amount
|
||||
if schedule.paid:
|
||||
self.total_amount_paid += schedule.total_payment
|
||||
|
||||
def update_total_amount_paid(doc):
|
||||
total_amount_paid = 0
|
||||
for data in doc.repayment_schedule:
|
||||
if data.paid:
|
||||
total_amount_paid += data.total_payment
|
||||
frappe.db.set_value("Loan", doc.name, "total_amount_paid", total_amount_paid)
|
||||
def update_total_amount_paid(self):
|
||||
total_amount_paid = 0
|
||||
for schedule in self.repayment_schedule:
|
||||
if schedule.paid:
|
||||
total_amount_paid += schedule.total_payment
|
||||
frappe.db.set_value("Loan", self.name, "total_amount_paid", total_amount_paid)
|
||||
|
||||
def update_disbursement_status(doc):
|
||||
disbursement = frappe.db.sql("""
|
||||
select posting_date, ifnull(sum(credit_in_account_currency), 0) as disbursed_amount
|
||||
from `tabGL Entry`
|
||||
where account = %s and against_voucher_type = 'Loan' and against_voucher = %s
|
||||
""", (doc.payment_account, doc.name), as_dict=1)[0]
|
||||
def set_status(self, from_validate=False):
|
||||
disbursement = self.get_disbursement_entry()
|
||||
disbursement_date = None
|
||||
|
||||
disbursement_date = None
|
||||
if not disbursement or disbursement.disbursed_amount == 0:
|
||||
status = "Sanctioned"
|
||||
elif disbursement.disbursed_amount == doc.loan_amount:
|
||||
disbursement_date = disbursement.posting_date
|
||||
status = "Disbursed"
|
||||
elif disbursement.disbursed_amount > doc.loan_amount:
|
||||
frappe.throw(_("Disbursed Amount cannot be greater than Loan Amount {0}").format(doc.loan_amount))
|
||||
self.status = "Draft"
|
||||
|
||||
if status == 'Disbursed' and getdate(disbursement_date) > getdate(frappe.db.get_value("Loan", doc.name, "repayment_start_date")):
|
||||
if (not disbursement or disbursement.disbursed_amount == 0) and self.docstatus == 1:
|
||||
self.status = "Sanctioned"
|
||||
if disbursement:
|
||||
self.validate_disbursed_amount_and_loan_amount(disbursement.disbursed_amount)
|
||||
if disbursement.disbursed_amount == self.loan_amount and disbursement.disbursed_amount != 0:
|
||||
self.status = "Disbursed"
|
||||
disbursement_date = disbursement.posting_date
|
||||
self.validate_disbursement_date(disbursement_date, self.status)
|
||||
|
||||
if self.total_amount_paid == self.total_payment:
|
||||
self.status = "Repaid/Closed"
|
||||
|
||||
if not from_validate:
|
||||
frappe.db.set_value("Loan", self.name, "status", self.status)
|
||||
if disbursement_date:
|
||||
frappe.db.set_value("Loan", self.name, "disbursement_date", disbursement_date)
|
||||
|
||||
def validate_disbursement_date(self, disbursement_date, loan_status):
|
||||
if loan_status == 'Disbursed' and getdate(disbursement_date) > getdate(frappe.db.get_value("Loan", self.name, "repayment_start_date")):
|
||||
frappe.throw(_("Disbursement Date cannot be after Loan Repayment Start Date"))
|
||||
|
||||
frappe.db.sql("""
|
||||
update `tabLoan`
|
||||
set status = %s, disbursement_date = %s
|
||||
where name = %s
|
||||
""", (status, disbursement_date, doc.name))
|
||||
|
||||
def validate_disbursed_amount_and_loan_amount(self, disbursed_amount):
|
||||
if disbursed_amount > self.loan_amount:
|
||||
frappe.throw(_("Disbursed Amount cannot be greater than Loan Amount {0}").format(self.loan_amount))
|
||||
|
||||
def get_disbursement_entry(self):
|
||||
return frappe.db.sql("""
|
||||
select posting_date, ifnull(sum(credit_in_account_currency), 0) as disbursed_amount
|
||||
from `tabGL Entry`
|
||||
where account = %s and against_voucher_type = 'Loan' and against_voucher = %s
|
||||
""", (self.payment_account, self.name), as_dict=1)[0]
|
||||
|
||||
def validate_repayment_method(repayment_method, loan_amount, monthly_repayment_amount, repayment_periods):
|
||||
if repayment_method == "Repay Over Number of Periods" and not repayment_periods:
|
||||
|
||||
@@ -62,6 +62,7 @@ class SalarySlip(TransactionBase):
|
||||
if self.net_pay < 0:
|
||||
frappe.throw(_("Net Pay cannot be less than 0"))
|
||||
else:
|
||||
self.update_loans()
|
||||
self.set_status()
|
||||
self.update_status(self.name)
|
||||
self.update_salary_slip_in_additional_salary()
|
||||
@@ -69,6 +70,7 @@ class SalarySlip(TransactionBase):
|
||||
self.email_salary_slip()
|
||||
|
||||
def on_cancel(self):
|
||||
self.update_loans()
|
||||
self.set_status()
|
||||
self.update_status()
|
||||
self.update_salary_slip_in_additional_salary()
|
||||
@@ -764,7 +766,8 @@ class SalarySlip(TransactionBase):
|
||||
self.total_principal_amount += loan.principal_amount
|
||||
|
||||
def get_loan_details(self):
|
||||
return frappe.db.sql("""select rps.principal_amount, rps.interest_amount, l.name,
|
||||
return frappe.db.sql("""select rps.principal_amount,
|
||||
rps.name as repayment_name, rps.interest_amount, l.name,
|
||||
rps.total_payment, l.loan_account, l.interest_income_account
|
||||
from
|
||||
`tabRepayment Schedule` as rps, `tabLoan` as l
|
||||
@@ -815,6 +818,17 @@ class SalarySlip(TransactionBase):
|
||||
timesheet.set_status()
|
||||
timesheet.save()
|
||||
|
||||
def update_loans(self):
|
||||
for loan in self.get_loan_details():
|
||||
doc = frappe.get_doc("Loan", loan.name)
|
||||
|
||||
#setting repayment schedule and updating total amount to pay
|
||||
repayment_status = 1 if doc.docstatus == 1 else 0
|
||||
frappe.db.set_value("Repayment Schedule", loan.repayment_name, "paid", repayment_status)
|
||||
doc.reload()
|
||||
doc.update_total_amount_paid()
|
||||
doc.set_status()
|
||||
|
||||
def set_status(self, status=None):
|
||||
'''Get and update status'''
|
||||
if not status:
|
||||
|
||||
Reference in New Issue
Block a user