A plain-language guide explaining what shifts are, how they connect to employees, and what happens after the assignment is made.
A shift is like a recipe card pinned to the kitchen wall. It says "work starts at 8:00 AM, ends at 4:30 PM, with a 30-minute break." The recipe card just sits there — it does not belong to anyone yet. When you assign it to an employee for a particular day, that is when the recipe becomes their instruction for that day.
In HRSanad, a shift is a template stored in the system. It holds the following information:
| Field | What it means | Example |
|---|---|---|
| Shift Name | A label you can recognise | Morning Shift, Night Shift |
| Start Time | When work is expected to begin | 08:00 |
| End Time | When work is expected to finish | 16:30 |
| Break Minutes | Unpaid break deducted from total hours | 30 minutes |
| Grace In | How many minutes late is still acceptable at clock-in | 5 minutes |
| Grace Out | How many minutes early is still acceptable at clock-out | 5 minutes |
| Minimum Hours | The minimum hours that count as a full working day | 8 hours |
| Night Shift Flag | Marks the shift as crossing midnight — used to calculate end time correctly for night workers | Yes / No |
| OT Rate Multiplier | The pay rate applied to overtime hours worked on this shift. 1.5 = time-and-a-half; 2.0 = double time (used for public holidays). | 1.5× |
There are three database tables involved. Understanding what each one holds makes the whole system clear.
The Roster is the bridge. It is the only place where an Employee and a Shift meet on a specific date. The default_shift_id on the employee record acts as a fallback when no roster entry exists for a given day.
| Table | What it holds | Has employee_id? |
|---|---|---|
| shifts | The shift definition — times, grace, break, OT rate. Reusable template. | No |
| shift_rosters | One row per employee per day. Links an employee to a shift on a date. | Yes |
| attendance | The result after actual clock-in and clock-out data is processed against the roster. | Yes |
Go to the Time & Attendance section. Click Roster in the sidebar. This is the dedicated page for all shift assignments — it is separate from the Attendance page.
Admin Portal → Time & Attendance → RosterThe Roster page has two views. Use the toggle in the top-right corner to switch between them.
List view shows a 7-day week for one employee. Each row is one day. Use this when you want to review or edit a specific week in detail.
Calendar view shows a full month grid. Each cell is one day. Use this to get an at-a-glance picture of the whole month and to assign shifts to multiple days at once by dragging across the calendar.
Use the employee search box to find the person. You can search by name or employee code. Select one employee — the roster loads for that employee in the currently visible week or month.
In List view: navigate to the correct week using the ‹ › arrows, then find the specific day row.
In Calendar view: click a single cell to open the inline editor for that day, or click and drag across multiple days to open the range-assignment modal. Dragging selects a contiguous range of dates and assigns the same shift to all of them in one step.
The dropdown shows all active shifts defined in the system — Morning, Evening, Night, or any custom shift. You can also mark the day as a Day Off or a Public Holiday instead of assigning a shift.
Click Save (or Assign in the range modal). The system writes one row into the shift_rosters table per selected day, linking that employee, that date, and that shift. If an entry already existed for any of those dates, it is updated in place — no duplicates are ever created.
In List view you can also click Save All in the top bar to commit all pending changes for the week at once.
Once a shift is assigned to an employee for a date, the system is ready to process their attendance for that day. Here is what happens from start to finish.
If no roster entry and no default shift exist, the attendance record is still saved but without shift-based calculations. If the employee has an approved leave for that day and no swipes, the status is set to on_leave (not absent) and linked to the leave request automatically.
When the system processes a swipe, it does the following calculations using the shift times from the roster:
Imagine you manage a team of 20 people who all work the Morning Shift every weekday in April. Doing this one day at a time would mean creating 20 people × 22 working days = 440 individual entries. Instead, you fill in a simple form once: "assign Morning Shift to these 20 employees from 1 April to 30 April, skip weekends" — and the system creates all 440 entries for you in one go.
There are two ways to do a bulk assignment:
Option A — Drag in Calendar view (one employee, many days)
Open the Roster page in Calendar view, select an employee, then click and drag across multiple days to select them. Release the mouse to open the range assignment modal, choose a shift, and click Assign.
Option B — Bulk Assign panel (many employees, any date range)
On the Roster page, click the Bulk Assign Shift accordion at the top. Fill in the form:
| Field | What you fill in |
|---|---|
| Employees | Search and add one or more employees. Each appears as a tag that you can remove. |
| From Date | The first day the shift should apply |
| To Date | The last day the shift should apply |
| Assign as | Which shift template to assign, or choose Day Off / Public Holiday |
| Skip Weekends | If ticked, Saturday and Sunday are left out of the generated range |
A roster entry does not always mean a shift was worked. Two flags on every roster row control non-working days, and the attendance processor adds a third status automatically:
| Flag / Status | What it means | Effect on attendance |
|---|---|---|
| is_day_off = true | The employee is not expected to work on this date. Their scheduled weekly rest day (e.g. Friday, Saturday). | No attendance calculation. Not counted as absent. |
| is_public_holiday = true | The date is an official public holiday. The employee is not expected to work. | No attendance calculation. If they do work, any hours are treated as overtime at the holiday rate. |
| status = on_leave | The employee has an approved leave request covering this date and did not swipe in. Set automatically by the system — you do not set this manually. | Attendance record created with status on_leave, linked to the leave request. Not counted as absent. |
| shift_id set, both flags false | A normal working day with a shift assigned. | Full attendance calculation runs when swipes arrive. |
| shift_id empty, both flags false | No instruction for this employee on this date. | Attendance record is saved with no shift calculations. Will be flagged as a discrepancy. |
To prevent this, two things should be in place:
Each employee can have a Default Shift set on their Employment tab. When no explicit roster entry exists for a date, the system falls back to this default shift automatically — it does not need to be in shift_rosters. For employees who always work the same shift, this means you never need to create individual daily entries; the default handles every working day.
Admin Portal → Personnel → Edit Employee → Employment tab → Default ShiftAt the start of every month, use the Bulk Assign panel on the Roster page to create entries for all employees across all working days. This ensures every day has an explicit entry, which makes it easier to handle exceptions (day swaps, holidays, shift changes) by editing individual cells.
If you change a roster entry for a date that has already been processed (i.e. the employee has a clock-in and clock-out record), the system automatically recalculates the late minutes, early-out minutes, and overtime hours using the corrected shift times. You do not need to manually re-run the attendance processing. The attendance record is updated immediately and marked with the recalculation timestamp.
This means retrospective corrections are safe — fixing a wrong shift assignment fixes the attendance figures at the same time.
When an HR Admin or employee submits an OT request for a future date, the system automatically looks up the employee's roster entry for that date to find the shift. If no explicit roster entry exists, it falls back to the employee's default shift.
| What is stored on the OT request | Where it comes from |
|---|---|
| shift_id | Resolved automatically from shift_rosters for the OT date, or from the employee's default_shift_id |
| OT rate multiplier | Carried over from the shift's ot_rate_multiplier field. Payroll uses this when calculating OT pay — no need to enter it separately on the OT request. |
| planned_hours | Entered by the requester — how many OT hours are planned |
| actual_hours | Entered by the approver at the time of approval — what actually happened |
Once attendance records exist with accurate late minutes and overtime hours, the payroll engine reads them at month end. Here is the link:
| Attendance figure | How it affects the pay cheque |
|---|---|
| Overtime hours (ot_approved_hours) | Multiplied by the shift's OT rate multiplier and the employee's hourly rate, then added to gross pay |
| Days absent (status = absent) | Deducted from pay if the company applies a loss-of-pay rule |
| Late minutes | Can be configured to trigger a deduction after a threshold (e.g. more than 3 late events per month) |
| Days on leave (status = on_leave) | Matched against approved leave records — not treated as absent, linked by leave_request_id |
When a line manager uses Team Logging to clock in employees on their behalf, the system checks whether that manager is authorised to log for each employee. This is controlled through the Supervisor Team Members configuration.
An HR Admin must first grant the supervisor access in the Grade Settings and Access List screen. Without this, the supervisor cannot use the Team Logging feature at all.
Admin Portal → Time & Attendance → Team Logging → Access List → GrantOptionally, define an explicit list of employees the supervisor is allowed to log for. If no list is defined, the system falls back to allowing the supervisor to log for any employee in the same department.
Admin Portal → Time & Attendance → Team Logging → Access List → [Supervisor name] → Team Members| Scenario | Who can be logged |
|---|---|
| Supervisor has an explicit team member list | Only the employees in that list. Attempting to log for anyone else returns an authorisation error. |
| Supervisor has no team member list defined | Any employee in the same department as the supervisor. |
| HR Admin or Sysadmin | Any employee — no scope restriction. |
Yes. Because every roster entry is per employee per date, you can assign a different shift to the same employee on each day of the week. For example, Monday Morning Shift, Tuesday Evening Shift, Wednesday off.
Yes. A shift is a template and can be assigned to any number of employees on the same date. There is no limit to how many roster entries can point to the same shift on any given day.
Go to the Roster page, find the cell for that employee and date, and change the shift to the correct one. If attendance has already been processed for that date (the employee has a clock-in and clock-out), the system automatically recalculates the late minutes and overtime hours using the corrected shift immediately — you do not need to reprocess the swipes manually.
The system first checks whether the employee has a Default Shift set on their record (Employment tab). If yes, that shift is used for all calculations. If no default shift exists either, the attendance record is saved with zero late minutes and zero overtime — the system treats it as a full shift, which may not be accurate. This is why setting a default shift or pre-filling the monthly roster is strongly recommended.
This cannot happen with current processing. When swipes are processed, the system checks all dates in the batch for employees with approved leave but no swipes. Those employees are automatically given a status of on_leave (not absent) and their attendance record is linked to the leave request. If you see "absent" for an employee who was on approved leave, the leave request may not have been approved before the swipe batch was processed — approve the leave and re-process the batch.
Yes. The roster is searchable by shift and date. The attendance map view also shows all employees who clocked in on a date, with their shift assignment visible in the popup.
No. Once a roster entry is created for a date, it stays until you delete or change it. The roster does not expire on its own. For recurring shifts (same shift every working day), the bulk assignment tool or setting a default shift is the easiest way to keep things current.
HR Administrators and Payroll Administrators can create, edit, and delete roster entries. Line managers with supervised attendance access can log clock-in and clock-out for their team members, but they cannot change the roster (shift assignment) directly.
Switch to Calendar view on the Roster page, select an employee, and click Export Excel. The system downloads an .xlsx file for the currently displayed month containing the date, day name, shift code, shift name, start/end times, and day-off / holiday flags.
| Task | Where to go | Who can do it |
|---|---|---|
| Create a new shift template | Time & Attendance → Shifts → New Shift | HR Admin |
| Set a default shift on an employee | Personnel → Employees → Edit → Employment tab → Default Shift | HR Admin |
| Assign a shift to one employee for one day | Time & Attendance → Roster → select employee → pick date cell → choose shift → Save | HR Admin |
| Assign a shift to one employee across multiple days (drag) | Time & Attendance → Roster → Calendar view → select employee → drag across days → choose shift → Assign | HR Admin |
| Assign a shift to many employees across a date range | Time & Attendance → Roster → Bulk Assign Shift panel | HR Admin |
| Mark a day as a day off | Roster → select employee + date → choose Day Off | HR Admin |
| Mark a day as a public holiday | Roster → select employee + date → choose Public Holiday | HR Admin |
| Export roster to Excel for a month | Time & Attendance → Roster → Calendar view → Export Excel | HR Admin |
| Process swipes into attendance | Time & Attendance → Attendance → Import Swipes | HR Admin |
| Correct a processed attendance record (change shift) | Time & Attendance → Roster → change the roster entry — attendance recalculates automatically | HR Admin |
| View GPS clock-in locations on a map | Time & Attendance → Map | HR Admin |
| Grant Team Logging access to a supervisor | Time & Attendance → Team Logging → Access List → Grant | HR Admin |
| Define which employees a supervisor can log for | Time & Attendance → Team Logging → Access List → [Supervisor] → Team Members | HR Admin |
| Clock in a team member (supervised) | Time & Attendance → Team Logging | Line Manager (with access granted) |
| Submit or approve an OT request | Time & Attendance → OT Requests | Employee / HR Admin |