From 60a51c0f68fac18340d63552980640a39020356a Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 7 Oct 2026 14:16:27 +0000 Subject: [PATCH] =?UTF-8?q?Widerrufsseite:=20Vertragsart=20Projektauftrag?= =?UTF-8?q?=20mit=20freiwilliger=20Nummer=20der=20Auftragsbest=C3=A4tigung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5.5 --- public/auftrag-widerruf.js | 56 +++++++++++ public/widerrufen.html | 10 +- test/auftraegeKundenportalWiderruf.test.js | 110 +++++++++++++++++++++ test/publicForms.test.js | 2 +- 4 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 public/auftrag-widerruf.js create mode 100644 test/auftraegeKundenportalWiderruf.test.js diff --git a/public/auftrag-widerruf.js b/public/auftrag-widerruf.js new file mode 100644 index 0000000..082c1ab --- /dev/null +++ b/public/auftrag-widerruf.js @@ -0,0 +1,56 @@ +/* Widerrufsseite: Vertragsart „Projektauftrag“ mit freiwilliger Nummer der Auftragsbestätigung (Feld abNummer). + Rechtsfunktion: dieses Modul darf die anderen Vertragsarten nie stören. Fällt es aus, funktioniert der Widerruf wie bisher. + Das Feld ist nur bei „Projektauftrag“ sichtbar; eine eingegebene, aber unpassende Nummer wird gemeldet und stoppt das Absenden, + ein leeres Feld lässt den Widerruf durch (der Widerruf bleibt formfrei). Die Meldung steht in auftrag-ansicht.js. */ +import { abNummerNormalisiert, texte } from './auftrag-ansicht.js' + +export function initProjektWiderruf(form) { + const wrap = form?.querySelector('#ab-nummer-wrap') + const feld = form?.querySelector('#abNummer') + const fehler = form?.querySelector('#form-error') + if (!form || !wrap || !feld || !fehler) return + const gewaehlt = () => form.querySelector('[name="order"]:checked')?.value + let eigeneMeldung = false + + const meldungWeg = () => { + if (!eigeneMeldung) return + eigeneMeldung = false + fehler.textContent = '' + fehler.classList.add('hidden') + } + const zeige = () => { + const projekt = gewaehlt() === 'projekt' + wrap.classList.toggle('hidden', !projekt) + if (!projekt) { + feld.value = '' + meldungWeg() + } + } + + form.addEventListener('change', zeige) + form.addEventListener('click', (ev) => { + if (!ev.target?.closest?.('button[type="submit"], input[type="submit"]') || gewaehlt() !== 'projekt') return + const eingabe = feld.value.trim() + if (!eingabe) { + feld.value = '' + meldungWeg() + return + } + const nummer = abNummerNormalisiert(eingabe) + if (!nummer) { + ev.preventDefault() + fehler.textContent = texte().abNummerUngueltig + fehler.classList.remove('hidden') + eigeneMeldung = true + feld.focus() + return + } + feld.value = nummer + meldungWeg() + }) + zeige() +} + +if (typeof document !== 'undefined' && document.getElementById('decl-form') && document.getElementById('ab-nummer-wrap')) { + initProjektWiderruf(document.getElementById('decl-form')) +} diff --git a/public/widerrufen.html b/public/widerrufen.html index 231320a..76fab22 100644 --- a/public/widerrufen.html +++ b/public/widerrufen.html @@ -24,8 +24,15 @@ + + +
+ + +
+ @@ -49,7 +56,8 @@ + diff --git a/test/auftraegeKundenportalWiderruf.test.js b/test/auftraegeKundenportalWiderruf.test.js new file mode 100644 index 0000000..0e18bcc --- /dev/null +++ b/test/auftraegeKundenportalWiderruf.test.js @@ -0,0 +1,110 @@ +import { test } from 'node:test' +import assert from 'node:assert/strict' +import { readFileSync } from 'node:fs' +import { installFakeDom } from './support/fakeDom.js' +import { h } from '../public/auftrag-dom.js' +import { initProjektWiderruf } from '../public/auftrag-widerruf.js' +import { pruefeQuelltext } from './auftraegeKundenportalDaten.js' + +const html = readFileSync(new URL('../public/widerrufen.html', import.meta.url), 'utf8') +const MELDUNG = 'Die Nummer sieht anders aus als AB-2026-0001. Bitte prüfen Sie die Nummer oder lassen Sie das Feld leer.' + +test('widerrufen.html: Vertragsart „Projektauftrag“ hinter „Öffnungszeiten live“, freiwilliges Feld abNummer vor dem Namen, Skripte', () => { + assert.match(html, /name="order" value="zeiten"[^>]*> Öffnungszeiten live<\/label>\s*