product variant route

This commit is contained in:
efrilm
2026-04-16 14:30:48 +07:00
parent f25ec1c06f
commit 535e4c84f6
4 changed files with 143 additions and 3 deletions
@@ -0,0 +1,39 @@
-- =========================
-- DROP ORDER DISCOUNTS
-- =========================
DROP INDEX IF EXISTS idx_order_discounts_discount;
DROP INDEX IF EXISTS idx_order_discounts_outlet;
DROP INDEX IF EXISTS idx_order_discounts_order;
DROP TABLE IF EXISTS order_discounts;
-- =========================
-- DROP DISCOUNT CATEGORIES
-- =========================
DROP INDEX IF EXISTS idx_discount_categories_category;
DROP INDEX IF EXISTS idx_discount_categories_discount;
DROP TABLE IF EXISTS discount_categories;
-- =========================
-- DROP DISCOUNT PRODUCTS
-- =========================
DROP INDEX IF EXISTS idx_discount_products_product;
DROP INDEX IF EXISTS idx_discount_products_discount;
DROP TABLE IF EXISTS discount_products;
-- =========================
-- DROP DISCOUNT OUTLETS
-- =========================
DROP INDEX IF EXISTS idx_discount_outlets_outlet;
DROP INDEX IF EXISTS idx_discount_outlets_discount;
DROP TABLE IF EXISTS discount_outlets;
-- =========================
-- DROP DISCOUNTS
-- =========================
DROP INDEX IF EXISTS idx_discounts_customer_type;
DROP INDEX IF EXISTS idx_discounts_dates;
DROP INDEX IF EXISTS idx_discounts_active;
DROP INDEX IF EXISTS idx_discounts_code;
DROP INDEX IF EXISTS idx_discounts_organization;
DROP INDEX IF EXISTS idx_discounts_campaign;
DROP TABLE IF EXISTS discounts;
@@ -0,0 +1,91 @@
CREATE TABLE discounts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
campaign_id UUID NULL,
organization_id UUID NOT NULL,
code VARCHAR(50) NOT NULL,
name VARCHAR(255) NOT NULL,
type VARCHAR(20) NOT NULL CHECK (type IN ('percentage', 'fixed_amount', 'free_product')),
value DECIMAL(15,2) NOT NULL,
min_purchase_qty INT DEFAULT 0,
min_purchase_amount DECIMAL(15,2) DEFAULT 0,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
usage_limit_per_customer INT DEFAULT NULL,
usage_limit_total INT DEFAULT NULL,
usage_count INT DEFAULT 0,
customer_type VARCHAR(20) DEFAULT 'all' CHECK (customer_type IN ('all', 'member', 'vip')),
is_stackable BOOLEAN DEFAULT FALSE,
is_active BOOLEAN DEFAULT TRUE,
priority INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (campaign_id) REFERENCES campaigns(id) ON DELETE SET NULL,
FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE,
CONSTRAINT chk_discount_ownership CHECK (campaign_id IS NOT NULL OR organization_id IS NOT NULL),
CONSTRAINT unique_code_per_org UNIQUE (organization_id, code)
);
CREATE INDEX idx_discounts_campaign ON discounts(campaign_id);
CREATE INDEX idx_discounts_organization ON discounts(organization_id);
CREATE INDEX idx_discounts_code ON discounts(code);
CREATE INDEX idx_discounts_active ON discounts(is_active);
CREATE INDEX idx_discounts_dates ON discounts(start_date, end_date);
CREATE INDEX idx_discounts_customer_type ON discounts(customer_type);
CREATE TABLE discount_outlets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
discount_id UUID NOT NULL,
outlet_id UUID NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (discount_id) REFERENCES discounts(id) ON DELETE CASCADE,
FOREIGN KEY (outlet_id) REFERENCES outlets(id) ON DELETE CASCADE,
CONSTRAINT unique_discount_outlet UNIQUE (discount_id, outlet_id)
);
CREATE INDEX idx_discount_outlets_discount ON discount_outlets(discount_id);
CREATE INDEX idx_discount_outlets_outlet ON discount_outlets(outlet_id);
CREATE TABLE discount_products (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
discount_id UUID NOT NULL,
product_id UUID NOT NULL,
rule_type VARCHAR(20) NOT NULL CHECK (rule_type IN ('required', 'free', 'excluded')),
quantity INT DEFAULT 1,
free_quantity INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (discount_id) REFERENCES discounts(id) ON DELETE CASCADE,
FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE
);
CREATE INDEX idx_discount_products_discount ON discount_products(discount_id);
CREATE INDEX idx_discount_products_product ON discount_products(product_id);
CREATE TABLE discount_categories (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
discount_id UUID NOT NULL,
category_id UUID NOT NULL,
rule_type VARCHAR(20) NOT NULL CHECK (rule_type IN ('included', 'excluded')),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (discount_id) REFERENCES discounts(id) ON DELETE CASCADE,
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
);
CREATE INDEX idx_discount_categories_discount ON discount_categories(discount_id);
CREATE INDEX idx_discount_categories_category ON discount_categories(category_id);
CREATE TABLE order_discounts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
order_id UUID NOT NULL,
outlet_id UUID NOT NULL,
discount_id UUID NOT NULL,
discount_amount DECIMAL(15,2) NOT NULL,
applied_rules JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE,
FOREIGN KEY (outlet_id) REFERENCES outlets(id) ON DELETE RESTRICT,
FOREIGN KEY (discount_id) REFERENCES discounts(id) ON DELETE RESTRICT
);
CREATE INDEX idx_order_discounts_order ON order_discounts(order_id);
CREATE INDEX idx_order_discounts_outlet ON order_discounts(outlet_id);
CREATE INDEX idx_order_discounts_discount ON order_discounts(discount_id);