Barplanner Hilfe & Dokumentation
Dieses Dokument dient als umfassendes Handbuch für die Barplanner-Anwendung. Es ist in drei Hauptbereiche unterteilt: eine Anleitung für Angestellte, eine für Manager und eine technische Übersicht für interessierte Benutzer.
1. Für Angestellte
Dieser Abschnitt erklärt alle Funktionen, die Ihnen als Angestellte(r) zur Verfügung stehen, um Ihre Arbeit effizient zu organisieren.
Das Dashboard: Ihre zentrale Anlaufstelle
Nach dem Einloggen gelangen Sie direkt auf Ihr persönliches Dashboard. Es bietet Ihnen auf einen Blick alle wichtigen Informationen:
- Aktueller Standort: Falls Ihr Betrieb mehrere Standorte hat, wird hier der aktuell ausgewählte Standort angezeigt.
- Wichtige Nachrichten: Ungelesene Rundnachrichten vom Management werden hier prominent angezeigt. Klicken Sie auf die Karte, um die Nachricht zu lesen.
- Inventarübersicht: Falls das Inventarfeature aktiv ist, wird ein Schnellzugriff auf das Inventarfeature angezeigt, mit der zusätzlichen Information, ob und wie viele Artikel unter dem Sollbestand sind.
- Planung: Wenn die Manager festgelegt haben, dass die Angestellten Zugriff auf die Planungsübersicht haben, wird hier ein Schnellzugriff angezeigt. Diese Ansicht dient für Angestellte nur zur Ansicht.
- Deine Monatsarbeitszeit: Diese Karte zeigt eine Zusammenfassung Ihrer geleisteten und geplanten Stunden für den aktuellen Monat sowie die Differenz.
- Unbesetzte Schichten: Hier sehen Sie alle Schichten, die noch keinem Mitarbeiter zugewiesen sind. Wenn Sie eine dieser Schichten übernehmen möchten, klicken Sie einfach darauf.
- Anstehende Schichten: Eine Liste Ihrer bevorstehenden Schichten. Ein
Klick auf eine Schicht zeigt Details wie Kommentare zur Schicht oder zum ganzen Tag. Mit
dem Export-Button () können Sie alle
Ihre anstehenden Schichten als
.ics-Datei herunterladen und in Ihren persönlichen Kalender (z.B. Google Calendar, Apple Kalender) importieren. - Fehlende Ist-Zeiten: Erscheint, wenn Sie vergessen haben, Ihre Arbeitszeiten für eine vergangene Schicht einzutragen. Ein Klick auf die Schicht öffnet ein Fenster, in dem Sie die Zeiten nachtragen können. Dieses Feld ist nur sichtbar, wenn das Management die Ist-Zeiten über barplanner verwaltet.
Schichten übernehmen
In der Karte "Unbesetzte Schichten" können Sie verfügbare Schichten sehen.
- Klicken Sie auf eine Schicht, die Sie interessiert.
- Ein Fenster öffnet sich und zeigt die genauen Zeiten und ggf. die Position (z.B. "Theke").
- Wenn ein Kommentar zur Schicht hinterlegt ist, wird dieser ebenfalls angezeigt.
- Klicken Sie auf den grünen Haken (), um die Schicht zu übernehmen. Sie wird dann in Ihre "Anstehenden Schichten" verschoben.
Schicht abgeben und übernehmen
Mitarbeiter können anstehende Schichten zur Übernahme durch Kollegen anbieten, falls sie verhindert sind.
- Schicht abgeben: Klicken Sie im Dashboard auf eine anstehende Schicht. Dort finden Sie einen "Schicht abgeben"-Button. Geben Sie einen Grund an, um die Schicht für andere freizugeben, anschließend werden die Manager als auch ihre Kollegen über E-Mail oder Push Benachrichtigung informiert. Die Schicht bleibt Ihnen zugewiesen, bis ein Kollege sie übernimmt.
- Angebotene Schichten: Eine zur Abgabe markierte Schicht erscheint in Ihren anstehenden Schichten mit einem Warnsymbol. Gleichzeitig wird sie für alle anderen Mitarbeiter in der Liste der "Unbesetzten Schichten" sichtbar.
- Schicht übernehmen: Kollegen können eine zur Abgabe stehende Schicht aus der Liste der unbesetzten Schichten wie gewohnt übernehmen. Der ursprüngliche Mitarbeiter, der neue Mitarbeiter und die Manager werden über die erfolgreiche Übernahme benachrichtigt.
Profil und Verfügbarkeiten verwalten
Über das Menü oben rechts (Ihr Benutzersymbol) gelangen Sie zu den Einstellungen. Hier haben Sie zwei wichtige Bereiche:
a) Profil:
Hier können Sie Ihre persönlichen Daten einsehen und bearbeiten. Dazu gehören:
- Name, Geburtstag, Kontaktdaten (Telefon, E-Mail)
- Adresse, Steuer-ID, IBAN (Diese können gefüllt werden, Funktionalität hierzu kommt aber erst in kommenden Updates.)
- Sprachauswahl: Hier kannst du deine Sprache wählen. Egal auf welchem Endgerät du dich anmeldest, die Anwendung wird in der gewählten Sprache angezeigt.
- Benachrichtigungen: Im Reiter "Benachrichtigungen" können Sie festlegen, für welche Ereignisse (z.B. neue Schicht, Schichtänderung) Sie Push-Nachrichten oder E-Mails erhalten möchten.
- Sie können hier auch Ihr Passwort ändern.
- Account löschen: Sie haben die Möglichkeit, Ihren Account endgültig zu löschen. Achtung: Diese Aktion kann nicht rückgängig gemacht werden. Damit werden alle Daten gelöscht. Das beeinhaltet die gearbeiteten, als auch die anstehenden Schichten, Zeiten etc.
b) Verfügbarkeiten:
In diesem Tab teilen Sie dem Management mit, wann Sie arbeiten können. Dabei gibt es drei mögliche Status für jeden Tag:
- Grün (Verfügbar): "Ja, ich kann den ganzen Tag arbeiten."
- Rot (Nicht verfügbar): "Nein, ich kann heute gar nicht."
- Orange (Teilweise): "Ja, aber nur zu bestimmten Zeiten (oder Schichten)." (Tipp: Nutzen Sie Rechtsklick oder langes Drücken, um Zeiten einzugeben.)
Wichtig: Ihr Manager legt fest, welcher Status der "Standard" ist:
- Standard-Verfügbar (Opt-Out): Alle Tage sind erst einmal grün. Sie müssen nur die Tage rot markieren, an denen Sie nicht können (z.B. Urlaub). Das spart Zeit für Festangestellte.
- Standard-Nicht-Verfügbar (Opt-In): Alle Tage sind erst einmal rot/grau. Sie müssen aktiv die Tage grün markieren, an denen Sie arbeiten wollen. Das ist üblich für Aushilfen.
Die Seite ist in drei Reiter unterteilt:
- Mein Kalender: Hier tragen Sie Ausnahmen für konkrete Tage
ein (z.B. "Am 24.12. kann ich nicht").
- Vorrang: Was Sie hier eintragen, überschreibt immer Ihre Standardwoche ("Wiederholend").
- Bedienung: Klicken Sie auf einen Tag, um zwischen Grün und Rot zu wechseln. Für "Orange" (Teilweise) nutzen Sie einen Rechtsklick (Desktop) oder langes Drücken (Handy).
- Schichtsystem: Wenn aktiviert, können Sie bei "Teilweise" direkt Schichten wie "Früh" oder "Spät" auswählen, statt Uhrzeiten einzutippen.
- Team-Kalender: Dieser Reiter bietet eine schreibgeschützte Übersicht der Verfügbarkeiten Ihres gesamten Teams. Er dient rein zur Information und hilft Ihnen, Ihre eigene Planung mit der Ihrer Kollegen abzustimmen, ohne dass Sie jemanden direkt fragen müssen.
- Wiederholend: Dies ist der letzte Reiter, um Ihre
grundsätzliche Wochenverfügbarkeit einzutragen. Was Sie hier einstellen, gilt für alle
Wochen, in dem angegeben Zeitraum
- Beispiel: Wenn Sie jeden Montag und Dienstag frei haben, stellen Sie dies hier einmal ein. Sie müssen es dann nicht für jede Woche neu eintragen.
- Tipp: Pflegen Sie hier Ihre Standardwoche. Das spart Ihnen am meisten Zeit.
Rundnachrichten (Broadcasts)
Manager können Nachrichten an alle oder ausgewählte Mitarbeiter senden.
- Ungelesene Nachrichten: Erscheinen als Benachrichtigungskarte auf dem Dashboard. Klicken Sie darauf, um die Nachricht zu lesen und als "gelesen" zu markieren.
- Verlauf: Über den Menüpunkt "Nachrichtenverlauf" in der Hauptnavigation können Sie alle vergangenen Nachrichten einsehen.
2. Für Manager
Dieser Abschnitt behandelt die zusätzlichen Funktionen und Konfigurationsmöglichkeiten, die Managern zur Verfügung stehen, um den Betrieb zu steuern. Manager haben Zugriff auf alle Funktionen der Angestellten und zusätzlich auf die folgenden Werkzeuge.
2.1 Erste Schritte: Einrichtung des Systems
Bevor Sie mit der Schichtplanung beginnen, sollten Sie das System einmalig für Ihren Betrieb konfigurieren. Gehen Sie dazu in die Einstellungen.
1. Regeln definieren
Unter Einstellungen -> Regeln legen Sie das Grundverhalten fest. Wichtige Entscheidungen sind:
- Verfügbarkeit Standard-Modus: Legt fest, ob Mitarbeiter im Kalender standardmäßig auf Grün (Verfügbar) oder Rot (Nicht verfügbar) starten. Dies bestimmt den "Workflow" (Mögliche Arbeitstage eintragen gegen Tage eintragen, an den nicht gearbeitet werden kann).
- Schichtsystem: Wollen Sie mit festen Schichtblöcken (z.B. Früh/Spät) arbeiten? Dies erleichtert die Verfügbarkeitsabgabe für Mitarbeiter.
- Positionen: Benötigen Sie eine Unterscheidung nach Qualifikation (Bar/Service)?
- Ist-Zeiten: Sollen die tatsächlichen Arbeitszeiten erfasst werden?
2. Stammdaten anlegen
- Ladendaten (Optional): Hinterlegen Sie Name und Adresse. Dies ist kein Muss, sieht aber auf Ausdrucken und in Kalender-Exporten professioneller aus.
- Rollen: Um den Start zu erleichtern, sind Standard-Rollen (z.B. "Manager", "Angestellter") bereits angelegt. Sie können diese bearbeiten oder neue hinzufügen (z.B. "Minijobber"), um Standardlöhne und Urlaubsansprüche zu definieren.
- Benutzer & Rechte: Erstellen Sie Accounts für Ihre Mitarbeiter. Wichtig: Nur der Besitzer kann anderen Nutzern die Rolle "Manager" (und damit Zugriff auf diese Einstellungen) zuweisen.
3. Die erste Planungswoche
Wechseln Sie zur Planung. Hinweis: Welche Eingabefelder (z.B. "Position") hier sichtbar sind, hängt von den Regeln ab, die Sie in Schritt 1 aktiviert haben.
- Navigieren Sie zur gewünschten Woche.
- Klicken Sie in die Tages-Spalten, um Schichten manuell anzulegen.
- Vorlagen nutzen (Templates): Haben Sie eine perfekte Woche geplant? Nutzen Sie den Vorlagen-Manager (Icon oben rechts), um die aktuelle Woche als Template zu speichern. Sie können dieses Template später auf jede beliebige Woche anwenden, um Zeit zu sparen.
- Veröffentlichen: Wenn der Plan steht, klicken Sie auf "Woche veröffentlichen", um ihn für alle Mitarbeiter sichtbar zu machen.
Erweitertes Dashboard
Ihr Dashboard enthält zusätzliche Karten für einen schnellen Überblick:
- Wichtige Hinweise: Diese Karte fasst kritische Informationen zusammen, z.B. die Anzahl unbesetzter Schichten, fehlende Ist-Zeiten im Team oder ob für die Zukunft keine Pläne mehr veröffentlicht sind.
- Nachricht an Mitarbeiter: Ein Schnellzugriff, um eine Rundnachricht (Broadcast) an die Mitarbeiter zu senden.
- Planung: Direkter Link zur Wochen- und Schichtplanung.
- Monatsabschluss: Link zur Übersicht der Monatsgehälter und Arbeitsstunden aller Mitarbeiter.
Rundnachrichten (Broadcasts) senden
Mit dieser Funktion können Sie gezielt Nachrichten an Ihre Mitarbeiter senden.
- Klicken Sie auf dem Dashboard auf "Nachricht an Mitarbeiter" oder navigieren Sie über das Hauptmenü.
- Es öffnet sich ein Fenster, in dem Sie Ihre Nachricht verfassen können.
- Zielgruppe definieren:
- An alle senden: Die Nachricht geht an alle Mitarbeiter an allen Standorten.
- Gezielte Auswahl: Wenn "An alle senden" nicht ausgewählt ist, können Sie die Empfänger nach Standort, Positionsgruppe (Rolle) und/oder spezifischer Position filtern. So können Sie z.B. nur eine Nachricht an das Thekenpersonal eines bestimmten Standorts senden.
- Gültigkeit (optional): Sie können ein Ablaufdatum für die Nachricht festlegen.
- Klicken Sie auf Senden. Die Empfänger erhalten eine Push-Benachrichtigung (falls aktiviert) und sehen die Nachricht auf ihrem Dashboard.
Broadcast-Verlauf
Hier können alle Nachrichten, die innerhalb eines Markts versendet wurden eingesehen werden, mit den notwendigen Eckdaten um herauszufinden, ob Informationen verteilt wurden.
Schichtplanung: Der Wochenplan
Die Schichtplanung ist eine der zentralen Aufgaben für Manager. Sie finden sie über den Navigationspunkt "Planung".
- Woche auswählen: Sie können mit den Pfeiltasten zwischen den Wochen navigieren oder eine spezifische Woche über die Datumsauswahl anspringen.
- Schichten erstellen: Klicken Sie in eine leere Zelle eines Tages, um eine neue Schicht zu erstellen. Es öffnet sich ein Fenster, in dem Sie die Start- und Endzeit, die benötigte Position (falls aktiviert) und die Pausenminuten eintragen können. Sie können hier auch einen Kommentar nur für diese Schicht hinterlegen.
- Mitarbeiter zuweisen: Im selben Fenster können Sie die Schicht einem Mitarbeiter zuweisen. Das System zeigt Ihnen an, welche Mitarbeiter verfügbar sind. Wenn Sie versuchen, einen nicht verfügbaren oder bereits verplanten Mitarbeiter zuzuweisen, erhalten Sie eine Warnung, können diese aber bei Bedarf überstimmen.
- Schichten bearbeiten und löschen: Klicken Sie auf eine existierende Schicht, um sie zu bearbeiten oder über den Löschen-Button zu entfernen.
- Tageskommentar hinzufügen: Am Anfang jeder Tages-Spalte gibt es ein Kommentarfeld. Ein hier eingetragener Kommentar wird allen Mitarbeitern angezeigt, die an diesem Tag arbeiten.
- Schichtkommentar: Sie können einer spezifischen Schicht einen Kommentar hinzufügen, der dann dem zugewiesen Mitarbeiter angezeigt wird.
- Woche veröffentlichen: Solange eine Woche nicht veröffentlicht ist, sind die Schichten nur für Manager und Admins sichtbar. Sobald der Plan fertig ist, klicken Sie auf den Button "Woche veröffentlichen". Alle eingeteilten Mitarbeiter erhalten daraufhin eine Benachrichtigung (falls aktiviert) und können ihre Schichten einsehen.
Schichtübergaben verwalten
Das System unterstützt den automatischen Tausch von Schichten zwischen Mitarbeitern (Handover). Als Manager behalten Sie dabei die Kontrolle:
- Benachrichtigungen: Sie werden informiert, wenn ein Mitarbeiter eine Schicht abgeben möchte und wenn ein anderer sie übernimmt.
- Intervention: Sie können jederzeit eingreifen, indem Sie im Schichtplan die Schicht bearbeiten und manuell einem anderen Mitarbeiter zuweisen oder die Übergabe-Anfrage zurückziehen.
- Transparenz: Im Dashboard unter "Wichtige Hinweise" sehen Sie auf einen Blick, ob es offene Schichtübergaben gibt.
Einstellungen und Regeln: Das Herzstück der Verwaltung
Unter dem Menüpunkt Einstellungen können Sie fast jeden Aspekt der Anwendung für Ihren Standort konfigurieren.
a) Ladendaten
Hier verwalten Sie die Stammdaten Ihres Standorts, wie Name, Adresse und Inhaber. Diese Informationen sind optional, aber wenn gefüllt werden sie beispielsweise in Mails und auch exportierten Kalendereinträgen verwendet.
b) Rollenverwaltung
Diese funktion ist nur sichtbar, wenn in den Regeln "Schichtpositionen aktivieren" ausgewählt wurde. Sie können verschiedene "Rollen" (Positionsgruppen) anlegen, z.B. "Minijob", "Student", "Festangestellt". Für jede Rolle können Standardwerte wie Stundenlohn, Wochenstunden, Urlaubstage und ein maximales Monatsgehalt festgelegt werden. Diese Werte dienen als Vorlage, wenn Sie neue Benutzer anlegen.
c) Regeln
Dies ist die mächtigste Seite zur Konfiguration, zu finden unter Einstellungen -> Regeln. Hier legen Sie die grundlegenden Betriebsregeln fest, indem Sie die jeweiligen Schalter aktivieren oder deaktivieren.
- Verfügbarkeit Standard-Modus: Wenn aktiv ("Standardmäßig verfügbar"), startet der Kalender für alle Mitarbeiter grün. Sie tragen nur Sperrzeiten ein (Opt-Out). Wenn inaktiv, startet der Kalender rot. Sie müssen sich aktiv eintragen (Opt-In).
- Pausenregel: Wenn aktiv, können Sie automatische Pausenabzüge basierend auf der Arbeitszeit definieren (z.B. 30 Minuten Pause nach 6 Stunden Arbeit). Diese Automatik kann im Einzelfall bei der Ist-Zeiten-Erfassung manuell korrigiert werden.
- Schichtsystem: Aktiviert ein System mit vordefinierten Schichten (z.B. "Früh", "Spät", "Nacht"). Mitarbeiter können diese Schichten dann bei ihrer Verfügbarkeitsplanung auswählen, was die Planung beschleunigt.
- Mindestruhezeit-Prüfung: Wenn aktiv, warnt das System bei der Planung, falls die gesetzliche Ruhezeit (z.B. 11 Stunden) zwischen zwei Schichten eines Mitarbeiters unterschritten wird. Die Stundenzahl ist hier ebenfalls konfigurierbar.
- Öffnungszeiten
berücksichtigen: Ist diese
Option aktiv, verhindert der Planer das Erstellen von Schichten außerhalb der
definierten Öffnungszeiten. Ist sie inaktiv, dienen die Öffnungszeiten nur als visuelle
Orientierungshilfe.
- Zusatzregel: Sie können hier ebenfalls festlegen, dass Mitarbeiter nur auf den Positionen geplant werden können, die ihnen in der Benutzerverwaltung explizit zugewiesen wurden.
- Angestellte dürfen Schichtplan sehen: Steuert, ob normale Mitarbeiter den gesamten Schichtplan einsehen können oder nur ihre eigenen Schichten.
- Ist-Stunden-Erfassung aktivieren: Ein zentraler Schalter, der die gesamte Logik rund um die Erfassung von tatsächlichen Arbeitszeiten (Ist-Zeiten) aktiviert.
- Schichtpositionen aktivieren:
Aktiviert die detaillierte Planung mit
Positionen (z.B. "Theke 1", "Service A"). Wenn dies aktiv ist, erscheint der zusätzliche
Reiter "Positionen" in den Einstellungen.
- Zusatzregel: Sie können hier ebenfalls festlegen, dass Mitarbeiter nur auf den Positionen geplant werden können, die ihnen in der Benutzerverwaltung explizit zugewiesen wurden.
- Inventur-Feature aktivieren:
Mit diesem Schalter wird das gesamte
Inventur-Modul in der Anwendung sichtbar und nutzbar gemacht.
- Zusatzregel: Hier können Sie auch die Berechtigung steuern, ob jeder Mitarbeiter den Ist-Bestand ändern darf oder nur Manager.
- Reservierungssystem aktivieren: Schaltet das gesamte Reservierungs-Modul frei.
d) Positionen
Dieser Reiter ist nur sichtbar, wenn die "Schichtpositionen" in den Regeln aktiviert sind. Hier können Sie die spezifischen Positionen anlegen (z.B. "Runner", "Barista"), ihnen eine Farbe für den Plan zuweisen und eine davon als Standard definieren.
e) Öffnungszeiten & Sperrtage
Hier verwalten Sie die regulären wöchentlichen Öffnungszeiten und können über einen Kalender einzelne Tage für Reservierungen sperren (z.B. für geschlossene Gesellschaften) oder Sonderöffnungstage (z.B. an Feiertagen) anlegen. Es steuert hierbei ausschließlich das Reservierungsfeature und die Möglichkeit über eine Webseite und unsere API Reservierungen anzufragen.
f) API-Keys (Für Fortgeschrittene)
Für technische Integrationen (z.B. Einbindung des Reservierungssystems auf Ihrer Webseite) können Sie hier API-Schlüssel generieren und verwalten. Wenn Sie keine eigene Webseite anbinden möchten, können Sie diesen Bereich ignorieren.
Weitere Verwaltungsfunktionen
- Benutzerverwaltung: Hier legen Sie neue Benutzer an, weisen ihnen eine Rolle, Gehalt und einen Standort zu und können bestehende Benutzer bearbeiten oder deaktivieren.
g) Reservierungssystem
Das Reservierungssystem bietet drei zentrale Ansichten zur Verwaltung:
- Übersicht: Eine tabellarische Liste aller Reservierungen.
- Grafische Oberfläche: Der visuelle Tischplan. Hinweis: Diese Ansicht ist für große Bildschirme (PC/Tablet) optimiert und sollte für die beste Erfahrung dort genutzt werden.
- Anfragen: Hier landen neue Reservierungsanfragen, die über die API oder Webseite reinkommen und noch bestätigt werden müssen.
Webseiten-Integration (Code-Beispiel)
Um Anfragen von Ihrer eigenen Webseite zu empfangen, können Sie folgenden Code-Schnipsel nutzen (API-Key und Slug müssen angepasst werden):
Code anzeigen/ausblenden
<div class="container">
<h1>Tisch reservieren</h1>
<form id="reservationForm">
<div class="form-group">
<label for="name">Vollständiger Name:</label>
<input type="text" id="name" name="name" required>
</div>
<div class="form-group">
<label for="email">E-Mail oder Telefon:</label>
<input type="text" id="email" name="email" required>
</div>
<div class="form-group">
<label for="people">Anzahl Personen:</label>
<input type="number" id="people" name="people" min="1" required>
</div>
<div class="form-group">
<label for="date">Datum:</label>
<input type="date" id="date" name="date" required>
<div id="date-warning" class="warning-message" style="display: none;"></div>
</div>
<div class="form-group">
<label for="time">Uhrzeit:</label>
<input type="time" id="time" name="time" required>
<div id="time-warning" class="warning-message" style="display: none;"></div>
</div>
<div class="form-group">
<label for="message">Optionale Nachricht:</label>
<textarea id="message" name="message" rows="3"></textarea>
</div>
<button type="submit" id="submitBtn">Reservierung anfragen</button>
</form>
<div id="response"></div>
</div>
<script>
// --- CONFIGURATION ---
const API_KEY = 'e089cb77fc0e4788a44c241d2d5e2e8c43659a55b80c1f68ef4bc34fa6ea267f';
const BAR_GROUP_SLUG = 'test';
// --- END CONFIGURATION ---
const dateInput = document.getElementById('date');
const timeInput = document.getElementById('time');
const dateWarningDiv = document.getElementById('date-warning');
const timeWarningDiv = document.getElementById('time-warning');
const submitBtn = document.getElementById('submitBtn');
let availabilityData = {
weeklyHours: [],
blockedDays: [],
specialOpeningDays: []
};
function toYYYYMMDD(date) {
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, '0');
const d = String(date.getDate()).padStart(2, '0');
return `${y}-${m}-${d}`;
}
async function fetchAvailability() {
const apiUrl = `https://bardev.barhelper.de/api/public/${BAR_GROUP_SLUG}/reservation-config`;
try {
const response = await fetch(apiUrl, { headers: { 'X-API-Key': API_KEY } });
if (!response.ok) throw new Error('Could not fetch availability.');
const data = await response.json();
availabilityData = {
weeklyHours: data.weeklyHours,
blockedDays: data.blockedDays.map(d => ({ ...d, date: d.blocked_date.split('T')[0] })),
specialOpeningDays: data.specialOpeningDays.map(d => ({ ...d, date: d.special_date.split('T')[0] }))
};
} catch (error) {
console.error('Error fetching availability:', error);
dateWarningDiv.textContent = "Fehler beim Laden der Verfügbarkeitsdaten.";
dateWarningDiv.style.display = 'block';
}
}
function validateForm() {
dateWarningDiv.style.display = 'none';
timeWarningDiv.style.display = 'none';
submitBtn.disabled = true;
const selectedDateStr = dateInput.value;
if (!selectedDateStr) return;
// 1. Check if the day is explicitly blocked
const blockedDay = availabilityData.blockedDays.find(d => d.date === selectedDateStr);
if (blockedDay) {
dateWarningDiv.textContent = `An diesem Tag sind leider keine Reservierungen möglich. ${blockedDay.reason ? 'Grund: ' + blockedDay.reason : ''}`.trim();
dateWarningDiv.style.display = 'block';
return;
}
// 2. Check for a special opening day
const specialDay = availabilityData.specialOpeningDays.find(d => d.date === selectedDateStr);
if (specialDay) {
validateTime(specialDay.open_time, specialDay.close_time);
return;
}
// 3. Fallback to weekly opening hours
const selectedDate = new Date(`${selectedDateStr}T12:00:00`); // Use midday to avoid timezone shifts
const dayOfWeek = selectedDate.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
const weeklyRule = availabilityData.weeklyHours.find(d => d.day_of_week === dayOfWeek);
if (!weeklyRule || weeklyRule.is_closed) {
dateWarningDiv.textContent = 'An diesem Wochentag haben wir regulär geschlossen.';
dateWarningDiv.style.display = 'block';
return;
}
validateTime(weeklyRule.open_time, weeklyRule.close_time);
}
function validateTime(openTime, closeTime) {
const selectedTime = timeInput.value;
if (!selectedTime) {
submitBtn.disabled = false; // Allow submission if time is not yet selected
return;
}
if (selectedTime < openTime || selectedTime > closeTime) {
timeWarningDiv.textContent = `Bitte wählen Sie eine Uhrzeit zwischen ${openTime.slice(0, 5)} und ${closeTime.slice(0, 5)} Uhr.`;
timeWarningDiv.style.display = 'block';
submitBtn.disabled = true;
} else {
timeWarningDiv.style.display = 'none';
submitBtn.disabled = false;
}
}
document.addEventListener('DOMContentLoaded', async () => {
const today = toYYYYMMDD(new Date());
dateInput.setAttribute('min', today);
await fetchAvailability();
dateInput.addEventListener('input', validateForm);
timeInput.addEventListener('input', validateForm);
});
document.getElementById('reservationForm').addEventListener('submit', async function (event) {
event.preventDefault();
validateForm(); // Final validation before submit
if (submitBtn.disabled) {
return;
}
const responseDiv = document.getElementById('response');
responseDiv.style.display = 'none';
const formData = {
guest_name: `${this.name.value} (${this.email.value})`,
guest_count: parseInt(this.people.value, 10),
reservation_date: this.date.value,
reservation_time: this.time.value,
reservation_duration: 2, // Defaulting to 2 hours
notes: this.message.value
};
const apiUrl = `https://bardev.barhelper.de/api/public/${BAR_GROUP_SLUG}/reservations`;
try {
const response = await fetch(apiUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': API_KEY },
body: JSON.stringify(formData)
});
const result = await response.json();
if (response.ok) {
responseDiv.className = 'success';
responseDiv.textContent = 'Vielen Dank! Ihre Reservierungsanfrage wurde erfolgreich übermittelt.';
this.reset();
} else {
responseDiv.className = 'error';
responseDiv.textContent = 'Fehler: ' + (result.error || 'Reservierung konnte nicht übermittelt werden.');
}
} catch (error) {
responseDiv.className = 'error';
responseDiv.textContent = 'Ein Netzwerkfehler ist aufgetreten. Bitte versuchen Sie es später erneut.';
console.error('Fetch error:', error);
}
});
</script>
Monatsabschluss und Gehaltsübersicht
Diese Seite, erreichbar über den Navigationspunkt "Monatsabschluss", ist entscheidend für die Gehaltsabrechnung. Sie bietet eine detaillierte monatliche Zusammenfassung für alle Mitarbeiter.
- Monat auswählen: Sie können den gewünschten Monat und das Jahr auswählen, um auch vergangene Abrechnungen einzusehen.
- Detaillierte Ansicht: Pro Mitarbeiter sehen Sie eine
Aufschlüsselung von:
- Geplanten vs. tatsächlich geleisteten Arbeitsstunden.
- Automatisch berechneten Pausenminuten.
- Dem daraus resultierenden Brutto-Lohn, der auf dem im System hinterlegten Stundenlohn basiert.
Diese Übersicht dient als Grundlage für die Lohn- und Gehaltsabrechnung.
3. Technische Übersicht
Dieser Abschnitt bietet einen Einblick in die technische Architektur und die Infrastruktur des Barplanner-Projekts für technisch interessierte Benutzer.
Infrastruktur und Aufbau
- Server-Umgebung: Die Anwendung läuft auf einem Apache-Server. Das Backend ist eine Node.js-Anwendung, die mit dem Express.js-Framework aufgebaut ist.
- Frontend-Serving: Das Frontend, bestehend aus statischen HTML-, CSS- und JavaScript-Dateien, wird für die Produktion mit Vite gebündelt und optimiert. Im Betrieb wird das Frontend direkt vom Node.js/Express-Backend ausgeliefert, um eine nahtlose Einheit zu bilden.
- Hintergrundprozesse (Cron Jobs): Das System nutzt automatisierte, zeitgesteuerte Skripte (Cron Jobs) für wiederkehrende Aufgaben. Dazu gehören das Senden von Erinnerungen für fehlende Ist-Zeiten oder das Aufräumen alter Daten (z.B. Löschnachrichten nach einem Jahr).
Datenbank und Multi-Tenancy-Architektur
Das Herzstück der Anwendung ist eine MariaDB-Datenbank, die auf einem Multi-Tenant-Modell basiert. Das bedeutet, die Anwendung kann mehrere Mandanten (z.B. verschiedene Bars oder Restaurantketten) komplett voneinander getrennt auf derselben Codebasis verwalten.
- Globale Datenbank
(
barplanner_master): Es gibt eine zentrale "Master"-Datenbank. Sie enthält die Liste aller Mandanten (Bar-Gruppen) und die globalen Benutzer-Logins. Ihre Hauptaufgabe ist es, den Benutzer zu authentifizieren und ihn dem richtigen Mandanten zuzuordnen. - Mandanten-Datenbanken
(
barplanner_agent, etc.): Jeder Mandant besitzt seine eigene, separate Datenbank. In dieser Datenbank werden alle mandantenspezifischen Daten gespeichert: Schichten, Mitarbeiter des Standorts, Einstellungen, Regeln, Verfügbarkeiten etc. - Dynamische Datenbankverbindung
(
dbMiddleware.js): Die Magie der Multi-Tenancy geschieht in einer speziellen Middleware. Nach dem Login wird die Kennung des Mandanten (activeBarGroupSlug) in der Session des Benutzers gespeichert. Bei jeder nachfolgenden Anfrage an das Backend:- Die
dbMiddlewareliest dieactiveBarGroupSlugaus der Session. - Sie nutzt einen "DB Resolver", um die passende Datenbankverbindung für genau diesen Mandanten aus einem Pool von Verbindungen auszuwählen.
- Diese spezifische Datenbankverbindung wird an
das
request-Objekt (req.db) angehängt. - Alle nachfolgenden Controller und Datenbankabfragen für diese Anfrage verwenden automatisch die richtige, isolierte Datenbank des Mandanten.
- Die
Dieses Design stellt sicher, dass die Daten eines Mandanten niemals mit denen eines anderen in Berührung kommen, was für Datensicherheit und -integrität sorgt.
Sicherheit
- Authentifizierung & Sessions:
Der Zugriff auf geschützte Bereiche wird
durch ein Session-basiertes System (
express-session) geregelt. Jede Anfrage an einen geschützten Endpunkt wird von dercheckSession-Middleware geprüft. Ohne gültige Session wird der Zugriff verweigert. - Passwort-Sicherheit: Passwörter werden nicht im Klartext gespeichert. Sie werden mit einem Algorithmus gehasht, bevor sie in der Datenbank abgelegt werden.
- Rollenbasiertes Berechtigungssystem (RBAC): Die Anwendung nutzt ein feingranulares Rechtesystem. Middleware prüft bei bestimmten Aktionen, ob der Benutzer die erforderliche Berechtigungsstufe hat.
- Schutz vor SQL-Injection: Alle Datenbankabfragen werden mit parametrisierten Abfragen (Prepared Statements) ausgeführt. Das bedeutet, dass Benutzereingaben strikt von der SQL-Logik getrennt werden, wodurch SQL-Injection-Angriffe verhindert werden.
- API-Sicherheit: Die meisten API-Endpunkte sind durch die
checkSession-Middleware geschützt. Öffentliche Endpunkte (z.B. für eine Reservierungs-Website) erfordern einen API-Key zur Authentifizierung.
Technologie-Stack im Überblick
- Backend: Node.js, Express.js
- Datenbank: MariaDB
- Frontend: Pures (Vanilla) HTML, CSS und JavaScript. Es wird bewusst auf große Frontend-Frameworks wie React oder Angular verzichtet, um die Anwendung leichtgewichtig und performant zu halten.
- Build-Tool: Vite (für das Bündeln und Optimieren des Frontends)
- Icons: FontAwesome
- Push-Benachrichtigungen: Firebase Cloud Messaging (FCM)