test: earned leave allocation for passed months and allocation on month-end
diff --git a/erpnext/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py b/erpnext/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py
index 3b7f8ec..3455bae 100644
--- a/erpnext/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py
+++ b/erpnext/hr/doctype/leave_policy_assignment/test_leave_policy_assignment.py
@@ -4,7 +4,7 @@
import unittest
import frappe
-from frappe.utils import add_months, get_first_day, getdate
+from frappe.utils import add_months, get_first_day, get_last_day, getdate
from erpnext.hr.doctype.leave_application.test_leave_application import (
get_employee,
@@ -125,6 +125,69 @@
}, "total_leaves_allocated")
self.assertEqual(leaves_allocated, 0)
+ def test_earned_leave_allocation_for_passed_months(self):
+ employee = get_employee()
+ leave_type = create_earned_leave_type("Test Earned Leave")
+ leave_period = create_leave_period("Test Earned Leave Period",
+ start_date=get_first_day(add_months(getdate(), -1)))
+ leave_policy = frappe.get_doc({
+ "doctype": "Leave Policy",
+ "title": "Test Leave Policy",
+ "leave_policy_details": [{"leave_type": leave_type.name, "annual_allocation": 12}]
+ }).insert()
+
+ # Case 1: assignment created one month after the leave period, should allocate 1 leave
+ frappe.flags.current_date = get_first_day(getdate())
+ data = {
+ "assignment_based_on": "Leave Period",
+ "leave_policy": leave_policy.name,
+ "leave_period": leave_period.name
+ }
+ leave_policy_assignments = create_assignment_for_multiple_employees([employee.name], frappe._dict(data))
+
+ leaves_allocated = frappe.db.get_value("Leave Allocation", {
+ "leave_policy_assignment": leave_policy_assignments[0]
+ }, "total_leaves_allocated")
+ self.assertEqual(leaves_allocated, 1)
+
+ def test_earned_leave_allocation_for_passed_months_on_month_end(self):
+ employee = get_employee()
+ leave_type = create_earned_leave_type("Test Earned Leave")
+ leave_period = create_leave_period("Test Earned Leave Period",
+ start_date=get_first_day(add_months(getdate(), -2)))
+ leave_policy = frappe.get_doc({
+ "doctype": "Leave Policy",
+ "title": "Test Leave Policy",
+ "leave_policy_details": [{"leave_type": leave_type.name, "annual_allocation": 12}]
+ }).insert()
+
+ # Case 2: assignment created on the last day of the leave period's latter month
+ # should allocate 1 leave for current month even though the month has not ended
+ # since the daily job might have already executed
+ frappe.flags.current_date = get_last_day(getdate())
+
+ data = {
+ "assignment_based_on": "Leave Period",
+ "leave_policy": leave_policy.name,
+ "leave_period": leave_period.name
+ }
+ leave_policy_assignments = create_assignment_for_multiple_employees([employee.name], frappe._dict(data))
+
+ leaves_allocated = frappe.db.get_value("Leave Allocation", {
+ "leave_policy_assignment": leave_policy_assignments[0]
+ }, "total_leaves_allocated")
+ self.assertEqual(leaves_allocated, 3)
+
+ # if the daily job is not completed yet, there is another check present
+ # to ensure leave is not already allocated to avoid duplication
+ from erpnext.hr.utils import allocate_earned_leaves
+ allocate_earned_leaves()
+
+ leaves_allocated = frappe.db.get_value("Leave Allocation", {
+ "leave_policy_assignment": leave_policy_assignments[0]
+ }, "total_leaves_allocated")
+ self.assertEqual(leaves_allocated, 3)
+
def tearDown(self):
frappe.db.rollback()
@@ -137,14 +200,14 @@
doctype="Leave Type",
is_earned_leave=1,
earned_leave_frequency="Monthly",
- rounding=0.5,
- max_leaves_allowed=6
+ rounding=0.5
)).insert()
-def create_leave_period(name):
+def create_leave_period(name, start_date=None):
frappe.delete_doc_if_exists("Leave Period", name, force=1)
- start_date = get_first_day(getdate())
+ if not start_date:
+ start_date = get_first_day(getdate())
return frappe.get_doc(dict(
name=name,