106 lines
4.5 KiB
MySQL
106 lines
4.5 KiB
MySQL
|
|
-- Produktkatalog, Bestellungen (mit unveränderlichem Preis-Snapshot) und Verträge
|
||
|
|
CREATE TABLE number_sequences (name VARCHAR(30) PRIMARY KEY, next_value INT NOT NULL);
|
||
|
|
INSERT INTO number_sequences VALUES ('order', 20000), ('contract', 30000);
|
||
|
|
|
||
|
|
CREATE TABLE tax_rates (
|
||
|
|
id CHAR(36) PRIMARY KEY,
|
||
|
|
name VARCHAR(100) NOT NULL,
|
||
|
|
rate_bp INT NOT NULL,
|
||
|
|
active TINYINT(1) NOT NULL DEFAULT 1,
|
||
|
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3)
|
||
|
|
);
|
||
|
|
INSERT INTO tax_rates (id, name, rate_bp) VALUES (UUID(), 'Regelsteuersatz 19 %', 1900), (UUID(), 'Ermäßigter Steuersatz 7 %', 700), (UUID(), 'Steuerfrei 0 %', 0);
|
||
|
|
|
||
|
|
CREATE TABLE products (
|
||
|
|
id CHAR(36) PRIMARY KEY,
|
||
|
|
sku VARCHAR(50) NOT NULL UNIQUE,
|
||
|
|
category ENUM('hosting','license','addon','service') NOT NULL,
|
||
|
|
status ENUM('draft','active','retired') NOT NULL DEFAULT 'draft',
|
||
|
|
connector_instance_id CHAR(36) NULL,
|
||
|
|
orderable_by_customer TINYINT(1) NOT NULL DEFAULT 0,
|
||
|
|
requires_approval TINYINT(1) NOT NULL DEFAULT 1,
|
||
|
|
customer_actions JSON NOT NULL DEFAULT '[]',
|
||
|
|
current_version_id CHAR(36) NULL,
|
||
|
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
|
|
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
|
|
FOREIGN KEY (connector_instance_id) REFERENCES connector_instances(id) ON DELETE SET NULL
|
||
|
|
);
|
||
|
|
-- Versionen sind unveränderlich; jede Preis-/Vertragsänderung erzeugt eine neue Version.
|
||
|
|
CREATE TABLE product_versions (
|
||
|
|
id CHAR(36) PRIMARY KEY,
|
||
|
|
product_id CHAR(36) NOT NULL,
|
||
|
|
version INT NOT NULL,
|
||
|
|
name VARCHAR(200) NOT NULL,
|
||
|
|
description TEXT NULL,
|
||
|
|
tax_rate_id CHAR(36) NOT NULL,
|
||
|
|
tax_bp INT NOT NULL,
|
||
|
|
setup_net_cents INT NOT NULL DEFAULT 0,
|
||
|
|
recurring_net_cents INT NOT NULL DEFAULT 0,
|
||
|
|
currency CHAR(3) NOT NULL DEFAULT 'EUR',
|
||
|
|
billing_interval ENUM('once','monthly','yearly') NOT NULL,
|
||
|
|
term_months INT NOT NULL DEFAULT 0,
|
||
|
|
renewal ENUM('auto','none') NOT NULL DEFAULT 'none',
|
||
|
|
renewal_term_months INT NOT NULL DEFAULT 0,
|
||
|
|
notice_days INT NOT NULL DEFAULT 30,
|
||
|
|
provisioning_json JSON NOT NULL DEFAULT '{}',
|
||
|
|
created_by CHAR(36) NULL,
|
||
|
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
|
|
UNIQUE KEY uq_product_version (product_id, version),
|
||
|
|
FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE,
|
||
|
|
FOREIGN KEY (tax_rate_id) REFERENCES tax_rates(id)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE orders (
|
||
|
|
id CHAR(36) PRIMARY KEY,
|
||
|
|
number VARCHAR(20) NOT NULL UNIQUE,
|
||
|
|
org_id CHAR(36) NOT NULL,
|
||
|
|
status ENUM('pending_approval','approved','provisioning','completed','failed','rejected','cancelled') NOT NULL,
|
||
|
|
placed_by CHAR(36) NULL,
|
||
|
|
placed_via ENUM('customer','staff') NOT NULL,
|
||
|
|
approval_required TINYINT(1) NOT NULL DEFAULT 1,
|
||
|
|
approved_by CHAR(36) NULL,
|
||
|
|
approved_at DATETIME(3) NULL,
|
||
|
|
note VARCHAR(500) NULL,
|
||
|
|
failure_note VARCHAR(500) NULL,
|
||
|
|
failure_ambiguous TINYINT(1) NOT NULL DEFAULT 0,
|
||
|
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
|
|
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
|
|
INDEX (org_id), INDEX (status),
|
||
|
|
FOREIGN KEY (org_id) REFERENCES organizations(id)
|
||
|
|
);
|
||
|
|
CREATE TABLE order_items (
|
||
|
|
id CHAR(36) PRIMARY KEY,
|
||
|
|
order_id CHAR(36) NOT NULL,
|
||
|
|
product_version_id CHAR(36) NOT NULL,
|
||
|
|
quantity INT NOT NULL DEFAULT 1,
|
||
|
|
discount_bp INT NOT NULL DEFAULT 0,
|
||
|
|
snapshot_json JSON NOT NULL,
|
||
|
|
FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE,
|
||
|
|
FOREIGN KEY (product_version_id) REFERENCES product_versions(id)
|
||
|
|
);
|
||
|
|
CREATE TABLE contracts (
|
||
|
|
id CHAR(36) PRIMARY KEY,
|
||
|
|
number VARCHAR(20) NOT NULL UNIQUE,
|
||
|
|
org_id CHAR(36) NOT NULL,
|
||
|
|
order_item_id CHAR(36) NOT NULL UNIQUE,
|
||
|
|
product_version_id CHAR(36) NOT NULL,
|
||
|
|
status ENUM('pending','active','suspended','cancelled','expired','failed') NOT NULL DEFAULT 'pending',
|
||
|
|
started_at DATETIME(3) NULL,
|
||
|
|
term_end DATETIME(3) NULL,
|
||
|
|
renewal ENUM('auto','none') NOT NULL DEFAULT 'none',
|
||
|
|
renewal_term_months INT NOT NULL DEFAULT 0,
|
||
|
|
notice_days INT NOT NULL DEFAULT 30,
|
||
|
|
cancel_requested_at DATETIME(3) NULL,
|
||
|
|
cancel_effective_at DATETIME(3) NULL,
|
||
|
|
cancelled_at DATETIME(3) NULL,
|
||
|
|
resource_id CHAR(36) NULL,
|
||
|
|
price_snapshot_json JSON NOT NULL,
|
||
|
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
|
|
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
|
|
INDEX (org_id), INDEX (status),
|
||
|
|
FOREIGN KEY (org_id) REFERENCES organizations(id),
|
||
|
|
FOREIGN KEY (order_item_id) REFERENCES order_items(id),
|
||
|
|
FOREIGN KEY (product_version_id) REFERENCES product_versions(id),
|
||
|
|
FOREIGN KEY (resource_id) REFERENCES resources(id) ON DELETE SET NULL
|
||
|
|
);
|