TL;DR
Two crews at the same address at the same hour is never a single mistake. It is a chain: something was promised outside the system, the schedule had forked, and nothing checked the person's day before the job was saved. Below is the chain, the four checks that break it, and the design decision that matters most — reporting rather than refusing.
Where they come from
Three sources, in rough order of frequency.
The fork. The week lives in a file or a whiteboard. Two people plan from two copies. The copies disagree for four hours, and four hours is enough. This is not a scheduling failure; it is a storage failure that looks like a scheduling failure, and no amount of conflict detection fixes it while there are two copies.
The promise. A customer phones. Somebody says "we can be there Thursday morning" while standing in a corridor. It goes in a notebook, or in a head. Thursday morning was already spoken for. The board never heard about either.
The agreement. A standing contract generates next Tuesday's visit overnight. Tuesday already has a one-off job on it, placed by hand in February. Nothing looked, because generation writes work orders — it does not place people on them.
Only the second and third are the software's to catch, and only after the first one is fixed. A conflict detector running against a schedule that is not the truth reports conflicts nobody has and misses the ones they do.
The check
Given a person, a start and an end, four questions.
Are they already somewhere else? A query for that person's work orders whose planned window overlaps the one being asked about. Cancelled work is excluded, because cancelled work is not work and leaving it in makes every rescheduled job look like a clash with the booking it replaced. The job currently being edited is excluded too, or moving a job by ten minutes would report it as clashing with itself.
Are they employed on that date? Employment start and end dates, checked against the day. This is the one that catches next month's leaver and the agency crew whose contract started on the 15th.
Are they down as absent? Holiday, sickness, leave or training overlapping the window.
Is it outside the hours they normally work? The weekday's working-hours rules, merged, compared with the job.
Two severities, and why the split is the whole design
The first two are errors. The second two are warnings.
That is not a UI decision about badge colour. It is a statement about what the system is allowed to conclude.
A person cannot be in two places. That is a fact about the world, and an error. A person who is not employed on the date cannot be sent, and that is a fact about the contract.
Working through a holiday is different. It happens, it is sometimes agreed, and the planner usually knows about it before the system does. Working outside your normal hours is the same. Both are worth saying out loud and neither is worth refusing.
Get the split wrong in the other direction — make everything an error — and something predictable happens. The planner who is refused does not fix the schedule. They write the job on paper. And the moment the paper exists, the schedule stops being where the truth is, which is the only thing it was ever for.
Reported, not enforced
So: an error stops the save and comes back with the clash described — which order number, which title, which planned times, so the planner can look at the other job rather than go hunting. The same request can then be sent again with an explicit override, and it will be written.
A warning never stops anything. It rides along with the successful response, because the planner still needs to see that they have just booked somebody through the second week of their holiday.
That override is not a loophole. It is the recognition that a planner regularly knows something the system cannot: that the customer moved the time and nobody updated the row, that the two addresses are in the same stairwell, that the "job" at four is a twenty-minute key handover. A system that cannot be overridden is a system that gets worked around.
The two details that make the warnings readable
Half-open overlap. A job finishing at 12:00 and a job starting at 12:00 do not collide. The comparison is start-before-other-end and end-after-other-start, not inclusive at both ends. Without it, every back-to-back day in the company reports itself as broken and the list becomes noise.
Merged working hours. Hours recorded as 08:00–12:00 and 13:00–17:00 contain no single rule covering an ordinary 09:00–15:00 job. Asking each rule in turn would flag every full day on that weekday. So the day's rules are merged first, and runs separated by sixty minutes or less are treated as one working day. A lunch break stops being a hole in the day. A genuine split shift — 06:00–10:00 and 18:00–22:00, eight hours apart — is not merged, and an afternoon job is still correctly reported as outside it.
Both of these exist for the same reason: a warning that fires on ordinary work is worse than no warning at all, because it takes the real ones down with it.
Finding the ones you already made
Catching a clash at the moment of saving only helps from the moment you start saving in the system. The board you inherited on Monday still has yesterday's mistakes in it.
So the same four checks run read-only over a date window and answer with everything wrong with the board as it stands: every assigned person on every planned job in the window, each finding tagged with the work order and the employee. Cancelled, completed and invoiced jobs are left out — a clash on work that has already happened is history, not a decision.
That is the banner at the top of the calendar. It is worth reading on a Monday morning before anything else.
What it does not check
Being explicit here, because this is the gap people assume is covered.
It does not know about drive time. Two jobs forty kilometres apart with ten minutes between them are not a clash by this definition, and nothing will tell you otherwise. Route optimisation is planned and not granted on any tier today.
It does not know about skills. You can filter the people list by skill when you assign, and the service catalogue records which skills a job needs, but assigning somebody unqualified is not refused. That judgement stays with the planner.
It does not know about vehicles, equipment or keys. If two jobs need the same lift, the schedule will not tell you.
It does not know about rest periods under a collective agreement. This is not a payroll system and will not pretend to be one.
The organisational half
None of the four checks helps with the promise made in a corridor. That is not a software problem and it is the most common cause.
The only fix that works is a rule everybody in the company agrees to: a time is not promised until it is on the board. Not "I'll check and confirm" — on the board, with a customer and an address, even as an unplaced job with no times. An unplaced job is a visible obligation. A note in somebody's head is not.
Once that holds, the four checks are worth something. Before it holds, they are checking a fiction.