Kundenansicht P5: generisches Einschalten im Abo (einschalten, Heilung, Ticket-Marker)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1d149f50b1
commit
f5b43c55a9
3 files changed
+396
-5
No files matched your search
@@ -4,7 +4,7 @@ import { pruefeAboFuerEinschalten } from '../featureOrder.js'
|
||||
import { featureConfig, ticketTexte } from '../featureRegistry.js'
|
||||
import { withLocks } from '../keyedLock.js'
|
||||
import { customerOf, ensureFeatureDoc, getFeatureDoc, stateFields, ticketWoid, unlockedByVon } from '../siteFeatures.js'
|
||||
import { createFeatureTicket } from '../ticketAdmin.js'
|
||||
import { ABRECHNUNGS_ZEILEN, createFeatureTicket } from '../ticketAdmin.js'
|
||||
import { k27Mail, sendeZeitenMail } from './mails.js'
|
||||
import { stosseNeubauAn } from './neubau.js'
|
||||
import { ladeZeiten } from './speicher.js'
|
||||
@@ -50,16 +50,24 @@ function notizDesTeams(staff, bisherige, now) {
|
||||
* by 'kunde': Abo frisch pruefen (kein_abo/gekuendigt/nicht_aktiv 409, Lesefehler 503), unlockedBy 'abo', K27 geht an den Kunden.
|
||||
* by 'team': keine Abo-Pruefung, unlockedBy 'team' (ein bisher gekauftes Dokument bleibt kauf), keine K27; staff ergibt die Notiz am Dokument.
|
||||
* nachweis: speichert den Zustimmungsnachweis (Schritt 3, nur wenn wirklich eingeschaltet wird); wirft er, bleibt der Zustand unveraendert.
|
||||
* abrechnung ('' | 'abo' | 'projekt', Abo-Modell der Kundenansicht neu, V7): ueberschreibt unlockedBy ('abo' | 'projekt'; ein gekauftes
|
||||
* Dokument bleibt kauf) und setzt einrichtungAbrechnung am Dokument (das Einrichtungs-Ticket traegt es in holeZeitenNach weiter).
|
||||
* Ohne abrechnung bleibt alles wie bisher. Ein anderer Wert ist ein TypeError.
|
||||
* vorpruefung: Funktion, die unter der Sperre statt pruefeAboFuerEinschalten laeuft (nur by 'kunde'); sie wirft, was der Aufrufer
|
||||
* als Fehler will (das Einschalten im Abo-Modell prueft damit Abo und Zustand mit eigenen Codes).
|
||||
* @returns {Promise<{ doc: object, changed: boolean }>} doc: das Dokument nach dem Nachholen; changed: false bei idempotentem Aufruf
|
||||
* @throws {Error} 409 (Abo, anderer Zustand), 503 (Abo nicht lesbar; oder Zustand gespeichert, aber Neubau/Ticket nicht fertig: erneut aufrufen)
|
||||
*/
|
||||
export async function einschaltenZeiten({ customerId, projectId, by = 'kunde', staff = null, nachweis = null, now = new Date() } = {}) {
|
||||
export async function einschaltenZeiten({ customerId, projectId, by = 'kunde', staff = null, nachweis = null, now = new Date(), abrechnung = '', vorpruefung = null } = {}) {
|
||||
if (by !== 'kunde' && by !== 'team') throw new TypeError(`einschaltenZeiten: by muss kunde oder team sein, nicht ${String(by)}`)
|
||||
if (abrechnung !== '' && abrechnung !== 'abo' && abrechnung !== 'projekt') {
|
||||
throw new TypeError(`einschaltenZeiten: abrechnung muss '', 'abo' oder 'projekt' sein, nicht ${String(abrechnung)}`)
|
||||
}
|
||||
const feature = featureConfig(KEY)
|
||||
|
||||
const { doc, changed } = await withLocks([`feature-order:${customerId}:${projectId}`], async () => {
|
||||
// 1 Abo frisch (nie aus einem Zwischenspeicher); fuer das Team entfaellt es
|
||||
if (by === 'kunde') await pruefeAboFuerEinschalten(customerId)
|
||||
if (by === 'kunde') await (vorpruefung ? vorpruefung() : pruefeAboFuerEinschalten(customerId))
|
||||
|
||||
// 2 Zustand: schon eingeschaltet (setup/active) ist idempotent; sonst nur aus off (der Kunde) bzw. off/ordered/disabled (das Team)
|
||||
const bisher = await getFeatureDoc(customerId, projectId, KEY)
|
||||
@@ -84,8 +92,9 @@ export async function einschaltenZeiten({ customerId, projectId, by = 'kunde', s
|
||||
const gespeichert = await updateDocument(config.collections.portalFeatures, vorhanden.$id, {
|
||||
...stateFields('setup'),
|
||||
featureKey: KEY,
|
||||
unlockedBy: gekauft ? 'kauf' : by === 'kunde' ? 'abo' : 'team',
|
||||
unlockedBy: gekauft ? 'kauf' : abrechnung || (by === 'kunde' ? 'abo' : 'team'),
|
||||
unlockedByPurchase: gekauft,
|
||||
...(abrechnung ? { einrichtungAbrechnung: abrechnung } : {}),
|
||||
...(gekauft ? {} : { einbau: '' }),
|
||||
aboEndeAt: null,
|
||||
behaltenSessionId: '',
|
||||
@@ -141,7 +150,9 @@ export async function holeZeitenNach(doc, { now = new Date() } = {}) {
|
||||
const customer = await customerOf(frisch.customerId)
|
||||
if (!frisch.ticketId) {
|
||||
const texte = await ticketTexte({ feature, doc: frisch, project, customer })
|
||||
const { ticketId } = await createFeatureTicket({ customerId: frisch.customerId, project, featureKey: KEY, siteKey: frisch.siteKey, ...texte })
|
||||
// Abo-Modell: die Abrechnung am Dokument (abo | projekt) geht ans Ticket; Dokumente ohne Marker (alte Ansicht) bleiben wie sie waren
|
||||
const abrechnung = Object.hasOwn(ABRECHNUNGS_ZEILEN, frisch.einrichtungAbrechnung) ? { abrechnung: frisch.einrichtungAbrechnung } : {}
|
||||
const { ticketId } = await createFeatureTicket({ customerId: frisch.customerId, project, featureKey: KEY, siteKey: frisch.siteKey, ...texte, ...abrechnung })
|
||||
frisch = await updateDocument(config.collections.portalFeatures, frisch.$id, { ticketId })
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user