import { Elysia, t } from "elysia"; import prisma from "../lib/prisma"; export const couponsRoute = new Elysia({ prefix: "/coupons" }) // Get all coupons (Admin) .get("/", async () => { return await prisma.coupon.findMany({ orderBy: { createdAt: 'desc' } }); }) // Get active coupons (Storefront) .get("/active", async () => { const now = new Date(); return await prisma.coupon.findMany({ where: { isActive: true, OR: [ { expiresAt: null }, { expiresAt: { gt: now } } ] }, orderBy: { createdAt: 'desc' } }); }) // Create new coupon (Admin) .post("/", async ({ body, set }) => { try { const data = body; // Check if code already exists const existing = await prisma.coupon.findUnique({ where: { code: data.code.toUpperCase() } }); if (existing) { set.status = 400; return { error: "Coupon code already exists" }; } const coupon = await prisma.coupon.create({ data: { code: data.code.toUpperCase(), type: data.type, value: data.value, minPurchase: data.minPurchase || 0, maxDiscount: data.maxDiscount || null, usageLimit: data.usageLimit || null, expiresAt: data.expiresAt ? new Date(data.expiresAt) : null, isActive: data.isActive !== undefined ? data.isActive : true } }); return coupon; } catch (err) { console.error("[Coupons] Create Error:", err); set.status = 500; return { error: "Failed to create coupon" }; } }, { body: t.Object({ code: t.String(), type: t.String(), value: t.Number(), minPurchase: t.Optional(t.Number()), maxDiscount: t.Optional(t.Nullable(t.Number())), usageLimit: t.Optional(t.Nullable(t.Number())), expiresAt: t.Optional(t.Nullable(t.String())), isActive: t.Optional(t.Boolean()) }) }) // Update coupon (Admin) .patch("/:id", async ({ params: { id }, body, set }) => { try { const data = body; const coupon = await prisma.coupon.update({ where: { id: Number(id) }, data: { ...(data.code && { code: data.code.toUpperCase() }), ...(data.type && { type: data.type }), ...(data.value !== undefined && { value: data.value }), ...(data.minPurchase !== undefined && { minPurchase: data.minPurchase }), ...(data.maxDiscount !== undefined && { maxDiscount: data.maxDiscount }), ...(data.usageLimit !== undefined && { usageLimit: data.usageLimit }), ...(data.expiresAt !== undefined && { expiresAt: data.expiresAt ? new Date(data.expiresAt) : null }), ...(data.isActive !== undefined && { isActive: data.isActive }) } }); return coupon; } catch (err) { console.error("[Coupons] Update Error:", err); set.status = 500; return { error: "Failed to update coupon" }; } }, { body: t.Object({ code: t.Optional(t.String()), type: t.Optional(t.String()), value: t.Optional(t.Number()), minPurchase: t.Optional(t.Number()), maxDiscount: t.Optional(t.Nullable(t.Number())), usageLimit: t.Optional(t.Nullable(t.Number())), expiresAt: t.Optional(t.Nullable(t.String())), isActive: t.Optional(t.Boolean()) }) }) // Delete coupon (Admin) .delete("/:id", async ({ params: { id }, set }) => { try { await prisma.coupon.delete({ where: { id: Number(id) } }); return { success: true }; } catch (err) { set.status = 500; return { error: "Failed to delete coupon" }; } }) // Validate coupon (Storefront) .post("/validate", async ({ body, set }) => { try { const { code, cartTotal } = body; const upperCode = code.toUpperCase(); const coupon = await prisma.coupon.findUnique({ where: { code: upperCode } }); if (!coupon) { set.status = 404; return { valid: false, error: "Coupon not found" }; } if (!coupon.isActive) { set.status = 400; return { valid: false, error: "Coupon is no longer active" }; } if (coupon.expiresAt && new Date() > coupon.expiresAt) { set.status = 400; return { valid: false, error: "Coupon has expired" }; } if (coupon.usageLimit && coupon.usedCount >= coupon.usageLimit) { set.status = 400; return { valid: false, error: "Coupon usage limit reached" }; } if (cartTotal < coupon.minPurchase) { set.status = 400; return { valid: false, error: `Minimum purchase of ฿${coupon.minPurchase} required` }; } // Calculate discount amount let discountAmount = 0; if (coupon.type === "PERCENTAGE") { discountAmount = cartTotal * (coupon.value / 100); if (coupon.maxDiscount && discountAmount > coupon.maxDiscount) { discountAmount = coupon.maxDiscount; } } else if (coupon.type === "FIXED_AMOUNT") { discountAmount = coupon.value; } else if (coupon.type === "FREE_SHIPPING") { // We handle free shipping separately, returning discountAmount = 0 but a flag return { valid: true, coupon, discountAmount: 0, isFreeShipping: true }; } // Ensure discount doesn't exceed cart total if (discountAmount > cartTotal) { discountAmount = cartTotal; } return { valid: true, coupon, discountAmount, isFreeShipping: false }; } catch (err) { console.error("[Coupons] Validate Error:", err); set.status = 500; return { error: "Failed to validate coupon" }; } }, { body: t.Object({ code: t.String(), cartTotal: t.Number() }) }); //# sourceMappingURL=coupons.js.map