-- Feature 3: Smart Packages with Task Ordering -- Date: 2025-01-XX -- Description: Tilføjer task ordering, dependencies og geometry-baseret material beregning -- Opret package_tasks tabel til at linke tasks til packages CREATE TABLE IF NOT EXISTS package_tasks ( id INT AUTO_INCREMENT PRIMARY KEY, package_id INT NOT NULL, task_name VARCHAR(255) NOT NULL, task_description TEXT, estimated_hours DECIMAL(8,2) DEFAULT 0, task_order INT DEFAULT 0 COMMENT 'Rækkefølge inden for fase', task_phase ENUM('forberedelse', 'hovedarbejde', 'afslutning', 'inspektion') DEFAULT 'hovedarbejde', depends_on_task_id INT DEFAULT NULL COMMENT 'ID af task der skal udføres først', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (package_id) REFERENCES material_packages(id) ON DELETE CASCADE, FOREIGN KEY (depends_on_task_id) REFERENCES package_tasks(id) ON DELETE SET NULL, INDEX idx_package_id (package_id), INDEX idx_task_phase (task_phase), INDEX idx_task_order (task_order), INDEX idx_depends_on (depends_on_task_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- Tilføj geometry multiplier kolonner til package_materials (skip hvis eksisterer) SET @dbname = 'tilbudgivern'; SET @tablename = 'package_materials'; SET @columnname = 'geometry_multiplier'; SET @preparedStatement = (SELECT IF( (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = @columnname) > 0, 'SELECT "Column geometry_multiplier already exists";', 'ALTER TABLE package_materials ADD COLUMN geometry_multiplier VARCHAR(50) DEFAULT NULL COMMENT "area, length, width, spaer_count, perimeter, none";' )); PREPARE alterStatement FROM @preparedStatement; EXECUTE alterStatement; DEALLOCATE PREPARE alterStatement; SET @columnname = 'base_quantity'; SET @preparedStatement = (SELECT IF( (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = @columnname) > 0, 'SELECT "Column base_quantity already exists";', 'ALTER TABLE package_materials ADD COLUMN base_quantity DECIMAL(10,3) DEFAULT NULL COMMENT "Basis mængde før geometri multiplikation";' )); PREPARE alterStatement FROM @preparedStatement; EXECUTE alterStatement; DEALLOCATE PREPARE alterStatement; SET @columnname = 'waste_factor'; SET @preparedStatement = (SELECT IF( (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @dbname AND TABLE_NAME = @tablename AND COLUMN_NAME = @columnname) > 0, 'SELECT "Column waste_factor already exists";', 'ALTER TABLE package_materials ADD COLUMN waste_factor DECIMAL(5,3) DEFAULT 1.10 COMMENT "Spildfaktor (1.10 = 10% spild)";' )); PREPARE alterStatement FROM @preparedStatement; EXECUTE alterStatement; DEALLOCATE PREPARE alterStatement; -- Opdater eksisterende records med default værdier UPDATE package_materials SET base_quantity = quantity, waste_factor = 1.10, geometry_multiplier = 'none' WHERE base_quantity IS NULL; -- Opret smart_packages tabel (hvis ikke eksisterer) til færdige packages CREATE TABLE IF NOT EXISTS smart_packages ( id INT AUTO_INCREMENT PRIMARY KEY, package_code VARCHAR(50) UNIQUE NOT NULL COMMENT 'B7, S12, etc', package_name VARCHAR(255) NOT NULL, package_description TEXT, default_geometry_type ENUM('fladt_tag', 'skraat_tag', 'mansard', 'komplekst') DEFAULT 'skraat_tag', estimated_total_hours DECIMAL(8,2) DEFAULT 0, estimated_material_cost DECIMAL(12,2) DEFAULT 0, is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_package_code (package_code), INDEX idx_active (is_active) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- Opret customer_project_packages junction tabel CREATE TABLE IF NOT EXISTS customer_project_packages ( id INT AUTO_INCREMENT PRIMARY KEY, project_id INT NOT NULL, smart_package_id INT NOT NULL, quantity INT DEFAULT 1, added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (project_id) REFERENCES customer_projects(id) ON DELETE CASCADE, FOREIGN KEY (smart_package_id) REFERENCES smart_packages(id) ON DELETE CASCADE, INDEX idx_project_id (project_id), INDEX idx_smart_package_id (smart_package_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- Indsæt eksempel B7 package i material_packages tabel først INSERT INTO material_packages (name, description, category, created_by, total_estimated_price, is_active) VALUES ('B7 - Tag Renovation Komplet', 'Komplet tagrenovation med nedtagning, spær, undertag, tagplader og isolering', 'Tagmaterialer', 'system', 85000, 1) ON DUPLICATE KEY UPDATE name = VALUES(name); -- Hent B7 package ID SET @b7_id = (SELECT id FROM material_packages WHERE name = 'B7 - Tag Renovation Komplet' LIMIT 1); -- Indsæt også i smart_packages (reference tabel) INSERT INTO smart_packages (package_code, package_name, package_description, estimated_total_hours, estimated_material_cost) SELECT 'B7', name, description, 120, total_estimated_price FROM material_packages WHERE id = @b7_id ON DUPLICATE KEY UPDATE package_name = VALUES(package_name); -- Indsæt tasks for B7 package med rækkefølge INSERT INTO package_tasks (package_id, task_name, task_description, estimated_hours, task_order, task_phase, depends_on_task_id) VALUES -- Fase 1: Forberedelse (@b7_id, 'Stillads opsætning', 'Opsætte stillads rundt om hele bygningen', 8, 1, 'forberedelse', NULL), (@b7_id, 'Sik kerhedsforanstaltninger', 'Opsætte sikkerhedsnet og advarselsskiltning', 2, 2, 'forberedelse', NULL), -- Fase 2: Hovedarbejde (nedrivning først) (@b7_id, 'Nedtagning af gamle tagplader', 'Fjerne og bortskaffe gamle tagplader', 12, 1, 'hovedarbejde', NULL), (@b7_id, 'Fjernelse af gamle lægter', 'Fjerne gamle lægter og genbrugsmaterialer', 8, 2, 'hovedarbejde', NULL), (@b7_id, 'Inspektion og reparation af spær', 'Inspicere spær og reparere/udskifte skadede dele', 12, 3, 'hovedarbejde', NULL), (@b7_id, 'Montering af nyt undertag', 'Montere undertag med overlæg og tape', 16, 4, 'hovedarbejde', NULL), (@b7_id, 'Montering af lægter', 'Montere nye lægter med korrekt afstand (0.6m eller 1.0m)', 14, 5, 'hovedarbejde', NULL), (@b7_id, 'Montering af tagplader', 'Montere nye tagplader med overlæg og skruer', 20, 6, 'hovedarbejde', NULL), (@b7_id, 'Montering af vindskeder', 'Montere vindskeder langs gavle', 10, 7, 'hovedarbejde', NULL), -- Fase 3: Afslutning (@b7_id, 'Montering af tagrende og nedløb', 'Montere tagrende og nedløb med korrekt fald', 12, 1, 'afslutning', NULL), (@b7_id, 'Tætning og fuger', 'Tætne gennemføringer og fuger', 6, 2, 'afslutning', NULL), (@b7_id, 'Oprydning', 'Fjerne affald og rengøre arbejdsområdet', 4, 3, 'afslutning', NULL), -- Fase 4: Inspektion (@b7_id, 'Endelig inspektion', 'Gennemgå hele taget for kvalitetskontrol', 4, 1, 'inspektion', NULL); SELECT 'Feature 3 Migration Complete!' as Status; SELECT COUNT(*) as total_tasks, task_phase, SUM(estimated_hours) as phase_hours FROM package_tasks WHERE package_id = @b7_id GROUP BY task_phase ORDER BY FIELD(task_phase, 'forberedelse', 'hovedarbejde', 'afslutning', 'inspektion');