1) Gutscheincodes können jetzt im Adminbereich auf "nur einmal pro Person einlösbar" gestellt werden. Wird serverseitig durchgesetzt (neue Spalte orders.gutschein_code + Prüfung in functions/api/orders.js gegen die echte Bestelldatenbank, case-insensitiv nach E-Mail-Adresse) — kann also NICHT durch Löschen von localStorage/einen anderen Browser umgangen werden, anders als die bisherige rein clientseitige Rabattlogik. Stornierte Bestellungen zählen nicht als "schon benutzt". Ausführlich getestet: echter Browser-Checkout mit Einmal-Code funktioniert beim ersten Versuch, wird beim zweiten Versuch (gleiche E-Mail) korrekt mit klarer Fehlermeldung abgelehnt, mit anderer E-Mail weiterhin nutzbar. 2) Bestell-E-Mail-Benachrichtigung an [email protected]: recherchiert und vorbereitet (existierte vorher nirgends im Code). Läuft über Resend (kostenlos bis 3.000 E-Mails/Monat), im Hintergrund per context.waitUntil() nach jeder neuen Bestellung — verzögert nie die Antwort an die Kundschaft und kann eine Bestellung niemals zum Scheitern bringen, selbst wenn der Versand fehlschlägt (mit ungültigem Testschlüssel verifiziert: Bestellung bleibt trotzdem erfolgreich gespeichert). Wird automatisch aktiv, sobald ein RESEND_API_KEY als Secret hinterlegt wird. Co-Authored-By: Claude Sonnet 5 <[email protected]>
43 lines
1.8 KiB
TypeScript
43 lines
1.8 KiB
TypeScript
// Gutscheincodes — site-weit gültig, von VanVan im Adminbereich unter "🎟️ Gutscheincodes"
|
|
// verwaltet. Werden im Warenkorb/Checkout eingelöst und auf den Gesamt-Warenwert angewendet.
|
|
|
|
// @ts-ignore -- JSON-Import, zur Build-Zeit von Astro/Vite aufgelöst
|
|
import gutscheineRaw from "../content/gutscheine.json";
|
|
|
|
export interface Gutschein {
|
|
code: string;
|
|
prozent?: number;
|
|
betrag?: number;
|
|
bis?: string; // ISO-Datum, optional
|
|
/** true = der Code gilt pro Person (genauer: pro E-Mail-Adresse) nur einmal — wird beim
|
|
* Abschicken der Bestellung serverseitig geprüft (siehe functions/api/orders.js, Spalte
|
|
* "gutschein_code" in der orders-Tabelle), kann also NICHT durch Löschen von localStorage/
|
|
* einen anderen Browser umgangen werden. Ohne dieses Flag (Standard) bleibt ein Code
|
|
* unbegrenzt mehrfach nutzbar, wie bisher. */
|
|
einmaligProPerson?: boolean;
|
|
}
|
|
|
|
const gutscheine = (gutscheineRaw as { codes: Gutschein[] }).codes ?? [];
|
|
|
|
function istGueltig(bis?: string): boolean {
|
|
if (!bis) return true;
|
|
return new Date() <= new Date(`${bis}T23:59:59`);
|
|
}
|
|
|
|
/** Sucht einen Gutschein anhand des eingegebenen Codes (Groß-/Kleinschreibung egal). */
|
|
export function findeGutschein(code: string): Gutschein | undefined {
|
|
const normalisiert = code.trim().toUpperCase();
|
|
return gutscheine.find((g) => g.code.toUpperCase() === normalisiert && istGueltig(g.bis));
|
|
}
|
|
|
|
/** Berechnet den Rabatt-Betrag in Euro für einen gegebenen Warenwert. */
|
|
export function gutscheinRabatt(gutschein: Gutschein, warenwert: number): number {
|
|
if (typeof gutschein.prozent === "number" && gutschein.prozent > 0) {
|
|
return Math.min(warenwert, warenwert * (gutschein.prozent / 100));
|
|
}
|
|
if (typeof gutschein.betrag === "number" && gutschein.betrag > 0) {
|
|
return Math.min(warenwert, gutschein.betrag);
|
|
}
|
|
return 0;
|
|
}
|