-- Webshop Module - Initial Migration -- Opret basis tabeller for webshop konfiguration og administration -- Webshop konfigurationer (én per kunde/domæne) CREATE TABLE IF NOT EXISTS webshop_configs ( id SERIAL PRIMARY KEY, customer_id INTEGER REFERENCES customers(id) ON DELETE CASCADE, name VARCHAR(255) NOT NULL, -- Webshop navn (fx "Advokatfirmaet A/S Webshop") -- Email domæner der må logge ind (komma-separeret, fx "firma.dk,firma.com") allowed_email_domains TEXT NOT NULL, -- Branding logo_filename VARCHAR(255), -- Filnavn i uploads/webshop_logos/ header_text TEXT, intro_text TEXT, primary_color VARCHAR(7) DEFAULT '#0f4c75', -- Hex color accent_color VARCHAR(7) DEFAULT '#3282b8', -- Pricing regler default_margin_percent DECIMAL(5, 2) DEFAULT 10.00, -- Standard avance % min_order_amount DECIMAL(10, 2) DEFAULT 0.00, shipping_cost DECIMAL(10, 2) DEFAULT 0.00, -- Status og versioning enabled BOOLEAN DEFAULT TRUE, config_version TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Timestamp for seneste ændring last_published_at TIMESTAMP, -- Hvornår blev config sendt til Gateway last_published_version TIMESTAMP, -- Hvilken version blev sendt created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(customer_id) -- Én webshop per kunde ); -- Tilladte produkter per webshop (whitelist) CREATE TABLE IF NOT EXISTS webshop_products ( id SERIAL PRIMARY KEY, webshop_config_id INTEGER REFERENCES webshop_configs(id) ON DELETE CASCADE, -- Produkt identifikation (fra e-conomic) product_number VARCHAR(100) NOT NULL, ean VARCHAR(50), -- Produkt info (synced fra e-conomic) name VARCHAR(255) NOT NULL, description TEXT, unit VARCHAR(50) DEFAULT 'stk', base_price DECIMAL(10, 2), -- Pris fra e-conomic category VARCHAR(100), -- Webshop-specifik konfiguration custom_margin_percent DECIMAL(5, 2), -- Override standard avance for dette produkt visible BOOLEAN DEFAULT TRUE, sort_order INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(webshop_config_id, product_number) ); -- Ordre importeret fra Gateway (når Hub poller Gateway) CREATE TABLE IF NOT EXISTS webshop_orders ( id SERIAL PRIMARY KEY, webshop_config_id INTEGER REFERENCES webshop_configs(id) ON DELETE SET NULL, customer_id INTEGER REFERENCES customers(id) ON DELETE SET NULL, -- Order data fra Gateway gateway_order_id VARCHAR(100) NOT NULL UNIQUE, -- ORD-2026-00123 order_email VARCHAR(255), -- Hvem bestilte total_amount DECIMAL(10, 2), status VARCHAR(50), -- pending, processing, completed, cancelled -- Shipping info shipping_company_name VARCHAR(255), shipping_street TEXT, shipping_postal_code VARCHAR(20), shipping_city VARCHAR(100), shipping_country VARCHAR(2) DEFAULT 'DK', delivery_note TEXT, -- Payload fra Gateway (JSON) gateway_payload JSONB, -- Komplet order data fra Gateway -- Import tracking imported_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, processed_in_economic BOOLEAN DEFAULT FALSE, economic_order_number INTEGER, -- e-conomic ordre nummer når oprettet created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Ordre linjer (items på ordre) CREATE TABLE IF NOT EXISTS webshop_order_items ( id SERIAL PRIMARY KEY, webshop_order_id INTEGER REFERENCES webshop_orders(id) ON DELETE CASCADE, product_number VARCHAR(100), product_name VARCHAR(255), quantity INTEGER NOT NULL, unit_price DECIMAL(10, 2), total_price DECIMAL(10, 2), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Indexes for performance CREATE INDEX IF NOT EXISTS idx_webshop_configs_customer ON webshop_configs(customer_id); CREATE INDEX IF NOT EXISTS idx_webshop_configs_enabled ON webshop_configs(enabled); CREATE INDEX IF NOT EXISTS idx_webshop_products_config ON webshop_products(webshop_config_id); CREATE INDEX IF NOT EXISTS idx_webshop_products_visible ON webshop_products(visible); CREATE INDEX IF NOT EXISTS idx_webshop_orders_gateway_id ON webshop_orders(gateway_order_id); CREATE INDEX IF NOT EXISTS idx_webshop_orders_customer ON webshop_orders(customer_id); CREATE INDEX IF NOT EXISTS idx_webshop_orders_status ON webshop_orders(status); CREATE INDEX IF NOT EXISTS idx_webshop_order_items_order ON webshop_order_items(webshop_order_id); -- Trigger for updated_at på configs CREATE OR REPLACE FUNCTION update_webshop_configs_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; NEW.config_version = CURRENT_TIMESTAMP; -- Bump version ved hver ændring RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trigger_webshop_configs_updated_at BEFORE UPDATE ON webshop_configs FOR EACH ROW EXECUTE FUNCTION update_webshop_configs_updated_at(); -- Trigger for updated_at på products CREATE OR REPLACE FUNCTION update_webshop_products_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trigger_webshop_products_updated_at BEFORE UPDATE ON webshop_products FOR EACH ROW EXECUTE FUNCTION update_webshop_products_updated_at(); -- Trigger for updated_at på orders CREATE OR REPLACE FUNCTION update_webshop_orders_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trigger_webshop_orders_updated_at BEFORE UPDATE ON webshop_orders FOR EACH ROW EXECUTE FUNCTION update_webshop_orders_updated_at();