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:
Anurag Mishra
2019-12-31 14:01:22 +05:30
committed by Nabin Hait
parent 25fd2743a8
commit fd68a682ca
4 changed files with 319 additions and 1193 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -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: