bmc_hub/migrations/192_also_cloud_billing_foundation.sql

109 lines
4.2 KiB
MySQL
Raw Normal View History

-- ALSO Cloud Billing foundation
-- Import jobs, import lines queue, and mapping tables
CREATE TABLE IF NOT EXISTS also_import_jobs (
id SERIAL PRIMARY KEY,
source_type VARCHAR(32) NOT NULL CHECK (source_type IN ('api', 'xml', 'json_export', 'xml_export', 'csv')),
source_label VARCHAR(255),
status VARCHAR(32) NOT NULL DEFAULT 'new',
file_name VARCHAR(512),
import_version VARCHAR(128),
imported_by_user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL,
imported_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
started_at TIMESTAMP,
finished_at TIMESTAMP,
raw_payload_json JSONB NOT NULL DEFAULT '{}'::jsonb,
log_json JSONB NOT NULL DEFAULT '[]'::jsonb,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_also_import_jobs_status ON also_import_jobs(status);
CREATE INDEX IF NOT EXISTS idx_also_import_jobs_imported_at ON also_import_jobs(imported_at DESC);
CREATE TABLE IF NOT EXISTS also_import_lines (
id BIGSERIAL PRIMARY KEY,
import_job_id INTEGER NOT NULL REFERENCES also_import_jobs(id) ON DELETE CASCADE,
line_no INTEGER,
queue_status VARCHAR(32) NOT NULL DEFAULT 'new' CHECK (queue_status IN (
'new',
'matching_products',
'matching_customers',
'ready_for_approval',
'approved',
'invoiced',
'error'
)),
source_line_ref VARCHAR(255),
line_hash VARCHAR(128) NOT NULL,
also_company_id VARCHAR(128),
company VARCHAR(255),
customer_id VARCHAR(128),
account_id VARCHAR(128),
vat VARCHAR(64),
material_number VARCHAR(128),
product_name VARCHAR(512),
vendor VARCHAR(255),
cost_amount NUMERIC(14, 4),
sales_price NUMERIC(14, 4),
unit_price NUMERIC(14, 4),
total_price NUMERIC(14, 4),
currency VARCHAR(16),
billing_start DATE,
charge_interval VARCHAR(64),
billing_interval VARCHAR(64),
billable_parameters NUMERIC(14, 4),
matched_customer_id INTEGER REFERENCES customers(id) ON DELETE SET NULL,
matched_product_id INTEGER REFERENCES products(id) ON DELETE SET NULL,
validation_errors_json JSONB NOT NULL DEFAULT '[]'::jsonb,
raw_line_json JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT uniq_also_import_line_hash UNIQUE (import_job_id, line_hash)
);
CREATE INDEX IF NOT EXISTS idx_also_import_lines_job ON also_import_lines(import_job_id);
CREATE INDEX IF NOT EXISTS idx_also_import_lines_status ON also_import_lines(queue_status);
CREATE INDEX IF NOT EXISTS idx_also_import_lines_material_vendor ON also_import_lines(material_number, vendor);
CREATE INDEX IF NOT EXISTS idx_also_import_lines_customer_keys ON also_import_lines(also_company_id, customer_id, vat);
CREATE INDEX IF NOT EXISTS idx_also_import_lines_unmatched_customer ON also_import_lines(matched_customer_id) WHERE matched_customer_id IS NULL;
CREATE INDEX IF NOT EXISTS idx_also_import_lines_unmatched_product ON also_import_lines(matched_product_id) WHERE matched_product_id IS NULL;
CREATE TABLE IF NOT EXISTS also_company_mapping (
id SERIAL PRIMARY KEY,
also_company_id VARCHAR(128) NOT NULL UNIQUE,
also_customer_id VARCHAR(128),
customer_id INTEGER NOT NULL REFERENCES customers(id) ON DELETE CASCADE,
match_confidence NUMERIC(5, 2),
notes TEXT,
is_active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_also_company_mapping_customer ON also_company_mapping(customer_id);
CREATE TABLE IF NOT EXISTS also_product_mapping (
id SERIAL PRIMARY KEY,
material_number VARCHAR(128) NOT NULL,
vendor VARCHAR(255) NOT NULL,
hub_product_id INTEGER NOT NULL REFERENCES products(id) ON DELETE CASCADE,
product_name_snapshot VARCHAR(512),
is_active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT uniq_also_product_mapping UNIQUE (material_number, vendor)
);
CREATE INDEX IF NOT EXISTS idx_also_product_mapping_product ON also_product_mapping(hub_product_id);