Files
Wabenhain/src/lib/discount-calc.ts
T
Nick Szaunig c7927f2883 feat: Wabenhain Honig-Shop Anwendung
Vollstaendige Next.js/Prisma-E-Commerce-Anwendung fuer eine Imkerei:
Shop, Warenkorb, Stripe-Checkout, Kundenkonto mit 2FA, Admin-Bereich
(Produkte, Ernten, Chargen, Bestellungen, Gutscheine, admin-editierbare
Website-Inhalte), i18n (DE/EN), Rate-Limiting/CSP/Audit-Log-Haertung,
PostgreSQL- und MySQL-Unterstuetzung ueber austauschbare Prisma-
Treiber-Adapter, Unit-/Komponenten-/E2E-Tests.
2026-08-17 14:30:28 +02:00

41 lines
1.5 KiB
TypeScript

export interface DiscountCodeLike {
isActive: boolean;
type: "PERCENT" | "FIXED";
value: number;
minOrderCents: number;
minQuantity: number | null;
maxUses: number | null;
usedCount: number;
validFrom: Date | null;
validUntil: Date | null;
}
/**
* Reine Pruef-/Berechnungsfunktionen ohne Datenbankzugriff — bewusst getrennt
* von der Checkout-Route (analog zu shipping-calc.ts), damit die Geldlogik
* isoliert testbar ist. totalQuantity ist optional (Default: praktisch immer
* erfuellt) — nur Codes mit gesetztem minQuantity (Mengenrabatte) pruefen ihn
* ueberhaupt, normale Gutscheine sind davon unberuehrt.
*/
export function isDiscountCodeValid(
code: DiscountCodeLike | null,
subtotalCents: number,
now: Date,
totalQuantity: number = Infinity
): boolean {
if (!code) return false;
return (
code.isActive &&
(!code.validFrom || code.validFrom <= now) &&
(!code.validUntil || code.validUntil >= now) &&
(code.maxUses === null || code.usedCount < code.maxUses) &&
subtotalCents >= code.minOrderCents &&
(code.minQuantity === null || totalQuantity >= code.minQuantity)
);
}
/** Rabatt gilt nur auf den Warenwert, nie auf den Versand, und kappt bei FIXED an der Zwischensumme (kein negativer Betrag). */
export function calculateDiscountCents(code: Pick<DiscountCodeLike, "type" | "value">, subtotalCents: number): number {
return code.type === "PERCENT" ? Math.round((subtotalCents * code.value) / 100) : Math.min(code.value, subtotalCents);
}