Files
tilbudgivern/bygma_prisbog_database_fixed.sql
T
alex fe8d73e8d1 Add integration tests for Bygma import services
- Implement test script for Bygma ESG data import (test_bygma_import.js)
- Create test script for Bygma Prisbog import functionality (test_bygma_prisbog_import.js)
- Develop full integration test for Bygma materials system (test_full_bygma_integration.js)
- Add materials synchronization test script (test_materials_sync.js)
- Ensure database connection and import statistics are logged
- Validate API visibility and price updates in integration tests
- Include sample data checks and cleanup procedures in tests
2025-09-18 13:24:50 +02:00

260 lines
7.5 KiB
SQL

-- Bygma Prisbog Database Schema (Fixed Version)
-- This creates tables for monthly Bygma price imports
-- Separate from the vendor history system
USE tilbudgivern;
-- Drop existing triggers first to avoid conflicts
DROP TRIGGER IF EXISTS tr_bygma_products_update_last_seen;
DROP TRIGGER IF EXISTS tr_bygma_price_history_deactivate_old;
DROP TRIGGER IF EXISTS tr_bygma_price_history_calculate_change;
-- Drop existing tables in correct order to avoid foreign key constraints
DROP TABLE IF EXISTS bygma_materials_mapping;
DROP TABLE IF EXISTS bygma_price_history;
DROP TABLE IF EXISTS bygma_import_log;
DROP TABLE IF EXISTS bygma_product_groups;
DROP TABLE IF EXISTS bygma_products;
-- Main table for Bygma products from monthly prisbog
CREATE TABLE bygma_products (
id INT PRIMARY KEY AUTO_INCREMENT,
vareNr VARCHAR(50) NOT NULL UNIQUE,
tekst TEXT,
enhed VARCHAR(20),
varegrp VARCHAR(10),
db_nr VARCHAR(50),
ean_nr VARCHAR(50),
std VARCHAR(50),
-- Current pricing (for quick access)
current_gross_price DECIMAL(15,2),
current_net_price DECIMAL(15,2),
-- Metadata
first_seen DATE,
last_seen DATE,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_vareNr (vareNr),
INDEX idx_varegrp (varegrp),
INDEX idx_tekst (tekst(100)),
INDEX idx_current_prices (current_gross_price, current_net_price),
INDEX idx_active (is_active),
INDEX idx_last_seen (last_seen)
);
-- Product groups for categorization
CREATE TABLE bygma_product_groups (
id INT PRIMARY KEY AUTO_INCREMENT,
varegrp VARCHAR(10) NOT NULL UNIQUE,
group_name VARCHAR(255),
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_varegrp (varegrp)
);
-- Price history to track all price changes over time
CREATE TABLE bygma_price_history (
id INT PRIMARY KEY AUTO_INCREMENT,
product_id INT NOT NULL,
gross_price DECIMAL(15,2),
net_price DECIMAL(15,2),
-- Price change tracking
price_change_pct DECIMAL(8,4) DEFAULT 0,
is_current BOOLEAN DEFAULT TRUE,
-- Import metadata
update_flag TINYINT DEFAULT 0,
import_date DATE,
import_file VARCHAR(500),
import_batch_id VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (product_id) REFERENCES bygma_products(id) ON DELETE CASCADE,
INDEX idx_product (product_id),
INDEX idx_import_batch (import_batch_id),
INDEX idx_import_date (import_date),
INDEX idx_current (is_current),
INDEX idx_prices (gross_price, net_price)
);
-- Import log to track all imports
CREATE TABLE bygma_import_log (
id INT PRIMARY KEY AUTO_INCREMENT,
batch_id VARCHAR(100) NOT NULL UNIQUE,
filename VARCHAR(500),
file_hash VARCHAR(64),
-- Import statistics
total_rows INT DEFAULT 0,
processed_rows INT DEFAULT 0,
new_products INT DEFAULT 0,
updated_products INT DEFAULT 0,
errors INT DEFAULT 0,
-- Status tracking
status ENUM('pending', 'processing', 'completed', 'failed') DEFAULT 'pending',
error_message TEXT,
-- Timing
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
completed_at TIMESTAMP NULL,
processing_time INT, -- seconds
INDEX idx_batch_id (batch_id),
INDEX idx_status (status),
INDEX idx_started_at (started_at),
INDEX idx_filename (filename(100))
);
-- Mapping table to connect Bygma products with existing materials
CREATE TABLE bygma_materials_mapping (
id INT PRIMARY KEY AUTO_INCREMENT,
bygma_product_id INT NOT NULL,
material_id INT, -- Kan være NULL hvis ikke mappet endnu
-- Mapping metadata
mapping_type ENUM('auto', 'manual', 'ai_suggested') DEFAULT 'auto',
mapping_confidence DECIMAL(5,4), -- 0.0 til 1.0
auto_update_price BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
mapped_by VARCHAR(100),
FOREIGN KEY (bygma_product_id) REFERENCES bygma_products(id) ON DELETE CASCADE,
INDEX idx_bygma_product (bygma_product_id),
INDEX idx_material (material_id),
INDEX idx_mapping_type (mapping_type),
INDEX idx_auto_update (auto_update_price),
-- Sikr kun én mapping per Bygma produkt
UNIQUE KEY unique_bygma_mapping (bygma_product_id)
);
-- Simplified Triggers (without recursive calls)
DELIMITER //
-- Trigger: Update last_seen when new price comes in
CREATE TRIGGER tr_bygma_products_update_last_seen
AFTER INSERT ON bygma_price_history
FOR EACH ROW
BEGIN
UPDATE bygma_products
SET last_seen = NEW.import_date,
current_gross_price = NEW.gross_price,
current_net_price = NEW.net_price,
updated_at = CURRENT_TIMESTAMP
WHERE id = NEW.product_id;
END//
-- Trigger: Calculate price change percentage
CREATE TRIGGER tr_bygma_price_history_calculate_change
BEFORE INSERT ON bygma_price_history
FOR EACH ROW
BEGIN
DECLARE prev_price DECIMAL(15,2);
-- Find previous price
SELECT net_price INTO prev_price
FROM bygma_price_history
WHERE product_id = NEW.product_id
AND is_current = TRUE
ORDER BY created_at DESC
LIMIT 1;
-- Calculate change if there's a previous price
IF prev_price IS NOT NULL AND prev_price > 0 THEN
SET NEW.price_change_pct = ((NEW.net_price - prev_price) / prev_price) * 100;
END IF;
-- Mark all other prices for this product as not current
UPDATE bygma_price_history
SET is_current = FALSE
WHERE product_id = NEW.product_id;
END//
DELIMITER ;
-- Useful views for reporting and analysis
-- View: Current prices with product details
CREATE VIEW v_bygma_current_prices AS
SELECT
p.id,
p.vareNr,
p.tekst,
p.enhed,
p.varegrp,
p.current_gross_price,
p.current_net_price,
p.last_seen,
pg.group_name,
mm.material_id as mapped_material_id,
mm.mapping_type,
mm.auto_update_price
FROM bygma_products p
LEFT JOIN bygma_product_groups pg ON p.varegrp = pg.varegrp
LEFT JOIN bygma_materials_mapping mm ON p.id = mm.bygma_product_id
WHERE p.is_active = TRUE;
-- View: Price history with changes
CREATE VIEW v_bygma_price_changes AS
SELECT
ph.id,
p.vareNr,
p.tekst,
ph.gross_price,
ph.net_price,
ph.price_change_pct,
ph.import_date,
ph.import_file,
ph.is_current
FROM bygma_price_history ph
JOIN bygma_products p ON ph.product_id = p.id
ORDER BY ph.import_date DESC, p.vareNr;
-- View: Import statistics
CREATE VIEW v_bygma_import_stats AS
SELECT
il.id,
il.batch_id,
il.filename,
il.total_rows,
il.processed_rows,
il.new_products,
il.updated_products,
il.errors,
il.status,
il.started_at,
il.completed_at,
il.processing_time,
ROUND((il.processed_rows / il.total_rows) * 100, 2) as success_rate_pct
FROM bygma_import_log il
ORDER BY il.started_at DESC;
-- Add some basic product groups
INSERT INTO bygma_product_groups (varegrp, group_name) VALUES
('3310', 'Porebeton og isolering'),
('3320', 'Leca og letbeton'),
('3330', 'Mursten og blokke')
ON DUPLICATE KEY UPDATE group_name = VALUES(group_name);
-- Grant necessary permissions to service user (run by admin separately if needed)
-- GRANT ALL PRIVILEGES ON tilbudgivern.bygma_* TO 'tilbudgivern_service'@'localhost';
-- GRANT SELECT ON tilbudgivern.v_bygma_* TO 'tilbudgivern_service'@'localhost';
-- FLUSH PRIVILEGES;