Buchungskalender: Anfragen-Reiter – Erstattung und Fehlermeldungen
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
db9fc61894
commit
37cd312549
2 files changed
+21
-9
No files matched your search
@@ -6,7 +6,8 @@
|
||||
POST …/freigeben {posten,fristTage,nachricht} (=> { buchungsLink? }), …/ablehnen {text}, …/bezahlt, …/stornieren {grund,erstattungCent}.
|
||||
Fremdtext (Gast, Nachricht) nur ueber textContent. render(panel, ctx) wie shop-tab-*.js. */
|
||||
|
||||
import { abschnitt, allgemeinerFehler, euroText, euroZuCent, fehlerKarte, feld, frage, h, zeigeFehler, datumText } from './shop-dom.js'
|
||||
import { abschnitt, allgemeinerFehler, centZuEuro, euroZuCent, fehlerKarte, feld, frage, h, zeigeFehler, datumText } from './shop-dom.js'
|
||||
import { fehlerFuerFormular } from './buchungen-fehler.js'
|
||||
import { baueEditor, euroMitVorzeichen } from './buchungen-posten.js'
|
||||
|
||||
export const STATUS = {
|
||||
@@ -142,7 +143,7 @@ export async function render(panel, ctx) {
|
||||
feld('nachricht', 'Nachricht an den Gast (optional)', nachricht),
|
||||
allgemeinerFehler())
|
||||
const freigeben = h('button', {
|
||||
type: 'button', class: 'kb-btn', 'data-aktion': 'freigeben', disabled: ctx.nurLesen && !ctx.abwickeln,
|
||||
type: 'button', class: 'kb-btn', 'data-aktion': 'freigeben',
|
||||
onclick: () => sendeFreigabe(a, editor, frist, nachricht, form, freigeben),
|
||||
}, 'Freigeben')
|
||||
const ablehnen = h('button', { type: 'button', class: 'kb-btn-outline', 'data-aktion': 'ablehnen', onclick: () => ablehnDialog(a, ablehnen) }, 'Ablehnen')
|
||||
@@ -160,12 +161,12 @@ export async function render(panel, ctx) {
|
||||
method: 'POST', body: { posten, fristTage: tage, nachricht: String(nachricht.value).trim() },
|
||||
})
|
||||
if (!ctx.aktuell()) return
|
||||
ctx.zeigeMeldung('Freigegeben. Dein Gast hat den Buchungslink per Mail bekommen.', 'ok')
|
||||
ctx.zeigeMeldung('Freigegeben. Der Buchungslink wurde an deinen Gast geschickt – falls die Mail nicht ankommt, kannst du ihn hier kopieren.', 'ok')
|
||||
zeigeLink(antwort?.buchungsLink, a)
|
||||
} catch (err) {
|
||||
knopf.disabled = false
|
||||
if (err.status === 409) zeigeFehler(form, { message: BELEGT, fehler: { _: BELEGT } })
|
||||
else zeigeFehler(form, err)
|
||||
else zeigeFehler(form, fehlerFuerFormular(err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +213,7 @@ export async function render(panel, ctx) {
|
||||
await zeigeListe()
|
||||
} catch (err) {
|
||||
ev.currentTarget.disabled = false
|
||||
zeigeFehler(box, err)
|
||||
zeigeFehler(box, fehlerFuerFormular(err))
|
||||
}
|
||||
},
|
||||
}, 'Ablehnen'),
|
||||
@@ -262,10 +263,10 @@ export async function render(panel, ctx) {
|
||||
}
|
||||
|
||||
function stornoDialog(a, dialogEl, ausloeser) {
|
||||
const online = a.bezahltVia === 'online'
|
||||
const online = a.bezahltVia === 'stripe'
|
||||
const grund = h('textarea', { id: 'bk-a-grund', rows: '3', maxlength: '500' })
|
||||
const betrag = h('input', { type: 'text', inputmode: 'decimal', id: 'bk-a-erstattung', autocomplete: 'off' })
|
||||
betrag.value = Number.isInteger(a.summen?.bruttoCent) ? `${Math.floor((a.summen.bruttoCent - (a.erstattetCent || 0)) / 100)},${String((a.summen.bruttoCent - (a.erstattetCent || 0)) % 100).padStart(2, '0')}` : ''
|
||||
betrag.value = Number.isInteger(a.summen?.bruttoCent) ? centZuEuro(a.summen.bruttoCent - (a.erstattetCent || 0)) : ''
|
||||
const box = frage('Buchung stornieren', h('p', { class: 'sh-hinweis' }, 'Der Gast bekommt eine Stornomail und eine Storno-Rechnung.'),
|
||||
feld('grund', 'Grund', grund),
|
||||
online ? feld('erstattungCent', 'Erstattung in Euro', betrag, 'Der Betrag geht an die Karte des Gastes zurück. 0 = keine Erstattung.') : null,
|
||||
@@ -290,7 +291,7 @@ export async function render(panel, ctx) {
|
||||
knopf.disabled = false
|
||||
if (err.fehler === 'erstattung_fehlgeschlagen' || err.body?.fehler === 'erstattung_fehlgeschlagen') {
|
||||
zeigeFehler(box, { message: 'Die Buchung ist storniert, aber die Erstattung ist fehlgeschlagen. Bitte versuch die Erstattung gleich noch einmal.', fehler: {} })
|
||||
} else zeigeFehler(box, err)
|
||||
} else zeigeFehler(box, fehlerFuerFormular(err))
|
||||
}
|
||||
},
|
||||
}, 'Stornieren'),
|
||||
|
||||
@@ -151,7 +151,7 @@ test('Gebucht: Rechnung-Link, „Als bezahlt (vor Ort)“, Storno ohne Erstattun
|
||||
}))
|
||||
|
||||
test('Storno bei Online-Zahlung: Erstattungsbetrag wird gesendet', mit(server({
|
||||
'GET /api/unterkunft/anfragen/a1': () => ({ body: gebucht({ status: 'bezahlt', zahlart: 'online', bezahltVia: 'online' }) }),
|
||||
'GET /api/unterkunft/anfragen/a1': () => ({ body: gebucht({ status: 'bezahlt', zahlart: 'online', bezahltVia: 'stripe' }) }),
|
||||
'POST /api/unterkunft/anfragen/a1/stornieren': () => ({ body: {} }),
|
||||
}), async (fx) => {
|
||||
const { panel } = await zeige(fx)
|
||||
@@ -369,3 +369,14 @@ test('iCal: Import hinzufügen (POST), entfernen mit Rückfrage, Link erneuern m
|
||||
await fx.ruhe()
|
||||
assert.equal(posts(fx).filter((a) => a.url.includes('erneuern')).length, 1)
|
||||
}))
|
||||
|
||||
test('Freigeben: Serverfehler 400 mit felder zeigt genau den Feldtext', mit(server({
|
||||
'POST /api/unterkunft/anfragen/a1/freigeben': () => ({ status: 400, body: { fehler: 'ungueltig', felder: { posten: 'Die Summe muss größer als 0 sein.' } } }),
|
||||
}), async (fx) => {
|
||||
const { panel } = await zeige(fx)
|
||||
await oeffne(fx, panel)
|
||||
await fx.klick(aktion(fx, panel, 'freigeben'))
|
||||
await fx.ruhe()
|
||||
assert.equal(fx.text(fx.finde(panel, '[data-fehler="posten"]')), 'Die Summe muss größer als 0 sein.')
|
||||
assert.equal(fx.text(fx.finde(panel, '[data-fehler="_"]')), '')
|
||||
}))
|
||||
Reference in new issue
Block a user