Design
Preisvererbung
In diesem Kapitel erfährst du, wie das Preissystem von CampingSaaS funktioniert: Wie Preise auf zwei Ebenen definiert werden, wie Saison-Preise Vorrang haben und welche Kombination am Ende gilt.
Übersicht
CampingSaaS nutzt ein Vererbungssystem für Preise. Das bedeutet: Du musst Preise nicht für jede einzelne Parzelle separat eingeben. Stattdessen kannst du globale Grundpreise setzen und diese bei Bedarf auf Parzellen-Ebene überschreiben.
Preise können auf drei Ebenen definiert werden:
| Ebene | Wo konfigurieren | Gilt für |
|---|---|---|
| Campingplatz | Bausteine → Preise | Alle Parzellen (globale Basis) |
| Kategorie | Bausteine → Preise → Kategorie | Alle Parzellen dieser Kategorie |
| Parzelle | Parzellen → Parzelle öffnen → Tab Preise | Nur diese einzelne Parzelle |
Grundprinzip: Die spezifischere Ebene hat Vorrang. Ein Kategorie-Preis überschreibt den Campingplatz-Preis, ein Parzellen-Preis überschreibt den Kategorie-Preis.
Zusätzlich gibt es pro Ebene zwei Preistypen:
- Basis-Preis – gilt, wenn keine Saison aktiv ist (ganzjähriger Fallback)
- Saison-Preis – gilt in einem definierten Zeitraum (z.B. Hauptsaison Juli–August)
Die Vererbungshierarchie
Campingplatz (globale Basis)
└── Kategorie (Override für alle Parzellen dieser Kategorie)
└── Parzelle (Override für genau diese Parzelle)Jede Ebene kann Preise setzen oder leer lassen. Ist eine Ebene leer, wird die nächst höhere Ebene verwendet.
Tabellarische Übersicht
| Parzelle hat eigenen Preis? | Kategorie hat Preis? | Campingplatz hat Preis? | Ergebnis |
|---|---|---|---|
| ✅ Ja | beliebig | beliebig | Parzellen-Preis gilt |
| ❌ Nein | ✅ Ja | beliebig | Kategorie-Preis gilt |
| ❌ Nein | ❌ Nein | ✅ Ja | Campingplatz-Preis gilt |
| ❌ Nein | ❌ Nein | ❌ Nein | Kein Preis definiert |
Der Zwei-Schritt-Algorithmus
Für jede Preisanfrage (Kombination aus Saison und Gästekategorie/Fahrzeugtyp) wird der gültige Preis in zwei Schritten ermittelt.
Schritt 1: Saison-spezifischer Preis (höchste Priorität)
Das System durchsucht die Hierarchie von unten nach oben nach einem Saison-Preis für die aktive Saison:
- Hat die Parzelle einen eigenen Saison-Preis? → verwenden
- Hat die Kategorie einen Saison-Preis? → verwenden
- Hat der Campingplatz einen Saison-Preis? → verwenden
Wird in Schritt 1 ein Preis gefunden, ist die Auflösung abgeschlossen.
Schritt 2: Basis-Preis als Fallback
Nur wenn kein Saison-Preis gefunden wurde, wird die Hierarchie erneut von unten nach oben nach einem Basis-Preis durchsucht:
- Hat die Parzelle einen eigenen Basis-Preis? → verwenden
- Hat die Kategorie einen Basis-Preis? → verwenden
- Hat der Campingplatz einen Basis-Preis? → verwenden
Flussdiagramm: Zwei-Schritt-Auflösung
mermaid
flowchart TD
A([Preisanfrage:\nSaison + Gästekategorie]) --> B{Parzelle hat\nSaison-Preis?}
B -- Ja --> R1([Preis verwenden\nQuelle: Parzelle / Saison])
B -- Nein --> C{Kategorie hat\nSaison-Preis?}
C -- Ja --> R2([Preis verwenden\nQuelle: Kategorie / Saison])
C -- Nein --> D{Campingplatz hat\nSaison-Preis?}
D -- Ja --> R3([Preis verwenden\nQuelle: Campingplatz / Saison])
D -- Nein --> E[Schritt 2: Basis-Fallback]
E --> F{Parzelle hat\nBasis-Preis?}
F -- Ja --> R4([Preis verwenden\nQuelle: Parzelle / Basis])
F -- Nein --> G{Kategorie hat\nBasis-Preis?}
G -- Ja --> R5([Preis verwenden\nQuelle: Kategorie / Basis])
G -- Nein --> H{Campingplatz hat\nBasis-Preis?}
H -- Ja --> R6([Preis verwenden\nQuelle: Campingplatz / Basis])
H -- Nein --> R7([Kein Preis gefunden])Wichtige Regel: „Saison schlägt Basis"
Dies ist die wichtigste Eigenschaft des Algorithmus: Ein Saison-Preis auf einer höheren Ebene hat Vorrang vor einem Basis-Preis auf einer tieferen Ebene.
Wenn der Campingplatz einen Hauptsaison-Preis definiert hat, soll dieser in der Hauptsaison überall gelten – auch dann, wenn eine Parzelle nur einen allgemeinen Basis-Preis gesetzt hat und keinen eigenen Hauptsaison-Preis.
Zusammengefasst:
- Schritt 1 (Saison) wird immer vollständig durchlaufen, bevor Schritt 2 (Basis) beginnt
- Ein Saison-Preis auf Campingplatz-Ebene hat Vorrang vor einem Basis-Preis auf Parzellen-Ebene
Diagramm: Saison schlägt Basis
mermaid
flowchart LR
subgraph Szenario["Szenario: Hauptsaison aktiv"]
direction TB
CS["Campingplatz\nHauptsaison-Preis: 15 €"]
PAR["Parzelle\nNur Basis-Preis: 12 €\nKein Saison-Preis"]
end
PAR -->|"kein Saison-Preis → weiter"| CS
CS -->|"Saison-Preis gefunden!"| ERG["Ergebnis: 15 €\nvom Campingplatz"]
style ERG fill:#22c55e,color:#fff
style CS fill:#3b82f6,color:#fffDer Basis-Preis der Parzelle (12 €) wird in der Hauptsaison nicht verwendet, weil Schritt 1 bereits beim Campingplatz-Saison-Preis (15 €) erfolgreich endet.
Praxisbeispiele
Beispiel 1: Einfache Vererbung ohne Overrides
Du betreibst einen Campingplatz mit 30 Parzellen. Du möchtest einheitliche Preise setzen, die für alle gelten.
Konfiguration:
| Ebene | Preistyp | Basis-Preis | Hauptsaison |
|---|---|---|---|
| Campingplatz | Stellplatz (Grundpreis) | 12,00 € | 18,00 € |
| Campingplatz | Erwachsener | 5,00 € | 7,00 € |
| Campingplatz | Kind | 2,50 € | 3,50 € |
Alle Parzellen lassen die Preise leer (kein Override).
Ergebnis:
- Im Juli (Hauptsaison): Stellplatz 18,00 €, Erwachsener 7,00 €, Kind 3,50 €
- Im März (keine Saison aktiv): Stellplatz 12,00 €, Erwachsener 5,00 €, Kind 2,50 €
Vorteil: Eine zentrale Stelle, keine Redundanz.
Beispiel 2: Kategorie-Grundpreis für unterschiedliche Kategorien
Du hast zwei Kategorien – „Premium" und „Standard" – mit unterschiedlichen Stellplatzpreisen. Alle Parzellen einer Kategorie sollen denselben Preis haben.
Konfiguration:
| Ebene | Kategorie | Stellplatz (Basis) | Hauptsaison |
|---|---|---|---|
| Kategorie | Premium | 18,00 € | 25,00 € |
| Kategorie | Standard | 12,00 € | 16,00 € |
Alle Parzellen lassen die Preise leer und erben von ihrer Kategorie.
Ergebnis für Premium-Parzellen:
- Hauptsaison: 25,00 € (von der Kategorie)
- Außerhalb Saison: 18,00 € (von der Kategorie)
Ergebnis für Standard-Parzellen:
- Hauptsaison: 16,00 € (von der Kategorie)
- Außerhalb Saison: 12,00 € (von der Kategorie)
Vorteil: Preise nach Kategorien gestaffelt, ohne jede Parzelle einzeln zu bearbeiten.
Beispiel 3: Parzelle überschreibt Kategorie-Preis
Du hast eine Sonderparzelle (z.B. mit Seeblick), die generell teurer sein soll als die restlichen Parzellen ihrer Kategorie.
Konfiguration:
| Ebene | Stellplatz (Basis) | Hauptsaison |
|---|---|---|
| Kategorie „Standard" | 12,00 € | 18,00 € |
| Parzelle „A-01" (Seeblick) | 15,00 € | 22,00 € |
Alle anderen Parzellen lassen die Preise leer und erben von der Kategorie.
Ergebnis für Standard-Parzellen:
- Hauptsaison: 18,00 € (von der Kategorie)
- Außerhalb Saison: 12,00 € (von der Kategorie)
Ergebnis für Parzelle A-01:
- Hauptsaison: 22,00 € (von der Parzelle – überschreibt Kategorie)
- Außerhalb Saison: 15,00 € (von der Parzelle – überschreibt Kategorie)
Beispiel 4: Die „Saison schlägt Basis"-Regel in der Praxis
Du hast eine Sonderparzelle, die grundsätzlich teurer ist (höherer Basis-Preis), aber für Hauptsaison-Preise fällt die Parzelle auf den Campingplatz-Preis zurück.
Konfiguration:
| Ebene | Gästekategorie | Basis-Preis | Hauptsaison |
|---|---|---|---|
| Campingplatz | Stellplatz | 12,00 € | 20,00 € |
| Parzelle „A-01" | Stellplatz | 16,00 € | (leer) |
Auflösung im Juli (Hauptsaison aktiv):
- Schritt 1: Parzelle → kein Saison-Preis
- Schritt 1: Kategorie → kein Saison-Preis
- Schritt 1: Campingplatz → Saison-Preis 20,00 € gefunden → verwenden
Ergebnis Hauptsaison: 20,00 € (Campingplatz-Saison-Preis, NICHT 16 € Parzellen-Basis-Preis)
Auflösung im März (keine Saison aktiv):
- Schritt 1: Gesamte Hierarchie – kein Saison-Preis gefunden
- Schritt 2: Parzelle → Basis-Preis 16,00 € gefunden → verwenden
Ergebnis außerhalb Saison: 16,00 € (Parzellen-Basis-Preis)
Interpretation: Die Sonderparzelle ist außerhalb der Saison teurer (16 € statt 12 €), aber in der Hauptsaison gilt einheitlich der campingplatzweite Saison-Preis (20 €).
Möchtest du, dass die Sonderparzelle auch in der Hauptsaison teurer ist, musst du der Parzelle explizit einen Hauptsaison-Preis geben (z.B. 24,00 €).
Einfacher und Fortgeschrittener Modus
CampingSaaS bietet zwei Modi für die Preiskonfiguration:
Einfacher Modus (Standard für neue Campingplätze)
Im einfachen Modus werden nur Basispreise verwendet. Saisons können zwar angelegt werden (z.B. für Öffnungszeiten), aber saisonale Preisunterschiede werden ignoriert. Das vereinfacht die Preispflege erheblich – du legst einen Preis pro Gästekategorie fest, und fertig.
Wann ist der einfache Modus sinnvoll?
- Kleine Campingplätze mit einheitlichen Preisen über das ganze Jahr
- Campingplätze die gerade erst einrichten und später Saisonpreise ergänzen möchten
Fortgeschrittener Modus
Im fortgeschrittenen Modus stehen Basis- und Saisonpreise zur Verfügung. Du kannst für jede Saison (Hauptsaison, Nebensaison etc.) unterschiedliche Preise definieren – auf allen drei Ebenen (Campingplatz, Kategorie und Parzelle).
Umschalten
- Klicke in der Navigation auf Bausteine → Preise
- Schalte den Toggle Saisonabhängige Preise oben rechts im Seitenkopf ein oder aus
Wichtig: Beim Umschalten gehen keine Daten verloren. Bestehende Saisonpreise bleiben in der Datenbank erhalten. Im einfachen Modus werden sie lediglich nicht angezeigt und bei der Preisberechnung ignoriert. Wenn du zurück in den fortgeschrittenen Modus wechselst, sind alle Saisonpreise wieder da.
Preise konfigurieren
Campingplatz-Preise setzen
- Wechsle zum gewünschten Campingplatz
- Klicke in der Navigation auf Bausteine
- Wähle den Abschnitt Preise
- Trage die Preise für jede Gästekategorie ein – getrennt nach Basis und Saison
- Klicke auf Speichern
Hinweis: Nur Owner können Campingplatz-Preise bearbeiten.
[Screenshot: Preise-Seite unter Bausteine mit Basis- und Saison-Preisen]
Parzellen-Preise setzen
- Öffne die gewünschte Parzelle (Klick auf Pill in der Seitenleiste)
- Wechsle zum Tab Preise
- Trage nur die Preise ein, die du überschreiben möchtest
- Klicke auf Speichern
Hinweis: Mitarbeiter können Parzellen-Preise bearbeiten. Campingplatz-Preise sind Owner-only.
[Screenshot: Parzellen-Panel, Tab Preise mit Inherited-Anzeige]
Kategorie-Grundpreis
Der Kategorie-Grundpreis ist ein Übernachtungspreis, der direkt für eine Kategorie gilt – ohne Gästekategorie- oder Fahrzeugbezug. Er dient als Basis-Stellplatzpreis für alle Parzellen dieser Kategorie.
Wann ist ein Kategorie-Grundpreis sinnvoll?
- Dein Campingplatz hat mehrere Kategorien mit unterschiedlichen Preisen (z.B. Premium-Kategorie: 18,00 € / Nacht, Standard-Kategorie: 12,00 € / Nacht)
- Du willst alle Parzellen einer Kategorie einheitlich bepreisen, ohne jeden Parzellen-Preis einzeln setzen zu müssen
Vererbungskette für Kategorie-Grundpreise:
| Schritt | Was wird geprüft? | Priorität |
|---|---|---|
| 1 | Parzelle: Saison-Preis | Höchste |
| 2 | Kategorie: Saison-Preis | ↕ |
| 3 | Parzelle: Basis-Preis | ↕ |
| 4 | Kategorie: Basis-Preis | Niedrigste |
[Screenshot: Preise-Seite unter Bausteine, Kategorie-Grundpreis-Bereich]
Tipp: Wo setzt du welche Preise?
| Ziel | Empfohlene Ebene |
|---|---|
| Einheitliche Preise für alle Parzellen | Campingplatz |
| Alle Parzellen einer Kategorie sollen gleich sein | Kategorie |
| Einzelne Sonderparzelle hat abweichenden Preis | Parzelle |
| Alles gleich, nur eine Saison überschreiben | Campingplatz (Saison-Preis) |
| Bestimmte Kategorie in Saison teurer | Kategorie (Saison-Preis) |
| Bestimmte Parzelle in Saison teurer | Parzelle (Saison-Preis) |
Empfehlung: Starte mit Campingplatz-Preisen und überschreibe nur, wo nötig. Je weniger Overrides, desto einfacher ist die Pflege.
Nächste Schritte
- Saisons verwalten – Zeiträume für Saison-Preise definieren
- Parzellen konfigurieren – Individuelle Parzellen-Preise setzen
Hinweis für Entwickler: Bei Änderungen an der Preisvererbungs-Logik müssen sowohl dieses Dokument als auch die Frontend-Komponente
PriceInheritanceInfo.tsxaktualisiert werden. Sieheshared/AGENTS.md→ Abschnitt "Synchronisationspflicht".