Files
Webklar-Kundenbereich/server/services/auftraege/texte.js
T

177 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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.',
],
}