Funktionen: Preis entfernt, Abrechnung und Abo-Fehlertext als reine Logik
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
dce7c3e53a
commit
8f75276c54
4 files changed
+119
-6
No files matched your search
@@ -65,6 +65,8 @@ export function createFinanceRequest({ baseUrl, createJWT, fetchImpl = (...args)
|
||||
if (info.invoiceNumber) err.invoiceNumber = info.invoiceNumber
|
||||
// Team-Einstellungen der Oeffnungszeiten (PATCH): code (409 ZEITEN_VERALTET) und fehler je Feld (400)
|
||||
if (typeof info.code === 'string') err.code = info.code
|
||||
// Funktion einschalten ohne passendes Abo (409 abo_fehlt): der Grund (kein_abo, falsches_abo, gekuendigt, nicht_aktiv …) bestimmt den Text
|
||||
if (typeof info.grund === 'string') err.grund = info.grund
|
||||
if (info.fehler && typeof info.fehler === 'object') err.fehler = info.fehler
|
||||
throw err
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export const FUNKTIONEN = [
|
||||
label: 'Terminplaner',
|
||||
bestaetigen: {
|
||||
activate: 'Terminplaner ohne Zahlung aktivieren?',
|
||||
disable: 'Terminplaner abschalten? Auf der Website sind dann keine Buchungen mehr möglich. Damit beginnt die Löschung: Nach 30 Tagen werden alle Termine und Einstellungen gelöscht. Wieder einschalten ist nach diesen 30 Tagen nur mit einer neuen Bestellung (149 €) möglich.',
|
||||
disable: 'Terminplaner abschalten? Auf der Website sind dann keine Buchungen mehr möglich. Damit beginnt die Löschung: Nach 30 Tagen werden alle Termine und Einstellungen gelöscht. Wieder einschalten ist nach diesen 30 Tagen nur mit einer neuen Einrichtung möglich.',
|
||||
abnahme: 'Terminplaner freischalten? Der Kunde bekommt die Mail „bereit“ und Gäste können buchen.',
|
||||
ticket: 'Fehlendes Einrichtungs-Ticket neu anlegen?',
|
||||
},
|
||||
@@ -291,13 +291,58 @@ export function textformBereit({ confirmed, date, channel, today }, feld) {
|
||||
return canSubmitTextform({ confirmed, date, channel, today, minDate, channels: FUNKTION_CHANNELS })
|
||||
}
|
||||
|
||||
/** Rumpf fuer POST /funktionen/:customerId/:key; Datum und Weg der Textform nur beim Aktivieren und nur, wenn beide da sind. */
|
||||
export function featureBody({ projectId, action, note, textformDate, textformChannel }) {
|
||||
/** Wahl beim Aktivieren: wohin die Einrichtungszeit geht (Portal: POST /funktionen/:customerId/:key, Feld abrechnung). */
|
||||
export const ABRECHNUNG_OPTIONEN = [
|
||||
{ value: 'abo', label: 'Aus dem Abo' },
|
||||
{ value: 'projekt', label: 'Im Projekt enthalten' },
|
||||
]
|
||||
|
||||
/** Erklaerung unter der Wahl (ohne Preis). */
|
||||
export const ABRECHNUNG_HINWEIS =
|
||||
'Aus dem Abo: Die Einrichtungszeit geht aufs Stundenkonto des Kunden. Im Projekt enthalten: Sie zählt nicht aufs Stundenkonto und läuft über die Projektkosten.'
|
||||
|
||||
/**
|
||||
* true, wenn diese Aktion die Wahl der Abrechnung braucht: "Aktivieren" einer Funktion aus FUNKTIONEN, ausser nach einer Team-Sperre
|
||||
* (state "disabled" mit disabledReason "team"): dort wird nur wieder eingeschaltet, die Abrechnung steht schon.
|
||||
*/
|
||||
export const fragtAbrechnung = (key, action, feature) =>
|
||||
action === 'activate' && FUNKTIONEN.some((f) => f.key === key) && !(feature?.state === 'disabled' && feature?.disabledReason === 'team')
|
||||
|
||||
/** Ohne Frage immer bereit, mit Frage nur mit "abo" oder "projekt". */
|
||||
export const abrechnungBereit = ({ key, action, feature, abrechnung }) =>
|
||||
!fragtAbrechnung(key, action, feature) || ABRECHNUNG_OPTIONEN.some((o) => o.value === abrechnung)
|
||||
|
||||
/** Text zu 409 abo_fehlt (Portal: grund = kein_abo | falsches_abo | gekuendigt | nicht_aktiv); unbekannter oder fehlender Grund -> allgemeiner Satz. */
|
||||
export function aboFehltText(grund, key) {
|
||||
const name = FUNKTIONEN.find((f) => f.key === key)?.label || key
|
||||
switch (grund) {
|
||||
case 'kein_abo':
|
||||
return `${name}: Der Kunde hat kein laufendes Abo. Die Funktion läuft nur mit passendem Abo.`
|
||||
case 'falsches_abo':
|
||||
return `${name}: Das Hosting-Abo des Kunden enthält diese Funktion nicht. Sie ist im Wartungs-Abo enthalten.`
|
||||
case 'gekuendigt':
|
||||
return `${name}: Das Abo des Kunden ist gekündigt. Eingeschaltet wird nicht, solange die Kündigung vorgemerkt ist.`
|
||||
case 'nicht_aktiv':
|
||||
return `${name}: Das Abo des Kunden läuft nicht (Status nicht aktiv). Bitte zuerst das Abo klären.`
|
||||
default:
|
||||
return `${name}: Das passende Abo fehlt.`
|
||||
}
|
||||
}
|
||||
|
||||
/** Fehlertext zu einer Aktion: bei abo_fehlt der Text zum Grund, sonst die Meldung des Fehlers, ohne beides "Speichern fehlgeschlagen.". */
|
||||
export const featureFehlerText = (err, key) => (err?.code === 'abo_fehlt' ? aboFehltText(err.grund, key) : err?.message || 'Speichern fehlgeschlagen.')
|
||||
|
||||
/**
|
||||
* Rumpf fuer POST /funktionen/:customerId/:key; Datum und Weg der Textform nur beim Aktivieren und nur, wenn beide da sind,
|
||||
* abrechnung nur beim Aktivieren und nur mit einem Wert aus ABRECHNUNG_OPTIONEN.
|
||||
*/
|
||||
export function featureBody({ projectId, action, note, textformDate, textformChannel, abrechnung }) {
|
||||
const body = { projectId, action, note }
|
||||
if (action === 'activate' && textformDate && textformChannel) {
|
||||
body.textformDate = textformDate
|
||||
body.textformChannel = textformChannel
|
||||
}
|
||||
if (action === 'activate' && ABRECHNUNG_OPTIONEN.some((o) => o.value === abrechnung)) body.abrechnung = abrechnung
|
||||
return body
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user