Percentage, fixed-amount and comp codes, limited by event, ticket option or variant, dates, use counts, minimum quantity, and people, roles or an email domain. The discount is locked in on the registration (mirrored on Registration.discountTotal so every total sees it), shows on invoices, receipts, emails and the Yoco checkout, and is released on cancellation. Use limits are enforced under an advisory lock. Ticket options and variants can also carry a staff price that Staff and above get automatically. Adds a Supervisor > Coupon codes page, code fields on registration, My Events, manual registration, at the door and the kiosk, a Discounts report, and audit log entries. Also fixes Yoco line items and the free-registration check for lines spanning several price tranches. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
165 lines
5.8 KiB
SQL
165 lines
5.8 KiB
SQL
-- CreateEnum
|
|
CREATE TYPE "CouponType" AS ENUM ('percent', 'fixed', 'comp');
|
|
|
|
-- AlterEnum
|
|
-- This migration adds more than one value to an enum.
|
|
-- With PostgreSQL versions 11 and earlier, this is not possible
|
|
-- in a single migration. This can be worked around by creating
|
|
-- multiple migrations, each migration adding only one value to
|
|
-- the enum.
|
|
|
|
|
|
ALTER TYPE "AdminAuditAction" ADD VALUE 'coupon_created';
|
|
ALTER TYPE "AdminAuditAction" ADD VALUE 'coupon_updated';
|
|
ALTER TYPE "AdminAuditAction" ADD VALUE 'coupon_disabled';
|
|
ALTER TYPE "AdminAuditAction" ADD VALUE 'coupon_applied_manual';
|
|
|
|
-- AlterTable
|
|
ALTER TABLE "EventOption" ADD COLUMN "staffPrice" DOUBLE PRECISION;
|
|
|
|
-- AlterTable
|
|
ALTER TABLE "OptionVariant" ADD COLUMN "staffPrice" DOUBLE PRECISION;
|
|
|
|
-- AlterTable
|
|
ALTER TABLE "Registration" ADD COLUMN "discountTotal" DOUBLE PRECISION NOT NULL DEFAULT 0;
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Coupon" (
|
|
"id" TEXT NOT NULL,
|
|
"code" TEXT NOT NULL,
|
|
"description" TEXT,
|
|
"type" "CouponType" NOT NULL,
|
|
"value" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
|
"stackEarlyBird" BOOLEAN NOT NULL DEFAULT false,
|
|
"validFrom" TIMESTAMP(3),
|
|
"validUntil" TIMESTAMP(3),
|
|
"maxUses" INTEGER,
|
|
"maxUsesPerUser" INTEGER DEFAULT 1,
|
|
"minQuantity" INTEGER,
|
|
"restrictRoles" "UserRole"[],
|
|
"restrictDomain" TEXT,
|
|
"active" BOOLEAN NOT NULL DEFAULT true,
|
|
"createdById" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "Coupon_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "CouponEvent" (
|
|
"id" TEXT NOT NULL,
|
|
"couponId" TEXT NOT NULL,
|
|
"eventId" TEXT NOT NULL,
|
|
|
|
CONSTRAINT "CouponEvent_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "CouponOption" (
|
|
"id" TEXT NOT NULL,
|
|
"couponId" TEXT NOT NULL,
|
|
"eventOptionId" TEXT NOT NULL,
|
|
"variantId" TEXT,
|
|
|
|
CONSTRAINT "CouponOption_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "CouponUser" (
|
|
"id" TEXT NOT NULL,
|
|
"couponId" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
|
|
CONSTRAINT "CouponUser_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "CouponRedemption" (
|
|
"id" TEXT NOT NULL,
|
|
"couponId" TEXT NOT NULL,
|
|
"registrationId" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"discountAmount" DOUBLE PRECISION NOT NULL,
|
|
"appliedById" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"releasedAt" TIMESTAMP(3),
|
|
|
|
CONSTRAINT "CouponRedemption_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "Coupon_code_key" ON "Coupon"("code");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Coupon_createdById_idx" ON "Coupon"("createdById");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "CouponEvent_eventId_idx" ON "CouponEvent"("eventId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "CouponEvent_couponId_eventId_key" ON "CouponEvent"("couponId", "eventId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "CouponOption_couponId_idx" ON "CouponOption"("couponId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "CouponOption_eventOptionId_idx" ON "CouponOption"("eventOptionId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "CouponOption_variantId_idx" ON "CouponOption"("variantId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "CouponUser_userId_idx" ON "CouponUser"("userId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "CouponUser_couponId_userId_key" ON "CouponUser"("couponId", "userId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "CouponRedemption_couponId_releasedAt_idx" ON "CouponRedemption"("couponId", "releasedAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "CouponRedemption_registrationId_idx" ON "CouponRedemption"("registrationId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "CouponRedemption_userId_idx" ON "CouponRedemption"("userId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "CouponRedemption_appliedById_idx" ON "CouponRedemption"("appliedById");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Coupon" ADD CONSTRAINT "Coupon_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CouponEvent" ADD CONSTRAINT "CouponEvent_couponId_fkey" FOREIGN KEY ("couponId") REFERENCES "Coupon"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CouponEvent" ADD CONSTRAINT "CouponEvent_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CouponOption" ADD CONSTRAINT "CouponOption_couponId_fkey" FOREIGN KEY ("couponId") REFERENCES "Coupon"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CouponOption" ADD CONSTRAINT "CouponOption_eventOptionId_fkey" FOREIGN KEY ("eventOptionId") REFERENCES "EventOption"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CouponOption" ADD CONSTRAINT "CouponOption_variantId_fkey" FOREIGN KEY ("variantId") REFERENCES "OptionVariant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CouponUser" ADD CONSTRAINT "CouponUser_couponId_fkey" FOREIGN KEY ("couponId") REFERENCES "Coupon"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CouponUser" ADD CONSTRAINT "CouponUser_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CouponRedemption" ADD CONSTRAINT "CouponRedemption_couponId_fkey" FOREIGN KEY ("couponId") REFERENCES "Coupon"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CouponRedemption" ADD CONSTRAINT "CouponRedemption_registrationId_fkey" FOREIGN KEY ("registrationId") REFERENCES "Registration"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CouponRedemption" ADD CONSTRAINT "CouponRedemption_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "CouponRedemption" ADD CONSTRAINT "CouponRedemption_appliedById_fkey" FOREIGN KEY ("appliedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|