-- IMPORTANT NOTE: Always also change this function in from_current.sql and in install_current.sql (up0000.sql)
DROP FUNCTION IF EXISTS GetStorageEngine;
-- EOC
DELIMITER $$
CREATE FUNCTION GetStorageEngine(desired_engine VARCHAR(64)) 
RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
    DECLARE result VARCHAR(64);
    -- If we have mariaDB (might be part of GALERA cluster) have not found a better way to check for galera cluster only
    IF INSTR(version(),'mariadb') != 0 THEN
        SET result = 'InnoDB';
    ELSE
        -- Check if desired_engine exists
        SET result = (SELECT engine FROM information_schema.engines WHERE engine = desired_engine AND support = 'YES' LIMIT 1);
        
        -- InnoDB as fallback
        IF result IS NULL THEN
            SET result = 'InnoDB';
        END IF;
    END IF;
    RETURN result;
END $$
DELIMITER ;
-- EOC
SELECT GetStorageEngine ('ARCHIVE') INTO @engineInnoDBorArchive;
-- EOC
SELECT GetStorageEngine ('MEMORY') INTO @engineInnoDBorMemory;
-- EOC

-- USC Entferne alte Tabellen und Stored-Procedures.

-- --------------------------------------------------------------------------------------------------
-- Remove report procedure for completion level - start
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_report_completion_level_start;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Remove report procedure for completion level - create data (Fill with projects before)
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_report_completion_level_create;
-- EOC

-- USC Entferne alte Tabellen
DROP TABLE IF EXISTS `u10_ci_registry`;
-- EOC

DROP TABLE IF EXISTS `meetingmanager_subjects`;
-- EOC
DROP TABLE IF EXISTS `meetingmanager_appointments`;
-- EOC
DROP TABLE IF EXISTS `meetingmanager_tasks`;
-- EOC
DROP TABLE IF EXISTS `lut_meetingmanager_tasks_status`;
-- EOC
DROP TABLE IF EXISTS `lut_meetingmanager_tasks_appointments`;
-- EOC
DROP TABLE IF EXISTS `lut_meetingmanager_appointments_addresses`;
-- EOC
DROP TABLE IF EXISTS `lut_meetingmanager_tasks_addresses`;
-- EOC

DROP TABLE IF EXISTS `lut_looop_calendar`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_contacts`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_countries`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_documents`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_km`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_notes`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_projects`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_protocol`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_ressources`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_termin_ressource`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_time`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_todo`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_worker`;
-- EOC
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC Wenn der nächste Schritt fehlschlägt, importieren Sie bitte die Datenbank neu, ohne Stored Procedures und Funktionen.
DROP PROCEDURE IF EXISTS us_get_parent;
-- EOC

-- USC Wenn der nächste Schritt fehlschlägt, importieren Sie bitte die Datenbank neu, ohne Stored Procedures und Funktionen.
DROP FUNCTION IF EXISTS us_get_parent_package;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC Remove tables, which we don't need for the update
DROP TABLE IF EXISTS `u10_ci_sessions`;
-- EOC
DROP TABLE IF EXISTS `u10_session_log`;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC Migration tables
CREATE TABLE IF NOT EXISTS `01migrate_11_12_steps` (
  `stepname` VARCHAR(100) NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC


-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC Erstelle alle Stored-Procedures.

-- Get the parent node
DROP FUNCTION IF EXISTS us_get_parent_package;
-- EOC
DELIMITER $$
CREATE FUNCTION us_get_parent_package(from_project_id INT, from_id BIGINT) 
    RETURNS BIGINT
    NOT DETERMINISTIC
    BEGIN
        DECLARE the_id BIGINT;
        SELECT id INTO the_id 
            FROM work_packages WHERE 
            lft < (SELECT lft FROM work_packages WHERE id = from_id) 
                AND 
            rgt > (SELECT rgt FROM work_packages WHERE id = from_id)
                AND 
            project_id =  from_project_id 
            ORDER BY lft DESC LIMIT 1;
        RETURN the_id;
END $$
DELIMITER ;
-- EOC

-- Get the parent node
DROP FUNCTION IF EXISTS us_get_parent_package_lftrgt;
-- EOC
DELIMITER $$
CREATE FUNCTION us_get_parent_package_lftrgt(from_project_id INT, from_lft BIGINT, from_rgt BIGINT) 
    RETURNS BIGINT
    NOT DETERMINISTIC
    BEGIN
        DECLARE the_id BIGINT;
        SELECT id INTO the_id 
            FROM work_packages WHERE 
            lft < from_lft
                AND 
            rgt > from_rgt
                AND 
            project_id =  from_project_id 
            ORDER BY lft DESC LIMIT 1;
        RETURN the_id;
END $$
DELIMITER ;
-- EOC

DROP FUNCTION IF EXISTS us_get_parent_package_preset;
-- EOC
DELIMITER $$
CREATE FUNCTION us_get_parent_package_preset(from_tree_id INT, from_id BIGINT) 
    RETURNS BIGINT
    NOT DETERMINISTIC
    BEGIN
        DECLARE the_id BIGINT;
        SELECT id INTO the_id 
            FROM work_package_presets WHERE 
            lft < (SELECT lft FROM work_package_presets WHERE id = from_id) 
                AND 
            rgt > (SELECT rgt FROM work_package_presets WHERE id = from_id)
                AND 
            tree_id =  from_tree_id 
            ORDER BY lft DESC LIMIT 1;
        RETURN the_id;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Add index to table, if not exists
--
-- tablename        Table name
-- indexname        Name of the index
-- indexinfo        Fields list
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_add_index_to_table;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_add_index_to_table(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
    IN indexname VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
    IN indexinfo VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    IF ((SELECT COUNT(*) AS index_exists FROM information_schema.statistics WHERE TABLE_SCHEMA = DATABASE() and table_name = tablename AND index_name = indexname) <= 0) THEN
        -- Simple alter table
        SET @stmt_alter = CONCAT('ALTER TABLE ', tablename, ' ADD  INDEX ', indexname, ' (', indexinfo, ')');
        PREPARE stmt_alter FROM @stmt_alter;
        EXECUTE stmt_alter;		
    END IF;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Add fulltext index to table, if not exists
--
-- tablename        Table name
-- indexname        Name of the index
-- indexinfo        Fields list
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_add_fulltext_index_to_table;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_add_fulltext_index_to_table(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN indexname VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN indexinfo VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    IF NOT EXISTS ( (SELECT * FROM information_schema.statistics WHERE TABLE_SCHEMA=DATABASE() and table_name=tablename AND index_type='FULLTEXT' AND index_name=indexname) ) THEN
        SET @stmt_create = CONCAT('CREATE FULLTEXT INDEX ', indexname, ' ON ', tablename, ' (', indexinfo, ')');
        PREPARE stmt_create FROM @stmt_create;
        EXECUTE stmt_create;		
    END IF;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Drop index of table, if exists
--
-- tablename        Table name
-- indexname        Name of the index
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_drop_index_if_exists;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_drop_index_if_exists(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN indexname VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    IF ((SELECT COUNT(*) AS index_exists FROM information_schema.statistics WHERE TABLE_SCHEMA = DATABASE() and table_name = tablename AND index_name = indexname) > 0) THEN
        SET @s = CONCAT('DROP INDEX ' , indexname , ' ON ' , tablename);
        PREPARE stmt FROM @s;
        EXECUTE stmt;
    END IF;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Drop fulltext index of table, if exists
--
-- tablename        Table name
-- indexname        Name of the index
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_drop_all_fulltext_indexes_if_exists;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_drop_all_fulltext_indexes_if_exists(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    DECLARE isDone INT;
    DECLARE indexname VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;

    DECLARE curs CURSOR FOR SELECT INDEX_NAME FROM information_schema.STATISTICS WHERE table_schema=DATABASE() AND TABLE_NAME=tablename AND INDEX_TYPE='FULLTEXT';
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET isDone = 1;

    OPEN curs;

    SET isDone = 0;
    REPEAT
        FETCH curs INTO indexname;

        CALL us_drop_index_if_exists(tablename, indexname);
    UNTIL isDone END REPEAT;

    CLOSE curs;
END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Avoid the usage of old up0....sql scripts from pre X.2 (Just in case, someone thinks this is a good idea)
-- Otherwise all views -> tables would be deleted
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_add_to_table;
-- EOC

DROP TABLE IF EXISTS `us_add_to_table`;
-- EOC

CREATE TABLE `us_add_to_table`(
    do_not_use_x1_installer VARCHAR(150),
    PRIMARY KEY (`do_not_use_x1_installer`)
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

INSERT INTO us_add_to_table VALUES('Versuchen Sie auf keinen Fall ein Downgrade von X.2 auf X.1 duchzuführen! Do not try to downgrade X.2 to X.1!');
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Add field to table, if not exists
--
-- tablename    Table name
-- fieldname    Field name
-- fieldtype    Field type including charset and collate
-- --------------------------------------------------------------------------------------------------
-- EOC
DROP PROCEDURE IF EXISTS us_add_to_table2;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_add_to_table2(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN fieldname VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN fieldtype VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    IF NOT EXISTS( (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND COLUMN_NAME=fieldname AND TABLE_NAME=tablename) ) THEN
        IF EXISTS( (SELECT * FROM information_schema.STATISTICS WHERE table_schema=DATABASE() AND TABLE_NAME=tablename AND INDEX_TYPE='FULLTEXT') ) THEN
            CALL us_drop_all_fulltext_indexes_if_exists(tablename);
        END IF;

        SET @s = CONCAT('ALTER TABLE ', tablename, ' ADD ', fieldname, ' ', fieldtype);
        PREPARE stmt2 FROM @s;
        EXECUTE stmt2;
    END IF;

END $$
DELIMITER ;
-- EOC


-- --------------------------------------------------------------------------------------------------
-- Remove duplicate entries from table
--
-- tablename            Table name
-- pk                   Name of primary key field
-- matching_fields      Fields to match (group by)
-- validation_string    Validation string to check if all done
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_remove_duplicates_from_table;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_remove_duplicates_from_table(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN pk VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN matching_fields VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
    BEGIN
        DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
        BEGIN
            ROLLBACK;
            SET autocommit=1;
        END;

        SET autocommit=0;
        START TRANSACTION;

        -- Trim spaces from matching_fields
        SET @matching_fields = replace(matching_fields, ' ', '');

        -- Build on_string
        SET @on_string = '';
        SET @strLen := 0; 
        SET @i := 1;
        WHILE @strLen < LENGTH(@matching_fields)  DO
                SET @str := SUBSTRING_INDEX(@matching_fields, ',', @i);
                SET @strLen := LENGTH(@str);
                SET @i := @i + 1;
                IF @i > 2 THEN
                        SET @on_string = CONCAT(@on_string, ' AND ');
                END IF;
                SET @on_string = CONCAT(@on_string, tablename, '.',SUBSTRING_INDEX(@str, ',', -1), '=temp.', SUBSTRING_INDEX(@str, ',', -1));
        END WHILE;

        -- Create query to get duplicate records to delete
        SET @sql1 = CONCAT('SELECT ',tablename,'.',pk,' FROM ', tablename, ' INNER JOIN(SELECT * FROM ', tablename, ' GROUP BY ', matching_fields, ' HAVING COUNT(*) >1) temp ON ', @on_string, ' where ', tablename,'.', pk, ' not in (SELECT ', pk, ' FROM ', tablename, ' GROUP BY ', matching_fields, ' HAVING  COUNT(*) > 1)');
        
        -- Create temp table for saving ids
        SET @unique_table_name = replace(CONCAT('us_remove_duplicates_from_table_',UUID()), '-', '');
        SET @sql2 = CONCAT('CREATE TEMPORARY TABLE ',@unique_table_name,' AS(',@sql1,')');
        PREPARE stmt2 FROM @sql2;
        EXECUTE stmt2;

        -- Delete from table
        SET @sql3 = CONCAT('DELETE FROM ',tablename, ' WHERE ', pk, ' IN(SELECT ',pk ,' FROM ',@unique_table_name,')');
        PREPARE stmt3 FROM @sql3;	
		  EXECUTE stmt3;	
    
        -- Delete temp table
        SET @sql4 = CONCAT('DROP TABLE ',@unique_table_name);
        PREPARE stmt4 FROM @sql4;
        EXECUTE stmt4;	

        COMMIT;
        SET autocommit=1;

        SET validation_string = 'true';	
    END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS us_remove_duplicates_from_table_without_pk;
-- EOC

-- Example:
-- CALL us_remove_duplicates_from_table_without_pk(
-- 	'completion_level', 
--      'id, project_id, work_area_id, staff_id, date, MAX(completion_level) AS completion_level ,completion_level_history_id', 
-- 	'project_id, work_area_id, completion_level_history_id',
-- 	@validate_eadfsefds);
-- CALL us_remove_duplicates_from_table_without_pk(
-- 	'budget_plan', 
--      'project_id, area_id, staff_id, budget_plan_history_id, planned_costs, planned_hours, start_date, end_date, MAX(last_changed_date) AS last_changed_date, proportion, threshold', 
-- 	'project_id, area_id, budget_plan_history_id',
-- 	@validate_eadfsefds);
-- DonauConsult:
-- CALL us_add_constraint_to_table('schaetzungfertig', 'schaetzungfertig_unique_1', 'UNIQUE', '`LfdNr_Projekt` , `LfdNr_AB` , `History_LfdNr`' );
-- CALL us_add_constraint_to_table('sollab', 'sollab_unique_1', 'UNIQUE', '`LfdNr_Projekt` , `LfdNr_AB` , `History_LfdNr`' );

DELIMITER $$
CREATE PROCEDURE us_remove_duplicates_from_table_without_pk(
    IN xtable VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN my_fields VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN matching_fields VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
    BEGIN
	
	DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
	BEGIN
	    ROLLBACK;
	    SET autocommit=1;
	END;

	SET autocommit=0;
	START TRANSACTION;
		
	SET @sql1 = 'DROP TABLE IF EXISTS us_remove_duplicates_from_table_without_pk__tmp;';
	PREPARE stmt1 FROM @sql1;
	EXECUTE stmt1;
	-- create cleaned temporary table
	SET @sql1 = CONCAT('CREATE TEMPORARY TABLE us_remove_duplicates_from_table_without_pk__tmp AS(
		SELECT ',my_fields,' FROM ',xtable,'
		GROUP BY ',matching_fields,')');
	PREPARE stmt1 FROM @sql1;
	EXECUTE stmt1;
    
 	-- Delete from orig table - use delete, not truncate cause delete supports transactions
 	SET @sql1 = CONCAT('DELETE FROM ',xtable);
	PREPARE stmt1 FROM @sql1;
	EXECUTE stmt1;
	
	-- insert from tmp to orig table
	SET @sql1 = CONCAT('INSERT INTO ',xtable,' (SELECT * FROM us_remove_duplicates_from_table_without_pk__tmp)');
	PREPARE stmt1 FROM @sql1;
        EXECUTE stmt1;

        COMMIT;
        SET autocommit=1;

        SET validation_string = 'true';	
    END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Add constraint to table, if not exists
--
-- tablename        Table name
-- constraintname   Name of the constraint
-- constrainttype   Type of constraint (PRIMARY, UNIQUE, FULLTEXT, SPATIAL, FOREIGN)
-- constraintinfo   Fields list
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_add_constraint_to_table;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_add_constraint_to_table(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN constraintname VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN constrainttype VARCHAR(20) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN constraintinfo VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    IF NOT EXISTS( (SELECT * FROM information_schema.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA=DATABASE() AND (CONSTRAINT_NAME=constraintname OR CONCAT('us_', CONSTRAINT_NAME)=constraintname) AND TABLE_NAME=tablename) ) THEN
        -- Alter table for PRIMARY or UNIQUE constraint
        IF UPPER(constrainttype) = 'PRIMARY' OR UPPER(constrainttype) = 'UNIQUE' THEN
            SET @new_table = CONCAT(tablename, '__', UUID_SHORT());

            -- Drop tmp table if exists
            SET @stmt_drop = CONCAT('DROP TABLE IF EXISTS ', @new_table);
            PREPARE stmt_drop FROM @stmt_drop;
            EXECUTE stmt_drop;

            -- Create new tmp table like orig. table
            SET @stmt_create = CONCAT('CREATE TABLE ', @new_table,' LIKE ', tablename);
            PREPARE stmt_create FROM @stmt_create;
            EXECUTE stmt_create;

            -- Alter created tmp table
            SET @stmt_alter = CONCAT('ALTER TABLE ', @new_table, ' ADD ', constrainttype, ' KEY ', constraintname, ' (', constraintinfo, ')');
            PREPARE stmt_alter FROM @stmt_alter;
            EXECUTE stmt_alter;	

            -- Insert IGNORE data form orig. to tmp table
            SET @stmt_insert = CONCAT('INSERT IGNORE INTO ', @new_table, ' SELECT * FROM ', tablename);
            PREPARE stmt_insert FROM @stmt_insert;
            EXECUTE stmt_insert;	

            -- Drop *__bak table if exists
            SET @stmt_drop_bak = CONCAT('DROP TABLE IF EXISTS ', tablename, '__bak');
            PREPARE stmt_drop_bak FROM @stmt_drop_bak;
            EXECUTE stmt_drop_bak;

            -- Rename orig. table to *__bak
            SET @stmt_bak = CONCAT('RENAME TABLE ', tablename, ' TO ', tablename, '__bak');
            PREPARE stmt_bak FROM @stmt_bak;
            EXECUTE stmt_bak;

            -- Rename tmp to orig. table
            SET @stmt_rename = CONCAT('RENAME TABLE ', @new_table, ' TO ', tablename);
            PREPARE stmt_rename FROM @stmt_rename;
            EXECUTE stmt_rename;		   

        ELSE
            -- Simple alter table
            SET @stmt_alter = CONCAT('ALTER TABLE ', tablename, ' ADD ', constrainttype, ' KEY ', constraintname, ' (', constraintinfo, ')');
            PREPARE stmt_alter FROM @stmt_alter;
            EXECUTE stmt_alter;		
        END IF;
    END IF;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Update extras views
-- --------------------------------------------------------------------------------------------------
-- @todo Remove the DROP command below, after some time
DROP PROCEDURE IF EXISTS update_extras_views;
-- EOC

DROP PROCEDURE IF EXISTS update_extras_views_do;
-- EOC

DELIMITER $$
CREATE PROCEDURE update_extras_views_do()
BEGIN
        -- Views to update
        CREATE OR REPLACE
         VIEW `externalexpenses_addi_merged`  AS
         SELECT *, 1+0 AS is_invoiced
         FROM zusatz_extkosten
         UNION
         SELECT *, 0 AS is_invoiced
         FROM zusatz_geextkosten;

        CREATE OR REPLACE
         VIEW `fees_addi_merged`  AS
         SELECT *, 1+0 AS is_invoiced
         FROM zusatz_honverw
         UNION
         SELECT *, 0 AS is_invoiced
         FROM zusatz_gehonverw;

END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Fill calender table for per day selects
--
-- start_date       Start date to add
-- end_date         End date to add
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_add_to_calendar;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_add_to_calendar(start_date DATE, end_date DATE)
BEGIN

    DECLARE curr_date DATE;
    SET curr_date=start_date;
    WHILE curr_date <= end_date DO
        INSERT IGNORE INTO `u10_calendar` VALUES(curr_date, CONCAT(MONTH(curr_date),'_',YEAR(curr_date)));
        SET curr_date = ADDDATE(curr_date, INTERVAL 1 DAY);
    END WHILE;

END $$
DELIMITER ;
-- EOC


-- --------------------------------------------------------------------------------------------------
-- Helper procedures for maintenance tools (Clean lookup tables)
-- 
-- Validate lut_fee_areas_proj
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_update_lost_lut_fee_areas_proj;
-- EOC

DELIMITER $$
CREATE PROCEDURE us_update_lost_lut_fee_areas_proj(offsett INTEGER, step INTEGER, projects_cnt INTEGER, OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci)
BEGIN
	DECLARE xproject_id INTEGER;
	DECLARE xwork_area_category_id INTEGER;
	DECLARE l_last_row_fetched_projects INTEGER;
	DECLARE cur_projects CURSOR FOR SELECT id, work_area_category_id FROM tmp_cur_projects;
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched_projects=1;
		
	IF projects_cnt = 0 THEN
		SET @s = CONCAT('SELECT COUNT(id) AS cnt FROM projects');
		PREPARE stmt FROM @s;
		EXECUTE stmt;	
	ELSE		
		-- create TEMPORARY TABLE
		DROP TABLE IF EXISTS tmp_cur_projects;
		SET @query = CONCAT('CREATE TEMPORARY TABLE tmp_cur_projects as select id, work_area_category_id from projects ORDER BY id ASC LIMIT ',offsett,', ',step);
		select @query;
		PREPARE stmt from @query;
		EXECUTE stmt;
		DEALLOCATE PREPARE stmt;	
	
		SET l_last_row_fetched_projects=0;
		OPEN cur_projects;
		cursor_loop: LOOP -- -------------------------------------
			FETCH cur_projects INTO xproject_id, xwork_area_category_id;
			IF l_last_row_fetched_projects = 1 THEN
				LEAVE cursor_loop;
			END IF;
				/*Do something with the row fetched*/
				CALL _us_update_lost_lut_fee_areas_proj1(xproject_id, xwork_area_category_id);
		END LOOP cursor_loop; -- -------------------------------------
		CLOSE  cur_projects;
		SET l_last_row_fetched_projects=0;	

		-- remove TEMPORARY TABLE
		DROP TABLE tmp_cur_projects;

	END IF;	
        SET validation_string = 'true';			
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS _us_update_lost_lut_fee_areas_proj1;
-- EOC

DELIMITER $$
CREATE PROCEDURE _us_update_lost_lut_fee_areas_proj1(IN xproject_id INTEGER, IN xwork_area_category_id INTEGER)
BEGIN
	DECLARE xfee_area_id INTEGER;
	DECLARE l_last_row_fetched INTEGER;
	DECLARE cur_work_areas CURSOR FOR 
		SELECT wa.fee_area_id AS fee_area_id FROM work_areas AS wa WHERE wa.id IN(SELECT work_area_id FROM lut_work_areas_work_areas_categories WHERE work_area_categories_id=xwork_area_category_id);
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

	SET l_last_row_fetched=0;
	OPEN cur_work_areas;
	cursor_loop: LOOP -- -------------------------------------
		FETCH cur_work_areas INTO xfee_area_id;
		IF l_last_row_fetched=1 THEN
			LEAVE cursor_loop;
		END IF;
			/*Do something with the row fetched*/
			CALL _us_update_lost_lut_fee_areas_proj2(xproject_id, xfee_area_id);
	END LOOP cursor_loop; -- -------------------------------------
	CLOSE  cur_work_areas;
	SET l_last_row_fetched=0;	
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS _us_update_lost_lut_fee_areas_proj2;
-- EOC

DELIMITER $$
CREATE PROCEDURE _us_update_lost_lut_fee_areas_proj2(IN xproject_id INTEGER, IN xfee_area_id INTEGER)
BEGIN
	DECLARE xcnt_fee_areas INTEGER;
	DECLARE l_last_row_fetched INTEGER;
	DECLARE cur_fee_areas CURSOR FOR 
		SELECT COUNT(fee_area_id) AS cnt_fee_areas FROM lut_fee_areas_proj WHERE project_id=xproject_id AND fee_area_id=xfee_area_id; 
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

	SET l_last_row_fetched=0;
	OPEN cur_fee_areas;
	cursor_loop: LOOP -- -------------------------------------
		FETCH cur_fee_areas INTO xcnt_fee_areas;
		IF l_last_row_fetched=1 THEN
			LEAVE cursor_loop;
		END IF;
			IF  xcnt_fee_areas=0 THEN
				/*Do insert*/
				INSERT  INTO lut_fee_areas_proj(`project_id`, `fee_area_id`, `costs`, `hours`, `status`)
				VALUES  (xproject_id, xfee_area_id, 0, 0, 20);				
			END IF;
	END LOOP cursor_loop; -- -------------------------------------
	CLOSE  cur_fee_areas;
	SET l_last_row_fetched=0;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Helper procedures for maintenance tools (Clean lookup tables)
-- 
-- Validate budget plan and completion levels
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_update_lost_budget_plan_completion_levels;
-- EOC

DELIMITER $$
CREATE PROCEDURE us_update_lost_budget_plan_completion_levels(offsett INTEGER, step INTEGER, projects_cnt INTEGER, OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci)
BEGIN
	DECLARE xproject_id INTEGER;
	DECLARE xwork_area_category_id INTEGER;
	DECLARE l_last_row_fetched_projects INTEGER;
	DECLARE cur_projects CURSOR FOR SELECT id, work_area_category_id FROM tmp_cur_projects;
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched_projects=1;
		
	IF projects_cnt = 0 THEN
		SET @s = CONCAT('SELECT COUNT(id) AS cnt FROM projects');
		PREPARE stmt FROM @s;
		EXECUTE stmt;	
	ELSE		
		-- create TEMPORARY TABLE
		DROP TABLE IF EXISTS tmp_cur_projects;
		SET @query = CONCAT('CREATE TEMPORARY TABLE tmp_cur_projects as select id, work_area_category_id  from projects ORDER BY id ASC LIMIT ',offsett,', ',step);
		select @query;
		PREPARE stmt from @query;
		EXECUTE stmt;
		DEALLOCATE PREPARE stmt;	
	
		SET l_last_row_fetched_projects=0;
		OPEN cur_projects;
		cursor_loop: LOOP -- -------------------------------------
			FETCH cur_projects INTO xproject_id, xwork_area_category_id;
			IF l_last_row_fetched_projects = 1 THEN
				LEAVE cursor_loop;
			END IF;
				/*Do something with the row fetched*/
				CALL _us_update_lost_budget_plan_completion_levels1(xproject_id, xwork_area_category_id);
				CALL _us_update_lost_budget_plan_completion_levels2_bp(xproject_id, xwork_area_category_id);
				CALL _us_update_lost_budget_plan_completion_levels2_cl(xproject_id, xwork_area_category_id);
		END LOOP cursor_loop; -- -------------------------------------
		CLOSE  cur_projects;
		SET l_last_row_fetched_projects=0;	

		-- remove TEMPORARY TABLE
		DROP TABLE tmp_cur_projects;

	END IF;	

        SET validation_string = 'true';			
END $$
DELIMITER ;
-- EOC

-- ----------------------------------------
-- Ensure we have values for each work area 
-- ----------------------------------------
DROP PROCEDURE IF EXISTS _us_update_lost_budget_plan_completion_levels1;
-- EOC

DELIMITER $$
CREATE PROCEDURE _us_update_lost_budget_plan_completion_levels1(IN xproject_id INTEGER, IN xwork_area_category_id INTEGER)
BEGIN
	DECLARE xwork_area_id INTEGER;
	DECLARE l_last_row_fetched INTEGER;
	DECLARE cur_work_areas CURSOR FOR 
		SELECT wa.id AS work_area_id FROM work_areas AS wa WHERE wa.id IN(SELECT work_area_id FROM lut_work_areas_work_areas_categories WHERE work_area_categories_id=xwork_area_category_id);
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

	SET l_last_row_fetched=0;
	OPEN cur_work_areas;
	cursor_loop: LOOP -- -------------------------------------
		FETCH cur_work_areas INTO xwork_area_id;
		IF l_last_row_fetched=1 THEN
			LEAVE cursor_loop;
		END IF;
			/*Do something with the row fetched */
			CALL _us_update_lost_budget_plan_completion_levels1_bp(xproject_id, xwork_area_id);
			CALL _us_update_lost_budget_plan_completion_levels1_cl(xproject_id, xwork_area_id);
	END LOOP cursor_loop; -- -------------------------------------
	CLOSE  cur_work_areas;
	SET l_last_row_fetched=0;	
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS _us_update_lost_budget_plan_completion_levels1_bp;
-- EOC

DELIMITER $$
CREATE PROCEDURE _us_update_lost_budget_plan_completion_levels1_bp(IN xproject_id INTEGER, IN xwork_area_id INTEGER)
BEGIN
	DECLARE xcnt_projects INTEGER;
	DECLARE l_last_row_fetched INTEGER;
	DECLARE cur_fee_areas CURSOR FOR 
		SELECT COUNT(project_id) AS cnt_projects FROM budget_plan WHERE project_id=xproject_id AND area_id=xwork_area_id; 
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

	SET l_last_row_fetched=0;
	OPEN cur_fee_areas;
	cursor_loop: LOOP -- -------------------------------------
		FETCH cur_fee_areas INTO xcnt_projects;
		IF l_last_row_fetched=1 THEN
			LEAVE cursor_loop;
		END IF;
			IF  xcnt_projects=0 THEN
				/*Do insert*/
				INSERT  INTO budget_plan(`project_id`, `area_id`, `staff_id`, `last_changed_date`, `planned_costs`, `planned_hours`,
				`start_date`, `end_date`, `proportion`, `threshold`, `budget_plan_history_id`)
				VALUES  (xproject_id, xwork_area_id, 0, null, 0, 0, null, null, 0, 0, null);				
			END IF;
	END LOOP cursor_loop; -- -------------------------------------
	CLOSE  cur_fee_areas;
	SET l_last_row_fetched=0;
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS _us_update_lost_budget_plan_completion_levels1_cl;
-- EOC

DELIMITER $$
CREATE PROCEDURE _us_update_lost_budget_plan_completion_levels1_cl(IN xproject_id INTEGER, IN xwork_area_id INTEGER)
BEGIN
	DECLARE xcnt_projects INTEGER;
	DECLARE l_last_row_fetched INTEGER;
	DECLARE cur_fee_areas CURSOR FOR 
		SELECT COUNT(project_id) AS cnt_projects FROM completion_level WHERE project_id=xproject_id AND work_area_id=xwork_area_id; 
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

	SET l_last_row_fetched=0;
	OPEN cur_fee_areas;
	cursor_loop: LOOP -- -------------------------------------
		FETCH cur_fee_areas INTO xcnt_projects;
		IF l_last_row_fetched=1 THEN
			LEAVE cursor_loop;
		END IF;
			IF  xcnt_projects=0 THEN
				/*Do insert*/
				INSERT  INTO completion_level(`project_id`, `work_area_id`, `staff_id`, `date`, `completion_level`, `completion_level_history_id`)
				VALUES  (xproject_id, xwork_area_id, 0, null, 0, null);				
			END IF;
	END LOOP cursor_loop; -- -------------------------------------
	CLOSE  cur_fee_areas;
	SET l_last_row_fetched=0;
END $$
DELIMITER ;
-- EOC

-- -------------------------------------------------------------
-- Ensure we remove work areas which are not part of the project
-- -------------------------------------------------------------
DROP PROCEDURE IF EXISTS _us_update_lost_budget_plan_completion_levels2_bp;
-- EOC

DELIMITER $$
CREATE PROCEDURE _us_update_lost_budget_plan_completion_levels2_bp(IN xproject_id INTEGER, IN xwork_area_category_id INTEGER)
BEGIN
        DELETE FROM budget_plan
        WHERE project_id=xproject_id AND
        area_id NOT IN (
            SELECT wa.id AS work_area_id FROM work_areas AS wa WHERE wa.id IN(SELECT work_area_id FROM lut_work_areas_work_areas_categories WHERE work_area_categories_id=xwork_area_category_id)
        );	
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS _us_update_lost_budget_plan_completion_levels2_cl;
-- EOC

DELIMITER $$
CREATE PROCEDURE _us_update_lost_budget_plan_completion_levels2_cl(IN xproject_id INTEGER, IN xwork_area_category_id INTEGER)
BEGIN
        DELETE FROM completion_level
        WHERE project_id=xproject_id AND
        work_area_id NOT IN (
            SELECT wa.id AS work_area_id FROM work_areas AS wa WHERE wa.id IN(SELECT work_area_id FROM lut_work_areas_work_areas_categories WHERE work_area_categories_id=xwork_area_category_id)
        );	
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Clean chars
--
-- tablename    Table name
-- ismultiline  Is a multi line field
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_clean_chars_column;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_clean_chars_column(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN colname VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN ismultiline BOOLEAN
)
BEGIN
    DECLARE char_i INTEGER;
    
    SET char_i = 0;
    char_loop: LOOP
        SET char_i = char_i + 1;

        IF char_i > 31 THEN
            LEAVE char_loop;
        END IF;

        IF char_i = 9 THEN -- TAB
            ITERATE char_loop;
        END IF;
        IF ismultiline AND char_i = 10 THEN -- LF
            ITERATE char_loop;
        END IF;
        IF ismultiline AND char_i = 13 THEN -- CR = ENTER
            ITERATE char_loop;
        END IF;

        -- CLEAN THA SHIT
        SET @s = CONCAT('UPDATE ', tablename, ' SET ', colname, ' = replace( ', colname, ', char(', char_i,'), "");');
        PREPARE stmt2 FROM @s;
        EXECUTE stmt2;

    END LOOP char_loop;

    
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS us_clean_chars;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_clean_chars(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN ismultiline BOOLEAN, 
    OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    DECLARE num_rows INTEGER;
    DECLARE i INTEGER;
    DECLARE col_name VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE dt_type VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;

    DECLARE col_names CURSOR FOR
        SELECT column_name, data_type
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE table_name = tablename
        AND table_schema = SCHEMA();
    
    OPEN col_names;

    SELECT FOUND_ROWS() INTO num_rows;

    SET i = 1;
    col_name_loop: LOOP
        IF i > num_rows THEN
            CLOSE col_names;
            LEAVE col_name_loop;
        END IF;
        
        FETCH col_names INTO col_name, dt_type;
        
        IF (dt_type='varchar' OR dt_type='longtext' OR dt_type='text') AND col_name NOT IN('Index') THEN

            CALL us_clean_chars_column(tablename, col_name, ismultiline);

        END IF;

        SET i = i + 1;
    END LOOP col_name_loop;
    SET validation_string = 'true';		
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS us_update_correspondence_attachment_number;
-- EOC

DELIMITER $$
CREATE PROCEDURE us_update_correspondence_attachment_number(IN corr_id INTEGER, OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci)
BEGIN
	DECLARE num_rows INTEGER;
	DECLARE thequery CURSOR FOR
	     SELECT id
	     FROM correspondence_attachments
	     WHERE correspondence_id = corr_id;
	OPEN thequery;     
	SELECT FOUND_ROWS() INTO num_rows;
	CLOSE thequery;
	UPDATE correspondence SET attachments=num_rows WHERE id = corr_id;
	SELECT num_rows AS `DEBUG`; 
        SET validation_string = 'true';
END $$
DELIMITER ;
-- EOC

DROP FUNCTION IF EXISTS `us_replace`;
-- EOC

-- If the creation of us_replace fails,
-- activate the log_bin_trust_function_creators within you MySQL config.
DELIMITER $$
CREATE FUNCTION `us_replace` (str TEXT CHARSET utf8mb4, search_str TEXT,replace_str TEXT,ci BOOL)
    RETURNS TEXT CHARSET utf8mb4
    DETERMINISTIC
    READS SQL DATA
    BEGIN
        DECLARE return_str TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '';
        DECLARE lower_str TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
        DECLARE lower_search_str TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
        DECLARE pos INT DEFAULT 1;
        DECLARE old_pos INT DEFAULT 1;
        
        IF ci = false THEN
            return replace(str, search_str, replace_str);	                     
        END IF;        
        
        SELECT lower(str) INTO lower_str;
        SELECT lower(search_str) INTO lower_search_str;
        SELECT locate(lower_search_str, lower_str, pos) INTO pos;
        WHILE pos > 0 DO
            SELECT concat(return_str, substr(str, old_pos, pos-old_pos), replace_str) INTO return_str;
            SELECT pos + char_length(search_str) INTO pos;
            SELECT pos INTO old_pos;
            SELECT locate(lower_search_str, lower_str, pos) INTO pos;
        END WHILE;
        SELECT concat(return_str, substr(str, old_pos, char_length(str))) INTO return_str;
        RETURN return_str;
END$$
DELIMITER ;
-- EOC

DROP FUNCTION IF EXISTS `us_replace_if_max_length`;
-- EOC

DELIMITER $$
CREATE FUNCTION `us_replace_if_max_length` ( str TEXT,search_str TEXT,replace_str TEXT,ci BOOL, max_length INT)
    RETURNS TEXT CHARSET utf8mb4
    DETERMINISTIC
    READS SQL DATA
    BEGIN
        DECLARE return_str TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '';

        SELECT us_replace(str, search_str, replace_str, ci) INTO return_str;
        if char_length(return_str) > max_length THEN 
            SELECT str INTO return_str;
        END IF;

        RETURN return_str;
END$$
DELIMITER ;
-- EOC


DROP FUNCTION IF EXISTS us_delete_spaces;
-- EOC
DELIMITER $$
CREATE FUNCTION us_delete_spaces(str VARCHAR(255)) 
    RETURNS VARCHAR(255) CHARSET utf8
    DETERMINISTIC
    NO SQL
    BEGIN
        while instr(str, '  ') > 0 do
        set str = replace(str, '  ', ' ');
        end while;
        return trim(str);
END $$
DELIMITER ;
-- EOC


DROP FUNCTION IF EXISTS `us_wrap`;
-- EOC

DELIMITER $$
CREATE FUNCTION `us_wrap` (str TEXT CHARSET utf8, search_str TEXT,wrap_left TEXT,wrap_right TEXT,ci BOOL)
    RETURNS TEXT CHARSET utf8
    DETERMINISTIC
    READS SQL DATA
    BEGIN
        DECLARE val TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '';
        DECLARE return_str TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '';
        DECLARE lower_str TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
        DECLARE lower_search_str TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
        DECLARE pos INT DEFAULT 1;
        DECLARE old_pos INT DEFAULT 1;
        
        IF ci = true THEN
            SELECT lower(str) INTO lower_str;
            SELECT lower(search_str) INTO lower_search_str;	   
            SELECT locate(lower_search_str, lower_str, pos) INTO pos;	             
        ELSE
            SELECT str INTO lower_str;
            SELECT search_str INTO lower_search_str;	      
            SELECT locate(BINARY lower_search_str, BINARY lower_str, pos) INTO pos;	        
        END IF;
	      
        WHILE pos > 0 DO
            SELECT substr(str, pos, old_pos+char_length(search_str)-old_pos) INTO val;
            SELECT concat(return_str, substr(str, old_pos, pos-old_pos), wrap_left, val, wrap_right) INTO return_str;
            SELECT pos + char_length(search_str) INTO pos;
            SELECT pos INTO old_pos;
            -- SELECT locate(lower_search_str, lower_str, pos) INTO pos;
            IF ci = true THEN
                    SELECT locate(lower_search_str, lower_str, pos) INTO pos;	             
            ELSE
                    SELECT locate(BINARY lower_search_str, BINARY lower_str, pos) INTO pos;        
            END IF;            
        END WHILE;
        SELECT concat(return_str, substr(str, old_pos, char_length(str))) INTO return_str;
        RETURN return_str;
END$$
DELIMITER ;
-- EOC

DROP FUNCTION IF EXISTS `us_uuid_v4`;
-- EOC
DELIMITER $$
CREATE FUNCTION `us_uuid_v4`() RETURNS CHAR(36)
DETERMINISTIC
NO SQL
BEGIN
	IF INSTR(version(),'mariadb') = 0 AND SUBSTRING(VERSION(), 1, 4) != '5.6.' THEN
		-- 1th and 2nd block are made of 6 random bytes
		SET @h1 = HEX(RANDOM_BYTES(4));
		SET @h2 = HEX(RANDOM_BYTES(2));
		-- 3th block will start with a 4 indicating the version, remaining iS random 
		SET @h3 = SUBSTR(HEX(RANDOM_BYTES(2)), 2, 3);
		-- 4th block first nibble can only be 8, 9 A or B, remaining is random 
		SET @h4 = CONCAT(HEX(FLOOR(ASCII(RANDOM_BYTES(1)) / 64)+8), SUBSTR(HEX(RANDOM_BYTES(2)), 2, 3));
		-- 5th block is made of 6 random bytes
		SET @h5 = HEX(RANDOM_BYTES(6));
		-- Build the complete UUID
		RETURN LOWER(CONCAT(@h1, '-', @h2, '-4', @h3, '-', @h4, '-', @h5)); 
	ELSE
        -- Generate 8 2-byte strings that we will combine into a UUIDv4
		SET @h1 = LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0');
		SET @h2 = LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0');
		SET @h3 = LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0');
		SET @h6 = LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0');
		SET @h7 = LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0');
		SET @h8 = LPAD(HEX(FLOOR(RAND() * 0xffff)), 4, '0');
		-- 4th section will start with a 4 indicating the version
		SET @h4 = CONCAT('4', LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'));
		-- 5th section first half-byte can only be 8, 9 A or B
		SET @h5 = CONCAT(HEX(FLOOR(RAND() * 4 + 8)), LPAD(HEX(FLOOR(RAND() * 0x0fff)), 3, '0'));
		-- Build the complete UUID
		RETURN LOWER(CONCAT(@h1, @h2, '-', @h3, '-', @h4, '-', @h5, '-', @h6, @h7, @h8));
    END IF;
END $$
DELIMITER ;
-- EOC


-- --------------------------------------------------------------------------------------------------
-- Create move_form_types_log_archive, if not exists
--
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_create_move_form_types_log_archive;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_create_move_form_types_log_archive()
BEGIN

    DECLARE sql1 TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci 
        DEFAULT 'CREATE TABLE IF NOT EXISTS `move_form_types_log_archive` (
    `id` INT NOT NULL ,
    `moving_session_id` VARCHAR( 50 ) NOT NULL,
    `project_id` INT NOT NULL ,
    `correspondence_id` INT NOT NULL ,
    `correspondence_type_id` INT NOT NULL ,
    `project_path_correspondence` longtext NOT NULL,
    `correspondence_structure_path` VARCHAR( 254 ) NOT NULL,
    `filename` VARCHAR( 254 ) NOT NULL,
    `path_from` longtext NOT NULL,
    `path_to` longtext NOT NULL,
    `created_date` DATETIME NOT NULL,
    `created_by_id` INT NOT NULL
) ENGINE=';

    DECLARE sql2 TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;';

    SELECT GetStorageEngine ('ARCHIVE') INTO @engineInnoDBorArchive;
    SET @s = CONCAT(sql1, @engineInnoDBorArchive, sql2);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Create system_modifications_log, if not exists
--
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_create_system_modifications_log;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_create_system_modifications_log()
BEGIN
    DECLARE sql1 TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci 
        DEFAULT 'CREATE TABLE IF NOT EXISTS `system_modifications_log` (
    `datetime` DATETIME NOT NULL,

    `us_serial` VARCHAR( 255 ) DEFAULT NULL ,
    `us_instinfo_hash` VARCHAR( 50 ) DEFAULT NULL ,
    `us_version` VARCHAR( 50 ) DEFAULT NULL ,
    `us_last_update` VARCHAR( 20 ) DEFAULT NULL ,
    `us_datapath` VARCHAR( 255 ) DEFAULT NULL ,
    `us_datapath_writeable` VARCHAR( 10 ) DEFAULT NULL ,
    `us_advanced_is_readable` VARCHAR( 10 ) DEFAULT NULL ,
    `us_base_url` VARCHAR( 255 ) DEFAULT NULL ,

    `apache_os` VARCHAR( 50 ) DEFAULT NULL ,
    `apache_on_host` VARCHAR( 100 ) DEFAULT NULL ,
    `apache_on_port` VARCHAR( 10 ) DEFAULT NULL ,
    `apache_version` VARCHAR( 50 ) DEFAULT NULL ,

    `php_version` VARCHAR( 50 ) DEFAULT NULL ,

    `mysql_version` VARCHAR( 50 ) DEFAULT NULL ,
    `mysql_sql_mode` VARCHAR( 255 ) DEFAULT NULL ,
    `mysql_on_host` VARCHAR( 100 ) DEFAULT NULL ,
    `mysql_on_port` VARCHAR( 10 ) DEFAULT NULL ,
    `mysql_database` VARCHAR( 50 ) DEFAULT NULL ,
    `tempmysql_on_host` VARCHAR( 100 ) DEFAULT NULL ,
    `tempmysql_on_port` VARCHAR( 10 ) DEFAULT NULL ,
    `tempmysql_database` VARCHAR( 50 ) DEFAULT NULL ,
    
    `java_path` VARCHAR( 255 ) DEFAULT NULL ,
    `java_executable` VARCHAR( 10 ) DEFAULT NULL ,
    `java_version` VARCHAR( 100 ) DEFAULT NULL ,

    `libre_path` VARCHAR( 255 ) DEFAULT NULL ,
    `libre_temppath` VARCHAR( 10 ) DEFAULT NULL ,
    `libre_executable` VARCHAR( 10 ) DEFAULT NULL ,

    `proxy_host` VARCHAR( 100 ) DEFAULT NULL ,
    `proxy_port` VARCHAR( 10 ) DEFAULT NULL ,
    `proxy_reachable` VARCHAR( 10 ) DEFAULT NULL ,

    `mof_installed` VARCHAR( 10 ) DEFAULT NULL ,
    `mof_version` VARCHAR( 50 ) DEFAULT NULL ,
    `mof_as_server` VARCHAR( 10 ) DEFAULT NULL ,
    `mof_server_version` VARCHAR( 255 ) DEFAULT NULL ,
    `mof_server_reachable` VARCHAR( 10 ) DEFAULT NULL ,

    `enough_diskspace` VARCHAR( 10 ) DEFAULT NULL
) ENGINE=';
    DECLARE sql2 TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;';

    SELECT GetStorageEngine ('ARCHIVE') INTO @engineInnoDBorArchive;
    SET @s = CONCAT(sql1, @engineInnoDBorArchive, sql2);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    CALL us_add_to_table2('system_modifications_log', 'apache_user', 'VARCHAR( 50 ) DEFAULT NULL AFTER `apache_os`' );

    SET @s2 = 'ALTER TABLE `system_modifications_log` CHANGE COLUMN `apache_version` `apache_version` VARCHAR( 150 ) DEFAULT NULL;';
    PREPARE stmt2 FROM @s2;
    EXECUTE stmt2;

END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Migrate projekte to lut_measurements
--
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_projekte_to_lut_measurements;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_projekte_to_lut_measurements()
BEGIN

    IF NOT EXISTS( (SELECT * FROM lut_measurements) ) THEN
        PREPARE stmt1 FROM '
            INSERT INTO lut_measurements (project_id, measurement_id, value) 
            SELECT LfdNr, MessSize_LfdNr, MessSize_Value
            FROM projekte WHERE MessSize_LfdNr>0 AND MessSize_Value IS NOT NULL
        ';
        EXECUTE stmt1;
    END IF;

END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Cleans project paths - UNUSED AT THE MOMENT BUT MAY BE USEFUL SOMEDAY
--
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_clean_project_paths;
-- EOC

DELIMITER $$
CREATE PROCEDURE us_clean_project_paths()
BEGIN
    DECLARE x_fields TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci 
        DEFAULT 'path_correspondence,path_correspondence_default,path_inbox,path_inbox_default,path_outbox,path_outbox_default,path_drawings,path_drawings_default,orig_structure_tree_root_node,orig_translated_structure_tree_root_node';
    DECLARE current_field TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '';
    
    SET x_fields = concat(x_fields, ',');
    WHILE (LOCATE(',', x_fields) > 0)
    DO
        SET current_field = LEFT(x_fields, LOCATE(',',x_fields) - 1);    
        SET x_fields = SUBSTRING(x_fields, LOCATE(',',x_fields) + 1);

        SET @sql = CONCAT('UPDATE projects SET ',current_field,' = REPLACE(',current_field,', "\\\\", "/")
                WHERE (',current_field,' LIKE "./%" OR ',current_field,' LIKE "/%") AND ',current_field,' NOT LIKE "//%";');
        PREPARE stmt FROM @sql;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;					

        SET @sql = CONCAT('UPDATE projects SET ',current_field,' = CONCAT(TRIM(TRAILING "/" FROM ',current_field,'), "/")
                WHERE (',current_field,' LIKE "./%" OR ',current_field,' LIKE "/%") AND ',current_field,' NOT LIKE "//%";');
        PREPARE stmt FROM @sql;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;

        SET @sql = CONCAT('UPDATE projects SET ',current_field,' = REPLACE(',current_field,', "/", "\\\\")
                WHERE ',current_field,' LIKE "%\\\\\%" OR ',current_field,' REGEXP "^[a-zA-Z]" OR ',current_field,' LIKE "//%";');
        PREPARE stmt FROM @sql;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;

        SET @sql = CONCAT('UPDATE projects SET ',current_field,' = CONCAT(TRIM(TRAILING "\\\\" FROM ',current_field,'), "\\\\")
                WHERE ',current_field,' LIKE "%\\\\\%";');
        PREPARE stmt FROM @sql;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
    END WHILE;
END $$
DELIMITER ;
-- EOC


-- --------------------------------------------------------------------------------------------------
-- Create cache_project_measurement
--
-- Set either filter_project_id_from and filter_project_id_to to a project ID     OR
-- filter_project_id_from=1 AND filter_project_id_from=~0 >> 33
-- ~0 >> 33 equeals max value for signed integer
-- always add parameter @validate_outinfo
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_create_cache_project_measurement;
-- EOC

DELIMITER $$
CREATE PROCEDURE us_create_cache_project_measurement(IN filter_project_id_from INTEGER, IN filter_project_id_to INTEGER, OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci)
BEGIN

    DECLARE xproject_id INTEGER;
    DECLARE xvalue DOUBLE;
    DECLARE xname VARCHAR(50) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE xname1 VARCHAR(50) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE xname2 VARCHAR(50) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE xname3 VARCHAR(50) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE xname4 VARCHAR(50) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE xname5 VARCHAR(50) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE l_last_row_fetched INTEGER;

    DECLARE measurements CURSOR FOR
        SELECT 
		lm.project_id,
		lm.value,
		m.name,
		lam1.name AS trans_name1,
		lam2.name AS trans_name2,
		lam3.name AS trans_name3,
		lam4.name AS trans_name4,
		lam5.name AS trans_name5

	FROM
		lut_measurements as lm
			LEFT JOIN
		measurements AS m ON lm.measurement_id = m.id
			LEFT JOIN
		langs_measurements AS lam1 ON lm.measurement_id = lam1.measurements_id AND lam1.language='german'
			LEFT JOIN
		langs_measurements AS lam2 ON lm.measurement_id = lam2.measurements_id AND lam2.language='germanarch'
			LEFT JOIN
		langs_measurements AS lam3 ON lm.measurement_id = lam3.measurements_id AND lam3.language='germanch'
			LEFT JOIN
		langs_measurements AS lam4 ON lm.measurement_id = lam4.measurements_id AND lam4.language='english'
			LEFT JOIN
		langs_measurements AS lam5 ON lm.measurement_id = lam5.measurements_id AND lam5.language='french'
        WHERE lm.project_id BETWEEN filter_project_id_from AND filter_project_id_to;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    SET @query_rem = CONCAT('DELETE FROM cache_project_measurement WHERE project_id BETWEEN ',filter_project_id_from,' AND ',filter_project_id_to);
    PREPARE stmt_rem FROM @query_rem;
    EXECUTE stmt_rem;
    DEALLOCATE PREPARE stmt_rem;
    
    SET @query = '
        INSERT INTO cache_project_measurement SET project_id=?, 
            name_german=?,
            name_germanarch=?,
            name_germanch=?,
            name_english=?,
            name_french=? 
        ON DUPLICATE KEY UPDATE 
            name_german=LEFT( CONCAT(name_german, ", ", ?), 480),
            name_germanarch=LEFT( CONCAT(name_germanarch, ", ", ?), 480),
            name_germanch=LEFT( CONCAT(name_germanch, ", ", ?), 480),
            name_english=LEFT( CONCAT(name_english, ", ", ?), 480),
            name_french=LEFT( CONCAT(name_french, ", ", ?), 480)
    ';
    PREPARE stmt FROM @query;

    SET l_last_row_fetched=0;
    OPEN measurements;
    cursor_loop: LOOP -- -------------------------------------
        FETCH measurements INTO xproject_id, xvalue, xname, xname1, xname2, xname3, xname4, xname5;

        -- Catch error, when a measurement was deleted. Should only happen on internal demo test server
        SET xname = IFNULL(xname, ' ');

        IF l_last_row_fetched=1 THEN
                LEAVE cursor_loop;
        END IF;
        
        SET @project_id=xproject_id;
        SET @name1=CONCAT(  ROUND(xvalue),  ' ',    LEFT(IFNULL(xname1, xname), 15));
        SET @name2=CONCAT(  ROUND(xvalue),  ' ',    LEFT(IFNULL(xname2, xname), 15));
        SET @name3=CONCAT(  ROUND(xvalue),  ' ',    LEFT(IFNULL(xname3, xname), 15));
        SET @name4=CONCAT(  ROUND(xvalue),  ' ',    LEFT(IFNULL(xname4, xname), 15));
        SET @name5=CONCAT(  ROUND(xvalue),  ' ',    LEFT(IFNULL(xname5, xname), 15));
        EXECUTE stmt USING @project_id, 
            @name1, @name2, @name3, @name4, @name5,
            @name1, @name2, @name3, @name4, @name5;

    END LOOP cursor_loop; -- -------------------------------------
    CLOSE measurements;
    SET l_last_row_fetched=0;

    DEALLOCATE PREPARE stmt;

    SET validation_string = 'true';
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Add PRIMARY and AUTO_INCREMENT to table, if not exists
--
-- tablename    Table name
-- fieldname    Field name
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_add_pk_auto_increment;
-- EOC

DELIMITER $$
CREATE PROCEDURE us_add_pk_auto_increment(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN fieldname VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
IF NOT EXISTS (
        SELECT NULL FROM information_schema.TABLE_CONSTRAINTS WHERE
        CONSTRAINT_SCHEMA = DATABASE() AND
        CONSTRAINT_TYPE = 'PRIMARY KEY' AND
        TABLE_NAME = tablename
    ) THEN
    -- recreate id column with PK if PK is not set
    
    SET @s = CONCAT('ALTER TABLE ', tablename, ' DROP ', fieldname);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    SET @s = CONCAT('ALTER TABLE ', tablename, ' ADD COLUMN ', fieldname, ' INT NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST');
    PREPARE stmt2 FROM @s;
    EXECUTE stmt2;
ELSE
    -- just add AUTO_INCREMENT if not set
    SET @s = CONCAT('ALTER TABLE ', tablename, ' CHANGE COLUMN ', fieldname, ' ', fieldname, ' INT NOT NULL AUTO_INCREMENT FIRST');
    PREPARE stmt3 FROM @s;
    EXECUTE stmt3;
END IF;
END $$
DELIMITER ;
-- EOC


-- --------------------------------------------------------------------------------------------------
-- Add AUTO_INCREMENT to table, if not exists
--
-- tablename    Table name
-- fieldname    Field name
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_add_auto_increment;
-- EOC

DELIMITER $$
CREATE PROCEDURE us_add_auto_increment(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN fieldname VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
IF NOT EXISTS (
        SELECT NULL FROM information_schema.TABLE_CONSTRAINTS WHERE
        CONSTRAINT_SCHEMA = DATABASE() AND
        CONSTRAINT_TYPE = 'PRIMARY KEY' AND
        TABLE_NAME = tablename
    ) THEN
    -- no recreate id column with PK if PK is not set
    CALL raise_error__Missing_PRIMARY_to_set_AUTO_INCREMENT;
ELSE
    -- just add AUTO_INCREMENT if not set
    SET @s = CONCAT('ALTER TABLE ', tablename, ' CHANGE COLUMN ', fieldname, ' ', fieldname, ' INT NOT NULL AUTO_INCREMENT FIRST');
    PREPARE stmt3 FROM @s;
    EXECUTE stmt3;
END IF;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Fill the crm_data_table with values from outbox, inbox and address_desc
-- --------------------------------------------------------------------------------------------------

DROP PROCEDURE IF EXISTS us_fill_crm_table;
-- EOC
DROP TABLE IF EXISTS crm_data_table;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Change name of column
-- --------------------------------------------------------------------------------------------------

DROP PROCEDURE IF EXISTS check_if_column_exists;
-- EOC
DROP PROCEDURE IF EXISTS check_rename_column_exists;
-- EOC
DELIMITER $$
CREATE PROCEDURE check_rename_column_exists(
    tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    column_name_old VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    column_name_new VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    column_type VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
begin
    IF EXISTS((SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() and table_name = tablename and COLUMN_NAME LIKE column_name_old)) THEN
        IF EXISTS( (SELECT * FROM information_schema.STATISTICS WHERE table_schema = DATABASE() AND TABLE_NAME=tablename AND INDEX_TYPE='FULLTEXT') ) THEN
            CALL us_drop_all_fulltext_indexes_if_exists(tablename);
        END IF;

        SET @s = CONCAT('ALTER TABLE `', tablename, '` CHANGE COLUMN `', column_name_old, '` `', column_name_new, '` ', column_type);
        PREPARE stmt2 FROM @s;
        EXECUTE stmt2;
    END IF;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Change column
--
-- @todo If the field already exists and there is a fulltext index, this method will always remove the fulltest index. 
-- Either always catch such calls or improve this procedure to not always remove the fulltext index.
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS change_column;
-- EOC
DELIMITER $$
CREATE PROCEDURE change_column(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN fieldname VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN fieldtype VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    IF EXISTS( (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() and table_name=tablename and COLUMN_NAME LIKE fieldname) ) THEN
        IF EXISTS( (SELECT * FROM information_schema.STATISTICS WHERE table_schema = DATABASE() AND TABLE_NAME=tablename AND INDEX_TYPE='FULLTEXT') ) THEN
            CALL us_drop_all_fulltext_indexes_if_exists(tablename);
        END IF;

        SET @s = CONCAT('ALTER TABLE `', tablename, '` MODIFY COLUMN `', fieldname, '` ', fieldtype);
        PREPARE stmt FROM @s;
        EXECUTE stmt;
    END IF;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Remove column
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS remove_column;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_column(
    tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    column_name_old VARCHAR (255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
begin
    IF EXISTS((SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() and table_name = tablename and COLUMN_NAME LIKE column_name_old)) THEN
        SET @s = CONCAT('ALTER TABLE `', tablename, '` DROP COLUMN `', column_name_old, '`');
        PREPARE stmt2 FROM @s;
        EXECUTE stmt2;
    END IF;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Remove column which is a PRIMARY KEY
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS remove_pk_column;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_pk_column(
    tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    column_name_old VARCHAR (255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
begin
    IF EXISTS((SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() and table_name = tablename and COLUMN_NAME LIKE column_name_old)) THEN
        SET @s = CONCAT('ALTER TABLE `', tablename, '` DROP COLUMN `', column_name_old, '`, DROP PRIMARY KEY');
        PREPARE stmt2 FROM @s;
        EXECUTE stmt2;
    END IF;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Procedures for lut_staff_proj
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS convert_lut_staff_proj_to_new_format;
-- EOC
DELIMITER $$
CREATE PROCEDURE convert_lut_staff_proj_to_new_format()
convert_lut_staff_proj_to_new_formatlbl:BEGIN
    DECLARE lut_item_id INT;
    DECLARE lut_project_id INT;
    DECLARE lut_project_grp_id INT;
    
    DECLARE lutDone INT;
    DECLARE lutCurs CURSOR FOR SELECT id, project_id, project_grp_id FROM lut_staff_proj;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET lutDone = 1;
    
    -- Check if table has old fields
    IF NOT (EXISTS((SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() and table_name = 'lut_staff_proj' and COLUMN_NAME LIKE 'project_id')) AND
        EXISTS((SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() and table_name = 'lut_staff_proj' and COLUMN_NAME LIKE 'project_grp_id'))) THEN
        LEAVE convert_lut_staff_proj_to_new_formatlbl;
    END IF;
    
    -- Move old data to new fields
    OPEN lutCurs;
    SET lutDone = 0;
    REPEAT
        SET lut_item_id = NULL;
        SET lut_project_id = NULL;
        SET lut_project_grp_id = NULL;
        
        FETCH lutCurs INTO lut_item_id, lut_project_id, lut_project_grp_id;
        
        IF (lut_item_id IS NOT NULL) THEN
            IF (lut_project_grp_id IS NOT NULL AND lut_project_grp_id > 0) THEN
                -- item_type=2 | project group
                UPDATE lut_staff_proj SET item_id=lut_project_grp_id, item_type=2 WHERE id=lut_item_id;
            ELSEIF (lut_project_id IS NOT NULL AND lut_project_id > 0) THEN
                -- item_type=1 | project
                UPDATE lut_staff_proj SET item_id=lut_project_id, item_type=1 WHERE id=lut_item_id;
            END IF;
        END IF;
    UNTIL lutDone END REPEAT;
    CLOSE lutCurs;
    
    -- Remove old fields
    CALL remove_column('lut_staff_proj', 'project_id');
    CALL remove_column('lut_staff_proj', 'project_grp_id');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_project_managers_to_lut_staff_proj;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_project_managers_to_lut_staff_proj()
add_project_managers_to_lut_staff_projlbl:BEGIN
    DECLARE project_id INT;
    DECLARE project_manager_staff_id INT;
    DECLARE project_division_staff_id INT;
    
    DECLARE projDone INT;
    DECLARE projCurs CURSOR FOR SELECT id, project_manager_id, division_manager_id FROM projects;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET projDone = 1;
    
    IF ( (SELECT COUNT(*) FROM lut_staff_proj) > 0) THEN
        LEAVE add_project_managers_to_lut_staff_projlbl;
    END IF;
    
    OPEN projCurs;
    SET projDone = 0;
    REPEAT
        SET project_id = NULL;
        SET project_manager_staff_id = NULL;
        SET project_division_staff_id = NULL;
        
        FETCH projCurs INTO project_id, project_manager_staff_id, project_division_staff_id;
        
        IF (project_id IS NOT NULL AND project_id > 0) THEN 
            IF (project_manager_staff_id IS NOT NULL AND project_manager_staff_id > 0) THEN
                INSERT INTO lut_staff_proj(`staff_id`, `staff_type`, `item_id`, `item_type`)
                VALUES(project_manager_staff_id, 1, project_id, 1);
            ELSEIF (project_division_staff_id IS NOT NULL AND project_division_staff_id > 0) THEN
                INSERT INTO lut_staff_proj(`staff_id`, `staff_type`, `item_id`, `item_type`)
                VALUES(project_division_staff_id, 2, project_id, 1);
            END IF;
        END IF;
    UNTIL projDone END REPEAT;
    CLOSE projCurs;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- PROCEDURES for the nested sets
-- --------------------------------------------------------------------------------------------------

-- INSERT new node

DROP PROCEDURE IF EXISTS us_insert_work_package_presets;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_insert_work_package_presets(
    IN parent_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN new_name VARCHAR(203) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN is_purpose BOOLEAN, IN is_special INTEGER, IN is_special_phase INTEGER, IN is_fee_area BOOLEAN, IN threshold DOUBLE, 
    IN is_extern BOOLEAN, IN cost_centre_id INTEGER, IN tag_id INTEGER, 
    IN description LONGTEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
    IN new_number VARCHAR(20) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    OUT insert_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
--   DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
--     BEGIN
--         ROLLBACK;
--         SET autocommit=1;
--     END;

        /* SET by SELECT */
        SELECT rgt, tree_id 
            INTO @myRight, @myTreeId
            FROM work_package_presets WHERE id = parent_id;

--     SET autocommit=0;
--     START TRANSACTION;
        SET @unique_wp_table_name = replace(CONCAT('work_packages_tmp_', UUID()), '-', '');
        SET @s = CONCAT('CREATE TEMPORARY TABLE IF NOT EXISTS ', @unique_wp_table_name, ' AS (SELECT id AS wp_id, lft, rgt, tree_id FROM work_package_presets WHERE ((rgt >=',@myRight,') 
                        OR (lft >=', @myRight,')) AND tree_id = ', @myTreeId, ')');
        PREPARE stmt1 FROM @s;
        EXECUTE stmt1;

        UPDATE work_package_presets SET lft=lft+1000000 WHERE lft >= @myRight AND tree_id = @myTreeId;
        UPDATE work_package_presets SET rgt=rgt+1000000 WHERE rgt >= @myRight AND tree_id = @myTreeId;

        SET @s = CONCAT('UPDATE ', @unique_wp_table_name, ' SET rgt = rgt + 2 WHERE rgt >=', @myRight, ' AND tree_id = ', @myTreeId);
        PREPARE stmt2 FROM @s;
        EXECUTE stmt2;

        SET @s = CONCAT('UPDATE ', @unique_wp_table_name, ' SET lft = lft + 2 WHERE lft >=', @myRight, ' AND tree_id = ', @myTreeId);
        PREPARE stmt3 FROM @s;
        EXECUTE stmt3;

        INSERT INTO work_package_presets(name, lft, rgt, tree_id, is_purpose_required, is_special, is_special_phase, is_fee_area, threshold, is_extern, cost_centre_id, tag_id, description, wp_number) VALUES(new_name, @myRight, @myRight + 1, @myTreeId, is_purpose, is_special, is_special_phase, is_fee_area, threshold, is_extern, cost_centre_id, tag_id, description, new_number);

        SET insert_id = LAST_INSERT_ID();

        SET @s = CONCAT('UPDATE work_package_presets wp INNER JOIN ', @unique_wp_table_name, ' wp_tmp ON wp.id = wp_tmp.wp_id SET wp.lft = wp_tmp.lft, wp.rgt = wp_tmp.rgt');
        PREPARE stmt4 FROM @s;
        EXECUTE stmt4;

        SET @s = CONCAT('DROP TABLE ', @unique_wp_table_name);
        PREPARE stmt5 FROM @s;
        EXECUTE stmt5;
--     COMMIT;
--     SET autocommit=1;
END $$
DELIMITER ;
-- EOC

-- DELETE  node

DROP PROCEDURE IF EXISTS us_delete_work_package;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_delete_work_package(
    IN tableName VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN tree_project VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN wp_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
us_delete_work_packagelbl:BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    BEGIN
        ROLLBACK;
        SET autocommit=1;
    END;

    -- Check of we have data to delete
    SET @s = CONCAT('SELECT count(*) INTO @rowsCount FROM ', tableName, ' WHERE id = ', wp_id);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    IF (@rowsCount < 1) THEN
        LEAVE us_delete_work_packagelbl;
    END IF;

    -- Get data to delete
    SET @s = CONCAT('SELECT lft, rgt, rgt - lft + 1, ', tree_project, ' INTO @myLeft, @myRight, @myWidth, @myTreeId FROM ', tableName, ' WHERE id = ', wp_id);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    SET autocommit=0;
    START TRANSACTION;

        SET @s = CONCAT('DELETE FROM ', tableName, ' WHERE lft = ', @myLeft, ' AND ', tree_project, ' = ', @myTreeId);
        PREPARE stmt2 FROM @s;
        EXECUTE stmt2;

        SET @unique_wp_table_name = replace(CONCAT('work_packages_tmp_', UUID()), '-', '');
        SET @s = CONCAT('CREATE TEMPORARY TABLE IF NOT EXISTS ', @unique_wp_table_name, ' AS (SELECT id AS wp_id, lft, rgt, ', tree_project, ' FROM ', tableName, ' WHERE ((rgt >=',@myRight,') 
                        OR (lft >=', @myRight,')) AND ', tree_project, '  = ', @myTreeId, ')');
        PREPARE stmt3 FROM @s;
        EXECUTE stmt3;

        SET @s = CONCAT('UPDATE ', tableName, ' SET rgt=rgt+1000000 WHERE rgt >', @myRight, ' AND ', tree_project, '  = ', @myTreeId);
        PREPARE stmt4 FROM @s;
        EXECUTE stmt4;

        SET @s = CONCAT('UPDATE ', tableName, ' SET lft=lft+1000000 WHERE rgt >', @myRight, ' AND ', tree_project, '  = ', @myTreeId);
        PREPARE stmt5 FROM @s;
        EXECUTE stmt5;

        SET @s = CONCAT('UPDATE ', @unique_wp_table_name, ' SET rgt = rgt - 2 WHERE rgt >', @myRight, ' AND ', tree_project, '  = ', @myTreeId);
        PREPARE stmt6 FROM @s;
        EXECUTE stmt6;

        SET @s = CONCAT('UPDATE ', @unique_wp_table_name, ' SET lft = lft - 2 WHERE lft >', @myRight, ' AND ', tree_project, '  = ', @myTreeId);
        PREPARE stmt7 FROM @s;
        EXECUTE stmt7;

        SET @s = CONCAT('UPDATE ', tableName, ' wp INNER JOIN ', @unique_wp_table_name, ' wp_tmp ON wp.id = wp_tmp.wp_id SET wp.lft = wp_tmp.lft, wp.rgt = wp_tmp.rgt');
        PREPARE stmt8 FROM @s;
        EXECUTE stmt8;

        SET @s = CONCAT('DROP TABLE ', @unique_wp_table_name);
        PREPARE stmt9 FROM @s;
        EXECUTE stmt9;

    COMMIT;
    SET autocommit=1;
    SET validation_string = 'true';	
END $$
DELIMITER ;
-- EOC


-- DELETE parent including all children
DROP PROCEDURE IF EXISTS us_delete_work_package_branch;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_delete_work_package_branch(
    IN tableName VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN tree_project VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN parent_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
us_delete_work_package_branchlbl:BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    BEGIN
        ROLLBACK;
        SET autocommit=1;
    END;
    SET autocommit=0;
    START TRANSACTION;

    -- Check of we have data to delete
    SET @s = CONCAT('SELECT count(*) INTO @rowsCount FROM ', tableName, ' WHERE id = ', wp_id);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    IF (@rowsCount < 1) THEN
        LEAVE us_delete_work_package_branchlbl;
    END IF;

    -- Get data to delete
    SET @s = CONCAT('SELECT  lft, rgt, rgt - lft + 1, ', tree_project, 'INTO @myLeft, @myRight, @myWidth,  @myTreeId FROM ', tableName, ' WHERE id = ', parent_id);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    SET @s = CONCAT('DELETE FROM ', tableName, ' WHERE ', tree_project, ' = ', @myTreeId, ' AND lft BETWEEN ', @myLeft, ' AND ', @myRight);
    PREPARE stmt2 FROM @s;
    EXECUTE stmt2;

    SET @s = CONCAT('UPDATE ', tableName, ' SET rgt = rgt - ', @myWidth, ' WHERE rgt > ', @myRight, ' AND ', tree_project, ' = ', @myTreeId);
    PREPARE stmt3 FROM @s;
    EXECUTE stmt3;

    SET @s = CONCAT('UPDATE ', tableName, ' SET lft = lft - ', @myWidth, ' WHERE lft > ', @myRight, ' AND ', tree_project, ' = ', @myTreeId);
    PREPARE stmt4 FROM @s;
    EXECUTE stmt4;

    COMMIT;

    SET autocommit=1;
    SET validation_string = 'true';	
END $$
DELIMITER ;
-- EOC


-- DELETE whole tree

DROP PROCEDURE IF EXISTS us_delete_whole_work_package;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_delete_whole_work_package(
    IN tableName VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN tree_project VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN del_tree_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    BEGIN
        ROLLBACK;
        SET autocommit=1;
    END;

    SET autocommit=0;
    START TRANSACTION;

    SET @s = CONCAT('DELETE FROM ', tableName, ' WHERE ', tree_project, ' = ', del_tree_id);
    PREPARE stmt FROM @s;
    EXECUTE stmt;

    COMMIT;
    SET autocommit=1;
END $$
DELIMITER ;
-- EOC

-- MOVE a branch or node inside the same level
DROP PROCEDURE IF EXISTS us_move_work_package;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_move_work_package(
    IN tableName VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN tree_project VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN item_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN neighbour_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN project_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN

    DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    BEGIN
        ROLLBACK;
        SET autocommit=1;
    END;

    SET autocommit=0;
    START TRANSACTION;

    SET @s = CONCAT('SELECT lft, rgt, ', tree_project, ' INTO  @myLeft,  @myRight,  @myTreeId  FROM ', tableName, ' WHERE id = ', item_id, ' AND ', tree_project, ' = ', project_id);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    
    SET @s = CONCAT('SELECT lft, rgt INTO  @myLeft2,  @myRight2 FROM ', tableName,' WHERE id = ', neighbour_id, ' AND ', tree_project, ' = ', project_id);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;


    IF tableName = 'work_package_presets' THEN
        SET @s = CONCAT('SELECT lft, rgt INTO @parentLft, @parentRgt FROM ', tableName, ' WHERE id = us_get_parent_package_preset(', @myTreeId, ', ', item_id, ') AND tree_id = ', project_id);
    ELSE
        SET @s = CONCAT('SELECT lft, rgt INTO @parentLft, @parentRgt FROM ', tableName, ' WHERE id = us_get_parent_package(', @myTreeId, ', ', item_id, ') AND project_id = ', project_id);
    END IF;

    
    PREPARE stmt4 FROM @s;
    EXECUTE stmt4;

    SET @unique_wp_table_name = replace(CONCAT('work_packages_tmp_', UUID()), '-', '');
    SET @s = CONCAT('CREATE TEMPORARY TABLE IF NOT EXISTS ', @unique_wp_table_name, ' AS (SELECT id AS wp_id, lft, rgt, ', tree_project, ' FROM  ', tableName, '  WHERE ((lft BETWEEN ', @myLeft, ' AND ', @myRight, ' OR id = ', item_id, ') 
                    OR (lft BETWEEN ', @myLeft2, ' AND ', @myRight2, ' OR id = ', neighbour_id, ')) AND ', tree_project, ' = ', @myTreeId, ')');
    PREPARE stmt5 FROM @s;
    EXECUTE stmt5;

    SET @s = CONCAT('UPDATE ', tableName, ' SET lft=lft+1000000, rgt=rgt+1000000 WHERE ', tree_project, ' = ', project_id, ' AND (lft BETWEEN ', @myLeft, ' AND ', @myRight, ' AND ', tree_project, ' = ', @myTreeId, ') OR id = ', item_id);
    PREPARE stmt6 FROM @s;
    EXECUTE stmt6;

    SET @s = CONCAT('UPDATE ', tableName, ' SET lft=lft+1000000, rgt=rgt+1000000 WHERE ', tree_project, ' = ', project_id, ' AND (lft BETWEEN ', @myLeft2, ' AND ', @myRight2, ' AND ', tree_project, ' = ', @myTreeId, ') OR id = ', neighbour_id);
    PREPARE stmt7 FROM @s;
    EXECUTE stmt7;

    IF ((@myLeft2 -1 > @parentLft) AND (@myRight + 1 < @parentRgt) AND ((@myLeft NOT BETWEEN @myLeft2 AND @myRight2) AND (@myLeft2 NOT BETWEEN @myLeft AND @myRight))) THEN
	SET @s = CONCAT('UPDATE ', @unique_wp_table_name, ' SET 
        lft=CASE
            WHEN lft = ', @myLeft2, ' OR (lft BETWEEN ', @myLeft2, ' AND ', @myRight2, ')
                THEN lft-(', @myLeft2, '-', @myLeft, ')
            WHEN lft = ', @myLeft, ' OR (lft BETWEEN ', @myLeft, ' AND ', @myRight, ')
                THEN lft+(', @myRight2, '-', @myRight, ')
            ELSE
                lft
            END,
        rgt=CASE
            WHEN rgt = ', @myRight2, ' OR (rgt BETWEEN ', @myLeft2, ' AND ', @myRight2, ')
                THEN rgt-(', @myLeft2, '-', @myLeft, ')
            WHEN rgt = ', @myRight, ' OR (rgt BETWEEN ', @myLeft, ' AND ', @myRight, ')
                THEN rgt+(', @myRight2, '-', @myRight, ')
            ELSE
                rgt
            END
        WHERE ', tree_project, '=', @myTreeId, ' AND lft BETWEEN ', @myLeft, ' AND ', @myRight2);
    END IF;
    PREPARE stmt8 FROM @s;
    EXECUTE stmt8;

    SET @s = CONCAT('UPDATE ', tableName, ' wp INNER JOIN ', @unique_wp_table_name, ' wp_tmp ON wp.id = wp_tmp.wp_id SET wp.lft = wp_tmp.lft, wp.rgt = wp_tmp.rgt');
    PREPARE stmt9 FROM @s;
    EXECUTE stmt9;

    SET @s = CONCAT('DROP TABLE ', @unique_wp_table_name);
    PREPARE stmt10 FROM @s;
    EXECUTE stmt10;

    COMMIT;
    SET autocommit=1;
END $$
DELIMITER ;
-- EOC

-- INSERT into the work package table

-- INSERT new node

DROP PROCEDURE IF EXISTS us_insert_work_package;
-- EOC

-- If you update this PROCEDURE also update us_migrate_11_12_copy_projects_fee_areas_insert
DELIMITER $$
CREATE PROCEDURE us_insert_work_package(
    IN parent_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN new_name VARCHAR(203) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN tag_id INTEGER, IN is_purpose BOOLEAN, IN is_special INTEGER, IN is_special_phase INTEGER, IN is_fee_area BOOLEAN, 
    IN threshold DOUBLE, IN is_extern BOOLEAN, IN cost_centre_id INTEGER, 
    IN description LONGTEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN new_number VARCHAR(20) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN new_status INTEGER, 
    OUT insert_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    BEGIN
        ROLLBACK;
        SET autocommit=1;
    END;

    /* SET by SELECT */
    SELECT rgt, project_id 
        INTO @myRight, @myProjectId
        FROM work_packages WHERE id = parent_id;

    SET autocommit=0;
    START TRANSACTION;
        SET @unique_wp_table_name = replace(CONCAT('work_packages_tmp_', UUID()), '-', '');
        SET @s = CONCAT('CREATE TEMPORARY TABLE IF NOT EXISTS ', @unique_wp_table_name, ' AS (SELECT id AS wp_id, lft, rgt, project_id FROM work_packages WHERE ((rgt >=',@myRight,') 
                        OR (lft >=', @myRight,')) AND project_id = ', @myProjectId, ')');
        PREPARE stmt1 FROM @s;
        EXECUTE stmt1;
        
        UPDATE work_packages SET rgt=rgt+1000000 WHERE rgt >= @myRight AND project_id = @myProjectId;
        UPDATE work_packages SET lft=lft+1000000 WHERE lft >= @myRight AND project_id = @myProjectId;

        SET @s = CONCAT('UPDATE ', @unique_wp_table_name, ' SET rgt = rgt + 2 WHERE rgt >=', @myRight, ' AND project_id = ', @myProjectId);
        PREPARE stmt2 FROM @s;
        EXECUTE stmt2;

        SET @s = CONCAT('UPDATE ', @unique_wp_table_name, ' SET lft = lft + 2 WHERE lft >=', @myRight, ' AND project_id = ', @myProjectId);
        PREPARE stmt3 FROM @s;
        EXECUTE stmt3;

        INSERT INTO work_packages(name, tag_id, lft, rgt, project_id, is_purpose_required, is_special, is_special_phase, is_fee_area, budget_threshold, is_extern, cost_centre_id, description, wp_number, status) VALUES(new_name, tag_id, @myRight, @myRight + 1, @myProjectId, is_purpose, is_special, is_special_phase, is_fee_area, threshold, is_extern, cost_centre_id, description, new_number, new_status);

        SET insert_id = LAST_INSERT_ID();

        SET @s = CONCAT('UPDATE work_packages wp INNER JOIN ', @unique_wp_table_name, ' wp_tmp ON wp.id = wp_tmp.wp_id SET wp.lft = wp_tmp.lft, wp.rgt = wp_tmp.rgt');
        PREPARE stmt4 FROM @s;
        EXECUTE stmt4;

        SET @s = CONCAT('DROP TABLE ', @unique_wp_table_name);
        PREPARE stmt5 FROM @s;
        EXECUTE stmt5;
    COMMIT;
    SET autocommit=1;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- PROCEDURES for the work packages history table
-- --------------------------------------------------------------------------------------------------

DROP PROCEDURE IF EXISTS us_update_work_packages_history;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_update_work_packages_history(IN old_wp_id BIGINT, IN new_wp_id BIGINT, IN fee_area_id BIGINT, OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci)
us_update_work_packages_historylbl:BEGIN    
    DECLARE history_date DATETIME;
    DECLARE l_last_row_fetched INTEGER;
    DECLARE cur_history_date CURSOR FOR SELECT DATE_FORMAT(wph.date, '%Y-%m-%d') AS `date` FROM work_packages_history AS wph WHERE wph.wp_id = old_wp_id GROUP BY wph.date;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    SELECT count(*), lft INTO @cntNewLft, @newLft FROM work_packages WHERE id = new_wp_id;
    SELECT count(*), lft INTO @cntOldLft, @oldLft FROM work_packages WHERE id = old_wp_id;
    SELECT count(*), lft INTO @cntFeeLft, @feeLft FROM work_packages WHERE id = fee_area_id;

    -- Catch no rows
    if @cntNewLft<1 || @cntOldLft<1 || @cntFeeLft<1 THEN
        LEAVE us_update_work_packages_historylbl;
    END IF;

    SET l_last_row_fetched=0;
    OPEN cur_history_date;
    cursor_loop: LOOP -- -------------------------------------
            FETCH cur_history_date INTO history_date;
            IF l_last_row_fetched=1 THEN
                    LEAVE cursor_loop;
            END IF;
            call us_update_wp_work_packages_history(old_wp_id, new_wp_id, fee_area_id, history_date, @newLft, @oldLft, @feeLft);
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  cur_history_date;


    SET validation_string = 'true';	
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS us_update_wp_work_packages_history;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_update_wp_work_packages_history(IN old_wp_id BIGINT, IN new_wp_id BIGINT, IN fee_area_id BIGINT, IN history_date DATETIME, IN newLft BIGINT, IN oldLft BIGINT, IN feeLft BIGINT)
BEGIN    
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    BEGIN
        ROLLBACK;
        SET autocommit=1;
    END;
    SET @myID = NULL;

    SET @s = CONCAT('SELECT IF(count(id) = 0, NULL, id) INTO @myID FROM work_packages_history WHERE wp_id = ', new_wp_id, ' AND `date` = "', history_date, '"');
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    SET @myProjectID = null; 
    SET @myLOC = null; 
    SET @myBudgetProp = null; 
    SET @myBudgetCosts = null; 
    SET @myBudgetHours = null; 
    SET @myBudgetThreshold = null; 
    SET @myFeeCosts = null; 
    SET @myFeeHours = null; 
    SET @myFeeProp = null; 
    IF (SELECT count(*) FROM work_packages_history WHERE wp_id = old_wp_id AND `date` = history_date) > 0 THEN
        SET @s = CONCAT('SELECT project_id, completion_level, budget_proportion, budget_planned_costs, budget_planned_hours, budget_threshold, fee_costs, fee_hours, fee_proportion 
                         INTO @myProjectID, @myLOC, @myBudgetProp, @myBudgetCosts, @myBudgetHours, @myBudgetThreshold, @myFeeCosts, @myFeeHours, @myFeeProp  FROM work_packages_history 
                         WHERE wp_id = ', old_wp_id, ' AND `date` = "', history_date, '"');
        PREPARE stmt2 FROM @s;
        EXECUTE stmt2;
    END IF;

    SET autocommit=0;
    START TRANSACTION;
        IF (@myID IS NOT NULL) THEN 
            SET @s = CONCAT('UPDATE work_packages_history SET completion_level = completion_level+', @myLOC, ', budget_proportion = budget_proportion+', @myBudgetProp, ', budget_planned_costs = budget_planned_costs+', @myBudgetCosts,
                ', budget_planned_hours = budget_planned_hours+', @myBudgetHours, ', budget_threshold = budget_threshold+', @myBudgetThreshold,
                ' WHERE project_id = ', @myProjectID, ' AND `date` = "', history_date, '" AND (wp_id IN (SELECT id FROM work_packages WHERE (',newLft,' > lft AND ',newLft,' < rgt) AND project_id = ', @myProjectID, ') OR wp_id =', new_wp_id, ')');
            PREPARE stmt3 FROM @s;
            EXECUTE stmt3;

            SET @s = CONCAT('UPDATE work_packages_history SET completion_level = completion_level-', @myLOC, ', budget_proportion = budget_proportion-', @myBudgetProp, ', budget_planned_costs = budget_planned_costs-', @myBudgetCosts,
                ', budget_planned_hours = budget_planned_hours-', @myBudgetHours, ', budget_threshold = budget_threshold-', @myBudgetThreshold,
                ' WHERE project_id = ', @myProjectID, ' AND `date` = "', history_date, '" AND wp_id IN (SELECT id FROM work_packages WHERE (',oldLft,' > lft AND ',oldLft,'< rgt) AND project_id = ', @myProjectID, ')');
            PREPARE stmt4 FROM @s;
            EXECUTE stmt4;

            SET @s = CONCAT('DELETE FROM work_packages_history WHERE wp_id = ', old_wp_id, ' AND `date` = "', history_date, '"');
            PREPARE stmt5 FROM @s;
            EXECUTE stmt5;
        END IF;
        IF (@myID IS NULL) THEN
            SET @s = CONCAT('UPDATE work_packages_history SET budget_planned_costs = 0, budget_planned_hours = 0, fee_costs = 0, fee_hours = 0, fee_proportion = 0, wp_id = ', new_wp_id, ' WHERE project_id = ', @myProjectID, ' AND `date` = "', history_date, '" AND wp_id = ', old_wp_id);
            PREPARE stmt6 FROM @s;
            EXECUTE stmt6;

            SET @s = CONCAT('UPDATE work_packages_history SET completion_level = completion_level+', @myLOC, ', budget_proportion = budget_proportion+', @myBudgetProp, ', budget_planned_costs = budget_planned_costs+', @myBudgetCosts,
                ', budget_planned_hours = budget_planned_hours+', @myBudgetHours, ', budget_threshold = budget_threshold+', @myBudgetThreshold,
                ' WHERE project_id = ', @myProjectID, ' AND `date` = "', history_date, '" AND wp_id IN (SELECT id FROM work_packages WHERE (',newLft,' BETWEEN lft AND rgt) AND project_id = ', @myProjectID, ')');
            PREPARE stmt7 FROM @s;
            EXECUTE stmt7;

            SET @s = CONCAT('UPDATE work_packages_history SET completion_level = completion_level-', @myLOC, ', budget_proportion = budget_proportion-', @myBudgetProp, ', budget_planned_costs = budget_planned_costs-', @myBudgetCosts,
                ', budget_planned_hours = budget_planned_hours-', @myBudgetHours, ', budget_threshold = budget_threshold-', @myBudgetThreshold,
                ' WHERE project_id = ', @myProjectID, ' AND `date` = "', history_date, '" AND wp_id IN (SELECT id FROM work_packages WHERE (',oldLft,' > lft AND ',oldLft,'< rgt) AND project_id = ', @myProjectID, ')');
            PREPARE stmt8 FROM @s;
            EXECUTE stmt8;
        END IF;
	COMMIT;
    SET autocommit=1;
    call us_update_fee_wp_work_packages_history(old_wp_id, fee_area_id, history_date, @myFeeCosts, @myFeeHours, @myFeeProp, @myProjectID, oldLft, feeLft);
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS us_update_fee_wp_work_packages_history;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_update_fee_wp_work_packages_history(IN old_wp_id BIGINT, IN fee_area_id BIGINT, IN history_date DATETIME, IN new_fee_costs DOUBLE, IN new_fee_hours DOUBLE, IN fee_prop DOUBLE, IN my_project_id DOUBLE, IN oldLft BIGINT, IN feeLft BIGINT)
BEGIN    
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    BEGIN
        ROLLBACK;
        SET autocommit=1;
    END;

    SET @myID = NULL;

    SET @s = CONCAT('SELECT IF(count(id) = 0, NULL, id) INTO @myID FROM work_packages_history WHERE wp_id = ', fee_area_id, ' AND `date` = "', history_date, '"');
    PREPARE stmt8 FROM @s;
    EXECUTE stmt8;

    SET autocommit=0;
    START TRANSACTION;
        IF (@myID IS NOT NULL) THEN 
            SET @s = CONCAT('UPDATE work_packages_history SET fee_costs = fee_costs+IFNULL(', new_fee_costs,', 0), fee_hours = fee_hours+IFNULL(', new_fee_hours,', 0), fee_proportion = fee_proportion+IFNULL(', fee_prop,', 0)
                 WHERE project_id = ', my_project_id, ' AND `date` = "', history_date, '" AND (wp_id IN (SELECT id FROM work_packages WHERE (',feeLft,' > lft AND ',feeLft,' < rgt) AND project_id = ', my_project_id, ') OR wp_id =', fee_area_id, ')');
            PREPARE stmt9 FROM @s;
            EXECUTE stmt9;

            SET @s = CONCAT('UPDATE work_packages_history SET fee_costs = fee_costs-IFNULL(', new_fee_costs,', 0), fee_hours = fee_hours-IFNULL(', new_fee_hours,', 0), fee_proportion = fee_proportion-IFNULL(', fee_prop,', 0)
                 WHERE project_id = ', my_project_id, ' AND `date` = "', history_date, '" AND wp_id IN (SELECT id FROM work_packages WHERE (',oldLft,' > lft AND ',oldLft,'< rgt) AND project_id = ', my_project_id, ')');
            PREPARE stmt10 FROM @s;
            EXECUTE stmt10;
        END IF;
        IF (@myID IS NULL) THEN
            SET @s = CONCAT('INSERT INTO work_packages_history (project_id, fee_costs, fee_hours, fee_proportion, wp_id, `date`) VALUES (', my_project_id, ', ', new_fee_costs,', ', new_fee_hours,', ', fee_prop,', ', fee_area_id, ', "', history_date, '")');
            PREPARE stmt11 FROM @s;
            EXECUTE stmt11;

            SET @s = CONCAT('UPDATE work_packages_history SET fee_costs = fee_costs+IFNULL(', new_fee_costs,', 0), fee_hours = fee_hours+IFNULL(', new_fee_hours,', 0), fee_proportion = fee_proportion+IFNULL(', fee_prop,', 0)
                 WHERE project_id = ', my_project_id, ' AND `date` = "', history_date, '" AND wp_id IN (SELECT id FROM work_packages WHERE (',feeLft,' > lft AND ',feeLft,' < rgt) AND project_id = ', my_project_id, ')');
            PREPARE stmt12 FROM @s;
            EXECUTE stmt12;

            SET @s = CONCAT('UPDATE work_packages_history SET fee_costs = fee_costs-IFNULL(', new_fee_costs,', 0), fee_hours = fee_hours-IFNULL(', new_fee_hours,', 0), fee_proportion = fee_proportion-IFNULL(', fee_prop,', 0)
                 WHERE project_id = ', my_project_id, ' AND `date` = "', history_date, '" AND wp_id IN (SELECT id FROM work_packages WHERE (',oldLft,' > lft AND ',oldLft,'< rgt) AND project_id = ', my_project_id, ')');
            PREPARE stmt13 FROM @s;
            EXECUTE stmt13;
        END IF;
    COMMIT;
    SET autocommit=1;
END $$
DELIMITER ;
-- EOC

-- Update parent nodes after reassign
DROP PROCEDURE IF EXISTS us_update_wp_budget_after_reassign;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_update_wp_budget_after_reassign(IN new_lft BIGINT, IN budget_costs DOUBLE, IN budget_hours DOUBLE, IN budget_prop DOUBLE, IN old_lft BIGINT, IN act_project_id BIGINT, OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci)
BEGIN
    SET @s = CONCAT('UPDATE work_packages SET budget_proportion=budget_proportion+IFNULL(', budget_prop,', 0), budget_planned_costs=budget_planned_costs+IFNULL(', budget_costs,', 0), budget_planned_hours=budget_planned_hours+IFNULL(',budget_hours,', 0)
     WHERE lft !=',new_lft,' AND (',new_lft,' BETWEEN lft AND rgt) AND project_id = ',act_project_id);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    SET @s1 = CONCAT('UPDATE work_packages SET budget_proportion=budget_proportion-IFNULL(', budget_prop,', 0), budget_planned_costs=budget_planned_costs-IFNULL(', budget_costs,', 0),budget_planned_hours=budget_planned_hours-IFNULL(',budget_hours,', 0) 
     WHERE (',old_lft,' BETWEEN lft AND rgt) AND project_id = ',act_project_id);
    PREPARE stmt2 FROM @s1;
    EXECUTE stmt2;

    SET validation_string = 'true';	
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS us_update_wp_fee_after_reassign;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_update_wp_fee_after_reassign(IN new_lft BIGINT, IN fee_costs DOUBLE, IN fee_hours DOUBLE, IN fee_prop DOUBLE, IN old_lft BIGINT, IN act_project_id BIGINT, OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci)
BEGIN

    SET @s = CONCAT('UPDATE work_packages SET fee_proportion=fee_proportion+IFNULL(', fee_prop,', 0), fee_costs=fee_costs+IFNULL(', fee_costs,', 0), fee_hours=fee_hours+IFNULL(',fee_hours,', 0) 
     WHERE lft !=',new_lft,' AND (',new_lft,' BETWEEN lft AND rgt) AND project_id = ',act_project_id);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    SET @s1 = CONCAT('UPDATE work_packages SET fee_proportion=fee_proportion -IFNULL(', fee_prop,', 0), fee_costs=fee_costs-IFNULL(', fee_costs,', 0),fee_hours=fee_hours-IFNULL(',fee_hours,', 0)
     WHERE (',old_lft,' BETWEEN lft AND rgt) AND project_id = ',act_project_id);
    PREPARE stmt2 FROM @s1;
    EXECUTE stmt2;

    SET validation_string = 'true';	
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- DELETE row and update the costs_sum in lut_fee_areas_offer table
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS change_column_to_old_and_remove_double;
-- EOC
DELIMITER $$
CREATE PROCEDURE change_column_to_old_and_remove_double(
    IN tableName VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN columnName VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
    IN columnType VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    SET @columnNameOld = CONCAT(columnName, '_old');
    
    IF ((SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() and table_name = tableName and COLUMN_NAME = @columnNameOld) > 0) THEN
        IF ((SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() and table_name = tableName and COLUMN_NAME = columnName) > 0) THEN
            CALL remove_column(tableName, columnName);
        END IF;
    ELSE
        IF ((SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() and table_name = tableName and COLUMN_NAME = columnName) > 0) THEN
            -- IF ebinterface_json column exists, rename to old
            CALL check_rename_column_exists(tableName, columnName, @columnNameOld, columnType);
        ELSE
            -- ELSE, create ebinterface_json_old column because of the view
            CALL us_add_to_table2(tableName, @columnNameOld, columnType);
        END IF;
    END IF;
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS convert_old_e_invoice_json_columns;
-- EOC
DELIMITER $$
CREATE PROCEDURE convert_old_e_invoice_json_columns()
BEGIN    
    -- -----Check if json_old columns already exist in fees table-----
    CALL change_column_to_old_and_remove_double('fees', 'ebinterface_json', 'LONGTEXT');
    CALL change_column_to_old_and_remove_double('fees', 'zugferd_json', 'LONGTEXT');
    CALL change_column_to_old_and_remove_double('fees', 'xrechnung_json', 'LONGTEXT');
    CALL change_column_to_old_and_remove_double('fees', 'peppol_json', 'LONGTEXT');
    CALL change_column_to_old_and_remove_double('fees', 'fatturapa_json', 'LONGTEXT');
    CALL change_column_to_old_and_remove_double('fees', 'swissqr_json', 'LONGTEXT');
    -- ---------------------------------------------------------------
    
    -- -----Check if json_old columns already exist in fees_planned table-----
    CALL change_column_to_old_and_remove_double('fees_planned', 'ebinterface_json', 'LONGTEXT');
    CALL change_column_to_old_and_remove_double('fees_planned', 'zugferd_json', 'LONGTEXT');
    CALL change_column_to_old_and_remove_double('fees_planned', 'xrechnung_json', 'LONGTEXT');
    CALL change_column_to_old_and_remove_double('fees_planned', 'peppol_json', 'LONGTEXT');
    CALL change_column_to_old_and_remove_double('fees_planned', 'fatturapa_json', 'LONGTEXT');
    CALL change_column_to_old_and_remove_double('fees_planned', 'swissqr_json', 'LONGTEXT');
    -- ---------------------------------------------------------------
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- DELETE row and update the costs_sum in lut_fee_areas_offer table
-- --------------------------------------------------------------------------------------------------

DROP PROCEDURE IF EXISTS us_update_delete_lut_fee_offer;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_update_delete_lut_fee_offer(
    IN wp_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN    
    DECLARE cur_offer_id INTEGER;
    DECLARE l_last_row_fetched INTEGER;
    DECLARE cur_lut_fee_offers CURSOR FOR SELECT offer_id FROM lut_fee_areas_offer WHERE work_package_id = wp_id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    BEGIN
        ROLLBACK;
        SET autocommit=1;
    END;
    SET autocommit=0;
    START TRANSACTION;

    SET l_last_row_fetched=0;
    OPEN cur_lut_fee_offers;
    cursor_loop: LOOP -- -------------------------------------
            FETCH cur_lut_fee_offers INTO cur_offer_id;
            IF l_last_row_fetched=1 THEN
                    LEAVE cursor_loop;
            END IF;
            /* SET by SELECT */
            SELECT (costs_sum-costs) 
                INTO @newSumCosts
                FROM lut_fee_areas_offer WHERE offer_id = cur_offer_id AND work_package_id = wp_id;
            UPDATE lut_fee_areas_offer SET costs_sum = @newSumCosts WHERE offer_id = cur_offer_id;
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  cur_lut_fee_offers;

    DELETE FROM lut_fee_areas_offer WHERE work_package_id=wp_id;

    COMMIT;
    SET autocommit=1;
    SET validation_string = 'true';	
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Work package maintenance 
-- --------------------------------------------------------------------------------------------------

-- Get the wholes between work packages and delete them
DROP PROCEDURE IF EXISTS repair_wps;
-- EOC
DELIMITER $$
CREATE PROCEDURE repair_wps(    
    IN tableName VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN tree_project VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN myTreeId VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
repair_wpslbl:BEGIN

DECLARE i INTEGER DEFAULT 1;

    SET @s = CONCAT('SET @myCount = (SELECT count(id)*2 FROM ', tableName, ' WHERE ',tree_project,' = ', myTreeId, ')');
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    cursor_loop: LOOP -- -------------------------------------
    IF i > @myCount THEN
        LEAVE cursor_loop;
    END IF;
    
    SET i = i+1;

    SET @s = CONCAT('SET @wp_exists = (SELECT count(*) FROM ', tableName, ' WHERE ',tree_project,' = ', myTreeId, ' AND (lft = ', i, ' OR rgt = ', i, '))');
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    IF @wp_exists = 0 THEN    
        SET @s = CONCAT('SET @curr_lft = (SELECT MIN(lft) FROM ', tableName, ' WHERE ',tree_project,' = ', myTreeId, ' AND lft > ', i, ')');
        PREPARE stmt1 FROM @s;
        EXECUTE stmt1;

        SET @s = CONCAT('SET @curr_rgt = (SELECT MIN(rgt) FROM ', tableName, ' WHERE ',tree_project,' = ', myTreeId, ' AND rgt > ', i, ')');
        PREPARE stmt1 FROM @s;
        EXECUTE stmt1;
        
    	IF @curr_lft < @curr_rgt THEN
            SET @to_del = @curr_lft;
    	ELSE
            SET @to_del = @curr_rgt;
    	END IF;
    	
    	-- PROCEDURE
    	CALL us_delete_not_existing_work_package_branch(tableName, tree_project, i, @to_del-1, myTreeId); 
    END IF;     
    END LOOP cursor_loop; -- -------------------------------------
    SET validation_string = 'true';	
END $$
DELIMITER ;
-- EOC

-- DELETE not existing work packages (simulate branch deletion)
DROP PROCEDURE IF EXISTS us_delete_not_existing_work_package_branch;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_delete_not_existing_work_package_branch(
    IN tableName VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN tree_project VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN myLft VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN myRgt VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN myTreeId VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    BEGIN
        ROLLBACK;
        SET autocommit=1;
    END;
    
    SET @myWidth = myRgt-myLft+1;
    
    SET autocommit=0;
    START TRANSACTION;

    SET @s = CONCAT('UPDATE ', tableName, ' SET rgt = rgt + 1000, lft = lft+1000 WHERE ', tree_project, ' = ', myTreeId);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    SET @s = CONCAT('UPDATE ', tableName, ' SET rgt = (rgt - ', @myWidth, ') - 1000 WHERE rgt > (', myRgt, '+1000) AND ', tree_project, ' = ', myTreeId);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    SET @s = CONCAT('UPDATE ', tableName, ' SET lft = (lft - ', @myWidth, ') - 1000 WHERE lft > (', myRgt, '+1000) AND ', tree_project, ' = ', myTreeId);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    
    SET @s = CONCAT('UPDATE ', tableName, ' SET lft = lft - 1000 WHERE lft > 1000 AND ', tree_project, ' = ', myTreeId);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    
    SET @s = CONCAT('UPDATE ', tableName, ' SET rgt = rgt - 1000 WHERE rgt > 1000 AND ', tree_project, ' = ', myTreeId);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    COMMIT;

    SET autocommit=1;
END $$
DELIMITER ;
-- EOC

-- UPDATE nodes with no children where rgt-lft > 1
DROP PROCEDURE IF EXISTS us_update_lft_rgt;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_update_lft_rgt(
    IN tableName VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN tree_project VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    BEGIN
        ROLLBACK;
        SET autocommit=1;
    END;
    
    SET autocommit=0;
    START TRANSACTION;

    SET @s = CONCAT('UPDATE ',tableName,' SET rgt = lft + 1
        WHERE
        id IN (SELECT 
            myTable.id
        FROM
            (SELECT 
                wp.id
            FROM
                ',tableName, ' wp
            LEFT JOIN ',tableName,' wp2 ON wp2.',tree_project,' = wp.',tree_project,'
                AND wp2.lft > wp.lft
                AND wp2.rgt < wp.rgt
            WHERE
                wp.rgt - wp.lft > 1
            GROUP BY wp.id
            HAVING COUNT(wp2.id) = 0
            ORDER BY wp.',tree_project,') AS myTable)');
    PREPARE stmt3 FROM @s;
    EXECUTE stmt3;

    COMMIT;

    SET autocommit=1;
    SET validation_string = 'true';	
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Work package parent calculation
-- --------------------------------------------------------------------------------------------------

-- POSSIBLE FIELDS TO UPDATE WITH THIS: budget_proportion, budget_planned_costs, budget_planned_hours
DROP PROCEDURE IF EXISTS recalc_budget_parent;
-- EOC
DELIMITER $$
CREATE PROCEDURE recalc_budget_parent(
    IN field_name VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    SET @s = CONCAT('UPDATE work_packages AS top 
        SET 
    ',field_name,' = (SELECT 
            SUM(chld.',field_name,')
        FROM
            (SELECT 
                ',field_name,', project_id, lft, rgt, is_fee_area
            FROM
                work_packages) AS chld
        WHERE
            top.project_id = chld.project_id
            AND (chld.lft > top.lft
            AND chld.rgt < top.rgt)
            AND chld.rgt - chld.lft = 1)
        WHERE
            top.rgt - top.lft > 1;');
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    SET validation_string = 'true';	
END $$
DELIMITER ;
-- EOC
    
-- POSSIBLE FIELDS TO UPDATE WITH THIS: fee_proportion, fee_costs, fee_hours
DROP PROCEDURE IF EXISTS recalc_fee_parent;
-- EOC
DELIMITER $$
CREATE PROCEDURE recalc_fee_parent(
    IN field_name VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    SET @s = CONCAT('UPDATE work_packages top 
        SET 
        ',field_name,' = (SELECT 
            SUM(chld.',field_name,')
        FROM
            (SELECT 
                ',field_name,',
                project_id,
                lft,
                rgt,
                is_fee_area
            FROM
                work_packages) AS chld
        WHERE
            top.project_id = chld.project_id
            AND (chld.lft > top.lft
            AND chld.rgt < top.rgt) AND chld.is_fee_area = 1)
            WHERE
            top.rgt - top.lft > 1 AND top.is_fee_area = 0;');
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    SET validation_string = 'true';	
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Work package check if fee areas are wrong at the projects
-- --------------------------------------------------------------------------------------------------

-- Check if there are some fee areas missing in a branch
DROP PROCEDURE IF EXISTS create_repair_tempTable;
-- EOC
DELIMITER $$
CREATE PROCEDURE create_repair_tempTable(
    IN temptableName VARCHAR (100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
create_repair_tempTablelbl:BEGIN

	DROP TEMPORARY TABLE IF EXISTS wp_repair_table;

	CREATE TEMPORARY TABLE IF NOT EXISTS wp_repair_table AS (SELECT 
	wp.project_id,
        wp.id,
        wp.lft,
        wp.rgt,
        (wp.rgt-wp.lft) AS diff,
        wp.is_fee_area,
        (COUNT(parent.id) - 1) AS depth,    
        (SELECT 
                id
            FROM
                work_packages wp2
            WHERE
                wp2.lft < wp.lft AND wp2.rgt > wp.rgt
                AND wp2.project_id = wp.project_id
            ORDER BY wp2.rgt - wp.rgt ASC
            LIMIT 1) AS parent_id
            FROM
                work_packages AS wp,
                work_packages AS parent
            WHERE
                wp.lft BETWEEN parent.lft AND parent.rgt
                AND wp.lft > 1
                AND wp.project_id = parent.project_id
            GROUP BY wp.id
            ORDER BY wp.project_id , wp.lft);

    CALL check_fee_area_some_missing(temptableName);
    
    DROP TEMPORARY TABLE IF EXISTS wrong_wps;
END $$
DELIMITER ;
-- EOC

-- Check if there are some fee areas missing in a branch
DROP PROCEDURE IF EXISTS check_fee_area_some_missing;
-- EOC
DELIMITER $$
CREATE PROCEDURE check_fee_area_some_missing(
    IN temptableName VARCHAR (100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
check_fee_area_some_missinglbl:BEGIN
BLOCK1: begin
    DECLARE curr_wp_id INTEGER;
    DECLARE curr_depth INTEGER;
    DECLARE curr_parent INTEGER;
    DECLARE l_last_row_fetched INTEGER;
    DECLARE curr_wps CURSOR FOR SELECT id, depth, parent_id FROM wp_repair_table WHERE is_fee_area = 1 GROUP BY project_id, depth, parent_id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    SET l_last_row_fetched=0;
    OPEN curr_wps;
    cursor_loop: LOOP -- -------------------------------------
        FETCH curr_wps INTO curr_wp_id, curr_depth, curr_parent;
        IF l_last_row_fetched=1 THEN
            LEAVE cursor_loop;
        END IF;

        SET @myParent = curr_parent;

        SET @myDepth = curr_depth;
        
        BLOCK2: BEGIN
            DECLARE curr_wp_id2 INTEGER;
            DECLARE l_last_row_fetched2 INTEGER;
            DECLARE curr_wps2 CURSOR FOR SELECT id FROM wp_repair_table WHERE parent_id = @myParent AND depth=@myDepth AND is_fee_area = 0;
            DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched2=1;

            SET l_last_row_fetched2=0;
            OPEN curr_wps2;
            cursor_loop2: LOOP -- -------------------------------------
                FETCH curr_wps2 INTO curr_wp_id2;
                IF l_last_row_fetched2=1 THEN
                                LEAVE cursor_loop2;
                END IF;

                /* SET by SELECT */
                SELECT (rgt-lft) 
                    INTO @myDistance
                    FROM wp_repair_table WHERE id =  curr_wp_id2;

                IF @myDistance = 1 THEN  
                    /* SET by SELECT */
                    SELECT project_id 
                        INTO @project
                        FROM wp_repair_table WHERE id = curr_wp_id2;

                    SET @s = CONCAT('INSERT INTO ',temptableName,' VALUES(',@project,')');
                    PREPARE stmt1 FROM @s;
                    EXECUTE stmt1;


                    LEAVE cursor_loop2;
                END IF;
            END LOOP cursor_loop2; -- -------------------------------------
        END BLOCK2;
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  curr_wps;
END BLOCK1;
END $$
DELIMITER ;
-- EOC

-- Check if there are too much fee areas in one project
DROP PROCEDURE IF EXISTS check_too_much_fee_areas;
-- EOC
DELIMITER $$
CREATE PROCEDURE check_too_much_fee_areas(
    IN temptableName VARCHAR (100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
check_too_much_fee_areaslbl:BEGIN
    SET @s = CONCAT('INSERT INTO ',temptableName,' (project_id) SELECT  
        project_id
    FROM
        work_packages wp
    WHERE
        (SELECT 
                COUNT(*)
            FROM
                work_packages wp2
            WHERE
                wp.project_id = wp2.project_id
                AND ((wp2.lft > wp.lft AND wp2.rgt < wp.rgt)
                OR (wp2.lft < wp.lft AND wp2.rgt > wp.rgt))
                AND wp2.is_fee_area = 1) > 0
                AND wp.is_fee_area = 1
                AND wp.rgt - wp.lft > 1
    GROUP BY project_id
    ORDER BY project_id , lft');

    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
END $$
DELIMITER ;
-- EOC

-- Check if there are fee areas missing in a branch or in the whole project
DROP PROCEDURE IF EXISTS check_missing_fee_areas;
-- EOC
DELIMITER $$
CREATE PROCEDURE check_missing_fee_areas(
    IN temptableName VARCHAR (100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
check_missing_fee_areaslbl:BEGIN
    SET @s = CONCAT('INSERT INTO ',temptableName,' (project_id) SELECT 
    project_id
    FROM
        work_packages wp
    WHERE
        (SELECT 
                COUNT(*)
            FROM
                work_packages wp2
            WHERE
                wp.project_id = wp2.project_id
                AND ((wp2.lft > wp.lft AND wp2.rgt < wp.rgt)
                OR (wp2.lft < wp.lft AND wp2.rgt > wp.rgt))
                AND wp2.is_fee_area = 1) = 0
                AND wp.is_fee_area = 0
                AND wp.rgt - wp.lft > 1
    GROUP BY project_id
    ORDER BY project_id , lft');

    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS check_nested_set_errors;
-- EOC
DELIMITER $$
CREATE PROCEDURE check_nested_set_errors (
    IN p_table_name VARCHAR(64),
    IN p_group_column VARCHAR(64)
)
BEGIN
    SET @sql = CONCAT(
        'SELECT ',
        p_group_column, ', error_type, SUM(error_count) AS error_count
         FROM (
             /* 1. LFT >= RGT */
             SELECT ',
                 p_group_column, ',
                 ''LFT_GE_RGT'' AS error_type,
                 COUNT(*) AS error_count
             FROM ', p_table_name, '
             WHERE lft >= rgt
             GROUP BY ', p_group_column, '

             UNION ALL

             /* 2. Duplicate LFT/RGT values */
             SELECT ',
                 p_group_column, ',
                 ''DUPLICATE_LFT_RGT_VALUES'' AS error_type,
                 COUNT(*) AS error_count
             FROM (
                 SELECT ', p_group_column, ', lft AS val FROM ', p_table_name, '
                 UNION ALL
                 SELECT ', p_group_column, ', rgt FROM ', p_table_name, '
             ) t
             GROUP BY ', p_group_column, ', val
             HAVING COUNT(*) > 1

             UNION ALL

             /* 3. Gaps in sequence */
             SELECT ',
                 p_group_column, ',
                 ''GAP_IN_LFT_RGT_SEQUENCE'' AS error_type,
                 COUNT(*) AS error_count
             FROM (
                 SELECT ',
                     p_group_column, ',
                     MIN(lft) AS min_lft,
                     MAX(rgt) AS max_rgt,
                     COUNT(*) * 2 AS expected
                 FROM ', p_table_name, '
                 GROUP BY ', p_group_column, '
             ) x
             WHERE min_lft <> 1 OR max_rgt <> expected
             GROUP BY ', p_group_column, '

             UNION ALL

             /* 4. Overlapping nodes */
             SELECT
                 a.', p_group_column, ',
                 ''OVERLAPPING_NODES'' AS error_type,
                 COUNT(*) AS error_count
             FROM ', p_table_name, ' a
             JOIN ', p_table_name, ' b
               ON a.', p_group_column, ' = b.', p_group_column, '
              AND a.id <> b.id
              AND a.lft < b.lft
              AND a.rgt > b.lft
              AND a.rgt < b.rgt
             GROUP BY a.', p_group_column, '
         ) errors
         GROUP BY ', p_group_column, ', error_type
         ORDER BY ', p_group_column, ', error_type'
    );

    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Times/Travels/Extras/Externalexpenses check if calcexp_id has wrong data, if yes delete/unset
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS clear_calcexp_wrong_deduction;
-- EOC

DELIMITER $$
CREATE PROCEDURE clear_calcexp_wrong_deduction()
clear_calcexp_wrong_deductionlbl:BEGIN
    DECLARE temp_id INT;
    DECLARE temp_calcexp_id INT;

    DECLARE temp_times_staff_id INT;
    DECLARE temp_calcexp_date DATETIME;

    BEGIN
        DECLARE calcDone INT;

        DECLARE calcCurs CURSOR FOR SELECT id FROM calculateaccordingexpenditure WHERE project_id IS NULL AND staff_id IS NULL;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET calcDone = 1;

        OPEN calcCurs;
        SET calcDone = 0;
        REPEAT
            SET temp_id = NULL;

            FETCH calcCurs INTO temp_id;

            IF (temp_id IS NOT NULL) THEN
                DELETE FROM calculateaccordingexpenditure WHERE id=temp_id;

                INSERT INTO deletions(`title`, `date`, `item_model`, `item_id`)
                    VALUES('Abrechnung/Calcexp', NOW(), 'calculateaccordingexpenditure', temp_id);
            END IF;
        UNTIL calcDone END REPEAT;
        CLOSE calcCurs;
    END;

    BEGIN
        DECLARE timesDone INT;

        DECLARE timesCurs CURSOR FOR SELECT id, calcexp_id FROM times WHERE calcexp_id IS NOT NULL;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET timesDone = 1;

        OPEN timesCurs;
        SET timesDone = 0;
        REPEAT
            SET temp_id = NULL;
            SET temp_calcexp_id = NULL;

            FETCH timesCurs INTO temp_id, temp_calcexp_id;

            IF (temp_id IS NOT NULL AND temp_calcexp_id IS NOT NULL) THEN
                IF ((SELECT COUNT(*) FROM calculateaccordingexpenditure WHERE id=temp_calcexp_id) = 0) THEN
                    UPDATE times SET calcexp_id=NULL, is_ignore=0 WHERE id=temp_id;
                END IF;
            END IF;
        UNTIL timesDone END REPEAT;
        CLOSE timesCurs;
    END;
    
    BEGIN
        DECLARE times_staffDone INT;

        DECLARE times_staffCurs CURSOR FOR SELECT id, calcexp_id_staff FROM times WHERE calcexp_id_staff IS NOT NULL;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET times_staffDone = 1;

        OPEN times_staffCurs;
        SET times_staffDone = 0;
        REPEAT
            SET temp_id = NULL;
            SET temp_calcexp_id = NULL;

            FETCH times_staffCurs INTO temp_id, temp_calcexp_id;

            IF (temp_id IS NOT NULL AND temp_calcexp_id IS NOT NULL) THEN
                IF ((SELECT COUNT(*) FROM calculateaccordingexpenditure WHERE id=temp_calcexp_id) = 0) THEN
                    UPDATE times SET calcexp_id_staff=NULL, is_ignore=0 WHERE id=temp_id;
                END IF;
            END IF;
        UNTIL times_staffDone END REPEAT;
        CLOSE times_staffCurs;
    END;
    
    BEGIN
        DECLARE times_woaDone INT;

        DECLARE times_woaCurs CURSOR FOR SELECT id, calcexp_id_woa FROM times WHERE calcexp_id_woa IS NOT NULL;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET times_woaDone = 1;

        OPEN times_woaCurs;
        SET times_woaDone = 0;
        REPEAT
            SET temp_id = NULL;
            SET temp_calcexp_id = NULL;

            FETCH times_woaCurs INTO temp_id, temp_calcexp_id;

            IF (temp_id IS NOT NULL AND temp_calcexp_id IS NOT NULL) THEN
                IF ((SELECT COUNT(*) FROM calculateaccordingexpenditure WHERE id=temp_calcexp_id) = 0) THEN
                    UPDATE times SET calcexp_id_woa=NULL, is_ignore=0 WHERE id=temp_id;
                END IF;
            END IF;
        UNTIL times_woaDone END REPEAT;
        CLOSE times_woaCurs;
    END;
    
    BEGIN
        DECLARE extrasDone INT;

        DECLARE extrasCurs CURSOR FOR SELECT id, calcexp_id FROM extras WHERE calcexp_id IS NOT NULL;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET extrasDone = 1;

        OPEN extrasCurs;
        SET extrasDone = 0;
        REPEAT
            SET temp_id = NULL;
            SET temp_calcexp_id = NULL;

            FETCH extrasCurs INTO temp_id, temp_calcexp_id;

            IF (temp_id IS NOT NULL AND temp_calcexp_id IS NOT NULL) THEN
                IF ((SELECT COUNT(*) FROM calculateaccordingexpenditure WHERE id=temp_calcexp_id) = 0) THEN
                    UPDATE extras SET calcexp_id=NULL, is_ignore=0 WHERE id=temp_id;
                END IF;
            END IF;
        UNTIL extrasDone END REPEAT;
        CLOSE extrasCurs;
    END;
    
    BEGIN
        DECLARE travelsDone INT;

        DECLARE travelsCurs CURSOR FOR SELECT id, calcexp_id FROM travels WHERE calcexp_id IS NOT NULL;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET travelsDone = 1;

        OPEN travelsCurs;
        SET travelsDone = 0;
        REPEAT
            SET temp_id = NULL;
            SET temp_calcexp_id = NULL;

            FETCH travelsCurs INTO temp_id, temp_calcexp_id;

            IF (temp_id IS NOT NULL AND temp_calcexp_id IS NOT NULL) THEN
                IF ((SELECT COUNT(*) FROM calculateaccordingexpenditure WHERE id=temp_calcexp_id) = 0) THEN
                    UPDATE travels SET calcexp_id=NULL, is_ignore=0 WHERE id=temp_id;
                END IF;
            END IF;
        UNTIL travelsDone END REPEAT;
        CLOSE travelsCurs;
    END;
    
    BEGIN
        DECLARE externalexpensesDone INT;

        DECLARE externalexpensesCurs CURSOR FOR SELECT id, calcexp_id FROM externalexpenses WHERE calcexp_id IS NOT NULL;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET externalexpensesDone = 1;

        OPEN externalexpensesCurs;
        SET externalexpensesDone = 0;
        REPEAT
            SET temp_id = NULL;
            SET temp_calcexp_id = NULL;

            FETCH externalexpensesCurs INTO temp_id, temp_calcexp_id;

            IF (temp_id IS NOT NULL AND temp_calcexp_id IS NOT NULL) THEN
                IF ((SELECT COUNT(*) FROM calculateaccordingexpenditure WHERE id=temp_calcexp_id) = 0) THEN
                    UPDATE externalexpenses SET calcexp_id=NULL, is_ignore=0 WHERE id=temp_id;
                END IF;
            END IF;
        UNTIL externalexpensesDone END REPEAT;
        CLOSE externalexpensesCurs;
    END;

    BEGIN
        DECLARE times_wrong_staffDone INT;

        DECLARE times_wrong_staffCurs CURSOR FOR SELECT t.id, t.staff_id, c.date FROM times AS t INNER JOIN calculateaccordingexpenditure AS c ON t.calcexp_id_staff=c.id WHERE t.staff_id != c.staff_id;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET times_wrong_staffDone = 1;

        OPEN times_wrong_staffCurs;
        SET times_wrong_staffDone = 0;
        REPEAT
            SET temp_id = NULL;
            SET temp_calcexp_id = NULL;
            SET temp_times_staff_id = NULL;
            SET temp_calcexp_date = NULL;

            FETCH times_wrong_staffCurs INTO temp_id, temp_times_staff_id, temp_calcexp_date;

            IF (temp_id IS NOT NULL AND temp_times_staff_id IS NOT NULL AND temp_calcexp_date IS NOT NULL) THEN
                IF ((SELECT COUNT(*) FROM calculateaccordingexpenditure WHERE staff_id=temp_times_staff_id AND date=temp_calcexp_date) = 0) THEN
                    INSERT INTO calculateaccordingexpenditure(staff_id, date, is_project, is_woa, is_staff) VALUES(temp_times_staff_id, temp_calcexp_date, 0, 0, 1);
                    SET temp_calcexp_id = LAST_INSERT_ID();
                ELSE
                    SELECT id INTO temp_calcexp_id FROM calculateaccordingexpenditure WHERE staff_id=temp_times_staff_id AND date=temp_calcexp_date;
                END IF;

                UPDATE times SET calcexp_id_staff=temp_calcexp_id WHERE id=temp_id;
            END IF;
        UNTIL times_wrong_staffDone END REPEAT;
        CLOSE times_wrong_staffCurs;
    END;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Remove old FULLTEXT
-- --------------------------------------------------------------------------------------------------
-- USC Bereinigung - Remove old FULLTEXT
CALL us_drop_index_if_exists('projekte', 'projects_fulltext');
-- EOC
CALL us_drop_index_if_exists('adressen', 'addresses_fulltext');
-- EOC
CALL us_drop_index_if_exists('adrbeschr', 'address_description_fulltext');
-- EOC
CALL us_drop_index_if_exists('todo', 'opentasks_fulltext');
-- EOC
CALL us_drop_index_if_exists('perstermin', 'personalappointments_fulltext');
-- EOC
CALL us_drop_index_if_exists('planausgabe', 'drawings_outbox_fulltext');
-- EOC
CALL us_drop_index_if_exists('formular', 'correspondence_fulltext');
-- EOC
CALL us_drop_index_if_exists('dateien', 'files_fulltext');
-- EOC

-- --------------------------------------------------------------------------------------------------
-- ADD DEFAULT FULLTEXT INDEXES
-- --------------------------------------------------------------------------------------------------
-- USC Erstelle alle Stored-Procedures - FULLTEXT

DROP PROCEDURE IF EXISTS add_projects_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_projects_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('projekte', 'projekte_fulltext', 'projektnummer, projekt, beschreibung, ort');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_addresses_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_addresses_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('adressen', 'adressen_fulltext', 'name, firma, anrede, titel, master_titel, vorname, ansprechpartner, strasse, strasse2, pltz, ort, land, email, url, comment_main, comment_main_more');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_address_descriptions_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_address_descriptions_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('adrbeschr', 'adrbeschr_fulltext', 'beschreibung');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_opentasks_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_opentasks_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('todo', 'todo_fulltext', 'beschreibung, bemerkung, ErlVermerk');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_externalexpenses_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_externalexpenses_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('externalexpenses', 'externalexpenses_fulltext', 'purpose, description');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_fees_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_fees_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('fees', 'fees_fulltext', 'purpose, fee_no, remit_purpose');
END $$
DELIMITER ;
-- EOC
DROP PROCEDURE IF EXISTS add_fees_planned_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_fees_planned_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('fees_planned', 'fees_planned_fulltext', 'purpose, fee_no, remit_purpose');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_personalappointments_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_personalappointments_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('personalappointments_ext_o365', 'personalappointments_ext_o365_fulltext', 'summary, comment, location, url');
    CALL us_add_fulltext_index_to_table('perstermin', 'perstermin_fulltext', 'summary, bemerkung, ort, url');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_drawings_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_drawings_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('drawings', 'drawings_fulltext', 'plan_no, plan_content, plan_index, sub_plan, redline_remarks, cad_file, plot_file, purpose, clipboard');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_drawings_outbox_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_drawings_outbox_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('planausgabe', 'planausgabe_fulltext', 'bemerkung');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_outbox_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_outbox_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('outbox', 'outbox_fulltext', 'no, content, outbox_index, mail_out_file, attached_file');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_inbox_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_inbox_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('inbox', 'inbox_fulltext', 'no, content, inbox_index, msg_file, attached_file');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_correspondences_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_correspondences_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('formular', 'formular_fulltext', 'betrifft, nurtext, rechnungsnummer');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_files_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_files_default_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('dateien', 'dateien_fulltext', 'pfad, beschreibung');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS add_all_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE add_all_default_fulltext_indexes()
BEGIN
    CALL add_projects_default_fulltext_indexes();
    CALL add_addresses_default_fulltext_indexes();
    CALL add_address_descriptions_default_fulltext_indexes();
    CALL add_opentasks_default_fulltext_indexes();
    CALL add_externalexpenses_default_fulltext_indexes();
    CALL add_fees_default_fulltext_indexes();
    CALL add_fees_planned_default_fulltext_indexes();
    CALL add_personalappointments_default_fulltext_indexes();
    CALL add_drawings_default_fulltext_indexes();
    CALL add_drawings_outbox_default_fulltext_indexes();
    CALL add_outbox_default_fulltext_indexes();
    CALL add_inbox_default_fulltext_indexes();
    CALL add_correspondences_default_fulltext_indexes();
    CALL add_files_default_fulltext_indexes();
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- REMOVE DEFAULT FULLTEXT INDEXES
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS remove_projects_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_projects_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('projekte', 'projekte_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_addresses_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_addresses_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('adressen', 'adressen_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_address_descriptions_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_address_descriptions_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('adrbeschr', 'adrbeschr_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_opentasks_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_opentasks_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('todo', 'todo_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_externalexpenses_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_externalexpenses_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('externalexpenses', 'externalexpenses_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_fees_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_fees_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('fees', 'fees_fulltext');
END $$
DELIMITER ;
-- EOC
DROP PROCEDURE IF EXISTS remove_fees_planned_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_fees_planned_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('fees_planned', 'fees_planned_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_personalappointments_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_personalappointments_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('perstermin', 'perstermin_fulltext');
    CALL us_drop_index_if_exists('personalappointments_ext_o365', 'personalappointments_ext_o365_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_drawings_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_drawings_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('drawings', 'drawings_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_drawings_outbox_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_drawings_outbox_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('planausgabe', 'planausgabe_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_outbox_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_outbox_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('outbox', 'outbox_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_inbox_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_inbox_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('inbox', 'inbox_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_correspondences_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_correspondences_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('formular', 'formular_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_files_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_files_default_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('dateien', 'dateien_fulltext');
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS remove_all_default_fulltext_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE remove_all_default_fulltext_indexes()
BEGIN
    CALL remove_projects_default_fulltext_indexes();
    CALL remove_addresses_default_fulltext_indexes();
    CALL remove_address_descriptions_default_fulltext_indexes();
    CALL remove_opentasks_default_fulltext_indexes();
    CALL remove_externalexpenses_default_fulltext_indexes();
    CALL remove_fees_default_fulltext_indexes();
    CALL remove_fees_planned_default_fulltext_indexes();
    CALL remove_personalappointments_default_fulltext_indexes();
    CALL remove_drawings_default_fulltext_indexes();
    CALL remove_drawings_outbox_default_fulltext_indexes();
    CALL remove_outbox_default_fulltext_indexes();
    CALL remove_inbox_default_fulltext_indexes();
    CALL remove_correspondences_default_fulltext_indexes();
    CALL remove_files_default_fulltext_indexes();
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- ADD ADDITIONAL FULLTEXT INDEXES
-- --------------------------------------------------------------------------------------------------
-- Adress-Emails
DROP PROCEDURE IF EXISTS add_address_emails_fulltext_indexes;
-- EOC

DELIMITER $$
CREATE PROCEDURE add_address_emails_fulltext_indexes()
BEGIN
    CALL us_add_fulltext_index_to_table('address_emails', 'address_emails_fulltext', 'email');
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- REMOVE ADDITIONAL FULLTEXT INDEXES
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS remove_all_addi_fulltext_indexes;
-- EOC

DELIMITER $$
CREATE PROCEDURE remove_all_addi_fulltext_indexes()
BEGIN
    CALL remove_address_emails_fulltext_indexes();
    CALL us_drop_index_if_exists('zusatz_projekt', 'zusatz_projekt_fulltext');
    CALL us_drop_index_if_exists('zusatz_adressen', 'zusatz_adressen_fulltext');
    CALL us_drop_index_if_exists('zusatz_todo', 'zusatz_todo_fulltext');
    CALL us_drop_index_if_exists('zusatz_planverz', 'zusatz_planverz_fulltext');
    CALL us_drop_index_if_exists('zusatz_postein', 'zusatz_postein_fulltext');
    CALL us_drop_index_if_exists('zusatz_postaus', 'zusatz_postaus_fulltext');
    CALL us_drop_index_if_exists('zusatz_formular', 'zusatz_formular_fulltext');
END $$
DELIMITER ;
-- EOC

-- Adress-Emails
DROP PROCEDURE IF EXISTS remove_address_emails_fulltext_indexes;
-- EOC

DELIMITER $$
CREATE PROCEDURE remove_address_emails_fulltext_indexes()
BEGIN
    CALL us_drop_index_if_exists('address_emails', 'address_emails_fulltext');
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- FTS_DOC_ID and old 
-- --------------------------------------------------------------------------------------------------
-- USC Bereinigung - Remove FTS_DOC_ID
DROP PROCEDURE IF EXISTS add_fts_doc_id_to_table;
-- EOC

DROP PROCEDURE IF EXISTS remove_fulltext_indexes_once2;
-- EOC

DELIMITER $$
CREATE PROCEDURE remove_fulltext_indexes_once2()
remove_fulltext_indexes_once2lbl:BEGIN

    -- Prevent double execution
    IF ( SELECT COUNT(*) FROM `01migrate_11_12_steps` WHERE stepname='remove_fulltext_indexes_once2_x4') THEN 
        LEAVE remove_fulltext_indexes_once2lbl;
    END IF;
    INSERT INTO `01migrate_11_12_steps` SET stepname='remove_fulltext_indexes_once2_x4'; 

    CALL remove_all_default_fulltext_indexes();

    DROP TABLE IF EXISTS `fulltext_max_fts_doc_ids`;

    DROP TRIGGER IF EXISTS add_fulltext_projekte_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_projekte_update_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_adressen_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_adressen_update_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_adrbeschr_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_adrbeschr_update_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_todo_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_todo_update_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_externalexpenses_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_externalexpenses_update_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_fees_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_fees_update_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_perstermin_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_perstermin_update_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_drawings_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_drawings_update_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_planausgabe_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_planausgabe_update_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_outbox_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_outbox_update_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_inbox_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_inbox_update_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_formular_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_formular_update_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_dateien_fill_fts_doc_id;
    DROP TRIGGER IF EXISTS add_fulltext_dateien_update_fts_doc_id;

    CALL remove_column('projekte', 'FTS_DOC_ID');
    CALL remove_column('adressen', 'FTS_DOC_ID');
    CALL remove_column('adrbeschr', 'FTS_DOC_ID');
    CALL remove_column('todo', 'FTS_DOC_ID');
    CALL remove_column('externalexpenses', 'FTS_DOC_ID');
    CALL remove_column('fees', 'FTS_DOC_ID');
    CALL remove_column('fees_planned', 'FTS_DOC_ID');
    CALL remove_column('todo', 'FTS_DOC_ID');
    CALL remove_column('externalexpenses', 'FTS_DOC_ID');
    CALL remove_column('fees', 'FTS_DOC_ID');
    CALL remove_column('perstermin', 'FTS_DOC_ID');
    CALL remove_column('drawings', 'FTS_DOC_ID');
    CALL remove_column('planausgabe', 'FTS_DOC_ID');
    CALL remove_column('outbox', 'FTS_DOC_ID');
    CALL remove_column('inbox', 'FTS_DOC_ID');
    CALL remove_column('formular', 'FTS_DOC_ID');
    CALL remove_column('dateien', 'FTS_DOC_ID');

    DELETE FROM settingssystem WHERE SettingType='fulltext_search_activate' AND SettingValue=1;

END $$
DELIMITER ;
-- EOC

CALL remove_fulltext_indexes_once2();
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Check if every project has a top node with lft=1 if not -> insert for such project a top node
-- --------------------------------------------------------------------------------------------------
-- USC Erstelle alle Stored-Procedures - Check project

-- Check if there are too much fee areas in one project
DROP PROCEDURE IF EXISTS check_projects_for_top_node;
-- EOC
DELIMITER $$
CREATE PROCEDURE check_projects_for_top_node(
    IN temptableName VARCHAR (100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
check_projects_for_top_nodelbl:BEGIN
    DECLARE project_ids INTEGER;
    DECLARE project_names VARCHAR(300) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE rgt_values INTEGER;
    DECLARE l_last_row_fetched INTEGER;
    DECLARE project_with_no_topnode CURSOR FOR SELECT 
    projects.id,
    projects.project_name,
    CASE WHEN max(work_packages.rgt) IS NULL THEN 0 ELSE max(work_packages.rgt) END
        FROM
            projects
                LEFT JOIN
            work_packages on work_packages.project_id = projects.id
        WHERE
            projects.id NOT IN (SELECT 
            project_id
        FROM
            work_packages
        GROUP BY project_id)
        OR (projects.id IN (SELECT 
            project_id
        FROM
            work_packages wp
        WHERE
            1 != (SELECT 
                MIN(lft)
            FROM
                work_packages wp2
            WHERE
                wp2.project_id = wp.project_id))) GROUP BY projects.id;
                
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    BEGIN
        ROLLBACK;
        SET autocommit=1;
    END;
    SET autocommit=0;
    START TRANSACTION;

    SET l_last_row_fetched=0;
    OPEN project_with_no_topnode;
    cursor_loop: LOOP -- -------------------------------------
            FETCH project_with_no_topnode INTO project_ids, project_names, rgt_values;
            IF l_last_row_fetched=1 THEN
                    LEAVE cursor_loop;
            END IF;
            IF rgt_values = 0 THEN
                INSERT INTO work_packages (`name`, `lft`, `rgt`, `project_id`) VALUES (project_names, '1', '4', project_ids);
                INSERT INTO work_packages (`name`, `lft`, `rgt`, `project_id`, `is_fee_area`) VALUES ('Standard', '2', '3', project_ids, 1);
            ELSE
                INSERT INTO work_packages (`name`, `lft`, `rgt`, `project_id`) VALUES (project_names, '1', rgt_values+1, project_ids);
            END IF;

    SET @s = CONCAT('INSERT INTO ',temptableName,' (project_id) VALUES (',project_ids,');');
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  project_with_no_topnode;

    COMMIT;
    SET autocommit=1;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Times/Travels/Extras check if wp id belongs to the project, if not update the wrong entries with the first valied wp id (set auto_assigned_wp true for this entries)
-- USC Erstelle alle Stored-Procedures - Times/Travels/Extras check

DROP PROCEDURE IF EXISTS update_wrong_entries;
-- EOC
DELIMITER $$
CREATE PROCEDURE update_wrong_entries(
    IN tableName VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    DECLARE wrong_ids INTEGER;
    DECLARE project_ids INTEGER;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;    
    DECLARE wrong_vals CURSOR FOR SELECT * FROM my_view; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    DROP VIEW IF EXISTS my_view;
    
    IF tableName != 'times' THEN
        SET @mywhere =  CONCAT(' myTable.calcexp_id <= 0 ');
    ELSE
        SET @mywhere =  CONCAT(' myTable.calcexp_id <= 0 AND myTable.calcexp_id_staff <= 0 AND myTable.calcexp_id_woa <= 0');
    END IF;


    SET @s = CONCAT('CREATE VIEW my_view as 
                    SELECT id, project_id FROM ', tableName, ' myTable
                            WHERE
                    work_package_id NOT IN (SELECT id
                            FROM
                    work_packages wp
                            WHERE
                    myTable.project_id = wp.project_id) AND myTable.project_id IS NOT NULL AND myTable.staff_id IS NOT NULL
                            AND
                    ',@mywhere);
                    
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

    OPEN wrong_vals;
    cursor_loop: LOOP -- -------------------------------------
        FETCH wrong_vals INTO wrong_ids, project_ids;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;            
            /*Do something with the row fetched*/
            /* SET by SELECT */
            SELECT id 
                INTO @myWPID
                FROM work_packages WHERE project_id = project_ids AND rgt-lft = 1 LIMIT 1;

            IF @myWPID IS NOT NULL THEN
                SET @s = CONCAT('UPDATE ',tableName,' SET work_package_id = ', @myWPID,', auto_assigned_wp = 2 WHERE id = ', wrong_ids);
                PREPARE stmt2 FROM @s;
                EXECUTE stmt2;
            END IF;
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  wrong_vals;
    
    DROP VIEW IF EXISTS my_view;

    SET validation_string = 'true';	
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS get_wrong_deducted_entries;
-- EOC
DELIMITER $$
CREATE PROCEDURE get_wrong_deducted_entries(
    IN tableName VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN temptableName VARCHAR (100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN    
    IF tableName != 'times' THEN
        SET @mywhere =  CONCAT(' myTable.calcexp_id > 0');
    ELSE
        SET @mywhere =  CONCAT(' (myTable.calcexp_id > 0 OR myTable.calcexp_id_staff > 0 OR myTable.calcexp_id_woa > 0)');
    END IF;

    SET @s = CONCAT('INSERT INTO ',temptableName,' (project_id, staff_id, date) SELECT project_id, staff_id, date FROM ', tableName, ' myTable
                        WHERE
                    work_package_id NOT IN (SELECT id
                        FROM
                    work_packages wp
                        WHERE
                    myTable.project_id = wp.project_id) AND myTable.project_id IS NOT NULL AND myTable.staff_id IS NOT NULL
                        AND
                    ',@mywhere);
                    
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC Remove fulltext main indexes, if needed once X4

DROP PROCEDURE IF EXISTS remove_fulltext_indexes_once;
-- EOC

DELIMITER $$
CREATE PROCEDURE remove_fulltext_indexes_once()
remove_fulltext_indexes_oncelbl:BEGIN

    -- Prevent double execution
    IF ( SELECT COUNT(*) FROM `01migrate_11_12_steps` WHERE stepname='remove_fulltext_indexes_once_x4') THEN 
        LEAVE remove_fulltext_indexes_oncelbl;
    END IF;
    INSERT INTO `01migrate_11_12_steps` SET stepname='remove_fulltext_indexes_once_x4'; 

    CALL remove_all_default_fulltext_indexes();
END $$
DELIMITER ;
-- EOC

CALL remove_fulltext_indexes_once();
-- EOC

-- USC add fulltext main indexes, if active X4
DROP PROCEDURE IF EXISTS add_fulltext_indexes_if_active;
-- EOC

DELIMITER $$
CREATE PROCEDURE add_fulltext_indexes_if_active()
add_fulltext_indexes_if_activelbl:BEGIN

    IF EXISTS ( (SELECT * FROM settingssystem WHERE SettingType='fulltext_search_activate' AND SettingValue=1) ) THEN
        CALL add_all_default_fulltext_indexes();
    END IF;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC Remove fulltext addi indexes, if needed once X4

DROP PROCEDURE IF EXISTS remove_fulltext_addi_indexes_once;
-- EOC

DELIMITER $$
CREATE PROCEDURE remove_fulltext_addi_indexes_once()
remove_fulltext_addi_indexes_oncelbl:BEGIN
    DECLARE cursDone INT;
    
    DECLARE tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE indexname VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE columnnames VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;

    DECLARE curs CURSOR FOR SELECT TABLE_NAME, INDEX_NAME, GROUP_CONCAT(COLUMN_NAME) AS COLUMN_NAMES FROM information_schema.statistics WHERE INDEX_TYPE='FULLTEXT' AND TABLE_SCHEMA = DATABASE() AND (TABLE_NAME LIKE 'zusatz_%' OR TABLE_NAME='address_emails') GROUP BY TABLE_NAME;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET cursDone = 1;

    -- Prevent double execution
    IF ( SELECT COUNT(*) FROM `01migrate_11_12_steps` WHERE stepname='remove_fulltext_addi_indexes_once_x4') THEN 
        LEAVE remove_fulltext_addi_indexes_oncelbl;
    END IF;
    INSERT INTO `01migrate_11_12_steps` SET stepname='remove_fulltext_addi_indexes_once_x4'; 

    OPEN curs;
    SET cursDone = 0;
    REPEAT
        SET tablename = NULL;
        SET indexname = NULL;
        SET columnnames = NULL;
        
        FETCH curs INTO tablename, indexname, columnnames;
        
        IF (tablename IS NOT NULL AND indexname IS NOT NULL AND columnnames IS NOT NULL) THEN
            INSERT INTO cache_fulltext_addi
            VALUES(default, tablename, indexname, columnnames);

            SET @s=CONCAT('ALTER TABLE ', tablename, ' DROP INDEX `', indexname, '`');
            PREPARE stmt1 FROM @s;
            EXECUTE stmt1;
            DEALLOCATE PREPARE stmt1;
        END IF;
    UNTIL cursDone END REPEAT;
    CLOSE curs;
END $$
DELIMITER ;
-- EOC


-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC Recreate fulltext addi indexes, if needed once X4

DROP PROCEDURE IF EXISTS add_addi_columns_once;
-- EOC

DELIMITER $$
CREATE PROCEDURE add_addi_columns_once()
add_addi_columns_oncelbl:BEGIN
    DECLARE cursDone INT;

    DECLARE temp_tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE temp_columnname VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;

    DECLARE curs CURSOR FOR SELECT TABLE_NAME, COLUMN_NAME FROM information_schema.STATISTICS as stats WHERE stats.INDEX_TYPE='FULLTEXT' AND stats.INDEX_SCHEMA=DATABASE() AND stats.INDEX_NAME LIKE '%_addi_fulltext';
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET cursDone = 1;

    -- Prevent double execution
    IF ( SELECT COUNT(*) FROM `01migrate_11_12_steps` WHERE stepname='add_addi_columns_once_x4') THEN 
        LEAVE add_addi_columns_oncelbl;
    END IF;
    INSERT INTO `01migrate_11_12_steps` SET stepname='add_addi_columns_once_x4'; 

    OPEN curs;
    SET cursDone = 0;
    REPEAT
        SET temp_tablename = NULL;
        SET temp_columnname = NULL;
        
        FETCH curs INTO temp_tablename, temp_columnname;
        
        IF (temp_tablename IS NOT NULL AND temp_columnname IS NOT NULL) THEN
            SET @s=CONCAT('UPDATE ', temp_tablename, '_def SET isfulltext=1 WHERE FeldName=\'', temp_columnname, '\'');
            PREPARE stmt1 FROM @s;
            EXECUTE stmt1;
            DEALLOCATE PREPARE stmt1;
        END IF;
    UNTIL cursDone END REPEAT;
    CLOSE curs;
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Change to INNODB, if not already
--
-- tablename        Table name
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_change_table_to_innodb;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_change_table_to_innodb(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    IF ((SELECT count(*) FROM information_schema.tables WHERE `TABLE_SCHEMA` = DATABASE() AND `table_name` = tablename AND `table_type` = 'BASE TABLE' AND `engine` != 'InnoDB') = 1) THEN
        -- Simple alter table
        SET @stmt_alter = CONCAT('ALTER TABLE ', tablename, ' ENGINE = InnoDB');
        PREPARE stmt_alter FROM @stmt_alter;
        EXECUTE stmt_alter;		
    END IF;
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS cleanup_all_except_tables;
-- EOC
DELIMITER $$
CREATE PROCEDURE cleanup_all_except_tables()
BEGIN
	 SET @sqlx = IFNULL(REPLACE((SELECT GROUP_CONCAT('DROP FUNCTION IF EXISTS ',ROUTINE_NAME,';\r\n') FROM information_schema.routines WHERE ROUTINE_SCHEMA=DATABASE() AND ROUTINE_TYPE='FUNCTION'), ',',''), '');
	 SET @sqlx = CONCAT(@sqlx, IFNULL(REPLACE((SELECT GROUP_CONCAT('DROP PROCEDURE IF EXISTS ',ROUTINE_NAME,';\r\n') FROM information_schema.routines WHERE ROUTINE_SCHEMA=DATABASE() AND ROUTINE_TYPE='PROCEDURE'), ',',''), ''));
	 SET @sqlx = CONCAT(@sqlx, IFNULL(REPLACE((SELECT GROUP_CONCAT('DROP TRIGGER IF EXISTS ',TRIGGER_NAME,';\r\n') FROM information_schema.triggers WHERE TRIGGER_SCHEMA=DATABASE()), ',',''), ''));
	 SET @sqlx = CONCAT(@sqlx, IFNULL(REPLACE((SELECT GROUP_CONCAT('DROP VIEW IF EXISTS ',TABLE_NAME,';\r\n') FROM information_schema.views WHERE TABLE_SCHEMA=DATABASE()), ',',''), ''));	 
	 SELECT @sqlx;
END $$
DELIMITER ;
-- EOC



-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC X4 - Some tables we need before UTF8MB4

-- Add temp fulltext search addi table
CREATE TABLE IF NOT EXISTS `cache_fulltext_addi` (
    `id` INT NOT NULL AUTO_INCREMENT ,
    `tablename` VARCHAR( 255 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `indexname` VARCHAR( 255 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `columnnames` VARCHAR( 255 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Remove fulltext addi indexes and store the fields in addi table
CALL remove_fulltext_addi_indexes_once();
-- EOC

-- Add Zip to name table
CREATE TABLE IF NOT EXISTS `zip_to_name` (
	`tzip` VARCHAR(50) NOT NULL,
	`tname` VARCHAR(255) NOT NULL,
	`tcountry` VARCHAR(50) NOT NULL,
        PRIMARY KEY ( `tzip`(50), `tname`(150), `tcountry`(50) )
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_change_table_to_innodb('zip_to_name');
-- EOC

-- Prepare drawings for read from dir
CREATE TABLE IF NOT EXISTS `drawings_deleted_log` (
	`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
	`project_id` INT NOT NULL ,
	`filename` LONGTEXT NOT NULL ,
	`deleted_date` DATETIME NOT NULL ,
	INDEX `project_filename` ( `project_id` , `filename` (185) )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CREATE TABLE IF NOT EXISTS `email_cache_mboxes` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `imap_host` VARCHAR( 255 ) NOT NULL ,
    `imap_user` VARCHAR( 100 ) NOT NULL ,
    `imap_mbox` VARCHAR( 255 ) NOT NULL ,
    `last_check_start` DATETIME NOT NULL,
    `last_check_stop` DATETIME DEFAULT NULL
    -- , UNIQUE `unique_imap` ( `imap_host`(50), `imap_user`(40), `imap_mbox`(100) ) -- had to remove cause data might be too long > 191 chars
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_task_descriptions` (
    `id` INT NOT NULL AUTO_INCREMENT ,
    `descr_name_id` VARCHAR( 255 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `name` VARCHAR( 255 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_task_descriptions', 'langs_task_descriptions_unique_1', 'UNIQUE', '`descr_name_id` (140) , `language`' );
-- EOC

CALL us_drop_index_if_exists('mail_id', 'mail_id_Mail_ID');
-- EOC

DROP PROCEDURE IF EXISTS us_delete_index_if_exists;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_delete_index_if_exists(
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE UTF8MB4_GENERAL_CI,
    IN indexname VARCHAR(255) CHARSET utf8mb4 COLLATE UTF8MB4_GENERAL_CI 
)
BEGIN
    IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.STATISTICS  WHERE TABLE_NAME = tablename AND INDEX_NAME = indexname AND INDEX_SCHEMA=DATABASE()) THEN
	    SET @stmt_create = CONCAT('ALTER TABLE ', tablename, ' DROP INDEX ', indexname, ';');
        PREPARE stmt_create FROM @stmt_create;
        EXECUTE stmt_create;			
	END IF;
END $$
DELIMITER ;
-- EOC

CALL us_delete_index_if_exists('email_cache_mboxes', 'unique_imap');
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC X4 - Migrate all tables to UTF8MB4

DROP PROCEDURE IF EXISTS us_to_mb4_main;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_to_mb4_main()
BEGIN
    IF SUBSTRING(VERSION(), 1, 4) = '5.6.' THEN
        ALTER TABLE `zip_to_name` 
        DROP PRIMARY KEY,
        ADD PRIMARY KEY (`tzip`(50), `tname`(150), `tcountry`(50));

        CALL us_delete_index_if_exists('adressen', 'adressen_email');
        ALTER TABLE `adressen`
        ADD INDEX `adressen_email` ( `EMail`(191) );

        CALL us_delete_index_if_exists('drawings_deleted_log', 'project_filename');
        ALTER TABLE `drawings_deleted_log`
        ADD INDEX `project_filename` ( `project_id` , `filename`(185) );

        CALL us_delete_index_if_exists('email_cache_mboxes', 'unique_imap');
        -- had to remove cause data might be too long > 191 chars
        -- ALTER TABLE `email_cache_mboxes` 
        -- ADD UNIQUE INDEX `unique_imap` ( `imap_host`(50), `imap_user`(40), `imap_mbox`(100) );

        CALL us_delete_index_if_exists('langs_task_descriptions', 'langs_task_descriptions_unique_1');
        ALTER TABLE `langs_task_descriptions` 
        ADD UNIQUE INDEX `langs_task_descriptions_unique_1` ( `descr_name_id`(140) , `language` );

        CALL us_delete_index_if_exists('settingssystem', 'settingssystem_settingtype');
        ALTER TABLE `settingssystem` 
        ADD INDEX `settingssystem_settingtype` ( `SettingType`(191) );

        CALL us_delete_index_if_exists('settingsuser', 'settingsuser_settingtype');
        ALTER TABLE `settingsuser` 
        ADD INDEX `settingsuser_settingtype` ( `SettingType`(191) );

    END IF;
END $$
DELIMITER ;
-- EOC

CALL us_to_mb4_main();
-- EOC

DROP PROCEDURE IF EXISTS us_to_mb4;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_to_mb4(
    IN dbname VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN tablename VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
        DECLARE xtable_name VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
	DECLARE l_last_row_fetched INTEGER;
	DECLARE cur_tables CURSOR FOR 
		SELECT 
                    T.TABLE_NAME
                FROM
                    information_schema.`TABLES` T
                WHERE
                    if (tablename IS NOT NULL, T.TABLE_NAME = tablename, true) AND T.TABLE_SCHEMA = DATABASE()
                    AND 
                    T.TABLE_TYPE <> 'VIEW'
                    AND
                    (
                    T.TABLE_COLLATION = 'latin1_swedish_ci' OR
                    T.TABLE_COLLATION = 'utf8_general_ci' OR
                    T.TABLE_COLLATION = 'utf8mb3_general_ci'
                    );
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

        SET foreign_key_checks = 0;

	SET l_last_row_fetched=0;
	OPEN cur_tables;
	cursor_loop: LOOP -- -------------------------------------
		FETCH cur_tables INTO xtable_name;
                IF l_last_row_fetched = 1 THEN
                        LEAVE cursor_loop;
                END IF;
                SET @stmt_create = CONCAT('ALTER TABLE ', dbname, '.', xtable_name, ' COLLATE utf8mb4_general_ci;');
                -- SELECT @stmt_create;
                PREPARE stmt_create FROM @stmt_create;
                EXECUTE stmt_create;	
	END LOOP cursor_loop; -- -------------------------------------
	CLOSE  cur_tables;
	SET l_last_row_fetched=0;

        SET foreign_key_checks = 1;

END $$
DELIMITER ;
-- EOC

-- USC X4 - Migrate all tables to UTF8MB4 - adressen
CALL us_to_mb4(DATABASE(), 'adressen');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - dateien
CALL us_to_mb4(DATABASE(), 'dateien');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - dokattachments
CALL us_to_mb4(DATABASE(), 'dokattachments');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - drawings
CALL us_to_mb4(DATABASE(), 'drawings');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - email_cache_data
CALL us_to_mb4(DATABASE(), 'email_cache_data');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - emailout
CALL us_to_mb4(DATABASE(), 'emailout');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - erased
CALL us_to_mb4(DATABASE(), 'erased');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - externalexpenses
CALL us_to_mb4(DATABASE(), 'externalexpenses');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - externalexpenses_planned
CALL us_to_mb4(DATABASE(), 'externalexpenses_planned');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - extras
CALL us_to_mb4(DATABASE(), 'extras');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - extras_logging
CALL us_to_mb4(DATABASE(), 'extras_logging');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - fees
CALL us_to_mb4(DATABASE(), 'fees');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - fees_planned
CALL us_to_mb4(DATABASE(), 'fees_planned');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - formular
CALL us_to_mb4(DATABASE(), 'formular');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - inbox
CALL us_to_mb4(DATABASE(), 'inbox');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - modifications
CALL us_to_mb4(DATABASE(), 'modifications');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - outbox
CALL us_to_mb4(DATABASE(), 'outbox');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - personen
CALL us_to_mb4(DATABASE(), 'personen');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - perstermin
CALL us_to_mb4(DATABASE(), 'perstermin');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - planausgabe
CALL us_to_mb4(DATABASE(), 'planausgabe');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - projektangebot
CALL us_to_mb4(DATABASE(), 'projektangebot');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - projekte
CALL us_to_mb4(DATABASE(), 'projekte');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - sendmail
CALL us_to_mb4(DATABASE(), 'sendmail');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - times
CALL us_to_mb4(DATABASE(), 'times');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - times_logging
CALL us_to_mb4(DATABASE(), 'times_logging');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - transmittal_form
CALL us_to_mb4(DATABASE(), 'transmittal_form');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - travels
CALL us_to_mb4(DATABASE(), 'travels');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - travels_logging
CALL us_to_mb4(DATABASE(), 'travels_logging');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - uv_buchungen
CALL us_to_mb4(DATABASE(), 'uv_buchungen');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - work_packages
CALL us_to_mb4(DATABASE(), 'work_packages');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - work_packages_tags
CALL us_to_mb4(DATABASE(), 'work_packages_tags');
-- EOC
-- USC X4 - Migrate all tables to UTF8MB4 - work_packages_tags
CALL us_to_mb4(DATABASE(), 'work_packages_tags');
-- EOC

-- USC X4 - Migrate all tables to UTF8MB4 - ZUSATZ
CALL us_to_mb4(DATABASE(), 'zusatz_adressen');
-- EOC

CALL us_to_mb4(DATABASE(), 'zusatz_extkosten');
-- EOC

CALL us_to_mb4(DATABASE(), 'zusatz_formular');
-- EOC

CALL us_to_mb4(DATABASE(), 'zusatz_geextkosten');
-- EOC

CALL us_to_mb4(DATABASE(), 'zusatz_honverw');
-- EOC

CALL us_to_mb4(DATABASE(), 'zusatz_personen');
-- EOC

CALL us_to_mb4(DATABASE(), 'zusatz_planverz');
-- EOC

CALL us_to_mb4(DATABASE(), 'zusatz_postaus');
-- EOC

CALL us_to_mb4(DATABASE(), 'zusatz_postein');
-- EOC

CALL us_to_mb4(DATABASE(), 'zusatz_projekt');
-- EOC

CALL us_to_mb4(DATABASE(), 'zusatz_propers');
-- EOC

CALL us_to_mb4(DATABASE(), 'zusatz_todo');
-- EOC

CALL us_to_mb4(DATABASE(), 'zusatz_wasistwo');
-- EOC

-- USC X4 - Migrate all tables to UTF8MB4 - Other tables
CALL us_to_mb4(DATABASE(), null);
-- EOC

-- Convert table collation utf8mb4_0900_ai_ci to utf8mb4_general_ci
-- Prepared procedure but not used at the moment
-- Mysql dumps may be repaired with: sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_general_ci/g' my_dump.sql
DROP PROCEDURE IF EXISTS us_to_utf8mb4_general_ci;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_to_utf8mb4_general_ci()
BEGIN
   DECLARE xtable_name VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
	DECLARE l_last_row_fetched INTEGER;
	DECLARE cur_tables CURSOR FOR 
		SELECT 
                    T.TABLE_NAME
                FROM
                    information_schema.`TABLES` T
                WHERE
                    T.TABLE_SCHEMA = DATABASE()
                    AND 
                    T.TABLE_TYPE <> 'VIEW'
                    AND 
					T.TABLE_COLLATION = 'utf8mb4_0900_ai_ci';
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    SET foreign_key_checks = 0;

	SET l_last_row_fetched=0;
	OPEN cur_tables;
	cursor_loop: LOOP -- -------------------------------------
		FETCH cur_tables INTO xtable_name;
                IF l_last_row_fetched = 1 THEN
                        LEAVE cursor_loop;
                END IF;
                SET @stmt_create = CONCAT('ALTER TABLE ', DATABASE(), '.', xtable_name, ' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci');
                -- SELECT @stmt_create;
                PREPARE stmt_create FROM @stmt_create;
                EXECUTE stmt_create;	
	END LOOP cursor_loop; -- -------------------------------------
	CLOSE  cur_tables;
	SET l_last_row_fetched=0;

    SET foreign_key_checks = 1;

END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC X4 - Migrate all columns to UTF8MB4
DROP PROCEDURE IF EXISTS us_col_to_mb4;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_col_to_mb4(
    IN dbname VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
    IN tablename VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
        DECLARE xtable_name VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
        DECLARE xcolumn_name VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
        DECLARE xcolumn_type VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
        DECLARE xcolumn_null VARCHAR(10) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
        DECLARE xcolumn_default VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
	DECLARE l_last_row_fetched INTEGER;
	DECLARE cur_tables CURSOR FOR 
		SELECT 
                    C.TABLE_NAME, C.COLUMN_NAME, C.`COLUMN_TYPE`,
                    IF(C.`IS_NULLABLE`='YES', 'NULL', 'NOT NULL'),
                    IF(C.`COLUMN_DEFAULT` IS NOT NULL, CONCAT(" DEFAULT '", C.`COLUMN_DEFAULT`, "'"), '')
                FROM
                    information_schema.`COLUMNS` C
                    INNER JOIN
                    information_schema.`TABLES` T
                    ON
                    C.TABLE_NAME = T.TABLE_NAME AND T.TABLE_SCHEMA = dbname
                WHERE
                    if (tablename IS NOT NULL, T.TABLE_NAME = tablename, true) AND C.TABLE_SCHEMA = dbname
                    AND 
                    T.TABLE_TYPE <> 'VIEW'
                    AND
                    (
                        C.COLLATION_NAME = 'latin1_swedish_ci' OR
                        C.COLLATION_NAME = 'utf8_general_ci' OR
                        C.COLLATION_NAME = 'utf8mb3_general_ci'
                    );
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

        SET foreign_key_checks = 0;

	SET l_last_row_fetched=0;
	OPEN cur_tables;
	cursor_loop: LOOP -- -------------------------------------
		FETCH cur_tables INTO xtable_name, xcolumn_name, xcolumn_type, xcolumn_null, xcolumn_default;
                IF l_last_row_fetched = 1 THEN
                        LEAVE cursor_loop;
                END IF;
                SET @stmt_create = CONCAT('ALTER TABLE ', dbname, '.', xtable_name, ' MODIFY `', xcolumn_name, '` ', xcolumn_type, ' CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ', xcolumn_null, xcolumn_default, ';');
                -- SELECT @stmt_create;
                PREPARE stmt_create FROM @stmt_create;
                EXECUTE stmt_create;	
	END LOOP cursor_loop; -- -------------------------------------
	CLOSE  cur_tables;
	SET l_last_row_fetched=0;

        SET foreign_key_checks = 1;

END $$
DELIMITER ;
-- EOC

-- USC X4 - Migrate all columns to UTF8MB4 - adressen
CALL us_col_to_mb4(DATABASE(), 'adressen');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - dateien
CALL us_col_to_mb4(DATABASE(), 'dateien');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - dokattachments
CALL us_col_to_mb4(DATABASE(), 'dokattachments');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - drawings
CALL us_col_to_mb4(DATABASE(), 'drawings');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - email_cache_data
CALL us_col_to_mb4(DATABASE(), 'email_cache_data');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - emailout
CALL us_col_to_mb4(DATABASE(), 'emailout');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - erased
CALL us_col_to_mb4(DATABASE(), 'erased');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - externalexpenses
CALL us_col_to_mb4(DATABASE(), 'externalexpenses');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - externalexpenses_planned
CALL us_col_to_mb4(DATABASE(), 'externalexpenses_planned');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - extras
CALL us_col_to_mb4(DATABASE(), 'extras');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - extras_logging
CALL us_col_to_mb4(DATABASE(), 'extras_logging');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - fees
CALL us_col_to_mb4(DATABASE(), 'fees');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - fees_planned
CALL us_col_to_mb4(DATABASE(), 'fees_planned');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - formular
CALL us_col_to_mb4(DATABASE(), 'formular');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - inbox
CALL us_col_to_mb4(DATABASE(), 'inbox');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - modifications
CALL us_col_to_mb4(DATABASE(), 'modifications');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - outbox
CALL us_col_to_mb4(DATABASE(), 'outbox');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - personen
CALL us_col_to_mb4(DATABASE(), 'personen');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - perstermin
CALL us_col_to_mb4(DATABASE(), 'perstermin');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - planausgabe
CALL us_col_to_mb4(DATABASE(), 'planausgabe');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - projektangebot
CALL us_col_to_mb4(DATABASE(), 'projektangebot');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - projekte
CALL us_col_to_mb4(DATABASE(), 'projekte');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - sendmail
CALL us_col_to_mb4(DATABASE(), 'sendmail');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - times
CALL us_col_to_mb4(DATABASE(), 'times');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - times_logging
CALL us_col_to_mb4(DATABASE(), 'times_logging');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - transmittal_form
CALL us_col_to_mb4(DATABASE(), 'transmittal_form');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - travels
CALL us_col_to_mb4(DATABASE(), 'travels');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - travels_logging
CALL us_col_to_mb4(DATABASE(), 'travels_logging');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - uv_buchungen
CALL us_col_to_mb4(DATABASE(), 'uv_buchungen');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - work_packages
CALL us_col_to_mb4(DATABASE(), 'work_packages');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - work_packages_tags
CALL us_col_to_mb4(DATABASE(), 'work_packages_tags');
-- EOC
-- USC X4 - Migrate all columns to UTF8MB4 - work_packages_tags
CALL us_col_to_mb4(DATABASE(), 'work_packages_tags');
-- EOC

-- USC X4 - Migrate all columns to UTF8MB4 - ZUSATZ
CALL us_col_to_mb4(DATABASE(), 'zusatz_adressen');
-- EOC

CALL us_col_to_mb4(DATABASE(), 'zusatz_extkosten');
-- EOC

CALL us_col_to_mb4(DATABASE(), 'zusatz_formular');
-- EOC

CALL us_col_to_mb4(DATABASE(), 'zusatz_geextkosten');
-- EOC

CALL us_col_to_mb4(DATABASE(), 'zusatz_honverw');
-- EOC

CALL us_col_to_mb4(DATABASE(), 'zusatz_personen');
-- EOC

CALL us_col_to_mb4(DATABASE(), 'zusatz_planverz');
-- EOC

CALL us_col_to_mb4(DATABASE(), 'zusatz_postaus');
-- EOC

CALL us_col_to_mb4(DATABASE(), 'zusatz_postein');
-- EOC

CALL us_col_to_mb4(DATABASE(), 'zusatz_projekt');
-- EOC

CALL us_col_to_mb4(DATABASE(), 'zusatz_propers');
-- EOC

CALL us_col_to_mb4(DATABASE(), 'zusatz_todo');
-- EOC

CALL us_col_to_mb4(DATABASE(), 'zusatz_wasistwo');
-- EOC


-- USC X4 - Migrate all columns to UTF8MB4 - Other tables
CALL us_col_to_mb4(DATABASE(), null);
-- EOC-- USC Spalten fuer bestehenden Tabellen werden angelegt.

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Projects
CALL us_add_to_table2('projektangebot', 'title', 'VARCHAR(80) DEFAULT \'\' AFTER `datei`');
-- EOC
CALL us_add_to_table2('projektangebot', 'GueltigBis', 'DATETIME DEFAULT NULL AFTER `Bezeichnung`');
-- EOC
CALL us_add_to_table2('projektangebot', 'BeauftragNr', 'VARCHAR(40) DEFAULT NULL AFTER `GueltigBis`' );
-- EOC
CALL us_add_to_table2('projektangebot', 'BeauftragDatum', 'DATETIME DEFAULT NULL AFTER `BeauftragNr`');
-- EOC
CALL us_add_to_table2('projektangebot', 'BeauftragWahrscheinl', 'INT NULL AFTER `BeauftragDatum`');
-- EOC
CALL us_add_to_table2('projektangebot', 'Person', 'INT NULL AFTER `BeauftragWahrscheinl`');
-- EOC
CALL us_add_to_table2('projektangebot', 'IsCalcexp', 'BOOLEAN DEFAULT 0 AFTER `Person`');
-- EOC
CALL us_add_to_table2('projektangebot', 'IsEstimation', 'BOOLEAN DEFAULT 0 AFTER `IsCalcexp`');
-- EOC
CALL us_add_to_table2('projektangebot', 'portlet_desc', 'LONGTEXT NULL DEFAULT NULL AFTER `IsEstimation`');
-- EOC
CALL us_add_to_table2('projektangebot', 'portlet_data', 'LONGTEXT NULL DEFAULT NULL AFTER `IsEstimation`');
-- EOC
CALL us_add_to_table2('projektangebot', 'vat_rate', 'DOUBLE NULL DEFAULT NULL AFTER `BeauftragWahrscheinl`');
-- EOC
CALL change_column('projektangebot', 'vat_rate', 'DOUBLE NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('projektangebot', 'currency_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL change_column('projektangebot', 'Bezeichnung', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `title`');
-- EOC
CALL us_add_to_table2('projektangebot', 'withholding_type', 'INT NOT NULL DEFAULT 0');
-- EOC
CALL us_add_to_table2('projektangebot', 'withholding', 'DOUBLE NOT NULL DEFAULT 0');
-- EOC
CALL us_add_to_table2('projektangebot', 'retention_type', 'INT NOT NULL DEFAULT 0');
-- EOC
CALL us_add_to_table2('projektangebot', 'retention_years', 'INT NOT NULL DEFAULT 0');
-- EOC
CALL us_add_to_table2('projektangebot', 'retention', 'DOUBLE NOT NULL DEFAULT 0');
-- EOC
CALL us_add_to_table2('projektangebot', 'extras_type', 'BOOLEAN NOT NULL DEFAULT 1');
-- EOC
CALL us_add_to_table2('projektangebot', 'rebate_type', 'BOOLEAN NOT NULL DEFAULT 1');
-- EOC
CALL us_add_to_table2('projektangebot', 'calc_rebate_first', 'BOOLEAN NOT NULL DEFAULT 0');
-- EOC
CALL change_column('projektangebot', 'calc_rebate_first', 'INT NOT NULL DEFAULT 0');
-- EOC
CALL us_add_to_table2('projektangebot', 'calc_type', 'BOOLEAN NOT NULL DEFAULT 0');
-- EOC
CALL us_add_to_table2('projektangebot', 'time', 'TIME DEFAULT NULL');
-- EOC
CALL us_add_to_table2('projektangebot', 'times_rate_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('projektangebot', 'times_rate_history_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('projektangebot', 'work_areas_rate_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('projektangebot', 'work_areas_rate_history_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('projektangebot', 'extras_rate_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('projektangebot', 'extras_rate_history_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('projektangebot', 'travel_rate_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('projektangebot', 'travel_rate_history_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('projektangebot', 'calcexp_valid_from', 'DATETIME NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('projektangebot', 'calcexp_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('projektangebot', 'offer_type', 'INT NOT NULL DEFAULT 0');
-- EOC
CALL us_add_to_table2('projektangebot', 'related_offer_id', 'INT NULL DEFAULT NULL');
-- EOC

CALL us_add_to_table2('bereichetab', 'aktiv', 'BOOLEAN DEFAULT 1 AFTER `indi`' );
-- EOC
CALL us_add_to_table2('bereichetab', 'special_id', 'INT NULL AFTER `aktiv`' );
-- EOC
CALL us_add_to_table2('bereichetab', 'was_special_id', 'INT NULL AFTER `aktiv`' );
-- EOC

CALL us_add_to_table2('honorarbereiche', 'is_special', 'BOOLEAN DEFAULT 0 AFTER `LfdNr`' );
-- EOC
CALL us_add_to_table2('honorarbereiche', 'is_project_only', 'BOOLEAN DEFAULT 0 AFTER `is_special`' );
-- EOC

CALL us_add_to_table2('arbeitsbereiche', 'is_special', 'BOOLEAN DEFAULT 0 AFTER `LfdNr`' );
-- EOC
CALL us_add_to_table2('arbeitsbereiche', 'is_project_only', 'BOOLEAN DEFAULT 0 AFTER `is_special`' );
-- EOC
CALL us_add_to_table2('arbeitsbereiche', 'is_purpose_required', 'BOOLEAN DEFAULT 0 AFTER `LfdNr`' );
-- EOC

CALL us_add_to_table2('projekte', 'division_manager_id', 'INT NULL' );
-- EOC
CALL us_add_to_table2('projekte', 'company_id', 'INT NULL COMMENT "Project company ID rules over staff company ID" AFTER `AendVon`' );
-- EOC
CALL us_add_to_table2('projekte', 'currency_id', 'INT NULL COMMENT "Is derived on creation from company" AFTER `company_id`' );
-- EOC
CALL us_add_to_table2('projekte', 'ignore_required_purpose', 'BOOLEAN DEFAULT 0 AFTER `LfdNr`' );
-- EOC
CALL us_add_to_table2('projekte', 'work_package_preset_id', 'BIGINT DEFAULT NULL AFTER `ignore_required_purpose`' );
-- EOC
-- SV_Pfad AS path_correspondence
CALL us_add_to_table2('projekte', 'path_correspondence_default', 'VARCHAR(255) COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `SV_Pfad`' );
-- EOC
-- EM_Pfad AS path_inbox
CALL us_add_to_table2('projekte', 'path_inbox_default', 'VARCHAR(255) COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `EM_Pfad`' );
-- EOC
-- EM_OUT_Pfad AS path_outbox
CALL us_add_to_table2('projekte', 'path_outbox_default', 'VARCHAR(255) COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `EM_OUT_Pfad`' );
-- EOC
-- path_drawings
CALL us_add_to_table2('projekte', 'planpfad', 'VARCHAR(255) COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `path_outbox_default`' );
-- EOC
CALL us_add_to_table2('projekte', 'path_drawings_default', 'VARCHAR(255) COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `planpfad`' );
-- EOC
-- original structure tree nodes (prepareation for future)
CALL us_add_to_table2('projekte', 'orig_structure_id', 'INT DEFAULT NULL AFTER `path_drawings_default`' );
-- EOC
CALL us_add_to_table2('projekte', 'orig_structure_tree_root_node', 'VARCHAR(255) COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `orig_structure_id`' );
-- EOC
CALL us_add_to_table2('projekte', 'orig_translated_structure_tree_root_node', 'VARCHAR(255) COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `orig_structure_tree_root_node`' );
-- EOC
CALL us_add_to_table2('projekte', 'auto_calc', 'INT DEFAULT 1' );
-- EOC
CALL us_add_to_table2('projekte', 'auto_calc_fee', 'INT DEFAULT 0' );
-- EOC
CALL us_add_to_table2('projekte', 'show_tags', 'INT DEFAULT 0' );
-- EOC
CALL us_add_to_table2('projekte', 'use_budget_top_prop', 'INT DEFAULT 0' );
-- EOC
CALL us_add_to_table2('projekte', 'default_extras', 'DOUBLE NULL' );
-- EOC
ALTER TABLE `projekte` CHANGE COLUMN `default_extras` `default_extras` DOUBLE NULL DEFAULT NULL;
-- EOC
CALL us_add_to_table2('projekte', 'default_discount', 'DOUBLE NULL' );
-- EOC
ALTER TABLE `projekte` CHANGE COLUMN `default_discount` `default_discount` DOUBLE NULL DEFAULT NULL;
-- EOC
CALL us_add_to_table2('projekte', 'default_discount_days', 'INT NULL' );
-- EOC
CALL us_add_to_table2('projekte', 'color', 'VARCHAR(30) COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `Bilddatei`' );
-- EOC

-- X2 Migration helper fields
CALL us_add_to_table2('lut_hon_proj_history', 'migrate_valid_from_date', 'DATETIME NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('sollab_history', 'migrate_valid_from_date', 'DATETIME NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('schaetzungfertig_history', 'migrate_valid_from_date', 'DATETIME NULL DEFAULT NULL');
-- EOC

-- X2 Related IDs in formular/correspondence needed by update_alloc_with_payments_fees
CALL us_add_to_table2('formular', 'related_id', 'INT DEFAULT NULL COMMENT \'Related item ID\'' );
-- EOC
CALL us_add_to_table2('formular', 'related_uuid', 'VARCHAR(36) DEFAULT NULL COMMENT \'Related item UDID\' AFTER related_id' );
-- EOC
CALL us_add_to_table2('formular', 'related_type', 'VARCHAR(30) DEFAULT NULL COMMENT \'Related item Type\'' );
-- EOC

-- Add more options to fee_multipliers
CALL us_add_to_table2('aufschlag', 'is_standard', 'BOOLEAN DEFAULT 0 AFTER SatzNr' );
-- EOC
CALL us_add_to_table2('aufschlag', 'is_r2', 'BOOLEAN DEFAULT 0 AFTER is_standard' );
-- EOC
CALL us_add_to_table2('aufschlag', 'is_r3', 'BOOLEAN DEFAULT 0 AFTER is_r2' );
-- EOC
CALL us_add_to_table2('aufschlag', 'is_r4', 'BOOLEAN DEFAULT 0 AFTER is_r3' );
-- EOC

-- Personalappointments
CALL us_add_to_table2('perstermin', 'url', 'TEXT COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `Ort`' );
-- EOC
CALL us_add_to_table2('perstermin', 'changed_url', 'BOOLEAN NOT NULL DEFAULT 0 AFTER `bOrt`' );
-- EOC
CALL us_add_to_table2('perstermin', 'summary', 'TEXT COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `Bei`' );
-- EOC
CALL us_add_to_table2('perstermin', 'changed_summary', 'BOOLEAN NOT NULL DEFAULT 0 AFTER `bBei`' );
-- EOC


DROP PROCEDURE IF EXISTS us_ensure_uuids;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_ensure_uuids()
BEGIN
    -- PROJECTS
    -- Add field to table. Don't forget to also add to view in e.g. up0005.sql!
    CALL us_add_to_table2('projekte', 'uuid', 'CHAR(36) DEFAULT NULL AFTER `LfdNr`' );
    -- Add index
    CALL us_add_constraint_to_table('projekte', 'uuid_unique', 'UNIQUE', '`uuid`' );
    -- Set UUIDs
    UPDATE projekte SET uuid = us_uuid_v4() WHERE uuid IS NULL;
    -- Remove/Add before insert trigger in up0025.sql!

    -- ADDRESSES
    -- Add field to table. Don't forget to also add to view in e.g. up0023.sql!
    CALL us_add_to_table2('adressen', 'uuid', 'CHAR(36) DEFAULT NULL AFTER `LfdNr`' );
    -- Add index
    CALL us_add_constraint_to_table('adressen', 'uuid_unique', 'UNIQUE', '`uuid`' );
    -- Set UUIDs
    UPDATE adressen SET uuid = us_uuid_v4() WHERE uuid IS NULL;
    -- Remove/Add before insert trigger in up0025.sql!    

END $$
DELIMITER ;
-- EOC

CALL us_ensure_uuids();
-- EOC
-- USC Stelle sicher, dass Views angelegt werden koennen.

-- Cleans corrupt backup recovery - just in case

DROP TABLE IF EXISTS `address_categories`;
-- EOC
DROP TABLE IF EXISTS `address_descriptions`;
-- EOC
DROP TABLE IF EXISTS `address_descriptions_comp`;
-- EOC
DROP TABLE IF EXISTS `address_files`;
-- EOC
DROP TABLE IF EXISTS `address_groups`;
-- EOC
DROP TABLE IF EXISTS `address_relations_both`;
-- EOC
DROP TABLE IF EXISTS `address_relations_comp`;
-- EOC
DROP TABLE IF EXISTS `addresses`;
-- EOC
DROP TABLE IF EXISTS `addresses_addi_def`;
-- EOC
DROP TABLE IF EXISTS `addresses_fullname`;
-- EOC
DROP TABLE IF EXISTS `address_groups_fullname`;
-- EOC
DROP TABLE IF EXISTS `budget_plan`;
-- EOC
DROP TABLE IF EXISTS `budget_plan_extended_data`;
-- EOC
DROP TABLE IF EXISTS `budget_plan_history`;
-- EOC
DROP TABLE IF EXISTS `calls`;
-- EOC
DROP TABLE IF EXISTS `companies`;
-- EOC
DROP TABLE IF EXISTS `completion_level`;
-- EOC
DROP TABLE IF EXISTS `completion_level_extended_data`;
-- EOC
DROP TABLE IF EXISTS `completion_level_history`;
-- EOC
DROP TABLE IF EXISTS `correspondence`;
-- EOC
DROP TABLE IF EXISTS `correspondence_addi_def`;
-- EOC
DROP TABLE IF EXISTS `correspondence_attachments`;
-- EOC
DROP TABLE IF EXISTS `correspondence_locking`;
-- EOC
DROP TABLE IF EXISTS `correspondence_readonly`;
-- EOC
DROP TABLE IF EXISTS `correspondence_structure`;
-- EOC
DROP TABLE IF EXISTS `correspondence_types`;
-- EOC
DROP TABLE IF EXISTS `correspondence_types_structure`;
-- EOC
DROP TABLE IF EXISTS `cost_centres`;
-- EOC
DROP TABLE IF EXISTS `countries`;
-- EOC
DROP TABLE IF EXISTS `deletions`;
-- EOC
DROP TABLE IF EXISTS `dispatch_modes`;
-- EOC
DROP TABLE IF EXISTS `drawing_sizes`;
-- EOC
DROP TABLE IF EXISTS `drawing_types`;
-- EOC
DROP TABLE IF EXISTS `drawings_addi_def`;
-- EOC
DROP TABLE IF EXISTS `drawings_outbox`;
-- EOC
DROP TABLE IF EXISTS `expenses_rates`;
-- EOC
DROP TABLE IF EXISTS `externalexpenses_addi_invoiced_def`;
-- EOC
DROP TABLE IF EXISTS `externalexpenses_addi_merged`;
-- EOC
DROP TABLE IF EXISTS `externalexpenses_addi_merged_def`;
-- EOC
DROP TABLE IF EXISTS `externalexpenses_addi_planned_def`;
-- EOC
DROP TABLE IF EXISTS `externalexpenses_calc`;
-- EOC
DROP TABLE IF EXISTS `externalexpenses_merged`;
-- EOC
DROP TABLE IF EXISTS `externalexpenses_planned_calc`;
-- EOC
DROP TABLE IF EXISTS `extras_rates`;
-- EOC
DROP TABLE IF EXISTS `extras_rates_history`;
-- EOC
DROP TABLE IF EXISTS `extras_types`;
-- EOC
DROP TABLE IF EXISTS `fee_accounts`;
-- EOC
DROP TABLE IF EXISTS `fee_areas`;
-- EOC
DROP TABLE IF EXISTS `fee_multipliers`;
-- EOC
DROP TABLE IF EXISTS `fees_addi_invoiced_def`;
-- EOC
DROP TABLE IF EXISTS `fees_addi_merged`;
-- EOC
DROP TABLE IF EXISTS `fees_addi_merged_def`;
-- EOC
DROP TABLE IF EXISTS `fees_addi_planned_def`;
-- EOC
DROP TABLE IF EXISTS `fees_calc`;
-- EOC
DROP TABLE IF EXISTS `fees_merged`;
-- EOC
DROP TABLE IF EXISTS `fees_planned_calc`;
-- EOC
DROP TABLE IF EXISTS `fees_reminder_level_logging`;
-- EOC
DROP TABLE IF EXISTS `files`;
-- EOC
DROP TABLE IF EXISTS `holiday_rates`;
-- EOC
DROP TABLE IF EXISTS `holidays`;
-- EOC
DROP TABLE IF EXISTS `inbox_addi_def`;
-- EOC
DROP TABLE IF EXISTS `inbox_path`;
-- EOC
DROP TABLE IF EXISTS `lut_addresses_address_categories`;
-- EOC
DROP TABLE IF EXISTS `lut_addresses_address_group`;
-- EOC
DROP TABLE IF EXISTS `lut_addresses_projects`;
-- EOC
DROP TABLE IF EXISTS `lut_correspondence_copies`;
-- EOC
DROP TABLE IF EXISTS `lut_correspondence_structure_type`;
-- EOC
DROP TABLE IF EXISTS `lut_drawings_addresses`;
-- EOC
DROP TABLE IF EXISTS `lut_fee_areas_proj`;
-- EOC
DROP TABLE IF EXISTS `lut_fee_areas_proj_history`;
-- EOC
DROP TABLE IF EXISTS `lut_outbox_attachments`;
-- EOC
DROP TABLE IF EXISTS `lut_outbox_bcc_addresses`;
-- EOC
DROP TABLE IF EXISTS `lut_personalapp_address`;
-- EOC
DROP TABLE IF EXISTS `lut_proj_category_rates`;
-- EOC
DROP TABLE IF EXISTS `lut_proj_proj_grps`;
-- EOC
DROP TABLE IF EXISTS `lut_route_proj`;
-- EOC
DROP TABLE IF EXISTS `lut_staff_occ_group`;
-- EOC
DROP TABLE IF EXISTS `lut_task_desc_proj`;
-- EOC
DROP TABLE IF EXISTS `lut_transmittal_form_addresses`;
-- EOC
DROP TABLE IF EXISTS `lut_wiw_items_projects`;
-- EOC
DROP TABLE IF EXISTS `lut_wiw_items_themes`;
-- EOC
DROP TABLE IF EXISTS `lut_work_areas_work_areas_categories`;
-- EOC
DROP TABLE IF EXISTS `lut_working_user`;
-- EOC
DROP TABLE IF EXISTS `max_sabre_synctokens`;
-- EOC
DROP TABLE IF EXISTS `max_sabre_task_synctokens`;
-- EOC
DROP TABLE IF EXISTS `max_sabre_card_synctokens`;
-- EOC
DROP TABLE IF EXISTS `measurements`;
-- EOC
DROP TABLE IF EXISTS `numbergeneration`;
-- EOC
DROP TABLE IF EXISTS `numbergeneration_log`;
-- EOC
DROP TABLE IF EXISTS `occupation_groups`;
-- EOC
DROP TABLE IF EXISTS `occupation_groups_fee_multipliers`;
-- EOC
DROP TABLE IF EXISTS `opentasks`;
-- EOC
DROP TABLE IF EXISTS `opentasks_addi_def`;
-- EOC
DROP TABLE IF EXISTS `outbox_addi_def`;
-- EOC
DROP TABLE IF EXISTS `outbox_path`;
-- EOC
DROP TABLE IF EXISTS `overtime`;
-- EOC
DROP TABLE IF EXISTS `overtime_rates`;
-- EOC
DROP TABLE IF EXISTS `payments_fees_values`;
-- EOC
DROP TABLE IF EXISTS `personalappointments`;
-- EOC
DROP TABLE IF EXISTS `project_archives`;
-- EOC
DROP TABLE IF EXISTS `project_categories`;
-- EOC
DROP TABLE IF EXISTS `project_offers`;
-- EOC
DROP TABLE IF EXISTS `project_participants_addi_def`;
-- EOC
DROP TABLE IF EXISTS `project_phases`;
-- EOC
DROP TABLE IF EXISTS `projects`;
-- EOC
DROP TABLE IF EXISTS `projects_addi_def`;
-- EOC
DROP TABLE IF EXISTS `projects_groups`;
-- EOC
DROP TABLE IF EXISTS `report_budget_plan_history`;
-- EOC
DROP TABLE IF EXISTS `report_completion_level`;
-- EOC
DROP TABLE IF EXISTS `report_completion_level_bbl1`;
-- EOC
DROP TABLE IF EXISTS `report_completion_level_bbl2`;
-- EOC
DROP TABLE IF EXISTS `report_completion_level_current`;
-- EOC
DROP TABLE IF EXISTS `report_completion_level_fee`;
-- EOC
DROP TABLE IF EXISTS `report_completion_level_history`;
-- EOC
DROP TABLE IF EXISTS `report_cost_centres_info`;
-- EOC
DROP TABLE IF EXISTS `report_externalexpenses`;
-- EOC
DROP TABLE IF EXISTS `report_externalexpenses_planned`;
-- EOC
DROP TABLE IF EXISTS `report_extras`;
-- EOC
DROP TABLE IF EXISTS `report_extras_logging`;
-- EOC
DROP TABLE IF EXISTS `report_fee_areas_project_allocation`;
-- EOC
DROP TABLE IF EXISTS `report_fee_areas_project_allocation_history`;
-- EOC
DROP TABLE IF EXISTS `report_measurements`;
-- EOC
DROP TABLE IF EXISTS `report_overtime_datemonth`;
-- EOC
DROP TABLE IF EXISTS `report_projects_fee_areas`;
-- EOC
DROP TABLE IF EXISTS `report_start_end_times`;
-- EOC
DROP TABLE IF EXISTS `report_times_from_to`;
-- EOC
DROP TABLE IF EXISTS `report_times`;
-- EOC
DROP TABLE IF EXISTS `report_times_changed_gross`;
-- EOC
DROP TABLE IF EXISTS `report_times_datemonth`;
-- EOC
DROP TABLE IF EXISTS `report_times_logging`;
-- EOC
DROP TABLE IF EXISTS `report_travels`;
-- EOC
DROP TABLE IF EXISTS `report_travels_logging`;
-- EOC
DROP TABLE IF EXISTS `report_sendmail`;
-- EOC
DROP TABLE IF EXISTS `routes`;
-- EOC
DROP TABLE IF EXISTS `staff`;
-- EOC
DROP TABLE IF EXISTS `staff_additional_def`;
-- EOC
DROP TABLE IF EXISTS `staff_favourite_proj`;
-- EOC
DROP TABLE IF EXISTS `start_end_times`;
-- EOC
DROP TABLE IF EXISTS `sys_installation`;
-- EOC
DROP TABLE IF EXISTS `system_settings`;
-- EOC
DROP TABLE IF EXISTS `target_hours_daily`;
-- EOC
DROP TABLE IF EXISTS `task_descriptions`;
-- EOC
DROP TABLE IF EXISTS `times_rates`;
-- EOC
DROP TABLE IF EXISTS `times_rates_history`;
-- EOC
DROP TABLE IF EXISTS `travels_rates`;
-- EOC
DROP TABLE IF EXISTS `travels_rates_history`;
-- EOC
DROP TABLE IF EXISTS `travels_types`;
-- EOC
DROP TABLE IF EXISTS `user_settings`;
-- EOC
DROP TABLE IF EXISTS `vacations`;
-- EOC
DROP TABLE IF EXISTS `whatiswhere_addi_def`;
-- EOC
DROP TABLE IF EXISTS `wiw_articles`;
-- EOC
DROP TABLE IF EXISTS `wiw_filings`;
-- EOC
DROP TABLE IF EXISTS `wiw_items`;
-- EOC
DROP TABLE IF EXISTS `wiw_merged`;
-- EOC
DROP TABLE IF EXISTS `wiw_racks`;
-- EOC
DROP TABLE IF EXISTS `wiw_rooms`;
-- EOC
DROP TABLE IF EXISTS `wiw_themes`;
-- EOC
DROP TABLE IF EXISTS `wiw_trays`;
-- EOC
DROP TABLE IF EXISTS `work_areas`;
-- EOC
DROP TABLE IF EXISTS `work_areas_categories`;
-- EOC
DROP TABLE IF EXISTS `workinput`;
-- EOC
DROP TABLE IF EXISTS `zip_to_name_merged`;
-- EOC

-- USC X2 Views fuer bestehende Tabellen werden angelegt.

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Projects
CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `project_offers`
 AS SELECT LfdNr AS id, ProjLfdNr AS project_id, AdrLfdNr AS address_id, AngebotsNummer AS offer_no,
 offer_type, related_offer_id, AngebotsDatum AS date, time, AngebotsStatus AS status, Datei AS file, title, Bezeichnung AS name,
 GueltigBis AS valid_to_date, BeauftragNr AS order_no, BeauftragDatum AS order_date, BeauftragWahrscheinl AS order_probability, vat_rate, Person AS staff_id,
 IsCalcexp AS is_calcexp, IsEstimation AS is_estimation, portlet_desc, portlet_data, currency_id,
 withholding_type, withholding, retention_type, retention_years, retention, extras_type, rebate_type, calc_rebate_first, calc_type,
 times_rate_id, times_rate_history_id, work_areas_rate_id, work_areas_rate_history_id, extras_rate_id, extras_rate_history_id,
 travel_rate_id, travel_rate_history_id, calcexp_valid_from, calcexp_id
 FROM projektangebot;
-- EOC


CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `work_areas_categories`
 AS SELECT LfdNr AS id, indi AS one_project_only, BereichName AS name, aktiv AS is_active, special_id, was_special_id FROM bereichetab;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `fee_areas`
 AS SELECT LfdNr AS id, HonorarName AS name, Feld AS sort, extern AS external, is_special, is_project_only FROM honorarbereiche;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `work_areas`
 AS SELECT LfdNr AS id, ArbName AS name, Feld AS sort, HonBer AS fee_area_id, is_special, is_purpose_required, is_project_only FROM arbeitsbereiche;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_work_areas_work_areas_categories`
 AS SELECT ArbNr AS work_area_id, SatzNr AS work_area_categories_id, schwelle AS threshold FROM lut_arb_hon;
-- EOC


CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `projects`
 AS SELECT LfdNr AS id, uuid, Projekt AS project_name, ProjektNummer AS project_number, Beginn AS start_date, Ende AS end_date, Beschreibung AS purpose,
 Ort AS location, BerSatz AS work_area_category_id, Bauherr AS client_id, Planer1 AS project_manager_id, division_manager_id, Planer2 AS office_in_charge_id,
 company_id, currency_id, LfdNr_Phase AS project_phase_id, Kategorie as project_category_id,
 SV_Pfad AS path_correspondence, path_correspondence_default, 
 EM_Pfad AS path_inbox, path_inbox_default, EM_OUT_Pfad AS path_outbox, path_outbox_default, Planpfad AS path_drawings, path_drawings_default,
 orig_structure_id, orig_structure_tree_root_node, orig_translated_structure_tree_root_node,
 LfdNr_ProjektArchiv AS project_archive_id,
 PrivatProjekt AS is_private_project, Aufwand AS is_calc_from_expenses, AbrArt AS is_add_to_indirect_costs, StdAbr AS is_included_in_time_sheet,
 ErstVon AS created_by_id, AendVon AS changed_by_id, ErstAm AS created_date, AendAm AS change_date, AufbewahrungsFrist AS safekeeping_period,
 Bilddatei AS photo_file, color, MessSize_LfdNr As measurement_id, MessSize_Value AS measurement_value, isSchwelle AS is_threshold,
 BudgetNotBound as is_budget_not_bound, SyncroDok AS sync_correspondence, SyncroEmailIn AS sync_inbox, SyncroEmailOut AS sync_outbox, ignore_required_purpose, work_package_preset_id, auto_calc, auto_calc_fee, show_tags,
 use_budget_top_prop, default_extras, default_discount, default_discount_days
 FROM projekte;
-- EOC


CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_fee_areas_proj`
 AS SELECT LfdNr AS id, Hon_LfdNr AS fee_area_id, Proj_LfdNr AS project_id, HonStatus AS status, History_LfdNr AS lut_fee_areas_proj_history_id,
 Stunden AS hours, Kosten AS costs, KostenProzent AS costs_percent, KostenGesamt AS costs_sum, KostenGesamtEingabe AS is_costs_sum
 FROM lut_hon_proj;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_fee_areas_proj_history`
 AS SELECT LfdNr AS id, Proj_LfdNr AS project_id, GueltigBis AS valid_to_date, HistBem AS comment, migrate_valid_from_date
 FROM lut_hon_proj_history;
-- EOC


CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `budget_plan`
 AS SELECT LfdNr_Projekt AS project_id, LfdNr_AB AS area_id, LfdNr_MA AS staff_id, History_LfdNr AS budget_plan_history_id,
 SollKosten AS planned_costs, SollStunden AS planned_hours, Beginn AS start_date, Ende AS end_date,
 Datum AS last_changed_date, Anteil AS proportion, schwelle AS threshold FROM sollab;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `budget_plan_history`
 AS SELECT LfdNr AS id, Proj_LfdNr AS project_id, GueltigBis AS valid_to_date, HistBem AS comment, migrate_valid_from_date 
 FROM sollab_history;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `completion_level`
 AS SELECT LfdNr AS id, LfdNr_Projekt AS project_id, LfdNr_AB AS work_area_id, LfdNr_MA AS staff_id, Datum AS date, Grad AS completion_level,
 History_LfdNr AS completion_level_history_id FROM schaetzungfertig;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `completion_level_history`
 AS SELECT LfdNr AS id, Proj_LfdNr AS project_id, GueltigBis AS valid_to_date, HistBem AS comment, migrate_valid_from_date 
 FROM schaetzungfertig_history;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `fee_multipliers` AS
 SELECT LfdNr AS id, OrdNr AS sort, Aufschlag AS name, Beschreibung AS purpose, SatzNr AS rate_id, 
 is_standard, is_r2, is_r3, is_r4, Arbeitskosten AS is_work, MAuswert AS is_ignore_mgmt
 FROM aufschlag;
-- EOC

-- USC Procedures fuer das X2 Update werden angelegt.

-- -----------------------------------------
-- Calculates the sum of the fields
-- -----------------------------------------

DROP PROCEDURE IF EXISTS calc_sum;
-- EOC
DELIMITER $$
CREATE PROCEDURE calc_sum(
    IN curr_project_id VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
	
    DECLARE done INT DEFAULT FALSE;
    DECLARE left_val INT;
    DECLARE right_val INT;    
    DECLARE id_val INT;       
    DECLARE wp CURSOR FOR SELECT id, lft, rgt FROM work_packages WHERE rgt-lft > 1 AND project_id = curr_project_id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN wp;

    REPEAT
            FETCH wp INTO id_val, left_val, right_val;

            IF NOT done THEN
                -- Fee area related values 
                /* SET by SELECT */
                SELECT SUM(fee_costs), SUM(fee_hours) 
                    INTO @fee_costs_sum, @fee_hours_sum
                    FROM work_packages WHERE lft >= left_val AND rgt <=  right_val AND project_id = curr_project_id AND (rgt-lft=1 OR is_fee_area IS TRUE);
                -- Work area related values
                /* SET by SELECT */
                SELECT SUM(budget_planned_costs), SUM(budget_planned_hours), SUM(budget_proportion)
                    INTO @budget_costs_sum, @budget_hours_sum, @budget_proportion
                    FROM work_packages WHERE lft > left_val AND rgt <  right_val AND project_id = curr_project_id AND rgt-lft = 1;
                 
                UPDATE work_packages SET fee_costs = @fee_costs_sum where id = id_val;
                UPDATE work_packages SET fee_hours = @fee_hours_sum where id = id_val;
                UPDATE work_packages SET budget_planned_costs = @budget_costs_sum where id = id_val;
                UPDATE work_packages SET budget_planned_hours = @budget_hours_sum where id = id_val;
                UPDATE work_packages SET budget_proportion = @budget_proportion where id = id_val;                   
            END IF;
      UNTIL done END REPEAT;

    CLOSE wp; 
END $$
DELIMITER ;
-- EOC


-- -----------------------------------------
-- Get the earliest date for the start and the latest date for the end
-- -----------------------------------------

DROP PROCEDURE IF EXISTS get_date;
-- EOC
DELIMITER $$
CREATE PROCEDURE get_date(
    IN curr_project_id VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
	
    DECLARE done INT DEFAULT FALSE;
    DECLARE left_val INT;
    DECLARE right_val INT;    
    DECLARE id_val INT;       
    DECLARE wp CURSOR FOR SELECT id, lft, rgt FROM work_packages WHERE rgt-lft > 1 AND project_id = curr_project_id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN wp;
        REPEAT
            FETCH wp INTO id_val, left_val, right_val;

            IF NOT done THEN
                /* SET by SELECT */
                SELECT MIN(budget_start), MAX(budget_end) 
                    INTO @start_date, @end_date
                    FROM work_packages WHERE lft > left_val AND rgt <  right_val AND project_id = curr_project_id;

                UPDATE work_packages SET budget_start = @start_date where id = id_val;
                UPDATE work_packages SET budget_end = @end_date where id = id_val;        
            END IF;
        UNTIL done END REPEAT;
    CLOSE wp; 
END $$
DELIMITER ;
-- EOC

-- ---------------------------------------
-- Calculates the completion level depending on the proportion
-- ---------------------------------------

DROP PROCEDURE IF EXISTS calc_completion_level;
-- EOC
DELIMITER $$
CREATE PROCEDURE calc_completion_level(
    IN curr_project_id VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN

    DECLARE done INT DEFAULT FALSE;
    DECLARE left_val INT;
    DECLARE right_val INT;    
    DECLARE id_val INT;   
    DECLARE proportion_val FLOAT;         
    DECLARE wp CURSOR FOR SELECT id, lft, rgt, budget_proportion FROM work_packages WHERE rgt-lft > 1 AND project_id = curr_project_id AND budget_proportion > 0;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN wp;
        REPEAT
            FETCH wp INTO id_val, left_val, right_val, proportion_val;
            IF NOT done THEN
                /* SET by SELECT */
                SELECT (SUM((budget_proportion * completion_level)/(proportion_val*100))*100)
                    INTO @completion_level
                    FROM work_packages WHERE lft > left_val AND rgt <  right_val AND project_id = curr_project_id;
                UPDATE work_packages SET completion_level = @completion_level where id = id_val;
            END IF;
	UNTIL done END REPEAT;
    CLOSE wp; 
END $$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Create 01migrate_11_12, if not exists
-- --------------------------------------------------------------------------------------------------

DROP PROCEDURE IF EXISTS us_create_01migrate_11_12;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_create_01migrate_11_12()
BEGIN

    DECLARE sql1 TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci 
        DEFAULT 'CREATE TABLE IF NOT EXISTS `01migrate_11_12` (
  `elem` VARCHAR(100) NOT NULL,
  `info` VARCHAR(500) NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=';

    DECLARE sql2 TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;';

    SELECT GetStorageEngine ('ARCHIVE') INTO @engineInnoDBorArchive;
    SET @s = CONCAT(sql1, @engineInnoDBorArchive, sql2);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

END $$
DELIMITER ;
-- EOC

-- ---------------------------------------
-- Add one day to archive dates (Because they are now 'from', instead of 'to' values)
-- ---------------------------------------

DROP PROCEDURE IF EXISTS update_add_one_day_projects_history_dates;
-- EOC
DELIMITER $$
CREATE PROCEDURE update_add_one_day_projects_history_dates(
    IN curr_project_id VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN

    DECLARE valid_from_dates datetime;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    -- --------------------------- Get current dates ---------------------------
    DECLARE project_dates CURSOR FOR 	SELECT migrate_valid_from_date
            FROM lut_hon_proj_history AS lh WHERE lh.Proj_LfdNr=curr_project_id AND lh.migrate_valid_from_date > '1901-01-31'
        UNION DISTINCT
            SELECT migrate_valid_from_date
            FROM sollab_history AS bh WHERE bh.Proj_LfdNr=curr_project_id AND bh.migrate_valid_from_date > '1901-01-31'
        UNION DISTINCT
            SELECT migrate_valid_from_date
            FROM schaetzungfertig_history AS cl WHERE cl.Proj_LfdNr=curr_project_id AND cl.migrate_valid_from_date > '1901-01-31'
        ORDER BY migrate_valid_from_date DESC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    -- --------------------------- Add one day to dates ---------------------------
    OPEN project_dates;
    cursor_loop: LOOP -- -------------------------------------
        FETCH project_dates INTO valid_from_dates;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
        
        -- Do not update, if the new date already exists in work_packages_history
        IF ( (SELECT COUNT(*) FROM work_packages_history AS wph WHERE wph.project_id=curr_project_id AND wph.date=ADDDATE(valid_from_dates, INTERVAL 1 DAY))>0 ) THEN 
            LEAVE cursor_loop;
        END IF;
        
        UPDATE work_packages_history AS wph SET wph.date = ADDDATE(valid_from_dates, INTERVAL 1 DAY) WHERE wph.project_id=curr_project_id AND wph.date=valid_from_dates;

        UPDATE work_packages_history_descriptions AS wph SET wph.archive_date = ADDDATE(valid_from_dates, INTERVAL 1 DAY) WHERE wph.project_id=curr_project_id AND wph.archive_date=valid_from_dates;
        
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  project_dates;
END $$
DELIMITER ;
-- EOC

-- -----------------------------------------
-- Extract a single string from a json like format
-- -----------------------------------------

DROP FUNCTION IF EXISTS `us_json_extract`;
-- EOC
DELIMITER $$
CREATE FUNCTION `us_json_extract`(
    json_doc TEXT,
    key_name VARCHAR (20)
) RETURNS TEXT
DETERMINISTIC
NO SQL
BEGIN
    DECLARE found_val TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    SET key_name = CONCAT('"', key_name, '"');
    
    -- Do we have the key in the json_doc
    IF INSTR(json_doc, key_name) <= 0 THEN
        RETURN null;
    END IF;
    
    -- Get value
    SET found_val = SUBSTRING_INDEX(
		SUBSTRING_INDEX(
			SUBSTRING_INDEX(
				json_doc,
				key_name,
				- 1
			),
			',"',
			1
		),
		':',
		-1
	);
    
    -- Return trimmed value
    RETURN TRIM(BOTH '"' FROM TRIM(TRAILING '}' FROM TRIM(LEADING '{' FROM found_val)));
END $$
DELIMITER ;
-- EOC

-- -----------------------------------------
-- Extract a single array from a json like format
-- -----------------------------------------

DROP FUNCTION IF EXISTS `us_json_extract_arr`;
-- EOC
DELIMITER $$
CREATE FUNCTION `us_json_extract_arr`(
    json_doc TEXT,
    key_name VARCHAR (20)
) RETURNS TEXT
DETERMINISTIC
NO SQL
BEGIN
    DECLARE found_val TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    SET key_name = CONCAT('"', key_name, '":[');
    
    -- Do we have the key in the json_doc
    IF INSTR(json_doc, key_name) <= 0 THEN
        RETURN null;
    END IF;
    
    -- Get value
    SET found_val = SUBSTRING_INDEX(
		SUBSTRING_INDEX(
			SUBSTRING_INDEX(
				json_doc,
				key_name,
				- 1
			),
			'],',
			1
		),
		':[',
		-1
	);
    
    -- Return trimmed value
    RETURN TRIM(TRAILING '}' FROM TRIM(LEADING '{' FROM found_val));
END $$
DELIMITER ;
-- EOC

-- -----------------------------------------
-- Change fields of times/travels/extras/externalexpenses for calcexp
-- -----------------------------------------

DROP PROCEDURE IF EXISTS us_migrate_12_13_add_id_to_calcexp_tables;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_12_13_add_id_to_calcexp_tables()
BEGIN
    CALL us_add_to_table2('times', 'calcexp_id', 'INT DEFAULT NULL AFTER is_ignore' );
    CALL us_add_to_table2('times', 'calcexp_id_staff', 'INT DEFAULT NULL AFTER is_ignore_staff' );
    CALL us_add_to_table2('times', 'calcexp_id_woa', 'INT DEFAULT NULL AFTER is_ignore_woa' );
    CALL us_add_to_table2('travels', 'calcexp_id', 'INT DEFAULT NULL AFTER is_ignore' );
    CALL us_add_to_table2('extras', 'calcexp_id', 'INT DEFAULT NULL AFTER is_ignore' );
    CALL us_add_to_table2('externalexpenses', 'calcexp_id', 'INT DEFAULT NULL AFTER is_deducted' );
END $$
DELIMITER ;
-- EOC

-- -----------------------------------------
-- Get a value from a string set/list
-- -----------------------------------------

DROP FUNCTION IF EXISTS `us_get_from_set`;
-- EOC
DELIMITER $$
CREATE FUNCTION `us_get_from_set`(
    key_index INTEGER,
    strlist TEXT
) RETURNS TEXT
DETERMINISTIC
NO SQL
BEGIN
    RETURN TRIM(BOTH '"' FROM SUBSTRING_INDEX(SUBSTRING_INDEX(strlist, ',', key_index), ',', -1));
END $$
DELIMITER ;
-- EOC



-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- USC Views fuer bestehende Tabellen werden angelegt.
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS us_migrate_11_12_prepare_old_views;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_prepare_old_views()
us_migrate_11_12_prepare_old_viewslbl:BEGIN
    -- Prevent execution, if externekosten is missing
    IF ( (SELECT COUNT(*) FROM information_schema.TABLES WHERE table_schema = DATABASE() AND table_name='externekosten')<=0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - us_migrate_11_12_prepare_old_views';
        LEAVE us_migrate_11_12_prepare_old_viewslbl;
    END IF;

    -- Allow calcexp for externalexpenses
    CALL us_add_to_table2('externekosten', 'is_deducted', 'TINYINT unsigned NOT NULL DEFAULT 0' );
    CALL us_add_to_table2('externekosten', 'deducted_day', 'datetime DEFAULT NULL AFTER `is_deducted`' );
    CALL us_add_to_table2('externekosten', 'is_ignore', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `deducted_day`' );

    CALL us_add_to_table2('kopien', 'company_id', 'INT NULL AFTER `KostenStelle`' );
    CALL us_add_to_table2('aenderungkopien', 'company_id', 'INT NULL AFTER `Kostenstelle`' );
    CALL us_add_to_table2('zeiten', 'company_id', 'INT NULL AFTER `Bemerkung_Intern`' );
    CALL us_add_to_table2('zeiten', 'skill_id', 'INT NULL' );
    CALL us_add_to_table2('aenderungzeiten', 'company_id', 'INT NULL AFTER `LfdNr`' );
    CALL us_add_to_table2('aenderungzeiten', 'skill_id', 'INT NULL' );
    CALL us_add_to_table2('km', 'company_id', 'INT NULL AFTER `ErstAm`' );
    CALL us_add_to_table2('aenderungkm', 'company_id', 'INT NULL AFTER `LfdNr`' );

    CALL us_add_to_table2('aenderungzeiten', 'Bemerkung_Intern', 'longtext' );
    CALL us_add_to_table2('aenderungzeiten', 'is_client_changed', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `Bemerkung_Intern`' );
    CALL us_add_to_table2('aenderungzeiten', 'addi_val1', 'DOUBLE NOT NULL DEFAULT 0' );
    CALL us_add_to_table2('aenderungzeiten', 'addi_val2', 'DOUBLE NOT NULL DEFAULT 0' );
    CALL us_add_to_table2('aenderungkopien', 'is_client_changed', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `Bemerkung`' );
    CALL us_add_to_table2('aenderungkopien', 'addi_val1', 'DOUBLE NOT NULL DEFAULT 0' );
    CALL us_add_to_table2('aenderungkopien', 'addi_val2', 'DOUBLE NOT NULL DEFAULT 0' );
    CALL us_add_to_table2('aenderungkm', 'is_client_changed', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `Bemerkung`' );
    CALL us_add_to_table2('aenderungkm', 'addi_val1', 'DOUBLE NOT NULL DEFAULT 0' );
    CALL us_add_to_table2('aenderungkm', 'addi_val2', 'DOUBLE NOT NULL DEFAULT 0' );

    CALL us_add_to_table2('planverz', 'is_autopath', 'BOOLEAN DEFAULT FALSE' );

    CALL us_add_to_table2('planverz', 'Arbeitsbereich', 'INT DEFAULT NULL' );
    CALL us_add_to_table2('planlieferschein', 'Arbeitsbereich', 'INT DEFAULT NULL' );
    CALL us_add_to_table2('planeingang', 'Arbeitsbereich', 'INT DEFAULT NULL' );

    -- Add currencies support
    CALL us_add_to_table2('kopien', 'company_cost_per_unit', 'DOUBLE NULL AFTER `Ep`' );
    CALL us_add_to_table2('kopien', 'company_cost_per_unit_ex', 'DOUBLE NOT NULL DEFAULT 1 AFTER `company_cost_per_unit`' );
    CALL us_add_to_table2('kopien', 'company_cost_per_unit_id', 'INT NULL AFTER `company_cost_per_unit_ex`' );

    CALL us_add_to_table2('kopien', 'company_price_per_unit', 'DOUBLE NULL AFTER `ExtSatz`' );
    CALL us_add_to_table2('kopien', 'company_price_per_unit_ex', 'DOUBLE NOT NULL DEFAULT 1 AFTER `company_price_per_unit`' );
    CALL us_add_to_table2('kopien', 'company_price_per_unit_id', 'INT NULL AFTER `company_price_per_unit_ex`' );

    CALL us_add_to_table2('kopien', 'is_client_changed', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `Bemerkung`' );
    CALL us_add_to_table2('kopien', 'addi_val1', 'DOUBLE NOT NULL DEFAULT 0' );
    CALL us_add_to_table2('kopien', 'addi_val2', 'DOUBLE NOT NULL DEFAULT 0' );

    -- Add currencies support
    CALL us_add_to_table2('km', 'company_cost_per_unit', 'DOUBLE NULL AFTER `Ep`' );
    CALL us_add_to_table2('km', 'company_cost_per_unit_ex', 'DOUBLE NOT NULL DEFAULT 1 AFTER `company_cost_per_unit`' );
    CALL us_add_to_table2('km', 'company_cost_per_unit_id', 'INT NULL AFTER `company_cost_per_unit_ex`' );

    CALL us_add_to_table2('km', 'company_price_per_unit', 'DOUBLE NULL AFTER `ExtSatz`' );
    CALL us_add_to_table2('km', 'company_price_per_unit_ex', 'DOUBLE NOT NULL DEFAULT 1 AFTER `company_price_per_unit`' );
    CALL us_add_to_table2('km', 'company_price_per_unit_id', 'INT NULL AFTER `company_price_per_unit_ex`' );

    CALL us_add_to_table2('km', 'is_client_changed', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `Bemerkung`' );
    CALL us_add_to_table2('km', 'addi_val1', 'DOUBLE NOT NULL DEFAULT 0' );
    CALL us_add_to_table2('km', 'addi_val2', 'DOUBLE NOT NULL DEFAULT 0' );

    -- Add currencies support
    CALL us_add_to_table2('zeiten', 'company_gross_hourly_wage', 'DOUBLE NULL AFTER `BruttoLohn`' );
    CALL us_add_to_table2('zeiten', 'company_gross_hourly_wage_ex', 'DOUBLE NOT NULL DEFAULT 1 AFTER `company_gross_hourly_wage`' );
    CALL us_add_to_table2('zeiten', 'company_gross_hourly_wage_id', 'INT NULL AFTER `company_gross_hourly_wage_ex`' );
    
    -- Add currencies support
    CALL us_add_to_table2('posteingang', 'Arbeitsbereich', 'INT DEFAULT NULL' );
    CALL us_add_to_table2('posteingang', 'recipient_id', 'INT DEFAULT NULL AFTER `Arbeitsbereich`' );
    UPDATE posteingang SET recipient_id=ErstVon WHERE recipient_id IS NULL;

    -- Add currencies support
    CALL us_add_to_table2('postausgang', 'Arbeitsbereich', 'INT DEFAULT NULL' );

    -- Add currencies support
    CALL us_add_to_table2('zeiten', 'company_value1', 'DOUBLE NULL AFTER `Betrag9`' );
    CALL us_add_to_table2('zeiten', 'company_value2', 'DOUBLE NULL AFTER `company_value1`' );
    CALL us_add_to_table2('zeiten', 'company_value3', 'DOUBLE NULL AFTER `company_value2`' );
    CALL us_add_to_table2('zeiten', 'company_value4', 'DOUBLE NULL AFTER `company_value3`' );
    CALL us_add_to_table2('zeiten', 'company_value5', 'DOUBLE NULL AFTER `company_value4`' );
    CALL us_add_to_table2('zeiten', 'company_value6', 'DOUBLE NULL AFTER `company_value5`' );
    CALL us_add_to_table2('zeiten', 'company_value7', 'DOUBLE NULL AFTER `company_value6`' );
    CALL us_add_to_table2('zeiten', 'company_value8', 'DOUBLE NULL AFTER `company_value7`' );
    CALL us_add_to_table2('zeiten', 'company_value9', 'DOUBLE NULL AFTER `company_value8`' );
    CALL us_add_to_table2('zeiten', 'company_value_ex', 'DOUBLE NOT NULL DEFAULT 1 AFTER `company_value9`' );
    CALL us_add_to_table2('zeiten', 'company_value_id', 'INT NULL AFTER `company_value_ex`' );

    CALL us_add_to_table2('zeiten', 'company_price_per_unit', 'DOUBLE NULL AFTER `ExtSatz`' );
    CALL us_add_to_table2('zeiten', 'company_price_per_unit_ex', 'DOUBLE NOT NULL DEFAULT 1 AFTER `company_price_per_unit`' );
    CALL us_add_to_table2('zeiten', 'company_price_per_unit_id', 'INT NULL AFTER `company_price_per_unit_ex`' );

    CALL us_add_to_table2('zeiten', 'company_price_external_staff', 'DOUBLE NULL AFTER `PersonenSatz`' );
    CALL us_add_to_table2('zeiten', 'company_price_external_staff_ex', 'DOUBLE NOT NULL DEFAULT 1 AFTER `company_price_external_staff`' );
    CALL us_add_to_table2('zeiten', 'company_price_external_staff_id', 'INT NULL AFTER `company_price_external_staff_ex`' );

    CALL us_add_to_table2('zeiten', 'company_price_area', 'DOUBLE NULL AFTER `ArbSatz`' );
    CALL us_add_to_table2('zeiten', 'company_price_area_ex', 'DOUBLE NOT NULL DEFAULT 1 AFTER `company_price_area`' );
    CALL us_add_to_table2('zeiten', 'company_price_area_id', 'INT NULL AFTER `company_price_area_ex`' );

    CALL us_add_to_table2('zeiten', 'is_client_changed', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `Bemerkung_Intern`' );
    CALL us_add_to_table2('zeiten', 'addi_val1', 'DOUBLE NOT NULL DEFAULT 0' );
    CALL us_add_to_table2('zeiten', 'addi_val2', 'DOUBLE NOT NULL DEFAULT 0' );
    CALL us_add_to_table2('zeiten', 'opta_id', 'INT DEFAULT 0 AFTER LfdNr_PersTermin' );
    CALL us_add_to_table2('stechuhr', 'is_client_changed', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `Bereich`' );
    CALL us_add_to_table2('stechuhr', 'skill_grp_id', 'INT DEFAULT NULL AFTER `Bereich`' );

    CALL us_add_to_table2('externekosten', 'UstSatz', 'DOUBLE DEFAULT NULL' );
    CALL us_add_to_table2('geexternekosten', 'UstSatz', 'DOUBLE DEFAULT NULL' );
    
    CALL us_add_to_table2('externekosten', 'surcharge_used', 'DOUBLE DEFAULT NULL' );
    CALL us_add_to_table2('geexternekosten', 'surcharge_used', 'DOUBLE DEFAULT NULL' );

    CALL change_column('kopien', 'zweck', 'VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    CALL change_column('aenderungkopien', 'zweck', 'VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    CALL change_column('km', 'zweck', 'VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    CALL change_column('aenderungkm', 'zweck', 'VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');

    CALL change_column('honverw', 'Bemerkung', 'VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    CALL change_column('gehonverw', 'Bemerkung', 'VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    CALL us_add_to_table2('honverw', 'correspondence_id', 'INT NULL AFTER `Arbeitsbereich`' );
    CALL us_add_to_table2('gehonverw', 'correspondence_id', 'INT NULL AFTER `FaelligAmGeplant`' );
    CALL us_add_to_table2('honverw', 'is_calcexp', 'BOOLEAN DEFAULT 0 AFTER `correspondence_id`');
    CALL us_add_to_table2('gehonverw', 'is_calcexp', 'BOOLEAN DEFAULT 0 AFTER `correspondence_id`');
    CALL us_add_to_table2('honverw', 'discount', 'DOUBLE DEFAULT 0' );
    CALL us_add_to_table2('gehonverw', 'discount', 'DOUBLE DEFAULT 0' );
    CALL us_add_to_table2('honverw', 'discount_date', 'datetime DEFAULT NULL' );
    CALL us_add_to_table2('gehonverw', 'discount_date', 'datetime DEFAULT NULL' );
    CALL us_add_to_table2('honverw', 'finally_invoiced', 'BOOLEAN DEFAULT 0 ');
    CALL us_add_to_table2('gehonverw', 'finally_invoiced', 'BOOLEAN DEFAULT 0 ');

    CALL change_column('zeiten', 'Bemerkung', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    CALL change_column('aenderungzeiten', 'Bemerkung', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    CALL change_column('km', 'Bemerkung', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    CALL change_column('aenderungkm', 'Bemerkung', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    CALL change_column('kopien', 'Bemerkung', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    CALL change_column('aenderungkopien', 'Bemerkung', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    
    CALL us_add_to_table2('kopien', 'KopienMwSt', 'DOUBLE DEFAULT NULL AFTER `AnzahlExtern`' );
    CALL us_add_to_table2('km', 'KmMwSt', 'DOUBLE DEFAULT NULL' );

    CALL change_column('planverz', 'CADFile', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    CALL change_column('planverz', 'PlanNr', 'VARCHAR(255) NULL DEFAULT NULL');
    CALL change_column('planverz', 'PLOTFile', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
    CALL change_column('planeingang', 'PlanInhalt', 'VARCHAR( 255 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');

    CALL us_add_to_table2('planeingang', 'description', 'TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL;' );

    -- VIEWS

    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `attendance_clock`
     AS SELECT LfdNr AS id, Projekt AS project_id, Person AS staff_id, Start AS start_date, Ende AS end_date, Aktuell AS current,
     Bemerkung AS purpose, BemerkungIntern AS purpose_internal, Bereich AS area_id, is_client_changed, editiert AS changed, Importiert AS imported, skill_grp_id FROM stechuhr;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `drawings` AS
     SELECT LfdNr AS id, Projekt AS project_id, PlanNr AS plan_no, PlanInhalt AS plan_content, `Index` AS `plan_index`, Art AS `type_id`, Flaeche as area,
     Gez AS signed_by, Datum AS `date`, ErsDurch AS replaced_by, ErsFuer AS re_destinations, Erledigt AS is_done, SubPlan AS sub_plan, 
     GroesseBez AS `size_id`, Aenderung AS redline_remarks, MassStab AS `scale`, CADFile AS cad_file, PLOTFile AS plot_file, ErstAm AS created_date, 
     ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id, Bemerkung AS purpose, Ablage AS clipboard, Freigabe AS approved, 
     FreiExt AS approved_external, FreiBis AS approval_deadline, Arbeitsbereich AS work_area_id, is_autopath
     FROM planverz;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `drawings_inbox` AS
     SELECT LfdNr AS id, Projekt AS project_id, PlanNr AS plan_no, PlanInhalt AS plan_content, EingangsDatum AS `date`, `Index` AS plan_index, Von AS address_id,
     Datei AS `file`, Arbeitsbereich AS work_area_id, ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id,
     description
     FROM planeingang;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `externalexpenses` AS
     SELECT  LfdNr AS id, Projekt AS project_id, Zweck as purpose, Beschreibung AS description, Betrag AS value, surcharge_used, Empfaenger AS address_id,
     Bereich AS area_id, UserNum AS creator_id, Datum AS date, ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date,
     AendVon AS changed_by_id, Kostenstelle AS cost_centre_id, isHonEff AS is_hon_decr, isANA AS is_calc_from_expenses, verrechnetAm AS charge_date,
     verrechnet AS charged, UstSatz AS turnover_rate,
     is_deducted, deducted_day, is_ignore
     FROM externekosten;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `externalexpenses_planned` AS
     SELECT  LfdNr AS id, Projekt AS project_id, Zweck as purpose, Beschreibung AS description, Betrag AS value, surcharge_used, Empfaenger AS address_id,
     Bereich AS area_id, UserNum AS creator_id, Datum AS date, ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date,
     AendVon AS changed_by_id, Kostenstelle AS cost_centre_id, isHonEff AS is_hon_decr, isANA AS is_calc_from_expenses, verrechnetAm AS charge_date,
     verrechnet AS charged, UEbernommen AS is_transfered, UstSatz AS turnover_rate
     FROM geexternekosten;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `extras`
     AS SELECT LfdNr AS id, Projekt AS project_id, Person AS staff_id, Zweck AS purpose, Anzahl AS number, Bemerkung AS description, is_client_changed,
     addi_val1, addi_val2,
     Datum AS DATE, ExtSatz AS price_per_unit, Art AS type_id, Bereich AS area_id, KostenStelle AS cost_centre_id, Ep AS cost_per_unit,
     deducted AS is_deducted, deductedDay AS deducted_day, AnzahlExtern AS number_external, 
     ErstAm AS change_date, EingabeVon AS changed_by_id, ignor AS is_ignore,
     company_id, company_cost_per_unit, company_cost_per_unit_ex, company_cost_per_unit_id, company_price_per_unit, company_price_per_unit_ex,
     company_price_per_unit_id, KopienMwSt as vat FROM kopien;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `extras_logging`
     AS SELECT  LfdNr AS id, Projekt AS project_id, Person AS staff_id, Zweck AS purpose, Anzahl AS number, Bemerkung AS description,
     Datum AS date, Art AS type_id, Bereich AS area_id, KostenStelle AS cost_centre_id,
     Ep AS cost_per_unit, deducted AS is_deducted, deductedDay AS deducted_day, 
     EingabeVon AS changed_by_id, ignor AS is_ignore, EditArt AS log_change_mode, EditDatum AS log_change_date, GeaendertVon  AS log_changed_by_id,
     company_id, is_client_changed,
     addi_val1, addi_val2
     FROM aenderungkopien;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `fees` AS
     SELECT  LfdNr AS id, Projekt AS project_id, Bemerkung as purpose, Betrag AS value, Betrag AS value_otcurr, Empfaenger AS address_id,
     Arbeitsbereich AS area_id, User AS user_id, ReDatum AS fee_date, ReNr AS fee_no, ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date,
     AendVon AS changed_by_id, Kostenstelle AS cost_centre_id, ErfDatum AS entry_date, Erledigt AS is_done, ErlDatum AS done_date,
     Konto AS fee_account_id, UstSatz AS turnover_rate, UEberwiesen AS remited, UEberweisungsbem AS remit_purpose, vorRechnung AS predecessor_id,
     nextRechnung AS successor_id, FaelligAm AS due_date, MahnStufe AS reminder_level, letzteMahn AS last_reminder_date, isProzent AS is_percentage,
     Abzug AS deduction, correspondence_id, is_calcexp, discount, discount_date, finally_invoiced
     FROM honverw;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `fees_planned` AS
     SELECT  LfdNr AS id, Projekt AS project_id, Bemerkung as purpose, Betrag AS value, Empfaenger AS address_id,
     Arbeitsbereich AS area_id, User AS user_id, ReDatum AS fee_date, ReNr AS fee_no, ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date,
     AendVon AS changed_by_id, Kostenstelle AS cost_centre_id, ErfDatum AS entry_date, Erledigt AS is_done, ErlDatum AS done_date,
     Konto AS fee_account_id, UstSatz AS turnover_rate, UEberwiesen AS remited, UEberweisungsbem AS remit_purpose, vorRechnung AS predecessor_id,
     nextRechnung AS successor_id, FaelligAm AS due_date, MahnStufe AS reminder_level, letzteMahn AS last_reminder_date, isProzent AS is_percentage,
     Abzug AS deduction, FaelligAmGeplant AS due_date_planned, correspondence_id, is_calcexp, discount, discount_date, finally_invoiced
     FROM gehonverw;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `lut_fee_areas_offer`
     AS SELECT LfdNr AS id, AngebotLfdNr AS offer_id, HonorarLfdNr AS fee_area_id, Kosten AS costs, KostenProzent AS costs_percent,
     KostenGesamt AS costs_sum, KostenGesamtEingabe AS is_costs_sum
     FROM lut_hon_angebot;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `times`
     AS SELECT LfdNr AS id, Projekt AS project_id, Person AS staff_id, Zeit01 AS number, Faktor AS factor, ZeitVon AS time_from, ZeitBis AS time_to, Bemerkung AS purpose,
     Bemerkung_Intern AS purpose_internal, is_client_changed, 
     addi_val1, addi_val2,
     Datum AS date, ArbBereich AS area_id, KostenStelle AS cost_centre_id, deducted AS is_deducted, deductedDay AS deducted_day, ignor AS is_ignore, 
     deducted_Pers AS is_deducted_staff, deductedDay_Pers AS deducted_day_staff, ignor_Pers AS is_ignore_staff, 
     deducted_Arb AS is_deducted_woa, deductedDay_Arb AS deducted_day_woa, ignor_Arb AS is_ignore_woa, 
     StundenExtern AS number_external, StundenExternChanged AS number_external_changed, 
     ErstAm AS change_date, EingabeVon AS changed_by_id, ExtSatz AS price_per_unit, PersonenSatz AS price_external_staff, ArbSatz AS price_area,
     Bruttolohn AS gross_hourly_wage, Satz1 AS percntg1, Satz2 AS percntg2, Satz3 AS percntg3, Satz4 AS percntg4, Satz5 AS percntg5, Satz6 AS percntg6,
     Satz7 AS percntg7, Satz8 AS percntg8, Satz9 AS percntg9, Betrag1 AS value1, Betrag2 AS value2, Betrag3 AS value3, Betrag4 AS value4, Betrag5 AS value5, Betrag6 AS value6,
     Betrag7 AS value7, Betrag8 AS value8, Betrag9 AS value9, company_id, company_value1, company_value2, company_value3, company_value4, company_value5,
     company_value6, company_value7, company_value8, company_value9, company_value_ex, company_value_id,
     LfdNr_Urlaub AS vacation_id, LfdNr_PersTermin AS persapp_id,
     company_gross_hourly_wage, company_gross_hourly_wage_ex, company_gross_hourly_wage_id, company_price_per_unit, company_price_per_unit_ex, company_price_per_unit_id,
     company_price_external_staff, company_price_external_staff_ex, company_price_external_staff_id, company_price_area, company_price_area_ex, company_price_area_id, opta_id, skill_id
     FROM zeiten;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `times_logging`
     AS SELECT LfdNr AS id, Projekt AS project_id, Person AS staff_id, Zeit01 AS number, Faktor AS factor, ZeitVon AS time_from, ZeitBis AS time_to,
     Bemerkung AS purpose, Datum AS date, ArbBereich AS area_id, KostenStelle AS cost_centre_id, deducted AS is_deducted, deductedDay AS deducted_day,
     EingabeVon AS changed_by_id, ignor AS is_ignore, Bruttolohn AS gross_hourly_wage, EditArt AS log_change_mode, EditDatum AS log_change_date, GeaendertVon  AS log_changed_by_id,
     company_id, Bemerkung_Intern AS purpose_internal, is_client_changed, skill_id,
     addi_val1, addi_val2
     FROM aenderungzeiten;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `transmittal_form` AS
     SELECT LfdNr AS id, Datum AS `date`, Projekt AS project_id, Empfaenger AS address_id, Von AS staff_id, Bemerkung AS purpose,
     ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id, LSNr AS transmittal_form_name,
     DOC_Datei AS doc_file, PDF_Datei AS pdf_file, BemerkungDruck AS print_purpose, ZusatzBemerkung AS comment, Anmerkungen AS remarks,
     Arbeitsbereich AS work_area_id
     FROM planlieferschein;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `travels`
     AS SELECT LfdNr AS id, Projekt AS project_id, Person AS staff_id, Ziel AS route, Zweck AS purpose, km AS number, BueroPKW AS is_company_car, 
     kmVon AS km_from, kmBis AS km_to, ZeitVon AS time_from, ZeitBis AS time_to, Bemerkung AS description, is_client_changed,
     addi_val1, addi_val2,
     Datum AS date, Ep AS cost_per_unit, ExtSatz AS price_per_unit, Art AS type_id, Bereich AS area_id, KostenStelle AS cost_centre_id, 
     deducted AS is_deducted, deductedDay AS deducted_day, KmExtern AS number_external, 
     ErstAm AS change_date, EingabeVon AS changed_by_id, ignor AS is_ignore,
     company_id, company_cost_per_unit, company_cost_per_unit_ex, company_cost_per_unit_id, company_price_per_unit, company_price_per_unit_ex,
     company_price_per_unit_id, KmMwSt as vat FROM km;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `travels_logging`
     AS SELECT LfdNr AS id, Projekt AS project_id, Person AS staff_id, Ziel AS route, Zweck AS purpose, km AS number, BueroPKW AS is_company_car, kmVon AS km_from, kmBis AS km_to,
     ZeitVon AS time_from, ZeitBis AS time_to, Bemerkung AS description, Datum AS date, Art AS type_id, Bereich AS area_id, KostenStelle AS cost_centre_id,
     Ep AS cost_per_unit, deducted AS is_deducted, deductedDay AS deducted_day, EingabeVon AS changed_by_id, ignor AS is_ignore,
     EditArt AS log_change_mode, EditDatum AS log_change_date, GeaendertVon  AS log_changed_by_id, company_id, is_client_changed,
     addi_val1, addi_val2
     FROM aenderungkm;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `work_areas_rates`
     AS SELECT LfdNr AS id, Satz AS rate_id, AB AS area_id, NeuerSatz AS rate, LfdNr_ProjektAbrAB_Zeit AS history_id FROM projektabrab;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `work_areas_rates_history`
     AS SELECT `LfdNr` AS id, `LfdNr_Satz` AS rate_id, `von` AS date_from, `bis` AS date_to
     FROM `projektabrab_zeit`;


    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `inbox` AS
     SELECT LfdNr AS id, Projekt AS project_id, Nr AS `no`, PostInhalt AS content, EingangsDatum AS `date`, `index` AS inbox_index, Von AS address_id,
     ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id, Art AS dispatch_mode_id, Mail_File AS msg_file,
     AddedFile AS `attached_file`, archiviert AS is_archived, MailAttAnz AS mail_attachments, MailGroesse AS mail_size, MailStufe AS security, Arbeitsbereich AS area_id, recipient_id
     FROM posteingang;

    CREATE OR REPLACE
     ALGORITHM = MERGE
     VIEW `outbox` AS
     SELECT LfdNr AS id, Projekt AS project_id, Nr AS `no`, PostInhalt AS content, AusgangsDatum AS `date`, `index` AS outbox_index, An AS address_id,
     Person AS staff_id, Art AS dispatch_mode_id, ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id,
     docNummer AS doc_id, AttAnzahl AS attachments, KopieAnAnz AS copies, PO_EM_OUT_Pfad AS mail_out_file, Pfad AS `path`, archiviert AS is_archived,
     AddedFile AS `attached_file`, MailID AS mail_id, ParentID AS parent_id, MailAttAnz AS mail_attachments, MailGroesse AS mail_size, LfdNr_Rechnung AS acc_after_exp_bill_id,
     LfdNr_Lieferschein AS transmittal_form_id, MailStufe AS security, Arbeitsbereich AS area_id
     FROM postausgang;


END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- USC Create prepare work package history for projects
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------


DROP PROCEDURE IF EXISTS us_migrate_11_12_projects_history_prepare;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_projects_history_prepare()
BEGIN

    -- --------------------------- Add date from previous rows ---------------------------
    UPDATE lut_fee_areas_proj_history AS bh
        JOIN (
            SELECT bh1.valid_to_date, bh1.project_id,
            (SELECT MAX(bh2.valid_to_date) FROM lut_fee_areas_proj_history AS bh2 WHERE bh2.project_id=bh1.project_id AND bh2.valid_to_date<bh1.valid_to_date) AS valid_from_date
            FROM lut_fee_areas_proj_history AS bh1
        ) bhsub
        ON bhsub.project_id=bh.project_id AND bhsub.valid_to_date=bh.valid_to_date
    SET bh.migrate_valid_from_date = bhsub.valid_from_date;


    UPDATE budget_plan_history AS bh
        JOIN (
            SELECT bh1.valid_to_date, bh1.project_id,
            (SELECT MAX(bh2.valid_to_date) FROM budget_plan_history AS bh2 WHERE bh2.project_id=bh1.project_id AND bh2.valid_to_date<bh1.valid_to_date) AS valid_from_date
            FROM budget_plan_history AS bh1
        ) bhsub
        ON bhsub.project_id=bh.project_id AND bhsub.valid_to_date=bh.valid_to_date
    SET bh.migrate_valid_from_date = bhsub.valid_from_date;


    UPDATE completion_level_history AS bh
        JOIN (
            SELECT bh1.valid_to_date, bh1.project_id,
            (SELECT MAX(bh2.valid_to_date) FROM completion_level_history AS bh2 WHERE bh2.project_id=bh1.project_id AND bh2.valid_to_date<bh1.valid_to_date) AS valid_from_date
            FROM completion_level_history AS bh1
        ) bhsub
        ON bhsub.project_id=bh.project_id AND bhsub.valid_to_date=bh.valid_to_date
    SET bh.migrate_valid_from_date = bhsub.valid_from_date;

    -- --------------------------- Add max date to NULL rows ---------------------------
    UPDATE lut_fee_areas_proj_history AS bh
        JOIN (
            SELECT bh1.project_id,
            (SELECT MAX(bh2.valid_to_date) FROM lut_fee_areas_proj_history AS bh2 WHERE bh2.project_id=bh1.project_id) AS valid_from_date
            FROM lut_fee_areas_proj_history AS bh1
        ) bhsub
        ON bhsub.project_id=bh.project_id
    SET bh.migrate_valid_from_date = bhsub.valid_from_date
    WHERE bh.valid_to_date IS NULL;


    UPDATE budget_plan_history AS bh
        JOIN (
            SELECT bh1.project_id,
            (SELECT MAX(bh2.valid_to_date) FROM budget_plan_history AS bh2 WHERE bh2.project_id=bh1.project_id) AS valid_from_date
            FROM budget_plan_history AS bh1
        ) bhsub
        ON bhsub.project_id=bh.project_id
    SET bh.migrate_valid_from_date = bhsub.valid_from_date
    WHERE bh.valid_to_date IS NULL;


    UPDATE completion_level_history AS bh
        JOIN (
            SELECT bh1.project_id,
            (SELECT MAX(bh2.valid_to_date) FROM completion_level_history AS bh2 WHERE bh2.project_id=bh1.project_id) AS valid_from_date
            FROM completion_level_history AS bh1
        ) bhsub
        ON bhsub.project_id=bh.project_id 
    SET bh.migrate_valid_from_date = bhsub.valid_from_date
    WHERE bh.valid_to_date IS NULL;

    -- --------------------------- Add date NULL values, for start entries ---------------------------
    UPDATE lut_fee_areas_proj_history SET migrate_valid_from_date = '1901-01-01 00:00:00' WHERE migrate_valid_from_date IS NULL;
    UPDATE budget_plan_history SET migrate_valid_from_date = '1901-01-01 00:00:00' WHERE migrate_valid_from_date IS NULL;
    UPDATE completion_level_history SET migrate_valid_from_date = '1901-01-01 00:00:00' WHERE migrate_valid_from_date IS NULL;

END $$
DELIMITER ;
-- EOC


-- @todo BIGINT work_package_id - attendance_clock
-- @todo BIGINT work_package_id - externalexpenses
-- @todo BIGINT work_package_id - externalexpenses_planned
-- @todo BIGINT work_package_id - extras
-- @todo BIGINT work_package_id - formular
-- @todo BIGINT work_package_id - inbox
-- @todo BIGINT work_package_id - lut_fee_areas_offer
-- @todo BIGINT wp_id - lut_fee_wp
-- @todo BIGINT work_package_id - outbox
-- @todo BIGINT work_package_id - times
-- @todo BIGINT work_package_id - todo
-- @todo BIGINT work_package_id - transmittal_form
-- @todo BIGINT work_package_id - travels

-- USC Erstelle X2 Tabellen.

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Work package presets
CREATE TABLE IF NOT EXISTS `work_package_presets` (
    `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `name` VARCHAR( 203 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
    `wp_number` VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
    `description` LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
    `tag_id` INT NULL,
    `lft` BIGINT NULL DEFAULT NULL, 
    `rgt` BIGINT NULL DEFAULT NULL, 
    `tree_id` INT NULL DEFAULT NULL, 
    `is_purpose_required` BOOLEAN, 
    `is_fee_area` BOOLEAN,
    `is_special` INT NULL DEFAULT 0,
    `is_special_phase` INT NULL DEFAULT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('work_package_presets', 'threshold', 'DOUBLE DEFAULT 0' );
-- EOC

CALL us_add_to_table2('work_package_presets', 'description', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `name`' );
-- EOC

CALL change_column('work_package_presets', 'lft', 'BIGINT NULL DEFAULT NULL');
-- EOC

CALL check_rename_column_exists('work_package_presets', 'name', 'name', 'VARCHAR( 203 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT \'\'');
-- EOC

CALL us_add_to_table2('work_package_presets', 'wp_number', 'VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT \'\' AFTER `name`' );
-- EOC

-- For later: CALL us_add_to_table2('work_package_presets', 'wp_fullname', 'VARCHAR(225) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci GENERATED ALWAYS AS (CONCAT(wp_number,\' \',name)) STORED AFTER `wp_number`' );
-- EOC


-- Work package - work_package lang-table
CREATE TABLE IF NOT EXISTS `langs_work_packages_presets` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`work_package_preset_id` INT DEFAULT NULL,
`name` LONGTEXT NULL DEFAULT NULL ,
`language` VARCHAR( 100 ) NULL DEFAULT NULL 
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_work_packages_presets', 'langs_work_packages_presets_unique_1', 'UNIQUE', '`work_package_preset_id` , `language`' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Work package

CREATE TABLE IF NOT EXISTS `work_packages` (
    `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `name` VARCHAR( 203 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
    `wp_number` VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
    `description` LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
    `tag_id` INT NULL,
    `lft` BIGINT NULL DEFAULT NULL, 
    `rgt` BIGINT NULL DEFAULT NULL, 
    `project_id` INT NULL DEFAULT NULL, 
    `is_purpose_required` BOOLEAN, 
    `is_fee_area` BOOLEAN,
    `is_special` INT NULL DEFAULT 0,
    `is_special_phase` INT NULL DEFAULT NULL,
    `completion_level` DOUBLE NULL,   
    `budget_proportion` DOUBLE NULL,
    `budget_planned_costs` DOUBLE NULL,
    `budget_planned_hours` DOUBLE NULL,
    `budget_start` DATETIME NULL,
    `budget_end` DATETIME NULL,
    `budget_threshold` DOUBLE DEFAULT 0,
    `fee_costs` DOUBLE NULL,   
    `fee_hours` DOUBLE NULL,   
    `fee_proportion` DOUBLE NULL,   
    `status` INT NULL,
    `wpp_tree_id` INT NULL COMMENT 'Work package preset tree id',
    `old_fee_area_id` INT NULL,
    `old_work_area_id` INT NULL,
    `category_rate` DOUBLE DEFAULT 0,
    INDEX `wp_lft_index` (`project_id`, `lft`),
    INDEX `wp_rgt_index` (`project_id`, `rgt`)
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('work_packages', 'description', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `name`' );
-- EOC

CALL check_rename_column_exists('work_packages', 'name', 'name', 'VARCHAR( 203 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT \'\'');
-- EOC

CALL us_add_to_table2('work_packages', 'wp_number', 'VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT \'\' AFTER `name`' );
-- EOC

-- For later: CALL us_add_to_table2('work_packages', 'wp_fullname', 'VARCHAR(225) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci GENERATED ALWAYS AS (CONCAT(wp_number,\' \',name)) STORED AFTER `wp_number`' );
-- EOC

-- Work package - work_package lang-table
CREATE TABLE IF NOT EXISTS `langs_work_packages_main` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`work_package_id` INT DEFAULT NULL,
`name` LONGTEXT NULL DEFAULT NULL ,
`language` VARCHAR( 100 ) NULL DEFAULT NULL 
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_work_packages_main', 'langs_work_packages_main_unique_1', 'UNIQUE', '`work_package_id` , `language`' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Work package history

CREATE TABLE IF NOT EXISTS `work_packages_history` (
    `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `project_id` INT NULL DEFAULT NULL, 
    `completion_level` DOUBLE NULL,   
    `budget_proportion` DOUBLE NULL,
    `budget_planned_costs` DOUBLE NULL,
    `budget_planned_hours` DOUBLE NULL,
    `budget_threshold` DOUBLE DEFAULT 0,
    `fee_costs` DOUBLE NULL,   
    `fee_hours` DOUBLE NULL,   
    `fee_proportion` DOUBLE NULL,   
    `wpp_tree_id` INT NULL,
    `date` DATETIME NULL ,
    `wp_id` BIGINT,
    INDEX `wp_id_index` ( `wp_id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Work package and skill group look up table
CREATE TABLE IF NOT EXISTS `lut_skill_wp` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `wp_id` INT NULL,
    `skill_grp_id` INT NULL,
    `proportion` DOUBLE NULL,
    `start` DATETIME NULL,
    `end` DATETIME NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Work package and staff look up table
CREATE TABLE IF NOT EXISTS `lut_staff_wp` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `rp_id` INT NULL,
    `staff_id` INT NULL,
    `proportion` DOUBLE NULL,
    `description` LONGTEXT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- work packages tags
CREATE TABLE IF NOT EXISTS `work_packages_tags` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `name` VARCHAR(100) DEFAULT NULL,
    `wp_name` VARCHAR(100) DEFAULT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- work packages tags lang-table
CREATE TABLE IF NOT EXISTS `langs_work_packages_tags` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `work_packages_tags_id` INT NOT NULL,
    `name` VARCHAR(100) NOT NULL,
    `wp_name` VARCHAR(100) NOT NULL,
    `language` VARCHAR(50) NOT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_work_packages_tags', 'langs_work_packages_tags_unique_1', 'UNIQUE', '`work_packages_tags_id` , `language`' );
-- EOC

CREATE TABLE IF NOT EXISTS `work_packages_history_descriptions` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `description` VARCHAR(255) DEFAULT NULL,
    `archive_date`  DATETIME NULL,
    `project_id` INT NULL DEFAULT NULL, 
    `type` VARCHAR(100) DEFAULT NULL,
    `staff_id` INT NULL DEFAULT NULL, 
    `insert_date`  DATETIME NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Work packages
CALL change_column('work_packages', 'status', 'DOUBLE NULL DEFAULT 20');
-- EOC
CALL us_add_to_table2('work_packages_history', 'wp_id', 'BIGINT' );
-- EOC
CALL us_add_to_table2('work_packages', 'active_calcexp', 'INT NULL DEFAULT 1' );
-- EOC
CALL us_add_to_table2('work_packages', 'is_special_phase', 'INT NULL DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('work_packages', 'cost_centre_id', 'INT NULL DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('work_packages', 'is_extern', 'TINYINT DEFAULT 0' );
-- EOC
CALL us_add_to_table2('work_packages', 'loc_estimation_date', 'DATETIME NULL' );
-- EOC
CALL us_add_to_table2('work_packages', 'min_start', 'DATETIME NULL' );
-- EOC
CALL us_add_to_table2('work_packages', 'max_end', 'DATETIME NULL' );
-- EOC
CALL us_add_to_table2('work_packages', 'category_rate', 'DOUBLE DEFAULT 0' );
-- EOC
CALL us_add_to_table2('work_packages', 'is_custom_category_rate', 'TINYINT DEFAULT 0' );
-- EOC
CALL us_add_to_table2('work_packages_history', 'loc_estimation_date', 'DATETIME NULL' );
-- EOC
CALL us_add_to_table2('work_package_presets', 'is_special_phase', 'INT NULL DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('work_package_presets', 'tag_id', 'INT NULL' );
-- EOC
CALL us_add_to_table2('work_package_presets', 'is_extern', 'TINYINT DEFAULT 0' );
-- EOC
CALL us_add_to_table2('work_package_presets', 'old_fee_area_id', 'INT NULL' );
-- EOC
CALL us_add_to_table2('work_package_presets', 'old_work_area_id', 'INT NULL' );
-- EOC
CALL us_add_to_table2('work_package_presets', 'cost_centre_id', 'INT NULL DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('work_packages', 'tag_id', 'INT NULL' );
-- EOC
CALL us_add_to_table2('work_packages', 'parent_id_cache', 'BIGINT NULL' );
-- EOC
CALL us_add_index_to_table('work_packages', 'parent_id_cache_index', '`parent_id_cache`' );
-- EOC


CALL us_add_constraint_to_table('work_package_presets', 'wpp_lft_unique', 'UNIQUE', '`tree_id` , `lft`' );
-- EOC
CALL us_add_constraint_to_table('work_package_presets', 'wpp_rgt_unique', 'UNIQUE', '`tree_id` , `rgt`' );
-- EOC
CALL us_add_constraint_to_table('work_packages_history', 'wp_history_unique', 'UNIQUE', '`project_id` , `wp_id`, `date`' );
-- EOC
CALL us_add_index_to_table('work_packages_history', 'wp_id_index', '`wp_id`' );
-- EOC


CREATE TABLE IF NOT EXISTS `langs_fee_areas` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`fee_area_id` INT NOT NULL ,
	`name` VARCHAR( 100 ) NOT NULL ,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_fee_areas', 'langs_fee_areas_unique_1', 'UNIQUE', '`fee_area_id` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_work_areas` (
	`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
	`work_area_id` INT NOT NULL ,
	`name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_work_areas', 'langs_work_areas_unique_1', 'UNIQUE', '`work_area_id` , `language`' );
-- EOC

-- Add lut fee table
CREATE TABLE IF NOT EXISTS `lut_fee_wp` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `planned_fee_id` INT NULL DEFAULT NULL, 
    `fee_id` INT NULL DEFAULT NULL, 
    `project_id` INT NULL DEFAULT NULL, 
    `wp_id` INT NULL DEFAULT NULL, 
    `value`  DOUBLE NULL,
    `value_pre_tax`  DOUBLE NULL,
    `diff_pre_tax`  DOUBLE NULL,
    `done_pre_tax`  DOUBLE NULL,
    `value_otcurr`  DOUBLE NULL,
    `value_pre_tax_otcurr`  DOUBLE NULL,
    `done_pre_tax_otcurr`  DOUBLE NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('lut_fee_wp', 'quantity', 'DOUBLE DEFAULT 1 AFTER `wp_id`' );
-- EOC
CALL us_add_to_table2('lut_fee_wp', 'quantity_id', 'INT DEFAULT NULL AFTER `quantity`' );
-- EOC
CALL us_add_to_table2('lut_fee_wp', 'price', 'DOUBLE DEFAULT 0 AFTER `quantity_id`' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Staff - cost_centre lut-table
CREATE TABLE IF NOT EXISTS `lut_staff_cost_centre` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `staff_id` INT DEFAULT NULL,
    `cost_centre_id` INT DEFAULT NULL,
    `from_date` DATETIME NULL,
    `to_date` DATETIME NULL,
    `description` LONGTEXT NULL DEFAULT NULL, 
    `unique_add_id` VARCHAR(140) NULL DEFAULT NULL 
    ) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Staff - gross_hourly_wage lut-table
CREATE TABLE IF NOT EXISTS `lut_staff_gross_hourly_wage` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `staff_id` INT DEFAULT NULL,
    `gross_hourly_wage` DOUBLE DEFAULT NULL,
    `from_date` DATETIME NULL,
    `to_date` DATETIME NULL,
    `description` LONGTEXT NULL DEFAULT NULL, 
    `unique_add_id` VARCHAR(140) NULL DEFAULT NULL 
    ) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Calculate according to expenditure
CREATE TABLE IF NOT EXISTS `calculateaccordingexpenditure` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `project_id` INT DEFAULT NULL,
    `staff_id` INT DEFAULT NULL,
    `description` TEXT DEFAULT NULL,
    `date` DATETIME NOT NULL,
    `is_project` INT DEFAULT 1,
    `is_woa` INT DEFAULT 1,
    `is_staff` INT DEFAULT 0,
    `created_date` DATETIME DEFAULT NULL,
    `created_by_id` INT DEFAULT NULL,
    `change_date` DATETIME DEFAULT NULL,
    `changed_by_id` INT DEFAULT NULL,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

-- @todo remove those rows in 2022
ALTER TABLE `calculateaccordingexpenditure` CHANGE COLUMN `created_date` `created_date` DATETIME DEFAULT NULL;
-- EOC
ALTER TABLE `calculateaccordingexpenditure` CHANGE COLUMN `created_by_id` `created_by_id` INT DEFAULT NULL;
-- EOC
ALTER TABLE `calculateaccordingexpenditure` CHANGE COLUMN `change_date` `change_date` DATETIME DEFAULT NULL;
-- EOC
ALTER TABLE `calculateaccordingexpenditure` CHANGE COLUMN `changed_by_id` `changed_by_id` INT DEFAULT NULL;
-- EOC

CALL us_add_to_table2('calculateaccordingexpenditure', 'staff_id', 'INT DEFAULT NULL AFTER `project_id`' );
-- EOC
CALL us_add_to_table2('calculateaccordingexpenditure', 'is_project', 'INT DEFAULT 1 AFTER `date`' );
-- EOC
CALL us_add_to_table2('calculateaccordingexpenditure', 'is_woa', 'INT DEFAULT 1 AFTER `is_project`' );
-- EOC
CALL us_add_to_table2('calculateaccordingexpenditure', 'is_staff', 'INT DEFAULT 0 AFTER `is_woa`' );
-- EOC
CALL us_add_to_table2('calculateaccordingexpenditure', 'correspondence_id', 'INT DEFAULT NULL AFTER `is_staff`' );
-- EOC
-- @todo End remove those rows in 2022-- USC X2 Update.
SET @debug = 0;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Cleanup, without any structure changes
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS us_migrate_11_12_cleanup;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_cleanup()
BEGIN

    UPDATE work_packages SET fee_costs=0 WHERE fee_costs IS NULL;
    UPDATE work_packages SET fee_hours=0 WHERE fee_hours IS NULL;

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migrate fee area tags to work package tags
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS us_migrate_fee_area_tags;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_fee_area_tags()
us_migrate_fee_area_tagslbl:BEGIN

    -- Prevent execution, if work_packages_tags has ids>10000000
    IF ( (SELECT COUNT(*) FROM work_packages_tags WHERE id>10000000)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - us_migrate_fee_area_tags';
        LEAVE us_migrate_fee_area_tagslbl;
    END IF;

    -- Insert work_packages_tags for fee areas, which are not equal to work areas
    INSERT INTO work_packages_tags(id, name, wp_name) 
        SELECT 
            hb.LfdNr+10000000, 
            IF((SELECT count(*) FROM work_packages_tags wpt WHERE us_delete_spaces(TRIM(wpt.name))=us_delete_spaces(TRIM(hb.HonorarName)))>0, CONCAT('HB ',hb.HonorarName), hb.HonorarName), 
            IF((SELECT count(*) FROM work_packages_tags wpt WHERE us_delete_spaces(TRIM(wpt.name))=us_delete_spaces(TRIM(hb.HonorarName)))>0, CONCAT('HB ',hb.HonorarName), hb.HonorarName)
        FROM honorarbereiche hb 
            WHERE 
                (
                    SELECT count(*) FROM arbeitsbereiche AS ab 
                    WHERE
                        ab.HonBer=hb.LfdNr AND us_delete_spaces(TRIM(ab.ArbName))<>us_delete_spaces(TRIM(hb.HonorarName))
                        AND
                        (SELECT count(*) FROM work_packages_tags WHERE id = hb.LfdNr+10000000)=0
                ) > 0;

    -- Update work package with tag from above
    UPDATE work_packages wp 
    SET 
        tag_id = (
            SELECT 
                id
            FROM
                work_packages_tags wpt
            WHERE
                wp.old_fee_area_id = wpt.id - 10000000
        )
    WHERE
        tag_id IS NULL AND is_fee_area = 1 AND lft > 1;

    -- Update work package presets with tag from above
    UPDATE work_package_presets wpp
    SET 
        tag_id = (
            SELECT 
                id
            FROM
                work_packages_tags wpt
            WHERE
                wpp.old_fee_area_id = wpt.id - 10000000
        )
    WHERE
        tag_id IS NULL AND is_fee_area = 1 AND lft > 1;

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Update work packages status
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS update_wp_status;
-- EOC
DELIMITER $$
CREATE PROCEDURE update_wp_status()
update_wp_statuslbl:BEGIN

    DECLARE project_ids INTEGER;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE wpids CURSOR FOR SELECT project_id FROM work_packages WHERE lft=1 AND (status<>50 OR status IS NULL);
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    OPEN wpids;
    cursor_loop: LOOP -- -------------------------------------
        FETCH wpids INTO project_ids;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
            /*Do something with the row fetched*/
            INSERT INTO `01migrate_11_12` SET elem='project_id_status', info=project_ids;

            UPDATE work_packages AS wp1
                SET status=(
                    SELECT wp2.status FROM (
                        SELECT status, project_id, lft, rgt
                        FROM work_packages
                        WHERE project_id = project_ids
                    ) wp2
                    WHERE wp2.project_id = wp1.project_id AND wp2.lft < wp1.lft AND wp2.rgt > wp1.rgt
                    ORDER BY wp2.rgt - wp1.rgt ASC
                    LIMIT 1)
                WHERE wp1.project_id = project_ids AND wp1.rgt - wp1.lft = 1;

    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  wpids;

    -- For migrations where the status is acitve at every work package
    CALL repair_wp_status();
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS repair_wp_status;
-- EOC
DELIMITER $$
CREATE PROCEDURE repair_wp_status()
repair_wp_statuslbl:BEGIN
    UPDATE work_packages wp 
        SET status = IFNULL(
            (SELECT 
                MAX(HonStatus) -- avoid "subquery returns more than one row": get the max status if "clean lookup table" was not used before the update (multiple entries possible)
            FROM
                lut_hon_proj lhp
            WHERE
                lhp.History_LfdNr = (SELECT 
                    lhph.LfdNr
                FROM
                    lut_hon_proj_history lhph
                WHERE
                    lhph.Proj_LfdNr = wp.project_id
                        AND lhph.GueltigBis IS NULL
                GROUP BY lhph.LfdNr)
                    AND wp.old_fee_area_id = lhp.Hon_LfdNr),
            status)
        WHERE wp.old_fee_area_id IS NOT NULL;
END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Update work packages dates
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS update_wp_add_one_day;
-- EOC
DELIMITER $$
CREATE PROCEDURE update_wp_add_one_day()
BEGIN

    DECLARE project_ids INTEGER;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE project_vals CURSOR FOR SELECT id FROM projects;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    OPEN project_vals;
    cursor_loop: LOOP -- -------------------------------------
        FETCH project_vals INTO project_ids;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
            /*Do something with the row fetched*/
            INSERT INTO `01migrate_11_12` SET elem='update_wp_add_one_day', info=project_ids;
            CALL update_add_one_day_projects_history_dates(project_ids);
            
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  project_vals;

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Update work packages cost centres for 12.6
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS update_cost_centres;
-- EOC
DELIMITER $$
CREATE PROCEDURE update_cost_centres()
update_update_cost_centreslbl:BEGIN

    DECLARE project_ids INTEGER;
    DECLARE cost_centre_ids INTEGER;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE project_vals CURSOR FOR SELECT Kostenstelle, LfdNr FROM projekte WHERE Kostenstelle > 0;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    OPEN project_vals;
    cursor_loop: LOOP -- -------------------------------------
        FETCH project_vals INTO cost_centre_ids, project_ids;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;            
             /*Do something with the row fetched*/
            INSERT INTO `01migrate_11_12` SET elem='project_cost_centres', info=project_ids;
            UPDATE work_packages set cost_centre_id = cost_centre_ids WHERE project_id = project_ids AND cost_centre_id IS NULL;
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  project_vals;

END $$
DELIMITER ;
-- EOC

-- Remove old Kostenstelle field
DROP PROCEDURE IF EXISTS update_cost_centres_cleanup;
-- EOC
DELIMITER $$
CREATE PROCEDURE update_cost_centres_cleanup()
BEGIN

    -- RENAME staff_id to password_salt
    CALL check_rename_column_exists('projekte', 'Kostenstelle', 'Kostenstelle__old', 'INT NULL DEFAULT NULL ');

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Move fee work package for 12.6 to the new look up table if user has used the work package dropdown field in the fee module
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS move_fee_work_package;
-- EOC
DELIMITER $$
CREATE PROCEDURE move_fee_work_package()
update_move_fee_work_packagelbl:BEGIN

     -- Insert the work package structure for the existing fee entries
    INSERT INTO lut_fee_wp (fee_id, project_id, wp_id, value, done_pre_tax, value_pre_tax) SELECT 
        fees.id AS fee_id,
        wp2.project_id,
        wp2.id AS work_package_id,
        CASE WHEN fees.work_package_id > 0 AND (fees.work_package_id = wp2.id OR wp2.id IN (SELECT id FROM work_packages WHERE lft < wp.lft AND rgt > wp.rgt AND project_id = wp.project_id)) THEN fees.value ELSE 0 END,
        CASE WHEN fees.work_package_id > 0 AND (fees.work_package_id = wp2.id OR wp2.id IN (SELECT id FROM work_packages WHERE lft < wp.lft AND rgt > wp.rgt AND project_id = wp.project_id)) THEN fees.remited ELSE 0 END,
	CASE WHEN fees.work_package_id > 0 AND (fees.work_package_id = wp2.id OR wp2.id IN (SELECT id FROM work_packages WHERE lft < wp.lft AND rgt > wp.rgt AND project_id = wp.project_id)) THEN (fees.value * fees.turnover_rate) + fees.value ELSE 0 END
    FROM
        work_packages wp
            INNER JOIN
        work_packages wp2 ON wp.lft >= wp2.lft AND wp.rgt <= wp2.rgt AND wp.project_id = wp2.project_id
            INNER JOIN
        fees on fees.project_id = wp.project_id
    WHERE
        wp.is_fee_area = 1 AND wp2.lft > 1 GROUP BY wp2.id, fee_id ORDER BY fee_id, wp.id;
        
    -- Insert the work package structure for the existing planned fee entries
    INSERT INTO lut_fee_wp (planned_fee_id, project_id, wp_id, value, done_pre_tax, value_pre_tax) SELECT 
        fees_planned.id AS planned_fee_id,
        wp2.project_id,
        wp2.id AS work_package_id,
        CASE WHEN fees_planned.work_package_id > 0 AND (fees_planned.work_package_id = wp2.id OR wp2.id IN (SELECT id FROM work_packages WHERE lft < wp.lft AND rgt > wp.rgt AND project_id = wp.project_id)) THEN fees_planned.value ELSE 0 END,
        CASE WHEN fees_planned.work_package_id > 0 AND (fees_planned.work_package_id = wp2.id OR wp2.id IN (SELECT id FROM work_packages WHERE lft < wp.lft AND rgt > wp.rgt AND project_id = wp.project_id)) THEN fees_planned.remited ELSE 0 END,
	CASE WHEN fees_planned.work_package_id > 0 AND (fees_planned.work_package_id = wp2.id OR wp2.id IN (SELECT id FROM work_packages WHERE lft < wp.lft AND rgt > wp.rgt AND project_id = wp.project_id)) THEN (fees_planned.value * fees_planned.turnover_rate) + fees_planned.value ELSE 0 END
    FROM
        work_packages wp
            INNER JOIN
        work_packages wp2 ON wp.lft >= wp2.lft AND wp.rgt <= wp2.rgt AND wp.project_id = wp2.project_id
            INNER JOIN
        fees_planned on fees_planned.project_id = wp.project_id
    WHERE
        wp.is_fee_area = 1 AND wp2.lft > 1 GROUP BY wp2.id, planned_fee_id ORDER BY planned_fee_id, wp.id;
    

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Move fee values from the payment entries to the new fee wp allocation table
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS update_alloc_with_payments_fees;
-- EOC
DELIMITER $$
CREATE PROCEDURE update_alloc_with_payments_fees()
update_alloc_with_payments_feeslbl:BEGIN

    DECLARE fee_ids INTEGER;
    DECLARE correspondence_ids INTEGER;
    DECLARE turnover_rates DOUBLE;
    DECLARE remited_perc DOUBLE;
    DECLARE fee_values DOUBLE;
    DECLARE fee_otcurr_values DOUBLE;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE fee_vals CURSOR FOR 
        SELECT id, correspondence_id, turnover_rate, remited*100/((value*(turnover_rate*100+100))/100), value, value_otcurr
        FROM fees 
        WHERE correspondence_id IN (select LfdNr from formular where related_id IS NOT NULL AND related_type = 'payment');
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    OPEN fee_vals;
    cursor_loop: LOOP -- -------------------------------------
        FETCH fee_vals INTO fee_ids, correspondence_ids, turnover_rates, remited_perc, fee_values, fee_otcurr_values;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;    
        
        /*Do something with the row fetched*/
        INSERT INTO `01migrate_11_12` SET elem='fee_work_package', info=fee_ids;

        /* SET by SELECT */
        SELECT related_id 
            INTO @paymentsID
            FROM formular WHERE related_type = 'payment' AND LfdNr = correspondence_ids;

        SELECT SUM(value), SUM(value_otcurr) 
            INTO @sumVal, @sumValOtcurr
            FROM payments_fees WHERE payments_id = @paymentsID;

        -- get the fee values from the payments table
        UPDATE lut_fee_wp lfw
                INNER JOIN 
        (SELECT fee_values * (pf.value/@sumVal) AS value, pf.value/@sumVal AS factor, IFNULL(fee_otcurr_values, fee_values) * (pf.value_otcurr/@sumValOtcurr) AS value_otcurr, lfao.work_package_id AS wp_id FROM payments_fees pf 
                INNER JOIN 
        lut_fee_areas_offer lfao ON pf.fee_areas_offer_id = lfao.id WHERE payments_id = @paymentsID) AS myTable
                ON myTable.wp_id = lfw.wp_id AND lfw.fee_id = fee_ids
        SET lfw.value = myTable.value, lfw.done_pre_tax = (((myTable.value*turnover_rates)+myTable.value)*remited_perc)/100, lfw.value_otcurr = myTable.value_otcurr, lfw.value_pre_tax=(myTable.value*turnover_rates)+myTable.value;
        
        -- UPDATE the parent values
        UPDATE lut_fee_wp
            INNER JOIN
        (SELECT 
            lfw.wp_id,
            SUM(lfw2.value) AS sum_val,
            SUM(lfw2.done_pre_tax) AS sum_done,
            SUM(lfw2.value_otcurr) AS sum_val_otcurr
        FROM
            lut_fee_wp lfw
                INNER JOIN
            lut_fee_wp lfw2 ON lfw2.wp_id IN (SELECT id FROM work_packages 
                WHERE
            lft > (SELECT lft FROM work_packages WHERE project_id = lfw.project_id AND id = lfw.wp_id)
                AND 
            rgt < (SELECT rgt FROM work_packages WHERE project_id = lfw.project_id AND id = lfw.wp_id) 
                AND 
            project_id = lfw.project_id AND lft > 1 AND is_fee_area = 1)
                AND
            lfw2.fee_id = fee_ids AND lfw.fee_id = fee_ids
                GROUP BY lfw.wp_id, lfw.fee_id) AS myTable
            SET value = myTable.sum_val, done_pre_tax=myTable.sum_done, value_otcurr = myTable.sum_val_otcurr, value_pre_tax=(myTable.sum_val*turnover_rates)+myTable.sum_val
                WHERE 
            lut_fee_wp.fee_id = fee_ids AND lut_fee_wp.wp_id = myTable.wp_id;
        
        END LOOP cursor_loop; -- -------------------------------------
    CLOSE  fee_vals;
END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migrate work package translation
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS us_migrate_translation;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_translation()
us_migrate_translationlbl:BEGIN

    -- Prevent execution, if times table has a work_package_id
    IF ( (SELECT COUNT(*) FROM langs_work_packages_main)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - us_migrate_translation';
        LEAVE us_migrate_translationlbl;
    END IF;

    -- Langs for main table
    INSERT INTO langs_work_packages_main
        (work_package_id, `name`, `language`)
        SELECT wp.id, la.name, la.language FROM langs_work_areas AS la INNER JOIN work_packages AS wp on la.work_area_id=wp.old_work_area_id;

    INSERT INTO langs_work_packages_main
        (work_package_id, `name`, `language`)
        SELECT wp.id, la.name, la.language FROM langs_fee_areas AS la INNER JOIN work_packages AS wp on la.fee_area_id=wp.old_fee_area_id;

    -- Langs for tags table
    INSERT INTO langs_work_packages_tags
        (work_packages_tags_id, `name`, `wp_name`, `language`)
        SELECT wp.id, la.name, la.name, la.language FROM langs_work_areas AS la INNER JOIN work_packages_tags AS wp on la.work_area_id=wp.id;

    -- Langs for presets table
    INSERT INTO langs_work_packages_presets
        (work_package_preset_id, `name`, `language`)
        SELECT wp.id, la.name, la.language FROM langs_work_areas AS la INNER JOIN work_package_presets AS wp on la.work_area_id=wp.old_work_area_id;

    INSERT INTO langs_work_packages_presets
        (work_package_preset_id, `name`, `language`)
        SELECT wp.id, la.name, la.language FROM langs_fee_areas AS la INNER JOIN work_package_presets AS wp on la.fee_area_id=wp.old_fee_area_id;

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migrate work area values to work packages of the data tables
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS us_migrate_11_12_areas_to_packages;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_areas_to_packages()
us_migrate_11_12_areas_to_packageslbl:BEGIN

    -- Prevent execution, if times table has a work_package_id
    IF ( (SELECT COUNT(*) FROM information_schema.COLUMNS WHERE table_schema = DATABASE() AND table_name='times' AND column_name='work_package_id')>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - us_migrate_11_12_areas_to_packages';
        LEAVE us_migrate_11_12_areas_to_packageslbl;
    END IF;

    CALL us_migrate_11_12_migrate_wa2wp('attendance_clock', 'area_id');
    CALL us_migrate_11_12_migrate_wa2wp('drawings', 'work_area_id');
    CALL us_migrate_11_12_migrate_wa2wp('drawings_inbox', 'work_area_id');
    CALL us_migrate_11_12_migrate_wa2wp('externalexpenses', 'area_id');
    CALL us_migrate_11_12_migrate_wa2wp('externalexpenses_planned', 'area_id');
    CALL us_migrate_11_12_migrate_wa2wp('extras', 'area_id');
    CALL us_migrate_11_12_migrate_wa2wp('extras_logging', 'area_id');
    CALL us_migrate_11_12_migrate_wa2wp('fees', 'area_id');
    CALL us_migrate_11_12_migrate_wa2wp('fees_planned', 'area_id');
    CALL us_migrate_11_12_migrate_wa2wp('inbox', 'area_id');
    CALL us_migrate_11_12_migrate_wa2wp('outbox', 'area_id');
    CALL us_migrate_11_12_migrate_wa2wp('times', 'area_id');
    CALL us_migrate_11_12_migrate_wa2wp('times_logging', 'area_id');
    CALL us_migrate_11_12_migrate_wa2wp('transmittal_form', 'work_area_id');
    CALL us_migrate_11_12_migrate_wa2wp('travels', 'area_id');
    CALL us_migrate_11_12_migrate_wa2wp('travels_logging', 'area_id');

    CALL us_add_to_table2('formular', 'work_package_id', 'INT (11) DEFAULT NULL' );
    UPDATE `formular` AS main SET work_package_id=(SELECT id FROM work_packages AS wp WHERE main.Projekt=wp.project_id AND main.Arbeitsbereich=wp.old_work_area_id);
    ALTER TABLE `formular` CHANGE COLUMN `Arbeitsbereich` `Arbeitsbereich__old` INT NULL DEFAULT NULL ;

    UPDATE lut_fee_areas_offer AS main SET  work_package_id = (
        SELECT wp.id
        FROM project_offers AS po INNER JOIN work_packages AS wp ON po.project_id = wp.project_id
        WHERE main.offer_id = po.id AND main.fee_area_id = wp.old_fee_area_id
    );

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migrate views to tables
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS us_migrate_11_12_migrate_views_to_tables;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_migrate_views_to_tables()
us_migrate_11_12_migrate_views_to_tableslbl:BEGIN

    -- Prevent execution, if attendance_clock is not a VIEW
    IF ( (SELECT COUNT(*) FROM information_schema.TABLES WHERE table_schema = DATABASE() AND table_name='attendance_clock' AND table_type='VIEW')<=0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - us_migrate_11_12_migrate_views_to_tables';
        LEAVE us_migrate_11_12_migrate_views_to_tableslbl;
    END IF;

    CALL us_migrate_11_12_migrate_view('attendance_clock');
        ALTER TABLE `attendance_clock` ADD INDEX(`project_id`); 
        ALTER TABLE `attendance_clock` ADD INDEX(`staff_id`);
    CALL us_migrate_11_12_migrate_view('drawings');
        ALTER TABLE `drawings` ADD INDEX(`project_id`); 
        ALTER TABLE `drawings` ADD INDEX(`type_id`); 
        ALTER TABLE `drawings` ADD INDEX(`signed_by`);
        ALTER TABLE `drawings` ADD INDEX(`replaced_by`);
        ALTER TABLE `drawings` ADD INDEX(`re_destinations`);
        ALTER TABLE `drawings` ADD INDEX(`size_id`); 
        ALTER TABLE `drawings` ADD INDEX(`created_by_id`);
        ALTER TABLE `drawings` ADD INDEX(`changed_by_id`);
    CALL us_migrate_11_12_migrate_view('drawings_inbox');
        ALTER TABLE `drawings_inbox` ADD INDEX(`project_id`);
        ALTER TABLE `drawings_inbox` ADD INDEX(`address_id`);
        ALTER TABLE `drawings_inbox` ADD INDEX(`date`);
        ALTER TABLE `drawings_inbox` ADD INDEX(`created_by_id`);
        ALTER TABLE `drawings_inbox` ADD INDEX(`changed_by_id`);
    CALL us_migrate_11_12_migrate_view('externalexpenses');
        ALTER TABLE `externalexpenses` ADD INDEX(`is_hon_decr`);
        ALTER TABLE `externalexpenses` ADD INDEX(`is_calc_from_expenses`);
        ALTER TABLE `externalexpenses` ADD INDEX(`date`);
        ALTER TABLE `externalexpenses` ADD INDEX(`project_id`);
        ALTER TABLE `externalexpenses` ADD INDEX(`address_id`);
        ALTER TABLE `externalexpenses` ADD INDEX(`creator_id`);
        ALTER TABLE `externalexpenses` ADD INDEX(`cost_centre_id`);
        ALTER TABLE `externalexpenses` ADD INDEX(`created_by_id`);
        ALTER TABLE `externalexpenses` ADD INDEX(`changed_by_id`);
    CALL us_migrate_11_12_migrate_view('externalexpenses_planned');
        ALTER TABLE `externalexpenses_planned` ADD INDEX(`is_hon_decr`);
        ALTER TABLE `externalexpenses_planned` ADD INDEX(`is_calc_from_expenses`);
        ALTER TABLE `externalexpenses_planned` ADD INDEX(`date`);
        ALTER TABLE `externalexpenses_planned` ADD INDEX(`project_id`);
        ALTER TABLE `externalexpenses_planned` ADD INDEX(`address_id`);
        ALTER TABLE `externalexpenses_planned` ADD INDEX(`creator_id`);
        ALTER TABLE `externalexpenses_planned` ADD INDEX(`cost_centre_id`);
        ALTER TABLE `externalexpenses_planned` ADD INDEX(`created_by_id`);
        ALTER TABLE `externalexpenses_planned` ADD INDEX(`changed_by_id`);
    CALL us_migrate_11_12_migrate_view('extras');
        ALTER TABLE `extras` ADD INDEX(`project_id`);
        ALTER TABLE `extras` ADD INDEX(`date`);
        ALTER TABLE `extras` ADD INDEX(`staff_id`);
        ALTER TABLE `extras` ADD INDEX(`type_id`);
        ALTER TABLE `extras` ADD INDEX(`cost_centre_id`);
        ALTER TABLE `extras` ADD INDEX(`changed_by_id`);
        ALTER TABLE `extras` ADD INDEX(`company_id`);
    CALL us_migrate_11_12_migrate_view('extras_logging');
        ALTER TABLE `extras_logging` ADD INDEX(`project_id`);
        ALTER TABLE `extras_logging` ADD INDEX(`date`);
        ALTER TABLE `extras_logging` ADD INDEX(`staff_id`);
        ALTER TABLE `extras_logging` ADD INDEX(`type_id`);
        ALTER TABLE `extras_logging` ADD INDEX(`cost_centre_id`);
        ALTER TABLE `extras_logging` ADD INDEX(`changed_by_id`);
        ALTER TABLE `extras_logging` ADD INDEX(`log_change_date`);
        ALTER TABLE `extras_logging` ADD INDEX(`log_changed_by_id`);
        ALTER TABLE `extras_logging` ADD INDEX(`company_id`);
    CALL us_migrate_11_12_migrate_view('fees');
        ALTER TABLE `fees` ADD INDEX(`fee_date`);
        ALTER TABLE `fees` ADD INDEX(`is_done`);
        ALTER TABLE `fees` ADD INDEX(`project_id`);
        ALTER TABLE `fees` ADD INDEX(`address_id`);
        ALTER TABLE `fees` ADD INDEX(`user_id`);
        ALTER TABLE `fees` ADD INDEX(`fee_account_id`);
        ALTER TABLE `fees` ADD INDEX(`predecessor_id`);
        ALTER TABLE `fees` ADD INDEX(`successor_id`);
        ALTER TABLE `fees` ADD INDEX(`cost_centre_id`);
        ALTER TABLE `fees` ADD INDEX(`created_by_id`);
        ALTER TABLE `fees` ADD INDEX(`changed_by_id`);
    CALL us_migrate_11_12_migrate_view('fees_planned');
        ALTER TABLE `fees_planned` ADD INDEX(`fee_date`);
        ALTER TABLE `fees_planned` ADD INDEX(`project_id`);
        ALTER TABLE `fees_planned` ADD INDEX(`address_id`);
        ALTER TABLE `fees_planned` ADD INDEX(`user_id`);
        ALTER TABLE `fees_planned` ADD INDEX(`fee_account_id`);
        ALTER TABLE `fees_planned` ADD INDEX(`predecessor_id`);
        ALTER TABLE `fees_planned` ADD INDEX(`successor_id`);
        ALTER TABLE `fees_planned` ADD INDEX(`cost_centre_id`);
        ALTER TABLE `fees_planned` ADD INDEX(`created_by_id`);
        ALTER TABLE `fees_planned` ADD INDEX(`changed_by_id`);
    CALL us_migrate_11_12_migrate_view('inbox');
        ALTER TABLE `inbox` ADD INDEX(`project_id`);
        ALTER TABLE `inbox` ADD INDEX(`date`);
        ALTER TABLE `inbox` ADD INDEX(`address_id`);
        ALTER TABLE `inbox` ADD INDEX(`dispatch_mode_id`);
        ALTER TABLE `inbox` ADD INDEX(`created_date`);
        ALTER TABLE `inbox` ADD INDEX(`created_by_id`);
        ALTER TABLE `inbox` ADD INDEX(`change_date`);
        ALTER TABLE `inbox` ADD INDEX(`changed_by_id`);
        ALTER TABLE `inbox` ADD INDEX(`recipient_id`);
    CALL us_migrate_11_12_migrate_view('lut_fee_areas_offer');
        ALTER TABLE lut_fee_areas_offer ADD COLUMN `work_package_id` INT NULL, ADD INDEX (`work_package_id`);
        ALTER TABLE `lut_fee_areas_offer` ADD INDEX(`offer_id`);
    CALL us_migrate_11_12_migrate_view('outbox');
        ALTER TABLE `outbox` ADD INDEX(`project_id`);
        ALTER TABLE `outbox` ADD INDEX(`date`);
        ALTER TABLE `outbox` ADD INDEX(`address_id`);
        ALTER TABLE `outbox` ADD INDEX(`staff_id`);
        ALTER TABLE `outbox` ADD INDEX(`dispatch_mode_id`);
        ALTER TABLE `outbox` ADD INDEX(`created_date`);
        ALTER TABLE `outbox` ADD INDEX(`created_by_id`);
        ALTER TABLE `outbox` ADD INDEX(`change_date`);
        ALTER TABLE `outbox` ADD INDEX(`changed_by_id`);
        ALTER TABLE `outbox` ADD INDEX(`doc_id`);
        ALTER TABLE `outbox` ADD INDEX(`mail_id`);
        ALTER TABLE `outbox` ADD INDEX(`parent_id`);
        ALTER TABLE `outbox` ADD INDEX(`acc_after_exp_bill_id`);
        ALTER TABLE `outbox` ADD INDEX(`transmittal_form_id`);
    CALL us_migrate_11_12_migrate_view('times');
        ALTER TABLE `times` ADD INDEX(`project_id`);
        ALTER TABLE `times` ADD INDEX(`date`);
        ALTER TABLE `times` ADD INDEX(`staff_id`);
        ALTER TABLE `times` ADD INDEX(`cost_centre_id`);
        ALTER TABLE `times` ADD INDEX(`changed_by_id`);
        ALTER TABLE `times` ADD INDEX(`company_id`);
        ALTER TABLE `times` ADD INDEX(`vacation_id`);
        ALTER TABLE `times` ADD INDEX(`persapp_id`);
        ALTER TABLE `times` ADD INDEX(`opta_id`);
        ALTER TABLE `times` ADD INDEX(`skill_id`);
    CALL us_migrate_11_12_migrate_view('times_logging');
        ALTER TABLE `times_logging` ADD INDEX(`project_id`);
        ALTER TABLE `times_logging` ADD INDEX(`date`);
        ALTER TABLE `times_logging` ADD INDEX(`staff_id`);
        ALTER TABLE `times_logging` ADD INDEX(`cost_centre_id`);
        ALTER TABLE `times_logging` ADD INDEX(`changed_by_id`);
        ALTER TABLE `times_logging` ADD INDEX(`log_change_date`);
        ALTER TABLE `times_logging` ADD INDEX(`log_changed_by_id`);
        ALTER TABLE `times_logging` ADD INDEX(`company_id`);
        ALTER TABLE `times_logging` ADD INDEX(`skill_id`);
    CALL us_migrate_11_12_migrate_view('transmittal_form');
        ALTER TABLE `transmittal_form` ADD INDEX(`project_id`);
        ALTER TABLE `transmittal_form` ADD INDEX(`address_id`);
        ALTER TABLE `transmittal_form` ADD INDEX(`staff_id`);
        ALTER TABLE `transmittal_form` ADD INDEX(`date`);
        ALTER TABLE `transmittal_form` ADD INDEX(`created_by_id`);
        ALTER TABLE `transmittal_form` ADD INDEX(`changed_by_id`);
    CALL us_migrate_11_12_migrate_view('travels');
        ALTER TABLE `travels` ADD INDEX(`project_id`);
        ALTER TABLE `travels` ADD INDEX(`date`);
        ALTER TABLE `travels` ADD INDEX(`staff_id`);
        ALTER TABLE `travels` ADD INDEX(`type_id`);
        ALTER TABLE `travels` ADD INDEX(`cost_centre_id`);
        ALTER TABLE `travels` ADD INDEX(`changed_by_id`);
        ALTER TABLE `travels` ADD INDEX(`company_id`);
    CALL us_migrate_11_12_migrate_view('travels_logging');
        ALTER TABLE `travels_logging` ADD INDEX(`project_id`);
        ALTER TABLE `travels_logging` ADD INDEX(`date`);
        ALTER TABLE `travels_logging` ADD INDEX(`staff_id`);
        ALTER TABLE `travels_logging` ADD INDEX(`type_id`);
        ALTER TABLE `travels_logging` ADD INDEX(`cost_centre_id`);
        ALTER TABLE `travels_logging` ADD INDEX(`changed_by_id`);
        ALTER TABLE `travels_logging` ADD INDEX(`log_change_date`);
        ALTER TABLE `travels_logging` ADD INDEX(`log_changed_by_id`);
        ALTER TABLE `travels_logging` ADD INDEX(`company_id`);
    CALL us_migrate_11_12_migrate_view('work_areas_rates');
        ALTER TABLE `work_areas_rates` ADD INDEX(`rate_id`);
        ALTER TABLE `work_areas_rates` ADD INDEX(`history_id`);
    CALL us_migrate_11_12_migrate_view('work_areas_rates_history');
        ALTER TABLE `work_areas_rates_history` ADD INDEX(`rate_id`);
END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Repair tables which are migrated from views
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_11_12_repair_table_structure;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_repair_table_structure()
BEGIN
    -- @todo Remove the UDPATE commands below, if the exchange rate is ever used.

    -- Times
    ALTER TABLE `times` CHANGE COLUMN `company_gross_hourly_wage_ex` `company_gross_hourly_wage_ex` DOUBLE NOT NULL DEFAULT 1;
    UPDATE `times` SET `company_gross_hourly_wage_ex` = 1 WHERE `company_gross_hourly_wage_ex` = 0;
    ALTER TABLE `times` CHANGE COLUMN `company_value_ex` `company_value_ex` DOUBLE NOT NULL DEFAULT 1;
    UPDATE `times` SET `company_value_ex` = 1 WHERE `company_value_ex` = 0;
    ALTER TABLE `times` CHANGE COLUMN `company_price_per_unit_ex` `company_price_per_unit_ex` DOUBLE NOT NULL DEFAULT 1;
    UPDATE `times` SET `company_price_per_unit_ex` = 1 WHERE `company_price_per_unit_ex` = 0;
    ALTER TABLE `times` CHANGE COLUMN `company_price_external_staff_ex` `company_price_external_staff_ex` DOUBLE NOT NULL DEFAULT 1;
    UPDATE `times` SET `company_price_external_staff_ex` = 1 WHERE `company_price_external_staff_ex` = 0;
    ALTER TABLE `times` CHANGE COLUMN `company_price_area_ex` `company_price_area_ex` DOUBLE NOT NULL DEFAULT 1;
    UPDATE `times` SET `company_price_area_ex` = 1 WHERE `company_price_area_ex` = 0;
    -- Extras
    ALTER TABLE `extras` CHANGE COLUMN `company_cost_per_unit_ex` `company_cost_per_unit_ex` DOUBLE NOT NULL DEFAULT 1;
    UPDATE `extras` SET `company_cost_per_unit_ex` = 1 WHERE `company_cost_per_unit_ex` = 0;
    ALTER TABLE `extras` CHANGE COLUMN `company_price_per_unit_ex` `company_price_per_unit_ex` DOUBLE NOT NULL DEFAULT 1;
    UPDATE `extras` SET `company_price_per_unit_ex` = 1 WHERE `company_price_per_unit_ex` = 0;
    -- Travels
    ALTER TABLE `travels` CHANGE COLUMN `company_cost_per_unit_ex` `company_cost_per_unit_ex` DOUBLE NOT NULL DEFAULT 1;
    UPDATE `travels` SET `company_cost_per_unit_ex` = 1 WHERE `company_cost_per_unit_ex` = 0;
    ALTER TABLE `travels` CHANGE COLUMN `company_price_per_unit_ex` `company_price_per_unit_ex` DOUBLE NOT NULL DEFAULT 1;
    UPDATE `travels` SET `company_price_per_unit_ex` = 1 WHERE `company_price_per_unit_ex` = 0;
END $$
DELIMITER ;
-- EOC


DROP PROCEDURE IF EXISTS us_migrate_11_12_migrate_view;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_migrate_view(
    IN tablename VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    DECLARE viewdef LONGTEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    
    SELECT VIEW_DEFINITION INTO viewdef
    FROM INFORMATION_SCHEMA.VIEWS
    WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = tablename;

    -- Get position of FROM
    SET @from_pos = LOCATE(' from ', viewdef);
    IF @from_pos<10 THEN
        SET @error = CONCAT('View definition for ', tablename, ' misses FROM part.');
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = @error;
    END IF;

    -- Prepare variables
    SET @viewtable = REPLACE( SUBSTRING(viewdef, @from_pos+6), '`', '');
    SET @tablename_temp = CONCAT(tablename, '__view');
    SET @viewtable_oldname = CONCAT(@viewtable, '__old');

    INSERT INTO `01migrate_11_12` SET elem='use_new_names_for_table', info=CONCAT('We now use ', tablename, ' and save the old table ', @viewtable, ' as ', @viewtable_oldname);

    -- Save original view to ..._view
    SET @s = CONCAT('RENAME TABLE ', tablename, ' TO ', @tablename_temp);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;

    -- Copy values from ..._view to tablename
    SET @s = CONCAT('CREATE TABLE ', tablename, ' AS SELECT * FROM ', @tablename_temp, ' ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci');
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;
    -- necessary to skip the logging tables here, because these throwing an error because of having multiple ids with 0
    IF (SUBSTRING(tablename, -7) NOT LIKE 'logging') THEN
            -- Add PRIMARY KEY
            SET @s = CONCAT('ALTER TABLE ', tablename, ' ADD PRIMARY KEY (`id`);');
            PREPARE stmt1 FROM @s;
            EXECUTE stmt1;
            DEALLOCATE PREPARE stmt1;

            -- Add AUTO_INCREMENT
            SET @s = CONCAT('ALTER TABLE ', tablename, ' CHANGE `id` `id` INT NOT NULL AUTO_INCREMENT;');
            PREPARE stmt1 FROM @s;
            EXECUTE stmt1;
            DEALLOCATE PREPARE stmt1;
    END IF;   

    -- Remove original view to ..._view
    SET @s = CONCAT('DROP VIEW ', @tablename_temp);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;

    -- Move now old table to new name
    SET @s = CONCAT('RENAME TABLE ', @viewtable, ' TO ', @viewtable_oldname);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;

    CALL us_to_mb4(DATABASE(), tablename);

    CALL us_col_to_mb4(DATABASE(), tablename);

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migrate work areas to work packages
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS us_migrate_11_12_migrate_wa2wp;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_migrate_wa2wp(
    IN tablename VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN area_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN

    INSERT INTO `01migrate_11_12` SET elem='wa2wp', info=CONCAT('For table ', tablename, ' we now use work_package_id insteas of ', area_id);

    -- Add work_package_id with INDEX
    SET @s = CONCAT('ALTER TABLE ', tablename, ' ADD COLUMN `work_package_id` INT NULL, ADD INDEX (`work_package_id`);');
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;

    -- Add work_package_id with INDEX (LIMIT 1 for dirty databases)
    SET @s = CONCAT('UPDATE ', tablename, ' AS main SET work_package_id=(SELECT id FROM work_packages AS wp WHERE main.project_id=wp.project_id AND main.', area_id,'=wp.old_work_area_id  LIMIT 1)');
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;


END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migrate work areas to work package tags
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS us_migrate_11_12_migrate_wa2wpt;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_migrate_wa2wpt()
us_migrate_11_12_migrate_wa2wptlbl:BEGIN

    -- Prevent execution, if work_packages_tags has content
    IF ( (SELECT COUNT(*) FROM work_packages_tags)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - us_migrate_11_12_migrate_wa2wpt';
        LEAVE us_migrate_11_12_migrate_wa2wptlbl;
    END IF;

    INSERT INTO work_packages_tags (id, `name`, wp_name) SELECT LfdNr, ArbName, ArbName FROM arbeitsbereiche;

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Create presets for all work_areas_categories
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_11_12_work_areas_categories;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_work_areas_categories()
us_migrate_11_12_work_areas_categorieslbl:BEGIN

    DECLARE woac_id INTEGER;
    DECLARE woac_name VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE woac_special_id INTEGER;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE woac CURSOR FOR SELECT id, name, special_id FROM work_areas_categories WHERE one_project_only=0 AND is_active=1 ORDER BY id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    -- Prevent execution, if work_package_presets has content
    IF ( (SELECT COUNT(*) FROM work_package_presets)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - us_migrate_11_12_work_areas_categories';
        LEAVE us_migrate_11_12_work_areas_categorieslbl;
    END IF;

    /* Just for dev. In live it should be empty */
    TRUNCATE work_package_presets;

    OPEN woac;
    cursor_loop: LOOP -- -------------------------------------
        FETCH woac INTO woac_id, woac_name, woac_special_id;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
            /*Do something with the row fetched*/
            INSERT INTO `01migrate_11_12` SET elem='woac_id', info=woac_id;
            
            /* Create work_package_presets main entry */
            INSERT INTO work_package_presets (tree_id, name, lft, rgt, is_purpose_required, is_fee_area, is_special) VALUES(woac_id, woac_name, 1, 2, 0, 0, 0);
            SET @insert_id_main = LAST_INSERT_ID();
            
            /* Create work_package_presets from fee and work areas */
            CALL us_migrate_11_12_copy_fee_areas(woac_id, woac_special_id, @insert_id_main);
            
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  woac;
END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- SUB - Copy all fee and work areas for a certain work_areas_category
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_11_12_copy_fee_areas;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_copy_fee_areas(IN woac_id INTEGER, IN woac_special_id INTEGER, IN main_tree_id INTEGER)
BEGIN
    DECLARE wo_id INTEGER;
    DECLARE wo_name VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE wo_is_special INTEGER;
    DECLARE wo_is_purpose_required INTEGER;
    DECLARE fe_id INTEGER;
    DECLARE fe_name VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE fe_is_special INTEGER;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE fee_areas CURSOR FOR SELECT 
            wo.id,
            wo.name,
            wo.is_special,
            wo.is_purpose_required,
            fe.id,
            fe.name,
            fe.is_special
        FROM
            work_areas AS wo
                INNER JOIN
            fee_areas AS fe ON wo.fee_area_id = fe.id
                INNER JOIN
            lut_work_areas_work_areas_categories AS wc ON wc.work_area_id=wo.id
        WHERE 
                wc.work_area_categories_id=woac_id
        ORDER BY
                fe.sort ASC, wo.sort ASC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    SET @last_fe_id = 0;

    OPEN fee_areas;
    cursor_loop: LOOP -- -------------------------------------
        FETCH fee_areas INTO wo_id, wo_name, wo_is_special, wo_is_purpose_required, fe_id, fe_name, fe_is_special;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
            /*Do something with the row fetched*/
            INSERT INTO `01migrate_11_12` SET elem='fee_woc', info=CONCAT_WS(', ', main_tree_id, wo_id, wo_name, wo_is_special, wo_is_purpose_required, fe_id, fe_name, fe_is_special);
            
            IF @last_fe_id<>fe_id THEN
                SET @have_work_area_for_fee_area = false;
                /* Create fee area as preset */
                CALL us_insert_work_package_presets(
                    main_tree_id, -- parent_id
                    fe_name, -- new_name
                    wo_is_purpose_required, -- is_purpose (Should only be set on LOWEST)
                    IF(fe_is_special, woac_special_id, 0), -- is_special
                    NULL, -- is_special_phase
                    true, -- is_fee_area
                    0, -- threshold
                    0, -- is_extern
                    null, -- cost centre
                    null, -- tag id
                    null, -- description
                    @insert_id_fe
                );
                INSERT INTO `01migrate_11_12` SET elem='us_insert_work_package_presets fee', info=COALESCE(@insert_id_fe, 'NULL');

                /* Set the fee values */
                UPDATE work_package_presets SET old_fee_area_id=fe_id WHERE ID=@insert_id_fe;
                
                /* Create preset if the work and fee area do not have the same name */
                IF us_delete_spaces(TRIM(wo_name))<>us_delete_spaces(TRIM(fe_name)) THEN
                    SET @have_work_area_for_fee_area = true;
                    CALL us_insert_work_package_presets(
                        @insert_id_fe, -- parent_id
                        wo_name, -- new_name
                        wo_is_purpose_required, -- is_purpose (Should only be set on LOWEST)
                        IF(wo_is_special, woac_special_id, 0), -- is_special
                        NULL, -- is_special_phase
                        false, -- is_fee_area
                        0, -- threshold
                        0, -- is_extern
                        null, -- cost centre
                        null, -- tag id
                        null, -- description
                        @insert_id_wo
                    );
                
                    /* Set the work area values */
                    UPDATE work_package_presets SET old_work_area_id=wo_id, tag_id=wo_id WHERE ID=@insert_id_wo;
                ELSE
                    /* Set the work area values */
                    UPDATE work_package_presets SET old_work_area_id=wo_id, tag_id=wo_id WHERE ID=@insert_id_fe;
                END IF;
            ELSE
                /* Create preset of first work area, if not  @have_work_area_for_fee_area */
                IF @have_work_area_for_fee_area<>true THEN
                    SET @have_work_area_for_fee_area = true;
                    CALL us_insert_work_package_presets(
                        @insert_id_fe, -- parent_id
                        fe_name, -- new_name (New name of wo was same)
                        @last_wo_is_purpose_required, -- is_purpose (Should only be set on LOWEST)
                        IF(@last_wo_is_special, woac_special_id, 0), -- is_special
                        NULL, -- is_special_phase
                        false, -- is_fee_area
                        0, -- threshold
                        0, -- is_extern
                        null, -- cost centre
                        null, -- tag id
                        null, -- description
                        @insert_id_wo
                    );
                    
                    /* Set the work area values */
                    UPDATE work_package_presets SET old_work_area_id=wo_id, tag_id=wo_id WHERE ID=@insert_id_wo;
                END IF;

                /* Create preset of next work area */
                CALL us_insert_work_package_presets(
                    @insert_id_fe, -- parent_id
                    wo_name, -- new_name
                    wo_is_purpose_required, -- is_purpose (Should only be set on LOWEST)
                    IF(wo_is_special, woac_special_id, 0), -- is_special
                    NULL, -- is_special_phase
                    false, -- is_fee_area
                    0, -- threshold
                    0, -- is_extern
                    null, -- cost centre
                    null, -- tag id
                    null, -- description
                    @insert_id_wo
                );
                
                /* Set the work area values */
                UPDATE work_package_presets SET old_work_area_id=wo_id, tag_id=wo_id WHERE ID=@insert_id_wo;
            END IF;

            SET @last_wo_is_purpose_required = wo_is_purpose_required;
            SET @last_wo_is_special = wo_is_special;
            SET @last_fe_id = fe_id;
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  fee_areas;
END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Create work_packages for project and change all work areas to work packages
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS us_migrate_11_12_projects;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_projects()
us_migrate_11_12_projectslbl:BEGIN
    
    DECLARE projects_id INTEGER;
    DECLARE projects_project_name VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE woac_id INTEGER;
    DECLARE woac_name VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE woac_special_id INTEGER;
    DECLARE woac_one_project_only INTEGER;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE projects CURSOR FOR SELECT 
            p.id, p.project_name, 
            woac.id, woac.name, IFNULL(woac.special_id, woac.was_special_id), one_project_only
        FROM
            projects AS p
                INNER JOIN
            work_areas_categories AS woac ON p.work_area_category_id=woac.id
        ORDER BY p.id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    -- Prevent execution, if work_packages has content
    IF ( (SELECT COUNT(*) FROM work_packages)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - us_migrate_11_12_projects';
        LEAVE us_migrate_11_12_projectslbl;
    END IF;

    IF @debug THEN -- ==========================================================
        select now() AS 'THE_START_TIME_____', 'us_migrate_11_12_projects <--' AS 'COMMENT';
    END IF;

    OPEN projects;
    cursor_loop: LOOP -- -------------------------------------
        FETCH projects INTO projects_id, projects_project_name, woac_id, woac_name, woac_special_id, woac_one_project_only;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
            /*Do something with the row fetched*/
            INSERT INTO `01migrate_11_12` SET elem='projects_id', info=projects_id;

            /* Create work_package main entry */
            INSERT INTO work_packages (project_id, name, lft, rgt, is_purpose_required, is_fee_area, is_special, wpp_tree_id) 
                VALUES(projects_id, CONCAT(projects_project_name, ' - ', woac_name), 1, 2, 0, 0, 0, IF(woac_one_project_only, null, woac_id));
            SET @insert_id_main = LAST_INSERT_ID();
            
            UPDATE projects SET work_package_preset_id = (SELECT wpp_tree_id FROM work_packages WHERE project_id = projects_id AND wpp_tree_id IS NOT NULL GROUP BY project_id) WHERE id = projects_id;

            CALL us_migrate_11_12_copy_projects_fee_areas(projects_id, woac_id, woac_special_id, @insert_id_main);
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  projects;

    IF @debug THEN -- ==========================================================
        select now() AS 'THE_START_TIME_____', 'Change INDEX to UNIQUE' AS 'COMMENT';
    END IF;

    -- Rem INDEX key for work_packages
    CALL us_drop_index_if_exists('work_packages', 'wp_lft_index');
    CALL us_drop_index_if_exists('work_packages', 'wp_rgt_index');

    -- Add UNIQUE key for work_packages
    CALL us_add_constraint_to_table('work_packages', 'wp_lft_unique', 'UNIQUE', '`project_id` , `lft`' );
    CALL us_add_constraint_to_table('work_packages', 'wp_rgt_unique', 'UNIQUE', '`project_id` , `rgt`' );


    IF @debug THEN -- ==========================================================
        select now() AS 'THE_START_TIME_____', 'Done <--' AS 'COMMENT';
    END IF;

END $$
DELIMITER ;
-- EOC


-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- SUB - Copy all fee and work areas for a certain work_areas_category
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_11_12_copy_projects_fee_areas;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_copy_projects_fee_areas(IN projects_id INTEGER, IN woac_id INTEGER, IN woac_special_id INTEGER, IN main_tree_id INTEGER)
BEGIN
    DECLARE wo_id INTEGER;
    DECLARE wo_name VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE wo_is_special INTEGER;
    DECLARE wo_is_purpose_required INTEGER;
    DECLARE fe_id INTEGER;
    DECLARE fe_name VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE fe_is_special INTEGER;
    DECLARE fep_status INTEGER;
    DECLARE fep_costs DOUBLE;
    DECLARE fep_hours DOUBLE;
    DECLARE bp_proportion DOUBLE;
    DECLARE bp_costs DOUBLE;
    DECLARE bp_hours DOUBLE;
    DECLARE bp_start_date DATETIME;
    DECLARE bp_end_date DATETIME;
    DECLARE bp_threshold DOUBLE;
    DECLARE cl_completion_level DOUBLE;
    DECLARE cl_date DATE;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE fee_areas CURSOR FOR SELECT 
        wo.id,
        wo.name,
        wo.is_special,
        wo.is_purpose_required,
        fe.id,
        fe.name,
        fe.is_special,
        fep.status,
        fep.costs,
        fep.hours,
        bp.proportion,
        bp.planned_costs,
        bp.planned_hours,
        bp.start_date,
        bp.end_date,
        bp.threshold,
        cl.completion_level,
        cl.date
    FROM
        work_areas AS wo
            INNER JOIN
        fee_areas AS fe ON wo.fee_area_id = fe.id
            INNER JOIN
        lut_work_areas_work_areas_categories AS wc ON wc.work_area_id = wo.id
            LEFT JOIN
        -- Fee areas for project
        lut_fee_areas_proj as fep ON fe.id = fep.fee_area_id AND fep.project_id = projects_id
            LEFT JOIN
        lut_fee_areas_proj_history AS lfaph ON lfaph.id = fep.lut_fee_areas_proj_history_id
            LEFT JOIN
        -- Budget plan for project
        budget_plan AS bp ON wo.id = bp.area_id AND bp.project_id = projects_id
            LEFT JOIN
        budget_plan_history AS bph ON bp.budget_plan_history_id = bph.id
            LEFT JOIN
        -- Completion level for project
        completion_level AS cl ON wo.id = cl.work_area_id AND cl.project_id = projects_id
            LEFT JOIN
        completion_level_history AS clh ON cl.completion_level_history_id = clh.id
        WHERE
        wc.work_area_categories_id = woac_id
            AND
        lfaph.valid_to_date IS NULL
            AND
        bph.valid_to_date IS NULL
            AND
        clh.valid_to_date IS NULL
        GROUP BY wo.id
        ORDER BY fe.sort ASC , wo.sort ASC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    SET @last_fe_id = 0;

    OPEN fee_areas;
    cursor_loop: LOOP -- -------------------------------------
        FETCH fee_areas INTO wo_id, wo_name, wo_is_special, wo_is_purpose_required, fe_id, fe_name, fe_is_special, fep_status, fep_costs, fep_hours, 
            bp_proportion, bp_costs, bp_hours, bp_start_date, bp_end_date, bp_threshold, cl_completion_level, cl_date;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
            /*Do something with the row fetched*/
            INSERT INTO `01migrate_11_12` SET elem='fee_woc', info=CONCAT_WS(', ', projects_id, main_tree_id, wo_id, wo_name, wo_is_special, wo_is_purpose_required, fe_id, fe_name, fe_is_special);
            
            IF @last_fe_id<>fe_id THEN
                SET @have_work_area_for_fee_area = false;
                /* Create fee area as preset */
                CALL us_migrate_11_12_copy_projects_fee_areas_insert(
                    main_tree_id, -- parent_id
                    fe_name, -- new_name
                    NULL, -- TAG ID
                    wo_is_purpose_required, -- is_purpose (Should only be set on LOWEST)
                    IF(fe_is_special, woac_special_id, 0), -- is_special
                    true, -- is_fee_area
                    0, -- threshold
                    @insert_id_fe
                );
                INSERT INTO `01migrate_11_12` SET elem='us_insert_work_package fee', info=@insert_id_fe;
                
                /* Set the fee values */
                UPDATE work_packages SET fee_costs=fep_costs, fee_hours=fep_hours, status=IFNULL(fep_status,20),
                    old_fee_area_id=fe_id WHERE ID=@insert_id_fe;
                INSERT INTO `01migrate_11_12` SET elem='work_packages fee values', info=CONCAT_WS(', ', projects_id, @insert_id_fe, fep_costs, fep_hours, fep_status);

                /* Create preset if the work and fee area do not have the same name */
                IF us_delete_spaces(TRIM(wo_name))<>us_delete_spaces(TRIM(fe_name)) THEN
                    SET @have_work_area_for_fee_area = true;
                    CALL us_migrate_11_12_copy_projects_fee_areas_insert(
                        @insert_id_fe, -- parent_id
                        wo_name, -- new_name
                        NULL, -- TAG ID
                        wo_is_purpose_required, -- is_purpose (Should only be set on LOWEST)
                        IF(wo_is_special, woac_special_id, 0), -- is_special
                        false, -- is_fee_area
                        0, -- threshold
                        @insert_id_wo
                    );
                    INSERT INTO `01migrate_11_12` SET elem='us_insert_work_package wo1', info=@insert_id_wo;
                    
                    /* Set the budget plan values */
                    UPDATE work_packages SET budget_proportion=IFNULL(bp_proportion,0), budget_planned_costs=bp_costs, budget_planned_hours=bp_hours, 
                        budget_start=bp_start_date, budget_end=bp_end_date, budget_threshold=bp_threshold, completion_level=cl_completion_level, loc_estimation_date=cl_date,
                        old_work_area_id=wo_id, tag_id=wo_id WHERE ID=@insert_id_wo;
                ELSE
                    /* Set the budget plan values */
                    UPDATE work_packages SET budget_proportion=IFNULL(bp_proportion,0), budget_planned_costs=bp_costs, budget_planned_hours=bp_hours, 
                        budget_start=bp_start_date, budget_end=bp_end_date, budget_threshold=bp_threshold, completion_level=cl_completion_level, loc_estimation_date=cl_date,
                        old_work_area_id=wo_id, tag_id=wo_id WHERE ID=@insert_id_fe;
                END IF;
            ELSE
                /* Create preset of first work area, if not  @have_work_area_for_fee_area */
                IF @have_work_area_for_fee_area<>true THEN
                    SET @have_work_area_for_fee_area = true;

                    /* Remove work area values from now fee area only */
                    UPDATE work_packages SET budget_proportion=null, budget_planned_costs=null, budget_planned_hours=null, 
                        budget_start=null, budget_end=null, budget_threshold=null, completion_level=null, loc_estimation_date=null,
                        old_work_area_id=null WHERE ID=@insert_id_fe;
                    
                    /* Create the new sub work area */
                    CALL us_migrate_11_12_copy_projects_fee_areas_insert(
                        @insert_id_fe, -- parent_id
                        fe_name, -- new_name (New name of wo was same)
                        NULL, -- TAG ID
                        @last_wo_is_purpose_required, -- is_purpose (Should only be set on LOWEST)
                        IF(@last_wo_is_special, woac_special_id, 0), -- is_special
                        false, -- is_fee_area
                        0, -- threshold
                        @insert_id_wo
                    );
                    INSERT INTO `01migrate_11_12` SET elem='us_insert_work_package wo2', info=@insert_id_wo;
                    
                    /* Set the budget plan values */
                    UPDATE work_packages SET budget_proportion=@last_bp_proportion, budget_planned_costs=@last_bp_costs, budget_planned_hours=@last_bp_hours, 
                        budget_start=@last_bp_start_date, budget_end=@last_bp_end_date, budget_threshold=@last_bp_threshold, completion_level=@last_cl_completion_level, loc_estimation_date=@last_cl_completion_level_date,
                        old_work_area_id=@last_wo_id, tag_id=@last_wo_id WHERE ID=@insert_id_wo;
                END IF;

                /* Create preset of next work area */
                CALL us_migrate_11_12_copy_projects_fee_areas_insert(
                    @insert_id_fe, -- parent_id
                    wo_name, -- new_name
                    NULL, -- TAG ID
                    wo_is_purpose_required, -- is_purpose (Should only be set on LOWEST)
                    IF(wo_is_special, woac_special_id, 0), -- is_special
                    false, -- is_fee_area
                    0, -- threshold
                    @insert_id_wo
                );
                INSERT INTO `01migrate_11_12` SET elem='us_insert_work_package wo3', info=@insert_id_wo;
                
                /* Set the budget plan values */
                UPDATE work_packages SET budget_proportion=IFNULL(bp_proportion,0), budget_planned_costs=bp_costs, budget_planned_hours=bp_hours, 
                    budget_start=bp_start_date, budget_end=bp_end_date, budget_threshold=bp_threshold, completion_level=cl_completion_level,
                    old_work_area_id=wo_id, tag_id=wo_id WHERE ID=@insert_id_wo;
            END IF;

            SET @last_wo_is_purpose_required = wo_is_purpose_required;
            SET @last_wo_is_special = wo_is_special;
            SET @last_fe_id = fe_id;
            SET @last_bp_proportion = IFNULL(bp_proportion,0);
            SET @last_bp_costs = bp_costs;
            SET @last_bp_hours = bp_hours;
            SET @last_bp_start_date = bp_start_date;
            SET @last_bp_end_date = bp_end_date;
            SET @last_bp_threshold = bp_threshold;
            SET @last_cl_completion_level = cl_completion_level;
            SET @last_cl_completion_level_date = cl_date;
            SET @last_wo_id = wo_id;
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  fee_areas;
    
CALL calc_sum(projects_id);
CALL get_date(projects_id);
CALL calc_completion_level(projects_id);
END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- SUB - Write work packages
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_11_12_copy_projects_fee_areas_insert;
-- EOC
DELIMITER $$
-- If you update this PROCEDURE also update us_insert_work_package
CREATE PROCEDURE us_migrate_11_12_copy_projects_fee_areas_insert(
    IN parent_id VARCHAR(100), IN new_name VARCHAR(100), IN tag_id INTEGER, IN is_purpose BOOLEAN, IN is_special BOOLEAN, 
    IN is_fee_area BOOLEAN, IN threshold DOUBLE, 
    OUT insert_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
    /* SET by SELECT */
    SELECT rgt, project_id 
        INTO @myRight, @myProjectId
        FROM work_packages WHERE id = parent_id;

    UPDATE work_packages SET rgt = rgt + 2 WHERE rgt >= @myRight AND project_id = @myProjectId;
    UPDATE work_packages SET lft = lft + 2 WHERE lft >= @myRight AND project_id = @myProjectId;

    INSERT INTO work_packages(name, tag_id, lft, rgt, project_id, is_purpose_required, is_special, is_fee_area, budget_threshold) VALUES(new_name, tag_id, @myRight, @myRight + 1, @myProjectId, is_purpose, is_special, is_fee_area, threshold);

    SET insert_id = LAST_INSERT_ID();

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Create work package history for projects
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS us_migrate_11_12_projects_history;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_projects_history()
us_migrate_11_12_projects_historylbl:BEGIN
    
    DECLARE projects_id INTEGER;
    DECLARE projects_project_name VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE projects CURSOR FOR SELECT 
            p.id, p.project_name
        FROM
            projects AS p
        ORDER BY p.id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    -- Prevent execution, if work_packages_history has content
    IF ( (SELECT COUNT(*) FROM work_packages_history)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - us_migrate_11_12_projects_history';
        LEAVE us_migrate_11_12_projects_historylbl;
    END IF;

    IF @debug THEN -- ==========================================================
        select now() AS 'THE_START_TIME_____', 'us_migrate_11_12_projects_history <--' AS 'COMMENT';
    END IF;
    -- --------------------------- Add dates ---------------------------
    OPEN projects;
    cursor_loop: LOOP -- -------------------------------------
        FETCH projects INTO projects_id, projects_project_name;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
            /*Do something with the row fetched*/
            INSERT INTO `01migrate_11_12` SET elem='projects_history', info=projects_id;

            CALL us_migrate_11_12_projects_history_dates(projects_id);

    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  projects;

    IF @debug THEN -- ==========================================================
        select now() AS 'THE_START_TIME_____', 'Add description values' AS 'COMMENT';
    END IF;
    -- --------------------------- Update history values ---------------------------
    INSERT INTO work_packages_history_descriptions (description, archive_date, project_id, type) 
        SELECT comment, migrate_valid_from_date, project_id, 'fee' FROM lut_fee_areas_proj_history
        WHERE comment IS NOT NULL AND COMMENT <> '';
    INSERT INTO work_packages_history_descriptions (description, archive_date, project_id, type) 
        SELECT comment, migrate_valid_from_date, project_id, 'budget' FROM budget_plan_history
        WHERE comment IS NOT NULL AND COMMENT <> '';
    INSERT INTO work_packages_history_descriptions (description, archive_date, project_id, type) 
        SELECT comment, migrate_valid_from_date, project_id, 'loc' FROM completion_level_history
        WHERE comment IS NOT NULL AND COMMENT <> '';

    IF @debug THEN -- ==========================================================
        select now() AS 'THE_START_TIME_____', 'Update history values' AS 'COMMENT';
    END IF;
    -- --------------------------- Update history values ---------------------------
    CALL us_migrate_11_12_projects_update_history();

    IF @debug THEN -- ==========================================================
        select now() AS 'THE_START_TIME_____', 'SUM child values' AS 'COMMENT';
    END IF;
    -- --------------------------- SUM child values ----------------------------
    CALL us_migrate_11_12_projects_sum_history();

    IF @debug THEN -- ==========================================================
        select now() AS 'THE_START_TIME_____', 'Calculate loc' AS 'COMMENT';
    END IF;
    -- --------------------------- Calculate loc -------------------------------
    CALL us_migrate_11_12_projects_calc_loc();

    IF @debug THEN -- ==========================================================
        select now() AS 'THE_START_TIME_____', 'Done <--' AS 'COMMENT';
    END IF;

END $$
DELIMITER ;
-- EOC

-- --------------------------- --------------------------- --------------------------- ---------------------------
DROP PROCEDURE IF EXISTS us_migrate_11_12_projects_update_history;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_projects_update_history()
BEGIN

    DECLARE dates datetime;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE get_dates CURSOR FOR SELECT 
            DISTINCT date 
        FROM work_packages_history
        ORDER BY date DESC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    -- --------------------------- Update history values ---------------------------
    OPEN get_dates;
    cursor_loop: LOOP -- -------------------------------------
        FETCH get_dates INTO dates;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
            /*Do something with the row fetched*/
            INSERT INTO `01migrate_11_12` SET elem='projects_update_history', info=dates;
            
            -- Update lut_fee_areas_proj values
            UPDATE work_packages_history AS wh 
                INNER JOIN (
                    SELECT w.id, l.costs, l.hours
                    FROM work_packages AS w
                    INNER JOIN lut_fee_areas_proj AS l ON w.old_fee_area_id=l.fee_area_id AND w.project_id=l.project_id
                    INNER JOIN lut_fee_areas_proj_history AS lh ON l.lut_fee_areas_proj_history_id=lh.id
                    WHERE lh.migrate_valid_from_date=dates
                ) whsub
                ON wh.wp_id=whsub.id
            SET wh.fee_costs=whsub.costs, wh.fee_hours=whsub.hours
            WHERE wh.fee_costs IS NULL AND wh.fee_hours IS NULL AND wh.date>=dates;
            
            -- Update basic budget_plan values
            UPDATE work_packages_history AS wh 
                INNER JOIN (
                    SELECT w.id, p.proportion, p.planned_costs, p.planned_hours, p.threshold
                    FROM work_packages AS w
                    INNER JOIN budget_plan AS p ON w.old_work_area_id=p.area_id AND w.project_id=p.project_id
                    INNER JOIN budget_plan_history AS ph ON p.budget_plan_history_id=ph.id
                    WHERE ph.migrate_valid_from_date=dates
                ) whsub
                ON wh.wp_id=whsub.id
            SET wh.budget_proportion=whsub.proportion, wh.budget_planned_costs=whsub.planned_costs, 
                wh.budget_planned_hours=whsub.planned_hours, wh.budget_threshold=whsub.threshold
            WHERE wh.budget_proportion IS NULL AND wh.budget_planned_costs IS NULL AND 
                wh.budget_planned_hours IS NULL AND wh.budget_threshold IS NULL AND wh.date>=dates;
            
            -- Update basic completion_level values
            UPDATE work_packages_history AS wh 
                INNER JOIN (
                    SELECT w.id, c.completion_level
                    FROM work_packages AS w
                    INNER JOIN completion_level AS c ON w.old_work_area_id=c.work_area_id AND w.project_id=c.project_id
                    INNER JOIN completion_level_history AS ch ON c.completion_level_history_id=ch.id
                    WHERE ch.migrate_valid_from_date=dates
                ) whsub
                ON wh.wp_id=whsub.id
            SET wh.completion_level=whsub.completion_level
            WHERE wh.completion_level IS NULL AND wh.date>=dates;
            
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  get_dates;

    UPDATE work_packages_history SET fee_costs=0 WHERE fee_costs IS NULL;
    UPDATE work_packages_history SET fee_hours=0 WHERE fee_hours IS NULL;
    UPDATE work_packages_history SET budget_proportion=0 WHERE budget_proportion IS NULL;
    UPDATE work_packages_history SET budget_planned_costs=0 WHERE budget_planned_costs IS NULL;
    UPDATE work_packages_history SET budget_planned_hours=0 WHERE budget_planned_hours IS NULL;
    UPDATE work_packages_history SET budget_threshold=0 WHERE budget_threshold IS NULL;
    UPDATE work_packages_history SET completion_level=0 WHERE completion_level IS NULL;

END $$
DELIMITER ;
-- EOC

-- --------------------------- --------------------------- --------------------------- ---------------------------
DROP PROCEDURE IF EXISTS us_migrate_11_12_projects_sum_history;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_projects_sum_history()
BEGIN

    -- --------------------------- Sum budget child values ---------------------------
    UPDATE
        work_packages_history AS wph
        JOIN (
                SELECT 
                    wph.date, wp.id,
                    (
                        SELECT 
                            SUM(wph1.budget_planned_costs)
                        FROM
                            work_packages_history AS wph1
                            INNER JOIN
                            work_packages AS wp1 ON wp1.id = wph1.wp_id
                        WHERE
                            wph1.project_id=wph.project_id
                            AND
                            wph1.date=wph.date
                            AND
                            wp1.lft>=wp.lft
                            AND
                            wp1.rgt<=wp.rgt
                    ) AS cost,
                    (
                        SELECT 
                            SUM(wph1.budget_planned_hours)
                        FROM
                            work_packages_history AS wph1
                            INNER JOIN
                            work_packages AS wp1 ON wp1.id = wph1.wp_id
                        WHERE
                            wph1.project_id=wph.project_id
                            AND
                            wph1.date=wph.date
                            AND
                            wp1.lft>=wp.lft
                            AND
                            wp1.rgt<=wp.rgt
                    ) AS hours,
                    (
                        SELECT 
                            SUM(wph1.budget_proportion)
                        FROM
                            work_packages_history AS wph1
                            INNER JOIN
                            work_packages AS wp1 ON wp1.id = wph1.wp_id
                        WHERE
                            wph1.project_id=wph.project_id
                            AND
                            wph1.date=wph.date
                            AND
                            wp1.lft>=wp.lft
                            AND
                            wp1.rgt<=wp.rgt
                    ) AS proportion,
                    (
                        SELECT 
                            SUM(wph1.fee_costs)
                        FROM
                            work_packages_history AS wph1
                            INNER JOIN
                            work_packages AS wp1 ON wp1.id = wph1.wp_id
                        WHERE
                            wph1.project_id=wph.project_id
                            AND
                            wph1.date=wph.date
                            AND
                            wp1.lft>=wp.lft
                            AND
                            wp1.rgt<=wp.rgt
                    ) AS fee_costs,
                    (
                        SELECT 
                            SUM(wph1.fee_hours)
                        FROM
                            work_packages_history AS wph1
                            INNER JOIN
                            work_packages AS wp1 ON wp1.id = wph1.wp_id
                        WHERE
                            wph1.project_id=wph.project_id
                            AND
                            wph1.date=wph.date
                            AND
                            wp1.lft>=wp.lft
                            AND
                            wp1.rgt<=wp.rgt
                    ) AS fee_hours
                FROM
                    work_packages_history AS wph
                    INNER JOIN
                    work_packages AS wp ON wp.id = wph.wp_id
        ) bhsub
        ON 
            bhsub.id=wph.wp_id
            AND
            bhsub.date=wph.date
    SET wph.budget_planned_costs = bhsub.cost, wph.budget_planned_hours = bhsub.hours, wph.budget_proportion = bhsub.proportion,
        wph.fee_costs = bhsub.fee_costs, wph.fee_hours = bhsub.fee_hours;

END $$
DELIMITER ;
-- EOC

-- --------------------------- Avoid division by zero (first sum all values together (especially budget_proportion) and then calculate loc --------------------------- ---------------------------
DROP PROCEDURE IF EXISTS us_migrate_11_12_projects_calc_loc;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_projects_calc_loc()
BEGIN

    -- --------------------------- Sum child values ---------------------------
    DECLARE wps_id INTEGER;
    DECLARE project_ids INTEGER;
    DECLARE lft_vals INTEGER;
    DECLARE rgt_vals INTEGER;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE work_packages CURSOR FOR SELECT 
            wp.id, wp.project_id, wp.lft, wp.rgt
        FROM
            work_packages AS wp WHERE rgt-lft > 1
        ORDER BY wp.id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    OPEN work_packages;
    cursor_loop: LOOP -- -------------------------------------
        FETCH work_packages INTO wps_id, project_ids, lft_vals, rgt_vals;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;

        CALL us_migrate_11_12_projects_calc_loc_sub(wps_id, project_ids, lft_vals, rgt_vals);
            
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  work_packages;
END $$
DELIMITER ;
-- EOC

-- --------------------------- --------------------------- --------------------------- ---------------------------
DROP PROCEDURE IF EXISTS us_migrate_11_12_projects_calc_loc_sub;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_projects_calc_loc_sub(IN my_wp_id integer, IN my_project integer, lft_val integer, rgt_val integer)
BEGIN

    -- --------------------------- Sum child values ---------------------------
    DECLARE dates datetime;
    DECLARE ids integer;
    DECLARE proportions integer;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE history_dates CURSOR FOR SELECT 
            wph.date, wph.id, wph.budget_proportion
        FROM
            work_packages_history AS wph WHERE wp_id = my_wp_id
        ORDER BY wph.date;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    OPEN history_dates;
    cursor_loop: LOOP -- -------------------------------------
        FETCH history_dates INTO dates, ids, proportions;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF; 

        IF (SELECT budget_proportion from work_packages_history where wp_id = my_wp_id AND date = dates) > 0 THEN
            /* SET by SELECT */
            SELECT SUM((completion_level * budget_proportion) / (SELECT budget_proportion from work_packages_history where wp_id = my_wp_id AND date = dates)) 
                INTO @loc
                FROM work_packages_history WHERE wp_id IN 
                (SELECT id from work_packages where project_id = my_project AND lft BETWEEN lft_val AND rgt_val AND rgt-lft = 1) AND date = dates;
            SET @s = CONCAT('UPDATE work_packages_history SET completion_level = ', @loc, '  WHERE id = ', ids);
            PREPARE stmt1 FROM @s;
            EXECUTE stmt1;
        END IF;
            
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  history_dates;
END $$
DELIMITER ;
-- EOC

-- --------------------------- --------------------------- --------------------------- ---------------------------
DROP PROCEDURE IF EXISTS us_migrate_11_12_projects_clone_to_history;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_projects_clone_to_history(IN projects_id INTEGER, IN valid_from_datess DATE)
BEGIN
    REPLACE INTO work_packages_history (project_id, completion_level, budget_proportion, budget_planned_costs, budget_planned_hours, budget_threshold, 
        fee_costs, fee_hours, fee_proportion, wpp_tree_id, date, wp_id, loc_estimation_date)
    SELECT project_id, NULL AS completion_level, NULL AS budget_proportion, NULL AS budget_planned_costs, NULL AS budget_planned_hours, NULL AS budget_threshold, 
        NULL AS fee_costs, NULL AS fee_hours, NULL AS fee_proportion, wpp_tree_id, valid_from_datess AS date, id AS wp_id, 
        NULL AS loc_estimation_date from work_packages
        WHERE project_id=projects_id;
END $$
DELIMITER ;
-- EOC

-- --------------------------- --------------------------- --------------------------- ---------------------------
DROP PROCEDURE IF EXISTS us_migrate_11_12_projects_history_dates;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12_projects_history_dates(IN projects_id INTEGER)
BEGIN
    
    DECLARE valid_from_dates datetime;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    -- --------------------------- Get current dates ---------------------------
    DECLARE project_dates CURSOR FOR 	SELECT migrate_valid_from_date
            FROM lut_fee_areas_proj_history AS lh WHERE lh.project_id=projects_id
        UNION DISTINCT
            SELECT migrate_valid_from_date
            FROM budget_plan_history AS bh WHERE bh.project_id=projects_id
        UNION DISTINCT
            SELECT migrate_valid_from_date
            FROM completion_level_history AS cl WHERE cl.project_id=projects_id
        ORDER BY migrate_valid_from_date;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    -- --------------------------- Add dates ---------------------------
    OPEN project_dates;
    cursor_loop: LOOP -- -------------------------------------
        FETCH project_dates INTO valid_from_dates;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
        
        CALL us_migrate_11_12_projects_clone_to_history(projects_id, valid_from_dates);
        
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  project_dates;

END $$
DELIMITER ;
-- EOC


-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Improve todo - In procedure, so that change_column does not always trigger remove of fulltext index
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS update_improve_todo;
-- EOC
DELIMITER $$
CREATE PROCEDURE update_improve_todo()
BEGIN

    -- Open tasks
    CALL check_rename_column_exists('todo', 'Modultyp', 'IsPostAusgang', 'integer');

    CALL check_rename_column_exists('todo', 'Modul_id', 'lfdnr_post', 'integer');

    -- Open tasks
    CALL us_add_to_table2('todo', 'active_from', 'DATETIME DEFAULT NULL AFTER `Bemerkung`' );

    CALL us_add_to_table2('todo', 'period_value', 'INT DEFAULT 1 AFTER `Bemerkung`' );

    CALL us_add_to_table2('todo', 'unit', 'INT  DEFAULT 1 AFTER `period_value`' );

    CALL us_add_to_table2('todo', 'working_hours', 'DOUBLE  DEFAULT NULL AFTER `unit`' );

    CALL change_column('todo', 'ErlVermerk', 'LONGTEXT NULL DEFAULT NULL AFTER `AendVon`');

    CALL us_add_to_table2('todo', 'lfdnr_post', 'INT NULL AFTER `IsPostAusgang`' );

    CALL change_column('todo', 'lfdnr_post', 'VARCHAR( 50 ) NULL DEFAULT NULL AFTER `IsPostAusgang`');

END $$
DELIMITER ;
-- EOC-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Update offers to new format with more features for X3, especially for HOAI
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- USC X3 Update.

DROP PROCEDURE IF EXISTS update_lut_fee_areas_offer_add_fields;
-- EOC
DELIMITER $$
CREATE PROCEDURE update_lut_fee_areas_offer_add_fields()
BEGIN
    CALL us_add_to_table2('lut_fee_areas_offer', 'custom_costs', 'DOUBLE DEFAULT NULL AFTER `fee_area_id`' );    
    CALL us_add_to_table2('lut_fee_areas_offer', 'costs_view', 'DOUBLE NOT NULL DEFAULT 0 AFTER `costs`' );
    CALL us_add_to_table2('lut_fee_areas_offer', 'quantity', 'DOUBLE DEFAULT 1 AFTER `costs_view`' );    
    CALL us_add_to_table2('lut_fee_areas_offer', 'quantity_id', 'INT DEFAULT NULL AFTER `quantity`' );    
    CALL us_add_to_table2('lut_fee_areas_offer', 'price', 'DOUBLE DEFAULT 0 AFTER `quantity_id`' );    
    CALL us_add_to_table2('lut_fee_areas_offer', 'repetition', 'DOUBLE NOT NULL DEFAULT 0 AFTER `price`' );
    CALL us_add_to_table2('lut_fee_areas_offer', 'supplement', 'DOUBLE NOT NULL DEFAULT 0 AFTER `repetition`' );
    CALL us_add_to_table2('lut_fee_areas_offer', 'extras', 'DOUBLE NOT NULL DEFAULT 0 AFTER `supplement`' );
    CALL us_add_to_table2('lut_fee_areas_offer', 'extras_otcurr', 'DOUBLE NOT NULL DEFAULT 0 AFTER `extras`' );
    CALL us_add_to_table2('lut_fee_areas_offer', 'extras_is_percentage', 'BOOLEAN NOT NULL DEFAULT 1 AFTER `extras_otcurr`' );
    CALL us_add_to_table2('lut_fee_areas_offer', 'rebate', 'DOUBLE NOT NULL DEFAULT 0 AFTER `extras_is_percentage`' );
    CALL us_add_to_table2('lut_fee_areas_offer', 'rebate_otcurr', 'DOUBLE NOT NULL DEFAULT 0 AFTER `rebate`' );
    CALL us_add_to_table2('lut_fee_areas_offer', 'rebate_is_percentage', 'BOOLEAN NOT NULL DEFAULT 1 AFTER `rebate_otcurr`' );
    CALL us_add_to_table2('lut_fee_areas_offer', 'calc_rep', 'BOOLEAN NOT NULL DEFAULT 0 AFTER `rebate_is_percentage`' );
    CALL us_add_to_table2('lut_fee_areas_offer', 'calc_rep_wp', 'INT NOT NULL DEFAULT 0 AFTER `calc_rep`' );
    CALL us_add_to_table2('lut_fee_areas_offer', 'calc_rebate_first', 'INT NOT NULL DEFAULT 0 AFTER `calc_rep_wp`');

    CALL us_add_to_table2('lut_fee_areas_offer', 'percent_sum', 'INT DEFAULT 0' );

    -- Original currency values
    CALL us_add_to_table2('lut_fee_areas_offer', 'custom_costs_otcurr', 'DOUBLE DEFAULT NULL');
    CALL us_add_to_table2('lut_fee_areas_offer', 'supplement_otcurr', 'DOUBLE DEFAULT NULL');
    CALL us_add_to_table2('lut_fee_areas_offer', 'costs_otcurr', 'DOUBLE DEFAULT NULL');
    CALL us_add_to_table2('lut_fee_areas_offer', 'costs_sum_otcurr', 'DOUBLE DEFAULT NULL');

END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS update_lut_fee_areas_offer_calc_rebate_first;
-- EOC
DELIMITER $$
CREATE PROCEDURE update_lut_fee_areas_offer_calc_rebate_first()
update_lut_fee_areas_offer_calc_rebate_firstlbl:BEGIN
    -- Prevent double execution
    IF ( SELECT COUNT(*) FROM `01migrate_11_12_steps` WHERE stepname='update_lut_fee_areas_offer_calc_rebate_first') THEN
        LEAVE update_lut_fee_areas_offer_calc_rebate_firstlbl;
    END IF;
    INSERT INTO `01migrate_11_12_steps` SET stepname='update_lut_fee_areas_offer_calc_rebate_first';
    
    UPDATE lut_fee_areas_offer JOIN project_offers ON lut_fee_areas_offer.offer_id=project_offers.id
    SET lut_fee_areas_offer.calc_rebate_first=project_offers.calc_rebate_first;
END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS update_lut_fee_areas_offer;
-- EOC
DELIMITER $$
CREATE PROCEDURE update_lut_fee_areas_offer()
update_lut_fee_areas_offerlbl:BEGIN

    DECLARE prof_ids INTEGER;
    DECLARE fees_arr_values TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE version_values VARCHAR(10) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE type_values VARCHAR(10) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE supplement_values DOUBLE;
    DECLARE specserv_values DOUBLE;
    DECLARE extras_values DOUBLE;
    DECLARE rebate_values DOUBLE;
    DECLARE fees_value DOUBLE DEFAULT NULL;
    DECLARE is_special_index INTEGER DEFAULT NULL;
    DECLARE is_special_value INTEGER DEFAULT NULL;
    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE prof CURSOR FOR SELECT 
        id,
        us_json_extract_arr(portlet_data, 'fees') AS fees_arr_value, 
        us_json_extract(portlet_data, 'version') AS version_value, 
        us_json_extract(portlet_data, 'type') AS type_value, 
        us_json_extract(portlet_data, 'supplement') AS supplement_value, 
        us_json_extract(portlet_data, 'specserv') AS specserv_value, 
        us_json_extract(portlet_data, 'extras') AS extras_value, 
        us_json_extract(portlet_data, 'rebate') AS rebate_value
        FROM project_offers;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    CALL update_lut_fee_areas_offer_add_fields();

    -- Prevent execution, if work_packages_tags has ids>10000000
    IF ( (SELECT SUM(costs_view) FROM lut_fee_areas_offer)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - update_lut_fee_areas_offer';
        LEAVE update_lut_fee_areas_offerlbl;
    END IF;

    -- Use those as sets to get the HOAI is_special value from Version-Type
    SET @planungsleistungen_keys = '2013-1,2013-2,2013-3,2013-4,2013-5,2013-6,2013-7,2009-1,2009-12,2009-13,2009-14,2009-15,2009-16,2009-17';
    SET @planungsleistungen_values = '-10,-11,-12,-13,-14,-15,-16,-2,-3,-4,-5,-6,-7,-8';

    OPEN prof;
    cursor_loop: LOOP -- -------------------------------------
        FETCH prof INTO prof_ids, fees_arr_values, version_values, type_values, supplement_values, specserv_values, extras_values, rebate_values;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;

        -- Simple update now
        UPDATE lut_fee_areas_offer SET 
            costs_view = costs,
            extras = IFNULL(extras_values,0), 
            rebate = IFNULL(rebate_values,0) 
            WHERE offer_id = prof_ids;

        -- Get HOAI is_special value
        SET is_special_index = FIND_IN_SET(CONCAT(version_values,'-',type_values), @planungsleistungen_keys);
        IF is_special_index = 0 THEN
            SET is_special_value = 0;
        ELSE
            SET is_special_value = CONVERT(us_get_from_set(is_special_index, @planungsleistungen_values), SIGNED);
        END IF;

        -- Update fee area costs_view value
        IF is_special_value IS NOT NULL THEN
            -- For each fee area
            SET @x = 0;
            REPEAT
                SET @x = @x + 1;
                
                SET fees_value = us_get_from_set(@x, fees_arr_values)+0.0;
                IF fees_value IS NOT NULL THEN
                    UPDATE lut_fee_areas_offer AS lof INNER JOIN work_packages AS wps ON lof.work_package_id=wps.id SET 
                        lof.costs_view = fees_value
                        WHERE lof.offer_id = prof_ids
                        AND wps.is_special = is_special_value
                        AND wps.is_special_phase = @x;
                END IF;

            UNTIL @x > 9 END REPEAT;

        END IF;

    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  prof;
END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migrates/Inserts the table drawings_inbox into table drawings
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS migrate_drawings_inbox_to_drawings;
-- EOC
DELIMITER $$
CREATE PROCEDURE migrate_drawings_inbox_to_drawings()
migrate_drawings_inbox_to_drawingslbl:BEGIN
    DECLARE drawings_type INT;
    DECLARE plot_file_types VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    
    -- If table doesn't exist, migration is not possible
    IF NOT EXISTS( (SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='drawings_inbox') ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='No migration necessary - migrate_drawings_inbox_to_drawings';
        LEAVE migrate_drawings_inbox_to_drawingslbl;
    END IF;
    
    -- If old-table already exists, migration must not be executed
    IF EXISTS( (SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='drawings_inbox_old') ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='No migration necessary - migrate_drawings_inbox_to_drawings';
        LEAVE migrate_drawings_inbox_to_drawingslbl;
    END IF;

    -- Add new field received_from
    CALL us_add_to_table2('drawings', 'received_from', 'INT DEFAULT NULL AFTER date' );

    -- Insert new drawing type for the migrated drawings
    INSERT INTO planart (ArtText, Bemerkung) VALUES('us_Planeingang', '');
    SET drawings_type = LAST_INSERT_ID();

    -- Get plot file types as SET
    SET plot_file_types = (SELECT SettingValue FROM settingssystem WHERE SettingType LIKE 'plot_file_types');
    IF plot_file_types IS NULL OR trim(plot_file_types)='' THEN
        SET plot_file_types = 'PLT,PDF';
    ELSE
        SET plot_file_types = REPLACE(plot_file_types, '|', ',');
    END IF;

    -- Insert data from the drawings_inbox table into the drawings table
    INSERT INTO
        drawings(
            type_id,
            project_id,
            plan_no,
            plan_content,
            `date`,
            plan_index,
            received_from,
            cad_file,
            plot_file,
            work_area_id,
            created_date,
            created_by_id,
            change_date,
            changed_by_id,
            purpose,
            work_package_id
        )
    SELECT
        drawings_type as type_id,
        inbox.project_id as project_id,
        inbox.plan_no as plan_no,
        inbox.plan_content as plan_content,
        inbox.`date` as `date`,
        inbox.plan_index as plan_index,
        inbox.address_id as received_from,
        (
            CASE WHEN 
                FIND_IN_SET(
                    SUBSTRING_INDEX(inbox.`file`, '.', -1),
                    plot_file_types
                ) <= 0
            THEN 
                inbox.`file` 
            ELSE 
                NULL 
            END
        ) as cad_file,
        (
            CASE WHEN 
                FIND_IN_SET(
                    SUBSTRING_INDEX(inbox.`file`, '.', -1), 
                    plot_file_types
                ) >= 1
            THEN
                inbox.`file` 
            ELSE 
                NULL 
            END
        ) as plot_file,
        inbox.work_area_id as work_area_id,
        inbox.created_date as created_date,
        inbox.created_by_id as created_by_id,
        inbox.change_date as change_date,
        inbox.changed_by_id as changed_by_id,
        inbox.description as purpose,
        inbox.work_package_id as work_package_id
    FROM
        drawings_inbox AS inbox;

    -- Finally rename table
    RENAME TABLE drawings_inbox TO drawings_inbox_old;
END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migrate Improve correspondence
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_12_13_improve_correspondence;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_12_13_improve_correspondence()
BEGIN
    
    UPDATE formular SET Stufe=3 WHERE Stufe IS NULL;

    UPDATE formart SET Sicherheit=3 WHERE Sicherheit IS NULL;

    ALTER TABLE `formular` CHANGE COLUMN `Stufe` `Stufe` SMALLINT NULL DEFAULT 3;
    -- NOT NULL would be better, but takes ages

    ALTER TABLE `formart` CHANGE COLUMN `Sicherheit` `Sicherheit` SMALLINT NOT NULL DEFAULT 3;

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migrate time protocol to user option for X3
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_12_13_migrate_timelog_to_user;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_12_13_migrate_timelog_to_user()
BEGIN
    
    -- Shall we start project, derive from timelogging_start_view and then set to old ProTodo
    INSERT INTO settingsuser(SettingType, SettingValue, LfdNr_User)
        SELECT 'timelogging_start_project_id', (SELECT LfdNr FROM projekte WHERE ProTodo=1), LfdNr_User 
        FROM settingsuser 
        WHERE SettingType='timelogging_start_view' AND SettingValue='TRUE';

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migrate to lut_company_proj
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_12_13_lut_company_proj;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_12_13_lut_company_proj()
BEGIN
    
    DROP VIEW IF EXISTS `lut_company_proj`;

    CREATE TABLE `lut_company_proj` (
      `company_id` INT NOT NULL,
      `project_id` INT NOT NULL,
      PRIMARY KEY (`company_id`, `project_id`),
      KEY `lut_firm_proj_firmen_id` (`company_id`),
      KEY `lut_firm_proj_projekt_id` (`project_id`)
    ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

    INSERT INTO `lut_company_proj`
        SELECT DISTINCT Firmen_ID, Projekt_ID FROM lut_firm_proj;

    RENAME TABLE lut_firm_proj TO lut_firm_proj__bak;

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migrate to lut_correspondence_addresses
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_12_13_lut_correspondence_addresses;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_12_13_lut_correspondence_addresses()
BEGIN
    
    DROP VIEW IF EXISTS `lut_correspondence_addresses`;

    CREATE TABLE `lut_correspondence_addresses` (
      `id` INT NOT NULL AUTO_INCREMENT,
      `correspondence_id` INT DEFAULT NULL,
      `address_id` INT DEFAULT NULL,
      `address_group_id` INT DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `verteiler_unique` (`correspondence_id`,`address_id`),
      KEY `verteiler_empfaengernr` (`address_id`),
      KEY `verteiler_dokunr` (`correspondence_id`)
    ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

    INSERT INTO `lut_correspondence_addresses`
        SELECT MIN(LfdNr), DokuNr, EmpfaengerNr, MIN(AdrGrpNr) FROM verteiler GROUP BY DokuNr, EmpfaengerNr;

    RENAME TABLE verteiler TO verteiler__bak;

END $$
DELIMITER ;
-- EOC


-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migrate fee_multipliers from system table to fee_multipliers table
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_12_13_fee_multipliers_from_system;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_12_13_fee_multipliers_from_system()
us_migrate_12_13_fee_multipliers_from_systemlbl:BEGIN

    DECLARE fee_mul_x  INT;

    -- Prevent execution, if system fee_multipliers are already in fee_multipliers table
    IF ( (SELECT count(*) FROM fee_multipliers WHERE is_standard <> FALSE OR is_r2 <> FALSE OR is_r3 <> FALSE OR is_r4 <> FALSE)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - us_migrate_12_13_fee_multipliers_from_system';
        LEAVE us_migrate_12_13_fee_multipliers_from_systemlbl;
    END IF;


    SET fee_mul_x = 1;
    WHILE fee_mul_x  <= 9 DO
        IF ( (SELECT count(*) FROM settingssystem WHERE SettingType=CONCAT('bueroausas_',fee_mul_x) AND SettingValue='TRUE')>0 ) THEN 
            UPDATE fee_multipliers SET is_standard=TRUE, is_r2=TRUE, is_r3=TRUE, is_r4=TRUE WHERE rate_id=fee_mul_x;
        END IF;
        
        SET  fee_mul_x = fee_mul_x + 1; 
    END WHILE;

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- ADD staff_cost_centre to times/travels/extras
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_12_13_staff_cost_centre_times_travles_extras;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_12_13_staff_cost_centre_times_travles_extras()
us_migrate_12_13_staff_cost_centre_times_travles_extraslbl:BEGIN

    DECLARE staff_ids INT;
    DECLARE staff_cost_centres INT;
    DECLARE l_last_row_fetched INTEGER;

    DECLARE curs CURSOR FOR SELECT LfdNr, PersKostenStelle FROM personen;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;
    SET l_last_row_fetched=0;
    OPEN curs;

        -- ADD staff_cost_centre to times/travels/extras
        CALL us_add_to_table2('times', 'staff_cost_centre', 'INT DEFAULT 0' );
        CALL us_add_to_table2('travels', 'staff_cost_centre', 'INT DEFAULT 0' );
        CALL us_add_to_table2('extras', 'staff_cost_centre', 'INT DEFAULT 0' );

	cursor_loop: LOOP -- -------------------------------------
            FETCH curs INTO staff_ids, staff_cost_centres;
            IF l_last_row_fetched=1 THEN
                LEAVE cursor_loop;
            END IF;

            UPDATE times set staff_cost_centre=staff_cost_centres WHERE staff_id = staff_ids AND staff_cost_centre = 0;
            UPDATE travels set staff_cost_centre=staff_cost_centres WHERE staff_id = staff_ids AND staff_cost_centre = 0;
            UPDATE extras set staff_cost_centre=staff_cost_centres WHERE staff_id = staff_ids AND staff_cost_centre = 0;
	END LOOP cursor_loop; -- -------------------------------------
    CLOSE curs;
	SET l_last_row_fetched=0;	
END $$
DELIMITER ;
-- EOC


-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- ADD values to lut_staff_cost_centre
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_12_13_lut_staff_cost_centre;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_12_13_lut_staff_cost_centre()
us_migrate_12_13_lut_staff_cost_centrelbl:BEGIN

    DECLARE staff_ids INT;
    DECLARE staff_cost_centres INT;
    DECLARE staff_start DateTime;
    DECLARE l_last_row_fetched INTEGER;

    DECLARE curs CURSOR FOR SELECT LfdNr, PersKostenStelle, `Start` FROM personen;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;


    -- Prevent execution, if system fee_multipliers are already in fee_multipliers table
    IF ( (SELECT count(*) FROM lut_staff_cost_centre)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - us_migrate_12_13_lut_staff_cost_centre';
        LEAVE us_migrate_12_13_lut_staff_cost_centrelbl;
    END IF;


    SET l_last_row_fetched=0;
    OPEN curs;

	cursor_loop: LOOP -- -------------------------------------
            FETCH curs INTO staff_ids, staff_cost_centres, staff_start;
            IF l_last_row_fetched=1 THEN
                LEAVE cursor_loop;
            END IF;

            IF staff_start IS NULL THEN
                SET staff_start = '1990-01-01 00:00:00';
            END IF;

            INSERT INTO lut_staff_cost_centre (staff_id, cost_centre_id, from_date, description) 
                VALUES (staff_ids, staff_cost_centres, staff_start, 'Start');

	END LOOP cursor_loop; -- -------------------------------------
    CLOSE curs;
	SET l_last_row_fetched=0;	
END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- ADD values to lut_staff_gross_hourly_wage
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_12_13_lut_staff_gross_hourly_wage;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_12_13_lut_staff_gross_hourly_wage()
us_migrate_12_13_lut_staff_gross_hourly_wagelbl:BEGIN

    DECLARE staff_ids INT;
    DECLARE staff_gross_hourly_wage DOUBLE;
    DECLARE staff_staff_start DateTime;
    DECLARE l_last_row_fetched INTEGER;

    DECLARE curs CURSOR FOR SELECT LfdNr, Bruttolohn, `Start` FROM personen;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;


    -- Prevent execution, if system fee_multipliers are already in fee_multipliers table
    IF ( (SELECT count(*) FROM lut_staff_gross_hourly_wage)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - us_migrate_12_13_lut_staff_gross_hourly_wage';
        LEAVE us_migrate_12_13_lut_staff_gross_hourly_wagelbl;
    END IF;

    -- Create the temp table to work from
    CREATE TEMPORARY TABLE IF NOT EXISTS migrate_staff_gross_hourly_wage_changed AS 
        SELECT staff_id, gross_hourly_wage, `date` FROM times GROUP BY staff_id, gross_hourly_wage, `date`;

    SET l_last_row_fetched=0;
    OPEN curs;

	cursor_loop: LOOP -- -------------------------------------
            FETCH curs INTO staff_ids, staff_gross_hourly_wage, staff_staff_start;
            IF l_last_row_fetched=1 THEN
                LEAVE cursor_loop;
            END IF;
 
            IF staff_staff_start IS NULL THEN
                SET staff_staff_start = '1990-01-01';
            END IF;

            -- Set values for staff
            CALL _us_migrate_12_13_lut_staff_gross_hourly_wage_staff(staff_ids, staff_gross_hourly_wage, staff_staff_start);

	END LOOP cursor_loop; -- -------------------------------------
    CLOSE curs;
	SET l_last_row_fetched=0;	
END $$
DELIMITER ;
-- EOC


DROP PROCEDURE IF EXISTS _us_migrate_12_13_lut_staff_gross_hourly_wage_staff;
-- EOC
DELIMITER $$
CREATE PROCEDURE _us_migrate_12_13_lut_staff_gross_hourly_wage_staff(IN xstaff_id INTEGER, IN xstaff_gross_hourly_wage DOUBLE, IN xstaff_staff_start DATE)
BEGIN

    DECLARE time_gross_hourly_wage DOUBLE;
    DECLARE time_date DATE;
    DECLARE ls_last_row_fetched INTEGER;

    DECLARE curs CURSOR FOR SELECT gross_hourly_wage, `date` FROM migrate_staff_gross_hourly_wage_changed WHERE staff_id=xstaff_id ORDER BY `date` DESC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET ls_last_row_fetched=1;

    SET @last_gross_hourly_wage = xstaff_gross_hourly_wage;
    SET @last_to_date = NULL;
    SET @rows_count = 0;

    SET ls_last_row_fetched=0;
    OPEN curs;

	cursor_loop: LOOP -- -------------------------------------
            FETCH curs INTO time_gross_hourly_wage, time_date;
            IF ls_last_row_fetched=1 THEN
                LEAVE cursor_loop;
            END IF;
            
            -- When the value changes and not still the same date
            IF round(time_gross_hourly_wage, 2) != @last_gross_hourly_wage AND (@last_to_date IS NULL OR @last_to_date != time_date) THEN
                
                INSERT INTO lut_staff_gross_hourly_wage (staff_id, gross_hourly_wage, from_date, to_date) 
                    VALUES (xstaff_id, @last_gross_hourly_wage, DATE_ADD(time_date, INTERVAL 1 DAY), @last_to_date);

                SET @last_gross_hourly_wage = round(time_gross_hourly_wage, 2);
                SET @last_to_date = time_date;
                SET @rows_count = @rows_count + 1;
            END IF;

            -- Max X rows +1
            IF @rows_count>20 THEN
                LEAVE cursor_loop;
            END IF;
            
	END LOOP cursor_loop; -- -------------------------------------
    CLOSE curs;

    IF @rows_count<=0 THEN
        INSERT INTO lut_staff_gross_hourly_wage (staff_id, gross_hourly_wage, from_date, description) 
            VALUES (xstaff_id, xstaff_gross_hourly_wage, xstaff_staff_start, 'Start');
    ELSEIF @rows_count<20 THEN
        IF xstaff_staff_start>=time_date THEN
            SET xstaff_staff_start = time_date;
        END IF;
        IF xstaff_staff_start>=@last_to_date THEN
            SET xstaff_staff_start = DATE_SUB(@last_to_date, INTERVAL 1 DAY);
        END IF;

        INSERT INTO lut_staff_gross_hourly_wage (staff_id, gross_hourly_wage, from_date, to_date, description) 
            VALUES (xstaff_id, @last_gross_hourly_wage, xstaff_staff_start, @last_to_date, 'Start');
    END IF;

    SET ls_last_row_fetched=0;	
END $$
DELIMITER ;
-- EOC
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Update calendar for X4
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- USC X4 Update.

DROP PROCEDURE IF EXISTS us_migrate_13_14_update_split_url_location;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_13_14_update_split_url_location()
update_split_url_locationlbl:BEGIN
    -- Prevent execution, if work_packages_tags has ids>10000000
    IF ( (SELECT COUNT(*) FROM perstermin WHERE url IS NOT NULL)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - update_split_url_location';
        LEAVE update_split_url_locationlbl;
    END IF;

    UPDATE perstermin  SET url=TRIM(Ort), changed_url=bOrt
    WHERE url IS NULL AND (TRIM(Ort) LIKE 'http://%' OR TRIM(Ort) LIKE 'https://%');

    UPDATE perstermin  SET Ort=''
    WHERE url IS NOT NULL AND (TRIM(Ort) LIKE 'http://%' OR TRIM(Ort) LIKE 'https://%');

END $$
DELIMITER ;
-- EOC

DROP PROCEDURE IF EXISTS us_migrate_13_14_update_split_summary_comment;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_13_14_update_split_summary_comment()
update_split_summary_commentlbl:BEGIN
    -- Prevent execution, if work_packages_tags has ids>10000000
    IF ( (SELECT COUNT(*) FROM perstermin WHERE summary IS NOT NULL)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - update_split_summary_comment';
        LEAVE update_split_summary_commentlbl;
    END IF;

    UPDATE perstermin  SET summary=SUBSTRING_INDEX(Bemerkung, "\n", 1), changed_summary=bBemerkung
    WHERE summary IS NULL;

    UPDATE perstermin  SET Bemerkung=TRIM(LEADING "\n" FROM TRIM(LEADING summary FROM Bemerkung))
    WHERE summary IS NOT NULL;

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Update calculateaccordingexpenditure for X4
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_13_14_save_calc_exp_entries_from_date;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_13_14_save_calc_exp_entries_from_date()
save_calc_exp_entries_from_datelbl:BEGIN
    DECLARE item_id INT;
    DECLARE item_project_id INT;
    DECLARE item_staff_id INT;
    DECLARE item_is_deducted INT;
    DECLARE item_is_deducted_woa INT;
    DECLARE item_deducted_day DATETIME;
    DECLARE item_deducted_day_woa DATETIME;
    DECLARE item_calcexp_id INT;
    
    -- Prevent execution, if calculateaccordingexpenditure already has entries
    IF ( (SELECT COUNT(*) FROM calculateaccordingexpenditure)>0 ) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info='ERROR No migration necessary - save_calc_exp_entries_from_date';
        LEAVE save_calc_exp_entries_from_datelbl;
    END IF;
    
    -- Migration of TIMES Table BOTH Project and WOA --
    BEGIN
        DECLARE times_done INT;
        DECLARE times_curs CURSOR FOR (
            SELECT id, project_id, is_deducted, is_deducted_woa, deducted_day, deducted_day_woa FROM times
            WHERE is_deducted=1 AND is_deducted_woa=1 ORDER BY deducted_day ASC
        );
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET times_done = 1;
        
        SET times_done = 0;
        SET item_calcexp_id = NULL;
        SET item_id = NULL;
        SET item_project_id = NULL;
        SET item_is_deducted = NULL;
        SET item_is_deducted_woa = NULL;
        SET item_deducted_day = NULL;
        SET item_deducted_day_woa = NULL;
        
        OPEN times_curs;
        REPEAT
            FETCH times_curs INTO item_id, item_project_id, item_is_deducted, item_is_deducted_woa, item_deducted_day, item_deducted_day_woa;
            
            IF (item_id IS NOT NULL AND (item_deducted_day IS NOT NULL OR item_deducted_day_woa IS NOT NULL)) THEN
                IF ( (SELECT count(*) FROM calculateaccordingexpenditure WHERE project_id=item_project_id AND date=item_deducted_day) <= 0 ) THEN 
                    INSERT INTO calculateaccordingexpenditure(id, project_id, date, is_project, is_woa)
                    VALUES(default, item_project_id, item_deducted_day, item_is_deducted, item_is_deducted_woa);
                    
                    SET item_calcexp_id = (SELECT LAST_INSERT_ID());
                ELSE
                    SET item_calcexp_id = (SELECT id FROM calculateaccordingexpenditure WHERE project_id=item_project_id AND date=item_deducted_day);
                END IF;
            
                IF (item_deducted_day IS NOT NULL) THEN
                    UPDATE times SET calcexp_id=item_calcexp_id WHERE id=item_id;
                END IF;
                IF (item_deducted_day_woa IS NOT NULL) THEN
                    UPDATE times SET calcexp_id_woa=item_calcexp_id WHERE id=item_id;
                END IF; 
            END IF;
        UNTIL times_done END REPEAT;
    END;
    
    -- Migration of TIMES Table ONLY Project --
    BEGIN
        DECLARE times_project_done INT;
        DECLARE times_project_curs CURSOR FOR (
            SELECT id, project_id, is_deducted, deducted_day FROM times
            WHERE is_deducted=1 AND is_deducted_woa=0 ORDER BY deducted_day ASC
        );
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET times_project_done = 1;
        
        SET times_project_done = 0;
        SET item_calcexp_id = NULL;
        SET item_id = NULL;
        SET item_project_id = NULL;
        SET item_is_deducted = NULL;
        SET item_deducted_day = NULL;
        
        OPEN times_project_curs;
        REPEAT
            FETCH times_project_curs INTO item_id, item_project_id, item_is_deducted, item_deducted_day;
	    
            IF (item_id IS NOT NULL AND item_deducted_day IS NOT NULL) THEN
                IF ( (SELECT count(*) FROM calculateaccordingexpenditure WHERE project_id=item_project_id AND date=item_deducted_day AND (is_project=1 OR is_woa=1)) <= 0 ) THEN 
                    INSERT INTO calculateaccordingexpenditure(id, project_id, date, is_project, is_woa)
                    VALUES(default, item_project_id, item_deducted_day, item_is_deducted, 0);
		    		
                    SET item_calcexp_id = (SELECT LAST_INSERT_ID());
                ELSE
                    SET item_calcexp_id = (SELECT id FROM calculateaccordingexpenditure WHERE project_id=item_project_id AND date=item_deducted_day AND (is_project=1 OR is_woa=1));
                    UPDATE calculateaccordingexpenditure SET is_project=1 WHERE id=item_calcexp_id;
                END IF;
                
                UPDATE times SET calcexp_id=item_calcexp_id WHERE id=item_id;
            END IF;
        UNTIL times_project_done END REPEAT;
    END;
    
    -- Migration of TIMES Table ONLY WOA --
    BEGIN
        DECLARE times_woa_done INT;
        DECLARE times_woa_curs CURSOR FOR (
            SELECT id, project_id, is_deducted_woa, deducted_day_woa FROM times
            WHERE is_deducted=0 AND is_deducted_woa=1 ORDER BY deducted_day_woa ASC
        );
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET times_woa_done = 1;
        
        SET times_woa_done = 0;
        SET item_calcexp_id = NULL;
        SET item_id = NULL;
        SET item_project_id = NULL;
        SET item_is_deducted_woa = NULL;
        SET item_deducted_day_woa = NULL;
        
        OPEN times_woa_curs;
        REPEAT
            FETCH times_woa_curs INTO item_id, item_project_id, item_is_deducted_woa, item_deducted_day_woa;
            
            IF (item_id IS NOT NULL AND item_deducted_day_woa IS NOT NULL) THEN
                IF ( (SELECT count(*) FROM calculateaccordingexpenditure WHERE project_id=item_project_id AND date=item_deducted_day_woa AND (is_project=1 OR is_woa=1)) <= 0 ) THEN 
                    INSERT INTO calculateaccordingexpenditure(id, project_id, date, is_project, is_woa)
                    VALUES(default, item_project_id, item_deducted_day_woa, 0, item_is_deducted_woa);
                    
                    SET item_calcexp_id = (SELECT LAST_INSERT_ID());
                ELSE
                    SET item_calcexp_id = (SELECT id FROM calculateaccordingexpenditure WHERE project_id=item_project_id AND date=item_deducted_day_woa AND (is_project=1 OR is_woa=1));
                    UPDATE calculateaccordingexpenditure SET is_woa=1 WHERE id=item_calcexp_id;
                END IF;
                
                UPDATE times SET calcexp_id_woa=item_calcexp_id WHERE id=item_id;
            END IF;
        UNTIL times_woa_done END REPEAT;
    END;
    
    -- Migration of TIMES Table (STAFF) --
    BEGIN
        DECLARE times_staff_done INT;
        DECLARE times_staff_curs CURSOR FOR (
            SELECT id, staff_id, deducted_day_staff FROM times 
            WHERE is_deducted_staff=1 ORDER BY deducted_day_staff ASC
        );
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET times_staff_done = 1;
        
        SET times_staff_done = 0;
        SET item_calcexp_id = NULL;
        SET item_id = NULL;
        SET item_staff_id = NULL;
        SET item_deducted_day = NULL;
        
        OPEN times_staff_curs;
        REPEAT
            FETCH times_staff_curs INTO item_id, item_staff_id, item_deducted_day;
            
            IF (item_id IS NOT NULL AND item_deducted_day IS NOT NULL) THEN
                IF ( (SELECT count(*) FROM calculateaccordingexpenditure WHERE staff_id=item_staff_id AND date=item_deducted_day) <= 0 ) THEN 
                    INSERT INTO calculateaccordingexpenditure(id, staff_id, date, is_project, is_woa, is_staff)
                    VALUES(default, item_staff_id, item_deducted_day, 0, 0, 1);
                    
                    SET item_calcexp_id = (SELECT LAST_INSERT_ID());
                ELSE
                    SET item_calcexp_id = (SELECT id FROM calculateaccordingexpenditure WHERE staff_id=item_staff_id AND date=item_deducted_day);
                END IF;
                
                UPDATE times SET calcexp_id_staff=item_calcexp_id WHERE id=item_id;
            END IF;
        UNTIL times_staff_done END REPEAT;
    END;
    
    -- Migration of EXTRAS Table --
    BEGIN
        DECLARE extras_done INT;
        DECLARE extras_curs CURSOR FOR (
            SELECT id, project_id, deducted_day FROM extras 
            WHERE is_deducted=1 ORDER BY deducted_day ASC
        );
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET extras_done = 1;
        
        SET extras_done = 0;
        SET item_calcexp_id = NULL;
        SET item_id = NULL;
        SET item_project_id = NULL;
        SET item_deducted_day = NULL;
        
        OPEN extras_curs;
        REPEAT
            FETCH extras_curs INTO item_id, item_project_id, item_deducted_day;
            
            IF (item_id IS NOT NULL AND item_deducted_day IS NOT NULL) THEN
                IF ( (SELECT count(*) FROM calculateaccordingexpenditure WHERE project_id=item_project_id AND date=item_deducted_day AND (is_project=1 OR is_woa=1)) <= 0 ) THEN 
                    INSERT INTO calculateaccordingexpenditure(id, project_id, date)
                    VALUES(default, item_project_id, item_deducted_day);
                    
                    SET item_calcexp_id = (SELECT LAST_INSERT_ID());
                ELSE
                    SET item_calcexp_id = (SELECT id FROM calculateaccordingexpenditure WHERE project_id=item_project_id AND date=item_deducted_day AND (is_project=1 OR is_woa=1));
                END IF;
                
                UPDATE extras SET calcexp_id=item_calcexp_id WHERE id=item_id;
            END IF;
        UNTIL extras_done END REPEAT;
    END;
    
    -- Migration of TRAVELS Table --
    BEGIN
        DECLARE travels_done INT;
        DECLARE travels_curs CURSOR FOR (
            SELECT id, project_id, deducted_day FROM travels 
            WHERE is_deducted=1 ORDER BY deducted_day ASC
        );
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET travels_done = 1;
        
        SET travels_done = 0;
        SET item_calcexp_id = NULL;
        SET item_id = NULL;
        SET item_project_id = NULL;
        SET item_deducted_day = NULL;
        
        OPEN travels_curs;
        REPEAT
            FETCH travels_curs INTO item_id, item_project_id, item_deducted_day;
            
            IF (item_id IS NOT NULL AND item_deducted_day IS NOT NULL) THEN
                IF ( (SELECT count(*) FROM calculateaccordingexpenditure WHERE project_id=item_project_id AND date=item_deducted_day AND (is_project=1 OR is_woa=1)) <= 0 ) THEN 
                    INSERT INTO calculateaccordingexpenditure(id, project_id, date)
                    VALUES(default, item_project_id, item_deducted_day);
                    
                    SET item_calcexp_id = (SELECT LAST_INSERT_ID());
                ELSE
                    SET item_calcexp_id = (SELECT id FROM calculateaccordingexpenditure WHERE project_id=item_project_id AND date=item_deducted_day AND (is_project=1 OR is_woa=1));
                END IF;
                
                UPDATE travels SET calcexp_id=item_calcexp_id WHERE id=item_id;
            END IF;
        UNTIL travels_done END REPEAT;
    END;
    
    -- Migration of EXTERNALEXPENSES Table --
    BEGIN
        DECLARE externalexpenses_done INT;
        DECLARE externalexpenses_curs CURSOR FOR (
            SELECT id, project_id, deducted_day FROM externalexpenses 
            WHERE is_deducted=1 ORDER BY deducted_day ASC
        );
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET externalexpenses_done = 1;
        
        SET externalexpenses_done = 0;
        SET item_calcexp_id = NULL;
        SET item_id = NULL;
        SET item_project_id = NULL;
        SET item_deducted_day = NULL;
        
        OPEN externalexpenses_curs;
        REPEAT
            FETCH externalexpenses_curs INTO item_id, item_project_id, item_deducted_day;
            
            IF (item_id IS NOT NULL AND item_deducted_day IS NOT NULL) THEN
                IF ( (SELECT count(*) FROM calculateaccordingexpenditure WHERE project_id=item_project_id AND date=item_deducted_day AND (is_project=1 OR is_woa=1)) <= 0 ) THEN 
                    INSERT INTO calculateaccordingexpenditure(id, project_id, date)
                    VALUES(default, item_project_id, item_deducted_day);
                    
                    SET item_calcexp_id = (SELECT LAST_INSERT_ID());
                ELSE
                    SET item_calcexp_id = (SELECT id FROM calculateaccordingexpenditure WHERE project_id=item_project_id AND date=item_deducted_day AND (is_project=1 OR is_woa=1));
                END IF;
                
                UPDATE externalexpenses SET calcexp_id=item_calcexp_id WHERE id=item_id;
            END IF;
        UNTIL externalexpenses_done END REPEAT;
    END;
END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Update calculateaccordingexpenditure for X4
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_13_14_reset_caldav_rights;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_13_14_reset_caldav_rights()
reset_caldav_rightslbl:BEGIN
    UPDATE personen SET ModSecurity24=3 WHERE ModSecurity24<3;
END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Update counters primary key
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_update_counters_pk;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_update_counters_pk()
update_counters_pklbl:BEGIN

    ALTER TABLE `update_counters` 
    ADD PRIMARY KEY `typepk` (`type`),
    DROP INDEX `type`;

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Update change_days_past field
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_update_change_days_past;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_update_change_days_past()
update_counters_pklbl:BEGIN

    UPDATE personen SET EditHowManyDays = -1 WHERE EditHowManyDays = 0;

END $$
DELIMITER ;
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- X5 cleanup
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
DROP PROCEDURE IF EXISTS us_migrate_14_15_reset_themes;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_14_15_reset_themes()
us_migrate_14_15_reset_themes:BEGIN

    UPDATE settingsuser SET SettingValue='"Open Sans",Arial,Helvetica,sans-serif' WHERE SettingType='webs_font';
    UPDATE settingsuser SET SettingValue='2' WHERE SettingType='webs_menustyle';
    UPDATE settingsuser SET SettingValue='9.5' WHERE SettingType='webs_fontsize';
    UPDATE settingsuser SET SettingValue='9' WHERE SettingType='webs_fontsizemobile';
    UPDATE settingsuser SET SettingValue='#33332F' WHERE SettingType='webs_colourfont';
    UPDATE settingsuser SET SettingValue='#0b74a1' WHERE SettingType='webs_colourblue';
    UPDATE settingsuser SET SettingValue='#bf1c1c' WHERE SettingType='webs_colourred';
    UPDATE settingsuser SET SettingValue='#ffffff' WHERE SettingType='webs_colourcontent';
    UPDATE settingsuser SET SettingValue='#f9f9f9' WHERE SettingType='webs_colourside';
    UPDATE settingsuser SET SettingValue='#fcfcfc' WHERE SettingType='webs_colourdialog';
    UPDATE settingsuser SET SettingValue='#f0f0f0' WHERE SettingType='webs_colourledger';
    UPDATE settingsuser SET SettingValue='#fefefe' WHERE SettingType='webs_colourbg';
    UPDATE settingsuser SET SettingValue='#e0e0e0' WHERE SettingType='webs_colourborder';
    UPDATE settingsuser SET SettingValue='#469346' WHERE SettingType='webs_calendarstate30';
    UPDATE settingsuser SET SettingValue='#56b256' WHERE SettingType='webs_calendarstate40';
    UPDATE settingsuser SET SettingValue='#4d92b5' WHERE SettingType='webs_calendarstate50';
    UPDATE settingsuser SET SettingValue='#a34646' WHERE SettingType='webs_calendarstate60';
    UPDATE settingsuser SET SettingValue='#d13737' WHERE SettingType='webs_calendarstate70';
    UPDATE settingsuser SET SettingValue='#bfbf4c' WHERE SettingType='webs_calendarother';
    UPDATE settingsuser SET SettingValue='#ffffff' WHERE SettingType='webs_calendarfont';
    UPDATE settingsuser SET SettingValue=(SettingValue+1) WHERE SettingType='theme_rev';

END $$
DELIMITER ;

-- EOC
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Migration router
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

DROP PROCEDURE IF EXISTS us_migrate_11_12;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_11_12(
    IN step VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
us_migrate_11_12lbl:BEGIN
    IF ( SELECT COUNT(*) FROM `01migrate_11_12_steps` WHERE stepname=step) THEN 
        -- INSERT info
        INSERT INTO `01migrate_11_12` SET elem='start', info=CONCAT('No migration necessary - ', step);
        LEAVE us_migrate_11_12lbl;
    END IF;

    -- INSERT info
    INSERT INTO `01migrate_11_12` SET elem='start', info=CONCAT('Starting migration - ', step);
    INSERT INTO `01migrate_11_12_steps` SET stepname=step; 

    IF @debug THEN
        select now() AS 'THE_START_TIME_____', CONCAT('Start ', step) AS 'COMMENT';
    END IF;
    
    CASE step
        WHEN 'prepare_old_views' THEN
            -- CALL Prepare old views
            IF @debug THEN
                select now() AS 'THE_START_TIME_____', 'Start migration <==========' AS 'COMMENT';
            END IF;

            CALL us_migrate_11_12_prepare_old_views();

        WHEN 'improve_todo' THEN
            -- CALL Improve todo
            CALL update_improve_todo();

        WHEN 'migrate_wa2wpt' THEN
            -- CALL INSERT work area to work packages tags
            CALL us_migrate_11_12_migrate_wa2wpt();

        WHEN 'tables' THEN
            -- CALL Migrate views to tables
            CALL us_migrate_11_12_migrate_views_to_tables();

        WHEN 'repair_table_structure' THEN
            -- CALL Migrate views to tables
            CALL us_migrate_11_12_repair_table_structure();

        WHEN 'work_areas_categories' THEN
            -- CALL Create presets for all work_areas_categories
            CALL us_migrate_11_12_work_areas_categories();

        WHEN 'projects' THEN
            -- CALL Create work_packages for project and change all work areas to work packages
            CALL us_migrate_11_12_projects();

        WHEN 'projects_history_prepare' THEN
            -- CALL Create prepare work package history for projects
            CALL us_migrate_11_12_projects_history_prepare();

        WHEN 'projects_history' THEN
            -- CALL Create work package history for projects
            CALL us_migrate_11_12_projects_history();

        WHEN 'areas_to_packages' THEN
            -- CALL Migrate work area values to work packages of the data tables
            CALL us_migrate_11_12_areas_to_packages();

        WHEN 'migrate_fee_area_tags' THEN
            -- CALL Migrate fee area tags to work package tags
            CALL us_migrate_fee_area_tags();

        WHEN 'migrate_translation' THEN
            -- CALL Migrate work package translation
            CALL us_migrate_translation();

        WHEN 'update_wp_status' THEN
            -- CALL Update work packages status
            CALL update_wp_status();

        WHEN 'update_wp_add_one_day' THEN
            -- CALL Update work packages dates
            CALL update_wp_add_one_day();

        WHEN 'update_cost_centres' THEN
            -- CALL Update work packages cost centres for 12.6
            CALL update_cost_centres();

        WHEN 'move_fee_work_package' THEN
            -- CALL Update move fee work package for 12.6
            CALL move_fee_work_package();

        WHEN 'update_alloc_with_payments_fees' THEN
            -- CALL Update move fee work package from the payments table for 12.6
            CALL update_alloc_with_payments_fees();

        WHEN 'update_lut_fee_areas_offer' THEN
            -- CALL Update offers to new format with more features for X3
            CALL update_lut_fee_areas_offer();

        WHEN 'migrate_drawings_inbox_to_drawings' THEN
            -- CALL Migrate drawings inbox to drawings X3
            CALL migrate_drawings_inbox_to_drawings();

        WHEN 'increase_rightblockwidth' THEN
            -- Increase rightblockwidth by 4 for X3
            UPDATE settingsuser SET SettingValue=SettingValue+4 WHERE SettingType='webs_rightblockwidth';

        WHEN 'set_new_default_font' THEN
            -- Set new default font
            UPDATE settingsuser SET SettingValue='"Open Sans", sans-serif' WHERE SettingType='webs_font' AND SettingValue='Arial, Helvetica, sans-serif';

        WHEN 'table_lut_company_proj' THEN
            -- CALL Migrate to lut_company_proj
            CALL us_migrate_12_13_lut_company_proj();

        WHEN 'table_lut_correspondence_addresses' THEN
            -- CALL Migrate to lut_correspondence_addresses
            CALL us_migrate_12_13_lut_correspondence_addresses();

        WHEN 'improve_correspondence' THEN
            -- CALL Improve correspondence
            CALL us_migrate_12_13_improve_correspondence();

        WHEN 'migrate_timelog_to_user' THEN
            -- CALL Migrate time protocol to user option for X3
            CALL us_migrate_12_13_migrate_timelog_to_user();

        WHEN 'migrate_fee_multipliers_from_system' THEN
            -- CALL Migrate fee_multipliers from system table to fee_multipliers table for X3
            CALL us_migrate_12_13_fee_multipliers_from_system();

        WHEN 'update_cost_centres_cleanup' THEN
            -- CALL Update work packages cost centres cleanup for 12.6
            CALL update_cost_centres_cleanup();

        WHEN 'add_staff_coste_centre_times_travles_extras' THEN
            -- CALL ADD staff_cost_centre for X3
            CALL us_migrate_12_13_staff_cost_centre_times_travles_extras();

        WHEN 'update_lut_staff_cost_centre' THEN
            -- CALL Update lut_staff_cost_centre for X3
            CALL us_migrate_12_13_lut_staff_cost_centre();

        WHEN 'update_lut_staff_gross_hourly_wage' THEN
            -- CALL Update lut_staff_gross_hourly_wage for X3
            CALL us_migrate_12_13_lut_staff_gross_hourly_wage();

        WHEN 'update_split_url_location' THEN
            -- CALL Update split url and location for X4
            CALL us_migrate_13_14_update_split_url_location();

        WHEN 'update_split_summary_comment' THEN
            -- CALL Update split summary from first row of comment for X4
            CALL us_migrate_13_14_update_split_summary_comment();
        
        WHEN 'add_id_to_calcexp_tables' THEN
            -- CALL Add fields for multiple calculate according to expenditures for one day for X4
            CALL us_migrate_12_13_add_id_to_calcexp_tables();

        WHEN 'save_calc_exp_entries_from_date' THEN
            -- CALL Allow multiple calculate according to expenditures for one day for X4
            CALL us_migrate_13_14_save_calc_exp_entries_from_date();

        WHEN 'reset_caldav_rights' THEN
            -- CALL CalDAV max right staff as start value X4
            CALL us_migrate_13_14_reset_caldav_rights();

        WHEN 'update_counters_pk' THEN
            -- CALL Update counters PK
            CALL us_migrate_update_counters_pk();

        WHEN 'update_change_days_past' THEN
            -- CALL Update change_days_past field
            CALL us_migrate_update_change_days_past();

        WHEN 'reset_themes' THEN
            -- CALL Reset X4 theme settings for all users to be compatible with X5 theme 
            CALL us_migrate_14_15_reset_themes();            

        WHEN 'cleanup' THEN
            -- CALL Cleanup, without any structure changes
            CALL us_migrate_11_12_cleanup();

            IF @debug THEN
                select now() AS 'THE_START_TIME_____', 'End migration <==========' AS 'COMMENT';
            END IF;

    END CASE;

    IF @debug THEN
        select now() AS 'THE_START_TIME_____', CONCAT('End ', step) AS 'COMMENT';
    END IF;

END $$
DELIMITER ;
-- EOC




-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Call migration
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------

-- USC X2 Update - Erstelle Log-Tabelle.
CALL us_create_01migrate_11_12();
-- EOC

-- USC X2 Update - Erstelle Views.
CALL us_migrate_11_12('prepare_old_views');
-- EOC

-- USC X1 Improve todo
CALL us_migrate_11_12('improve_todo');
-- EOC

-- USC X2 Update - Migrate work areas to work package tags.
CALL us_migrate_11_12('migrate_wa2wpt');
-- EOC

-- USC X2 Update - Migrate views to tables.
CALL us_migrate_11_12('tables');
-- EOC

-- USC X2 Update - Repair table structure for tables created from views.
CALL us_migrate_11_12('repair_table_structure');
-- EOC

-- USC X2 Update - Create presets for all work_areas_categories.
CALL us_migrate_11_12('work_areas_categories');
-- EOC

-- USC X2 Update - Create work packages for projects and change all work areas to work packages.
CALL us_migrate_11_12('projects');
-- EOC

-- USC X2 Update - Create work package history for projects - prepare
CALL us_migrate_11_12('projects_history_prepare');
-- EOC

-- USC X2 Update - Create work package history for projects
CALL us_migrate_11_12('projects_history');
-- EOC

-- USC X2 Update - Migrate work area values to work packages for all data tables.
CALL us_migrate_11_12('areas_to_packages');
-- EOC

-- USC X2 Update - Migrate fee area tags to work package tags
CALL us_migrate_11_12('migrate_fee_area_tags');
-- EOC

-- USC X2 Update - Migrate work package translation.
CALL us_migrate_11_12('migrate_translation');
-- EOC

-- USC X2 Update - Update work packages status
CALL us_migrate_11_12('update_wp_status');
-- EOC

-- USC X2 Update - Update work packages dates
CALL us_migrate_11_12('update_wp_add_one_day');
-- EOC

-- USC X2 Update - Update work packages cost centres for 12.6
CALL us_migrate_11_12('update_cost_centres');
-- EOC

-- USC X2 Update - Update work packages cost centres for 12.6
CALL us_migrate_11_12('move_fee_work_package');
-- EOC

-- USC X2 Update - Update work packages cost centres for 12.6
CALL us_migrate_11_12('update_alloc_with_payments_fees');
-- EOC

-- USC X3 Update - Update offers to new format
CALL us_migrate_11_12('update_lut_fee_areas_offer');
-- EOC

-- USC X3 Update - Move drawings inbox to drawings
CALL us_migrate_11_12('migrate_drawings_inbox_to_drawings');
-- EOC

-- USC X3 Increase rightblockwidth by 4
CALL us_migrate_11_12('increase_rightblockwidth');
-- EOC

-- USC X3 Set new default font
CALL us_migrate_11_12('set_new_default_font');
-- EOC

-- USC X3 Migrate to lut_company_proj
CALL us_migrate_11_12('table_lut_company_proj');
-- EOC

-- USC X3 Migrate to lut_correspondence_addresses
CALL us_migrate_11_12('table_lut_correspondence_addresses');
-- EOC

-- USC X3 Improve correspondence
CALL us_migrate_11_12('improve_correspondence');
-- EOC

-- USC X3 Migrate time protocol to user option
CALL us_migrate_11_12('migrate_timelog_to_user');
-- EOC

-- USC X3 Migrate fee_multipliers from system table to fee_multipliers table
CALL us_migrate_11_12('migrate_fee_multipliers_from_system');
-- EOC

-- USC X2 Remove old Kostenstelle field
CALL us_migrate_11_12('update_cost_centres_cleanup');
-- EOC

-- USC X2 Add staff_cost_centre for X3
CALL us_migrate_11_12('add_staff_coste_centre_times_travles_extras');
-- EOC

-- USC X3 Update lut_staff_cost_centre
CALL us_migrate_11_12('update_lut_staff_cost_centre');
-- EOC

-- USC X3 Update lut_staff_gross_hourly_wage
CALL us_migrate_11_12('update_lut_staff_gross_hourly_wage');
-- EOC

-- USC X4 Update split_url_location
CALL us_migrate_11_12('update_split_url_location');
-- EOC

-- USC X Update split summary from first row of comment for X4
CALL us_migrate_11_12('update_split_summary_comment');
-- EOC

-- USC X4 Prepare tables for calcexp restructuring
CALL us_migrate_11_12('add_id_to_calcexp_tables');
-- EOC

-- USC X4 Update tables for calcexp restructuring
CALL us_migrate_11_12('save_calc_exp_entries_from_date');
-- EOC

-- USC X4 CalDAV max right staff as start value
CALL us_migrate_11_12('reset_caldav_rights');
-- EOC

-- USC X4 Update counters PK
CALL us_migrate_11_12('update_counters_pk');
-- EOC

-- USC X4 Update change_days_past field
CALL us_migrate_11_12('update_change_days_past');
-- EOC

-- USC X5 Reset X4 themes
CALL us_migrate_11_12('reset_themes');
-- EOC

-- USC X Update - Cleanup.
CALL us_migrate_11_12('cleanup');
-- EOC
-- USC Entferne alte Views.

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Remove old views

DROP VIEW IF EXISTS `fee_areas`;
-- EOC
DROP VIEW IF EXISTS `work_areas`;
-- EOC
DROP VIEW IF EXISTS `lut_work_areas_work_areas_categories`;
-- EOC
DROP VIEW IF EXISTS `lut_fee_areas_proj`;
-- EOC
DROP VIEW IF EXISTS `lut_fee_areas_proj_history`;
-- EOC
DROP VIEW IF EXISTS `budget_plan`;
-- EOC
DROP VIEW IF EXISTS `budget_plan_history`;
-- EOC
DROP VIEW IF EXISTS `completion_level`;
-- EOC
DROP VIEW IF EXISTS `completion_level_history`;
-- EOC

-- Java clients - OLD
DROP VIEW IF EXISTS `staff_hashes`;
-- EOC

DROP VIEW IF EXISTS `report_times_from_to`;
-- EOC

DROP VIEW IF EXISTS `cost_centres_report_info`;
-- EOC

-- Old views
DROP VIEW IF EXISTS `budget_plan_extended_data`;
-- EOC
DROP VIEW IF EXISTS `report_budget_plan_history`;
-- EOC
DROP VIEW IF EXISTS `report_completion_level_fee`;
-- EOC
DROP VIEW IF EXISTS `report_fee_areas_project_allocation`;
-- EOC
DROP VIEW IF EXISTS `report_fee_areas_project_allocation_history`;
-- EOC
DROP VIEW IF EXISTS `report_projects_fee_areas`;
-- EOC

DROP VIEW IF EXISTS `completion_level_extended_data`;
-- EOC
DROP VIEW IF EXISTS `report_completion_level`;
-- EOC
DROP VIEW IF EXISTS `report_completion_level_bbl1`;
-- EOC
DROP VIEW IF EXISTS `report_completion_level_bbl2`;
-- EOC
DROP VIEW IF EXISTS `report_completion_level_current`;
-- EOC
DROP VIEW IF EXISTS `report_completion_level_fee`;
-- EOC
DROP VIEW IF EXISTS `report_completion_level_only`;
-- EOC

DROP VIEW IF EXISTS `report_cost_centres_info`;
-- EOC

DROP VIEW IF EXISTS `report_externalexpenses`;
-- EOC
DROP VIEW IF EXISTS `report_externalexpenses_planned`;
-- EOC

DROP VIEW IF EXISTS `report_extras`;
-- EOC
DROP VIEW IF EXISTS `report_times`;
-- EOC
DROP VIEW IF EXISTS `report_travels`;
-- EOC

DROP VIEW IF EXISTS `company_installation_merged`;
-- EOC

-- Very old views
DROP VIEW IF EXISTS `report_completion_level_history`;
-- EOC

-- Old locking. Now only lut_working_user is active
DROP VIEW IF EXISTS `locking`;
-- EOC
DROP TABLE IF EXISTS `locking`;
-- EOC
DROP TABLE IF EXISTS `locking_info`;
-- EOC
DROP TABLE IF EXISTS `tbllocking`;
-- EOC
DROP VIEW IF EXISTS `locking_info`;
-- EOC
-- Remove old
DROP TABLE IF EXISTS `lang_address_groups`;
-- EOC


-- Old pre X4
DROP TABLE IF EXISTS `ana_proj_rechnung`;
-- EOC
DROP TABLE IF EXISTS `aufschlagkosten`;
-- EOC
DROP TABLE IF EXISTS `eingabe`;
-- EOC
DROP TABLE IF EXISTS `emailout`;
-- EOC
DROP TABLE IF EXISTS `extra`;
-- EOC
DROP TABLE IF EXISTS `hon_archiv`;
-- EOC
DROP TABLE IF EXISTS `kalkprostunden`;
-- EOC
DROP TABLE IF EXISTS `kennwerte`;
-- EOC
DROP TABLE IF EXISTS `lastdata`;
-- EOC
DROP TABLE IF EXISTS `layout`;
-- EOC
DROP TABLE IF EXISTS `licenseinuse`;
-- EOC
DROP TABLE IF EXISTS `lut_hon_archiv`;
-- EOC
DROP TABLE IF EXISTS `lut_honverw_extkost`;
-- EOC
DROP TABLE IF EXISTS `lut_out_us`;
-- EOC
DROP TABLE IF EXISTS `lut_pers_brutto`;
-- EOC
DROP TABLE IF EXISTS `lut_pers_grp_temp`;
-- EOC
DROP TABLE IF EXISTS `lut_termin_ressource`;
-- EOC
DROP TABLE IF EXISTS `mitarbeiterkosten`;
-- EOC
DROP TABLE IF EXISTS `outsync`;
-- EOC
DROP TABLE IF EXISTS `outsyncadr`;
-- EOC
DROP TABLE IF EXISTS `prognose`;
-- EOC
DROP TABLE IF EXISTS `progtemp`;
-- EOC
DROP TABLE IF EXISTS `provorgang`;
-- EOC
DROP TABLE IF EXISTS `reise`;
-- EOC
DROP TABLE IF EXISTS `ressources`;
-- EOC
DROP TABLE IF EXISTS `sicherheit`;
-- EOC
DROP TABLE IF EXISTS `sollab_history_psp`;
-- EOC
DROP TABLE IF EXISTS `sollab_psp`;
-- EOC
DROP TABLE IF EXISTS `sollstunden`;
-- EOC
DROP TABLE IF EXISTS `stueckrechte`;
-- EOC
-- @todo Remove later (Uralte Sonderpgrm.)
-- DROP TABLE IF EXISTS `t_union`;
-- EOC
DROP TABLE IF EXISTS `tagessollstdtemp`;
-- EOC
DROP TABLE IF EXISTS `terminfiltersatz`;
-- EOC
DROP TABLE IF EXISTS `useraktiv`;
-- EOC
DROP TABLE IF EXISTS `warnschwelle`;
-- EOC

-- Old meetingmanager
DROP TABLE IF EXISTS `meetingmanager_subjects`;
-- EOC
DROP TABLE IF EXISTS `meetingmanager_appointments`;
-- EOC
DROP TABLE IF EXISTS `meetingmanager_tasks`;
-- EOC
DROP TABLE IF EXISTS `lut_meetingmanager_tasks_status`;
-- EOC
DROP TABLE IF EXISTS `lut_meetingmanager_tasks_appointments`;
-- EOC
DROP TABLE IF EXISTS `lut_meetingmanager_appointments_addresses`;
-- EOC
DROP TABLE IF EXISTS `lut_meetingmanager_tasks_addresses`;
-- EOC

-- Old looop
DROP TABLE IF EXISTS `lut_looop_calendar`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_contacts`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_countries`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_documents`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_km`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_notes`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_projects`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_protocol`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_ressources`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_termin_ressource`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_time`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_todo`;
-- EOC
DROP TABLE IF EXISTS `lut_looop_worker`;
-- EOC

DROP TABLE IF EXISTS `company_installation`;
-- EOC


-- @todo remove is_deducted, is_deducted_staff, is_deducted_woa from times, extras, travels, externalexpenses
-- USC Erstelle weitere X2 Tabellen - Session.

-- --------------------------------------------------------------------------------------------------
-- To save config.php values
CREATE TABLE IF NOT EXISTS `u10_ci_config` (
    `id` INT NOT NULL AUTO_INCREMENT ,
    `name` VARCHAR(255) NOT NULL ,
    `value` TEXT NOT NULL ,
    PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Add session information table
DROP PROCEDURE IF EXISTS ensure_u10_ci_sessions;
-- EOC
DELIMITER $$
CREATE PROCEDURE ensure_u10_ci_sessions()
BEGIN
    SELECT GetStorageEngine ('MEMORY') INTO @engineInnoDBorMemory;
    DROP TABLE IF EXISTS `u10_ci_sessions`;

    SET @create_table_query = CONCAT(
    'CREATE TABLE `u10_ci_sessions` (',
    '`uniqid` VARCHAR(40) COLLATE utf8mb4_general_ci NULL DEFAULT NULL,',
    '`session_id` VARCHAR(40) COLLATE utf8mb4_general_ci NOT NULL DEFAULT "0",',
    '`old1_session_id` VARCHAR(40) COLLATE utf8mb4_general_ci NULL DEFAULT NULL,',
    '`old2_session_id` VARCHAR(40) COLLATE utf8mb4_general_ci NULL DEFAULT NULL,',
    '`ip_address` VARCHAR(50) COLLATE utf8mb4_general_ci NOT NULL,',
    '`user_agent` VARCHAR(150) COLLATE utf8mb4_general_ci NOT NULL,',
    '`first_activity` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,',
    '`last_activity` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
    '`login_time` DATETIME NULL DEFAULT NULL,',
    '`login_type` BOOLEAN DEFAULT 0,' -- Was webversion'
    '`login_staff_id` INT DEFAULT NULL,', -- Was UserNummer
    '`user_data` VARBINARY(20000) NULL,',
    'PRIMARY KEY (`session_id`)',
    ') ENGINE=', @engineInnoDBorMemory, ' DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;'
    );
    PREPARE stmt FROM @create_table_query;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

    -- FLASHDATA
    DROP TABLE IF EXISTS `u10_ci_session_flashdata`;

    CREATE TABLE `u10_ci_session_flashdata` (
      `uniqid` VARCHAR(40) NOT NULL,
      `name` VARCHAR(55) NOT NULL,
      `value` LONGBLOB NULL,
      PRIMARY KEY (`name`, `uniqid`)
    ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

END $$
DELIMITER ;
-- EOC
CALL ensure_u10_ci_sessions();
-- EOC

CALL change_column('u10_ci_sessions', 'ip_address', 'VARCHAR(50) NOT NULL');
-- EOC

-- Clean flashdata table
DROP PROCEDURE IF EXISTS clean_u10_ci_session_flashdata;
-- EOC
DELIMITER $$
CREATE PROCEDURE clean_u10_ci_session_flashdata()
BEGIN
    DELETE b FROM u10_ci_session_flashdata b LEFT JOIN u10_ci_sessions ses 
        ON ses.uniqid = b.uniqid 
        WHERE ses.uniqid IS NULL;

END $$
DELIMITER ;
-- EOC

-- USC Erstelle weitere X2 Tabellen - Hilfstabellen

-- Clean lut_working_user table
DROP PROCEDURE IF EXISTS clean_u10_ci_session_lut_working_user;
-- EOC
DELIMITER $$
CREATE PROCEDURE clean_u10_ci_session_lut_working_user()
BEGIN
    DELETE FROM lut_working_user WHERE user_id NOT IN (
        SELECT login_staff_id FROM u10_ci_sessions WHERE login_staff_id IS NOT NULL
    );

END $$
DELIMITER ;
-- EOC

-- To update tables - counter
CREATE TABLE IF NOT EXISTS `update_counters` (
    `type` INT NOT NULL,
    `count` BIGINT NOT NULL,
    PRIMARY KEY `typepk` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

ALTER TABLE `update_counters` ENGINE=InnoDB;
-- EOC

-- Insert first
INSERT IGNORE INTO `update_counters` (`type`, `count`) VALUES (1, 1);
-- EOC

-- Create mutex table (Keep as MyISAM to prevent problems with transactions)
DROP TABLE IF EXISTS `u10_mutex`;
-- EOC
-- CREATE TABLE IF NOT EXISTS `u10_mutex`(
--     i INT NOT NULL PRIMARY KEY
-- ) ENGINE=MyISAM CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- INSERT INTO u10_mutex(i) VALUES (0), (1);

CREATE OR REPLACE ALGORITHM = MERGE VIEW `u10_mutex` AS SELECT 0 AS i  FROM dual UNION ALL SELECT 1;
-- EOC

-- USC Erstelle weitere X2 Tabellen - Kalender
-- Create calendar table
DROP TABLE IF EXISTS `u10_calendar`;
-- EOC
CREATE TABLE IF NOT EXISTS `u10_calendar`(
    date DATE,
    PRIMARY KEY ( `date` ),
    datemonth VARCHAR(10) NOT NULL
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC
CALL us_add_to_calendar(SUBDATE(now(), INTERVAL 1 MONTH), ADDDATE(now(), INTERVAL 1 MONTH));
-- EOC

-- USC Erstelle weitere X2 Tabellen - Modifications
-- Add modifications table
CREATE TABLE IF NOT EXISTS `modifications` (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `date` datetime DEFAULT NULL,
  `staff` VARCHAR(255) DEFAULT NULL,
  `staff_id` INT DEFAULT NULL,
  `title` longtext,
  `info` LONGBLOB DEFAULT NULL,
  `isCompressed` TINYINT DEFAULT 0,
  `item_model` VARCHAR(100) DEFAULT NULL,
  `item_title` text,
  `item_id` INT DEFAULT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_change_table_to_innodb('modifications');
-- EOC

CALL us_add_to_table2('modifications', 'staff_id', 'INT DEFAULT NULL AFTER `staff`');
-- EOC
CALL change_column('modifications', 'item_model', 'VARCHAR(100) DEFAULT NULL');
-- EOC
CALL change_column('modifications', 'info', 'LONGBLOB DEFAULT NULL');
-- EOC
CALL us_add_to_table2('modifications', 'isCompressed', 'TINYINT DEFAULT 0' );
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Add ebInterface columns to fees
-- USC Erstelle weitere X2 Tabellen - E-Rechnung
CALL us_add_to_table2('fees', 'e_invoice_json', 'LONGTEXT' );
-- EOC
CALL us_add_to_table2('fees_planned', 'e_invoice_json', 'LONGTEXT' );
-- EOC

CALL convert_old_e_invoice_json_columns();
-- EOC

-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Add fees - fee_areas lut-table
CREATE TABLE IF NOT EXISTS `lut_fee_areas_fee` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `planned_fee_id` INT DEFAULT NULL,
    `fee_id` INT DEFAULT NULL,
    `offer_id` INT NOT NULL,
    `work_package_id` INT NOT NULL,
    `costs` DOUBLE NOT NULL DEFAULT 0,
    `costs_otcurr` DOUBLE NOT NULL DEFAULT 0,
    `quantity` DOUBLE NOT NULL DEFAULT 1,
    `quantity_id` INT DEFAULT NULL,
    `price` DOUBLE DEFAULT 0,
    `supplement` DOUBLE NOT NULL DEFAULT 0,
    `supplement_otcurr` DOUBLE NOT NULL DEFAULT 0,
    `extras` DOUBLE NOT NULL DEFAULT 0,
    `extras_otcurr` DOUBLE NOT NULL DEFAULT 0,
    `rebate` DOUBLE NOT NULL DEFAULT 0,
    `rebate_otcurr` DOUBLE NOT NULL DEFAULT 0,
    `costs_view` DOUBLE NOT NULL DEFAULT 0
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Improve erased
-- USC Erstelle weitere X2 Tabellen - Protokollierung
CALL us_add_to_table2('erased', 'staff_id', 'INT DEFAULT NULL AFTER `Wer`');
-- EOC
CALL us_add_to_table2('erased', 'item_model', 'VARCHAR(100) COLLATE utf8mb4_general_ci DEFAULT NULL AFTER `Was`' );
-- EOC
CALL change_column('erased', 'item_model', 'VARCHAR(100) DEFAULT NULL');
-- EOC
CALL us_add_to_table2('erased', 'item_title', 'text DEFAULT NULL AFTER `item_model`' );
-- EOC
CALL change_column('erased', 'item_title', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC
CALL change_column('erased', 'Was', 'LONGBLOB DEFAULT NULL');
-- EOC
CALL us_add_to_table2('erased', 'item_id', 'INT NULL AFTER `item_title`' );
-- EOC
CALL us_add_to_table2('erased', 'isCompressed', 'TINYINT DEFAULT 0' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add column to rates tables
CALL us_add_to_table2('projektabrma', 'skill_grp_id', 'int DEFAULT NULL' );
-- EOC

CALL us_add_to_table2('projektabrma_zeit', 'name', 'VARCHAR( 200 ) DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('projektabrma_zeit', 'is_times_skill_grp', 'BOOLEAN DEFAULT 0' );
-- EOC

CALL us_add_to_table2('projektabrrk_zeit', 'name', 'VARCHAR( 200 ) DEFAULT NULL' );
-- EOC

CALL us_add_to_table2('projektabrextra_zeit', 'name', 'VARCHAR( 200 ) DEFAULT NULL' );
-- EOC

CALL us_add_to_table2('work_areas_rates_history', 'name', 'VARCHAR( 200 ) DEFAULT NULL' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add web settings and user
CALL us_add_to_table2('zusatz_personen', 'web', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL' );
-- EOC

CALL us_add_to_table2('personen', 'username', 'VARCHAR(80) DEFAULT NULL' );
-- EOC

CALL us_add_to_table2('personen', 'staff_location_id', 'INT NOT NULL DEFAULT 1' );
-- EOC

CALL change_column('personen', 'passwort', 'VARCHAR( 255 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC

CALL us_add_to_table2('personen', 'passwort_mode', 'INT DEFAULT NULL AFTER `passwort`' );
-- EOC

CALL us_add_to_table2('personen', 'login_extras', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL AFTER `passwort`' );
-- EOC

CALL us_add_to_table2('personen', 'secdetail_2', 'SMALLINT DEFAULT 0 AFTER ModSecurity02' );
-- EOC
CALL us_add_to_table2('personen', 'secdetail_3', 'SMALLINT DEFAULT 0 AFTER ModSecurity03' );
-- EOC
CALL us_add_to_table2('personen', 'secdetail_5', 'SMALLINT DEFAULT 0 AFTER ModSecurity05' );
-- EOC
CALL us_add_to_table2('personen', 'secdetail_16', 'SMALLINT DEFAULT 0 AFTER ModSecurity16' );
-- EOC

CALL us_add_to_table2('personen', 'days_warning_no_workinput', 'INT NOT NULL DEFAULT 7 AFTER EditHowManyDays' );
-- EOC
CALL us_add_to_table2('personen', 'days_warning_no_mail_allocation', 'INT NOT NULL DEFAULT 7 AFTER days_warning_no_workinput' );
-- EOC
CALL us_add_to_table2('personen', 'sync_only_category_addresses', 'INT DEFAULT NULL AFTER days_warning_no_mail_allocation' );
-- EOC
CALL us_add_to_table2('personen', 'user_is_management_user', 'TINYINT(1) DEFAULT 0 AFTER ModSecurity50' );
-- EOC
CALL us_add_to_table2('personen', 'user_is_simple_user', 'TINYINT(1) DEFAULT 0 AFTER user_is_management_user' );
-- EOC
CALL us_add_to_table2('personen', 'named_license_changed_date', 'datetime DEFAULT NULL AFTER user_is_simple_user' );
-- EOC
CALL us_add_to_table2('personen', 'user_access_license_changed_date', 'datetime DEFAULT NULL AFTER named_license_changed_date' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add division manager / second project manager to staff and new allow rights
CALL us_add_to_table2('personen', 'is_division_manager', 'TINYINT(1) DEFAULT 0' );
-- EOC
CALL us_add_to_table2('personen', 'division_manager_id', 'INT NULL' );
-- EOC
CALL us_add_to_table2('personen', 'respect_division_manager', 'TINYINT(1) DEFAULT 0' );
-- EOC

CALL us_add_to_table2('personen', 'allow_staff_even_if_not_by_project_manager', 'TINYINT(1) DEFAULT 0' );
-- EOC
CALL us_add_to_table2('personen', 'allow_own_project_if_other_project_manager', 'TINYINT(1) DEFAULT 0' );
-- EOC
CALL us_add_to_table2('personen', 'allow_staff_even_if_not_by_division_manager', 'TINYINT(1) DEFAULT 0' );
-- EOC
CALL us_add_to_table2('personen', 'allow_own_project_if_other_division_manager', 'TINYINT(1) DEFAULT 0' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add company_id to tables
-- USC Erstelle weitere X2 Tabellen - Firmen 
CALL us_add_to_table2('kostenstellen', 'company_id', 'INT NULL AFTER `Bemerkung`' );
-- EOC
CALL us_add_to_table2('kopiekat', 'company_id', 'INT NULL AFTER `KostenEinheit`' );
-- EOC
CALL us_add_to_table2('gruppen', 'company_id', 'INT NULL FIRST' );
-- EOC
CALL us_add_to_table2('uestd', 'company_id', 'INT NULL AFTER `WerHatAusb`' );
-- EOC
CALL us_add_to_table2('uesatz', 'company_id', 'INT NULL AFTER `Drucken`' );
-- EOC
CALL us_add_to_table2('orte', 'company_id', 'INT NULL AFTER `Km`' );
-- EOC
CALL us_add_to_table2('zusatz_personen', 'company_id', 'INT NULL FIRST' );
-- EOC
CALL us_add_to_table2('zeiten_beginnende', 'company_id', 'INT NULL AFTER `ZeitAbzug`' );
-- EOC
CALL us_add_to_table2('settingssystem', 'company_id', 'INT NULL AFTER `SettingValue`' );
-- EOC
CALL us_add_to_table2('arbbeschtxte', 'company_id', 'INT NULL AFTER `OrdnNr`' );
-- EOC
CALL us_add_to_table2('reisekosten', 'company_id', 'INT NULL AFTER `ZeitVonBis`' );
-- EOC
CALL us_add_to_table2('projektabrsaetze', 'company_id', 'INT NULL AFTER `ABSatz`' );
-- EOC
CALL us_add_to_table2('adrkategorien', 'company_id', 'INT NULL AFTER `EditDatum`' );
-- EOC
CALL us_add_to_table2('adrgruppendef', 'company_id', 'INT NULL AFTER `LfdNr_Projekt`' );
-- EOC
CALL us_add_to_table2('planart', 'company_id', 'INT NULL AFTER `LfdNr`' );
-- EOC
CALL us_add_to_table2('plangroessen', 'company_id', 'INT NULL AFTER `LfdNr`' );
-- EOC
CALL us_add_to_table2('postart', 'company_id', 'INT NULL AFTER `LfdNr`' );
-- EOC

-- ADD flag to the cost centre table
CALL us_add_to_table2('kostenstellen', 'use_in_reports', 'TINYINT unsigned NOT NULL DEFAULT 0' );
-- EOC


-- --------------------------------------------------------------------------------------------------
-- Prepare drawings for read from dir
CREATE TABLE IF NOT EXISTS `drawings_autopath_log` (
	`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
	`project_id` INT NOT NULL ,
	`hash` VARCHAR( 100 ) NOT NULL ,
	`change_date` DATETIME NOT NULL ,
	INDEX ( `project_id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Change filename from varchar to longtext
CALL us_drop_index_if_exists('drawings_deleted_log', 'project_id');
-- EOC
CALL change_column('drawings_deleted_log', 'filename', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL');
-- EOC


-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add workinput, HonZus to certain tables
-- USC Erstelle weitere X2 Tabellen - Formulare

CALL us_add_to_table2('formular', 'Arbeitsbereich', 'INT DEFAULT NULL' );
-- EOC

CALL us_add_to_table2('formular', 'HonZus', 'longtext' );
-- EOC

CALL us_add_to_table2('formular', 'add_image', 'LONGBLOB DEFAULT NULL AFTER `HonZus`' );
-- EOC

CALL us_add_to_table2('formular', 'is_valid', 'TINYINT unsigned NOT NULL DEFAULT 1 AFTER `add_image`' );
-- EOC

CALL us_add_to_table2('formular', 'timestamp_file', 'datetime DEFAULT NULL COMMENT \'Timestamp of modification of file\'' );
-- EOC

CALL us_add_to_table2('formular', 'last_autofulltext', 'datetime DEFAULT NULL COMMENT \'Last check for file changes\'' );
-- EOC
CALL us_add_to_table2('formular', 'last_autofulltext_staff_id', 'INT DEFAULT NULL COMMENT \'Last check for file changes started by\'' );
-- EOC

CALL us_add_to_table2('formular', 'last_fulltext_update', 'datetime DEFAULT NULL COMMENT \'Last actual update of fulltext\'' );
-- EOC

CALL us_add_to_table2('formular', 'discount', 'DOUBLE DEFAULT 0' );
-- EOC
CALL us_add_to_table2('formular', 'discount_date', 'datetime DEFAULT NULL' );
-- EOC

CALL us_add_to_table2('formular', 'fee_account_id', 'INT DEFAULT NULL' );
-- EOC

CALL us_add_to_table2('formart', 'special_type', 'VARCHAR(30) DEFAULT \'\' COMMENT \'Special Type\'' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add masterdata quantities table
CREATE TABLE IF NOT EXISTS `quantities` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `name` VARCHAR( 100 ) NOT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC Erstelle weitere X2 Tabellen - Translation.

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_cost_centres` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`cost_centre_id` INT NOT NULL ,
	`name` VARCHAR( 60 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	`remark` VARCHAR(100) NULL,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_cost_centres', 'langs_cost_centres_unique_1', 'UNIQUE', '`cost_centre_id` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_countries` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`country_name_id` VARCHAR( 50 ) NOT NULL ,
	`name` VARCHAR( 50 ) NOT NULL ,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_countries', 'langs_countries_unique_1', 'UNIQUE', '`country_name_id` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_extras_types` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`extras_type_id` INT NOT NULL ,
	`type` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	`unit` VARCHAR( 10 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_extras_types', 'langs_extras_types_unique_1', 'UNIQUE', '`extras_type_id` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_occupation_groups` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`occupation_groups_id` INT NOT NULL ,
	`name` VARCHAR( 30 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	`description` LONGTEXT NULL,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_occupation_groups', 'langs_occupation_groups_unique_1', 'UNIQUE', '`occupation_groups_id` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_travels_types` (
	`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
	`travels_type_id` INT NOT NULL ,
	`type` VARCHAR( 60 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	`unit` VARCHAR( 15 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_travels_types', 'langs_travels_types_unique_1', 'UNIQUE', '`travels_type_id` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_overtime_rates` (
    `id` INT NOT NULL AUTO_INCREMENT ,
    `rate_id` INT NOT NULL ,
    `name` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_overtime_rates', 'langs_overtime_rates_unique_1', 'UNIQUE', '`rate_id` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_fee_multipliers` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `fee_multiplier_id` INT NOT NULL,
    `name` VARCHAR( 30 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `purpose` LONGTEXT NULL,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_fee_multipliers', 'langs_fee_multipliers_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_address_categories` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `address_category_id` INT NOT NULL,
    `name` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `purpose` LONGTEXT NULL,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_address_categories', 'langs_address_categories_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `lang_addresses_addi_def` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `def_id` INT NOT NULL,
    `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('lang_addresses_addi_def', 'lang_addresses_addi_def_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `lang_opentasks_addi_def` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `def_id` INT NOT NULL,
    `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('lang_opentasks_addi_def', 'lang_opentasks_addi_def_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC

-- @todo BIGINT work_package_id
CALL us_add_to_table2('todo', 'work_package_id', 'BIGINT NULL' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `lang_externalexpenses_addi_merged_def` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `def_id` INT NOT NULL,
    `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('lang_externalexpenses_addi_merged_def', 'lang_externalexpenses_addi_merged_def_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `lang_fees_addi_merged_def` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `def_id` INT NOT NULL,
    `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('lang_fees_addi_merged_def', 'lang_fees_addi_merged_def_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_project_phases` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`project_phase_id` VARCHAR( 50 ) NOT NULL ,
	`name` VARCHAR( 50 ) NOT NULL ,
        `purpose` VARCHAR(100) NULL,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC


CALL us_add_constraint_to_table('langs_project_phases', 'langs_project_phases_unique_1', 'UNIQUE', '`project_phase_id` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `lang_projects_addi_def` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `def_id` INT NOT NULL,
    `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('lang_projects_addi_def', 'lang_projects_addi_def_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_project_categories` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`project_categories_id` INT NOT NULL ,
	`name` VARCHAR( 50 ) NOT NULL ,
	`purpose` LONGTEXT NULL,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_project_categories', 'langs_project_categories_unique_1', 'UNIQUE', '`project_categories_id` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `lang_staff_additional_def` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `def_id` INT NOT NULL,
    `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('lang_staff_additional_def', 'lang_staff_additional_def_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_measurements` (
	`id` INT NOT NULL AUTO_INCREMENT,
	`measurements_id` INT NOT NULL,
	`name` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
	PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_measurements', 'langs_measurements_unique_1', 'UNIQUE', '`measurements_id` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `lang_project_participants_addi_def` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `def_id` INT NOT NULL,
    `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('lang_project_participants_addi_def', 'lang_project_participants_addi_def_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `lang_whatiswhere_addi_def` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `def_id` INT NOT NULL,
    `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC


-- Add translation tables
CREATE TABLE IF NOT EXISTS `lang_drawings_addi_def` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `def_id` INT NOT NULL,
    `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_drawing_types` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`type_id` VARCHAR( 50 ) NOT NULL ,
	`name` VARCHAR( 50 ) NOT NULL ,
        `purpose` VARCHAR(100) NULL,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC


CALL us_add_constraint_to_table('langs_drawing_types', 'langs_drawing_types_unique_1', 'UNIQUE', '`type_id` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_dispatch_modes` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`mode_id` VARCHAR( 50 ) NOT NULL ,
	`name` VARCHAR( 50 ) NOT NULL ,
        `purpose` VARCHAR(100) NULL,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC


CALL us_add_constraint_to_table('langs_dispatch_modes', 'langs_dispatch_modes_unique_1', 'UNIQUE', '`mode_id` , `language`' );
-- EOC


-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_quantities` (
	`id` INT NOT NULL AUTO_INCREMENT,
	`quantity_id` INT NOT NULL,
	`name` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	`language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
	PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_quantities', 'langs_quantities_unique_1', 'UNIQUE', '`quantity_id` , `language`' );
-- EOC


-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add to quantities
CALL us_add_to_table2('quantities', 'quantity_code', 'VARCHAR( 10 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL AFTER `name`' );
-- EOC
CALL us_add_to_table2('quantities', 'default_value', 'DOUBLE NOT NULL DEFAULT 1 AFTER `quantity_code`' );
-- EOC
CALL us_add_to_table2('quantities', 'default_price', 'DOUBLE AFTER `default_value`' );
-- EOC
CALL us_add_to_table2('quantities', 'is_calcexp', 'BOOLEAN DEFAULT 0 AFTER `default_price`' );
-- EOC

CALL change_column('quantities', 'default_value', 'DOUBLE DEFAULT NULL');
-- EOC
CALL change_column('quantities', 'default_price', 'DOUBLE DEFAULT NULL');
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add address to companies
CALL us_add_to_table2('firmen', 'address_id', 'INT NULL AFTER `name`' );
-- EOC

-- Add country code
CALL us_add_to_table2('land', 'Kennzeichen', 'VARCHAR(2) AFTER `Bez`');
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add currencies table
-- USC Erstelle weitere X2 Tabellen - Currencies.

CREATE TABLE IF NOT EXISTS `currencies` (
	`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
	`name` VARCHAR( 60 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
	`abbreviation` VARCHAR( 10 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
	UNIQUE KEY ( `abbreviation` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Add currencies_translation table
CREATE TABLE IF NOT EXISTS `currencies_translation` (
	`currency_id_from` INT NOT NULL ,
	`currency_id_to` INT NOT NULL ,
	`exchange_rate` DOUBLE NOT NULL,
        `online` TEXT DEFAULT NULL,
        PRIMARY KEY (`currency_id_from`,`currency_id_to`)
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('currencies_translation', 'online', 'TEXT DEFAULT NULL' );
-- EOC

-- Add currencies support
CALL us_add_to_table2('firmen', 'currency_id', 'INT NULL AFTER `aktiv`' );
-- EOC



-- Add currency code
CALL us_add_to_table2('currencies', 'currency_code', 'VARCHAR(3) AFTER `abbreviation`');
-- EOC

-- Add currencies support
CALL us_add_to_table2('uestd', 'company_price_per_unit', 'DOUBLE NULL AFTER `BruttoSatz`' );
-- EOC
CALL us_add_to_table2('uestd', 'company_price_per_unit_ex', 'DOUBLE NOT NULL DEFAULT 1 AFTER `company_price_per_unit`' );
-- EOC
CALL us_add_to_table2('uestd', 'company_price_per_unit_id', 'INT NULL AFTER `company_price_per_unit_ex`' );
-- EOC

-- Add currencies support - Stammdaten
CALL us_add_to_table2('kopiekat', 'currency_id', 'INT NULL AFTER `company_id`' );
-- EOC

CALL us_add_to_table2('reisekosten', 'currency_id', 'INT NULL AFTER `company_id`' );
-- EOC

CALL us_add_to_table2('personen', 'currency_id', 'INT NULL AFTER `Bruttolohn`' );
-- EOC

CALL us_add_to_table2('gruppen_zeit', 'currency_id', 'INT NULL AFTER `Betrag9`' );
-- EOC

CALL us_add_to_table2('projektabrsaetze', 'currency_id', 'INT NULL AFTER `ABSatz`' );
-- EOC

CALL us_add_to_table2('projektabrsaetze', 'aktiv', 'BOOLEAN DEFAULT 1 AFTER `currency_id`' );
-- EOC

CALL us_add_to_table2('adressen', 'Master_Titel', 'VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `TITEL`' );
-- EOC

CALL us_add_to_table2('adressen', 'Strasse2', 'VARCHAR( 255 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `Strasse`' );
-- EOC

CALL us_add_to_table2('adressen', 'bMaster_Titel', 'BOOLEAN DEFAULT 0 AFTER `bTitel`' );
-- EOC

CALL us_add_to_table2('adressen', 'bStrasse2', 'BOOLEAN DEFAULT 0 AFTER `bStrasse`' );
-- EOC

CALL us_add_to_table2('adressen', 'longitude', 'DOUBLE DEFAULT NULL AFTER `Bilddatei`' );
-- EOC

CALL us_add_to_table2('adressen', 'longitude_deri', 'BOOLEAN DEFAULT 0 AFTER `longitude`' );
-- EOC

CALL us_add_to_table2('adressen', 'latitude', 'DOUBLE DEFAULT NULL AFTER `longitude`' );
-- EOC

CALL us_add_to_table2('adressen', 'latitude_deri', 'BOOLEAN DEFAULT 0 AFTER `latitude`' );
-- EOC

CALL us_add_to_table2('adressen', 'comment_main', 'VARCHAR(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT \'\'' );
-- EOC
CALL us_add_to_table2('adressen', 'comment_main_staff', 'INT NULL AFTER comment_main' );
-- EOC
CALL us_add_to_table2('adressen', 'comment_main_date', 'datetime DEFAULT NULL AFTER comment_main_staff' );
-- EOC
CALL us_add_to_table2('adressen', 'comment_main_more', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL' );
-- EOC

-- Creditor number / Debtor number fields (DO NOT MAKE THEM DERIVABLE.)
CALL us_add_to_table2('adressen', 'creditor_no', 'VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT \'\' AFTER `Bilddatei`;' );
-- EOC

CALL us_add_to_table2('adressen', 'debtor_no', 'VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT \'\' AFTER `Bilddatei`;' );
-- EOC

CALL us_add_to_table2('adressen', 'dsgvo_delete_date', 'datetime DEFAULT NULL AFTER debtor_no' );
-- EOC
CALL us_add_to_table2('adressen', 'dsgvo_data_from', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci AFTER dsgvo_delete_date' );
-- EOC

-- ADD auto_assigned_wp flag to times/travels/extras
CALL us_add_to_table2('times', 'auto_assigned_wp', 'TINYINT unsigned NOT NULL DEFAULT 0' );
-- EOC
CALL us_add_to_table2('travels', 'auto_assigned_wp', 'TINYINT unsigned NOT NULL DEFAULT 0' );
-- EOC
CALL us_add_to_table2('extras', 'auto_assigned_wp', 'TINYINT unsigned NOT NULL DEFAULT 0' );
-- EOC

-- ADD new addi_val fields to times/extras
CALL us_add_to_table2('times', 'addi_val3', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER addi_val2' );
-- EOC
CALL us_add_to_table2('times', 'addi_val4', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER addi_val3' );
-- EOC
CALL us_add_to_table2('extras', 'addi_val3', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER addi_val2' );
-- EOC
CALL us_add_to_table2('extras', 'addi_val4', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER addi_val3' );
-- EOC
-- Migrate addi_val3 personio absence id to JSON
UPDATE times SET addi_val3 = CONCAT('{"personio_absence_id": "',addi_val3,'"}') WHERE addi_val3 IS NOT NULL AND SUBSTR(addi_val3, 1, 1) != "{" AND SUBSTR(addi_val3, 1, 1) != "[";
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- BIC / IBAN
CALL change_column('honkonten', 'Blz', 'VARCHAR( 11 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC
CALL change_column('honkonten', 'KNR', 'VARCHAR( 35 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC
CALL change_column('personen', 'KontoNr', 'VARCHAR( 150 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add search tables
DROP TABLE IF EXISTS `search_times`;
-- EOC

-- Add search tables
DROP TABLE IF EXISTS `search_adresses`;
-- EOC

-- Add search tables
DROP TABLE IF EXISTS `search_projects`;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Translate folders for different OS
CREATE TABLE IF NOT EXISTS `folder_translation` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `target` enum('WIN','UNIX','MAC') COLLATE utf8mb4_general_ci NOT NULL,
    `path` VARCHAR(254) COLLATE utf8mb4_general_ci NOT NULL,
    `trans_path` VARCHAR(254) COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ;
-- EOC

CALL us_add_pk_auto_increment('folder_translation', 'id');
-- EOC

CALL us_add_to_table2('folder_translation', 'auto_translate_project_paths', 'BOOLEAN DEFAULT 0 AFTER `trans_path`' );
-- EOC

-- Java clients - OLD
DROP TABLE IF EXISTS `staff_javaclients`;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add instinfo
CALL us_add_to_table2('installation', 'instinfo', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL AFTER `Mod60`' );
-- EOC
CALL change_column('installation', 'R3', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
DROP TABLE IF EXISTS `aktuser`;
-- EOC
DROP TABLE IF EXISTS `aktuser_log`;
-- EOC
DROP VIEW IF EXISTS `aktuser`;
-- EOC

-- Add never active users view
CREATE VIEW `aktuser` AS SELECT 
  NULL AS `LfdNr_AktUser`,
  NULL AS `UserNummer`,
  NULL AS `UserName`,
  NULL AS `LoginTime`,
  NULL AS `WorkstationName`,
  NULL AS `WorkstationLogin`,
  NULL AS `LfdNr_Alt`,
  NULL AS `webversion`
FROM dual WHERE FALSE;
-- EOC

DROP TABLE IF EXISTS `aktuser2`;
-- EOC
DROP VIEW IF EXISTS `aktuser2`;
-- EOC

-- Add never active users 2 view
CREATE VIEW `aktuser2` AS SELECT 
  NULL AS `LfdNr_AktUser`,
  NULL AS `UserNummer`,
  NULL AS `UserName`,
  NULL AS `LoginTime`,
  NULL AS `WorkstationName`,
  NULL AS `WorkstationLogin`,
  NULL AS `LfdNr_Alt`,
  NULL AS `webversion`
FROM dual WHERE FALSE;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- VAT
CALL us_add_to_table2('kopiekat', 'MwStKopie', 'DOUBLE DEFAULT NULL' );
-- EOC

CALL us_add_to_table2('reisekosten', 'MwStReise', 'DOUBLE DEFAULT NULL' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Allow workinput related types to be set inactive
CALL us_add_to_table2('kopiekat', 'active', 'INT DEFAULT 1 AFTER `MwStKopie`' );
-- EOC
CALL us_add_to_table2('reisekosten', 'active', 'INT DEFAULT 1 AFTER `MwStReise`' );
-- EOC
CALL us_add_to_table2('uesatz', 'active', 'INT DEFAULT 1 AFTER `Satz`' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- UNIQUE ID FOR NEW ENTRIES
CALL us_add_to_table2('adrbeschr', 'unique_add_id', 'VARCHAR( 140 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `LfdNr_Adr`' );
-- EOC

CALL us_add_to_table2('adrbeschr', 'call_id', 'INT NULL DEFAULT NULL AFTER `unique_add_id`' );
-- EOC

CALL us_add_to_table2('tagessollstd', 'unique_add_id', 'VARCHAR( 140 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `Pers_LfdNr`' );
-- EOC

-- CALL us_add_to_table2('tagessollstdtemp', 'unique_add_id', 'VARCHAR( 140 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `Pers_LfdNr`' );
-- -- EOC

CALL us_add_to_table2('lut_pers_grp', 'unique_add_id', 'VARCHAR( 140 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `LfdNr_Pers`' );
-- EOC

-- CALL us_add_to_table2('lut_pers_grp_temp', 'unique_add_id', 'VARCHAR( 140 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `LfdNr_Pers`' );
-- -- EOC

CALL us_add_to_table2('lut_plan_adr', 'unique_add_id', 'VARCHAR( 140 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `LfdNr_Plan`' );
-- EOC


-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add tableconfig table
CREATE TABLE IF NOT EXISTS `tableconfig` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`table_id` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL ,
`column` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL ,
`staff_id` INT NULL DEFAULT NULL ,
`visible` BOOLEAN DEFAULT NULL,
`visiblemob` BOOLEAN DEFAULT NULL,
`width` DOUBLE DEFAULT NULL,
`maxchars` DOUBLE DEFAULT NULL,
`widthmob` DOUBLE DEFAULT NULL,
`maxcharsmob` DOUBLE DEFAULT NULL,
`order` SMALLINT DEFAULT NULL,
INDEX ( `staff_id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('tableconfig', 'maxchars', 'DOUBLE DEFAULT NULL AFTER `width`' );
-- EOC
CALL us_add_to_table2('tableconfig', 'maxcharsmob', 'DOUBLE DEFAULT NULL AFTER `widthmob`' );
-- EOC

-- Add tableconfig table
CREATE TABLE IF NOT EXISTS `tableconfig_save` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `table_id` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL ,
 `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL ,
 `config` LONGTEXT NOT NULL,
 INDEX ( `table_id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('tableconfig_save', 'staff_id', 'INT NULL DEFAULT NULL AFTER `config`' );
-- EOC
CALL us_add_to_table2('tableconfig_save', 'security', 'SMALLINT DEFAULT NULL AFTER `staff_id`' );
-- EOC
CALL us_add_to_table2('tableconfig_save', 'company_id', 'INT NULL DEFAULT NULL AFTER `security`' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add portlets table
-- USC Erstelle weitere X2 Tabellen - Portlets.

CREATE TABLE IF NOT EXISTS `portlets` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`position_id` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL ,
`portlet_id` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL ,
`staff_id` INT NULL DEFAULT NULL ,
`col` INT UNSIGNED DEFAULT NULL,
`row` INT UNSIGNED DEFAULT NULL,
`open` BOOLEAN DEFAULT 0,
INDEX ( `staff_id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('portlets', 'tab', 'INT NULL DEFAULT NULL AFTER `row`' );
-- EOC

CALL us_add_to_table2('portlets', 'page_id', 'INT DEFAULT 1 AFTER `tab`' );
-- EOC

CALL us_add_to_table2('portlets', 'unique_id', 'VARCHAR( 140 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `portlet_id`' );
-- EOC

CALL us_add_to_table2('portlets', 'data', ' TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `open`' );
-- EOC

CALL us_add_to_table2('portlets', 'title', ' VARCHAR( 140 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `data`' );
-- EOC

CALL us_add_to_table2('portlets', 'auto_refresh', 'INT NULL DEFAULT NULL AFTER `title`' );
-- EOC

-- Add portlets_tabs
CREATE TABLE IF NOT EXISTS `portlets_tabs` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`staff_id` INT NOT NULL ,
`name` VARCHAR( 100 ) NOT NULL ,
`sort` SMALLINT NOT NULL DEFAULT 0
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('portlets_tabs', 'columns', 'INT NULL DEFAULT 3 AFTER `name`' );
-- EOC

CALL us_add_to_table2('portlets_tabs', 'color', 'INT NULL DEFAULT 1 AFTER `columns`' );
-- EOC

CALL us_add_to_table2('portlets_tabs', 'page_id', 'INT NOT NULL DEFAULT 1 AFTER `staff_id`' );
-- EOC

-- Add portlets_pages
CREATE TABLE IF NOT EXISTS `portlets_pages` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`staff_id` INT NOT NULL DEFAULT 0 ,
`name` VARCHAR( 100 ) NOT NULL ,
`is_deleteable` BOOLEAN DEFAULT 1
) auto_increment=100 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add address relations
CREATE TABLE IF NOT EXISTS `address_relations` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `address_id` INT NOT NULL ,
 `from_staff_id` INT DEFAULT NULL ,
 `from_address_id` INT DEFAULT NULL ,
 `from_personalapp_id` INT DEFAULT NULL ,
 `description` TEXT NOT NULL,
  `date` datetime DEFAULT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- UNIQUE ID FOR NEW ENTRIES
CALL us_add_to_table2('address_relations', 'unique_add_id', 'VARCHAR( 140 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `address_id`' );
-- EOC

CALL us_add_to_table2('address_relations', 'created_by_id', 'INT NULL' );
-- EOC
CALL us_add_to_table2('address_relations', 'changed_by_id', 'INT NULL' );
-- EOC
CALL us_add_to_table2('address_relations', 'created_date', 'DATETIME NULL' );
-- EOC
CALL us_add_to_table2('address_relations', 'change_date', 'DATETIME NULL' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Messaging system
CREATE TABLE IF NOT EXISTS `messaging_message` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `text` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
 `url` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
 `sticky` BOOLEAN NOT NULL,
 `staff_id` INT NULL ,
 `min_right` SMALLINT NULL ,
 `from_date` DATETIME NULL ,
 `to_date` DATETIME NULL ,
 `active` BOOLEAN NOT NULL,
 `created_by_id` INT NOT NULL ,
 `changed_by_id` INT NOT NULL ,
 `created_date` DATETIME NOT NULL ,
 `change_date` DATETIME NOT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CREATE TABLE IF NOT EXISTS `messaging_received` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `message_id` INT NOT NULL ,
 `staff_id` INT NOT NULL,
 `show_date` DATETIME NOT NULL,
 `active` BOOLEAN NOT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CREATE TABLE IF NOT EXISTS `reminder_appoi_received` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `appoi_id` INT NOT NULL ,
 `staff_id` INT NOT NULL,
 `show_date` DATETIME NOT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('reminder_appoi_received', 'calendar_type', 'enum(\'LOCAL\', \'O365\') COLLATE utf8mb4_general_ci DEFAULT \'LOCAL\' AFTER `show_date`');
-- EOC

CREATE TABLE IF NOT EXISTS `reminder_opta_received` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `opta_id` INT NOT NULL ,
 `staff_id` INT NOT NULL,
 `show_date` DATETIME NOT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add project_directory_structures table
CREATE TABLE IF NOT EXISTS `project_directory_structures` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 100 ) NOT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('project_directory_structures', 'exec_script', 'VARCHAR(255) DEFAULT NULL AFTER `name`' );
-- EOC

-- Add project_directory_structure_trees table
CREATE TABLE IF NOT EXISTS `project_directory_structure_trees` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`parent_id` INT NOT NULL,
`structure_id` INT NOT NULL,
`name` VARCHAR( 100 ) NOT NULL,
`is_path_correspondence` BOOLEAN DEFAULT NULL,
`is_path_inbox` BOOLEAN DEFAULT NULL,
`is_path_outbox` BOOLEAN DEFAULT NULL,
`is_path_drawings` BOOLEAN DEFAULT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('project_directory_structure_trees', 'file', 'VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `is_path_drawings`' );
-- EOC
CALL change_column('project_directory_structure_trees', 'file', 'VARCHAR( 255 ) NULL DEFAULT NULL AFTER `is_path_drawings`');
-- EOC
CALL change_column('project_directory_structure_trees', 'name', 'VARCHAR( 200 ) NOT NULL AFTER `structure_id`');
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC Erstelle weitere X2 Tabellen - DAV.

-- Personalappointments
CALL us_add_to_table2('perstermin', 'state_color_id', 'INT NULL AFTER `bOrt`' );
-- EOC
UPDATE perstermin SET TerminStatus=10 WHERE TerminStatus IS NULL;
-- EOC
CALL us_add_to_table2('perstermin', 'sabre_synctoken', 'BIGINT UNSIGNED NOT NULL' );
-- EOC
CALL us_add_to_table2('perstermin', 'sabre_calendar_data', 'MEDIUMBLOB DEFAULT NULL AFTER `sabre_synctoken`' );
-- EOC
CALL us_add_to_table2('perstermin', 'sabre_uri', 'VARBINARY( 255 ) NOT NULL' );
-- EOC
CALL us_add_to_table2('perstermin', 'sabre_uid', 'VARBINARY( 255 ) NOT NULL' );
-- EOC
CALL us_add_to_table2('perstermin', 'sabre_etag', 'VARBINARY( 40 ) NOT NULL' );
-- EOC

UPDATE perstermin SET sabre_synctoken=lfdnr WHERE sabre_synctoken=0 OR sabre_synctoken IS NULL;
-- EOC
UPDATE perstermin SET sabre_uid=uuid() WHERE sabre_uid='' OR sabre_uid IS NULL;
-- EOC
UPDATE perstermin SET sabre_uri=CONCAT('ustrich-', sabre_uid, '.ics') WHERE sabre_uri='' OR sabre_uri IS NULL;
-- EOC
UPDATE perstermin SET sabre_etag=CONCAT('us', sabre_uid) WHERE sabre_etag='' OR sabre_etag IS NULL;
-- EOC

CALL us_add_index_to_table('perstermin', 'sabre_synctoken_index', '`sabre_synctoken`' );
-- EOC
CALL us_add_constraint_to_table('perstermin', 'sabre_unique', 'UNIQUE', '`An` , `sabre_uri`' );
-- EOC

CREATE TABLE IF NOT EXISTS sabre_calendarchanges (
    calendarid INT NOT NULL,
    uri VARBINARY(255) NOT NULL,
    synctoken INT UNSIGNED NOT NULL,
    `operation` TINYINT NOT NULL,
    UNIQUE calendarid_synctoken (calendarid, synctoken, `operation`),
    INDEX synctoken_index (synctoken),
    `date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('sabre_calendarchanges', 'date', 'DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' );
-- EOC

CREATE OR REPLACE
    VIEW max_sabre_synctokens AS SELECT 
    (SELECT MAX(synctoken) FROM sabre_calendarchanges) AS sabre_synctoken1,
    (SELECT MAX(sabre_synctoken) FROM perstermin) AS sabre_synctoken2;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------

-- Opentasks
CALL us_add_to_table2('todo', 'sabre_synctoken', 'BIGINT UNSIGNED NOT NULL' );
-- EOC
CALL us_add_to_table2('todo', 'sabre_calendar_data', 'MEDIUMBLOB DEFAULT NULL AFTER `sabre_synctoken`' );
-- EOC
CALL us_add_to_table2('todo', 'sabre_uri', 'VARBINARY( 255 ) NOT NULL' );
-- EOC
CALL us_add_to_table2('todo', 'sabre_uid', 'VARBINARY( 255 ) NOT NULL' );
-- EOC
CALL us_add_to_table2('todo', 'sabre_etag', 'VARBINARY( 40 ) NOT NULL' );
-- EOC

UPDATE todo SET sabre_synctoken=lfdnr WHERE sabre_synctoken=0 OR sabre_synctoken IS NULL;
-- EOC
UPDATE todo SET sabre_uid=uuid() WHERE sabre_uid='' OR sabre_uid IS NULL;
-- EOC
UPDATE todo SET sabre_uri=CONCAT('ustrich-', sabre_uid, '.ics') WHERE sabre_uri='' OR sabre_uri IS NULL;
-- EOC
UPDATE todo SET sabre_etag=CONCAT('us', sabre_uid) WHERE sabre_etag='' OR sabre_etag IS NULL;
-- EOC

CALL us_add_index_to_table('todo', 'sabre_synctoken_index', '`sabre_synctoken`' );
-- EOC
CALL us_add_constraint_to_table('todo', 'sabre_unique', 'UNIQUE', '`ZuTunVon` , `sabre_uri`' );
-- EOC

CREATE TABLE IF NOT EXISTS sabre_taskchanges (
    calendarid INT NOT NULL,
    uri VARBINARY(255) NOT NULL,
    synctoken INT UNSIGNED NOT NULL,
    `operation` TINYINT NOT NULL,
    UNIQUE taskid_synctoken (calendarid, synctoken, `operation`),
    INDEX synctoken_index (synctoken),
    `date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('sabre_taskchanges', 'date', 'DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' );
-- EOC

CREATE OR REPLACE
    VIEW max_sabre_task_synctokens AS SELECT 
    (SELECT MAX(synctoken) FROM sabre_taskchanges) AS sabre_synctoken1,
    (SELECT MAX(sabre_synctoken) FROM todo) AS sabre_synctoken2;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------

-- Addresses
CALL us_add_to_table2('adressen', 'sabre_synctoken', 'BIGINT UNSIGNED NOT NULL' );
-- EOC
CALL us_add_to_table2('adressen', 'sabre_card_data', 'MEDIUMBLOB DEFAULT NULL AFTER `sabre_synctoken`' );
-- EOC
CALL us_add_to_table2('adressen', 'sabre_uri', 'VARBINARY( 255 ) NOT NULL' );
-- EOC
CALL us_add_to_table2('adressen', 'sabre_uid', 'VARBINARY( 255 ) NOT NULL' );
-- EOC
CALL us_add_to_table2('adressen', 'sabre_etag', 'VARBINARY( 40 ) NOT NULL' );
-- EOC

UPDATE adressen SET sabre_synctoken=lfdnr WHERE sabre_synctoken=0 OR sabre_synctoken IS NULL;
-- EOC
UPDATE adressen SET sabre_uid=uuid() WHERE sabre_uid='' OR sabre_uid IS NULL;
-- EOC
UPDATE adressen SET sabre_uri=CONCAT('ustrich-', sabre_uid, '.vcf') WHERE sabre_uri='' OR sabre_uri IS NULL;
-- EOC
UPDATE adressen SET sabre_etag=CONCAT('us', sabre_uid) WHERE sabre_etag='' OR sabre_etag IS NULL;
-- EOC

CALL us_add_index_to_table('adressen', 'sabre_synctoken_index', '`sabre_synctoken`' );
-- EOC
CALL us_add_constraint_to_table('adressen', 'sabre_unique', 'UNIQUE', '`sabre_uri`' );
-- EOC

CREATE TABLE IF NOT EXISTS sabre_cardchanges (
    uri VARBINARY(255) NOT NULL,
    synctoken INT UNSIGNED NOT NULL,
    `operation` TINYINT NOT NULL,
    UNIQUE cardid_synctoken (synctoken, `operation`),
    INDEX synctoken_index (synctoken),
    `date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('sabre_cardchanges', 'date', 'DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' );
-- EOC

CREATE OR REPLACE
    VIEW max_sabre_card_synctokens AS SELECT 
    (SELECT MAX(synctoken) FROM sabre_cardchanges) AS sabre_synctoken1,
    (SELECT MAX(sabre_synctoken) FROM adressen) AS sabre_synctoken2;
-- EOC

-- Sabre DAV Tables
CREATE TABLE IF NOT EXISTS `sabre_locks` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
    `owner` VARCHAR(100),
    `timeout` INTEGER UNSIGNED,
    `created` INTEGER,
    `token` VARBINARY(100),
    `scope` TINYINT,
    `depth` TINYINT,
    `uri` VARBINARY(1000),
    PRIMARY KEY ( `id` ),
    INDEX(token),
    INDEX(uri(100))
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Add sabre_log table
CREATE TABLE IF NOT EXISTS `sabre_log` (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `date` datetime DEFAULT NULL,
  `staff` VARCHAR(255) DEFAULT NULL,
  `staff_id` INT DEFAULT NULL,
  `title` longtext,
  `info` LONGBLOB DEFAULT NULL,
  `isCompressed` TINYINT DEFAULT 0,
  `item_model` VARCHAR(100) DEFAULT NULL,
  `item_title` text,
  `item_id` INT DEFAULT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Report settings
-- USC Erstelle weitere X2 Tabellen - Report and Filter.

CREATE TABLE IF NOT EXISTS `report_designs` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `name` VARCHAR( 100 ) NOT NULL,
 `company_id` INT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT = 'Report design settings';
-- EOC

CREATE TABLE IF NOT EXISTS `report_designs_vars` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `design_id` INT NOT NULL ,
 `name` VARCHAR( 100 ) NOT NULL ,
 `param` VARCHAR( 255 ) NOT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL change_column('report_designs_vars', 'param', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL');
-- EOC

DROP TABLE IF EXISTS `report_output`;
-- EOC

CREATE TABLE IF NOT EXISTS `report_output_templates` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `report_id` VARCHAR( 255 ) NOT NULL ,
 `company_id` INT NULL ,
 `result` LONGTEXT NOT NULL,
 `output` LONGTEXT NOT NULL
) auto_increment=1 ENGINE = InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT = 'Report column settings';
-- EOC

CREATE TABLE IF NOT EXISTS `report_output_templates_sort` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `report_id` VARCHAR( 255 ) NOT NULL ,
 `output_template_id` VARCHAR( 100 ) NOT NULL ,
 `sort` SMALLINT NOT NULL DEFAULT 0
) auto_increment=1 ENGINE = InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT = 'Report output sorting';
-- EOC

CALL us_add_to_table2('report_output_templates_sort', 'inactive', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `sort`' );
-- EOC

CREATE TABLE IF NOT EXISTS `report_output_portlet` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `xml_id` VARCHAR( 255 ) NOT NULL ,
 `name` VARCHAR( 100 ) NOT NULL,
 `company_id` INT NULL DEFAULT NULL ,
 `output` LONGTEXT NOT NULL
) auto_increment=1 ENGINE = InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT = 'Report column settings for portlet based reports';
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Filter settings

DROP TABLE IF EXISTS `filter_settings`;
-- EOC

CREATE TABLE IF NOT EXISTS `filter_settings_main` (
 `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
 `staff_id` INT NOT NULL ,
 `xml_id` VARCHAR( 255 ) NOT NULL ,
 `name` VARCHAR( 100 ) NOT NULL,
 `security` SMALLINT NOT NULL DEFAULT 0 ,
 `request_settings` LONGTEXT NOT NULL,
 `request_settings_addable` LONGTEXT NOT NULL
) auto_increment=1 ENGINE = InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT = 'Filter settings';
-- EOC

CALL us_add_to_table2('filter_settings_main', 'security', 'SMALLINT NOT NULL DEFAULT 0 AFTER `name`' );
-- EOC

CALL us_add_to_table2('progruppendef', 'filter_id', 'INT DEFAULT NULL' );
-- EOC

CALL us_add_to_table2('progruppendef', 'filter_last_count', 'BIGINT DEFAULT NULL' );
-- EOC

CALL us_add_to_table2('progruppendef', 'filter_hash', 'VARCHAR( 40 ) DEFAULT NULL' );
-- EOC

CALL us_add_to_table2('progruppendef', 'filter_creator_info', 'longtext DEFAULT NULL' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add times - times_project_staff portlet lut table
CREATE TABLE IF NOT EXISTS `lut_times_project_staff` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`times_id` INT NOT NULL ,
`already_confirmed` INT NOT NULL DEFAULT 0
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_index_to_table('lut_times_project_staff', 'lut_tps_already_confirmed_index', '`already_confirmed`');
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Add staff_group table
CREATE TABLE IF NOT EXISTS `staff_groups` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 100 ) NOT NULL ,
`created_by_id` INT NOT NULL ,
`security` SMALLINT DEFAULT NULL,
`company_id` INT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Add staff - staff_group lut-table
CREATE TABLE IF NOT EXISTS `lut_staff_staff_group` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`staff_id` INT NOT NULL ,
`staff_group_id` INT NOT NULL 
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC


CALL change_column('dokattachments', 'Att_Pfad', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('dokattachments', 'orig_correspondence_id', 'INT NULL AFTER `Betreff`' );
-- EOC
CALL us_add_to_table2('dokattachments', 'drawing_id', 'INT NULL AFTER `orig_correspondence_id`' );
-- EOC
CALL us_add_to_table2('dokattachments', 'addressfile_id', 'INT NULL AFTER `drawing_id`' );
-- EOC
CALL us_add_to_table2('dokattachments', 'created_by_id', 'INT NULL AFTER `orig_correspondence_id`' );
-- EOC
CALL us_add_to_table2('dokattachments', 'created_date', 'DATETIME NULL AFTER `created_by_id`' );
-- EOC

CREATE TABLE IF NOT EXISTS `zusatz_formular` (
  `formular_lfdnr` INT DEFAULT NULL,
  `LfdNr_Alt` INT DEFAULT NULL,
  `LfdNr` INT NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`LfdNr`),
  KEY `zusatz_formular_formular_lfdnr` (`formular_lfdnr`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
-- EOC

-- This very important index INDEX was not created on MSSQL2MySQL migration 
CALL us_add_index_to_table('zusatz_formular', 'zusatz_formular_formular_lfdnr', '`formular_lfdnr`');
-- EOC

CREATE TABLE IF NOT EXISTS `zusatz_formular_def` (
  `OrdNr` SMALLINT DEFAULT NULL,
  `FeldName` VARCHAR(30) DEFAULT NULL,
  `Typ` SMALLINT DEFAULT NULL,
  `Name` VARCHAR(100) DEFAULT NULL,
  `Laenge` SMALLINT DEFAULT NULL,
  `Sicherheit` SMALLINT DEFAULT NULL,
  `LfdNr_Alt` INT DEFAULT NULL,
  `LfdNr` INT NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`LfdNr`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `lang_correspondence_addi_def` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `def_id` INT NOT NULL,
    `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('lang_correspondence_addi_def', 'lang_correspondence_addi_def_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `lang_outbox_addi_def` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `def_id` INT NOT NULL,
    `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('lang_outbox_addi_def', 'lang_outbox_addi_def_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `lang_inbox_addi_def` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `def_id` INT NOT NULL,
    `name` VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('lang_inbox_addi_def', 'lang_inbox_addi_def_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC

CREATE TABLE IF NOT EXISTS `staff_last_login` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `staff_id` INT NOT NULL ,
    `date` DATETIME NOT NULL ,
    INDEX ( `staff_id` )
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CREATE TABLE IF NOT EXISTS `staff_last_login_fail` (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
  `staff_id` INT DEFAULT NULL ,
  `staff_name` VARCHAR(50) DEFAULT NULL,
  `ip_address` VARCHAR( 50 ) NOT NULL ,
  `user_agent` VARCHAR( 150 ) NOT NULL ,
  `date` DATETIME NOT NULL
) auto_increment=1 ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ;
-- EOC

CALL change_column('staff_last_login_fail', 'user_agent', 'VARCHAR(150) NOT NULL');
-- EOC

CALL change_column('staff_last_login_fail', 'ip_address', 'VARCHAR(50) NOT NULL');
-- EOC

CREATE TABLE IF NOT EXISTS `fee_number_log` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `last_number` VARCHAR( 30 ) NOT NULL,
     UNIQUE KEY (`last_number`)
) ENGINE = InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL change_column('fee_number_log', 'last_number', 'VARCHAR(30) NOT NULL');
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC Erstelle weitere X4 Tabellen - Zusatzdaten
CALL us_add_to_table2('zusatz_adressen_def', 'subtype', 'SMALLINT NOT NULL DEFAULT 0 AFTER `Typ`' );
-- EOC

CALL us_add_to_table2('zusatz_adressen_def', 'fieldvalues', 'text DEFAULT NULL AFTER `subtype`' );
-- EOC

CALL us_add_to_table2('zusatz_adressen_def', 'isrequired', 'SMALLINT DEFAULT 0 AFTER `fieldvalues`' );
-- EOC

CALL us_add_to_table2('zusatz_adressen_def', 'color', 'VARCHAR(30) DEFAULT NULL AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_adressen_def', 'isfulltext', 'SMALLINT NOT NULL DEFAULT 0 AFTER `color`' );
-- EOC

CALL us_add_to_table2('zusatz_personen_def', 'subtype', 'SMALLINT NOT NULL DEFAULT 0 AFTER `Typ`' );
-- EOC

CALL us_add_to_table2('zusatz_personen_def', 'fieldvalues', 'text DEFAULT NULL AFTER `subtype`' );
-- EOC

CALL us_add_to_table2('zusatz_personen_def', 'isrequired', 'SMALLINT DEFAULT 0 AFTER `fieldvalues`' );
-- EOC

CALL us_add_to_table2('zusatz_personen_def', 'color', 'VARCHAR(30) DEFAULT NULL AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_projekt_def', 'subtype', 'SMALLINT NOT NULL DEFAULT 0 AFTER `Typ`' );
-- EOC

CALL us_add_to_table2('zusatz_projekt_def', 'fieldvalues', 'text DEFAULT NULL AFTER `subtype`' );
-- EOC

CALL us_add_to_table2('zusatz_projekt_def', 'isrequired', 'SMALLINT DEFAULT 0 AFTER `fieldvalues`' );
-- EOC

CALL us_add_to_table2('zusatz_projekt_def', 'color', 'VARCHAR(30) DEFAULT NULL AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_projekt_def', 'isfulltext', 'SMALLINT NOT NULL DEFAULT 0 AFTER `color`' );
-- EOC

CALL us_add_to_table2('zusatz_propers_def', 'subtype', 'SMALLINT NOT NULL DEFAULT 0 AFTER `Typ`' );
-- EOC

CALL us_add_to_table2('zusatz_propers_def', 'fieldvalues', 'text DEFAULT NULL AFTER `subtype`' );
-- EOC

CALL us_add_to_table2('zusatz_propers_def', 'isrequired', 'SMALLINT DEFAULT 0 AFTER `fieldvalues`' );
-- EOC

CALL us_add_to_table2('zusatz_propers_def', 'color', 'VARCHAR(30) DEFAULT NULL AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_todo_def', 'subtype', 'SMALLINT NOT NULL DEFAULT 0 AFTER `Typ`' );
-- EOC

CALL us_add_to_table2('zusatz_todo_def', 'fieldvalues', 'text DEFAULT NULL AFTER `subtype`' );
-- EOC

CALL us_add_to_table2('zusatz_todo_def', 'isrequired', 'SMALLINT DEFAULT 0 AFTER `fieldvalues`' );
-- EOC

CALL us_add_to_table2('zusatz_todo_def', 'color', 'VARCHAR(30) DEFAULT NULL AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_todo_def', 'isfulltext', 'SMALLINT NOT NULL DEFAULT 0 AFTER `color`' );
-- EOC

CALL us_add_to_table2('zusatz_extkosten_def', 'subtype', 'SMALLINT NOT NULL DEFAULT 0 AFTER `Typ`' );
-- EOC

CALL us_add_to_table2('zusatz_extkosten_def', 'fieldvalues', 'text DEFAULT NULL AFTER `subtype`' );
-- EOC

CALL us_add_to_table2('zusatz_extkosten_def', 'isrequired', 'SMALLINT DEFAULT 0 AFTER `fieldvalues`' );
-- EOC

CALL us_add_to_table2('zusatz_extkosten_def', 'color', 'VARCHAR(30) DEFAULT NULL AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_honverw_def', 'subtype', 'SMALLINT NOT NULL DEFAULT 0 AFTER `Typ`' );
-- EOC

CALL us_add_to_table2('zusatz_honverw_def', 'fieldvalues', 'text DEFAULT NULL AFTER `subtype`' );
-- EOC

CALL us_add_to_table2('zusatz_honverw_def', 'isrequired', 'SMALLINT DEFAULT 0 AFTER `fieldvalues`' );
-- EOC

CALL us_add_to_table2('zusatz_honverw_def', 'color', 'VARCHAR(30) DEFAULT NULL AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_wasistwo_def', 'subtype', 'SMALLINT NOT NULL DEFAULT 0 AFTER `Typ`' );
-- EOC

CALL us_add_to_table2('zusatz_wasistwo_def', 'fieldvalues', 'text DEFAULT NULL AFTER `subtype`' );
-- EOC

CALL us_add_to_table2('zusatz_wasistwo_def', 'isrequired', 'SMALLINT DEFAULT 0 AFTER `fieldvalues`' );
-- EOC

CALL us_add_to_table2('zusatz_wasistwo_def', 'color', 'VARCHAR(30) DEFAULT NULL AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_planverz_def', 'subtype', 'SMALLINT NOT NULL DEFAULT 0 AFTER `Typ`' );
-- EOC

CALL us_add_to_table2('zusatz_planverz_def', 'fieldvalues', 'text DEFAULT NULL AFTER `subtype`' );
-- EOC

CALL us_add_to_table2('zusatz_planverz_def', 'isrequired', 'SMALLINT DEFAULT 0 AFTER `fieldvalues`' );
-- EOC

CALL us_add_to_table2('zusatz_planverz_def', 'color', 'VARCHAR(30) DEFAULT NULL AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_planverz_def', 'isfulltext', 'SMALLINT NOT NULL DEFAULT 0 AFTER `color`' );
-- EOC

CALL us_add_to_table2('zusatz_formular_def', 'subtype', 'SMALLINT NOT NULL DEFAULT 0 AFTER `Typ`' );
-- EOC

CALL us_add_to_table2('zusatz_formular_def', 'fieldvalues', 'text DEFAULT NULL AFTER `subtype`' );
-- EOC

CALL us_add_to_table2('zusatz_formular_def', 'isrequired', 'SMALLINT DEFAULT 0 AFTER `fieldvalues`' );
-- EOC

CALL us_add_to_table2('zusatz_formular_def', 'color', 'VARCHAR(30) DEFAULT NULL AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_formular_def', 'isfulltext', 'SMALLINT NOT NULL DEFAULT 0 AFTER `color`' );
-- EOC

CALL us_add_to_table2('zusatz_postaus_def', 'subtype', 'SMALLINT NOT NULL DEFAULT 0 AFTER `Typ`' );
-- EOC

CALL us_add_to_table2('zusatz_postaus_def', 'fieldvalues', 'text DEFAULT NULL AFTER `subtype`' );
-- EOC

CALL us_add_to_table2('zusatz_postaus_def', 'isrequired', 'SMALLINT DEFAULT 0 AFTER `fieldvalues`' );
-- EOC

CALL us_add_to_table2('zusatz_postaus_def', 'isfulltext', 'SMALLINT NOT NULL DEFAULT 0 AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_postaus_def', 'color', 'VARCHAR(30) DEFAULT NULL AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_postein_def', 'subtype', 'SMALLINT NOT NULL DEFAULT 0 AFTER `Typ`' );
-- EOC

CALL us_add_to_table2('zusatz_postein_def', 'fieldvalues', 'text DEFAULT NULL AFTER `subtype`' );
-- EOC

CALL us_add_to_table2('zusatz_postein_def', 'isrequired', 'SMALLINT DEFAULT 0 AFTER `fieldvalues`' );
-- EOC

CALL us_add_to_table2('zusatz_postein_def', 'color', 'VARCHAR(30) DEFAULT NULL AFTER `isrequired`' );
-- EOC

CALL us_add_to_table2('zusatz_postein_def', 'isfulltext', 'SMALLINT NOT NULL DEFAULT 0 AFTER `color`' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
CALL us_add_to_table2('lut_projektabr', 'warnschwelle', 'DOUBLE NULL AFTER `SatzAB`' );
-- EOC

-- CALL us_add_to_table2('outsync', 'A10', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `A9`' );
-- -- EOC

-- CALL us_add_to_table2('outsync', 'ADR_Kategorie', 'INT DEFAULT NULL AFTER `A10`' );
-- -- EOC

CALL change_column('projektabrsaetze', 'Beschreibung', 'VARCHAR( 100 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC

CALL change_column('projektabrsaetze', 'RKSatz', 'VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC

CALL change_column('projektabrsaetze', 'ExtraSatz', 'VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC

CALL change_column('projektabrsaetze', 'MASatz', 'VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC

CALL change_column('projektabrsaetze', 'ABSatz', 'VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC

CALL us_add_to_table2('telefonate', 'LfdNr_Adr_Caller', 'INT DEFAULT NULL AFTER `LfdNr_Adr`' );
-- EOC

CALL us_add_to_table2('telefonate', 'No_Adr_Caller', 'BOOLEAN DEFAULT FALSE AFTER `LfdNr_Adr_Caller`' );
-- EOC

CALL us_add_to_table2('telefonate', 'disconnected', 'BOOLEAN DEFAULT FALSE AFTER `beendet`' );
-- EOC

CALL us_add_to_table2('telefonate', 'last_update', 'DATETIME NULL' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- OAuth accounts
-- USC Erstelle weitere X4 Tabellen - OAuth

CREATE TABLE IF NOT EXISTS `oauth_clients` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `name` VARCHAR( 255 ) DEFAULT NULL,
    `client_type` VARCHAR( 20 ) DEFAULT NULL,
    `client_authority` VARCHAR( 255 ) DEFAULT NULL,
    `client_id` VARCHAR( 255 ) DEFAULT NULL,
    `client_secret` VARCHAR( 255 ) DEFAULT NULL,
    `internal_client_secret` VARCHAR( 255 ) DEFAULT NULL,
    `internal_client_secret_date` DATE DEFAULT NULL,
    `client_config` LONGTEXT NOT NULL
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('oauth_clients', 'client_authority', 'VARCHAR( 255 ) DEFAULT NULL AFTER `client_type`' );
-- EOC
CALL us_add_to_table2('oauth_clients', 'internal_client_secret', 'VARCHAR( 255 ) DEFAULT NULL AFTER `client_secret`' );
-- EOC
CALL us_add_to_table2('oauth_clients', 'internal_client_secret_date', 'DATE DEFAULT NULL AFTER `internal_client_secret`' );
-- EOC

-- Oauth tokens
CREATE TABLE IF NOT EXISTS `oauth_tokens` (
    `staff_id` INT NOT NULL,
    `account_id` INT NOT NULL,
    `access_token` LONGBLOB NOT NULL,
    `refresh_token` LONGBLOB NOT NULL,
    `login_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `last_update` DATETIME NOT NULL,
    `expires_date` DATETIME DEFAULT NULL,
  PRIMARY KEY (`staff_id`, `account_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('oauth_tokens', 'login_date', 'DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER `refresh_token`' );
-- EOC

CALL check_rename_column_exists('oauth_tokens', 'client_id', 'staff_id', 'INT NOT NULL ');
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Logging for moving form types
-- USC Erstelle weitere X2 Tabellen - Logging

CREATE TABLE IF NOT EXISTS `move_form_types_log` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `moving_session_id` VARCHAR( 50 ) NOT NULL,
    `project_id` INT NOT NULL ,
    `correspondence_id` INT NOT NULL ,
    `correspondence_type_id` INT NOT NULL ,
    `project_path_correspondence` longtext NOT NULL,
    `correspondence_structure_path` VARCHAR( 254 ) NOT NULL,
    `filename` VARCHAR( 254 ) NOT NULL,
    `path_from` longtext NOT NULL,
    `path_to` longtext NOT NULL,
    `move_failed` BOOLEAN DEFAULT 0,
    `created_date` DATETIME NOT NULL,
    `created_by_id` INT NOT NULL,
    `change_date` DATETIME NOT NULL,
    `changed_by_id` INT NOT NULL
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

-- Logging for moving form types (archive table)
CALL us_create_move_form_types_log_archive();
-- EOC

-- Create system_modifications_log, if not exists
CALL us_create_system_modifications_log();
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- USC Erstelle weitere X4 Tabellen - Email

-- E-mail accounts
-- E-mail 256 http://www.rfc-editor.org/errata_search.php?rfc=3696
-- DNS name max 255 octets http://blogs.msdn.com/b/oldnewthing/archive/2012/04/12/10292868.aspx
-- Port number max 65535
CREATE TABLE IF NOT EXISTS `email_accounts` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `staff_id` INT NOT NULL ,
    `auth_mode` enum('basic', 'oauth') COLLATE utf8mb4_general_ci DEFAULT 'basic',
    `oauth_account` INT DEFAULT NULL,
    `oauth_token_staff_id` INT DEFAULT NULL,
    `password_mode` INT NOT NULL  DEFAULT 1,
    `password_mode_info` VARCHAR( 255 ) DEFAULT NULL,
    `email` VARCHAR( 256 ) NOT NULL,
    `smtp_host` VARCHAR( 255 ) NOT NULL ,
    `smtp_user` VARCHAR( 100 ) NOT NULL ,
    `smtp_pass` VARCHAR( 255 ) NOT NULL ,
    `smtp_port` INT NOT NULL ,
    `smtp_service_flags` VARCHAR( 254 ) NOT NULL ,
    `imap_host` VARCHAR( 255 ) NOT NULL ,
    `imap_user` VARCHAR( 100 ) NOT NULL ,
    `imap_pass` VARCHAR( 255 ) NOT NULL ,
    `imap_port` INT NOT NULL ,
    `imap_mailbox` VARCHAR( 100 ) NOT NULL ,
    `imap_service_flags` VARCHAR( 254 ) NOT NULL
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('email_accounts', 'auth_mode', 'enum(\'basic\', \'oauth\') COLLATE utf8mb4_general_ci DEFAULT \'basic\' AFTER `id`'  );
-- EOC
UPDATE email_accounts SET auth_mode='basic' WHERE auth_mode IS NULL; 
-- EOC
CALL us_add_to_table2('email_accounts', 'oauth_account', 'INT DEFAULT NULL AFTER `auth_mode`' );
-- EOC
CALL us_add_to_table2('email_accounts', 'oauth_token_staff_id', 'INT DEFAULT NULL AFTER `oauth_account`' );
-- EOC

CALL us_add_to_table2('email_accounts', 'password_mode', 'INT DEFAULT 1 AFTER `id`' );
-- EOC

CALL us_add_to_table2('email_accounts', 'password_mode_info', 'VARCHAR( 255 ) DEFAULT NULL AFTER `password_mode`' );
-- EOC

CALL us_add_to_table2('email_accounts', 'smtp_mode', 'enum(\'plain\', \'ssl\', \'tls\') COLLATE utf8mb4_general_ci DEFAULT \'plain\' AFTER `smtp_port`' );
-- EOC

CALL us_add_to_table2('email_accounts', 'imap_mode', 'enum(\'plain\', \'ssl\', \'tls\') COLLATE utf8mb4_general_ci DEFAULT \'plain\' AFTER `imap_port`' );
-- EOC

CALL us_add_to_table2('email_accounts', 'imap_mailbox_out', 'VARCHAR( 100 ) NOT NULL AFTER `imap_mailbox`' );
-- EOC

CALL us_add_to_table2('email_accounts', 'imap_mailbox_trash', 'VARCHAR( 100 ) DEFAULT NULL AFTER `imap_mailbox_out`' );
-- EOC

CALL us_add_to_table2('email_accounts', 'imap_save_sent', 'BOOLEAN DEFAULT TRUE AFTER `imap_mailbox_out`' );
-- EOC

CALL us_add_to_table2('email_accounts', 'imap_mbox_delimiter', 'VARCHAR( 255 ) DEFAULT NULL AFTER `imap_mailbox_out`' );
-- EOC

CALL us_add_to_table2('email_accounts', 'owner_id', 'INT ( 11 ) DEFAULT NULL AFTER `email`' );
-- EOC

CALL us_add_to_table2('email_accounts', 'smtp_ldap_auth_staff_id', 'INT ( 11 ) DEFAULT NULL AFTER `owner_id`' );
-- EOC

CALL us_add_to_table2('email_accounts', 'imap_ldap_auth_staff_id', 'INT ( 11 ) DEFAULT NULL AFTER `smtp_ldap_auth_staff_id`' );
-- EOC

CALL us_add_to_table2('email_accounts', 'auto_expunge', 'BOOLEAN DEFAULT FALSE' );
-- EOC

CALL us_add_to_table2('email_accounts', 'import_eml_later', 'BOOLEAN DEFAULT TRUE' );
-- EOC

CALL us_add_to_table2('email_accounts', 'address_signature_id', 'INT ( 11 ) DEFAULT 1 AFTER `owner_id`' );
-- EOC

CREATE TABLE IF NOT EXISTS `email_favourite_mboxes` (
    `id` INT NOT NULL AUTO_INCREMENT ,
    `email_account_id` INT NOT NULL ,
    `name` VARCHAR(255) NOT NULL ,
    `is_out` BOOLEAN DEFAULT 0,
    PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('mail_id', 'Mail_ID_long', 'VARCHAR( 500 ) DEFAULT NULL AFTER `Mail_ID`' );
-- EOC

CALL us_add_to_table2('mail_id', 'inbox_id', 'VARCHAR( 11 ) DEFAULT NULL AFTER `Mail_ID_long`' );
-- EOC

CALL us_add_to_table2('mail_id', 'outbox_id', 'VARCHAR( 11 ) DEFAULT NULL AFTER `inbox_id`' );
-- EOC

CALL us_add_to_table2('dokattachments', 'real_name', 'VARCHAR( 255 ) DEFAULT \'\' AFTER `Att_Pfad`' );
-- EOC

CALL change_column('mail_id', 'Mail_ID', 'VARCHAR( 500 ) DEFAULT NULL');
-- EOC

CALL change_column('mail_id', 'Mail_ID_long', 'VARCHAR( 500 ) DEFAULT NULL');
-- EOC

-- Send email
CREATE TABLE IF NOT EXISTS `sendmail` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    `send_account` INT DEFAULT NULL,
    `recipients_to` LONGTEXT NOT NULL,
    `recipients_cc` LONGTEXT NOT NULL,
    `recipients_bcc` LONGTEXT NOT NULL,
    `subject` TEXT NOT NULL, 
    `message` LONGTEXT NOT NULL, 
    `related_id` INT NULL,
    `related_type` VARCHAR(30) NULL, 
    `status` ENUM('new', 'send_do', 'send_done') NOT NULL, 
    `created_date` DATETIME NOT NULL,
    `created_by_id` INT NOT NULL
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('sendmail', 'recipients', 'MEDIUMTEXT NOT NULL AFTER `recipients_bcc`' );
-- EOC
CALL us_add_to_table2('sendmail', 'flags_mode', 'VARCHAR( 255 ) DEFAULT \'\' AFTER `status`' );
-- EOC
CALL us_add_to_table2('sendmail', 'flags', 'VARCHAR( 255 ) DEFAULT \'\' AFTER `status`' );
-- EOC
CALL us_add_to_table2('sendmail', 'outbox', 'VARCHAR( 255 ) DEFAULT \'\' AFTER `flags`' );
-- EOC
CALL us_add_to_table2('sendmail', 'attachments', 'LONGTEXT AFTER `outbox`' );
-- EOC
CALL us_add_to_table2('sendmail', 'zip_attachments', 'BOOLEAN DEFAULT FALSE AFTER `attachments`' );
-- EOC
CALL us_add_to_table2('sendmail', 'external', 'LONGTEXT DEFAULT NULL AFTER `zip_attachments`' );
-- EOC
CALL change_column('sendmail', 'related_id', 'VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC

CALL us_add_to_table2('sendmail', 'recipients_to_ids', 'MEDIUMTEXT NULL AFTER `recipients_to`' );
-- EOC
CALL us_add_to_table2('sendmail', 'recipients_cc_ids', 'MEDIUMTEXT NULL AFTER `recipients_cc`' );
-- EOC
CALL us_add_to_table2('sendmail', 'recipients_bcc_ids', 'MEDIUMTEXT NULL AFTER `recipients_bcc`' );
-- EOC

SET @create_table_query = CONCAT(
    'CREATE TABLE IF NOT EXISTS `staff_status` (',
    '`staff_id` INT DEFAULT NULL,',
    '`status` INT NOT NULL,',
    '`comment` VARCHAR(100) COLLATE utf8mb4_general_ci NOT NULL,',
    '`max_age` datetime DEFAULT NULL',
    ') ENGINE=', @engineInnoDBorMemory, ' DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;'
);
-- EOC
PREPARE stmt FROM @create_table_query;
-- EOC
EXECUTE stmt;
-- EOC
DEALLOCATE PREPARE stmt;
-- EOC

CALL us_add_to_table2('arbbeschtxte', 'active', 'TINYINT unsigned NOT NULL DEFAULT 1 AFTER `OrdnNr`' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Measurements

CREATE TABLE IF NOT EXISTS `lut_measurements` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `project_id` INT NOT NULL,
  `measurement_id` INT NOT NULL,
  `value` DOUBLE NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE `proj_meas` (`project_id`, `measurement_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci AUTO_INCREMENT=1 ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Orte km as DOUBLE

CALL change_column('orte', 'Km', 'DOUBLE NULL DEFAULT NULL');
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- More description fields

CALL us_add_to_table2('tagessollstd', 'description', 'TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL;' );
-- EOC

CALL us_add_to_table2('lut_pers_grp', 'description', 'TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL;' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Project Offers - extras calcexp
CREATE TABLE IF NOT EXISTS `project_offers_calcexp`(
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `offer_id` INT NOT NULL,
  `wp_id` INT NOT NULL,
  `rate_type` INT NOT NULL,
  `item_id` INT NOT NULL,
  `item_quantity` DOUBLE DEFAULT 0
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Calcexp payments
-- USC Erstelle weitere X2 Tabellen - Payments.

CREATE TABLE IF NOT EXISTS `payments` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `offer_id` INT NOT NULL,
  `correspondence_type_id` INT NOT NULL,
  `from_date` datetime DEFAULT NULL COMMENT 'Optional Period of service',
  `to_date` datetime DEFAULT NULL COMMENT 'Optional Period of service',
  `fee_type` INT NOT NULL COMMENT 'instalment or final',
  `fee_no` VARCHAR(20) DEFAULT NULL COMMENT 'set when invoiced',
  `fee_date` datetime DEFAULT NULL COMMENT 'set when invoiced',
  `due_days` INT NOT NULL,
  `status` INT NOT NULL COMMENT 'PLANNED 10, INVOICED 20, INVALID 30',
  `discount` DOUBLE NOT NULL,
  `discount_days` INT NOT NULL,
  `approved_by` INT DEFAULT NULL COMMENT 'set when approved',
  `approved_date` datetime DEFAULT NULL COMMENT 'set when approved',
  `created_date` DATETIME NOT NULL,
  `created_by_id` INT NOT NULL,
  `change_date` DATETIME NOT NULL,
  `changed_by_id` INT NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci AUTO_INCREMENT=1 ;
-- EOC

CALL us_add_to_table2('payments', 'vat', 'DOUBLE DEFAULT 0 AFTER `fee_type`' );
-- EOC

CALL us_add_to_table2('payments', 'round', 'INT DEFAULT 0 AFTER `discount_days`' );
-- EOC
CALL us_add_to_table2('payments', 'round_gross', 'BOOLEAN DEFAULT FALSE AFTER `round`' );
-- EOC

CALL us_add_to_table2('payments', 'withholding_amount', 'DOUBLE NOT NULL DEFAULT 0 AFTER `value_ontop`' );
-- EOC

CALL us_add_to_table2('payments', 'value_supplement', 'DOUBLE DEFAULT 0 COMMENT \'set when approved. all values not beeing part of payments_fees.\' AFTER `approved_date`' );
-- EOC
CALL us_add_to_table2('payments', 'value_specserv', 'DOUBLE DEFAULT 0 COMMENT \'set when approved. all values not beeing part of payments_fees.\' AFTER `value_supplement`' );
-- EOC
CALL us_add_to_table2('payments', 'value_costs_supplement', 'DOUBLE DEFAULT 0 COMMENT \'set when approved. all values not beeing part of payments_fees.\' AFTER `value_specserv`' );
-- EOC
CALL us_add_to_table2('payments', 'value_extras', 'DOUBLE DEFAULT 0 COMMENT \'set when approved. all values not beeing part of payments_fees.\' AFTER `value_costs_supplement`' );
-- EOC
CALL us_add_to_table2('payments', 'value_rebate', 'DOUBLE DEFAULT 0 COMMENT \'set when approved. all values not beeing part of payments_fees.\' AFTER `value_extras`' );
-- EOC
CALL us_add_to_table2('payments', 'value_ontop', 'DOUBLE DEFAULT 0 COMMENT \'set when approved. all values not beeing part of payments_fees.\' AFTER `value_rebate`' );
-- EOC

CALL us_add_to_table2('payments', 'invoice_date', 'DATETIME NULL AFTER `status`' );
-- EOC
CALL us_add_to_table2('payments', 'corr_component_type_ids', 'LONGTEXT DEFAULT NULL AFTER `correspondence_type_id`' );
-- EOC

CALL us_add_index_to_table('payments', 'offer_id', '`offer_id`');
-- EOC

CREATE TABLE IF NOT EXISTS `payments_fees` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `payments_id` INT NOT NULL,
  `fee_areas_offer_id` INT NOT NULL,
  `percentage` DOUBLE NOT NULL,
  `value` DOUBLE DEFAULT 0 COMMENT 'set when invoiced',
  `fixed_value` DOUBLE DEFAULT 0 COMMENT 'set when invoiced',
  `value_otcurr` DOUBLE DEFAULT 0 COMMENT 'set when invoiced',
  `supplement_value` DOUBLE DEFAULT 0 COMMENT 'set when invoiced',
  `extras_value` DOUBLE DEFAULT 0 COMMENT 'set when invoiced',
  `rebate_value` DOUBLE DEFAULT 0 COMMENT 'set when invoiced',
  `supplement_otcurr` DOUBLE DEFAULT 0 COMMENT 'set when invoiced',
  `extras_otcurr` DOUBLE DEFAULT 0 COMMENT 'set when invoiced',
  `rebate_otcurr` DOUBLE DEFAULT 0 COMMENT 'set when invoiced',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci AUTO_INCREMENT=1 ;
-- EOC

CALL us_add_to_table2('payments_fees', 'fixed_value', 'DOUBLE DEFAULT 0' );
-- EOC

CALL us_add_to_table2('payments_fees', 'value_otcurr', 'DOUBLE DEFAULT 0');
-- EOC

CALL us_add_to_table2('payments_fees', 'quantity', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'supplement_value', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'extras_value', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'rebate_value', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'repetition_value', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'repetition50_value', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'repetition40_value', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'repetition10_value', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'supplement_otcurr', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'extras_otcurr', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'rebate_otcurr', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'repetition_otcurr', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'repetition50_otcurr', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'repetition40_otcurr', 'DOUBLE DEFAULT 0');
-- EOC
CALL us_add_to_table2('payments_fees', 'repetition10_otcurr', 'DOUBLE DEFAULT 0');
-- EOC

CREATE TABLE IF NOT EXISTS `payments_change_project_offer` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `payment_id` INT NOT NULL,
  `old_offer_id` INT NOT NULL,
  `new_offer_id` INT NOT NULL,
  `change_date` datetime NOT NULL,
  `staff_id` INT NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci AUTO_INCREMENT=1 ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Addresses e-mail
-- USC Erstelle weitere X2 Tabellen - E-Mail.

CREATE TABLE IF NOT EXISTS `address_emails` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `address_id` INT NOT NULL,
  `email` VARCHAR( 255 ) NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci AUTO_INCREMENT=1 ;
-- EOC

CALL us_add_to_table2('address_emails', 'description', 'LONGTEXT NULL DEFAULT NULL AFTER `email`' );
-- EOC
CALL us_add_to_table2('address_emails', 'created_by_id', 'INT NULL' );
-- EOC
CALL us_add_to_table2('address_emails', 'changed_by_id', 'INT NULL' );
-- EOC
CALL us_add_to_table2('address_emails', 'created_date', 'DATETIME NULL' );
-- EOC
CALL us_add_to_table2('address_emails', 'change_date', 'DATETIME NULL' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Cache for measurement

CREATE TABLE IF NOT EXISTS `cache_project_measurement` (
  `project_id` INT NOT NULL,
  `name_german` VARCHAR(500) NOT NULL,
  `name_germanarch` VARCHAR(500) NOT NULL,
  `name_germanch` VARCHAR(500) NOT NULL,
  `name_english` VARCHAR(500) NOT NULL,
  `name_french` VARCHAR(500) NOT NULL,
  UNIQUE KEY `project_id` (`project_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- New security_zip

CALL us_add_to_table2('formular', 'security_zip', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `Stufe`' );
-- EOC
CALL us_add_to_table2('dokattachments', 'security_zip', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `Stufe`' );
-- EOC

CALL us_add_to_table2('formart', 'security_zip', 'TINYINT unsigned NOT NULL DEFAULT 0 AFTER `Sicherheit`' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- For external systems. A key value table with type for external type
CREATE TABLE IF NOT EXISTS `external` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `type` VARCHAR(100) NOT NULL,
  `keyid` VARCHAR(100) NOT NULL,
  `value` longtext NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='For external systems';
-- EOC

CALL us_add_to_table2('external', 'url_id', 'INT DEFAULT NULL AFTER `type`' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
DROP TABLE IF EXISTS `node_chat_messages`;
-- EOC

SET @create_table_query = CONCAT(
    'CREATE TABLE IF NOT EXISTS `node_chat_messages` (',
    '`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,',
    '`staff_id` INT DEFAULT NULL,',
    '`room` VARCHAR(100) DEFAULT NULL,',
    '`message` VARCHAR(255) NOT NULL,',
    '`created_date` datetime',
    ') ENGINE=', @engineInnoDBorMemory, ' DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;'
);
-- EOC
PREPARE stmt FROM @create_table_query;
-- EOC
EXECUTE stmt;
-- EOC
DEALLOCATE PREPARE stmt;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
DROP TABLE IF EXISTS `sse_event`;
-- EOC

SET @create_table_query = CONCAT(
    'CREATE TABLE IF NOT EXISTS `sse_event` (',
    '`uniqid` VARCHAR(40) COLLATE utf8mb4_general_ci NOT NULL PRIMARY KEY,',
    '`staff_id` INT NOT NULL',
    ') ENGINE=', @engineInnoDBorMemory, ' DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;'
);
-- EOC
PREPARE stmt FROM @create_table_query;
-- EOC
EXECUTE stmt;
-- EOC
DEALLOCATE PREPARE stmt;
-- EOC

CREATE TABLE IF NOT EXISTS `sse_event_data` (
	`id` BIGINT NOT NULL AUTO_INCREMENT,
	`staff_id` INT NOT NULL,
	`data_object` LONGTEXT NULL,
	`lifetime` DATETIME NULL DEFAULT NULL,
	PRIMARY KEY (`id`)
) ENGINE=InnoDB COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('sse_event_data', 'uniqid', 'VARCHAR(40) COLLATE utf8mb4_general_ci NULL DEFAULT NULL' );
-- EOC

CALL us_add_to_table2('sse_event_data', 'ensure_execution_lock', 'DATETIME DEFAULT NULL' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Staff or office location
CREATE TABLE IF NOT EXISTS `staff_locations` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) NOT NULL,
  `address` text NOT NULL,
  `tapi` LONGTEXT NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('staff_locations', 'tapi', 'LONGTEXT NULL DEFAULT NULL AFTER `address`' );
-- EOC

-- Ensure we have always have a staff_location
INSERT INTO staff_locations (`id`, `name`, `address`) 
SELECT 1, 'Zentrale', '' FROM DUAL
WHERE NOT EXISTS (SELECT * FROM staff_locations);
-- EOC

UPDATE personen SET staff_location_id=1 WHERE staff_location_id=0;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Skill Group
-- USC Erstelle weitere X2 Tabellen - Skill Group.

CREATE TABLE IF NOT EXISTS `skill_group` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL ,
`description` LONGTEXT NULL DEFAULT NULL ,
`sort` SMALLINT NULL DEFAULT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL change_column('skill_group', 'sort', 'SMALLINT NULL DEFAULT NULL');
-- EOC

-- Skill Group - skill_group lut-table

CREATE TABLE IF NOT EXISTS `lut_staff_skill_group` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`staff_id` INT DEFAULT NULL,
`skill_id` INT DEFAULT NULL,
`from_date` DATETIME NULL,
`to_date` DATETIME NULL,
`description` LONGTEXT NULL DEFAULT NULL, 
`unique_add_id` VARCHAR(140) NULL DEFAULT NULL 
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('lut_skill_wp', 'description', 'LONGTEXT' );
-- EOC

-- Skill Group - skill_group lang-table

CREATE TABLE IF NOT EXISTS `langs_skill_groups` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`skill_id` INT DEFAULT NULL,
`name` LONGTEXT NULL DEFAULT NULL ,
`description` LONGTEXT NULL DEFAULT NULL ,
`language` VARCHAR( 50 ) NULL DEFAULT NULL 
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Report working hours

CREATE TABLE IF NOT EXISTS `report_working_hours` (
`staff_id` INT,
`skill_id` INT DEFAULT NULL,
`date` DATETIME,
`hours` FLOAT(11) DEFAULT NULL,
PRIMARY KEY(`staff_id`, `date`)
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- CALL change_column('report_working_hours', 'date', 'DATETIME DEFAULT `1900-01-01 00:00:00`');
ALTER TABLE `report_working_hours` CHANGE `date` `date` DATETIME DEFAULT '1900-01-01 00:00:00';
-- EOC

ALTER TABLE `report_working_hours` CHANGE `hours` `hours` FLOAT(11) DEFAULT NULL;
-- EOC

call remove_column('report_working_hours', 'id');
-- EOC

CALL us_add_constraint_to_table('report_working_hours', 'US_PRIMARY', 'PRIMARY', '`staff_id` , `date`' );
-- EOC

CALL us_add_to_table2('report_working_hours', 'is_vac', 'TINYINT DEFAULT 0' );
-- EOC

CREATE TABLE IF NOT EXISTS `report_working_hours_dirty` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`staff_id` INT DEFAULT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('email_cache_mboxes', 'pid', 'VARCHAR( 25 ) DEFAULT NULL AFTER `last_check_stop`' );
-- EOC

ALTER TABLE `email_cache_mboxes` CHANGE COLUMN `pid` `pid` VARCHAR(50) NULL DEFAULT NULL AFTER `last_check_stop`;
-- EOC

CREATE TABLE IF NOT EXISTS `email_cache_data` (
    `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `email_cache_mbox_id` INT NOT NULL ,
    `uid` INT NOT NULL ,
    `message_id` VARCHAR( 500 ) NOT NULL ,
    `subject` VARCHAR( 255 ) DEFAULT NULL ,
    `from` VARCHAR( 500 ) DEFAULT NULL ,
    `to` LONGTEXT DEFAULT NULL,
    `to_count` INT DEFAULT 0 ,
    `cc` LONGTEXT DEFAULT NULL,
    `cc_count` INT DEFAULT 0 ,
    `bcc` LONGTEXT DEFAULT NULL,
    `bcc_count` INT DEFAULT 0 ,
    `in_reply_to` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
    `attachments` LONGTEXT DEFAULT NULL,
    `attachments_count` INT DEFAULT 0 ,
    `date` DATETIME NOT NULL,
    `size` DOUBLE DEFAULT NULL,
    `delete` BOOLEAN DEFAULT 0,
    `text` LONGTEXT DEFAULT NULL,
    `ignored` BOOLEAN DEFAULT 0,
    UNIQUE `unique_mbox_uid` (`email_cache_mbox_id`, `uid`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('email_cache_data', 'email_cache_hash', 'VARCHAR( 500 ) DEFAULT NULL AFTER `uid`' );
-- EOC
CALL us_add_to_table2('email_cache_data', 'address_id', 'INT NOT NULL DEFAULT "0" AFTER `uid`' );
-- EOC
CALL us_add_to_table2('email_cache_data', 'project_id', 'INT NOT NULL DEFAULT "0" AFTER `address_id`' );
-- EOC

CALL change_column('email_cache_data', 'message_id', 'VARCHAR(500) NULL DEFAULT NULL');
-- EOC
CALL change_column('email_cache_data', 'from', 'VARCHAR(500) NULL DEFAULT NULL');
-- EOC
CALL change_column('email_cache_data', 'in_reply_to', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC

-- EOC

CALL us_add_to_table2('inbox', 'email_cache_id', 'BIGINT DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('inbox', 'email_cache_hash', 'VARCHAR( 500 ) DEFAULT NULL AFTER `email_cache_id`' );
-- EOC
CALL us_add_to_table2('inbox', 'email_account_id', 'INT DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('inbox', 'pid', 'VARCHAR( 25 ) DEFAULT NULL' );
-- EOC
ALTER TABLE `inbox` CHANGE COLUMN `pid` `pid` VARCHAR(50) DEFAULT NULL;
-- EOC
CALL us_add_to_table2('inbox', 'email_import_start', 'DATETIME DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('inbox', 'email_import_attempts', 'INT DEFAULT 0' );
-- EOC
CALL us_add_to_table2('inbox', 'projectmail_account_id', 'INT DEFAULT 0' );
-- EOC

CALL us_add_to_table2('outbox', 'email_cache_id', 'BIGINT DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('outbox', 'email_cache_hash', 'VARCHAR( 500 ) DEFAULT NULL AFTER `email_cache_id`' );
-- EOC
CALL us_add_to_table2('outbox', 'email_account_id', 'INT DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('outbox', 'pid', 'VARCHAR( 25 ) DEFAULT NULL' );
-- EOC
ALTER TABLE `outbox` CHANGE COLUMN `pid` `pid` VARCHAR(50) DEFAULT NULL;
-- EOC
CALL us_add_to_table2('outbox', 'email_import_start', 'DATETIME DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('outbox', 'email_import_attempts', 'INT DEFAULT 0' );
-- EOC
CALL us_add_to_table2('outbox', 'projectmail_account_id', 'INT DEFAULT 0' );
-- EOC

CREATE TABLE IF NOT EXISTS `email_projects` (
	`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
	`project_id` INT NOT NULL,
	`email_account_id` INT NOT NULL,
	`inbox` VARCHAR(255) NULL DEFAULT NULL,
	`outbox` VARCHAR(255) NULL DEFAULT NULL,
	`security` INT NOT NULL DEFAULT '3',
	`delete_after_save` BOOLEAN NOT NULL DEFAULT '0'
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Lookup Table - Projects / Staff
CREATE TABLE IF NOT EXISTS `lut_staff_proj` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `staff_id` INT NOT NULL
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_drop_index_if_exists('lut_staff_proj', 'lut_staff_proj_unique');
-- EOC

CALL us_add_to_table2('lut_staff_proj', 'staff_type', 'INT NOT NULL DEFAULT 0 AFTER `staff_id`' );
-- EOC
CALL us_add_to_table2('lut_staff_proj', 'item_id', 'INT NOT NULL AFTER `staff_type`' );
-- EOC
CALL us_add_to_table2('lut_staff_proj', 'item_type', 'INT NOT NULL AFTER `item_id`' );
-- EOC

CALL us_add_constraint_to_table('lut_staff_proj', 'lutstaffproj_items_unique', 'UNIQUE', '`staff_id` , `item_id`, `item_type`' );
-- EOC

CALL us_add_index_to_table('lut_staff_proj', 'item_id_index', '`item_id`' );
-- EOC
CALL us_add_index_to_table('lut_staff_proj', 'staff_id_index', '`staff_id`' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- Big-Bau allocation table
CREATE TABLE IF NOT EXISTS `lut_project_allocations` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `project_id` INT NOT NULL,
    `calc_project_id` INT NOT NULL,
    `target_project_id` INT NOT NULL,
    UNIQUE KEY `calc_project_unique` (`project_id`,`calc_project_id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_index_to_table('lut_project_allocations', 'project_id_index', '`project_id`' );
-- EOC
CALL us_add_index_to_table('lut_project_allocations', 'calc_project_id_index', '`calc_project_id`' );
-- EOC
CALL us_add_index_to_table('lut_project_allocations', 'target_project_id_index', '`target_project_id`' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- -- Outlook-Sync
-- CALL us_add_to_table2('outsync', 'ProfilName', 'VARCHAR(30) NULL' );
-- -- EOC
-- CALL us_add_to_table2('outsync', 'ProfilKennwort', 'VARCHAR(30) NULL' );
-- -- EOC
-- CALL us_add_to_table2('outsync', 'AutoSync', 'BOOLEAN NOT NULL DEFAULT 0' );
-- -- EOC

CREATE TABLE IF NOT EXISTS `lut_working_user` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `user_id` INT NOT NULL,
    `date` DATETIME NOT NULL,
    `type` VARCHAR(100) NOT NULL,
    `item_id` INT NOT NULL
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Update Fees
UPDATE fees SET remited=0 WHERE remited IS NULL;
-- EOC

-- UPDATE work packages NULL fields to 0
UPDATE work_packages SET budget_planned_costs = 0 WHERE budget_planned_costs IS NULL;
-- EOC
UPDATE work_packages SET budget_planned_hours = 0 WHERE budget_planned_hours IS NULL;
-- EOC
UPDATE work_packages SET budget_proportion = 0 WHERE budget_proportion IS NULL;
-- EOC
UPDATE work_packages SET fee_costs = 0 WHERE fee_costs IS NULL;
-- EOC
UPDATE work_packages SET fee_hours = 0 WHERE fee_hours IS NULL;
-- EOC
UPDATE work_packages SET fee_proportion = 0 WHERE fee_proportion IS NULL;
-- EOC
UPDATE work_packages SET completion_level = 0 WHERE completion_level IS NULL;
-- EOC

CALL change_column('work_packages', 'fee_costs', 'DOUBLE NULL DEFAULT 0');
-- EOC
CALL change_column('work_packages', 'fee_hours', 'DOUBLE NULL DEFAULT 0');
-- EOC
CALL change_column('work_packages', 'budget_planned_costs', 'DOUBLE NULL DEFAULT 0');
-- EOC
CALL change_column('work_packages', 'budget_planned_hours', 'DOUBLE NULL DEFAULT 0');
-- EOC
CALL change_column('work_packages', 'fee_proportion', 'DOUBLE NULL DEFAULT 0');
-- EOC
CALL change_column('work_packages', 'budget_proportion', 'DOUBLE NULL DEFAULT 0');
-- EOC

CREATE TABLE IF NOT EXISTS `staff_token` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `staff_id` INT NOT NULL,
  `date` DATETIME NOT NULL,
  `token` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('externalexpenses_planned', 'valid_from', 'datetime DEFAULT NULL' );
-- EOC

UPDATE externalexpenses_planned SET `valid_from` = `created_date` WHERE `valid_from` IS NULL;
-- EOC

-- Add fee_categories
CREATE TABLE IF NOT EXISTS `fee_categories` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `name` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Add translation tables
CREATE TABLE IF NOT EXISTS `langs_fee_categories` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `fee_category_id` INT NOT NULL,
    `name` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    `language` VARCHAR( 50 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
    PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- EOC

CALL us_add_constraint_to_table('langs_fee_categories', 'langs_fee_categories_unique_1', 'UNIQUE', '`name` , `language`' );
-- EOC


CALL us_add_to_table2('externalexpenses', 'fee_category_id', 'INT DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('externalexpenses_planned', 'fee_category_id', 'INT DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('fees', 'fee_category_id', 'INT DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('fees_planned', 'fee_category_id', 'INT DEFAULT NULL' );
-- EOC


CALL us_add_to_table2('externalexpenses', 'currency_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('externalexpenses', 'value_otcurr', 'DOUBLE DEFAULT NULL');
-- EOC
CALL us_add_to_table2('externalexpenses_planned', 'currency_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('externalexpenses_planned', 'value_otcurr', 'DOUBLE DEFAULT NULL');
-- EOC


CALL us_add_to_table2('fees', 'currency_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('fees', 'value_otcurr', 'DOUBLE DEFAULT NULL');
-- EOC
CALL us_add_to_table2('fees', 'remited_otcurr', 'DOUBLE DEFAULT NULL');
-- EOC
CALL us_add_to_table2('fees', 'deduction_otcurr', 'DOUBLE DEFAULT NULL');
-- EOC
CALL us_add_to_table2('fees', 'retention_type', 'INT NOT NULL DEFAULT 0');
-- EOC
CALL us_add_to_table2('fees', 'retention_date', 'DATETIME NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('fees', 'retention', 'DOUBLE NOT NULL DEFAULT 0');
-- EOC
CALL us_add_to_table2('fees', 'from_date', 'datetime DEFAULT NULL COMMENT \'Optional Period of service\'');
-- EOC
CALL us_add_to_table2('fees', 'to_date', 'datetime DEFAULT NULL COMMENT \'Optional Period of service\'');
-- EOC
CALL us_add_to_table2('fees', 'remited_is_withholded', 'BOOLEAN DEFAULT FALSE');
-- EOC
CALL us_add_to_table2('fees_planned', 'currency_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('fees_planned', 'value_otcurr', 'DOUBLE DEFAULT NULL');
-- EOC
CALL us_add_to_table2('fees_planned', 'remited_otcurr', 'DOUBLE DEFAULT NULL');
-- EOC
CALL us_add_to_table2('fees_planned', 'deduction_otcurr', 'DOUBLE DEFAULT NULL');
-- EOC
CALL us_add_to_table2('fees_planned', 'retention_type', 'INT NOT NULL DEFAULT 0');
-- EOC
CALL us_add_to_table2('fees_planned', 'retention_date', 'DATETIME NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('fees_planned', 'retention', 'DOUBLE NOT NULL DEFAULT 0');
-- EOC
CALL us_add_to_table2('fees_planned', 'from_date', 'datetime DEFAULT NULL COMMENT \'Optional Period of service\'');
-- EOC
CALL us_add_to_table2('fees_planned', 'to_date', 'datetime DEFAULT NULL COMMENT \'Optional Period of service\'');
-- EOC
CALL us_add_to_table2('fees_planned', 'remited_is_withholded', 'BOOLEAN DEFAULT FALSE');
-- EOC


CALL us_add_to_table2('formular', 'fee_currency_id', 'INT NULL DEFAULT NULL');
-- EOC
CALL us_add_to_table2('formular', 'fee_value_otcurr', 'DOUBLE DEFAULT NULL');
-- EOC

CALL us_add_to_table2('uv_buchungen', 'is_absent_social', 'BOOLEAN DEFAULT FALSE AFTER `UV_ZA`' );
-- EOC

DROP TABLE IF EXISTS portlets_settings;
-- EOC

CREATE TABLE IF NOT EXISTS `portlets_settings` (
	`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
	`portlet_id` VARCHAR(100) NOT NULL,
	`allow_right` BOOLEAN NOT NULL DEFAULT '0',
	UNIQUE INDEX `portlet_id` (`portlet_id`)
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Funpic_portlet', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Sysinfo_portlet', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Webinar_view', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Active_users', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Call_phone', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Send_sms_at', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Iframe', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Rss_view', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Daily_hint', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Exchange_rate', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Numbergeneration', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Timelogging_active_staff', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Timelogging_select', 1);
-- EOC
INSERT INTO `portlets_settings` (`id`, `portlet_id`, `allow_right`) VALUES (null, 'Com_untermstrich_us_download', 1);
-- EOC

-- Remove Portlet_admin from db
DELETE FROM portlets WHERE portlet_id='Portlet_admin';
-- EOC

-- -------------------------------------------------------------
-- Move the prohibited portlets from the rightblock to a new tab
-- -------------------------------------------------------------
DROP PROCEDURE IF EXISTS move_prohibited_portlets_from_rightblock;
-- EOC

DELIMITER $$
CREATE PROCEDURE move_prohibited_portlets_from_rightblock()
BEGIN
    DECLARE cur_id INTEGER;
    DECLARE cur_portlet_id VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE cur_staff_id INTEGER;
    DECLARE cur_page_id INTEGER;
    DECLARE cur_tab_id INTEGER;
    DECLARE last_staff_id INTEGER;
    DECLARE last_page_id INTEGER;	
    DECLARE last_row_fetched INTEGER;

    DECLARE portlets_to_move CURSOR FOR SELECT id, portlet_id, staff_id, page_id FROM portlets where 
        position_id = 'rightblockcontent' AND
        portlet_id NOT IN(SELECT portlet_id from portlets_settings where allow_right = 1) ORDER BY staff_id, page_id, col;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET last_row_fetched=1;	

    SET last_row_fetched = 0;	
    SET last_staff_id = -1;
    SET last_page_id = -1;	
    OPEN portlets_to_move;
        cursor_loop: LOOP -- -------------------------------------
            FETCH portlets_to_move INTO cur_id, cur_portlet_id, cur_staff_id, cur_page_id;
            IF last_row_fetched = 1 THEN
                LEAVE cursor_loop;
            END IF;
            /*Have to reset page_id cause page 1 is available for all users*/
            IF (cur_staff_id != last_staff_id) THEN 
                SET last_page_id = -1;
            END IF;

            /*Create a new tab*/
            IF (cur_staff_id != last_staff_id OR cur_page_id != last_page_id) THEN 
                /* SET by SELECT */
                SELECT (IFNULL(MAX(portlets_tabs.sort), 0)+1)
                    INTO @nextsort
                    FROM portlets_tabs WHERE staff_id= cur_staff_id AND page_id=cur_page_id;
                SET @s = CONCAT('INSERT INTO portlets_tabs (staff_id, page_id, name, `columns`, `sort`) VALUES (', cur_staff_id, ', ', cur_page_id,', "von rechts", 1, ', @nextsort, ')');
                PREPARE stmt11 FROM @s;
                EXECUTE stmt11;
                SET cur_tab_id = LAST_INSERT_ID();
            END IF;

            /*Move*/
            SET @nextrow = COALESCE((SELECT IFNULL(MAX(portlets.row), 0)+1 FROM portlets WHERE tab= cur_tab_id), 0);
            SET @s = CONCAT('UPDATE portlets SET tab=',cur_tab_id,', position_id="midblockcontent", `col`=0, `row`=',@nextrow,' WHERE id=',cur_id);
            PREPARE stmt11 FROM @s;
            EXECUTE stmt11;					

            /*Set last_..._id*/
            SET last_staff_id = cur_staff_id;
            SET last_page_id = cur_page_id;
        END LOOP cursor_loop; -- -------------------------------------
    CLOSE  portlets_to_move;		
    SET last_row_fetched = 0;	
END $$
DELIMITER ;
-- EOC

CALL move_prohibited_portlets_from_rightblock();
-- EOC

-- -------------------------------------------------------------
-- Copy portlets
-- -------------------------------------------------------------
DROP PROCEDURE IF EXISTS copy_portlets;
-- EOC

DELIMITER $$
CREATE PROCEDURE copy_portlets(
	IN from_staff_id INTEGER,
	IN to_staff_ids LONGTEXT,
	IN page_ids LONGTEXT,
    OUT validation_string VARCHAR(4) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
BEGIN
	DECLARE from_tab_id INT;
	DECLARE from_tab_name VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
	DECLARE from_tab_columns INT;
	DECLARE from_tab_color INT;
	DECLARE from_tab_sort SMALLINT;
	
	DECLARE l_last_row_fetched_portlets_tabs INTEGER;
	DECLARE cur_portlets_tabs CURSOR FOR SELECT * FROM tmp_copy_portlets_tabs;
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched_portlets_tabs=1;

	-- Clean and prepare string parameters
	SET to_staff_ids = TRIM(BOTH ',' FROM REPLACE(to_staff_ids, ' ', ''));
	SET page_ids = TRIM(BOTH ',' FROM REPLACE(page_ids, ' ', ''));    
	 
	-- Get staff_to_ids and page_ids from database if not defined by parameter
	IF to_staff_ids = '' THEN
		SELECT GROUP_CONCAT(id) INTO to_staff_ids FROM staff WHERE id != from_staff_id;
	END IF;
	IF page_ids = '' THEN
		SELECT GROUP_CONCAT(id) INTO page_ids FROM portlets_pages;
	END IF;  

	-- Get count of staff_to_ids and page_ids
	SET @staff_to_count = LENGTH(to_staff_ids)- LENGTH(REPLACE(to_staff_ids,',','')) + 1;
	SET @page_count = LENGTH(page_ids)- LENGTH(REPLACE(page_ids,',','')) + 1;
 
	-- Iterate page_ids
	SET @ii = 1;
	WHILE @ii <= @page_count DO
		SET @curr_page_id = REPLACE(SUBSTRING_INDEX(page_ids, ',', @ii), CONCAT(SUBSTRING_INDEX(page_ids, ',', @ii - 1), ','), '');
   	
		-- Get portlets_tabs of page
		DROP VIEW IF EXISTS tmp_copy_portlets_tabs;
		SET @v = CONCAT('CREATE OR REPLACE VIEW tmp_copy_portlets_tabs as SELECT id, name, columns, color, sort FROM portlets_tabs WHERE staff_id = ',from_staff_id,' AND page_id = ', @curr_page_id);
		PREPARE stm FROM @v;
		EXECUTE stm;
		DEALLOCATE PREPARE stm;
		
		-- Iterate staff_to_ids for each page
		SET @i = 1;
		loop_staff: WHILE @i <= @staff_to_count DO
			-- Get current staff_to id
			SET @curr_staff_to_id = REPLACE(SUBSTRING_INDEX(to_staff_ids, ',', @i), CONCAT(SUBSTRING_INDEX(to_staff_ids, ',', @i - 1), ','), '');	
			
			-- Skip loop iteration if staff_from_id equals staff_to_id
			IF from_staff_id=@curr_staff_to_id THEN
         	    ITERATE loop_staff;
     		END IF; 
			
			-- DROP portlets_tabs for page and staff
			DELETE FROM portlets_tabs WHERE `page_id`=@curr_page_id AND staff_id=@curr_staff_to_id;
			-- DROP portlets for page and staff
			DELETE FROM portlets WHERE `page_id`=@curr_page_id AND staff_id=@curr_staff_to_id;

			-- Iterate all tabs
			SET l_last_row_fetched_portlets_tabs=0;
			OPEN cur_portlets_tabs;
			portlets_tabs_loop: LOOP -- -------------------------------------
				FETCH cur_portlets_tabs INTO from_tab_id, from_tab_name, from_tab_columns, from_tab_color, from_tab_sort;
				IF l_last_row_fetched_portlets_tabs = 1 THEN
					LEAVE portlets_tabs_loop;
				END IF;
					-- Create new tab
					INSERT INTO portlets_tabs (`staff_id`, `page_id`, `name`, `columns`, `color`, `sort`) VALUES(@curr_staff_to_id, @curr_page_id, from_tab_name, from_tab_columns, from_tab_color, from_tab_sort);
					SET @insert_tab_id = LAST_INSERT_ID();
					-- Now copy all portlets
					INSERT INTO portlets (`position_id`,`portlet_id`,`unique_id`,`staff_id`,`col`,`row`,`tab`,`page_id`,`open`,`data`,`title`,`auto_refresh`) 
					SELECT `position_id`,`portlet_id`, CONCAT('a',SUBSTRING(SHA1(RAND()),1,13)), @curr_staff_to_id, `col`,`row`, @insert_tab_id, `page_id`,`open`,`data`,`title`,`auto_refresh`
					FROM portlets WHERE `tab` = from_tab_id;
			END LOOP portlets_tabs_loop; -- -------------------------------------
			CLOSE  cur_portlets_tabs;
			SET l_last_row_fetched_portlets_tabs=0;	
			
			-- Also copy rightblockcontent if page_id = 1			
			IF @curr_page_id = 1 THEN
				INSERT INTO portlets (`position_id`,`portlet_id`,`unique_id`,`staff_id`,`col`,`row`,`tab`,`page_id`,`open`,`data`,`title`,`auto_refresh`) 
				SELECT `position_id`,`portlet_id`, CONCAT('a',SUBSTRING(SHA1(RAND()),1,13)), @curr_staff_to_id, `col`,`row`, null, `page_id`,`open`,`data`,`title`,`auto_refresh`
				FROM portlets WHERE `tab` IS NULL AND staff_id = from_staff_id;
			END IF;
						
			SET @i = @i + 1;
		END WHILE;

		SET @ii = @ii + 1;
	END WHILE;
	
	-- Remove temp view
	DROP VIEW IF EXISTS tmp_copy_portlets_tabs;

    SET validation_string = 'true';	
END $$
DELIMITER ;
-- EOC

CREATE TABLE IF NOT EXISTS `fees_collective_bill` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `collective_id` INT NOT NULL COMMENT 'correspondence ID of collective bill',
    `fees_id` INT NOT NULL,
    `correspondence_id` INT NULL,
    PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CREATE TABLE IF NOT EXISTS `project_collective_offer` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `collective_id` INT NOT NULL COMMENT 'correspondence ID of collective offer',
    `offer_id` INT NOT NULL,
    `correspondence_id` INT NULL,
    PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CREATE TABLE IF NOT EXISTS `email_projects` (
	`id` INT NOT NULL AUTO_INCREMENT,
	`project_id` INT NOT NULL,
	`email_account_id` INT NOT NULL,
	`inbox` VARCHAR(255) NULL DEFAULT NULL,
	`outbox` VARCHAR(255) NULL DEFAULT NULL,
	`security` INT NOT NULL DEFAULT '3',
	`delete_after_save` BOOLEAN NOT NULL DEFAULT '0',
	PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

DROP TABLE IF EXISTS `watchdog`;
-- EOC

SET @create_table_query = CONCAT(
    'CREATE TABLE IF NOT EXISTS `watchdog` (',
    '`keyname` VARCHAR(255) NOT NULL,',
    '`created` DATETIME NOT NULL,',
    '`updated` DATETIME NOT NULL,',
    'PRIMARY KEY (`keyname`)',
    ') ENGINE=', @engineInnoDBorMemory, ' DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;'
);
-- EOC
PREPARE stmt FROM @create_table_query;
-- EOC
EXECUTE stmt;
-- EOC
DEALLOCATE PREPARE stmt;
-- EOC

CREATE TABLE IF NOT EXISTS `address_signatures` (
	`id` INT NOT NULL AUTO_INCREMENT,
        `name` VARCHAR(255) NULL DEFAULT NULL,
        `main` longtext NULL DEFAULT NULL,
        `main_plain` longtext NULL DEFAULT NULL,
        `main_subject` VARCHAR(255) NULL DEFAULT NULL,
        `appoi` longtext NULL DEFAULT NULL,
        `appoi_plain` longtext NULL DEFAULT NULL,
        `appoi_subject` VARCHAR(255) NULL DEFAULT NULL,
        `opta` longtext NULL DEFAULT NULL,
        `opta_plain` longtext NULL DEFAULT NULL,
        `opta_subject` VARCHAR(255) NULL DEFAULT NULL,
	PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

INSERT INTO address_signatures SELECT 1 as id, 'Standard' as `name`, 
null as main, null as main_plain, null as main_subject, null as appoi, null as appoi_plain, null as appoi_subject, null as opta, null as opta_plain, null as opta_subject
FROM address_signatures
WHERE (id=1)
HAVING COUNT(*) = 0;
-- EOC

CALL update_lut_fee_areas_offer_add_fields();
-- EOC

CALL update_lut_fee_areas_offer_calc_rebate_first();
-- EOC
    
-- us_create_u10_session_log ---------------------------------------------------
-- USC Erstelle weitere X2 Tabellen - Session log.
DROP PROCEDURE IF EXISTS us_create_u10_session_log;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_create_u10_session_log()
BEGIN

    DECLARE sql1 TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci 
        DEFAULT 'CREATE TABLE IF NOT EXISTS `u10_session_log` (
        `info` VARCHAR(500) NOT NULL,

        `session_id` VARCHAR(40) COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
        `old1_session_id` VARCHAR(40) COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
        `old2_session_id` VARCHAR(40) COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
        `session_uniqid` VARCHAR(40) COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
        `ip_address` VARCHAR(50) COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
        `user_agent` VARCHAR(50) COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
        `last_activity` INT unsigned NULL DEFAULT NULL,

        `aktuser_id` INT NULL DEFAULT NULL COMMENT "LfdNr_AktUser",
        `staff_id` INT NULL DEFAULT NULL COMMENT "UserNummer",
        `staff_name` VARCHAR(50) NULL DEFAULT NULL COMMENT "UserName",
        `login_update_time` datetime NULL DEFAULT NULL COMMENT "LoginTime",
        `browser_info` VARCHAR(50) NULL DEFAULT NULL COMMENT "WorkstationName",
        `aktuser_uniqid` VARCHAR(50) NULL DEFAULT NULL COMMENT "WorkstationLogin",

        `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    ) ENGINE=';

    DECLARE sql2 TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;';

    DROP TABLE IF EXISTS `u10_session_log`;

    SELECT GetStorageEngine ('ARCHIVE') INTO @engineInnoDBorArchive;
    SET @s = CONCAT(sql1, @engineInnoDBorArchive, sql2);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

END $$
DELIMITER ;
-- EOC

CALL us_create_u10_session_log();
-- EOC

CALL change_column('u10_session_log', 'ip_address', 'VARCHAR(50) COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC

-- Add new field received_from -------------------------------------------------
CALL us_add_to_table2('drawings', 'received_from', 'INT DEFAULT NULL AFTER date' );
-- EOC

CALL us_add_to_table2('opendocs', 'session_uniqid', 'VARCHAR(40) COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `User_LfdNr`' );
-- EOC

-- Add new field lock_time - Will fail before 5.6.5
CALL us_add_to_table2('opendocs', 'lock_time', 'DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER `session_uniqid`' );
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Allow holiday_rates to be set inactive
CALL us_add_to_table2('feiertagsatz', 'is_active', 'INT DEFAULT 1' );
-- EOC

-- us_create_reports_history ---------------------------------------------------
DROP PROCEDURE IF EXISTS us_create_reports_history;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_create_reports_history()
BEGIN

    DECLARE sql1 TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci 
        DEFAULT 'CREATE TABLE IF NOT EXISTS `reports_history` (
        `report_id` VARCHAR(255) NOT NULL,
        `created_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        `data` LONGTEXT NOT NULL,
        `for_date` DATE NOT NULL
    ) ENGINE=';

    DECLARE sql2 TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;';

    SELECT GetStorageEngine ('ARCHIVE') INTO @engineInnoDBorArchive;
    SET @s = CONCAT(sql1, @engineInnoDBorArchive, sql2);
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;

END $$
DELIMITER ;
-- EOC

CALL us_create_reports_history();
-- EOC

CALL remove_pk_column('reports_history', 'id');
-- EOC

CREATE TABLE IF NOT EXISTS `home_office` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `staff_id` INT NOT NULL,
    `date` DATE NOT NULL,
    `in_home_office` TINYINT NOT NULL,
    `change_date` DATETIME NOT NULL,
    `changed_by_id` INT NOT NULL,
    PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- More space for URLs
ALTER TABLE `perstermin` CHANGE COLUMN `Ort` `Ort` TEXT COLLATE utf8mb4_general_ci NULL DEFAULT NULL;
-- EOC

ALTER TABLE `adressen` CHANGE COLUMN `URL` `URL` TEXT COLLATE utf8mb4_general_ci NULL DEFAULT NULL;
-- EOC

-- Office 365
-- USC Erstelle weitere X2 Tabellen - Office 365.
ALTER TABLE `projekte` CHANGE COLUMN `SV_Pfad` `SV_Pfad` VARCHAR(500) NULL DEFAULT NULL;
-- EOC
ALTER TABLE `projekte` CHANGE COLUMN `path_correspondence_default` `path_correspondence_default` VARCHAR(500) NULL DEFAULT NULL;
-- EOC
CREATE TABLE IF NOT EXISTS `correspondence_temp_edit` (
	`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
	`correspondence_id` INT NOT NULL,
	`staff_id` INT NOT NULL,
	`oauth_account_id` INT NULL DEFAULT NULL,
	`path` VARCHAR(500) NOT NULL,
    `type` INTEGER UNSIGNED,
	`change_date` DATETIME NULL DEFAULT NULL,
	PRIMARY KEY (`id`),
	INDEX `correspondence_id` (`correspondence_id`),
	INDEX `staff_id` (`staff_id`)
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC
ALTER TABLE `projekte` CHANGE COLUMN `EM_Pfad` `EM_Pfad` VARCHAR(500) NULL DEFAULT NULL;
-- EOC
ALTER TABLE `projekte` CHANGE COLUMN `path_inbox_default` `path_inbox_default` VARCHAR(500) NULL DEFAULT NULL;
-- EOC
ALTER TABLE `projekte` CHANGE COLUMN `EM_OUT_Pfad` `EM_OUT_Pfad` VARCHAR(500) NULL DEFAULT NULL;
-- EOC
ALTER TABLE `projekte` CHANGE COLUMN `path_outbox_default` `path_outbox_default` VARCHAR(500) NULL DEFAULT NULL;
-- EOC
ALTER TABLE `projekte` CHANGE COLUMN `planpfad` `planpfad` VARCHAR(500) NULL DEFAULT NULL;
-- EOC
ALTER TABLE `projekte` CHANGE COLUMN `path_drawings_default` `path_drawings_default` VARCHAR(500) NULL DEFAULT NULL;
-- EOC
ALTER TABLE `projekte` CHANGE COLUMN `orig_structure_tree_root_node` `orig_structure_tree_root_node` VARCHAR(500) NULL DEFAULT NULL;
-- EOC
ALTER TABLE `projekte` CHANGE COLUMN `orig_translated_structure_tree_root_node` `orig_translated_structure_tree_root_node` VARCHAR(500) NULL DEFAULT NULL;
-- EOC
CALL change_column('projektangebot', 'datei', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC
CALL change_column('lut_adr_dateien', 'Datei', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC
CALL change_column('poausattachments', 'PoAtt_Pfad', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL');
-- EOC

-- GoBD
-- Correspondence
CALL us_add_to_table2('formular', 'gobd_date', 'DATETIME DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('formular', 'gobd_hash', 'VARCHAR(40) DEFAULT NULL' );
-- EOC-- outbox
CALL us_add_to_table2('outbox', 'gobd_date', 'DATETIME DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('outbox', 'gobd_hash', 'VARCHAR(40) DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('formular', 'from_date', 'datetime DEFAULT NULL COMMENT \'Optional Period of service\'');
-- EOC
CALL us_add_to_table2('formular', 'to_date', 'datetime DEFAULT NULL COMMENT \'Optional Period of service\'');
-- EOC

ALTER TABLE `externalexpenses` CHANGE COLUMN `is_deducted` `is_deducted` TINYINT UNSIGNED NULL DEFAULT NULL ;
-- EOC

CALL us_add_to_table2('uv_buchungen', 'is_ok_pre', 'TINYINT UNSIGNED NOT NULL DEFAULT 0 AFTER `UV_OK`' );
-- EOC
CALL us_add_to_table2('uv_buchungen', 'work_package_id', 'INT NULL DEFAULT NULL AFTER `LfdNr_Projekt`' );
-- EOC

ALTER TABLE `formular` CHANGE COLUMN `RechnungsNummer` `RechnungsNummer` VARCHAR(100) COLLATE utf8mb4_general_ci NULL DEFAULT NULL ;
-- EOC

ALTER TABLE `fees` CHANGE COLUMN `fee_no` `fee_no` VARCHAR(100) COLLATE utf8mb4_general_ci NULL DEFAULT NULL ;
-- EOC

ALTER TABLE `fees_planned` CHANGE COLUMN `fee_no` `fee_no` VARCHAR(100) COLLATE utf8mb4_general_ci NULL DEFAULT NULL ;
-- EOC

ALTER TABLE `payments` CHANGE COLUMN `fee_no` `fee_no` VARCHAR(30) COLLATE utf8mb4_general_ci NULL DEFAULT NULL ;
-- EOC

-- Rename old is_deducted columns
CALL check_rename_column_exists('times', 'is_deducted', 'is_deducted_old', 'TINYINT UNSIGNED NULL DEFAULT NULL');
-- EOC
CALL check_rename_column_exists('times', 'is_deducted_staff', 'is_deducted_staff_old', 'TINYINT UNSIGNED NULL DEFAULT NULL');
-- EOC
CALL check_rename_column_exists('times', 'is_deducted_woa', 'is_deducted_woa_old', 'TINYINT UNSIGNED NULL DEFAULT NULL');
-- EOC

CALL check_rename_column_exists('extras', 'is_deducted', 'is_deducted_old', 'TINYINT UNSIGNED NULL DEFAULT NULL');
-- EOC

CALL check_rename_column_exists('travels', 'is_deducted', 'is_deducted_old', 'TINYINT UNSIGNED NULL DEFAULT NULL');
-- EOC

CREATE TABLE IF NOT EXISTS `personalappointments_ical_token` (
	`id` INT NOT NULL AUTO_INCREMENT,
	`staff_id` INT NOT NULL,
	`created_by_id` INT NOT NULL,
	`token` VARCHAR(40) NOT NULL COLLATE 'utf8mb4_general_ci',
	PRIMARY KEY (`id`),
	UNIQUE INDEX `token` (`token`)
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('personalappointments_ical_token', 'comment', 'VARCHAR(255) COLLATE utf8mb4_general_ci DEFAULT NULL AFTER `token`');
-- EOC

CREATE TABLE IF NOT EXISTS `action_log` (
	`id` INT NOT NULL AUTO_INCREMENT,
	`staff_id` INT NOT NULL,
    `year` INT NOT NULL,
    `month` INT DEFAULT NULL,
	`section` VARCHAR(255) NOT NULL,
	`page` VARCHAR(255) NULL,
	`portletorviewname` VARCHAR(255) DEFAULT NULL,
	`portletorviewaction` VARCHAR(255) DEFAULT NULL,
	`count` BIGINT NOT NULL,
	PRIMARY KEY (`id`),
	UNIQUE INDEX `actionfullidx` (`staff_id`, `year`,  `month`, `section` (100), `page` (100), `portletorviewname` (100), `portletorviewaction` (100))
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('action_log', 'year', 'INT NOT NULL DEFAULT 2024 AFTER `staff_id`' );
-- EOC

CALL us_add_to_table2('action_log', 'month', 'INT DEFAULT NULL AFTER `year`' );
-- EOC

CALL us_drop_index_if_exists('action_log', 'actionidx');
-- EOC

CALL us_add_constraint_to_table('action_log', 'actionfullidx', 'UNIQUE', '`staff_id`, `year`,  `month`, `section` (100), `page` (100), `portletorviewname` (100), `portletorviewaction` (100)');
-- EOC

-- ADD edit until values
CALL us_add_to_table2('times', 'allow_edit_until', 'datetime DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('travels', 'allow_edit_until', 'datetime DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('extras', 'allow_edit_until', 'datetime DEFAULT NULL' );
-- EOC

CALL change_column('adrkategorien', 'Bezeichnung', 'VARCHAR(100) NULL DEFAULT NULL');
-- EOC

CREATE TABLE IF NOT EXISTS `form_vars` (
    `id` INT NOT NULL AUTO_INCREMENT,
    `description` VARCHAR(255) NOT NULL,
    `content` LONGTEXT NULL,
    PRIMARY KEY (`id`)
    ) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CALL us_add_to_table2('externalexpenses', 'correspondence_id', 'INT NULL AFTER `address_id`' );
-- EOC
CALL us_add_to_table2('externalexpenses', 'invoice_number', 'VARCHAR(255) NULL DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('externalexpenses', 'invoice_due_date', 'datetime DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('externalexpenses', 'invoice_json', 'LONGTEXT' );
-- EOC

CALL us_add_to_table2('externalexpenses_planned', 'correspondence_id', 'INT NULL AFTER `address_id`' );
-- EOC
CALL us_add_to_table2('externalexpenses_planned', 'invoice_number', 'VARCHAR(255) NULL DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('externalexpenses_planned', 'invoice_due_date', 'datetime DEFAULT NULL' );
-- EOC
CALL us_add_to_table2('externalexpenses_planned', 'invoice_json', 'LONGTEXT' );
-- EOC

CREATE TABLE IF NOT EXISTS `personalappointments_ext_calendars` (
    `id` INT(10) NOT NULL AUTO_INCREMENT,
    `ext_calendar_id` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
    `staff_id` INT(10) NOT NULL,
    `ext_staff_id` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_general_ci',
    `name` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_general_ci',
    `type` ENUM('O365', 'O365_INACTIVE') NOT NULL DEFAULT 'O365' COLLATE 'utf8mb4_general_ci',
    `last_check_start` DATETIME NULL DEFAULT NULL,
    `last_check_stop` DATETIME NULL DEFAULT NULL,
    `delta_links` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
    PRIMARY KEY (`id`) USING BTREE
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

CREATE TABLE IF NOT EXISTS `personalappointments_ext_o365` (
	`id` INT(10) NOT NULL AUTO_INCREMENT,
	`ext_id` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_general_ci',
	`calendar_id` INT(10) NOT NULL,
    `icaluid` TEXT NOT NULL COLLATE 'utf8mb4_general_ci',
	`is_series_master` TINYINT UNSIGNED NOT NULL DEFAULT '0',
    `organizer_email` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_general_ci',
    `organizer_staff_id` INT(10) NULL DEFAULT NULL,
	`date` DATETIME NULL DEFAULT NULL,
	`time_from` DATETIME NULL DEFAULT NULL,
	`date_to` DATETIME NULL DEFAULT NULL,    
	`time_to` DATETIME NULL DEFAULT NULL,
	`project_id` INT(10) NULL DEFAULT NULL,
	`staff_from_id` INT(10) NULL DEFAULT NULL,
	`staff_to_id` INT(10) NULL DEFAULT NULL,
	`location` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
	`url` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
	`summary` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
	`comment` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
    `comment_html` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
	`created_date` DATETIME NULL DEFAULT NULL,
	`created_by_id` INT(10) NULL DEFAULT NULL,
	`change_date` DATETIME NULL DEFAULT NULL,
	`changed_by_id` INT(10) NULL DEFAULT NULL,
	`is_new` TINYINT UNSIGNED NOT NULL DEFAULT '0',
	`is_private` TINYINT UNSIGNED NOT NULL DEFAULT '0',
	`multistaff_first_id` INT(10) NULL DEFAULT NULL,
	`several_days` TINYINT UNSIGNED NOT NULL DEFAULT '0',
	`several_days_first_id` INT(10) NULL DEFAULT NULL,
	`several_days_last_date` DATETIME NULL DEFAULT NULL,
	`several_days_day` INT(10) NULL DEFAULT NULL,
	`periodical` SMALLINT(5) NULL DEFAULT NULL,
	`app_type` SMALLINT(5) NULL DEFAULT NULL,
	`periodical_last_date` DATETIME NULL DEFAULT NULL,
	`periodical_first_id` INT(10) NULL DEFAULT NULL,
	`is_notify` TINYINT UNSIGNED NOT NULL DEFAULT '0',
	`notify_date` DATETIME NULL DEFAULT NULL,
	`status` INT(10) NULL DEFAULT NULL,
	`vacation_id` INT(10) NULL DEFAULT NULL,
	`changed_time_from` TINYINT UNSIGNED NOT NULL DEFAULT '0',
	`changed_location` TINYINT UNSIGNED NOT NULL DEFAULT '0',
	`changed_url` TINYINT NOT NULL DEFAULT '0',
	`changed_summary` TINYINT NOT NULL DEFAULT '0',
	`changed_comment` TINYINT UNSIGNED NOT NULL DEFAULT '0',
	`changed_time_to` TINYINT UNSIGNED NOT NULL DEFAULT '0',
	`changed_project_id` TINYINT UNSIGNED NOT NULL DEFAULT '0',
	`changed_is_notify` TINYINT UNSIGNED NOT NULL DEFAULT '0',
	`changed_notify_date` TINYINT UNSIGNED NOT NULL DEFAULT '0',
	`changed_status` TINYINT UNSIGNED NOT NULL DEFAULT '0',
	`state_color_id` INT(10) NULL DEFAULT NULL,
    `attendees` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
    `o365_data` LONGTEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
	PRIMARY KEY (`id`) USING BTREE,
	INDEX `personalappointments_ext_o365_project` (`project_id`) USING BTREE,
	INDEX `personalappointments_ext_o365_staff_from_id` (`staff_from_id`) USING BTREE,
	INDEX `personalappointments_ext_o365_staff_to_id` (`staff_to_id`) USING BTREE,
	INDEX `personalappointments_ext_o365_created_by_id` (`created_by_id`) USING BTREE,
	INDEX `personalappointments_ext_o365_changed_by_id` (`changed_by_id`) USING BTREE,
	INDEX `personalappointments_ext_o365_multistaff_first_id` (`multistaff_first_id`) USING BTREE,
	INDEX `personalappointments_ext_o365_several_days_first_id` (`several_days_first_id`) USING BTREE,
	INDEX `personalappointments_ext_o365_periodical_first_id` (`periodical_first_id`) USING BTREE,
	INDEX `personalappointments_ext_o365_vacation_id` (`vacation_id`) USING BTREE
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC
CALL change_column('personalappointments_ext_o365', 'icaluid', 'TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL');
-- EOC
CALL us_add_index_to_table('personalappointments_ext_o365', 'icaluid_index', '`icaluid`(150)' );
-- EOC
-- Make ext_id ascii for better performance and length limitations for UNIQUE KEY
CALL change_column('personalappointments_ext_o365', 'ext_id', 'VARCHAR(255) CHARACTER SET ascii COLLATE ascii_bin NOT NULL');
-- EOC
-- Sync modes - in_sync=evetns new from o365 or already synced migrated events, to_sync=migrated events which are not synced to o365 yet, no_sync=migrated events which will not synced to o365 in future
CALL us_add_to_table2('personalappointments_ext_o365', 'sync_mode', 'enum(\'in_sync\', \'to_sync\', \'no_sync\') COLLATE utf8mb4_general_ci DEFAULT \'in_sync\' AFTER `o365_data`'  );
-- EOC
CALL us_add_to_table2('personalappointments_ext_o365', 'uuid', 'CHAR(36) DEFAULT NULL AFTER `id`' );
-- EOC
CALL us_add_constraint_to_table('personalappointments_ext_o365', 'uuid_unique', 'UNIQUE', '`uuid`' );
-- EOC
UPDATE personalappointments_ext_o365 SET uuid = us_uuid_v4() WHERE uuid IS NULL;
-- EOC

DROP VIEW IF EXISTS `personalappointments_ext_o365_listview`;
-- EOC
CREATE VIEW `personalappointments_ext_o365_listview` AS SELECT * FROM personalappointments_ext_o365 WHERE is_series_master != 1;
-- EOC
CREATE TABLE IF NOT EXISTS `lut_personalapp_address_ext_o365` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `personalapp_id` int(11) DEFAULT NULL,
  `address_id` int(11) DEFAULT NULL,
  `sort` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC
-- Delete duplicates in lut_personalapp_address_ext_o365
DELETE t1 FROM lut_personalapp_address_ext_o365 t1 INNER JOIN lut_personalapp_address_ext_o365 t2 ON t1.personalapp_id = t2.personalapp_id AND t1.address_id = t2.address_id WHERE t1.id > t2.id;
-- EOC
-- Robustly remove duplicates in lut_termin_teilnehmer by keeping the smallest LfdNr per (LfdNr_Termin, LfdNr_Adr)
DELETE t
FROM lut_termin_teilnehmer t
LEFT JOIN (
    SELECT MIN(LfdNr) AS min_id
    FROM lut_termin_teilnehmer
    GROUP BY LfdNr_Termin, LfdNr_Adr
) keepers ON t.LfdNr = keepers.min_id
WHERE keepers.min_id IS NULL;
-- EOC
-- Remove unique index for lut_personalapp_address_ext_o365
CALL us_drop_index_if_exists('lut_personalapp_address_ext_o365','personalapp_id_address_id');
-- EOC
-- Create unique index for lut_personalapp_address_ext_o365
ALTER TABLE `lut_personalapp_address_ext_o365` ADD UNIQUE INDEX `personalapp_id_address_id` (`personalapp_id`, `address_id`) USING BTREE;      
-- EOC
CALL us_drop_index_if_exists('lut_termin_teilnehmer','personalapp_id_address_id');
-- EOC
ALTER TABLE `lut_termin_teilnehmer` ADD UNIQUE INDEX `personalapp_id_address_id` (`LfdNr_Termin`, `LfdNr_Adr`) USING BTREE;      
-- EOC
-- Remove non required indizes
CALL us_drop_index_if_exists('lut_personalapp_address_ext_o365','lut_personalapp_address_ext_o365_personalapp_id');
-- EOC
CALL us_drop_index_if_exists('lut_personalapp_address_ext_o365','lut_personalapp_address_ext_o365_address_id');
-- EOC

-- Toggle between personalappointments calendar modes local and office365
DROP PROCEDURE IF EXISTS personalappointments_toggle_calendar_mode;
-- EOC
DELIMITER $$
CREATE PROCEDURE personalappointments_toggle_calendar_mode()
BEGIN

    DECLARE calendar_mode INTEGER;
    DECLARE current_auto_increment INTEGER;
    DECLARE current_table VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE after_toggle_table VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
	
    SET current_table = 'perstermin';
    SET after_toggle_table = 'personalappointments_ext_o365';

    -- Get current mode
    SELECT value FROM system_settings WHERE NAME='calendar_mode' INTO calendar_mode;
    IF calendar_mode = 1 THEN
    	-- currently O365 => toggle to local
		UPDATE system_settings SET VALUE = 0 WHERE NAME='calendar_mode';
        SET current_table = 'personalappointments_ext_o365';
        SET after_toggle_table = 'perstermin';
    ELSEIF calendar_mode = 0 THEN
	    -- currently local => toggle to O365
		UPDATE system_settings SET VALUE = 1 WHERE NAME='calendar_mode';
    ELSE
    	-- currently local but calendar_mode entry does not exists => toggle to O365
	 	INSERT INTO system_settings SET name='calendar_mode', VALUE=1;
    END IF;
    
    -- Update auto_increment value of appointments table    
    SELECT `AUTO_INCREMENT` FROM  INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = current_table INTO current_auto_increment;
    SET @s = CONCAT('ALTER TABLE `',after_toggle_table,'` AUTO_INCREMENT=', current_auto_increment);
	PREPARE stmt1 FROM @s;
	EXECUTE stmt1; 

    -- Update cache of AUTO_INCREMENT value
	SET @s = CONCAT('ANALYZE TABLE ', after_toggle_table);
	PREPARE stmt1 FROM @s;
	EXECUTE stmt1; 
    
END $$
DELIMITER ;
-- EOC

CALL us_add_to_table2('perstermin', 'o365_migrated', 'TINYINT NOT NULL DEFAULT 0 AFTER `sabre_etag`' );
-- EOC

-- Migrate local appointments to (unsynced) o365 events DO
DROP PROCEDURE IF EXISTS personalappointments_migrate_local_to_o365_do;
-- EOC

DELIMITER $$
CREATE PROCEDURE personalappointments_migrate_local_to_o365_do()
BEGIN
	DECLARE last_row_fetched INTEGER;
	DECLARE loc_id INTEGER;
	DECLARE loc_staff_from_id INTEGER;
	DECLARE loc_staff_to_id INTEGER;
	DECLARE loc_date datetime;
	DECLARE loc_time_from datetime;
	DECLARE loc_time_to datetime;
	DECLARE loc_project_id INTEGER;
	DECLARE loc_location TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT null;
	DECLARE loc_url TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT null;
	DECLARE loc_summary TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT null;
	DECLARE loc_comment LONGTEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT null;
	DECLARE loc_created_date datetime;
	DECLARE loc_created_by_id INTEGER;
	DECLARE loc_change_date datetime;
	DECLARE loc_changed_by_id INTEGER;
	DECLARE loc_is_private TINYINT;
	DECLARE loc_is_notify TINYINT;
	DECLARE loc_notify_date datetime DEFAULT null;
	DECLARE loc_status INTEGER;
	DECLARE loc_vacation_id INTEGER;
	DECLARE loc_state_color_id INTEGER;
	DECLARE loc_multistaff_first_id INTEGER;

    DECLARE local_events CURSOR FOR SELECT 
    id, staff_from_id, staff_to_id, `date`, time_from, time_to, project_id, location, url, 
    summary, comment, created_date, created_by_id, change_date, changed_by_id, is_private,
    is_notify, notify_date, status, vacation_id,
    state_color_id, multistaff_first_id
    FROM personalappointments WHERE o365_migrated=0 ORDER BY id ASC LIMIT 50;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET last_row_fetched=1;	
   
	SET last_row_fetched = 0;
    OPEN local_events;
        cursor_loop: LOOP -- -------------------------------------
            FETCH local_events INTO 
           		loc_id, loc_staff_from_id, loc_staff_to_id, loc_date, loc_time_from, loc_time_to, loc_project_id, loc_location, loc_url,
           		loc_summary, loc_comment, loc_created_date, loc_created_by_id, loc_change_date, loc_changed_by_id, loc_is_private,
           		loc_is_notify, loc_notify_date, loc_status, loc_vacation_id,
           		loc_state_color_id, loc_multistaff_first_id;
            IF last_row_fetched = 1 THEN
                LEAVE cursor_loop;
            END IF;
            SET @loc_id = loc_id;
            SET @loc_multistaff_first_id = loc_multistaff_first_id;

            -- Skip faulty appointments if important required fields are not set properly
            IF  	loc_date is null
				OR 	loc_time_from is null
                OR 	loc_time_to is null
                OR 	loc_staff_to_id is null
                OR 	loc_project_id is null
            THEN 
                -- Update migrated flag
                UPDATE personalappointments SET o365_migrated=1 WHERE id=@loc_id;
                ITERATE cursor_loop;
            END IF;

	        -- GET STAFF attendees data 
	        SET @staff_attendees = NULL;
	       	SELECT GROUP_CONCAT(CONCAT('{"staff_id":',id,',"address_id":null,"address":"',email,'","name":"',REPLACE(staff_name,"'", "\\'"),'","type":"required"}')) INTO @staff_attendees
			FROM staff
			WHERE id IN(SELECT DISTINCT staff_to_id FROM personalappointments WHERE multistaff_first_id=@loc_multistaff_first_id);
	
			-- GET ADDRESSES attendees data
			SET @address_attendees = NULL;
			SELECT GROUP_CONCAT(CONCAT('{"staff_id":null,"address_id":',fn.id,',"address":"',fn.email,'","name":"',REPLACE(fn.fullname,"'", "\\'"),'","type":"required"}')) INTO @address_attendees
			FROM lut_personalapp_address AS lut
			INNER JOIN addresses_fullname AS fn ON lut.address_id=fn.id
			WHERE lut.personalapp_id=@loc_id;	
		
			-- MERGE arrendees data
			SET @attendees = CONCAT('[',COALESCE(@staff_attendees, ''));
			IF @staff_attendees IS NOT NULL AND @address_attendees IS NOT NULL THEN 
				SET @attendees = CONCAT(@attendees,','); -- add comma if necessary
			END IF;
			SET @attendees = CONCAT(@attendees,COALESCE(@address_attendees, ''));
			SET @attendees = CONCAT(@attendees,']');           
           
           -- Build insert query
           	SET @query = CONCAT('INSERT IGNORE INTO personalappointments_ext_o365 (
			`id`,
			`ext_id`,`calendar_id`, `icaluid`, `is_series_master`, `organizer_email`, `organizer_staff_id`, 
			`date`, `time_from`, `date_to`, `time_to`,
			`project_id`, `staff_from_id`, `staff_to_id`, `location`, `url`,
			`summary`, `comment`, `comment_html`,
			`created_date`, `created_by_id`, `change_date`, `changed_by_id`, `is_private`,
			`several_days_last_date`, `several_days_day`, `periodical`, `app_type`, `periodical_last_date`,
			`multistaff_first_id`,`several_days_first_id`,`periodical_first_id`,
			`is_notify`, `notify_date`, `status`, `vacation_id`,
			`state_color_id`, `attendees`, `o365_data`, `sync_mode`
			) 
			VALUES(
			',loc_id,',
			',loc_id,', 0, \'\', 0, \'nomail@no.no\', ',COALESCE(loc_staff_from_id, loc_staff_to_id),',
			\'',loc_date,'\',\'',loc_time_from,'\',\'',loc_date,'\',\'',loc_time_to,'\',
            ',loc_project_id,', ',COALESCE(loc_staff_from_id, loc_staff_to_id),', ',loc_staff_to_id,', ',COALESCE(CONCAT('\'',REPLACE(REPLACE(loc_location, "\\", "\\\\"),"'", "\\'"),'\''), 'NULL'),', ',COALESCE(CONCAT('\'',REPLACE(REPLACE(loc_url, "\\", "\\\\"),"'", "\\'"),'\''), 'NULL'),',
			',COALESCE(CONCAT('\'',REPLACE(REPLACE(loc_summary, "\\", "\\\\"),"'", "\\'"),'\''), 'NULL'),', ',COALESCE(CONCAT('\'',REPLACE(REPLACE(loc_comment, "\\", "\\\\"),"'", "\\'"),'\''), 'NULL'),', ',COALESCE(CONCAT('\'',REPLACE(REPLACE(loc_comment, "\\", "\\\\"),"'", "\\'"),'\''), 'NULL'),',
            \'',COALESCE(loc_created_date, loc_change_date, loc_date),'\',',COALESCE(loc_created_by_id, loc_staff_from_id, loc_staff_to_id),',\'',COALESCE(loc_change_date, loc_created_date, loc_date),'\',',COALESCE(loc_changed_by_id, loc_created_by_id, loc_staff_from_id, loc_staff_to_id),',',loc_is_private,',
			\'',loc_date,'\', NULL, 0, 0, \'',loc_date,'\',
			',loc_id,',',loc_id,',',loc_id,',
			',COALESCE(loc_is_notify, 0),', ',COALESCE(CONCAT('\'',loc_notify_date,'\''), 'NULL'),', ',COALESCE(loc_status, 'NULL'),', ',COALESCE(loc_vacation_id, 'NULL'),',
			',COALESCE(loc_state_color_id, 'NULL'),', \'',@attendees,'\', NULL, \'to_sync\'
			);');
			-- IGNORE setting some fields (take advantage of default values): is_new=0, several_days=0, changed_*=0, 
		
			SET @insert_last_id = 0;
		    -- PREPARE STATEMENT
			PREPARE stmt from @query;
			EXECUTE stmt; 
			-- Continue if not inserted right now
		    IF ROW_COUNT() != 1 THEN
		    	DEALLOCATE PREPARE stmt;
	            ITERATE cursor_loop;
	        END IF;
	        DEALLOCATE PREPARE stmt;
	       
	        -- Migrate data from lut_personalapp_address to lut_personalapp_address_ext_o365
	        INSERT IGNORE INTO lut_personalapp_address_ext_o365 (SELECT * FROM lut_personalapp_address WHERE personalapp_id=@loc_id);

            -- Update migrated flag
            UPDATE personalappointments SET o365_migrated=1 WHERE id=@loc_id;
	       
        END LOOP cursor_loop;
    CLOSE  local_events;		
    SET last_row_fetched = 0;	           
	
END $$
DELIMITER ;
-- EOC

-- Migrate local appointments to (unsynced) o365 events
DROP PROCEDURE IF EXISTS personalappointments_migrate_local_to_o365;
-- EOC
DELIMITER $$
CREATE PROCEDURE personalappointments_migrate_local_to_o365()
BEGIN
	SELECT COUNT(id) INTO @unmigrated FROM personalappointments WHERE o365_migrated=0;
	WHILE @unmigrated > 0 DO
		CALL personalappointments_migrate_local_to_o365_do();
		SELECT COUNT(id) INTO @unmigrated FROM personalappointments WHERE o365_migrated=0;
	END WHILE;
	
END $$
DELIMITER ;
-- EOC

CALL us_add_to_table2('zeiten_beginnende', 'breaks', 'LONGTEXT NULL' );
-- EOC

-- USC Erstelle weitere X2 Tabellen - Indexes.

DROP PROCEDURE IF EXISTS us_other_indexes;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_other_indexes()
BEGIN
    CALL us_drop_index_if_exists('personalappointments_ext_o365','calendar_id_ext_id');

    IF SUBSTRING(VERSION(), 1, 4) = '5.6.' THEN
        CALL us_add_index_to_table('mail_id', 'mail_id_Mail_ID', '`Mail_ID`(150)');
        CALL us_add_index_to_table('mail_id', 'mail_id_Mail_ID_long', '`Mail_ID_long`(150)');
        ALTER TABLE `personalappointments_ext_o365` ADD UNIQUE INDEX `calendar_id_ext_id` (`calendar_id`, `ext_id`(190)) USING BTREE;
    ELSE
        CALL us_add_index_to_table('mail_id', 'mail_id_Mail_ID', '`Mail_ID`(200)');
        CALL us_add_index_to_table('mail_id', 'mail_id_Mail_ID_long', '`Mail_ID_long`(200)');
        ALTER TABLE `personalappointments_ext_o365` ADD UNIQUE INDEX `calendar_id_ext_id` (`calendar_id`, `ext_id`) USING BTREE;        
    END IF;
END $$
DELIMITER ;
-- EOC

CALL us_other_indexes();
-- EOC

-- Add description to lut_fee_areas_offer
CALL us_add_to_table2('lut_fee_areas_offer', 'description', 'TEXT CHARSET utf8mb4 COLLATE utf8mb4_general_ci' );
-- EOC
-- USC Views werden angelegt.

-- --------------------------------------------------------------------------------------------------
CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `addresses`
 AS SELECT LfdNr AS id, uuid, name, bName AS name_deri, firma AS comp_supp, bFirma AS comp_supp_deri, anrede AS title, bAnrede AS title_deri, Titel AS academic_title,
 bTitel AS academic_title_deri, Master_Titel AS master_title, bMaster_Titel AS master_title_deri, Vorname AS first_name, bVorname AS first_name_deri,
 Ansprechpartner AS contact_person, bAnsprech AS contact_person_deri, Strasse AS street, bStrasse AS street_deri, Strasse2 AS street2, bStrasse2 AS street2_deri, Pltz AS zip, Ort AS town, bPltzOrt as zip_town_deri,
 Land AS country, bLand AS country_deri, Telefon1 AS phone1, bTelefon1 AS phone1_deri, Telefon2 AS phone2, bTelefon2 AS phone2_deri,
 Mobil AS mobile_phone, bMobil AS mobile_phone_deri, fax, bFax AS fax_deri, modem, bModem AS modem_deri, email, bEMail AS email_deri, UID_Nr AS vat, bUID_Nr AS vat_deri,
 URL AS url, bURL AS url_deri, ErstVon AS created_by_id, AendVon AS changed_by_id, ErstAm AS created_date,
 AendAm AS change_date, Aktiv AS active, bAktiv AS active_deri, Bilddatei AS image, creditor_no, debtor_no, dsgvo_delete_date, dsgvo_data_from,
 longitude, longitude_deri, latitude, latitude_deri, 
 bKategorien AS categories_deri, comment_main, comment_main_staff, comment_main_date, comment_main_more, parent,
 sabre_synctoken, sabre_card_data, sabre_uri, sabre_uid, sabre_etag
 FROM adressen;
-- EOC

DROP VIEW IF EXISTS addresses_fullname;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `addresses_fullname` AS
 SELECT id,
    CONCAT_WS( ', ',
        CASE WHEN NULLIF(contact_person, '') IS NULL
            THEN CONCAT_WS( ' ' , NULLIF(academic_title, ''), NULLIF(first_name, ''), name, NULLIF(master_title, '') )
            ELSE CONCAT_WS( ', ', name, CONCAT_WS( ' ', NULLIF(academic_title, '') , NULLIF(first_name, '') , NULLIF(contact_person, ''), NULLIF(master_title, '') ) )
        END,
        NULLIF(REPLACE(comp_supp, CHAR(13, 10), ' '), ''),
        NULLIF(town, '')
    ) AS fullname,
    CONCAT_WS( ', ',
        NULLIF(NULLIF(creditor_no, '0'), ''),
        NULLIF(NULLIF(debtor_no, '0'), ''),
        CASE WHEN NULLIF(contact_person, '') IS NULL
            THEN CONCAT_WS( ' ' , NULLIF(academic_title, ''), NULLIF(first_name, ''), name, NULLIF(master_title, '') )
            ELSE CONCAT_WS( ', ', name, CONCAT_WS( ' ', NULLIF(academic_title, '') , NULLIF(first_name, '') , NULLIF(contact_person, ''), NULLIF(master_title, '') ) )
        END,
        NULLIF(REPLACE(comp_supp, CHAR(13, 10), ' '), ''),
        NULLIF(street, ''),
        NULLIF(street2, ''),
        NULLIF(CONCAT_WS( ' ', NULLIF(zip, '') , NULLIF(town, '') ), ' ')
    ) AS fullnamelong,
    CASE WHEN NULLIF(contact_person, '') IS NULL
            THEN CONCAT_WS( ' ' , NULLIF(academic_title, ''), NULLIF(first_name, ''), name, NULLIF(master_title, '') )
        ELSE CONCAT_WS( ', ', CONCAT_WS( ' ', NULLIF(academic_title, '') , NULLIF(first_name, '') , NULLIF(contact_person, ''), NULLIF(master_title, '') ) )
    END AS fullnameshort,
    CASE WHEN NULLIF(contact_person, '') IS NULL
        THEN ''
        ELSE CONCAT_WS( ', ',
            name,
            NULLIF(REPLACE(comp_supp, CHAR(13, 10), ' '), '')
        )
    END AS fullnameorg,
 name,
 active,
 email,
 comment_main,
 comment_main_staff,
 comment_main_date,
 parent
 FROM addresses;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `addresses_addi_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color, Laenge AS length, Sicherheit AS security, isfulltext FROM zusatz_adressen_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `staff_additional_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color, Laenge AS length, Sicherheit AS security FROM zusatz_personen_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `address_categories`
 AS SELECT LfdNr AS id, Bezeichnung AS name, Beschreibung as purpose, company_id FROM adrkategorien;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `address_descriptions`
 AS SELECT LfdNr AS id, LfdNr_Adr AS address_id, unique_add_id, call_id, beschreibung AS description, wer AS staff_id, wann AS created_date,
 prioritaet AS security, LfdNr_Proj AS project_id FROM adrbeschr;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `address_files`
 AS SELECT LfdNr AS id, LfdNr_Adr AS address_id, Datei AS file, DateiBeschreibung AS description,
 DateiPosition AS sort,
 ErstVon AS created_by_id, AendVon AS changed_by_id, ErstAm AS created_date,
 AendAm AS change_date FROM lut_adr_dateien;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `address_groups`
 AS SELECT LfdNr AS id, GruppenName AS name, company_id, LfdNr_Projekt AS project_id FROM adrgruppendef;
-- EOC

CREATE OR REPLACE
 ALGORITHM = UNDEFINED
 VIEW `zip_to_name_merged` AS
 SELECT zip, town, country, COUNT( * ) AS count_hits FROM addresses GROUP BY zip, town, country
 UNION
 SELECT tzip AS zip, tname AS town, tcountry AS country, 0 FROM zip_to_name;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `companies`
 AS SELECT LfdNr AS id, name, address_id, canDel as can_del, aktiv as active, currency_id FROM firmen;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `cost_centres`
 AS SELECT LfdNr AS id, Kostenstelle AS name, Bemerkung AS remark, company_id, use_in_reports FROM kostenstellen;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `countries`
 AS SELECT LfdNr as id, Bez as name, Kennzeichen as country_code FROM land;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `expenses_rates`
 AS SELECT LfdNr AS id, Beschreibung AS description, RKSatz AS travel_name, ExtraSatz AS extras_name, MASatz AS times_name,
 ABSatz AS work_areas_name, company_id, currency_id, aktiv AS is_active FROM projektabrsaetze;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `extras_types`
 AS SELECT LfdNr AS id, OrdNr AS sort, Bezeichnung AS type, Einheit AS unit, KostenEinheit AS rate, company_id, currency_id, 
 MwStKopie AS vat, active FROM kopiekat;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `extras_rates`
 AS SELECT LfdNr AS id, Satz AS rate_id, Extra AS extra_id, NeuerSatz AS rate, LfdNr_ProjektAbrExtra_Zeit AS history_id FROM projektabrextra;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `extras_rates_history`
 AS SELECT `LfdNr` AS id, `LfdNr_Satz` AS rate_id, `von` AS date_from, `bis` AS date_to, name
 FROM `projektabrextra_zeit`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_addresses_address_categories`
 AS SELECT LfdNr_Adr AS address_id, LfdNr_Kat AS address_category_id FROM adrkat_lut;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_addresses_address_group`
 AS SELECT AdressNr AS address_id, GruppenNr AS address_group_id FROM adrgruppenmitglieder;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_addresses_projects`
 AS SELECT LfdNr AS id, Person AS address_id, Projekt AS project_id, LfdNr_Kat AS address_category_id, isFreigeber AS auto_plan_approv, Bemerkung as purpose,
 Reihenfolge AS sort FROM propersonen;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_proj_category_rates`
 AS SELECT LfdNr AS id, Projekt AS project_id,
 SatzExtra AS extras_rate_id, SatzRK AS travels_rate_id, SatzMA AS times_rate_id, SatzAB AS areas_rate_id, warnschwelle AS threshold FROM lut_projektabr;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_proj_proj_grps`
 AS SELECT LfdNr AS id, Projekt AS project_id, ProGrupNr AS project_grp_id FROM progrp_lut;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_route_proj`
 AS SELECT LfdNr AS id, Proj_LfdNr AS project_id, Ort_LfdNr AS route_id FROM lut_orte_proj;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `occupation_groups`
 AS SELECT LfdNr AS id, LfdNr_Mitarb AS staff_id, KurzBesch AS name, Beschreibung AS description, company_id FROM gruppen;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_staff_occ_group`
 AS SELECT LfdNr AS id, LfdNr_Pers AS staff_id, LfdNr_Grp AS group_id, von AS fr_om_date, bis AS to_date, unique_add_id, description 
 FROM lut_pers_grp;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_task_desc_proj`
 AS SELECT LfdNr AS id, Proj_LfdNr AS project_id, ArbBesch_LfdNr AS tdesc_id FROM lut_arbbeschtxte_proj;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `occupation_groups_fee_multipliers`
 AS SELECT  LfdNr AS id, LfdNr_Grp AS group_id, von AS fr_om_date, bis AS to_date,
 Satz1 AS percntg1, Satz2 AS percntg2, Satz3 AS percntg3, Satz4 AS percntg4, Satz5 AS percntg5, Satz6 AS percntg6, Satz7 AS percntg7, Satz8 AS percntg8, Satz9 AS percntg9,
 Betrag1 AS value1, Betrag2 AS value2, Betrag3 AS value3, Betrag4 AS value4, Betrag5 AS value5, Betrag6 AS value6, Betrag7 AS value7, Betrag8 AS value8, Betrag9 AS value9,
 currency_id FROM gruppen_zeit;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `overtime`
 AS SELECT LfdNr AS id, Projekt AS project_id, Person AS staff_id, Datum AS date, Anzahl AS number, UeStdSatz AS overtime_rate,
 SatzArt AS overtime_rate_id, Lagerung AS storage, Ausbezahlt AS paid, WerHatAusb AS paid_by_staff_id, company_id FROM uestd;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `overtime_rates`
 AS SELECT LfdNr AS id, OrdNr AS sort, SatzArt AS name, Satz AS rate, active, Drucken AS print, company_id AS company_id FROM uesatz;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `projects_addi_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color,  Laenge AS length, Sicherheit AS security, isfulltext FROM zusatz_projekt_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `project_participants_addi_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color,  Laenge AS length, Sicherheit AS security FROM zusatz_propers_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `projects_groups`
 AS SELECT LfdNr AS id, ProGrupName AS name, filter_id, filter_hash, filter_last_count, filter_creator_info FROM progruppendef;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `project_categories`
 AS SELECT LfdNr as id, OrdNr AS sort, Kategorie AS name, Bemerkung as purpose
 FROM prokategorie;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `routes`
 AS SELECT LfdNr AS id, Ort AS name, Km AS value, company_id FROM orte;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `staff`
 AS SELECT LfdNr AS id, Name AS staff_name, Passwort AS password, passwort_mode AS password_mode, login_extras,
 Strasse AS street, Ort AS town, Pltz AS zip_code, Telefon1 AS phone_1, Telefon2 AS phone_2,
 Fax AS fax, Start AS start_date, Ende AS end_date, SVNummer AS insurance_no, Geschlecht AS gender, Bemerkung AS remark,
 ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id, BLZ AS bank_code, Bank AS bank_name, KontoNr AS account_no,
 Kurzzeichen AS abbreviation, DW AS direct_dial, EMail AS email, Zusatz AS annex, FeiertagSatz AS holiday_rate_id, GebDatum AS birthday,
 ModSecurity01 AS security_1, ModSecurity02 AS security_2, ModSecurity03 AS security_3, ModSecurity04 AS security_4, ModSecurity05 AS security_5,
 ModSecurity06 AS security_6, ModSecurity07 AS security_7, ModSecurity08 AS security_8, ModSecurity09 AS security_9, ModSecurity10 AS security_10, ModSecurity11 AS security_11,
 ModSecurity12 AS security_12, ModSecurity13 AS security_13, ModSecurity14 AS security_14, ModSecurity15 AS security_15, ModSecurity16 AS security_16, ModSecurity17 AS security_17,
 ModSecurity18 AS security_18, ModSecurity19 AS security_19, ModSecurity20 AS security_20, ModSecurity21 AS security_21, ModSecurity22 AS security_22, ModSecurity23 AS security_23,
 ModSecurity24 AS security_24, ModSecurity25 AS security_25, ModSecurity26 AS security_26, ModSecurity27 AS security_27, ModSecurity28 AS security_28, ModSecurity29 AS security_29,
 ModSecurity30 AS security_30, ModSecurity31 AS security_31, ModSecurity32 AS security_32, ModSecurity33 AS security_33, ModSecurity34 AS security_34, ModSecurity35 AS security_35,
 ModSecurity36 AS security_36, ModSecurity37 AS security_37, ModSecurity38 AS security_38, ModSecurity39 AS security_39, ModSecurity40 AS security_40, ModSecurity41 AS security_41,
 ModSecurity42 AS security_42, ModSecurity43 AS security_43, ModSecurity44 AS security_44, ModSecurity45 AS security_45, ModSecurity46 AS security_46, ModSecurity47 AS security_47,
 ModSecurity48 AS security_48, ModSecurity49 AS security_49, ModSecurity50 AS security_50,
 user_is_management_user, user_is_simple_user, named_license_changed_date, user_access_license_changed_date, 
 secdetail_2 AS secd_2, secdetail_3 AS secd_3, secdetail_5 AS secd_5, secdetail_16 AS secd_16, 
 Firmen_ID AS company_id, staff_location_id, UseLeiterInfo AS respect_project_manager, respect_division_manager, IstProjektLeiter AS is_project_manager, is_division_manager, DientUnter AS project_manager_id, division_manager_id, 
 allow_staff_even_if_not_by_project_manager, allow_own_project_if_other_project_manager, allow_staff_even_if_not_by_division_manager, allow_own_project_if_other_division_manager,
 IsSU AS is_superuser,
 KstPrioritaet AS cost_centre_present, EditHowManyDays AS change_days_past, days_warning_no_workinput, days_warning_no_mail_allocation, 
 sync_only_category_addresses, Lehrling AS exclude_from_turnover,
 Urlaub_Stichtag AS holiday_deadline, Urlaub_Anspruch AS add_holiday_balance, Bilddatei AS photo_file, currency_id, username FROM personen;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `staff_favourite_proj`
 AS SELECT LfdNr AS id, Person AS staff_id, Projekt AS project_id FROM stechprojekte;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `start_end_times`
 AS SELECT LfdNr AS id, Person AS staff_id, Datum AS date, ZeitBeginn AS start_time, ZeitEnde AS end_time,
 ZeitAbzug AS time_deduct, breaks, company_id
 FROM zeiten_beginnende;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `system_settings`
 AS SELECT LfdNr AS id, SettingType AS name, SettingValue AS value, company_id FROM settingssystem;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `sys_installation`
 AS SELECT LfdNr AS id, Seriennummer AS serial,
 mod01, mod02, mod03, mod04, mod05, mod06, mod07, mod08, mod09, mod10, mod11, mod12, mod13, mod14, mod15, mod16, mod17, mod18,
 mod19, mod20, mod21, mod22, mod23, mod24, mod25, mod26, mod27, mod28, mod29, mod30, mod31, mod32, mod33, mod34, mod35, mod36,
 mod37, mod38, mod39, mod40, mod41, mod42, mod43, mod44, mod45, mod46, mod47, mod48, mod49, mod50, mod51, mod52, mod53, mod54,
 mod55, mod56, mod57, mod58, mod59, mod60,
 Ablauf AS end_date, DemoVersion AS is_demo,
 r1, r2, r3,
 instname AS name, instadresse AS address, insttel AS telephone, instinfo FROM installation;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `target_hours_daily`
 AS SELECT LfdNr AS id, Pers_LfdNr AS staff_id, Nz01 AS norm_work_mon, Nz02 AS norm_work_tue, Nz03 AS norm_work_wed, Nz04 AS norm_work_thu,
 Nz05 AS norm_work_fri, Nz06 AS norm_work_sat, Nz07 AS norm_work_sun, TagSollvon AS fr_om_date, TagSollbis AS to_date, ErstAm AS created_date,
 ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id, unique_add_id, description
 FROM tagessollstd;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `task_descriptions`
 AS SELECT LfdNr AS id, active, OrdnNr AS sort, ArbBeschTxt AS name, company_id FROM arbbeschtxte;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `times_rates`
 AS SELECT LfdNr AS id, Satz AS rate_id, Mitarbeiter AS times_id, skill_grp_id, NeuerSatz AS rate,
 PersonenSatz AS external_staff_rate, LfdNr_ProjektAbrMA_Zeit AS history_id FROM projektabrma;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `times_rates_history`
 AS SELECT `LfdNr` AS id, `LfdNr_Satz` AS rate_id, `von` AS date_from, `bis` AS date_to, name, is_times_skill_grp
 FROM `projektabrma_zeit`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `travels_rates`
 AS SELECT LfdNr AS id, Satz AS rate_id, RK AS travel_id, NeuerSatz AS rate, LfdNr_ProjektAbrRK_Zeit AS history_id FROM projektabrrk;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `travels_rates_history`
 AS SELECT `LfdNr` AS id, `LfdNr_Satz` AS rate_id, `von` AS date_from, `bis` AS date_to, name
 FROM `projektabrrk_zeit`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `travels_types`
 AS SELECT LfdNr AS id, OrdNr AS sort, KostenArt AS type, Einheit AS unit, Satz AS rate, KmVonBis AS km_from_to,
 ZeitVonBis AS time_from_to, company_id, currency_id, MwStReise AS vat, active FROM reisekosten;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `user_settings`
 AS SELECT LfdNr AS id, LfdNr_User AS staff_id, SettingType AS name, SettingValue AS value FROM settingsuser;
-- EOC

-- Create  view for the address_descriptions including the firmen_id
CREATE OR REPLACE
 ALGORITHM = UNDEFINED
 VIEW `address_descriptions_comp` AS
 SELECT address_descriptions . * , staff.company_id
 FROM address_descriptions
 LEFT JOIN staff ON ( address_descriptions.staff_id = staff.id );
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `holiday_rates`
 AS SELECT LfdNr AS id, Beschreibung AS title, is_active
 FROM `feiertagsatz`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `holidays`
 AS SELECT LfdNr AS id, Satz AS holiday_rate_id, Datum AS date, Beschreibung AS description, Stunden AS hour_deduction, Faktor AS rate
 FROM `feiertage`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `deletions` AS
 SELECT LfdNr AS id, Wann AS date, Wer AS staff, staff_id, Wo AS title, Was AS info,
 item_model, item_title, item_id, isCompressed,
 ModNr AS moduleid
 FROM `erased`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `personalappointments` AS
 SELECT LfdNr as id, Termin as date, Zeit as time_from, BisZeit as time_to, Projekt as project_id, Von as staff_from_id, An as staff_to_id,
 Ort as location, url,
 summary, Bemerkung as comment,
 ErstAm as created_date, ErstVon as created_by_id, AendAm as change_date, AendVon as changed_by_id, Neu as is_new, Privat as is_private, FirstLfdNr multistaff_first_id, SeveralDays as several_days, SeveralNumber as several_days_first_id, TerminBis as several_days_last_date, Tag as several_days_day, Periodical as periodical, TerminArt as app_type, PeriodeBis as periodical_last_date, PeriodNumber as periodical_first_id, IsEr as is_notify, ErDate as notify_date, TerminStatus as status, LfdNr_Urlaub as vacation_id, bZeit as changed_time_from,
 bOrt as changed_location, changed_url,
 changed_summary, bBemerkung as changed_comment, 
 bBisZeit as changed_time_to, bProjekt as changed_project_id, bIsEr as changed_is_notify, bErDate as changed_notify_date, bTerminStatus as changed_status, state_color_id,
 sabre_synctoken, sabre_calendar_data, sabre_uri, sabre_uid, sabre_etag, o365_migrated
 FROM perstermin;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_personalapp_address` AS
 SELECT LfdNr AS id, LfdNr_Termin AS personalapp_id, LfdNr_Adr AS address_id, OrdNr as sort
 FROM lut_termin_teilnehmer;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `opentasks` AS
 SELECT LfdNr AS id, Projekt AS project_id, Beschreibung AS purpose, bis AS todo_date, Erledigt AS is_done, ErlVon AS done_staff_id,
 ErlAm AS done_date, ErlVermerk AS done_annotation, ZuTunVon AS todo_id, Person AS creator_id, ErstAm AS created_date,
 ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id, Neu AS is_new, Privat AS is_private, prioritaet AS need_mgmt_right,
 dringend AS is_urgent, Mail_File AS msg_file, IsPostAusgang AS module_type, lfdnr_post AS module_id, IsEr AS is_notify, ErDate AS notify_date,
 LfdNr_Adr AS address_id, Bemerkung AS description, active_from, ToDoParent AS parent_id, period_value, unit, working_hours, work_package_id,
 sabre_synctoken, sabre_calendar_data, sabre_uri, sabre_uid, sabre_etag
 FROM todo;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `opentasks_addi_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color,  Laenge AS length, Sicherheit AS security, isfulltext FROM zusatz_todo_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `vacations`
 AS SELECT LfdNr AS id, LfdNr_Mitarbeiter AS staff_id, LfdNr_Projekt AS project_id, work_package_id, UV_DatumVon AS start_date, UV_DatumBis AS end_date,
 UV_Tage AS days, UV_Bemerkung AS comment , UV_OK AS holiday_is_ok, is_ok_pre, UV_Beantragt AS is_submitted, UV_NO AS is_refused, UV_ZA AS is_absent, is_absent_social,
 ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id, EingabeSaved AS imported_workinput,
 PersTerminSaved AS imported_persapp, aufgestockt AS increased, Saldo AS balance
 FROM uv_buchungen;
-- EOC










CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `externalexpenses_calc` AS
 SELECT  id, project_id, purpose, description, value, 
 (value * (1+turnover_rate)) AS value_pre_tax, surcharge_used,
 address_id, correspondence_id, invoice_number, invoice_due_date, invoice_json,
 area_id, creator_id, date, created_date, created_by_id, change_date,
 changed_by_id, cost_centre_id, is_hon_decr, is_calc_from_expenses, charge_date,
 charged, 0 AS is_transfered, 1+0 AS is_invoiced, turnover_rate, NULL AS valid_from, work_package_id, fee_category_id,
 currency_id, value_otcurr, (value_otcurr * (1+turnover_rate)) AS value_otcurr_pre_tax
 FROM externalexpenses;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `externalexpenses_planned_calc` AS
 SELECT  id, project_id, purpose, description, value, 
 (value * (1+turnover_rate)) AS value_pre_tax, surcharge_used,
 address_id, correspondence_id, invoice_number, invoice_due_date, invoice_json,
 area_id, creator_id, date, created_date, created_by_id, change_date,
 changed_by_id, cost_centre_id, is_hon_decr, is_calc_from_expenses, charge_date,
 charged, is_transfered, 0 AS is_invoiced, turnover_rate, valid_from, work_package_id, fee_category_id,
 currency_id, value_otcurr, (value_otcurr * (1+turnover_rate)) AS value_otcurr_pre_tax
 FROM externalexpenses_planned;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `externalexpenses_merged`  AS
 SELECT id, project_id, purpose, description, value, value_pre_tax, surcharge_used, address_id, correspondence_id,
 invoice_number, invoice_due_date, invoice_json, area_id, creator_id, date, created_date, created_by_id, change_date,
 changed_by_id, cost_centre_id, is_hon_decr, is_calc_from_expenses, charge_date, charged, is_transfered, is_invoiced, turnover_rate, valid_from, work_package_id,
 fee_category_id, currency_id, value_otcurr, value_otcurr_pre_tax
 FROM externalexpenses_calc
 UNION
 SELECT id, project_id, purpose, description, value, value_pre_tax, surcharge_used, address_id, correspondence_id,
 invoice_number, invoice_due_date, invoice_json, area_id, creator_id, date, created_date, created_by_id, change_date,
 changed_by_id, cost_centre_id, is_hon_decr, is_calc_from_expenses, charge_date, charged, is_transfered, is_invoiced, turnover_rate, valid_from, work_package_id,
 fee_category_id, currency_id, value_otcurr, value_otcurr_pre_tax
 FROM externalexpenses_planned_calc;
-- EOC





CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `externalexpenses_addi_merged_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color, Laenge AS length, Sicherheit AS security FROM zusatz_extkosten_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `externalexpenses_addi_invoiced_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color, Laenge AS length, Sicherheit AS security FROM zusatz_extkosten_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `externalexpenses_addi_planned_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color, Laenge AS length, Sicherheit AS security FROM zusatz_extkosten_def;
-- EOC





CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `fees_calc` AS
 SELECT  id, project_id, purpose, value, address_id,
 area_id, user_id, fee_date, fee_no, created_date, created_by_id, change_date,
 changed_by_id, cost_centre_id, e_invoice_json, ebinterface_json_old, zugferd_json_old, xrechnung_json_old, peppol_json_old, fatturapa_json_old, swissqr_json_old, entry_date, is_done, done_date,
 fee_account_id, turnover_rate, remited, remit_purpose, predecessor_id,
 successor_id, due_date, reminder_level, last_reminder_date, is_percentage,
 deduction,
 (value * (1+turnover_rate)) AS value_pre_tax, 
 (value * (1+turnover_rate) - remited) AS diff_pre_tax, 
 null AS due_date_planned, 1+0 AS is_invoiced, 0 AS is_transfered, (remited/(turnover_rate*100+100)*100) AS remited_after_tax, correspondence_id,
 is_calcexp, discount, discount_date, work_package_id, finally_invoiced, fee_category_id,
 currency_id, value_otcurr, remited_otcurr, deduction_otcurr,
 (value_otcurr * (1+turnover_rate)) AS value_otcurr_pre_tax, 
 (value_otcurr * (1+turnover_rate) - remited_otcurr) AS diff_otcurr_pre_tax,
 (remited_otcurr/(turnover_rate*100+100)*100) AS remited_otcurr_after_tax,
 retention_type, retention_date, retention, from_date, to_date, remited_is_withholded
 FROM fees;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `fees_planned_calc` AS
 SELECT  id, project_id, purpose, value, address_id,
 area_id, user_id, fee_date, fee_no, created_date, created_by_id, change_date,
 changed_by_id, cost_centre_id, e_invoice_json, ebinterface_json_old, zugferd_json_old, xrechnung_json_old, peppol_json_old, fatturapa_json_old, swissqr_json_old, entry_date, is_done, done_date,
 fee_account_id, turnover_rate, remited, remit_purpose, predecessor_id,
 successor_id, due_date, reminder_level, last_reminder_date, is_percentage,
 deduction, 
 (value * (1+turnover_rate)) AS value_pre_tax, 
 (value * (1+turnover_rate) - remited) AS diff_pre_tax, 
 due_date_planned, 0 AS is_invoiced, is_done AS is_transfered, (remited/(turnover_rate*100+100)*100) AS remited_after_tax, correspondence_id,
 is_calcexp, discount, discount_date, work_package_id, finally_invoiced, fee_category_id,
 currency_id, value_otcurr, remited_otcurr, deduction_otcurr,
 (value_otcurr * (1+turnover_rate)) AS value_otcurr_pre_tax, 
 (value_otcurr * (1+turnover_rate) - remited_otcurr) AS diff_otcurr_pre_tax,
 (remited_otcurr/(turnover_rate*100+100)*100) AS remited_otcurr_after_tax,
 retention_type, retention_date, retention, from_date, to_date, remited_is_withholded
 FROM fees_planned;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `fees_merged`  AS
 SELECT id, project_id, purpose, value, address_id, area_id, user_id, fee_date, fee_no, created_date, created_by_id, change_date, changed_by_id, cost_centre_id, 
 e_invoice_json, ebinterface_json_old, zugferd_json_old, xrechnung_json_old, peppol_json_old, fatturapa_json_old, swissqr_json_old, 
 entry_date, is_done, done_date, fee_account_id, turnover_rate, remited, remit_purpose, predecessor_id, successor_id, due_date, reminder_level,
 last_reminder_date, is_percentage, deduction,
 value_pre_tax, diff_pre_tax, due_date_planned, is_invoiced, is_transfered, remited_after_tax, correspondence_id, is_calcexp, discount, discount_date, 
 work_package_id, finally_invoiced, fee_category_id, currency_id, value_otcurr, remited_otcurr, deduction_otcurr,value_otcurr_pre_tax, diff_otcurr_pre_tax, remited_otcurr_after_tax,
 retention_type, retention_date, retention, from_date, to_date, remited_is_withholded
 FROM fees_calc
 UNION
 SELECT id, project_id, purpose, value, address_id, area_id, user_id, fee_date, fee_no, created_date, created_by_id, change_date, changed_by_id, cost_centre_id, 
 e_invoice_json, ebinterface_json_old, zugferd_json_old, xrechnung_json_old, peppol_json_old, fatturapa_json_old, swissqr_json_old, 
 entry_date, is_done, done_date, fee_account_id, turnover_rate, remited, remit_purpose, predecessor_id, successor_id, due_date, reminder_level,
 last_reminder_date, is_percentage, deduction,
 value_pre_tax, diff_pre_tax, due_date_planned, is_invoiced, is_transfered, remited_after_tax, correspondence_id, is_calcexp, discount, discount_date, 
 work_package_id, finally_invoiced, fee_category_id, currency_id, value_otcurr, remited_otcurr, deduction_otcurr, value_otcurr_pre_tax, diff_otcurr_pre_tax, remited_otcurr_after_tax,
 retention_type, retention_date, retention, from_date, to_date, remited_is_withholded
 FROM fees_planned_calc;
-- EOC




CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `fees_addi_merged_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color, Laenge AS length, Sicherheit AS security FROM zusatz_honverw_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `fees_addi_invoiced_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color, Laenge AS length, Sicherheit AS security FROM zusatz_honverw_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `fees_addi_planned_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color, Laenge AS length, Sicherheit AS security FROM zusatz_honverw_def;
-- EOC




CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `fees_reminder_level_logging` AS
 SELECT  LfdNr AS id, Hon_LfdNr AS fee_id, MahnStufe AS reminder_level, MahnDatum as reminder_date
 FROM honverwmahnung;
-- EOC

-- Update extras views
CALL update_extras_views_do();
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `project_phases`
 AS SELECT LfdNr as id, PhasenBez as name, Bemerkung AS purpose, OrdNr AS sort FROM phasen;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `fee_accounts`
 AS SELECT LfdNr as id, Blz as bank_code, Bank AS bank, KNR AS account_number, KontoBez AS account_designation, Firmen_ID AS company_id,
 inaktiv AS inactive FROM honkonten;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `project_archives`
 AS SELECT LfdNr as id, ArchivBezeichnung as name FROM projektarchive;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `workinput` AS
	(SELECT id, 1+0 AS time, 0 AS travel, 0 AS extra, date, staff_id FROM times)
	UNION ALL
	(SELECT id, 0 AS time, 1+0 AS travel, 0 AS extra, date, staff_id FROM travels)
	UNION ALL
	(SELECT id, 0 AS time, 0 AS travel, 1+0 AS extra, date, staff_id FROM extras);
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `measurements` AS
 SELECT LfdNr as id, MessSize_Name as name FROM messsize;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `address_relations_comp`
 AS SELECT adre.*,
 adrf.fullname AS address_name,
 from_adrf.fullname AS from_address_name,
 staff.staff_name AS from_staff_name,
 CONCAT_WS(' - ', peap.comment, peap.location) AS from_personalapp_comment,
 CONCAT_WS(' | ', NULLIF(from_adrf.fullname, ''), NULLIF(adre.description, ''), NULLIF(peap.comment, ''), NULLIF(staff.staff_name, '')) AS title
 FROM `address_relations` AS adre
 LEFT JOIN `staff` ON adre.from_staff_id=staff.id
 LEFT JOIN `addresses_fullname` AS adrf ON adre.address_id=adrf.id
 LEFT JOIN `addresses_fullname` AS from_adrf ON adre.from_address_id=from_adrf.id
 LEFT JOIN `personalappointments` AS peap ON adre.from_personalapp_id=peap.id;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `address_relations_both`
 AS
  SELECT adrecomp.id,
  adrecomp.address_id, adrecomp.address_name, 1+0 AS 'direct',
   adrecomp.description, adrecomp.date,
   adrecomp.from_staff_id, adrecomp.from_staff_name,
   adrecomp.from_personalapp_id, adrecomp.from_personalapp_comment,
   adrecomp.from_address_id, adrecomp.from_address_name,
  adrecomp.address_id AS first_address_id,
  adrecomp.from_address_id as snd_address_id,
  adrecomp.title
  FROM `address_relations_comp` AS adrecomp
 UNION ALL
  SELECT adrecomp.id,
  adrecomp.address_id, adrecomp.address_name, 0 AS 'direct',
   adrecomp.description, adrecomp.date,
   adrecomp.from_staff_id, adrecomp.from_staff_name,
   adrecomp.from_personalapp_id, adrecomp.from_personalapp_comment,
   adrecomp.from_address_id, adrecomp.from_address_name,
  adrecomp.from_address_id as first_address_id,
  adrecomp.address_id AS snd_address_id,
  CONCAT_WS(' | ', NULLIF(adrecomp.address_name, ''), NULLIF(adrecomp.description, ''), NULLIF(adrecomp.from_personalapp_comment, ''), NULLIF(adrecomp.from_staff_name, '')) AS title
  FROM `address_relations_comp` AS adrecomp;
-- EOC

CREATE OR REPLACE
 ALGORITHM = UNDEFINED
 VIEW `wiw_items` AS
 SELECT LfdNr AS id, Artikel AS title, autor AS author, buchtitel AS article_id, seite AS page,
 memofeld AS note, adressat AS address_id,
 file
 FROM `artikeltab`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = UNDEFINED
 VIEW `wiw_articles` AS
 SELECT LfdNr AS article_id, buchtitel AS article_title, ausgabe AS version, eingelangtAm AS in_date, autor AS article_author,
 BTRaum AS room_id, BTRregal AS rack_id, BTFach AS tray_id, BTAblage AS filing_id, BTadressat AS address_id, BTadressatJN AS addressee_yn
 FROM `buchtiteltab`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = UNDEFINED
 VIEW `wiw_rooms` AS
 SELECT LfdNr AS id, raum AS title
 FROM `raumtab`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = UNDEFINED
 VIEW `wiw_racks` AS
 SELECT LfdNr AS id, regal AS title, lfdNrRegal AS room_id
 FROM `regaltab`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = UNDEFINED
 VIEW `wiw_trays` AS
 SELECT LfdNr AS id, fach AS title, lfdnrFach AS rack_id
 FROM `fachtab`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = UNDEFINED
 VIEW `wiw_filings` AS
 SELECT LfdNr AS id, ablage AS title, lfdnrAblage AS tray_id
 FROM `ablagetab`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = UNDEFINED
 VIEW `lut_wiw_items_projects` AS
 SELECT LfdNr_Artikel AS item_id, LfdNr_Proj AS project_id
 FROM `lut_artikel_proj`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = UNDEFINED
 VIEW `lut_wiw_items_themes` AS
 SELECT ArtikellfdNr AS item_id, ThemenlfdNr AS theme_id, StandThLfdnr as stdtheme_id
 FROM `zwischtab`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = UNDEFINED
 VIEW `wiw_themes` AS
 SELECT LfdNr AS id, Thema AS theme_name
 FROM `thementab`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `wiw_merged` AS
 SELECT wiw_items.id, wiw_items.title, wiw_items.author, wiw_items.page, wiw_items.note, wiw_items.file,
 CONCAT_WS('/', wiw_articles.article_title, wiw_articles.version) AS article_fulltitle,
 wiw_articles.article_id, wiw_articles.article_title, wiw_articles.version,
 wiw_rooms.title AS room_title, wiw_racks.title AS rack_title,
 wiw_trays.title AS tray_title, wiw_filings.title AS filing_title, wiw_items.address_id
 FROM wiw_items
 INNER JOIN wiw_articles ON wiw_items.article_id=wiw_articles.article_id
 LEFT JOIN wiw_rooms ON wiw_rooms.id=wiw_articles.room_id 
 LEFT JOIN wiw_racks ON wiw_racks.id=wiw_articles.rack_id 
 LEFT JOIN wiw_trays ON wiw_trays.id=wiw_articles.tray_id
 LEFT JOIN wiw_filings ON wiw_filings.id=wiw_articles.filing_id;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `whatiswhere_addi_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color, Laenge AS length, Sicherheit AS security FROM zusatz_wasistwo_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `calls` AS 
 SELECT LfdNr AS id, `Datum` AS date_from, beendet AS date_to, disconnected, `RufNummer` AS phone, `ausgehend` AS active_call, `angenommen` AS received,
 `LfdNr_Adr` AS address_id, `LfdNr_Adr_Caller` AS caller_address_id, `No_Adr_Caller` AS caller_no_address, `LfdNr_User` AS staff_id, last_update FROM `telefonate`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `drawings_addi_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color, Laenge AS length, Sicherheit AS security, isfulltext FROM zusatz_planverz_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_drawings_addresses`
 AS SELECT LfdNr AS id, LfdNr_Adr AS address_id, LfdNr_Plan AS drawing_id, unique_add_id,
 isFrei AS is_released, FreiDate AS released_on, FreiBis AS released_until FROM lut_plan_adr;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `drawing_sizes`
 AS SELECT LfdNr AS id, Bez AS name, Flaeche AS area, company_id  FROM plangroessen;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `drawing_types`
 AS SELECT LfdNr AS id, ArtText AS name, Bemerkung AS purpose, company_id FROM planart;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `drawings_outbox` AS
 SELECT LfdNr AS id, An AS address_id, plan AS drawing_id, Anzahl AS amount, Datum AS `date`,  Bemerkung AS purpose, LieferScheinNr AS transmittal_form_id,
 ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id
 FROM planausgabe;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_transmittal_form_addresses` AS
 SELECT `LfdNr` AS id, `LfdNrLieferschein` AS transmittal_form_id, `LfdNrAdresse` AS address_id, `OrdNr` AS sort 
 FROM `lut_lieferscheinadresse`;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `outbox_path` AS
 SELECT outb.id, outb.project_id, p.path_outbox
 FROM outbox AS outb
 LEFT JOIN projects AS p ON outb.project_id=p.id;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_outbox_bcc_addresses`
 AS SELECT LfdNr AS id, LfdNr_PoA AS outbox_id, LfdNr_AdrBCC AS address_id  FROM poausbcc;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_outbox_attachments`
 AS SELECT LfdNr AS id, LfdNr_PoA AS outbox_id, PoAtt_Pfad AS `path`, PoBeschreibung AS description  FROM poausattachments;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `outbox_addi_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color,  Laenge AS length, Sicherheit AS security, isfulltext FROM zusatz_postaus_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `inbox_addi_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color,  Laenge AS length, Sicherheit AS security, isfulltext FROM zusatz_postein_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `inbox_path` AS
 SELECT inb.id, inb.project_id, p.path_inbox
 FROM inbox AS inb
 LEFT JOIN projects AS p ON inb.project_id=p.id;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `dispatch_modes`
 AS SELECT LfdNr AS id, ArtText AS name, Bemerkung AS purpose, company_id  FROM postart;
-- EOC

-- ALSO CHANGE FOR VIEW correspondence_readonly
CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `correspondence` AS
 SELECT LfdNr AS id, Person AS staff_id, Projekt AS project_id, ArtForm AS `correspondence_type_id`, Betrifft AS subject, Empfaenger AS address_id, 
 Text AS text, Datum AS `date`, nurText AS search_text, Serie AS is_serial, Datei AS `file`, Stufe AS security, security_zip, Seiten AS pages, Att_Anz AS attachments, 
 Kopien_Anz AS copies, ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id, PoAusWieOft AS outbox_times,
 archiviert AS is_archived, InHonverwExp AS is_exported_to_fees, RechnungsBetrag AS fee_value, RechnungsNummer AS fee_no, FaelligAm AS due_date, 
 ust AS vat, Rechnungsdatum AS fee_date, Arbeitsbereich AS area_id, HonZus AS fee_addi, add_image, is_valid, timestamp_file, last_autofulltext, last_autofulltext_staff_id,
 last_fulltext_update, related_id, related_uuid, related_type, discount, discount_date, work_package_id, fee_currency_id, fee_value_otcurr, fee_account_id, gobd_date, gobd_hash, from_date, to_date
 FROM formular;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `correspondence_readonly` AS
 SELECT CONCAT_WS( '__', corr.id, lca.address_id) AS id, corr.id AS correspondence_id, lca.address_id AS address_id, corr.address_id AS address_or_group_id,
 corr.staff_id, corr.project_id, corr.correspondence_type_id, corr.subject, corr.text, corr.`date`, corr.search_text, corr.is_serial, corr.`file`, corr.security, corr.security_zip, corr.pages, corr.attachments,
 corr.copies, corr.created_date, corr.created_by_id, corr.change_date, corr.changed_by_id, corr.outbox_times, corr.is_archived, corr.is_exported_to_fees, corr.fee_value,
 corr.fee_no, corr.due_date, corr.vat, corr.fee_date, corr.area_id, corr.fee_addi, corr.add_image, corr.is_valid, corr.timestamp_file, corr.last_autofulltext, corr.last_autofulltext_staff_id,
 corr.last_fulltext_update, corr.related_id, corr.related_uuid, corr.related_type, discount, discount_date, work_package_id, fee_currency_id, fee_value_otcurr, fee_account_id, gobd_date, gobd_hash
 FROM lut_correspondence_addresses AS lca
 INNER JOIN correspondence AS corr ON corr.id = lca.correspondence_id;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `correspondence_addi_def`
 AS SELECT LfdNr AS id, name, OrdNr AS sort, FeldName AS field, Typ AS type, subtype, fieldvalues, isrequired, color,  Laenge AS length, Sicherheit AS security, isfulltext FROM zusatz_formular_def;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `correspondence_types` AS
 SELECT LfdNr AS id, Art AS `name`, Text1 AS text1, Text2 AS text2, rtfDefault AS rtf_default, VorlagenDatei AS template_file, gueltig AS is_valid,
 ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id, Sicherheit AS security, security_zip, special_type
 FROM formart;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `correspondence_types_structure` AS
 SELECT formart.LfdNr AS type_id, 
    struct.LfdNr AS struct_id, struct.LfdNr_Parent AS parent_id, struct.OrdnerBezeichnung AS name, struct.VorlagenPfad AS path
 FROM formart
 LEFT JOIN lut_formart_struktur AS lut ON lut.LfdNr_FormArt = formart.LfdNr
 LEFT JOIN formart_struktur AS struct ON lut.LfdNr_Struktur = struct.LfdNr;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `correspondence_structure` AS
 SELECT LfdNr AS id, LfdNr_Parent AS parent_id, OrdnerBezeichnung AS name, VorlagenPfad AS path
 FROM formart_struktur;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_correspondence_structure_type` AS
 SELECT LfdNr AS id, LfdNr_FormArt AS type_id, LfdNr_Struktur AS struct_id
 FROM lut_formart_struktur;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `correspondence_locking`
 AS SELECT LfdNr AS id, OpenDoc_Nr AS correspondence_id, User_LfdNr AS staff_id, session_uniqid, lock_time FROM opendocs;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `lut_correspondence_copies`
 AS SELECT LfdNr AS id, LfdNr_Dok AS correspondence_id, Lfdnr_Empf AS address_id, OrdNr AS sort FROM kopienan;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `correspondence_attachments`
 AS SELECT LfdNr AS id, LfdNr_Dok AS correspondence_id, Att_Pfad AS `path`, real_name, Beschreibung AS description, 
 ustrDok AS is_us_document, Stufe AS security, security_zip,
 Betreff AS subject, orig_correspondence_id, drawing_id, addressfile_id, created_by_id, created_date FROM dokattachments;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `files`
 AS SELECT LfdNr AS id, Pfad AS `path`, Beschreibung AS purpose, Projekt AS project_id, Ebene AS `level`, Titel AS title, Root AS root,
 ErstAm AS created_date, ErstVon AS created_by_id, AendAm AS change_date, AendVon AS changed_by_id FROM dateien;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `numbergeneration`
 AS SELECT `Nummer` AS number, `Text` AS subject, `User` AS staff_id, `Projekt` AS project_id, `Datum` AS gdate,
 `Jahr` AS gyear, `Monat` AS gmonth FROM nummern_generieren;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `numbergeneration_log`
 AS SELECT `Nummer` AS gnumber, `User` AS staff_id, `Datum` AS gdate, `Bemerkung` AS subject FROM nummern_protokoll;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `payments_fees_values`
 AS SELECT pf.payments_id AS id, pf.fee_areas_offer_id AS fee_areas_offer_id, pf.percentage AS percentage, pf.`value` AS `value`, pp.invoice_date
 FROM `payments_fees` `pf` 
 INNER JOIN `payments` `pp` 
 ON `pf`.`payments_id` = `pp`.`id`
 WHERE status=20;
-- EOC


CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `address_groups_fullname` AS
 SELECT a.id, a.name, a.company_id, a.project_id, 
    IFNULL(CONCAT(p.project_name, ' ', p.project_number), '') AS projectname1,
    IFNULL(CONCAT(p.project_number, ' ', p.project_name), '') AS projectname2,
    IFNULL(CONCAT(a.name, ' [', p.project_name, ' ', p.project_number, ']'), a.name) AS fullname1,
    IFNULL(CONCAT(a.name, ' [', p.project_number, ' ', p.project_name, ']'), a.name) AS fullname2
FROM `address_groups` AS a
    LEFT JOIN `projects` AS p
    ON a.project_id = p.id;
-- EOC

-- Add translations main tables
CREATE TABLE IF NOT EXISTS `translations` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`name` VARCHAR( 50 ) NOT NULL ,
	`language` VARCHAR( 50 ) NOT NULL ,
	`value` TEXT NOT NULL ,
	PRIMARY KEY ( `id` )
) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC
-- USC Erstelle work_packages parent_id cache.

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------
UPDATE work_packages SET parent_id_cache = us_get_parent_package_lftrgt(project_id, lft, rgt);
-- EOC
-- USC Erstelle Trigger und Indizes.

-- --------------------------------------------------------------------------------------------------
-- @todo Remove the DROP commands below, after some time
DROP TRIGGER IF EXISTS update_zusatz_extkosten;
-- EOC
DROP TRIGGER IF EXISTS rem_zusatz_extkosten;
-- EOC
DROP TRIGGER IF EXISTS update_zusatz_honverw;
-- EOC
DROP TRIGGER IF EXISTS rem_zusatz_honverw;
-- EOC
DROP TABLE IF EXISTS `update_views`;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- Create Trigger for INSERT
DROP TRIGGER IF EXISTS add_projekte_update_views;
-- EOC

DELIMITER $$
	CREATE TRIGGER add_projekte_update_views AFTER INSERT on projekte
		FOR EACH ROW BEGIN
                        UPDATE `update_counters` SET `count` = `count` + 1 WHERE `type` = 1;
		END;
	$$
DELIMITER ;
-- EOC

-- Create Trigger for UPDATE
DROP TRIGGER IF EXISTS update_projekte_update_views;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_projekte_update_views AFTER UPDATE on projekte
		FOR EACH ROW BEGIN
                        UPDATE `update_counters` SET `count` = `count` + 1 WHERE `type` = 1;
		END;
	$$
DELIMITER ;
-- EOC

-- Create Trigger for DELETE
DROP TRIGGER IF EXISTS rem_projekte_to_search;
-- EOC

DELIMITER $$
	CREATE TRIGGER rem_projekte_to_search AFTER DELETE on projekte
		FOR EACH ROW BEGIN
                        UPDATE `update_counters` SET `count` = `count` + 1 WHERE `type` = 1;
		END;
	$$
DELIMITER ;
-- EOC

-- Create Triggers for the resource planner portlet

-- when staff start, end or holiday rate has changed AND - after staff gets set inactive
DROP TRIGGER IF EXISTS update_report_wh_staff_change;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_report_wh_staff_change AFTER UPDATE on personen
            FOR EACH ROW BEGIN
                if (NEW.`Start` <=> OLD.`Start`)=0 || (NEW.`Ende` <=> OLD.`Ende`)=0 || (NEW.`FeiertagSatz` <=> OLD.`FeiertagSatz`)=0 THEN
                    begin
                            INSERT INTO report_working_hours_dirty(staff_id) VALUES(NEW.LfdNr);
                    end;
                end if;

                DELETE FROM report_working_hours WHERE staff_id = NEW.LfdNr AND date >= NEW.Ende;
            END;
	$$
DELIMITER ;
-- EOC

-- after staff has been deleted
DROP TRIGGER IF EXISTS delete_staff_from_report_working_hours;
-- EOC

DELIMITER $$
	CREATE TRIGGER delete_staff_from_report_working_hours BEFORE DELETE on personen
		FOR EACH ROW BEGIN
			DELETE FROM report_working_hours WHERE staff_id = OLD.LfdNr;
			DELETE FROM report_working_hours_dirty WHERE staff_id = OLD.LfdNr;
		END;
	$$
DELIMITER ;
-- EOC

-- Remove old after staff gets set inactive
DROP TRIGGER IF EXISTS after_set_staff_incative;
-- EOC

-- when target hours change
DROP TRIGGER IF EXISTS update_report_wh_target_hours_change;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_report_wh_target_hours_change AFTER UPDATE on tagessollstd
		FOR EACH ROW BEGIN
			INSERT INTO report_working_hours_dirty(staff_id) VALUES(NEW.Pers_LfdNr);
		END;
	$$
DELIMITER ;
-- EOC

-- when new target hours added
DROP TRIGGER IF EXISTS update_report_wh_target_hours_insert;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_report_wh_target_hours_insert AFTER INSERT on tagessollstd
		FOR EACH ROW BEGIN
			INSERT INTO report_working_hours_dirty(staff_id) VALUES(NEW.Pers_LfdNr);
		END;
	$$
DELIMITER ;
-- EOC

-- when target hour gets removed
DROP TRIGGER IF EXISTS update_report_wh_target_hours_delete;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_report_wh_target_hours_delete BEFORE DELETE on tagessollstd
		FOR EACH ROW BEGIN
			INSERT INTO report_working_hours_dirty(staff_id) VALUES(OLD.Pers_LfdNr);
		END;
	$$
DELIMITER ;
-- EOC

-- when skill grp gets updated
DROP TRIGGER IF EXISTS update_report_wh_skill_grp_update;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_report_wh_skill_grp_update AFTER UPDATE on lut_staff_skill_group
		FOR EACH ROW BEGIN
			INSERT INTO report_working_hours_dirty(staff_id) VALUES(NEW.staff_id);
		END;
	$$
DELIMITER ;
-- EOC

-- when user gets a new skill grp
DROP TRIGGER IF EXISTS update_report_wh_skill_grp_insert;
-- EOC
 
DELIMITER $$
	CREATE TRIGGER update_report_wh_skill_grp_insert AFTER INSERT on lut_staff_skill_group
		FOR EACH ROW BEGIN
			INSERT INTO report_working_hours_dirty(staff_id) VALUES(NEW.staff_id);
		END;
	$$
DELIMITER ;
-- EOC

-- before skill grps gets removed
DROP TRIGGER IF EXISTS update_report_wh_skill_grp_delete;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_report_wh_skill_grp_delete BEFORE DELETE on lut_staff_skill_group
		FOR EACH ROW BEGIN
			INSERT INTO report_working_hours_dirty(staff_id) VALUES(OLD.staff_id);
		END;
	$$
DELIMITER ;
-- EOC

-- when vacation added
DROP TRIGGER IF EXISTS update_report_wh_vacation_insert;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_report_wh_vacation_insert AFTER INSERT on uv_buchungen
		FOR EACH ROW BEGIN
			INSERT INTO report_working_hours_dirty(staff_id) VALUES(NEW.LfdNr_Mitarbeiter);
		END;
	$$
DELIMITER ;
-- EOC

-- when vacation has changed
DROP TRIGGER IF EXISTS update_report_wh_vacation_change;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_report_wh_vacation_change AFTER UPDATE on uv_buchungen
		FOR EACH ROW BEGIN
			INSERT INTO report_working_hours_dirty(staff_id) VALUES(NEW.LfdNr_Mitarbeiter);
		END;
	$$
DELIMITER ;
-- EOC

-- before vacation has been deleted
DROP TRIGGER IF EXISTS update_report_wh_vacation_delete;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_report_wh_vacation_delete BEFORE DELETE on uv_buchungen
		FOR EACH ROW BEGIN
			INSERT INTO report_working_hours_dirty(staff_id) VALUES(OLD.LfdNr_Mitarbeiter);
		END;
	$$
DELIMITER ;
-- EOC

-- when holiday changed
DROP TRIGGER IF EXISTS update_report_wh_holiday_change;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_report_wh_holiday_change AFTER UPDATE on feiertage
		FOR EACH ROW BEGIN
			INSERT INTO report_working_hours_dirty(staff_id) VALUES(-1);
		END;
	$$
DELIMITER ;
-- EOC

-- before holiday has been removed
DROP TRIGGER IF EXISTS update_report_wh_holiday_delete;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_report_wh_holiday_delete BEFORE DELETE on feiertage
		FOR EACH ROW BEGIN
			INSERT INTO report_working_hours_dirty(staff_id) VALUES(-1);
		END;
	$$
DELIMITER ;
-- EOC

-- after holiday has been insert
DROP TRIGGER IF EXISTS update_report_wh_holiday_insert;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_report_wh_holiday_insert AFTER INSERT on feiertage
		FOR EACH ROW BEGIN
			INSERT INTO report_working_hours_dirty(staff_id) VALUES(-1);
		END;
	$$
DELIMITER ;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- update the work package table when the resource planner changes the start/end date
DROP TRIGGER IF EXISTS update_work_package_date;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_work_package_date AFTER UPDATE on lut_skill_wp
		FOR EACH ROW BEGIN
                    SET @new_start = (SELECT min(`start`) FROM lut_skill_wp WHERE wp_id = NEW.wp_id);
                    SET @new_end = (SELECT max(`end`) FROM lut_skill_wp WHERE wp_id = NEW.wp_id);
                    UPDATE `work_packages` SET `budget_start` = @new_start, `budget_end` = @new_end WHERE `id` = NEW.wp_id; 
		END;
	$$
DELIMITER ;
-- EOC

-- after insert to the lut_skill_wp table
DROP TRIGGER IF EXISTS update_work_package_date_after_insert;
-- EOC

DELIMITER $$
	CREATE TRIGGER update_work_package_date_after_insert AFTER INSERT on lut_skill_wp
		FOR EACH ROW BEGIN
                    SET @new_start = (SELECT min(`start`) FROM lut_skill_wp WHERE wp_id = NEW.wp_id);
                    SET @new_end = (SELECT max(`end`) FROM lut_skill_wp WHERE wp_id = NEW.wp_id);
                    UPDATE `work_packages` SET `budget_start` = @new_start, `budget_end` = @new_end WHERE `id` = NEW.wp_id; 
		END;
	$$
DELIMITER ;
-- EOC

DROP TRIGGER IF EXISTS update_work_package_date_after_delete;
-- EOC

-- after delete at the lut_skill_wp table
DELIMITER $$
	CREATE TRIGGER update_work_package_date_after_delete AFTER DELETE on lut_skill_wp
		FOR EACH ROW BEGIN
                    SET @new_start = (SELECT min(`start`) FROM lut_skill_wp WHERE wp_id = OLD.wp_id);
                    SET @new_end = (SELECT max(`end`) FROM lut_skill_wp WHERE wp_id = OLD.wp_id);
                    UPDATE `work_packages` SET `budget_start` = @new_start, `budget_end` = @new_end WHERE `id` = OLD.wp_id; 
		END;
	$$
DELIMITER ;
-- EOC

CALL us_add_index_to_table('email_cache_data', 'date', '`date`');
-- EOC

CALL us_add_index_to_table('fees', 'fee_no', '`fee_no`');
-- EOC
CALL us_add_index_to_table('fees_planned', 'fee_no', '`fee_no`');
-- EOC
CALL us_add_index_to_table('fees', 'correspondence_id', '`correspondence_id`');
-- EOC
CALL us_add_index_to_table('fees_planned', 'correspondence_id', '`correspondence_id`');
-- EOC

CALL us_add_index_to_table('formular', 'date', '`Datum`');
-- EOC
CALL us_add_index_to_table('formular', 'is_exported_to_fees', '`InHonverwExp`');
-- EOC

CALL us_add_index_to_table('work_packages', 'is_fee_area', '`is_fee_area`');
-- EOC
CALL us_add_index_to_table('work_packages', 'tag_id', '`tag_id`');
-- EOC
CALL us_add_index_to_table('work_packages', 'cost_centre_id', '`cost_centre_id`');
-- EOC
CALL us_add_index_to_table('work_packages_history', 'date', '`date`' );
-- EOC

CALL us_add_index_to_table('inbox', 'emailcount_test', 'created_by_id, email_cache_id, email_account_id, pid, email_import_start, email_import_attempts' );
-- EOC
CALL us_add_index_to_table('outbox', 'emailcount_test', 'created_by_id, email_cache_id, email_account_id, pid, email_import_start, email_import_attempts' );
-- EOC

CALL us_add_index_to_table('formular', 'formular_stufe', '`Stufe`');
-- EOC

CALL us_add_index_to_table('lut_fee_wp', 'planned_fee_id', '`planned_fee_id`');
-- EOC
CALL us_add_index_to_table('lut_fee_wp', 'fee_id', '`fee_id`');
-- EOC
CALL us_add_index_to_table('lut_fee_wp', 'project_id', '`project_id`');
-- EOC
CALL us_add_index_to_table('lut_fee_wp', 'wp_id', '`wp_id`');
-- EOC

CALL us_add_constraint_to_table('lut_measurements', 'proj_meas', 'UNIQUE', '`project_id` , `measurement_id`' );
-- EOC

-- Personalappointments
-- Create Trigger for INSERT
DROP TRIGGER IF EXISTS add_perstermin_sabre_calendarchanges;
-- EOC

DELIMITER $$
	CREATE TRIGGER add_perstermin_sabre_calendarchanges AFTER INSERT on perstermin
		FOR EACH ROW BEGIN
                    INSERT INTO sabre_calendarchanges(calendarid, uri, synctoken, operation) 
                        VALUES(NEW.An, NEW.sabre_uri, NEW.sabre_synctoken, 1);
		END;
	$$
DELIMITER ;
-- EOC

-- Create Trigger for DELETE
DROP TRIGGER IF EXISTS rem_perstermin_sabre_calendarchanges;
-- EOC

DELIMITER $$
	CREATE TRIGGER rem_perstermin_sabre_calendarchanges AFTER DELETE on perstermin
		FOR EACH ROW BEGIN
                    INSERT INTO sabre_calendarchanges(calendarid, uri, synctoken, operation) 
                        VALUES(
                            OLD.An, 
                            OLD.sabre_uri, 
                            (SELECT GREATEST(IFNULL(sabre_synctoken1, 0), IFNULL(sabre_synctoken2, 0))+1 FROM max_sabre_synctokens),
                            2
                        );
                    DELETE FROM sabre_calendarchanges WHERE calendarid=OLD.An AND uri=OLD.sabre_uri AND operation<>2;
		END;
	$$
DELIMITER ;
-- EOC

-- Opentasks
-- Create Trigger for INSERT
DROP TRIGGER IF EXISTS add_todo_sabre_taskchanges;
-- EOC

DELIMITER $$
	CREATE TRIGGER add_todo_sabre_taskchanges AFTER INSERT on todo
		FOR EACH ROW BEGIN
                    INSERT INTO sabre_taskchanges(calendarid, uri, synctoken, operation) 
                        VALUES(NEW.ZuTunVon, NEW.sabre_uri, NEW.sabre_synctoken, 1);
		END;
	$$
DELIMITER ;
-- EOC

-- Create Trigger for DELETE
DROP TRIGGER IF EXISTS rem_todo_sabre_calendarchanges;
-- EOC
DROP TRIGGER IF EXISTS rem_todo_sabre_taskchanges;
-- EOC

DELIMITER $$
	CREATE TRIGGER rem_todo_sabre_taskchanges AFTER DELETE on todo
		FOR EACH ROW BEGIN
                    INSERT INTO sabre_taskchanges(calendarid, uri, synctoken, operation) 
                        VALUES(
                            OLD.ZuTunVon, 
                            OLD.sabre_uri, 
                            (SELECT GREATEST(IFNULL(sabre_synctoken1, 0), IFNULL(sabre_synctoken2, 0))+1 FROM max_sabre_task_synctokens),
                            2
                        );
                    DELETE FROM sabre_taskchanges WHERE calendarid=OLD.ZuTunVon AND uri=OLD.sabre_uri AND operation<>2;
		END;
	$$
DELIMITER ;
-- EOC

-- Addresses
-- Create Trigger for INSERT
DROP TRIGGER IF EXISTS add_adressen_sabre_cardchanges;
-- EOC

DELIMITER $$
	CREATE TRIGGER add_adressen_sabre_cardchanges AFTER INSERT on adressen
		FOR EACH ROW BEGIN
                    INSERT INTO sabre_cardchanges(uri, synctoken, operation) 
                        VALUES(NEW.sabre_uri, NEW.sabre_synctoken, 1);
		END;
	$$
DELIMITER ;
-- EOC

-- Create Trigger for DELETE
DROP TRIGGER IF EXISTS rem_adressen_sabre_calendarchanges;
-- EOC
DROP TRIGGER IF EXISTS rem_adressen_sabre_cardchanges;
-- EOC

DELIMITER $$
	CREATE TRIGGER rem_adressen_sabre_cardchanges AFTER DELETE on adressen
		FOR EACH ROW BEGIN
                    INSERT INTO sabre_cardchanges(uri, synctoken, operation) 
                        VALUES(
                            OLD.sabre_uri, 
                            (SELECT GREATEST(IFNULL(sabre_synctoken1, 0), IFNULL(sabre_synctoken2, 0))+1 FROM max_sabre_card_synctokens),
                            2
                        );
                    DELETE FROM sabre_cardchanges WHERE uri=OLD.sabre_uri AND operation<>2;
		END;
	$$
DELIMITER ;
-- EOC

-- UUIDS
-- Create Trigger for INSERT
-- PROJECTS
DROP TRIGGER IF EXISTS add_project;
-- EOC
DELIMITER $$
	CREATE TRIGGER add_project BEFORE INSERT on projekte
		FOR EACH ROW BEGIN
        	SET NEW.uuid = us_uuid_v4();
		END;
	$$
DELIMITER ;
-- EOC

-- ADDRESSES
DROP TRIGGER IF EXISTS add_address;
-- EOC
DELIMITER $$
	CREATE TRIGGER add_address BEFORE INSERT on adressen
		FOR EACH ROW BEGIN
        	SET NEW.uuid = us_uuid_v4();
		END;
	$$
DELIMITER ;
-- EOC

-- PERSONALAPPOINTMENTS O365
DROP TRIGGER IF EXISTS add_appointment_o365;
-- EOC
DELIMITER $$
	CREATE TRIGGER add_appointment_o365 BEFORE INSERT on personalappointments_ext_o365
		FOR EACH ROW BEGIN
        	SET NEW.uuid = us_uuid_v4();
		END;
	$$
DELIMITER ;
-- EOC

-- USC Erstelle work_packages parent_id cache and check if left value is not bigger than right value Trigger.
-- --------------------------------------------------------------------------------------------------
-- Create Trigger for INSERT
DROP trigger IF EXISTS CHK_rgtGreaterlft_on_insert;
-- EOC
DROP TRIGGER IF EXISTS add_work_packages_update_parent_id;
-- EOC
DROP TRIGGER IF EXISTS trgr_work_packages_on_insert;
-- EOC

-- before insert check if rgt is greater than the lft value
-- before insert set parent_id_cache value
DELIMITER $$
	CREATE TRIGGER trgr_work_packages_on_insert BEFORE INSERT ON work_packages
            FOR EACH ROW BEGIN
                IF (NEW.rgt < NEW.lft) THEN 
                    SIGNAL SQLSTATE '45000'
                    SET MESSAGE_TEXT = 'uStrich: left value has to be less than the right value';
		END IF;
                SET NEW.parent_id_cache = us_get_parent_package_lftrgt(NEW.project_id, NEW.lft, NEW.rgt);
            END;
	$$
DELIMITER ;
-- EOC

-- Create Trigger for UPDATE
DROP trigger IF EXISTS CHK_rgtGreaterlft_on_update;
-- EOC
DROP TRIGGER IF EXISTS update_work_packages_update_parent_id;
-- EOC
DROP TRIGGER IF EXISTS trgr_work_packages_on_update;
-- EOC

-- before update check if rgt is greater than the lft value
-- before update set parent_id_cache value
DELIMITER $$
	CREATE TRIGGER trgr_work_packages_on_update BEFORE UPDATE ON work_packages
            FOR EACH ROW BEGIN
                IF (NEW.rgt < NEW.lft) THEN 
                    SIGNAL SQLSTATE '45000'
                    SET MESSAGE_TEXT = 'uStrich: left value has to be less than the right value';
		END IF;
                SET NEW.parent_id_cache = us_get_parent_package_lftrgt(NEW.project_id, NEW.lft, NEW.rgt);
            END;
	$$
DELIMITER ;
-- EOC

CALL us_add_constraint_to_table('portlets', 'unique_id_unique', 'UNIQUE', '`unique_id`' );
-- EOC
-- USC Messgrößen.

-- Migrate projekte to lut_measurements
CALL us_migrate_projekte_to_lut_measurements();
-- EOC

-- Prepare cache_project_measurement
CALL us_create_cache_project_measurement(1, ~0 >> 33, @validate_outinfo);
-- EOC
-- USC Views fuer Auswertungen werden angelegt.

-- --------------------------------------------------------------------------------------------------
-- For reports
-- --------------------------------------------------------------------------------------------------

-- #x2#
-- CREATE OR REPLACE
--  ALGORITHM = MERGE
--  VIEW `report_times`
--  AS SELECT times.*, woa.fee_area_id
--  FROM times
--  LEFT JOIN work_areas AS woa ON times.area_id=woa.id;
-- -- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `report_times_datemonth`
 AS SELECT project_id, staff_id, number, date, CONCAT(MONTH(date),'_',YEAR(date)) AS datemonth
 FROM times;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `report_overtime_datemonth`
 AS SELECT overtime_rate_id, staff_id, number, date, CONCAT(MONTH(date),'_',YEAR(date)) AS datemonth, paid
 FROM overtime;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `report_start_end_times`
 AS SELECT Person AS staff_id, Datum AS date,
 CONCAT_WS(' - ', DATE_FORMAT(ZeitBeginn, '%H:%i'), DATE_FORMAT(ZeitEnde, '%H:%i')) AS set_info,
 TIMESTAMPDIFF(SECOND, ZeitBeginn, ZeitEnde)-(ZeitAbzug*3600) AS timediff,
 DATE_FORMAT(ZeitBeginn, '%H:%i') AS start_time, DATE_FORMAT(ZeitEnde, '%H:%i') AS end_time,
 ZeitAbzug AS time_deduct, breaks
 FROM zeiten_beginnende;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `report_measurements`
 AS SELECT mess.id, mess.name,
 ( SELECT SUM(lm1.value) FROM lut_measurements AS lm1 WHERE lm1.measurement_id=mess.id ) AS mess_sum,
 ( SELECT SUM(t1.number) FROM times AS t1 WHERE t1.project_id IN (SELECT lm2.project_id from lut_measurements AS lm2 WHERE lm2.measurement_id=mess.id) ) AS mess_hours
 FROM measurements AS mess;
-- EOC

-- --------------------------------------------------------------------------------------------------
-- For logging reports
-- --------------------------------------------------------------------------------------------------
CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `report_times_logging`
 AS SELECT tilo.id AS old_id, tilo.project_id AS old_project_id, tilo.staff_id AS old_staff_id, tilo.number AS old_number,
 tilo.factor AS old_factor, tilo.time_from AS old_time_from, tilo.time_to AS old_time_to,
 tilo.purpose AS old_purpose, tilo.date AS old_date, tilo.area_id AS old_area_id, tilo.cost_centre_id AS old_cost_centre_id,
 tilo.deducted_day AS old_deducted_day,
 tilo.changed_by_id AS old_changed_by_id, tilo.is_ignore AS old_is_ignore, tilo.gross_hourly_wage AS old_gross_hourly_wage,
 tilo.log_change_mode AS log_change_mode, tilo.log_change_date AS log_change_date, tilo.log_changed_by_id  AS log_changed_by_id,
 tilo.company_id AS old_company_id, tilo.purpose_internal AS old_purpose_internal,
 tilo.is_client_changed AS old_is_client_changed, 
 tilo.addi_val1 AS old_addi_val1, tilo.addi_val2 AS old_addi_val2, 
 tilo.work_package_id AS old_work_package_id,
 1+0 AS one, times.*
 FROM times_logging AS tilo
 LEFT OUTER JOIN times ON tilo.id = times.id;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `report_extras_logging`
 AS SELECT 
 exlo.id AS old_id, exlo.project_id AS old_project_id, exlo.staff_id AS old_staff_id, 
 exlo.purpose AS old_purpose, exlo.number AS old_number, exlo.description AS old_description,
 exlo.date AS old_date, exlo.type_id AS old_type_id,
 exlo.area_id AS old_area_id, exlo.cost_centre_id AS old_cost_centre_id,
 exlo.changed_by_id AS old_changed_by_id, exlo.is_ignore AS old_is_ignore,
 exlo.log_change_mode AS log_change_mode, exlo.log_change_date AS log_change_date, exlo.log_changed_by_id  AS log_changed_by_id,
 exlo.company_id AS old_company_id, 
 exlo.is_client_changed AS old_is_client_changed, 
 exlo.addi_val1 AS old_addi_val1, exlo.addi_val2 AS old_addi_val2, 
 exlo.work_package_id AS old_work_package_id,
 1+0 AS one, extras.*
 FROM extras_logging AS exlo
 LEFT OUTER JOIN extras ON exlo.id = extras.id;
-- EOC


CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `report_travels_logging`
 AS SELECT 
 trlo.id AS old_id, trlo.project_id AS old_project_id, trlo.staff_id AS old_staff_id, 
 trlo.number AS old_number, trlo.route AS old_route, trlo.is_company_car AS old_is_company_car,
 trlo.km_from AS old_km_from, trlo.km_to AS old_km_to, 
 trlo.time_from AS old_time_from, trlo.time_to AS old_time_to, 
 trlo.purpose AS old_purpose, trlo.description AS old_description,
 trlo.date AS old_date, trlo.type_id AS old_type_id,
 trlo.area_id AS old_area_id, trlo.cost_centre_id AS old_cost_centre_id,
 trlo.changed_by_id AS old_changed_by_id, trlo.is_ignore AS old_is_ignore,
 trlo.log_change_mode AS log_change_mode, trlo.log_change_date AS log_change_date, trlo.log_changed_by_id  AS log_changed_by_id,
 trlo.company_id AS old_company_id, 
 trlo.is_client_changed AS old_is_client_changed,
 trlo.addi_val1 AS old_addi_val1, trlo.addi_val2 AS old_addi_val2,
 trlo.work_package_id AS old_work_package_id,
 1+0 AS one, travels.*
 FROM travels_logging AS trlo
 LEFT OUTER JOIN travels ON trlo.id = travels.id;
-- EOC

CREATE OR REPLACE
 ALGORITHM = MERGE
 VIEW `report_sendmail`
 AS SELECT sema.*, afm.fullname AS first_recipient_fullname, afm.fullnamelong AS first_recipient_fullnamelong, afm.fullnameshort AS first_recipient_fullnameshort, afm.id AS first_recipient_id
 FROM sendmail AS sema
 LEFT JOIN addresses_fullname AS afm ON afm.id = substring(sema.recipients_to_ids, 1, LOCATE('_', sema.recipients_to_ids)-1);
-- EOC

-- #x2#
-- CREATE OR REPLACE
--  ALGORITHM = MERGE
--  VIEW `report_fee_areas_project_allocation`
--  AS SELECT sum(l1.costs) as costs, l1.project_id, lh1.valid_to_date,
-- lh1.id,
-- 	CASE lh1.valid_to_date IS NULL WHEN true THEN 
-- 		(SELECT max(lh3.valid_to_date) FROM lut_fee_areas_proj_history AS lh3 WHERE lh1.project_id=lh3.project_id)
-- 	ELSE
-- 		(SELECT max(lh2.valid_to_date) FROM lut_fee_areas_proj_history AS lh2 WHERE lh1.project_id=lh2.project_id AND lh2.valid_to_date<lh1.valid_to_date)
-- 	END AS before_date
-- FROM lut_fee_areas_proj AS l1
-- LEFT JOIN lut_fee_areas_proj_history AS lh1 ON l1.lut_fee_areas_proj_history_id=lh1.id
-- 
-- GROUP BY l1.project_id, lh1.valid_to_date
-- 
-- ORDER BY before_date, lh1.valid_to_date;
-- -- EOC

-- #x2#
-- CREATE OR REPLACE
--  ALGORITHM = MERGE
--  VIEW `report_completion_level`
--  AS SELECT cl.project_id, cl.work_area_id,
--  cl.completion_level AS completion_level,
--  cl.completion_level_history_id AS completion_level_history_id,
--  clh.valid_to_date AS valid_to_date,
--  (
--     SELECT MAX(bbl1.planned_costs)
--     FROM budget_plan AS bbl1 
--     LEFT JOIN budget_plan_history AS lh1 ON bbl1.budget_plan_history_id=lh1.id 
--     WHERE lh1.valid_to_date IS NULL AND bbl1.project_id=cl.project_id AND bbl1.area_id=cl.work_area_id
--  ) * cl.completion_level AS costscompleted,
--  (
--     SELECT MAX(bbl1.proportion)
--     FROM budget_plan AS bbl1 
--     LEFT JOIN budget_plan_history AS lh1 ON bbl1.budget_plan_history_id=lh1.id 
--     WHERE lh1.valid_to_date IS NULL AND bbl1.project_id=cl.project_id AND bbl1.area_id=cl.work_area_id
--  ) AS proportion,
--  (
--     SELECT SUM(bbl1.proportion)
--     FROM budget_plan AS bbl1 
--     LEFT JOIN budget_plan_history AS lh1 ON bbl1.budget_plan_history_id=lh1.id 
--     WHERE lh1.valid_to_date IS NULL AND bbl1.project_id=cl.project_id
--  ) AS sumproportion,
--  CASE clh.valid_to_date IS NULL WHEN true THEN 
--     (SELECT max(clh3.valid_to_date) FROM completion_level_history AS clh3 WHERE clh.project_id=clh3.project_id)
--  ELSE
--     (SELECT max(clh2.valid_to_date) FROM completion_level_history AS clh2 WHERE clh.project_id=clh2.project_id AND clh2.valid_to_date<clh.valid_to_date)
--  END AS before_date
--  FROM `completion_level` AS cl
--  LEFT JOIN `completion_level_history` AS clh ON cl.completion_level_history_id = clh.id;
-- -- EOC

-- #x2#
-- CREATE OR REPLACE
--  VIEW `report_completion_level_only`
--  AS SELECT cl.project_id, cl.work_area_id,
--  cl.completion_level AS completion_level,
--  cl.completion_level_history_id AS completion_level_history_id,
--  clh.valid_to_date AS valid_to_date,
--  (
--     SELECT bbl1.planned_costs
--     FROM budget_plan AS bbl1 
--     LEFT JOIN budget_plan_history AS lh1 ON bbl1.budget_plan_history_id=lh1.id 
--     WHERE lh1.valid_to_date IS NULL AND bbl1.project_id=cl.project_id AND bbl1.area_id=cl.work_area_id
--     LIMIT 1
--  ) * cl.completion_level AS costscompleted,
--  CASE clh.valid_to_date IS NULL WHEN true THEN 
--     (SELECT max(clh3.valid_to_date) FROM completion_level_history AS clh3 WHERE clh.project_id=clh3.project_id)
--  ELSE
--     (SELECT max(clh2.valid_to_date) FROM completion_level_history AS clh2 WHERE clh.project_id=clh2.project_id AND clh2.valid_to_date<clh.valid_to_date)
--  END AS before_date
--  FROM `completion_level` AS cl
--  LEFT JOIN `completion_level_history` AS clh ON cl.completion_level_history_id = clh.id;
-- -- EOC

-- #x2#
-- CREATE OR REPLACE
--  ALGORITHM = MERGE
--  VIEW `report_completion_level_bbl1`
--  AS SELECT bbl.planned_costs, bbl.proportion, bbl.project_id, bbl.area_id
--     FROM budget_plan AS bbl 
--     LEFT JOIN budget_plan_history AS lh1 ON bbl.budget_plan_history_id=lh1.id 
--     WHERE lh1.valid_to_date IS NULL;
-- -- EOC
    
-- #x2#
-- CREATE OR REPLACE
--  ALGORITHM = MERGE
--  VIEW `report_completion_level_bbl2`
--  AS SELECT SUM(bbl.proportion) AS proportion, bbl.project_id
--     FROM budget_plan AS bbl 
--     LEFT JOIN budget_plan_history AS lh1 ON bbl.budget_plan_history_id=lh1.id 
--     WHERE lh1.valid_to_date IS NULL
--     GROUP BY bbl.project_id;
-- -- EOC

-- #x2#
-- CREATE OR REPLACE
--  ALGORITHM = MERGE
--  VIEW `report_completion_level_current`
--  AS SELECT cl.project_id, cl.work_area_id,
--  cl.completion_level AS completion_level,
--  cl.completion_level_history_id AS completion_level_history_id,
--  clh.valid_to_date AS valid_to_date,
--  bbl1.planned_costs * cl.completion_level AS costscompleted,
--  bbl1.proportion,
--  bbl2.proportion AS sumproportion
--  FROM `completion_level` AS cl
--  LEFT JOIN `completion_level_history` AS clh ON cl.completion_level_history_id = clh.id
--  LEFT JOIN report_completion_level_bbl1 AS bbl1 ON bbl1.project_id=cl.project_id AND bbl1.area_id=cl.work_area_id
--  LEFT JOIN report_completion_level_bbl2 AS bbl2 ON bbl2.project_id=cl.project_id
--  WHERE clh.valid_to_date IS NULL;
-- -- EOC

-- #x2#
-- CREATE OR REPLACE
--  ALGORITHM = MERGE
--  VIEW `report_completion_level_fee`
--  AS SELECT cl.*, woas.fee_area_id
--  FROM `report_completion_level_current` AS cl
--  LEFT JOIN work_areas AS woas ON cl.work_area_id=woas.id
--  WHERE cl.valid_to_date IS NULL;
-- -- EOC


CREATE OR REPLACE
 VIEW `report_times_changed_gross`
 AS SELECT staff_id, gross_hourly_wage, `date`
 FROM times
 GROUP BY staff_id, gross_hourly_wage, `date`;
-- EOC

-- #x2#
-- CREATE OR REPLACE
--  VIEW `report_projects_fee_areas`
--  AS SELECT
--  p.id as project_id,
--  p.project_name as project_name,
--  p.work_area_category_id,
--  lutwoa.work_area_id,
--  woa.sort AS work_area_sort,
--  woa.fee_area_id
--  FROM projects AS p
--  INNER JOIN lut_work_areas_work_areas_categories AS lutwoa ON lutwoa.work_area_categories_id= p.work_area_category_id
--  INNER JOIN work_areas AS woa ON lutwoa.work_area_id=woa.id;
-- -- EOC

-- #x2#
-- CREATE OR REPLACE
--  VIEW `report_fee_areas_project_allocation_history`
--  AS 
--     SELECT 
--     sum(l1.costs) as costs,
--     l1.project_id,
--     CASE
--         WHEN valid_to_date IS NULL THEN '2099-01-01'
--         ELSE valid_to_date
--     END AS valid_to_date
--     FROM lut_fee_areas_proj AS l1
--     LEFT JOIN lut_fee_areas_proj_history AS lh1 ON l1.lut_fee_areas_proj_history_id=lh1.id
--     GROUP BY l1.project_id, lh1.valid_to_date;
-- -- EOC

-- #x2#
-- CREATE OR REPLACE
--  VIEW `report_budget_plan_history`
--  AS 
--     SELECT 
--     sum(l1.planned_costs) as planned_costs,
--     sum(l1.planned_hours) as planned_hours,
--     l1.project_id, 
--     CASE
--         WHEN valid_to_date IS NULL THEN '2099-01-01'
--         ELSE valid_to_date
--     END AS valid_to_date,
--     lh1.id
--     FROM budget_plan AS l1
--     LEFT JOIN budget_plan_history AS lh1 ON l1.budget_plan_history_id=lh1.id
--     GROUP BY l1.project_id, lh1.valid_to_date;
-- -- EOC
-- USC Standardwerte.

INSERT INTO `currencies` (`id`, `name`, `abbreviation`) 
VALUES (1, 'Euro', '€') 
ON DUPLICATE KEY UPDATE id=id;
-- EOC

-- ONE TIME BUG FIX - REMOVE!!
-- Set invoice date in payments tabe, if missing
UPDATE payments 
SET invoice_date=change_date 
WHERE invoice_date IS NULL 
    AND status=20;
-- EOC

-- Get passwort mode from system settings
UPDATE `personen` 
SET passwort_mode=( SELECT IF(SettingValue='TRUE', 1, 0) FROM settingssystem WHERE SettingType='userpasswordencrypted' )
WHERE passwort_mode IS NULL;
-- EOC

-- Increase passwort mode to 1 (SHA1 with fixed salts)
UPDATE `personen` 
SET `passwort` = SHA1( CONCAT('477518110', `passwort`, '13749', '48492') ),
    passwort_mode = 1
WHERE passwort_mode=0 OR passwort_mode IS NULL;
-- EOC

-- Increase passwort mode to 2 (Only adds random salt)
UPDATE `personen` 
SET `passwort` = CONCAT(SHA1(RAND()), `passwort`),
    passwort_mode = 2
WHERE passwort_mode=1;
-- EOC

-- Increase passwort mode to 3 (Create SHA1 with random salt)
UPDATE `personen` 
SET `passwort` = CONCAT(LEFT(`passwort`, 40), SHA1(`passwort`)),
    passwort_mode = 3
WHERE passwort_mode=2;
-- EOC

-- Write is_special_phase based on the name for work_package_presets
UPDATE 
    work_package_presets 
SET 
    is_special_phase=CONVERT(SUBSTRING(TRIM(name), 1, 1), UNSIGNED) 
WHERE 
        is_special<0 
    AND
        is_special_phase IS NULL
    AND
        LENGTH(name)>1;
-- EOC

-- Write is_special_phase based on the name for work_packages
UPDATE 
    work_packages 
SET 
    is_special_phase=CONVERT(SUBSTRING(TRIM(name), 1, 1), UNSIGNED) 
WHERE 
        is_special<0 
    AND
        is_special_phase IS NULL
    AND
        LENGTH(name)>1;
-- EOC

-- Convert old lut_staff_proj entries to current format
CALL convert_lut_staff_proj_to_new_format();
-- EOC

-- Create is_absent_social flag, based on project

DROP PROCEDURE IF EXISTS us_migrate_12_5__12_6;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_migrate_12_5__12_6()
us_migrate_12_5__12_6lbl:BEGIN

    DECLARE xdate DATETIME DEFAULT curdate() - INTERVAL 1 YEAR;
    DECLARE step VARCHAR(30) CHARSET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'us_migrate_12_5__12_6';
    
    -- Prevent double execution
    IF ( SELECT COUNT(*) FROM `01migrate_11_12_steps` WHERE stepname=step) THEN 
        LEAVE us_migrate_12_5__12_6lbl;
    END IF;
    INSERT INTO `01migrate_11_12_steps` SET stepname=step; 

    -- Prevent execution, if we already have is_absent_social vacations
    IF ( (SELECT COUNT(*) FROM vacations WHERE is_absent_social=true)>0 ) THEN 
        -- INSERT info
        LEAVE us_migrate_12_5__12_6lbl;
    END IF;
    
    UPDATE vacations 
    SET is_absent_social = true
    WHERE 
        is_absent=1 
    AND
        imported_workinput=0
    AND 
        start_date>xdate 
    AND 
        project_id IN (
            SELECT id FROM projects 
            WHERE is_included_in_time_sheet=true 
            AND ID<>(SELECT MAX(value) FROM system_settings WHERE NAME='projekturlaub')
        );
    
END $$
DELIMITER ;
-- EOC

CALL us_migrate_12_5__12_6();
-- EOC

DROP PROCEDURE IF EXISTS migrate_to_global_email_accounts;
-- EOC

DELIMITER $$
CREATE PROCEDURE migrate_to_global_email_accounts()
update_global_email_accountslbl:BEGIN

    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE email_account_id INTEGER;
    DECLARE email_account_staff_id INTEGER;
    DECLARE email_account_email VARCHAR(256) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE email_account_smtp_host VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE email_account_smtp_user VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE email_account_imap_host VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE email_account_imap_user VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE email_account_imap_mailbox VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE email_account_imap_mailbox_out VARCHAR(100) CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
    DECLARE email_account_default_account BOOLEAN;
    DECLARE account_vals CURSOR FOR SELECT id, staff_id, email, smtp_host, smtp_user, imap_host, imap_user, imap_mailbox, imap_mailbox_out, default_account 
        FROM email_accounts
        ORDER BY email, smtp_host, smtp_user, imap_host, imap_user, imap_mailbox, imap_mailbox_out, id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    -- Prevent double execution
    IF ( SELECT COUNT(*) FROM `01migrate_11_12_steps` WHERE stepname='migrate_to_global_email_accounts') THEN 
        LEAVE update_global_email_accountslbl;
    END IF;
    INSERT INTO `01migrate_11_12_steps` SET stepname='migrate_to_global_email_accounts'; 
    
    -- Only for migration
    CALL us_add_to_table2('email_accounts', 'default_account', 'BOOLEAN DEFAULT FALSE AFTER `email`' );

    -- CREATE TABLE
    SET @s = '
        CREATE TABLE IF NOT EXISTS `lut_email_accounts_staff` (
            `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
            `email_account_id` INT NOT NULL,
            `staff_id` INT NOT NULL,
            `right` INT NOT NULL, 
            `is_default_account` BOOLEAN NOT NULL DEFAULT "0"
        ) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    ';
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;

    -- MIGRATE
    SET @last_hash = '';
    SET @current_email_account_id = 0;
    OPEN account_vals;
    cursor_loop: LOOP -- -------------------------------------
        FETCH account_vals INTO email_account_id, email_account_staff_id, email_account_email, email_account_smtp_host, email_account_smtp_user, email_account_imap_host, email_account_imap_user, email_account_imap_mailbox, email_account_imap_mailbox_out, email_account_default_account;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
            /*Create hash value*/
            SET @current_hash = SHA1(CONCAT(email_account_email, email_account_smtp_host, email_account_smtp_user, email_account_imap_host, email_account_imap_user, email_account_imap_mailbox, email_account_imap_mailbox_out));

            /*Cleanup*/
            IF @last_hash = @current_hash THEN
                -- update inbox/outbox for eml download
                UPDATE inbox SET email_account_id = @current_email_account_id WHERE inbox.email_account_id = email_account_id;
                UPDATE outbox SET email_account_id = @current_email_account_id WHERE outbox.email_account_id = email_account_id;
                -- delete from accounts
                DELETE FROM email_accounts WHERE id = email_account_id;
            ELSE
                SET @current_email_account_id = email_account_id;
            END IF;

            /*Update is_default_account*/    
            IF email_account_default_account = 1 THEN
                UPDATE lut_email_accounts_staff SET is_default_account = 0 WHERE lut_email_accounts_staff.staff_id = email_account_staff_id;
            END IF;

            /*Add to lut with full rights*/
            INSERT INTO lut_email_accounts_staff(`email_account_id`, `staff_id`, `right`, `is_default_account`) VALUES(@current_email_account_id, email_account_staff_id, 7, email_account_default_account);

            /*Update last hash value*/
            SET @last_hash = @current_hash;
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  account_vals;

    -- RENAME staff_id to password_salt
    CALL check_rename_column_exists('email_accounts', 'staff_id', 'password_salt', 'INT');

END $$
DELIMITER ;
-- EOC

CALL migrate_to_global_email_accounts();
-- EOC

-- REMOVE default_account cause it has moved to lut table
CALL remove_column('email_accounts', 'default_account');
-- EOC

DROP PROCEDURE IF EXISTS migrate_to_email_ignored_table;
-- EOC

DELIMITER $$
CREATE PROCEDURE migrate_to_email_ignored_table()
migrate_to_email_ignored_tablelbl:BEGIN
    -- Prevent double execution
    IF ( SELECT COUNT(*) FROM `01migrate_11_12_steps` WHERE stepname='migrate_to_email_ignored_table') THEN 
        LEAVE migrate_to_email_ignored_tablelbl;
    END IF;
    INSERT INTO `01migrate_11_12_steps` SET stepname='migrate_to_email_ignored_table'; 
    
    -- CREATE TABLE
    SET @s = '
        CREATE TABLE IF NOT EXISTS `email_ignored` (
            `id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
            `email_cache_mbox_id` INT NOT NULL ,
            `message_id` VARCHAR( 500 ) NOT NULL
        ) auto_increment=1 ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
    ';
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;

    -- MIGRATE
	SET @sql1 = CONCAT('INSERT IGNORE INTO email_ignored (SELECT null, email_cache_mbox_id, message_id  FROM email_cache_data WHERE ignored = 1)');
	PREPARE stmt1 FROM @sql1;
        EXECUTE stmt1;

	-- REMOVE DUPLICATES
    SET @sql2 = CONCAT('DELETE FROM email_ignored WHERE id NOT IN (SELECT * FROM (SELECT MAX(id) FROM email_ignored GROUP BY email_cache_mbox_id, message_id) AS e);');
	PREPARE stmt2 FROM @sql2;
        EXECUTE stmt2;

    -- REMOVE ignored column from email_cache_data table
    -- CALL remove_column('email_cache_data', 'ignored');

END $$
DELIMITER ;
-- EOC

CALL migrate_to_email_ignored_table();
-- EOC

CALL us_add_index_to_table('email_ignored', 'email_cache_mbox_id', '`email_cache_mbox_id`');
-- EOC
CALL us_add_index_to_table('email_cache_data', 'email_cache_mbox_id', '`email_cache_mbox_id`');
-- EOC

DROP PROCEDURE IF EXISTS us_email_indexes;
-- EOC

DELIMITER $$
CREATE PROCEDURE us_email_indexes()
BEGIN
    IF SUBSTRING(VERSION(), 1, 4) = '5.6.' THEN
        CALL us_add_index_to_table('email_ignored', 'message_id', '`message_id`(150)');
        CALL us_add_index_to_table('email_cache_data', 'message_id', '`message_id`(150)');
    ELSE
        CALL us_add_index_to_table('email_ignored', 'message_id', '`message_id`(200)');
        CALL us_add_index_to_table('email_cache_data', 'message_id', '`message_id`(200)');
    END IF;
END $$
DELIMITER ;
-- EOC

CALL us_email_indexes();
-- EOC

-- --------------------------------------------------------------------------------------------------
-- SaaS V2
-- --------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS us_init_saas_v2;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_init_saas_v2(
    IN force_init BOOLEAN, 
    IN domain VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci, 
    IN encryption_key VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
us_init_saas_v2:BEGIN
	DECLARE l_last_row_fetched INTEGER;
	DECLARE tablename TEXT;
	DECLARE non_innodb CURSOR FOR SELECT `TABLE_NAME` FROM information_schema.tables WHERE `TABLE_SCHEMA` = DATABASE() AND `table_type`="BASE TABLE" AND `engine` != 'InnoDB';
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;
        
    IF force_init THEN
        DELETE FROM u10_ci_config WHERE name='us_rights_mode';
        INSERT INTO u10_ci_config SET name='us_rights_mode', value='3';
    END IF;
    
    SELECT COUNT(`value`), `value` INTO @cnt, @us_rights_mode FROM u10_ci_config WHERE name='us_rights_mode';
    IF @cnt != 1 OR IFNULL(@us_rights_mode, 0) != '3' THEN
        LEAVE us_init_saas_v2;
    END IF;
    
    -- ####################
    -- DO INIT
    -- ####################
    
    -- set base url
    IF domain IS NOT NULL THEN
        DELETE FROM u10_ci_config WHERE name='base_url';
        SET @s = CONCAT("INSERT INTO u10_ci_config SET name='base_url', value='", domain, "/ustrich/';");
        PREPARE stmt1 FROM @s;
        EXECUTE stmt1;      
        DEALLOCATE PREPARE stmt1;      	  
    END IF; 	
    
    -- set encryption key
    IF encryption_key IS NOT NULL THEN
        DELETE FROM u10_ci_config WHERE name='encryption_key';
        SET @s = CONCAT("INSERT INTO u10_ci_config SET name='encryption_key', value='", encryption_key, "';");
        PREPARE stmt1 FROM @s;
        EXECUTE stmt1;      
        DEALLOCATE PREPARE stmt1; 
    END IF; 	
    
    -- migrate almost all non innodb tables to innodb for mariadb galera cluster
    SET l_last_row_fetched=0;
    OPEN non_innodb;
    cursor_loop: LOOP -- -------------------------------------
        FETCH non_innodb INTO tablename;
        IF l_last_row_fetched=1 THEN
            LEAVE cursor_loop;
        END IF;
        IF tablename='u10_mutex' THEN  -- skip u10_mutex table from engine conversion
            ITERATE cursor_loop;
        END IF;      
            SET @s=CONCAT('ALTER TABLE ', tablename, ' ENGINE = InnoDB;');
            PREPARE stmt1 FROM @s;
            EXECUTE stmt1;
            DEALLOCATE PREPARE stmt1;      	
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  non_innodb;
    
    -- Set some u10_ci_config settings
    DELETE FROM u10_ci_config WHERE name='login_force_username';
    INSERT INTO u10_ci_config SET name='login_force_username', value='1';
    DELETE FROM u10_ci_config WHERE name='smarty_compile_dir';
    INSERT INTO u10_ci_config SET name='smarty_compile_dir', value='/var/www/html/ustrich/writeable/cache/smarty';
    DELETE FROM u10_ci_config WHERE name='log_threshold';
    INSERT INTO u10_ci_config SET name='log_threshold', value='1';
    DELETE FROM u10_ci_config WHERE name='dav_log_threshold';
    INSERT INTO u10_ci_config SET name='dav_log_threshold', value='1';
    DELETE FROM u10_ci_config WHERE name='email_log_threshold';
    INSERT INTO u10_ci_config SET name='email_log_threshold', value='1';
    DELETE FROM u10_ci_config WHERE name='interfaces_log_threshold';
    INSERT INTO u10_ci_config SET name='interfaces_log_threshold', value='1';
    DELETE FROM u10_ci_config WHERE name='us_block_not_datapath';
    INSERT INTO u10_ci_config SET name='us_block_not_datapath', value='TRUE';
    DELETE FROM u10_ci_config WHERE name='us_pdf_converter';
    INSERT INTO u10_ci_config SET name='us_pdf_converter', value='o365';
    
    -- Set some u10_ci_config settings
    IF NOT EXISTS (SELECT * FROM system_settings WHERE `name`='password_policy_use' AND `value`='TRUE') THEN
        DELETE FROM system_settings WHERE name='password_policy_use';
        INSERT INTO system_settings SET name='password_policy_use', value='TRUE';
        DELETE FROM system_settings WHERE name='password_policy_regex';
        INSERT INTO system_settings SET name='password_policy_regex', value='(?=^[\\wöäüÖÄÜß@!,._\\-\\+=\\/*#$(){}\\[\\]^]{8,}$)';
        DELETE FROM system_settings WHERE name='password_policy_params';
        INSERT INTO system_settings SET name='password_policy_params', value='{\"min_length\":\"8\",\"max_length\":\"0\",\"min_numeric\":\"0\",\"min_upper\":\"0\",\"min_special\":\"0\"}';
    END IF;

END $$
DELIMITER ;
-- EOC

CALL us_init_saas_v2(NULL, NULL, NULL);
-- EOC
UPDATE system_settings SET value='(?=^[\\wöäüÖÄÜß@!,._\\-\\+=\\/*#$(){}\\[\\]^]{8,}$)' WHERE name='password_policy_regex' AND (value='(?=^[-wöäüÖÄÜß@!,._-+=/*#$(){}[]^]{8,}$)' OR value='(?=^[wöäüÖÄÜß@!,._-+=/*#$(){}[]^]{8,}$)');
-- EOC

-- HELPER for migrating DB from SAAS v2 to On-Prem
DROP PROCEDURE IF EXISTS us_uninit_saas_v2;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_uninit_saas_v2()
us_uninit_saas_v2:BEGIN
    -- Unset special rights mode
    DELETE FROM u10_ci_config WHERE name='us_rights_mode';
    -- Unset base url
    DELETE FROM u10_ci_config WHERE name='base_url';
    -- Unset some u10_ci_config settings
    DELETE FROM u10_ci_config WHERE name='smarty_compile_dir';
    DELETE FROM u10_ci_config WHERE name='us_block_not_datapath';
END $$
DELIMITER ;
-- EOC

-- HELPER for optimizing all tables
DROP PROCEDURE IF EXISTS us_optimize_tables;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_optimize_tables()
BEGIN

	SELECT GROUP_CONCAT(table_name)
	FROM INFORMATION_SCHEMA.TABLES
	WHERE table_schema = SCHEMA()
	AND (ENGINE = "InnoDB" OR ENGINE = "MyISAM" OR ENGINE = "ARCHIVE") INTO @my_tables;

	SET @s = CONCAT('OPTIMIZE TABLE ',@my_tables, ';');
	PREPARE stmt1 FROM @s;
	EXECUTE stmt1;
    
END $$
DELIMITER ;
-- EOC

-- Check for activate multitenancy based on companies count
INSERT INTO u10_ci_config (`name`, `value`)
SELECT 'activate_multitenancy',
   CASE WHEN (SELECT COUNT(*) FROM companies) > 1 THEN true ELSE false END
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM u10_ci_config WHERE name = 'activate_multitenancy');
-- EOC
-- USC Bereinige CalDAV und CardDAV Tabellen

-- --------------------------------------------------------------------------------------------------
-- Cleanup for addresses

DROP PROCEDURE IF EXISTS _us_synctoken_incremented_addresses;
-- EOC
DELIMITER $$
CREATE PROCEDURE _us_synctoken_incremented_addresses(
    IN sabre_synctoken_start BIGINT UNSIGNED
)
BEGIN

    DECLARE curr_id INTEGER;

    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE double_rows CURSOR FOR SELECT id
        FROM addresses WHERE sabre_synctoken=sabre_synctoken_start;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;    

    SET @rows_count = 0;

    OPEN double_rows;
    cursor_loop: LOOP -- -------------------------------------
        FETCH double_rows INTO curr_id;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
        
        -- Increase by row count
        UPDATE addresses SET sabre_synctoken = sabre_synctoken + @rows_count WHERE id=curr_id;
        SET @rows_count = @rows_count + 1;
                
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  double_rows;


END $$
DELIMITER ;
-- EOC



DROP PROCEDURE IF EXISTS us_one_per_synctoken_addresses;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_one_per_synctoken_addresses()
us_one_per_synctoken_addresseslbl:BEGIN

    DECLARE curr_sabre_synctoken BIGINT UNSIGNED;
    DECLARE curr_count BIGINT UNSIGNED;

    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE double_synctoken CURSOR FOR SELECT sabre_synctoken, COUNT(*)
        FROM addresses
        GROUP BY sabre_synctoken
        HAVING COUNT(*) > 1
        ORDER BY sabre_synctoken DESC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;
    
    
    OPEN double_synctoken;
    cursor_loop: LOOP -- -------------------------------------
        FETCH double_synctoken INTO curr_sabre_synctoken, curr_count;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
        
        -- Increase all after
        UPDATE sabre_cardchanges SET synctoken = synctoken + curr_count + 1 WHERE synctoken>curr_sabre_synctoken ORDER BY synctoken DESC;
        UPDATE addresses SET sabre_synctoken = sabre_synctoken + curr_count + 1 WHERE sabre_synctoken>curr_sabre_synctoken ORDER BY sabre_synctoken DESC;

        -- Increase found synctoken
        CALL _us_synctoken_incremented_addresses(curr_sabre_synctoken);
                
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  double_synctoken;

END $$
DELIMITER ;
-- EOC




-- --------------------------------------------------------------------------------------------------
-- Cleanup for personalappointments

DROP PROCEDURE IF EXISTS _us_synctoken_incremented_persapp;
-- EOC
DELIMITER $$
CREATE PROCEDURE _us_synctoken_incremented_persapp(
    IN sabre_synctoken_start BIGINT UNSIGNED
)
BEGIN

    DECLARE curr_id INTEGER;

    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE double_rows CURSOR FOR SELECT id
        FROM personalappointments WHERE sabre_synctoken=sabre_synctoken_start;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;    

    SET @rows_count = 0;

    OPEN double_rows;
    cursor_loop: LOOP -- -------------------------------------
        FETCH double_rows INTO curr_id;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
        
        -- Increase by row count
        UPDATE personalappointments SET sabre_synctoken = sabre_synctoken + @rows_count WHERE id=curr_id;
        SET @rows_count = @rows_count + 1;
                
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  double_rows;


END $$
DELIMITER ;
-- EOC



DROP PROCEDURE IF EXISTS us_one_per_synctoken_persapp;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_one_per_synctoken_persapp()
us_one_per_synctoken_persapplbl:BEGIN

    DECLARE curr_sabre_synctoken BIGINT UNSIGNED;
    DECLARE curr_count BIGINT UNSIGNED;

    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE double_synctoken CURSOR FOR SELECT sabre_synctoken, COUNT(*)
        FROM personalappointments
        GROUP BY sabre_synctoken
        HAVING COUNT(*) > 1
        ORDER BY sabre_synctoken DESC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;
    
    
    OPEN double_synctoken;
    cursor_loop: LOOP -- -------------------------------------
        FETCH double_synctoken INTO curr_sabre_synctoken, curr_count;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
        
        -- Increase all after
        UPDATE sabre_cardchanges SET synctoken = synctoken + curr_count + 1 WHERE synctoken>curr_sabre_synctoken ORDER BY synctoken DESC;
        UPDATE personalappointments SET sabre_synctoken = sabre_synctoken + curr_count + 1 WHERE sabre_synctoken>curr_sabre_synctoken ORDER BY sabre_synctoken DESC;

        -- Increase found synctoken
        CALL _us_synctoken_incremented_persapp(curr_sabre_synctoken);
                
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  double_synctoken;

END $$
DELIMITER ;
-- EOC




-- --------------------------------------------------------------------------------------------------
-- Cleanup for opentasks

DROP PROCEDURE IF EXISTS _us_synctoken_incremented_opta;
-- EOC
DELIMITER $$
CREATE PROCEDURE _us_synctoken_incremented_opta(
    IN sabre_synctoken_start BIGINT UNSIGNED
)
BEGIN

    DECLARE curr_id INTEGER;

    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE double_rows CURSOR FOR SELECT id
        FROM opentasks WHERE sabre_synctoken=sabre_synctoken_start;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;    

    SET @rows_count = 0;

    OPEN double_rows;
    cursor_loop: LOOP -- -------------------------------------
        FETCH double_rows INTO curr_id;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
        
        -- Increase by row count
        UPDATE opentasks SET sabre_synctoken = sabre_synctoken + @rows_count WHERE id=curr_id;
        SET @rows_count = @rows_count + 1;
                
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  double_rows;


END $$
DELIMITER ;
-- EOC



DROP PROCEDURE IF EXISTS us_one_per_synctoken_opta;
-- EOC
DELIMITER $$
CREATE PROCEDURE us_one_per_synctoken_opta()
us_one_per_synctoken_optalbl:BEGIN

    DECLARE curr_sabre_synctoken BIGINT UNSIGNED;
    DECLARE curr_count BIGINT UNSIGNED;

    DECLARE l_last_row_fetched INTEGER DEFAULT 0;
    DECLARE double_synctoken CURSOR FOR SELECT sabre_synctoken, COUNT(*)
        FROM opentasks
        GROUP BY sabre_synctoken
        HAVING COUNT(*) > 1
        ORDER BY sabre_synctoken DESC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;
    
    
    OPEN double_synctoken;
    cursor_loop: LOOP -- -------------------------------------
        FETCH double_synctoken INTO curr_sabre_synctoken, curr_count;
        IF l_last_row_fetched = 1 THEN
            LEAVE cursor_loop;
        END IF;
        
        -- Increase all after
        UPDATE sabre_cardchanges SET synctoken = synctoken + curr_count + 1 WHERE synctoken>curr_sabre_synctoken ORDER BY synctoken DESC;
        UPDATE opentasks SET sabre_synctoken = sabre_synctoken + curr_count + 1 WHERE sabre_synctoken>curr_sabre_synctoken ORDER BY sabre_synctoken DESC;

        -- Increase found synctoken
        CALL _us_synctoken_incremented_opta(curr_sabre_synctoken);
                
    END LOOP cursor_loop; -- -------------------------------------
    CLOSE  double_synctoken;

END $$
DELIMITER ;
-- EOC
-- User Filters for PlanQ / X5 / whatever it will be name in the future
DROP TABLE IF EXISTS `filter_q`;
-- EOC
CREATE TABLE `filter_q`
(
    `id`        INT          NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `staff_id`  INT          NOT NULL,
    `filter_id` varchar(255) NOT NULL,
    `value`     MEDIUMTEXT
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- EOC

-- Increase length of account designation in fee accounts
ALTER TABLE `honkonten`
    MODIFY `KontoBez` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL;
-- EOC
# Filename up0040.sql
# Changes to tables are made with procedure calls (us_add_to_table2)
# discuss drop columns (do not drop at the moment)

CALL us_add_to_table2('portlets', 'sort', 'INT' );
-- EOC
CALL us_add_to_table2('portlets', 'width', 'INT' );
-- EOC
CALL us_add_to_table2('portlets', 'height', 'INT' );
-- EOC
CALL remove_column('portlets', 'min_height');
-- EOC

# ALTER TABLE `portlets`
#     DROP COLUMN `position_id`,
#     DROP COLUMN `col`,
#     DROP COLUMN `row`,
#     DROP COLUMN `page_id`,
#     DROP COLUMN `open`
# ;
-- EOC

CALL us_add_to_table2('portlets_tabs', 'icon', 'VARCHAR( 255 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci' );
-- EOC
CALL us_add_to_table2('portlets_pages', 'portlets_group_id', 'INT' );
-- EOC
CALL us_add_to_table2('portlets_pages', 'default_tab_id', 'INT' );
-- EOC

# ALTER TABLE `portlets_tabs`
#     DROP COLUMN `staff_id`,
#     DROP COLUMN `page_id`,
#     DROP COLUMN `columns`
# ;
-- EOC

DROP TABLE IF EXISTS `portlets_sections`;
-- EOC
# Filename up0041.sql

-- USC Entferne alte Tabellen
DROP TABLE IF EXISTS `portlets_groups`;
-- EOC-- USC Weitere Standardwerte.

-- #x2#
-- -- FIX LUT FEE AREA PROJECT WITHOUT HISTORY ID
-- UPDATE lut_fee_areas_proj SET lut_fee_areas_proj_history_id = (
-- 	SELECT id FROM lut_fee_areas_proj_history WHERE project_id = lut_fee_areas_proj.project_id AND lut_fee_areas_proj_history.valid_to_date IS NULL LIMIT 1
-- ) WHERE lut_fee_areas_proj_history_id IS NULL;
-- -- EOC


-- FIX NEW RIGHT R_DATACOLLECTION - DEFAULT GRANT RIGHT
UPDATE staff SET security_49=0 WHERE security_49<>99 OR security_49 IS NULL;
-- EOC

-- corr_mailout_to_pdf - This is not neccessary for X.1. Mail-In is deprecated and mail allocation is done in mailinboxandoutbox
UPDATE system_settings SET value='FALSE' WHERE name='em_out';
-- EOC

-- Ensure DataBaseVersion is 99, to avoid X.1 Connector installation.
UPDATE system_settings SET value='99' WHERE name='DataBaseVersion' AND value<99;
-- EOC

-- Get rid of address_signature_subject_project
UPDATE system_settings SET value = '<D_BETREFF> (<PROJEKT>)'
WHERE 
name = 'signatur_subject' 
AND value = ''
AND (SELECT count(*) FROM (SELECT t2.name FROM system_settings AS t2 WHERE t2.name = 'BetreffMitProjekt'  AND t2.value = 'TRUE') AS t1)  = 1;
-- EOC

UPDATE system_settings SET value = 'FALSE' WHERE name = 'BetreffMitProjekt' OR name = 'BetreffMitProjektLS';
-- EOC

-- X3 Set project office_in_charge show
INSERT INTO settingssystem (`SettingType`, `SettingValue`) 
SELECT 'project_office_in_charge_show', IF( (SELECT count(*) FROM projekte WHERE Planer2 IS NOT NULL AND Planer2 > 0)>1, 'TRUE', 'FALSE') FROM DUAL
WHERE NOT EXISTS (SELECT * FROM settingssystem WHERE SETTINGTYPE='project_office_in_charge_show');
-- EOC

-- X3 Set project archive show
INSERT INTO settingssystem (`SettingType`, `SettingValue`) 
SELECT 'project_archive_show', IF( (SELECT count(*) FROM projektarchive)>=1, 'TRUE', 'FALSE') FROM DUAL
WHERE NOT EXISTS (SELECT * FROM settingssystem WHERE SETTINGTYPE='project_archive_show');
-- EOC

-- X3 Add country_code for default countries
UPDATE `countries` SET `country_code`='AT' WHERE `name`='Österreich' AND `country_code` IS NULL;
-- EOC
UPDATE `countries` SET `country_code`='DE' WHERE `name`='Deutschland' AND `country_code` IS NULL;
-- EOC
UPDATE `countries` SET `country_code`='CH' WHERE `name`='Schweiz' AND `country_code` IS NULL;
-- EOC

-- X3 Add currency_code for default currencies
UPDATE `currencies` SET `currency_code`='EUR' WHERE `name`='Euro' AND `currency_code` IS NULL;
-- EOC

-- Ensure fee_multipliers flags are set to ignore, when no name
UPDATE `fee_multipliers` 
SET is_standard=false, is_r2=false, is_r3=false, is_r4=false, is_work=false, is_ignore_mgmt=true
WHERE `name`='' AND purpose='';
-- EOC

-- USC X4 Security
-- From X4 we have security 38 R_CALCULATEACCORDINGEXPENDITURE separate
UPDATE staff SET security_38=CASE
    WHEN security_3 = 1 AND secd_3 > 30 THEN 2
    ELSE security_3
END WHERE security_38 IS NULL;
-- EOC

UPDATE user_settings 
SET `value` = 'opta.created_date' 
WHERE `name` = 'filterglobal_opentasks_order_by' AND `value` = "opta.creation_date";
-- EOC
-- USC Entferne alte Trigger.

-- --------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------

-- Drop Trigger for INSERT
DROP TRIGGER IF EXISTS add_adressen_to_search;
-- EOC

-- Drop Trigger for UPDATE
DROP TRIGGER IF EXISTS update_adressen_to_search;
-- EOC

-- Drop Trigger for DELETE
DROP TRIGGER IF EXISTS rem_adressen_to_search;
-- EOC

-- Drop Trigger for INSERT
DROP TRIGGER IF EXISTS add_projekte_to_search;
-- EOC

-- Drop Trigger for UPDATE
DROP TRIGGER IF EXISTS update_projekte_to_search;
-- EOC

-- Drop Trigger for DELETE
DROP TRIGGER IF EXISTS rem_projekte_to_search;
-- EOC

-- ---------------------------------------------------
-- TRIGGER FOR UPDATE
-- ---------------------------------------------------

-- Drop UPDATE inbox
DROP TRIGGER IF EXISTS update_crm_table_inbox;
-- EOC
			

-- Drop UPDATE outbox
DROP TRIGGER IF EXISTS update_crm_table_outbox;
-- EOC

-- Drop UPDATE addr_desc
DROP TRIGGER IF EXISTS update_crm_table_addr;
-- EOC
			
-- ---------------------------------------------------
-- TRIGGER FOR INSERET
-- ---------------------------------------------------

-- Drop INSERT INTO INBOX
DROP TRIGGER IF EXISTS insert_crm_table_inbox;
-- EOC

-- Drop INSERT INTO OUTBOX
DROP TRIGGER IF EXISTS insert_crm_table_outbox;
-- EOC

-- Drop INSERT into addr_desc
DROP TRIGGER IF EXISTS insert_crm_table_addr;
-- EOC
			
-- ---------------------------------------------------
-- TRIGGER FOR DELETE
-- ---------------------------------------------------

-- Drop DELETE FROM INBOX
DROP TRIGGER IF EXISTS delete_crm_table_inbox;
-- EOC

-- Drop DELETE FROM OUTBOX
DROP TRIGGER IF EXISTS delete_crm_table_outbox;
-- EOC

-- Drop DELETE FROM addr_desc
DROP TRIGGER IF EXISTS delete_crm_table_addr;
-- EOC

-- USC Alle Indizes fuer die Volltextsuche werden angelegt, falls aktiv.
CALL add_fulltext_indexes_if_active();
-- EOC



-- EOC
CALL add_addi_columns_once();
-- EOC

-- USC Zusatztabelle fuer Indizes wird geloescht, falls sie noch existiert.
DROP TABLE IF EXISTS cache_fulltext_addi;
-- EOC

-- We might keep that later on.-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- Functions to clean paths for SaaS v2 tenants
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- -------------------------------------  -- ------------------------------------- -- ------------------------------------- -- -------------------------------------
-- USC Spezielle Bereinigungsfunktionen
DROP PROCEDURE IF EXISTS list_migrate_saas_v2;
-- EOC

DELIMITER $$
CREATE PROCEDURE list_migrate_saas_v2()
BEGIN
    SELECT * FROM projects WHERE 
	(IFNULL(path_correspondence, '')<>'' AND path_correspondence NOT LIKE 'O365://%')
        OR 
        (IFNULL(path_inbox, '')<>'' AND path_inbox NOT LIKE 'O365://%')
        OR 
        (IFNULL(path_outbox, '')<>'' AND path_outbox NOT LIKE 'O365://%')
        OR 
        (IFNULL(path_drawings, '')<>'' AND path_drawings NOT LIKE 'O365://%')
        OR 
        (IFNULL(orig_translated_structure_tree_root_node, '')<>'' AND orig_translated_structure_tree_root_node NOT LIKE 'O365://%');
END $$
DELIMITER ;
-- EOC


DROP PROCEDURE IF EXISTS migrate_saas_v2;
-- EOC

DELIMITER $$
CREATE PROCEDURE migrate_saas_v2(
    IN domain VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
    IN old_datapath VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci,
    IN new_datapath VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
)
migrate_saas_v2:BEGIN
    DECLARE l_last_row_fetched INTEGER;
    DECLARE fieldname TEXT;
    DECLARE fieldlength INTEGER;
	DECLARE xdata CURSOR FOR SELECT * FROM tmp_addi_view;
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row_fetched=1;

    -- Keep old project paths
    CALL us_add_to_table2('projekte', 'SV_Pfad_presaas', 'VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `SV_Pfad`');
    CALL us_add_to_table2('projekte', 'path_correspondence_default_presaas', 'VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `path_correspondence_default`');
    CALL us_add_to_table2('projekte', 'EM_Pfad_presaas', 'VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `EM_Pfad`');
    CALL us_add_to_table2('projekte', 'path_inbox_default_presaas', 'VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `path_inbox_default`');
    CALL us_add_to_table2('projekte', 'EM_OUT_Pfad_presaas', 'VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `EM_OUT_Pfad`');
    CALL us_add_to_table2('projekte', 'path_outbox_default_presaas', 'VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `path_outbox_default`');
    CALL us_add_to_table2('projekte', 'Planpfad_presaas', 'VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `Planpfad`');
    CALL us_add_to_table2('projekte', 'path_drawings_default_presaas', 'VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `path_drawings_default`');
    CALL us_add_to_table2('projekte', 'orig_structure_tree_root_node_presaas', 'VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `orig_structure_tree_root_node`');
    CALL us_add_to_table2('projekte', 'orig_translated_structure_tree_root_node_presaas', 'VARCHAR(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `orig_translated_structure_tree_root_node`');
    CALL us_add_to_table2('projektangebot', 'Datei_presaas', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `Datei`');
    CALL us_add_to_table2('dokattachments', 'Att_Pfad_presaas', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `Att_Pfad`');
    CALL us_add_to_table2('drawings', 'cad_file_presaas', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `cad_file`');
    CALL us_add_to_table2('drawings', 'plot_file_presaas', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `plot_file`');
    CALL us_add_to_table2('poausattachments', 'PoAtt_Pfad_presaas', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `PoAtt_Pfad`');
    CALL us_add_to_table2('lut_adr_dateien', 'Datei_presaas', 'LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `Datei`');
    CALL us_add_to_table2('dateien', 'Pfad_presaas', 'VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `Pfad`');
    CALL us_add_to_table2('artikeltab', 'File_presaas', 'VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `File`');

    UPDATE projekte SET SV_Pfad_presaas=SV_Pfad WHERE SV_Pfad_presaas IS NULL;
    UPDATE projekte SET path_correspondence_default_presaas=path_correspondence_default WHERE path_correspondence_default_presaas IS NULL;
    UPDATE projekte SET EM_Pfad_presaas=EM_Pfad WHERE EM_Pfad_presaas IS NULL;
    UPDATE projekte SET path_inbox_default_presaas=path_inbox_default WHERE path_inbox_default_presaas IS NULL;
    UPDATE projekte SET EM_OUT_Pfad_presaas=EM_OUT_Pfad WHERE EM_OUT_Pfad_presaas IS NULL;
    UPDATE projekte SET path_outbox_default_presaas=path_outbox_default WHERE path_outbox_default_presaas IS NULL;
    UPDATE projekte SET Planpfad_presaas=Planpfad WHERE Planpfad_presaas IS NULL;
    UPDATE projekte SET path_drawings_default_presaas=path_drawings_default WHERE path_drawings_default_presaas IS NULL;
    UPDATE projekte SET orig_structure_tree_root_node_presaas=orig_structure_tree_root_node WHERE orig_structure_tree_root_node_presaas IS NULL;
    UPDATE projekte SET orig_translated_structure_tree_root_node_presaas=orig_translated_structure_tree_root_node WHERE orig_translated_structure_tree_root_node_presaas IS NULL;
    UPDATE projektangebot SET Datei_presaas=Datei WHERE Datei_presaas IS NULL;
    UPDATE dokattachments SET Att_Pfad_presaas=Att_Pfad WHERE Att_Pfad_presaas IS NULL;
    UPDATE drawings SET cad_file_presaas=cad_file WHERE cad_file_presaas IS NULL;
    UPDATE drawings SET plot_file_presaas=plot_file WHERE plot_file_presaas IS NULL;
    UPDATE poausattachments SET PoAtt_Pfad_presaas=PoAtt_Pfad WHERE PoAtt_Pfad_presaas IS NULL;
    UPDATE lut_adr_dateien SET Datei_presaas=Datei WHERE Datei_presaas IS NULL;
    UPDATE dateien SET Pfad_presaas=Pfad WHERE Pfad_presaas IS NULL;
    UPDATE artikeltab SET File_presaas=`File` WHERE File_presaas IS NULL;

    -- Delete all project paths which are not O365 paths
    UPDATE projects SET path_correspondence=NULL WHERE path_correspondence NOT LIKE 'O365://%';
    UPDATE projects SET path_correspondence_default=NULL WHERE path_correspondence_default NOT LIKE 'O365://%';
    UPDATE projects SET path_inbox=NULL WHERE path_inbox NOT LIKE 'O365://%';
    UPDATE projects SET path_inbox_default=NULL WHERE path_inbox_default NOT LIKE 'O365://%';
    UPDATE projects SET path_outbox=NULL WHERE path_outbox NOT LIKE 'O365://%';
    UPDATE projects SET path_outbox_default=NULL WHERE path_outbox_default NOT LIKE 'O365://%';
    UPDATE projects SET path_drawings=NULL WHERE path_drawings NOT LIKE 'O365://%';
    UPDATE projects SET path_drawings_default=NULL WHERE path_drawings_default NOT LIKE 'O365://%';
    UPDATE projects SET orig_structure_tree_root_node=NULL WHERE orig_structure_tree_root_node NOT LIKE 'O365://%';
    UPDATE projects SET orig_translated_structure_tree_root_node=NULL WHERE orig_translated_structure_tree_root_node NOT LIKE 'O365://%';

    -- Prepare paths
    -- Slashes only and end with slash
    SET old_datapath = REPLACE(old_datapath, '\\', '/');
    SET new_datapath = REPLACE(new_datapath, '\\', '/');
    SET old_datapath = concat(old_datapath, IF(RIGHT(old_datapath, 1) = '/', '', '/'));
    SET new_datapath = concat(new_datapath, IF(RIGHT(new_datapath, 1) = '/', '', '/'));

    -- Replace all addi paths from old (local) datapath to new (saas) datapath 
    -- Replace paths and remove non datapaths
    BEGIN 
        SET @addi_tables :='zusatz_adressen,zusatz_extkosten,zusatz_formular,zusatz_geextkosten,zusatz_gehonverw,zusatz_honverw,zusatz_personen,zusatz_planverz,zusatz_postaus,zusatz_postein,zusatz_projekt,zusatz_propers,zusatz_todo,zusatz_wasistwo,'; 
        WHILE (LOCATE(',', @addi_tables) > 0) DO
            SET @addi_table = SUBSTRING(@addi_tables,1, LOCATE(',',@addi_tables)-1); 
            SET @addi_tables = SUBSTRING(@addi_tables, LOCATE(',',@addi_tables) + 1); 
            IF @addi_table = 'zusatz_geextkosten' THEN
                SET @addi_table_def = 'zusatz_extkosten_def';
            ELSEIF @addi_table = 'zusatz_gehonverw' THEN
                SET @addi_table_def = 'zusatz_honverw_def';
            ELSE
                SET @addi_table_def = CONCAT(@addi_table, '_def');
            END IF;

            SET @s = concat('CREATE OR REPLACE VIEW tmp_addi_view as SELECT `FeldName` as fieldname, `Laenge` AS fieldlength FROM ',@addi_table_def,' WHERE Typ=4 OR (Typ=1 AND subtype=4)');
            PREPARE stm FROM @s;
            EXECUTE stm;
            DEALLOCATE PREPARE stm;
            SET l_last_row_fetched=0;
            OPEN xdata;
            cursor_loop: LOOP -- -------------------------------------
                FETCH xdata INTO fieldname, fieldlength;
                IF l_last_row_fetched=1 THEN
                    LEAVE cursor_loop;
                END IF;
                IF fieldname IS NOT NULL THEN
                -- We have a path field
                    -- Update all backslashes to slashes
                    SET @s = CONCAT('UPDATE ', @addi_table, ' SET `', fieldname, '`= us_replace(',fieldname,',\'\\\\\',\'/\',TRUE) WHERE `', fieldname, '` IS NOT NULL');
                    PREPARE stm FROM @s;
                    EXECUTE stm;
                    DEALLOCATE PREPARE stm;

                    -- Update old datapaths
                    SET @s = CONCAT('UPDATE ', @addi_table, ' SET `', fieldname, '`= us_replace_if_max_length(',fieldname,',"',old_datapath,'","',new_datapath,'",TRUE,',fieldlength,') WHERE `', fieldname, '` IS NOT NULL AND `', fieldname, '` NOT LIKE "O365://%"');
                    PREPARE stm FROM @s;
                    EXECUTE stm;
                    DEALLOCATE PREPARE stm;

                    -- Remove all not new datapath and not O365      
                    SET @s = CONCAT('UPDATE ', @addi_table, ' SET `', fieldname, '`= NULL WHERE `', fieldname, '` IS NOT NULL AND `', fieldname, '` NOT LIKE "O365://%" AND `', fieldname, '` NOT LIKE "',new_datapath,'%"');
                    PREPARE stm FROM @s;
                    EXECUTE stm;
                    DEALLOCATE PREPARE stm;                           
                END IF;

            END LOOP cursor_loop; -- -------------------------------------
            CLOSE  xdata;
            DROP VIEW IF EXISTS `tmp_addi_view`;
        END WHILE;
    END;  

    -- Delete all paths which are not in datapath or O365
    --  -- Offers
    --  --  -- Update all backslashes to slashes
            UPDATE project_offers SET `file`= us_replace(`file`,'\\','/',TRUE) WHERE `file` IS NOT NULL;
    --  --  -- Update old datapaths
            SET @s = CONCAT('UPDATE project_offers SET `file`= us_replace(file,"',old_datapath,'","',new_datapath,'",TRUE) WHERE `file` IS NOT NULL AND `file` NOT LIKE "O365://%"');
            PREPARE stm FROM @s;
            EXECUTE stm;
            DEALLOCATE PREPARE stm;
    --  --  -- Remove all not new datapath and not O365      
            SET @s = CONCAT('UPDATE project_offers SET `file`= NULL WHERE `file` IS NOT NULL AND `file` NOT LIKE "O365://%" AND `file` NOT LIKE "',new_datapath,'%"');
            PREPARE stm FROM @s;
            EXECUTE stm;
            DEALLOCATE PREPARE stm;
    --  -- Correspondence attachments
    --  --  -- Update all backslashes to slashes
            UPDATE correspondence_attachments SET `path`= us_replace(`path`,'\\','/',TRUE) WHERE `path` IS NOT NULL;
    --  --  -- Update empty all not O365 paths
            UPDATE correspondence_attachments SET `path`= NULL WHERE `path` NOT LIKE 'O365://%';
    --  -- Drawings CAD and PLOT files
    --  --  -- Update all backslashes to slashes
            UPDATE drawings SET `cad_file`= us_replace(`cad_file`,'\\','/',TRUE) WHERE `cad_file` IS NOT NULL;
            UPDATE drawings SET `plot_file`= us_replace(`plot_file`,'\\','/',TRUE) WHERE `plot_file` IS NOT NULL;
    --  --  -- Update empty all not O365 paths  
            UPDATE drawings SET `cad_file`= NULL WHERE `cad_file` NOT LIKE 'O365://%';
            UPDATE drawings SET `plot_file`= NULL WHERE `plot_file` NOT LIKE 'O365://%';
    --  -- Mail attachments
    --  --  -- Update all backslashes to slashes
            UPDATE lut_outbox_attachments SET `path`= us_replace(`path`,'\\','/',TRUE) WHERE `path` IS NOT NULL;    
    --  --  -- Update empty all not O365 paths
            UPDATE lut_outbox_attachments SET `path`= NULL WHERE `path` NOT LIKE 'O365://%'; 
    --  -- Addresses files
    --  --  -- Update all backslashes to slashes
            UPDATE address_files SET `file`= us_replace(`file`,'\\','/',TRUE) WHERE `file` IS NOT NULL;   
    --  --  -- Update old datapaths
            SET @s = CONCAT('UPDATE address_files SET `file`= us_replace(file,"',old_datapath,'","',new_datapath,'",TRUE) WHERE `file` IS NOT NULL AND `file` NOT LIKE "O365://%"');
            PREPARE stm FROM @s;
            EXECUTE stm;
            DEALLOCATE PREPARE stm;
    --  --  -- Remove all not new datapath and not O365      
            SET @s = CONCAT('UPDATE address_files SET `file`= NULL WHERE `file` IS NOT NULL AND `file` NOT LIKE "O365://%" AND `file` NOT LIKE "',new_datapath,'%"');
            PREPARE stm FROM @s;
            EXECUTE stm;
            DEALLOCATE PREPARE stm;             
    --  -- Data files 
    --  --  -- Update all backslashes to slashes
            UPDATE files SET `path`= us_replace(`path`,'\\','/',TRUE) WHERE `path` IS NOT NULL;   
    --  --  -- Update old datapaths
            SET @s = CONCAT('UPDATE files SET `path`= us_replace_if_max_length(path,"',old_datapath,'","',new_datapath,'",TRUE,255) WHERE `path` IS NOT NULL AND `path` NOT LIKE "O365://%"');
            PREPARE stm FROM @s;
            EXECUTE stm;
            DEALLOCATE PREPARE stm;
    --  --  -- Remove all not new datapath and not O365      
            SET @s = CONCAT('UPDATE files SET `path`= NULL WHERE `path` IS NOT NULL AND `path` NOT LIKE "O365://%" AND `path` NOT LIKE "',new_datapath,'%"');
            PREPARE stm FROM @s;
            EXECUTE stm;
            DEALLOCATE PREPARE stm;               
    --  -- WIW files
    --  --  -- Update all backslashes to slashes
            UPDATE wiw_items SET `file`= us_replace(`file`,'\\','/',TRUE) WHERE `file` IS NOT NULL;   
    --  --  -- Update old datapaths
            SET @s = CONCAT('UPDATE wiw_items SET `file`= us_replace_if_max_length(file,"',old_datapath,'","',new_datapath,'",TRUE,255) WHERE `file` IS NOT NULL AND `file` NOT LIKE "O365://%"');
            PREPARE stm FROM @s;
            EXECUTE stm;
            DEALLOCATE PREPARE stm;
    --  --  -- Remove all not new datapath and not O365      
            SET @s = CONCAT('UPDATE wiw_items SET `file`= NULL WHERE `file` IS NOT NULL AND `file` NOT LIKE "O365://%" AND `file` NOT LIKE "',new_datapath,'%"');
            PREPARE stm FROM @s;
            EXECUTE stm;
            DEALLOCATE PREPARE stm;   

    -- Remove settings, not possible for SaaS
    DELETE FROM u10_ci_config WHERE name='us_java_path';
    DELETE FROM u10_ci_config WHERE name='us_xsltproc_filesize';
    DELETE FROM u10_ci_config WHERE name='us_libreoffice_set_temp';
    DELETE FROM u10_ci_config WHERE name='us_use_session_logging';
    DELETE FROM u10_ci_config WHERE name='custom_config';
    DELETE FROM u10_ci_config WHERE name='us_logoffall_active_only';
    DELETE FROM u10_ci_config WHERE name='kerberos_ntlm_domain_after';
    DELETE FROM u10_ci_config WHERE name='kerberos_ntlm_domain';
    DELETE FROM u10_ci_config WHERE name='us_libreoffice_path';

    DELETE FROM system_settings WHERE name LIKE 'u10_check_%';
    DELETE FROM system_settings WHERE name LIKE 'userpasswordencrypted';
    INSERT INTO system_settings SET name='userpasswordencrypted', value='TRUE';

    -- Do basic settings
    CALL us_init_saas_v2(TRUE, domain, NULL);
 
END $$
DELIMITER ;
-- EOC




-- Calls:
--
-- CALL list_migrate_saas_v2();
-- CALL migrate_saas_v2('https://tenent.ustrich-server.example', '\\\\server\\usdata\\', '/the/new/datapath/' );-- USC Abschluss.

-- --------------------------------------------------------------------------------------------------
DELETE FROM system_settings WHERE name='u10_last_update';
-- EOC

INSERT INTO system_settings(`name`, `value`) VALUES ('u10_last_update', '2022-11-18');
-- EOC






