bmc_hub/migrations/104_sag_subscriptions.sql
Christian 6320809f17 feat: Add subscriptions and products management
- Implemented frontend views for products and subscriptions using FastAPI and Jinja2 templates.
- Created API endpoints for managing subscriptions, including creation, listing, and status updates.
- Added HTML templates for displaying active subscriptions and their statistics.
- Established database migrations for sag_subscriptions, sag_subscription_items, and products, including necessary indexes and triggers for automatic subscription number generation.
- Introduced product price history tracking to monitor changes in product pricing.
2026-02-08 12:42:19 +01:00

62 lines
2.2 KiB
PL/PgSQL

-- Migration 104: Sag Subscriptions
-- Sag-based subscriptions (module on cases)
CREATE TABLE IF NOT EXISTS sag_subscriptions (
id SERIAL PRIMARY KEY,
subscription_number VARCHAR(50) UNIQUE NOT NULL,
-- Ownership
sag_id INTEGER NOT NULL REFERENCES sag_sager(id) ON DELETE CASCADE,
customer_id INTEGER NOT NULL REFERENCES customers(id) ON DELETE RESTRICT,
-- Product and billing
product_name VARCHAR(255),
billing_interval VARCHAR(20) NOT NULL DEFAULT 'monthly' CHECK (billing_interval IN ('monthly', 'quarterly', 'yearly')),
billing_day INTEGER NOT NULL DEFAULT 1 CHECK (billing_day BETWEEN 1 AND 31),
price DECIMAL(10,2) NOT NULL CHECK (price >= 0),
-- Lifecycle
start_date DATE NOT NULL,
end_date DATE,
status VARCHAR(20) NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'active', 'paused', 'cancelled')),
-- Metadata
notes TEXT,
created_by_user_id INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_sag_subscriptions_customer ON sag_subscriptions(customer_id);
CREATE INDEX IF NOT EXISTS idx_sag_subscriptions_sag ON sag_subscriptions(sag_id);
CREATE INDEX IF NOT EXISTS idx_sag_subscriptions_status ON sag_subscriptions(status);
CREATE INDEX IF NOT EXISTS idx_sag_subscriptions_dates ON sag_subscriptions(start_date, end_date);
-- Auto-generate subscription_number (SUB-YYYYMMDD-XXX)
CREATE OR REPLACE FUNCTION generate_sag_subscription_number()
RETURNS TRIGGER AS $$
DECLARE
new_number VARCHAR(50);
day_count INTEGER;
BEGIN
SELECT COUNT(*) INTO day_count
FROM sag_subscriptions
WHERE DATE(created_at) = CURRENT_DATE;
new_number := 'SUB-' || TO_CHAR(CURRENT_DATE, 'YYYYMMDD') || '-' || LPAD((day_count + 1)::TEXT, 3, '0');
NEW.subscription_number := new_number;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_generate_sag_subscription_number
BEFORE INSERT ON sag_subscriptions
FOR EACH ROW
EXECUTE FUNCTION generate_sag_subscription_number();
CREATE TRIGGER trigger_sag_subscriptions_updated_at
BEFORE UPDATE ON sag_subscriptions
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();