Sell a set of tickets together for one price (e.g. 5 Adult + 3 Child for R500). Bundles apply automatically, as many times as a registration's tickets allow, and only when cheaper than the prices actually charged. Coupons come off afterwards. - EventBundle/EventBundleItem/RegistrationBundle models and Registration.bundleDiscount - Supervisor "Bundle deals" page, quote endpoint, bundle lines on invoices, receipts, emails, WhatsApp and Yoco checkout, Discounts report rows - Register form shows started bundles with "Complete bundle" and "+" buttons - Demo: Family Fun Day sells a Family deal bundle instead of the Family pass ticket Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
84 lines
3.1 KiB
SQL
84 lines
3.1 KiB
SQL
-- AlterEnum
|
|
ALTER TYPE "AdminAuditAction" ADD VALUE 'bundle_created';
|
|
ALTER TYPE "AdminAuditAction" ADD VALUE 'bundle_updated';
|
|
ALTER TYPE "AdminAuditAction" ADD VALUE 'bundle_deleted';
|
|
|
|
-- AlterTable
|
|
ALTER TABLE "Registration" ADD COLUMN "bundleDiscount" DOUBLE PRECISION NOT NULL DEFAULT 0;
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "EventBundle" (
|
|
"id" TEXT NOT NULL,
|
|
"eventId" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"description" TEXT,
|
|
"price" DOUBLE PRECISION NOT NULL,
|
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
|
"validFrom" TIMESTAMP(3),
|
|
"validUntil" TIMESTAMP(3),
|
|
"order" INTEGER NOT NULL DEFAULT 0,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "EventBundle_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "EventBundleItem" (
|
|
"id" TEXT NOT NULL,
|
|
"bundleId" TEXT NOT NULL,
|
|
"eventOptionId" TEXT NOT NULL,
|
|
"variantId" TEXT,
|
|
"quantity" INTEGER NOT NULL,
|
|
|
|
CONSTRAINT "EventBundleItem_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "RegistrationBundle" (
|
|
"id" TEXT NOT NULL,
|
|
"registrationId" TEXT NOT NULL,
|
|
"bundleId" TEXT NOT NULL,
|
|
"count" INTEGER NOT NULL,
|
|
"discount" DOUBLE PRECISION NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "RegistrationBundle_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "EventBundle_eventId_idx" ON "EventBundle"("eventId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "EventBundleItem_bundleId_idx" ON "EventBundleItem"("bundleId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "EventBundleItem_eventOptionId_idx" ON "EventBundleItem"("eventOptionId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "EventBundleItem_variantId_idx" ON "EventBundleItem"("variantId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "RegistrationBundle_registrationId_idx" ON "RegistrationBundle"("registrationId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "RegistrationBundle_bundleId_idx" ON "RegistrationBundle"("bundleId");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "EventBundle" ADD CONSTRAINT "EventBundle_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "EventBundleItem" ADD CONSTRAINT "EventBundleItem_bundleId_fkey" FOREIGN KEY ("bundleId") REFERENCES "EventBundle"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "EventBundleItem" ADD CONSTRAINT "EventBundleItem_eventOptionId_fkey" FOREIGN KEY ("eventOptionId") REFERENCES "EventOption"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "EventBundleItem" ADD CONSTRAINT "EventBundleItem_variantId_fkey" FOREIGN KEY ("variantId") REFERENCES "OptionVariant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "RegistrationBundle" ADD CONSTRAINT "RegistrationBundle_registrationId_fkey" FOREIGN KEY ("registrationId") REFERENCES "Registration"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "RegistrationBundle" ADD CONSTRAINT "RegistrationBundle_bundleId_fkey" FOREIGN KEY ("bundleId") REFERENCES "EventBundle"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|