109 lines
4.2 KiB
MySQL
109 lines
4.2 KiB
MySQL
|
|
-- 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);
|