Terminplaner: Hinweistexte nach Recherche, Storno nur bei Preis

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-05 04:29:32 +00:00
1 parent 722c686690
commit 6ec8885bfd
11 files changed
+230 -21

No files matched your search

+45 -1
View File
@@ -34,7 +34,7 @@ const { zellenFuer, zellenId } = await import('../server/services/termine/zellen
const { RECHTSTEXTE_VERSION, ZUSTIMMUNG_STORNO, ZUSTIMMUNG_VORZEITIG, ZUSTIMMUNG_ERINNERUNG, formularHinweis } = await import(
'../server/services/termine/rechtstexte.js'
)
const { halte, vorschau, bestaetige } = await import('../server/services/termine/ablauf.js')
const { halte, vorschau, bestaetige, pruefeEingabe } = await import('../server/services/termine/ablauf.js')
after(() => setMailTransportForTests(null))
const MIN = 60000
@@ -280,6 +280,50 @@ test('halte: Anfrage und Leistung ohne Preis bekommen ihre Knoepfe und brauchen
assert.match(JSON.parse(anfrage.nachweis).widerruf.hash, /^[0-9a-f]{64}$/)
})
test('storno_haken_nur_bei_preis: der Storno-Haken ist nur bei einer Leistung mit Preis Pflicht und steht nur dort im Nachweis', async () => {
const ctx = await speichere()
// mit Preis: ohne Haken wie bisher 400 (Feld storno), nichts angelegt
const err = await fehlerVon(() => halte(ctx, eingabe({ zustimmungen: { storno: false, vorzeitig: false } }), JETZT))
assert.equal(err.status, 400)
assert.deepEqual(Object.keys(err.fehler), ['storno'])
assert.equal(buchungen().length, 0)
// ohne Preis (sofort): ohne Haken gehalten, kein Eintrag storno im Nachweis
await halte(ctx, eingabe({ leistung: S_GRATIS, zeit: '10:00', email: 'a@example.com', zustimmungen: { storno: false, vorzeitig: false } }), JETZT)
// ohne Preis, auch ganz ohne Zustimmungen
await halte(ctx, eingabe({ leistung: S_GRATIS, zeit: '12:00', email: 'b@example.com', zustimmungen: undefined }), JETZT)
// ohne Preis, Anfrage
await halte(ctx, eingabe({ leistung: S_ANFRAGE, zeit: '14:00', email: 'c@example.com', zustimmungen: {} }), JETZT)
// ohne Preis mit storno: true (altes Widget, anderer Client): ebenfalls kein Nachweis des Hakens
await halte(ctx, eingabe({ leistung: S_GRATIS, zeit: '16:00', email: 'd@example.com', zustimmungen: { storno: true, vorzeitig: false } }), JETZT)
assert.equal(buchungen().length, 4)
for (const b of buchungen()) {
assert.equal(b.status, 'gehalten')
const nachweis = JSON.parse(b.nachweis)
assert.equal(nachweis.storno, undefined, `${b.leistungId}: kein Storno-Nachweis ohne Preis`)
assert.equal(Object.hasOwn(nachweis, 'storno'), false)
assert.ok(!b.nachweis.includes(sha256(ZUSTIMMUNG_STORNO)), 'auch der Hash des Haken-Textes fehlt')
}
// mit Preis und Haken: Nachweis wie bisher
await halte(ctx, eingabe({ zeit: '09:00', email: 'e@example.com' }), JETZT)
const mitPreis = buchungen().find((b) => b.leistungId === S_SOFORT)
assert.deepEqual(JSON.parse(mitPreis.nachweis).storno, { version: ctx.einstellung.storno.version, hash: sha256(ctx.einstellung.storno.text), haken: sha256(ZUSTIMMUNG_STORNO), am: iso(JETZT) })
// Anfrage mit Preis: Haken bleibt Pflicht
const anfrageMitPreis = { id: 's_bbbbbbb4', name: 'Beratung', dauer: 30, preisArt: 'fest', preisCent: 3000, buchungsart: 'anfrage', ressourcen: [R1, R2] }
const mitAnfrage = await speichere(einstellung({ leistungen: [anfrageMitPreis] }))
const ohneHaken = await fehlerVon(() => halte(mitAnfrage, eingabe({ leistung: 's_bbbbbbb4', zeit: '11:00', email: 'f@example.com', zustimmungen: { storno: false, vorzeitig: true } }), JETZT))
assert.deepEqual(Object.keys(ohneHaken.fehler), ['storno'])
// Handeintrag (manuell): nie Zustimmungen, mit und ohne Preis
const e = ctx.einstellung
for (const leistung of [S_SOFORT, S_GRATIS]) {
const geprueft = pruefeEingabe(e, eingabe({ leistung, zustimmungen: undefined }), JETZT, { manuell: true })
assert.equal(geprueft.stornoNoetig, false, `Handeintrag ${leistung}`)
}
assert.equal(pruefeEingabe(e, eingabe({ leistung: S_SOFORT }), JETZT).stornoNoetig, true)
assert.equal(pruefeEingabe(e, eingabe({ leistung: S_GRATIS }), JETZT).stornoNoetig, false)
})
test('halte: egal waehlt die Ressource mit den wenigsten Buchungen des Tages, eine feste Ressource bleibt sie', async () => {
const ctx = await speichere()
await halte(ctx, eingabe({ ressource: R1, zeit: '09:00' }), JETZT)