Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Earned Leave allocation based on joining date fixes (backport #29711) #29763

Merged
merged 7 commits into from
Feb 11, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@
import frappe
from frappe import _, bold
from frappe.model.document import Document
from frappe.utils import date_diff, flt, formatdate, get_datetime, get_last_day, getdate
from frappe.utils import date_diff, flt, formatdate, get_last_day, getdate
from six import string_types


class LeavePolicyAssignment(Document):

def validate(self):
self.validate_policy_assignment_overlap()
self.set_dates()
Expand Down Expand Up @@ -95,10 +94,12 @@ def get_new_leaves(self, leave_type, new_leaves_allocated, leave_type_details, d
new_leaves_allocated = 0

elif leave_type_details.get(leave_type).is_earned_leave == 1:
if self.assignment_based_on == "Leave Period":
new_leaves_allocated = self.get_leaves_for_passed_months(leave_type, new_leaves_allocated, leave_type_details, date_of_joining)
else:
if not self.assignment_based_on:
new_leaves_allocated = 0
else:
# get leaves for past months if assignment is based on Leave Period / Joining Date
new_leaves_allocated = self.get_leaves_for_passed_months(leave_type, new_leaves_allocated, leave_type_details, date_of_joining)

# Calculate leaves at pro-rata basis for employees joining after the beginning of the given leave period
elif getdate(date_of_joining) > getdate(self.effective_from):
remaining_period = ((date_diff(self.effective_to, date_of_joining) + 1) / (date_diff(self.effective_to, self.effective_from) + 1))
Expand All @@ -109,25 +110,24 @@ def get_new_leaves(self, leave_type, new_leaves_allocated, leave_type_details, d
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(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):
from_date = date_of_joining
current_date = frappe.flags.current_date or getdate()
if current_date > getdate(self.effective_to):
current_date = getdate(self.effective_to)

from_date_month = get_datetime(from_date).month
from_date_year = get_datetime(from_date).year
from_date = getdate(self.effective_from)
if getdate(date_of_joining) > from_date:
from_date = getdate(date_of_joining)

months_passed = 0
based_on_doj = leave_type_details.get(leave_type).based_on_date_of_joining

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)
if current_date.year == from_date.year and current_date.month >= from_date.month:
months_passed = current_date.month - from_date.month
months_passed = add_current_month_if_applicable(months_passed, date_of_joining, based_on_doj)

elif current_year > from_date_year:
months_passed = (12 - from_date_month) + current_month
months_passed = add_current_month_if_applicable(months_passed)
elif current_date.year > from_date.year:
months_passed = (12 - from_date.month) + current_date.month
months_passed = add_current_month_if_applicable(months_passed, date_of_joining, based_on_doj)

if months_passed > 0:
monthly_earned_leave = get_monthly_earned_leave(new_leaves_allocated,
Expand All @@ -139,13 +139,19 @@ def get_leaves_for_passed_months(self, leave_type, new_leaves_allocated, leave_t
return new_leaves_allocated


def add_current_month_if_applicable(months_passed):
def add_current_month_if_applicable(months_passed, date_of_joining, based_on_doj):
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
if based_on_doj:
# if leave type allocation is based on DOJ, and the date of assignment creation is same as DOJ,
# then the month should be considered
if date.day == date_of_joining.day:
months_passed += 1
else:
last_day_of_month = get_last_day(date)
# if its the last day of the month, then that month should be considered
if last_day_of_month == date:
months_passed += 1

return months_passed

Expand Down Expand Up @@ -184,7 +190,7 @@ def create_assignment_for_multiple_employees(employees, data):
def get_leave_type_details():
leave_type_details = frappe._dict()
leave_types = frappe.get_all("Leave Type",
fields=["name", "is_lwp", "is_earned_leave", "is_compensatory",
fields=["name", "is_lwp", "is_earned_leave", "is_compensatory", "based_on_date_of_joining",
"is_carry_forward", "expire_carry_forwarded_leaves_after_days", "earned_leave_frequency", "rounding"])
for d in leave_types:
leave_type_details.setdefault(d.name, d)
Expand Down
Loading