Skip to content

Comparing plan with reality

A report showing every scheduled shift alongside the actual clock-in / clock-out, with a colour-coded status for each: on time, late, left early, no-show, or unscheduled. Lives behind the Reconciliation tab on the Roster page.

What it does

The roster’s planning side answers “who should be working when”. The till’s clock-in side answers “who is working now”. This page is where the two meet: for every scheduled shift in the chosen week, the system finds the closest matching clock-in/out pair, computes the difference in minutes, and labels the result.

It’s the report the manager opens on Monday morning to ask: did anyone slip last week? It’s also the source for any payroll or HR conversation — the data is exportable to a spreadsheet for sharing.

How to use it

Open Settings → Roster and tap the Reconciliation tab.

Picking the period and filters

Top of the page:

  • / / This week — navigate between weeks. The default is the current week.
  • The week’s start date is shown (“Week starting May 4, 2026”).
  • All staff dropdown — narrow to one person.
  • All departments dropdown — narrow to one department (the report keeps shifts that include that department; clock-ins without a planned shift drop out when this filter is set).
  • ⬇ CSV — download the visible rows as a spreadsheet file.

Below the controls, a small banner shows the thresholds in effect — by default, “late after 5 minutes”, “early-out under 5 minutes”, “pairing tolerance ±2 hours” — plus the venue’s time zone.

Reading the table

Each row is one event: usually a planned shift paired with an actual clock-in/out, sometimes a planned shift with nothing matched (no-show), sometimes a clock-in with no plan (unscheduled).

The columns:

  • Date — the date and start time of the planned shift, or the clock-in if there’s no plan.
  • Employee — the staff member.
  • Departments — the chips for the planned shift. Empty for unscheduled punches.
  • Planned — the shift’s start–end time in 24-hour format, or for unscheduled punches.
  • Actual — the clock-in / clock-out time, or (open) if still clocked in, or for no-shows.
  • Δin — minutes the clock-in differed from the planned start. Positive = late, negative = early. Empty for no-shows and unscheduled punches.
  • Δout — minutes the clock-out differed from the planned end. Positive = stayed longer, negative = left early. Empty for shifts still open or with no clock-out yet.
  • Status — a colour-coded badge:
    • 🟢 On time — both deltas within thresholds.
    • 🟡 Late in — clocked in more than 5 minutes after planned start.
    • 🟡 Early out — clocked out more than 5 minutes before planned end.
    • 🔴 Late + early out — both happened on the same shift.
    • 🔴 No show — planned shift, no matching clock-in.
    • Unscheduled — clock-in with no matching planned shift.
    • 🔵 Still clocked in — clocked in, hasn’t clocked out yet (in-progress shift).

Exporting

Tap the ⬇ CSV button. A spreadsheet downloads with the same columns as the on-screen table, plus the raw delta values. The file name includes the week-start date — useful when archiving by week.

The export reflects whatever filters you’ve applied (employee, department) — what you see is what you get.

What happens behind the scenes

The system runs the same matching logic the Coverage view uses, then attaches a status to each row.

The matching:

  1. Pull every planned shift in the chosen week.
  2. Pull every clock-in/out pair that started in a slightly wider window (the chosen week ± 2 hours, to catch punches that started just before the week boundary).
  3. For each shift, find the closest unconsumed clock-in from the same staff member whose start is within 2 hours of the shift’s planned start. That’s the pairing.
  4. Any clock-in not paired to a shift becomes an Unscheduled row.
  5. Any shift not paired to a clock-in becomes a No show row.

The status:

  • The system computes the difference in minutes between actual clock-in and planned start (Δin), and between actual clock-out and planned end (Δout).
  • Δin > 5 minutes → Late in.
  • Δout < −5 minutes → Early out (negative means the staff member left earlier than planned).
  • Both → Late + early out.
  • Neither, and the shift is closed → On time.
  • Open clock-out → Still clocked in (no Δout to compute yet).

The thresholds are configurable per venue. The defaults are 5 minutes either way for late / early-out, and ±2 hours for pairing. Click the Edit thresholds button next to the banner above the table to open the editor: a formal dining room might set late=2, a casual bistro late=15, and so on. Each venue keeps its own setting.

Automatic no-show alerts

Independently of opening this page, the system runs a 5-minute cron sweep that flags shifts whose start time has passed by more than the late threshold with no matching clock-in. Each flag surfaces as an amber banner on the main Roster page: ”⚠ N no-shows flagged in the last 24h”. Click the banner to see who, when, and how many minutes late. Each shift is flagged only once per 24 hours so the banner stays informative rather than noisy.

The whole report is computed on demand each time the page loads — there’s no nightly job, no cached table to refresh. Up to a 31-day window per page load (a few weeks ahead or behind), then the system asks you to narrow.

Examples

🟢 On time — Marco was scheduled 18:00–23:00 in the Kitchen on Tuesday. He clocked in at 17:58 and out at 23:01. Δin = −2, Δout = +1. Status: On time, green.

🟡 Late — Sara was scheduled 11:00–15:00 in the Dining Room on Wednesday. She clocked in at 11:09 and out at 15:00. Δin = +9, Δout = 0. Status: Late in, amber. The Δin column shows +9m in red.

🔴 Late + early out — Luca was scheduled 20:00–02:00 (overnight) in the Bar on Friday. He clocked in at 20:07 (late) and out at 01:50 (10 minutes early). Δin = +7, Δout = −10. Status: Late + early out, red. Probably worth a chat.

🔴 No show — Marco was scheduled Saturday morning Kitchen but called in sick last-minute. There’s no clock-in for that shift. Status: No show, red. The Actual column shows .

Unscheduled punch — Antonio wasn’t on the schedule for Sunday but came in to cover for someone. He clocked in at 12:30 and out at 18:00. There’s no matching planned shift, so the row appears at the bottom of the day with status Unscheduled, grey. The Departments column is empty (the system has no shift to read tags from).

🔵 Still clocked in — at the moment of opening this report, the bartender Luca clocked in two hours ago and is still at the till. His row shows planned 18:00–02:00, clocked-in 18:02, clocked-out (open). Δin = +2, Δout = empty. Status: Still clocked in, blue. Once he clocks out, the row will refresh to its final status.

⚠️ Edge case — punch on a different day’s shift A staff member’s shift was 18:00–23:00 on Tuesday, but they accidentally clocked in Wednesday at 18:01 (a clock-in lag). Because the pairing tolerance is ±2 hours, the Wednesday punch isn’t matched to the Tuesday shift — instead, Tuesday becomes a No show row, and Wednesday’s punch becomes an Unscheduled row. The manager then knows to use the time-clock edit feature on the staff page to back-date the punch correctly.

  • Coverage view — same actuals data, but aggregated as headcount per department/hour.
  • Weekly schedule — where the planned shifts come from.
  • Time clock at the till — where the actual clock-in / clock-out punches are recorded. Manager-edited corrections happen on the staff member’s profile page.