Buchungskalender: Verwaltungs-API – Einstellungen, Zustimmung, Online-Zahlung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d0ab92658a
commit
32cffb3518
5 files changed
+87
-27
No files matched your search
@@ -21,7 +21,7 @@ const { istFrei } = await import('../server/services/unterkunft/belegung.js')
|
||||
|
||||
after(() => aw.close())
|
||||
const NOW = new Date('2026-11-01T12:00:00Z')
|
||||
const ctx = { featureId: 'f1', customerId: 'c1', projectId: 'p1', siteKey: 'sk', einstellungen: { firma: 'Haus', strasse: 'Str 1', plz: '10115', ort: 'Berlin', steuernummer: '12/345', onlineZahlung: false } }
|
||||
const ctx = { featureId: 'f1', customerId: 'c1', projectId: 'p1', siteKey: 'sk', einstellungen: { firma: 'Haus', strasse: 'Str 1', plz: '10115', ort: 'Berlin', steuernummer: '12/345', onlineZahlung: false, rechnungAuftragAt: '2026-10-01T00:00:00.000Z' } }
|
||||
const GAST = { name: 'Eva Gast', firma: '', email: 'eva@example.com', telefon: '', nachricht: 'Hallo' }
|
||||
const ADRESSE = { name: 'Eva Gast', strasse: 'Weg 1', plz: '12345', ort: 'Berlin', land: 'DE' }
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ const vorher = { ...config.unterkunft }
|
||||
|
||||
const einstellungen = (extra = {}) => ({
|
||||
$id: FEATURE, featureId: FEATURE, firma: 'Donau Home', inhaber: 'Mimi', strasse: 'Str 1', plz: '78576', ort: 'Stetten', email: 'x@y.de',
|
||||
steuernummer: '12/345', iban: 'DE00', akzentfarbe: '#112233', ...extra,
|
||||
steuernummer: '12/345', iban: 'DE00', akzentfarbe: '#112233', rechnungAuftragAt: '2026-10-01T00:00:00.000Z', ...extra,
|
||||
})
|
||||
|
||||
async function seedBasis(einstExtra = {}) {
|
||||
|
||||
@@ -41,7 +41,7 @@ const del = (pfad, opts = { cookie }) => send('DELETE', `/api/unterkunft${pfad}?
|
||||
|
||||
const EINST = {
|
||||
firma: 'Donau Home', inhaber: 'Mimi', strasse: 'Weg 1', plz: '78576', ort: 'Stetten', email: 'mimi@example.com',
|
||||
telefon: '', steuernummer: '12/345/67890', ustId: '', iban: '', bic: '', bank: '', rechnungsPraefix: 'DH', akzentfarbe: '#112233',
|
||||
telefon: '', rechnungAuftragAt: '2026-10-01T00:00:00.000Z', steuernummer: '12/345/67890', ustId: '', iban: '', bic: '', bank: '', rechnungsPraefix: 'DH', akzentfarbe: '#112233',
|
||||
}
|
||||
const PREISE = {
|
||||
staffeln: [{ abNaechten: 1, preisProNachtCent: 10000 }, { abNaechten: 7, preisProNachtCent: 9000 }],
|
||||
@@ -140,14 +140,16 @@ test('Einstellungen: speichern, Rueckgabe ohne Stripe-Konto-ID, USt-ID statt Ste
|
||||
assert.equal(ok.body.einstellungen.ustId, 'DE123456789')
|
||||
assert.equal(ok.body.einstellungen.iban, 'DE89370400440532013000')
|
||||
assert.equal(ok.body.einstellungen.firma, 'Haus')
|
||||
assert.equal(ok.body.vollstaendig, true)
|
||||
assert.equal(ok.body.einstellungen.stripeAccountId, undefined)
|
||||
const schlecht = await put('/einstellungen', { email: 'kaputt', akzentfarbe: 'rot', iban: 'x', rechnungsPraefix: 'A-B', onlineZahlung: true })
|
||||
assert.equal(ok.body.einstellungen.rechnungAuftrag, true)
|
||||
const schlecht = await put('/einstellungen', { email: 'kaputt', akzentfarbe: 'rot', iban: 'x', rechnungsPraefix: 'A-B' })
|
||||
assert.equal(schlecht.status, 400)
|
||||
for (const f of ['email', 'akzentfarbe', 'iban', 'rechnungsPraefix', 'onlineZahlung']) assert.ok(schlecht.body.felder[f], f)
|
||||
for (const f of ['email', 'akzentfarbe', 'iban', 'rechnungsPraefix']) assert.ok(schlecht.body.felder[f], f)
|
||||
const g = await get('/einstellungen')
|
||||
assert.equal(g.body.einstellungen.firma, 'Haus')
|
||||
assert.equal(g.body.einstellungen.rechnungsPraefixFrei, true)
|
||||
assert.equal(g.body.rechnungenVorhanden, false)
|
||||
assert.deepEqual(g.body.stripe, { status: 'keins', vorhandenesShopKonto: false })
|
||||
assert.deepEqual(Object.keys(g.body).sort(), ['einstellungen', 'rechnungenVorhanden', 'stripe'])
|
||||
})
|
||||
|
||||
test('Einstellungen: Praefix nach der ersten Rechnung 409, gleicher Wert bleibt erlaubt', async () => {
|
||||
@@ -158,7 +160,8 @@ test('Einstellungen: Praefix nach der ersten Rechnung 409, gleicher Wert bleibt
|
||||
assert.ok(r.body.felder.rechnungsPraefix)
|
||||
assert.equal(aw.docs('ukEinstellungen').get(FEATURE).rechnungsPraefix, 'DH')
|
||||
assert.equal((await put('/einstellungen', { ...EINST, firma: 'Neu GmbH' })).status, 200)
|
||||
assert.equal((await get('/einstellungen')).body.einstellungen.rechnungsPraefixFrei, false)
|
||||
aw.seed('ukRechnungen', { $id: 'r9', featureId: FEATURE, anfrageId: 'a1', art: 'rechnung', nummer: 'DH-2026-0001', datum: '2026-11-01', bruttoCent: 1, inhalt: '{}' })
|
||||
assert.equal((await get('/einstellungen')).body.rechnungenVorhanden, true)
|
||||
})
|
||||
|
||||
// ------------------------------------------------------------------------------------------------ Unterkuenfte
|
||||
@@ -477,7 +480,9 @@ test('Rechnungen: Liste nur des Projekts; PDF fremde Rechnung 404, eigene 200 od
|
||||
const l = (await get('/rechnungen')).body.rechnungen
|
||||
assert.deepEqual(l.map((r) => r.id), ['r1'])
|
||||
assert.equal(l[0].anfrageNummer, 'A-X')
|
||||
assert.equal(l[0].empfaenger, 'Eva')
|
||||
assert.equal(l[0].gastName, 'Eva')
|
||||
assert.equal(l[0].empfaenger, undefined)
|
||||
assert.equal(l[0].anfrageId, undefined)
|
||||
assert.equal((await get('/rechnungen/rfremd.pdf')).status, 404)
|
||||
assert.equal((await get('/rechnungen/nix.pdf')).status, 404)
|
||||
assert.equal((await get('/rechnungen/r1')).status, 404)
|
||||
@@ -552,3 +557,44 @@ test('pruefeEinstellungen: nur gesendete Felder, Vollstaendigkeit aus vorher + e
|
||||
assert.deepEqual(r.werte, { telefon: '123' })
|
||||
assert.ok(pruefeEinstellungen({ steuernummer: '' }, { ...EINST }).fehler.steuernummer)
|
||||
})
|
||||
|
||||
test('Einstellungen: rechnungAuftrag setzt/widerruft rechnungAuftragAt', async () => {
|
||||
aw.seed('ukEinstellungen', { $id: FEATURE, featureId: FEATURE, ...EINST, rechnungAuftragAt: undefined })
|
||||
assert.equal((await get('/einstellungen')).body.einstellungen.rechnungAuftrag, false)
|
||||
const an = await put('/einstellungen', { ...EINST, rechnungAuftrag: true })
|
||||
assert.equal(an.body.einstellungen.rechnungAuftrag, true)
|
||||
const zeit = aw.docs('ukEinstellungen').get(FEATURE).rechnungAuftragAt
|
||||
assert.ok(zeit)
|
||||
await put('/einstellungen', { ...EINST, rechnungAuftrag: true })
|
||||
assert.equal(new Date(aw.docs('ukEinstellungen').get(FEATURE).rechnungAuftragAt).getTime(), new Date(zeit).getTime())
|
||||
const aus = await put('/einstellungen', { ...EINST, rechnungAuftrag: false })
|
||||
assert.equal(aus.body.einstellungen.rechnungAuftrag, false)
|
||||
assert.ok(!aw.docs('ukEinstellungen').get(FEATURE).rechnungAuftragAt)
|
||||
assert.equal((await put('/einstellungen', { rechnungAuftrag: 'ja' })).status, 400)
|
||||
})
|
||||
|
||||
test('Zustimmung: ohne rechnungAuftrag verweigern freigeben und bucheVerbindlich mit 409 zustimmung_fehlt', async () => {
|
||||
aw.seed('ukEinstellungen', { $id: FEATURE, featureId: FEATURE, ...EINST, rechnungAuftragAt: undefined })
|
||||
anfrage('a1')
|
||||
const r = await post('/anfragen/a1/freigeben', { posten: POSTEN })
|
||||
assert.equal(r.status, 409)
|
||||
assert.equal(r.body.fehler, 'zustimmung_fehlt')
|
||||
assert.equal(aw.docs('ukAnfragen').get('a1').status, 'neu')
|
||||
const ab = await import('../server/services/unterkunft/ablauf.js')
|
||||
anfrage('a2', { status: 'freigegeben', tokenHash: 'x', fristAt: new Date(Date.now() + 86400000).toISOString(), posten: JSON.stringify(POSTEN), summen: JSON.stringify({ bruttoCent: 20000, nettoCent: 20000, ust: [] }) })
|
||||
const ctx = { featureId: FEATURE, einstellungen: { ...EINST } }
|
||||
await assert.rejects(ab.bucheVerbindlich(ctx, 'a2', 'x', { rechnungsadresse: {}, zahlart: 'vorort' }), (e) => e instanceof UkFehler && e.code === 'zustimmung_fehlt' || e.code === 'nicht_gefunden')
|
||||
assert.equal(aw.docs('ukAnfragen').get('a2').status, 'freigegeben')
|
||||
assert.equal(aw.docs('ukRechnungen').size, 0)
|
||||
})
|
||||
|
||||
test('Online-Zahlung: nur mit aktivem Stripe-Konto, sonst 409 mit felder.onlineZahlung', async () => {
|
||||
await post('/stripe/verbinden')
|
||||
st.setAccount(aw.docs('ukEinstellungen').get(FEATURE).stripeAccountId, { charges_enabled: false })
|
||||
await post('/stripe/aktualisieren')
|
||||
assert.equal((await get('/status')).body.stripe.status, 'onboarding')
|
||||
const r = await put('/einstellungen', { onlineZahlung: true })
|
||||
assert.equal(r.status, 409)
|
||||
assert.ok(r.body.felder.onlineZahlung)
|
||||
assert.notEqual(aw.docs('ukEinstellungen').get(FEATURE).onlineZahlung, true)
|
||||
})
|
||||
Reference in new issue
Block a user