97 lines
3.8 KiB
MySQL
97 lines
3.8 KiB
MySQL
|
|
-- Migration 181: FedEx shipments foundation (case-linked)
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS fedex_shipments (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
booking_ref VARCHAR(64) NOT NULL UNIQUE,
|
||
|
|
case_id INTEGER NOT NULL REFERENCES sag_sager(id) ON DELETE CASCADE,
|
||
|
|
customer_id INTEGER REFERENCES customers(id) ON DELETE SET NULL,
|
||
|
|
contact_id INTEGER REFERENCES contacts(id) ON DELETE SET NULL,
|
||
|
|
|
||
|
|
service_type VARCHAR(32) NOT NULL,
|
||
|
|
shipment_status VARCHAR(32) NOT NULL DEFAULT 'draft',
|
||
|
|
|
||
|
|
pickup_window_start TIMESTAMP NOT NULL,
|
||
|
|
pickup_window_end TIMESTAMP NOT NULL,
|
||
|
|
|
||
|
|
recipient_name VARCHAR(150) NOT NULL,
|
||
|
|
company_name VARCHAR(150),
|
||
|
|
address_line1 VARCHAR(200) NOT NULL,
|
||
|
|
address_line2 VARCHAR(200),
|
||
|
|
postal_code VARCHAR(20) NOT NULL,
|
||
|
|
city VARCHAR(120) NOT NULL,
|
||
|
|
country_code VARCHAR(2) NOT NULL,
|
||
|
|
phone VARCHAR(50),
|
||
|
|
email VARCHAR(150),
|
||
|
|
|
||
|
|
tracking_number VARCHAR(64),
|
||
|
|
label_url TEXT,
|
||
|
|
cancel_reason TEXT,
|
||
|
|
|
||
|
|
dry_run BOOLEAN NOT NULL DEFAULT FALSE,
|
||
|
|
submitted_at TIMESTAMP,
|
||
|
|
|
||
|
|
api_payload JSONB,
|
||
|
|
api_response JSONB,
|
||
|
|
|
||
|
|
created_by_user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL,
|
||
|
|
updated_by_user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL,
|
||
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
deleted_at TIMESTAMP,
|
||
|
|
|
||
|
|
CONSTRAINT fedex_shipments_service_type_check CHECK (service_type IN ('PRIORITY', 'ECONOMY')),
|
||
|
|
CONSTRAINT fedex_shipments_status_check CHECK (
|
||
|
|
shipment_status IN ('draft', 'submitted', 'booked', 'in_transit', 'delivered', 'cancelled', 'failed')
|
||
|
|
),
|
||
|
|
CONSTRAINT fedex_shipments_pickup_window_check CHECK (pickup_window_end > pickup_window_start)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS fedex_shipment_packages (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
shipment_id INTEGER NOT NULL REFERENCES fedex_shipments(id) ON DELETE CASCADE,
|
||
|
|
weight_kg NUMERIC(10,3) NOT NULL,
|
||
|
|
length_cm NUMERIC(10,2) NOT NULL,
|
||
|
|
width_cm NUMERIC(10,2) NOT NULL,
|
||
|
|
height_cm NUMERIC(10,2) NOT NULL,
|
||
|
|
description VARCHAR(255) NOT NULL,
|
||
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
|
||
|
|
CONSTRAINT fedex_package_weight_positive CHECK (weight_kg > 0),
|
||
|
|
CONSTRAINT fedex_package_length_positive CHECK (length_cm > 0),
|
||
|
|
CONSTRAINT fedex_package_width_positive CHECK (width_cm > 0),
|
||
|
|
CONSTRAINT fedex_package_height_positive CHECK (height_cm > 0)
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS fedex_tracking_events (
|
||
|
|
id SERIAL PRIMARY KEY,
|
||
|
|
shipment_id INTEGER NOT NULL REFERENCES fedex_shipments(id) ON DELETE CASCADE,
|
||
|
|
status VARCHAR(64) NOT NULL,
|
||
|
|
description TEXT,
|
||
|
|
event_timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
location_city VARCHAR(120),
|
||
|
|
location_country VARCHAR(2),
|
||
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||
|
|
);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_fedex_shipments_case_id ON fedex_shipments(case_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_fedex_shipments_status ON fedex_shipments(shipment_status);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_fedex_shipments_tracking_number ON fedex_shipments(tracking_number);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_fedex_shipments_created_at ON fedex_shipments(created_at DESC);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_fedex_packages_shipment_id ON fedex_shipment_packages(shipment_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_fedex_tracking_shipment_id ON fedex_tracking_events(shipment_id);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_fedex_tracking_event_timestamp ON fedex_tracking_events(event_timestamp DESC);
|
||
|
|
|
||
|
|
CREATE OR REPLACE FUNCTION update_fedex_shipments_updated_at()
|
||
|
|
RETURNS TRIGGER AS $$
|
||
|
|
BEGIN
|
||
|
|
NEW.updated_at = CURRENT_TIMESTAMP;
|
||
|
|
RETURN NEW;
|
||
|
|
END;
|
||
|
|
$$ LANGUAGE plpgsql;
|
||
|
|
|
||
|
|
DROP TRIGGER IF EXISTS fedex_shipments_updated_at_trigger ON fedex_shipments;
|
||
|
|
CREATE TRIGGER fedex_shipments_updated_at_trigger
|
||
|
|
BEFORE UPDATE ON fedex_shipments
|
||
|
|
FOR EACH ROW
|
||
|
|
EXECUTE FUNCTION update_fedex_shipments_updated_at();
|