fix: Leave Encashment calculations (#31062)

This commit is contained in:
Rucha Mahabal 2022-05-23 10:13:49 +05:30 committed by GitHub
parent 3019f93915
commit 34e238ce4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 37 deletions

View File

@ -7,7 +7,7 @@ from frappe import _
from frappe.model.document import Document
from frappe.utils import getdate, nowdate
from erpnext.hr.doctype.leave_allocation.leave_allocation import get_unused_leaves
from erpnext.hr.doctype.leave_application.leave_application import get_leaves_for_period
from erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry import create_leave_ledger_entry
from erpnext.hr.utils import set_employee_name, validate_active_employee
from erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment import (
@ -107,7 +107,10 @@ class LeaveEncashment(Document):
self.leave_balance = (
allocation.total_leaves_allocated
- allocation.carry_forwarded_leaves_count
- get_unused_leaves(self.employee, self.leave_type, allocation.from_date, self.encashment_date)
# adding this because the function returns a -ve number
+ get_leaves_for_period(
self.employee, self.leave_type, allocation.from_date, self.encashment_date
)
)
encashable_days = self.leave_balance - frappe.db.get_value(
@ -126,14 +129,25 @@ class LeaveEncashment(Document):
return True
def get_leave_allocation(self):
leave_allocation = frappe.db.sql(
"""select name, to_date, total_leaves_allocated, carry_forwarded_leaves_count 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
),
as_dict=1,
) # nosec
date = self.encashment_date or getdate()
LeaveAllocation = frappe.qb.DocType("Leave Allocation")
leave_allocation = (
frappe.qb.from_(LeaveAllocation)
.select(
LeaveAllocation.name,
LeaveAllocation.from_date,
LeaveAllocation.to_date,
LeaveAllocation.total_leaves_allocated,
LeaveAllocation.carry_forwarded_leaves_count,
)
.where(
((LeaveAllocation.from_date <= date) & (date <= LeaveAllocation.to_date))
& (LeaveAllocation.docstatus == 1)
& (LeaveAllocation.leave_type == self.leave_type)
& (LeaveAllocation.employee == self.employee)
)
).run(as_dict=True)
return leave_allocation[0] if leave_allocation else None

View File

@ -4,26 +4,42 @@
import unittest
import frappe
from frappe.utils import add_months, today
from frappe.tests.utils import FrappeTestCase
from frappe.utils import add_days, get_year_ending, get_year_start, getdate
from erpnext.hr.doctype.employee.test_employee import make_employee
from erpnext.hr.doctype.holiday_list.test_holiday_list import set_holiday_list
from erpnext.hr.doctype.leave_period.test_leave_period import create_leave_period
from erpnext.hr.doctype.leave_policy.test_leave_policy import create_leave_policy
from erpnext.hr.doctype.leave_policy_assignment.leave_policy_assignment import (
create_assignment_for_multiple_employees,
)
from erpnext.payroll.doctype.salary_slip.test_salary_slip import (
make_holiday_list,
make_leave_application,
)
from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure
test_dependencies = ["Leave Type"]
test_records = frappe.get_test_records("Leave Type")
class TestLeaveEncashment(unittest.TestCase):
class TestLeaveEncashment(FrappeTestCase):
def setUp(self):
frappe.db.sql("""delete from `tabLeave Period`""")
frappe.db.sql("""delete from `tabLeave Policy Assignment`""")
frappe.db.sql("""delete from `tabLeave Allocation`""")
frappe.db.sql("""delete from `tabLeave Ledger Entry`""")
frappe.db.sql("""delete from `tabAdditional Salary`""")
frappe.db.delete("Leave Period")
frappe.db.delete("Leave Policy Assignment")
frappe.db.delete("Leave Allocation")
frappe.db.delete("Leave Ledger Entry")
frappe.db.delete("Additional Salary")
frappe.db.delete("Leave Encashment")
if not frappe.db.exists("Leave Type", "_Test Leave Type Encashment"):
frappe.get_doc(test_records[2]).insert()
date = getdate()
year_start = getdate(get_year_start(date))
year_end = getdate(get_year_ending(date))
make_holiday_list("_Test Leave Encashment", year_start, year_end)
# create the leave policy
leave_policy = create_leave_policy(
@ -32,9 +48,9 @@ class TestLeaveEncashment(unittest.TestCase):
leave_policy.submit()
# create employee, salary structure and assignment
self.employee = make_employee("test_employee_encashment@example.com")
self.employee = make_employee("test_employee_encashment@example.com", company="_Test Company")
self.leave_period = create_leave_period(add_months(today(), -3), add_months(today(), 3))
self.leave_period = create_leave_period(year_start, year_end, "_Test Company")
data = {
"assignment_based_on": "Leave Period",
@ -53,27 +69,15 @@ class TestLeaveEncashment(unittest.TestCase):
other_details={"leave_encashment_amount_per_day": 50},
)
def tearDown(self):
for dt in [
"Leave Period",
"Leave Allocation",
"Leave Ledger Entry",
"Additional Salary",
"Leave Encashment",
"Salary Structure",
"Leave Policy",
]:
frappe.db.sql("delete from `tab%s`" % dt)
@set_holiday_list("_Test Leave Encashment", "_Test Company")
def test_leave_balance_value_and_amount(self):
frappe.db.sql("""delete from `tabLeave Encashment`""")
leave_encashment = frappe.get_doc(
dict(
doctype="Leave Encashment",
employee=self.employee,
leave_type="_Test Leave Type Encashment",
leave_period=self.leave_period.name,
payroll_date=today(),
encashment_date=self.leave_period.to_date,
currency="INR",
)
).insert()
@ -88,15 +92,46 @@ class TestLeaveEncashment(unittest.TestCase):
add_sal = frappe.get_all("Additional Salary", filters={"ref_docname": leave_encashment.name})[0]
self.assertTrue(add_sal)
def test_creation_of_leave_ledger_entry_on_submit(self):
frappe.db.sql("""delete from `tabLeave Encashment`""")
@set_holiday_list("_Test Leave Encashment", "_Test Company")
def test_leave_balance_value_with_leaves_and_amount(self):
date = self.leave_period.from_date
leave_application = make_leave_application(
self.employee, date, add_days(date, 3), "_Test Leave Type Encashment"
)
leave_application.reload()
leave_encashment = frappe.get_doc(
dict(
doctype="Leave Encashment",
employee=self.employee,
leave_type="_Test Leave Type Encashment",
leave_period=self.leave_period.name,
payroll_date=today(),
encashment_date=self.leave_period.to_date,
currency="INR",
)
).insert()
self.assertEqual(leave_encashment.leave_balance, 10 - leave_application.total_leave_days)
# encashable days threshold is 5, total leaves are 6, so encashable days = 6-5 = 1
# with charge of 50 per day
self.assertEqual(leave_encashment.encashable_days, leave_encashment.leave_balance - 5)
self.assertEqual(leave_encashment.encashment_amount, 50)
leave_encashment.submit()
# assert links
add_sal = frappe.get_all("Additional Salary", filters={"ref_docname": leave_encashment.name})[0]
self.assertTrue(add_sal)
@set_holiday_list("_Test Leave Encashment", "_Test Company")
def test_creation_of_leave_ledger_entry_on_submit(self):
leave_encashment = frappe.get_doc(
dict(
doctype="Leave Encashment",
employee=self.employee,
leave_type="_Test Leave Type Encashment",
leave_period=self.leave_period.name,
encashment_date=self.leave_period.to_date,
currency="INR",
)
).insert()