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

feat: option to enable/disable multiple Shift Assignments for same dates #1100

Merged
15 changes: 14 additions & 1 deletion hrms/hr/doctype/hr_settings/hr_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
"column_break_hyec",
"sender",
"sender_email",
"shift_management_settings_section",
"allow_multiple_shift_assignments",
"leave_and_expense_claim_settings",
"send_leave_notification",
"leave_approval_notification_template",
Expand Down Expand Up @@ -267,13 +269,24 @@
{
"fieldname": "column_break_hyec",
"fieldtype": "Column Break"
},
{
"default": "1",
"fieldname": "allow_multiple_shift_assignments",
"fieldtype": "Check",
"label": "Allow Multiple Shift Assignments for Same Date"
},
{
"fieldname": "shift_management_settings_section",
"fieldtype": "Section Break",
"label": "Shift Management Settings"
krantheman marked this conversation as resolved.
Show resolved Hide resolved
}
],
"icon": "fa fa-cog",
"idx": 1,
"issingle": 1,
"links": [],
"modified": "2023-11-01 11:06:31.329718",
"modified": "2023-11-22 18:56:33.884740",
"modified_by": "Administrator",
"module": "HR",
"name": "HR Settings",
Expand Down
28 changes: 28 additions & 0 deletions hrms/hr/doctype/shift_assignment/shift_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ class OverlappingShiftError(frappe.ValidationError):
pass


class MultipleShiftError(frappe.ValidationError):
pass


class ShiftAssignment(Document):
def validate(self):
validate_active_employee(self.employee)
self.validate_overlapping_shifts()
self.validate_same_date_multiple_shifts()

if self.end_date:
self.validate_from_to_dates("start_date", "end_date")
Expand All @@ -35,6 +40,29 @@ def validate_overlapping_shifts(self):
if overlapping_timings:
self.throw_overlap_error(overlapping_dates[0])

def validate_same_date_multiple_shifts(self):
krantheman marked this conversation as resolved.
Show resolved Hide resolved
overlapping_dates = self.get_overlapping_dates()
if not len(overlapping_dates):
return

allow_multiple_shift_assignments = frappe.db.get_single_value(
"HR Settings", "allow_multiple_shift_assignments"
)
if not allow_multiple_shift_assignments:
frappe.throw(
msg=_(
"Multiple shift assignments for the same date has been disabled. Please enable this feature under {0}."
krantheman marked this conversation as resolved.
Show resolved Hide resolved
).format(get_link_to_form("HR Settings", "HR Settings")),
exc=MultipleShiftError,
)

if not self.docstatus:
krantheman marked this conversation as resolved.
Show resolved Hide resolved
frappe.msgprint(
_(
"Note: You have already assigned different Shifts to {0} for some/all of these dates. Multiple Shift Assignments for the same date can be disabled under {1}."
krantheman marked this conversation as resolved.
Show resolved Hide resolved
).format(self.employee, get_link_to_form("HR Settings", "HR Settings"))
)

def get_overlapping_dates(self):
if not self.name:
self.name = "New Shift Assignment"
Expand Down
34 changes: 34 additions & 0 deletions hrms/hr/doctype/shift_assignment/test_shift_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from erpnext.setup.doctype.employee.test_employee import make_employee

from hrms.hr.doctype.shift_assignment.shift_assignment import (
MultipleShiftError,
OverlappingShiftError,
get_actual_start_end_datetime_of_shift,
get_events,
Expand Down Expand Up @@ -66,6 +67,39 @@ def test_overlapping_for_ongoing_shift(self):

self.assertRaises(OverlappingShiftError, shift_assignment.save)

def test_multiple_shift_assignments_for_same_date(self):
setup_shift_type(shift_type="Day Shift")
shift_assignment_1 = frappe.get_doc(
{
"doctype": "Shift Assignment",
"shift_type": "Day Shift",
"company": "_Test Company",
"employee": "_T-Employee-00001",
"start_date": nowdate(),
"end_date": add_days(nowdate(), 30),
"status": "Active",
}
).insert()
shift_assignment_1.submit()

setup_shift_type(shift_type="Night Shift", start_time="19:00:00", end_time="23:00:00")
shift_assignment_2 = frappe.get_doc(
{
"doctype": "Shift Assignment",
"shift_type": "Night Shift",
"company": "_Test Company",
"employee": "_T-Employee-00001",
"start_date": nowdate(),
"end_date": add_days(nowdate(), 30),
"status": "Active",
}
)

frappe.db.set_single_value("HR Settings", "allow_multiple_shift_assignments", 0)
self.assertRaises(MultipleShiftError, shift_assignment_2.save)
frappe.db.set_single_value("HR Settings", "allow_multiple_shift_assignments", 1)
shift_assignment_2.save() # would throw error if multiple shift assignments not allowed

def test_overlapping_for_fixed_period_shift(self):
# shift should is for Fixed period if Only start_date and end_date both are present and status = Active
setup_shift_type(shift_type="Day Shift")
Expand Down
4 changes: 2 additions & 2 deletions hrms/hr/doctype/shift_type/test_shift_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -613,8 +613,8 @@ def setup_shift_type(**args):
{
"doctype": "Shift Type",
"__newname": args.shift_type or "_Test Shift",
"start_time": "08:00:00",
"end_time": "12:00:00",
"start_time": args.start_time or "08:00:00",
"end_time": args.end_time or "12:00:00",
"enable_auto_attendance": 1,
"determine_check_in_and_check_out": "Alternating entries as IN and OUT during the same shift",
"working_hours_calculation_based_on": "First Check-in and Last Check-out",
Expand Down
Loading