weekend on call shifts
This commit is contained in:
parent
aee4604fed
commit
b8ec5dbf69
|
|
@ -1529,6 +1529,18 @@ class _ScheduleGeneratorPanelState
|
||||||
startMinute: 0,
|
startMinute: 0,
|
||||||
duration: const Duration(hours: 8),
|
duration: const Duration(hours: 8),
|
||||||
);
|
);
|
||||||
|
// Weekend Saturday on_call: 5PM (17:00) to 8AM (08:00) next day = 15 hours
|
||||||
|
templates['on_call_saturday'] = _ShiftTemplate(
|
||||||
|
startHour: 17,
|
||||||
|
startMinute: 0,
|
||||||
|
duration: const Duration(hours: 15),
|
||||||
|
);
|
||||||
|
// Weekend Sunday on_call: 5PM (17:00) to 7AM (07:00) next day = 14 hours
|
||||||
|
templates['on_call_sunday'] = _ShiftTemplate(
|
||||||
|
startHour: 17,
|
||||||
|
startMinute: 0,
|
||||||
|
duration: const Duration(hours: 14),
|
||||||
|
);
|
||||||
// Default normal shift (8am-5pm = 9 hours)
|
// Default normal shift (8am-5pm = 9 hours)
|
||||||
templates['normal'] = _ShiftTemplate(
|
templates['normal'] = _ShiftTemplate(
|
||||||
startHour: 8,
|
startHour: 8,
|
||||||
|
|
@ -1684,14 +1696,7 @@ class _ScheduleGeneratorPanelState
|
||||||
final pmUserId = itStaff.isEmpty
|
final pmUserId = itStaff.isEmpty
|
||||||
? null
|
? null
|
||||||
: itStaff[pmBaseIndex % itStaff.length].id;
|
: itStaff[pmBaseIndex % itStaff.length].id;
|
||||||
final nextWeekPmUserId = itStaff.isEmpty
|
|
||||||
? null
|
|
||||||
: itStaff[(pmBaseIndex + 1) % itStaff.length].id;
|
|
||||||
final pmRelievers = _buildRelievers(pmBaseIndex, itStaff);
|
final pmRelievers = _buildRelievers(pmBaseIndex, itStaff);
|
||||||
final nextWeekRelievers = itStaff.isEmpty
|
|
||||||
? <String>[]
|
|
||||||
: _buildRelievers((pmBaseIndex + 1) % itStaff.length, itStaff);
|
|
||||||
var weekendNormalOffset = 0;
|
|
||||||
|
|
||||||
for (
|
for (
|
||||||
var day = weekStart;
|
var day = weekStart;
|
||||||
|
|
@ -1706,32 +1711,53 @@ class _ScheduleGeneratorPanelState
|
||||||
final dayIsRamadan = isApproximateRamadan(day);
|
final dayIsRamadan = isApproximateRamadan(day);
|
||||||
|
|
||||||
if (isWeekend) {
|
if (isWeekend) {
|
||||||
// Weekend: only IT Staff get normal + on_call (rotating)
|
final isSaturday = day.weekday == DateTime.saturday;
|
||||||
if (itStaff.isNotEmpty) {
|
if (isSaturday) {
|
||||||
final normalIndex =
|
// Saturday: AM person gets normal shift, PM person gets weekend on_call
|
||||||
(amBaseIndex + pmBaseIndex + weekendNormalOffset) %
|
if (amUserId != null) {
|
||||||
itStaff.length;
|
_tryAddDraft(
|
||||||
_tryAddDraft(
|
draft,
|
||||||
draft,
|
existing,
|
||||||
existing,
|
templates,
|
||||||
templates,
|
'normal',
|
||||||
'normal',
|
amUserId,
|
||||||
itStaff[normalIndex].id,
|
day,
|
||||||
day,
|
const [],
|
||||||
const [],
|
);
|
||||||
);
|
}
|
||||||
weekendNormalOffset += 1;
|
if (pmUserId != null) {
|
||||||
}
|
_tryAddDraft(
|
||||||
if (nextWeekPmUserId != null) {
|
draft,
|
||||||
_tryAddDraft(
|
existing,
|
||||||
draft,
|
templates,
|
||||||
existing,
|
'on_call_saturday',
|
||||||
templates,
|
pmUserId,
|
||||||
'on_call',
|
day,
|
||||||
nextWeekPmUserId,
|
pmRelievers,
|
||||||
day,
|
);
|
||||||
nextWeekRelievers,
|
}
|
||||||
);
|
} else {
|
||||||
|
// Sunday: PM person gets both normal and weekend on_call
|
||||||
|
if (pmUserId != null) {
|
||||||
|
_tryAddDraft(
|
||||||
|
draft,
|
||||||
|
existing,
|
||||||
|
templates,
|
||||||
|
'normal',
|
||||||
|
pmUserId,
|
||||||
|
day,
|
||||||
|
const [],
|
||||||
|
);
|
||||||
|
_tryAddDraft(
|
||||||
|
draft,
|
||||||
|
existing,
|
||||||
|
templates,
|
||||||
|
'on_call_sunday',
|
||||||
|
pmUserId,
|
||||||
|
day,
|
||||||
|
pmRelievers,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Weekday: IT Staff rotate AM/PM/on_call
|
// Weekday: IT Staff rotate AM/PM/on_call
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
-- Add weekend-specific on_call shift types for Saturday and Sunday
|
||||||
|
-- Saturday on_call: 5PM to 8AM (15 hours)
|
||||||
|
-- Sunday on_call: 5PM to 7AM (14 hours)
|
||||||
|
|
||||||
|
-- Update duty_schedules.shift_type.
|
||||||
|
-- If enum-backed, add new enum values.
|
||||||
|
-- If CHECK-backed, replace the existing CHECK constraint with expanded values.
|
||||||
|
DO $$
|
||||||
|
DECLARE
|
||||||
|
_is_enum boolean := false;
|
||||||
|
_con text;
|
||||||
|
BEGIN
|
||||||
|
SELECT (t.typtype = 'e') INTO _is_enum
|
||||||
|
FROM pg_attribute a
|
||||||
|
JOIN pg_type t ON t.oid = a.atttypid
|
||||||
|
WHERE a.attrelid = 'duty_schedules'::regclass
|
||||||
|
AND a.attname = 'shift_type'
|
||||||
|
AND NOT a.attisdropped;
|
||||||
|
|
||||||
|
IF _is_enum THEN
|
||||||
|
BEGIN
|
||||||
|
ALTER TYPE shift_type ADD VALUE IF NOT EXISTS 'on_call_saturday';
|
||||||
|
EXCEPTION WHEN undefined_object THEN
|
||||||
|
NULL;
|
||||||
|
END;
|
||||||
|
BEGIN
|
||||||
|
ALTER TYPE shift_type ADD VALUE IF NOT EXISTS 'on_call_sunday';
|
||||||
|
EXCEPTION WHEN undefined_object THEN
|
||||||
|
NULL;
|
||||||
|
END;
|
||||||
|
ELSE
|
||||||
|
FOR _con IN
|
||||||
|
SELECT con.conname
|
||||||
|
FROM pg_constraint con
|
||||||
|
JOIN pg_attribute att
|
||||||
|
ON att.attrelid = con.conrelid
|
||||||
|
AND att.attnum = ANY(con.conkey)
|
||||||
|
WHERE con.conrelid = 'duty_schedules'::regclass
|
||||||
|
AND con.contype = 'c'
|
||||||
|
AND att.attname = 'shift_type'
|
||||||
|
LOOP
|
||||||
|
EXECUTE format('ALTER TABLE duty_schedules DROP CONSTRAINT %I', _con);
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
ALTER TABLE duty_schedules
|
||||||
|
ADD CONSTRAINT duty_schedules_shift_type_check
|
||||||
|
CHECK (
|
||||||
|
shift_type IN (
|
||||||
|
'normal',
|
||||||
|
'am',
|
||||||
|
'pm',
|
||||||
|
'on_call',
|
||||||
|
'weekend',
|
||||||
|
'overtime',
|
||||||
|
'on_call_saturday',
|
||||||
|
'on_call_sunday'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
END IF;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
-- Replace attendance_logs shift_type CHECK constraint regardless of current name.
|
||||||
|
DO $$
|
||||||
|
DECLARE
|
||||||
|
_is_enum boolean := false;
|
||||||
|
_con text;
|
||||||
|
BEGIN
|
||||||
|
SELECT (t.typtype = 'e') INTO _is_enum
|
||||||
|
FROM pg_attribute a
|
||||||
|
JOIN pg_type t ON t.oid = a.atttypid
|
||||||
|
WHERE a.attrelid = 'attendance_logs'::regclass
|
||||||
|
AND a.attname = 'shift_type'
|
||||||
|
AND NOT a.attisdropped;
|
||||||
|
|
||||||
|
IF _is_enum THEN
|
||||||
|
BEGIN
|
||||||
|
ALTER TYPE shift_type ADD VALUE IF NOT EXISTS 'on_call_saturday';
|
||||||
|
EXCEPTION WHEN undefined_object THEN
|
||||||
|
NULL;
|
||||||
|
END;
|
||||||
|
BEGIN
|
||||||
|
ALTER TYPE shift_type ADD VALUE IF NOT EXISTS 'on_call_sunday';
|
||||||
|
EXCEPTION WHEN undefined_object THEN
|
||||||
|
NULL;
|
||||||
|
END;
|
||||||
|
ELSE
|
||||||
|
FOR _con IN
|
||||||
|
SELECT con.conname
|
||||||
|
FROM pg_constraint con
|
||||||
|
JOIN pg_attribute att
|
||||||
|
ON att.attrelid = con.conrelid
|
||||||
|
AND att.attnum = ANY(con.conkey)
|
||||||
|
WHERE con.conrelid = 'attendance_logs'::regclass
|
||||||
|
AND con.contype = 'c'
|
||||||
|
AND att.attname = 'shift_type'
|
||||||
|
LOOP
|
||||||
|
EXECUTE format('ALTER TABLE attendance_logs DROP CONSTRAINT %I', _con);
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
ALTER TABLE attendance_logs
|
||||||
|
ADD CONSTRAINT attendance_logs_shift_type_check
|
||||||
|
CHECK (
|
||||||
|
shift_type IN (
|
||||||
|
'normal',
|
||||||
|
'am',
|
||||||
|
'pm',
|
||||||
|
'on_call',
|
||||||
|
'weekend',
|
||||||
|
'overtime',
|
||||||
|
'on_call_saturday',
|
||||||
|
'on_call_sunday'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
END IF;
|
||||||
|
END $$;
|
||||||
Loading…
Reference in New Issue
Block a user