Terminplaner: Fix Widerruf nach Terminbeginn, Zustimmung beim Verschieben, Berliner Widerrufsfrist, Grenzen nur ohne Treffer

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-03 08:17:43 +00:00
1 parent 2d9b75b3bf
commit c4ec24448e
10 files changed
+319 -77

No files matched your search

+12 -1
View File
@@ -439,6 +439,7 @@ const FAELLE = [
['G07', buchung({ icsSequenz: 1 }), { altStart: ALT_START }],
['G08', buchung(), { fall: 'zugeordnet', eingang: EINGANG }],
['G08', buchung(), { fall: 'nach_frist', eingang: EINGANG }],
['G08', buchung(), { fall: 'begonnen', eingang: EINGANG }],
['G08', null, { fall: 'nicht_zugeordnet', eingang: EINGANG, an: 'erika@example.com' }],
['K20', buchung(), {}],
['K20', buchung({ status: 'angefragt' }), { fall: 'anfrage' }],
@@ -446,6 +447,7 @@ const FAELLE = [
['K21', buchung(), { fall: 'verschoben', altStart: ALT_START }],
['K21', buchung(), { fall: 'widerrufen', eingang: EINGANG }],
['K21', buchung(), { fall: 'nach_frist', eingang: EINGANG }],
['K21', buchung(), { fall: 'begonnen', eingang: EINGANG }],
['K21', ERKLAERUNG, { fall: 'nicht_zugeordnet', eingang: EINGANG }],
]
@@ -506,6 +508,7 @@ test('Betreffzeilen der Betriebsmails: Buchung/Anfrage und je Fall von K21; nie
assert.match(betreff('K21', buchung(), { fall: 'verschoben', altStart: ALT_START }), /^Termin verschoben: Damenschnitt, jetzt am 12\.10\.2026 um 10:00$/)
assert.match(betreff('K21', buchung(), { fall: 'widerrufen', eingang: EINGANG }), /^Termin widerrufen: /)
assert.match(betreff('K21', buchung(), { fall: 'nach_frist', eingang: EINGANG }), /^Widerruf nach Ablauf der Frist: /)
assert.equal(betreff('K21', buchung(), { fall: 'begonnen', eingang: EINGANG }), 'Widerruf nach Terminbeginn: Damenschnitt am 12.10.2026 um 10:00')
assert.equal(betreff('K21', ERKLAERUNG, { fall: 'nicht_zugeordnet', eingang: EINGANG }), 'Widerruf ohne passende Buchung')
for (const [art, b, extra] of FAELLE) {
const text = betreff(art, b, extra)
@@ -751,6 +754,14 @@ test('G08: Eingang als "TT.MM.JJJJ, HH:MM Uhr" (Berliner Zeit), Nummer nur der g
assert.deepEqual(keine.blocks, { sie: true }, 'weder zugeordnet noch nach_frist')
assert.equal(keine.values.nummer, '–')
// Widerruf nach Terminbeginn (Frist laeuft noch): neutraler Satz ohne Fallblock und ohne Nummer
const begonnen = werteFuer('G08', ctx, buchung(), { fall: 'begonnen', eingang: EINGANG })
assert.deepEqual(begonnen.blocks, { sie: true })
assert.equal(begonnen.values.nummer, '–')
const text = renderMail('G08', begonnen.values, begonnen.blocks).text
assert.doesNotMatch(text, /abgelaufen|Der Termin ist abgesagt/)
assert.match(text, /prüft Ihre Erklärung und meldet sich bei Ihnen/)
// Nummer aus der Buchung, nie aus einer Eingabe des Gastes
assert.throws(() => werteFuer('G08', ctx, null, { fall: 'zugeordnet', eingang: EINGANG }), TypeError)
assert.throws(() => werteFuer('G08', ctx, buchung(), { eingang: EINGANG }), TypeError, 'fall ist Pflicht')
@@ -769,7 +780,7 @@ test('K20 und K21: Gastangaben, "–" fuer Leeres, Kundenname, ein Fallblock je
assert.deepEqual(werteFuer('K20', ctx, buchung(), { fall: 'anfrage' }).blocks, { anfrage: true })
assert.equal(werteFuer('K20', ctx, buchung(), {}).values.kunde_name, 'Salon Müller', 'ohne Kundenname der Betriebsname')
for (const fall of ['abgesagt', 'verschoben', 'widerrufen', 'nach_frist']) {
for (const fall of ['abgesagt', 'verschoben', 'widerrufen', 'nach_frist', 'begonnen']) {
const { blocks } = werteFuer('K21', ctx, buchung(), { fall, altStart: ALT_START, eingang: EINGANG })
assert.deepEqual(blocks, { [fall]: true }, fall)
}