166 lines
6.2 KiB
SQL
166 lines
6.2 KiB
SQL
-- Global vendor partnumber mapping foundation with backward compatibility.
|
|
|
|
ALTER TABLE lot_partnumbers
|
|
ADD COLUMN IF NOT EXISTS vendor VARCHAR(255) NOT NULL DEFAULT '' AFTER partnumber;
|
|
|
|
CREATE TABLE IF NOT EXISTS qt_lot_bundles (
|
|
bundle_lot_name VARCHAR(255) NOT NULL,
|
|
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (bundle_lot_name)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS qt_lot_bundle_items (
|
|
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
bundle_lot_name VARCHAR(255) NOT NULL,
|
|
lot_name VARCHAR(255) NOT NULL,
|
|
qty DECIMAL(14,6) NOT NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
UNIQUE KEY uq_qt_lot_bundle_items_bundle_lot (bundle_lot_name, lot_name),
|
|
INDEX idx_qt_lot_bundle_items_lot_name (lot_name)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS qt_vendor_partnumber_seen (
|
|
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
source_type VARCHAR(32) NOT NULL,
|
|
vendor VARCHAR(255) NOT NULL DEFAULT '',
|
|
partnumber VARCHAR(255) NOT NULL,
|
|
description VARCHAR(10000) NULL,
|
|
last_seen_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
is_ignored TINYINT(1) NOT NULL DEFAULT 0,
|
|
ignored_at DATETIME NULL,
|
|
ignored_by VARCHAR(100) NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
UNIQUE KEY uq_qt_vendor_partnumber_seen_source_key (source_type, vendor, partnumber),
|
|
INDEX idx_qt_vendor_partnumber_seen_vendor_partnumber (vendor, partnumber),
|
|
INDEX idx_qt_vendor_partnumber_seen_ignored (is_ignored)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS qt_bom (
|
|
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
external_bom_id VARCHAR(255) NOT NULL,
|
|
source_system VARCHAR(100) NOT NULL,
|
|
payload JSON NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
UNIQUE KEY uq_qt_bom_source_external (source_system, external_bom_id)
|
|
);
|
|
|
|
ALTER TABLE qt_configurations
|
|
ADD COLUMN IF NOT EXISTS bom_id BIGINT UNSIGNED NULL AFTER competitor_pricelist_id;
|
|
|
|
-- Convert legacy many-to-one rows into bundle lots so (vendor,partnumber) can be unique.
|
|
CREATE TEMPORARY TABLE tmp_lp_dups AS
|
|
SELECT
|
|
vendor,
|
|
partnumber,
|
|
CONCAT('BND_', UPPER(SUBSTRING(MD5(CONCAT(vendor, '|', partnumber)), 1, 20))) AS bundle_lot_name,
|
|
MAX(description) AS description
|
|
FROM lot_partnumbers
|
|
GROUP BY vendor, partnumber
|
|
HAVING COUNT(*) > 1;
|
|
|
|
INSERT INTO lot (lot_name, lot_description, lot_category)
|
|
SELECT
|
|
d.bundle_lot_name,
|
|
CONCAT('Auto-generated bundle for ', d.partnumber, IF(d.vendor = '', '', CONCAT(' (', d.vendor, ')'))),
|
|
'BUNDLE'
|
|
FROM tmp_lp_dups d
|
|
LEFT JOIN lot l ON l.lot_name = d.bundle_lot_name
|
|
WHERE l.lot_name IS NULL;
|
|
|
|
INSERT INTO qt_lot_bundles (bundle_lot_name, is_active)
|
|
SELECT d.bundle_lot_name, 1
|
|
FROM tmp_lp_dups d
|
|
LEFT JOIN qt_lot_bundles b ON b.bundle_lot_name = d.bundle_lot_name
|
|
WHERE b.bundle_lot_name IS NULL;
|
|
|
|
INSERT INTO qt_lot_bundle_items (bundle_lot_name, lot_name, qty)
|
|
SELECT
|
|
d.bundle_lot_name,
|
|
lp.lot_name,
|
|
1
|
|
FROM tmp_lp_dups d
|
|
INNER JOIN lot_partnumbers lp
|
|
ON lp.vendor = d.vendor AND lp.partnumber = d.partnumber
|
|
WHERE TRIM(lp.lot_name) <> ''
|
|
ON DUPLICATE KEY UPDATE qty = VALUES(qty), updated_at = CURRENT_TIMESTAMP;
|
|
|
|
DELETE lp
|
|
FROM lot_partnumbers lp
|
|
INNER JOIN tmp_lp_dups d
|
|
ON lp.vendor = d.vendor AND lp.partnumber = d.partnumber;
|
|
|
|
INSERT INTO lot_partnumbers (vendor, partnumber, lot_name, description)
|
|
SELECT vendor, partnumber, bundle_lot_name, description
|
|
FROM tmp_lp_dups;
|
|
|
|
DROP TEMPORARY TABLE IF EXISTS tmp_lp_dups;
|
|
|
|
CREATE UNIQUE INDEX uq_lot_partnumbers_vendor_partnumber ON lot_partnumbers (vendor, partnumber);
|
|
CREATE INDEX idx_lot_partnumbers_vendor_partnumber ON lot_partnumbers (vendor, partnumber);
|
|
|
|
-- Add optional FKs if not present.
|
|
SET @fk_cfg_bom_exists := (
|
|
SELECT COUNT(*)
|
|
FROM information_schema.REFERENTIAL_CONSTRAINTS
|
|
WHERE CONSTRAINT_SCHEMA = DATABASE()
|
|
AND CONSTRAINT_NAME = 'fk_qt_configurations_bom'
|
|
);
|
|
SET @fk_cfg_bom_sql := IF(
|
|
@fk_cfg_bom_exists > 0,
|
|
'SELECT 1',
|
|
'ALTER TABLE qt_configurations ADD CONSTRAINT fk_qt_configurations_bom FOREIGN KEY (bom_id) REFERENCES qt_bom(id) ON DELETE SET NULL'
|
|
);
|
|
PREPARE stmt_cfg_bom FROM @fk_cfg_bom_sql;
|
|
EXECUTE stmt_cfg_bom;
|
|
DEALLOCATE PREPARE stmt_cfg_bom;
|
|
|
|
SET @fk_bundle_exists := (
|
|
SELECT COUNT(*)
|
|
FROM information_schema.REFERENTIAL_CONSTRAINTS
|
|
WHERE CONSTRAINT_SCHEMA = DATABASE()
|
|
AND CONSTRAINT_NAME = 'fk_qt_lot_bundles_lot'
|
|
);
|
|
SET @fk_bundle_sql := IF(
|
|
@fk_bundle_exists > 0,
|
|
'SELECT 1',
|
|
'ALTER TABLE qt_lot_bundles ADD CONSTRAINT fk_qt_lot_bundles_lot FOREIGN KEY (bundle_lot_name) REFERENCES lot(lot_name) ON DELETE CASCADE'
|
|
);
|
|
PREPARE stmt_bundle FROM @fk_bundle_sql;
|
|
EXECUTE stmt_bundle;
|
|
DEALLOCATE PREPARE stmt_bundle;
|
|
|
|
SET @fk_bundle_item_bundle_exists := (
|
|
SELECT COUNT(*)
|
|
FROM information_schema.REFERENTIAL_CONSTRAINTS
|
|
WHERE CONSTRAINT_SCHEMA = DATABASE()
|
|
AND CONSTRAINT_NAME = 'fk_qt_lot_bundle_items_bundle'
|
|
);
|
|
SET @fk_bundle_item_bundle_sql := IF(
|
|
@fk_bundle_item_bundle_exists > 0,
|
|
'SELECT 1',
|
|
'ALTER TABLE qt_lot_bundle_items ADD CONSTRAINT fk_qt_lot_bundle_items_bundle FOREIGN KEY (bundle_lot_name) REFERENCES qt_lot_bundles(bundle_lot_name) ON DELETE CASCADE'
|
|
);
|
|
PREPARE stmt_bundle_item_bundle FROM @fk_bundle_item_bundle_sql;
|
|
EXECUTE stmt_bundle_item_bundle;
|
|
DEALLOCATE PREPARE stmt_bundle_item_bundle;
|
|
|
|
SET @fk_bundle_item_lot_exists := (
|
|
SELECT COUNT(*)
|
|
FROM information_schema.REFERENTIAL_CONSTRAINTS
|
|
WHERE CONSTRAINT_SCHEMA = DATABASE()
|
|
AND CONSTRAINT_NAME = 'fk_qt_lot_bundle_items_lot'
|
|
);
|
|
SET @fk_bundle_item_lot_sql := IF(
|
|
@fk_bundle_item_lot_exists > 0,
|
|
'SELECT 1',
|
|
'ALTER TABLE qt_lot_bundle_items ADD CONSTRAINT fk_qt_lot_bundle_items_lot FOREIGN KEY (lot_name) REFERENCES lot(lot_name) ON DELETE RESTRICT'
|
|
);
|
|
PREPARE stmt_bundle_item_lot FROM @fk_bundle_item_lot_sql;
|
|
EXECUTE stmt_bundle_item_lot;
|
|
DEALLOCATE PREPARE stmt_bundle_item_lot;
|