Vermietung ist Lagerbestand auf Zeit
Warum zwölf Artikel auf Lager noch lange nicht bedeuten, dass zwölf Artikel vermietet werden können.
Zwölf Funkmikrofone liegen im Lager. Sind damit auch zwölf verfügbar? Für einen klassischen Onlineshop ist die Antwort einfach. Bei einer Vermietung fehlt in dieser Frage allerdings die wichtigste Information: wann?
Ein klassischer Onlineshop kennt vor allem eine Frage: Ist Artikel X verfügbar — ja oder nein? Du hast 12 Stück auf Lager, jemand kauft 3, danach sind es noch 9. Der Bestand ist ein einzelner Zähler. Er zählt nach unten und beim Wareneingang wieder hoch. Meistens jedenfalls.
Bei einer Vermietung reicht dieser Zähler nicht. Dieselben 12 Funkmikrofone können am kommenden Wochenende vollständig gebucht, am Montag wieder frei und drei Monate später nur teilweise verfügbar sein. Entscheidend ist nicht nur, wie viele Einheiten existieren, sondern wie viele davon in einem bestimmten Zeitraum bereits gebunden sind.
Vermietung ist Lagerbestand auf Zeit. Der Bestand verschwindet dabei nicht. Aber aus einer einzelnen Zahl wird eine Funktion über die Zeit.
Warum der Zähler nicht reicht
Der naheliegende Ansatz wäre, den Lagerbestand beim Buchen zu reduzieren — genau wie beim Verkauf. Das funktioniert ungefähr bis zur ersten Rückgabe. Denn wann wird wieder hochgezählt? Beim geplanten Rückgabedatum? Bei der tatsächlichen Rückgabe? Und ist ein Artikel, dessen Buchung erst in drei Monaten beginnt, bis dahin bereits „weg“?
Deshalb verändert eine Buchung in FlexRental den physischen Bestand nicht. Stattdessen wird für jede Anfrage neu berechnet, wie viele Einheiten eines Artikels im gewünschten Zeitraum bereits gebunden sind.
-- Halb-offenes Intervall: [start, ende)
SELECT COALESCE(SUM(b.quantity), 0) AS reserved
FROM rental_booking b
WHERE b.product_id = :productId
AND b.state IN ('confirmed', 'in_use', 'pre_confirmed')
AND b.period_start < :end
AND b.period_end > :start;
Vereinfacht lautet die Rechnung anschließend: bestand - reserviert = verfügbar. Der Ausdruck start < :end AND end > :start prüft hier, ob sich zwei halb-offene Zeiträume überschneiden. Zwei Intervalle kollidieren genau dann, wenn jedes vor dem Ende des anderen beginnt. Das wirkt zunächst etwas sperrig, erspart aber eine überraschend große Sammlung kreativer Randfälle.
Halb-offen oder geschlossen? Es kommt auf die Vermietung an
Ob der letzte Tag einer Buchung bereits wieder für die nächste Buchung genutzt werden darf, ist keine rein technische Entscheidung. Sie hängt davon ab, was vermietet wird und was Start- und Enddatum fachlich bedeuten. Deshalb unterstützt FlexRental sowohl halb-offene als auch geschlossene Intervalle.
Halb-offen: Abreise und Anreise am selben Tag
Bei einer Ferienwohnung ist der Abreisetag von Gast A häufig gleichzeitig der Anreisetag von Gast B. Gast A verlässt die Wohnung am Vormittag, anschließend wird gereinigt und Gast B reist am Nachmittag an. Im Kalender stehen damit zwei Buchungen am selben Datum — fachlich ist das trotzdem keine Doppelbuchung.
Eine Buchung von Montag bis Sonntag belegt die Unterkunft bis zum Beginn des Sonntags. Eine weitere Buchung darf am Sonntag beginnen. Das Enddatum gehört nicht mehr zum belegten Intervall. Die scheinbare Doppelbelegung des Wechseltags ist gewollt.
Geschlossen: Der Rückgabetag bleibt belegt
Bei einem gemieteten Bagger kann dieselbe Logik falsch sein. Wird die Maschine von Montag bis Sonntag vermietet, steht sie am Sonntag noch auf der Baustelle oder kommt erst im Laufe des Tages zurück. Prüfung, Reinigung oder Transport folgen möglicherweise erst danach. Eine neue Buchung ab Sonntag wäre dann keine elegante Kalenderlösung, sondern tatsächlich eine Doppelbuchung.
Start- und Enddatum gehören vollständig zur Buchung. Eine Miete bis Sonntag blockiert daher auch den Sonntag; die nächste Buchung kann frühestens am Montag beginnen. Bei der Überschneidungsprüfung werden die Randwerte entsprechend mit <= und >= einbezogen.
Die Mathematik dahinter ist klein, die fachliche Wirkung groß. Ein einziges Gleichheitszeichen entscheidet im Zweifel darüber, ob ein Gast am Anreisetag vor einer bereits belegten Ferienwohnung steht oder zwei Kunden denselben Bagger erwarten. Beides fördert die Kundenbindung eher in der falschen Richtung.
Bestand ist nicht gleich Verfügbarkeit
Sobald der Zeitraum ins Spiel kommt, besteht „verfügbar“ aus mehreren Schichten:
- Physischer Bestand — wie viele Einheiten überhaupt existieren.
- Gebundene Einheiten — wie viele davon durch bestätigte oder laufende Buchungen im angefragten Zeitraum belegt sind.
- Sperrzeiten — Zeiträume für Wartung, Inventur, Messen oder Betriebsferien. Kein Kunde, trotzdem nicht verfügbar.
- Pufferzeiten — zusätzliche Zeit vor oder nach einer Miete, etwa für Reinigung, Prüfung oder Transport.
Die Verfügbarkeits-Engine legt diese Schichten über denselben Zeitstrahl und liefert am Ende eine konkrete Zahl für den angefragten Zeitraum. Nicht „normalerweise verfügbar“, nicht „müsste passen“, sondern beispielsweise: sechs Einheiten vom 14. bis 16. August.
Sperrzeiten auf mehreren Ebenen
Eine Sperrzeit kann für den gesamten Betrieb gelten, etwa während der Betriebsferien. Sie kann aber auch nur einen einzelnen Artikel betreffen, beispielsweise einen Bagger in der Werkstatt. Technisch landen beide im selben Überschneidungscheck; lediglich ihr Geltungsbereich unterscheidet sich.
public function unitsAvailable(
string $productId,
\DateTimeInterface $start,
\DateTimeInterface $end,
): int {
$stock = $this->stock->physical($productId);
$reserved = $this->bookings->reservedIn($productId, $start, $end);
$blocked = $this->blocks->appliesTo($productId, $start, $end);
if ($blocked) {
return 0; // Sperrzeit schlaegt alles
}
return max(0, $stock - $reserved);
}
Das Beispiel ist bewusst unspektakulär. Die eigentliche Stärke liegt nicht in besonders cleverem Code, sondern in klar getrennten Verantwortlichkeiten: physischer Bestand, Buchungen und Sperrzeiten lassen sich unabhängig voneinander prüfen und testen.
Was das für den Rest des Systems bedeutet
Wenn Verfügbarkeit vom Zeitraum abhängt, ist sie keine Zahl, die einmal berechnet und anschließend für immer abgeheftet werden kann. Warenkorb, Datumssuche und Administration müssen sie für das jeweils angefragte Fenster bestimmen.
Natürlich liegt der Gedanke nahe, das Ergebnis einfach zu speichern. Schließlich mögen Computer gespeicherte Antworten. Buchungen, Stornierungen, Sperrzeiten und Rückgaben haben allerdings die unangenehme Eigenschaft, diese Antworten regelmäßig veralten zu lassen.
Der einzige Bestand, der wirklich zählt, ist der Bestand im konkret angefragten Zeitraum.Grundregel der Verfügbarkeitsberechnung
Dieser Perspektivwechsel — vom Zähler zur zeitabhängigen Verfügbarkeit — bildet die Grundlage von FlexRental. Darauf bauen unter anderem der Buchungsprozess, die Datumssuche, Pufferzeiten und Saisonpreise auf. Die folgenden Beiträge nehmen diese Bausteine einzeln auseinander.
Kommentare