Öffnungszeiten: Mails K24–K27 heißen jetzt K27–K30, Feld k24At heißt einschaltMailAt

K24–K26 sind seit dem Webshop-Livegang (main) vergeben; der Mail-Lader sucht die Vorlage über den
Dateianfang, doppelte Nummern hätten die falsche Mail geschickt. Das Feld ist noch nicht in der
Produktion angelegt (zeiten-setup.mjs lief noch nicht), daher jetzt ein sprechender Name.
Spec und Plan behalten die alten Nummern (Hinweis oben im Dokument).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-06 06:00:17 +00:00
1 parent ea4457e6a4
commit c7cd436ec2
34 files changed
+359 -354

No files matched your search

+20 -20
View File
@@ -3,11 +3,11 @@ import { sendCustomerMail } from '../mailer.js'
import { datumKurz, wochentag } from '../termine/zeit.js'
/**
* Mails von Öffnungszeiten live an Kunden (Vorlagen server/mail-templates/K24 bis K27):
* K24 eingeschaltet (Gratisweg im Wartungs-Abo; mit Block `wieder` nach der Rückkehr des Abos)
* K25 Feiertags-Erinnerung (eine Mail mit allen neuen Tagen, ohne BCC)
* K26 Wartungs-Abo beendet: Funktion läuft bis zur Frist, „für einmalig 30 € behalten“ (Varianten nach der Abo-Lage)
* K27 abgeschaltet: feste Zeiten auf der Seite, Eingaben noch bis zum Löschdatum
* Mails von Öffnungszeiten live an Kunden (Vorlagen server/mail-templates/K27 bis K30):
* K27 eingeschaltet (Gratisweg im Wartungs-Abo; mit Block `wieder` nach der Rückkehr des Abos)
* K28 Feiertags-Erinnerung (eine Mail mit allen neuen Tagen, ohne BCC)
* K29 Wartungs-Abo beendet: Funktion läuft bis zur Frist, „für einmalig 30 € behalten“ (Varianten nach der Abo-Lage)
* K30 abgeschaltet: feste Zeiten auf der Seite, Eingaben noch bis zum Löschdatum
* Die Builder sind rein (kein Zugriff auf Appwrite, kein Versand) und liefern { template, values, blocks }, so wie
* siteFeatures.bestellMail: die Werte decken genau die Platzhalter der Vorlage ab. sendeZeitenMail verschickt sie.
*
@@ -35,7 +35,7 @@ function datum(wert, feld) {
}
/**
* K24: Öffnungszeiten live ist eingeschaltet.
* K27: Öffnungszeiten live ist eingeschaltet.
* @param {{ kunde: string | { name?: string }, projekt: string, einbau?: string | null, wieder?: boolean, ticketNr?: string | number | null }} p
* einbau: 'angestossen' (Neubau läuft: Leisten erscheinen nach dem nächsten Veröffentlichen) oder 'manuell' (das Team baut ein);
* alles andere, auch ein fehlender Wert, sagt das Vorsichtige: das Team baut ein.
@@ -44,13 +44,13 @@ function datum(wert, feld) {
* wieder: das Wartungs-Abo läuft wieder und die Funktion wurde automatisch wieder eingeschaltet.
* ticketNr: Nummer des Einbau-Tickets; ohne sie steht kein Ticket in der Mail.
*/
export function k24Mail({ kunde, projekt, einbau, wieder = false, ticketNr = null }) {
export function k27Mail({ kunde, projekt, einbau, wieder = false, ticketNr = null }) {
const nr = String(ticketNr ?? '').trim().replace(/^#/, '')
const keinNeubau = wieder === true && einbau === null
const angestossen = einbau === 'angestossen'
const manuell = !keinNeubau && !angestossen
return {
template: 'K24',
template: 'K27',
values: {
kunde_name: kundenName(kunde),
projekt,
@@ -73,14 +73,14 @@ function tagesZeile(eintrag) {
}
/**
* K25: Feiertage stehen an (eine Mail für alle neuen Tage; Aufrufer: Erinnerungs-Job, ohne BCC ans Team).
* K28: Feiertage stehen an (eine Mail für alle neuen Tage; Aufrufer: Erinnerungs-Job, ohne BCC ans Team).
* @param {{ kunde: string | { name?: string }, projekt: string, tage: Array<{ tag: string, name?: string, art?: 'feiertag' | 'pruefen' }> }} p
* tage: [{ tag: 'YYYY-MM-DD', name, art }] wie zeitlogik.erinnerungsTage(); Blöcke: pruefen (mindestens ein „bitte prüfen“-Tag), mehrere (> 1 Tag).
*/
export function k25Mail({ kunde, projekt, tage }) {
export function k28Mail({ kunde, projekt, tage }) {
const liste = Array.isArray(tage) ? tage : []
return {
template: 'K25',
template: 'K28',
values: {
kunde_name: kundenName(kunde),
projekt,
@@ -92,27 +92,27 @@ export function k25Mail({ kunde, projekt, tage }) {
}
/**
* K26: Das Wartungs-Abo ist beendet, die Funktion läuft noch bis zur Frist; für einmalig `preis` behalten.
* K29: Das Wartungs-Abo ist beendet, die Funktion läuft noch bis zur Frist; für einmalig `preis` behalten.
* @param {{ kunde: string | { name?: string }, projekt: string, art?: string, frist: Date, preis: string }} p
* art: Abo-Lage aus aboStatus.aboLage(): 'hosting' (das Abo ist ein Hosting-Abo), 'wechsel_widerrufen' (Wechsel ins Wartungs-Abo
* widerrufen), sonst (auch 'beendet' und Unbekanntes) 'abo_ende'. frist: Tag des Abschaltens (aboEndeAt + 30 Tage).
*/
export function k26Mail({ kunde, projekt, art, frist, preis }) {
export function k29Mail({ kunde, projekt, art, frist, preis }) {
return {
template: 'K26',
template: 'K29',
values: { kunde_name: kundenName(kunde), projekt, frist: datum(frist, 'frist'), preis, portal_url: portalUrl() },
blocks: { abo_ende: art !== 'hosting' && art !== 'wechsel_widerrufen', hosting: art === 'hosting', wechsel_widerrufen: art === 'wechsel_widerrufen' },
}
}
/**
* K27: Öffnungszeiten live ist abgeschaltet (Wartungs-Abo beendet, Frist zum Behalten abgelaufen).
* K30: Öffnungszeiten live ist abgeschaltet (Wartungs-Abo beendet, Frist zum Behalten abgelaufen).
* @param {{ kunde: string | { name?: string }, projekt: string, loeschdatum: Date, preis: string }} p
* loeschdatum: Tag, ab dem die Eingaben gelöscht werden (30 Tage nach dem Abschalten); preis: Preis zum Wiedereinschalten.
*/
export function k27Mail({ kunde, projekt, loeschdatum, preis }) {
export function k30Mail({ kunde, projekt, loeschdatum, preis }) {
return {
template: 'K27',
template: 'K30',
values: { kunde_name: kundenName(kunde), projekt, loeschdatum: datum(loeschdatum, 'loeschdatum'), preis, portal_url: portalUrl() },
}
}
@@ -129,10 +129,10 @@ function fehlerText(err, customer) {
}
/**
* Eine der Mails K24 bis K27 an die E-Mail-Adresse des Kundenkontos senden. Wirft nie; das Log nennt weder Adresse noch Namen.
* Eine der Mails K27 bis K30 an die E-Mail-Adresse des Kundenkontos senden. Wirft nie; das Log nennt weder Adresse noch Namen.
* @param {{ email?: string, name?: string } | null | undefined} customer Kundendokument
* @param {{ template: string, values?: object, blocks?: object }} nachricht Ergebnis von k24Mail ... k27Mail
* @param {{ bccTeam?: boolean }} [options] bccTeam false: keine Kopie ans Team (K25)
* @param {{ template: string, values?: object, blocks?: object }} nachricht Ergebnis von k27Mail ... k30Mail
* @param {{ bccTeam?: boolean }} [options] bccTeam false: keine Kopie ans Team (K28)
* @returns {Promise<{ sent: boolean, reason?: 'keine_adresse' | 'fehler' }>}
*/
export async function sendeZeitenMail(customer, nachricht, { bccTeam = true } = {}) {