fix: earned leaves not allocated if assignment is created on month-end
diff --git a/erpnext/hr/doctype/leave_policy_assignment/leave_policy_assignment.py b/erpnext/hr/doctype/leave_policy_assignment/leave_policy_assignment.py
index 355370f..41a9558 100644
--- a/erpnext/hr/doctype/leave_policy_assignment/leave_policy_assignment.py
+++ b/erpnext/hr/doctype/leave_policy_assignment/leave_policy_assignment.py
@@ -8,7 +8,7 @@
import frappe
from frappe import _, bold
from frappe.model.document import Document
-from frappe.utils import date_diff, flt, formatdate, get_datetime, getdate
+from frappe.utils import date_diff, flt, formatdate, get_datetime, get_last_day, getdate
class LeavePolicyAssignment(Document):
@@ -108,8 +108,8 @@
def get_leaves_for_passed_months(self, leave_type, new_leaves_allocated, leave_type_details, date_of_joining):
from erpnext.hr.utils import get_monthly_earned_leave
- current_month = get_datetime().month
- current_year = get_datetime().year
+ current_month = get_datetime(frappe.flags.current_date).month or get_datetime().month
+ current_year = get_datetime(frappe.flags.current_date).year or get_datetime().year
from_date = frappe.db.get_value("Leave Period", self.leave_period, "from_date")
if getdate(date_of_joining) > getdate(from_date):
@@ -119,10 +119,14 @@
from_date_year = get_datetime(from_date).year
months_passed = 0
+
if current_year == from_date_year and current_month > from_date_month:
months_passed = current_month - from_date_month
+ months_passed = add_current_month_if_applicable(months_passed)
+
elif current_year > from_date_year:
months_passed = (12 - from_date_month) + current_month
+ months_passed = add_current_month_if_applicable(months_passed)
if months_passed > 0:
monthly_earned_leave = get_monthly_earned_leave(new_leaves_allocated,
@@ -134,6 +138,17 @@
return new_leaves_allocated
+def add_current_month_if_applicable(months_passed):
+ date = getdate(frappe.flags.current_date) or getdate()
+ last_day_of_month = get_last_day(date)
+
+ # if its the last day of the month, then that month should also be considered
+ if last_day_of_month == date:
+ months_passed += 1
+
+ return months_passed
+
+
@frappe.whitelist()
def create_assignment_for_multiple_employees(employees, data):
diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py
index 0febce1..2006ef3 100644
--- a/erpnext/hr/utils.py
+++ b/erpnext/hr/utils.py
@@ -277,9 +277,12 @@
new_allocation = e_leave_type.max_leaves_allowed
if new_allocation != allocation.total_leaves_allocated:
- allocation.db_set("total_leaves_allocated", new_allocation, update_modified=False)
today_date = today()
- create_additional_leave_ledger_entry(allocation, earned_leaves, today_date)
+
+ if not is_earned_leave_already_allocated(allocation, annual_allocation):
+ allocation.db_set("total_leaves_allocated", new_allocation, update_modified=False)
+ create_additional_leave_ledger_entry(allocation, earned_leaves, today_date)
+
def get_monthly_earned_leave(annual_leaves, frequency, rounding):
earned_leaves = 0.0
@@ -297,6 +300,21 @@
return earned_leaves
+def is_earned_leave_already_allocated(allocation, annual_allocation):
+ from erpnext.hr.doctype.leave_policy_assignment.leave_policy_assignment import get_leave_type_details
+
+ leave_type_details = get_leave_type_details()
+ date_of_joining = frappe.db.get_value("Employee", allocation.employee, "date_of_joining")
+
+ assignment = frappe.get_doc("Leave Policy Assignment", allocation.leave_policy_assignment)
+ leaves_for_passed_months = assignment.get_leaves_for_passed_months(allocation.leave_type,
+ annual_allocation, leave_type_details, date_of_joining)
+
+ if allocation.total_leaves_allocated >= leaves_for_passed_months:
+ return True
+ return False
+
+
def get_leave_allocations(date, leave_type):
return frappe.db.sql("""select name, employee, from_date, to_date, leave_policy_assignment, leave_policy
from `tabLeave Allocation`