feat: pro-rata leave allocation
This commit is contained in:
parent
f281f00d43
commit
6bed870dfa
@ -515,7 +515,7 @@ def get_remaining_leaves(allocation, leaves_taken, date, expiry):
|
|||||||
|
|
||||||
return remaining_leaves
|
return remaining_leaves
|
||||||
|
|
||||||
if expiry:
|
if expiry and allocation.carry_forwarded_leaves:
|
||||||
remaining_leaves = _get_remaining_leaves(allocation.carry_forwarded_leaves, expiry)
|
remaining_leaves = _get_remaining_leaves(allocation.carry_forwarded_leaves, expiry)
|
||||||
|
|
||||||
return flt(allocation.new_leaves_allocated) + flt(remaining_leaves)
|
return flt(allocation.new_leaves_allocated) + flt(remaining_leaves)
|
||||||
|
|||||||
@ -68,7 +68,7 @@ frappe.ui.form.on('Leave Period', {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Add unused leaves from previous allocations",
|
"label": "Add unused leaves from previous allocations",
|
||||||
"fieldname": "carry_forward_leaves",
|
"fieldname": "carry_forward",
|
||||||
"fieldtype": "Check"
|
"fieldtype": "Check"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import getdate, cstr, add_days
|
from frappe.utils import getdate, cstr, add_days, date_diff, getdate, ceil
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.hr.utils import validate_overlap, get_employee_leave_policy
|
from erpnext.hr.utils import validate_overlap, get_employee_leave_policy
|
||||||
from erpnext.hr.doctype.leave_allocation.leave_allocation import get_carry_forwarded_leaves
|
from erpnext.hr.doctype.leave_allocation.leave_allocation import get_carry_forwarded_leaves
|
||||||
@ -22,8 +22,8 @@ class LeavePeriod(Document):
|
|||||||
|
|
||||||
condition_str = " and " + " and ".join(conditions) if len(conditions) else ""
|
condition_str = " and " + " and ".join(conditions) if len(conditions) else ""
|
||||||
|
|
||||||
employees = frappe.db.sql_list("select name from tabEmployee where status='Active' {condition}"
|
employees = frappe._dict(frappe.db.sql("select name, date_of_joining from tabEmployee where status='Active' {condition}"
|
||||||
.format(condition=condition_str), tuple(values))
|
.format(condition=condition_str), tuple(values)))
|
||||||
|
|
||||||
return employees
|
return employees
|
||||||
|
|
||||||
@ -37,29 +37,29 @@ class LeavePeriod(Document):
|
|||||||
|
|
||||||
|
|
||||||
def grant_leave_allocation(self, grade=None, department=None, designation=None,
|
def grant_leave_allocation(self, grade=None, department=None, designation=None,
|
||||||
employee=None, carry_forward_leaves=0):
|
employee=None, carry_forward=0):
|
||||||
employees = self.get_employees({
|
employee_records = self.get_employees({
|
||||||
"grade": grade,
|
"grade": grade,
|
||||||
"department": department,
|
"department": department,
|
||||||
"designation": designation,
|
"designation": designation,
|
||||||
"name": employee
|
"name": employee
|
||||||
})
|
})
|
||||||
|
|
||||||
if employees:
|
if employee_records:
|
||||||
if len(employees) > 20:
|
if len(employee_records) > 20:
|
||||||
frappe.enqueue(grant_leave_alloc_for_employees, timeout=600,
|
frappe.enqueue(grant_leave_alloc_for_employees, timeout=600,
|
||||||
employees=employees, leave_period=self, carry_forward_leaves=carry_forward_leaves)
|
employee_records=employee_records, leave_period=self, carry_forward=carry_forward)
|
||||||
else:
|
else:
|
||||||
grant_leave_alloc_for_employees(employees, self, carry_forward_leaves)
|
grant_leave_alloc_for_employees(employee_records, self, carry_forward)
|
||||||
else:
|
else:
|
||||||
frappe.msgprint(_("No Employee Found"))
|
frappe.msgprint(_("No Employee Found"))
|
||||||
|
|
||||||
def grant_leave_alloc_for_employees(employees, leave_period, carry_forward_leaves=0):
|
def grant_leave_alloc_for_employees(employee_records, leave_period, carry_forward=0):
|
||||||
leave_allocations = []
|
leave_allocations = []
|
||||||
existing_allocations_for = get_existing_allocations(employees, leave_period.name)
|
existing_allocations_for = get_existing_allocations(list(employee_records.keys()), leave_period.name)
|
||||||
leave_type_details = get_leave_type_details()
|
leave_type_details = get_leave_type_details()
|
||||||
count = 0
|
count = 0
|
||||||
for employee in employees:
|
for employee in employee_records.keys():
|
||||||
if employee in existing_allocations_for:
|
if employee in existing_allocations_for:
|
||||||
continue
|
continue
|
||||||
count +=1
|
count +=1
|
||||||
@ -68,10 +68,10 @@ def grant_leave_alloc_for_employees(employees, leave_period, carry_forward_leave
|
|||||||
for leave_policy_detail in leave_policy.leave_policy_details:
|
for leave_policy_detail in leave_policy.leave_policy_details:
|
||||||
if not leave_type_details.get(leave_policy_detail.leave_type).is_lwp:
|
if not leave_type_details.get(leave_policy_detail.leave_type).is_lwp:
|
||||||
leave_allocation = create_leave_allocation(employee, leave_policy_detail.leave_type,
|
leave_allocation = create_leave_allocation(employee, leave_policy_detail.leave_type,
|
||||||
leave_policy_detail.annual_allocation, leave_type_details, leave_period, carry_forward_leaves)
|
leave_policy_detail.annual_allocation, leave_type_details, leave_period, carry_forward, employee_records.get(employee))
|
||||||
leave_allocations.append(leave_allocation)
|
leave_allocations.append(leave_allocation)
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
frappe.publish_progress(count*100/len(set(employees) - set(existing_allocations_for)), title = _("Allocating leaves..."))
|
frappe.publish_progress(count*100/len(set(employee_records.keys()) - set(existing_allocations_for)), title = _("Allocating leaves..."))
|
||||||
|
|
||||||
if leave_allocations:
|
if leave_allocations:
|
||||||
frappe.msgprint(_("Leaves has been granted sucessfully"))
|
frappe.msgprint(_("Leaves has been granted sucessfully"))
|
||||||
@ -100,21 +100,30 @@ def get_leave_type_details():
|
|||||||
leave_type_details.setdefault(d.name, d)
|
leave_type_details.setdefault(d.name, d)
|
||||||
return leave_type_details
|
return leave_type_details
|
||||||
|
|
||||||
def create_leave_allocation(employee, leave_type, new_leaves_allocated, leave_type_details, leave_period, carry_forward_leaves):
|
def create_leave_allocation(employee, leave_type, new_leaves_allocated, leave_type_details, leave_period, carry_forward, date_of_joining):
|
||||||
allocation = frappe.new_doc("Leave Allocation")
|
''' Creates leave allocation for the given employee in the provided leave period '''
|
||||||
allocation.employee = employee
|
if carry_forward and not leave_type_details.get(leave_type).is_carry_forward:
|
||||||
allocation.leave_type = leave_type
|
carry_forward = 0
|
||||||
allocation.from_date = leave_period.from_date
|
|
||||||
allocation.to_date = leave_period.to_date
|
# Calculate leaves at pro-rata basis for employees joining after the beginning of the given leave period
|
||||||
|
if getdate(date_of_joining) > getdate(leave_period.from_date):
|
||||||
|
remaining_period = ((date_diff(leave_period.to_date, date_of_joining) + 1) / (date_diff(leave_period.to_date, leave_period.from_date) + 1))
|
||||||
|
new_leaves_allocated = ceil(new_leaves_allocated * remaining_period)
|
||||||
|
|
||||||
# Earned Leaves and Compensatory Leaves are allocated by scheduler, initially allocate 0
|
# Earned Leaves and Compensatory Leaves are allocated by scheduler, initially allocate 0
|
||||||
if leave_type_details.get(leave_type).is_earned_leave == 1 or leave_type_details.get(leave_type).is_compensatory == 1:
|
if leave_type_details.get(leave_type).is_earned_leave == 1 or leave_type_details.get(leave_type).is_compensatory == 1:
|
||||||
new_leaves_allocated = 0
|
new_leaves_allocated = 0
|
||||||
|
|
||||||
allocation.new_leaves_allocated = new_leaves_allocated
|
allocation = frappe.get_doc(dict(
|
||||||
allocation.leave_period = leave_period.name
|
doctype="Leave Allocation",
|
||||||
if carry_forward_leaves:
|
employee=employee,
|
||||||
if leave_type_details.get(leave_type).is_carry_forward:
|
leave_type=leave_type,
|
||||||
allocation.carry_forward = carry_forward_leaves
|
from_date=leave_period.from_date,
|
||||||
|
to_date=leave_period.to_date,
|
||||||
|
new_leaves_allocated=new_leaves_allocated,
|
||||||
|
leave_period=leave_period.name,
|
||||||
|
carry_forward=carry_forward
|
||||||
|
))
|
||||||
allocation.save(ignore_permissions = True)
|
allocation.save(ignore_permissions = True)
|
||||||
allocation.submit()
|
allocation.submit()
|
||||||
return allocation.name
|
return allocation.name
|
||||||
Loading…
x
Reference in New Issue
Block a user