All features

Leave

Leave nobody has to recount

Leave types matching your policy, a work schedule per employee and public holidays that cost no hours. The request form shows, live, exactly which number gets stored and why.

To your policy, not to law written in code

You define the leave types yourself: vacation, sick, unpaid, special leave, each with its own accrual, carry-over and expiry rules. No country's law is hardcoded, so you model statutory and extra-statutory days exactly as your collective agreement knows them. Sick leave is its own type and never comes off the vacation balance. Per type you also say how it belongs on the calendar — a full-day chip or an hour block — because whether an absence reads as "away today" or "away between 08:30 and 17:00" is a property of the kind of leave, not of the individual request.

The server does the math, not the browser

Every request is computed by the API, day by day; the browser only shows the result. The request form reveals, live, which number will be stored: 40 h ≈ 5 working days, with the public holiday visible at 0 h in the breakdown. Edit the request into the Christmas week and it gets cheaper on its own, because the hours are recomputed on every change.

  • Not a scheduled working day: 0 h.
  • An active public holiday: 0 h.
  • An ordinary day: the scheduled window intersected with the requested one, minus every break that falls inside it.
  • Rounding happens once, on the summed minutes.

Schedules that hang on the contract

A schedule is a week per employee: for each weekday a working block with any number of break windows inside it. A break is a window, not a duration — you don't subtract "30 minutes" from a day, you say when the break falls. The hours per week roll out of that week and are never typed in. And because a change of schedule is usually a change of contract, the week lives on the employment contract: contracts are periods with a start date, an end date or none, contract hours per week and a week of their own. A changed contract is a new row rather than an edit, so last year's leave stays priced at last year's roster, even when a request crosses a contract boundary. You set it per employee under Instellingen → Team & gebruikers (Settings → Team & users), in a three-step wizard: Contract, Werkweek, Vrije tijd. Public holidays come from a generator that derives them from Easter, so 2028 needs no code change; if you work Good Friday, you switch it off and a re-import never brings it back.

One balance, built from pots that really do expire

Statutory and extra-statutory vacation are two pots with their own accrual and their own expiry term, but the employee sees one figure: Vakantieverlof. Underneath sits the breakdown per pot, with its accrual year, what is left and when it expires. Expiry is real: a year's accrual lapses as many months after that year as you set on the type, and consumption runs by expiry date, shortest-lived pot first. That favours the employee, because nothing lapses that could have been spent. Ask for more than is left and the form warns but the request still goes through: an advance is the manager's call, the balance reads negative, and the approver sees the shortfall again on the pending list. Overlapping requests and zero-hour spans stay hard errors. Yearly entitlements are derived from the contract and recomputed on every contract change, while a manual correction is never overwritten and a closed year is never re-priced; a December cron rolls the whole staff forward.

Free time that plans itself

When someone works less than your organisation's full-time norm, that shortfall is free time: a forty-hour norm minus a thirty-six-hour contract gives four hours a week, rounded to the nearest half day. Whether it should work that way is decided per contract rather than per organisation, because both arrangements live side by side in the same agency. Then you put those days on the calendar, in one of two shapes, because two different things can be known: sometimes the arrangement is a rhythm, sometimes only the number of days. They are placed as pre-approved leave, so they simply sit on the calendar and each one can be moved or cancelled; deleting a pattern leaves the placed days alone unless you ask for the ones from today onward back. And because a balance of zero says nothing once every day has been placed (accrued then equals taken), your leave page carries the Vrije tijd card beside the balance.

  • Per contract: derive it from the norm, "already in the roster" for someone who has Friday off anyway, or an agreed number of hours no formula expresses
  • "x days a year": spread across the year on the same weekday, sliding past holidays and non-working days so the count actually lands
  • Or a fixed rhythm: every other Friday, or every Wednesday afternoon from 15:00
  • The Vrije tijd card: this year, taken, still to be planned, and the next free day
  • Plus the overhang: days that no longer fit the balance after a contract change, reported with a button to withdraw them, never silently cancelled

Approval, and the rest of the platform

Self-approval is off by default: whoever may approve is, on their own requests, an ordinary requester, and Instellingen → Verlof (Settings → Leave) restores that for a trusted approver — where there is only one approver, they may always manage themselves, because a one-person agency must not deadlock. When a schedule can't express something (four hours on a day no one was scheduled), a manager sets the hours by hand, recorded against their name. Approvers work on the Team tab beside Mijn verlof: the approval queue with the shortfall spelled out, balances and requests per employee per year, the contract hours alongside, and approve or reject across a whole selection. From there, approved leave travels into the rest of the platform on its own. Verlof is an extension module: the core of schakl. is open source (AGPL) and modules like this one run on a licence key the administrator installs under Instellingen → Licentie; when it lapses the module goes read-only and balances, schedules and requests stay readable.

  • Timesheet: approved leave appears as a row of its own and falls outside billable capacity, never counted a second time as a time entry
  • Agenda: its own feed beside the public holidays, coloured per leave type or per colleague, shown or hidden per person, and a day you drag to another date is recomputed by the server and sent back for approval where that is needed
  • Types set to "per uur" are drawn as a positioned hour block in the day and week views instead of a full-day chip
  • Google Calendar: approved leave mirrors to the employee's own calendar, all-day or timed by that same setting
  • My Day: your own balance, the approver's "goed te keuren" queue, and who is out today

Want to know more?

The documentation describes every module in detail, from installation to permissions.

The demo is on its way

The live demo isn't ready yet. We're working hard on it and are excited to share it here as soon as it's done.

Go to the docs

More features