Add giftcard management

This commit is contained in:
2026-06-06 14:26:33 +01:00
parent 44c9d423ec
commit 310e6aaa80
10 changed files with 1281 additions and 523 deletions
+38 -1
View File
@@ -14,7 +14,7 @@ CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE TYPE account_role AS ENUM ('unverified_email', 'verified_email', 'admin', 'guest', 'affiliate');
CREATE TYPE account_type AS ENUM ('email', 'google', 'microsoft', 'facebook', 'guest');
CREATE TYPE payment_type AS ENUM ('deposit', 'full', 'tip', 'balance', 'partial');
CREATE TYPE payment_method AS ENUM ('online_square', 'in_person_card', 'cash', 'giftcard', 'discount');
CREATE TYPE payment_method AS ENUM ('online_square', 'in_person_card', 'cash', 'giftcard', 'discount', 'on_the_house');
CREATE TYPE payment_status AS ENUM ('pending', 'completed', 'failed', 'refunded');
CREATE TYPE booking_status AS ENUM ('pending', 'confirmed', 'in_progress', 'completed', 'client_cancelled', 'we_cancelled', 're-schedule', 'no_show', 'no_deposit');
CREATE TYPE campaign_type AS ENUM ('time_based', 'milestone');
@@ -22,6 +22,7 @@ CREATE TYPE milestone_type AS ENUM ('per_user_booking_count', 'global_booking_co
CREATE TYPE milestone_unit AS ENUM ('bookings', 'months', 'years');
CREATE TYPE discount_campaign_scope AS ENUM ('all_bookings', 'first_booking_only', 'new_customers_only');
CREATE TYPE discount_campaign_status AS ENUM ('draft', 'active', 'completed', 'cancelled');
CREATE TYPE till_item_type AS ENUM ('gift_card', 'retail_product');
-- =======================================
-- SHORT ID GENERATION
@@ -63,6 +64,10 @@ CREATE OR REPLACE FUNCTION generate_refund_id() RETURNS CHAR(12) AS $$
SELECT generate_short_id('refunds');
$$ LANGUAGE sql;
CREATE OR REPLACE FUNCTION generate_till_sale_id() RETURNS CHAR(12) AS $$
SELECT generate_short_id('till_sales');
$$ LANGUAGE sql;
CREATE OR REPLACE FUNCTION generate_affiliate_payout_id() RETURNS CHAR(12) AS $$
SELECT generate_short_id('affiliate_payouts');
$$ LANGUAGE sql;
@@ -1517,6 +1522,38 @@ CREATE TABLE refunds (
CREATE INDEX idx_refunds_payment ON refunds(payment_id);
CREATE INDEX idx_refunds_booking ON refunds(booking_id);
-- =======================================
-- TILL SALES TABLE
-- Point-of-sale transactions not linked to a booking (gift card purchases, retail products, etc.)
-- Extensible for future at-the-till products via till_item_type + item_id
-- =======================================
CREATE TABLE till_sales (
id CHAR(12) PRIMARY KEY DEFAULT generate_till_sale_id(),
item_type till_item_type NOT NULL,
item_id CHAR(12), -- FK to gift_cards, future product tables
description TEXT NOT NULL DEFAULT '',
quantity INT NOT NULL DEFAULT 1,
unit_price NUMERIC(10,2) NOT NULL,
total_amount NUMERIC(10,2) NOT NULL,
payment_method payment_method NOT NULL,
status payment_status NOT NULL DEFAULT 'pending',
user_id CHAR(12) REFERENCES users(id) ON DELETE SET NULL, -- customer (nullable for walk-ins)
user_saved_card_id CHAR(12) REFERENCES user_saved_cards(id) ON DELETE SET NULL,
square_payment_id TEXT,
square_checkout_id TEXT,
idempotency_key VARCHAR(64) UNIQUE,
notes TEXT,
created_by CHAR(12) NOT NULL REFERENCES users(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_till_sales_created_at ON till_sales(created_at);
CREATE INDEX idx_till_sales_item_type ON till_sales(item_type);
CREATE INDEX idx_till_sales_user ON till_sales(user_id) WHERE user_id IS NOT NULL;
CREATE INDEX idx_till_sales_square_checkout ON till_sales(square_checkout_id) WHERE square_checkout_id IS NOT NULL;
-- =======================================
-- FINANCIAL AGGREGATES TABLE
-- Monthly aggregated financial statistics (no PII)