Files
Wabenhain/src/lib/shipping-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

51 lines
2.1 KiB
TypeScript

export interface ShippingTierLike {
minQuantity: number;
maxQuantity: number | null;
priceCents: number;
}
// Greift nur, wenn im Admin-Bereich (noch) keine Staffeln gepflegt sind —
// verhindert einen kaputten Checkout statt einer korrekten Preisauskunft.
export const FALLBACK_SHIPPING_CENTS = 490;
/**
* Reine Zuordnungsfunktion ohne Datenbankzugriff — bewusst getrennt von
* shipping.ts, damit sowohl der serverseitige Checkout (lib/shipping.ts) als
* auch die client-seitige Warenkorb-Live-Vorschau (warenkorb-content.tsx)
* exakt dieselbe Staffel-Logik verwenden, ohne Prisma ins Client-Bundle zu
* ziehen.
*/
export function resolveShippingCostCents(tiers: ShippingTierLike[], totalQuantity: number): number {
if (totalQuantity <= 0) return 0;
if (tiers.length === 0) return FALLBACK_SHIPPING_CENTS;
const sorted = [...tiers].sort((a, b) => a.minQuantity - b.minQuantity);
const matching = sorted.find(
(tier) => totalQuantity >= tier.minQuantity && (tier.maxQuantity === null || totalQuantity <= tier.maxQuantity)
);
// Menge liegt oberhalb aller gepflegten Staffeln (z.B. nur bis 19 Stueck
// definiert) — die teuerste/oberste Staffel greift, statt die Bestellung
// mangels passendem Tarif abzulehnen.
return matching ? matching.priceCents : sorted[sorted.length - 1].priceCents;
}
/**
* Naechste (teurere) Staffel oberhalb der aktuellen Menge — fuer eine ehrliche
* Transparenz-Anzeige im Warenkorb ("noch X Stueck bis zur naechsten Stufe").
* Anders als ein "kostenloser Versand ab X"-Hinweis wird hier bewusst NICHT
* suggeriert, dass mehr kaufen guenstiger wird — die Staffeln steigen mit der
* Menge, siehe FALLBACK_SHIPPING_CENTS-Kommentar oben.
*/
export function getNextShippingTier(
tiers: ShippingTierLike[],
totalQuantity: number
): { unitsUntilNext: number; priceCents: number } | null {
if (tiers.length === 0 || totalQuantity <= 0) return null;
const sorted = [...tiers].sort((a, b) => a.minQuantity - b.minQuantity);
const next = sorted.find((tier) => tier.minQuantity > totalQuantity);
if (!next) return null;
return { unitsUntilNext: next.minQuantity - totalQuantity, priceCents: next.priceCents };
}