From 118be44847901ea46f11d682087cc0697b6067a9 Mon Sep 17 00:00:00 2001 From: Kenso Grimm Date: Wed, 7 Oct 2026 14:06:11 +0000 Subject: [PATCH 1/5] Buchungskalender: PDF-Writer und Rechnungs-PDF Co-Authored-By: Claude Opus 5.5 --- server/services/unterkunft/pdf.js | 169 ++++++++++++++++++++++ server/services/unterkunft/rechnungPdf.js | 134 +++++++++++++++++ test/unterkunftPdf.test.js | 110 ++++++++++++++ 3 files changed, 413 insertions(+) create mode 100644 server/services/unterkunft/pdf.js create mode 100644 server/services/unterkunft/rechnungPdf.js create mode 100644 test/unterkunftPdf.test.js diff --git a/server/services/unterkunft/pdf.js b/server/services/unterkunft/pdf.js new file mode 100644 index 0000000..b0e0b60 --- /dev/null +++ b/server/services/unterkunft/pdf.js @@ -0,0 +1,169 @@ +// Minimaler PDF-Writer (Buchungskalender N2): Helvetica und Helvetica-Bold, WinAnsiEncoding, keine Abhaengigkeit. +// Koordinaten: Punkt, Ursprung oben links (y waechst nach unten). Ausgabe ist deterministisch. + +// Helvetica-AFM-Breiten (1/1000 em) fuer die WinAnsi-Codes 32..255 (0 = nicht definiert, wird als '?' geschrieben). +const W_NORMAL = [ + 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, + 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, + 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, + 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, + 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, + 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 0, + 556, 0, 222, 556, 333, 1000, 556, 556, 333, 1000, 667, 333, 1000, 0, 611, 0, + 0, 222, 222, 333, 333, 350, 556, 1000, 333, 1000, 500, 333, 944, 0, 500, 667, + 278, 333, 556, 556, 556, 556, 260, 556, 333, 737, 370, 556, 584, 333, 737, 333, + 400, 584, 333, 333, 333, 556, 537, 278, 333, 333, 365, 556, 834, 834, 834, 611, + 667, 667, 667, 667, 667, 667, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, + 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, + 556, 556, 556, 556, 556, 556, 889, 500, 556, 556, 556, 556, 278, 278, 278, 278, + 556, 556, 556, 556, 556, 556, 556, 584, 611, 556, 556, 556, 556, 500, 556, 500, +] +const W_FETT = [ + 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, + 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, + 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, + 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, + 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, + 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 0, + 556, 0, 278, 556, 500, 1000, 556, 556, 333, 1000, 667, 333, 1000, 0, 611, 0, + 0, 278, 278, 500, 500, 350, 556, 1000, 333, 1000, 556, 333, 944, 0, 500, 667, + 278, 333, 556, 556, 556, 556, 280, 556, 333, 737, 370, 556, 584, 333, 737, 333, + 400, 584, 333, 333, 333, 611, 556, 278, 333, 333, 365, 556, 834, 834, 834, 611, + 722, 722, 722, 722, 722, 722, 1000, 722, 667, 667, 667, 667, 278, 278, 278, 278, + 722, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667, 667, 611, + 556, 556, 556, 556, 556, 556, 889, 556, 556, 556, 556, 556, 278, 278, 278, 278, + 611, 611, 611, 611, 611, 611, 611, 584, 611, 611, 611, 611, 611, 556, 611, 556, +] + +// CP1252-Zeichen oberhalb von U+007F im Bereich 0x80..0x9F. +const CP1252 = new Map(Object.entries({ + '€': 0x80, '‚': 0x82, 'ƒ': 0x83, '„': 0x84, '…': 0x85, '†': 0x86, '‡': 0x87, 'ˆ': 0x88, '‰': 0x89, 'Š': 0x8a, + '‹': 0x8b, 'Œ': 0x8c, 'Ž': 0x8e, '‘': 0x91, '’': 0x92, '“': 0x93, '”': 0x94, '•': 0x95, '–': 0x96, '—': 0x97, + '˜': 0x98, '™': 0x99, 'š': 0x9a, '›': 0x9b, 'œ': 0x9c, 'ž': 0x9e, 'Ÿ': 0x9f, +})) + +/** Ein Zeichen als WinAnsi-Code; Unbekanntes wird '?'. */ +function code(ch) { + if (ch === '−') return 0x2d + const c = ch.codePointAt(0) + if (c === 0x0a || c === 0x0d || c === 0x09) return 0x20 + if (c >= 32 && c < 127) return c + if (c >= 160 && c <= 255) return c + return CP1252.get(ch) ?? 0x3f +} + +const bytes = (str) => Array.from(String(str ?? ''), code) +const zahl = (n) => String(Math.round(n * 100) / 100) + +export class PdfDoc { + constructor({ breite = 595.28, hoehe = 841.89 } = {}) { + this.b = breite + this.h = hoehe + this.seiten = [] + this.aktuell = null + this.seite() + } + + /** Neue Seite beginnen (und zur aktuellen machen). */ + seite() { + this.seiten.push([]) + this.aktuell = this.seiten.length - 1 + return this.aktuell + } + + /** Auf eine bestehende Seite zurueckschalten (z. B. fuer Fusszeilen). */ + aufSeite(n) { + if (!(n >= 0 && n < this.seiten.length)) throw new RangeError('Seite existiert nicht') + this.aktuell = n + } + + get seitenzahl() { + return this.seiten.length + } + + breite(str, groesse = 10, fett = false) { + const w = fett ? W_FETT : W_NORMAL + let sum = 0 + for (const c of bytes(str)) sum += w[c - 32] || w[0x3f - 32] + return (sum * groesse) / 1000 + } + + /** Text; y = Grundlinie von oben, x = linker Rand (bei rechts: rechter Rand). */ + text(x, y, str, { groesse = 10, fett = false, rechts = false } = {}) { + const bs = bytes(str) + if (bs.length === 0) return + const px = rechts ? x - this.breite(str, groesse, fett) : x + let s = '' + for (const c of bs) s += c === 0x5c || c === 0x28 || c === 0x29 ? `\\${String.fromCharCode(c)}` : String.fromCharCode(c) + this.seiten[this.aktuell].push(`BT /${fett ? 'F2' : 'F1'} ${zahl(groesse)} Tf ${zahl(px)} ${zahl(this.h - y)} Td (${s}) Tj ET`) + } + + linie(x1, y1, x2, y2, { dicke = 0.5 } = {}) { + this.seiten[this.aktuell].push(`${zahl(dicke)} w ${zahl(x1)} ${zahl(this.h - y1)} m ${zahl(x2)} ${zahl(this.h - y2)} l S`) + } + + /** Bricht an Leerzeichen um; ueberlange Woerter werden hart getrennt. */ + umbrechen(str, maxBreite, groesse = 10, fett = false) { + const zeilen = [] + for (const absatz of String(str ?? '').split(/\r?\n/)) { + let zeile = '' + for (let wort of absatz.split(/ +/).filter(Boolean)) { + const probe = zeile ? `${zeile} ${wort}` : wort + if (this.breite(probe, groesse, fett) <= maxBreite) { + zeile = probe + continue + } + if (zeile) zeilen.push(zeile) + zeile = '' + while (this.breite(wort, groesse, fett) > maxBreite && wort.length > 1) { + let n = wort.length - 1 + while (n > 1 && this.breite(wort.slice(0, n), groesse, fett) > maxBreite) n-- + zeilen.push(wort.slice(0, n)) + wort = wort.slice(n) + } + zeile = wort + } + zeilen.push(zeile) + } + return zeilen + } + + toBuffer() { + const teile = [] + const offs = [] + let len = 0 + const add = (buf) => { + const b = Buffer.isBuffer(buf) ? buf : Buffer.from(buf, 'latin1') + teile.push(b) + len += b.length + } + const obj = (nr, inhalt) => { + offs[nr] = len + add(`${nr} 0 obj\n`) + add(inhalt) + add('\nendobj\n') + } + const n = this.seiten.length + add('%PDF-1.4\n%\xe2\xe3\xcf\xd3\n') + obj(1, '<< /Type /Catalog /Pages 2 0 R >>') + const kids = this.seiten.map((_, i) => `${5 + i * 2} 0 R`).join(' ') + obj(2, `<< /Type /Pages /Kids [${kids}] /Count ${n} >>`) + obj(3, '<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >>') + obj(4, '<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >>') + this.seiten.forEach((ops, i) => { + const pn = 5 + i * 2 + obj(pn, `<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${zahl(this.b)} ${zahl(this.h)}] /Resources << /Font << /F1 3 0 R /F2 4 0 R >> >> /Contents ${pn + 1} 0 R >>`) + const strom = Buffer.from(ops.join('\n') + '\n', 'latin1') + offs[pn + 1] = len + add(`${pn + 1} 0 obj\n<< /Length ${strom.length} >>\nstream\n`) + add(strom) + add('endstream\nendobj\n') + }) + const total = 5 + n * 2 + const xref = len + add(`xref\n0 ${total}\n0000000000 65535 f \n`) + for (let i = 1; i < total; i++) add(`${String(offs[i]).padStart(10, '0')} 00000 n \n`) + add(`trailer\n<< /Size ${total} /Root 1 0 R >>\nstartxref\n${xref}\n%%EOF\n`) + return Buffer.concat(teile) + } +} diff --git a/server/services/unterkunft/rechnungPdf.js b/server/services/unterkunft/rechnungPdf.js new file mode 100644 index 0000000..9050fd2 --- /dev/null +++ b/server/services/unterkunft/rechnungPdf.js @@ -0,0 +1,134 @@ +// Rechnungs-PDF aus dem unveraenderlichen Schnappschuss ukRechnungen.inhalt (N2). Deterministisch, A4. +import { PdfDoc } from './pdf.js' +import { formatEuro } from './preis.js' +import { formatTag } from './datum.js' + +const L = 56 +const R = 595.28 - 56 +const UNTEN = 745 // Inhalt endet hier, darunter Fusszeile +const tag = (t) => (/^\d{4}-\d{2}-\d{2}$/.test(String(t ?? '')) ? formatTag(t) : String(t ?? '')) +const nz = (s) => String(s ?? '').trim() +const ortZeile = (o) => [nz(o?.plz), nz(o?.ort)].filter(Boolean).join(' ') + +export function rechnungPdf(inhalt, { art = 'rechnung', nummer = '', datum = '' } = {}) { + const i = inhalt || {} + const a = i.aussteller || {} + const e = i.empfaenger || {} + const storno = art === 'storno' + const klein = (i.steuerart || i.summen?.steuerart) === 'kleinunternehmer' + const doc = new PdfDoc() + let y + + // Absenderzeile (klein) + const absender = [nz(a.firma), nz(a.strasse), ortZeile(a)].filter(Boolean).join(' · ') + doc.text(L, 60, absender, { groesse: 7.5 }) + doc.linie(L, 64, L + 250, 64, { dicke: 0.3 }) + + // Empfaenger + const adr = [nz(e.firma), nz(e.name), nz(e.strasse), ortZeile(e), nz(e.land)].filter(Boolean) + adr.forEach((z, k) => doc.text(L, 82 + k * 13, z, { groesse: 10 })) + + // Rechts: Nummer, Datum, Leistungszeitraum + const kopf = [ + [storno ? 'Stornonummer' : 'Rechnungsnummer', nz(nummer)], + ['Datum', tag(datum)], + ['Leistungszeitraum', `${tag(i.von)} – ${tag(i.bis)}`], + ] + if (storno && i.bezugNummer) kopf.splice(1, 0, ['Zu Rechnung', nz(i.bezugNummer)]) + kopf.forEach(([k, v], n) => { + doc.text(350, 82 + n * 13, k, { groesse: 9 }) + doc.text(R, 82 + n * 13, v, { groesse: 9, fett: true, rechts: true }) + }) + + // Titel + y = 190 + doc.text(L, y, storno ? `Stornorechnung zu ${nz(i.bezugNummer)}` : 'Rechnung', { groesse: 16, fett: true }) + y += 22 + const leistung = `Beherbergung ${nz(i.unterkunft?.name)}, ${tag(i.von)}–${tag(i.bis)} (${i.naechte} ${i.naechte === 1 ? 'Nacht' : 'Nächte'}, ${i.personen} ${i.personen === 1 ? 'Person' : 'Personen'})` + for (const z of doc.umbrechen(leistung, R - L, 10)) { + doc.text(L, y, z, { groesse: 10 }) + y += 13 + } + y += 10 + + // Posten-Tabelle + const cMenge = 318 + const cUst = 362 + const cEinzel = 450 + const cBetrag = R + const textBreite = (klein ? cMenge - 30 : cUst - 40) - L - 20 + const kopfzeile = () => { + doc.text(L, y, 'Leistung', { groesse: 9, fett: true }) + doc.text(cMenge, y, 'Menge', { groesse: 9, fett: true, rechts: true }) + if (!klein) doc.text(cUst, y, 'USt', { groesse: 9, fett: true, rechts: true }) + doc.text(cEinzel, y, 'Einzelpreis', { groesse: 9, fett: true, rechts: true }) + doc.text(cBetrag, y, 'Betrag', { groesse: 9, fett: true, rechts: true }) + doc.linie(L, y + 4, R, y + 4) + y += 18 + } + kopfzeile() + for (const p of i.posten || []) { + const zeilen = doc.umbrechen(nz(p.text), textBreite, 10) + if (y + zeilen.length * 12 > UNTEN) { + doc.seite() + y = 70 + kopfzeile() + } + const betrag = Math.round(p.menge * p.einzelCent) + zeilen.forEach((z, k) => doc.text(L, y + k * 12, z, { groesse: 10 })) + doc.text(cMenge, y, String(p.menge), { groesse: 10, rechts: true }) + if (!klein) doc.text(cUst, y, `${p.ustProzent} %`, { groesse: 10, rechts: true }) + doc.text(cEinzel, y, formatEuro(p.einzelCent), { groesse: 10, rechts: true }) + doc.text(cBetrag, y, formatEuro(betrag), { groesse: 10, rechts: true }) + y += zeilen.length * 12 + 4 + } + doc.linie(L, y - 2, R, y - 2) + y += 12 + + // Summen (zusammenhaengend auf einer Seite) + const s = i.summen || {} + const zeilenSumme = [] + if (klein) { + zeilenSumme.push(['Gesamtbetrag', formatEuro(s.bruttoCent ?? 0), true]) + } else { + for (const u of s.ust || []) { + zeilenSumme.push([`Nettobetrag ${u.satz} %`, formatEuro(u.nettoCent), false]) + zeilenSumme.push([`Enthaltene USt ${u.satz} %`, formatEuro(u.steuerCent), false]) + } + zeilenSumme.push(['Gesamtbetrag (brutto)', formatEuro(s.bruttoCent ?? 0), true]) + } + const hinweis = klein ? doc.umbrechen('Gemäß § 19 UStG wird keine Umsatzsteuer berechnet.', R - L, 9) : [] + const zahlText = i.zahlart === 'online' ? 'Zahlart: Online-Zahlung' : i.zahlart === 'vorort' ? 'Zahlart: Zahlung vor Ort' : '' + const noetig = zeilenSumme.length * 14 + hinweis.length * 12 + 40 + if (y + noetig > UNTEN) { + doc.seite() + y = 70 + } + for (const [k, v, fett] of zeilenSumme) { + doc.text(cEinzel, y, k, { groesse: 10, fett, rechts: true }) + doc.text(cBetrag, y, v, { groesse: 10, fett, rechts: true }) + y += 14 + } + y += 8 + for (const z of hinweis) { + doc.text(L, y, z, { groesse: 9 }) + y += 12 + } + if (zahlText) { + y += 4 + doc.text(L, y, zahlText, { groesse: 9 }) + } + + // Fusszeile auf jeder Seite + const fuss1 = [nz(a.firma), nz(a.inhaber) && `Inh. ${nz(a.inhaber)}`, nz(a.strasse), ortZeile(a)].filter(Boolean).join(' · ') + const fuss2 = [nz(a.steuernummer) && `Steuernummer ${nz(a.steuernummer)}`, nz(a.ustId) && `USt-IdNr. ${nz(a.ustId)}`, nz(a.email), nz(a.telefon)].filter(Boolean).join(' · ') + const fuss3 = [nz(a.bank), nz(a.iban) && `IBAN ${nz(a.iban)}`, nz(a.bic) && `BIC ${nz(a.bic)}`].filter(Boolean).join(' · ') + const n = doc.seitenzahl + for (let p = 0; p < n; p++) { + doc.aufSeite(p) + doc.linie(L, 790, R, 790, { dicke: 0.3 }) + ;[fuss1, fuss2, fuss3].filter(Boolean).forEach((z, k) => doc.text(L, 802 + k * 10, z, { groesse: 7.5 })) + if (n > 1) doc.text(R, 826, `Seite ${p + 1} von ${n}`, { groesse: 7.5, rechts: true }) + } + return doc.toBuffer() +} diff --git a/test/unterkunftPdf.test.js b/test/unterkunftPdf.test.js new file mode 100644 index 0000000..07330ad --- /dev/null +++ b/test/unterkunftPdf.test.js @@ -0,0 +1,110 @@ +import { test } from 'node:test' +import assert from 'node:assert/strict' +import { PdfDoc } from '../server/services/unterkunft/pdf.js' +import { rechnungPdf } from '../server/services/unterkunft/rechnungPdf.js' + +// Buchungskalender Task 19: PDF-Writer und Rechnungs-PDF +const latin = (b) => b.toString('latin1') + +function inhalt(extra = {}) { + return { + aussteller: { firma: 'Haus Seeblick', inhaber: 'Anna Muster', strasse: 'Seestr. 1', plz: '88662', ort: 'Ueberlingen', email: 'a@x.de', telefon: '0123', steuernummer: '12/345/67890', ustId: '', iban: 'DE02 1203 0000 0000 2020 51', bic: 'BYLADEM1001', bank: 'DKB' }, + empfaenger: { name: 'Max Gast', firma: '', strasse: 'Weg 2', plz: '10115', ort: 'Berlin', land: 'Deutschland' }, + unterkunft: { name: 'Ferienwohnung Süd' }, + von: '2026-11-12', bis: '2026-11-15', naechte: 3, personen: 2, + posten: [{ text: 'Übernachtung (Frühstück), 3 Nächte', menge: 3, einzelCent: 9000, ustProzent: 7 }, { text: 'Endreinigung', menge: 1, einzelCent: 5000, ustProzent: 19 }], + summen: { bruttoCent: 32000, nettoCent: 29000, ust: [{ satz: 7, nettoCent: 25234, steuerCent: 1766 }, { satz: 19, nettoCent: 4202, steuerCent: 798 }], steuerart: 'regel' }, + steuerart: 'regel', zahlart: 'vorort', bezugNummer: '', anfrageNummer: 'A-1', ...extra, + } +} +const kleinInhalt = () => inhalt({ + steuerart: 'kleinunternehmer', + posten: [{ text: 'Übernachtung, 3 Nächte', menge: 3, einzelCent: 9000, ustProzent: 0 }], + summen: { bruttoCent: 27000, nettoCent: 27000, ust: [], steuerart: 'kleinunternehmer' }, +}) + +test('PdfDoc: Struktur, xref, Kopf und Ende', () => { + const d = new PdfDoc() + d.text(50, 50, 'Hallo') + const b = d.toBuffer() + const s = latin(b) + assert.ok(s.startsWith('%PDF-1.4')) + assert.ok(s.endsWith('%%EOF\n')) + const start = Number(/startxref\n(\d+)\n/.exec(s)[1]) + assert.equal(s.slice(start, start + 4), 'xref') + const eintraege = s.slice(start).split('\n').filter((z) => /^\d{10} 00000 n $/.test(z)) + assert.ok(eintraege.length >= 6) + eintraege.forEach((z, k) => { + const off = Number(z.slice(0, 10)) + assert.ok(s.slice(off).startsWith(`${k + 1} 0 obj`), `Objekt ${k + 1}`) + }) +}) + +test('PdfDoc: CP1252, Euro, Escaping, Minus', () => { + const d = new PdfDoc() + d.text(10, 10, 'Übernachtung ß 5 € −3 (a) \\ ☃') + const s = latin(d.toBuffer()) + assert.ok(s.includes('\xdcbernachtung \xdf 5 \x80 -3 \\(a\\) \\\\ ?')) + assert.ok(s.includes('/Encoding /WinAnsiEncoding')) +}) + +test('PdfDoc: Breiten und Umbruch', () => { + const d = new PdfDoc() + assert.equal(Math.round(d.breite('Hello', 10) * 100), 2278) + assert.ok(d.breite('Hello', 10, true) > d.breite('Hello', 10)) + const z = d.umbrechen('eins zwei drei vier fünf sechs', 60, 10) + assert.ok(z.length > 1) + z.forEach((x) => assert.ok(d.breite(x, 10) <= 60)) + assert.ok(d.umbrechen('Donaudampfschifffahrtsgesellschaft', 50, 10).length > 1) + assert.ok(d.breite('x', 10) > 0 && d.breite('€', 10) > 0) +}) + +test('Rechnung: Regelbesteuerung', () => { + const s = latin(rechnungPdf(inhalt(), { art: 'rechnung', nummer: 'RE-2026-0001', datum: '2026-11-01' })) + assert.ok(s.includes('RE-2026-0001')) + assert.ok(s.includes('Enthaltene USt 7 %')) + assert.ok(s.includes('Nettobetrag 19 %')) + assert.ok(s.includes('12.11.2026')) + assert.ok(s.includes('Beherbergung Ferienwohnung S\xfcd')) + assert.ok(s.includes('Zahlung vor Ort')) + assert.ok(!s.includes('Gem\xe4\xdf \xa7 19 UStG')) + assert.ok(s.includes('Steuernummer 12/345/67890')) + assert.ok(s.includes('IBAN')) +}) + +test('Rechnung: Kleinunternehmer und Online-Zahlung', () => { + const s = latin(rechnungPdf({ ...kleinInhalt(), zahlart: 'online' }, { art: 'rechnung', nummer: 'RE-2026-0002', datum: '2026-11-01' })) + assert.ok(s.includes('Gem\xe4\xdf \xa7 19 UStG wird keine Umsatzsteuer berechnet.')) + assert.ok(s.includes('Online-Zahlung')) + assert.ok(!s.includes('Enthaltene USt')) +}) + +test('Storno: Titel mit Bezug, negative Betraege', () => { + const neg = kleinInhalt() + neg.posten = neg.posten.map((p) => ({ ...p, einzelCent: -p.einzelCent })) + neg.summen = { ...neg.summen, bruttoCent: -27000, nettoCent: -27000 } + neg.bezugNummer = 'RE-2026-0002' + const s = latin(rechnungPdf(neg, { art: 'storno', nummer: 'RE-2026-0003', datum: '2026-11-02' })) + assert.ok(s.includes('Stornorechnung zu RE-2026-0002')) + assert.ok(s.includes('-270,00 \x80')) +}) + +test('Viele Posten: Seitenumbruch', () => { + const posten = Array.from({ length: 40 }, (_, k) => ({ text: `Posten ${k + 1}`, menge: 1, einzelCent: 1000, ustProzent: 0 })) + const s = latin(rechnungPdf({ ...kleinInhalt(), posten }, { art: 'rechnung', nummer: 'RE-2026-0004', datum: '2026-11-01' })) + assert.ok(s.includes('/Count 2')) + assert.ok(s.includes('Seite 2 von 2')) +}) + +test('Deterministisch', () => { + const o = { art: 'rechnung', nummer: 'RE-2026-0001', datum: '2026-11-01' } + assert.ok(rechnungPdf(inhalt(), o).equals(rechnungPdf(inhalt(), o))) +}) + +test('Beispiel-PDF schreiben (nur wenn Zielordner existiert)', async () => { + const { mkdirSync, writeFileSync } = await import('node:fs') + const dir = '/root/reports/buchungskalender-2026-10-07' + if (process.env.UK_BEISPIEL_PDF !== '1') return + mkdirSync(dir, { recursive: true }) + writeFileSync(`${dir}/beispiel-rechnung.pdf`, rechnungPdf(inhalt(), { art: 'rechnung', nummer: 'RE-2026-0001', datum: '2026-11-01' })) +}) From e15486263ff97fbbcd8ed118c4508e3db73e4c13 Mon Sep 17 00:00:00 2001 From: Kenso Grimm Date: Wed, 7 Oct 2026 14:12:47 +0000 Subject: [PATCH 2/5] =?UTF-8?q?Buchungskalender:=20Mails=20an=20G=C3=A4ste?= =?UTF-8?q?,=20Vermieter=20und=20Team?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- .../G16 Buchungsanfrage eingegangen.html | 52 ++++++ .../G17 Buchungsanfrage freigegeben.html | 61 +++++++ .../G18 Buchungsanfrage abgelehnt.html | 56 ++++++ .../G19 Buchungsbestätigung.html | 61 +++++++ .../G20 Zahlung eingegangen (Unterkunft).html | 54 ++++++ .../G21 Reservierung abgelaufen.html | 52 ++++++ .../mail-templates/G22 Buchung storniert.html | 58 ++++++ .../K31 Neue Buchungsanfrage.html | 55 ++++++ server/mail-templates/K32 Neue Buchung.html | 54 ++++++ .../K33 Kalenderabgleich fehlgeschlagen.html | 48 +++++ .../K34 Anfrage Buchungskalender.html | 55 ++++++ .../T22 Neue Anfrage Buchungskalender.html | 55 ++++++ server/services/mailer.js | 5 +- server/services/termine/outbox.js | 37 ++++ server/services/unterkunft/mails.js | 171 +++++++++++++++++- test/mailTemplates.test.js | 76 +++++++- test/termineOutbox.test.js | 38 +++- test/unterkunftMails.test.js | 113 ++++++++++++ 18 files changed, 1095 insertions(+), 6 deletions(-) create mode 100644 server/mail-templates/G16 Buchungsanfrage eingegangen.html create mode 100644 server/mail-templates/G17 Buchungsanfrage freigegeben.html create mode 100644 server/mail-templates/G18 Buchungsanfrage abgelehnt.html create mode 100644 server/mail-templates/G19 Buchungsbestätigung.html create mode 100644 server/mail-templates/G20 Zahlung eingegangen (Unterkunft).html create mode 100644 server/mail-templates/G21 Reservierung abgelaufen.html create mode 100644 server/mail-templates/G22 Buchung storniert.html create mode 100644 server/mail-templates/K31 Neue Buchungsanfrage.html create mode 100644 server/mail-templates/K32 Neue Buchung.html create mode 100644 server/mail-templates/K33 Kalenderabgleich fehlgeschlagen.html create mode 100644 server/mail-templates/K34 Anfrage Buchungskalender.html create mode 100644 server/mail-templates/T22 Neue Anfrage Buchungskalender.html create mode 100644 test/unterkunftMails.test.js diff --git a/server/mail-templates/G16 Buchungsanfrage eingegangen.html b/server/mail-templates/G16 Buchungsanfrage eingegangen.html new file mode 100644 index 0000000..9210e44 --- /dev/null +++ b/server/mail-templates/G16 Buchungsanfrage eingegangen.html @@ -0,0 +1,52 @@ + + + + + + + + +Ihre Buchungsanfrage bei {{firma}} ist eingegangen + + + + + + + + + diff --git a/server/mail-templates/G17 Buchungsanfrage freigegeben.html b/server/mail-templates/G17 Buchungsanfrage freigegeben.html new file mode 100644 index 0000000..5d87eaf --- /dev/null +++ b/server/mail-templates/G17 Buchungsanfrage freigegeben.html @@ -0,0 +1,61 @@ + + + + + + + + +Ihre Buchungsanfrage {{nummer}} bei {{firma}}: jetzt buchen + + + + + + + + + diff --git a/server/mail-templates/G18 Buchungsanfrage abgelehnt.html b/server/mail-templates/G18 Buchungsanfrage abgelehnt.html new file mode 100644 index 0000000..ecd2b09 --- /dev/null +++ b/server/mail-templates/G18 Buchungsanfrage abgelehnt.html @@ -0,0 +1,56 @@ + + + + + + + + +Zu Ihrer Buchungsanfrage {{nummer}} bei {{firma}} + + + + + + + + + diff --git a/server/mail-templates/G19 Buchungsbestätigung.html b/server/mail-templates/G19 Buchungsbestätigung.html new file mode 100644 index 0000000..17c03d2 --- /dev/null +++ b/server/mail-templates/G19 Buchungsbestätigung.html @@ -0,0 +1,61 @@ + + + + + + + + +Ihre Buchung {{nummer}} bei {{firma}} ist bestätigt + + + + + + + + + diff --git a/server/mail-templates/G20 Zahlung eingegangen (Unterkunft).html b/server/mail-templates/G20 Zahlung eingegangen (Unterkunft).html new file mode 100644 index 0000000..1724a88 --- /dev/null +++ b/server/mail-templates/G20 Zahlung eingegangen (Unterkunft).html @@ -0,0 +1,54 @@ + + + + + + + + +Zahlung zu Ihrer Buchung {{nummer}} eingegangen + + + + + + + + + diff --git a/server/mail-templates/G21 Reservierung abgelaufen.html b/server/mail-templates/G21 Reservierung abgelaufen.html new file mode 100644 index 0000000..815f65b --- /dev/null +++ b/server/mail-templates/G21 Reservierung abgelaufen.html @@ -0,0 +1,52 @@ + + + + + + + + +Ihre Reservierung {{nummer}} bei {{firma}} ist abgelaufen + + + + + + + + + diff --git a/server/mail-templates/G22 Buchung storniert.html b/server/mail-templates/G22 Buchung storniert.html new file mode 100644 index 0000000..192fdbf --- /dev/null +++ b/server/mail-templates/G22 Buchung storniert.html @@ -0,0 +1,58 @@ + + + + + + + + +Ihre Buchung {{nummer}} bei {{firma}} wurde storniert + + + + + + + + + diff --git a/server/mail-templates/K31 Neue Buchungsanfrage.html b/server/mail-templates/K31 Neue Buchungsanfrage.html new file mode 100644 index 0000000..5a7460a --- /dev/null +++ b/server/mail-templates/K31 Neue Buchungsanfrage.html @@ -0,0 +1,55 @@ + + + + + + + + +Neue Buchungsanfrage {{nummer}} für {{unterkunft}} + + + + + + + + + diff --git a/server/mail-templates/K32 Neue Buchung.html b/server/mail-templates/K32 Neue Buchung.html new file mode 100644 index 0000000..e7225c6 --- /dev/null +++ b/server/mail-templates/K32 Neue Buchung.html @@ -0,0 +1,54 @@ + + + + + + + + +Neue Buchung {{nummer}} für {{unterkunft}} + + + + + + + + + diff --git a/server/mail-templates/K33 Kalenderabgleich fehlgeschlagen.html b/server/mail-templates/K33 Kalenderabgleich fehlgeschlagen.html new file mode 100644 index 0000000..afae82c --- /dev/null +++ b/server/mail-templates/K33 Kalenderabgleich fehlgeschlagen.html @@ -0,0 +1,48 @@ + + + + + + + + +Der Kalenderabgleich für {{unterkunft}} funktioniert nicht + + + + + + + + + diff --git a/server/mail-templates/K34 Anfrage Buchungskalender.html b/server/mail-templates/K34 Anfrage Buchungskalender.html new file mode 100644 index 0000000..9eaf2de --- /dev/null +++ b/server/mail-templates/K34 Anfrage Buchungskalender.html @@ -0,0 +1,55 @@ + + + + + + + + +Deine Anfrage zum Buchungskalender für {{projekt}} + + + + + + + + + diff --git a/server/mail-templates/T22 Neue Anfrage Buchungskalender.html b/server/mail-templates/T22 Neue Anfrage Buchungskalender.html new file mode 100644 index 0000000..aae109e --- /dev/null +++ b/server/mail-templates/T22 Neue Anfrage Buchungskalender.html @@ -0,0 +1,55 @@ + + + + + + + + +[Buchungskalender] Neue Anfrage: {{kunde_name}} + + + + + + + + + diff --git a/server/services/mailer.js b/server/services/mailer.js index 5a5781d..aedd6b3 100644 --- a/server/services/mailer.js +++ b/server/services/mailer.js @@ -191,9 +191,9 @@ const oneLine = (value) => String(value ?? '').replace(/\s*[\r\n]+\s*/g, ' ').tr * (Betriebs-E-Mail), nie BCC. Mit `ics` haengt die Kalenderdatei als icalEvent (nodemailer-Kalenderteil, kein Anhang) an. * Wirft bei fehlendem SMTP, ungueltiger Adresse oder Methode - der Aufrufer (Outbox) entscheidet ueber Wiederholung. * @param {{ to: string, fromName: string, replyTo?: string|null, subject: string, html: string, text: string, - * ics?: string|null, icsMethod?: 'REQUEST'|'CANCEL'|'PUBLISH' }} message + * ics?: string|null, icsMethod?: 'REQUEST'|'CANCEL'|'PUBLISH', attachments?: object[]|null (nodemailer, unveraendert, z. B. Rechnungs-PDF) }} message */ -export async function sendGuestMail({ to, fromName, replyTo = null, subject, html, text, ics = null, icsMethod = 'REQUEST' }) { +export async function sendGuestMail({ to, fromName, replyTo = null, subject, html, text, ics = null, icsMethod = 'REQUEST', attachments = null }) { const mailer = getTransporter() if (!mailer) throw new Error('SMTP nicht konfiguriert') checkMailbox(to, 'to') @@ -211,6 +211,7 @@ export async function sendGuestMail({ to, fromName, replyTo = null, subject, htm text, html, icalEvent: ics ? { method: icsMethod, filename: 'termin.ics', content: ics } : undefined, + attachments: Array.isArray(attachments) && attachments.length ? attachments : undefined, }) } diff --git a/server/services/termine/outbox.js b/server/services/termine/outbox.js index e41522a..198e7af 100644 --- a/server/services/termine/outbox.js +++ b/server/services/termine/outbox.js @@ -3,6 +3,8 @@ import { Query, countDocuments, createDocument, deleteDocument, getDocument, kei import { withLocks } from '../keyedLock.js' import { sendGuestMail } from '../mailer.js' import { renderMail } from '../mailTemplates.js' +import { ladeRechnung } from '../unterkunft/speicher.js' +import { rechnungPdf } from '../unterkunft/rechnungPdf.js' import { pruefeNow, pruefeText, zeitMs } from './util.js' /** @@ -286,6 +288,7 @@ async function sende(id, now) { if (!platz) return 'wartet' try { + const attachments = await baueAnhaenge(doc) await sendGuestMail({ to: doc.an, fromName: doc.fromName, @@ -295,6 +298,7 @@ async function sende(id, now) { text: doc.text, ics: doc.ics || null, icsMethod: doc.icsMethod || 'REQUEST', + ...(attachments.length ? { attachments } : {}), }) } catch (err) { gibPlatzFrei(platz) @@ -305,6 +309,39 @@ async function sende(id, now) { }) } +/** Nach so vielen Fehlschlaegen beim Erzeugen des Anhangs geht die Mail ohne ihn raus (Buchungskalender). */ +const ANHANG_VERSUCHE = 3 + +/** + * Anhaenge des Eintrags. Das Feld `anhang` ist JSON {art:'ukRechnung', rechnungId}: die Rechnung (ukRechnungen) wird als PDF + * gerendert (Rechnung-.pdf bzw. Stornorechnung-.pdf). Ohne `anhang` oder mit anderem Inhalt: keine Anhaenge. Scheitert das + * Laden oder Rendern, wirft die Funktion einen gewoehnlichen Fehler (der Eintrag bleibt `wartet` und wird wie jeder vorlaeufige + * Fehler wiederholt); ab dem vierten Versuch geht die Mail ohne Anhang raus. Der Fehlertext enthaelt keine Personendaten. + */ +async function baueAnhaenge(doc) { + if (!doc.anhang) return [] + let verweis + try { + verweis = JSON.parse(doc.anhang) + } catch { + return [] + } + if (verweis?.art !== 'ukRechnung' || typeof verweis.rechnungId !== 'string' || !verweis.rechnungId) return [] + try { + const rechnung = await ladeRechnung(verweis.rechnungId) + if (!rechnung?.inhalt) throw new Error('Rechnung nicht lesbar') + const storno = rechnung.art === 'storno' + const pdf = rechnungPdf(rechnung.inhalt, { art: rechnung.art, nummer: rechnung.nummer, datum: rechnung.datum }) + return [{ filename: `${storno ? 'Stornorechnung' : 'Rechnung'}-${rechnung.nummer}.pdf`, content: Buffer.from(pdf), contentType: 'application/pdf' }] + } catch (err) { + if ((Number(doc.versuche) || 0) >= ANHANG_VERSUCHE) { + console.error(`[termine-outbox] Eintrag ${doc.$id}: Rechnungs-PDF nicht erzeugt, Mail geht ohne Anhang raus (${String(err?.message).slice(0, 80)})`) + return [] + } + throw new Error(`Anhang nicht erzeugt: ${String(err?.message).slice(0, 80)}`) + } +} + /** * Ist der Bestaetigungslink dieser G01 schon verfallen? Das Halte-Fenster (config.termine.holdMinutes, bei jedem Aufruf * gelesen) plus eine Minute Toleranz ab Einreihen; genau so alt ist noch nicht veraltet. G01 ohne Buchung (zu_viele) hat diff --git a/server/services/unterkunft/mails.js b/server/services/unterkunft/mails.js index a4c1147..a679d11 100644 --- a/server/services/unterkunft/mails.js +++ b/server/services/unterkunft/mails.js @@ -1,10 +1,179 @@ -// Stub: Task 20 ersetzt den Inhalt, die Signaturen bleiben. Protokolliert die Aufrufe fuer Tests. +import { config } from '../../config.js' +import { loadTemplate } from '../mailTemplates.js' +import { sendAdminNotice, sendCustomerMail } from '../mailer.js' +import { einreihen } from '../termine/outbox.js' +import { formatTag } from './datum.js' +import { formatEuro } from './preis.js' +import { ladeEinstellungen, ladePreise, ladeUnterkunft } from './speicher.js' + +/** + * Mails des Buchungskalenders: G16-G22 an Gaeste (ueber die Mail-Warteschlange termineOutbox, Absendername = Firma des Vermieters, + * Antworten an dessen E-Mail), K31-K34 an den Vermieter (Kunde des Portals, ohne BCC bei Gastdaten) und T22 ans Team. + * `_aufrufe` protokolliert jeden Aufruf fuer Tests (die Mail geht trotzdem raus). Fehler werden geworfen; der Aufrufer + * (ablauf.js) faengt sie ab, weil der gespeicherte Schritt nicht rueckgaengig gemacht wird. + * + * extra je Gastmail: G17 token (Roh-Token, nur hier und nur einmal bekannt; ergibt den Buchungslink), text (G18 Begruendung), + * rechnung (G19: ukRechnungen-Dokument), stornoRechnung + erstattetCent + grund (G22), G21 braucht nichts. + */ export const _aufrufe = [] +const LEER = '–' +const text = (v) => (typeof v === 'string' ? v.trim() : '') +const GAST_ARTEN = ['G16', 'G17', 'G18', 'G19', 'G20', 'G21', 'G22'] + +const mehrzahl = (n, eins, viele) => `${n} ${n === 1 ? eins : viele}` +const FRIST_FORMAT = new Intl.DateTimeFormat('de-DE', { timeZone: 'Europe/Berlin', day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }) + +function fristText(wert) { + const t = Date.parse(wert) + if (!Number.isFinite(t)) return LEER + const teile = Object.fromEntries(FRIST_FORMAT.formatToParts(new Date(t)).map((p) => [p.type, p.value])) + return `${teile.day}.${teile.month}.${teile.year}, ${teile.hour}:${teile.minute} Uhr` +} + +function anbieterKontakt(e) { + return [text(e.firma), text(e.strasse), [text(e.plz), text(e.ort)].filter(Boolean).join(' '), text(e.email), text(e.telefon)].filter(Boolean).join('\n') +} + +function postenText(posten) { + if (!Array.isArray(posten) || posten.length === 0) return LEER + return posten.map((p) => `${p.text}: ${formatEuro(p.menge * p.einzelCent)}`).join('\n') +} + +const ZAHLART = { online: 'Online-Zahlung', vorort: 'Zahlung vor Ort' } + +/** Einstellungen des Vermieters: aus dem Kontext, sonst aus der Datenbank. */ +async function einstellungenVon(ctx, featureId) { + return ctx?.einstellungen ?? (featureId ? await ladeEinstellungen(featureId) : null) ?? {} +} + +/** Gemeinsame Werte aller Mails zu einer Anfrage. */ +async function werteZuAnfrage(ctx, anfrage) { + const e = await einstellungenVon(ctx, anfrage.featureId ?? ctx?.featureId) + const u = anfrage.unterkunftId ? await ladeUnterkunft(anfrage.unterkunftId) : null + const n = Number(anfrage.naechte) || naechteVon(anfrage) + return { + einstellungen: e, + unterkunft: u, + werte: { + gast_name: text(anfrage.gast?.name) || 'Gast', + firma: text(e.firma) || text(u?.name) || 'Ihr Gastgeber', + farbe: /^#[0-9a-fA-F]{6}$/.test(text(e.akzentfarbe)) ? e.akzentfarbe : '#111111', + anbieter_kontakt: anbieterKontakt(e) || LEER, + unterkunft: text(u?.name) || LEER, + zeitraum: `${formatTag(anfrage.von)} – ${formatTag(anfrage.bis)}`, + naechte: mehrzahl(n, 'Nacht', 'Nächte'), + personen: mehrzahl(Number(anfrage.personen) || 0, 'Person', 'Personen'), + nummer: text(anfrage.nummer) || LEER, + }, + } +} + +function naechteVon(a) { + return Math.max(0, Math.round((Date.parse(a.bis) - Date.parse(a.von)) / 86400000)) +} + +async function stornoText(anfrage) { + // Schnappschuss bei der Freigabe gilt; nur ohne ihn die aktuellen Bedingungen + if (text(anfrage.stornobedingungenText)) return text(anfrage.stornobedingungenText) + const preise = anfrage.unterkunftId ? await ladePreise(anfrage.unterkunftId) : null + return text(preise?.stornobedingungen) || 'Es wurden keine besonderen Stornobedingungen vereinbart.' +} + export async function anGast(art, ctx, anfrage, extra = {}) { _aufrufe.push({ an: 'gast', art, anfrageId: anfrage?.$id, extra }) + if (!GAST_ARTEN.includes(art)) throw new TypeError(`${String(art).slice(0, 20)} ist keine Gastmail`) + extra = extra ?? {} + const gast = anfrage?.gast ?? {} + if (!text(gast.email)) throw new TypeError('Empfänger fehlt') + const { einstellungen: e, werte } = await werteZuAnfrage(ctx, anfrage) + const values = { ...werte } + const blocks = {} + let anhang = null + + if (art !== 'G16' && art !== 'G18' && art !== 'G21' && art !== 'G20') values.stornobedingungen = await stornoText(anfrage) + if (art === 'G17' || art === 'G19' || art === 'G20') values.gesamt = formatEuro(anfrage.summen?.bruttoCent ?? 0) + if (art === 'G17' || art === 'G19') values.posten_text = postenText(anfrage.posten) + if (art === 'G17') { + values.frist = fristText(anfrage.fristAt) + const token = text(extra.token) + values.buchungs_link = `${config.publicBaseUrl}/unterkunft/${ctx?.siteKey ?? ''}/buchung/${anfrage.$id}?t=${token}` + values.nachricht_vermieter = text(anfrage.nachrichtVermieter) + blocks.nachricht = values.nachricht_vermieter !== '' + if (!token) throw new TypeError('Token für den Buchungslink fehlt') + } + if (art === 'G18') { + values.nachricht_vermieter = text(extra.text) + blocks.nachricht = values.nachricht_vermieter !== '' + } + if (art === 'G19') { + const zahlart = anfrage.zahlart + values.zahlart_text = ZAHLART[zahlart] ?? LEER + values.rechnung_nummer = text(extra.rechnung?.nummer) || LEER + blocks.online_unbezahlt = zahlart === 'online' && anfrage.status !== 'bezahlt' + if (extra.rechnung?.$id) anhang = { art: 'ukRechnung', rechnungId: extra.rechnung.$id } + } + if (art === 'G20') { + values.rechnung_nummer = text(extra.rechnung?.nummer) || text(anfrage.rechnungNummer) || LEER + } + if (art === 'G21') values.frist = fristText(anfrage.fristAt) + if (art === 'G22') { + values.rechnung_nummer = text(extra.stornoRechnung?.nummer) || LEER + values.nachricht_vermieter = text(extra.grund) + blocks.nachricht = values.nachricht_vermieter !== '' + const erstattung = Number(extra.erstattetCent) || 0 + values.erstattung = erstattung > 0 ? formatEuro(erstattung) : '' + blocks.erstattung = erstattung > 0 + if (extra.stornoRechnung?.$id) anhang = { art: 'ukRechnung', rechnungId: extra.stornoRechnung.$id } + } + + return einreihen({ + featureId: anfrage.featureId ?? ctx?.featureId, + bookingId: anfrage.$id, + art: `uk-${art}`, + an: text(gast.email), + fromName: values.firma.slice(0, 120), + replyTo: text(e.email) || null, + template: art, + values, + blocks, + ...(anhang ? { anhang: JSON.stringify(anhang) } : {}), + }) } +const portalUrl = (ctx) => `${config.publicBaseUrl}/dashboard.html#buchungen?projekt=${encodeURIComponent(ctx?.projectId ?? '')}` + +/** + * Mail an den Vermieter (K31-K34, Kunde des Portals) bzw. ans Team (T22). K31/K32: values.anfrage; die Werte lassen sich ueberschreiben, + * values.an ersetzt die Adresse (Standard ctx.besitzerEmail). T22 geht an die Team-Adressen und wirft nie. + */ export async function anVermieter(template, ctx, values = {}) { _aufrufe.push({ an: 'vermieter', template, values }) + const { anfrage, an, ...eigene } = values ?? {} + const vorgabe = {} + if (anfrage) { + const { werte } = await werteZuAnfrage(ctx, anfrage) + Object.assign(vorgabe, werte, { + kunde_name: text(ctx?.kundeName) || werte.firma, + gast_email: text(anfrage.gast?.email) || LEER, + nachricht_gast: text(anfrage.gast?.nachricht) || LEER, + gesamt: formatEuro(anfrage.summen?.bruttoCent ?? 0), + zahlart_text: ZAHLART[anfrage.zahlart] ?? LEER, + }) + } + const alle = { portal_url: portalUrl(ctx), ...vorgabe, ...eigene } + if (template === 'T22') { + const r = await sendAdminNotice({ template, values: nurPlatzhalter(template, alle) }) + if (!r?.sent) console.warn(`[unterkunft] Team-Mail ${template} nicht gesendet: ${r?.reason || 'unbekannt'}`) + return r + } + const empfaenger = text(an) || text(ctx?.besitzerEmail) + if (!empfaenger) throw new TypeError('Empfänger fehlt') + return sendCustomerMail(empfaenger, { template, values: nurPlatzhalter(template, alle), blocks: eigene.blocks ?? {}, bccTeam: ['K33', 'K34'].includes(template) }) +} + +/** Nur die Werte, die die Vorlage kennt (keine Warnung wegen Zusatzwerten wie farbe oder anbieter_kontakt). */ +function nurPlatzhalter(template, werte) { + const kennt = loadTemplate(template).placeholders + return Object.fromEntries(Object.entries(werte).filter(([k]) => kennt.includes(k) && k !== 'blocks')) } diff --git a/test/mailTemplates.test.js b/test/mailTemplates.test.js index 9fe42ff..9cd12c5 100644 --- a/test/mailTemplates.test.js +++ b/test/mailTemplates.test.js @@ -8,7 +8,7 @@ const DIR = new URL('../server/mail-templates/', import.meta.url) // G01–G08 Gästemails des Terminplaners (Task 9, neutrales Layout im Auftrag eines Betriebs), K20 und K21 Hinweise an den Betrieb; // K12, K14 und T12 (Wechsel ins Wartungs-Abo) aus Task 9, K13 und T13 (Zusatzspeicher) aus Task 8 (Fix 1); Endfassung der Texte in Task 12; T14 „Löschfristen“ aus Task 21 (F39); T15 Push-Zeitmail; K15, K16, T16 Funktionen (News-Pinnwand, Terminplaner; K15, K16 und T16 gelten je Funktion, Terminplaner TP2 B9a und B9b); T17 Repo zuordnen; K17 Chat-Hinweis an Kunden; K18, K19 Website-Analyse; K22, K23 Terminplaner beendet/läuft wieder (Terminplaner TP2 E3); T18 Bankzugang erneuern (Finanzen); T19 Erstattung fällig und T20 Terminplaner Betriebsmeldung (Terminplaner TP2, Team-Hinweise; T16 gilt je Funktion, T19 aus B9b); T21 Neue Webshop-Anfrage (Webshop B1, Team-Hinweis); K24 Webshop-Anfrage entschieden (Webshop B2, Kunde); G09–G14 Käufermails des Webshops (Bestellbestätigung, versendet, abholbereit, Eingang Widerruf, Erstattung, Zahlung fehlgeschlagen; Webshop E4, eigener Fuß statt Terminplaner-Fuß, Sie-Form) und K25, K26 an den Händler (neue Bestellung, Widerruf; Webshop E4); K27–K30 Öffnungszeiten live (eingeschaltet, Feiertage prüfen, Abo beendet, abgeschaltet; Öffnungszeiten live Task 13); K04 und T09 gelten beim Widerruf einer Funktion je Funktion (produkt, T09 zusätzlich preis; Terminplaner TP2 F9) const ids = (prefix, count) => Array.from({ length: count }, (_, i) => `${prefix}${String(i + 1).padStart(2, '0')}`) -const EXPECTED = [...ids('G', 15), ...ids('K', 30), ...ids('T', 21)] +const EXPECTED = [...ids('G', 22), ...ids('K', 34), ...ids('T', 22)] // GUEST = Gästemails des Terminplaners (gemeinsamer Fuß, Anrede-Blöcke); SHOP_GUEST = Käufermails des Webshops (G09–G14, siehe unten) const GUEST = ids('G', 8) const SHOP_GUEST = ['G09', 'G10', 'G11', 'G12', 'G13', 'G14', 'G15'] @@ -27,7 +27,7 @@ for (const id of EXPECTED) { const title = source.match(/([\s\S]*?)<\/title>/)[1] assert.equal(title, tpl.subject, 'Betreff im Kopf und <title> sind gleich') // F34: Team-Hinweise tragen [Abo], [Speicher] (Zusatzspeicher-Aufgaben), [Datenschutz] (Loeschfristen), [Zeit] (Push-Zeitmail), [Finanzen] (Bankzugang), [Terminplaner] (Betriebsmeldung) oder [Webshop] (neue Anfrage) - assert.equal(id.startsWith('T'), /^\[(Abo|Speicher|Datenschutz|Zeit|Finanzen|Terminplaner|Webshop)\]/.test(tpl.subject) || id === 'T01' || id === 'T16' || id === 'T17', 'Team-Hinweise ab T02 mit [Abo], [Speicher], [Datenschutz], [Zeit], [Finanzen], [Terminplaner] oder [Webshop] (T16 Funktion bestellt und T17 Repo zuordnen ohne Kennung)') + assert.equal(id.startsWith('T'), /^\[(Abo|Speicher|Datenschutz|Zeit|Finanzen|Terminplaner|Webshop|Buchungskalender)\]/.test(tpl.subject) || id === 'T01' || id === 'T16' || id === 'T17', 'Team-Hinweise ab T02 mit [Abo], [Speicher], [Datenschutz], [Zeit], [Finanzen], [Terminplaner], [Webshop] oder [Buchungskalender] (T16 Funktion bestellt und T17 Repo zuordnen ohne Kennung)') const used = new Set([...tpl.body.matchAll(/\{\{(\w+)\}\}/g), ...tpl.subject.matchAll(/\{\{(\w+)\}\}/g)].map((m) => m[1])) assert.deepEqual([...used].sort(), [...tpl.placeholders].sort(), 'deklarierte = verwendete Platzhalter') @@ -1280,3 +1280,75 @@ test('K26: Betreff, Platzhalter, Erklärung nur im Block, Hinweis auf die 14 Tag assert.match(mit.text, /innerhalb von 14 Tagen/) assert.doesNotMatch(renderMail('K26', K26_WERTE, {}).text, /Ich widerrufe|Erklärung:/) }) + +// --------------------------------------------------------------------------- +// Buchungskalender (Task 20): G16–G22 an Gäste (Sie-Form, neutral), K31–K34 und T22 (Du-Form, WEBklar) +// --------------------------------------------------------------------------- + +const UK_GAST = ['G16', 'G17', 'G18', 'G19', 'G20', 'G21', 'G22'] +const UK_BASIS = ['gast_name', 'unterkunft', 'zeitraum', 'naechte', 'personen', 'nummer', 'firma', 'farbe', 'anbieter_kontakt'] +const UK_ERWARTET = { + G16: { p: [], b: [] }, + G17: { p: ['posten_text', 'gesamt', 'frist', 'buchungs_link', 'stornobedingungen', 'nachricht_vermieter'], b: ['nachricht'] }, + G18: { p: ['nachricht_vermieter'], b: ['nachricht'] }, + G19: { p: ['posten_text', 'gesamt', 'zahlart_text', 'rechnung_nummer', 'stornobedingungen'], b: ['online_unbezahlt'] }, + G20: { p: ['gesamt', 'rechnung_nummer'], b: [] }, + G21: { p: ['frist'], b: [] }, + G22: { p: ['rechnung_nummer', 'erstattung', 'nachricht_vermieter'], b: ['erstattung', 'nachricht'] }, +} + +test('G16–G22: Platzhalter und Blöcke, Sie-Form, kein WEBklar-Logo, keine festen Adressen', () => { + for (const id of UK_GAST) { + const tpl = loadTemplate(id) + assert.deepEqual([...tpl.placeholders].sort(), [...UK_BASIS, ...UK_ERWARTET[id].p].sort(), `${id}: Platzhalter`) + assert.deepEqual([...tpl.blocks].sort(), [...UK_ERWARTET[id].b].sort(), `${id}: Blöcke`) + assert.doesNotMatch(sourceOf(id), /<img|webklar-logo|project\.webklar\.com/i, `${id}: neutral`) + for (const on of [true, false]) { + const mail = renderMail(id, sampleValues(tpl), allBlocks(tpl, on)) + assert.deepEqual(mail.problems, [], id) + assert.doesNotMatch(mail.text, DU_FORM, `${id}: Sie-Form\n${mail.text}`) + assert.match(mail.html, /background:Wert-farbe/, id) + } + } +}) + +test('G17: Preis, Frist, Stornobedingungen, Knopf und der Satz zur verbindlichen Buchung', () => { + const mail = renderMail('G17', sampleValues(loadTemplate('G17')), { nachricht: true }) + for (const w of ['Wert-posten_text', 'Wert-gesamt', 'Wert-frist', 'Wert-stornobedingungen']) assert.ok(mail.text.includes(w), w) + assert.match(mail.html, /href="Wert-buchungs_link"[^>]*>Jetzt verbindlich buchen/) + assert.ok(mail.text.includes('Erst mit dem Klick auf „Zahlungspflichtig buchen“ auf der Buchungsseite ist Ihre Buchung verbindlich.')) +}) + +test('G19: dauerhafter Datenträger mit allen Angaben, Hinweis kein Widerrufsrecht, Bezahl-Hinweis nur im Block', () => { + const tpl = loadTemplate('G19') + const aus = renderMail('G19', sampleValues(tpl), { online_unbezahlt: false }) + const an = renderMail('G19', sampleValues(tpl), { online_unbezahlt: true }) + for (const w of ['Wert-posten_text', 'Wert-gesamt', 'Wert-zahlart_text', 'Wert-stornobedingungen', 'Wert-anbieter_kontakt', 'Wert-rechnung_nummer']) assert.ok(aus.text.includes(w), w) + assert.match(aus.text, /kein gesetzliches Widerrufsrecht/) + assert.ok(!aus.text.includes('Bezahl-Link')) + assert.ok(an.text.includes('Den Bezahl-Link finden Sie auf der Buchungsseite aus unserer vorigen E-Mail.')) +}) + +test('G22: Erstattung „wird veranlasst“ nur im Block', () => { + const tpl = loadTemplate('G22') + assert.ok(renderMail('G22', { ...sampleValues(tpl), erstattung: '50,00 €' }, { erstattung: true }).text.includes('Eine Erstattung von 50,00 € wird veranlasst.')) + assert.ok(!renderMail('G22', sampleValues(tpl), { erstattung: false }).text.includes('Erstattung von')) +}) + +test('K31–K34, T22: Dateien, Platzhalter, Du-Form', () => { + const erwartet = { + K31: ['kunde_name', 'gast_name', 'gast_email', 'unterkunft', 'zeitraum', 'naechte', 'personen', 'nummer', 'nachricht_gast', 'portal_url'], + K32: ['kunde_name', 'gast_name', 'unterkunft', 'zeitraum', 'naechte', 'personen', 'nummer', 'gesamt', 'zahlart_text', 'portal_url'], + K33: ['kunde_name', 'unterkunft', 'portal_url'], + K34: ['kunde_name', 'projekt', 'preis', 'ust_hinweis', 'begruendung', 'portal_url'], + T22: ['kunde_name', 'email', 'projekt', 'nachricht', 'woms_url'], + } + for (const [id, p] of Object.entries(erwartet)) { + const tpl = loadTemplate(id) + assert.deepEqual([...tpl.placeholders].sort(), [...p].sort(), id) + const mail = renderMail(id, sampleValues(tpl), allBlocks(tpl, true)) + assert.deepEqual(mail.problems, [], id) + } + assert.equal(loadTemplate('K32').file, 'K32 Neue Buchung.html') + assert.equal(loadTemplate('T22').subject, '[Buchungskalender] Neue Anfrage: {{kunde_name}}') +}) diff --git a/test/termineOutbox.test.js b/test/termineOutbox.test.js index acd495c..8de5be1 100644 --- a/test/termineOutbox.test.js +++ b/test/termineOutbox.test.js @@ -10,7 +10,7 @@ import { TERMINE_DATETIMES } from '../server/services/termine/schema.js' // Produktion. Der Mailtransport ist ein Fake, der Sendeversuche zaehlt und gezielt Fehler wirft (nodemailer-Fehler // tragen `code` und SMTP-`responseCode`). Alle Zeiten sind feste Parameter. const aw = await startAppwriteMock({ - schema: { termineOutbox: schemaKeys('termineOutbox') }, + schema: { termineOutbox: schemaKeys('termineOutbox'), ukRechnungen: schemaKeys('ukRechnungen') }, datetimes: TERMINE_DATETIMES, defaultLimit: 25, }) @@ -1290,3 +1290,39 @@ test('einreihen: optionaler Anhang-Verweis wird gespeichert (Senden unverändert const attribut = (await import('../server/services/termine/schema.js')).TERMINE_COLLECTIONS.termineOutbox.attributes.find((a) => a.key === 'anhang') assert.deepEqual(attribut, { key: 'anhang', type: 'string', size: 500, required: false }) }) + +// Buchungskalender (Task 20): anhang {art:'ukRechnung', rechnungId} -> Rechnungs-PDF als Anhang +const RE_INHALT = { aussteller: { firma: 'Haus' }, empfaenger: { name: 'Eva' }, unterkunft: { name: 'Wohnung' }, von: '2026-11-12', bis: '2026-11-14', naechte: 2, personen: 2, posten: [{ text: 'Übernachtung', menge: 2, einzelCent: 10000, ustProzent: 0 }], summen: { bruttoCent: 20000, nettoCent: 20000, ust: [] }, steuerart: 'kleinunternehmer' } +const seedRechnung = (extra = {}) => aw.seed('ukRechnungen', { $id: 'r1', featureId: 'f_feature01', anfrageId: 'a1', art: 'rechnung', nummer: 'RE-2026-0001', datum: '2026-11-01', bruttoCent: 20000, inhalt: JSON.stringify(RE_INHALT), ...extra }) + +test('Anhang ukRechnung: gesendete Mail hat Rechnung-<nr>.pdf (beginnt mit %PDF); Stornorechnung heißt Stornorechnung-<nr>.pdf', async () => { + seedRechnung() + seedRechnung({ $id: 'r2', art: 'storno', nummer: 'RE-2026-0002' }) + await einreihen(eintrag({ bookingId: 'b_re', anhang: JSON.stringify({ art: 'ukRechnung', rechnungId: 'r1' }) }), JETZT) + await einreihen(eintrag({ bookingId: 'b_st', anhang: JSON.stringify({ art: 'ukRechnung', rechnungId: 'r2' }) }), JETZT) + await einreihen(eintrag({ bookingId: 'b_ohne' }), JETZT) + await warteAufVersand() + const namen = tr.senke.sent.map((m) => (m.attachments ?? []).map((a) => a.filename)) + assert.deepEqual(namen.map((n) => n.join()).sort(), ['', 'Rechnung-RE-2026-0001.pdf', 'Stornorechnung-RE-2026-0002.pdf']) + const mit = tr.senke.sent.find((m) => m.attachments?.length) + assert.equal(Buffer.from(mit.attachments[0].content, 'base64').subarray(0, 4).toString(), '%PDF') + assert.equal(mit.attachments[0].contentType, 'application/pdf') +}) + +test('Anhang nicht erzeugbar: Eintrag bleibt wartet (Wiederholung), nach 3 Fehlversuchen geht die Mail ohne Anhang raus', async () => { + const doc = await einreihen(eintrag({ bookingId: 'b_fehlt', art: 'uk-G19', anhang: JSON.stringify({ art: 'ukRechnung', rechnungId: 'gibtsnicht' }) }), JETZT) + await warteAufVersand() + let d = await lies(doc.$id) + assert.equal(d.status, 'wartet') + assert.equal(d.versuche, 1) + assert.equal(tr.aufrufe, 0) + let jetzt = JETZT + for (const warte of [2 * MIN, 6 * MIN, 31 * MIN]) { + jetzt = plus(warte, jetzt) + await sendeEintrag(doc.$id, jetzt) + } + d = await lies(doc.$id) + assert.equal(d.status, 'gesendet') + assert.equal(tr.senke.sent.length, 1) + assert.equal(tr.senke.sent[0].attachments?.length ?? 0, 0) +}) diff --git a/test/unterkunftMails.test.js b/test/unterkunftMails.test.js new file mode 100644 index 0000000..fc2a611 --- /dev/null +++ b/test/unterkunftMails.test.js @@ -0,0 +1,113 @@ +import { test, after, beforeEach } from 'node:test' +import assert from 'node:assert/strict' +import { startAppwriteMock } from './support/appwriteMock.js' +import { mailSink } from './support/mailSink.js' +import { useTestEnv } from './support/testEnv.js' +import { schemaKeys } from './support/schema.js' +import { TERMINE_DATETIMES } from '../server/services/termine/schema.js' + +// Buchungskalender Task 20: Mails an Gaeste (ueber die Warteschlange), Vermieter und Team +const NAMEN = ['ukUnterkuenfte', 'ukPreise', 'ukAnfragen', 'ukRechnungen', 'ukEinstellungen', 'termineOutbox'] +const aw = await startAppwriteMock({ + schema: Object.fromEntries(NAMEN.map((n) => [n, schemaKeys(n)])), + datetimes: { ...TERMINE_DATETIMES, ukAnfragen: ['fristAt', 'freigegebenAt', 'gebuchtAt', 'abgelehntAt', 'abgelaufenAt', 'storniertAt', 'bezahltAt'] }, + defaultLimit: 25, +}) +after(() => aw.close()) +useTestEnv({ appwriteUrl: aw.url, stripeUrl: 'http://127.0.0.1:1/v1' }) +const { config } = await import('../server/config.js') +const { deleteDocument } = await import('../server/services/appwriteAdmin.js') +const { setMailTransportForTests } = await import('../server/services/mailer.js') +const { warteAufVersand, resetOutboxForTests } = await import('../server/services/termine/outbox.js') +const mails = await import('../server/services/unterkunft/mails.js') +const sp = await import('../server/services/unterkunft/speicher.js') +after(() => setMailTransportForTests(null)) + +const EIN = { firma: 'Haus am See', strasse: 'Weg 1', plz: '10115', ort: 'Berlin', email: 'vermieter@example.com', telefon: '0123', akzentfarbe: '#336699' } +const ctx = { featureId: 'f1', customerId: 'c1', projectId: 'p1', siteKey: 'abcdefghijklmnop', besitzerEmail: 'besitzer@example.com', einstellungen: EIN } +const POSTEN = [{ text: 'Übernachtung, 2 Nächte', menge: 2, einzelCent: 10000, ustProzent: 7 }, { text: 'Endreinigung', menge: 1, einzelCent: 5000, ustProzent: 19 }] +const anfrage = (extra = {}) => ({ + $id: 'a1', featureId: 'f1', unterkunftId: 'u1', nummer: 'A-K7QM', von: '2026-11-12', bis: '2026-11-14', personen: 2, status: 'freigegeben', + gast: { name: 'Eva Gast', email: 'eva@example.com', nachricht: 'Hallo' }, posten: POSTEN, summen: { bruttoCent: 25000 }, + fristAt: '2026-11-05T16:00:00.000Z', stornobedingungenText: 'Kostenlos bis 7 Tage vorher.', nachrichtVermieter: '', ...extra, +}) +let sink +beforeEach(async () => { + for (const c of ['termineOutbox', 'ukRechnungen', 'ukUnterkuenfte', 'ukEinstellungen']) for (const id of aw.docs(c).keys()) await deleteDocument(c, id) + config.smtp.from = 'noreply@webklar.com' + resetOutboxForTests() + mails._aufrufe.length = 0 + sink = mailSink() + setMailTransportForTests(sink) + aw.seed('ukUnterkuenfte', { $id: 'u1', featureId: 'f1', name: 'Wohnung See', maxPersonen: 4, mindestNaechte: 1, aktiv: true }) +}) +const gesendet = async () => { + await warteAufVersand() + return sink.sent +} + +test('G17: Absender = Firma, Antworten an den Vermieter, Buchungslink mit Token, Preis und Frist', async () => { + await mails.anGast('G17', ctx, anfrage(), { token: 'tok123' }) + const [m] = await gesendet() + assert.equal(m.from.name, 'Haus am See') + assert.equal(m.replyTo[0].address, 'vermieter@example.com') + assert.equal(m.to[0].address, 'eva@example.com') + assert.ok(m.text.includes(`${config.publicBaseUrl}/unterkunft/abcdefghijklmnop/buchung/a1?t=tok123`)) + assert.ok(m.text.includes('250,00 €')) + assert.ok(m.text.includes('12.11.2026 – 14.11.2026')) + assert.ok(m.text.includes('Kostenlos bis 7 Tage vorher.')) + assert.ok(m.text.includes('05.11.2026, 17:00 Uhr')) + assert.ok(m.text.includes('Erst mit dem Klick auf „Zahlungspflichtig buchen“')) + assert.equal(mails._aufrufe[0].art, 'G17') +}) + +test('Minimaler ctx: Einstellungen und Unterkunft werden selbst geladen', async () => { + aw.seed('ukEinstellungen', { $id: 'f1', featureId: 'f1', ...EIN, firma: 'Geladene Firma' }) + await mails.anGast('G21', { featureId: 'f1' }, anfrage()) + const [m] = await gesendet() + assert.equal(m.from.name, 'Geladene Firma') + assert.ok(m.text.includes('Wohnung See')) + assert.doesNotMatch(m.text, /buchung\/a1/) +}) + +test('G17 ohne Token wirft, G16 hat keinen Link', async () => { + await assert.rejects(() => mails.anGast('G17', ctx, anfrage(), {}), TypeError) + await mails.anGast('G16', ctx, anfrage({ status: 'neu', posten: null, summen: null })) + const [m] = await gesendet() + assert.doesNotMatch(m.text, /\?t=/) +}) + +test('G19 hängt die Rechnung als PDF an (online, unbezahlt: Bezahl-Hinweis), G22 die Stornorechnung mit Erstattung', async () => { + const inhalt = { aussteller: { firma: 'Haus am See' }, empfaenger: { name: 'Eva Gast' }, unterkunft: { name: 'Wohnung See' }, von: '2026-11-12', bis: '2026-11-14', naechte: 2, personen: 2, posten: POSTEN, summen: { bruttoCent: 25000, nettoCent: 23000, ust: [] }, steuerart: 'kleinunternehmer', zahlart: 'online' } + const re = await sp.legeRechnungAn({ featureId: 'f1', anfrageId: 'a1', art: 'rechnung', nummer: 'RE-2026-0001', datum: '2026-11-01', bruttoCent: 25000, inhalt }) + const st = await sp.legeRechnungAn({ featureId: 'f1', anfrageId: 'a1', art: 'storno', nummer: 'RE-2026-0002', datum: '2026-11-02', bruttoCent: -25000, inhalt: { ...inhalt, bezugNummer: 'RE-2026-0001' } }) + await mails.anGast('G19', ctx, anfrage({ status: 'gebucht', zahlart: 'online' }), { rechnung: re }) + await mails.anGast('G22', ctx, anfrage({ status: 'storniert' }), { stornoRechnung: st, erstattetCent: 25000, grund: 'Wasserschaden' }) + const sent = await gesendet() + const g19 = sent.find((m) => m.subject.includes('bestätigt')) + const g22 = sent.find((m) => m.subject.includes('storniert')) + assert.equal(g19.attachments.length, 1) + assert.equal(g19.attachments[0].filename, 'Rechnung-RE-2026-0001.pdf') + assert.ok(Buffer.from(g19.attachments[0].content, 'base64').subarray(0, 4).toString() === '%PDF') + assert.ok(g19.text.includes('Den Bezahl-Link finden Sie auf der Buchungsseite')) + assert.equal(g22.attachments[0].filename, 'Stornorechnung-RE-2026-0002.pdf') + assert.ok(g22.text.includes('Eine Erstattung von 250,00 € wird veranlasst.')) + assert.ok(g22.text.includes('Wasserschaden')) +}) + +test('G22 ohne Erstattung: kein Erstattungssatz; G19 vor Ort bezahlt: kein Bezahl-Hinweis', async () => { + await mails.anGast('G22', ctx, anfrage({ status: 'storniert' }), { erstattetCent: 0 }) + await mails.anGast('G19', ctx, anfrage({ status: 'gebucht', zahlart: 'vorort' }), {}) + const sent = await gesendet() + assert.ok(sent.every((m) => !m.text.includes('Erstattung von') && !m.text.includes('Bezahl-Link'))) +}) + +test('Vermieter: K31 geht an den Besitzer ohne BCC, mit Portal-Link; T22 ans Team; unbekannte Gastart wirft', async () => { + await mails.anVermieter('K31', ctx, { anfrage: anfrage({ status: 'neu' }) }) + const [k] = await gesendet() + assert.equal(k.to[0].address, 'besitzer@example.com') + assert.ok(!k.bcc || k.bcc.length === 0) + assert.ok(k.text.includes(`${config.publicBaseUrl}/dashboard.html#buchungen?projekt=p1`)) + assert.ok(k.text.includes('Eva Gast')) + await assert.rejects(() => mails.anGast('K31', ctx, anfrage()), TypeError) +}) From 4553bc8e9247a395bf52819a0cda488fe7ccc612 Mon Sep 17 00:00:00 2001 From: Kenso Grimm <kenso@webklar.com> Date: Wed, 7 Oct 2026 14:16:04 +0000 Subject: [PATCH 3/5] =?UTF-8?q?Buchungskalender:=20Mails=20=E2=80=93=20Lin?= =?UTF-8?q?k-Pflicht=20und=20Testprotokoll=20nur=20im=20Test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --- server/services/unterkunft/mails.js | 20 ++++++++++++++++---- server/services/unterkunft/zahlung.js | 4 +++- test/support/testEnv.js | 1 + test/unterkunftAblauf.test.js | 2 +- test/unterkunftMails.test.js | 25 +++++++++++++++++++++---- 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/server/services/unterkunft/mails.js b/server/services/unterkunft/mails.js index a679d11..821556a 100644 --- a/server/services/unterkunft/mails.js +++ b/server/services/unterkunft/mails.js @@ -1,5 +1,6 @@ import { config } from '../../config.js' import { loadTemplate } from '../mailTemplates.js' +import { customerOf } from '../siteFeatures.js' import { sendAdminNotice, sendCustomerMail } from '../mailer.js' import { einreihen } from '../termine/outbox.js' import { formatTag } from './datum.js' @@ -16,6 +17,8 @@ import { ladeEinstellungen, ladePreise, ladeUnterkunft } from './speicher.js' * rechnung (G19: ukRechnungen-Dokument), stornoRechnung + erstattetCent + grund (G22), G21 braucht nichts. */ export const _aufrufe = [] +/** Protokoll nur im Test (UK_TESTPROTOKOLL, setzt useTestEnv); nie Token, Werte oder Gastdaten. */ +const testProtokoll = () => process.env.NODE_ENV === 'test' || process.env.UK_TESTPROTOKOLL === '1' const LEER = '–' const text = (v) => (typeof v === 'string' ? v.trim() : '') @@ -81,10 +84,11 @@ async function stornoText(anfrage) { } export async function anGast(art, ctx, anfrage, extra = {}) { - _aufrufe.push({ an: 'gast', art, anfrageId: anfrage?.$id, extra }) + if (testProtokoll()) _aufrufe.push({ an: 'gast', art, anfrageId: anfrage?.$id, hatToken: Boolean(extra?.token), grund: extra?.grund }) if (!GAST_ARTEN.includes(art)) throw new TypeError(`${String(art).slice(0, 20)} ist keine Gastmail`) extra = extra ?? {} const gast = anfrage?.gast ?? {} + if (art === 'G17' && (!text(extra.token) || !text(ctx?.siteKey))) throw new TypeError('Token oder siteKey für den Buchungslink fehlt') if (!text(gast.email)) throw new TypeError('Empfänger fehlt') const { einstellungen: e, werte } = await werteZuAnfrage(ctx, anfrage) const values = { ...werte } @@ -100,7 +104,6 @@ export async function anGast(art, ctx, anfrage, extra = {}) { values.buchungs_link = `${config.publicBaseUrl}/unterkunft/${ctx?.siteKey ?? ''}/buchung/${anfrage.$id}?t=${token}` values.nachricht_vermieter = text(anfrage.nachrichtVermieter) blocks.nachricht = values.nachricht_vermieter !== '' - if (!token) throw new TypeError('Token für den Buchungslink fehlt') } if (art === 'G18') { values.nachricht_vermieter = text(extra.text) @@ -148,13 +151,13 @@ const portalUrl = (ctx) => `${config.publicBaseUrl}/dashboard.html#buchungen?pro * values.an ersetzt die Adresse (Standard ctx.besitzerEmail). T22 geht an die Team-Adressen und wirft nie. */ export async function anVermieter(template, ctx, values = {}) { - _aufrufe.push({ an: 'vermieter', template, values }) + if (testProtokoll()) _aufrufe.push({ an: 'vermieter', template, anfrageId: values?.anfrage?.$id }) const { anfrage, an, ...eigene } = values ?? {} const vorgabe = {} if (anfrage) { const { werte } = await werteZuAnfrage(ctx, anfrage) Object.assign(vorgabe, werte, { - kunde_name: text(ctx?.kundeName) || werte.firma, + kunde_name: text(ctx?.kundeName) || (await kundenName(ctx)) || werte.firma, gast_email: text(anfrage.gast?.email) || LEER, nachricht_gast: text(anfrage.gast?.nachricht) || LEER, gesamt: formatEuro(anfrage.summen?.bruttoCent ?? 0), @@ -177,3 +180,12 @@ function nurPlatzhalter(template, werte) { const kennt = loadTemplate(template).placeholders return Object.fromEntries(Object.entries(werte).filter(([k]) => kennt.includes(k) && k !== 'blocks')) } + +/** Name des Kunden (Vermieters) aus dem Kundendokument; Fehler beim Laden machen die Mail nicht kaputt. */ +async function kundenName(ctx) { + try { + return text((await customerOf(ctx?.customerId))?.name) + } catch { + return '' + } +} diff --git a/server/services/unterkunft/zahlung.js b/server/services/unterkunft/zahlung.js index d73ed70..c992c44 100644 --- a/server/services/unterkunft/zahlung.js +++ b/server/services/unterkunft/zahlung.js @@ -2,9 +2,11 @@ import { UkFehler } from './fehler.js' export const _aufrufe = [] +/** Aufrufprotokoll nur im Test (UK_TESTPROTOKOLL, setzt useTestEnv); in Produktion waechst nichts. */ +const testProtokoll = () => process.env.NODE_ENV === 'test' || process.env.UK_TESTPROTOKOLL === '1' export async function erstatte(ctx, anfrage, betragCent, { now, idempotencyKey } = {}) { - _aufrufe.push({ anfrageId: anfrage?.$id, betragCent, idempotencyKey }) + if (testProtokoll()) _aufrufe.push({ anfrageId: anfrage?.$id, betragCent, idempotencyKey }) if (!ctx?.einstellungen?.stripeAccountId) throw new UkFehler(409, 'online_aus') return { erstattetCent: betragCent } } diff --git a/test/support/testEnv.js b/test/support/testEnv.js index f6159b8..aca4b30 100644 --- a/test/support/testEnv.js +++ b/test/support/testEnv.js @@ -15,5 +15,6 @@ export function useTestEnv({ appwriteUrl, stripeUrl }) { SMTP_HOST: '', SESSION_SECRET: 'test-session-secret-mit-mindestens-32-zeichen', ABO_PILOT_EMAILS: '*', + UK_TESTPROTOKOLL: '1', }) } diff --git a/test/unterkunftAblauf.test.js b/test/unterkunftAblauf.test.js index fc9cc55..514d472 100644 --- a/test/unterkunftAblauf.test.js +++ b/test/unterkunftAblauf.test.js @@ -251,7 +251,7 @@ test('Storno: Erstattung scheitert -> storniert, eine Stornorechnung, 502; Wiede assert.equal(a.erstattetCent, 0) assert.equal(aw.docs('ukRechnungen').size, 2) assert.deepEqual(arten(), ['G22']) - assert.equal(mails._aufrufe[0].extra.grund, 'g') + assert.equal(mails._aufrufe[0].grund, 'g') const r = await ab.storniere(sctx, id, { grund: 'g', erstattungCent: 20000, now: NOW }) assert.equal(r.anfrage.erstattetCent, 20000) assert.equal(aw.docs('ukRechnungen').size, 2) diff --git a/test/unterkunftMails.test.js b/test/unterkunftMails.test.js index fc2a611..5a95b8b 100644 --- a/test/unterkunftMails.test.js +++ b/test/unterkunftMails.test.js @@ -7,9 +7,9 @@ import { schemaKeys } from './support/schema.js' import { TERMINE_DATETIMES } from '../server/services/termine/schema.js' // Buchungskalender Task 20: Mails an Gaeste (ueber die Warteschlange), Vermieter und Team -const NAMEN = ['ukUnterkuenfte', 'ukPreise', 'ukAnfragen', 'ukRechnungen', 'ukEinstellungen', 'termineOutbox'] +const NAMEN = ['customers', 'ukUnterkuenfte', 'ukPreise', 'ukAnfragen', 'ukRechnungen', 'ukEinstellungen', 'termineOutbox'] const aw = await startAppwriteMock({ - schema: Object.fromEntries(NAMEN.map((n) => [n, schemaKeys(n)])), + schema: Object.fromEntries(NAMEN.map((n) => [n, n === 'customers' ? ['name', 'email'] : schemaKeys(n)])), datetimes: { ...TERMINE_DATETIMES, ukAnfragen: ['fristAt', 'freigegebenAt', 'gebuchtAt', 'abgelehntAt', 'abgelaufenAt', 'storniertAt', 'bezahltAt'] }, defaultLimit: 25, }) @@ -58,7 +58,8 @@ test('G17: Absender = Firma, Antworten an den Vermieter, Buchungslink mit Token, assert.ok(m.text.includes('Kostenlos bis 7 Tage vorher.')) assert.ok(m.text.includes('05.11.2026, 17:00 Uhr')) assert.ok(m.text.includes('Erst mit dem Klick auf „Zahlungspflichtig buchen“')) - assert.equal(mails._aufrufe[0].art, 'G17') + assert.deepEqual(mails._aufrufe[0], { an: 'gast', art: 'G17', anfrageId: 'a1', hatToken: true, grund: undefined }) + assert.ok(!JSON.stringify(mails._aufrufe).includes('tok123')) }) test('Minimaler ctx: Einstellungen und Unterkunft werden selbst geladen', async () => { @@ -70,8 +71,10 @@ test('Minimaler ctx: Einstellungen und Unterkunft werden selbst geladen', async assert.doesNotMatch(m.text, /buchung\/a1/) }) -test('G17 ohne Token wirft, G16 hat keinen Link', async () => { +test('G17 ohne Token oder ohne siteKey wirft vor dem Einreihen, G16 hat keinen Link', async () => { await assert.rejects(() => mails.anGast('G17', ctx, anfrage(), {}), TypeError) + await assert.rejects(() => mails.anGast('G17', { ...ctx, siteKey: '' }, anfrage(), { token: 't' }), TypeError) + assert.equal(aw.docs('termineOutbox').size, 0) await mails.anGast('G16', ctx, anfrage({ status: 'neu', posten: null, summen: null })) const [m] = await gesendet() assert.doesNotMatch(m.text, /\?t=/) @@ -111,3 +114,17 @@ test('Vermieter: K31 geht an den Besitzer ohne BCC, mit Portal-Link; T22 ans Tea assert.ok(k.text.includes('Eva Gast')) await assert.rejects(() => mails.anGast('K31', ctx, anfrage()), TypeError) }) + +test('Gastname wird in der Mail maskiert', async () => { + await mails.anGast('G16', ctx, anfrage({ gast: { name: '<b>x</b>', email: 'eva@example.com' } })) + const [m] = await gesendet() + assert.ok(!m.html.includes('<b>x</b>')) + assert.ok(m.html.includes('<b>x</b>')) +}) + +test('K31: Kundenname kommt aus dem Kundendokument, wenn ctx keinen hat', async () => { + aw.seed('customers', { $id: 'c1', name: 'Mimi Muster', email: 'besitzer@example.com' }) + await mails.anVermieter('K31', ctx, { anfrage: anfrage({ status: 'neu' }) }) + const [k] = await gesendet() + assert.ok(k.text.includes('Hallo Mimi Muster')) +}) From b25689a0154de7456bb9e17dff67fd19732cdc91 Mon Sep 17 00:00:00 2001 From: Kenso Grimm <kenso@webklar.com> Date: Wed, 7 Oct 2026 14:23:21 +0000 Subject: [PATCH 4/5] Buchungskalender: Rechtstexte, Einbau- und Livegang-Notiz Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --- .../unterkunft-datenschutz-absatz.md | 57 ++++ docs/funktionen/unterkunft-einbau.md | 91 +++++++ docs/funktionen/unterkunft-livegang.md | 115 ++++++++ docs/funktionen/unterkunft-storno-muster.md | 35 +++ docs/rechtliches/avv-unterkunft.md | 157 +++++++++++ .../leistungsbeschreibung-unterkunft.md | 194 +++++++++++++ .../unterkunft-datenschutz-6f-entwurf.md | 21 ++ docs/rechtliches/unterkunft-kanzlei-fragen.md | 34 +++ .../avv-unterkunft-2026-10-07.html | 212 +++++++++++++++ .../rechtliches/avv-unterkunft-2026-10-07.pdf | Bin 0 -> 131774 bytes .../avv-unterkunft-2026-10-07.pdf.sha256 | 1 + ...ngsbeschreibung-unterkunft-2026-10-07.html | 255 ++++++++++++++++++ ...ungsbeschreibung-unterkunft-2026-10-07.pdf | Bin 0 -> 136408 bytes ...chreibung-unterkunft-2026-10-07.pdf.sha256 | 1 + ...errufsbelehrung-funktionen-2026-10-07.html | 105 ++++++++ ...derrufsbelehrung-funktionen-2026-10-07.pdf | Bin 0 -> 53611 bytes ...belehrung-funktionen-2026-10-07.pdf.sha256 | 1 + scripts/build-legal-html.mjs | 40 ++- scripts/build-legal-pdfs.sh | 31 ++- test/buildLegalHtml.test.js | 98 ++++++- test/legalDocs.test.js | 19 ++ 21 files changed, 1456 insertions(+), 11 deletions(-) create mode 100644 docs/funktionen/unterkunft-datenschutz-absatz.md create mode 100644 docs/funktionen/unterkunft-einbau.md create mode 100644 docs/funktionen/unterkunft-livegang.md create mode 100644 docs/funktionen/unterkunft-storno-muster.md create mode 100644 docs/rechtliches/avv-unterkunft.md create mode 100644 docs/rechtliches/leistungsbeschreibung-unterkunft.md create mode 100644 docs/rechtliches/unterkunft-datenschutz-6f-entwurf.md create mode 100644 docs/rechtliches/unterkunft-kanzlei-fragen.md create mode 100644 public/rechtliches/avv-unterkunft-2026-10-07.html create mode 100644 public/rechtliches/avv-unterkunft-2026-10-07.pdf create mode 100644 public/rechtliches/avv-unterkunft-2026-10-07.pdf.sha256 create mode 100644 public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.html create mode 100644 public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.pdf create mode 100644 public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.pdf.sha256 create mode 100644 public/rechtliches/widerrufsbelehrung-funktionen-2026-10-07.html create mode 100644 public/rechtliches/widerrufsbelehrung-funktionen-2026-10-07.pdf create mode 100644 public/rechtliches/widerrufsbelehrung-funktionen-2026-10-07.pdf.sha256 diff --git a/docs/funktionen/unterkunft-datenschutz-absatz.md b/docs/funktionen/unterkunft-datenschutz-absatz.md new file mode 100644 index 0000000..7b3f271 --- /dev/null +++ b/docs/funktionen/unterkunft-datenschutz-absatz.md @@ -0,0 +1,57 @@ +# Mustertext: Datenschutzerklärung der Kundenwebsite (Buchungskalender) + +**Muster – keine Rechtsberatung.** Entwurf, Prüfung durch Kanzlei offen (`docs/rechtliches/unterkunft-kanzlei-fragen.md`, Frage U12). Der Absatz gehört in die Datenschutzerklärung jeder Kundenwebsite, auf der der Buchungskalender läuft. Der Vermieter ist Verantwortlicher und verantwortet seine Datenschutzerklärung selbst; WEBklar liefert nur diesen Baustein (Leistungsbeschreibung Buchungskalender Nr. 5 Abs. 10 und Nr. 6). Bau das Widget erst ein, wenn der Absatz in der Datenschutzerklärung steht. + +Hinweise für das Team: + +- Liegt die Datenschutzerklärung in der Website, die WEBklar betreut, fügen wir den Absatz beim Einbau ein (gehört zur Einrichtung). Liegt sie woanders, bekommt der Vermieter den Text im Chat und fügt ihn selbst ein. +- Platzhalter in eckigen Klammern durch die Angaben des Vermieters ersetzen. Nicht Zutreffendes streichen: Den Absatz „Zahlung über Stripe“ nur, wenn der Vermieter die Online-Zahlung eingeschaltet hat; den Satz zu anderen Plattformen nur, wenn er Kalender einbindet. +- Anrede und Ton an die übrige Erklärung der Website anpassen (meist Sie). Die Nummerierung der Überschrift der Website beachten. +- Wenn der Vermieter im Impressum oder in der Erklärung einen Datenschutzbeauftragten nennt, dort dazuschreiben. +- Die Löschfristen entsprechen dem AVV Buchungskalender Nr. 9 und Abschnitt 6f der Datenschutzerklärung von WEBklar (project.webklar.com/datenschutz.html, nach dem Livegang). Ändert sich dort etwas, hier mitändern. Die Frist für Server-Protokolle (14 Tage) steht in Abschnitt 3 dieser Erklärung. +- Das Widget setzt keine Cookies. +- Im sichtbaren Text der Kundenwebsite die Wünsche des Vermieters beachten (etwa keine Gedankenstriche). + +--- + +## [Nummer]. Anfragen und Buchungen über unseren Buchungskalender + +### Verantwortlicher und technischer Betrieb + +Verantwortlich für die Verarbeitung Ihrer Daten bei einer Anfrage oder Buchung ist [Name des Vermieters, Anschrift, E-Mail-Adresse], also der Vermieter. Den Buchungskalender betreibt technisch die WEBklar GbR, Am Schwimmbad 10, 67722 Winnweiler, in unserem Auftrag. Sie verarbeitet Ihre Daten nur nach unseren Weisungen und nicht für eigene Zwecke (Auftragsverarbeitung nach Art. 28 DSGVO). Der Server steht bei der Hetzner Online GmbH in Falkenstein (Deutschland); der Versand der E-Mails zu Ihrer Anfrage und Buchung läuft über den E-Mail-Dienst der Hetzner Online GmbH in Nürnberg (Deutschland). + +### Welche Daten wir bei einer Anfrage und Buchung verarbeiten + +Wenn Sie über den Buchungskalender anfragen, verarbeiten wir die gewünschte Unterkunft, den Zeitraum und die Zahl der Personen, Ihren Namen, Ihre E-Mail-Adresse und, wenn Sie es angeben, Ihre Firma, Ihre Telefonnummer und Ihre Nachricht. Bitte schreiben Sie keine Angaben zu Ihrer Gesundheit oder anderen besonders schutzbedürftigen Umständen in die Nachricht. Die Verarbeitung ist nötig, um Ihre Anfrage zu beantworten und gegebenenfalls einen Vertrag mit Ihnen zu schließen (Art. 6 Abs. 1 lit. b DSGVO). Ohne diese Angaben können wir Ihre Anfrage nicht bearbeiten. Eine Anfrage ist unverbindlich. Geben wir sie frei, erhalten Sie eine E-Mail mit dem Preis, den Stornobedingungen und einem Link zur Buchungsseite; erst dort buchen Sie verbindlich. + +Wenn Sie buchen, verarbeiten wir zusätzlich Ihre Rechnungsadresse (Name oder Firma, Straße, Postleitzahl, Ort, Land), die gewählte Zahlart, die Buchung mit ihrem Stand (zum Beispiel gebucht, bezahlt, storniert) und die Rechnung. Die Rechnung wird in unserem Namen und in unserem Auftrag von der WEBklar GbR erstellt (§ 14 Abs. 2 Satz 4 UStG) und Ihnen als PDF mit der Buchungsbestätigung gesendet. + +Außerdem speichern wir in der Anfrage einen Hashwert Ihrer IP-Adresse (nicht die IP-Adresse selbst; er wird mit einem geheimen Schlüssel des Servers berechnet, sodass sich daraus keine IP-Adresse ableiten lässt). Wir begrenzen damit die Zahl der Anfragen je IP-Adresse und schützen den Buchungskalender so vor automatisierten Massenanfragen. Das ist unser berechtigtes Interesse (Art. 6 Abs. 1 lit. f DSGVO); Sie können dieser Verarbeitung widersprechen (Art. 21 DSGVO). Wir verwenden den Hashwert nur dafür und entfernen ihn, sobald wir Ihre Anfrage freigeben oder ablehnen, spätestens nach 30 Tagen. + +### Zahlung über Stripe + +[Nur aufnehmen, wenn die Online-Zahlung eingeschaltet ist.] Wenn Sie online zahlen, werden Sie auf die Zahlungsseite der Stripe Payments Europe, Limited, 1 Grand Canal Street Lower, Grand Canal Dock, Dublin, D02 H210, Irland („Stripe“) weitergeleitet. Die Zahlung geht direkt auf unser Stripe-Konto. Karten- und Kontodaten geben Sie nur dort ein; wir und der technische Betreiber des Buchungskalenders erhalten sie nicht. Stripe verarbeitet Ihre Daten teils im Rahmen der Zahlungsabwicklung für uns und teils als eigener Verantwortlicher, zum Beispiel zur Betrugsvorbeugung und zur Erfüllung gesetzlicher Pflichten; dafür gilt die Datenschutzerklärung von Stripe (stripe.com/de/privacy). Dabei können Daten an die Stripe, LLC in den USA übermittelt werden. Die Stripe, LLC ist nach dem EU-US Data Privacy Framework zertifiziert, für das ein Angemessenheitsbeschluss der EU-Kommission besteht. Rechtsgrundlage ist Art. 6 Abs. 1 lit. b DSGVO. Zahlen Sie vor Ort, entfällt dieser Absatz für Sie. + +### E-Mails zu Ihrer Anfrage und Buchung + +Zu Ihrer Anfrage und Buchung senden wir Ihnen E-Mails an die angegebene E-Mail-Adresse: eine Bestätigung, dass Ihre Anfrage eingegangen ist, die Freigabe mit dem Link zur Buchungsseite oder die Absage, die Buchungsbestätigung mit den Vertragsangaben, den Stornobedingungen und der Rechnung, die Bestätigung eines Zahlungseingangs, einen Hinweis, wenn eine Reservierung abgelaufen ist, und bei einer Stornierung die Stornorechnung. Das sind Mitteilungen zur Abwicklung Ihres Vertrags (Art. 6 Abs. 1 lit. b DSGVO), keine Werbung. Bis zum Versand liegt jede E-Mail in einer Warteschlange; nach dem Versand wird Empfängeradresse und Inhalt dort gelöscht, der Eintrag selbst nach sieben Tagen. Der Link zur Buchungsseite enthält ein geheimes Kennzeichen; behandeln Sie ihn vertraulich. + +### Besuch der Seite + +Beim Aufruf der Seite lädt Ihr Browser das Programm des Buchungskalenders und die Belegung von der Adresse project.webklar.com. Dabei werden Ihre IP-Adresse, Datum und Uhrzeit des Aufrufs sowie Angaben zu Ihrem Browser und Betriebssystem übertragen und für 14 Tage in Server-Protokollen gespeichert, um den sicheren und störungsfreien Betrieb zu gewährleisten (Art. 6 Abs. 1 lit. f DSGVO). Der Buchungskalender setzt keine Cookies. Zum Schutz vor Missbrauch begrenzen wir die Zahl der Anfragen je IP-Adresse; die Zeitpunkte der Aufrufe werden nur im Arbeitsspeicher des Servers gehalten. Mit Ihrer Anfrage wird Ihre IP-Adresse nicht gespeichert, sondern nur der oben beschriebene Hashwert. + +### Abgleich mit anderen Plattformen + +[Nur aufnehmen, wenn der Vermieter Kalender einbindet.] Wir gleichen die Belegung unserer Unterkünfte mit [Booking.com, Airbnb, …] über Kalenderdateien (iCal) ab, damit eine Unterkunft nicht doppelt vergeben wird. Dabei werden nur belegte Zeiträume ausgetauscht, keine Namen oder anderen Angaben zu Gästen. + +### Weitergabe + +Wir geben Ihre Daten nur weiter, soweit das für die Vertragsabwicklung nötig ist (technischer Betreiber des Buchungskalenders als Auftragsverarbeiter, Stripe bei Online-Zahlung) oder wir gesetzlich dazu verpflichtet sind (zum Beispiel an das Finanzamt oder, soweit vorgeschrieben, an die Meldebehörde). Eine Weitergabe zu Werbezwecken findet nicht statt. + +### Speicherdauer + +Anfragen, aus denen keine Buchung wird, anonymisiert das System nach sechs Monaten. Für gebuchte Aufenthalte sind wir als Vermieter verpflichtet, Rechnungen und Buchungsbelege nach Handels- und Steuerrecht aufzubewahren (in der Regel acht bis zehn Jahre, § 257 HGB, § 147 AO; Art. 6 Abs. 1 lit. c DSGVO); dafür bewahrt das System die Rechnungen und die Rechnungsadresse acht Jahre auf, solange der Buchungskalender läuft. Name, Firma, E-Mail-Adresse, Telefonnummer und Nachricht eines gebuchten Aufenthalts werden drei Jahre nach dem Ende des Jahres Ihrer Abreise anonymisiert. + +### Ihre Rechte + +Sie haben das Recht auf Auskunft über Ihre Daten (Art. 15 DSGVO), auf Berichtigung (Art. 16), Löschung (Art. 17), Einschränkung der Verarbeitung (Art. 18), Datenübertragbarkeit (Art. 20) und auf Widerspruch gegen Verarbeitungen, die auf Art. 6 Abs. 1 lit. f DSGVO beruhen (Art. 21). Wenden Sie sich dazu an uns unter [E-Mail-Adresse des Vermieters]; wir leiten Ihre Anfrage, soweit nötig, an den technischen Betreiber des Buchungskalenders weiter. Außerdem können Sie sich bei einer Datenschutz-Aufsichtsbehörde beschweren, etwa bei der für uns zuständigen Behörde [zuständige Aufsichtsbehörde des Vermieters]. diff --git a/docs/funktionen/unterkunft-einbau.md b/docs/funktionen/unterkunft-einbau.md new file mode 100644 index 0000000..79d6615 --- /dev/null +++ b/docs/funktionen/unterkunft-einbau.md @@ -0,0 +1,91 @@ +# Buchungskalender auf der Kundenwebsite einbauen + +Anleitung für das WEBklar-Team. Das Widget lässt Besucher auf der Website des Kunden („Vermieter“) einen Zeitraum im Kalender wählen und eine unverbindliche Anfrage senden. Unterkünfte, Preise, Anfragen, Rechnungen und die Verbindung zu Stripe pflegt der Vermieter im Kundenportal (Tab „Funktionen“, Kachel „Buchungskalender“, Reiter „Buchungen“). Den `siteKey` (16 Zeichen, a–z und 2–7) findest Du im Einrichtungs-Ticket und im Ticketsystem (WOMS): Kunde → Reiter „Funktionen“, Zeile Buchungskalender. Im Ticket stehen Snippet und Schritte schon fertig; dieses Dokument ist die Referenz dahinter. Ohne aktive Funktion oder ohne freigeschaltete Unterkunft ist nichts buchbar: Das Widget zeigt dann den Ausweichtext (Abschnitt 4). API-Vertrag: `docs/funktionen/unterkunft-api.md`. + +Der Buchungskalender ist an den Vertrag über den Betrieb der Website gekoppelt (Leistungsbeschreibung Buchungskalender Nr. 10), aber **nicht in der Software**: Das Portal schaltet ihn nicht von selbst ab. Das Abschalten zum Vertragsende machen wir von Hand (Abschnitt 8). + +## 1. Das Snippet + +```html +<div data-webklar-unterkunft="SITEKEY" data-api="https://project.webklar.com"> + <p>Der Buchungskalender ist gerade nicht erreichbar. Bitte schreiben Sie uns: info@beispiel.de</p> <!-- Ausweichtext, Abschnitt 4 --> +</div> +<script src="https://project.webklar.com/embed/unterkunft.js" defer></script> +``` + +Das Skript steht einmal pro Seite, vor `</body>`. Es hat keine Abhängigkeiten, setzt keine Cookies, lädt nichts von Dritten und fragt nur `project.webklar.com` an. Texte des Vermieters setzt das Skript nur als Text ein, nie als HTML. Das Widget rechnet nie selbst: Preise, Summen und belegte Nächte kommen fertig vom Server (die Anfrage ist unverbindlich; der Preis wird erst bei der Freigabe festgelegt). + +| Attribut | Pflicht | Bedeutung | +| --- | --- | --- | +| `data-webklar-unterkunft` | ja | der `siteKey` des Projekts | +| `data-api` | nein | Herkunft des Portals, Standard `https://project.webklar.com`. Bei Modul-Import, Tag-Manager oder nachgeladenem Skript ist `data-api` Pflicht. | + +## 2. Wohin damit + +1. Auf der Seite einen **Bereich „Anfrage“** (Anker `#anfrage` oder eine eigene Seite) anlegen und das Snippet an die Stelle des Formulars setzen. Ein bisheriges Anfrageformular wird ersetzt; Telefon und E-Mail des Vermieters stehen unter dem Kalender. Das `div` braucht Breite (normaler Blockcontainer; in einem Flex- oder Grid-Element ohne Breite schrumpft es auf null). +2. Layout: Das Widget zeigt zwei Spalten (Kalender links, Formular rechts) und unter 760 px Breite beide untereinander; der Kalender zeigt einen Monat, ab 1100 px Breite zwei. +3. Menüpunkt oder Knopf „Anfragen“ auf den Bereich verlinken. +4. **Mehrere Widgets** auf einer Seite sind nicht vorgesehen. Der Buchungskalender ist ein Widget je Website; mehrere Unterkünfte wählt der Gast im Widget (bei nur einer Unterkunft entfällt die Auswahl). + +Aussehen: Das Widget nimmt die Akzentfarbe aus den Einstellungen des Vermieters. Die Stile stehen in `@layer wku`, jede Regel der Kundenseite gewinnt also. Anpassen per CSS-Variablen auf dem `div`, in der Seiten-CSS oder auf `:root`, zum Beispiel `[data-webklar-unterkunft]{ --wku-akzent:#8a5a2b; --wku-akzent-text:#fff; }`: + +| Variable | Standard | +| --- | --- | +| `--wku-akzent` und `--wku-akzent-text` (Auswahl, Knöpfe; setze beide zusammen) | Akzentfarbe des Vermieters, sonst Standardblau und `#fff` | +| `--wku-hintergrund` | `#fff` | +| `--wku-text` | `#1f2937` | +| `--wku-rand` | `#858f9e` | +| `--wku-radius` | `10px` | +| `--wku-schrift`, `--wku-schrift-titel` | Schrift der Seite | + +Kontrast (WCAG 2.1 AA): Text auf dem Hintergrund und Schrift auf dem Akzent mindestens 4,5 : 1, Rand gegen den Hintergrund mindestens 3 : 1. Prüfe beim Abnehmen, ob globale Regeln des Themes (`button{…}`, `input{…}`) das Widget stören, und überschreibe sie gezielt (`[data-webklar-unterkunft] .wku-btn{ … }`). + +## 3. Datenschutz-Absatz (Pflicht vor dem Einbau) + +Bau das Widget erst ein, wenn der Absatz aus `docs/funktionen/unterkunft-datenschutz-absatz.md` in der Datenschutzerklärung der Website steht. Liegt sie in der Website, die WEBklar betreut, fügst Du ihn ein (gehört zur Einrichtung), Platzhalter und nicht Zutreffendes angepasst. Liegt sie woanders, schickst Du ihn dem Vermieter im Chat (Leistungsbeschreibung Nr. 5 Abs. 10). Dasselbe gilt für Impressum und Verlinkung der Datenschutzerklärung: Die Adresse der Datenschutzerklärung trägt der Vermieter in den Einstellungen ein; das Widget und die Buchungsseite verlinken sie. + +## 4. Ausweichtext + +Der Inhalt des `div` bleibt stehen, solange das Widget nicht lädt oder die Funktion nicht aktiv ist (zum Beispiel vor der Freischaltung, bei `UNTERKUNFT_ENABLED=off`, bei Wartung). Schreib dort Kontaktdaten des Vermieters hinein, damit niemand ohne Möglichkeit zur Anfrage bleibt. Ein aktives Widget ersetzt den Inhalt. + +## 5. Vor der Abnahme prüfen + +- Im Portal: mindestens eine aktive Unterkunft mit Preisen und Stornobedingungen, Firmendaten vollständig, Steuernummer oder USt-ID, Steuerart gewählt. Sonst ist die Funktion nicht freischaltbar. +- Der Datenschutz-Absatz steht in der Datenschutzerklärung. +- Auf dem Handy und am Desktop: Anreise und Abreise wählbar, belegte Nächte nicht wählbar, Mindestnächte und Höchstzahl der Personen werden geprüft, Anfrage senden zeigt die Nummer. +- Tastatur: Pfeiltasten im Kalender, Enter wählt; jeder Tag hat ein `aria-label` mit Datum und Status. +- Kein Konflikt mit globalen Stilen des Themes (Abschnitt 2). +- Testanfrage mit eigener Adresse: E-Mail G16 (Eingang) beim Gast, K31 beim Vermieter. + +## 6. Vorschau und Testanfrage + +1. Vorschau-Subdomain des Projekts (`<subdomain>.project.webklar.com`) ansehen. +2. Anfrage senden, im Portal unter „Buchungen → Anfragen“ öffnen, Preis prüfen, **Freigeben** (E-Mail G17 mit Buchungslink). +3. Buchungslink öffnen: Rechnungsadresse eintragen, Zahlart „vor Ort“ wählen, **„Zahlungspflichtig buchen“**. E-Mail G19 mit Rechnungs-PDF prüfen (Rechnung trägt Name und Daten des Vermieters, keinen WEBklar-Hinweis). +4. Online-Zahlung nur testen, wenn das Stripe-Konto verbunden ist (kleiner Betrag, danach im Portal stornieren und erstatten). +5. Im Portal „bezahlt (vor Ort)“ setzen, dann stornieren (Stornorechnung, E-Mail G22). +6. Testanfragen danach im Portal stornieren oder ablehnen; Sperren des Tests im Kalender entfernen. + +## 7. Was das Widget zeigt (Kurzüberblick) + +- Kalender mit belegten Nächten (durchgestrichen); vergangene Tage und Zeiträume über eine belegte Nacht hinweg sind nicht wählbar. Anreise am Abreisetag eines anderen Gastes ist möglich. +- Zusammenfassung des Zeitraums („12.–30. Nov. · 18 Nächte“), Personenzahl, Name, E-Mail, Telefon und Nachricht (optional), Firma (optional), Datenschutzhinweis. +- Schaltfläche „Anfrage senden“ (unverbindlich). Danach die Anfragenummer und der Hinweis, dass der Vermieter sich meldet. +- Die Buchung selbst läuft nicht im Widget, sondern auf der Buchungsseite bei WEBklar (Link in der E-Mail G17). + +## 8. Wenn der Vertrag über die Website endet (Abschalten von Hand) + +Der Buchungskalender läuft, solange WEBklar die Website des Vermieters betreibt (Leistungsbeschreibung Nr. 10). Die Software prüft das **nicht**. Du musst es selbst im Blick haben, wenn ein solcher Vertrag endet, gekündigt oder widerrufen wird: + +1. **Vorher** schreibst Du dem Vermieter eine E-Mail (oder Chat): Der Vertrag endet am TT.MM.JJJJ, damit endet auch der Buchungskalender. Er soll **seine Rechnungen als PDF herunterladen** (WEBklar löscht sie 90 Tage nach dem Abschalten), offene Anfragen bearbeiten und seine Gäste informieren. +2. **Zum Vertragsende** im Ticketsystem (WOMS): Kunde → Reiter „Funktionen“ → Buchungskalender → **„Abschalten“**. Danach nimmt das Widget keine Anfragen mehr an und zeigt den Ausweichtext; Reservierungen laufen aus. +3. Der Vermieter kann Anfragen, Buchungen und Rechnungen danach **90 Tage** lang im Portal lesen und die Rechnungen herunterladen. Danach löscht der tägliche Job automatisch alle Daten des Buchungskalenders; das Einrichtungs-Ticket bleibt als Arbeitsnachweis ohne Gästedaten. +4. Nimm nach den 90 Tagen das Snippet und den Menüpunkt aus der Website. +5. Beginnt **innerhalb der 90 Tage** wieder ein Vertrag über den Betrieb der Website, schaltest Du den Buchungskalender auf Wunsch des Vermieters in Textform ohne weitere Kosten wieder ein (WOMS → Funktionen → Buchungskalender → Aktivieren). +6. **Erstattung (Leistungsbeschreibung Nr. 10 Abs. 6):** Endet der Vertrag, bevor wir den Buchungskalender freigeschaltet haben, erstatten wir den gezahlten Einrichtungspreis (199 €) vollständig, in Stripe von Hand. Sonst gibt es keine Erstattung. + +Das Stripe-Konto des Vermieters bleibt in jedem Fall beim Vermieter; wir rühren es nicht an. + +## 9. Kalenderabgleich (iCal) einrichten + +Im Portal unter Buchungen → Unterkünfte & Preise → Kalenderabgleich: Der Vermieter trägt die iCal-Adresse von Booking.com oder Airbnb als Import ein (Name und `https`-Adresse) und kopiert die **Export-Adresse** des Buchungskalenders zu Booking.com („Kalender synchronisieren“) oder Airbnb. Der Abgleich ist zeitversetzt (Minuten bis Stunden, Leistungsbeschreibung Nr. 4); sag das dem Vermieter, damit er vor jeder Freigabe seine anderen Plattformen prüft. diff --git a/docs/funktionen/unterkunft-livegang.md b/docs/funktionen/unterkunft-livegang.md new file mode 100644 index 0000000..424f0a4 --- /dev/null +++ b/docs/funktionen/unterkunft-livegang.md @@ -0,0 +1,115 @@ +# Buchungskalender – Livegang + +Reihenfolge für den Inhaber. Jeder Schritt braucht seine Freigabe; nichts davon hat Claude gegen Produktion, das Live-Stripe-Konto oder die Website Donau Home ausgeführt. Code: Portal `feature/unterkunft`, WOMS `feature/unterkunft`. Erste Kundin ist Mimi (Donau Home, MIMI FEWO, Website `WEBklar/donau-home`, lokaler Klon `/root/reports/donau-home-website`). + +**Wichtig beim Pushen:** Den Feature-Zweig nie unter seinem eigenen Namen pushen. Der Portal-Webhook deployt jeden Zweig. Immer mit Zielzweig: + +- Portal: `git push origin feature/unterkunft:main` +- WOMS: `git push origin feature/unterkunft:test` + +## 0. Voraussetzung + +- TP2, Webshop und Öffnungszeiten-Zweig liegen schon auf `origin/main` (Portal) bzw. `test` (WOMS) oder werden vorher gemerged: Das Funktionen-Register, die Mail-Warteschlange (`termineOutbox`) und die Connect-Anbindung stammen von dort. `git merge origin/main` im Worktree, Tests laufen lassen. Erwartbare Konflikte: `server/config.js` (features), `public/funktionen.js`, `test/mailTemplates.test.js` (Vorlagen-IDs: K31 bis K34, G16 bis G22, T22 sind für den Buchungskalender vergeben, vor dem Merge gegen `main` prüfen). +- Die Rechtstexte der Fassung 2026-10-07 liegen als HTML und PDF im Zweig (`public/rechtliches/*-2026-10-07.*`, siehe Schritt 6). + +## 1. Inhaber prüft die Texte + +Vom Inhaber freizugeben, bevor irgendetwas live geht: + +- `docs/rechtliches/leistungsbeschreibung-unterkunft.md` und `avv-unterkunft.md` (beide „Entwurf – Prüfung durch Kanzlei offen“), +- `docs/rechtliches/unterkunft-datenschutz-6f-entwurf.md`, +- `docs/funktionen/unterkunft-datenschutz-absatz.md` und `unterkunft-storno-muster.md`, +- `docs/rechtliches/unterkunft-kanzlei-fragen.md` (Fragen U1 bis U12 für die Kanzlei). + +Ändert sich ein Text, gibt es eine neue Fassung (neues Datum in `config.unterkunft.fassung` und im Zustimmungs-Pin der Bestelltexte); ausgelieferte Fassungen werden nie überschrieben. + +## 2. Datenbank (vor dem Deploy) + +Zuerst die Datenbank, dann der Schalter (Livegang-Reihenfolge aus `docs/funktionen/unterkunft-api.md`): + +```bash +cd /home/webklar/apps/kundenbereich.webklar.com/build +docker exec -w /app webklar-kundenbereich-server node scripts/unterkunft-setup.mjs --check +docker exec -w /app webklar-kundenbereich-server node scripts/unterkunft-setup.mjs # legt ukUnterkuenfte, ukPreise, ukSperren, ukAnfragen, ukRechnungen, ukEinstellungen samt Indizes an +docker exec -w /app webklar-kundenbereich-server node scripts/termine-setup.mjs --check +docker exec -w /app webklar-kundenbereich-server node scripts/termine-setup.mjs # zieht das Attribut anhang der Mail-Warteschlange nach (Rechnung als Anhang) +``` + +Die Skripte müssen aus dem neuen Code laufen (nach Schritt 5 oder vorher aus dem Worktree mit derselben Umgebung). `termine-setup.mjs` ändert nichts an vorhandenen Daten, es fügt nur fehlende Attribute und Indizes hinzu. + +## 3. Stripe-Preis + +```bash +docker exec -w /app webklar-kundenbereich-server node scripts/stripe-products.mjs --pruefen +docker exec -w /app webklar-kundenbereich-server node scripts/stripe-products.mjs --anlegen # legt unterkunftSetup (199 €, Lookup-Key webklar_unterkunft_einrichtung_19900) an +``` + +Der vorhandene Connect-Webhook (`https://project.webklar.com/api/shop/stripe-webhook`) bleibt unverändert; er leitet nach dem Metadatum `wkUk` an den Buchungskalender weiter. Kontrolle im Stripe-Dashboard: Die Ereignisse `account.updated`, `checkout.session.completed`, `checkout.session.async_payment_succeeded`, `checkout.session.async_payment_failed`, `checkout.session.expired` und `charge.refunded` sind schon eingetragen (Webshop-Livegang). + +## 4. Server-Konfiguration (Pilot) + +Sicherungen zuerst: `cp /home/webklar/apps/docker-compose.yml /home/webklar/apps/docker-compose.yml.bak-2026-10-07-unterkunft` und `(umask 077; cp /home/webklar/apps/.env /home/webklar/apps/.env.bak-2026-10-07-unterkunft)` (`.env` enthält Zugangsdaten). + +In `/home/webklar/apps/.env`: +``` +UNTERKUNFT_ENABLED=pilot +UNTERKUNFT_PILOT_EMAILS=kenso.gri@gmail.com,<Mimis Portal-Adresse> +``` +In `/home/webklar/apps/docker-compose.yml` beim Dienst `kundenbereich-server` neben `ZEITEN_ENABLED` und `SHOP_ENABLED` zwei Zeilen: +``` + - UNTERKUNFT_ENABLED=${UNTERKUNFT_ENABLED:-off} + - UNTERKUNFT_PILOT_EMAILS=${UNTERKUNFT_PILOT_EMAILS:-} +``` +Prüfen mit `docker compose -f /home/webklar/apps/docker-compose.yml config -q` (keine Ausgabe = gültig), dann übernehmen mit `docker compose -f /home/webklar/apps/docker-compose.yml up -d --no-deps kundenbereich-server`. Ein bloßes `docker restart` liest neue Umgebungswerte nicht. Das alles vor dem Push (Schritt 5): Der Container läuft dann mit dem alten Code und den neuen Werten (die kennt er nicht, harmlos), und der Neustart durch den Deploy nach dem Push ist der einzige mit dem neuen Code. Rückweg: `UNTERKUNFT_ENABLED=off`, Compose neu anwenden; das Schema ist rein additiv, es gibt nichts zurückzubauen. + +## 5. Push (durch den Inhaber) + +- Portal: `git push origin feature/unterkunft:main` (der Webhook deployt), +- WOMS: `git push origin feature/unterkunft:test`. + +Nie `git push origin feature/unterkunft` (eigener Name). Danach prüfen: `https://project.webklar.com/embed/unterkunft.js` antwortet 200; `https://project.webklar.com/rechtliches/leistungsbeschreibung-unterkunft.html` und `…/avv-unterkunft.html` antworten 200. + +## 6. Rechtstexte in WOMS „Rechtliches“ hochladen (macht Claude) + +Das macht Claude selbst (Wunsch des Inhabers). Dafür legt der Inhaber vorher den **kurzlebigen** Appwrite-Schlüssel mit dem Recht für Rechtliches unter `/root/.appwrite-rechtliches.key` ab und löscht ihn danach. Claude legt (falls nötig, `scripts/setup-legal.mjs` im WOMS) die Karten „Leistungsbeschreibung Buchungskalender“ und „AVV Buchungskalender“ an und lädt die Fassung 2026-10-07 hoch: + +- `public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.pdf` +- `public/rechtliches/avv-unterkunft-2026-10-07.pdf` + +(Die Widerrufsbelehrung `widerrufsbelehrung-funktionen-2026-10-07.pdf` ist ein Anhang der Bestellmail und der Bestellseite; sie ist inhaltlich die der Funktionen.) + +## 7. Mimi freischalten und Donau Home einbauen + +1. WOMS → Kunde (Mimi) → Funktionen → Buchungskalender → **„Aktivieren (ohne Zahlung)“** (`action: 'activate'`; der Weg für Kunden, die die Funktion als Teil ihres Projekts bekommen; Pilot-Adressen brauchen keine Textform). +2. Mimi richtet im Portal ein: Unterkünfte, Preise, Stornobedingungen (Muster `docs/funktionen/unterkunft-storno-muster.md`), Firmendaten, Steuerart, optional Stripe; mit dem Team zusammen. +3. **siteKey in Donau Home:** den `siteKey` aus dem Ticket oder dem WOMS in `/root/reports/donau-home-website/index.html` im Abschnitt `#anfrage` einsetzen (`data-webklar-unterkunft="SITEKEY"`), das Skript `https://project.webklar.com/embed/unterkunft.js` einbinden, CSS-Variablen (`--wku-*`) auf Palette A (Eiche & Leinen) und Schrift Figtree stellen, den Datenschutz-Absatz in die Datenschutzerklärung der Website einfügen, den Einleitungstext anpassen. Einbau nach `docs/funktionen/unterkunft-einbau.md`. +4. Donau Home pushen (Inhaber, nicht Claude); die Vorschau zeigt das Widget, solange `UNTERKUNFT_ENABLED=pilot` mit Mimis siteKey läuft. + +## 8. Pilot mit Mimi + +1. Testanfrage im Widget (eigene Adresse): Mails G16 und K31 prüfen. +2. Im Portal freigeben (G17), Buchungslink öffnen, „vor Ort“ buchen (G19 mit Rechnung als PDF, K32). +3. Rechnung prüfen: Mimis Name und Anschrift, Steuernummer oder USt-ID, Nummer lückenlos, Steuerart, kein WEBklar-Hinweis. +4. Mit Stripe-Konto: Online-Zahlung mit kleinem Betrag testen (G20), dann stornieren mit Erstattung (G22, Stornorechnung). +5. Stornieren (Stornorechnung), Testbuchungen wieder entfernen; iCal-Import und -Export mit einem Test-Kalender prüfen. + +## 9. Datenschutz § 6f übernehmen + +Den Abschnitt 6f aus `docs/rechtliches/unterkunft-datenschutz-6f-entwurf.md` in `public/datenschutz.html` übernehmen (hinter 6d, vor Abschnitt 7; Abschnitt 12 anpassen), danach `FORCE=1 scripts/build-legal-pdfs.sh datenschutz`. Erst mit der Freigabe des Inhabers. + +## 10. Freigabe für alle + +- Kanzlei-Fragen (`unterkunft-kanzlei-fragen.md`) beantworten lassen, Befund einarbeiten (neue Fassung, falls sich Texte ändern; neue Texte hochladen wie in Schritt 6). +- Dann `UNTERKUNFT_ENABLED=on` in `.env`, Compose neu anwenden (wie Schritt 4). + +## PDFs der Rechtstexte erzeugen + +Die PDFs entstehen aus den HTML-Seiten auf dem Host mit Chrome (Memory prüfen, `free -m` > 1500 MB verfügbar): + +```bash +node --max-old-space-size=512 scripts/build-legal-html.mjs unterkunft # schreibt die HTML-Seiten +node --max-old-space-size=512 scripts/build-legal-html.mjs unterkunft --check # Exit 0 = ok +nice scripts/build-legal-pdfs.sh unterkunft # druckt die PDFs samt .sha256 +``` + +Änderst Du einen Text, HTML neu erzeugen und die PDFs neu drucken (Prüfsumme entscheidet, was neu gedruckt wird; `FORCE=1` druckt alle neu). diff --git a/docs/funktionen/unterkunft-storno-muster.md b/docs/funktionen/unterkunft-storno-muster.md new file mode 100644 index 0000000..c1bf68a --- /dev/null +++ b/docs/funktionen/unterkunft-storno-muster.md @@ -0,0 +1,35 @@ +# Muster: Stornobedingungen für den Buchungskalender + +**Vorlage, keine Rechtsberatung.** Entwurf, Prüfung durch Kanzlei offen (`docs/rechtliches/unterkunft-kanzlei-fragen.md`, Frage U11). Der Vermieter ist für seine Stornobedingungen allein verantwortlich (Leistungsbeschreibung Buchungskalender Nr. 5 Abs. 3 und Nr. 6). Das Portal bietet diesen Text in den Einstellungen („Mustertext Stornobedingungen zum Übernehmen“) an; der Vermieter prüft ihn, passt ihn an seinen Betrieb an und kann ihn von einer Rechtsanwältin oder einem Rechtsanwalt prüfen lassen. Ohne Stornobedingungen kann der Buchungskalender nicht freigeschaltet werden. + +Hinweise für das Team: + +- Die Bedingungen werden bei der Freigabe einer Anfrage als Schnappschuss in der Anfrage gespeichert; die Buchungsseite und die Buchungsbestätigung zeigen genau diese Fassung. Eine spätere Änderung gilt nur für neue Freigaben. +- Der Buchungskalender erstattet eine Online-Zahlung nur auf Anweisung des Vermieters (Stornieren mit Erstattungsbetrag 0 bis Gesamtbetrag); die Staffel unten ist Text, die Software wendet sie nicht von selbst an. Der Vermieter trägt den Betrag beim Stornieren selbst ein. +- Zahlt der Gast vor Ort, entfällt eine Erstattung; die Stornierung stellt die Stornorechnung aus. +- Gäste können nicht selbst stornieren: Sie schreiben dem Vermieter. Der Text sagt das. +- Prozentsätze und Fristen sind Platzhalter und Beispiele; der Vermieter wählt eigene Werte. Pauschalen müssen den üblichen Schaden angemessen berücksichtigen (§ 309 Nr. 5 BGB); bei Verbrauchern sind überhöhte Pauschalen unwirksam. + +--- + +## Stornobedingungen (Muster) + +**1. Stornierung durch den Gast.** Eine Stornierung der Buchung ist nur in Textform möglich (E-Mail an [E-Mail-Adresse des Vermieters]) und wird erst mit unserer Bestätigung wirksam; wir stornieren die Buchung in unserem System und senden Ihnen eine Stornorechnung. Maßgeblich für die Frist ist der Eingang Ihrer Nachricht bei uns. + +**2. Kosten der Stornierung.** Bei einer Stornierung berechnen wir folgenden Anteil des Gesamtpreises (ohne Endreinigung, soweit der Aufenthalt nicht angetreten wird): +- bis [30] Tage vor der Anreise: kostenfrei, +- [29] bis [14] Tage vor der Anreise: [30] Prozent, +- [13] bis [7] Tage vor der Anreise: [60] Prozent, +- ab [6] Tage vor der Anreise und bei Nichtanreise: [90] Prozent. + +Ihnen bleibt der Nachweis gestattet, dass uns kein oder ein geringerer Schaden entstanden ist. Uns bleibt unser Anspruch unberührt, wenn wir die Unterkunft anderweitig vermieten können: In diesem Fall berechnen wir nur den tatsächlichen Ausfall. + +**3. Erstattung.** Haben Sie bereits online bezahlt, erstatten wir den Teil des Preises, der nach Nr. 2 nicht anfällt, auf das Zahlungsmittel, mit dem Sie bezahlt haben. Die Erstattung geht über unser Stripe-Konto; die Gutschrift auf Ihrem Konto kann einige Tage dauern. Haben Sie noch nicht bezahlt, zahlen Sie den nach Nr. 2 anfallenden Betrag vor Ort oder nach Rechnung. + +**4. Verspätete Anreise und vorzeitige Abreise.** Reisen Sie später an oder früher ab, besteht kein Anspruch auf Erstattung des Preises für die nicht genutzten Nächte, es sei denn, wir können die Unterkunft anderweitig vermieten. + +**5. Stornierung durch uns.** Können wir die Unterkunft aus einem Grund, den wir zu vertreten haben, nicht bereitstellen, stornieren wir die Buchung, bieten nach Möglichkeit eine gleichwertige Unterkunft an und erstatten bereits gezahlte Beträge vollständig. + +**6. Kein Widerrufsrecht.** Für die Buchung zu einem bestimmten Zeitraum besteht kein gesetzliches Widerrufsrecht (§ 312g Abs. 2 Nr. 9 BGB). Diese Stornobedingungen gelten stattdessen. + +**7. Reiserücktrittsversicherung.** Wir empfehlen Ihnen eine Reiserücktrittsversicherung. diff --git a/docs/rechtliches/avv-unterkunft.md b/docs/rechtliches/avv-unterkunft.md new file mode 100644 index 0000000..9ce7e68 --- /dev/null +++ b/docs/rechtliches/avv-unterkunft.md @@ -0,0 +1,157 @@ +# Auftragsverarbeitungsvertrag Buchungskalender (Art. 28 DSGVO) + +**Fassung 2026-10-07** · Entwurf – Prüfung durch Kanzlei offen + +zwischen dem Kunden als Verantwortlichem („Kunde“; in der Leistungsbeschreibung „Vermieter“) und der WEBklar GbR, Am Schwimmbad 10, 67722 Winnweiler, vertreten durch die Gesellschafter Kenso Grimm und Justin Klein, als Auftragsverarbeiter („WEBklar“). + +## Vorbemerkung: Abschluss und Verhältnis zu anderen Verträgen + +(1) Der Kunde schließt diesen Vertrag, wenn er im Kundenportal die Einrichtung des Buchungskalenders bestellt und dabei per Haken diesem Vertrag und der Leistungsbeschreibung „Buchungskalender“ („Leistungsbeschreibung“) in der angezeigten Fassung zustimmt. Das Portal speichert die Fassung, den Zeitpunkt, das Kundenkonto und die angemeldete Person. Anschließend sendet WEBklar dem Kunden eine E-Mail, die beide Texte und die Widerrufsbelehrung in dieser Fassung als PDF enthält und auf sie verlinkt. + +(2) Ein Mitarbeiter von WEBklar darf die Funktion auch ohne Bestellung im Portal einschalten (zum Beispiel für einen Kunden, dem WEBklar sie als Teil seines Website-Projekts bereitstellt), aber nur, wenn der Kunde vorher in Textform (etwa im Chat des Kundenportals oder per E-Mail) erklärt hat, dass er diesem Vertrag und der Leistungsbeschreibung in der aktuellen Fassung zustimmt. Das Portal verlangt dafür das Datum und den Weg der Erklärung; fehlt eine Angabe, schaltet es nicht ein. WEBklar speichert vor dem Einschalten einen Zustimmungsnachweis mit der Fassung der beiden Texte, dem Datum und dem Weg dieser Erklärung, dem Zeitpunkt des Einschaltens und dem Namen des Mitarbeiters (ohne IP-Adresse und Browser-Kennzeichen, weil der Kunde nicht im Portal zugestimmt hat). Der Kunde erhält anschließend eine E-Mail mit diesen beiden Texten als PDF. + +(3) Dieser Vertrag ist ein eigener Vertrag für den Buchungskalender. Er ergänzt den Auftragsverarbeitungsvertrag in Anlage 1 der Abo-Bedingungen. Für den Buchungskalender geht er Anlage 1 vor; im Übrigen gilt Anlage 1 ergänzend. In Datenschutzfragen geht er den Abo-Bedingungen und der Leistungsbeschreibung vor. + +(4) Die Rollen: Der Kunde ist Verantwortlicher für die personenbezogenen Daten seiner Gäste im Buchungskalender. WEBklar ist sein Auftragsverarbeiter. Stripe ist nicht Auftragsverarbeiter von WEBklar, sondern Vertragspartner des Kunden (Nummer 7 Abs. 4). Die Plattformen, deren Kalender der Kunde einbindet (zum Beispiel Booking.com oder Airbnb), sind weder Auftragsverarbeiter noch Unterauftragsverarbeiter von WEBklar. + +## 1. Gegenstand und Dauer + +(1) WEBklar betreibt für die öffentliche Website des Kunden ein Buchungs-Widget mit einer Buchungsseite und einer Verwaltung im Kundenportal („Buchungskalender“) und verarbeitet dabei personenbezogene Daten der Gäste des Kunden im Auftrag des Kunden. Den Umfang beschreibt die Leistungsbeschreibung. + +(2) Der Vertrag beginnt mit dem Einschalten der Funktion. Er endet mit dem Abschalten, spätestens mit dem Ende des Vertrags, aufgrund dessen WEBklar die Website des Kunden betreibt; den Buchungskalender schaltet WEBklar dann zum Vertragsende ab (Nr. 10 Abs. 1 der Leistungsbeschreibung). Die Pflichten aus diesem Vertrag gelten fort, bis alle Daten nach Nummer 9 gelöscht sind. + +## 2. Art und Zweck der Verarbeitung + +(1) Art: Übermitteln der Anfrage und der Buchung vom Widget und von der Buchungsseite an den Server von WEBklar, Speichern, Verwalten und Anzeigen im Kundenportal, Berechnen des Preises, Erzeugen von Rechnungen und Stornorechnungen im Namen des Kunden (Nr. 3 Abs. 6 der Leistungsbeschreibung), Abgleichen von Kalendern, Versenden von E-Mails, Übernehmen von Zahlungsstatus aus Stripe, Weitergeben von Erstattungen an Stripe im Auftrag des Kunden, Anonymisieren und Löschen. + +(2) Zwecke: Der Kunde soll Anfragen und Buchungen seiner Gäste abwickeln. Dazu nimmt der Buchungskalender Anfragen entgegen, reserviert Zeiträume nach der Freigabe durch den Kunden, nimmt die verbindliche Buchung des Gastes entgegen, stellt die Rechnung aus, gleicht Online-Zahlungen mit Stripe ab, bildet Zahlungen vor Ort ab, bildet Stornierungen ab und benachrichtigt den Kunden. WEBklar versendet die E-Mails im Auftrag des Kunden. Außerdem schützt WEBklar den Buchungskalender für den Kunden vor Missbrauch (Mengenbegrenzung, Begrenzung der Anfragen je IP-Adresse, Erkennen automatisierter Anfragen). + +(3) WEBklar verwendet die Daten für keine eigenen Zwecke, auch nicht in anonymisierter Form und nicht für Auswertungen über mehrere Kunden. Es findet keine Werbung und keine Zusammenführung mit anderen Daten statt. WEBklar bildet keine Profile einzelner Gäste. Zählungen ohne Personenbezug, die WEBklar für den sicheren Betrieb braucht (etwa die Zahl der anonymisierten Anfragen je Tag oder die Länge der Versandwarteschlange), sind keine eigenen Zwecke. + +## 3. Datenarten und Betroffene + +(1) Daten der Gäste, die WEBklar aus dem Widget, von der Buchungsseite und aus Stripe erhält und speichert: +- bei der Anfrage: Name, E-Mail-Adresse, auf Wunsch Firma, Telefonnummer und eine Nachricht, die gewünschte Unterkunft, der Zeitraum, die Zahl der Personen, die Anfragenummer, ein Hashwert der IP-Adresse (Absatz 4) und der Zeitpunkt; +- bei der Freigabe: die Posten und Summen des Preises (Text, Menge, Einzelbetrag, Steuersatz), die Reservierungsfrist, eine Nachricht des Kunden an den Gast, die Stornobedingungen, die galten, und die Fassung der Rechtstexte, der der Gast gesehen hat, jeweils als Schnappschuss; +- bei der Buchung: die Rechnungsadresse (Name, Firma, Straße, Postleitzahl, Ort, Land), die Zahlart, der Zeitpunkt der Buchung und die Rechnungsnummer; +- bei der Zahlung und der Erstattung: Status, Zeitpunkt, Art (online über Stripe oder vor Ort), die Kennungen der Zahlung bei Stripe, erstattete Beträge und der Grund einer Stornierung; +- die Rechnung und die Stornorechnung als unveränderlicher Schnappschuss (Angaben des Ausstellers, Empfänger, Unterkunft, Zeitraum, Posten, Summen, Steuerart, Bezug), aus dem WEBklar das PDF bei jedem Abruf erzeugt; +- ein Hashwert des geheimen Zugangs zur Buchungsseite (der Link in der E-Mail wird nur als Prüfsumme gespeichert); +- der Zustellstatus der E-Mails an den Gast. + +**Kartendaten und Kontodaten (IBAN) des Gastes erhält und speichert WEBklar nicht;** die gibt der Gast nur bei Stripe ein. Die Bankverbindung des Kunden selbst (Angabe auf der Rechnung) und seine Firmen- und Steuerangaben gehören nicht zu den Gästedaten. + +(2) Von Kalendern anderer Plattformen übernimmt WEBklar nur die belegten Zeiträume (Datum von und bis), nicht Namen, Beschreibungen oder andere Angaben der dortigen Buchungen, auch wenn der Kalender sie enthält. Die iCal-Adresse, die WEBklar dem Kunden bereitstellt, enthält nur belegte Nächte, keine Angaben zu Gästen. Wer die geheime Adresse kennt, sieht die belegten Nächte; der Kunde kann sie jederzeit erneuern. + +(3) Besondere Kategorien personenbezogener Daten (Art. 9 DSGVO) werden nicht verarbeitet. Der Kunde fordert von seinen Gästen keine entsprechenden Angaben und bittet sie, solche Angaben nicht in das Nachrichtenfeld zu schreiben (Nummer 11 Abs. 4). Meldedaten nach dem Bundesmeldegesetz (Meldeschein) und Daten zur Kurtaxe verarbeitet der Buchungskalender nicht. + +(4) IP-Adresse und Browser-Kennzeichen (User-Agent) erhält der Server von WEBklar technisch bei jedem Abruf des Widgets und jeder Anfrage. Die Mengenbegrenzung (Missbrauchsschutz) verwendet die IP-Adresse im Arbeitsspeicher des Servers; ein Neustart leert sie. Mit der Anfrage werden weder eine IP-Adresse im Klartext noch ein Browser-Kennzeichen gespeichert, sondern nur ein **Hashwert der IP-Adresse („IP-Hash“)**: ein SHA-256-Wert, den WEBklar mit einem geheimen Schlüssel des Servers salzt. Der IP-Hash ist ein pseudonymes technisches Datum und bleibt ein personenbezogenes Datum, weil WEBklar mit dem Schlüssel für dieselbe IP-Adresse denselben Wert berechnen kann; ohne den Schlüssel lässt sich aus ihm keine IP-Adresse ableiten. WEBklar verwendet ihn ausschließlich zum Missbrauchsschutz. Er dient nicht dazu, Gäste zu identifizieren, wiederzuerkennen oder zu profilieren, wird dem Kunden weder angezeigt noch exportiert und steht nur im Datensatz der Anfrage. WEBklar entfernt ihn aus dem Datensatz, sobald der Kunde die Anfrage freigibt oder ablehnt, spätestens nach 30 Tagen (Nummer 9 Abs. 1). In den Server-Protokollen stehen IP-Adresse und Browser-Kennzeichen 14 Tage (Anlage 2 der Abo-Bedingungen). + +(5) Der Buchungskalender setzt keine Cookies. Das Widget und die Buchungsseite speichern im Browser des Besuchers keine personenbezogenen Daten dauerhaft; das Widget hält Eingaben nur im Arbeitsspeicher der geöffneten Seite. Soweit für die Funktion etwas im Sitzungsspeicher des Tabs abgelegt wird, ist es technisch erforderlich und verschwindet mit dem Tab. + +(6) Betroffene: Gäste, die über die Website des Kunden Anfragen stellen oder buchen, und Personen, deren Angaben der Gast in der Anfrage oder Buchung macht (zum Beispiel Mitreisende oder abweichende Rechnungsempfänger). Beschäftigte des Kunden sind von diesem Vertrag nicht betroffen. + +## 4. Weisungen + +(1) WEBklar verarbeitet die Daten nur auf dokumentierte Weisung des Kunden, auch in Bezug auf eine Übermittlung in ein Drittland oder an eine internationale Organisation. Das gilt nicht, wenn das Recht der Europäischen Union oder Deutschlands WEBklar zu einer Verarbeitung verpflichtet. In diesem Fall teilt WEBklar dem Kunden die Pflicht vorher mit, soweit das Gesetz es nicht verbietet. + +(2) Mit der Bestellung weist der Kunde WEBklar an, den Buchungskalender nach seinen Einstellungen und der Leistungsbeschreibung zu betreiben und in seinem Namen Rechnungen auszustellen. Weitere Weisungen ergeben sich aus den Einstellungen und Aktionen im Kundenportal (Unterkünfte, Preise, Sperren, Kalenderverbindungen, Freigabe und Ablehnung von Anfragen, Zahlungseingang vor Ort, Stornierungen und Erstattungen, Online-Zahlung, Öffnen und Schließen des Buchungskalenders). Sonstige Weisungen erteilt der Kunde in Textform, etwa im Chat des Kundenportals. Weisungen, die über diese Einstellungen hinausgehen, setzt WEBklar nur um, wenn das technisch vorgesehen ist; sonst kann der Kunde den Buchungskalender abschalten lassen (Nr. 10 Abs. 7 der Leistungsbeschreibung). Die Anonymisierung und Löschung auf Weisung nach Nummer 8 Abs. 2 und Nummer 9 Abs. 6 setzt WEBklar immer um, soweit Aufbewahrungspflichten dem nicht entgegenstehen (Nummer 9 Abs. 8). + +(3) Hält WEBklar eine Weisung für rechtswidrig, weist es den Kunden unverzüglich darauf hin. WEBklar darf die Ausführung aussetzen, bis der Kunde die Weisung ändert oder die Rechtslage geklärt ist. + +## 5. Vertraulichkeit + +WEBklar setzt nur Personen ein, die zur Vertraulichkeit verpflichtet sind oder einer gesetzlichen Verschwiegenheitspflicht unterliegen. + +## 6. Technische und organisatorische Maßnahmen + +(1) WEBklar trifft die Maßnahmen nach Art. 32 DSGVO, die in der Anlage zu diesem Vertrag beschrieben sind. WEBklar darf sie an den Stand der Technik anpassen, sofern das Schutzniveau nicht sinkt. + +(2) Für den Server gelten ergänzend die Maßnahmen der Anlage 2 der Abo-Bedingungen, soweit die Anlage zu diesem Vertrag nichts anderes regelt. + +## 7. Unterauftragsverarbeiter + +(1) Der Kunde genehmigt den Einsatz der Hetzner Online GmbH, Industriestraße 25, 91710 Gunzenhausen, für den Betrieb des Servers, auf dem der Buchungskalender läuft, und für dessen Sicherung (Rechenzentrum Falkenstein, Deutschland) sowie für den Versand der E-Mails über den SMTP-Dienst des Webhostings (Rechenzentrum Nürnberg, Deutschland). Eine Übermittlung in Drittländer findet nicht statt. + +(2) Will WEBklar einen weiteren Unterauftragsverarbeiter hinzuziehen oder einen ersetzen, teilt es das dem Kunden mindestens vier Wochen vorher in Textform mit. Der Kunde kann innerhalb von zwei Wochen nach Zugang der Mitteilung aus wichtigem datenschutzrechtlichem Grund in Textform widersprechen. WEBklar setzt den neuen Unterauftragsverarbeiter nicht vor Ablauf dieser Frist ein. Kündigt ein Unterauftragsverarbeiter von WEBklar eine eigene Änderung mit kürzerer Frist an, informiert WEBklar den Kunden unverzüglich, nachdem die Ankündigung eingegangen ist; der Kunde kann dann unverzüglich widersprechen. Einigen sich die Parteien nicht, kann der Kunde den Buchungskalender abschalten lassen und WEBklar ihn für diese Website zu dem Zeitpunkt beenden, zu dem der neue Unterauftragsverarbeiter eingesetzt wird. Die Daten werden dann nach Nummer 9 gelöscht, auf Weisung des Kunden früher (Nummer 9 Abs. 6). + +(3) WEBklar verpflichtet jeden Unterauftragsverarbeiter vertraglich auf die Datenschutzpflichten nach Art. 28 Abs. 4 DSGVO. Bei der Hetzner Online GmbH ist das deren Vertrag zur Auftragsverarbeitung, den WEBklar abgeschlossen hat. Kommt ein Unterauftragsverarbeiter seinen Datenschutzpflichten nicht nach, haftet WEBklar dem Kunden für die Einhaltung dieser Pflichten (Art. 28 Abs. 4 Satz 2 DSGVO). + +(4) **Stripe ist kein Unterauftragsverarbeiter von WEBklar.** Der Kunde verwendet sein eigenes Stripe-Konto und hat den Vertrag darüber unmittelbar mit Stripe geschlossen (Nr. 3 der Leistungsbeschreibung); die Zahlung des Gastes fließt direkt auf dieses Konto. Die Zahlungsseite (Stripe Checkout), die Erhebung von Zahlungs-, Karten- und Kontodaten, die Prüfung von Zahlungen und die Auszahlungen verantworten der Kunde und Stripe nach ihrem Vertrag; WEBklar erhält diese Daten nicht. Auf Weisung des Kunden legt WEBklar bei Stripe die Zahlung an, ruft die Angaben zu Zahlungen ab, die der Buchungskalender braucht (Nummer 2 Abs. 1), und veranlasst Erstattungen. Daten von Gästen gehen dabei nicht von WEBklar an Stripe, außer der Bezeichnung des Aufenthalts und der Rechnungsnummer auf der Zahlungsseite, der Kennung der Buchung, dem Betrag und der Erstattung selbst. Die Weitergabe von Daten durch Stripe, auch an Stellen außerhalb der Europäischen Union, regeln der Kunde und Stripe; dafür ist WEBklar nicht verantwortlich. + +(5) Plattformen, deren iCal-Kalender der Kunde einbindet oder denen er die iCal-Adresse des Buchungskalenders mitteilt, sind Empfänger nach seiner Entscheidung. WEBklar übermittelt ihnen keine Daten von Gästen. + +## 8. Unterstützung des Kunden, Betroffenenrechte + +(1) WEBklar leitet Anfragen von Gästen, die an WEBklar gerichtet sind, unverzüglich an den Kunden weiter. WEBklar unterstützt ihn mit geeigneten technischen und organisatorischen Maßnahmen bei der Beantwortung. + +(2) Dafür bietet das Kundenportal die Anzeige der Anfragen und Buchungen, mit denen der Kunde Auskunft erteilen kann, und den Abruf der Rechnungen als PDF. Auf Weisung des Kunden in Textform (etwa im Chat des Kundenportals) anonymisiert WEBklar die Gästedaten einer Anfrage oder Buchung unverzüglich: Name, Firma, E-Mail-Adresse, Telefonnummer und die Freitexte werden gelöscht oder unkenntlich gemacht (ein IP-Hash ist zu diesem Zeitpunkt in der Regel längst entfernt); Anfragenummer, Zeitraum, Beträge und Status bleiben. Rechnungen und Rechnungsadresse einer gebuchten Anfrage bleiben, solange eine Aufbewahrungspflicht besteht (Nummer 9 Abs. 3). Dabei löscht WEBklar die E-Mails zu dieser Anfrage, die noch auf den Versand warten. E-Mails, deren Versand endgültig fehlgeschlagen ist, behalten Empfängeradresse und Inhalt, bis WEBklar sie nach Nummer 9 Abs. 5 löscht (48 Stunden nach dem Fehlschlag). + +(3) Verletzungen des Schutzes personenbezogener Daten meldet WEBklar dem Kunden unverzüglich, möglichst innerhalb von 24 Stunden nach Kenntnis, mit den Informationen, die zu diesem Zeitpunkt vorliegen. + +(4) WEBklar unterstützt den Kunden bei seinen Pflichten aus Art. 32 bis 36 DSGVO. Dazu gehören die Angaben, die er für sein Verzeichnis von Verarbeitungstätigkeiten und für eine etwaige Datenschutz-Folgenabschätzung braucht. + +(5) Die Gäste informiert der Kunde (Art. 13 DSGVO; Nummer 11 Abs. 2). + +## 9. Löschung und Rückgabe + +(1) Den IP-Hash entfernt WEBklar aus dem Datensatz einer Anfrage, sobald der Kunde sie freigibt oder ablehnt, spätestens 30 Tage nach dem Anlegen. + +(2) Anfragen, aus denen keine Buchung wurde (abgelehnt, abgelaufen, oder neu und nicht innerhalb von 60 Tagen entschieden), anonymisiert WEBklar nach 6 Monaten: Name, Firma, E-Mail-Adresse, Telefonnummer und Nachricht werden gelöscht. Anfragenummer, Zeitraum, Status und, soweit vorhanden, der Preisvorschlag bleiben ohne Personenbezug erhalten. + +(3) Bei gebuchten Aufenthalten anonymisiert WEBklar die Gästedaten (Name, Firma, E-Mail-Adresse, Telefonnummer und Nachricht) 3 Jahre nach dem Ende des Kalenderjahres, in dem der Gast abgereist ist (Abreisejahr; maßgeblich ist die Zeit in Berlin). **Rechnungen, Stornorechnungen und die Rechnungsadresse bleiben 8 Jahre erhalten**, gerechnet ab dem Ende des Kalenderjahres der Rechnung, solange der Buchungskalender läuft (Buchungsbelege, § 147 AO); sie sind für den Kunden als Aussteller bestimmt. Anfragenummer, Zeitraum, Beträge und Status bleiben ebenfalls. + +(4) Die Anonymisierung nach den Absätzen 2 und 3 sowie die Entfernung des IP-Hash laufen im täglichen Löschlauf; anonymisiert oder entfernt wird frühestens nach Ablauf der jeweiligen Frist. Ist an einem Tag mehr zu bearbeiten, als ein Lauf schafft, folgt der Rest im nächsten Lauf. + +(5) In der Versandwarteschlange für E-Mails leert WEBklar die Empfängeradresse und den Inhalt einer E-Mail nach dem Versand und löscht den Eintrag 7 Tage nach dem Versand. E-Mails, die nicht zugestellt werden können, löscht WEBklar mit Empfängeradresse und Inhalt 48 Stunden nach dem endgültigen Fehlschlag. + +(6) Ist der Buchungskalender abgeschaltet oder der Vertrag über den Betrieb der Website beendet, kann der Kunde die Anfragen, Buchungen und Rechnungen 90 Tage lang im Kundenportal lesen und die Rechnungen einzeln als PDF herunterladen; WEBklar weist ihn vor dem Abschalten per E-Mail darauf hin. Danach löscht WEBklar alle Daten des Buchungskalenders: Unterkünfte, Preise, Anfragen, Buchungen, Rechnungen, Kalenderverbindungen, Sperren und Einstellungen. Damit endet auch die Aufbewahrung der Rechnungen nach Absatz 3; sie bewahrt der Kunde dann selbst auf. Eine Ausnahme ist das Einrichtungs-Ticket, in dem WEBklar die Einrichtung als Arbeitsnachweis festhält: Es bleibt mit einer Kurzfassung der Angaben zur Einrichtung bestehen (zum Beispiel Adresse der Website, Einbau-Code und die Angaben des Kunden aus der Anfrage) und enthält keine Daten von Gästen; dafür gilt die Datenschutzerklärung von WEBklar (Abschnitt 6). Beginnt innerhalb dieser Frist wieder ein Vertrag über den Betrieb der Website, schaltet WEBklar den Buchungskalender auf Wunsch des Kunden mit den vorhandenen Daten wieder ein (Nr. 10 Abs. 5 der Leistungsbeschreibung). Früher anonymisiert WEBklar einzelne Daten auf Weisung des Kunden (Nummer 8 Abs. 2); alle Daten des Buchungskalenders löscht WEBklar auf Weisung des Kunden in Textform unverzüglich. + +(7) Die Daten sind in der täglichen Vollsicherung des Servers enthalten (§ 3 Abs. 5 der Abo-Bedingungen). Gelöschte oder anonymisierte Daten bleiben dort bis zu sieben Tage erhalten und werden dann überschrieben. Wird eine Sicherung zurückgespielt, holt der tägliche Löschlauf die fälligen Löschungen und Anonymisierungen nach; Löschungen auf Weisung des Kunden wiederholt WEBklar. + +(8) Gesetzliche Aufbewahrungspflichten bleiben unberührt. Der Kunde ist für seine eigenen Aufbewahrungspflichten (zum Beispiel für Rechnungen und Buchungsbelege) selbst verantwortlich; WEBklar ist kein Archiv im Sinne der Buchführung. Die Aufbewahrung der Rechnungen nach Absatz 3 geschieht als Dienst für den Kunden und für die Dauer des Buchungskalenders. Der Kunde sichert die Belege, die er braucht, rechtzeitig vor der Löschung nach Absatz 6 durch den Download. Soweit eine gesetzliche Aufbewahrungspflicht besteht, löscht oder anonymisiert WEBklar auch auf Weisung des Kunden nicht früher; stattdessen sperrt es die Daten für die weitere Verarbeitung. + +## 10. Nachweise und Kontrollen + +WEBklar stellt dem Kunden alle Informationen zur Verfügung, die zum Nachweis der Pflichten aus Art. 28 DSGVO nötig sind, und ermöglicht Überprüfungen einschließlich Inspektionen durch den Kunden oder einen von ihm beauftragten, zur Verschwiegenheit verpflichteten Prüfer. Sie finden nach Anmeldung mit angemessener Frist (in der Regel 14 Tage) zu den Servicezeiten statt, ohne den Betrieb unzumutbar zu stören. Für das Rechenzentrum genügen in der Regel die Nachweise des Betreibers (Zertifizierung der Hetzner Online GmbH nach ISO/IEC 27001). Für mehr als eine Vor-Ort-Kontrolle pro Jahr kann WEBklar eine angemessene Vergütung verlangen. + +## 11. Pflichten des Kunden + +(1) Der Kunde ist Verantwortlicher für die Verarbeitung der Daten seiner Gäste im Buchungskalender. + +(2) Der Kunde informiert seine Gäste nach Art. 13 DSGVO. Dazu nimmt er den Datenschutz-Absatz für den Buchungskalender in seine Datenschutzerklärung auf (Nr. 5 Abs. 10 der Leistungsbeschreibung) und nennt in seinen Rechtstexten (Datenschutzerklärung, Impressum) die Angaben, die das Gesetz verlangt. + +(3) Der Kunde schließt mit Stripe den Vertrag über sein Stripe-Konto selbst, wenn er die Online-Zahlung nutzt, und verantwortet die Verarbeitung von Daten durch Stripe, soweit sie nicht in diesem Vertrag geregelt ist (Nummer 7 Abs. 4). + +(4) Der Kunde fordert von seinen Gästen keine Angaben zu ihrer Gesundheit oder zu anderen besonderen Kategorien personenbezogener Daten und weist sie auf der Website darauf hin, solche Angaben nicht in das Nachrichtenfeld zu schreiben. + +(5) Der Kunde verändert den Einbau-Code und die gesetzlich vorgeschriebenen Hinweise des Widgets und der Buchungsseite nicht (Nr. 5 Abs. 9 der Leistungsbeschreibung). + +(6) Der Kunde erfüllt seine Pflichten zu Meldeschein, Kurtaxe und sonstigen Meldungen an Behörden selbst und verarbeitet die dafür nötigen Daten außerhalb des Buchungskalenders (Nr. 5 Abs. 6 der Leistungsbeschreibung). + +## 12. Haftung, Änderungen, Schlussbestimmungen + +(1) Gegenüber betroffenen Personen gilt Art. 82 DSGVO. Für die Haftung zwischen Kunde und WEBklar gilt § 13 der Abo-Bedingungen. + +(2) Eine neue Fassung dieses Vertrags oder der Leistungsbeschreibung, auch wegen geänderter Datenerhebung, teilt WEBklar dem Kunden mindestens sechs Wochen vor ihrem Wirksamwerden in Textform mit. Sie wird wirksam, wenn der Kunde ihr im Kundenportal oder in Textform zustimmt. Stimmt er nicht zu, gilt die bisherige Fassung weiter. + +(3) Ist die neue Fassung nötig, weil ein Gesetz, eine Gerichtsentscheidung oder eine Vorgabe einer Aufsichtsbehörde den Betrieb in der bisherigen Form nicht mehr zulässt, und stimmt der Kunde ihr nicht zu, darf WEBklar den Buchungskalender für seine Website nach Nr. 12 Abs. 2 der Leistungsbeschreibung beenden oder nach Nr. 12 Abs. 3 der Leistungsbeschreibung aussetzen. Das Abo bleibt davon unberührt. + +(4) Im Übrigen gilt § 16 der Abo-Bedingungen. + +## Anlage: Technische und organisatorische Maßnahmen des Buchungskalenders (Art. 32 DSGVO) + +| Bereich | Maßnahmen | +|---|---| +| Übertragung | Das Widget, die Buchungsseite und das Kundenportal werden nur über TLS (HTTPS) übertragen. Der Einbau-Code verweist auf eine Adresse mit https://. Die Zahlung geschieht auf der Zahlungsseite von Stripe. Kalender anderer Plattformen ruft WEBklar nur über https ab. | +| Speicher im Browser | Es werden keine Cookies gesetzt. Das Widget sendet seine Anfragen ohne Cookies und ruft nur die Schnittstelle des Buchungskalenders auf, keine Dienste Dritter. | +| Zugriffskontrolle | Das Kundenportal ist nur nach Anmeldung erreichbar; jeder Kunde sieht nur die Daten seiner eigenen Projekte. Die öffentliche Schnittstelle des Widgets liefert nur für einen vorhandenen Buchungskalender Daten und ist über den Website-Schlüssel (Site-Key) adressiert; die belegten Nächte nennt sie ohne Quelle und ohne Daten von Gästen. Die Buchungsseite ruft der Gast nur mit einem geheimen Token ab, das nur als Prüfsumme gespeichert und zeitkonstant verglichen wird. Benachrichtigungen von Stripe werden nur nach Prüfung ihrer Signatur verarbeitet; die Schlüssel für Stripe liegen nur auf dem Server. Die iCal-Adresse des Buchungskalenders ist ein geheimer, erneuerbarer Zufallswert. | +| Missbrauchsschutz | Ein verstecktes Feld (Honeypot), eine Mindestzeit bis zum Absenden des Formulars mit signiertem Formular-Token und Grenzen je IP-Adresse und je Buchungskalender schützen vor automatisierten Anfragen. Die Grenzen gelten im Arbeitsspeicher; ein Neustart leert sie. Mit der Anfrage wird nur ein gesalzener IP-Hash gespeichert (Nummer 3 Abs. 4). Beim Abruf von Kalendern anderer Plattformen sind nur Adressen mit https erlaubt, private und lokale Ziele sind gesperrt, und Größe und Dauer des Abrufs sind begrenzt. | +| Datenminimierung | Kartendaten und Kontodaten erhält und speichert WEBklar nicht. Preise berechnet der Server aus den gespeicherten Preisen und Posten, nie aus Angaben des Browsers. Von anderen Kalendern werden nur Zeiträume übernommen. Mit der Anfrage werden keine IP-Adresse im Klartext und kein Browser-Kennzeichen gespeichert; der IP-Hash wird mit der Entscheidung des Kunden entfernt. Die Gästedaten werden nach den Fristen der Nummer 9 anonymisiert. Nach dem Versand einer E-Mail werden Empfängeradresse und Inhalt in der Warteschlange geleert. | +| Integrität der Rechnungen | Rechnungen und Stornorechnungen werden als unveränderlicher Schnappschuss gespeichert; das PDF entsteht bei jedem Abruf aus diesem Schnappschuss. Rechnungsnummern werden unter Sperre lückenlos je Kunde und Jahr vergeben. Freigabe und Buchung prüfen unter Sperre erneut, dass der Zeitraum frei ist. | +| Trennung | Alle Unterkünfte, Anfragen und Rechnungen tragen die Kennung des Kunden, des Projekts und der Funktion; das Kundenportal und die öffentliche Schnittstelle lesen immer nur die Daten des jeweiligen Buchungskalenders. Die Hintergrundläufe (Ablauf von Reservierungen, Kalenderabgleich, Versand der E-Mails, Anonymisierung und Löschung) schreiben jeweils nur in das Dokument, um das es geht. | +| Löschung | Täglicher Löschlauf für Anfragen, Buchungen und Warteschlange nach den Fristen der Nummer 9; die Daten abgeschalteter Buchungskalender 90 Tage nach dem Abschalten; das Einrichtungs-Ticket bleibt als Arbeitsnachweis mit einer Kurzfassung der Angaben zur Einrichtung bestehen und enthält keine Daten von Gästen (Nummer 9 Abs. 6). | +| Protokolle | Die Programmprotokolle des Buchungskalenders und der Tagesbericht enthalten nur Zählungen und Anfragenummern, keine Namen, E-Mail-Adressen oder Adressen von Gästen. Server-Protokolle des Webservers werden nach 14 Tagen gelöscht (Anlage 2 der Abo-Bedingungen). | +| Datensicherung | Tägliche Vollsicherung des Servers durch Hetzner; verfügbar sind die letzten sieben Tagessicherungen (§ 3 Abs. 5 der Abo-Bedingungen). | +| Rechenzentrum | Hetzner Online GmbH, Rechenzentren Falkenstein und Nürnberg (Deutschland). Hetzner ist nach ISO/IEC 27001 zertifiziert; der Geltungsbereich umfasst die Hosting-Dienstleistungen und die Rechenzentren. | +| Organisation | Verpflichtung aller Beteiligten auf Vertraulichkeit, Ablauf für Datenschutzverletzungen (Nummer 8 Abs. 3), Überprüfung der Maßnahmen mindestens einmal im Jahr. | diff --git a/docs/rechtliches/leistungsbeschreibung-unterkunft.md b/docs/rechtliches/leistungsbeschreibung-unterkunft.md new file mode 100644 index 0000000..6c8b918 --- /dev/null +++ b/docs/rechtliches/leistungsbeschreibung-unterkunft.md @@ -0,0 +1,194 @@ +# Leistungsbeschreibung Buchungskalender + +**Fassung 2026-10-07** · Entwurf – Prüfung durch Kanzlei offen · Zusatzbedingungen zum Vertrag über den Betrieb der Website + +## 1. Geltung + +(1) Diese Leistungsbeschreibung regelt die Funktion „Buchungskalender“. Mit dem Buchungskalender nimmt der Kunde über seine Website Anfragen für die Vermietung von Unterkünften entgegen (Ferienwohnungen, Monteurzimmer, kleine Pensionen) und rechnet die Aufenthalte ab („Vermieter“); Gäste sind die Besucher seiner Website, die im Buchungskalender anfragen und buchen („Gäste“). Die Leistungsbeschreibung ist eine Zusatzleistung zum Vertrag über den Betrieb der Website: Sie setzt voraus, dass WEBklar die Website des Vermieters aufgrund eines Vertrags betreibt, etwa im Hosting-Abo, im Wartungs-Abo oder aufgrund eines anderen Vertrags über den Betrieb der Website. Sie richtet sich nur an Unternehmer, die in eigenem Namen und für eigene Rechnung vermieten. + +(2) Sie wird vereinbart, wenn der Vermieter die Einrichtung des Buchungskalenders im Kundenportal bestellt und dabei dieser Leistungsbeschreibung, dem Auftragsverarbeitungsvertrag Buchungskalender („AVV Buchungskalender“) und der Widerrufsbelehrung zustimmt. Wie die Zustimmung abläuft, regelt die Vorbemerkung des AVV Buchungskalender. Bestellen kann der Vermieter erst, nachdem WEBklar seine Anfrage für den Buchungskalender geprüft und angenommen hat (Nr. 2 Abs. 1). Für einen Vermieter, dem WEBklar die Funktion als Teil seines Website-Projekts bereitstellt, schaltet WEBklar sie nach seiner Zustimmung in Textform frei; die Bedingungen dieser Leistungsbeschreibung gelten dann ebenso, ein Einrichtungspreis fällt nur an, wenn er vereinbart ist. + +(3) Im Übrigen gelten die Abo-Bedingungen. Bei Widersprüchen geht für den Buchungskalender diese Leistungsbeschreibung vor, in Datenschutzfragen der AVV Buchungskalender. + +(4) Leistungsbeschreibung A Nr. 2 Abs. 3 und Nr. 4 sowie Leistungsbeschreibung B Nr. 3 der Abo-Bedingungen (Formulare mit Server, „Rechtstexte … nicht enthalten“) stehen dem Buchungskalender nicht entgegen. Das Widget des Buchungskalenders läuft auf dem Server von WEBklar, nicht auf dem Server der Website, und der Muster-Text zur Stornierung nach Nr. 6 ist Teil des Buchungskalenders. Das gilt auch im Hosting-Abo. + +## 2. Leistung + +(1) Der Vermieter fragt den Buchungskalender im Kundenportal an und beschreibt seine Unterkünfte (Art der Unterkunft, Zahl der Einheiten, ob er Booking.com oder Airbnb nutzt). WEBklar prüft die Anfrage und nimmt sie an oder lehnt sie mit einer Begründung ab. Ein Anspruch auf Annahme besteht nicht. Erst nach der Annahme kann der Vermieter die Einrichtung bestellen. + +(2) Die Einrichtung umfasst den Einbau eines Kalender-Widgets an einer Stelle der Website des Vermieters, die Bereitstellung der Verwaltung im Kundenportal, den Einbau des Datenschutz-Absatzes für den Buchungskalender (Nr. 5 Abs. 10) und die Freischaltung durch WEBklar. Für jede Website wird ein Buchungskalender eingerichtet; er kann mehrere Unterkünfte desselben Vermieters enthalten. Zusätzlich gibt es für jeden freigegebenen Aufenthalt eine Buchungsseite bei WEBklar, die der Gast über den Link in seiner E-Mail erreicht. + +(3) So läuft eine Buchung ab: +- Das Widget zeigt dem Gast die belegten Nächte. Er wählt Anreise und Abreise, gibt Personenzahl, Namen, E-Mail-Adresse und auf Wunsch Firma, Telefonnummer und Nachricht an und sendet eine **unverbindliche Anfrage**. Er erhält eine Eingangsbestätigung, der Vermieter eine Benachrichtigung. +- Der Vermieter prüft die Anfrage im Kundenportal, sieht den vorgerechneten Preis, kann die Posten ändern und gibt die Anfrage mit einer Reservierungsfrist frei oder lehnt sie ab. Gibt er sie frei, reserviert der Buchungskalender die Nächte bis zum Ablauf der Frist, und der Gast erhält eine E-Mail mit Preis, Stornobedingungen und dem Link zur Buchungsseite. +- Auf der Buchungsseite sieht der Gast alle Angaben zum Aufenthalt, trägt seine Rechnungsadresse ein, wählt die Zahlart (online über Stripe, wenn der Vermieter sie eingeschaltet hat, oder vor Ort) und bucht mit der Schaltfläche „Zahlungspflichtig buchen“. Erst damit kommt der Vertrag zwischen Vermieter und Gast zustande, nicht schon mit der Anfrage oder der Freigabe. +- Mit der Buchung erzeugt der Buchungskalender eine Rechnung mit lückenloser Nummer und sendet dem Gast eine Buchungsbestätigung mit der Rechnung als PDF; der Vermieter wird benachrichtigt. +- Verstreicht die Frist ohne Buchung, läuft die Reservierung ab und die Nächte werden frei; der Gast erhält darüber eine E-Mail. +- Der Vermieter kann einen Aufenthalt stornieren. Dann erhält der Gast eine Stornorechnung mit eigener Nummer und, soweit der Vermieter eine Online-Zahlung erstattet, eine Mitteilung über den Erstattungsbetrag. Eine Stornierung durch den Gast gibt es im Widget nicht; er wendet sich an den Vermieter. + +(4) Im Kundenportal verwaltet der Vermieter: +- Unterkünfte mit Beschreibung, Höchstzahl der Personen, Mindestnächten und Check-in- und Check-out-Zeiten, +- Preise (Staffel nach Aufenthaltsdauer, Endreinigung, Zusatzpersonen, Direktbuchungsrabatt, Steuerart und Steuersätze) und seine Stornobedingungen, +- Anfragen und Buchungen mit Status, die Eintragung „bezahlt (vor Ort)“ und Stornierungen, +- Kalender mit manuellen Sperren, +- die Verbindungen zu anderen Kalendern (Nr. 4), +- seine Rechnungen als PDF, +- seine Angaben als Aussteller der Rechnungen (Name, Anschrift, Steuernummer oder Umsatzsteuer-Identifikationsnummer, Bankverbindung, Rechnungspräfix) und die Verbindung mit seinem Stripe-Konto (Nr. 3). + +(5) Der Buchungskalender versendet im Namen des Vermieters E-Mails an die Gäste: Eingang der Anfrage, Freigabe mit Buchungslink, Ablehnung, Buchungsbestätigung mit Rechnung, Zahlungseingang, Ablauf der Reservierung und Stornierung. Absender ist die Versandadresse von WEBklar mit dem Namen des Vermieters, als Antwortadresse dient seine E-Mail-Adresse. Den Vermieter benachrichtigt der Buchungskalender über neue Anfragen und neue Buchungen sowie, wenn der Abgleich mit einem anderen Kalender seit mindestens sechs Stunden fehlschlägt. + +(6) Der Buchungskalender enthält einen Missbrauchsschutz gegen automatisierte Anfragen (verstecktes Feld, Mindest-Ausfüllzeit, Obergrenzen je IP-Adresse). Dafür speichert WEBklar mit der Anfrage nur einen Hashwert der IP-Adresse, nicht die IP-Adresse selbst; er wird entfernt, sobald der Vermieter die Anfrage freigibt oder ablehnt, spätestens nach 30 Tagen (Nummer 3 Abs. 4 des AVV Buchungskalender). + +(7) Nicht enthalten sind: +- der Meldeschein nach dem Bundesmeldegesetz und die Verwaltung der Meldedaten, +- Kurtaxe, Gästebeitrag und Beherbergungsabgaben, +- Anzahlungen und Teilzahlungen (der Gast zahlt den Gesamtbetrag in einer Zahlung, online oder vor Ort), +- Sofortbuchung ohne Freigabe, +- saisonale Preise (die Preise richten sich nur nach der Aufenthaltsdauer), +- Gutscheine, Channel-Manager-Anbindungen außer dem Kalenderabgleich nach Nr. 4 und Mehrsprachigkeit (der Buchungskalender ist deutschsprachig), +- die Buchführung des Vermieters. + +Zusätzliche Wünsche, etwa ein Sonderdesign, ein zweiter Buchungskalender oder eine über das übliche Maß hinausgehende Zahl von Unterkünften, gehören nicht zur Einrichtung nach Nr. 9. WEBklar führt sie nach Absprache nach Stunden aus (Nr. 9 Abs. 5). + +## 3. Zahlungen über Stripe und Rechnungen im Namen des Vermieters + +(1) Online-Zahlungen im Buchungskalender sind optional und laufen über Stripe Connect. Der Vermieter verbindet dazu sein eigenes Stripe-Konto mit dem Buchungskalender. Hat er für den Webshop von WEBklar bereits ein Stripe-Konto verbunden, kann er es auch für den Buchungskalender verwenden. Den Vertrag über dieses Konto schließt der Vermieter unmittelbar mit Stripe; WEBklar ist daran nicht beteiligt. Für das Konto, die Prüfung des Vermieters durch Stripe und die Auszahlungen gelten die Bedingungen von Stripe. Ohne verbundenes und freigeschaltetes Stripe-Konto ist nur die Zahlart „vor Ort“ möglich. + +(2) Das Geld der Gäste fließt direkt an den Vermieter (Zahlung unmittelbar auf dem Konto des Vermieters, sogenannte Direct Charge). WEBklar erhält und verwahrt kein Geld der Gäste, leitet keines weiter und beteiligt sich nicht am Umsatz des Vermieters. WEBklar ist kein Zahlungsdienstleister. Die Gebühren von Stripe trägt der Vermieter; sie fallen nur zwischen dem Vermieter und Stripe an. + +(3) Der Vermieter prüft selbst, ob sein Stripe-Konto Zahlungen annehmen und Auszahlungen leisten kann. WEBklar zeigt ihm im Kundenportal den Stand, den Stripe meldet, hat aber keinen Einfluss darauf, ob und wann Stripe ein Konto freischaltet, einschränkt oder sperrt, und haftet dafür nicht. Rückbuchungen, Streitfälle mit Gästen und Zahlungsausfälle regeln der Vermieter und Stripe. + +(4) Erstattungen bei einer Stornierung veranlasst der Vermieter im Kundenportal; WEBklar führt die Erstattung über das Stripe-Konto des Vermieters aus. Er bestimmt den Betrag bis zur Höhe der Zahlung des Gastes. Erstattungen aus dem Stripe-Dashboard trägt WEBklar in die Buchung nach, soweit Stripe sie meldet. + +(5) Die Zahlungsseite selbst (Stripe Checkout) betreibt Stripe. Kartendaten und Kontodaten gibt der Gast nur dort ein; WEBklar erhält sie nicht. + +(6) **Rechnungen im Namen des Vermieters.** Der Vermieter beauftragt WEBklar mit der Zustimmung bei der Bestellung, in seinem Namen und für seine Rechnung Rechnungen und Stornorechnungen an seine Gäste auszustellen (Rechnung durch einen Dritten im Namen und im Auftrag des Leistenden, § 14 Abs. 2 Satz 4 UStG). Aussteller der Rechnung ist der Vermieter; sie trägt seinen Namen, seine Anschrift, seine Steuernummer oder Umsatzsteuer-Identifikationsnummer und keinen Hinweis auf WEBklar. WEBklar erzeugt die Rechnung aus den Angaben, die der Vermieter hinterlegt und bei der Freigabe bestätigt hat. Er verantwortet die Richtigkeit seiner Angaben, der Preise, der Steuerart und der Steuersätze; WEBklar prüft sie nicht steuerrechtlich. Die Rechnung wird nach ihrer Ausstellung nicht mehr verändert; Fehler korrigiert der Vermieter durch Stornierung und neue Buchung nach den Möglichkeiten des Kundenportals. Die Zustimmung zu diesem Auftrag gibt der Vermieter bei der Bestellung und bestätigt sie in den Einstellungen des Buchungskalenders. Widerruft er den Auftrag in Textform, stellt der Buchungskalender keine Rechnungen mehr aus und ist für ihn nicht mehr nutzbar. + +(7) Die Rechnungsnummern sind je Vermieter und Jahr lückenlos fortlaufend; sie bestehen aus dem Präfix, das der Vermieter vor der ersten Rechnung festlegt, dem Jahr und einer laufenden Nummer. + +## 4. Verfügbarkeit und Kalenderabgleich (iCal) + +(1) Der Vermieter kann Kalender anderer Plattformen (zum Beispiel Booking.com oder Airbnb) über eine iCal-Adresse einlesen lassen; die eingelesenen Zeiträume blockiert der Buchungskalender. Umgekehrt stellt der Buchungskalender dem Vermieter eine geheime iCal-Adresse bereit, die er bei anderen Plattformen einträgt; sie enthält die belegten Nächte ohne Daten der Gäste. Der Vermieter kann diese Adresse jederzeit erneuern; die bisherige Adresse funktioniert dann nicht mehr. + +(2) Der Abgleich läuft regelmäßig, aber zeitversetzt: WEBklar liest die Kalender anderer Plattformen etwa alle 15 Minuten ein, und die anderen Plattformen lesen die Adresse des Buchungskalenders nach ihrem eigenen Takt, oft nur alle paar Stunden. **Zwischen einer Buchung hier und ihrem Eingang dort können deshalb Minuten bis Stunden vergehen, und umgekehrt.** WEBklar sagt keine Echtzeit-Verfügbarkeit zu und übernimmt keine Gewähr dafür, dass eine Unterkunft nicht doppelt gebucht wird. + +(3) Dieses Risiko mindert die Freigabe: Jede Anfrage im Buchungskalender braucht die Freigabe des Vermieters. Er prüft vor der Freigabe seine anderen Plattformen und seinen Kalender. Beim Freigeben und beim Buchen prüft der Buchungskalender zusätzlich, ob die Nächte nach seinem Stand frei sind. Eine Doppelbuchung entsteht trotzdem, wenn eine andere Plattform eine Buchung noch nicht gemeldet hat oder der Abgleich ausfällt. Der Vermieter löst eine Doppelbuchung selbst (etwa durch Stornierung) und trägt die Folgen gegenüber seinen Gästen und den Plattformen. + +(4) Fehlerhafte oder nicht erreichbare iCal-Adressen kann WEBklar nicht beheben. Schlägt der Abruf fehl, bleibt der zuletzt gelesene Stand erhalten, und der Vermieter wird benachrichtigt, wenn der Abruf seit mindestens sechs Stunden nicht gelungen ist (höchstens einmal je 24 Stunden und Kalender). Eingelesen werden nur Zeiträume von gestern bis 18 Monate in die Zukunft, höchstens 1 Megabyte je Kalender; nur Adressen mit https werden abgerufen. + +## 5. Pflichten des Vermieters + +(1) Der Vermieter hat einen laufenden Vertrag mit WEBklar über den Betrieb seiner Website (Hosting-Abo, Wartungs-Abo oder ein anderer Vertrag über den Betrieb der Website), ist Unternehmer und vermietet in eigenem Namen. Will er Online-Zahlungen nutzen, stellt er sein eigenes Stripe-Konto bereit und schließt die Anmeldung bei Stripe selbst ab. + +(2) Er verantwortet seine Unterkünfte, Preise und Angaben zum Angebot. Dazu gehören richtige Preise einschließlich Steuerausweis (Umsatzsteuer, für die Beherbergung und die Endreinigung nach den dafür geltenden Steuersätzen, oder Hinweis auf § 19 UStG), Check-in- und Check-out-Zeiten, Höchstbelegung, Mindestnächte und alle Angaben, die er seinen Gästen vor der Buchung geben muss. Die Steuerart und die Steuersätze trägt er selbst im Kundenportal ein; WEBklar berät dazu nicht. + +(3) Er legt vor der Freischaltung seine Stornobedingungen fest und verantwortet sie. Der Muster-Text nach Nr. 6 ist nur ein Vorschlag. + +(4) Er verantwortet die Verfügbarkeit seiner Unterkünfte, pflegt Sperren und Kalenderverbindungen im Kundenportal und prüft regelmäßig auf neue Anfragen und Buchungen. Die Folgen von Angaben, die er setzt (zum Beispiel einer fälschlich freien oder gesperrten Zeit), trägt er. + +(5) Er gibt Anfragen nur frei, wenn er die Unterkunft für den Zeitraum zu den angegebenen Bedingungen bereitstellen kann, und erfüllt die gebuchten Aufenthalte. Er trägt alle Pflichten eines Vermieters gegenüber seinen Gästen, auch Gewährleistung, Kundenservice und Beschwerden. + +(6) Er erfüllt seine gesetzlichen Pflichten rund um die Beherbergung selbst. Das betrifft insbesondere den Meldeschein nach dem Bundesmeldegesetz, die Kurtaxe und andere kommunale Abgaben, Anzeige- und Genehmigungspflichten für die Vermietung (zum Beispiel Zweckentfremdungs- oder Gewerberecht) sowie die Pflichten aus seinem Steuerrecht. Der Buchungskalender nimmt ihm davon nichts ab. + +(7) Anzahlungen und Teilzahlungen bietet der Buchungskalender nicht an. Vereinbart der Vermieter außerhalb des Buchungskalenders etwas anderes mit seinem Gast, ist das nicht Gegenstand dieser Leistungsbeschreibung. + +(8) Er erfüllt seine Aufbewahrungspflichten selbst, etwa nach der Abgabenordnung und dem Handelsgesetzbuch. WEBklar ist kein Archiv für die Buchführung und kein Buchführungssystem. WEBklar bewahrt die Rechnungen des Vermieters im Buchungskalender 8 Jahre auf, solange der Buchungskalender läuft und nach Nr. 10 bis zur Löschung, hält sie ihm zum Abruf als PDF bereit und anonymisiert personenbezogene Daten der Gäste nach Nummer 9 des AVV Buchungskalender. Der Vermieter lädt seine Rechnungen deshalb rechtzeitig vor der Löschung nach Nr. 10 Abs. 3 herunter und bewahrt sie selbst auf. + +(9) Er hält die Vorgaben dieser Leistungsbeschreibung ein und verändert den Einbau-Code und die gesetzlich vorgeschriebenen Hinweise des Widgets und der Buchungsseite nicht. + +(10) Liegt die Datenschutzerklärung in der von WEBklar betreuten Website, fügt WEBklar beim Einbau dort den Datenschutz-Absatz für den Buchungskalender ein; das gehört zur Einrichtung. Liegt sie woanders, erhält der Vermieter den Absatz als Textbaustein und fügt ihn selbst ein. Für den übrigen Inhalt seiner Datenschutzerklärung bleibt er verantwortlich (§ 6 Abs. 3 der Abo-Bedingungen). Fällt WEBklar beim Einfügen ein offensichtlicher Widerspruch auf, weist WEBklar den Vermieter darauf hin; eine Pflicht zur Prüfung der Datenschutzerklärung entsteht daraus nicht. + +(11) Der Vermieter informiert seine Gäste nach Art. 13 DSGVO. Die Rollen im Datenschutz regelt der AVV Buchungskalender: Der Vermieter ist Verantwortlicher, WEBklar Auftragsverarbeiter, Stripe Vertragspartner des Vermieters. + +## 6. Muster-Text zur Stornierung, keine Rechtsberatung + +(1) WEBklar stellt dem Vermieter einen Muster-Text für Stornobedingungen bereit. Er ist eine **Vorlage ohne Gewähr** und keine Rechtsberatung (kein Rechtsrat im Sinne des Rechtsdienstleistungsgesetzes). Er passt zur Technik des Buchungskalenders, kann aber auf den Betrieb des Vermieters nicht zugeschnitten sein. + +(2) WEBklar empfiehlt, die Stornobedingungen und die Angaben zum Angebot vor der Freischaltung von einer Rechtsanwältin oder einem Rechtsanwalt prüfen zu lassen. + +(3) Der Vermieter bleibt für seine Stornobedingungen und alle seine Texte verantwortlich, auch wenn er den Muster-Text unverändert übernimmt (Nr. 5 Abs. 3). Die Stornobedingungen, die bei der Freigabe galten, speichert der Buchungskalender mit der Anfrage; die Buchungsseite und die Buchungsbestätigung zeigen dem Gast diese Fassung. + +## 7. Kein Widerrufsrecht des Gastes, Hinweise auf der Buchungsseite + +(1) Für die Buchung von Beherbergungsleistungen zu einem bestimmten Zeitpunkt oder in einem bestimmten Zeitraum besteht nach § 312g Abs. 2 Nr. 9 BGB kein gesetzliches Widerrufsrecht. Die Buchungsseite weist den Gast darauf hin; der Vermieter kann ihm vertraglich ein weitergehendes Recht einräumen, der Buchungskalender bietet dafür aber keine Funktion. + +(2) Die Buchungsseite zeigt dem Gast vor der Schaltfläche „Zahlungspflichtig buchen“ die wesentlichen Angaben nach Art. 246a EGBGB, soweit der Buchungskalender sie kennt (Anbieter, Unterkunft, Zeitraum, Leistung, Gesamtpreis, Zahlart, Stornobedingungen, Hinweis auf das fehlende Widerrufsrecht). Der Vermieter ergänzt, was darüber hinausgeht, in seinen Texten selbst (Nr. 5 Abs. 2). + +(3) Die Buchungsbestätigung erhält der Gast als E-Mail mit der Rechnung als PDF; sie enthält die Angaben zum Vertrag und die Stornobedingungen auf einem dauerhaften Datenträger. + +## 8. Verfügbarkeit und Störungen + +(1) Das Verfügbarkeitsziel nach § 5 der Abo-Bedingungen gilt für die Website, nicht für den Buchungskalender. WEBklar sagt für den Buchungskalender keine bestimmte Verfügbarkeit zu, die über den Betrieb der Website im Abo hinausgeht. Störungen des Buchungskalenders beheben wir in angemessener Frist (§ 12 der Abo-Bedingungen). + +(2) Angekündigte Wartungsfenster (§ 5 der Abo-Bedingungen) können den Buchungskalender kurzzeitig unterbrechen. Während einer Unterbrechung sind Anfragen und Buchungen nicht möglich; das Widget zeigt dann einen Ausweichtext. + +(3) Zahlungen übernimmt der Buchungskalender über Benachrichtigungen von Stripe und einen Abgleich beim Aufruf der Buchungsseite. Fällt die Verbindung zu Stripe oder zum Server aus, kann sich die Bestätigung einer Zahlung verzögern. Ausfälle von Stripe, von Zahlungsarten und von Banken liegen nicht im Einflussbereich von WEBklar. + +(4) Alle Zeiten gelten in der Zeitzone Europe/Berlin. + +(5) WEBklar übernimmt keine Gewähr dafür, dass E-Mails zugestellt und gelesen werden. Das hängt vom Postfach des Empfängers und von den Mailgrenzen seines Anbieters ab. + +(6) Die gesetzlichen Rechte des Vermieters sowie §§ 12 und 13 der Abo-Bedingungen bleiben unberührt. + +## 9. Preis, Abrechnung und Widerruf + +(1) Die Einrichtung kostet 199 € einmalig je Website-Projekt, ohne Umsatzsteuer gemäß § 19 UStG. Für den Betrieb des Buchungskalenders berechnet WEBklar nichts weiter; es gibt keine laufende Gebühr und keine Beteiligung am Umsatz oder an den Buchungen. Der Buchungskalender läuft, solange WEBklar die Website betreibt (Nr. 10). + +(2) Die Einrichtung dauert nach der Erfahrung von WEBklar meist 1 bis 2 Wochen ab der Bestellung. Sie hängt davon ab, wie schnell der Vermieter Unterkünfte, Preise und gegebenenfalls das Stripe-Konto bereitstellt und wie umfangreich der Einbau ist. Die Dauer ist eine Einschätzung und keine verbindliche Zusage eines Termins. + +(3) Der Vermieter bezahlt bei der Bestellung im Kundenportal über Stripe und erhält eine Rechnung. Für einen Vermieter, dem WEBklar die Funktion als Teil seines Website-Projekts bereitstellt (Nr. 1 Abs. 2), gilt die dafür getroffene Vereinbarung. + +(4) Der Preis steht neben den Leistungen eines Abos: Die Einrichtung wird weder auf ein Stundenkontingent angerechnet noch damit bezahlt. + +(5) Mehraufwand, der nicht zur Einrichtung gehört (Nr. 2 Abs. 7), führt WEBklar nur nach Absprache vor der Ausführung und nach Freigabe des Vermieters in Textform aus. WEBklar nennt vorher den geschätzten Aufwand und berechnet 100 € je Stunde in Schritten von 15 Minuten, ohne Umsatzsteuer gemäß § 19 UStG (§ 4 der Abo-Bedingungen). Der Mehraufwand wird gesondert berechnet und nicht auf ein Stundenkontingent angerechnet. + +(6) Verbraucher können die Bestellung der Einrichtung nach der Widerrufsbelehrung widerrufen. Belehrung und Muster-Widerrufsformular stehen in der Anlage „Widerrufsbelehrung und Muster-Widerrufsformular (Einrichtung von Funktionen)“. Ob das Widerrufsrecht erlischt und ob der Vermieter einen angemessenen Betrag für die bis dahin erbrachte Leistung schuldet, richtet sich nach der Zustimmung, die er bei der Bestellung gibt, und nach den Hinweisen zum Widerruf in der Anlage. Mit dem Widerruf endet der Buchungskalender. Dieses Widerrufsrecht des Vermieters gegenüber WEBklar ist vom Widerrufsrecht der Gäste gegenüber dem Vermieter (Nr. 7) zu unterscheiden. + +## 10. Laufzeit und Ende + +(1) Der Buchungskalender läuft, solange WEBklar die Website des Vermieters betreibt. Endet der Vertrag über den Betrieb der Website, endet auch der Buchungskalender; WEBklar schaltet ihn zum Vertragsende ab und informiert den Vermieter vorher per E-Mail und weist ihn darauf hin, seine Rechnungen als PDF herunterzuladen. Das gilt auch beim Widerruf dieses Vertrags. + +(2) Mit dem Abschalten nimmt der Buchungskalender keine neuen Anfragen und Buchungen mehr an, und das Widget zeigt den Ausweichtext. Reservierungen laufen aus. Bereits gebuchte Aufenthalte bleiben Verträge zwischen dem Vermieter und seinen Gästen; der Vermieter erfüllt sie und informiert seine Gäste, wenn er den Buchungskalender nicht mehr anbietet. Anfragen, Buchungen und Rechnungen bleiben im Kundenportal 90 Tage lesbar; Rechnungen kann er einzeln als PDF herunterladen. + +(3) WEBklar löscht alle Daten des Buchungskalenders, also Unterkünfte, Preise, Anfragen, Buchungen, Rechnungen, Kalenderverbindungen, Sperren und Einstellungen, 90 Tage nach dem Abschalten. Eine Ausnahme ist das Einrichtungs-Ticket, in dem WEBklar die Einrichtung als Arbeitsnachweis festhält: Es bleibt mit einer Kurzfassung der Angaben zur Einrichtung bestehen und enthält keine Daten von Gästen (Nummer 9 Abs. 6 des AVV Buchungskalender). Die Aufbewahrungsfrist der Rechnungen (Nr. 5 Abs. 8) endet damit mit der Löschung; der Vermieter bewahrt sie danach selbst auf. + +(4) Das Stripe-Konto bleibt beim Vermieter. Das Ende des Buchungskalenders berührt weder das Konto noch die Auszahlungen noch den Vertrag mit Stripe. Der Vermieter kann die Verbindung zwischen dem Konto und dem Buchungskalender im Stripe-Dashboard beenden. + +(5) Beginnt innerhalb der 90 Tage wieder ein Vertrag über den Betrieb der Website, schaltet WEBklar den Buchungskalender auf Wunsch des Vermieters in Textform mit den vorhandenen Daten und Einstellungen ohne weitere Kosten wieder ein. Nach der Löschung ist eine neue Anfrage und eine neue Einrichtung nötig (neuer Preis nach Nr. 9). + +(6) Endet der Vertrag über den Betrieb der Website, bevor WEBklar den Buchungskalender freigeschaltet hat, erstattet WEBklar den gezahlten Einrichtungspreis vollständig. + +(7) Auf Wunsch des Vermieters in Textform schaltet WEBklar den Buchungskalender jederzeit ab. Eine Erstattung des Einrichtungspreises folgt daraus nicht; für den Widerruf gilt Nr. 9 Abs. 6. + +## 11. Haftung + +(1) Der Buchungskalender ist ein Hilfsmittel für die Vermietung des Vermieters. Der Vertrag über die Unterkunft besteht allein zwischen dem Vermieter und dem Gast; WEBklar ist daran nicht beteiligt. + +(2) Für entgangenen Gewinn und Folgeschäden aus Störungen des Buchungskalenders, aus Verzögerungen oder Fehlern beim Kalenderabgleich (Nr. 4), aus Doppelbuchungen und aus nicht zugestellten E-Mails haftet WEBklar nur im Rahmen von § 13 Abs. 1 und 2 der Abo-Bedingungen. + +(3) WEBklar haftet nicht für Inhalte des Vermieters, insbesondere nicht für seine Unterkünfte, Preise, Steuerangaben, Stornobedingungen und Rechtstexte, auch nicht für den Muster-Text, den er übernommen hat (Nr. 6), und nicht für die Erfüllung seiner Pflichten gegenüber den Gästen und den Behörden (Nr. 5). + +(4) WEBklar haftet nicht für Ausfälle, Sperren oder Entscheidungen von Stripe und der Zahlungsarten sowie für Rückbuchungen und Zahlungsausfälle (Nr. 3 Abs. 3), und nicht für Ausfälle, Änderungen und Entscheidungen anderer Plattformen, deren Kalender der Vermieter einbindet. + +(5) Die Haftung nach § 13 Abs. 1 der Abo-Bedingungen (unter anderem bei Vorsatz, grober Fahrlässigkeit, Verletzung von Leben, Körper oder Gesundheit und nach dem Produkthaftungsgesetz) bleibt unberührt. Der Haftungsrahmen des Vermieters gegenüber seinen Gästen bleibt unberührt. + +## 12. Änderungen und Einstellung + +(1) WEBklar darf die Technik des Buchungskalenders verbessern, solange der Leistungsumfang nicht schlechter wird (§ 3 Abs. 7 der Abo-Bedingungen). Ändert sich dabei, welche Daten erhoben werden, gilt Nummer 12 des AVV Buchungskalender. + +(2) WEBklar darf den Buchungskalender für eine Website mit einer Frist von vier Wochen beenden oder für alle Vermieter mit einer Frist von drei Monaten einstellen, wenn +- ein Gesetz, eine Gerichtsentscheidung oder eine Vorgabe einer Aufsichtsbehörde den Betrieb in der bisherigen Form unzulässig macht oder nur mit wesentlich anderer Technik erlaubt und der Vermieter einer dafür nötigen neuen Fassung nicht zustimmt (AVV Buchungskalender Nummer 12), +- Stripe die Anbindung nach Nr. 3 beendet oder wesentlich ändert, so dass die Online-Zahlung in der bisherigen Form nicht weiterbetrieben werden kann (dann entfällt nur die Online-Zahlung, soweit der Buchungskalender ohne sie weiterläuft), oder +- eine Sicherheitslücke sich nicht anders beheben lässt. + +Die Mitteilung erfolgt in Textform und nennt den Grund, die Merkmale der Änderung, den Zeitpunkt und bei Verbrauchern das Recht, den Vertrag nach § 327r Abs. 3 BGB zu beenden, mit seiner Frist. + +(3) Ist der Weiterbetrieb aus einem Grund nach Absatz 2 schon vor Ablauf der Frist nicht zulässig, darf WEBklar den Buchungskalender ohne Vorankündigung aussetzen, solange das nötig ist. WEBklar informiert den Vermieter darüber unverzüglich in Textform mit dem Grund und nimmt den Betrieb wieder auf, sobald das zulässig und technisch möglich ist. + +(4) Eine Einstellung ohne einen Grund nach Absatz 2 ist ausgeschlossen. Gesetzliche Rechte von Verbrauchern bei Änderungen digitaler Produkte (§ 327r BGB) bleiben unberührt. + +## 13. Hinweise + +(1) **Keine Rechtsberatung.** Der Buchungskalender und der Muster-Text sind technische Hilfsmittel, keine Rechtsberatung (Nr. 6). Die rechtliche und steuerliche Einordnung seiner Vermietung, seiner Preisangaben und seines Angebots trägt der Vermieter. + +(2) **Barrierefreiheit.** Das Widget ist für die Bedienung mit Tastatur und Hilfstechniken gestaltet (Beschriftungen der Tage, Bedienung mit Pfeiltasten, Fehlermeldungen als Live-Region). Eine Konformität nach WCAG 2.1 AA oder EN 301 549 sagt WEBklar nicht zu. Ob der Vermieter als Anbieter von Dienstleistungen im elektronischen Geschäftsverkehr unter das BFSG fällt (Ausnahme für Kleinstunternehmen, § 3 Abs. 3 BFSG), entscheidet und prüft der Vermieter. diff --git a/docs/rechtliches/unterkunft-datenschutz-6f-entwurf.md b/docs/rechtliches/unterkunft-datenschutz-6f-entwurf.md new file mode 100644 index 0000000..ed63a09 --- /dev/null +++ b/docs/rechtliches/unterkunft-datenschutz-6f-entwurf.md @@ -0,0 +1,21 @@ +# Entwurf: Abschnitt 6f der Datenschutzerklärung (Buchungskalender) + +Stand 2026-10-07, Fassung der Rechtstexte 2026-10-07. **Entwurf – Prüfung durch Kanzlei offen.** Der Text kommt als Abschnitt `6f` in `public/datenschutz.html`, hinter 6d (Webshop; 6e ist für die Öffnungszeiten reserviert und noch nicht live) und vor Abschnitt 7. Er wird erst mit dem Livegang übernommen (`docs/funktionen/unterkunft-livegang.md`, Schritt 9), danach die PDF-Fassung `scripts/build-legal-pdfs.sh datenschutz` neu drucken. Mit der Übernahme zugleich im Abschnitt 12 „Empfänger im Überblick“ die Zeile zu Stripe und in Abschnitt 3 die Verweise prüfen. Der Text ist an Abschnitt 6d angelehnt und beschreibt, was die Software tut; ändert sich der AVV Buchungskalender, hier mitändern. + +## Text (als HTML-Absätze übernehmen) + +**6f. Buchungskalender auf Websites unserer Kunden** + +Kunden können auf ihrer eigenen Website einen Buchungskalender für ihre Unterkünfte betreiben („Buchungskalender“), sobald wir die Funktion für sie freigeschaltet haben. Dabei verarbeiten wir die Daten der Personen, die dort eine Unterkunft anfragen oder buchen („Gäste“), ausschließlich als Auftragsverarbeiter nach den Weisungen des jeweiligen Kunden, der dafür Verantwortlicher ist (Auftragsverarbeitungsvertrag Buchungskalender). Wir verwenden diese Daten nicht für eigene Zwecke. Verantwortliche sind wir für die Betriebsdaten des Kunden im Kundenportal und für seine Bestellung der Funktion. Diese Datenschutzerklärung gilt für unsere eigenen Seiten und das Kundenportal. Wer auf der Website eines Kunden anfragt oder bucht, findet die Informationen dazu (Zwecke, Rechtsgrundlagen, Speicherdauer, Rechte) in der Datenschutzerklärung dieser Website. Anfragen von Gästen zu ihren Daten leiten wir an den Kunden weiter. + +Für den Betrieb des Buchungskalenders speichern wir im Auftrag des Kunden: bei einer Anfrage Name, E-Mail-Adresse, auf Wunsch Firma, Telefonnummer und Nachricht, die Unterkunft, den Zeitraum und die Zahl der Personen sowie bis zur Entscheidung des Kunden einen Hashwert der IP-Adresse (siehe unten); nach der Freigabe die Posten und den Preis des Aufenthalts, die Stornobedingungen und die Fassung der Rechtstexte, die galten; bei der Buchung die Rechnungsadresse, die Zahlart und die Rechnung (und bei einer Stornierung die Stornorechnung) mit lückenloser Rechnungsnummer, in der der Kunde als Aussteller genannt ist; den Stand der Buchung (zum Beispiel gebucht, bezahlt, storniert) mit den Zeitpunkten, bei einer Online-Zahlung die Kennungen der Zahlung bei Stripe und erstattete Beträge. Zahlungsdaten wie Kartennummer oder IBAN gibt der Gast nur auf der Zahlungsseite von Stripe ein; wir erhalten sie nicht. Der Kunde sieht und bearbeitet Anfragen, Buchungen und Rechnungen im Kundenportal. Im Namen des Kunden stellen wir die Rechnungen aus (Rechnung im Namen und im Auftrag des Kunden, § 14 Abs. 2 Satz 4 UStG) und senden E-Mails an Gäste (Eingang der Anfrage, Freigabe mit Link zur Buchung, Ablehnung, Buchungsbestätigung mit Rechnung, Zahlungseingang, Ablauf einer Reservierung, Stornierung) und an den Kunden (neue Anfrage, neue Buchung, Hinweis bei fehlgeschlagenem Kalenderabgleich) über den E-Mail-Dienst der Hetzner Online GmbH (Rechenzentrum Nürnberg, Abschnitt 8). Als Absender erscheint der Kunde, Antworten gehen an ihn. Bis zum Versand liegt jede E-Mail in einer Warteschlange; nach dem Versand löschen wir dort Empfängeradresse und Inhalt, den Eintrag selbst nach sieben Tagen; E-Mails, die nicht zugestellt werden konnten, löschen wir nach 48 Stunden. Der Link zur Buchungsseite enthält ein geheimes Kennzeichen, das wir nur als Prüfsumme speichern. Das Widget setzt keine Cookies. Der Kunde kann Kalender anderer Plattformen einbinden und die geheime Kalenderadresse des Buchungskalenders bei ihnen eintragen; wir lesen aus fremden Kalendern nur belegte Zeiträume, nicht Angaben zu Gästen, und die Adresse des Buchungskalenders enthält nur belegte Nächte. Zum Schutz vor Missbrauch begrenzen wir die Zahl der Anfragen je IP-Adresse; die Zeitpunkte der Aufrufe merken wir uns nur im Arbeitsspeicher des Servers, nicht dauerhaft. Mit der Anfrage speichern wir nicht die IP-Adresse, sondern einen Hashwert davon, der mit einem geheimen Schlüssel unseres Servers berechnet wird (Pseudonym); ohne den Schlüssel lässt sich daraus keine IP-Adresse ableiten. Wir verwenden ihn nur für den Missbrauchsschutz und entfernen ihn, sobald der Kunde die Anfrage freigibt oder ablehnt, spätestens nach 30 Tagen. Im Übrigen gelten die Protokolle in Abschnitt 3. + +Online-Zahlungen im Buchungskalender laufen über Stripe Connect unmittelbar auf das eigene Stripe-Konto des Kunden; wir erhalten und verwahren kein Geld der Gäste und beteiligen uns nicht am Umsatz. Um dieses Konto zu eröffnen, übermitteln wir, sobald der Kunde im Kundenportal die Verbindung mit Stripe auslöst, seine E-Mail-Adresse, die Adresse seiner Website und den Namen seines Projekts an die Stripe Payments Europe, Limited, 1 Grand Canal Street Lower, Grand Canal Dock, Dublin, D02 H210, Irland („Stripe“), zusammen mit internen Kennzeichen, mit denen wir das Konto seinem Projekt zuordnen. Die weiteren Angaben für das Konto gibt der Kunde direkt bei Stripe ein. Wir speichern die Kennung des Stripe-Kontos und seinen Stand (ob Zahlungen und Auszahlungen möglich sind), den uns Stripe meldet, und zeigen ihn dem Kunden im Kundenportal an. Rechtsgrundlage ist Art. 6 Abs. 1 lit. b DSGVO (Vertrag mit dem Kunden). Stripe verarbeitet die Daten für sein Konto als eigener Verantwortlicher; dabei können Daten an die Stripe, LLC in den USA übermittelt werden, die nach dem EU-US Data Privacy Framework zertifiziert ist (Abschnitt 7). Es gelten die Datenschutzhinweise von Stripe: stripe.com/de/privacy. + +Löschfristen: Den IP-Hash entfernen wir, sobald der Kunde eine Anfrage freigibt oder ablehnt, spätestens nach 30 Tagen. Anfragen, aus denen keine Buchung wurde, anonymisieren wir nach sechs Monaten. Bei gebuchten Aufenthalten anonymisieren wir Name, Firma, E-Mail-Adresse, Telefonnummer und Nachricht drei Jahre nach dem Ende des Jahres der Abreise; die Rechnungen und die Rechnungsadresse bewahren wir für den Kunden acht Jahre auf (Buchungsbelege, § 147 AO), solange der Buchungskalender läuft. Schaltet der Kunde den Buchungskalender ab oder endet der Vertrag über den Betrieb seiner Website, schalten wir den Buchungskalender ab und weisen den Kunden vorher darauf hin, seine Rechnungen herunterzuladen. Der Kunde kann Anfragen, Buchungen und Rechnungen danach 90 Tage lang im Kundenportal lesen; danach löschen wir alle Daten des Buchungskalenders (Unterkünfte, Preise, Anfragen, Buchungen, Rechnungen, Kalenderverbindungen, Sperren und Einstellungen). Beginnt innerhalb dieser Frist wieder ein Vertrag über den Betrieb der Website, schalten wir den Buchungskalender auf Wunsch des Kunden mit den vorhandenen Daten wieder ein. Eine Ausnahme ist das Einrichtungs-Ticket, in dem wir die Einrichtung als Arbeitsnachweis festhalten (Abschnitt 6): Es bleibt mit einer Kurzfassung der Angaben zur Einrichtung bestehen und enthält keine Daten von Gästen. Löschen wir Daten oder anonymisieren wir sie, bleiben sie in unseren Datensicherungen noch bis zu sieben Tage erhalten und werden dann überschrieben. Die Daten liegen auf unserem Server bei Hetzner im Rechenzentrum Falkenstein (Deutschland), wie die übrigen Portal-Daten (Abschnitt 3). Die Bestellung der Funktion und ihren Nachweis beschreibt Abschnitt 7. + +## Hinweise für die Übernahme + +- Die Aufbewahrung der Rechnungen für 8 Jahre durch WEBklar ist ein Dienst für den Kunden und endet mit der Löschung 90 Tage nach dem Abschalten (Frage U6 im Kanzlei-Paket). +- Abschnitt 12 „Empfänger im Überblick“ der Datenschutzerklärung: Stripe-Zeile um „Buchungskalender“ ergänzen. +- Abschnitt 7 (Bestellung der Funktion): Der Satz zu Zustimmungsnachweisen gilt für den Buchungskalender entsprechend; prüfen, ob die Aufzählung der Funktionen dort ergänzt werden muss. diff --git a/docs/rechtliches/unterkunft-kanzlei-fragen.md b/docs/rechtliches/unterkunft-kanzlei-fragen.md new file mode 100644 index 0000000..0569f08 --- /dev/null +++ b/docs/rechtliches/unterkunft-kanzlei-fragen.md @@ -0,0 +1,34 @@ +# Fragen an die Kanzlei: Buchungskalender + +Stand 2026-10-07. Gegenstand der Prüfung: Leistungsbeschreibung Buchungskalender und AVV Buchungskalender (Fassung 2026-10-07, beide als „Entwurf – Prüfung durch Kanzlei offen“ gekennzeichnet), Abschnitt 6f der Datenschutzerklärung (`unterkunft-datenschutz-6f-entwurf.md`), Muster-Datenschutz-Absatz für die Website des Vermieters (`docs/funktionen/unterkunft-datenschutz-absatz.md`), Muster-Stornobedingungen (`docs/funktionen/unterkunft-storno-muster.md`), die Zustimmungen der Bestellung (Wortlaut in `server/config.js`, Register `unterkunft`) und die Buchungsseite. Der Buchungskalender ist für Ferienwohnungen, Monteurzimmer und kleine Pensionen gedacht; erste Kundin ist eine Vermieterin von Monteurunterkünften (Unternehmer als Gäste, Verbraucher möglich). Die Arbeitsweise der Software steht im Entwurf der Spezifikation `docs/superpowers/specs/2026-10-07-buchungskalender-design.md`; Muster ist das Kanzlei-Paket zum Webshop (`webshop-kanzlei-paket.md`). + +## Fragen + +**U1. Button-Lösung über Mail-Link (§ 312j Abs. 3 BGB).** Die Anfrage des Gastes ist unverbindlich (Schaltfläche „Anfrage senden“). Der Vertrag entsteht erst, wenn der Gast nach der Freigabe durch den Vermieter über den Link in der E-Mail die Buchungsseite öffnet und „Zahlungspflichtig buchen“ klickt; unmittelbar darüber stehen alle Pflichtangaben. Genügt das für die Button-Lösung, auch wenn der Vermieter den Preis vor der Freigabe ändern kann und der Gast ihn erst auf der Buchungsseite verbindlich sieht? Ist die Beschriftung „Zahlungspflichtig buchen“ auch bei der Zahlart „vor Ort“ (keine Zahlung im Moment der Buchung) zulässig, oder braucht es eine andere Beschriftung („Verbindlich buchen“)? Muss die Anfrage-Schaltfläche anders heißen, damit niemand sie für verbindlich hält? + +**U2. Pflichtinformationen (Art. 246a § 1 EGBGB, § 312d BGB) und Rolle des Vermieters.** Welche Angaben muss die Buchungsseite zeigen, welche stehen in der Buchungsbestätigung (dauerhafter Datenträger, § 312f BGB), und welche muss der Vermieter auf seiner Website selbst vorhalten (Impressum, Informationen zum Anbieter, Verbraucherstreitbeilegung nach § 36 VSBG)? Reicht die Buchungsseite (Anbieter, Unterkunft, Zeitraum, Leistung, Gesamtpreis, Zahlart, Stornobedingungen, Hinweis zum Widerrufsrecht), und was fehlt für Beherbergung typischerweise (zum Beispiel Preisangabenverordnung, Pflichtangaben zur Unterkunft, Hausordnung)? Welche Pflichten treffen WEBklar als Betreiber der Seite im Namen des Vermieters? + +**U3. Kein Widerrufsrecht (§ 312g Abs. 2 Nr. 9 BGB).** Wir weisen auf der Buchungsseite darauf hin, dass für die Buchung zu einem bestimmten Zeitraum kein Widerrufsrecht besteht. Gilt die Ausnahme auch für Monteurunterkünfte, die langfristig oder für Unternehmer und Verbraucher gemischt vermietet werden, und für Aufenthalte, deren Zeitraum über Wochen reicht? Ist die Formulierung („Ein Widerrufsrecht besteht nicht (§ 312g Abs. 2 Nr. 9 BGB).“) ausreichend, und wie ist die Belehrungspflicht zu verstehen, wenn eine Ausnahme vorliegt? + +**U4. Umsatzsteuer der Endreinigung.** Die Software kennt je Vermieter einen Steuersatz für die Übernachtung (Standard 7 %) und einen für die Endreinigung (Standard 7 %) und rechnet die Steuer aus den Bruttobeträgen heraus. Ist es zulässig, die Endreinigung als unselbständige Nebenleistung der Beherbergung mit demselben Satz zu behandeln (§ 12 Abs. 2 Nr. 11 UStG), oder wäre 19 % der sichere Standard? Wie ist es bei Kleinunternehmern (§ 19 UStG, Hinweistext auf der Rechnung) und bei langfristigen Vermietungen, bei denen die Steuerbefreiung nach § 4 Nr. 12 UStG greifen kann? Wie weit darf WEBklar Voreinstellungen vorgeben, ohne dass daraus eine Steuerberatung wird? + +**U5. Rechnung im Namen des Vermieters (§ 14 Abs. 2 Satz 4 UStG).** WEBklar stellt die Rechnungen in Namen und Auftrag des Vermieters aus; er stimmt bei der Bestellung und mit einem Haken in den Einstellungen zu. Genügt das als Zustimmung (Textform?) und ist die Abrechnung durch einen Dritten damit sauber geregelt, auch für die Stornorechnung (Rechnungskorrektur mit eigener Nummer) und die lückenlose Nummerierung je Vermieter und Jahr? Gilt das Konstrukt auch für Rechnungen an Verbraucher (dann ist die Rechnung keine Pflichtrechnung, sondern Beleg) und reichen die Pflichtangaben nach § 14 Abs. 4 UStG, wenn der Vermieter unvollständige Stammdaten hinterlegt? Wer haftet für falsche Steuerangaben auf der Rechnung (§ 14c UStG)? + +**U6. Aufbewahrung durch WEBklar (8 Jahre).** WEBklar speichert die Rechnungen und die Rechnungsadresse der Gäste 8 Jahre lang, solange der Buchungskalender läuft, und löscht sie 90 Tage nach dem Abschalten; der Vermieter wird vorher aufgefordert, sie herunterzuladen. Reicht dieser Dienst, ohne dass WEBklar selbst aufbewahrungspflichtig oder zum Buchführungssystem wird (§ 147 AO, GoBD), und wie ist die Spannung zwischen der 8-Jahres-Frist und der Löschung nach 90 Tagen zu regeln? Die Gästedaten ohne Rechnungsbezug werden 3 Jahre nach dem Ende des Abreisejahres anonymisiert und Anfragen ohne Buchung nach 6 Monaten: Sind die Fristen angemessen (Art. 5 Abs. 1 lit. e DSGVO)? + +**U7. Rolle im Datenschutz, AVV Buchungskalender.** Der Vermieter ist Verantwortlicher, WEBklar Auftragsverarbeiter (Muster AVV Webshop). Ist die Rollenverteilung für die Rechnungserstellung und die Aufbewahrung richtig (kein eigener Zweck von WEBklar)? Ist die Behandlung von Stripe (Vertragspartner des Vermieters, kein Unterauftragsverarbeiter) und der importierten Kalender anderer Plattformen (nur Zeiträume, keine Gästedaten) vertretbar? Genügt die Bezeichnung des IP-Hash als pseudonymes Datum mit Löschung bei der Entscheidung? + +**U8. Haftung bei Doppelbuchung durch iCal-Verzögerung.** Der Abgleich mit Booking.com, Airbnb und ähnlichen Plattformen geschieht über iCal mit Verzögerung von Minuten bis Stunden; jede Anfrage braucht die Freigabe, und beim Freigeben und Buchen prüft die Software erneut. Eine Doppelbuchung ist trotzdem möglich. Ist der Haftungsausschluss in Nr. 4 und Nr. 11 der Leistungsbeschreibung (keine Echtzeit-Verfügbarkeit, kein Ersatz von Folgeschäden außer im Rahmen von § 13 Abs. 1 und 2 der Abo-Bedingungen) wirksam, auch gegenüber Verbrauchern? Die Leistungsbeschreibung richtet sich nur an Vermieter, die Unternehmer sind; für deren Gäste gilt das nicht. Ist eine hervorgehobene Warnung im Portal sinnvoll oder nötig? + +**U9. Zustimmungen der Bestellung.** Genügen die sechs Haken (Unterlagen, Verantwortung, Rechnung im Auftrag, Stripe, Beginn der Leistung und Erlöschen des Widerrufsrechts, Pflichtinformationen) und die Widerrufsbelehrung der Funktionen, wenn der Vermieter in der Praxis Unternehmer ist? Muss der Haken zu Stripe entfallen, wenn der Vermieter keine Online-Zahlung nutzt? + +**U10. Kein Meldeschein, keine Kurtaxe, keine Anzahlung.** Die Leistungsbeschreibung nimmt Meldeschein, Kurtaxe und Anzahlungen aus dem Umfang und weist die Pflichten dem Vermieter zu (Nr. 2 Abs. 7, Nr. 5 Abs. 6). Ist das ausreichend deutlich, und wie ist eine Haftung von WEBklar wegen fehlender Hinweise ausgeschlossen? + +**U11. Muster-Stornobedingungen.** Der Text `unterkunft-storno-muster.md` ist eine Vorlage für Vermieter (Staffel nach Zeit bis zur Anreise, Erstattungen, Verhältnis zu § 537 BGB und § 308 Nr. 7 BGB bei Verbrauchern, Pauschalen nach § 309 Nr. 5 BGB). Ist er als Vorlage mit Hinweis „keine Rechtsberatung“ vertretbar? Welche Pauschalen sind üblich und zulässig? + +**U12. Datenschutz-Absatz für die Vermieter-Website.** Ist der Muster-Absatz `unterkunft-datenschutz-absatz.md` (Verantwortlicher, Rechtsgrundlagen Art. 6 Abs. 1 lit. b und f, Stripe, E-Mails, Speicherdauer) und der Abschnitt 6f der WEBklar-Erklärung in sich schlüssig und vollständig? + +## Prüfpunkte vor dem Livegang + +- Fassung der Rechtstexte: Ändert die Kanzlei etwas, gibt es eine neue Fassung (Datum, `config.unterkunft.fassung`, Zustimmungs-Pin in `test/featureConsentTexte.test.js`); ausgelieferte Fassungen werden nie überschrieben. +- Danach Upload in WOMS „Rechtliches“ und Schalter `UNTERKUNFT_ENABLED` von `pilot` auf `on` (Livegang-Schritt 10). diff --git a/public/rechtliches/avv-unterkunft-2026-10-07.html b/public/rechtliches/avv-unterkunft-2026-10-07.html new file mode 100644 index 0000000..2a95cda --- /dev/null +++ b/public/rechtliches/avv-unterkunft-2026-10-07.html @@ -0,0 +1,212 @@ +<!DOCTYPE html> +<html lang="de"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta name="webklar-fassung" content="2026-10-07"> + <title>Auftragsverarbeitungsvertrag Buchungskalender – WEBklar + + + +
+ + +
WEBKLAR
+

Auftragsverarbeitungsvertrag Buchungskalender (Art. 28 DSGVO)

+ +

Fassung 2026-10-07 · Entwurf – Prüfung durch Kanzlei offen

+ +

zwischen dem Kunden als Verantwortlichem („Kunde“; in der Leistungsbeschreibung „Vermieter“) und der WEBklar GbR, Am Schwimmbad 10, 67722 Winnweiler, vertreten durch die Gesellschafter Kenso Grimm und Justin Klein, als Auftragsverarbeiter („WEBklar“).

+ +

Vorbemerkung: Abschluss und Verhältnis zu anderen Verträgen

+ +

(1) Der Kunde schließt diesen Vertrag, wenn er im Kundenportal die Einrichtung des Buchungskalenders bestellt und dabei per Haken diesem Vertrag und der Leistungsbeschreibung „Buchungskalender“ („Leistungsbeschreibung“) in der angezeigten Fassung zustimmt. Das Portal speichert die Fassung, den Zeitpunkt, das Kundenkonto und die angemeldete Person. Anschließend sendet WEBklar dem Kunden eine E-Mail, die beide Texte und die Widerrufsbelehrung in dieser Fassung als PDF enthält und auf sie verlinkt.

+ +

(2) Ein Mitarbeiter von WEBklar darf die Funktion auch ohne Bestellung im Portal einschalten (zum Beispiel für einen Kunden, dem WEBklar sie als Teil seines Website-Projekts bereitstellt), aber nur, wenn der Kunde vorher in Textform (etwa im Chat des Kundenportals oder per E-Mail) erklärt hat, dass er diesem Vertrag und der Leistungsbeschreibung in der aktuellen Fassung zustimmt. Das Portal verlangt dafür das Datum und den Weg der Erklärung; fehlt eine Angabe, schaltet es nicht ein. WEBklar speichert vor dem Einschalten einen Zustimmungsnachweis mit der Fassung der beiden Texte, dem Datum und dem Weg dieser Erklärung, dem Zeitpunkt des Einschaltens und dem Namen des Mitarbeiters (ohne IP-Adresse und Browser-Kennzeichen, weil der Kunde nicht im Portal zugestimmt hat). Der Kunde erhält anschließend eine E-Mail mit diesen beiden Texten als PDF.

+ +

(3) Dieser Vertrag ist ein eigener Vertrag für den Buchungskalender. Er ergänzt den Auftragsverarbeitungsvertrag in Anlage 1 der Abo-Bedingungen. Für den Buchungskalender geht er Anlage 1 vor; im Übrigen gilt Anlage 1 ergänzend. In Datenschutzfragen geht er den Abo-Bedingungen und der Leistungsbeschreibung vor.

+ +

(4) Die Rollen: Der Kunde ist Verantwortlicher für die personenbezogenen Daten seiner Gäste im Buchungskalender. WEBklar ist sein Auftragsverarbeiter. Stripe ist nicht Auftragsverarbeiter von WEBklar, sondern Vertragspartner des Kunden (Nummer 7 Abs. 4). Die Plattformen, deren Kalender der Kunde einbindet (zum Beispiel Booking.com oder Airbnb), sind weder Auftragsverarbeiter noch Unterauftragsverarbeiter von WEBklar.

+ +

1. Gegenstand und Dauer

+ +

(1) WEBklar betreibt für die öffentliche Website des Kunden ein Buchungs-Widget mit einer Buchungsseite und einer Verwaltung im Kundenportal („Buchungskalender“) und verarbeitet dabei personenbezogene Daten der Gäste des Kunden im Auftrag des Kunden. Den Umfang beschreibt die Leistungsbeschreibung.

+ +

(2) Der Vertrag beginnt mit dem Einschalten der Funktion. Er endet mit dem Abschalten, spätestens mit dem Ende des Vertrags, aufgrund dessen WEBklar die Website des Kunden betreibt; den Buchungskalender schaltet WEBklar dann zum Vertragsende ab (Nr. 10 Abs. 1 der Leistungsbeschreibung). Die Pflichten aus diesem Vertrag gelten fort, bis alle Daten nach Nummer 9 gelöscht sind.

+ +

2. Art und Zweck der Verarbeitung

+ +

(1) Art: Übermitteln der Anfrage und der Buchung vom Widget und von der Buchungsseite an den Server von WEBklar, Speichern, Verwalten und Anzeigen im Kundenportal, Berechnen des Preises, Erzeugen von Rechnungen und Stornorechnungen im Namen des Kunden (Nr. 3 Abs. 6 der Leistungsbeschreibung), Abgleichen von Kalendern, Versenden von E-Mails, Übernehmen von Zahlungsstatus aus Stripe, Weitergeben von Erstattungen an Stripe im Auftrag des Kunden, Anonymisieren und Löschen.

+ +

(2) Zwecke: Der Kunde soll Anfragen und Buchungen seiner Gäste abwickeln. Dazu nimmt der Buchungskalender Anfragen entgegen, reserviert Zeiträume nach der Freigabe durch den Kunden, nimmt die verbindliche Buchung des Gastes entgegen, stellt die Rechnung aus, gleicht Online-Zahlungen mit Stripe ab, bildet Zahlungen vor Ort ab, bildet Stornierungen ab und benachrichtigt den Kunden. WEBklar versendet die E-Mails im Auftrag des Kunden. Außerdem schützt WEBklar den Buchungskalender für den Kunden vor Missbrauch (Mengenbegrenzung, Begrenzung der Anfragen je IP-Adresse, Erkennen automatisierter Anfragen).

+ +

(3) WEBklar verwendet die Daten für keine eigenen Zwecke, auch nicht in anonymisierter Form und nicht für Auswertungen über mehrere Kunden. Es findet keine Werbung und keine Zusammenführung mit anderen Daten statt. WEBklar bildet keine Profile einzelner Gäste. Zählungen ohne Personenbezug, die WEBklar für den sicheren Betrieb braucht (etwa die Zahl der anonymisierten Anfragen je Tag oder die Länge der Versandwarteschlange), sind keine eigenen Zwecke.

+ +

3. Datenarten und Betroffene

+ +

(1) Daten der Gäste, die WEBklar aus dem Widget, von der Buchungsseite und aus Stripe erhält und speichert:

+ +
    +
  • bei der Anfrage: Name, E-Mail-Adresse, auf Wunsch Firma, Telefonnummer und eine Nachricht, die gewünschte Unterkunft, der Zeitraum, die Zahl der Personen, die Anfragenummer, ein Hashwert der IP-Adresse (Absatz 4) und der Zeitpunkt;
  • +
  • bei der Freigabe: die Posten und Summen des Preises (Text, Menge, Einzelbetrag, Steuersatz), die Reservierungsfrist, eine Nachricht des Kunden an den Gast, die Stornobedingungen, die galten, und die Fassung der Rechtstexte, der der Gast gesehen hat, jeweils als Schnappschuss;
  • +
  • bei der Buchung: die Rechnungsadresse (Name, Firma, Straße, Postleitzahl, Ort, Land), die Zahlart, der Zeitpunkt der Buchung und die Rechnungsnummer;
  • +
  • bei der Zahlung und der Erstattung: Status, Zeitpunkt, Art (online über Stripe oder vor Ort), die Kennungen der Zahlung bei Stripe, erstattete Beträge und der Grund einer Stornierung;
  • +
  • die Rechnung und die Stornorechnung als unveränderlicher Schnappschuss (Angaben des Ausstellers, Empfänger, Unterkunft, Zeitraum, Posten, Summen, Steuerart, Bezug), aus dem WEBklar das PDF bei jedem Abruf erzeugt;
  • +
  • ein Hashwert des geheimen Zugangs zur Buchungsseite (der Link in der E-Mail wird nur als Prüfsumme gespeichert);
  • +
  • der Zustellstatus der E-Mails an den Gast.
  • +
+ +

Kartendaten und Kontodaten (IBAN) des Gastes erhält und speichert WEBklar nicht; die gibt der Gast nur bei Stripe ein. Die Bankverbindung des Kunden selbst (Angabe auf der Rechnung) und seine Firmen- und Steuerangaben gehören nicht zu den Gästedaten.

+ +

(2) Von Kalendern anderer Plattformen übernimmt WEBklar nur die belegten Zeiträume (Datum von und bis), nicht Namen, Beschreibungen oder andere Angaben der dortigen Buchungen, auch wenn der Kalender sie enthält. Die iCal-Adresse, die WEBklar dem Kunden bereitstellt, enthält nur belegte Nächte, keine Angaben zu Gästen. Wer die geheime Adresse kennt, sieht die belegten Nächte; der Kunde kann sie jederzeit erneuern.

+ +

(3) Besondere Kategorien personenbezogener Daten (Art. 9 DSGVO) werden nicht verarbeitet. Der Kunde fordert von seinen Gästen keine entsprechenden Angaben und bittet sie, solche Angaben nicht in das Nachrichtenfeld zu schreiben (Nummer 11 Abs. 4). Meldedaten nach dem Bundesmeldegesetz (Meldeschein) und Daten zur Kurtaxe verarbeitet der Buchungskalender nicht.

+ +

(4) IP-Adresse und Browser-Kennzeichen (User-Agent) erhält der Server von WEBklar technisch bei jedem Abruf des Widgets und jeder Anfrage. Die Mengenbegrenzung (Missbrauchsschutz) verwendet die IP-Adresse im Arbeitsspeicher des Servers; ein Neustart leert sie. Mit der Anfrage werden weder eine IP-Adresse im Klartext noch ein Browser-Kennzeichen gespeichert, sondern nur ein Hashwert der IP-Adresse („IP-Hash“): ein SHA-256-Wert, den WEBklar mit einem geheimen Schlüssel des Servers salzt. Der IP-Hash ist ein pseudonymes technisches Datum und bleibt ein personenbezogenes Datum, weil WEBklar mit dem Schlüssel für dieselbe IP-Adresse denselben Wert berechnen kann; ohne den Schlüssel lässt sich aus ihm keine IP-Adresse ableiten. WEBklar verwendet ihn ausschließlich zum Missbrauchsschutz. Er dient nicht dazu, Gäste zu identifizieren, wiederzuerkennen oder zu profilieren, wird dem Kunden weder angezeigt noch exportiert und steht nur im Datensatz der Anfrage. WEBklar entfernt ihn aus dem Datensatz, sobald der Kunde die Anfrage freigibt oder ablehnt, spätestens nach 30 Tagen (Nummer 9 Abs. 1). In den Server-Protokollen stehen IP-Adresse und Browser-Kennzeichen 14 Tage (Anlage 2 der Abo-Bedingungen).

+ +

(5) Der Buchungskalender setzt keine Cookies. Das Widget und die Buchungsseite speichern im Browser des Besuchers keine personenbezogenen Daten dauerhaft; das Widget hält Eingaben nur im Arbeitsspeicher der geöffneten Seite. Soweit für die Funktion etwas im Sitzungsspeicher des Tabs abgelegt wird, ist es technisch erforderlich und verschwindet mit dem Tab.

+ +

(6) Betroffene: Gäste, die über die Website des Kunden Anfragen stellen oder buchen, und Personen, deren Angaben der Gast in der Anfrage oder Buchung macht (zum Beispiel Mitreisende oder abweichende Rechnungsempfänger). Beschäftigte des Kunden sind von diesem Vertrag nicht betroffen.

+ +

4. Weisungen

+ +

(1) WEBklar verarbeitet die Daten nur auf dokumentierte Weisung des Kunden, auch in Bezug auf eine Übermittlung in ein Drittland oder an eine internationale Organisation. Das gilt nicht, wenn das Recht der Europäischen Union oder Deutschlands WEBklar zu einer Verarbeitung verpflichtet. In diesem Fall teilt WEBklar dem Kunden die Pflicht vorher mit, soweit das Gesetz es nicht verbietet.

+ +

(2) Mit der Bestellung weist der Kunde WEBklar an, den Buchungskalender nach seinen Einstellungen und der Leistungsbeschreibung zu betreiben und in seinem Namen Rechnungen auszustellen. Weitere Weisungen ergeben sich aus den Einstellungen und Aktionen im Kundenportal (Unterkünfte, Preise, Sperren, Kalenderverbindungen, Freigabe und Ablehnung von Anfragen, Zahlungseingang vor Ort, Stornierungen und Erstattungen, Online-Zahlung, Öffnen und Schließen des Buchungskalenders). Sonstige Weisungen erteilt der Kunde in Textform, etwa im Chat des Kundenportals. Weisungen, die über diese Einstellungen hinausgehen, setzt WEBklar nur um, wenn das technisch vorgesehen ist; sonst kann der Kunde den Buchungskalender abschalten lassen (Nr. 10 Abs. 7 der Leistungsbeschreibung). Die Anonymisierung und Löschung auf Weisung nach Nummer 8 Abs. 2 und Nummer 9 Abs. 6 setzt WEBklar immer um, soweit Aufbewahrungspflichten dem nicht entgegenstehen (Nummer 9 Abs. 8).

+ +

(3) Hält WEBklar eine Weisung für rechtswidrig, weist es den Kunden unverzüglich darauf hin. WEBklar darf die Ausführung aussetzen, bis der Kunde die Weisung ändert oder die Rechtslage geklärt ist.

+ +

5. Vertraulichkeit

+ +

WEBklar setzt nur Personen ein, die zur Vertraulichkeit verpflichtet sind oder einer gesetzlichen Verschwiegenheitspflicht unterliegen.

+ +

6. Technische und organisatorische Maßnahmen

+ +

(1) WEBklar trifft die Maßnahmen nach Art. 32 DSGVO, die in der Anlage zu diesem Vertrag beschrieben sind. WEBklar darf sie an den Stand der Technik anpassen, sofern das Schutzniveau nicht sinkt.

+ +

(2) Für den Server gelten ergänzend die Maßnahmen der Anlage 2 der Abo-Bedingungen, soweit die Anlage zu diesem Vertrag nichts anderes regelt.

+ +

7. Unterauftragsverarbeiter

+ +

(1) Der Kunde genehmigt den Einsatz der Hetzner Online GmbH, Industriestraße 25, 91710 Gunzenhausen, für den Betrieb des Servers, auf dem der Buchungskalender läuft, und für dessen Sicherung (Rechenzentrum Falkenstein, Deutschland) sowie für den Versand der E-Mails über den SMTP-Dienst des Webhostings (Rechenzentrum Nürnberg, Deutschland). Eine Übermittlung in Drittländer findet nicht statt.

+ +

(2) Will WEBklar einen weiteren Unterauftragsverarbeiter hinzuziehen oder einen ersetzen, teilt es das dem Kunden mindestens vier Wochen vorher in Textform mit. Der Kunde kann innerhalb von zwei Wochen nach Zugang der Mitteilung aus wichtigem datenschutzrechtlichem Grund in Textform widersprechen. WEBklar setzt den neuen Unterauftragsverarbeiter nicht vor Ablauf dieser Frist ein. Kündigt ein Unterauftragsverarbeiter von WEBklar eine eigene Änderung mit kürzerer Frist an, informiert WEBklar den Kunden unverzüglich, nachdem die Ankündigung eingegangen ist; der Kunde kann dann unverzüglich widersprechen. Einigen sich die Parteien nicht, kann der Kunde den Buchungskalender abschalten lassen und WEBklar ihn für diese Website zu dem Zeitpunkt beenden, zu dem der neue Unterauftragsverarbeiter eingesetzt wird. Die Daten werden dann nach Nummer 9 gelöscht, auf Weisung des Kunden früher (Nummer 9 Abs. 6).

+ +

(3) WEBklar verpflichtet jeden Unterauftragsverarbeiter vertraglich auf die Datenschutzpflichten nach Art. 28 Abs. 4 DSGVO. Bei der Hetzner Online GmbH ist das deren Vertrag zur Auftragsverarbeitung, den WEBklar abgeschlossen hat. Kommt ein Unterauftragsverarbeiter seinen Datenschutzpflichten nicht nach, haftet WEBklar dem Kunden für die Einhaltung dieser Pflichten (Art. 28 Abs. 4 Satz 2 DSGVO).

+ +

(4) Stripe ist kein Unterauftragsverarbeiter von WEBklar. Der Kunde verwendet sein eigenes Stripe-Konto und hat den Vertrag darüber unmittelbar mit Stripe geschlossen (Nr. 3 der Leistungsbeschreibung); die Zahlung des Gastes fließt direkt auf dieses Konto. Die Zahlungsseite (Stripe Checkout), die Erhebung von Zahlungs-, Karten- und Kontodaten, die Prüfung von Zahlungen und die Auszahlungen verantworten der Kunde und Stripe nach ihrem Vertrag; WEBklar erhält diese Daten nicht. Auf Weisung des Kunden legt WEBklar bei Stripe die Zahlung an, ruft die Angaben zu Zahlungen ab, die der Buchungskalender braucht (Nummer 2 Abs. 1), und veranlasst Erstattungen. Daten von Gästen gehen dabei nicht von WEBklar an Stripe, außer der Bezeichnung des Aufenthalts und der Rechnungsnummer auf der Zahlungsseite, der Kennung der Buchung, dem Betrag und der Erstattung selbst. Die Weitergabe von Daten durch Stripe, auch an Stellen außerhalb der Europäischen Union, regeln der Kunde und Stripe; dafür ist WEBklar nicht verantwortlich.

+ +

(5) Plattformen, deren iCal-Kalender der Kunde einbindet oder denen er die iCal-Adresse des Buchungskalenders mitteilt, sind Empfänger nach seiner Entscheidung. WEBklar übermittelt ihnen keine Daten von Gästen.

+ +

8. Unterstützung des Kunden, Betroffenenrechte

+ +

(1) WEBklar leitet Anfragen von Gästen, die an WEBklar gerichtet sind, unverzüglich an den Kunden weiter. WEBklar unterstützt ihn mit geeigneten technischen und organisatorischen Maßnahmen bei der Beantwortung.

+ +

(2) Dafür bietet das Kundenportal die Anzeige der Anfragen und Buchungen, mit denen der Kunde Auskunft erteilen kann, und den Abruf der Rechnungen als PDF. Auf Weisung des Kunden in Textform (etwa im Chat des Kundenportals) anonymisiert WEBklar die Gästedaten einer Anfrage oder Buchung unverzüglich: Name, Firma, E-Mail-Adresse, Telefonnummer und die Freitexte werden gelöscht oder unkenntlich gemacht (ein IP-Hash ist zu diesem Zeitpunkt in der Regel längst entfernt); Anfragenummer, Zeitraum, Beträge und Status bleiben. Rechnungen und Rechnungsadresse einer gebuchten Anfrage bleiben, solange eine Aufbewahrungspflicht besteht (Nummer 9 Abs. 3). Dabei löscht WEBklar die E-Mails zu dieser Anfrage, die noch auf den Versand warten. E-Mails, deren Versand endgültig fehlgeschlagen ist, behalten Empfängeradresse und Inhalt, bis WEBklar sie nach Nummer 9 Abs. 5 löscht (48 Stunden nach dem Fehlschlag).

+ +

(3) Verletzungen des Schutzes personenbezogener Daten meldet WEBklar dem Kunden unverzüglich, möglichst innerhalb von 24 Stunden nach Kenntnis, mit den Informationen, die zu diesem Zeitpunkt vorliegen.

+ +

(4) WEBklar unterstützt den Kunden bei seinen Pflichten aus Art. 32 bis 36 DSGVO. Dazu gehören die Angaben, die er für sein Verzeichnis von Verarbeitungstätigkeiten und für eine etwaige Datenschutz-Folgenabschätzung braucht.

+ +

(5) Die Gäste informiert der Kunde (Art. 13 DSGVO; Nummer 11 Abs. 2).

+ +

9. Löschung und Rückgabe

+ +

(1) Den IP-Hash entfernt WEBklar aus dem Datensatz einer Anfrage, sobald der Kunde sie freigibt oder ablehnt, spätestens 30 Tage nach dem Anlegen.

+ +

(2) Anfragen, aus denen keine Buchung wurde (abgelehnt, abgelaufen, oder neu und nicht innerhalb von 60 Tagen entschieden), anonymisiert WEBklar nach 6 Monaten: Name, Firma, E-Mail-Adresse, Telefonnummer und Nachricht werden gelöscht. Anfragenummer, Zeitraum, Status und, soweit vorhanden, der Preisvorschlag bleiben ohne Personenbezug erhalten.

+ +

(3) Bei gebuchten Aufenthalten anonymisiert WEBklar die Gästedaten (Name, Firma, E-Mail-Adresse, Telefonnummer und Nachricht) 3 Jahre nach dem Ende des Kalenderjahres, in dem der Gast abgereist ist (Abreisejahr; maßgeblich ist die Zeit in Berlin). Rechnungen, Stornorechnungen und die Rechnungsadresse bleiben 8 Jahre erhalten, gerechnet ab dem Ende des Kalenderjahres der Rechnung, solange der Buchungskalender läuft (Buchungsbelege, § 147 AO); sie sind für den Kunden als Aussteller bestimmt. Anfragenummer, Zeitraum, Beträge und Status bleiben ebenfalls.

+ +

(4) Die Anonymisierung nach den Absätzen 2 und 3 sowie die Entfernung des IP-Hash laufen im täglichen Löschlauf; anonymisiert oder entfernt wird frühestens nach Ablauf der jeweiligen Frist. Ist an einem Tag mehr zu bearbeiten, als ein Lauf schafft, folgt der Rest im nächsten Lauf.

+ +

(5) In der Versandwarteschlange für E-Mails leert WEBklar die Empfängeradresse und den Inhalt einer E-Mail nach dem Versand und löscht den Eintrag 7 Tage nach dem Versand. E-Mails, die nicht zugestellt werden können, löscht WEBklar mit Empfängeradresse und Inhalt 48 Stunden nach dem endgültigen Fehlschlag.

+ +

(6) Ist der Buchungskalender abgeschaltet oder der Vertrag über den Betrieb der Website beendet, kann der Kunde die Anfragen, Buchungen und Rechnungen 90 Tage lang im Kundenportal lesen und die Rechnungen einzeln als PDF herunterladen; WEBklar weist ihn vor dem Abschalten per E-Mail darauf hin. Danach löscht WEBklar alle Daten des Buchungskalenders: Unterkünfte, Preise, Anfragen, Buchungen, Rechnungen, Kalenderverbindungen, Sperren und Einstellungen. Damit endet auch die Aufbewahrung der Rechnungen nach Absatz 3; sie bewahrt der Kunde dann selbst auf. Eine Ausnahme ist das Einrichtungs-Ticket, in dem WEBklar die Einrichtung als Arbeitsnachweis festhält: Es bleibt mit einer Kurzfassung der Angaben zur Einrichtung bestehen (zum Beispiel Adresse der Website, Einbau-Code und die Angaben des Kunden aus der Anfrage) und enthält keine Daten von Gästen; dafür gilt die Datenschutzerklärung von WEBklar (Abschnitt 6). Beginnt innerhalb dieser Frist wieder ein Vertrag über den Betrieb der Website, schaltet WEBklar den Buchungskalender auf Wunsch des Kunden mit den vorhandenen Daten wieder ein (Nr. 10 Abs. 5 der Leistungsbeschreibung). Früher anonymisiert WEBklar einzelne Daten auf Weisung des Kunden (Nummer 8 Abs. 2); alle Daten des Buchungskalenders löscht WEBklar auf Weisung des Kunden in Textform unverzüglich.

+ +

(7) Die Daten sind in der täglichen Vollsicherung des Servers enthalten (§ 3 Abs. 5 der Abo-Bedingungen). Gelöschte oder anonymisierte Daten bleiben dort bis zu sieben Tage erhalten und werden dann überschrieben. Wird eine Sicherung zurückgespielt, holt der tägliche Löschlauf die fälligen Löschungen und Anonymisierungen nach; Löschungen auf Weisung des Kunden wiederholt WEBklar.

+ +

(8) Gesetzliche Aufbewahrungspflichten bleiben unberührt. Der Kunde ist für seine eigenen Aufbewahrungspflichten (zum Beispiel für Rechnungen und Buchungsbelege) selbst verantwortlich; WEBklar ist kein Archiv im Sinne der Buchführung. Die Aufbewahrung der Rechnungen nach Absatz 3 geschieht als Dienst für den Kunden und für die Dauer des Buchungskalenders. Der Kunde sichert die Belege, die er braucht, rechtzeitig vor der Löschung nach Absatz 6 durch den Download. Soweit eine gesetzliche Aufbewahrungspflicht besteht, löscht oder anonymisiert WEBklar auch auf Weisung des Kunden nicht früher; stattdessen sperrt es die Daten für die weitere Verarbeitung.

+ +

10. Nachweise und Kontrollen

+ +

WEBklar stellt dem Kunden alle Informationen zur Verfügung, die zum Nachweis der Pflichten aus Art. 28 DSGVO nötig sind, und ermöglicht Überprüfungen einschließlich Inspektionen durch den Kunden oder einen von ihm beauftragten, zur Verschwiegenheit verpflichteten Prüfer. Sie finden nach Anmeldung mit angemessener Frist (in der Regel 14 Tage) zu den Servicezeiten statt, ohne den Betrieb unzumutbar zu stören. Für das Rechenzentrum genügen in der Regel die Nachweise des Betreibers (Zertifizierung der Hetzner Online GmbH nach ISO/IEC 27001). Für mehr als eine Vor-Ort-Kontrolle pro Jahr kann WEBklar eine angemessene Vergütung verlangen.

+ +

11. Pflichten des Kunden

+ +

(1) Der Kunde ist Verantwortlicher für die Verarbeitung der Daten seiner Gäste im Buchungskalender.

+ +

(2) Der Kunde informiert seine Gäste nach Art. 13 DSGVO. Dazu nimmt er den Datenschutz-Absatz für den Buchungskalender in seine Datenschutzerklärung auf (Nr. 5 Abs. 10 der Leistungsbeschreibung) und nennt in seinen Rechtstexten (Datenschutzerklärung, Impressum) die Angaben, die das Gesetz verlangt.

+ +

(3) Der Kunde schließt mit Stripe den Vertrag über sein Stripe-Konto selbst, wenn er die Online-Zahlung nutzt, und verantwortet die Verarbeitung von Daten durch Stripe, soweit sie nicht in diesem Vertrag geregelt ist (Nummer 7 Abs. 4).

+ +

(4) Der Kunde fordert von seinen Gästen keine Angaben zu ihrer Gesundheit oder zu anderen besonderen Kategorien personenbezogener Daten und weist sie auf der Website darauf hin, solche Angaben nicht in das Nachrichtenfeld zu schreiben.

+ +

(5) Der Kunde verändert den Einbau-Code und die gesetzlich vorgeschriebenen Hinweise des Widgets und der Buchungsseite nicht (Nr. 5 Abs. 9 der Leistungsbeschreibung).

+ +

(6) Der Kunde erfüllt seine Pflichten zu Meldeschein, Kurtaxe und sonstigen Meldungen an Behörden selbst und verarbeitet die dafür nötigen Daten außerhalb des Buchungskalenders (Nr. 5 Abs. 6 der Leistungsbeschreibung).

+ +

12. Haftung, Änderungen, Schlussbestimmungen

+ +

(1) Gegenüber betroffenen Personen gilt Art. 82 DSGVO. Für die Haftung zwischen Kunde und WEBklar gilt § 13 der Abo-Bedingungen.

+ +

(2) Eine neue Fassung dieses Vertrags oder der Leistungsbeschreibung, auch wegen geänderter Datenerhebung, teilt WEBklar dem Kunden mindestens sechs Wochen vor ihrem Wirksamwerden in Textform mit. Sie wird wirksam, wenn der Kunde ihr im Kundenportal oder in Textform zustimmt. Stimmt er nicht zu, gilt die bisherige Fassung weiter.

+ +

(3) Ist die neue Fassung nötig, weil ein Gesetz, eine Gerichtsentscheidung oder eine Vorgabe einer Aufsichtsbehörde den Betrieb in der bisherigen Form nicht mehr zulässt, und stimmt der Kunde ihr nicht zu, darf WEBklar den Buchungskalender für seine Website nach Nr. 12 Abs. 2 der Leistungsbeschreibung beenden oder nach Nr. 12 Abs. 3 der Leistungsbeschreibung aussetzen. Das Abo bleibt davon unberührt.

+ +

(4) Im Übrigen gilt § 16 der Abo-Bedingungen.

+ +

Anlage: Technische und organisatorische Maßnahmen des Buchungskalenders (Art. 32 DSGVO)

+ + + + + + + + + + + + + + + + + +
BereichMaßnahmen
ÜbertragungDas Widget, die Buchungsseite und das Kundenportal werden nur über TLS (HTTPS) übertragen. Der Einbau-Code verweist auf eine Adresse mit https://. Die Zahlung geschieht auf der Zahlungsseite von Stripe. Kalender anderer Plattformen ruft WEBklar nur über https ab.
Speicher im BrowserEs werden keine Cookies gesetzt. Das Widget sendet seine Anfragen ohne Cookies und ruft nur die Schnittstelle des Buchungskalenders auf, keine Dienste Dritter.
ZugriffskontrolleDas Kundenportal ist nur nach Anmeldung erreichbar; jeder Kunde sieht nur die Daten seiner eigenen Projekte. Die öffentliche Schnittstelle des Widgets liefert nur für einen vorhandenen Buchungskalender Daten und ist über den Website-Schlüssel (Site-Key) adressiert; die belegten Nächte nennt sie ohne Quelle und ohne Daten von Gästen. Die Buchungsseite ruft der Gast nur mit einem geheimen Token ab, das nur als Prüfsumme gespeichert und zeitkonstant verglichen wird. Benachrichtigungen von Stripe werden nur nach Prüfung ihrer Signatur verarbeitet; die Schlüssel für Stripe liegen nur auf dem Server. Die iCal-Adresse des Buchungskalenders ist ein geheimer, erneuerbarer Zufallswert.
MissbrauchsschutzEin verstecktes Feld (Honeypot), eine Mindestzeit bis zum Absenden des Formulars mit signiertem Formular-Token und Grenzen je IP-Adresse und je Buchungskalender schützen vor automatisierten Anfragen. Die Grenzen gelten im Arbeitsspeicher; ein Neustart leert sie. Mit der Anfrage wird nur ein gesalzener IP-Hash gespeichert (Nummer 3 Abs. 4). Beim Abruf von Kalendern anderer Plattformen sind nur Adressen mit https erlaubt, private und lokale Ziele sind gesperrt, und Größe und Dauer des Abrufs sind begrenzt.
DatenminimierungKartendaten und Kontodaten erhält und speichert WEBklar nicht. Preise berechnet der Server aus den gespeicherten Preisen und Posten, nie aus Angaben des Browsers. Von anderen Kalendern werden nur Zeiträume übernommen. Mit der Anfrage werden keine IP-Adresse im Klartext und kein Browser-Kennzeichen gespeichert; der IP-Hash wird mit der Entscheidung des Kunden entfernt. Die Gästedaten werden nach den Fristen der Nummer 9 anonymisiert. Nach dem Versand einer E-Mail werden Empfängeradresse und Inhalt in der Warteschlange geleert.
Integrität der RechnungenRechnungen und Stornorechnungen werden als unveränderlicher Schnappschuss gespeichert; das PDF entsteht bei jedem Abruf aus diesem Schnappschuss. Rechnungsnummern werden unter Sperre lückenlos je Kunde und Jahr vergeben. Freigabe und Buchung prüfen unter Sperre erneut, dass der Zeitraum frei ist.
TrennungAlle Unterkünfte, Anfragen und Rechnungen tragen die Kennung des Kunden, des Projekts und der Funktion; das Kundenportal und die öffentliche Schnittstelle lesen immer nur die Daten des jeweiligen Buchungskalenders. Die Hintergrundläufe (Ablauf von Reservierungen, Kalenderabgleich, Versand der E-Mails, Anonymisierung und Löschung) schreiben jeweils nur in das Dokument, um das es geht.
LöschungTäglicher Löschlauf für Anfragen, Buchungen und Warteschlange nach den Fristen der Nummer 9; die Daten abgeschalteter Buchungskalender 90 Tage nach dem Abschalten; das Einrichtungs-Ticket bleibt als Arbeitsnachweis mit einer Kurzfassung der Angaben zur Einrichtung bestehen und enthält keine Daten von Gästen (Nummer 9 Abs. 6).
ProtokolleDie Programmprotokolle des Buchungskalenders und der Tagesbericht enthalten nur Zählungen und Anfragenummern, keine Namen, E-Mail-Adressen oder Adressen von Gästen. Server-Protokolle des Webservers werden nach 14 Tagen gelöscht (Anlage 2 der Abo-Bedingungen).
DatensicherungTägliche Vollsicherung des Servers durch Hetzner; verfügbar sind die letzten sieben Tagessicherungen (§ 3 Abs. 5 der Abo-Bedingungen).
RechenzentrumHetzner Online GmbH, Rechenzentren Falkenstein und Nürnberg (Deutschland). Hetzner ist nach ISO/IEC 27001 zertifiziert; der Geltungsbereich umfasst die Hosting-Dienstleistungen und die Rechenzentren.
OrganisationVerpflichtung aller Beteiligten auf Vertraulichkeit, Ablauf für Datenschutzverletzungen (Nummer 8 Abs. 3), Überprüfung der Maßnahmen mindestens einmal im Jahr.
+
+ + diff --git a/public/rechtliches/avv-unterkunft-2026-10-07.pdf b/public/rechtliches/avv-unterkunft-2026-10-07.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6e7b49dd08599dbdd59b7efdbb3b785e32a29d97 GIT binary patch literal 131774 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 literal 0 HcmV?d00001 diff --git a/public/rechtliches/avv-unterkunft-2026-10-07.pdf.sha256 b/public/rechtliches/avv-unterkunft-2026-10-07.pdf.sha256 new file mode 100644 index 0000000..a242e04 --- /dev/null +++ b/public/rechtliches/avv-unterkunft-2026-10-07.pdf.sha256 @@ -0,0 +1 @@ +59c834a1fb774340a3c6d604391786e049f253cd491ec562dd6129bce75e3d49 diff --git a/public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.html b/public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.html new file mode 100644 index 0000000..6625d0c --- /dev/null +++ b/public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.html @@ -0,0 +1,255 @@ + + + + + + + Leistungsbeschreibung Buchungskalender – WEBklar + + + +
+ + +
WEBKLAR
+

Leistungsbeschreibung Buchungskalender

+ +

Fassung 2026-10-07 · Entwurf – Prüfung durch Kanzlei offen · Zusatzbedingungen zum Vertrag über den Betrieb der Website

+ +

1. Geltung

+ +

(1) Diese Leistungsbeschreibung regelt die Funktion „Buchungskalender“. Mit dem Buchungskalender nimmt der Kunde über seine Website Anfragen für die Vermietung von Unterkünften entgegen (Ferienwohnungen, Monteurzimmer, kleine Pensionen) und rechnet die Aufenthalte ab („Vermieter“); Gäste sind die Besucher seiner Website, die im Buchungskalender anfragen und buchen („Gäste“). Die Leistungsbeschreibung ist eine Zusatzleistung zum Vertrag über den Betrieb der Website: Sie setzt voraus, dass WEBklar die Website des Vermieters aufgrund eines Vertrags betreibt, etwa im Hosting-Abo, im Wartungs-Abo oder aufgrund eines anderen Vertrags über den Betrieb der Website. Sie richtet sich nur an Unternehmer, die in eigenem Namen und für eigene Rechnung vermieten.

+ +

(2) Sie wird vereinbart, wenn der Vermieter die Einrichtung des Buchungskalenders im Kundenportal bestellt und dabei dieser Leistungsbeschreibung, dem Auftragsverarbeitungsvertrag Buchungskalender („AVV Buchungskalender“) und der Widerrufsbelehrung zustimmt. Wie die Zustimmung abläuft, regelt die Vorbemerkung des AVV Buchungskalender. Bestellen kann der Vermieter erst, nachdem WEBklar seine Anfrage für den Buchungskalender geprüft und angenommen hat (Nr. 2 Abs. 1). Für einen Vermieter, dem WEBklar die Funktion als Teil seines Website-Projekts bereitstellt, schaltet WEBklar sie nach seiner Zustimmung in Textform frei; die Bedingungen dieser Leistungsbeschreibung gelten dann ebenso, ein Einrichtungspreis fällt nur an, wenn er vereinbart ist.

+ +

(3) Im Übrigen gelten die Abo-Bedingungen. Bei Widersprüchen geht für den Buchungskalender diese Leistungsbeschreibung vor, in Datenschutzfragen der AVV Buchungskalender.

+ +

(4) Leistungsbeschreibung A Nr. 2 Abs. 3 und Nr. 4 sowie Leistungsbeschreibung B Nr. 3 der Abo-Bedingungen (Formulare mit Server, „Rechtstexte … nicht enthalten“) stehen dem Buchungskalender nicht entgegen. Das Widget des Buchungskalenders läuft auf dem Server von WEBklar, nicht auf dem Server der Website, und der Muster-Text zur Stornierung nach Nr. 6 ist Teil des Buchungskalenders. Das gilt auch im Hosting-Abo.

+ +

2. Leistung

+ +

(1) Der Vermieter fragt den Buchungskalender im Kundenportal an und beschreibt seine Unterkünfte (Art der Unterkunft, Zahl der Einheiten, ob er Booking.com oder Airbnb nutzt). WEBklar prüft die Anfrage und nimmt sie an oder lehnt sie mit einer Begründung ab. Ein Anspruch auf Annahme besteht nicht. Erst nach der Annahme kann der Vermieter die Einrichtung bestellen.

+ +

(2) Die Einrichtung umfasst den Einbau eines Kalender-Widgets an einer Stelle der Website des Vermieters, die Bereitstellung der Verwaltung im Kundenportal, den Einbau des Datenschutz-Absatzes für den Buchungskalender (Nr. 5 Abs. 10) und die Freischaltung durch WEBklar. Für jede Website wird ein Buchungskalender eingerichtet; er kann mehrere Unterkünfte desselben Vermieters enthalten. Zusätzlich gibt es für jeden freigegebenen Aufenthalt eine Buchungsseite bei WEBklar, die der Gast über den Link in seiner E-Mail erreicht.

+ +

(3) So läuft eine Buchung ab:

+ +
    +
  • Das Widget zeigt dem Gast die belegten Nächte. Er wählt Anreise und Abreise, gibt Personenzahl, Namen, E-Mail-Adresse und auf Wunsch Firma, Telefonnummer und Nachricht an und sendet eine unverbindliche Anfrage. Er erhält eine Eingangsbestätigung, der Vermieter eine Benachrichtigung.
  • +
  • Der Vermieter prüft die Anfrage im Kundenportal, sieht den vorgerechneten Preis, kann die Posten ändern und gibt die Anfrage mit einer Reservierungsfrist frei oder lehnt sie ab. Gibt er sie frei, reserviert der Buchungskalender die Nächte bis zum Ablauf der Frist, und der Gast erhält eine E-Mail mit Preis, Stornobedingungen und dem Link zur Buchungsseite.
  • +
  • Auf der Buchungsseite sieht der Gast alle Angaben zum Aufenthalt, trägt seine Rechnungsadresse ein, wählt die Zahlart (online über Stripe, wenn der Vermieter sie eingeschaltet hat, oder vor Ort) und bucht mit der Schaltfläche „Zahlungspflichtig buchen“. Erst damit kommt der Vertrag zwischen Vermieter und Gast zustande, nicht schon mit der Anfrage oder der Freigabe.
  • +
  • Mit der Buchung erzeugt der Buchungskalender eine Rechnung mit lückenloser Nummer und sendet dem Gast eine Buchungsbestätigung mit der Rechnung als PDF; der Vermieter wird benachrichtigt.
  • +
  • Verstreicht die Frist ohne Buchung, läuft die Reservierung ab und die Nächte werden frei; der Gast erhält darüber eine E-Mail.
  • +
  • Der Vermieter kann einen Aufenthalt stornieren. Dann erhält der Gast eine Stornorechnung mit eigener Nummer und, soweit der Vermieter eine Online-Zahlung erstattet, eine Mitteilung über den Erstattungsbetrag. Eine Stornierung durch den Gast gibt es im Widget nicht; er wendet sich an den Vermieter.
  • +
+ +

(4) Im Kundenportal verwaltet der Vermieter:

+ +
    +
  • Unterkünfte mit Beschreibung, Höchstzahl der Personen, Mindestnächten und Check-in- und Check-out-Zeiten,
  • +
  • Preise (Staffel nach Aufenthaltsdauer, Endreinigung, Zusatzpersonen, Direktbuchungsrabatt, Steuerart und Steuersätze) und seine Stornobedingungen,
  • +
  • Anfragen und Buchungen mit Status, die Eintragung „bezahlt (vor Ort)“ und Stornierungen,
  • +
  • Kalender mit manuellen Sperren,
  • +
  • die Verbindungen zu anderen Kalendern (Nr. 4),
  • +
  • seine Rechnungen als PDF,
  • +
  • seine Angaben als Aussteller der Rechnungen (Name, Anschrift, Steuernummer oder Umsatzsteuer-Identifikationsnummer, Bankverbindung, Rechnungspräfix) und die Verbindung mit seinem Stripe-Konto (Nr. 3).
  • +
+ +

(5) Der Buchungskalender versendet im Namen des Vermieters E-Mails an die Gäste: Eingang der Anfrage, Freigabe mit Buchungslink, Ablehnung, Buchungsbestätigung mit Rechnung, Zahlungseingang, Ablauf der Reservierung und Stornierung. Absender ist die Versandadresse von WEBklar mit dem Namen des Vermieters, als Antwortadresse dient seine E-Mail-Adresse. Den Vermieter benachrichtigt der Buchungskalender über neue Anfragen und neue Buchungen sowie, wenn der Abgleich mit einem anderen Kalender seit mindestens sechs Stunden fehlschlägt.

+ +

(6) Der Buchungskalender enthält einen Missbrauchsschutz gegen automatisierte Anfragen (verstecktes Feld, Mindest-Ausfüllzeit, Obergrenzen je IP-Adresse). Dafür speichert WEBklar mit der Anfrage nur einen Hashwert der IP-Adresse, nicht die IP-Adresse selbst; er wird entfernt, sobald der Vermieter die Anfrage freigibt oder ablehnt, spätestens nach 30 Tagen (Nummer 3 Abs. 4 des AVV Buchungskalender).

+ +

(7) Nicht enthalten sind:

+ +
    +
  • der Meldeschein nach dem Bundesmeldegesetz und die Verwaltung der Meldedaten,
  • +
  • Kurtaxe, Gästebeitrag und Beherbergungsabgaben,
  • +
  • Anzahlungen und Teilzahlungen (der Gast zahlt den Gesamtbetrag in einer Zahlung, online oder vor Ort),
  • +
  • Sofortbuchung ohne Freigabe,
  • +
  • saisonale Preise (die Preise richten sich nur nach der Aufenthaltsdauer),
  • +
  • Gutscheine, Channel-Manager-Anbindungen außer dem Kalenderabgleich nach Nr. 4 und Mehrsprachigkeit (der Buchungskalender ist deutschsprachig),
  • +
  • die Buchführung des Vermieters.
  • +
+ +

Zusätzliche Wünsche, etwa ein Sonderdesign, ein zweiter Buchungskalender oder eine über das übliche Maß hinausgehende Zahl von Unterkünften, gehören nicht zur Einrichtung nach Nr. 9. WEBklar führt sie nach Absprache nach Stunden aus (Nr. 9 Abs. 5).

+ +

3. Zahlungen über Stripe und Rechnungen im Namen des Vermieters

+ +

(1) Online-Zahlungen im Buchungskalender sind optional und laufen über Stripe Connect. Der Vermieter verbindet dazu sein eigenes Stripe-Konto mit dem Buchungskalender. Hat er für den Webshop von WEBklar bereits ein Stripe-Konto verbunden, kann er es auch für den Buchungskalender verwenden. Den Vertrag über dieses Konto schließt der Vermieter unmittelbar mit Stripe; WEBklar ist daran nicht beteiligt. Für das Konto, die Prüfung des Vermieters durch Stripe und die Auszahlungen gelten die Bedingungen von Stripe. Ohne verbundenes und freigeschaltetes Stripe-Konto ist nur die Zahlart „vor Ort“ möglich.

+ +

(2) Das Geld der Gäste fließt direkt an den Vermieter (Zahlung unmittelbar auf dem Konto des Vermieters, sogenannte Direct Charge). WEBklar erhält und verwahrt kein Geld der Gäste, leitet keines weiter und beteiligt sich nicht am Umsatz des Vermieters. WEBklar ist kein Zahlungsdienstleister. Die Gebühren von Stripe trägt der Vermieter; sie fallen nur zwischen dem Vermieter und Stripe an.

+ +

(3) Der Vermieter prüft selbst, ob sein Stripe-Konto Zahlungen annehmen und Auszahlungen leisten kann. WEBklar zeigt ihm im Kundenportal den Stand, den Stripe meldet, hat aber keinen Einfluss darauf, ob und wann Stripe ein Konto freischaltet, einschränkt oder sperrt, und haftet dafür nicht. Rückbuchungen, Streitfälle mit Gästen und Zahlungsausfälle regeln der Vermieter und Stripe.

+ +

(4) Erstattungen bei einer Stornierung veranlasst der Vermieter im Kundenportal; WEBklar führt die Erstattung über das Stripe-Konto des Vermieters aus. Er bestimmt den Betrag bis zur Höhe der Zahlung des Gastes. Erstattungen aus dem Stripe-Dashboard trägt WEBklar in die Buchung nach, soweit Stripe sie meldet.

+ +

(5) Die Zahlungsseite selbst (Stripe Checkout) betreibt Stripe. Kartendaten und Kontodaten gibt der Gast nur dort ein; WEBklar erhält sie nicht.

+ +

(6) Rechnungen im Namen des Vermieters. Der Vermieter beauftragt WEBklar mit der Zustimmung bei der Bestellung, in seinem Namen und für seine Rechnung Rechnungen und Stornorechnungen an seine Gäste auszustellen (Rechnung durch einen Dritten im Namen und im Auftrag des Leistenden, § 14 Abs. 2 Satz 4 UStG). Aussteller der Rechnung ist der Vermieter; sie trägt seinen Namen, seine Anschrift, seine Steuernummer oder Umsatzsteuer-Identifikationsnummer und keinen Hinweis auf WEBklar. WEBklar erzeugt die Rechnung aus den Angaben, die der Vermieter hinterlegt und bei der Freigabe bestätigt hat. Er verantwortet die Richtigkeit seiner Angaben, der Preise, der Steuerart und der Steuersätze; WEBklar prüft sie nicht steuerrechtlich. Die Rechnung wird nach ihrer Ausstellung nicht mehr verändert; Fehler korrigiert der Vermieter durch Stornierung und neue Buchung nach den Möglichkeiten des Kundenportals. Die Zustimmung zu diesem Auftrag gibt der Vermieter bei der Bestellung und bestätigt sie in den Einstellungen des Buchungskalenders. Widerruft er den Auftrag in Textform, stellt der Buchungskalender keine Rechnungen mehr aus und ist für ihn nicht mehr nutzbar.

+ +

(7) Die Rechnungsnummern sind je Vermieter und Jahr lückenlos fortlaufend; sie bestehen aus dem Präfix, das der Vermieter vor der ersten Rechnung festlegt, dem Jahr und einer laufenden Nummer.

+ +

4. Verfügbarkeit und Kalenderabgleich (iCal)

+ +

(1) Der Vermieter kann Kalender anderer Plattformen (zum Beispiel Booking.com oder Airbnb) über eine iCal-Adresse einlesen lassen; die eingelesenen Zeiträume blockiert der Buchungskalender. Umgekehrt stellt der Buchungskalender dem Vermieter eine geheime iCal-Adresse bereit, die er bei anderen Plattformen einträgt; sie enthält die belegten Nächte ohne Daten der Gäste. Der Vermieter kann diese Adresse jederzeit erneuern; die bisherige Adresse funktioniert dann nicht mehr.

+ +

(2) Der Abgleich läuft regelmäßig, aber zeitversetzt: WEBklar liest die Kalender anderer Plattformen etwa alle 15 Minuten ein, und die anderen Plattformen lesen die Adresse des Buchungskalenders nach ihrem eigenen Takt, oft nur alle paar Stunden. Zwischen einer Buchung hier und ihrem Eingang dort können deshalb Minuten bis Stunden vergehen, und umgekehrt. WEBklar sagt keine Echtzeit-Verfügbarkeit zu und übernimmt keine Gewähr dafür, dass eine Unterkunft nicht doppelt gebucht wird.

+ +

(3) Dieses Risiko mindert die Freigabe: Jede Anfrage im Buchungskalender braucht die Freigabe des Vermieters. Er prüft vor der Freigabe seine anderen Plattformen und seinen Kalender. Beim Freigeben und beim Buchen prüft der Buchungskalender zusätzlich, ob die Nächte nach seinem Stand frei sind. Eine Doppelbuchung entsteht trotzdem, wenn eine andere Plattform eine Buchung noch nicht gemeldet hat oder der Abgleich ausfällt. Der Vermieter löst eine Doppelbuchung selbst (etwa durch Stornierung) und trägt die Folgen gegenüber seinen Gästen und den Plattformen.

+ +

(4) Fehlerhafte oder nicht erreichbare iCal-Adressen kann WEBklar nicht beheben. Schlägt der Abruf fehl, bleibt der zuletzt gelesene Stand erhalten, und der Vermieter wird benachrichtigt, wenn der Abruf seit mindestens sechs Stunden nicht gelungen ist (höchstens einmal je 24 Stunden und Kalender). Eingelesen werden nur Zeiträume von gestern bis 18 Monate in die Zukunft, höchstens 1 Megabyte je Kalender; nur Adressen mit https werden abgerufen.

+ +

5. Pflichten des Vermieters

+ +

(1) Der Vermieter hat einen laufenden Vertrag mit WEBklar über den Betrieb seiner Website (Hosting-Abo, Wartungs-Abo oder ein anderer Vertrag über den Betrieb der Website), ist Unternehmer und vermietet in eigenem Namen. Will er Online-Zahlungen nutzen, stellt er sein eigenes Stripe-Konto bereit und schließt die Anmeldung bei Stripe selbst ab.

+ +

(2) Er verantwortet seine Unterkünfte, Preise und Angaben zum Angebot. Dazu gehören richtige Preise einschließlich Steuerausweis (Umsatzsteuer, für die Beherbergung und die Endreinigung nach den dafür geltenden Steuersätzen, oder Hinweis auf § 19 UStG), Check-in- und Check-out-Zeiten, Höchstbelegung, Mindestnächte und alle Angaben, die er seinen Gästen vor der Buchung geben muss. Die Steuerart und die Steuersätze trägt er selbst im Kundenportal ein; WEBklar berät dazu nicht.

+ +

(3) Er legt vor der Freischaltung seine Stornobedingungen fest und verantwortet sie. Der Muster-Text nach Nr. 6 ist nur ein Vorschlag.

+ +

(4) Er verantwortet die Verfügbarkeit seiner Unterkünfte, pflegt Sperren und Kalenderverbindungen im Kundenportal und prüft regelmäßig auf neue Anfragen und Buchungen. Die Folgen von Angaben, die er setzt (zum Beispiel einer fälschlich freien oder gesperrten Zeit), trägt er.

+ +

(5) Er gibt Anfragen nur frei, wenn er die Unterkunft für den Zeitraum zu den angegebenen Bedingungen bereitstellen kann, und erfüllt die gebuchten Aufenthalte. Er trägt alle Pflichten eines Vermieters gegenüber seinen Gästen, auch Gewährleistung, Kundenservice und Beschwerden.

+ +

(6) Er erfüllt seine gesetzlichen Pflichten rund um die Beherbergung selbst. Das betrifft insbesondere den Meldeschein nach dem Bundesmeldegesetz, die Kurtaxe und andere kommunale Abgaben, Anzeige- und Genehmigungspflichten für die Vermietung (zum Beispiel Zweckentfremdungs- oder Gewerberecht) sowie die Pflichten aus seinem Steuerrecht. Der Buchungskalender nimmt ihm davon nichts ab.

+ +

(7) Anzahlungen und Teilzahlungen bietet der Buchungskalender nicht an. Vereinbart der Vermieter außerhalb des Buchungskalenders etwas anderes mit seinem Gast, ist das nicht Gegenstand dieser Leistungsbeschreibung.

+ +

(8) Er erfüllt seine Aufbewahrungspflichten selbst, etwa nach der Abgabenordnung und dem Handelsgesetzbuch. WEBklar ist kein Archiv für die Buchführung und kein Buchführungssystem. WEBklar bewahrt die Rechnungen des Vermieters im Buchungskalender 8 Jahre auf, solange der Buchungskalender läuft und nach Nr. 10 bis zur Löschung, hält sie ihm zum Abruf als PDF bereit und anonymisiert personenbezogene Daten der Gäste nach Nummer 9 des AVV Buchungskalender. Der Vermieter lädt seine Rechnungen deshalb rechtzeitig vor der Löschung nach Nr. 10 Abs. 3 herunter und bewahrt sie selbst auf.

+ +

(9) Er hält die Vorgaben dieser Leistungsbeschreibung ein und verändert den Einbau-Code und die gesetzlich vorgeschriebenen Hinweise des Widgets und der Buchungsseite nicht.

+ +

(10) Liegt die Datenschutzerklärung in der von WEBklar betreuten Website, fügt WEBklar beim Einbau dort den Datenschutz-Absatz für den Buchungskalender ein; das gehört zur Einrichtung. Liegt sie woanders, erhält der Vermieter den Absatz als Textbaustein und fügt ihn selbst ein. Für den übrigen Inhalt seiner Datenschutzerklärung bleibt er verantwortlich (§ 6 Abs. 3 der Abo-Bedingungen). Fällt WEBklar beim Einfügen ein offensichtlicher Widerspruch auf, weist WEBklar den Vermieter darauf hin; eine Pflicht zur Prüfung der Datenschutzerklärung entsteht daraus nicht.

+ +

(11) Der Vermieter informiert seine Gäste nach Art. 13 DSGVO. Die Rollen im Datenschutz regelt der AVV Buchungskalender: Der Vermieter ist Verantwortlicher, WEBklar Auftragsverarbeiter, Stripe Vertragspartner des Vermieters.

+ +

6. Muster-Text zur Stornierung, keine Rechtsberatung

+ +

(1) WEBklar stellt dem Vermieter einen Muster-Text für Stornobedingungen bereit. Er ist eine Vorlage ohne Gewähr und keine Rechtsberatung (kein Rechtsrat im Sinne des Rechtsdienstleistungsgesetzes). Er passt zur Technik des Buchungskalenders, kann aber auf den Betrieb des Vermieters nicht zugeschnitten sein.

+ +

(2) WEBklar empfiehlt, die Stornobedingungen und die Angaben zum Angebot vor der Freischaltung von einer Rechtsanwältin oder einem Rechtsanwalt prüfen zu lassen.

+ +

(3) Der Vermieter bleibt für seine Stornobedingungen und alle seine Texte verantwortlich, auch wenn er den Muster-Text unverändert übernimmt (Nr. 5 Abs. 3). Die Stornobedingungen, die bei der Freigabe galten, speichert der Buchungskalender mit der Anfrage; die Buchungsseite und die Buchungsbestätigung zeigen dem Gast diese Fassung.

+ +

7. Kein Widerrufsrecht des Gastes, Hinweise auf der Buchungsseite

+ +

(1) Für die Buchung von Beherbergungsleistungen zu einem bestimmten Zeitpunkt oder in einem bestimmten Zeitraum besteht nach § 312g Abs. 2 Nr. 9 BGB kein gesetzliches Widerrufsrecht. Die Buchungsseite weist den Gast darauf hin; der Vermieter kann ihm vertraglich ein weitergehendes Recht einräumen, der Buchungskalender bietet dafür aber keine Funktion.

+ +

(2) Die Buchungsseite zeigt dem Gast vor der Schaltfläche „Zahlungspflichtig buchen“ die wesentlichen Angaben nach Art. 246a EGBGB, soweit der Buchungskalender sie kennt (Anbieter, Unterkunft, Zeitraum, Leistung, Gesamtpreis, Zahlart, Stornobedingungen, Hinweis auf das fehlende Widerrufsrecht). Der Vermieter ergänzt, was darüber hinausgeht, in seinen Texten selbst (Nr. 5 Abs. 2).

+ +

(3) Die Buchungsbestätigung erhält der Gast als E-Mail mit der Rechnung als PDF; sie enthält die Angaben zum Vertrag und die Stornobedingungen auf einem dauerhaften Datenträger.

+ +

8. Verfügbarkeit und Störungen

+ +

(1) Das Verfügbarkeitsziel nach § 5 der Abo-Bedingungen gilt für die Website, nicht für den Buchungskalender. WEBklar sagt für den Buchungskalender keine bestimmte Verfügbarkeit zu, die über den Betrieb der Website im Abo hinausgeht. Störungen des Buchungskalenders beheben wir in angemessener Frist (§ 12 der Abo-Bedingungen).

+ +

(2) Angekündigte Wartungsfenster (§ 5 der Abo-Bedingungen) können den Buchungskalender kurzzeitig unterbrechen. Während einer Unterbrechung sind Anfragen und Buchungen nicht möglich; das Widget zeigt dann einen Ausweichtext.

+ +

(3) Zahlungen übernimmt der Buchungskalender über Benachrichtigungen von Stripe und einen Abgleich beim Aufruf der Buchungsseite. Fällt die Verbindung zu Stripe oder zum Server aus, kann sich die Bestätigung einer Zahlung verzögern. Ausfälle von Stripe, von Zahlungsarten und von Banken liegen nicht im Einflussbereich von WEBklar.

+ +

(4) Alle Zeiten gelten in der Zeitzone Europe/Berlin.

+ +

(5) WEBklar übernimmt keine Gewähr dafür, dass E-Mails zugestellt und gelesen werden. Das hängt vom Postfach des Empfängers und von den Mailgrenzen seines Anbieters ab.

+ +

(6) Die gesetzlichen Rechte des Vermieters sowie §§ 12 und 13 der Abo-Bedingungen bleiben unberührt.

+ +

9. Preis, Abrechnung und Widerruf

+ +

(1) Die Einrichtung kostet 199 € einmalig je Website-Projekt, ohne Umsatzsteuer gemäß § 19 UStG. Für den Betrieb des Buchungskalenders berechnet WEBklar nichts weiter; es gibt keine laufende Gebühr und keine Beteiligung am Umsatz oder an den Buchungen. Der Buchungskalender läuft, solange WEBklar die Website betreibt (Nr. 10).

+ +

(2) Die Einrichtung dauert nach der Erfahrung von WEBklar meist 1 bis 2 Wochen ab der Bestellung. Sie hängt davon ab, wie schnell der Vermieter Unterkünfte, Preise und gegebenenfalls das Stripe-Konto bereitstellt und wie umfangreich der Einbau ist. Die Dauer ist eine Einschätzung und keine verbindliche Zusage eines Termins.

+ +

(3) Der Vermieter bezahlt bei der Bestellung im Kundenportal über Stripe und erhält eine Rechnung. Für einen Vermieter, dem WEBklar die Funktion als Teil seines Website-Projekts bereitstellt (Nr. 1 Abs. 2), gilt die dafür getroffene Vereinbarung.

+ +

(4) Der Preis steht neben den Leistungen eines Abos: Die Einrichtung wird weder auf ein Stundenkontingent angerechnet noch damit bezahlt.

+ +

(5) Mehraufwand, der nicht zur Einrichtung gehört (Nr. 2 Abs. 7), führt WEBklar nur nach Absprache vor der Ausführung und nach Freigabe des Vermieters in Textform aus. WEBklar nennt vorher den geschätzten Aufwand und berechnet 100 € je Stunde in Schritten von 15 Minuten, ohne Umsatzsteuer gemäß § 19 UStG (§ 4 der Abo-Bedingungen). Der Mehraufwand wird gesondert berechnet und nicht auf ein Stundenkontingent angerechnet.

+ +

(6) Verbraucher können die Bestellung der Einrichtung nach der Widerrufsbelehrung widerrufen. Belehrung und Muster-Widerrufsformular stehen in der Anlage „Widerrufsbelehrung und Muster-Widerrufsformular (Einrichtung von Funktionen)“. Ob das Widerrufsrecht erlischt und ob der Vermieter einen angemessenen Betrag für die bis dahin erbrachte Leistung schuldet, richtet sich nach der Zustimmung, die er bei der Bestellung gibt, und nach den Hinweisen zum Widerruf in der Anlage. Mit dem Widerruf endet der Buchungskalender. Dieses Widerrufsrecht des Vermieters gegenüber WEBklar ist vom Widerrufsrecht der Gäste gegenüber dem Vermieter (Nr. 7) zu unterscheiden.

+ +

10. Laufzeit und Ende

+ +

(1) Der Buchungskalender läuft, solange WEBklar die Website des Vermieters betreibt. Endet der Vertrag über den Betrieb der Website, endet auch der Buchungskalender; WEBklar schaltet ihn zum Vertragsende ab und informiert den Vermieter vorher per E-Mail und weist ihn darauf hin, seine Rechnungen als PDF herunterzuladen. Das gilt auch beim Widerruf dieses Vertrags.

+ +

(2) Mit dem Abschalten nimmt der Buchungskalender keine neuen Anfragen und Buchungen mehr an, und das Widget zeigt den Ausweichtext. Reservierungen laufen aus. Bereits gebuchte Aufenthalte bleiben Verträge zwischen dem Vermieter und seinen Gästen; der Vermieter erfüllt sie und informiert seine Gäste, wenn er den Buchungskalender nicht mehr anbietet. Anfragen, Buchungen und Rechnungen bleiben im Kundenportal 90 Tage lesbar; Rechnungen kann er einzeln als PDF herunterladen.

+ +

(3) WEBklar löscht alle Daten des Buchungskalenders, also Unterkünfte, Preise, Anfragen, Buchungen, Rechnungen, Kalenderverbindungen, Sperren und Einstellungen, 90 Tage nach dem Abschalten. Eine Ausnahme ist das Einrichtungs-Ticket, in dem WEBklar die Einrichtung als Arbeitsnachweis festhält: Es bleibt mit einer Kurzfassung der Angaben zur Einrichtung bestehen und enthält keine Daten von Gästen (Nummer 9 Abs. 6 des AVV Buchungskalender). Die Aufbewahrungsfrist der Rechnungen (Nr. 5 Abs. 8) endet damit mit der Löschung; der Vermieter bewahrt sie danach selbst auf.

+ +

(4) Das Stripe-Konto bleibt beim Vermieter. Das Ende des Buchungskalenders berührt weder das Konto noch die Auszahlungen noch den Vertrag mit Stripe. Der Vermieter kann die Verbindung zwischen dem Konto und dem Buchungskalender im Stripe-Dashboard beenden.

+ +

(5) Beginnt innerhalb der 90 Tage wieder ein Vertrag über den Betrieb der Website, schaltet WEBklar den Buchungskalender auf Wunsch des Vermieters in Textform mit den vorhandenen Daten und Einstellungen ohne weitere Kosten wieder ein. Nach der Löschung ist eine neue Anfrage und eine neue Einrichtung nötig (neuer Preis nach Nr. 9).

+ +

(6) Endet der Vertrag über den Betrieb der Website, bevor WEBklar den Buchungskalender freigeschaltet hat, erstattet WEBklar den gezahlten Einrichtungspreis vollständig.

+ +

(7) Auf Wunsch des Vermieters in Textform schaltet WEBklar den Buchungskalender jederzeit ab. Eine Erstattung des Einrichtungspreises folgt daraus nicht; für den Widerruf gilt Nr. 9 Abs. 6.

+ +

11. Haftung

+ +

(1) Der Buchungskalender ist ein Hilfsmittel für die Vermietung des Vermieters. Der Vertrag über die Unterkunft besteht allein zwischen dem Vermieter und dem Gast; WEBklar ist daran nicht beteiligt.

+ +

(2) Für entgangenen Gewinn und Folgeschäden aus Störungen des Buchungskalenders, aus Verzögerungen oder Fehlern beim Kalenderabgleich (Nr. 4), aus Doppelbuchungen und aus nicht zugestellten E-Mails haftet WEBklar nur im Rahmen von § 13 Abs. 1 und 2 der Abo-Bedingungen.

+ +

(3) WEBklar haftet nicht für Inhalte des Vermieters, insbesondere nicht für seine Unterkünfte, Preise, Steuerangaben, Stornobedingungen und Rechtstexte, auch nicht für den Muster-Text, den er übernommen hat (Nr. 6), und nicht für die Erfüllung seiner Pflichten gegenüber den Gästen und den Behörden (Nr. 5).

+ +

(4) WEBklar haftet nicht für Ausfälle, Sperren oder Entscheidungen von Stripe und der Zahlungsarten sowie für Rückbuchungen und Zahlungsausfälle (Nr. 3 Abs. 3), und nicht für Ausfälle, Änderungen und Entscheidungen anderer Plattformen, deren Kalender der Vermieter einbindet.

+ +

(5) Die Haftung nach § 13 Abs. 1 der Abo-Bedingungen (unter anderem bei Vorsatz, grober Fahrlässigkeit, Verletzung von Leben, Körper oder Gesundheit und nach dem Produkthaftungsgesetz) bleibt unberührt. Der Haftungsrahmen des Vermieters gegenüber seinen Gästen bleibt unberührt.

+ +

12. Änderungen und Einstellung

+ +

(1) WEBklar darf die Technik des Buchungskalenders verbessern, solange der Leistungsumfang nicht schlechter wird (§ 3 Abs. 7 der Abo-Bedingungen). Ändert sich dabei, welche Daten erhoben werden, gilt Nummer 12 des AVV Buchungskalender.

+ +

(2) WEBklar darf den Buchungskalender für eine Website mit einer Frist von vier Wochen beenden oder für alle Vermieter mit einer Frist von drei Monaten einstellen, wenn

+ +
    +
  • ein Gesetz, eine Gerichtsentscheidung oder eine Vorgabe einer Aufsichtsbehörde den Betrieb in der bisherigen Form unzulässig macht oder nur mit wesentlich anderer Technik erlaubt und der Vermieter einer dafür nötigen neuen Fassung nicht zustimmt (AVV Buchungskalender Nummer 12),
  • +
  • Stripe die Anbindung nach Nr. 3 beendet oder wesentlich ändert, so dass die Online-Zahlung in der bisherigen Form nicht weiterbetrieben werden kann (dann entfällt nur die Online-Zahlung, soweit der Buchungskalender ohne sie weiterläuft), oder
  • +
  • eine Sicherheitslücke sich nicht anders beheben lässt.
  • +
+ +

Die Mitteilung erfolgt in Textform und nennt den Grund, die Merkmale der Änderung, den Zeitpunkt und bei Verbrauchern das Recht, den Vertrag nach § 327r Abs. 3 BGB zu beenden, mit seiner Frist.

+ +

(3) Ist der Weiterbetrieb aus einem Grund nach Absatz 2 schon vor Ablauf der Frist nicht zulässig, darf WEBklar den Buchungskalender ohne Vorankündigung aussetzen, solange das nötig ist. WEBklar informiert den Vermieter darüber unverzüglich in Textform mit dem Grund und nimmt den Betrieb wieder auf, sobald das zulässig und technisch möglich ist.

+ +

(4) Eine Einstellung ohne einen Grund nach Absatz 2 ist ausgeschlossen. Gesetzliche Rechte von Verbrauchern bei Änderungen digitaler Produkte (§ 327r BGB) bleiben unberührt.

+ +

13. Hinweise

+ +

(1) Keine Rechtsberatung. Der Buchungskalender und der Muster-Text sind technische Hilfsmittel, keine Rechtsberatung (Nr. 6). Die rechtliche und steuerliche Einordnung seiner Vermietung, seiner Preisangaben und seines Angebots trägt der Vermieter.

+ +

(2) Barrierefreiheit. Das Widget ist für die Bedienung mit Tastatur und Hilfstechniken gestaltet (Beschriftungen der Tage, Bedienung mit Pfeiltasten, Fehlermeldungen als Live-Region). Eine Konformität nach WCAG 2.1 AA oder EN 301 549 sagt WEBklar nicht zu. Ob der Vermieter als Anbieter von Dienstleistungen im elektronischen Geschäftsverkehr unter das BFSG fällt (Ausnahme für Kleinstunternehmen, § 3 Abs. 3 BFSG), entscheidet und prüft der Vermieter.

+
+ + diff --git a/public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.pdf b/public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bbe803a8c82a96af5eb5a4607561e3af4c5ab304 GIT binary patch literal 136408 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 Tn%~C=!cvTizP|P3u`2%p*;*e2 literal 0 HcmV?d00001 diff --git a/public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.pdf.sha256 b/public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.pdf.sha256 new file mode 100644 index 0000000..90ccf23 --- /dev/null +++ b/public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.pdf.sha256 @@ -0,0 +1 @@ +4d7fb04c2cc24adc8a4cc9926a3272d01bcc5870360aab595c9602e8f1afd1ba diff --git a/public/rechtliches/widerrufsbelehrung-funktionen-2026-10-07.html b/public/rechtliches/widerrufsbelehrung-funktionen-2026-10-07.html new file mode 100644 index 0000000..4bef9ab --- /dev/null +++ b/public/rechtliches/widerrufsbelehrung-funktionen-2026-10-07.html @@ -0,0 +1,105 @@ + + + + + + + Widerrufsbelehrung und Muster-Widerrufsformular (Funktionen) – WEBklar + + + +

+ + +
WEBKLAR
+

Widerrufsbelehrung und Muster-Widerrufsformular (Einrichtung von Funktionen)

+ +

Fassung 2026-10-07

+ +

Das Widerrufsrecht gilt nur für Verbraucher. Wir zeigen die Belehrung und das Muster-Widerrufsformular trotzdem allen, die eine Funktion bestellen. Die Belehrung gilt für die Bestellung der Einrichtung einer Funktion im Kundenportal, zum Beispiel des Terminplaners. Hinweise dazu stehen nach dem Muster-Widerrufsformular.

+ +

Widerrufsbelehrung

+ +

Widerrufsrecht

+ +

Sie haben das Recht, binnen vierzehn Tagen ohne Angabe von Gründen diesen Vertrag zu widerrufen.

+ +

Die Widerrufsfrist beträgt vierzehn Tage ab dem Tag des Vertragsabschlusses.

+ +

Um Ihr Widerrufsrecht auszuüben, müssen Sie uns (WEBklar GbR, Am Schwimmbad 10, 67722 Winnweiler, Telefon: 0176 23726355, E-Mail: support@webklar.com) mittels einer eindeutigen Erklärung (z. B. ein mit der Post versandter Brief oder eine E-Mail) über Ihren Entschluss, diesen Vertrag zu widerrufen, informieren. Sie können dafür das beigefügte Muster-Widerrufsformular verwenden, das jedoch nicht vorgeschrieben ist.

+ +

Sie können Ihr Widerrufsrecht auch online unter https://project.webklar.com/widerrufen.html ausüben. Wenn Sie diese Online-Funktion nutzen, übermitteln wir Ihnen auf einem dauerhaften Datenträger (z. B. durch eine E-Mail) unverzüglich eine Eingangsbestätigung mit Informationen zum Inhalt der Widerrufserklärung sowie dem Datum und der Uhrzeit ihres Eingangs.

+ +

Zur Wahrung der Widerrufsfrist reicht es aus, dass Sie die Mitteilung über die Ausübung des Widerrufsrechts vor Ablauf der Widerrufsfrist absenden.

+ +

Folgen des Widerrufs

+ +

Wenn Sie diesen Vertrag widerrufen, haben wir Ihnen alle Zahlungen, die wir von Ihnen erhalten haben, einschließlich der Lieferkosten (mit Ausnahme der zusätzlichen Kosten, die sich daraus ergeben, dass Sie eine andere Art der Lieferung als die von uns angebotene, günstigste Standardlieferung gewählt haben), unverzüglich und spätestens binnen vierzehn Tagen ab dem Tag zurückzuzahlen, an dem die Mitteilung über Ihren Widerruf dieses Vertrags bei uns eingegangen ist. Für diese Rückzahlung verwenden wir dasselbe Zahlungsmittel, das Sie bei der ursprünglichen Transaktion eingesetzt haben, es sei denn, mit Ihnen wurde ausdrücklich etwas anderes vereinbart; in keinem Fall werden Ihnen wegen dieser Rückzahlung Entgelte berechnet.

+ +

Haben Sie verlangt, dass die Dienstleistungen während der Widerrufsfrist beginnen soll, so haben Sie uns einen angemessenen Betrag zu zahlen, der dem Anteil der bis zu dem Zeitpunkt, zu dem Sie uns von der Ausübung des Widerrufsrechts hinsichtlich dieses Vertrags unterrichten, bereits erbrachten Dienstleistungen im Vergleich zum Gesamtumfang der im Vertrag vorgesehenen Dienstleistungen entspricht.

+ +

Muster-Widerrufsformular

+ +

(Wenn Sie den Vertrag widerrufen wollen, dann füllen Sie bitte dieses Formular aus und senden Sie es zurück.)

+ +

– An WEBklar GbR, Am Schwimmbad 10, 67722 Winnweiler, E-Mail: support@webklar.com:

+ +

– Hiermit widerrufe(n) ich/wir (*) den von mir/uns (*) abgeschlossenen Vertrag über den Kauf der folgenden Waren (*)/die Erbringung der folgenden Dienstleistung (*)

+ +

– Bestellt am (*)/erhalten am (*)

+ +

– Name des/der Verbraucher(s)

+ +

– Anschrift des/der Verbraucher(s)

+ +

– Unterschrift des/der Verbraucher(s) (nur bei Mitteilung auf Papier)

+ +

– Datum

+ +

(*) Unzutreffendes streichen.

+ +

Hinweise zum Widerruf

+ +

Diese Hinweise gehören nicht zur gesetzlichen Widerrufsbelehrung. Sie erklären, wie sich das Widerrufsrecht auf die Bestellung einer Funktion auswirkt.

+ +
    +
  • Das Widerrufsrecht gilt für jede Bestellung einer Funktion gesondert, also für jedes Website-Projekt, für das der Kunde eine Funktion bestellt. Die Frist von vierzehn Tagen beginnt jeweils mit dem Vertragsschluss.
  • +
  • Widerruft der Kunde die Einrichtung einer Funktion, endet diese Funktion. Das Wartungs-Abo bleibt davon unberührt.
  • +
  • Hat WEBklar auf ausdrücklichen Wunsch des Kunden vor Ablauf der Widerrufsfrist mit der Einrichtung begonnen, schuldet der Kunde bei einem Widerruf einen angemessenen Betrag für die bis dahin erbrachte Leistung. Der Betrag bemisst sich als Anteil am Gesamtpreis; Maß ist der im Arbeitsblatt erfasste Aufwand für die Einrichtung.
  • +
  • Die Rückzahlung erfolgt über das ursprüngliche Zahlungsmittel; die Zahlung lief über Stripe.
  • +
+
+ + diff --git a/public/rechtliches/widerrufsbelehrung-funktionen-2026-10-07.pdf b/public/rechtliches/widerrufsbelehrung-funktionen-2026-10-07.pdf new file mode 100644 index 0000000000000000000000000000000000000000..23e9831894a30677eaadbbef8de117a6d1961171 GIT binary patch literal 53611 zcmce;1yr2L@;;0^!QF=75}d&yNbun9?(QBWKyV8#fj}U*1()FNPC{@EF2Mu;0dnuM zd-v@Aa?W?YLnbrR^}f|lRXttZUDGoZaw4M7m>Jj*D8{$9mJpZ$OaNO03j|(XMkRA6 zD`Nn!=nGL%CMI?cCMF;k=)nehuro1nu>5*}UIT%k*Q}stP}`jhDE#Z0^U*agKy4r$ zpi7uI?yk9e57Kq_o=xPT?M?^BBmFF(_Wx7Ap#Fg%jCYuTzjWPWV18)3>w^V^h3yXK zfBF{s)z_U(pnLD}{F1SN+E_q;%pg2>_ugS(1IgI#^n>pELpMJHqp*XqzLTv3fcmAa zhq;xNJ|jB=6F`evjhUGTAZ>2r>;`b-1nL6Wv}gc=c6L_As>TLV=1z?4tQ-uiK+uI! z;z}>2=>b;emc{@vV?#?@(1qg0`bJj9j*h}+4z||DjLhuJ3`}=_07ZQheFyVjH`5?6 z$~o8?IU5>-dRMeG*JlKU5?~Fw8YH=gWo~ODqVHr3pcdf<*#o?D2Q$bBR#rMDCMwWB z&~-0ujsE!(etraF8>2f)u>L^}Lwx`<0;AAN0HchpgSEcZ9~W`{agnIGl@kaWqo@@K zgNU)At&uSTqqMP&sgoIi9mvei&kt~P0(s9G!7Xi9`>PFkcZ~Oj>cla`Q12BqDpWKp z;V!=!_$=fOteG`9jFDm0(JjFX6=yM*ANnthOmKq9zKn=}S8!e9lS$)5%P*pny-hvI z$rGSCDxD=zmZovPyqIpdZE)Afw- zJS~}_S}%`i1UInH_ItJCQ_z}2#g}hVQm4>D<~0n5QKqsGNWUA*Rg>h_VlMl@wwsRx z^mo03{Z>jO-3n#f!`PVzD;TKfaFSCc_(g+P_J9B-vu^nYI)K{;r5@aLD#2OA>tyst zBLV$p^pyF_+3%}oi85u|a4G19k>RfG>_4s}x*0ticrmf!dfi#-XPg_v4&VD~`v>^? zSR|MKOu#92>gyU!AQ=AXpu~l#>P%1)FPBiwO_Yw42cT-*&k+ibO3dD~Ywm{|LZTPQu6C1io1m?ZZ_g~$tFn+#0 zEq(V&;Ae%p&xLt-n~@ef@Nz4lj|nQ0Qw_f6F*Z?;0c zyZ91G3=H=z33qPdnl%giae5@z+t;z`FrW19W2ozk4dk)YzIt5K z<(09#8rlt1A?C#Xp8T9$FBff%;3BUybKi*J)OeZ?YEAam0TujOJpKVk`68OYYEruW zIQF&1okYj^Lbak^C;RM@ck}uV(hSx+d)0OQ?g?)zX~e#?!j2Rev%(l#_sFFFwAYm> zrVD@z{>kbFcy&?XS$YDA%#%hvC&(s`64gGxH051d88I)evb@HF4QNV7xkj#q-vV$; zejjzlI)TyGy@1&gW4J`XGZChqMKv>PQTve&X2Wk(8WnOFp7>gJdyhVgymHAZ!<1Ie zC2%i5q=;jl%We!ASEtc!3r+Q~!c2Uze~AZsx`BE{yGOsB&YCJc4QwE>JrLToOr!CO zEmK=Od+0hOBg_R)bnnujUX>)w7n!C@!e&g8&Cme8*D44^%U5F0KS>byKVfKWPb?FS z#F-eaL4-Wu*!eQIsO><2vMcHMgIkS)#}YzqR@pP=u&ZC*3V8|L9}doy=mwLwd#w;W z^6C79S=qrs8!Ww{V4mEo1Pv8lN;}z*VmSWGtixQQ98<*rcuiq&nZK~ynm2T_PX zNy>&6^+{BKQX%&S@(zNW{@7`l*>uQz`=v)=C|mQw%B~2Vvt77i zQ4Wfzqp)7+dC?li%i3ly3#Q2$>q6%r>b≀}uVz$}~<8cT{==x)HfWAPer~Q%&J| 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�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Ëi$ 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�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 KT3AK|`F{b>kz-~6 literal 0 HcmV?d00001 diff --git a/public/rechtliches/widerrufsbelehrung-funktionen-2026-10-07.pdf.sha256 b/public/rechtliches/widerrufsbelehrung-funktionen-2026-10-07.pdf.sha256 new file mode 100644 index 0000000..b7d2f90 --- /dev/null +++ b/public/rechtliches/widerrufsbelehrung-funktionen-2026-10-07.pdf.sha256 @@ -0,0 +1 @@ +32e53411e95d65d8707b9ef80090c69db0a435a4a3e38f09a7b9d20eb02529d4 diff --git a/scripts/build-legal-html.mjs b/scripts/build-legal-html.mjs index 7c5c4ed..2d63de5 100755 --- a/scripts/build-legal-html.mjs +++ b/scripts/build-legal-html.mjs @@ -7,8 +7,12 @@ // node scripts/build-legal-html.mjs termine --check vergleicht mit den eingecheckten Seiten (Exit 1 bei Abweichung, schreibt nichts) // node scripts/build-legal-html.mjs shop [--check] dasselbe für Leistungsbeschreibung und AVV des Webshops (die Widerrufsbelehrung der // Funktionen gehört zum Satz termine und wird von shop nicht angefasst) +// node scripts/build-legal-html.mjs unterkunft [--check] +// Leistungsbeschreibung, AVV und Widerrufsbelehrung des Buchungskalenders in der Fassung +// config.unterkunft.fassung; die Widerrufsbelehrung ist derselbe Text wie beim Satz termine +// (docs/rechtliches/widerrufsbelehrung-funktionen.md), nur mit der Fassung des Buchungskalenders gestempelt // -// Fassung = config.termine.avvVersion (Satz termine) bzw. config.shop.fassung (Satz shop). Die Ausgabe enthält keine Datumsangabe außer der Fassung und hängt nur vom Markdown und +// Fassung = config.termine.avvVersion (Satz termine) bzw. config.shop.fassung (Satz shop) bzw. config.unterkunft.fassung (Satz unterkunft). Die Ausgabe enthält keine Datumsangabe außer der Fassung und hängt nur vom Markdown und // von der Fassung ab (zweimal erzeugen ergibt dieselben Bytes). Unterstützte Teilmenge von Markdown: Überschriften # bis ### // (# nur als erste Zeile), Absätze, Listen mit "- ", **fett**, `code` und Tabellen (Kopfzeile, Trennzeile |---|---|, Zeilen). // Jede andere Syntax (Codeblöcke, Zitate, Bilder, Links, rohes HTML, nummerierte Listen, Einrückungen, Trennlinien) bricht laut ab, @@ -269,9 +273,15 @@ const SHOP_NAMEN = { lb: { titel: 'Leistungsbeschreibung Webshop', seitenkopf: 'Leistungsbeschreibung Webshop' }, avv: { titel: 'Auftragsverarbeitungsvertrag Webshop', seitenkopf: 'AVV Webshop' }, } +const UNTERKUNFT_NAMEN = { + lb: { titel: 'Leistungsbeschreibung Buchungskalender', seitenkopf: 'Leistungsbeschreibung Buchungskalender' }, + avv: { titel: 'Auftragsverarbeitungsvertrag Buchungskalender', seitenkopf: 'AVV Buchungskalender' }, + widerruf: { titel: 'Widerrufsbelehrung und Muster-Widerrufsformular (Funktionen)', seitenkopf: 'Widerrufsbelehrung Funktionen' }, +} const NAV_NAMEN = { termine: { lb: 'Leistungsbeschreibung Terminplaner', avv: 'AVV Terminplaner', widerruf: 'Widerrufsbelehrung Funktionen' }, shop: { lb: 'Leistungsbeschreibung Webshop', avv: 'AVV Webshop', widerruf: 'Widerrufsbelehrung Funktionen' }, + unterkunft: { lb: 'Leistungsbeschreibung Buchungskalender', avv: 'AVV Buchungskalender', widerruf: 'Widerrufsbelehrung Funktionen' }, } /** @@ -309,25 +319,45 @@ export function shopDokumente(fassung = config.shop.fassung) { return dokumenteDesSatzes('shop', fassung, SHOP_NAMEN) } +/** + * Die drei Dokumente des Buchungskalenders in der Fassung config.unterkunft.fassung. Die Widerrufsbelehrung hat dieselbe Quelle wie die des + * Terminplaners (ein Text für alle Funktionen); sie liegt hier unter der Fassung des Buchungskalenders, weil die Bestellung auf diese + * Adresse verweist (legalPaths('unterkunft', …).widerruf). stempel = Fassung, die in der Quelle steht und beim Rendern ersetzt wird. + */ +export function unterkunftDokumente(fassung = config.unterkunft.fassung) { + return dokumenteDesSatzes('unterkunft', fassung, UNTERKUNFT_NAMEN).map((d) => + d.doc === 'widerruf' ? { ...d, stempel: config.termine.avvVersion } : d, + ) +} + /** Sätze der Kommandozeile: Name => Dokumente. */ -const SAETZE = { termine: termineDokumente, shop: shopDokumente } +const SAETZE = { termine: termineDokumente, shop: shopDokumente, unterkunft: unterkunftDokumente } + +/** Markdown eines Dokuments; trägt die Quelle eine andere Fassung (d.stempel), wird die Fassungszeile auf die des Dokuments gesetzt. */ +export function quelleVon(d, root = ROOT) { + const md = readFileSync(join(root, d.md), 'utf8') + if (!d.stempel || d.stempel === d.meta.fassung) return md + const alt = `**Fassung ${d.stempel}**` + if (!md.includes(alt)) throw new MarkdownFehler(3, `${d.md}: die Zeile ${alt} fehlt`) + return md.replace(alt, `**Fassung ${d.meta.fassung}**`) +} // ---------------------------------------------------------------------------------------------------------- Aufruf /** - * Kommandozeile: `termine|shop [--check]`. root = Wurzel des Projekts (Tests übergeben ein Verzeichnis mit Kopien). + * Kommandozeile: `termine|shop|unterkunft [--check]`. root = Wurzel des Projekts (Tests übergeben ein Verzeichnis mit Kopien). * => Exit-Code: 0 ok, 1 mindestens eine Seite weicht ab (nur --check), 2 falscher Aufruf */ export function lauf(argv, { root = ROOT, log = console.log, fehler = console.error } = {}) { const [satz, ...optionen] = argv const pruefen = optionen.includes('--check') if (!Object.hasOwn(SAETZE, satz ?? '') || optionen.some((o) => o !== '--check')) { - fehler('Aufruf: node scripts/build-legal-html.mjs termine|shop [--check]') + fehler('Aufruf: node scripts/build-legal-html.mjs termine|shop|unterkunft [--check]') return 2 } let abweichungen = 0 for (const d of SAETZE[satz]()) { - const html = render(readFileSync(join(root, d.md), 'utf8'), d.meta) + const html = render(quelleVon(d, root), d.meta) const ziel = join(root, d.html) if (pruefen) { const gleich = existsSync(ziel) && readFileSync(ziel, 'utf8') === html diff --git a/scripts/build-legal-pdfs.sh b/scripts/build-legal-pdfs.sh index 640bb6a..247ba4b 100755 --- a/scripts/build-legal-pdfs.sh +++ b/scripts/build-legal-pdfs.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Erzeugt die Druck-/PDF-Fassungen der Vertragsunterlagen aus den HTML-Quellen. # Laeuft auf dem Host (braucht Chrome/Chromium), die PDFs werden eingecheckt. -# Usage: CHROME=/pfad/zu/chrome scripts/build-legal-pdfs.sh [all|analyse|termine|shop|datenschutz] +# Usage: CHROME=/pfad/zu/chrome scripts/build-legal-pdfs.sh [all|analyse|termine|shop|unterkunft|datenschutz] # analyse = nur AVV und Leistungsbeschreibung der Website-Analyse (Fassung ANALYSE_VERSION), andere PDFs bleiben unveraendert # termine = Leistungsbeschreibung, AVV und Widerrufsbelehrung des Terminplaners (Fassung TERMINE_VERSION, Standard: config.termine.avvVersion); # die HTML-Seiten kommen vorher aus `node scripts/build-legal-html.mjs termine`. Neben jedem PDF liegt .sha256 mit der @@ -10,6 +10,8 @@ # shop = Leistungsbeschreibung und AVV des Webshops (Fassung SHOP_VERSION, Standard: config.shop.fassung); die HTML-Seiten kommen vorher # aus `node scripts/build-legal-html.mjs shop`, Pruefsumme und Neudruck wie bei termine. Die Widerrufsbelehrung der Funktionen # gehoert zu termine (dieselbe Datei) und wird hier nicht gedruckt. `all` druckt auch diese beiden PDFs. +# unterkunft = Leistungsbeschreibung, AVV und Widerrufsbelehrung des Buchungskalenders (Fassung UNTERKUNFT_VERSION, Standard: config.unterkunft.fassung); die HTML-Seiten +# kommen vorher aus `node scripts/build-legal-html.mjs unterkunft`, Pruefsumme und Neudruck wie bei termine. `all` druckt diese PDFs nicht mit. # datenschutz = nur die Datenschutzerklaerung (docs/WEBklar-Datenschutzerklaerung.pdf); daneben liegt .sha256 mit der SHA-256 von # public/datenschutz.html (test/legalTexts.test.js prueft sie); ein PDF mit passender Pruefsumme wird nicht neu gedruckt (FORCE=1 druckt neu) # Vorher `free -m` pruefen und mit `nice` aufrufen; jeder Chrome-Aufruf laeuft hoechstens 120 Sekunden (timeout), die PDFs nacheinander. @@ -47,6 +49,16 @@ shop_version() { echo "$v" } +# Fassung des Buchungskalenders: UNTERKUNFT_VERSION, sonst die Konstante des Servers +unterkunft_version() { + local v="${UNTERKUNFT_VERSION:-}" + if [ -z "$v" ]; then + v="$(timeout 60 node --max-old-space-size=256 --input-type=module -e "const { config } = await import('./server/config.js'); console.log(config.unterkunft.fassung)")" + fi + [[ "$v" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] || { echo "Ungueltige Fassung: $v" >&2; exit 1; } + echo "$v" +} + # Leistungsbeschreibung und AVV des Webshops drucken (je PDF nur, wenn die Pruefsumme der HTML-Seite nicht mehr passt) shop_pdfs() { local fassung slug quelle ziel summe @@ -88,6 +100,21 @@ termine) shop) shop_pdfs ;; +unterkunft) + fassung="$(unterkunft_version)" + for slug in leistungsbeschreibung-unterkunft avv-unterkunft widerrufsbelehrung-funktionen; do + [ -f "public/rechtliches/$slug-$fassung.html" ] || { echo "HTML fehlt: public/rechtliches/$slug-$fassung.html (zuerst node scripts/build-legal-html.mjs unterkunft)"; exit 1; } + quelle="public/rechtliches/$slug-$fassung.html" + ziel="public/rechtliches/$slug-$fassung.pdf" + summe="$(sha256sum "$quelle" | cut -d' ' -f1)" + if [ -z "${FORCE:-}" ] && [ -f "$ziel" ] && [ "$(cat "$ziel.sha256" 2>/dev/null)" = "$summe" ]; then + echo "= $ziel (unveraendert)" + else + pdf "$quelle" "$ziel" + echo "$summe" > "$ziel.sha256" + fi + done + ;; datenschutz) quelle="public/datenschutz.html" ziel="docs/WEBklar-Datenschutzerklaerung.pdf" @@ -107,6 +134,6 @@ all) shop_pdfs ;; *) - echo "Usage: $0 [all|analyse|termine|shop|datenschutz]"; exit 1 + echo "Usage: $0 [all|analyse|termine|shop|unterkunft|datenschutz]"; exit 1 ;; esac diff --git a/test/buildLegalHtml.test.js b/test/buildLegalHtml.test.js index cbe1f96..4bfcce1 100644 --- a/test/buildLegalHtml.test.js +++ b/test/buildLegalHtml.test.js @@ -16,7 +16,7 @@ useTestEnv({ appwriteUrl: 'http://127.0.0.1:1', stripeUrl: 'http://127.0.0.1:1' const { config } = await import('../server/config.js') const { startTestApp } = await import('./support/testApp.js') const { legalPaths, legalPdfFiles, legalPdfAttachments, legalRouter } = await import('../server/services/legalDocs.js') -const { render, parse, lauf, termineDokumente, shopDokumente, MarkdownFehler } = await import('../scripts/build-legal-html.mjs') +const { render, parse, lauf, termineDokumente, shopDokumente, unterkunftDokumente, MarkdownFehler } = await import('../scripts/build-legal-html.mjs') const V = config.termine.avvVersion const ROOT = fileURLToPath(new URL('..', import.meta.url)) @@ -24,6 +24,8 @@ const lies = (rel) => readFileSync(join(ROOT, rel), 'utf8') const DOKUMENTE = termineDokumente(V) const S = config.shop.fassung const SHOP = shopDokumente(S) +const U = config.unterkunft.fassung +const UK = unterkunftDokumente(U) const META = { fassung: '2026-10-05', titel: 'Prüfdokument', seitenkopf: 'Prüfdokument', nav: [{ href: '/dashboard.html', text: 'Portal' }] } const KOPF = '# Titel\n\n**Fassung 2026-10-05**\n\n' @@ -359,7 +361,7 @@ test('script_modus: build-legal-pdfs.sh kennt termine und datenschutz, lässt di // bash versteht das Skript, und ein unbekannter Modus liefert die Usage mit allen Modi const syntax = spawnSync('bash', ['-n', 'scripts/build-legal-pdfs.sh'], { cwd: ROOT, encoding: 'utf8' }) assert.equal(syntax.status, 0, syntax.stderr) - assert.ok(sh.includes('Usage: $0 [all|analyse|termine|shop|datenschutz]')) + assert.ok(sh.includes('Usage: $0 [all|analyse|termine|shop|unterkunft|datenschutz]')) }) // ---------------------------------------------------------------------------------------------------- Webshop (Task J1) @@ -438,7 +440,7 @@ test('shop_lauf: --check meldet fehlende oder abweichende Seiten mit Exit 1, sch assert.equal(ruf('analyse'), 2) assert.equal(ruf('shop', '--schreiben'), 2) assert.equal(ruf(), 2) - assert.match(zeilen[0], /Aufruf: node scripts\/build-legal-html\.mjs termine\|shop \[--check\]/) + assert.match(zeilen[0], /Aufruf: node scripts\/build-legal-html\.mjs termine\|shop\|unterkunft \[--check\]/) } finally { rmSync(dir, { recursive: true, force: true }) } @@ -480,7 +482,95 @@ test('shop_script_modus: build-legal-pdfs.sh kennt den Modus shop (Slugs der Reg assert.ok(shop.includes('sha256sum "$quelle"') && shop.includes('echo "$summe" > "$ziel.sha256"') && shop.includes('(unveraendert)')) assert.match(sh, /^shop\)\n {2}shop_pdfs\n {2};;$/m) assert.ok(sh.slice(sh.indexOf('\nall)'), sh.indexOf('\n*)')).includes(' shop_pdfs\n'), 'all druckt auch die Webshop-PDFs') - assert.ok(sh.includes('Usage: $0 [all|analyse|termine|shop|datenschutz]')) + assert.ok(sh.includes('Usage: $0 [all|analyse|termine|shop|unterkunft|datenschutz]')) const syntax = spawnSync('bash', ['-n', 'scripts/build-legal-pdfs.sh'], { cwd: ROOT, encoding: 'utf8' }) assert.equal(syntax.status, 0, syntax.stderr) }) + +// ---------------------------------------------------------------------------------------------------- Buchungskalender (Task 21) + +test('unterkunftDokumente: lb, avv und widerruf mit Quelle, Ziel und Navigation auf die Fassung des Buchungskalenders', () => { + assert.deepEqual(UK.map((d) => d.doc), ['lb', 'avv', 'widerruf']) + assert.deepEqual( + UK.map((d) => [d.md, d.html]), + [ + ['docs/rechtliches/leistungsbeschreibung-unterkunft.md', `public/rechtliches/leistungsbeschreibung-unterkunft-${U}.html`], + ['docs/rechtliches/avv-unterkunft.md', `public/rechtliches/avv-unterkunft-${U}.html`], + ['docs/rechtliches/widerrufsbelehrung-funktionen.md', `public/rechtliches/widerrufsbelehrung-funktionen-${U}.html`], + ], + ) + assert.deepEqual(Object.values(legalPaths('unterkunft', U)), UK.map((d) => d.html.replace(/^public/, ''))) + assert.deepEqual(unterkunftDokumente(), UK) + // nur die Widerrufsbelehrung trägt eine fremde Fassung in der Quelle (die des Terminplaners) + assert.deepEqual(UK.map((d) => d.stempel), [undefined, undefined, config.termine.avvVersion]) +}) + +test('unterkunft_html_gleich_generator: eingecheckte Seiten sind genau render(Markdown), Entwurfskennzeichen in LB und AVV, --check Exit 0', () => { + for (const d of UK) { + const md = d.stempel ? lies(d.md).replace(`**Fassung ${d.stempel}**`, `**Fassung ${U}**`) : lies(d.md) + const html = render(md, d.meta) + assert.equal(lies(d.html), html, `${d.html} weicht vom Generator ab (node scripts/build-legal-html.mjs unterkunft)`) + assert.equal(render(md, d.meta), html, 'deterministisch') + assert.ok(html.includes(`Fassung ${U}`)) + assert.ok(html.includes(``)) + assert.doesNotMatch(html.replaceAll(U, ''), /\b\d{4}-\d{2}-\d{2}\b/, `${d.html}: Datum außer der Fassung`) + assert.doesNotMatch(html, /