← All posts
Scheduling

Scheduling for a Swedish service company

Five to fifty people in the field, a week that changes twice a day, and a spreadsheet that forks the moment two people open it. What a schedule has to hold before it can hold a week.

The Closepact team9 min read

TL;DR

Most scheduling software for service companies fails in the same place: it models a calendar instead of modelling a working week. A calendar has appointments. A working week has people with contracted hours, people who are off sick, a Tuesday that was promised to a customer six months ago, and a planner who knows something the system does not. This is what a schedule has to hold before it can hold a week, and what each piece costs to get wrong.

The spreadsheet is not the problem. The fork is.

Nobody schedules in a spreadsheet because they like spreadsheets. They do it because a spreadsheet lets you write anything in any cell, which is exactly what a real week demands.

The failure is not the format. It is that the file forks. Whoever has the file open has the truth, and the truth changed at seven this morning in a version somebody else has not opened. Two vans go to the same address. A customer calls to ask where the crew is, and three people give three answers.

Every property of a real scheduling system is a property that stops the fork: one board, one write, and a record of what changed. Everything below is in service of that.

Employees are not users

The first modelling decision, and the one that quietly decides your monthly bill.

A person who can be sent somewhere and a person who signs in are not the same thing. A cleaner on a two-day-a-week contract is a resource to be scheduled — they have working hours, skills, an employment start date, a colour on the board — and they may never open the software. A planner who never leaves the office is the reverse.

So employees and users are separate records, and the link between them is optional. You can put somebody on the board, give them working hours and skills, and schedule them for a year without paying for a licence. The licence is for the people who log in: the planner, the supervisor, the crews who use the field app to clock in and tick off a checklist.

This matters most for the companies that use agency staff or seasonal crews. Grounds maintenance doubles its headcount in April. You do not want the price of the schedule to double with it.

The limit that does apply is on employees, not users: 25 on the entry tier, 100 on the middle one, no limit on the top one.

Availability is two rules a day, not one

Here is the detail that decides whether anybody reads your warnings.

Working hours are recorded per weekday as a time of day — "Tuesdays, 07:00 to 16:00" — rather than as timestamps, because the rule outlives any particular Tuesday. Each rule carries an optional valid-from and valid-to, so a person who changes from four days to five in March does not have their February rewritten. When a March timesheet is questioned in June, the rules that were in force in March are still there.

The part that looks like a technicality and is not: a day can carry more than one rule. Hours of 08:00–12:00 and 13:00–17:00 are how you record a lunch break.

Now ask the obvious question — "is this 09:00 to 15:00 job inside this person's working hours?" — of each rule in turn, and the answer is no. Neither rule contains it. Every ordinary full-day job on that weekday reports itself as unusual, the planner sees a warning on everything, and within a week they stop reading warnings entirely. The double bookings further down the list go unread alongside.

So the day's rules are merged before the question is asked, and two runs separated by a gap of sixty minutes or less are read as one working day. An hour, because that is what a Swedish lunch break is recorded as when anybody records one at all. It is a threshold, not a claim about what the gap was for.

The case it still catches: hours of 06:00–10:00 and 18:00–22:00 are eight hours apart, are not merged, and an afternoon job is correctly reported as outside them. A split shift is a split shift. A lunch is not.

Absence is the other half

Working hours say when somebody is normally around. Absence says when they are not, whatever the weekly rule claims.

Four types, because four is what a service company actually distinguishes: vacation, sick, leave, training. Timestamps rather than dates, because half a day off is the common case and a plain all-day flag cannot say "leaves at two".

One asymmetry worth copying if you are building this yourself: holiday is requested, sickness is reported. The status defaults to approved and the planner rejects if they must, because the case that happens at seven in the morning is somebody phoning in sick, and a system that needs an approval before it will show the absence on the board is a system that shows the wrong board all morning.

Placing the work

Assigning somebody to a job and dragging a job to a new time are the two things a planner does all day, so each is its own action rather than a field in an edit form. Each has to answer "is this a mistake" before it writes, and a field in a form cannot.

Two side effects that save a second step nobody remembers to take. Putting somebody on a job that has a start time moves it from booked to scheduled — placing work on a person is what scheduling means. Taking the last person off a scheduled job drops it back to booked, so it reappears in the list of work still to be placed, which is the one list a planner works from.

The conflicts you get told about

Four checks, two severities.

Two are errors: the person is already on another job in that window, and the person is not employed on that date. Two are warnings: they are down as absent, and the job falls outside the hours they normally work.

Errors stop the save and come back with the clash named — which job, which order number, which times — and the planner can send the same request back with an override if they mean it. Warnings never stop anything; they ride along on the response, so the planner still finds out that they have booked somebody through their holiday.

The overlap test is half-open at both ends: a job finishing at 12:00 and one starting at 12:00 do not collide. Without that, every back-to-back day reports itself as broken.

And a person with no working-hours rules at all is never warned about. Most companies will never fill that in, and a system that warns on every booking made by anybody without a schedule is one nobody reads.

We wrote a whole post on where double bookings actually come from, because the mechanism is more interesting than the warning.

Standing agreements write themselves, forward only

A cleaning contract every other Tuesday is a rule, not forty jobs somebody types in.

The rule is an iCal RRULE, restricted to a subset the system will guarantee: daily, weekly or monthly, with an interval, with named weekdays, and with either a count or an end date. Anything outside that — "the second Tuesday of the month", a rule combining month days with weekdays — is refused with a 422 at the moment you save it, naming the part that was not understood, rather than accepted and expanded into the wrong days six months later. Nobody proof-reads a schedule that writes itself.

Generation looks forward only. A rule that started in January does not deposit six months of backdated jobs the first time it runs, because work nobody did is not work and a board full of overdue phantoms is a board nobody trusts.

And an occurrence that was cancelled stays cancelled. Somebody who deleted next Tuesday's visit meant it; having the generator put it back the following morning is exactly the behaviour that teaches an office to stop using the schedule.

Weeks start on Monday. Everywhere — in the recurrence expander, in the availability rules, in the reports.

What it does not do

Route optimisation is not built. It is listed on the top tier as planned and is deliberately not granted, so nothing in the product will reorder your day by drive time. Neither is online booking, where a customer picks a slot themselves. If you need either today, we are the wrong answer today.

The conflict check knows about time, employment dates and absence. It does not know about drive time between two addresses, about vehicles, or about whether the person is qualified for the work. You can filter the list of people by skill when you assign, and the service catalogue records which skills a job needs, but nothing refuses an unqualified assignment. The planner does that.

There is more on how to plan geography by hand in route planning for a team of five vans.

The first week

In order, because each step makes the next one useful:

  1. People, with employment dates. Fifteen minutes. The employment dates are what make the "not employed on that date" check work at all.
  2. Working hours. Two rules a day for anybody with a lunch. Skip it for the people whose hours genuinely vary; an empty rule set is read as "no opinion", not as "unavailable".
  3. Services, with duration and VAT rate. A cleaning is 25 %, a passenger transport is 6 %, and the catalogue is where that gets decided once.
  4. This week's work. Not last year's. Type in the week you are in, drag it onto people, and let the conflict check tell you what the spreadsheet was hiding.
  5. Standing agreements last. Once the board is real, turn the repeating customers into rules and let the generator fill the horizon.

Absences and skills can wait until somebody needs them. The board being correct on Monday cannot.

Further reading

Keep reading

Want to see this with your own jobs?

Book a 20-minute demo. We set up one of your own jobs before the call: a quote, a week on the schedule or an invoice.

Book a demo