Lab
Billing scheduled hours, paying worked hours
A client is billed the hours scheduled and a guard is paid the hours worked.
↓
Two figures from one shift
- InvoiceService bills a client with useScheduledHours set to true and computes a guard's pay with it set to false.
- The client is billed in full for a guard who books on fifteen minutes late, and the guard is paid from actual attendance.
- The difference is the firm's margin.
Grace and window
- Fifteen minutes of grace at book-on, none at book-off. The grace is subtracted from the lateness: booking on at 10:16 for a 10:00 start costs one minute. Leaving early is deducted from the first minute.
- The booking window is a separate rule that shares the number. The button that books a guard on works from fifteen minutes before the shift until it ends.
- Lateness within the window stays unbounded. A guard due at 10:00 who arrives at 11:20 after traffic has to be able to book on, or the record shows a shift nobody worked.
Rate snapshots
- Rates snapshot onto the shift when it is created. An invoice already sent does not change.
- The system being replaced has the rule and a fallback that breaks it. When a snapshot is null or zero, RateResolver reads the site's live rate at the moment the invoice is generated. Two invoices for the same past period, run a week apart, can differ.
- A rate change reaches every shift back to a date the caller supplies, invoiced or not.
- The redesign removes the fallback. A rate change reaches exactly the shifts not yet invoiced.
Statutory figures
- Statutory sick pay (£23.75 a day, three waiting days, a 28-week cap) and holiday accrual (12.07% of hours worked) are UK law and change every April.
- The current code holds them as literals in five and two places. They become configuration with effective dates. A past period keeps the figures that applied to it, as a shift keeps its snapshotted rate.
A wrong rate already invoiced
When a shift was created with a wrong rate and has already been invoiced, the snapshot rule forbids re-rating it. The correction is a voided invoice with the reason recorded.
Up next
A discrepancy register→