Staff — Common cases
"One person appears as two rows in Weekly Planner"
Not allowed — the planner dedupes one person = one row. If two rows appear, check:
- Does the person have
enterpriseUserId? If yes → must dedupe byenterpriseUserId. - Missing
enterpriseUserId→ dedupe byemployeeId. - Is the correct
employeeIdof the selected BU kept as the canonical resource id?
A person missing both identities is allowed to be a separate row (per
INV-ROSTER-WP-001 v3).
Real-world example: A staff member works in two BUs, and Weekly Planner shows two rows. → One row per person so scheduling is not confusing. → Dedupe by
enterpriseUserId(or the selected BU'semployeeId) → merge into one row.
"Scheduling a shift while staff is on leave"
The Create/Edit Shift popup shows the Leave read-only field when leave overlaps the shift interval. If no warning appears although leave exists:
- Check whether evaluation uses a time interval (not same-date comparison). Leave
09:00–11:00and shift10:30–12:00overlap → must show. - This field also applies to Timesheet rows and Timesheet exports.
Real-world example: A manager schedules
10:30–12:00for someone on leave09:00–11:00. → The two intervals overlap. → Show theLeaveread-only field in the popup.
"Admin leave form shows Shift tracking codes"
Wrong — the admin form create/edit/approve only shows codes with TypeId = Leave; the staff form has no Tracking Code or Notes. If the admin selector shows Shift codes → the filter is wrong.
Real-world example: While approving a leave request, the selector also shows Shift-type codes. → Only allow codes valid for leave. → Filter
TypeId = Leave, exclude Shift codes from the create/edit/approve form.
"Time slots display out of order"
- Availability slots sort by ascending start time within each weekday column, regardless of API order.
5:00 AM–9:30 AMappears before2:30 PM–6:30 PM; sort must not move a slot to another weekday.- Edit Time Slot popup templates also sort by start time.
"Timetable has two date-navigation control sets"
Page /staff/timetable must have one date/view control set; the Syncfusion ScheduleComponent header is the source of truth for prev/next/today + view switch. A second set (custom date-range selector) → redundant, remove; the range label must match the rendered grid.
"Roster shows unapproved absence"
Weekly Planner only shows approved absence (approved-only). Pending absence does not appear on the planner.
Real-world example: A staff member just submitted leave, and the manager already sees "leave" on the planner. → Only reflect approved leave so scheduling is reliable. → Pending absence stays off the planner; it appears only after approval.
"Is an unassigned shift an Open Shift?"
Only when the shift has been published. An unassigned shift that is not yet published is still an admin draft and does not show for staff to claim.
Real-world example: Admin creates Tuesday's
15:00–17:00shift but has not picked staff. → Not yet published, it is a draft. → It does not show in the staff portal; once published it enters Open Shifts.
"Two staff both claim the same Open Shift"
The claim must be single-winner: only the first staff to claim gets assigned; the other gets a conflict.
Real-world example: An and Binh both tap claim on Thursday's
07:00–09:00shift. → Avoid assigning the same shift twice. → One person getsEmployeeIdassigned; the other sees the shift is no longer claimable after refresh.
"+New Leave or Add Leave?"
The correct wording is +New Leave. If you see Add Leave → it is old and needs changing. The button opens the correct existing create-leave drawer.
"Leave drawer is cramped/hard to use on small screens"
The drawer uses one Date; Start/End Time are required and sit on the same row when the viewport is wide enough. Narrow viewport → the paired controls collapse without overlapping text, label, input, summary or action.
Real-world example: Admin creates leave on a narrow laptop. → Still sees the full time and the Save button. → The time controls wrap to a new line; the form shows no date range or
All Day.
"Is Open Leave an Open Shift?"
No. Open Shift is a published shift with no staff assigned; Open Leave is leave with no ShiftId.
Real-world example: Lan has no Wednesday shift and requests leave
13:00–15:00. → No shift to select. → Use Open Leave; do not create or claim an Open Shift.
"Open Leave overlaps a published shift"
Open Leave cannot overlap an active published shift the same day, regardless of the BU's restriction. If a shift already exists, create the leave with Shifts.
Real-world example: Nam's shift is
09:00–17:00, Open Leave13:00–15:00. → The leave interval is inside the scheduled shift. → The API blocks Open; the user selects the shift in Shifts.
"Can I create Open Leave without Availability?"
Published Shifts Only: no Open.Shifts & Availability: staff is blocked; admin gets a warning and can confirm.No Restrictions: staff is not blocked by Availability; admin outside Availability still gets a warning.
Real-world example: Mai has not declared Availability and needs Monday Open Leave. → The result depends on the BU restriction. → Blocked under
Shifts & Availability, allowed underNo Restrictions.
"Selecting multiple shifts but one candidate is invalid"
Review and Save use an atomic batch. One failing candidate means the whole batch is not written.
Real-world example: Admin selects three shifts, but the second is unpublished before Save. → Avoid two separate unintended leaves. → The server rejects the whole batch; admin reviews again.
"Pressing Save twice creates two identical Leaves"
No. An active leave duplicating the employee, Date, TimeStart and TimeEnd is blocked with SLOT_DUPLICATE. A soft-deleted leave does not block re-creating the slot.
Real-world example: Staff double-clicks Save for Leave
09:00–12:00on 18/07. → Avoid two identical requests. → The later request getsSLOT_DUPLICATE; only one active leave is saved.
"Does archiving an employee auto-disable login?"
Yes — archiving disables login in the same operation; restore does not re-enable it automatically.
- Archive sets
StatusId = ArchivedandLoginStatusId = Initialisedat the same time (applies to both Admin PortalEmployeeand Enterprise PortalEnterpriseUser). - An archived row shows the "Login Disabled" tag, never "Login Enabled".
- Restore keeps
LoginStatusIdat archive time; login is only re-enabled by an explicit action.
Real-world example: Admin archives staff Quan who has login
Approved. → Do not let a departed staff member keep login rights. → In the same operation login is set toInitialised; after restore it staysInitialiseduntil admin re-enables it manually.