diff --git a/erpnext/hr/doctype/leave_encashment/leave_encashment.py b/erpnext/hr/doctype/leave_encashment/leave_encashment.py index 70cd5780c8..c47ff85717 100644 --- a/erpnext/hr/doctype/leave_encashment/leave_encashment.py +++ b/erpnext/hr/doctype/leave_encashment/leave_encashment.py @@ -11,6 +11,7 @@ from erpnext.hr.utils import set_employee_name from erpnext.hr.doctype.leave_application.leave_application import get_leave_balance_on from erpnext.hr.doctype.salary_structure_assignment.salary_structure_assignment import get_assigned_salary_structure from erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry import create_leave_ledger_entry +from erpnext.hr.doctype.leave_allocation.leave_allocation import get_unused_leaves class LeaveEncashment(Document): def validate(self): @@ -26,7 +27,7 @@ class LeaveEncashment(Document): def on_submit(self): if not self.leave_allocation: - self.leave_allocation = self.get_leave_allocation() + self.leave_allocation = self.get_leave_allocation().get('name') additional_salary = frappe.new_doc("Additional Salary") additional_salary.company = frappe.get_value("Employee", self.employee, "company") additional_salary.employee = self.employee @@ -61,8 +62,9 @@ class LeaveEncashment(Document): if not frappe.db.get_value("Leave Type", self.leave_type, 'allow_encashment'): frappe.throw(_("Leave Type {0} is not encashable").format(self.leave_type)) - self.leave_balance = get_leave_balance_on(self.employee, self.leave_type, - self.encashment_date or getdate(nowdate()), consider_all_leaves_in_the_allocation_period=True) + allocation = self.get_leave_allocation() + + self.leave_balance = allocation.total_leaves_allocated - get_unused_leaves(self.employee, self.leave_type, allocation.from_date, self.encashment_date) encashable_days = self.leave_balance - frappe.db.get_value('Leave Type', self.leave_type, 'encashment_threshold_days') self.encashable_days = encashable_days if encashable_days > 0 else 0 @@ -70,15 +72,15 @@ class LeaveEncashment(Document): per_day_encashment = frappe.db.get_value('Salary Structure', salary_structure , 'leave_encashment_amount_per_day') self.encashment_amount = self.encashable_days * per_day_encashment if per_day_encashment > 0 else 0 - self.leave_allocation = self.get_leave_allocation() + self.leave_allocation = allocation.name return True def get_leave_allocation(self): - leave_allocation = frappe.db.sql("""select name from `tabLeave Allocation` where '{0}' + leave_allocation = frappe.db.sql("""select name, to_date, total_leaves_allocated from `tabLeave Allocation` where '{0}' between from_date and to_date and docstatus=1 and leave_type='{1}' - and employee= '{2}'""".format(self.encashment_date or getdate(nowdate()), self.leave_type, self.employee)) + and employee= '{2}'""".format(self.encashment_date or getdate(nowdate()), self.leave_type, self.employee), as_dict=1) - return leave_allocation[0][0] if leave_allocation else None + return leave_allocation[0] if leave_allocation else None def create_leave_ledger_entry(self, submit=True): args = frappe._dict( @@ -87,4 +89,16 @@ class LeaveEncashment(Document): to_date=self.encashment_date, is_carry_forward=0 ) - create_leave_ledger_entry(self, args, submit) \ No newline at end of file + create_leave_ledger_entry(self, args, submit) + + # create reverse entry for expired leaves + to_date = self.get_leave_allocation().get('to_date') + if to_date < getdate(nowdate()): + args = frappe._dict( + leaves=self.encashable_days, + from_date=to_date, + to_date=to_date, + is_carry_forward=0 + ) + create_leave_ledger_entry(self, args, submit) + diff --git a/erpnext/hr/doctype/leave_encashment/test_leave_encashment.py b/erpnext/hr/doctype/leave_encashment/test_leave_encashment.py index 2daeffcffe..e5bd170bc4 100644 --- a/erpnext/hr/doctype/leave_encashment/test_leave_encashment.py +++ b/erpnext/hr/doctype/leave_encashment/test_leave_encashment.py @@ -38,7 +38,6 @@ class TestLeaveEncashment(unittest.TestCase): self.leave_period = create_leave_period(add_months(today(), -3), add_months(today(), 3)) self.leave_period.grant_leave_allocation(employee=self.employee) - def test_leave_balance_value_and_amount(self): frappe.db.sql('''delete from `tabLeave Encashment`''') leave_encashment = frappe.get_doc(dict(