Let's talk
data-modelling

Booking software with nowhere to put 'until further notice'

About fifteen of a media owner's thirty-eight campaigns had no end date. Leaving the date blank would have quietly broken availability. What we did instead.

· · updated

A monitor on a desk in a quiet home office; beside it the Sazinga AdBoard booking calendar with its bars drawn to a right-hand edge.

If you sell hoardings, you know the booking that says “Long Term”. The advert stays up until the client asks for it to come down. There is no end date and no agreed term, and it is an entirely normal way to sell a board.

When we loaded a media owner’s real occupancy spreadsheet into AdBoard, about fifteen of the thirty-eight campaigns in it were on those terms, and the system had nowhere to put them. The obvious fix is to leave the end date blank. It is also the fix that quietly breaks the four things the system does most, and the risk is a board that looks free when it is not, with nothing on screen to say anything is wrong.

What was actually going on

Everything important in a booking system is a question about dates. Is this board committed on a given day? Does this booking overlap that one? Which bookings end in the next thirty days? Where does the bar on the calendar start and stop?

A blank end date turns each of those into a special case, and the special case is different every time. The overlap check has to treat blank as “goes on for ever”. The calendar has to invent a right-hand edge to draw the bar to, so the bar redraws differently every time the user scrolls. The list of bookings about to expire has to leave blanks out on purpose, otherwise it silently drops rows and looks correct while missing a whole class of them. Sorting by end date has to decide where blanks go, and “soonest to free up first” and “busiest first” want different answers.

Four places, four conventions, all invisible until one is wrong. The failure is never an error message. It is a row that does not appear.

What we changed

Two things, together, and both are needed.

A yes-or-no marker on the booking, and on each board line within it, says this one is open-ended. That is the true commercial arrangement, and it is what the screens read. The list shows “Ongoing” instead of a date, the calendar draws the bar running off the edge, and the about-to-expire list leaves it out, because a booking with no agreed end is not expiring.

And the end date holds a date far in the future, not a blank. Every date question already written keeps working untouched: the overlap check, the lookup of what covers a given day, the availability sort, the calendar layout. None of them has to learn a new rule. To the rest of the system it is simply a booking with a very long term, which is what it is commercially.

The rule that came out of it: store the value that keeps existing questions correct, and store the meaning separately for the screens that have to say it out loud. A far-future date with no marker beside it is a lie waiting to be printed on a client document. A marker with a blank beside it is four rewrites, and one will be missed.

I was wrong at first, twice. My instinct was that the far-future date was a hack and the blank the honest choice, to be handled by fixing the four questions properly. That holds only if those four are all of them. The overlap check is not a query, it is a rule with money behind it, and it is reached from creating a booking, converting a proposal, importing data and checking availability. A rule that has to be re-implemented in each of those will be re-implemented differently in one. The second mistake was putting the marker only on the booking as a whole. One campaign can hold a long-term board and two that run a fixed three months, and availability belongs to the board, so the marker has to sit on each line.

The same spreadsheet taught two more rules for values the system had no room for. A board marked as booked with no client name against it: we import the board and do not invent the booking, so missing data means fewer rows, never guessed ones. A long-term booking with no start date: here a default is fair, because the booking is certain and only its origin is unknown, so it takes the start of the current year and the record says so. The difference is whether the missing field is identity or background detail. You may default the background. You may not default who the client is.

What it did not fix

The far-future date will eventually show up in an export or a printed cost sheet if somebody adds a document that prints the raw date instead of asking the marker. Nothing prevents that today except the habit of checking for it whenever a new document template is added.

The pattern, for anyone booking anything with no end date

Before you allow a blank in a date range, list every screen and report that reads the range, and ask what a blank does in each. If the answers differ, you do not want a blank. You want a value the existing questions already understand and a marker that carries the meaning.

The same test applies to your own spreadsheet. If “Long Term” is in a column that is supposed to hold dates, the software you move to needs a place for it, or it will go missing.

Where this ends up

Long-term bookings are stored this way in Sazinga AdBoard, so availability across every structure answers the same date question whether or not a booking has an agreed end.

This came out of building Sazinga AdBoard

Every site, every booking, every invoice — in one place. The problem above is one we met while building it, and what we did about it is in the product.

If you run something like this, there is one thing you can do without a call: tell us your board count.