feat: set carry forwarded leave allocation
This commit is contained in:
parent
c28d2e4b2a
commit
e46d3a87ea
@ -325,7 +325,7 @@
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.is_carry_forward != 1",
|
||||
"depends_on": "eval: doc.carry_forward != 1",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "new_leaves_allocated",
|
||||
"fieldtype": "Float",
|
||||
@ -351,73 +351,6 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.is_carry_forward == 1",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "old_leaves_allocated",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Old Leaves Allocated",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "is_carry_forward",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "is carry forward",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
@ -437,7 +370,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Add unused leaves from previous allocations",
|
||||
"label": "Allocate unused leaves from previous allocations",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@ -452,39 +385,6 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "carry_forward",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "carry_forwarded_leaves",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Unused leaves",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
@ -492,6 +392,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "total_leaves_allocated",
|
||||
"fieldtype": "Float",
|
||||
@ -764,7 +665,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-04-04 15:09:33.421008",
|
||||
"modified": "2019-04-05 15:31:04.627015",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Leave Allocation",
|
||||
|
@ -18,14 +18,19 @@ class ValueMultiplierError(frappe.ValidationError): pass
|
||||
class LeaveAllocation(Document):
|
||||
def validate(self):
|
||||
self.validate_period()
|
||||
self.validate_new_leaves_allocated_value()
|
||||
self.validate_lwp()
|
||||
self.validate_allocation_overlap()
|
||||
self.validate_back_dated_allocation()
|
||||
if not self.carry_forward:
|
||||
self.validate_new_leaves_allocated_value()
|
||||
self.validate_leave_allocation_days()
|
||||
self.set_total_leaves_allocated()
|
||||
self.validate_total_leaves_allocated()
|
||||
self.validate_lwp()
|
||||
set_employee_name(self)
|
||||
self.validate_leave_allocation_days()
|
||||
|
||||
def on_update(self):
|
||||
if self.carry_forward:
|
||||
self.set_carry_forward_leaves()
|
||||
|
||||
def validate_leave_allocation_days(self):
|
||||
company = frappe.db.get_value("Employee", self.employee, "company")
|
||||
@ -44,7 +49,6 @@ class LeaveAllocation(Document):
|
||||
self.validate_new_leaves_allocated_value()
|
||||
self.set_total_leaves_allocated()
|
||||
|
||||
frappe.db.set(self,'carry_forwarded_leaves', flt(self.carry_forwarded_leaves))
|
||||
frappe.db.set(self,'total_leaves_allocated',flt(self.total_leaves_allocated))
|
||||
|
||||
self.validate_against_leave_applications()
|
||||
@ -62,7 +66,7 @@ class LeaveAllocation(Document):
|
||||
if flt(self.new_leaves_allocated) % 0.5:
|
||||
frappe.throw(_("Leaves must be allocated in multiples of 0.5"), ValueMultiplierError)
|
||||
|
||||
def validate_allocation_overlap(self, carry_forward=0):
|
||||
def validate_allocation_overlap(self):
|
||||
leave_allocation = frappe.db.sql("""
|
||||
SELECT
|
||||
name
|
||||
@ -71,10 +75,10 @@ class LeaveAllocation(Document):
|
||||
employee=%s
|
||||
AND leave_type=%s
|
||||
AND docstatus=1
|
||||
AND is_carry_forward={0}
|
||||
AND carry_forward={0}
|
||||
AND to_date >= %s
|
||||
AND from_date <= %s""".format(carry_forward),
|
||||
(self.employee, self.leave_type, self.from_date, self.to_date))
|
||||
AND from_date <= %s""" #nosec
|
||||
.format(self.carry_forward), (self.employee, self.leave_type, self.from_date, self.to_date))
|
||||
|
||||
if leave_allocation:
|
||||
frappe.msgprint(_("{0} already allocated for Employee {1} for period {2} to {3}")
|
||||
@ -94,12 +98,11 @@ class LeaveAllocation(Document):
|
||||
BackDatedAllocationError)
|
||||
|
||||
def set_total_leaves_allocated(self):
|
||||
self.carry_forwarded_leaves = get_carry_forwarded_leaves(self.employee,
|
||||
self.leave_type, self.from_date, self.carry_forward)
|
||||
|
||||
self.total_leaves_allocated = flt(self.carry_forwarded_leaves) + flt(self.new_leaves_allocated)
|
||||
self.total_leaves_allocated = flt(self.new_leaves_allocated)
|
||||
|
||||
if not self.total_leaves_allocated and not frappe.db.get_value("Leave Type", self.leave_type, "is_earned_leave") and not frappe.db.get_value("Leave Type", self.leave_type, "is_compensatory"):
|
||||
if not self.total_leaves_allocated and not frappe.db.get_value("Leave Type", self.leave_type, "is_earned_leave")\
|
||||
and not frappe.db.get_value("Leave Type", self.leave_type, "is_compensatory"):
|
||||
frappe.throw(_("Total leaves allocated is mandatory for Leave Type {0}".format(self.leave_type)))
|
||||
|
||||
def validate_total_leaves_allocated(self):
|
||||
@ -119,20 +122,44 @@ class LeaveAllocation(Document):
|
||||
frappe.throw(_("Total allocated leaves {0} cannot be less than already approved leaves {1} for the period").format(self.total_leaves_allocated, leaves_taken), LessAllocationError)
|
||||
|
||||
def set_carry_forward_leaves(self):
|
||||
self.validate_allocation_overlap(carry_forward=1)
|
||||
self.old_leaves_allocated = get_carry_forwarded_leaves(self.employee, self.leave_type,
|
||||
self.from_date, self.is_carry_forward)
|
||||
|
||||
leaves_allocated
|
||||
# check number of days to expire, ignore expiry for default value
|
||||
expiry_days = frappe.db.get_value("Leave Type",
|
||||
filters={"leave_type": leave_type, "is_carry_forward": 1},
|
||||
fieldname="carry_forward_leave_expiry")
|
||||
|
||||
max_leaves_allowed = frappe.db.get_value("Leave Type", self.leave_type, "max_leaves_allowed")
|
||||
leave_period = get_leave_period(self.from_date, self.to_date, company)
|
||||
if leave_period:
|
||||
leave_allocated = get_leave_allocation_for_period(self.employee, self.leave_type, leave_period[0].from_date, leave_period[0].to_date)
|
||||
|
||||
carry_forwarded_leaves = get_carry_forwarded_leaves(self.employee, self.leave_type,
|
||||
self.from_date, expiry_days)
|
||||
leaves_allocated += carry_forwarded_leaves
|
||||
|
||||
if leaves_allocated > max_leaves_allowed:
|
||||
self.total_leaves_allocated = max_leaves_allowed - leaves_allocated
|
||||
else:
|
||||
self.total_leaves_allocated = carry_forwarded_leaves
|
||||
|
||||
def get_leave_allocation_for_period(employee, leave_type, from_date, to_date):
|
||||
leave_allocated = 0
|
||||
leave_allocations = frappe.db.sql("""
|
||||
select employee, leave_type, from_date, to_date, total_leaves_allocated
|
||||
from `tabLeave Allocation`
|
||||
where employee=%(employee)s and leave_type=%(leave_type)s
|
||||
and docstatus=1
|
||||
and (from_date between %(from_date)s and %(to_date)s
|
||||
or to_date between %(from_date)s and %(to_date)s
|
||||
or (from_date < %(from_date)s and to_date > %(to_date)s))
|
||||
SELECT
|
||||
employee,
|
||||
leave_type,
|
||||
from_date,
|
||||
to_date,
|
||||
total_leaves_allocated
|
||||
FROM `tabLeave Allocation`
|
||||
WHERE
|
||||
employee=%(employee)s
|
||||
AND leave_type=%(leave_type)s
|
||||
AND docstatus=1
|
||||
AND (from_date BETWEEN %(from_date)s AND %(to_date)s
|
||||
OR to_date BETWEEN %(from_date)s AND %(to_date)s
|
||||
OR (from_date < %(from_date)s AND to_date > %(to_date)s))
|
||||
""", {
|
||||
"from_date": from_date,
|
||||
"to_date": to_date,
|
||||
@ -147,31 +174,32 @@ def get_leave_allocation_for_period(employee, leave_type, from_date, to_date):
|
||||
return leave_allocated
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_carry_forwarded_leaves(employee, leave_type, date, is_carry_forward=None):
|
||||
def get_carry_forwarded_leaves(employee, leave_type, date, expiry_days):
|
||||
carry_forwarded_leaves = 0
|
||||
|
||||
if is_carry_forward:
|
||||
validate_carry_forward(leave_type)
|
||||
validate_carry_forward(leave_type)
|
||||
filters = {
|
||||
"employee": employee,
|
||||
"leave_type": leave_type,
|
||||
"docstatus": 1,
|
||||
"to_date": ("<", date)
|
||||
}
|
||||
limit = 1
|
||||
if expiry_days:
|
||||
filters.update(carry_forward=0)
|
||||
limit = 2
|
||||
|
||||
previous_allocation = frappe.db.sql("""
|
||||
SELECT
|
||||
name,
|
||||
from_date,
|
||||
to_date,
|
||||
total_leaves_allocated
|
||||
FROM `tabLeave Allocation`
|
||||
WHERE
|
||||
employee=%s
|
||||
AND leave_type=%s
|
||||
AND docstatus=1
|
||||
AND to_date < %s
|
||||
ORDER BY to_date desc limit 1
|
||||
""", (employee, leave_type, date), as_dict=1)
|
||||
if previous_allocation:
|
||||
leaves_taken = get_approved_leaves_for_period(employee, leave_type,
|
||||
previous_allocation[0].from_date, previous_allocation[0].to_date)
|
||||
previous_allocation = frappe.get_all("Leave Allocation",
|
||||
filters=filters,
|
||||
fields=["name","from_date","to_date","total_leaves_allocated"],
|
||||
order_by="to_date desc",
|
||||
limit=limit)
|
||||
|
||||
carry_forwarded_leaves = flt(previous_allocation[0].total_leaves_allocated) - flt(leaves_taken)
|
||||
if previous_allocation:
|
||||
leaves_taken = get_approved_leaves_for_period(employee, leave_type,
|
||||
previous_allocation[0].from_date, previous_allocation[0].to_date)
|
||||
|
||||
carry_forwarded_leaves = flt(previous_allocation[0].total_leaves_allocated) - flt(leaves_taken)
|
||||
|
||||
return carry_forwarded_leaves
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user