Öffnungszeiten: Bezahlen gesperrt, wenn im Abo enthalten

Checkout: neue Stufe 7b pruefeInklusive (Funktionen mit aboInklusive):
laeuft das Wartungs-Abo (auch nicht aktiv), 409 inklusive mit Hinweis aufs
Einschalten; kein Abo, Hosting und gekuendigt zahlen weiter 30 Euro.

Zahlung (markPaid): setup mit unlockedBy kauf, dann Neubau (stosseNeubauAn,
einbau am Dokument), erst danach das Einbau-Ticket mit dem Ergebnis; die
Webhook-Wiederholung baut nicht noch einmal. Spaete Zahlungen aendern ein
vorhandenes unlockedBy abo/team nicht. News und Terminplaner unveraendert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-05 02:18:30 +00:00
1 parent 66793d06d5
commit 47ae572fff
4 files changed
+518 -4

No files matched your search

+25
View File
@@ -144,6 +144,31 @@ export async function pruefeAbo(feature, customerId) {
throw bestellFehler(409, aboMeldung(feature, grund), grund, { grund })
}
const INKLUSIVE_TEXT = 'Im Wartungs-Abo bereits enthalten – einfach einschalten.'
/**
* Pruefstufe 7b: Funktionen mit aboInklusive (Oeffnungszeiten live) kosten im laufenden Wartungs-Abo nichts. Laeuft das Abo und ist
* es nicht gekuendigt (bestellbar ok) oder nur gerade nicht aktiv (nicht_aktiv: Probezeit, offene Zahlung), gibt es keinen Grund zu
* bezahlen: 409 inklusive mit dem Hinweis aufs Einschalten; body.grund ist null (Abo laeuft) oder 'nicht_aktiv' (wie zeiten.grund in
* GET /api/funktionen). kein_abo und gekuendigt lassen den 30-Euro-Weg offen. Wie pruefeAbo: gleicher Memo je Anfrage, ein Lesefehler
* wirft (500, die Route zeigt nur ihren allgemeinen Text), im Zweifel nicht bestellbar; ein Ergebnis ohne gueltigen Grund ist ein Fehler.
* Funktionen ohne aboInklusive (News, Terminplaner) lassen es unberuehrt und lesen das Abo hier nicht.
*/
export async function pruefeInklusive(feature, customerId) {
if (feature.aboInklusive !== true) return
let ergebnis
try {
ergebnis = await orderDeps.aboMemo().bestellbar(customerId)
} catch (err) {
throw Object.assign(new Error(`Abo-Prüfung fehlgeschlagen: ${err?.message}`), { status: 500, cause: err })
}
if (ergebnis?.ok === true) throw bestellFehler(409, INKLUSIVE_TEXT, 'inklusive', { grund: null })
const grund = ergebnis?.grund
if (grund === 'nicht_aktiv') throw bestellFehler(409, INKLUSIVE_TEXT, 'inklusive', { grund })
if (grund === 'kein_abo' || grund === 'gekuendigt') return
throw new Error('Abo-Prüfung ohne gültiges Ergebnis')
}
const GRATIS_ABO_TEXT = {
kein_abo_gekuendigt: (name, preis) => `Ohne laufendes Wartungs-Abo kannst Du ${name} für einmalig ${preis} bestellen.`,
nicht_aktiv: () => 'Einschaltbar, sobald Dein Abo aktiv ist.',