177 lines
11 KiB
JavaScript
177 lines
11 KiB
JavaScript
/**
|
||
* Wortlaute der Auftragsbestätigung (AB), der Bestätigung durch den Kunden und der Texte für Privatpersonen (Frühbeginn,
|
||
* Widerrufsbelehrung, Muster-Widerrufsformular). Reine Konstanten und Funktionen ohne Zugriff auf Appwrite, Stripe oder die
|
||
* Konfiguration. Endfassung der Rechtsrunde vom 06.10.2026 (Strang L7); die Zusammenstellung zur Freigabe liegt in
|
||
* /root/reports/auftraege-rechnungen-2026-10-06/rechtsrunde.md.
|
||
*
|
||
* Alle Kundentexte stehen in der Sie-Form und ohne Gedankenstriche im Fließtext. Widerrufsbelehrung und Muster-Widerrufsformular sind
|
||
* die Muster der Anlagen 1 und 2 zu Art. 246a § 1 Abs. 2 Satz 2 EGBGB für einen Dienstleistungsvertrag (Quellen:
|
||
* docs/rechtliches/quellen/anlage-1.txt und anlage-2.txt) und gleich der Belehrung für die Bestellung einer Funktion
|
||
* (widerrufsbelehrungFunktion in services/termine/rechtstexte.js); test/auftraegeRechtstexte.test.js prüft beides.
|
||
* Die Frühbeginn-Erklärung folgt den Erklärungen der Funktionen: § 356 Abs. 5 Nr. 2 BGB (Erlöschen), § 357a Abs. 2 BGB (Wertersatz).
|
||
*
|
||
* Ändert sich ein Wortlaut nach der Auslieferung, bekommt TEXTE_FASSUNG ein neues Datum. Die Fassung steht im Nachweis jeder
|
||
* Auftragsbestätigung (texteFassung); die Dateien früherer Fassungen unter public/rechtliches/ bleiben unverändert.
|
||
*/
|
||
import { AUFTRAG_WEGE, LIMITS } from './konstanten.js'
|
||
|
||
export const TEXTE_FASSUNG = '2026-10-06'
|
||
|
||
export const ABSENDER = { name: 'WEBklar GbR', strasse: 'Am Schwimmbad 10', plzOrt: '67722 Winnweiler',
|
||
telefon: '0176 23726355', email: 'support@webklar.com', web: 'webklar.com', vertretenDurch: 'Kenso Grimm und Justin Klein' }
|
||
|
||
// ---------------------------------------------------------------------------------------------------------- Hilfen
|
||
|
||
/** Pflichtwert: fehlt er, entsteht ein Fehler statt eines Textes mit „undefined“ (eine Auftragsbestätigung darf nie unvollständig entstehen). */
|
||
function pflicht(wert, name) {
|
||
if (wert === undefined || wert === null || String(wert).trim() === '') throw new TypeError(`Text der Auftragsbestätigung: ${name} fehlt.`)
|
||
return String(wert).trim()
|
||
}
|
||
|
||
/** Klartext der Absprache: der Schlüssel aus AUFTRAG_WEGE („telefon“) wird zu „telefonisch“, ein fertiger Klartext bleibt, ohne Angabe entfällt er. */
|
||
function wegText(weg) {
|
||
const w = typeof weg === 'string' ? weg.trim() : ''
|
||
if (w === '') return ''
|
||
return Object.hasOwn(AUFTRAG_WEGE, w) ? AUFTRAG_WEGE[w] : w
|
||
}
|
||
|
||
/** Zahlungsziel als Satzteil: 0 = sofort, sonst „innerhalb von n Tagen nach Rechnungsdatum“; fehlend oder ungültig = Vorgabe (14 Tage). */
|
||
function zielText(ziel) {
|
||
const n = typeof ziel === 'number' ? ziel : Number.parseInt(String(ziel), 10)
|
||
const tage = Number.isInteger(n) && n >= 0 ? n : LIMITS.standardZahlungszielTage
|
||
if (tage === 0) return 'sofort nach Rechnungsstellung'
|
||
return `innerhalb von ${tage} ${tage === 1 ? 'Tag' : 'Tagen'} nach Rechnungsdatum`
|
||
}
|
||
|
||
/** Zahl mit Dezimalkomma (33.5 wird „33,5“). */
|
||
const zahl = (wert) => String(wert).replace('.', ',')
|
||
|
||
const PRIVAT_BEGINN = 'Ohne Ihr ausdrückliches Verlangen beginnen wir erst nach Ablauf der Widerrufsfrist.'
|
||
|
||
// ---------------------------------------------------------------------------------------------------------- Auftragsbestätigung
|
||
|
||
export const AB_TEXTE = {
|
||
titel: 'Auftragsbestätigung',
|
||
|
||
einleitung: ({ datum, weg } = {}) => {
|
||
const art = wegText(weg)
|
||
return `Vielen Dank für Ihren Auftrag vom ${pflicht(datum, 'datum')}${art ? ` (${art})` : ''}. Wir bestätigen ihn wie folgt:`
|
||
},
|
||
|
||
aufwand: ({ satz, schaetzung } = {}) => {
|
||
const saetze = [
|
||
`Wir rechnen nach Aufwand ab: ${pflicht(satz, 'satz')} pro Stunde, erfasst je Arbeitsschritt in Schritten von 15 Minuten; angefangene 15 Minuten werden aufgerundet.`,
|
||
'Wirkt eine weitere Person unterstützend mit, berechnen wir für sie die Hälfte der Arbeitszeit (AGB Nr. 9).',
|
||
]
|
||
if (schaetzung !== undefined && schaetzung !== null && String(schaetzung).trim() !== '') {
|
||
const stunden = String(schaetzung).trim()
|
||
saetze.push(`Der geschätzte Umfang beträgt etwa ${stunden} ${stunden === '1' ? 'Stunde' : 'Stunden'}; die Schätzung ist unverbindlich.`)
|
||
saetze.push('Zeichnet sich eine deutliche Überschreitung ab, melden wir uns vorher.')
|
||
}
|
||
return saetze.join(' ')
|
||
},
|
||
|
||
kleinunternehmer: 'Gemäß § 19 UStG wird keine Umsatzsteuer berechnet.',
|
||
|
||
zahlungsplan: {
|
||
nach_abnahme: ({ ziel } = {}) => `Wir stellen die Vergütung nach Abnahme in Rechnung; zahlbar ${zielText(ziel)}.`,
|
||
anzahlung: ({ prozent, anzahlung, rest, ziel } = {}) =>
|
||
`Anzahlung ${zahl(pflicht(prozent, 'prozent'))} % (${pflicht(anzahlung, 'anzahlung')}) nach Auftragsbestätigung, `
|
||
+ `Rest (${pflicht(rest, 'rest')}) nach Abnahme; zahlbar jeweils ${zielText(ziel)}.`,
|
||
monatlich: ({ ziel } = {}) => `Wir stellen den angefallenen Aufwand monatlich in Rechnung; zahlbar ${zielText(ziel)}.`,
|
||
frei: ({ text, ziel } = {}) => {
|
||
const t = pflicht(text, 'text')
|
||
return `${t}${/[.!?]$/.test(t) ? '' : '.'} Zahlbar jeweils ${zielText(ziel)}.`
|
||
},
|
||
},
|
||
|
||
termine: ({ start, fertig, privat = false } = {}) => {
|
||
const teile = []
|
||
if (start && fertig) teile.push(`Beginn: ${start}; voraussichtliche Fertigstellung: ${fertig}.`)
|
||
else if (start) teile.push(`Beginn: ${start}.`)
|
||
else if (fertig) teile.push(`Voraussichtliche Fertigstellung: ${fertig}.`)
|
||
if (privat) teile.push(PRIVAT_BEGINN)
|
||
return teile.length > 0 ? teile.join(' ') : null
|
||
},
|
||
|
||
mitwirkung:
|
||
'Mitwirkung und Abnahme richten sich nach Nr. 7 und Nr. 8 unserer Allgemeinen Geschäftsbedingungen. '
|
||
+ 'Bitte stellen Sie uns die benötigten Inhalte, Daten und Freigaben rechtzeitig bereit.',
|
||
|
||
agb: ({ fassung } = {}) =>
|
||
`Es gelten unsere Allgemeinen Geschäftsbedingungen in der Fassung vom ${pflicht(fassung, 'fassung')}, die dieser Bestätigung beiliegen.`,
|
||
|
||
ersetzt: ({ nummer, datum } = {}) => `Diese Auftragsbestätigung ersetzt ${pflicht(nummer, 'nummer')} vom ${pflicht(datum, 'datum')}.`,
|
||
|
||
gruss: 'Mit freundlichen Grüßen',
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------------------------------------- Bestätigung und Frühbeginn
|
||
|
||
/** Häkchen auf der Bestätigungsseite und im Kundenportal (Wortlaut der Spezifikation; Alternative mit Bezug auf die AGB: Entscheidung E2 im Freigabe-Dokument). */
|
||
export const BESTAETIGUNG_TEXT = 'Ich bestätige den Auftrag zu diesen Bedingungen.'
|
||
|
||
/** Fassung der Frühbeginn-Erklärung; steht im Nachweis der Bestätigung (fruehbeginnFassung). */
|
||
export const FRUEHBEGINN_FASSUNG = '2026-10-06'
|
||
|
||
/** Zweites, freiwilliges Häkchen für Privatpersonen: Verlangen (§ 357a Abs. 2 Nr. 1 BGB), Zustimmung und Kenntnis (§ 356 Abs. 5 Nr. 2 BGB). */
|
||
export const FRUEHBEGINN_TEXT =
|
||
'Ich verlange ausdrücklich, dass WEBklar vor Ablauf der Widerrufsfrist mit der Ausführung dieses Projektauftrags beginnt. '
|
||
+ 'Mir ist bekannt, dass mein Widerrufsrecht mit der vollständigen Erbringung der Leistung erlischt (§ 356 Abs. 5 Nr. 2 BGB). '
|
||
+ 'Widerrufe ich vor der vollständigen Erbringung, schulde ich einen angemessenen Betrag für die bis dahin erbrachte Leistung (§ 357a Abs. 2 BGB).'
|
||
|
||
// ---------------------------------------------------------------------------------------------------------- Widerrufsbelehrung und Formular
|
||
|
||
const KONTAKT = `${ABSENDER.name}, ${ABSENDER.strasse}, ${ABSENDER.plzOrt}, Telefon: ${ABSENDER.telefon}, E-Mail: ${ABSENDER.email}`
|
||
|
||
/** Muster der Anlage 1 für einen Dienstleistungsvertrag; Lücken: Frist „des Vertragsabschlusses.“, Kontaktangaben, Widerrufsfunktion, Wertersatz. */
|
||
export const WIDERRUFSBELEHRUNG_PROJEKT = {
|
||
titel: 'Widerrufsbelehrung',
|
||
abschnitte: [
|
||
{
|
||
ueberschrift: 'Widerrufsrecht',
|
||
absaetze: [
|
||
'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 (${KONTAKT}) 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.',
|
||
],
|
||
},
|
||
{
|
||
ueberschrift: 'Folgen des Widerrufs',
|
||
absaetze: [
|
||
'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 der Anlage 2; „–“ ist das Aufzählungszeichen des Musters, die letzte Zeile gehört zum Muster. */
|
||
export const WIDERRUFSFORMULAR = {
|
||
titel: 'Muster-Widerrufsformular',
|
||
einleitung: '(Wenn Sie den Vertrag widerrufen wollen, dann füllen Sie bitte dieses Formular aus und senden Sie es zurück.)',
|
||
zeilen: [
|
||
`– An ${ABSENDER.name}, ${ABSENDER.strasse}, ${ABSENDER.plzOrt}, E-Mail: ${ABSENDER.email}:`,
|
||
'– 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.',
|
||
],
|
||
}
|