From bb9a5b0ed27920033ee3463b452550631af5619b Mon Sep 17 00:00:00 2001 From: Asmita Hase Date: Fri, 24 Jan 2025 14:21:48 +0530 Subject: [PATCH 1/4] chore: fixed test for leave policy assignment based on employee joining date (cherry picked from commit 91db1c07487888d7a7b91d0b50d8e24a2aa6548a) --- .../doctype/leave_allocation/test_earned_leaves.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hrms/hr/doctype/leave_allocation/test_earned_leaves.py b/hrms/hr/doctype/leave_allocation/test_earned_leaves.py index b8bf62019d..6c0f3689d5 100644 --- a/hrms/hr/doctype/leave_allocation/test_earned_leaves.py +++ b/hrms/hr/doctype/leave_allocation/test_earned_leaves.py @@ -137,8 +137,14 @@ def test_alloc_based_on_joining_date(self): # assignment created on the last day of the current month frappe.flags.current_date = get_last_day(getdate()) - - leave_policy_assignments = make_policy_assignment(self.employee, assignment_based_on="Joining Date") + """set end date while making assignment based on Joining date because while start date is fetched from + employee master, make_policy_assignment ends up taking current date as end date if not specified which + causes the date of assignment to be later than the end date of leave period""" + start_date = self.employee.date_of_joining + end_date = get_last_day(add_months(self.employee.date_of_joining, 12)) + leave_policy_assignments = make_policy_assignment( + self.employee, assignment_based_on="Joining Date", start_date=start_date, end_date=end_date + ) leaves_allocated = get_allocated_leaves(leave_policy_assignments[0]) effective_from = frappe.db.get_value( "Leave Policy Assignment", leave_policy_assignments[0], "effective_from" @@ -581,6 +587,8 @@ def make_policy_assignment( "leave_policy": leave_policy.name, "leave_period": leave_period.name, "carry_forward": carry_forward, + "effective_from": start_date, + "effective_to": end_date, } leave_policy_assignments = create_assignment_for_multiple_employees([employee.name], frappe._dict(data)) From 6a537df357a67cdabef52c7e242b92ac8f178095 Mon Sep 17 00:00:00 2001 From: Asmita Hase Date: Fri, 24 Jan 2025 14:23:38 +0530 Subject: [PATCH 2/4] fix: allocate earned leaves pro-rata if policy assignment is submitted after the effective period (cherry picked from commit bff9ed2158352dbfe61e6e55b42586bb7159a2f5) # Conflicts: # hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py --- .../leave_policy_assignment.py | 7 ++-- .../test_leave_policy_assignment.py | 36 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/hrms/hr/doctype/leave_policy_assignment/leave_policy_assignment.py b/hrms/hr/doctype/leave_policy_assignment/leave_policy_assignment.py index dc151e4cdb..f1dfa7e363 100644 --- a/hrms/hr/doctype/leave_policy_assignment/leave_policy_assignment.py +++ b/hrms/hr/doctype/leave_policy_assignment/leave_policy_assignment.py @@ -38,6 +38,8 @@ def set_dates(self): ) elif self.assignment_based_on == "Joining Date": self.effective_from = frappe.db.get_value("Employee", self.employee, "date_of_joining") + if not self.effective_to: + self.effective_to = get_last_day(add_months(self.effective_from, 12)) def validate_policy_assignment_overlap(self): leave_policy_assignment = frappe.db.get_value( @@ -134,12 +136,13 @@ def get_new_leaves(self, annual_allocation, leave_details, date_of_joining): from frappe.model.meta import get_field_precision precision = get_field_precision(frappe.get_meta("Leave Allocation").get_field("new_leaves_allocated")) - + current_date = getdate(frappe.flags.current_date) or getdate() # Earned Leaves and Compensatory Leaves are allocated by scheduler, initially allocate 0 if leave_details.is_compensatory: new_leaves_allocated = 0 + # if earned leave is being allcated after the effective period, then let them be calculated pro-rata - elif leave_details.is_earned_leave: + elif leave_details.is_earned_leave and current_date < getdate(self.effective_to): new_leaves_allocated = self.get_leaves_for_passed_months( annual_allocation, leave_details, date_of_joining ) diff --git a/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py b/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py index 4416090b87..1c884eb646 100644 --- a/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py +++ b/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py @@ -2,8 +2,13 @@ # See license.txt import frappe +<<<<<<< HEAD from frappe.tests.utils import FrappeTestCase from frappe.utils import add_months, get_first_day, get_year_ending, getdate +======= +from frappe.tests import IntegrationTestCase +from frappe.utils import add_days, add_months, get_first_day, get_year_ending, get_year_start, getdate +>>>>>>> bff9ed21 (fix: allocate earned leaves pro-rata if policy assignment is submitted after the effective period) from hrms.hr.doctype.leave_application.test_leave_application import get_employee, get_leave_period from hrms.hr.doctype.leave_period.test_leave_period import create_leave_period @@ -33,6 +38,9 @@ def setUp(self): self.original_doj = employee.date_of_joining self.employee = employee + def tearDown(self): + frappe.db.set_value("Employee", self.employee.name, "date_of_joining", self.original_doj) + def test_grant_leaves(self): leave_period = get_leave_period() leave_policy = create_leave_policy(annual_allocation=10) @@ -208,5 +216,29 @@ def test_pro_rated_leave_allocation_for_custom_date_range(self): self.assertGreater(new_leaves_allocated, 0) - def tearDown(self): - frappe.db.set_value("Employee", self.employee.name, "date_of_joining", self.original_doj) + def test_earned_leave_allocation_if_leave_policy_assignment_submitted_after_period(self): + year_start_date = get_year_start(getdate()) + year_end_date = get_year_ending(getdate()) + leave_period = create_leave_period(year_start_date, year_end_date) + + # assignment 10 days after the leave period + frappe.flags.current_date = add_days(year_end_date, 10) + leave_type = create_leave_type( + leave_type_name="_Test Earned Leave", is_earned_leave=True, allocate_on_day="Last Day" + ) + annual_earned_leaves = 10 + leave_policy = create_leave_policy(leave_type=leave_type, annual_allocation=annual_earned_leaves) + leave_policy.submit() + + data = { + "assignment_based_on": "Leave Period", + "leave_policy": leave_policy.name, + "leave_period": leave_period.name, + } + assignment = create_assignment(self.employee.name, frappe._dict(data)) + assignment.submit() + + earned_leave_allocation = frappe.get_value( + "Leave Allocation", {"leave_policy_assignment": assignment.name}, "new_leaves_allocated" + ) + self.assertEqual(earned_leave_allocation, annual_earned_leaves) From e4d2d7d6b9331cf9d6efc1f407e49014d86c4942 Mon Sep 17 00:00:00 2001 From: Asmita Hase Date: Fri, 24 Jan 2025 15:57:36 +0530 Subject: [PATCH 3/4] chore: added a test for earned allocation with leave period spanning two years (cherry picked from commit 980f117676b290bdbe20d09e637f83d468b1e1fc) --- .../test_leave_policy_assignment.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py b/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py index 1c884eb646..b19b5059ce 100644 --- a/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py +++ b/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py @@ -242,3 +242,32 @@ def test_earned_leave_allocation_if_leave_policy_assignment_submitted_after_peri "Leave Allocation", {"leave_policy_assignment": assignment.name}, "new_leaves_allocated" ) self.assertEqual(earned_leave_allocation, annual_earned_leaves) + + def test_earned_leave_allocation_for_leave_period_spanning_two_years(self): + first_year_start_date = get_year_start(getdate()) + second_year_end_date = get_year_ending(add_months(first_year_start_date, 12)) + leave_period = create_leave_period(first_year_start_date, second_year_end_date) + + # assignment during mid second year + frappe.flags.current_date = add_months(second_year_end_date, -6) + leave_type = create_leave_type( + leave_type_name="_Test Earned Leave", is_earned_leave=True, allocate_on_day="Last Day" + ) + annual_earned_leaves = 24 + leave_policy = create_leave_policy(leave_type=leave_type, annual_allocation=annual_earned_leaves) + leave_policy.submit() + + data = { + "assignment_based_on": "Leave Period", + "leave_policy": leave_policy.name, + "leave_period": leave_period.name, + } + assignment = create_assignment(self.employee.name, frappe._dict(data)) + assignment.submit() + + earned_leave_allocation = frappe.get_value( + "Leave Allocation", {"leave_policy_assignment": assignment.name}, "new_leaves_allocated" + ) + # months passed (18) are calculated correctly but total allocation of 36 exceeds 24 hence 24 + # this upper cap is intentional, without that 36 leaves would be allocated correctly + self.assertEqual(earned_leave_allocation, 24) From e191f00ba2f2440e57ec5fa3f36a2cbc144ba7cf Mon Sep 17 00:00:00 2001 From: Asmita Hase Date: Tue, 4 Feb 2025 14:00:26 +0530 Subject: [PATCH 4/4] chore: resolved merge conflicts --- .../leave_policy_assignment/test_leave_policy_assignment.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py b/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py index b19b5059ce..7c8df9a972 100644 --- a/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py +++ b/hrms/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py @@ -2,13 +2,8 @@ # See license.txt import frappe -<<<<<<< HEAD from frappe.tests.utils import FrappeTestCase -from frappe.utils import add_months, get_first_day, get_year_ending, getdate -======= -from frappe.tests import IntegrationTestCase from frappe.utils import add_days, add_months, get_first_day, get_year_ending, get_year_start, getdate ->>>>>>> bff9ed21 (fix: allocate earned leaves pro-rata if policy assignment is submitted after the effective period) from hrms.hr.doctype.leave_application.test_leave_application import get_employee, get_leave_period from hrms.hr.doctype.leave_period.test_leave_period import create_leave_period