Leave application overlap validation for half day and test cases
This commit is contained in:
parent
a8d02bfd4a
commit
697150f339
@ -64,7 +64,10 @@ class LeaveApplication(Document):
|
|||||||
if self.from_date and self.to_date and (getdate(self.to_date) < getdate(self.from_date)):
|
if self.from_date and self.to_date and (getdate(self.to_date) < getdate(self.from_date)):
|
||||||
frappe.throw(_("To date cannot be before from date"))
|
frappe.throw(_("To date cannot be before from date"))
|
||||||
|
|
||||||
if self.half_day and (getdate(self.half_day_date) < getdate(self.from_date) or (getdate(self.half_day_date) > getdate(self.to_date))):
|
if self.half_day and self.half_day_date \
|
||||||
|
and (getdate(self.half_day_date) < getdate(self.from_date)
|
||||||
|
or getdate(self.half_day_date) > getdate(self.to_date)):
|
||||||
|
|
||||||
frappe.throw(_("Half Day Date should be between From Date and To Date"))
|
frappe.throw(_("Half Day Date should be between From Date and To Date"))
|
||||||
|
|
||||||
if not is_lwp(self.leave_type):
|
if not is_lwp(self.leave_type):
|
||||||
@ -154,7 +157,9 @@ class LeaveApplication(Document):
|
|||||||
# hack! if name is null, it could cause problems with !=
|
# hack! if name is null, it could cause problems with !=
|
||||||
self.name = "New Leave Application"
|
self.name = "New Leave Application"
|
||||||
|
|
||||||
for d in frappe.db.sql("""select name, leave_type, posting_date, from_date, to_date, total_leave_days
|
for d in frappe.db.sql("""
|
||||||
|
select
|
||||||
|
name, leave_type, posting_date, from_date, to_date, total_leave_days, half_day_date
|
||||||
from `tabLeave Application`
|
from `tabLeave Application`
|
||||||
where employee = %(employee)s and docstatus < 2 and status in ("Open", "Approved")
|
where employee = %(employee)s and docstatus < 2 and status in ("Open", "Approved")
|
||||||
and to_date >= %(from_date)s and from_date <= %(to_date)s
|
and to_date >= %(from_date)s and from_date <= %(to_date)s
|
||||||
@ -165,9 +170,13 @@ class LeaveApplication(Document):
|
|||||||
"name": self.name
|
"name": self.name
|
||||||
}, as_dict = 1):
|
}, as_dict = 1):
|
||||||
|
|
||||||
if d['total_leave_days']==0.5 and cint(self.half_day)==1:
|
if cint(self.half_day)==1 and getdate(self.half_day_date) == getdate(d.half_day_date) and (
|
||||||
sum_leave_days = self.get_total_leaves_on_half_day()
|
flt(self.total_leave_days)==0.5
|
||||||
if sum_leave_days==1:
|
or getdate(self.from_date) == getdate(d.to_date)
|
||||||
|
or getdate(self.to_date) == getdate(d.from_date)):
|
||||||
|
|
||||||
|
total_leaves_on_half_day = self.get_total_leaves_on_half_day()
|
||||||
|
if total_leaves_on_half_day >= 1:
|
||||||
self.throw_overlap_error(d)
|
self.throw_overlap_error(d)
|
||||||
else:
|
else:
|
||||||
self.throw_overlap_error(d)
|
self.throw_overlap_error(d)
|
||||||
@ -179,19 +188,20 @@ class LeaveApplication(Document):
|
|||||||
frappe.throw(msg, OverlapError)
|
frappe.throw(msg, OverlapError)
|
||||||
|
|
||||||
def get_total_leaves_on_half_day(self):
|
def get_total_leaves_on_half_day(self):
|
||||||
return frappe.db.sql("""select sum(total_leave_days) from `tabLeave Application`
|
leave_count_on_half_day_date = frappe.db.sql("""select count(name) from `tabLeave Application`
|
||||||
where employee = %(employee)s
|
where employee = %(employee)s
|
||||||
and docstatus < 2
|
and docstatus < 2
|
||||||
and status in ("Open", "Approved")
|
and status in ("Open", "Approved")
|
||||||
and from_date = %(from_date)s
|
and half_day = 1
|
||||||
and to_date = %(to_date)s
|
and half_day_date = %(half_day_date)s
|
||||||
and name != %(name)s""", {
|
and name != %(name)s""", {
|
||||||
"employee": self.employee,
|
"employee": self.employee,
|
||||||
"from_date": self.from_date,
|
"half_day_date": self.half_day_date,
|
||||||
"to_date": self.to_date,
|
|
||||||
"name": self.name
|
"name": self.name
|
||||||
})[0][0]
|
})[0][0]
|
||||||
|
|
||||||
|
return leave_count_on_half_day_date * 0.5
|
||||||
|
|
||||||
def validate_max_days(self):
|
def validate_max_days(self):
|
||||||
max_days = frappe.db.get_value("Leave Type", self.leave_type, "max_days_allowed")
|
max_days = frappe.db.get_value("Leave Type", self.leave_type, "max_days_allowed")
|
||||||
if max_days and self.total_leave_days > cint(max_days):
|
if max_days and self.total_leave_days > cint(max_days):
|
||||||
|
@ -134,7 +134,7 @@ class TestLeaveApplication(unittest.TestCase):
|
|||||||
application.leave_approver = "test2@example.com"
|
application.leave_approver = "test2@example.com"
|
||||||
self.assertRaises(OverlapError, application.insert)
|
self.assertRaises(OverlapError, application.insert)
|
||||||
|
|
||||||
def test_overlap_with_half_day(self):
|
def test_overlap_with_half_day_1(self):
|
||||||
self._clear_roles()
|
self._clear_roles()
|
||||||
self._clear_applications()
|
self._clear_applications()
|
||||||
|
|
||||||
@ -146,25 +146,33 @@ class TestLeaveApplication(unittest.TestCase):
|
|||||||
|
|
||||||
make_allocation_record()
|
make_allocation_record()
|
||||||
|
|
||||||
# allow second half-day on the same day if available
|
# leave from 1-5, half day on 3rd
|
||||||
application = self.get_application(_test_records[0])
|
application = self.get_application(_test_records[0])
|
||||||
application.leave_approver = "test2@example.com"
|
application.leave_approver = "test2@example.com"
|
||||||
application.half_day = 1
|
application.half_day = 1
|
||||||
|
application.half_day_date = "2013-01-03"
|
||||||
application.insert()
|
application.insert()
|
||||||
|
|
||||||
# allow second half-day on the same day if available
|
# Apply again for a half day leave on 3rd
|
||||||
application = self.get_application(_test_records[0])
|
application = self.get_application(_test_records[0])
|
||||||
application.leave_approver = "test2@example.com"
|
application.leave_approver = "test2@example.com"
|
||||||
|
application.from_date = "2013-01-03"
|
||||||
|
application.to_date = "2013-01-03"
|
||||||
application.half_day = 1
|
application.half_day = 1
|
||||||
|
application.half_day_date = "2013-01-03"
|
||||||
application.insert()
|
application.insert()
|
||||||
|
|
||||||
|
# Apply again for a half day leave on 3rd
|
||||||
application = self.get_application(_test_records[0])
|
application = self.get_application(_test_records[0])
|
||||||
application.leave_approver = "test2@example.com"
|
application.leave_approver = "test2@example.com"
|
||||||
|
application.from_date = "2013-01-03"
|
||||||
|
application.to_date = "2013-01-03"
|
||||||
application.half_day = 1
|
application.half_day = 1
|
||||||
|
application.half_day_date = "2013-01-03"
|
||||||
|
|
||||||
self.assertRaises(OverlapError, application.insert)
|
self.assertRaises(OverlapError, application.insert)
|
||||||
|
|
||||||
def test_overlap_with_half_day_not_applicable(self):
|
def test_overlap_with_half_day_2(self):
|
||||||
self._clear_roles()
|
self._clear_roles()
|
||||||
self._clear_applications()
|
self._clear_applications()
|
||||||
|
|
||||||
@ -176,18 +184,57 @@ class TestLeaveApplication(unittest.TestCase):
|
|||||||
|
|
||||||
make_allocation_record()
|
make_allocation_record()
|
||||||
|
|
||||||
# allow second half-day on the same day if available
|
# leave from 1-5, no half day
|
||||||
application = self.get_application(_test_records[0])
|
application = self.get_application(_test_records[0])
|
||||||
application.leave_approver = "test2@example.com"
|
application.leave_approver = "test2@example.com"
|
||||||
application.insert()
|
application.insert()
|
||||||
|
|
||||||
# allow second half-day on the same day if available
|
# Apply again for a half day leave on 1st
|
||||||
application = self.get_application(_test_records[0])
|
application = self.get_application(_test_records[0])
|
||||||
application.leave_approver = "test2@example.com"
|
application.leave_approver = "test2@example.com"
|
||||||
application.half_day = 1
|
application.half_day = 1
|
||||||
|
application.half_day_date = application.from_date
|
||||||
|
|
||||||
self.assertRaises(OverlapError, application.insert)
|
self.assertRaises(OverlapError, application.insert)
|
||||||
|
|
||||||
|
def test_overlap_with_half_day_3(self):
|
||||||
|
self._clear_roles()
|
||||||
|
self._clear_applications()
|
||||||
|
|
||||||
|
from frappe.utils.user import add_role
|
||||||
|
add_role("test@example.com", "Employee")
|
||||||
|
add_role("test2@example.com", "Leave Approver")
|
||||||
|
|
||||||
|
frappe.set_user("test@example.com")
|
||||||
|
|
||||||
|
make_allocation_record()
|
||||||
|
|
||||||
|
# leave from 1-5, half day on 5th
|
||||||
|
application = self.get_application(_test_records[0])
|
||||||
|
application.leave_approver = "test2@example.com"
|
||||||
|
application.half_day = 1
|
||||||
|
application.half_day_date = "2013-01-05"
|
||||||
|
application.insert()
|
||||||
|
|
||||||
|
# Apply leave from 4-7, half day on 5th
|
||||||
|
application = self.get_application(_test_records[0])
|
||||||
|
application.leave_approver = "test2@example.com"
|
||||||
|
application.from_date = "2013-01-04"
|
||||||
|
application.to_date = "2013-01-07"
|
||||||
|
application.half_day = 1
|
||||||
|
application.half_day_date = "2013-01-05"
|
||||||
|
|
||||||
|
self.assertRaises(OverlapError, application.insert)
|
||||||
|
|
||||||
|
# Apply leave from 5-7, half day on 5th
|
||||||
|
application = self.get_application(_test_records[0])
|
||||||
|
application.leave_approver = "test2@example.com"
|
||||||
|
application.from_date = "2013-01-05"
|
||||||
|
application.to_date = "2013-01-07"
|
||||||
|
application.half_day = 1
|
||||||
|
application.half_day_date = "2013-01-05"
|
||||||
|
application.insert()
|
||||||
|
|
||||||
def test_global_block_list(self):
|
def test_global_block_list(self):
|
||||||
self._clear_roles()
|
self._clear_roles()
|
||||||
|
|
||||||
|
@ -2,13 +2,14 @@ import frappe
|
|||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
frappe.reload_doctype('Salary Slip', 'Salary Component')
|
frappe.reload_doctype('Salary Slip', 'Salary Component')
|
||||||
salary_components = ['Arrear', 'Leave Encashment']
|
salary_components = [['Arrear', "ARR"], ['Leave Encashment', 'LENC']]
|
||||||
for salary_component in salary_components:
|
for salary_component, salary_abbr in salary_components:
|
||||||
if not frappe.db.exists('Salary Component', salary_component):
|
if not frappe.db.exists('Salary Component', salary_component):
|
||||||
sal_comp = frappe.get_doc({
|
sal_comp = frappe.get_doc({
|
||||||
"doctype": "Salary Component",
|
"doctype": "Salary Component",
|
||||||
"salary_component": salary_component,
|
"salary_component": salary_component,
|
||||||
"type": "Earning"
|
"type": "Earning",
|
||||||
|
"salary_component_abbr": salary_abbr
|
||||||
}).insert()
|
}).insert()
|
||||||
|
|
||||||
salary_slips = frappe.db.sql("""select name, arrear_amount, leave_encashment_amount from `tabSalary Slip`
|
salary_slips = frappe.db.sql("""select name, arrear_amount, leave_encashment_amount from `tabSalary Slip`
|
||||||
|
Loading…
Reference in New Issue
Block a user