Files
tilbudgivern/enhanced_quotes_schema.sql

206 lines
6.9 KiB
SQL

-- Enhanced quote database structure
-- This script creates tables to store detailed quote information for better reporting
-- Create project_types table for standardized project types
CREATE TABLE IF NOT EXISTS project_types (
id INT AUTO_INCREMENT PRIMARY KEY,
type_name VARCHAR(100) NOT NULL UNIQUE,
type_icon VARCHAR(10) DEFAULT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Insert standard project types
INSERT IGNORE INTO project_types (type_name, type_icon, description) VALUES
('tagrenovering', '🏠', 'Komplet renovering af eksisterende tag'),
('tagskifte', '🔧', 'Udskiftning af tagmaterialer'),
('tagudskiftning', '🔨', 'Fuldstændig udskiftning af tag'),
('tagreparation', '⚒️', 'Reparation af eksisterende tag'),
('tagterasse', '🏗️', 'Installation eller renovering af tagterasse'),
('tageftersyn', '🔍', 'Inspektion og mindre reparationer');
-- Create roof_types table for standardized roof types
CREATE TABLE IF NOT EXISTS roof_types (
id INT AUTO_INCREMENT PRIMARY KEY,
roof_name VARCHAR(100) NOT NULL UNIQUE,
roof_icon VARCHAR(10) DEFAULT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Insert standard roof types
INSERT IGNORE INTO roof_types (roof_name, roof_icon, description) VALUES
('skrå tag', '📐', 'Traditionelt skrå tag med hældning'),
('fladt tag', '📏', 'Fladt tag eller tagterasse'),
('tagterasse', '🏗️', 'Bebygget tagterasse'),
('mansardtag', '🏛️', 'Tag med knækket profil'),
('saddeltag', '', 'Klassisk saddeltag');
-- Add project_type_id to customer_projects table
ALTER TABLE customer_projects
ADD COLUMN project_type_id INT DEFAULT NULL,
ADD FOREIGN KEY (project_type_id) REFERENCES project_types(id);
-- Add roof_type_id to roof_geometry table
ALTER TABLE roof_geometry
ADD COLUMN roof_type_id INT DEFAULT NULL,
ADD FOREIGN KEY (roof_type_id) REFERENCES roof_types(id);
-- Create enhanced_quote_details table to store additional quote information
CREATE TABLE IF NOT EXISTS enhanced_quote_details (
id INT AUTO_INCREMENT PRIMARY KEY,
quote_id INT NOT NULL,
project_type_id INT,
roof_type_id INT,
total_area DECIMAL(10,2),
roof_pitch DECIMAL(5,2),
work_hours DECIMAL(8,2),
worker_count INT,
hourly_rate DECIMAL(8,2),
material_count INT DEFAULT 0,
material_categories JSON,
labor_breakdown JSON,
material_breakdown JSON,
pricing_details JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (quote_id) REFERENCES generated_quotes(id) ON DELETE CASCADE,
FOREIGN KEY (project_type_id) REFERENCES project_types(id),
FOREIGN KEY (roof_type_id) REFERENCES roof_types(id)
);
-- Create index for faster lookups
CREATE INDEX idx_enhanced_quote_details_quote_id ON enhanced_quote_details(quote_id);
CREATE INDEX idx_customer_projects_type ON customer_projects(project_type_id);
CREATE INDEX idx_roof_geometry_type ON roof_geometry(roof_type_id);
-- Create view for easy quote retrieval with all details
CREATE OR REPLACE VIEW v_enhanced_quotes AS
SELECT
gq.id,
gq.quote_text,
gq.quote_format,
gq.ai_tokens_used,
gq.ai_cost,
gq.ai_model,
gq.created_at,
gq.updated_at,
-- Project information
cp.project_name,
cp.customer_name,
cp.customer_email,
cp.customer_phone,
cp.customer_address,
cp.project_description,
cp.project_status,
pt.type_name as project_type,
pt.type_icon as project_icon,
-- Calculation details
pc.total_incl_vat,
pc.total_labor_cost,
pc.total_material_cost,
pc.subtotal,
pc.vat_amount,
pc.vat_percentage,
pc.overhead_percentage,
pc.profit_percentage,
-- Geometry details
rg.total_area,
rt.roof_name as roof_type,
rt.roof_icon as roof_icon,
rg.roof_pitch,
rg.length,
rg.width,
-- Labor details
pl.total_work_hours,
pl.carpenter_count,
pl.hourly_rate,
-- Enhanced details
eqd.material_count,
eqd.material_categories,
eqd.labor_breakdown,
eqd.material_breakdown,
eqd.pricing_details
FROM generated_quotes gq
LEFT JOIN project_calculations pc ON gq.calculation_id = pc.id
LEFT JOIN customer_projects cp ON gq.project_id = cp.id
LEFT JOIN project_types pt ON cp.project_type_id = pt.id
LEFT JOIN roof_geometry rg ON cp.id = rg.project_id
LEFT JOIN roof_types rt ON rg.roof_type_id = rt.id
LEFT JOIN project_labor pl ON cp.id = pl.project_id
LEFT JOIN enhanced_quote_details eqd ON gq.id = eqd.quote_id;
-- Create trigger to automatically populate enhanced_quote_details when a quote is created
DELIMITER //
CREATE OR REPLACE TRIGGER tr_populate_enhanced_quote_details
AFTER INSERT ON generated_quotes
FOR EACH ROW
BEGIN
DECLARE project_type_id_val INT DEFAULT NULL;
DECLARE roof_type_id_val INT DEFAULT NULL;
DECLARE area_val DECIMAL(10,2) DEFAULT NULL;
DECLARE pitch_val DECIMAL(5,2) DEFAULT NULL;
DECLARE hours_val DECIMAL(8,2) DEFAULT NULL;
DECLARE workers_val INT DEFAULT NULL;
DECLARE rate_val DECIMAL(8,2) DEFAULT NULL;
DECLARE material_cnt INT DEFAULT 0;
DECLARE material_cats JSON DEFAULT NULL;
-- Get project type
SELECT cp.project_type_id INTO project_type_id_val
FROM customer_projects cp
WHERE cp.id = NEW.project_id;
-- Get roof information
SELECT rg.roof_type_id, rg.total_area, rg.roof_pitch
INTO roof_type_id_val, area_val, pitch_val
FROM roof_geometry rg
WHERE rg.project_id = NEW.project_id;
-- Get labor information
SELECT pl.total_work_hours, pl.carpenter_count, pl.hourly_rate
INTO hours_val, workers_val, rate_val
FROM project_labor pl
WHERE pl.project_id = NEW.project_id;
-- Get material information
SELECT COUNT(*), JSON_ARRAYAGG(DISTINCT material_category)
INTO material_cnt, material_cats
FROM project_materials pm
WHERE pm.project_id = NEW.project_id;
-- Insert enhanced details
INSERT INTO enhanced_quote_details (
quote_id, project_type_id, roof_type_id, total_area, roof_pitch,
work_hours, worker_count, hourly_rate, material_count, material_categories
) VALUES (
NEW.id, project_type_id_val, roof_type_id_val, area_val, pitch_val,
hours_val, workers_val, rate_val, material_cnt, material_cats
);
END//
DELIMITER ;
-- Update existing quotes to have enhanced details
INSERT INTO enhanced_quote_details (
quote_id, project_type_id, roof_type_id, total_area, roof_pitch,
work_hours, worker_count, hourly_rate, material_count, material_categories
)
SELECT
gq.id,
cp.project_type_id,
rg.roof_type_id,
rg.total_area,
rg.roof_pitch,
pl.total_work_hours,
pl.carpenter_count,
pl.hourly_rate,
COALESCE((SELECT COUNT(*) FROM project_materials pm WHERE pm.project_id = cp.id), 0),
COALESCE((SELECT JSON_ARRAYAGG(DISTINCT material_category) FROM project_materials pm WHERE pm.project_id = cp.id), JSON_ARRAY())
FROM generated_quotes gq
LEFT JOIN customer_projects cp ON gq.project_id = cp.id
LEFT JOIN roof_geometry rg ON cp.id = rg.project_id
LEFT JOIN project_labor pl ON cp.id = pl.project_id
WHERE NOT EXISTS (
SELECT 1 FROM enhanced_quote_details eqd WHERE eqd.quote_id = gq.id
);