Terminplaner: Widerrufsfunktion im Satzrahmen des Musters, Belehrung nur mit Anschrift und Telefon
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
459efff10a
commit
0c033ab1d2
3 files changed
+56
-42
No files matched your search
@@ -11,8 +11,8 @@ Der Text unten ist die Fassung, die `widerrufsbelehrung(betrieb)` in `server/ser
|
||||
| Gestaltungshinweis in Anlage 1 | Umsetzung |
|
||||
|---|---|
|
||||
| Frist: Textbaustein a) für Dienstleistungsverträge | „des Vertragsabschlusses.“ (Fristbeginn ist der Vertragsschluss: bei einer sofort verbindlichen Buchung die Bestätigung per Link, bei einer Anfrage die Annahme durch den Betrieb) |
|
||||
| „Fügen Sie Ihren Namen, Ihre Anschrift, Ihre Telefonnummer und Ihre E-Mail-Adresse ein.“ | Name, Anschrift, Telefon, E-Mail aus den Betriebsangaben der Einstellung (`betrieb.name`, `adresse`, `telefon`, `email`); fehlen Anschrift oder Telefon, entfallen sie aus dem Text |
|
||||
| Widerrufsfunktion bei online geschlossenen Verträgen (§ 356a BGB) | „anderer geeigneter Hinweis“ statt Internetadresse: Schaltfläche „Vertrag widerrufen“ im Terminbereich der Website und Link „Termin verwalten“ in der Bestätigungs-E-Mail; danach der Gesetzeswortlaut zur Eingangsbestätigung unverändert |
|
||||
| „Fügen Sie Ihren Namen, Ihre Anschrift, Ihre Telefonnummer und Ihre E-Mail-Adresse ein.“ | Name, Anschrift, Telefon, E-Mail aus den Betriebsangaben der Einstellung (`betrieb.name`, `adresse`, `telefon`, `email`); alle vier sind Pflicht, fehlt oder ist eine Angabe leer, wirft `widerrufsbelehrung()` einen TypeError |
|
||||
| Widerrufsfunktion bei online geschlossenen Verträgen (§ 356a BGB) | Satzrahmen des Gesetzes wörtlich („Sie können Ihr Widerrufsrecht auch online unter … ausüben. Wenn Sie diese Online-Funktion nutzen, …“); in die Lücke „…“ kommt statt einer Internetadresse ein „anderer geeigneter Hinweis“: „Vertrag widerrufen“ (Schaltfläche im Terminbereich auf unserer Website sowie Link „Termin verwalten“ in Ihrer Bestätigungs-E-Mail); der Gesetzeswortlaut zur Eingangsbestätigung bleibt unverändert |
|
||||
| Absatz zum elektronisch ausfüllbaren Webformular | ausgelassen: Es gibt keine eigene Webformular-Funktion außer der Widerrufsfunktion |
|
||||
| Textbausteine zu Waren (Besitz, Rückzahlungsverweigerung, Abholung oder Rücksendung, Rücksendekosten, Wertverlust) | ausgelassen: Ein Termin hat keine Waren |
|
||||
| Dienstleistungen: Wertersatz („Haben Sie verlangt, dass die Dienstleistungen …“) | enthalten; „oder Lieferung von Wasser/Gas/Strom/Fernwärme [Unzutreffendes streichen]“ ist gestrichen, wie der Gestaltungshinweis es vorsieht |
|
||||
@@ -33,7 +33,7 @@ Die Widerrufsfrist beträgt vierzehn Tage ab dem Tag des Vertragsabschlusses.
|
||||
|
||||
Um Ihr Widerrufsrecht auszuüben, müssen Sie uns ({{Name des Betriebs}}, {{Anschrift}}, Telefon: {{Telefon}}, E-Mail: {{E-Mail}}) 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 über die Schaltfläche „Vertrag widerrufen“ ausüben, die Sie im Terminbereich auf unserer Website und über den Link „Termin verwalten“ in Ihrer Bestätigungs-E-Mail finden. 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.
|
||||
Sie können Ihr Widerrufsrecht auch online unter „Vertrag widerrufen“ (Schaltfläche im Terminbereich auf unserer Website sowie Link „Termin verwalten“ in Ihrer Bestätigungs-E-Mail) 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.
|
||||
|
||||
@@ -67,7 +67,7 @@ Muster-Widerrufsformular
|
||||
|
||||
1. **Lieferkosten-Klammer** im Absatz „Folgen des Widerrufs“ („einschließlich der Lieferkosten (mit Ausnahme …)“) steht unverändert im Text. Anlage 1 enthält keinen Gestaltungshinweis, der sie bei reinen Dienstleistungen zu streichen erlaubt; sie ist deshalb nicht gekürzt. Prüfen, ob sie für Dienstleistungen entfallen darf.
|
||||
2. **„… beginnen soll“**: Nach dem Streichen von „oder Lieferung von Wasser/Gas/Strom/Fernwärme“ steht „die Dienstleistungen … beginnen soll“ (Singular im Gesetzestext). Der Wortlaut ist bewusst nicht geglättet, damit das Muster unverändert bleibt. Prüfen, ob „sollen“ zulässig ist.
|
||||
3. **Anschrift und Telefon**: Das Muster verlangt Anschrift und Telefonnummer. Die Einstellung verlangt nur Name und E-Mail. Das Portal sollte die Anschrift (und besser auch die Telefonnummer) verlangen, bevor eine verbindliche Verbraucher-Buchung möglich ist; sonst fehlt sie in der Belehrung.
|
||||
3. **Anschrift und Telefon**: Das Muster verlangt Anschrift und Telefonnummer. `widerrufsbelehrung()` wirft deshalb einen TypeError, wenn eine der vier Angaben fehlt. Die Einstellungsprüfung (späterer Task) soll Anschrift und Telefon verlangen, sobald Gäste ein Widerrufsrecht haben können (öffentlich `widerruf: true`).
|
||||
4. **Wertersatz-Absatz** gilt nur, wenn der Gast den vorzeitigen Beginn verlangt hat (Zustimmung `ZUSTIMMUNG_VORZEITIG`, nur bei Terminbeginn innerhalb von 14 Tagen). Der Absatz steht trotzdem immer in der Belehrung, wie das Muster es für Dienstleistungen vorsieht.
|
||||
5. **„Terminbereich auf unserer Website“** ist als geeigneter Hinweis gewählt (Entscheidung R12). Prüfen, ob ein Hinweis ohne Internetadresse genügt oder die Adresse der Seite genannt werden muss.
|
||||
5. **Hinweis statt Internetadresse**: „Vertrag widerrufen“ (Schaltfläche im Terminbereich auf unserer Website sowie Link „Termin verwalten“ in Ihrer Bestätigungs-E-Mail) ist als geeigneter Hinweis gewählt (Entscheidung R12). Prüfen, ob ein Hinweis ohne Internetadresse genügt oder die Adresse der Seite genannt werden muss.
|
||||
6. **Gültigkeit der Gesetzlichkeitsfiktion**: Sie gilt nur, wenn das Muster inhaltlich und gestalterisch dem Gesetz entspricht. Jede Abweichung (auch Zeilenumbrüche, Überschriften, die „–“-Aufzählung im Formular) ist hier Darstellung, nicht Inhalt. Vor dem Einsatz bei fremden Betrieben durch eine Kanzlei prüfen lassen.
|
||||
@@ -7,8 +7,8 @@
|
||||
*
|
||||
* widerrufsbelehrung: Muster der Anlage 1 und Muster-Widerrufsformular der Anlage 2 zu Art. 246a § 1 Abs. 2 Satz 2 EGBGB
|
||||
* (docs/rechtliches/quellen/, abgerufen 2026-10-02), Gestaltungshinweise fuer einen Dienstleistungsvertrag angewendet:
|
||||
* Fristbeginn „des Vertragsabschlusses.“, Betriebsdaten, Hinweis auf die Widerrufsfunktion als „anderer geeigneter
|
||||
* Hinweis“ (ohne Internetadresse), Wertersatz fuer Dienstleistungen. Alles Uebrige ist der Gesetzestext, unveraendert.
|
||||
* Fristbeginn „des Vertragsabschlusses.“, Betriebsdaten (Name, Anschrift, Telefon, E-Mail, alle Pflicht), Hinweis auf die
|
||||
* Widerrufsfunktion als „anderer geeigneter Hinweis“ (ohne Internetadresse) im woertlichen Satzrahmen, Wertersatz fuer Dienstleistungen. Alles Uebrige ist der Gesetzestext, unveraendert.
|
||||
* Ausgelassen: Textbausteine zu Waren (Besitz, Rueckzahlungsverweigerung, Rueckgabe, Rueckkosten, Wertverlust) und der
|
||||
* Absatz zum elektronischen Webformular (es gibt nur die Widerrufsfunktion). test/termineRechtstexte.test.js prueft
|
||||
* den Wortlaut gegen die Quelldateien.
|
||||
@@ -24,12 +24,21 @@ const ABSATZ = '\n\n'
|
||||
/** Einzeiliger Text: jeder Leerraum (auch Umbrueche) wird zu einem Leerzeichen, Rand getrimmt; Nicht-Text = ''. */
|
||||
const einzeilig = (wert) => (typeof wert === 'string' ? wert.replace(/\s+/g, ' ').trim() : '')
|
||||
|
||||
/** Betriebsdaten fuer die Texte. Name und E-Mail sind Pflicht (die Einstellung prueft sie), Anschrift und Telefon entfallen, wenn leer. */
|
||||
function betriebsdaten(betrieb) {
|
||||
/**
|
||||
* Betriebsdaten fuer die Texte. Name und E-Mail sind immer Pflicht (die Einstellung prueft sie). Mit vollstaendig: true
|
||||
* auch Anschrift und Telefonnummer (das Muster der Anlage 1 verlangt alle vier): fehlt eine Angabe oder ist sie leer,
|
||||
* entsteht ein TypeError, nie ein unvollstaendiger Text.
|
||||
*/
|
||||
function betriebsdaten(betrieb, { vollstaendig = false } = {}) {
|
||||
const name = einzeilig(betrieb?.name)
|
||||
const email = einzeilig(betrieb?.email)
|
||||
if (!name || !email) throw new TypeError('Betriebsname und E-Mail-Adresse sind für die Rechtstexte erforderlich.')
|
||||
return { name, email, adresse: einzeilig(betrieb.adresse), telefon: einzeilig(betrieb.telefon) }
|
||||
const adresse = einzeilig(betrieb.adresse)
|
||||
const telefon = einzeilig(betrieb.telefon)
|
||||
if (vollstaendig && (!adresse || !telefon)) {
|
||||
throw new TypeError('Anschrift und Telefonnummer des Betriebs sind für die Widerrufsbelehrung erforderlich.')
|
||||
}
|
||||
return { name, email, adresse, telefon }
|
||||
}
|
||||
|
||||
const verbinde = (teile) => teile.filter(Boolean).join(', ')
|
||||
@@ -38,10 +47,11 @@ const verbinde = (teile) => teile.filter(Boolean).join(', ')
|
||||
|
||||
const FRIST = 'des Vertragsabschlusses.' // Gestaltungshinweis a): Dienstleistungsvertrag
|
||||
|
||||
// Widerrufsfunktion: „anderer geeigneter Hinweis“ statt Internetadresse, danach der Gesetzeswortlaut.
|
||||
// Widerrufsfunktion: Satzrahmen des Gesetzes wörtlich („Sie können Ihr Widerrufsrecht auch online unter … ausüben.“); in die
|
||||
// Lücke „… [Internetadresse oder anderen geeigneten Hinweis …]“ kommt ein geeigneter Hinweis statt einer Internetadresse.
|
||||
const WIDERRUFSFUNKTION =
|
||||
'Sie können Ihr Widerrufsrecht auch online über die Schaltfläche „Vertrag widerrufen“ ausüben, '
|
||||
+ 'die Sie im Terminbereich auf unserer Website und über den Link „Termin verwalten“ in Ihrer Bestätigungs-E-Mail finden. '
|
||||
'Sie können Ihr Widerrufsrecht auch online unter „Vertrag widerrufen“ (Schaltfläche im Terminbereich auf unserer Website '
|
||||
+ 'sowie Link „Termin verwalten“ in Ihrer Bestätigungs-E-Mail) 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.'
|
||||
|
||||
@@ -53,7 +63,7 @@ const WERTERSATZ =
|
||||
|
||||
/** Kontaktangaben fuer „Um Ihr Widerrufsrecht auszuüben, müssen Sie uns (…)“: Name, Anschrift, Telefonnummer, E-Mail-Adresse. */
|
||||
function kontakt({ name, adresse, telefon, email }) {
|
||||
return verbinde([name, adresse, telefon && `Telefon: ${telefon}`, `E-Mail: ${email}`])
|
||||
return verbinde([name, adresse, `Telefon: ${telefon}`, `E-Mail: ${email}`])
|
||||
}
|
||||
|
||||
function belehrungsAbsaetze(daten) {
|
||||
@@ -98,11 +108,12 @@ function formularAbsaetze({ name, adresse, email }) {
|
||||
|
||||
/**
|
||||
* Widerrufsbelehrung und Muster-Widerrufsformular fuer einen Dienstleistungs-Termin, Sie-Form, als Text mit Zeilenumbruechen.
|
||||
* betrieb: { name, email, adresse?, telefon? } aus der Einstellung. Fehlen Name oder E-Mail: TypeError. Fehlende Anschrift
|
||||
* oder Telefonnummer entfallen aus dem Text (die Einstellung verlangt sie nicht; das Portal sollte die Anschrift verlangen).
|
||||
* betrieb: { name, email, adresse, telefon } aus der Einstellung, alle vier Pflicht. Fehlt eine Angabe oder ist sie leer: TypeError
|
||||
* (eine unvollstaendige gesetzliche Belehrung wird nie stillschweigend erzeugt). Die Einstellungspruefung soll Anschrift und
|
||||
* Telefon verlangen, sobald Gaeste ein Widerrufsrecht haben koennen (spaeterer Task); bis dahin faengt diese Funktion es ab.
|
||||
*/
|
||||
export function widerrufsbelehrung(betrieb) {
|
||||
const daten = betriebsdaten(betrieb)
|
||||
const daten = betriebsdaten(betrieb, { vollstaendig: true })
|
||||
return [...belehrungsAbsaetze(daten), ...formularAbsaetze(daten)].join(ABSATZ)
|
||||
}
|
||||
|
||||
|
||||
@@ -64,18 +64,19 @@ test('Belehrung: alle Muster-Absaetze der Anlage 1 stehen wörtlich darin, nur d
|
||||
}
|
||||
})
|
||||
|
||||
test('Belehrung: Widerrufsfunktion als „anderer geeigneter Hinweis“, Rest des Gesetzeswortlauts unverändert', () => {
|
||||
test('Belehrung: Satzrahmen der Widerrufsfunktion wörtlich aus der Anlage, nur die Lücke „…“ ist mit einem geeigneten Hinweis gefüllt', () => {
|
||||
const text = belehrung()
|
||||
const m = /Wenn Sie diese Online-Funktion nutzen, ([^“]+?)\s*“/.exec(ANLAGE_1)
|
||||
assert.ok(m, 'Gestaltungshinweis zur Widerrufsfunktion fehlt in anlage-1.txt')
|
||||
assert.ok(m[1].includes('Eingangsbestätigung') && m[1].includes('Uhrzeit ihres Eingangs'))
|
||||
const absatz = 'Sie können Ihr Widerrufsrecht auch online über die Schaltfläche „Vertrag widerrufen“ ausüben, '
|
||||
+ 'die Sie im Terminbereich auf unserer Website und über den Link „Termin verwalten“ in Ihrer Bestätigungs-E-Mail finden. '
|
||||
+ `Wenn Sie diese Online-Funktion nutzen, ${m[1]}`
|
||||
assert.ok(text.includes(absatz), 'Absatz zur Widerrufsfunktion fehlt oder weicht ab')
|
||||
assert.ok(text.includes('Vertrag widerrufen'))
|
||||
assert.ok(!text.includes('online unter'), 'keine Internetadresse, kein Parameter')
|
||||
assert.ok(!/https?:\/\//.test(text))
|
||||
// Rahmen und Gesetzesteil kommen aus anlage-1.txt, nichts davon ist hier abgeschrieben:
|
||||
// „Sie können Ihr Widerrufsrecht auch online unter … [Internetadresse oder anderen geeigneten Hinweis …] ausüben. Wenn Sie diese Online-Funktion nutzen, …“
|
||||
const m = /„(Sie können Ihr Widerrufsrecht auch online unter) … \[[^\]]+\] (ausüben\.) (Wenn Sie diese Online-Funktion nutzen, [^“]+?)\s*“/.exec(ANLAGE_1)
|
||||
assert.ok(m, 'Gestaltungshinweis zur Widerrufsfunktion fehlt oder hat sich geändert in anlage-1.txt')
|
||||
assert.ok(m[3].includes('Eingangsbestätigung') && m[3].includes('Uhrzeit ihres Eingangs'))
|
||||
const hinweis = '„Vertrag widerrufen“ (Schaltfläche im Terminbereich auf unserer Website sowie Link „Termin verwalten“ in Ihrer Bestätigungs-E-Mail)'
|
||||
const absatz = `${m[1]} ${hinweis} ${m[2]} ${m[3]}`
|
||||
assert.ok(text.includes(absatz), 'Absatz zur Widerrufsfunktion fehlt oder weicht vom Satzrahmen der Anlage ab')
|
||||
assert.ok(text.includes('Vertrag widerrufen') && text.includes('Termin verwalten'))
|
||||
assert.ok(!/https?:\/\/|www\./.test(text), 'keine Internetadresse, kein Parameter')
|
||||
assert.ok(!text.includes('über die Schaltfläche'), 'kein umformulierter Satzrahmen')
|
||||
})
|
||||
|
||||
test('Belehrung: Wertersatz für Dienstleistungen, Unzutreffendes (Wasser/Gas/Strom/Fernwärme) gestrichen', () => {
|
||||
@@ -130,23 +131,25 @@ test('Belehrung: reiner Text mit Zeilenumbrüchen, nicht HTML-maskiert (die Mail
|
||||
assert.equal(belehrung(), belehrung(), 'deterministisch')
|
||||
})
|
||||
|
||||
test('Belehrung: fehlende Telefonnummer oder Anschrift hinterlässt keine leeren Klammern oder Kommas', () => {
|
||||
const ohneTel = belehrung({ ...BETRIEB, telefon: '' })
|
||||
assert.ok(ohneTel.includes('uns (Salon Müller & Söhne, Hauptstraße 1, 67722 Winnweiler, E-Mail: info@salon-mueller.de)'))
|
||||
assert.ok(!ohneTel.includes('Telefon:'))
|
||||
const ohneAdresse = belehrung({ ...BETRIEB, adresse: '', telefon: undefined })
|
||||
assert.ok(ohneAdresse.includes('uns (Salon Müller & Söhne, E-Mail: info@salon-mueller.de)'))
|
||||
assert.ok(ohneAdresse.includes('An Salon Müller & Söhne, info@salon-mueller.de:'))
|
||||
assert.ok(!/,\s*,|\(\s*,|,\s*\)|:\s*,/.test(ohneAdresse))
|
||||
})
|
||||
|
||||
test('Belehrung: Betriebsname und E-Mail sind Pflicht, Leerraum in Angaben wird zu einem Leerzeichen', () => {
|
||||
assert.throws(() => widerrufsbelehrung({ ...BETRIEB, name: '' }), TypeError)
|
||||
assert.throws(() => widerrufsbelehrung({ ...BETRIEB, email: undefined }), TypeError)
|
||||
test('Belehrung: Name, Anschrift, Telefon und E-Mail sind Pflicht, eine unvollständige Belehrung entsteht nie (TypeError)', () => {
|
||||
for (const feld of ['name', 'adresse', 'telefon', 'email']) {
|
||||
for (const leer of [undefined, null, '', ' ', ' \n\t ', 42, {}]) {
|
||||
assert.throws(() => widerrufsbelehrung({ ...BETRIEB, [feld]: leer }), TypeError, `${feld}=${JSON.stringify(leer)}`)
|
||||
}
|
||||
const ohne = { ...BETRIEB }
|
||||
delete ohne[feld]
|
||||
assert.throws(() => widerrufsbelehrung(ohne), TypeError, `${feld} fehlt`)
|
||||
}
|
||||
assert.throws(() => widerrufsbelehrung({ name: 'Salon Müller', email: 'info@salon.de' }), TypeError)
|
||||
assert.throws(() => widerrufsbelehrung(undefined), TypeError)
|
||||
assert.throws(() => widerrufsbelehrung(null), TypeError)
|
||||
assert.throws(() => widerrufsbelehrung('Salon'), TypeError)
|
||||
})
|
||||
|
||||
test('Belehrung: Leerraum in den Angaben wird zu einem Leerzeichen, vollständige Angaben stehen in Klammer und „An“-Zeile', () => {
|
||||
const text = belehrung({ ...BETRIEB, name: ' Salon \n Müller ', adresse: 'Hauptstraße 1,\n67722 Winnweiler' })
|
||||
assert.ok(text.includes('uns (Salon Müller, Hauptstraße 1, 67722 Winnweiler, Telefon:'))
|
||||
assert.ok(text.includes('uns (Salon Müller, Hauptstraße 1, 67722 Winnweiler, Telefon: 06301 1234, E-Mail: info@salon-mueller.de)'))
|
||||
assert.ok(text.includes('An Salon Müller, Hauptstraße 1, 67722 Winnweiler, info@salon-mueller.de:'))
|
||||
})
|
||||
|
||||
test('Belehrung ist die Quelle von docs/rechtliches/termine-widerrufsbelehrung-muster.md (Platzhalter-Fassung steht dort wörtlich)', () => {
|
||||
|
||||
Reference in new issue
Block a user