-- Default application settings
INSERT INTO settings (
    name, value, category, tenant_id, branch_id
) VALUES
    ('default_currency', 'FJD', 'finance', NULL, NULL),
    ('timezone', 'Pacific/Fiji', 'system', 1, 1),
    ('policy_publish_webhook', '', 'system', NULL, NULL),
    ('policy_update_webhook', '', 'system', NULL, NULL);

-- Ensure the sequence for settings continues from the inserted values
SELECT setval('settings_id_seq', (SELECT MAX(id) FROM settings));

-- Default hazard types
INSERT INTO ohs_hazard_types (name, tenant_id, branch_id) VALUES
    ('Physical', NULL, NULL),
    ('Chemical', NULL, NULL),
    ('Biological', NULL, NULL),
    ('Psychosocial', NULL, NULL),
    ('Ergonomic', NULL, NULL);

-- Ensure the sequence for ohs_hazard_types continues from the inserted values
SELECT setval('ohs_hazard_types_id_seq', (SELECT MAX(id) FROM ohs_hazard_types));

-- Default incident types
INSERT INTO ohs_incident_types (name, form_id, tenant_id, branch_id) VALUES
    ('Injury', 20, NULL, NULL),
    ('Property Damage', 13, NULL, NULL),
    ('Environmental', 14, NULL, NULL),
    ('Near Miss', 15, NULL, NULL),
    ('First Aid', 16, NULL, NULL),
    ('Medical Treatment', 17, NULL, NULL),
    ('LTI', 18, NULL, NULL),
    ('Fatality', 19, NULL, NULL),
    ('Field Incident', 105, NULL, NULL);

    --Ensures General tables
    INSERT INTO form_wizard_lookup (name, form_id, categories, tenant_id, branch_id) VALUES
    ('Individual', 201, NULL, NULL, NULL),
    ('Corporate', 200, NULL, NULL, NULL),
    ('Government', 202, NULL, NULL, NULL)
    ON CONFLICT DO NOTHING;

-- Ensure the sequence for ohs_incident_types continues from the inserted values
SELECT setval('ohs_incident_types_id_seq', (SELECT MAX(id) FROM ohs_incident_types));

-- Default safety incident types
INSERT INTO safety_incident_types (name, form_id, tenant_id, branch_id) VALUES
    ('Minor Injury', 20, NULL, NULL),
    ('Near Miss', 15, NULL, NULL),
    ('Property Damage', 13, NULL, NULL),
    ('Environmental', 14, NULL, NULL),
    ('Other', 97, NULL, NULL),
    ('Field Incident', 108, NULL, NULL);

-- Ensure the sequence for safety_incident_types continues from the inserted values
SELECT setval('safety_incident_types_id_seq', (SELECT MAX(id) FROM safety_incident_types));

-- Default incident statuses
INSERT INTO ohs_incident_statuses (name, purpose, tenant_id, branch_id) VALUES
    ('Reported / Logged', 'Capture the initial incident details', NULL, NULL),
    ('Under Review / Triage', 'Assess seriousness and need for investigation', NULL, NULL),
    ('Investigation in Progress', 'Conduct full investigation and identify root causes', NULL, NULL),
    ('Action Required', 'Implement corrective and preventive measures', NULL, NULL),
    ('Awaiting Review', 'Final review before closure', NULL, NULL),
    ('Closed / Resolved', 'All actions complete, incident formally closed', NULL, NULL),
    ('Reopened', 'Reevaluate due to new info or recurrence', NULL, NULL),
    ('Deferred / On Hold', 'Temporarily paused due to dependencies', NULL, NULL);

-- Ensure the sequence for ohs_incident_statuses continues from the inserted values
SELECT setval('ohs_incident_statuses_id_seq', (SELECT MAX(id) FROM ohs_incident_statuses));

-- Default severity levels
INSERT INTO ohs_severities (name, tenant_id, branch_id) VALUES
    ('Minor', NULL, NULL),
    ('Moderate', NULL, NULL),
    ('Major', NULL, NULL),
    ('Severe', NULL, NULL),
    ('Critical', NULL, NULL);

-- Ensure the sequence for ohs_severities continues from the inserted values
SELECT setval('ohs_severities_id_seq', (SELECT MAX(id) FROM ohs_severities));

-- Default district levels
INSERT INTO districts (name, tenant_id, branch_id) VALUES
    ('Central', NULL, NULL),
    ('Eastern', NULL, NULL),
    ('Northern', NULL, NULL),
    ('Western', NULL, NULL);

-- Ensure the sequence for districts continues from the inserted values
SELECT setval('districts_id_seq', (SELECT MAX(id) FROM districts));

-- Default inspection types
INSERT INTO ohs_inspection_types (name, form_id, tenant_id, branch_id) VALUES
    ('General Site', 91, NULL, NULL),
    ('Plant & Equipment', 92, NULL, NULL),
    ('Confined Space Entry', 93, NULL, NULL),
    ('Field Work', 94, NULL, NULL),
    ('Vehicle', 95, NULL, NULL);

-- Ensure the sequence for ohs_inspection_types continues from the inserted values
SELECT setval('ohs_inspection_types_id_seq', (SELECT MAX(id) FROM ohs_inspection_types));

-- Default work types for time entries
INSERT INTO work_types (name) VALUES
    ('Research'),
    ('Drafting'),
    ('Review'),
    ('Client Meeting'),
    ('Court Preparation'),
    ('Court Appearance'),
    ('Document Preparation'),
    ('Administrative');


-- Default calendar categories for kanban boards
INSERT INTO calendar_categories (name, tenant_id, branch_id)
VALUES
  ('WorkCOM Inspections', NULL, NULL),
  ('OHS Inspections', NULL, NULL),
  ('OHS Incidents', NULL, NULL),
  ('Safety Incidents', NULL, NULL);

-- Ensure the sequence for calendar_categories continues from the inserted values
SELECT setval('calendar_categories_id_seq', (SELECT MAX(id) FROM calendar_categories));

-- Default kanban board for WorkCOM inspections
INSERT INTO kanban_boards (project_id, name, calendar_category_id)
VALUES
  (1, 'WorkCOM Inspections', (SELECT id FROM calendar_categories WHERE name='WorkCOM Inspections' LIMIT 1)),
  (1, 'OHS Inspections', (SELECT id FROM calendar_categories WHERE name='OHS Inspections' LIMIT 1)),
  (1, 'OHS Incidents', (SELECT id FROM calendar_categories WHERE name='OHS Incidents' LIMIT 1)),
  (1, 'Safety Incidents', (SELECT id FROM calendar_categories WHERE name='Safety Incidents' LIMIT 1));

-- Ensure the sequence for kanban_boards continues from the inserted values
SELECT setval('kanban_boards_id_seq', (SELECT MAX(id) FROM kanban_boards));


INSERT INTO kanban_columns (board_id, title, position)
VALUES
  ((SELECT id FROM kanban_boards WHERE name='WorkCOM Inspections' LIMIT 1), 'Pending', 1),
  ((SELECT id FROM kanban_boards WHERE name='WorkCOM Inspections' LIMIT 1), 'In Progress', 2),
  ((SELECT id FROM kanban_boards WHERE name='WorkCOM Inspections' LIMIT 1), 'Completed', 3),
  ((SELECT id FROM kanban_boards WHERE name='OHS Inspections' LIMIT 1), 'Pending', 1),
  ((SELECT id FROM kanban_boards WHERE name='OHS Inspections' LIMIT 1), 'In Progress', 2),
  ((SELECT id FROM kanban_boards WHERE name='OHS Inspections' LIMIT 1), 'Completed', 3),
  ((SELECT id FROM kanban_boards WHERE name='OHS Incidents' LIMIT 1), 'Pending', 1),
  ((SELECT id FROM kanban_boards WHERE name='OHS Incidents' LIMIT 1), 'In Progress', 2),
  ((SELECT id FROM kanban_boards WHERE name='OHS Incidents' LIMIT 1), 'Completed', 3),
  ((SELECT id FROM kanban_boards WHERE name='Safety Incidents' LIMIT 1), 'Pending', 1),
  ((SELECT id FROM kanban_boards WHERE name='Safety Incidents' LIMIT 1), 'In Progress', 2),
  ((SELECT id FROM kanban_boards WHERE name='Safety Incidents' LIMIT 1), 'Completed', 3);


-- Ensure the sequence for kanban_columns continues from the inserted values
SELECT setval('kanban_columns_id_seq', (SELECT MAX(id) FROM kanban_columns));

-- Seed tasks for the default WorkCOM kanban board
INSERT INTO kanban_tasks (column_id, title, description, assignee_id, due_date, status)
VALUES
  ((SELECT id FROM kanban_columns WHERE title='Pending' AND board_id=(SELECT id FROM kanban_boards WHERE name='WorkCOM Inspections' LIMIT 1) LIMIT 1),
   'Schedule initial inspection', 'Arrange inspection date with site manager', 1, '2025-07-01', 'pending'),
  ((SELECT id FROM kanban_columns WHERE title='In Progress' AND board_id=(SELECT id FROM kanban_boards WHERE name='WorkCOM Inspections' LIMIT 1) LIMIT 1),
   'Conduct site inspection', 'Review compliance checklist on-site', 1, '2025-07-10', 'in_progress'),
  ((SELECT id FROM kanban_columns WHERE title='Completed' AND board_id=(SELECT id FROM kanban_boards WHERE name='WorkCOM Inspections' LIMIT 1) LIMIT 1),
   'Submit inspection report', 'Compile results and upload to system', 1, '2025-07-15', 'pending');

-- Ensure the sequence for kanban_tasks continues from the inserted values
SELECT setval('kanban_tasks_id_seq', (SELECT MAX(id) FROM kanban_tasks));

INSERT INTO user_board_settings (user_id, board_id, column_order, hidden_columns)
VALUES (
    1,
    (SELECT id FROM kanban_boards WHERE name='WorkCOM Inspections' LIMIT 1),
    '[1,2,3]',
    '[]'
  ),
  (
    1,
    (SELECT id FROM kanban_boards WHERE name='OHS Inspections' LIMIT 1),
    '[1,2,3]',
    '[]'
  ),
  (
    1,
    (SELECT id FROM kanban_boards WHERE name='OHS Incidents' LIMIT 1),
    '[1,2,3]',
    '[]'
  ),
  (
    1,
    (SELECT id FROM kanban_boards WHERE name='Safety Incidents' LIMIT 1),
    '[1,2,3]',
    '[]'
  );

-- Ensure the sequence for user_board_settings continues from the inserted values
SELECT setval('user_board_settings_id_seq', (SELECT MAX(id) FROM user_board_settings));

-- Calendar events for seeded kanban tasks
INSERT INTO calendar_events (title, start_time, kanban_task_id, category_id, tenant_id, branch_id)
SELECT t.title, t.due_date, t.id, b.calendar_category_id, NULL, NULL
FROM kanban_tasks t
JOIN kanban_columns c ON t.column_id = c.id
JOIN kanban_boards  b ON c.board_id = b.id;

-- Ensure the sequence for calendar_events continues from the inserted values
SELECT setval('calendar_events_id_seq', (SELECT MAX(id) FROM calendar_events));

-- Default form element types
INSERT INTO element_types (name, html_type, sql_type)
VALUES
  ('text', 'text', 'VARCHAR(255)'),
  ('number', 'number', 'INT'),
  ('date', 'date', 'DATE'),
  ('dropdown', 'select', 'VARCHAR(255)'),
  ('checkbox', 'checkbox', 'BOOLEAN'),
  ('checkbox-table', 'checkbox-table', NULL),
  ('input-table', 'input-table', NULL),
  ('textarea', 'textarea', 'TEXT'),
  ('file', 'file', 'VARCHAR(255)'),
  ('datetime', 'datetime-local', 'TIMESTAMP'),
  ('group', 'group', NULL),
  ('section', 'section', NULL),
  ('select-addable', 'select', 'VARCHAR(255)'),
  ('multiselect-search', 'multiselect', 'VARCHAR(255)'),
  ('email', 'email', 'VARCHAR(255)'),
  ('text-multiple', 'text-multiple', 'VARCHAR(255)'),
  ('hidden', 'hidden', 'INT'),
  ('rating', 'rating', 'INT'),
  ('button', 'button', NULL),
  ('gps', 'gps', 'VARCHAR(255)'),
  ('camera', 'camera', 'VARCHAR(255)'),
  ('dynamic-table', 'dynamic-table', 'JSONB'),
  ('select-search', 'select-search', 'VARCHAR(255)'),
  ('shopping-cart', 'shopping-cart', 'JSONB');

-- Ensure the sequence for element_types continues from the inserted values
SELECT setval('element_types_id_seq', (SELECT MAX(id) FROM element_types));

-- Leave Application Form
INSERT INTO forms (id, name, description, mapped_table, elements) VALUES (
  1,
  'Leave Application',
  'Form to apply for leave',
  'leave_requests',
  '[{"type_id": 4, 
      "label": "Leave Type", 
      "field_name": "leavetype", 
      "required": true, 
      "default_value": "Annual", 
        "options": [
          {"value": "Annual", "label": "Annual Leave"},
          {"value": "Sick", "label": "Sick Leave"},
          {"value": "Bereavement", "label": "Bereavement Leave"},
          {"value": "FamilyCare", "label": "Family Care Leave"},
          {"value": "Maternity", "label": "Maternity Leave"},
          {"value": "Paternity", "label": "Paternity Leave"}
        ]
    }, 
      
      {"type_id": 3, 
        "label": "Start Date", 
        "field_name": "startdate", 
        "required": true
      }, 
        
      {"type_id": 3, 
        "label": "End Date", 
        "field_name": "enddate", 
        "required": true
      }, 

      {"type_id": 8, 
        "label": "Reason", 
        "field_name": "reason", 
        "required": true
      }, 
      
      {"type_id": 9, 
        "label": "Medical Certificate", 
        "field_name": "medical_certificate", 
        "required": false, 
        "condition_field": "leavetype", 
        "condition_value": "Sick"
      },
      
      {"type_id": 1, 
        "label": "Relationship to Deceased", 
        "field_name": "bereavement_relationship", 
        "required": true, 
        "condition_field": "leavetype", 
        "condition_value": "Bereavement",
        "placeholder": "e.g., Parent, Sibling, Spouse, etc."
      },
      
      {"type_id": 1, 
        "label": "Name of the Deceased", 
        "field_name": "deceased_name", 
        "required": true, 
        "condition_field": "leavetype", 
        "condition_value": "Bereavement",
        "placeholder": "Enter the name of the deceased"
      },
      
      {"type_id": 1, 
        "label": "Relationship for Person Needing The Care", 
        "field_name": "familycare_relationship", 
        "required": true, 
        "condition_field": "leavetype", 
        "condition_value": "FamilyCare",
        "placeholder": "e.g., Parent, Child, Spouse, etc."
      },
      
      {"type_id": 1, 
        "label": "Name of the Person Who Needs Care", 
        "field_name": "care_recipient_name", 
        "required": true, 
        "condition_field": "leavetype", 
        "condition_value": "FamilyCare",
        "placeholder": "Enter the name of the person needing care"
      },
      
      {"type_id": 9, 
        "label": "Medical Certificate", 
        "field_name": "maternity_medical_certificate", 
        "required": true, 
        "condition_field": "leavetype", 
        "condition_value": "Maternity"
      },
      
      {"type_id": 3, 
        "label": "Expected Due Date", 
        "field_name": "expected_due_date", 
        "required": true, 
        "condition_field": "leavetype", 
        "condition_value": "Maternity"
      },
      
      {"type_id": 4, 
        "label": "Number of Previous Births", 
        "field_name": "number_of_births", 
        "required": true, 
        "condition_field": "leavetype", 
        "condition_value": "Maternity",
        "options": [
          {"value": "0", "label": "1st Birth"},
          {"value": "1", "label": "2nd Birth"},
          {"value": "2", "label": "3rd Birth"},
          {"value": "3", "label": "4th Birth or More"}
        ]
      },
      
      {"type_id": 9, 
        "label": "Medical Certificate (stating expected birth date)", 
        "field_name": "paternity_medical_certificate", 
        "required": true, 
        "condition_field": "leavetype", 
        "condition_value": "Paternity"
      },
      
      {"type_id": 3, 
        "label": "Expected Birth Date", 
        "field_name": "paternity_expected_birth_date", 
        "required": true, 
        "condition_field": "leavetype", 
        "condition_value": "Paternity"
      },
      
      {"type_id": 4, 
        "label": "Number of Previous Births", 
        "field_name": "paternity_number_of_births", 
        "required": true, 
        "condition_field": "leavetype", 
        "condition_value": "Paternity",
        "options": [
          {"value": "0", "label": "1st Birth"},
          {"value": "1", "label": "2nd Birth"},
          {"value": "2", "label": "3rd Birth"},
          {"value": "3", "label": "4th Birth or More"}
        ]
      },
      
      {"type_id": 5, 
        "label": "I confirm I am/will be the primary caregiver", 
        "field_name": "primary_caregiver_confirmation", 
        "required": true, 
        "condition_field": "leavetype", 
        "condition_value": "Paternity"
      }]'::jsonb
);



-- Default workflow to launch the Dashboard Card Permissions modal
INSERT INTO workflows (name, trigger_event, definition, is_active)
VALUES (
  'Dashboard Card Permissions',
  'dashboard.card.permissions',
  '{"conditions":[]}',
  TRUE
);


INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
VALUES (
  (SELECT id FROM workflows WHERE name='Dashboard Card Permissions' LIMIT 1),
  1,
  'open_modal',
  '{"modal":"dashboard_card_permissions"}'
);


-- Default vehicle makes and models
INSERT INTO vehicle_makes (name, tenant_id, branch_id)
VALUES ('Toyota', NULL, NULL);


INSERT INTO vehicle_models (make_id, name, tenant_id, branch_id)
VALUES ((SELECT id FROM vehicle_makes WHERE name='Toyota' LIMIT 1), 'Corolla',NULL, NULL);


-- Default vehicle service workflow to schedule maintenance after registration
INSERT INTO workflows (name, trigger_event, definition, is_active)
VALUES ('Vehicle Service Setup', 'vehicle.registered', '{"conditions": []}', TRUE);


INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
VALUES (
  (SELECT id FROM workflows WHERE name='Vehicle Service Setup' LIMIT 1),
  1,
  'schedule_services',
  '{}'
);

-- Hours Aggregation Workflow
INSERT INTO workflows (name, trigger_event, definition, is_active)
VALUES (
  'Hours Aggregation',
  'hours.aggregate',
  '{"description":"Aggregates work hours from time_clocks based on user IDs and date ranges","version":"1.0.0"}',
  TRUE
);

-- Hours Aggregation Workflow Steps
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
VALUES
  (
    (SELECT id FROM workflows WHERE name='Hours Aggregation' LIMIT 1),
    1,
    'query_records',
    '{"table":"time_clocks","where":{"user_id":"{user_ids}","clocked_at":{"clause":"clocked_at >= ? AND clocked_at <= ?","params":["{start_date}","{end_date}"]},"is_deleted":false},"order_by":"user_id, clocked_at","context_key":"raw_time_clocks"}'
  ),
  (
    (SELECT id FROM workflows WHERE name='Hours Aggregation' LIMIT 1),
    2,
    'validate_data',
    '{"source":"raw_time_clocks","validation_rules":[{"field":"user_id","type":"uuid","required":true},{"field":"clocked_at","type":"timestamp","required":true},{"field":"clock_type","type":"string","required":true}],"context_key":"validated_time_clocks","error_key":"validation_errors"}'
  ),
  (
    (SELECT id FROM workflows WHERE name='Hours Aggregation' LIMIT 1),
    3,
    'group_records',
    '{"source":"validated_time_clocks","group_fields":["user_id","work_date"],"date_function":"DATE(clocked_at)","context_key":"grouped_by_user_date"}'
  ),
  (
    (SELECT id FROM workflows WHERE name='Hours Aggregation' LIMIT 1),
    4,
    'calculate_time_difference',
    '{"source":"grouped_by_user_date","start_field":"clock_in_time","end_field":"clock_out_time","result_field":"duration_minutes","unit":"minutes","context_key":"records_with_duration"}'
  ),
  (
    (SELECT id FROM workflows WHERE name='Hours Aggregation' LIMIT 1),
    5,
    'apply_break_rules',
    '{"source":"records_with_duration","duration_field":"duration_minutes","result_field":"net_duration_minutes","break_rules":[{"threshold_minutes":480,"break_minutes":60},{"threshold_minutes":300,"break_minutes":30}],"context_key":"records_with_breaks_applied"}'
  ),
  (
    (SELECT id FROM workflows WHERE name='Hours Aggregation' LIMIT 1),
    6,
    'calculate_overtime',
    '{"source":"records_with_breaks_applied","duration_field":"net_duration_minutes","result_field":"overtime_minutes","overtime_rules":[{"threshold_minutes":480,"rate":1.5}],"context_key":"records_with_overtime"}'
  ),
  (
    (SELECT id FROM workflows WHERE name='Hours Aggregation' LIMIT 1),
    7,
    'aggregate_by_user',
    '{"source":"records_with_overtime","user_field":"user_id","aggregate_fields":[{"field":"duration_minutes","operation":"sum","result_field":"total_duration_minutes"},{"field":"net_duration_minutes","operation":"sum","result_field":"total_net_minutes"},{"field":"overtime_minutes","operation":"sum","result_field":"total_overtime_minutes"},{"field":"regular_time_minutes","operation":"sum","result_field":"total_regular_minutes"},{"field":"total_payable_minutes","operation":"sum","result_field":"total_payable_minutes"},{"field":"record_count","operation":"sum","result_field":"total_days_worked"}],"context_key":"user_aggregates"}'
  ),
  (
    (SELECT id FROM workflows WHERE name='Hours Aggregation' LIMIT 1),
    8,
    'generate_report',
    '{"source":"user_aggregates","report_type":"hours_aggregation","include_fields":["user_id","user_name","department","org_id","total_duration_minutes","total_net_minutes","total_overtime_minutes","total_regular_minutes","total_payable_minutes","total_days_worked","date_range"],"sort_by":{"field":"total_payable_minutes","direction":"desc"},"context_key":"final_report"}'
  ),
  (
    (SELECT id FROM workflows WHERE name='Hours Aggregation' LIMIT 1),
    9,
    'export_data',
    '{"source":"final_report.data","format":"{export_format}","filename":"hours_aggregation_report_{start_date}_to_{end_date}","include_fields":["user_id","user_name","department","total_duration_minutes","total_net_minutes","total_overtime_minutes","total_regular_minutes","total_payable_minutes","total_days_worked"],"context_key":"export_result"}'
  ),
  (
    (SELECT id FROM workflows WHERE name='Hours Aggregation' LIMIT 1),
    10,
    'save_record',
    '{"table":"time_clock_aggregates","data":{"org_id":"{org_id}","user_id":"user_id","start_date":"{start_date}","end_date":"{end_date}","total_duration_minutes":"total_duration_minutes","total_net_minutes":"total_net_minutes","total_overtime_minutes":"total_overtime_minutes","total_regular_minutes":"total_regular_minutes","total_payable_minutes":"total_payable_minutes","total_days_worked":"total_days_worked"},"match":{"org_id":"{org_id}","user_id":"user_id","start_date":"{start_date}","end_date":"{end_date}"},"context_key":"saved_aggregates"}'
  );




-- Workflow step type definitions
INSERT INTO workflow_step_types (type, description, metadata) VALUES
  ('start', 'Workflow entry point', '{"trigger":""}'),
  ('save_record', 'Insert or update a record', '{"table":"","data":{},"match":{}}'),
  ('sms', 'Send an SMS notification', '{"to":"","message":""}'),
  ('http_request', 'HTTP request to external API', '{"url":"","method":"GET"}'),
  ('alert', 'Send a push notification', '{"title":"","body":""}'),
  ('create_task', 'Add a kanban board task', '{"column_id":0,"title":""}'),
  ('add_calendar_event', 'Create a calendar event', '{"title":"","start_time":"","end_time":""}'),
  ('open_form', 'Open a form for the user', '{"form_id":0}'),
  ('condition', 'Evaluate workflow conditions', '{"conditions":[]}'),
  ('query_budget', 'Load remaining budget for a category', '{"category":"","context_key":"budget_amount"}'),
  ('map_fields', 'Copy values between context fields', '{"map":{}}'),
  ('load_record', 'Load a record into context', '{"table":"","id_key":"id","context_key":"record"}'),
  ('query_records', 'Query records from a table', '{"table":"","where":{},"context_key":"records"}'),
  ('for_each_record', 'Execute steps for each record', '{"list_key":"records","steps":[]}'),
  ('queue_notification', 'Queue a notification payload', '{"entity":"","record_id":"","event_type":"insert","payload":null}');


-- Default document folders
INSERT INTO document_folders (id, name, tenant_id, branch_id)
VALUES
  (1, 'Training', NULL, NULL),
  (2, 'Compliance', NULL, NULL)
ON CONFLICT (id) DO NOTHING;

-- OHS inspection forms
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  91,
  'General OHS Site Inspection',
  'Routine safety inspection of work areas, signage, and emergency readiness',
  'ohs_inspections',
  '[{"field_name":"inspection_type_id","data_column":"inspection_type_id","type_id":1,"order_index":0},{"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
    {"label":"Inspection Date","field_name":"inspection_date","data_column":"date","type_id":3,"order_index":1},
    {"label":"Site Name","field_name":"site_name","data_column":"location","type_id":1,"order_index":2},
    {"label":"Inspector Comments","field_name":"comments","json_column":"form_data","type_id":7,"order_index":3},
    {"label":"Emergency Exits Clear","field_name":"emergency_exits","json_column":"form_data","type_id":5,"order_index":4},
    {"label":"Safety Signage Present","field_name":"signage","json_column":"form_data","type_id":5,"order_index":5},
    {"label":"General Comments","field_name":"general_comments","json_column":"form_data","type_id":7,"order_index":6}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  92,
  'Plant & Equipment OHS Inspection',
  'Inspection of machinery, maintenance records, guards, and operating safety',
  'ohs_inspections',
  '[{"field_name":"inspection_type_id","data_column":"inspection_type_id","type_id":1,"order_index":0},{"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":1},{"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
    {"label":"Equipment Name","field_name":"equipment","json_column":"form_data","type_id":1,"order_index":1},
    {"label":"Inspection Date","field_name":"inspection_date","data_column":"date","type_id":3,"order_index":2},
    {"label":"Last Maintenance Date","field_name":"maintenance_date","data_column":"date","type_id":3,"order_index":3},
    {"label":"Guards in Place","field_name":"guards","json_column":"form_data","type_id":5,"order_index":4},
    {"label":"Emergency Stop Working","field_name":"emergency_stop","json_column":"form_data","type_id":5,"order_index":5},
    {"label":"Operator Safety Training Verified","field_name":"training","json_column":"form_data","type_id":5,"order_index":6},
    {"label":"Remarks","field_name":"remarks","json_column":"form_data","type_id":7,"order_index":7}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  93,
  'Confined Space Entry Inspection',
  'Inspection checklist before confined space entry at tanks or manholes',
  'ohs_inspections',
  '[{"field_name":"inspection_type_id","data_column":"inspection_type_id","type_id":1,"order_index":0},{"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
    {"label":"Inspection Date","field_name":"inspection_date","data_column":"date","type_id":3,"order_index":1},
    {"label":"Gas Test Conducted","field_name":"gas_test","json_column":"form_data","type_id":5,"order_index":2},
    {"label":"Ventilation Set Up","field_name":"ventilation","json_column":"form_data","type_id":5,"order_index":3},
    {"label":"Permit to Work Issued","field_name":"ptw","json_column":"form_data","type_id":5,"order_index":4},
    {"label":"Rescue Equipment Available","field_name":"rescue","json_column":"form_data","type_id":5,"order_index":5},
    {"label":"Remarks","field_name":"remarks","json_column":"form_data","type_id":7,"order_index":6}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  94,
  'Field Work Safety Inspection',
  'On-site inspection checklist for pipe repair, excavation, or rural works',
  'ohs_inspections',
  '[{"field_name":"inspection_type_id","data_column":"inspection_type_id","type_id":1,"order_index":0},{"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
    {"label":"Inspection Date","field_name":"inspection_date","data_column":"date","type_id":3,"order_index":1},
    {"label":"Traffic Management In Place","field_name":"traffic_control","json_column":"form_data","type_id":5,"order_index":2},
    {"label":"Tools in Good Condition","field_name":"tools","json_column":"form_data","type_id":5,"order_index":3},
    {"label":"First Aid Kit Available","field_name":"first_aid","json_column":"form_data","type_id":5,"order_index":4},
    {"label":"Team Briefing Conducted","field_name":"briefing","json_column":"form_data","type_id":5,"order_index":5},
    {"label":"Inspector Notes","field_name":"notes","json_column":"form_data","type_id":7,"order_index":6}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  95,
  'OHS Vehicle Inspection',
  'Safety checklist for operational and pool vehicles used by staff',
  'ohs_inspections',
  '[{"field_name":"inspection_type_id","data_column":"inspection_type_id","type_id":1,"order_index":0},{"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":1},{"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
    {"label":"Inspection Date","field_name":"inspection_date","data_column":"date","type_id":3,"order_index":1},
    {"label":"Vehicle Number","field_name":"vehicle_no","json_column":"form_data","type_id":1,"order_index":2},
    {"label":"Brakes Functional","field_name":"brakes","json_column":"form_data","type_id":5,"order_index":3},
    {"label":"Headlights & Signals","field_name":"lights","json_column":"form_data","type_id":5,"order_index":4},
    {"label":"Seat Belts Working","field_name":"seat_belts","json_column":"form_data","type_id":5,"order_index":5},
    {"label":"Fire Extinguisher Present","field_name":"extinguisher","json_column":"form_data","type_id":5,"order_index":6},
    {"label":"Inspector Comments","field_name":"comments","json_column":"form_data","type_id":7,"order_index":7}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  96,
  'OHS Inspection Start',
  'Choose inspection type and location',
  'ohs_inspections',
  '[{"label":"Inspection Type","field_name":"inspection_type_id","data_column":"inspection_type_id","type_id":4,"options_table":"ohs_inspection_types","options_label_column":"name","options_value_column":"id","order_index":1},
    {"label":"Location","field_name":"location","data_column":"location","type_id":4,"options_table":"locations","options_label_column":"name","options_value_column":"name","order_index":2}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO form_buttons (form_id,label,action_type,action_payload,order_index)
VALUES (
  96,'Open Form','open-form',
  '{"lookupTable":"ohs_inspection_types","lookupField":"inspection_type_id","valueColumn":"id","formColumn":"form_id","prefillFields":["inspection_type_id","location"]}',
  1
) ON CONFLICT DO NOTHING;

INSERT INTO document_categories (id, name, tenant_id, branch_id)
VALUES
  (1, 'Training', NULL, NULL),
  (2, 'Compliance', NULL, NULL)
ON CONFLICT (id) DO NOTHING;

INSERT INTO form_buttons (form_id,label,action_type,action_payload,order_index) VALUES
  (51,'Approve','workflow',(SELECT id FROM workflows WHERE trigger_event='case.approved' LIMIT 1),1),
  (51,'Reject','workflow',(SELECT id FROM workflows WHERE trigger_event='case.rejected' LIMIT 1),2);

INSERT INTO form_buttons (form_id, label, action_type, action_payload, order_index)
VALUES
  (59, 'Open Form', 'open-form',
   '{"lookupTable":"ohs_incident_types","lookupField":"classification","valueColumn":"name","formColumn":"form_id","prefillFields":["classification","location","severity"]}',
   1
 );

-- POS Settings table (idempotent, UUIDv7 keys)
CREATE TABLE IF NOT EXISTS pos_settings (
  pos_settings_id uuid PRIMARY KEY DEFAULT uuid_generate_v7(),
  org_id     uuid NULL,
  branch_id  uuid NULL,
  password   text NOT NULL,
  pin        text NOT NULL,
  isDeleted  boolean NOT NULL DEFAULT false,
  createdAt  timestamptz NOT NULL DEFAULT now(),
  updatedAt  timestamptz NOT NULL DEFAULT now()
);
CREATE UNIQUE INDEX IF NOT EXISTS uq_pos_settings_org_branch
  ON pos_settings(org_id, branch_id) WHERE isDeleted = false;

-- Seed a default POS Settings row if none exists (editable via the form)
-- Use first org_id if available; leave branch_id NULL by default
INSERT INTO pos_settings (org_id, branch_id, password, pin)
SELECT (SELECT org_id FROM orgs LIMIT 1), NULL, '2CBP6HMW', '3840'
WHERE NOT EXISTS (SELECT 1 FROM pos_settings);
-- Backfill new URL columns with defaults if they exist and are NULL
DO $$ BEGIN
  BEGIN
    -- Ensure new UUIDv7 PK exists and is populated
    ALTER TABLE pos_settings ADD COLUMN IF NOT EXISTS pos_settings_id uuid;
    UPDATE pos_settings SET pos_settings_id = COALESCE(pos_settings_id, uuid_generate_v7());
    -- Promote to primary key if old serial id existed
    BEGIN
      ALTER TABLE pos_settings DROP CONSTRAINT IF EXISTS pos_settings_pkey;
    EXCEPTION WHEN undefined_object THEN NULL; END;
    BEGIN
      ALTER TABLE pos_settings ADD PRIMARY KEY (pos_settings_id);
    EXCEPTION WHEN duplicate_table THEN NULL; END;
  EXCEPTION WHEN duplicate_column THEN NULL; END;
  BEGIN
    -- Replace tenant_id with org_id
    ALTER TABLE pos_settings ADD COLUMN IF NOT EXISTS org_id uuid NULL;
  EXCEPTION WHEN duplicate_column THEN NULL; END;
  BEGIN
    -- Ensure branch_id is uuid; if existing non-uuid column, rename and add new
    IF EXISTS (
      SELECT 1 FROM information_schema.columns
      WHERE table_name = 'pos_settings' AND column_name = 'branch_id' AND data_type <> 'uuid'
    ) THEN
      BEGIN
        ALTER TABLE pos_settings RENAME COLUMN branch_id TO branch_id_int;
      EXCEPTION WHEN undefined_column THEN NULL; END;
      BEGIN
        ALTER TABLE pos_settings ADD COLUMN IF NOT EXISTS branch_id uuid NULL;
      EXCEPTION WHEN duplicate_column THEN NULL; END;
    ELSE
      ALTER TABLE pos_settings ADD COLUMN IF NOT EXISTS branch_id uuid NULL;
    END IF;
  EXCEPTION WHEN duplicate_column THEN NULL; END;
  -- Drop old unique index that referenced tenant_id
  BEGIN
    DROP INDEX IF EXISTS uq_pos_settings_tenant_branch;
  EXCEPTION WHEN undefined_object THEN NULL; END;
  BEGIN
    ALTER TABLE pos_settings ADD COLUMN IF NOT EXISTS sdc_endpoint text NULL;
  EXCEPTION WHEN duplicate_column THEN NULL; END;
  BEGIN
    ALTER TABLE pos_settings ADD COLUMN IF NOT EXISTS sdc_pin_url text NULL;
  EXCEPTION WHEN duplicate_column THEN NULL; END;
END $$;

UPDATE pos_settings SET sdc_endpoint = COALESCE(sdc_endpoint,
  'http://devesdc.sandbox.vms.frcs.org.fj:8888/20f351f3-9b39-4c63-b9e0-d8a00b6e93fb/api');
UPDATE pos_settings SET sdc_pin_url = COALESCE(sdc_pin_url,
  'http://devesdc.sandbox.vms.frcs.org.fj:8888/20f351f3-9b39-4c63-b9e0-d8a00b6e93fb/api/v3/pin');
-- Ensure pos_settings have an org_id; default to Cybex PTE LTD if missing
UPDATE pos_settings
SET org_id = COALESCE(
  (SELECT org_id FROM orgs WHERE name = 'Cybex PTE LTD' LIMIT 1),
  '0194a8b2-1234-7123-8123-123456789abc'::uuid
)
WHERE org_id IS NULL;
  



INSERT INTO workflows (name, trigger_event, definition, is_active)
VALUES
  ('Driver Created', 'form.45.updated', '{"conditions":[]}', TRUE),
  ('Lawyer Created', 'form.37.updated', '{"conditions":[]}', TRUE),
  ('Fleet Engineer Created', 'form.46.updated', '{"conditions":[]}', TRUE),
  ('Investigator Created', 'form.73.updated', '{"conditions":[]}', TRUE);


-- Driver workflow steps
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config) VALUES
  ((SELECT id FROM workflows WHERE name='Driver Created'),1,'map_fields','{"map":{"user_id":"id"}}'),
  ((SELECT id FROM workflows WHERE name='Driver Created'),2,'ensure_group','{"name":"Drivers"}'),
  ((SELECT id FROM workflows WHERE name='Driver Created'),3,'save_record','{"table":"user_group_memberships","data":{"user_id":"{user_id}","group_id":"{group_id}","role":"Driver"}}'),
  ((SELECT id FROM workflows WHERE name='Driver Created'),4,'load_record','{"table":"users","id_key":"user_id","context_key":"user"}'),
  ((SELECT id FROM workflows WHERE name='Driver Created'),5,'queue_notification','{"entity":"users","record_id":"{user_id}","event_type":"insert","payload":"{user}"}');


-- Lawyer workflow steps
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config) VALUES
  ((SELECT id FROM workflows WHERE name='Lawyer Created'),1,'map_fields','{"map":{"user_id":"id"}}'),
  ((SELECT id FROM workflows WHERE name='Lawyer Created'),2,'ensure_group','{"name":"Lawyers"}'),
  ((SELECT id FROM workflows WHERE name='Lawyer Created'),3,'save_record','{"table":"user_group_memberships","data":{"user_id":"{user_id}","group_id":"{group_id}","role":"Lawyer"}}'),
  ((SELECT id FROM workflows WHERE name='Lawyer Created'),4,'load_record','{"table":"users","id_key":"user_id","context_key":"user"}'),
  ((SELECT id FROM workflows WHERE name='Lawyer Created'),5,'queue_notification','{"entity":"users","record_id":"{user_id}","event_type":"insert","payload":"{user}"}');


-- Ensure Lawyer form references the correct workflow now that it exists
UPDATE forms
  SET on_submit_workflow_id = (
    SELECT id FROM workflows WHERE name='Lawyer Created'
  )
WHERE name='Lawyer';


-- Fleet Engineer workflow steps
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config) VALUES
  ((SELECT id FROM workflows WHERE name='Fleet Engineer Created'),1,'map_fields','{"map":{"user_id":"id"}}'),
  ((SELECT id FROM workflows WHERE name='Fleet Engineer Created'),2,'ensure_group','{"name":"Fleet Engineers"}'),
  ((SELECT id FROM workflows WHERE name='Fleet Engineer Created'),3,'save_record','{"table":"user_group_memberships","data":{"user_id":"{user_id}","group_id":"{group_id}","role":"Fleet Engineer"}}'),
  ((SELECT id FROM workflows WHERE name='Fleet Engineer Created'),4,'load_record','{"table":"users","id_key":"user_id","context_key":"user"}'),
  ((SELECT id FROM workflows WHERE name='Fleet Engineer Created'),5,'queue_notification','{"entity":"users","record_id":"{user_id}","event_type":"insert","payload":"{user}"}');

-- Investigator workflow steps
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config) VALUES
  ((SELECT id FROM workflows WHERE name='Investigator Created'),1,'map_fields','{"map":{"user_id":"id"}}'),
  ((SELECT id FROM workflows WHERE name='Investigator Created'),2,'save_record','{"table":"users","data":{"full_name":"{full_name}","password":"{password}"},"context_key":"user_id"}'),
  ((SELECT id FROM workflows WHERE name='Investigator Created'),3,'ensure_group','{"name":"Investigators"}'),
  ((SELECT id FROM workflows WHERE name='Investigator Created'),4,'save_record','{"table":"user_group_memberships","data":{"user_id":"{user_id}","group_id":"{group_id}","role":"Investigator"}}'),
  ((SELECT id FROM workflows WHERE name='Investigator Created'),5,'load_record','{"table":"users","id_key":"user_id","context_key":"user"}'),
  ((SELECT id FROM workflows WHERE name='Investigator Created'),6,'queue_notification','{"entity":"users","record_id":"{user_id}","event_type":"insert","payload":"{user}"}');




INSERT INTO detail_views (id, name, config, tenant_id, branch_id) VALUES (
  2,
  'Case Details',
  $${
    "name": "Case Details",
    "sources": [
      { "table": "clients", "foreignKey": "client_id", "alias": "client" },
      { "table": "time_entries", "foreignKey": "time_entry_id" }
    ],
    "rows": [
      {
        "classes": "card bg-base-100 shadow card-body grid grid-cols-4 gap-4",
        "columns": [
          {
            "classes": "card bg-base-100 shadow p-4 space-y-1",
            "elements": [
              { "type": "heading", "text": "Client Information", "tag": "h2", "classes": "card-title" },
              { "type": "paragraph", "label": "Name", "data_column": "client.name", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" },
              { "type": "paragraph", "label": "Phone", "data_column": "client.phone", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" },
              { "type": "paragraph", "label": "Email", "data_column": "client.email", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" },
              { "type": "paragraph", "label": "Address", "data_column": "client.address", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" },
              { "type": "paragraph", "label": "City", "data_column": "client.city", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" },
              { "type": "paragraph", "label": "Country", "data_column": "client.country", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" },
              { "type": "paragraph", "label": "Description", "data_column": "client.description", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" }
            ]
          },
          {
            "classes": "card bg-base-100 shadow p-4 space-y-1",
            "elements": [
              { "type": "heading", "text": "Case Information", "tag": "h2", "classes": "card-title" },
              { "type": "paragraph", "label": "Title", "data_column": "title", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" },
              { "type": "paragraph", "label": "Case Number", "data_column": "case_number", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" },
              { "type": "paragraph", "label": "Status", "data_column": "status", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" },
              { "type": "paragraph", "label": "Lead Rep", "data_column": "lead_rep_name", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" },
              { "type": "paragraph", "label": "Opened", "data_column": "opened_at", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" },
              { "type": "paragraph", "label": "Closed", "data_column": "closed_at", "classes": "grid grid-cols-2 gap-2", "label_classes": "font-semibold" }
            ]
          },
          {
            "classes": "stats",
            "elements": [
              {
                "type": "div",
                "classes": "stat",
                "elements": [
                  { "type": "div", "classes": "stat-title", "text": "Hours" },
                  { "type": "aggregate", "table": "time_entries", "column": "hours", "function": "sum", "filterField": "time_entry_id", "classes": "stat-value" }
                ]
              },
              {
                "type": "div",
                "classes": "stat",
                "elements": [
                  { "type": "div", "classes": "stat-title", "text": "Expenses" },
                  { "type": "aggregate", "table": "expenses", "column": "amount", "function": "sum", "filterField": "case_id", "classes": "stat-value" }
                ]
              },
              {
                "type": "div",
                "classes": "stat",
                "elements": [
                  { "type": "div", "classes": "stat-title", "text": "Total Hours" },
                  { "type": "aggregate", "table": "time_entries", "column": "hours", "function": "sum", "filterField": "time_entry_id", "classes": "stat-value" }
                ]
              },
              {
                "type": "div",
                "classes": "stat",
                "elements": [
                  { "type": "div", "classes": "stat-title", "text": "Value" },
                  { "type": "aggregate", "table": "time_entries", "column": "total", "function": "sum", "filterField": "time_entry_id", "classes": "stat-value" }
                ]
              },
              {
                "type": "div",
                "classes": "stat",
                "elements": [
                  { "type": "div", "classes": "stat-title", "text": "Billed Hours" },
                  { "type": "aggregate", "table": "time_entries", "column": "hours", "function": "sum", "filterField": "time_entry_id", "filters": { "billed_to_client": 1 }, "classes": "stat-value" }
                ]
              },
              {
                "type": "div",
                "classes": "stat",
                "elements": [
                  { "type": "div", "classes": "stat-title", "text": "Billed Amount" },
                  { "type": "aggregate", "table": "time_entries", "column": "total", "function": "sum", "filterField": "time_entry_id", "filters": { "billed_to_client": 1 }, "classes": "stat-value" }
                ]
              }
            ]
          },
          {
            "classes": "card bg-base-100 shadow p-4 space-y-1",
            "elements": [
              { "type": "paragraph", "label": "Initial Instructions", "data_column": "initial_instructions" }
            ]
          }
        ]
      }
    ]
  }$$,
  NULL,
  NULL
);


-- Default invoice templates
INSERT INTO invoice_templates (name, file_path, tenant_id)
VALUES
  ('Basic', 'templates/invoices/basic.php', NULL),
  ('Detailed', 'templates/invoices/detailed.php', NULL),
  ('Modern', 'templates/invoices/modern.php', NULL),
  ('Notice of Certain Workplaces', 'templates/invoices/workplace_notice.php', NULL),
  ('Jagath Case', 'templates/invoices/jagath_template.php', NULL);

-- Default certificate templates
INSERT INTO certificate_templates (name, file_path, tenant_id)
VALUES ('Basic Certificate', 'templates/certificates/basic.php', NULL);

-- Default invoice settings row
INSERT INTO invoice_settings (tenant_id)
VALUES (NULL);

UPDATE invoice_settings
SET template_id = (SELECT id FROM invoice_templates WHERE name='Notice of Certain Workplaces' LIMIT 1),
    case_template_id = (SELECT id FROM invoice_templates WHERE name='Jagath Case' LIMIT 1)
WHERE tenant_id IS NULL;


-- Duplicate "Notice of Certain Workplaces" template for tenant 4
INSERT INTO invoice_templates (name, file_path, tenant_id)
SELECT name, file_path, 4
FROM invoice_templates
WHERE name = 'Notice of Certain Workplaces' AND tenant_id IS NULL
LIMIT 1;

-- Duplicate "Jagath Case" template for tenant 4
INSERT INTO invoice_templates (name, file_path, tenant_id)
SELECT name, file_path, 4
FROM invoice_templates
WHERE name = 'Jagath Case' AND tenant_id IS NULL
LIMIT 1;

INSERT INTO workflows (name, trigger_event, definition, is_active)
VALUES (
  'Invoice Configuration',
  'invoice.configure',
  '{"conditions":[]}',
  TRUE
);


INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
VALUES (
  (SELECT id FROM workflows WHERE name='Invoice Configuration' LIMIT 1),
  1,
  'open_modal',
  '{"modal":"Invoice Configuration"}'
);


-- Workflows triggered when time entries are approved or rejected
INSERT INTO workflows (name, trigger_event, definition, is_active)
VALUES ('Time Entries Approved', 'time_entries.approved', '{"conditions": []}', TRUE);


INSERT INTO workflows (name, trigger_event, definition, is_active)
VALUES ('Time Entries Rejected', 'time_entries.rejected', '{"conditions": []}', TRUE);


INSERT INTO workflow_steps (workflow_id, step_order, step_type, config) VALUES
  ((SELECT id FROM workflows WHERE name='Time Entries Approved' LIMIT 1),1,'map_fields','{"map":{"id":"time_entry_id"}}'),
  ((SELECT id FROM workflows WHERE name='Time Entries Approved' LIMIT 1),2,'save_record','{"table":"time_entries","data":{"comments":"{comments}","status":"Approved"},"match":{"id":"{id}"}}'),
  ((SELECT id FROM workflows WHERE name='Time Entries Approved' LIMIT 1),3,'load_record','{"table":"time_entries","id_key":"id","context_key":"time_entry"}'),
  ((SELECT id FROM workflows WHERE name='Time Entries Approved' LIMIT 1),4,'queue_notification','{"entity":"time_entries","record_id":"{id}","payload":"{time_entry}"}');


INSERT INTO workflow_steps (workflow_id, step_order, step_type, config) VALUES
  ((SELECT id FROM workflows WHERE name='Time Entries Rejected' LIMIT 1),1,'map_fields','{"map":{"id":"time_entry_id"}}'),
  ((SELECT id FROM workflows WHERE name='Time Entries Rejected' LIMIT 1),2,'save_record','{"table":"time_entries","data":{"comments":"{comments}","status":"Rejected"},"match":{"id":"{time_entry_id}"}}'),
  ((SELECT id FROM workflows WHERE name='Time Entries Rejected' LIMIT 1),3,'load_record','{"table":"time_entries","id_key":"id","context_key":"time_entry"}'),
  ((SELECT id FROM workflows WHERE name='Time Entries Rejected' LIMIT 1),4,'queue_notification','{"entity":"time_entries","record_id":"{id}","payload":"{time_entry}"}');


INSERT INTO workflow_event_triggers (event_name, table_name, trigger_type, operations, field_map)
VALUES (
  'workplace.registration.created',
  'workplace_registrations',
  'insert',
  '["insert"]',
  '{"id":"id","assigned_reviewer_id":"assigned_reviewer_id"}'
);

-- Workflow to auto assign inspectors when WorkCOM inspections are created
INSERT INTO workflows (name, trigger_event, definition, is_active)
VALUES (
  'WorkCOM Inspection Assignment',
  'workplace.inspection.created',
  '{"conditions": []}',
  TRUE
);

INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
VALUES (
  (SELECT id FROM workflows WHERE name='WorkCOM Inspection Assignment' LIMIT 1),
  1,
  'query_records',
  '{"table":"inspection_assignment_rules","where":{"district_id":"{district_id}"},"context_key":"rules"}'
);

INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
VALUES (
  (SELECT id FROM workflows WHERE name='WorkCOM Inspection Assignment' LIMIT 1),
  2,
  'map_fields',
  '{"map":{"inspector_id":"rules.0.inspector_id"}}'
);

INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
VALUES (
  (SELECT id FROM workflows WHERE name='WorkCOM Inspection Assignment' LIMIT 1),
  3,
  'save_record',
  '{"table":"workplace_inspections","data":{"inspector_id":"{inspector_id}"},"match":{"id":"{id}"}}'
);

INSERT INTO workflow_event_triggers (event_name, table_name, trigger_type, operations, field_map)
VALUES (
  'workplace.inspection.created',
  'workplace_inspections',
  'insert',
  '["insert"]',
  '{"id":"id","location":"location","inspection_type_id":"inspection_type_id","inspector_id":"inspector_id"}'
);


-- Workflow to handle WorkCOM payment verification and schedule a Kanban task and calendar event
INSERT INTO workflows (name, trigger_event, definition, is_active)
VALUES (
  'WorkCOM Payment Verification',
  'invoice.payment.verified',
  '{"conditions": []}',
  TRUE
);

-- Step 1: load workplace registration
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
VALUES (
  (SELECT id FROM workflows WHERE name='WorkCOM Payment Verification' LIMIT 1),
  1,
  'query_records',
  '{"table":"workplace_registrations","where":{"id":"{workplace_id}"},"context_key":"registration"}'
);

-- Step 2: map registration fields
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
VALUES (
  (SELECT id FROM workflows WHERE name='WorkCOM Payment Verification' LIMIT 1),
  2,
  'map_fields',
  '{"map":{"district_id":"registration.0.district","company_name":"registration.0.company_name","contact_person":"registration.0.contact_person","contact_email":"registration.0.contact_email","contact_phone":"registration.0.contact_phone","contact_telephone_number":"registration.0.contact_telephone_number","branch_id":"registration.0.branch_id","tenant_id":"registration.0.tenant_id"}}'
);

-- Step 3: find inspector assignment rules
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
VALUES (
  (SELECT id FROM workflows WHERE name='WorkCOM Payment Verification' LIMIT 1),
  3,
  'query_records',
  '{"table":"inspection_assignment_rules","where":{"district_id":"{district_id}"},"context_key":"rules"}'
);

-- Step 4: map inspector to assignee
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
VALUES (
  (SELECT id FROM workflows WHERE name='WorkCOM Payment Verification' LIMIT 1),
  4,
  'map_fields',
  '{"map":{"inspector_id":"rules.0.inspector_id","assignee_id":"rules.0.inspector_id"}}'
);

-- Step 5: create kanban task
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
SELECT
  (SELECT id FROM workflows WHERE name='WorkCOM Payment Verification' LIMIT 1),
  5,
  'create_task',
  json_build_object(
    'column_id', kc.id,
    'title', 'Workplace Inspection - {company_name}',
    'description', 'Inspection for {company_name}',
    'assignee_id', '{assignee_id}',
    'due_date', '{due_date}'
  )
FROM kanban_columns kc
JOIN kanban_boards kb ON kc.board_id = kb.id
WHERE kb.name='WorkCOM Inspections' AND kc.title='Pending'
LIMIT 1;

-- Step 6: add calendar event
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
SELECT
  (SELECT id FROM workflows WHERE name='WorkCOM Payment Verification' LIMIT 1),
  6,
  'add_calendar_event',
  json_build_object(
    'title', 'Workplace Inspection',
    'start_time', '{due_date}',
    'category_id', kb.calendar_category_id,
    'user_id', '{assignee_id}'
  )
FROM kanban_boards kb
WHERE kb.name='WorkCOM Inspections'
LIMIT 1;


-- Wizard configuration for incident forms
INSERT INTO form_wizards (id, name, description, tenant_id, branch_id)
VALUES (1, 'OHS Incident Wizard', 'Guided incident reporting',NULL, NULL)
ON CONFLICT DO NOTHING;

INSERT INTO form_wizards (id, name, description, tenant_id, branch_id)
VALUES (3, 'OHS Inspection Wizard', 'Guided inspection entry',NULL, NULL)
ON CONFLICT DO NOTHING;

INSERT INTO form_wizards (id, name, description, tenant_id, branch_id)
VALUES (5, 'WorkCOM Inspection Wizard', 'Guided WorkCOM inspection entry',NULL, NULL)
ON CONFLICT DO NOTHING;

INSERT INTO form_wizards (id, name, description, tenant_id, branch_id)
VALUES (6, 'Safety Incident Wizard', 'Guided safety incident entry', NULL, NULL)
ON CONFLICT DO NOTHING;

INSERT INTO form_wizards (id, name, description, tenant_id, branch_id)
VALUES (7, 'Customer Management Wizard', 'Guided customer management entry', NULL, NULL)
ON CONFLICT DO NOTHING;


INSERT INTO form_wizard_steps (wizard_id, step_number, form_id, condition_field, condition_value)
VALUES
  (1, 1, 59,NULL, NULL),
  (1, 2, 13, 'classification', 'Property Damage'),
  (1, 3, 14, 'classification', 'Environmental'),
  (1, 4, 15, 'classification', 'Near Miss'),
  (1, 5, 16, 'classification', 'First Aid'),
  (1, 6, 17, 'classification', 'Medical Treatment'),
  (1, 7, 18, 'classification', 'LTI'),
  (1, 8, 19, 'classification', 'Fatality'),
  (1, 9, 105, 'classification', 'Field Incident')
ON CONFLICT DO NOTHING;

INSERT INTO form_wizard_steps (wizard_id, step_number, form_id, condition_field, condition_value)
VALUES
  (7, 1, 199,NULL, NULL),
  (7, 2, 201, 'customer_type', 'Individual'),
  (7, 3, 200, 'customer_type', 'Corporate')
ON CONFLICT DO NOTHING;

INSERT INTO form_wizard_steps (wizard_id, step_number, form_id, condition_field, condition_value)
VALUES (6, 1, 107, NULL, NULL)
ON CONFLICT DO NOTHING;



-- Kanban board for WorkCOM inspections
INSERT INTO kanban_boards (id, name, description, tenant_id, branch_id)
VALUES (1, 'WorkCOM Inspection Kanban', 'Inspection workflow board', NULL, NULL)
ON CONFLICT DO NOTHING;

INSERT INTO kanban_columns (board_id, title, position, tenant_id, branch_id)
VALUES
  (1, 'Pending', 1, NULL, NULL),
  (1, 'In Progress', 2, NULL, NULL),
  (1, 'Completed', 3, NULL, NULL)
ON CONFLICT DO NOTHING;

INSERT INTO fishbone_diagrams (id, problem, categories, diagram_data)
VALUES
-- Diagram 1
(1, 'Low Water Pressure in Urban Areas',
 '[{"name":"Infrastructure","causes":["Aging pipes","Undersized mains","Leaks in distribution lines"]},{"name":"Demand Surge","causes":["Population growth","Unauthorized connections"]},{"name":"Maintenance","causes":["Infrequent valve flushing","Inadequate pressure zoning"]},{"name":"Energy Supply","causes":["Pump outages","Fluctuating voltage"]}]',
 $json$
 {
   "problem": "Low Water Pressure in Urban Areas",
   "categories": [
     {
       "name": "Infrastructure",
       "color": "#3366cc",
       "comment": "Focus on pipe upgrades",
       "causes": [
         { "text": "Aging pipes", "color": "#333", "comment": "Over 30 years old" },
         { "text": "Undersized mains", "color": "#333", "comment": "Can't handle peak flow" },
         { "text": "Leaks in distribution lines", "color": "#333", "comment": "Common in zones 4, 6" }
       ]
     },
     {
       "name": "Demand Surge",
       "color": "#ff9900",
       "comment": "Urban population growth outpacing planning",
       "causes": [
         { "text": "Population growth", "color": "#333" },
         { "text": "Unauthorized connections", "color": "#cc0000", "comment": "Found in squatter areas" }
       ]
     },
     {
       "name": "Maintenance",
       "color": "#109618",
       "causes": [
         { "text": "Infrequent valve flushing", "color": "#333" },
         { "text": "Inadequate pressure zoning", "color": "#333" }
       ]
     },
     {
       "name": "Energy Supply",
       "color": "#990099",
       "causes": [
         { "text": "Pump outages", "color": "#333" },
         { "text": "Fluctuating voltage", "color": "#333" }
       ]
     }
   ]
 }
 $json$::jsonb),

-- Diagram 2
(2, 'High Water Loss (Non-Revenue Water)',
 '[{"name":"Metering","causes":["Inaccurate customer meters","Missing bulk meters"]},{"name":"Illegal Use","causes":["Bypassed meters","Unauthorized hydrants"]},{"name":"Pipeline Integrity","causes":["Undetected leaks","Old pipe materials"]},{"name":"Monitoring","causes":["Poor SCADA integration","Infrequent audits"]}]',
 $json$
 {
   "problem": "High Water Loss (Non-Revenue Water)",
   "categories": [
     {
       "name": "Metering",
       "color": "#1f77b4",
       "causes": [
         { "text": "Inaccurate customer meters", "comment": "Affects billing accuracy" },
         { "text": "Missing bulk meters" }
       ]
     },
     {
       "name": "Illegal Use",
       "color": "#d62728",
       "causes": [
         { "text": "Bypassed meters" },
         { "text": "Unauthorized hydrants" }
       ]
     },
     {
       "name": "Pipeline Integrity",
       "color": "#2ca02c",
       "causes": [
         { "text": "Undetected leaks", "comment": "Leak detection overdue" },
         { "text": "Old pipe materials" }
       ]
     },
     {
       "name": "Monitoring",
       "color": "#ff7f0e",
       "causes": [
         { "text": "Poor SCADA integration" },
         { "text": "Infrequent audits" }
       ]
     }
   ]
 }
 $json$::jsonb),

-- Diagram 3
(3, 'Delayed Response to Water Complaints',
 '[{"name":"Customer Service","causes":["Long call wait times","Poor ticket routing"]},{"name":"Field Operations","causes":["Limited repair crews","Incomplete work logs"]},{"name":"Communication","causes":["No SMS alerts","Delayed internal escalation"]},{"name":"Technology","causes":["Outdated ticketing system","No real-time dashboard"]}]',
 $json$
 {
   "problem": "Delayed Response to Water Complaints",
   "categories": [
     {
       "name": "Customer Service",
       "color": "#8c564b",
       "causes": [
         { "text": "Long call wait times" },
         { "text": "Poor ticket routing" }
       ]
     },
     {
       "name": "Field Operations",
       "color": "#e377c2",
       "causes": [
         { "text": "Limited repair crews" },
         { "text": "Incomplete work logs" }
       ]
     },
     {
       "name": "Communication",
       "color": "#7f7f7f",
       "causes": [
         { "text": "No SMS alerts" },
         { "text": "Delayed internal escalation" }
       ]
     },
     {
       "name": "Technology",
       "color": "#bcbd22",
       "causes": [
         { "text": "Outdated ticketing system" },
         { "text": "No real-time dashboard" }
       ]
     }
   ]
 }
 $json$::jsonb);


INSERT INTO graphs (name, config)
VALUES
  ('Incidents by classification',
   '{"table":"ohs_incidents","x":"classification","y":"id","type":"bar","groupBy":"classification","aggregateFunc":"count","timeUnit":""}'),
  ('Incident Trends',
   '{"table":"ohs_incidents","x":"date","y":"id","type":"groupedBar","groupBy":"date,classification","aggregateFunc":"count","timeUnit":"year"}'),
  ('Top 10 Customers by Revenue',
   '{"table":"revenue_by_customer","x":"customer_name","y":"total_revenue","type":"bar","groupBy":null,"aggregateFunc":null,"timeUnit":null}'),
  ('Revenue Acquisition Over Time',
   '{"table":"revenue_by_customer","x":"customer_since","y":"revenue_ytd","type":"line","groupBy":"customer_since","aggregateFunc":"sum","timeUnit":"month"}'),
  ('Revenue by Customer Status',
   '{"table":"revenue_by_customer","x":"customer_status","y":"total_revenue","type":"pie","groupBy":"customer_status","aggregateFunc":"sum","timeUnit":null}'),
  ('Revenue Trends: 30 vs 90 Days',
   '{"table":"revenue_by_customer","x":"customer_name","y":"revenue_last_30_days,revenue_last_90_days","type":"groupedBar","groupBy":"customer_name","aggregateFunc":null,"timeUnit":null}');

INSERT INTO ohs_fault_trees (id, incident_id, tree_data, tenant_id, branch_id)
VALUES (1, 0, '{"name":"Top Event","children":[{"name":"Cause A"},{"name":"Cause B"}]}', NULL, NULL);

INSERT INTO form_wizard_steps (wizard_id, step_number, form_id, condition_field, condition_value)
VALUES
  (3, 1, 96,NULL, NULL)
ON CONFLICT DO NOTHING;

INSERT INTO form_wizard_steps (wizard_id, step_number, form_id, condition_field, condition_value)
VALUES
  (5, 1, 103, NULL, NULL)
ON CONFLICT DO NOTHING;



-- Converted on 2025-07-11T16:28:17+12:00

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 4, 'OHS Incident', 'Default incident report form', 'ohs_incidents', '[{"label":"Date","field_name":"date","data_column":"date","type_id":3,"order_index":1},{"label":"Time","field_name":"time","data_column":"time","type_id":1,"order_index":2},{"label":"Classification","field_name":"classification","data_column":"classification","type_id":4,"order_index":3},{"label":"Nature","field_name":"nature","data_column":"nature","type_id":1,"order_index":4},{"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":5},{"label":"Status","field_name":"status","data_column":"status_id","type_id":4,"order_index":6,"options_table":"ohs_incident_statuses","options_label_column":"name","options_value_column":"id"}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 4);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 6, 'Job Safety Analysis', 'Record JSA details', 'ohs_jsas', '[{"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},{"label":"Description","field_name":"description","data_column":"description","type_id":1,"order_index":2},{"label":"Doc Path","field_name":"doc_path","data_column":"doc_path","type_id":7,"order_index":3},{"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":4},{"label":"Department Id","field_name":"department_id","data_column":"department_id","type_id":2,"order_index":5},{"label":"Analysis Date","field_name":"analysis_date","data_column":"analysis_date","type_id":3,"order_index":6},{"label":"Prepared By","field_name":"prepared_by","data_column":"prepared_by","type_id":2,"order_index":7},{"label":"Team Member Ids","field_name":"team_member_ids","data_column":"team_member_ids","type_id":7,"order_index":8},{"label":"Ppe Required","field_name":"ppe_required","data_column":"ppe_required","type_id":7,"order_index":9},{"label":"Permit Requirements","field_name":"permit_requirements","data_column":"permit_requirements","type_id":7,"order_index":10},{"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":11}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 6);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 7, 'OHS Hazard', 'Default hazard report form', 'ohs_hazards', '[{"label":"Description","field_name":"description","data_column":"description","type_id":1,"order_index":1},{"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":2},{"label":"Probability","field_name":"probability","data_column":"probability","type_id":4,"order_index":4,"options":[{"display_text":"1","value":"1"},{"display_text":"2","value":"2"},{"display_text":"3","value":"3"},{"display_text":"4","value":"4"},{"display_text":"5","value":"5"}]},{"label":"Severity","field_name":"severity","data_column":"severity","type_id":4,"order_index":5,"options":[{"display_text":"1","value":"1"},{"display_text":"2","value":"2"},{"display_text":"3","value":"3"},{"display_text":"4","value":"4"},{"display_text":"5","value":"5"}]},{"label":"Risk Level","field_name":"risk_level","data_column":"risk_level","type_id":2,"order_index":6},{"label":"Latitude","field_name":"latitude","data_column":"latitude","type_id":2,"order_index":7},{"label":"Longitude","field_name":"longitude","data_column":"longitude","type_id":2,"order_index":8},{"label":"Hazard Type","field_name":"hazard_type_id","data_column":"hazard_type_id","type_id":4,"order_index":3,"options_table":"ohs_hazard_types","options_label_column":"name","options_value_column":"id"}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 7);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 8, 'SCORM Package', 'Upload SCORM content', ' NULL', '[{"label":"Course Id","field_name":"course_id","data_column":"course_id","type_id":2,"order_index":1},{"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":2},{"label":"Scorm Zip","field_name":"scorm_zip","data_column":"scorm_zip","type_id":7,"order_index":3},{"label":"Is Scorm","field_name":"is_scorm","data_column":"is_scorm","type_id":5,"order_index":4},{"label":"Caption","field_name":"caption","data_column":"caption","type_id":7,"order_index":5},{"label":"Language Code","field_name":"language_code","data_column":"language_code","type_id":1,"order_index":6}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 8);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 9, 'Training Path', 'Create a learning path', ' NULL', '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},{"label":"Description","field_name":"description","data_column":"description","type_id":1,"order_index":2},{"label":"Department Id","field_name":"department_id","data_column":"department_id","type_id":2,"order_index":3},{"label":"Role Id","field_name":"role_id","data_column":"role_id","type_id":2,"order_index":4}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 9);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 10, 'Safety Induction', 'Record employee safety inductions', ' NULL', '[{"label":"Employee Id","field_name":"employee_id","data_column":"employee_id","type_id":2,"order_index":1},{"label":"Induction Date","field_name":"induction_date","data_column":"induction_date","type_id":3,"order_index":2},{"label":"Document Id","field_name":"document_id","data_column":"document_id","type_id":7,"order_index":3}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 10);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 11, 'Employee License', 'Track employee licenses', ' NULL', '[{"label":"Employee Id","field_name":"employee_id","data_column":"employee_id","type_id":2,"order_index":1},{"label":"License Type","field_name":"license_type","data_column":"license_type","type_id":1,"order_index":2},{"label":"License Number","field_name":"license_number","data_column":"license_number","type_id":1,"order_index":3},{"label":"Expiry Date","field_name":"expiry_date","data_column":"expiry_date","type_id":3,"order_index":4},{"label":"Document Id","field_name":"document_id","data_column":"document_id","type_id":7,"order_index":5}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 11);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 12, 'Training Requirement', 'Assign mandatory courses per project', ' NULL', '[{"label":"Project Id","field_name":"project_id","data_column":"project_id","type_id":2,"order_index":1},{"label":"Role Id","field_name":"role_id","data_column":"role_id","type_id":2,"order_index":2},{"label":"Location Id","field_name":"location_id","data_column":"location_id","type_id":2,"order_index":3},{"label":"Course Id","field_name":"course_id","data_column":"course_id","type_id":2,"order_index":4}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 12);
-- Category for incident forms
INSERT INTO form_categories (name, description, tenant_id, branch_id)
VALUES ('OHS Incident Forms', 'Incident reporting forms', NULL, NULL)
ON CONFLICT DO NOTHING;
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id, category_id)
VALUES (
  13,
  'OHS Incident – Property Damage',
  'Report property damage incidents',
  'ohs_incidents',
  $json$[{"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
      {"label":"Date of Damage","field_name":"date","data_column":"date","type_id":3,"order_index":1},
      {"label":"Time of Damage","field_name":"time","data_column":"time","type_id":1,"order_index":2},
      {"label":"Location","field_name":"location","data_column":"location","type_id":17,"order_index":3},
      {"label":"Asset Affected","field_name":"asset_affected","type_id":1,"order_index":4,"json_column":"form_data"},
      {"label":"Damage Description","field_name":"damage_description","type_id":1,"order_index":5,"json_column":"form_data"},
      {"label":"Estimated Cost","field_name":"estimated_cost","type_id":2,"order_index":6,"json_column":"form_data"},
      {"label":"Immediate Action","field_name":"immediate_action","type_id":1,"order_index":7,"json_column":"form_data"},
      {"label":"Severity","field_name":"severity","data_column":"severity","type_id":17,"order_index":12},
      {"label":"Responsible Person","field_name":"responsible_person","type_id":1,"order_index":8,"json_column":"form_data"},
      {"label":"Status","field_name":"status","type_id":4,"order_index":9,"options_table":"ohs_incident_statuses","options_label_column":"name","options_value_column":"id","json_column":"form_data"},
      {"label":"Investigator","field_name":"investigator_id","data_column":"investigator_id","type_id":17,"order_index":10,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Investigators\"]}}"},
      {"label":"Reviewer","field_name":"reviewer_id","data_column":"reviewer_id","type_id":17,"order_index":11,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Reviewers\"]}}"},
      {"label":"Classification","field_name":"classification","data_column":"classification","type_id":17,"order_index":12}]$json$::jsonb,
  NULL,
  NULL,
  1
)
ON CONFLICT (id) DO NOTHING;
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id, category_id)
VALUES (
  14,
  'OHS Incident – Environmental',
  'Report environmental incidents (spills, emissions, etc.)',
  'ohs_incidents',
  $json$
  [
    {"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
    {"label":"Date","field_name":"date","data_column":"date","type_id":3,"order_index":1},
    {"label":"Time","field_name":"time","data_column":"time","type_id":1,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Type of Incident","field_name":"env_incident_type","data_column":"env_incident_type","type_id":1,"order_index":4},
    {"label":"Impact Description","field_name":"impact_description","data_column":"impact_description","type_id":1,"order_index":5},
    {"label":"Area Affected","field_name":"area_affected","data_column":"area_affected","type_id":1,"order_index":6},
    {"label":"Volume/Quantity","field_name":"volume","data_column":"volume","type_id":2,"order_index":7},
    {"label":"Remediation Action","field_name":"remediation_action","data_column":"remediation_action","type_id":1,"order_index":8},
    {"label":"Status","field_name":"status_id","data_column":"status_id","type_id":4,"order_index":9,"options_table":"ohs_incident_statuses","options_label_column":"name","options_value_column":"id"},
    {"label":"Investigator","field_name":"investigator_id","data_column":"investigator_id","type_id":4,"order_index":10,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Investigators\"]}}"},
    {"label":"Reviewer","field_name":"reviewer_id","data_column":"reviewer_id","type_id":4,"order_index":11,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Reviewers\"]}}"}, {"label":"Classification","field_name":"classification","data_column":"classification","type_id":16,"order_index":12}]
  $json$::jsonb,
  NULL,
  NULL,
  1
)
ON CONFLICT (id) DO NOTHING;
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id, category_id)
VALUES (
  15,
  'OHS Incident – Near Miss',
  'Report near-miss incidents',
  'ohs_incidents',
  $json$[{"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
      {"label":"Date","field_name":"date","data_column":"date","type_id":3,"order_index":1},
      {"label":"Time","field_name":"time","data_column":"time","type_id":1,"order_index":2},
      {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
      {"label":"Description of Near Miss","field_name":"description","type_id":1,"order_index":4,"json_column":"form_data"},
      {"label":"Hazard Identified","field_name":"hazard_identified","type_id":1,"order_index":5,"json_column":"form_data"},
      {"label":"Potential Consequence","field_name":"potential_consequence","type_id":1,"order_index":6,"json_column":"form_data"},
      {"label":"Immediate Action","field_name":"immediate_action","type_id":1,"order_index":7,"json_column":"form_data"},
      {"label":"Status","field_name":"status","type_id":4,"order_index":8,"options_table":"ohs_incident_statuses","options_label_column":"name","options_value_column":"id","json_column":"form_data"},
      {"label":"Investigator","field_name":"investigator_id","data_column":"investigator_id","type_id":4,"order_index":9,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Investigators\"]}}"},
      {"label":"Reviewer","field_name":"reviewer_id","data_column":"reviewer_id","type_id":4,"order_index":10,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Reviewers\"]}}"}, {"label":"Classification","field_name":"classification","data_column":"classification","type_id":16,"order_index":11}]$json$::jsonb,
  NULL,
  NULL,
  1
)
ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id, category_id)
VALUES (
  16,
  'OHS Incident – First Aid',
  'Report incidents requiring first aid',
  'ohs_incidents',
  $json$[{"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
      {"label":"Date","field_name":"date","data_column":"date","type_id":3,"order_index":1},
      {"label":"Time","field_name":"time","data_column":"time","type_id":1,"order_index":2},
      {"label":"Location","field_name":"location","data_column":"location","type_id":17,"order_index":3},
      {"label":"Person Treated","field_name":"person_treated","type_id":1,"order_index":4,"json_column":"form_data"},
      {"label":"Injury Description","field_name":"injury_description","type_id":1,"order_index":5,"json_column":"form_data"},
      {"label":"First Aid Given","field_name":"first_aid_given","type_id":1,"order_index":6,"json_column":"form_data"},
      {"label":"Treated By","field_name":"treated_by","type_id":1,"order_index":7,"json_column":"form_data"},
      {"label":"Follow-Up Required?","field_name":"follow_up_required","type_id":4,"order_index":8,"options":[{"display_text":"Yes","value":"yes"},{"display_text":"No","value":"no"}],"json_column":"form_data"},
      {"label":"Classification","field_name":"classification","data_column":"classification","type_id":17,"order_index":12},
      {"label":"Severity","field_name":"severity","data_column":"severity","type_id":17,"order_index":13},
      {"label":"Status","field_name":"status","type_id":4,"order_index":9,"options_table":"ohs_incident_statuses","options_label_column":"name","options_value_column":"id","json_column":"form_data"},
      {"label":"Investigator","field_name":"investigator_id","data_column":"investigator_id","type_id":4,"order_index":10,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Investigators\"]}}"},
      {"label":"Reviewer","field_name":"reviewer_id","data_column":"reviewer_id","type_id":4,"order_index":11,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Reviewers\"]}}"}]$json$::jsonb,
  NULL,
  NULL,
  1
)
ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id, category_id)
VALUES (
  17,
  'OHS Incident – Medical Treatment',
  'Report incidents requiring medical treatment',
  'ohs_incidents',
  $json$[{"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
      {"label":"Date","field_name":"date","data_column":"date","type_id":3,"order_index":1},
      {"label":"Time","field_name":"time","data_column":"time","type_id":1,"order_index":2},
      {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
      {"label":"Person Treated","field_name":"person_treated","type_id":1,"order_index":4,"json_column":"form_data"},
      {"label":"Injury Description","field_name":"injury_description","type_id":1,"order_index":5,"json_column":"form_data"},
      {"label":"Medical Details","field_name":"medical_details","type_id":1,"order_index":6,"json_column":"form_data"},
      {"label":"Provider","field_name":"medical_provider","type_id":1,"order_index":7,"json_column":"form_data"},
      {"label":"Follow-Up Required?","field_name":"follow_up_required","type_id":4,"order_index":8,"options":[{"display_text":"Yes","value":"yes"},{"display_text":"No","value":"no"}],"json_column":"form_data"},
      {"label":"Classification","field_name":"classification","data_column":"classification","type_id":16,"order_index":12},
      {"label":"Severity","field_name":"severity","data_column":"severity","type_id":16,"order_index":13},
      {"label":"Status","field_name":"status","type_id":4,"order_index":9,"options_table":"ohs_incident_statuses","options_label_column":"name","options_value_column":"id","json_column":"form_data"},
      {"label":"Investigator","field_name":"investigator_id","data_column":"investigator_id","type_id":4,"order_index":10,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Investigators\"]}}"},
      {"label":"Reviewer","field_name":"reviewer_id","data_column":"reviewer_id","type_id":4,"order_index":11,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Reviewers\"]}}"}]$json$::jsonb,
  NULL,
  NULL,
  1
)
ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id, category_id)
VALUES (
  18,
  'OHS Incident – LTI',
  'Report lost-time injuries',
  'ohs_incidents',
  $json$[{"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
      {"label":"Date","field_name":"date","data_column":"date","type_id":3,"order_index":1},
      {"label":"Time","field_name":"time","data_column":"time","type_id":1,"order_index":2},
      {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
      {"label":"Person Injured","field_name":"person_injured","type_id":1,"order_index":4,"json_column":"form_data"},
      {"label":"Injury Description","field_name":"injury_description","type_id":1,"order_index":5,"json_column":"form_data"},
      {"label":"Days Lost","field_name":"days_lost","type_id":2,"order_index":6,"json_column":"form_data"},
        {"label":"Classification","field_name":"classification","data_column":"classification","type_id":16,"order_index":12},
        {"label":"Severity","field_name":"severity","data_column":"severity","type_id":16,"order_index":13},
      {"label":"Return-to-Work Date","field_name":"rtw_date","type_id":3,"order_index":7,"json_column":"form_data"},
      {"label":"Corrective Action","field_name":"corrective_action","type_id":1,"order_index":8,"json_column":"form_data"},
      {"label":"Status","field_name":"status","type_id":4,"order_index":9,"options_table":"ohs_incident_statuses","options_label_column":"name","options_value_column":"id","json_column":"form_data"},
      {"label":"Investigator","field_name":"investigator_id","data_column":"investigator_id","type_id":4,"order_index":10,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Investigators\"]}}"},
      {"label":"Reviewer","field_name":"reviewer_id","data_column":"reviewer_id","type_id":4,"order_index":11,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Reviewers\"]}}"}]$json$::jsonb,
  NULL,
  NULL,
  1
)
ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id, category_id)
VALUES (
  19,
  'OHS Incident – Fatality',
  'Report fatalities',
  'ohs_incidents',
  $json$[{"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
      {"label":"Date","field_name":"date","data_column":"date","type_id":3,"order_index":1},
      {"label":"Time","field_name":"time","data_column":"time","type_id":1,"order_index":2},
      {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
      {"label":"Deceased Name","field_name":"deceased_name","type_id":1,"order_index":4,"json_column":"form_data"},
      {"label":"Cause of Death","field_name":"cause_of_death","type_id":1,"order_index":5,"json_column":"form_data"},
      {"label":"Reported to Authorities","field_name":"reported_authorities","type_id":3,"order_index":6,"json_column":"form_data"},
      {"label":"Coroner Details","field_name":"coroner_details","type_id":1,"order_index":7,"json_column":"form_data"},
      {"label":"Corrective Action","field_name":"corrective_action","type_id":1,"order_index":8,"json_column":"form_data"},
        {"label":"Classification","field_name":"classification","data_column":"classification","type_id":16,"order_index":12},
        {"label":"Severity","field_name":"severity","data_column":"severity","type_id":16,"order_index":13},
      {"label":"Status","field_name":"status","type_id":4,"order_index":9,"options_table":"ohs_incident_statuses","options_label_column":"name","options_value_column":"id","json_column":"form_data"},
      {"label":"Investigator","field_name":"investigator_id","data_column":"investigator_id","type_id":4,"order_index":10,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Investigators\"]}}"},
      {"label":"Reviewer","field_name":"reviewer_id","data_column":"reviewer_id","type_id":4,"order_index":11,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Reviewers\"]}}"}]$json$::jsonb,
  NULL,
  NULL,
  1
)
ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id, category_id)
VALUES (
  20,
  'OHS Incident',
  'Default incident report form',
  'ohs_incidents',
  $json$[{"label":"Short Description","field_name":"short_description","data_column":"short_description","type_id":1,"order_index":0},
      {"label":"Date","field_name":"date","data_column":"date","type_id":3,"order_index":1},
      {"label":"Time","field_name":"time","data_column":"time","type_id":1,"order_index":2},
      {"label":"Classification","field_name":"classification","data_column":"classification","type_id":4,"order_index":3,"options":[{"display_text":"Injury","value":"injury"},{"display_text":"Property Damage","value":"property_damage"},{"display_text":"Environmental","value":"environmental"},{"display_text":"Near Miss","value":"near_miss"},{"display_text":"First Aid","value":"first_aid"},{"display_text":"Medical Treatment","value":"medical_treatment"},{"display_text":"LTI","value":"lti"},{"display_text":"Fatality","value":"fatality"}]},
      {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":4},
      {"label":"Nature","field_name":"nature","type_id":1,"order_index":5,"json_column":"form_data"},
      {"label":"Workplace Part","field_name":"workplace_part","type_id":1,"order_index":6,"json_column":"form_data"},
      {"label":"Activity","field_name":"activity","type_id":1,"order_index":7,"json_column":"form_data"},
      {"label":"Unexpected","field_name":"unexpected","type_id":1,"order_index":8,"json_column":"form_data"},
      {"label":"How Sustained","field_name":"how_sustained","type_id":1,"order_index":9,"json_column":"form_data"},
      {"label":"Completed By","field_name":"completed_by","type_id":1,"order_index":10,"json_column":"form_data"},
      {"label":"Position","field_name":"position","type_id":1,"order_index":11,"json_column":"form_data"},
      {"label":"Outcome","field_name":"outcome","type_id":1,"order_index":12,"json_column":"form_data"},
      {"label":"Preventative Action","field_name":"preventative_action","type_id":1,"order_index":13,"json_column":"form_data"},
      {"label":"Investigator Id","field_name":"investigator_id","data_column":"investigator_id","type_id":4,"order_index":14,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Investigators\"]}}"},
      {"label":"Reviewer","field_name":"reviewer_id","data_column":"reviewer_id","type_id":4,"order_index":15,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Reviewers\"]}}"},
      {"label":"Status","field_name":"status","type_id":4,"order_index":16,"options_table":"ohs_incident_statuses","options_label_column":"name","options_value_column":"id","json_column":"form_data"},
      {"label":"Days Lost","field_name":"days_lost","type_id":2,"order_index":17,"json_column":"form_data"},
      {"label":"Return-to-Work Date","field_name":"rtw_date","type_id":3,"order_index":18,"json_column":"form_data"},
      {"label":"Restricted Duty Notes","field_name":"restricted_duty_notes","type_id":1,"order_index":19,"json_column":"form_data"},
        {"label":"Severity","field_name":"severity","data_column":"severity","type_id":16,"order_index":20}]$json$::jsonb,
  NULL,
  NULL,
  1
)
ON CONFLICT (id) DO NOTHING;


INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 29, 'Vehicle Registration', 'Capture fleet vehicle details', 'vehicles', '[{"label":"Vehicle Number","field_name":"vehicle_number","data_column":"vehicle_number","type_id":1,"order_index":1,"options_table":" NULL","options_label_column":" NULL","options_value_column":" NULL"},{"label":"Vin","field_name":"vin","data_column":"vin","type_id":1,"order_index":2,"options_table":" NULL","options_label_column":" NULL","options_value_column":" NULL"},{"label":"Engine Number","field_name":"engine_number","data_column":"engine_number","type_id":1,"order_index":3,"options_table":" NULL","options_label_column":" NULL","options_value_column":" NULL"},{"label":"Mileage","field_name":"mileage","data_column":"mileage","type_id":2,"order_index":4,"options_table":" NULL","options_label_column":" NULL","options_value_column":" NULL"},{"label":"Make","field_name":"make","data_column":"make","type_id":9,"order_index":5,"options_table":"vehicle_makes","options_label_column":"name","options_value_column":"id"},{"label":"Model","field_name":"model","data_column":"model","type_id":9,"order_index":6,"options_table":"vehicle_models","options_label_column":"name","options_value_column":"id"},{"label":"Type","field_name":"type","data_column":"type","type_id":9,"order_index":7,"options_table":"vehicle_types","options_label_column":"name","options_value_column":"id"},{"label":"Year","field_name":"year","data_column":"year","type_id":2,"order_index":8,"options_table":" NULL","options_label_column":" NULL","options_value_column":" NULL"},{"label":"Fitness Expires","field_name":"fitness_expires","data_column":"fitness_expires","type_id":3,"order_index":9,"options_table":" NULL","options_label_column":" NULL","options_value_column":" NULL"}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 29);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 30, 'Trip Log', 'Record vehicle trips with mileage', ' NULL', '[{"label":"Vehicle Id","field_name":"vehicle_id","data_column":"vehicle_id","type_id":2,"order_index":1},{"label":"Driver Id","field_name":"driver_id","data_column":"driver_id","type_id":2,"order_index":2},{"label":"Trip Date","field_name":"trip_date","data_column":"trip_date","type_id":3,"order_index":3},{"label":"Start Time","field_name":"start_time","data_column":"start_time","type_id":8,"order_index":4},{"label":"End Time","field_name":"end_time","data_column":"end_time","type_id":8,"order_index":5},{"label":"Start Location","field_name":"start_location","data_column":"start_location","type_id":1,"order_index":6},{"label":"End Location","field_name":"end_location","data_column":"end_location","type_id":1,"order_index":7},{"label":"Start Mileage","field_name":"start_mileage","data_column":"start_mileage","type_id":2,"order_index":8},{"label":"End Mileage","field_name":"end_mileage","data_column":"end_mileage","type_id":2,"order_index":9},{"label":"Distance Km","field_name":"distance_km","data_column":"distance_km","type_id":2,"order_index":10},{"label":"Status","field_name":"status","data_column":"status_id","type_id":1,"order_index":11}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 30);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 31, 'Service Type', 'Define maintenance intervals', 'service_types', '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1,"options_table":" NULL","options_label_column":" NULL","options_value_column":" NULL"},{"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":2,"options_table":" NULL","options_label_column":" NULL","options_value_column":" NULL"},{"label":"Make","field_name":"make","data_column":"make","type_id":9,"order_index":3,"options_table":"vehicle_makes","options_label_column":"name","options_value_column":"id"},{"label":"Model","field_name":"model","data_column":"model","type_id":9,"order_index":4,"options_table":"vehicle_models","options_label_column":"name","options_value_column":"id"},{"label":"Vehicle Type","field_name":"type","data_column":"type","type_id":9,"order_index":5,"options_table":"vehicle_types","options_label_column":"name","options_value_column":"id"},{"label":"Km Interval","field_name":"km_interval","data_column":"km_interval","type_id":2,"order_index":6,"options_table":" NULL","options_label_column":" NULL","options_value_column":" NULL"},{"label":"Month Interval","field_name":"month_interval","data_column":"month_interval","type_id":2,"order_index":7,"options_table":" NULL","options_label_column":" NULL","options_value_column":" NULL"}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 31);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 32, 'User Group', 'Manage user groups and permissions', 'groups', '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},{"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":2},{"label":"Parent Id","field_name":"parent_id","data_column":"parent_id","type_id":2,"order_index":3}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 32);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 33, 'Group Member', 'Assign users to groups', 'user_group_memberships', '[{"label":"User Id","field_name":"user_id","data_column":"user_id","type_id":2,"order_index":1},{"label":"Group Id","field_name":"group_id","data_column":"group_id","type_id":2,"order_index":2},{"label":"Role","field_name":"role","data_column":"role","type_id":1,"order_index":3}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 33);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 34, 'Vehicle Issue Report', 'Report vehicle issues', 'vehicle_reports', '[{"label":"Vehicle Id","field_name":"vehicle_id","data_column":"vehicle_id","type_id":9,"order_index":1,"options_table":"vehicles","options_label_column":"vehicle_number","options_value_column":"id"},{"label":"Report Type","field_name":"report_type","data_column":"report_type","type_id":4,"order_index":2,"options_table":"\n        NULL","options_label_column":" NULL","options_value_column":" NULL","options":[{"display_text":"minor","value":"minor"},{"display_text":"major","value":"major"},{"display_text":"breakdown","value":"breakdown"}]},{"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":3,"options_table":"\n        NULL","options_label_column":" NULL","options_value_column":" NULL"}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 34);
/* ---- Client form (id 35) – JSON format ---- */
INSERT INTO forms
        (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT  35,
        'Client',
        'Client details',
        'clients',
        '[
          {"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1,"validation":"{\"unique\":{\"table\":\"clients\",\"column\":\"name\"}}"},
          {"label":"Phone","field_name":"phone","data_column":"phone","type_id":1,"order_index":2},
          {"label":"Email","field_name":"email","data_column":"email","type_id":1,"order_index":3},
          {"label":"Address","field_name":"address","data_column":"address","type_id":1,"order_index":4},
          {"label":"City","field_name":"city","data_column":"city","type_id":1,"order_index":5},
          {"label":"Country","field_name":"country","data_column":"country","type_id":1,"order_index":6},
          {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":7},
          {"label":"Comments","field_name":"comments","data_column":"comments","type_id":8,"order_index":8}
         ]',
        NULL,   -- tenant_id
        NULL    -- branch_id
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 35);

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 36, 'Case', 'Case record', 'cases', '[
  {"label":"Client","field_name":"client_id","data_column":"client_id","type_id":4,"options_table":"clients","options_label_column":"name","options_value_column":"client_id","order_index":1},
  {"label":"Case Number","field_name":"case_number","data_column":"case_number","type_id":1,"order_index":2},
  {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":3},
  {"label":"Status","field_name":"status","data_column":"status_id","type_id":4,"order_index":4,"options":[{"display_text":"open","value":"open"},{"display_text":"closed","value":"closed"},{"display_text":"pending","value":"pending"}]},
  {"label":"Assigned Representative","field_name":"lead_rep_id","data_column":"lead_rep_id","type_id":4,"options_table":"users","options_label_column":"full_name","options_value_column":"user_id","order_index":7,"validation":"{\"filter_columns\":{\"groups.name\":[\"lawyer\",\"lawyers\"]}}"},
  {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":8},
  {"label":"Initial Instructions","field_name":"initial_instructions","data_column":"initial_instructions","type_id":8,"order_index":9}
 ]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 36);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 37, 'Lawyer', 'Lawyer user', 'users', 
'[{"label":"Full Name","field_name":"full_name","data_column":"full_name","type_id":1,"order_index":1},
{"label":"Emails","field_name":"emails","data_column":"emails","type_id":16,"order_index":2},
{"label":"Phones","field_name":"phones","data_column":"phones","type_id":16,"order_index":3},
{"label":"Password","field_name":"password","data_column":"NULL","type_id":0,"order_index":4}]', 
NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 37);

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 38, 'Time Entries', 'Record hours worked on a case', 'time_entries',
'[{"label":"Case","field_name":"case_id","data_column":"reference_id","type_id":4,"options_table":"cases","options_label_column":"title","options_value_column":"case_id","order_index":1},
  {"label":"Date","field_name":"date","data_column":"date","default":"now()","type_id":3,"order_index":2},
  {"label":"Hours","field_name":"hours","data_column":"hours","type_id":2,"order_index":3},
  {"label":"Billable","field_name":"billable","data_column":"billable","type_id":5,"order_index":4},
  {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":6},
  {"label":"Work Type","field_name":"work_type","data_column":"work_type_id","type_id":13,"options_table":"work_types","options_label_column":"name","options_value_column":"work_type_id","order_index":7},
  {"label":"Instructions","field_name":"instructions","data_column":"instructions","type_id":8,"order_index":9},
  {"label":"Documents","field_name":"documents","data_column":"document_ids","type_id":9,"order_index":10,"options":{"linkTable":"case_hour_documents","linkField":"document_id"}},
  {"field_name":"reference_table","data_column":"reference_table","type_id":17,"default_value":"cases","order_index":11}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 38);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 39, 'Tenant', 'Tenant details', 'tenants', '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},{"label":"Subdomain","field_name":"subdomain","data_column":"subdomain","type_id":1,"order_index":2},{"label":"Custom Domain","field_name":"custom_domain","data_column":"custom_domain","type_id":1,"order_index":3},{"label":"Settings","field_name":"settings","data_column":"settings","type_id":7,"order_index":4},{"label":"Product Name","field_name":"product_name","data_column":"product_name","type_id":1,"order_index":5},{"label":"Dashboard Name","field_name":"dashboard_name","data_column":"dashboard_name","type_id":1,"order_index":6},{"label":"Logo Url","field_name":"logo_url","data_column":"logo_url","type_id":1,"order_index":7}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 39);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 40, 'Admin', 'Admin user', 'users', '[{"label":"Full Name","field_name":"full_name","data_column":"full_name","type_id":1,"order_index":1},{"label":"Email","field_name":"emails","data_column":"emails","type_id":16,"order_index":2},{"label":"Phones","field_name":"phones","data_column":"phones","type_id":16,"order_index":3},{"label":"Password","field_name":"password","data_column":"password","type_id":1,"order_index":4},{"label":"Tenant Id","field_name":"tenant_id","data_column":"tenant_id","type_id":4,"options_table":"tenants","options_label_column":"name","options_value_column":"id","order_index":5}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 40);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 41, 'User', 'User account details', 'users', '[]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 41);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 42, 'Vehicle Downtime', 'Record vehicle downtime periods', 'vehicle_downtime', '[]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 42);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 44, 'Invoice Settings', 'Configure invoice defaults', 'invoice_settings', '[{"label":"Template Id","field_name":"template_id","data_column":"template_id","type_id":0,"order_index":1,"options_table":"invoice_templates","options_label_column":"name","options_value_column":"id"},{"label":"Case Template Id","field_name":"case_template_id","data_column":"case_template_id","type_id":0,"order_index":2,"options_table":"invoice_templates","options_label_column":"name","options_value_column":"id"},{"label":"Logo Document Id","field_name":"logo_document_id","data_column":"logo_document_id","type_id":0,"order_index":3},{"label":"Instructions","field_name":"instructions","data_column":"instructions","type_id":0,"order_index":4},{"label":"Disclaimer","field_name":"disclaimer","data_column":"disclaimer","type_id":0,"order_index":5},{"label":"Bank Details","field_name":"bank_details","data_column":"bank_details","type_id":0,"order_index":6},{"label":"Number Format","field_name":"number_format","data_column":"number_format","type_id":0,"order_index":7},{"label":"Starting Number","field_name":"starting_number","data_column":"starting_number","type_id":0,"order_index":8},{"label":"Rollover Date","field_name":"rollover_date","data_column":"rollover_date","type_id":0,"order_index":9}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 44);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 45, 'Driver', 'Driver user', 'users', '[{"label":"Full Name","field_name":"full_name","data_column":"full_name","type_id":1,"order_index":1},{"label":"Email","field_name":"email","data_column":"NULL","type_id":0,"order_index":2},{"label":"Phone","field_name":"phone","data_column":"NULL","type_id":1,"order_index":3},{"label":"Password","field_name":"password","data_column":"NULL","type_id":0,"order_index":4}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 45);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 46, 'Fleet Engineer', 'Fleet engineer user', 'users', '[{"label":"Full Name","field_name":"full_name","data_column":"full_name","type_id":1,"order_index":1},{"label":"Email","field_name":"email","data_column":"NULL","type_id":0,"order_index":2},{"label":"Phone","field_name":"phone","data_column":"NULL","type_id":1,"order_index":3},{"label":"Password","field_name":"password","data_column":"NULL","type_id":0,"order_index":4}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 46);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 47, 'Case Instruction', 'Matter instruction', 'case_instructions', '[{"label":"Case Id","field_name":"case_id","data_column":"case_id","type_id":0,"order_index":1},{"label":"Instruction Date","field_name":"instruction_date","data_column":"instruction_date","type_id":3,"order_index":2},{"label":"Instruction","field_name":"instruction","data_column":"instruction","type_id":0,"order_index":3},{"label":"Documents","field_name":"document_ids","data_column":"document_ids","type_id":9,"order_index":4}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 47);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
  SELECT 48, 'Case Expense', 'Case related expense', 'expenses', 
  '[{"label":"Case","field_name":"case_id","data_column":"reference_id","type_id":4,"options_table":"cases","options_label_column":"title","options_value_column":"case_id","order_index":1},
    {"label":"Expense Date","field_name":"date","default":"now()","data_column":"date","type_id":3,"order_index":2},
    {"label":"Vendor","field_name":"vendor","data_column":"vendor_id","type_id":13,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id","order_index":3},
    {"label":"Invoice Number","field_name":"invoice_number","data_column":"invoice_number","type_id":1,"order_index":4},
    {"label":"Amount","field_name":"amount","data_column":"amount","type_id":2,"order_index":6},
    {"label":"Billable","field_name":"billable","data_column":"billable","type_id":5,"order_index":7},
    {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":10},
    {"label":"Documents","field_name":"document_ids","data_column":"document_ids","type_id":9,"order_index":14},
    {"field_name":"reference_table","data_column":"reference_table","type_id":17,"default_value":"cases","order_index":15}]',
  NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 48);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
  SELECT 58, 'One Time Cost', 'One time service cost for a case', 'one_time_service_costs', 
  '[{"label":"Case","field_name":"case_id","data_column":"reference_id","type_id":4,"options_table":"cases","options_label_column":"title","options_value_column":"case_id","order_index":1},
    {"label":"Cost Date","field_name":"date","default":"now()","data_column":"date","type_id":3,"order_index":2},
    {"label":"Vendor","field_name":"vendor","data_column":"vendor_id","type_id":13,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id","order_index":3},
    {"label":"Invoice Number","field_name":"invoice_number","data_column":"invoice_number","type_id":1,"order_index":4},
    {"label":"Amount","field_name":"amount","data_column":"amount","type_id":2,"order_index":6},
    {"label":"Billable","field_name":"billable","data_column":"billable","type_id":5,"order_index":7},
    {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":10},
    {"label":"Documents","field_name":"document_ids","data_column":"document_ids","type_id":9,"order_index":14},
    {"field_name":"reference_table","data_column":"reference_table","type_id":17,"default_value":"cases","order_index":15}]',
  NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 58);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 49, 'Case Invoice', 'Invoice for a case', 'invoices', '[{"label":"Reference Id","field_name":"invoice_id","data_column":"invoice_id","type_id":0,"order_index":1},{"label":"Invoice Number","field_name":"invoice_number","data_column":"invoice_number","type_id":0,"order_index":2},{"label":"Invoice Date","field_name":"invoice_date","data_column":"invoice_date","type_id":3,"order_index":3},{"label":"Amount","field_name":"amount","data_column":"amount","type_id":0,"order_index":4},{"label":"Status","field_name":"status","data_column":"status_id","type_id":0,"order_index":5},{"label":"Invoice Template Id","field_name":"invoice_template_id","data_column":"invoice_template_id","type_id":0,"order_index":6,"options_table":"invoice_templates","options_label_column":"name","options_value_column":"id"}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 49);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 50, 'Case Payment', 'Payment for a case invoice', 'payments', '[{"label": "Client", "field_name": "client_id", "data_column": "client_id", "type_id":4, "order_index":1, "options_table": "clients", "options_label_column": "name", "options_value_column": "client_id"}, {"label": "Invoice Id", "field_name": "invoice_id", "data_column": "invoice_id", "type_id":4, "order_index":2, "options_table": "invoices", "options_label_column": "invoice_number", "options_value_column": "id"}, {"label": "Payment Date", "field_name": "payment_date", "data_column": "payment_date", "type_id":3, "order_index":3}, {"label": "Payment Amount", "field_name": "payment_amount", "data_column": "payment_amount", "type_id":2, "order_index":4}, {"label": "Payment Method", "field_name": "payment_method", "data_column": "payment_method", "type_id":4, "order_index":5, "options": [{"display_text": "credit card", "value": "credit_card"}, {"display_text": "bank transfer", "value": "bank_transfer"}, {"display_text": "cash", "value": "cash"}, {"display_text": "check", "value": "check"}]}, {"label": "Reference Id", "field_name": "reference_id", "data_column": "reference_id", "type_id":1, "order_index":6}, {"label": "Reference Table", "field_name": "reference_table", "data_column": "reference_table", "type_id":1, "order_index":7, "default_value": "cases"}, {"label": "Notes", "field_name": "notes", "data_column": "notes", "type_id":8, "order_index":8}, {"label": "Status", "field_name": "status", "data_column": "status", "type_id":4, "order_index":9, "options": [{"display_text": "completed", "value": "completed"}, {"display_text": "pending", "value": "pending"}, {"display_text": "failed", "value": "failed"}]}, {"label": "Screenshots", "field_name": "screenshot_ids", "data_column": "screenshot_ids", "type_id":7, "order_index":10}, {"label": "Documents", "field_name": "document_ids", "data_column": "document_ids", "type_id":9, "order_index":11}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 50);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 51, 'Case Approval', 'Approve or reject case', NULL, '[{"label":"Case Id","field_name":"case_id","data_column":"case_id","type_id":0,"order_index":1},{"label":"Comments","field_name":"comments","data_column":"comments","type_id":0,"order_index":2}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 51);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 52, 'OHS Action', 'Action taken for an incident', 'ohs_actions', '[{"label":"Description","field_name":"description","data_column":"description","type_id":0,"order_index":1},{"label":"Responsible User Id","field_name":"responsible_user_id","data_column":"responsible_user_id","type_id":0,"order_index":2},{"label":"Target Date","field_name":"target_date","data_column":"target_date","type_id":0,"order_index":3},{"label":"Status","field_name":"status","data_column":"status_id","type_id":0,"order_index":4},{"label":"Completed At","field_name":"completed_at","data_column":"completed_at","type_id":0,"order_index":5}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 52);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 53, 'OHS Regulation', 'Record safety regulations', 'ohs_regulations', '[{"label":"Title","field_name":"title","data_column":"title","type_id":0,"order_index":1},{"label":"Description","field_name":"description","data_column":"description","type_id":0,"order_index":2},{"label":"Effective Date","field_name":"effective_date","data_column":"effective_date","type_id":0,"order_index":3}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 53);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 54, 'OHS Compliance Task', 'Task to meet a regulation', 'ohs_compliance_tasks', '[{"label":"Regulation Id","field_name":"regulation_id","data_column":"regulation_id","type_id":0,"order_index":1,"options_table":"ohs_regulations","options_label_column":"title","options_value_column":"id"},{"label":"Title","field_name":"title","data_column":"title","type_id":0,"order_index":2},{"label":"Due Date","field_name":"due_date","data_column":"due_date","type_id":0,"order_index":3},{"label":"Assigned To","field_name":"assigned_to","data_column":"assigned_to","type_id":0,"order_index":4},{"label":"Status","field_name":"status","data_column":"status_id","type_id":0,"order_index":5}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 54);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 55, 'Permit Inspection', 'Record permit inspections', 'permit_inspections', '[]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 55);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 56, 'Hazard Type', 'Manage hazard classifications', 'ohs_hazard_types', '[]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 56);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 57, 'Incident Type', 'Manage incident categories', 'ohs_incident_types',
'[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
  {"label":"Form Id","field_name":"form_id","data_column":"form_id","type_id":4,"options_table":"forms","options_label_column":"name","options_value_column":"id","order_index":2}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 57);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 58, 'OHS Assignment Rule', 'Investigator assignment rule', 'ohs_assignment_rules', '[]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 58);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 84, 'Inspection Assignment Rule', 'Inspector assignment rule', 'inspection_assignment_rules', '[]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 84);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 101, 'WorkCOM Inspection Assignment Rule', 'Inspector assignment rule', 'inspection_assignment_rules', '[{"label":"District","field_name":"district_id","data_column":"district_id","type_id":4,"options_table":"districts","options_label_column":"name","options_value_column":"id","order_index":1},
  {"label":"Assign","field_name":"inspector_id","data_column":"inspector_id","type_id":4,"options_table":"users","options_label_column":"full_name","options_value_column":"id","validation":"{\"filter_columns\":{\"groups.name\":[\"Investigators\"]}}","order_index":2},
  {"label":"Email","field_name":"email","data_column":"email","type_id":1,"order_index":3},
  {"label":"Send Email","field_name":"send_email","data_column":"send_email","type_id":5,"order_index":4},
  {"label":"Phone","field_name":"phone","data_column":"phone","type_id":1,"order_index":5},
  {"label":"Send SMS","field_name":"send_sms","data_column":"send_sms","type_id":5,"order_index":6},
  {"label":"Send Push","field_name":"send_push","data_column":"send_push","type_id":5,"order_index":7}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 101);
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  59,
  'OHS Incident Classification',
  'Select incident type and location',
  'ohs_incidents',
  '[
    {
      "label":"Classification",
      "field_name":"classification",
      "data_column":"classification",
      "type_id":4,
      "order_index":1,
      "options_table":"ohs_incident_types",
      "options_label_column":"name",
      "options_value_column":"name"
    },
    {
      "label":"Location",
      "field_name":"location",
      "data_column":"location",
      "type_id":4,
      "order_index":2,
      "options_table":"locations",
      "options_label_column":"name",
      "options_value_column":"name",
      "options":[{"display_text":"Other","value":"Other"}]
    },
    {
      "label":"Address",
      "field_name":"address",
      "data_column":"address",
      "type_id":7,
      "order_index":3,
      "show_when":{"field":"location","value":"Other"}
    },
    {
      "label":"Severity",
      "field_name":"severity",
      "data_column":"severity",
      "type_id":4,
      "order_index":4,
      "options_table":"ohs_severities",
      "options_label_column":"name",
      "options_value_column":"name"
    }
  ]',
  NULL,
  NULL
)
ON CONFLICT (id) DO NOTHING;

-- Button to open appropriate OHS incident form based on classification
DELETE FROM form_buttons WHERE form_id = 59 AND label = 'Open Form';
INSERT INTO form_buttons (form_id, label, action_type, action_payload, order_index)
VALUES
  (59, 'Open Form', 'open-form',
   '{"lookupTable":"ohs_incident_types","lookupField":"classification","valueColumn":"name","formColumn":"form_id"}',
   1
 );

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 66, 'Issues Log', 'Record safety issues', 'ohs_issues', '[{"label":"Description","field_name":"description","data_column":"description","type_id":0,"order_index":1},{"label":"Type","field_name":"type","data_column":"type","type_id":0,"order_index":2},{"label":"Category","field_name":"category","data_column":"category","type_id":0,"order_index":3},{"label":"Impact","field_name":"impact","data_column":"impact","type_id":0,"order_index":4},{"label":"Risk Or Opportunity","field_name":"risk_or_opportunity","data_column":"risk_or_opportunity","type_id":0,"order_index":5},{"label":"Action Taken","field_name":"action_taken","data_column":"action_taken","type_id":0,"order_index":6},{"label":"Owner","field_name":"owner","data_column":"owner","type_id":0,"order_index":7},{"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":0,"order_index":8}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 66);

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  67,
  'Needs & Expectations Assessment',
  'Stakeholder needs and expectations',
  'ohs_needs_expectations',
  '[
    {"label":"Interested Party","field_name":"interested_party","data_column":"interested_party","type_id":0,"order_index":1},
    {"label":"Needs","field_name":"needs","data_column":"needs","type_id":0,"order_index":2},
    {"label":"Expectations","field_name":"expectations","data_column":"expectations","type_id":0,"order_index":3},
    {"label":"Compliance Required","field_name":"compliance_required","data_column":"compliance_required","type_id":0,"order_index":4},
    {"label":"Source","field_name":"source","data_column":"source","type_id":0,"order_index":5},
    {"label":"Status","field_name":"status_id","data_column":"status_id","type_id":0,"order_index":6},
    {"label":"Notes","field_name":"notes","data_column":"notes","type_id":0,"order_index":7},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":0,"order_index":8},
    {"label":"Review By","field_name":"review_by","data_column":"review_by","type_id":0,"order_index":9}
  ]',
  NULL,
  NULL
)
ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 68, 'Inspection Type', 'Manage inspection categories', 'ohs_inspection_types',
'[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
  {"label":"Form Id","field_name":"form_id","data_column":"form_id","type_id":4,"options_table":"forms","options_label_column":"name","options_value_column":"id","order_index":2}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 68);

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 104, 'WorkCOM Inspection Type', 'Manage WorkCOM inspection categories', 'workcom_inspection_types',
 '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
  {"label":"Form Id","field_name":"form_id","data_column":"form_id","type_id":4,"options_table":"forms","options_label_column":"name","options_value_column":"id","order_index":2}]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 104);

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 105, 'OHS Field Incident', 'Report field incidents', 'ohs_incidents', '[
  {"label":"Incident Type","field_name":"incident_type","json_column":"form_data","type_id":1,"order_index":1},
  {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":2},
  {"label":"Description","field_name":"description","json_column":"form_data","type_id":8,"order_index":3},
  {"label":"Documents","field_name":"document_ids","json_column":"form_data","type_id":9,"order_index":4},
  {"label":"GPS","field_name":"gps","json_column":"form_data","type_id":20,"order_index":5}
]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 105);



INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  71,
  'Form Category',
  'Manage form categories',
  'form_categories',
  $json$
  [
    {"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
    {"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":2}
  ]$json$::jsonb,
  NULL,
  NULL
)
ON CONFLICT (id) DO NOTHING;
-- Training Certificate form

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 72, 'Training Certificate', 'Employee training record', 'training_certificates',
'[
  {"label":"Certificate Name","field_name":"certificate_name","data_column":"certificate_name","type_id":1,"options_table":"training_courses","options_label_column":"name","options_value_column":"id","order_index":1},
  {"label":"Category","field_name":"category","data_column":"category","type_id":1,"options_table":"training_categories","options_label_column":"name","options_value_column":"id","order_index":2},
  {"label":"Employee Id","field_name":"employee_id","data_column":"certificate_user_id","type_id":4,"options_table":"users","options_label_column":"full_name","options_value_column":"id","order_index":3},
  {"label":"Issued At","field_name":"issued_at","data_column":"issued_at","type_id":3,"order_index":4},
  {"label":"Expiry Date","field_name":"expiry_date","data_column":"expiry_date","type_id":3,"order_index":5}
]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 72);

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  73,
  'Investigator',
  'Investigator user',
  'users',
  $json$
  [
    {"label":"Full Name","field_name":"full_name","data_column":"full_name","type_id":1,"order_index":1},
    {"label":"Emails","field_name":"emails","data_column":"emails","type_id":15,"order_index":2},
    {"label":"Phones","field_name":"phones","data_column":"phones","type_id":15,"order_index":3},
    {"label":"Password","field_name":"password","data_column":null,"type_id":0,"order_index":4}
  ]
  $json$::jsonb,
  NULL,
  NULL
)
ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  74,
  'Inspection Template',
  'Define reusable inspection templates',
  'ohs_inspection_templates',
  $json$
  [
    {"label":"Template Name","field_name":"template_name","data_column":"template_name","type_id":1,"order_index":1},
    {"label":"Form Id","field_name":"form_id","data_column":"form_id","type_id":4,"options_table":"forms","options_label_column":"name","options_value_column":"id","order_index":2},
    {"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":3}
  ]
  $json$::jsonb,
  NULL,
  NULL
)
ON CONFLICT (id) DO NOTHING;


INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  97,
  'Safety Incident',
  'Record safety incidents',
  'safety_incidents',
  $json$
    [
    {"label":"Incident Type","field_name":"incident_type","data_column":"incident_type","type_id":4,"options_table":"safety_incident_types","options_label_column":"name","options_value_column":"id","order_index":1},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":2},
    {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":3},
    {"label":"Documents","field_name":"document_ids","data_column":"document_ids","type_id":9,"order_index":4},
    {"label":"GPS","field_name":"gps","data_column":"gps","type_id":20,"order_index":5}
  ]
  $json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  107,
  'Safety Incident Classification',
  'Select incident type and location',
  'safety_incidents',
  '[{"label":"Incident Type","field_name":"incident_type","data_column":"incident_type","type_id":4,"options_table":"safety_incident_types","options_label_column":"name","options_value_column":"id","order_index":1},{"label":"Location","field_name":"location","data_column":"location","type_id":4,"options_table":"locations","options_label_column":"name","options_value_column":"name","order_index":2}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO form_buttons (form_id,label,action_type,action_payload,order_index)
VALUES (
  107,'Open Form','open-form',
  '{"lookupTable":"safety_incident_types","lookupField":"incident_type","valueColumn":"id","formColumn":"form_id","prefillFields":["incident_type","location"]}',
  1
) ON CONFLICT DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 108, 'Safety Field Incident', 'Report field incidents', 'safety_incidents', '[
  {"label":"Incident Type","field_name":"incident_type","data_column":"incident_type","type_id":4,"options_table":"safety_incident_types","options_label_column":"name","options_value_column":"id","order_index":1},
  {"label":"Location","field_name":"location","data_column":"location","type_id":4,"options_table":"locations","options_label_column":"name","options_value_column":"name","order_index":2},
  {"label":"Description","field_name":"description","json_column":"form_data","type_id":8,"order_index":3},
  {"label":"Documents","field_name":"document_ids","json_column":"form_data","type_id":9,"order_index":4},
  {"label":"GPS","field_name":"gps","json_column":"form_data","type_id":20,"order_index":5}
]', NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 108);

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  98,
  'Incident Alert Rule',
  'Alert configuration per incident type',
  'incident_alert_rules',
  $json$
  [
    {"label":"Incident Type","field_name":"incident_type_id","data_column":"incident_type_id","type_id":4,"options_table":"ohs_incident_types","options_label_column":"name","options_value_column":"id","order_index":1},
    {"label":"Severity","field_name":"severity","data_column":"severity","type_id":4,"order_index":2,"options":[{"display_text":"Minor","value":"Minor"},{"display_text":"Moderate","value":"Moderate"},{"display_text":"Major","value":"Major"},{"display_text":"Severe","value":"Severe"},{"display_text":"Critical","value":"Critical"}]},
    {"label":"Location","field_name":"location_id","data_column":"location_id","type_id":4,"options_table":"locations","options_label_column":"name","options_value_column":"id","options":[{"display_text":"All Locations","value":""}],"order_index":3},
    {"label":"Send Alert To","field_name":"send_alert_to","data_column":"send_alert_to","type_id":4,"options_table":"users","options_label_column":"full_name","options_value_column":"id","order_index":4},
    {"label":"Email","field_name":"email","data_column":"email","type_id":1,"order_index":5},
    {"label":"Send Email","field_name":"send_email","data_column":"send_email","type_id":5,"order_index":6},
    {"label":"Phone","field_name":"phone","data_column":"phone","type_id":1,"order_index":7},
    {"label":"Send SMS","field_name":"send_sms","data_column":"send_sms","type_id":5,"order_index":8},
    {"label":"Send Push","field_name":"send_push","data_column":"send_push","type_id":5,"order_index":9}
  ]
  $json$::jsonb,
  NULL,
  NULL
)
ON CONFLICT (id) DO NOTHING;


-- Workflow to send notifications based on incident alert rules
INSERT INTO workflows (name, trigger_event, definition, is_active)
VALUES (
  'Incident Alert Notifications',
  'ohs.incidentCreated',
  '{"conditions": []}',
  TRUE
);

INSERT INTO workflow_steps (workflow_id, step_order, step_type, config) VALUES
  ((SELECT id FROM workflows WHERE name='Incident Alert Notifications' LIMIT 1),1,'load_record','{"table":"ohs_incidents","id_key":"record_id","context_key":"incident"}'),
  ((SELECT id FROM workflows WHERE name='Incident Alert Notifications' LIMIT 1),2,'query_records','{"table":"incident_alert_rules","where":{"incident_type_id":"{classification}","severity":"{severity}","location_id":"{location_id}"},"context_key":"recipients"}'),
  ((SELECT id FROM workflows WHERE name='Incident Alert Notifications' LIMIT 1),3,'for_each_record','{"list_key":"recipients","steps":[{"type":"condition","field":"send_email","operator":"==","value":true},{"type":"email","to":"{email}","message":"Incident {record_id} reported"},{"type":"condition","field":"send_sms","operator":"==","value":true},{"type":"sms","to":"{phone}","message":"Incident {record_id} reported"},{"type":"condition","field":"send_push","operator":"==","value":true},{"type":"alert","user_id":"{send_alert_to}","title":"New Incident","body":"Incident {record_id} reported"}]}');


-- Forms and UI for Risk Assessments



-- Risk Assessment form - administrative details
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  75,
  'Risk Assessment',
  'Record assessment administrative info',
  'risk_assessments',
  '[{"label":"Type","field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":4,"options_table":"risk_assessment_types","options_label_column":"name","options_value_column":"id","order_index":1},
    {"label":"Location","field_name":"location","data_column":"location","type_id":4,"options_table":"locations","options_label_column":"name","options_value_column":"name","order_index":2}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO form_buttons (form_id, label, action_type, action_payload, order_index)
VALUES (
  75,
  'Open Form',
  'open-form',
  '{"lookupTable":"risk_assessment_types","lookupField":"risk_assessment_type_id","valueColumn":"id","formColumn":"form_id","prefillFields":["risk_assessment_type_id","location"]}',
  1
) ON CONFLICT DO NOTHING;

-- Risk Assessment Hazard form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  76,
  'Risk Assessment Hazard',
  'Identify hazards and controls',
  'risk_assessment_hazards',
  '[{"label":"Hazard Description","field_name":"hazard_description","data_column":"hazard_description","type_id":7,"order_index":1},
    {"label":"Who Might Be Harmed","field_name":"who_might_be_harmed","data_column":"who_might_be_harmed","type_id":1,"order_index":2},
    {"label":"Existing Controls","field_name":"existing_control_measures","data_column":"existing_control_measures","type_id":7,"order_index":3},
    {"label":"Risk Rating Before","field_name":"risk_rating_before","data_column":"risk_rating_before","type_id":2,"order_index":4},
    {"label":"Additional Controls","field_name":"additional_controls","data_column":"additional_controls","type_id":7,"order_index":5},
    {"label":"Residual Risk","field_name":"residual_risk_rating","data_column":"residual_risk_rating","type_id":2,"order_index":6},
    {"label":"Responsible Person","field_name":"responsible_person","data_column":"responsible_person","type_id":1,"order_index":7}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Risk Assessment PPE form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  77,
  'Risk Assessment PPE',
  'Personal protective equipment checklist',
  'risk_assessment_ppe',
  '[{"label":"Checklist Item","field_name":"checklist_item","data_column":"checklist_item","type_id":1,"order_index":1}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Risk Assessment Sign-off form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  78,
  'Risk Assessment Sign-off',
  'Record assessment approvals',
  'risk_assessment_signoffs',
  '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
    {"label":"Position","field_name":"position","data_column":"position","type_id":1,"order_index":2},
    {"label":"Signature","field_name":"signature","data_column":"signature","type_id":7,"order_index":3},
    {"label":"Signed At","field_name":"signed_at","data_column":"signed_at","type_id":3,"order_index":4}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Wizard configuration for risk assessments
INSERT INTO form_wizards (id, name, description, tenant_id, branch_id)
VALUES (4, 'Risk Assessment Wizard', 'Guided risk assessment entry', NULL, NULL)
ON CONFLICT DO NOTHING;

INSERT INTO form_wizard_steps (wizard_id, step_number, form_id, condition_field, condition_value)
VALUES
  (4, 1, 75, NULL, NULL)
ON CONFLICT DO NOTHING;


-- Risk Identification form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  80,
  'Risk Identification',
  'Identify risks',
  'risk_identifications',
  $json$
  [
    {"label":"Risk Description","field_name":"risk_description","data_column":"risk_description","type_id":7,"order_index":1},
    {"label":"Risk category","field_name":"risk_category_id","data_column":"risk_category_id","type_id":4,"options_table":"risk_categories","options_label_column":"name","options_value_column":"id","order_index":2},
    {"label":"Root Cause","field_name":"root_cause","data_column":"root_cause","type_id":1,"order_index":3},
    {"label":"Likelihood","field_name":"likelihood","data_column":"likelihood","type_id":4,"order_index":4,"options":[{"display_text":"1","value":"1"},{"display_text":"2","value":"2"},{"display_text":"3","value":"3"},{"display_text":"4","value":"4"},{"display_text":"5","value":"5"}]},
    {"label":"Impact","field_name":"impact","data_column":"impact","type_id":4,"order_index":5,"options":[{"display_text":"1","value":"1"},{"display_text":"2","value":"2"},{"display_text":"3","value":"3"},{"display_text":"4","value":"4"},{"display_text":"5","value":"5"}]},
    {"label":"Current Controls","field_name":"current_controls","data_column":"current_controls","type_id":7,"order_index":6}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO table_views (form_id, name, columns, sort_by, sort_dir)
VALUES (
  80,
  'Default',
  '["risk_description","risk_category_id","risk_category_name","likelihood","impact",{"field":"risk_rating","formula":"impact * likelihood"}]',
  'risk_description',
  'ASC'
);

/* ---- Risk Category (id 74) – JSON format ---- */
INSERT INTO forms
        (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT  79,
        'Risk Category',
        'Risk classification',
        'risk_categories',
        '[
          {"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
          {"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":2}
         ]',
        NULL,   -- tenant_id
        NULL    -- branch_id
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 79);

-- Form 624: Quick Time Clock Entry
-- Simplified form for quick clock in/out entries with hidden pre-filled fields
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id) VALUES (
  624,
  'Time Clock Entry',
  'Quick clock in/out entry for employees',
  'time_clocks',
  $json$[
    {
      "id": 1,
      "name": "user_id",
      "label": "Employee",
      "type": 16,
      "data_column": "user_id",
      "required": true,
      "order": 1,
      "hidden": true
    },
    {
      "id": 2,
      "name": "clock_type",
      "label": "Clock Type",
      "type": 16,
      "data_column": "clock_type",
      "required": true,
      "order": 2,
      "hidden": true
    },
    {
      "id": 3,
      "name": "clocked_at",
      "label": "Date & Time",
      "type": 10,
      "data_column": "clocked_at",
      "required": true,
      "order": 3
    }
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO UPDATE SET
  name = EXCLUDED.name,
  description = EXCLUDED.description,
  mapped_table = EXCLUDED.mapped_table,
  elements = EXCLUDED.elements;



INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  81
  ,
  'Calendar Category',
  'Manage calendar categories',
  'calendar_categories',
  $json$
  [
    {"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
    {"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":2}
  ]
  $json$::jsonb,
  NULL,
  NULL
)
ON CONFLICT (id) DO NOTHING;


-- Incident Status form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 82, 'Incident Status', 'Manage incident status options', 'ohs_incident_statuses',
       '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
         {"label":"Purpose","field_name":"purpose","data_column":"purpose","type_id":7,"order_index":2}]',
       NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 82);


-- Five Whys form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 83, 'Five Whys', 'Record Five Whys analysis', 'ohs_five_whys',
       $json$
       [
         {"label":"Incident","field_name":"incident_id","data_column":"incident_id","type_id":4,"order_index":1,"options_table":"ohs_incidents","options_label_column":"id","options_value_column":"id"},
         {"label":"Why 1","field_name":"why1","json_column":"whys","type_id":1,"order_index":2},
         {"label":"Why 2","field_name":"why2","json_column":"whys","type_id":1,"order_index":3},
         {"label":"Why 3","field_name":"why3","json_column":"whys","type_id":1,"order_index":4},
         {"label":"Why 4","field_name":"why4","json_column":"whys","type_id":1,"order_index":5},
         {"label":"Why 5","field_name":"why5","json_column":"whys","type_id":1,"order_index":6}
       ]
       $json$::jsonb,
       NULL,
       NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 83);


SELECT setval('calendar_events_id_seq', (SELECT MAX(id) FROM calendar_events));



-- Corrective Action form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 83, 'Corrective Action', 'Track corrective actions for incidents', 'corrective_actions',
       '[{"label":"Incident","field_name":"incident_id","data_column":"incident_id","type_id":4,"order_index":1,"options_table":"ohs_incidents","options_label_column":"short_desc","options_value_column":"id"},
         {"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":2},
         {"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":3},
         {"label":"Steps","field_name":"steps","data_column":"steps","type_id":7,"order_index":4},
         {"label":"Responsible Person","field_name":"responsible_user_id","data_column":"responsible_user_id","type_id":4,"order_index":5,"options_table":"users","options_label_column":"full_name","options_value_column":"id"},
         {"label":"Status","field_name":"status","data_column":"status","type_id":1,"order_index":6}]',
       NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 83);



-- Risk Assessment Type form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  84,
  'Risk Assessment Type',
  'Manage risk assessment classifications',
  'risk_assessment_types',
  '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
    {"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":2},
    {"label":"Form","field_name":"form_id","data_column":"form_id","type_id":4,"options_table":"forms","options_label_column":"name","options_value_column":"id","order_index":3}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Additional risk assessment forms
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  85,
  'Water Treatment Plant Risk Assessment',
  'Assessment of operational and chemical risks in treatment facilities',
  'risk_assessments',
  '[{"field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":1,"order_index":0},
    {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Assessment Date","field_name":"assessment_date","data_column":"assessment_date","type_id":3,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Assessor Names","field_name":"assessor_names","json_column":"form_data","type_id":1,"order_index":4},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":5},
    {"label":"Approver","field_name":"approver_name","json_column":"form_data","type_id":1,"order_index":6},
    {"label":"Work Description","field_name":"work_description","json_column":"form_data","type_id":7,"order_index":7},
    {"label":"Permit Requirements","field_name":"permit_requirements","json_column":"form_data","type_id":7,"order_index":8},
    {"label":"Chemical Used","field_name":"chemical","json_column":"form_data","type_id":1,"order_index":9},
    {"label":"Hazard Identified","field_name":"hazard","json_column":"form_data","type_id":7,"order_index":10},
    {"label":"Risk Rating","field_name":"risk_rating","json_column":"form_data","type_id":2,"order_index":11},
    {"label":"Control Measures","field_name":"controls","json_column":"form_data","type_id":7,"order_index":12}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  86,
  'Pipeline & Infrastructure Risk Assessment',
  'Evaluation of potential failure points across distribution infrastructure',
  'risk_assessments',
  '[{"field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":1,"order_index":0},
    {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Assessment Date","field_name":"assessment_date","data_column":"assessment_date","type_id":3,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Assessor Names","field_name":"assessor_names","json_column":"form_data","type_id":1,"order_index":4},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":5},
    {"label":"Approver","field_name":"approver_name","json_column":"form_data","type_id":1,"order_index":6},
    {"label":"Work Description","field_name":"work_description","json_column":"form_data","type_id":7,"order_index":7},
    {"label":"Permit Requirements","field_name":"permit_requirements","json_column":"form_data","type_id":7,"order_index":8},
    {"label":"Pipe Segment","field_name":"pipe_segment","json_column":"form_data","type_id":1,"order_index":9},
    {"label":"Material Type","field_name":"material","json_column":"form_data","type_id":1,"order_index":10},
    {"label":"Identified Risk","field_name":"risk","json_column":"form_data","type_id":7,"order_index":11},
    {"label":"Failure Likelihood","field_name":"likelihood","json_column":"form_data","type_id":2,"order_index":12},
    {"label":"Mitigation Action","field_name":"action","json_column":"form_data","type_id":7,"order_index":13}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  87,
  'Environmental and Climate Risk Assessment',
  'Assesses environmental vulnerabilities to water supply and treatment',
  'risk_assessments',
  '[{"field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":1,"order_index":0},
    {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Assessment Date","field_name":"assessment_date","data_column":"assessment_date","type_id":3,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Assessor Names","field_name":"assessor_names","json_column":"form_data","type_id":1,"order_index":4},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":5},
    {"label":"Approver","field_name":"approver_name","json_column":"form_data","type_id":1,"order_index":6},
    {"label":"Work Description","field_name":"work_description","json_column":"form_data","type_id":7,"order_index":7},
    {"label":"Permit Requirements","field_name":"permit_requirements","json_column":"form_data","type_id":7,"order_index":8},
    {"label":"Area Assessed","field_name":"area","json_column":"form_data","type_id":1,"order_index":9},
    {"label":"Environmental Risk","field_name":"env_risk","json_column":"form_data","type_id":7,"order_index":10},
    {"label":"Climate Trigger","field_name":"trigger","json_column":"form_data","type_id":1,"order_index":11},
    {"label":"Severity","field_name":"severity","json_column":"form_data","type_id":2,"order_index":12},
    {"label":"Control Plan","field_name":"plan","json_column":"form_data","type_id":7,"order_index":13}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  88,
  'Occupational Health & Safety Risk Assessment',
  'OHS-focused hazard evaluation in operational areas and fieldwork',
  'risk_assessments',
  '[{"field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":1,"order_index":0},
    {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Assessment Date","field_name":"assessment_date","data_column":"assessment_date","type_id":3,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Assessor Names","field_name":"assessor_names","json_column":"form_data","type_id":1,"order_index":4},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":5},
    {"label":"Approver","field_name":"approver_name","json_column":"form_data","type_id":1,"order_index":6},
    {"label":"Work Description","field_name":"work_description","json_column":"form_data","type_id":7,"order_index":7},
    {"label":"Permit Requirements","field_name":"permit_requirements","json_column":"form_data","type_id":7,"order_index":8},
    {"label":"Job Task","field_name":"task","json_column":"form_data","type_id":1,"order_index":9},
    {"label":"Identified Hazard","field_name":"hazard","json_column":"form_data","type_id":7,"order_index":10},
    {"label":"Risk Level","field_name":"risk_level","json_column":"form_data","type_id":2,"order_index":11},
    {"label":"PPE Required","field_name":"ppe","json_column":"form_data","type_id":1,"order_index":12},
    {"label":"First Aid Measures","field_name":"first_aid","json_column":"form_data","type_id":7,"order_index":13}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  89,
  'Cybersecurity & SCADA Risk Assessment',
  'Review of IT security and SCADA operational risk vulnerabilities',
  'risk_assessments',
  '[{"field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":1,"order_index":0},
    {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Assessment Date","field_name":"assessment_date","data_column":"assessment_date","type_id":3,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Assessor Names","field_name":"assessor_names","json_column":"form_data","type_id":1,"order_index":4},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":5},
    {"label":"Approver","field_name":"approver_name","json_column":"form_data","type_id":1,"order_index":6},
    {"label":"Work Description","field_name":"work_description","json_column":"form_data","type_id":7,"order_index":7},
    {"label":"Permit Requirements","field_name":"permit_requirements","json_column":"form_data","type_id":7,"order_index":8},
    {"label":"System/Module","field_name":"system","json_column":"form_data","type_id":1,"order_index":9},
    {"label":"Threat Type","field_name":"threat","json_column":"form_data","type_id":1,"order_index":10},
    {"label":"Vulnerability Description","field_name":"vuln","json_column":"form_data","type_id":7,"order_index":11},
    {"label":"Impact Rating","field_name":"impact","json_column":"form_data","type_id":2,"order_index":12},
    {"label":"Mitigation Strategy","field_name":"strategy","json_column":"form_data","type_id":7,"order_index":13}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  90,
  'Community & Stakeholder Risk Assessment',
  'Analyzes public-facing risks and reputational threats from service issues',
  'risk_assessments',
  '[{"field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":1,"order_index":0},
    {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Assessment Date","field_name":"assessment_date","data_column":"assessment_date","type_id":3,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Assessor Names","field_name":"assessor_names","json_column":"form_data","type_id":1,"order_index":4},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":5},
    {"label":"Approver","field_name":"approver_name","json_column":"form_data","type_id":1,"order_index":6},
    {"label":"Work Description","field_name":"work_description","json_column":"form_data","type_id":7,"order_index":7},
    {"label":"Permit Requirements","field_name":"permit_requirements","json_column":"form_data","type_id":7,"order_index":8},
    {"label":"Community Area","field_name":"community","json_column":"form_data","type_id":1,"order_index":9},
    {"label":"Public Concern","field_name":"concern","json_column":"form_data","type_id":7,"order_index":10},
    {"label":"Likelihood of Escalation","field_name":"escalation","json_column":"form_data","type_id":2,"order_index":11},
    {"label":"Communication Strategy","field_name":"communication","json_column":"form_data","type_id":7,"order_index":12},
    {"label":"Resolution Timeline","field_name":"timeline","json_column":"form_data","type_id":1,"order_index":13}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Default risk assessment types
INSERT INTO risk_assessment_types (id, name, description, form_id, tenant_id, branch_id) VALUES
  (1, 'Water Treatment Plant Risk Assessment', 'Assessment of operational and chemical risks in treatment facilities', 85, NULL, NULL),
  (2, 'Pipeline & Infrastructure Risk Assessment', 'Evaluation of potential failure points across distribution infrastructure', 86, NULL, NULL),
  (3, 'Environmental and Climate Risk Assessment', 'Assesses environmental vulnerabilities to water supply and treatment', 87, NULL, NULL),
  (4, 'Occupational Health & Safety Risk Assessment', 'OHS-focused hazard evaluation in operational areas and fieldwork', 88, NULL, NULL),
  (5, 'Cybersecurity & SCADA Risk Assessment', 'Review of IT security and SCADA operational risk vulnerabilities', 89, NULL, NULL),
  (6, 'Community & Stakeholder Risk Assessment', 'Analyzes public-facing risks and reputational threats from service issues', 90, NULL, NULL)
ON CONFLICT (id) DO NOTHING;


-- Inspection Request form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  99,
  'Inspection Request',
  'Submit request for workplace inspection',
  'inspection_requests',
  $json$
  [
    {"label":"Workplace","field_name":"workplace_id","data_column":"workplace_id","type_id":4,"options_table":"workplace_registrations","options_label_column":"company_name","options_value_column":"id","order_index":1},
    {"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":2},
    {"label":"Preferred Date","field_name":"preferred_date","data_column":"preferred_date","type_id":3,"order_index":3}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- WorkCOM Inspection Assignment form and modal
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  100,
  'WorkCOM Inspection Assignment',
  'Assign inspector to a workplace inspection',
  'workplace_inspections',
  $json$
  [
    {"label":"Inspection Request","field_name":"inspection_request_id","data_column":"inspection_request_id","type_id":4,"options_table":"inspection_requests","options_label_column":"id","options_value_column":"id","order_index":1},
    {"label":"Inspector","field_name":"inspector_id","data_column":"inspector_id","type_id":4,"options_table":"users","options_label_column":"full_name","options_value_column":"id","order_index":2,"validation":"{\"filter_columns\":{\"groups.name\":[\"Investigators\"]}}"}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- WorkCOM Inspection Start form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  103,
  'WorkCOM Inspection Start',
  'Select inspection type and workplace',
  'workcom_inspections',
  '[{"label":"Workplace","field_name":"workplace_id","data_column":"workplace_id","type_id":4,"options_table":"workplace_registrations","options_label_column":"company_name","options_value_column":"id","order_index":1},
    {"label":"Inspection Request","field_name":"inspection_request_id","data_column":"inspection_request_id","type_id":4,"options_table":"inspection_requests","options_label_column":"id","options_value_column":"id","order_index":2},
    {"label":"Inspection Type","field_name":"workcom_inspection_type_id","data_column":"inspection_type_id","type_id":4,"options_table":"workcom_inspection_types","options_label_column":"name","options_value_column":"id","order_index":3}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO form_buttons (form_id,label,action_type,action_payload,order_index)
VALUES (
  103,'Open Form','open-form',
  '{"lookupTable":"workcom_inspection_types","lookupField":"workcom_inspection_type_id","valueColumn":"id","formColumn":"form_id","prefillFields":["workcom_inspection_type_id","workplace_id","inspection_request_id"]}',
  1
) ON CONFLICT DO NOTHING;

-- Workplace Notice form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  104,
  'Workplace Notice',
  'Notice of certain workplaces',
  'invoices',
  $json$
  [
    {"label":"Business Name","field_name":"business_name","data_column":"details","json_column":"business_name","type_id":1,"order_index":1},
    {"label":"Trading Name","field_name":"trading_name","data_column":"details","json_column":"trading_name","type_id":1,"order_index":2},
    {"label":"Workplace Address","field_name":"workplace_address","data_column":"details","json_column":"workplace_address","type_id":7,"order_index":3},
    {"label":"Postal Address","field_name":"postal_address","data_column":"details","json_column":"postal_address","type_id":7,"order_index":4},
    {"label":"Commencement Date","field_name":"commencement_date","data_column":"details","json_column":"commencement_date","type_id":3,"order_index":5},
    {"label":"Invoice Template","field_name":"invoice_template_id","data_column":"invoice_template_id","type_id":4,"options_table":"invoice_templates","options_label_column":"name","options_value_column":"id","order_index":6}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Safety Incident Type form and modal
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  105,
  'Safety Incident Type',
  'Define safety incident type',
  'safety_incident_types',
  $json$
  [
    {"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;




-- Default resource types
INSERT INTO resource_types (code, name, description, tenant_id, branch_id)
VALUES
  ('module', 'Module', 'Application module entry point', NULL, NULL),
  ('table', 'Table', 'Backend table name', NULL, NULL),
  ('form', 'Form', 'Form builder form', NULL, NULL),
  ('wizard', 'Wizard', 'Multi step wizard', NULL, NULL),
  ('chart', 'Chart', 'Chart or report', NULL, NULL),
  ('worksheet', 'Worksheet', 'Spreadsheet worksheet', NULL, NULL),
  ('table_column', 'Table Column', 'Specific table column resource', NULL, NULL)
ON CONFLICT DO NOTHING;



INSERT INTO invoice_templates (name, file_path, tenant_id)
SELECT 'Notice of Certain Workplaces', 'templates/invoices/workplace_notice.php', NULL
WHERE NOT EXISTS (
    SELECT 1 FROM invoice_templates WHERE file_path='templates/invoices/workplace_notice.php'
);

-- Ensure case invoice type exists
INSERT INTO invoice_types (name)
SELECT 'case'
WHERE NOT EXISTS (
    SELECT 1 FROM invoice_types WHERE name='case'
);

-- Ensure workplace invoice type exists
INSERT INTO invoice_types (name)
SELECT 'workplace'
WHERE NOT EXISTS (
    SELECT 1 FROM invoice_types WHERE name='workplace'
);

-- Ensure schedule_of_costs invoice type exists
INSERT INTO invoice_types (name)
SELECT 'schedule_of_costs'
WHERE NOT EXISTS (
    SELECT 1 FROM invoice_types WHERE name='schedule_of_costs'
);


-- Workflow for workplace registration approval
INSERT INTO workflows (name, trigger_event, definition, is_active)
VALUES (
  'Workplace Registration Review',
  'workplace.registration.created',
  '{"conditions": []}',
  TRUE
);

INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
VALUES (
  (SELECT id FROM workflows WHERE name='Workplace Registration Review' LIMIT 1),
  1,
  'save_record',
  '{"table":"workplace_registrations","data":{"status":"approved"},"match":{"id":"{id}"}}'
);

-- Map tenant_id then create invoice within Workplace Registration Review workflow
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
SELECT w.id, 2, 'map_fields', '{"map":{"tenant_id":"tenant_id"}}'
FROM workflows w
WHERE w.name='Workplace Registration Review'
  AND NOT EXISTS (
    SELECT 1 FROM workflow_steps ws
    WHERE ws.workflow_id = w.id AND ws.step_order = 2 AND ws.step_type='map_fields'
  );

INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
SELECT w.id, 3, 'create_invoice', '{}'
FROM workflows w
WHERE w.name='Workplace Registration Review'
  AND NOT EXISTS (
    SELECT 1 FROM workflow_steps ws
    WHERE ws.workflow_id = w.id AND ws.step_order = 3 AND ws.step_type='create_invoice'
  );

INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
SELECT w.id, 4, 'save_record', '{"table":"workplace_registrations","data":{"invoice_id":"{invoice_id}"},"match":{"id":"{id}"}}'
FROM workflows w
WHERE w.name='Workplace Registration Review'
  AND NOT EXISTS (
    SELECT 1 FROM workflow_steps ws
    WHERE ws.workflow_id = w.id AND ws.step_order = 4 AND ws.step_type='save_record'
  );

INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
SELECT w.id, 5, 'queue_notification', '{"entity":"workplace_registrations","record_id":"{id}","event_type":"update","payload":{"invoice_id":"{invoice_id}"}}'
FROM workflows w
WHERE w.name='Workplace Registration Review'
  AND NOT EXISTS (
    SELECT 1 FROM workflow_steps ws
    WHERE ws.workflow_id = w.id AND ws.step_order = 5 AND ws.step_type='queue_notification'
  );

-- Open Workplace Invoice Preview after invoice creation
INSERT INTO workflow_steps (workflow_id, step_order, step_type, config)
SELECT w.id, 6, 'open_modal', '{"modal":"Workplace Invoice Preview"}'
FROM workflows w
WHERE w.name='Workplace Registration Review'
  AND NOT EXISTS (
    SELECT 1 FROM workflow_steps ws
    WHERE ws.workflow_id = w.id AND ws.step_order = 6 AND ws.step_type='open_modal'
      AND ws.config->>'modal'='Workplace Invoice Preview'
  );

-- Workflow to generate Workplace Registration certificate
INSERT INTO workflows (name, trigger_event, definition, is_active)
VALUES (
  'Workplace Registration Certificate',
  'workplace.registration.certificate',
  '{"conditions": []}',
  TRUE
);

INSERT INTO workflow_steps (workflow_id, step_order, step_type, config) VALUES
  (
    (SELECT id FROM workflows WHERE name='Workplace Registration Certificate' LIMIT 1),
    1,
    'create_certificate',
    json_build_object(
      'template_id', (SELECT id FROM certificate_templates WHERE name='Basic Certificate' LIMIT 1),
      'submission_id_key', 'id',
      'status', 'issued'
    )
  ),
  ((SELECT id FROM workflows WHERE name='Workplace Registration Certificate' LIMIT 1),2,'generate_certificate_document','{}'),
  ((SELECT id FROM workflows WHERE name='Workplace Registration Certificate' LIMIT 1),3,'queue_notification','{"entity":"form_certificates","record_id":"{certificate_id}","event_type":"update"}'),
  ((SELECT id FROM workflows WHERE name='Workplace Registration Certificate' LIMIT 1),4,'open_modal','{"modal":"Certificates"}');

INSERT INTO workflow_event_triggers (event_name, table_name, trigger_type, operations, field_map)
VALUES (
  'workplace.registration.certificate',
  'workplace_registrations',
  'update',
  '["update"]',
  '{"id":"id"}'
);

SELECT setval('workflow_steps_id_seq', (SELECT MAX(id) FROM workflow_steps));

-- Restore Workplace Registration form and modal

-- Workplace Registration form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  106,
  'Workplace Registration',
  'Record new workplaces',
  'workplace_registrations',
  $json$
 [
  {
    "label": "Name of owner(s) of business",
    "type_id": 16,
    "field_name": "name_of_owners_of_business",
    "order_index": 0,
    "placeholder": "Name of owner(s) of business:"
  },
  {
    "label": "Trading name",
    "type_id": 1,
    "field_name": "trading_name",
    "order_index": 1,
    "placeholder": "Trading name"
  },
  {
    "label": "Address of workplace",
    "type_id": 1,
    "field_name": "address_of_workplace",
    "order_index": 2,
    "placeholder": "Address of workplace"
  },
  {
    "label": "Postal address",
    "type_id": 1,
    "field_name": "postal_address",
    "order_index": 3,
    "placeholder": "Postal address"
  },
  {
    "label": "Date of business commenced operations at these premises",
    "type_id": 3,
    "field_name": "date_of_business_commenced_operations_at_these_premises",
    "order_index": 4,
    "placeholder": "Date of business commenced operations at these premises"
  },
  {
    "label": "Details of ownership of premises",
    "type_id": 8,
    "field_name": "details_of_ownership_of_premises",
    "order_index": 5,
    "placeholder": "Details of ownership of premises"
  },
  {
    "label": "Name & address of Owner of the Building:",
    "type_id": 1,
    "field_name": "name_and_address_of_owner_of_the_building",
    "order_index": 6,
    "placeholder": "Name & address of Owner of the Building"
  },
  {
    "label": "Details of business activity: (Refer to First Schedule)",
    "type_id": 8,
    "field_name": "details_of_business_activiy",
    "order_index": 7,
    "placeholder": "Details of business activity"
  },
  {
    "label": "Main Activity Conducted by Business",
    "type_id": 1,
    "field_name": "main_activity_conducted_by_business",
    "order_index": 8,
    "placeholder": "Main Activity Conducted by Business"
  },
  {
    "label": "Principal Articles to be manufactured repaired or sold",
    "type_id": 1,
    "field_name": "principal_articles_to_be_manufactured_repaired_or_sold",
    "order_index": 9,
    "placeholder": "Principal Articles to be manufactured repaired or sold"
  },
  {
    "label": "Are goods sold at this location:",
    "type_id": 5,
    "field_name": "goods_sold",
    "order_index": 10,
    "placeholder": ""
  },
  {
    "label": "Sales Type",
    "options": [
      {
        "value": "wholesale",
        "display_text": "Wholesale"
      },
      {
        "value": "retail",
        "display_text": "Retail"
      },
      {
        "value": "both",
        "display_text": "Both"
      }
    ],
    "type_id": 4,
    "field_name": "sales_type",
    "order_index": 11,
    "condition_field": "goods_sold",
    "condition_value": "1"
  },
  {
    "label": "Has Site Previously been used as a workplace",
    "type_id": 1,
    "field_name": "has_site_previously_been_used_as_a_workplace",
    "order_index": 12,
    "placeholder": "Has Site Previously been used as a workplace"
  },
  {
    "label": "Name of previous Occupier",
    "type_id": 1,
    "field_name": "name_of_previous_occupier",
    "order_index": 13,
    "placeholder": "Name of previous Occupier"
  },
  {
    "label": "Contact telephone number",
    "type_id": 2,
    "field_name": "contact_telephone_number",
    "order_index": 14,
    "placeholder": "Contact telephone number"
  },
  {
    "label": "Maximum Number of Employees",
    "type_id": 2,
    "field_name": "maximum_number_of_employees",
    "order_index": 14,
    "placeholder": "Maximum Number of Employees"
  },
  {
    "label": "Committee Members",
    "type_id": 8,
    "field_name": "committee_members",
    "order_index": 14,
    "placeholder": "Committee Members"
  },
  {
    "label": "Training Undergone",
    "type_id": 5,
    "field_name": "training_undergone",
    "order_index": 14,
    "placeholder": "Training Undergone"
  },
  {
    "label": "Districts",
    "type_id": 4,
    "field_name": "districts",
    "order_index": 14,
    "placeholder": "Districts",
    "options_table":"districts",
    "options_label_column":"name",
    "options_value_column":"id"
  },
  {
    "label": "OHS Policy",
    "type_id": 9,
    "field_name": "ohs_policy",
    "order_index": 14,
    "placeholder": "OHS Policy"
  },
  {
    "label": "Meeting Minutes",
    "type_id": 9,
    "field_name": "minutes",
    "order_index": 14,
    "placeholder": "Meeting Minutes"
  }
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


CREATE OR REPLACE FUNCTION notify_notification_queue()
RETURNS trigger AS $$
BEGIN
  PERFORM pg_notify('taf_queue', row_to_json(NEW)::text);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS notification_notify ON notification_queue;
CREATE TRIGGER notification_notify
AFTER INSERT ON notification_queue
FOR EACH ROW EXECUTE PROCEDURE notify_notification_queue();

-- Seed legacy modules referenced in FrontEnd/Dashboard.php
-- Ensure unique names via unique index and idempotent inserts

CREATE UNIQUE INDEX IF NOT EXISTS legacy_resources_name_idx ON legacy_resources (name);

INSERT INTO legacy_resources (name, description, isDeleted) VALUES
  ('SystemSettings', 'Legacy module from Dashboard.php', false),
  ('CountryHolidays', 'Legacy module from Dashboard.php', false),
  ('Calendar', 'Legacy module from Dashboard.php', false),
  ('Logout', 'Legacy module from Dashboard.php', false),
  ('WorkflowInstances', 'Legacy module from Dashboard.php', false),
  ('KanbanBoard', 'Legacy module from Dashboard.php', false),
  ('CustomizeDashboard', 'Legacy module from Dashboard.php', false),
  ('FormBuilder', 'Legacy module from Dashboard.php', false),
  ('DetailViewBuilder', 'Legacy module from Dashboard.php', false),
  ('PageCustomizer', 'Legacy module from Dashboard.php', false),
  ('PageConfigBuilder', 'Legacy module from Dashboard.php', false),
  ('ModuleBuilder', 'Legacy module from Dashboard.php', false),
  ('WorkflowBuilder', 'Legacy module from Dashboard.php', false),
  ('TableBuilder', 'Legacy module from Dashboard.php', false),
  ('TableManager', 'Legacy module from Dashboard.php', false),
  ('ModuleManager', 'Legacy module from Dashboard.php', false),
  ('PermissionsManager', 'Legacy module from Dashboard.php', false),
  ('Employees', 'Employee management module', false),
  ('AutoOrders', 'Manage Auto Orders for Products', false)
ON CONFLICT (name) DO NOTHING;


INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  110,
  'Vendor',
  'Manage Vendors',
  'vendors',
  '[
    {"label":"Vendor Name","field_name":"vendorname","data_column":"vendorname","type_id":1,"order_index":1},
    {"label":"Business Registration Number","field_name":"businessRegNumber","data_column":"businessRegNumber","type_id":1,"order_index":2},
    {"label":"TIN Number","field_name":"tin","data_column":"tin","type_id":1,"order_index":3},
    {"label":"Phone Numbers","field_name":"phone_numbers","type_id":16,"order_index":4,"options_table":"vendor_phone_numbers","options_label_column":"phone_number","options_value_column":"vendor_phone_id","multiple":true},
    {"label":"Emails","field_name":"emails","type_id":16,"order_index":5,"options_table":"vendor_emails","options_label_column":"email","options_value_column":"vendor_email_id","multiple":true}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  620,
  'RFQ Template',
  'Define reusable RFQ templates',
  'rfq_templates',
  '[
    {"label":"Template Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
    {"label":"Template Code","field_name":"code","data_column":"code","type_id":1,"order_index":2,"placeholder":"Optional short code"},
    {"label":"Category","field_name":"category","data_column":"category","type_id":1,"order_index":3},
    {"label":"Default Template","field_name":"is_default","data_column":"is_default","type_id":5,"order_index":4},
    {"label":"Valid From","field_name":"valid_from","data_column":"valid_from","type_id":3,"order_index":5},
    {"label":"Valid Until","field_name":"valid_until","data_column":"valid_until","type_id":3,"order_index":6},
    {"label":"Distribution Channels","field_name":"distribution_channels","data_column":"distribution_channels","type_id":8,"order_index":7,"placeholder":"Comma separated, e.g. email,portal"},
    {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":8}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  621,
  'RFQ Template Section',
  'Manage RFQ template sections',
  'rfq_template_sections',
  '[
    {"label":"Template","field_name":"rfq_template_id","data_column":"rfq_template_id","type_id":13,"order_index":1,"options_table":"rfq_templates","options_label_column":"name","options_value_column":"rfq_template_id","required":true},
    {"label":"Section Key","field_name":"section_key","data_column":"section_key","type_id":1,"order_index":2,"placeholder":"e.g. scope,terms,pricing"},
    {"label":"Heading","field_name":"heading","data_column":"heading","type_id":1,"order_index":3},
    {"label":"Body (Markdown)","field_name":"body_markdown","data_column":"body_markdown","type_id":8,"order_index":4},
    {"label":"Body (HTML)","field_name":"body_html","data_column":"body_html","type_id":8,"order_index":5},
    {"label":"Display Order","field_name":"sort_order","data_column":"sort_order","type_id":2,"order_index":6},
    {"label":"Required","field_name":"is_required","data_column":"is_required","type_id":5,"order_index":7},
    {"label":"Include In Printed PDF","field_name":"include_in_print","data_column":"include_in_print","type_id":5,"order_index":8},
    {"label":"Include In Email","field_name":"include_in_email","data_column":"include_in_email","type_id":5,"order_index":9}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  622,
  'RFQ Template Attachment',
  'Attach standard files to RFQ templates',
  'rfq_template_attachments',
  '[
    {"label":"Template","field_name":"rfq_template_id","data_column":"rfq_template_id","type_id":13,"order_index":1,"options_table":"rfq_templates","options_label_column":"name","options_value_column":"rfq_template_id","required":true},
    {"label":"Label","field_name":"label","data_column":"label","type_id":1,"order_index":2},
    {"label":"File Type","field_name":"filetype","data_column":"filetype","type_id":1,"order_index":3,"placeholder":"e.g. pdf,docx"},
    {"label":"File URL","field_name":"file_url","data_column":"file_url","type_id":7,"order_index":4},
    {"label":"Include When","field_name":"include_when","data_column":"include_when","type_id":4,"order_index":5,"options":[{"label":"Always","value":"always"},{"label":"Awarded","value":"awarded"},{"label":"Pre-Issuance","value":"pre_issuance"}]},
    {"label":"Sort Order","field_name":"sort_order","data_column":"sort_order","type_id":2,"order_index":6}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  610,
  'Vendor Contact',
  'Capture vendor contact records',
  'vendor_contacts',
  '[
    {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":17,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"Contact Name","field_name":"contact_name","data_column":"contact_name","type_id":1,"order_index":2},
    {"label":"Role","field_name":"contact_role","data_column":"contact_role","type_id":1,"order_index":3},
    {"label":"Email","field_name":"email","data_column":"email","type_id":1,"order_index":4},
    {"label":"Phone Number","field_name":"phone_number","data_column":"phone_number","type_id":1,"order_index":5},
    {"label":"Primary Contact","field_name":"is_primary","data_column":"is_primary","type_id":5,"order_index":6},
    {"label":"Notes","field_name":"notes","data_column":"notes","type_id":8,"order_index":7}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  611,
  'Vendor Address',
  'Manage vendor address records',
  'vendor_addresses',
  '[
  {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":17,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"Address Type","field_name":"address_type","data_column":"address_type","type_id":4,"order_index":2,"options":[{"display_text":"Office","value":"office"},{"display_text":"Billing","value":"billing"},{"display_text":"Shipping","value":"shipping"},{"display_text":"Registered","value":"registered"},{"display_text":"Other","value":"other"}]},
    {"label":"Address Line 1","field_name":"line1","data_column":"line1","type_id":1,"order_index":3},
    {"label":"Address Line 2","field_name":"line2","data_column":"line2","type_id":1,"order_index":4},
    {"label":"City","field_name":"city","data_column":"city","type_id":1,"order_index":5},
    {"label":"State / Region","field_name":"state_region","data_column":"state_region","type_id":1,"order_index":6},
    {"label":"Postal Code","field_name":"postal_code","data_column":"postal_code","type_id":1,"order_index":7},
    {"label":"Country","field_name":"country_code","data_column":"country_code","type_id":1,"order_index":8},
    {"label":"Primary Address","field_name":"is_primary","data_column":"is_primary","type_id":5,"order_index":9}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  612,
  'Vendor Capability',
  'Track vendor capabilities and experience',
  'vendor_capabilities',
  '[
    {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"Capability Category","field_name":"capability_category","data_column":"capability_category","type_id":1,"order_index":2},
    {"label":"Capability Description","field_name":"capability_description","data_column":"capability_description","type_id":8,"order_index":3},
    {"label":"Experience (Years)","field_name":"experience_years","data_column":"experience_years","type_id":2,"order_index":4},
    {"label":"Certifications","field_name":"certifications","data_column":"certifications","type_id":8,"order_index":5},
    {"label":"Capacity Notes","field_name":"capacity_notes","data_column":"capacity_notes","type_id":8,"order_index":6},
    {"label":"Competency Score","field_name":"competency_score","data_column":"competency_score","type_id":2,"order_index":7}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  613,
  'Vendor Documents',
  'Collect required compliance documents for vendor onboarding',
  'vendor_documents',
  '[
    {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":17,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"FNPF Compliance Document","field_name":"fnpf_document","type_id":9,"order_index":2,"doc_type":"fnpf_compliance","doc_field":"file_url","widget_options":{"maxFiles":1}},
    {"label":"FNPF Compliance Expiry Date","field_name":"fnpf_validity","type_id":3,"order_index":3,"doc_type":"fnpf_compliance","doc_field":"validity"},
    {"label":"FRCS VAT Clearance Certificate","field_name":"frcs_vat_document","type_id":9,"order_index":4,"doc_type":"frcs_vat_clearance","doc_field":"file_url","widget_options":{"maxFiles":1}},
    {"label":"FRCS VAT Clearance Expiry Date","field_name":"frcs_vat_validity","type_id":3,"order_index":5,"doc_type":"frcs_vat_clearance","doc_field":"validity"},
    {"label":"FRCS Tax Clearance Certificate","field_name":"frcs_tax_document","type_id":9,"order_index":6,"doc_type":"frcs_tax_clearance","doc_field":"file_url","widget_options":{"maxFiles":1}},
    {"label":"FRCS Tax Clearance Expiry Date","field_name":"frcs_tax_validity","type_id":3,"order_index":7,"doc_type":"frcs_tax_clearance","doc_field":"validity"},
    {"label":"FNU Levy Confirmation","field_name":"fnu_levy_document","type_id":9,"order_index":8,"doc_type":"fnu_levy","doc_field":"file_url","widget_options":{"maxFiles":1}},
    {"label":"FNU Levy Expiry Date","field_name":"fnu_levy_validity","type_id":3,"order_index":9,"doc_type":"fnu_levy","doc_field":"validity"},
    {"label":"Business Registration Document","field_name":"business_registration_document","type_id":9,"order_index":10,"doc_type":"business_registration","doc_field":"file_url","widget_options":{"maxFiles":1}},
    {"label":"Business Registration Expiry Date","field_name":"business_registration_validity","type_id":3,"order_index":11,"doc_type":"business_registration","doc_field":"validity"}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  614,
  'Vendor Supporting Document',
  'Track additional vendor supporting materials',
  'vendor_supporting_docs',
  '[
    {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"Document Category","field_name":"type","data_column":"type","type_id":4,"order_index":2,"options":[{"display_text":"Questionnaire","value":"questionnaire"},{"display_text":"Financial","value":"financial"},{"display_text":"Insurance","value":"insurance"},{"display_text":"Policy","value":"policy"},{"display_text":"Other","value":"other"}]},
    {"label":"File Type","field_name":"filetype","data_column":"filetype","type_id":1,"order_index":3},
    {"label":"File URL","field_name":"file_url","data_column":"file_url","type_id":9,"order_index":4},
    {"label":"Validity","field_name":"validity","data_column":"validity","type_id":3,"order_index":5}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  615,
  'Vendor Performance Metric',
  'Log vendor performance reviews',
  'vendor_performance_metrics',
  '[
    {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"Period Start","field_name":"period_start","data_column":"period_start","type_id":3,"order_index":2},
    {"label":"Period End","field_name":"period_end","data_column":"period_end","type_id":3,"order_index":3},
    {"label":"KPI Name","field_name":"kpi_name","data_column":"kpi_name","type_id":1,"order_index":4},
    {"label":"KPI Value","field_name":"kpi_value","data_column":"kpi_value","type_id":2,"order_index":5},
    {"label":"Rating","field_name":"rating","data_column":"rating","type_id":2,"order_index":6},
    {"label":"Reviewer","field_name":"reviewer_id","data_column":"reviewer_id","type_id":4,"order_index":7,"options_table":"users","options_label_column":"full_name","options_value_column":"user_id"},
    {"label":"Comments","field_name":"comments","data_column":"comments","type_id":8,"order_index":8}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  616,
  'Vendor Certificate',
  'Maintain vendor certification records',
  'vendor_certificates',
  '[
    {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"Certificate Name","field_name":"certificate_name","data_column":"certificate_name","type_id":1,"order_index":2},
    {"label":"Issued At","field_name":"issued_at","data_column":"issued_at","type_id":3,"order_index":3},
    {"label":"Expiry Date","field_name":"expiry_date","data_column":"expiry_date","type_id":3,"order_index":4},
    {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":5}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


-- Customer Management form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 109, 'Customer', 'Manage customer information', 'customers',
'[{"label":"Customer Type","field_name":"customer_type","data_column":"customer_type","type_id":4,"order_index":1,"options":[{"display_text":"Individual","value":"individual"},{"display_text":"Corporate","value":"corporate"},{"display_text":"Government","value":"government"}]},
  {"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":2},
  {"label":"Email","field_name":"email","data_column":"email","type_id":1,"order_index":3},
  {"label":"Phone Number","field_name":"phone_number","data_column":"phone_number","type_id":1,"order_index":4},
  {"label":"Address","field_name":"address","data_column":"address","type_id":1,"order_index":5},
  {"label":"TIN","field_name":"tin","data_column":"tin","type_id":1,"order_index":6},
  {"label":"Risk Rating","field_name":"risk_rating","data_column":"risk_rating","type_id":4,"order_index":7,"options":[{"display_text":"Low","value":"low"},{"display_text":"Medium","value":"medium"},{"display_text":"High","value":"high"}]},
  {"label":"Compliance Status","field_name":"compliance_status","data_column":"compliance_status","type_id":4,"order_index":8,"options":[{"display_text":"Compliant","value":"compliant"},{"display_text":"Non-Compliant","value":"non-compliant"},{"display_text":"Pending","value":"pending"}]}]',
NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 109);

-- Department Management form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 121, 'Department', 'Manage organizational departments', 'departments',
'[{"label":"Department","field_name":"name","data_column":"name","type_id":1,"order_index":1},
  {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":2}]',
NULL, 
NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 121);

-- Default departments
INSERT INTO departments (department_id, name)
SELECT uuid_generate_v7(), 'Human Resources' WHERE NOT EXISTS (SELECT 1 FROM departments WHERE name = 'Human Resources')
UNION ALL
SELECT uuid_generate_v7(), 'Finance' WHERE NOT EXISTS (SELECT 1 FROM departments WHERE name = 'Finance')
UNION ALL
SELECT uuid_generate_v7(), 'IT' WHERE NOT EXISTS (SELECT 1 FROM departments WHERE name = 'IT')
UNION ALL
SELECT uuid_generate_v7(), 'Operations' WHERE NOT EXISTS (SELECT 1 FROM departments WHERE name = 'Operations')
UNION ALL
SELECT uuid_generate_v7(), 'Sales' WHERE NOT EXISTS (SELECT 1 FROM departments WHERE name = 'Sales')
UNION ALL
SELECT uuid_generate_v7(), 'Marketing' WHERE NOT EXISTS (SELECT 1 FROM departments WHERE name = 'Marketing');

-- -- Alter products table to make price numeric
-- ALTER TABLE products ALTER COLUMN price TYPE numeric;

-- Add size column to products table
ALTER TABLE products ADD COLUMN IF NOT EXISTS size text;

-- Product form
INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  111,
  'Product',
  'Manage Products',
  'products',
  '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1,"required":true},
    {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":2},
    {"label":"Price","field_name":"price","data_column":"price","type_id":1,"order_index":3},
    {"label":"Barcode (GTIN)","field_name":"barcode","data_column":"barcode","type_id":1,"order_index":4},
    {"label":"Product Number","field_name":"product_number","data_column":"product_number","type_id":1,"order_index":5},
    {"label":"Brand","field_name":"brand","data_column":"brand","type_id":1,"order_index":6},
    {"label":"Category","field_name":"category_id","data_column":"category_id","type_id":13,"options_table":"product_categories","options_label_column":"name","options_value_column":"category_id","order_index":7,"required":true},
    {"label":"VAT","field_name":"vat","json_column":"tax_rates","type_id":4,"order_index":8,"options":[{"display_text":"12.5%","value":"G"},{"display_text":"0%","value":"B"}]},
    {"label":"STT","field_name":"stt","json_column":"tax_rates","type_id":4,"order_index":9,"options":[{"display_text":"Not Applicable","value":""},{"display_text":"6%","value":"E"}]},
    {"label":"Size","field_name":"size","data_column":"size","type_id":1,"order_index":10},
    {"label":"Base Unit","field_name":"base_unit","data_column":"base_unit","type_id":4,"order_index":11,"help_text":"Smallest sellable unit (e.g., PIECE, CAN, BOTTLE)","default_value":"PIECE","options":[{"display_text":"Piece","value":"PIECE"},{"display_text":"Can","value":"CAN"},{"display_text":"Bottle","value":"BOTTLE"},{"display_text":"Unit","value":"UNIT"},{"display_text":"Each","value":"EACH"}]},
    {"label":"Master Unit (Level 1)","field_name":"master_unit","data_column":"master_unit","type_id":4,"order_index":12,"help_text":"First bulk level (e.g., CARTON, BOX, PACK)","options":[{"display_text":"None","value":""},{"display_text":"Carton","value":"CARTON"},{"display_text":"Box","value":"BOX"},{"display_text":"Pack","value":"PACK"},{"display_text":"Case","value":"CASE"},{"display_text":"Bag","value":"BAG"}]},
    {"label":"Units per Master","field_name":"units_per_master","data_column":"units_per_master","type_id":2,"order_index":13,"help_text":"How many base units in one master unit (e.g., 24)"},
    {"label":"Master Unit (Level 2)","field_name":"master_unit_2","data_column":"master_unit_2","type_id":4,"order_index":14,"help_text":"Second bulk level (e.g., PALLET) - optional","options":[{"display_text":"None","value":""},{"display_text":"Pallet","value":"PALLET"},{"display_text":"Container","value":"CONTAINER"},{"display_text":"Crate","value":"CRATE"}]},
    {"label":"Units per Master 2","field_name":"units_per_master_2","data_column":"units_per_master_2","type_id":2,"order_index":15,"help_text":"How many master units in one master_unit_2 (e.g., 40 cartons per pallet)"}]',
  NULL,
  NULL
) ON CONFLICT (id) DO UPDATE SET elements = EXCLUDED.elements;

-- Auto Order form
INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  131,
  'Auto Order',
  'Manage Auto Orders for Products',
  'auto_orders',
  '[{"label":"Product","field_name":"product_id","data_column":"product_id","type_id":13,"options_table":"products","options_label_column":"name","options_value_column":"product_id","order_index":1},
    {"label":"Minimum Stock Qty","field_name":"minimum_stock_qty","data_column":"minimum_stock_qty","type_id":2,"order_index":2},
    {"label":"Order Qty","field_name":"order_qty","data_column":"order_qty","type_id":2,"order_index":3}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


-- Software Info form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  112,
  'Software Info',
  'Software Information',
  'software_info',
  '[{"label":"Manufacturer Name","field_name":"manufacturer_name","data_column":"manufacturer_name","type_id":1,"order_index":1,"default_value":"Cybex PTE Limited."},
    {"label":"Serial Number","field_name":"serial_number","data_column":"serial_number","type_id":1,"order_index":2,"default_value":"CYBEXPTE-ERP-2025-001."},
    {"label":"Software Version","field_name":"software_version","data_column":"software_version","type_id":1,"order_index":3,"default_value":"2025.08"}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


-- Insert default system info record
INSERT INTO software_info (manufacturer_name, serial_number, software_version)
SELECT 'Cybex PTE Limited.', 'CYBEXPTE-ERP-2025-001.', '2025.08'
WHERE NOT EXISTS (SELECT 1 FROM software_info LIMIT 1);

-- POS Settings form
INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  113,
  'POS Settings',
  'Point of Sale Settings',
  'pos_settings',
  '[{"label":"Password","field_name":"password","data_column":"password","type_id":1,"order_index":1,"default_value":"2CBP6HMW"},
    {"label":"PIN","field_name":"pin","data_column":"pin","type_id":1,"order_index":2,"default_value":"3840"},
    {"label":"SDC Base URL","field_name":"sdc_endpoint","data_column":"sdc_endpoint","type_id":1,"order_index":3,"placeholder":"http://devesdc.sandbox.vms.frcs.org.fj:8888/<tenant>/api"},
    {"label":"SDC PIN URL","field_name":"sdc_pin_url","data_column":"sdc_pin_url","type_id":1,"order_index":4,"placeholder":"http://devesdc.sandbox.vms.frcs.org.fj:8888/<tenant>/api/v3/pin"}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


-- Procurement form
INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  114,
  'Restaurant Product',
  'Manage Restaurant Products',
  'products',
  '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
{"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":2},
{"label":"Quantity","field_name":"quantity","data_column":"quantity","type_id":1,"order_index":3},
{"label":"Price","field_name":"price","data_column":"price","type_id":1,"order_index":4},
{"label":"Barcode (GTIN)","field_name":"barcode","data_column":"barcode","type_id":1,"order_index":5},
{"label":"Product Number","field_name":"product_number","data_column":"product_number","type_id":1,"order_index":6},
{"label":"Brand","field_name":"brand","data_column":"brand","type_id":1,"order_index":7},
{"label":"Size","field_name":"size","data_column":"size","type_id":1,"order_index":8},
{"label":"Category","field_name":"category_id","data_column":"category_id","type_id":13,"options_table":"product_categories","options_label_column":"name","options_value_column":"category_id","order_index":9},
{"label":"VAT","field_name":"vat","json_column":"tax_rates","type_id":4,"order_index":11,"options":[{"display_text":"12.5%","value":"G"},{"display_text":"0%","value":"A"}]},
{"label":"STT","field_name":"stt","json_column":"tax_rates","type_id":4,"order_index":12,"options":[{"display_text":"Not Applicable","value":""},{"display_text":"6%","value":"E"}]},
{"label":"Ingredients","field_name":"ingredients","type_id":22,"columns":[{"name":"ingredient_id","label":"Ingredient","type":"select-search","options_table":"ingredients","options_label_column":"name","options_value_column":"id"},{"name":"quantity","label":"Quantity","type":"number"},{"name":"units","label":"Units","type":"select","options":[{"display_text":"Pieces","value":"pieces"},{"display_text":"Kg","value":"kg"},{"display_text":"Grams","value":"grams"},{"display_text":"Liters","value":"liters"},{"display_text":"Ml","value":"ml"}]}],"link_table":"ingredients_to_products","link_columns":{"product_id":"id","ingredient_id":"ingredient_id","quantity":"quantity","units":"unit"},"order_index":10}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Procurement form
INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  115,
  'Procurement',
  'Manage procurement and L.P.O records',
  'procurements',
  '[
    {"label":"L.P.O Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"options_table":"Vendors","options_label_column":"vendorName","options_value_column":"id","order_index":1},
    {"label":"Quotation Number","field_name":"quotation_number","data_column":"quotation_number","type_id":1,"order_index":3},
    {"label":"Invoice Number","field_name":"invoice_number","data_column":"invoice_number","type_id":1,"order_index":4},
    {"label":"Requested By Date","field_name":"requested_by_date","data_column":"requested_by_date","type_id":3,"order_index":5},
    {"label":"Product Barcode","field_name":"product_barcode","data_column":"product_barcode","type_id":1,"order_index":2,"show_product_below":true}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;



-- Vendor Bank Accounts form
INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  120,
  'Vendor Bank Account',
  'Manage vendor bank account details',
  'vendor_bank_accounts',
  '[
  {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"options_table":"Vendors","options_label_column":"vendorName","options_value_column":"vendor_id","order_index":1},
    {"label":"Account Name","field_name":"account_name","data_column":"account_name","type_id":1,"order_index":2},
    {"label":"Account Number","field_name":"account_number","data_column":"account_number","type_id":1,"order_index":3},
    {"label":"Bank Name","field_name":"bank_name","data_column":"bank_name","type_id":1,"order_index":4},
    {"label":"IFSC/SWIFT Code","field_name":"ifsc_swift","data_column":"ifsc_swift","type_id":1,"order_index":5},
    {"label":"Branch","field_name":"branch","data_column":"branch","type_id":1,"order_index":6},
    {"label":"Account Type","field_name":"account_type","data_column":"account_type","type_id":4,"order_index":7,"options":[{"display_text":"Savings","value":"savings"},{"display_text":"Current","value":"current"},{"display_text":"Other","value":"other"}]},
    {"label":"Active","field_name":"is_active","data_column":"is_active","type_id":5,"order_index":8}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Ingredients form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  116,
  'Ingredients',
  'Manage Ingredients',
  'ingredients',
  '[{"label":"Ingredient Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
    {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":2},
    {"label":"Units","field_name":"units","data_column":"units","type_id":4,"order_index":4,"options":[{"display_text":"Pieces","value":"pieces"},{"display_text":"Kg","value":"kg"},{"display_text":"Grams","value":"grams"},{"display_text":"Liters","value":"liters"},{"display_text":"Ml","value":"ml"}]},
    {"label":"Quantity","field_name":"quantity","data_column":"quantity","type_id":1,"order_index":3},
    {"label":"Price","field_name":"price","data_column":"price","type_id":1,"order_index":5}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


  -- Purchase Order Form
  INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
  VALUES (
    130,
    'Purchase Order',
    'Form for creating and editing purchase orders',
    'purchase_orders',
    '[
      {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id","order_index":1},
      {"label":"Order Date","field_name":"order_date","data_column":"order_date","type_id":3,"order_index":2},
      {"label":"Order Number","field_name":"order_number","data_column":"order_number","type_id":1,"order_index":3},
      {"label":"Products","field_name":"products","type_id":22,"columns":[
        {"name":"product_barcode","label":"Product","type":"select-search","options_table":"products","options_label_column":"name","options_value_column":"barcode","show_selected_name":true},
        {"name":"quantity","label":"Qty","type":"number"},
  {"name":"units","label":"Units","type":"select","options":[{"display_text":"Box","value":"box"},{"display_text":"Package","value":"package"},{"display_text":"Carton","value":"carton"}]}
      ],"order_index":6}
    ]',
    NULL,
    NULL
  )
  ON CONFLICT (id) DO NOTHING;

-- Product Discount Form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  132,
  'Product Discount',
  'Manage product discounts with date ranges',
  'product_discounts',
  '[
    {"label":"Product","field_name":"product_name","type_id":1,"order_index":1,"readonly":true,"default":""},
    {"field_name":"product_id","data_column":"product_id","type_id":1,"order_index":0,"hidden":true,"required":true},
    {"label":"Discount Amount","field_name":"discount_amount","data_column":"discount_amount","type_id":2,"order_index":2,"required":true,"placeholder":"Enter discount amount"},
    {"label":"Start Date","field_name":"start_date","data_column":"start_date","type_id":3,"order_index":3,"required":true},
    {"label":"End Date","field_name":"end_date","data_column":"end_date","type_id":3,"order_index":4,"required":true}
  ]',
  NULL,
  NULL
)
ON CONFLICT (id) DO NOTHING;

-- Discount Rule Form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  150,
  'Discount Rule',
  'Configure discount rules with conditional inputs',
  'discount_rules',
  '[
    {"label":"Discount Name","field_name":"name","data_column":"name","type_id":1,"order_index":1,"required":true},
    {"label":"Discount Type","field_name":"discount_type","data_column":"discount_type","type_id":4,"order_index":2,"required":true,"options":[{"value":"product_percent","label":"Percentage on Product"},{"value":"product_amount","label":"Amount on Product"},{"value":"category_percent","label":"Category (% Only)"},{"value":"store_percent","label":"Storewide (% Only)"},{"value":"bogo_product","label":"Buy X Get Y Free - Product"},{"value":"bogo_category","label":"Buy X Get Y Free - Category"},{"value":"bogo_store","label":"Buy X Get Y Free - Storewide"},{"value":"x_for_y","label":"X Products for $Y"},{"value":"percent_for_x_items","label":"% Off for X Items"}]},
    {"label":"Product","field_name":"product_id","data_column":"product_id","type_id":13,"options_table":"products","options_label_column":"name","options_value_column":"product_id","order_index":3,"condition_field":"discount_type","condition_value":"product_percent|product_amount|bogo_product|x_for_y|percent_for_x_items","required":true},
    {"label":"Category","field_name":"category_id","data_column":"category_id","type_id":13,"options_table":"product_categories","options_label_column":"name","options_value_column":"category_id","order_index":4,"condition_field":"discount_type","condition_value":"category_percent|bogo_category","required":true},
    {"label":"Discount Percentage","field_name":"percentage_value","data_column":"percentage_value","type_id":2,"order_index":5,"condition_field":"discount_type","condition_value":"product_percent|category_percent|store_percent|percent_for_x_items","required":true},
    {"label":"Discount Amount","field_name":"amount_value","data_column":"amount_value","type_id":2,"order_index":6,"condition_field":"discount_type","condition_value":"product_amount","required":true},
    {"label":"Buy Quantity","field_name":"buy_quantity","data_column":"buy_quantity","type_id":2,"order_index":7,"condition_field":"discount_type","condition_value":"bogo_product|bogo_category|bogo_store","required":true},
    {"label":"Free Quantity","field_name":"free_quantity","data_column":"free_quantity","type_id":2,"order_index":8,"condition_field":"discount_type","condition_value":"bogo_product|bogo_category|bogo_store","required":true},
    {"label":"Bundle Quantity","field_name":"bundle_quantity","data_column":"bundle_quantity","type_id":2,"order_index":9,"condition_field":"discount_type","condition_value":"x_for_y","required":true},
    {"label":"Bundle Price","field_name":"bundle_price","data_column":"bundle_price","type_id":2,"order_index":10,"condition_field":"discount_type","condition_value":"x_for_y","required":true},
    {"label":"Required Item Count","field_name":"threshold_quantity","data_column":"threshold_quantity","type_id":2,"order_index":11,"condition_field":"discount_type","condition_value":"percent_for_x_items","required":true},
    {"label":"Start Date","field_name":"start_date","data_column":"start_date","type_id":3,"order_index":12},
    {"label":"End Date","field_name":"end_date","data_column":"end_date","type_id":3,"order_index":13},
    {"label":"Notes","field_name":"notes","data_column":"notes","type_id":8,"order_index":14}
  ]',
  NULL,
  NULL
)
ON CONFLICT (id) DO NOTHING;

-- Employee Form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  113,
  'Employee Form',
  'Edit employee details',
  'Employees',
  '[{"label":"Full Name","field_name":"full_name","data_column":"full_name","type_id":1,"order_index":1,"required":true},
    {"label":"Designation","field_name":"designation","data_column":"designation","type_id":1,"order_index":2},
    {"label":"Department","field_name":"department","data_column":"department","type_id":1,"order_index":3},
    {"label":"Join Date","field_name":"join_date","data_column":"join_date","type_id":3,"order_index":4},
    {"label":"Salary Type","field_name":"salary.salary_type","data_column":"salary.salary_type","type_id":4,"order_index":5,"options":[{"value":"hourly","label":"Hourly"},{"value":"monthly","label":"Monthly"},{"value":"contract","label":"Contract"}]},
    {"label":"Salary Rate","field_name":"salary.rate","data_column":"salary.rate","type_id":2,"order_index":6},
    {"label":"Currency","field_name":"salary.currency","data_column":"salary.currency","type_id":1,"order_index":7,"default":"FJD"}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Open Positions Form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  117,
  'Open Position',
  'Form to create and edit open positions',
  'open_positions',
  '[{"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":0,"required":true},
    {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":1},
    {"label":"Branch","field_name":"branch_id","data_column":"branch_id","type_id":1,"order_index":2},
    {"label":"Position","field_name":"position","data_column":"position","type_id":1,"order_index":3},
    {"label":"Applicant Type","field_name":"applicant_type","data_column":"applicant_type","type_id":4,"order_index":4,"options":[{"value":"All","label":"All"},{"value":"Internal Only","label":"Internal Only"},{"value":"External Only","label":"External Only"}]},
    {"label":"Open Date","field_name":"open_date","data_column":"open_date","type_id":3,"order_index":5},
    {"label":"Close Date","field_name":"close_date","data_column":"close_date","type_id":3,"order_index":6},
    {"label":"Department","field_name":"department","data_column":"department","type_id":1,"order_index":7},
    {"label":"Qualifications","field_name":"qualifications","data_column":"qualifications","type_id":8,"order_index":8},
    {"label":"Salary","field_name":"salary","data_column":"salary","type_id":2,"order_index":9},
    {"label":"Status","field_name":"status","data_column":"status","type_id":4,"order_index":10,"options":[{"value":"Open","label":"Open"},{"value":"Closed","label":"Closed"},{"value":"Pending","label":"Pending"}]}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Application Form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  118,
  'Job Application',
  'Form to submit job applications',
  'applications',
  '[{"label":"Position","field_name":"open_position_id","data_column":"open_position_id","type_id":4,"order_index":0,"required":true,"options_table":"open_positions","options_label_column":"title","options_value_column":"open_position_id"},
    {"label":"First Name","field_name":"first_name","data_column":"first_name","type_id":1,"order_index":1,"required":true},
    {"label":"Last Name","field_name":"last_name","data_column":"last_name","type_id":1,"order_index":2,"required":true},
    {"label":"Email","field_name":"email","data_column":"email","type_id":15,"order_index":3,"required":true},
    {"label":"Phone","field_name":"phone","data_column":"phone","type_id":1,"order_index":4},
    {"label":"Address","field_name":"address","data_column":"address","type_id":8,"order_index":5},
    {"label":"Date of Birth","field_name":"date_of_birth","data_column":"date_of_birth","type_id":3,"order_index":6},
    {"label":"Status","field_name":"status","data_column":"status","type_id":4,"order_index":7,"required":true,"options":[{"value":"New","label":"New"},{"value":"Under Review","label":"Under Review"},{"value":"ShortListed","label":"ShortListed"},{"value":"Interviewing","label":"Interviewing"},{"value":"Rejected","label":"Rejected"},{"value":"Hired","label":"Hired"}]},
    {"label":"Notes","field_name":"notes","data_column":"notes","type_id":8,"order_index":8}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Interview Form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  119,
  'Interview',
  'Form to schedule and manage job interviews',
  'interviews',
  '[{"label":"Application","field_name":"application_id","data_column":"application_id","type_id":4,"order_index":0,"required":true,"options_table":"applications","options_label_column":"first_name","options_value_column":"application_id"},
    {"label":"Interview Date","field_name":"interview_date","data_column":"interview_date","type_id":3,"order_index":1,"required":true},
    {"label":"Interview Number","field_name":"interview_number","data_column":"interview_number","type_id":2,"order_index":2,"required":true},
    {"label":"Interviewers","field_name":"interviewer_id","data_column":"interviewer_id","type_id":14,"order_index":3,"options_table":"users","options_label_column":"first_name","options_value_column":"user_id"},
    {"label":"Status","field_name":"status","data_column":"status","type_id":4,"order_index":4,"options":[{"value":"Scheduled","label":"Scheduled"},{"value":"Completed","label":"Completed"},{"value":"Cancelled","label":"Cancelled"}]},
    {"label":"Notes","field_name":"notes","data_column":"notes","type_id":8,"order_index":5},
    {"label":"Feedback","field_name":"feedback","data_column":"feedback","type_id":8,"order_index":6},
    {"label":"Rating","field_name":"rating","data_column":"rating","type_id":2,"order_index":7}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- New Employee Form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  140,
  'New Employee',
  'Form to create and manage new employee profiles',
  'users_profiles',
  '[{"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Address","field_name":"address","data_column":"address","type_id":16,"order_index":2},
    {"label":"Phone Number","field_name":"phone_number","data_column":"phone_number","type_id":16,"order_index":3,"required":true},
    {"label":"Email","field_name":"email","data_column":"email","type_id":16,"order_index":4},
    {"label":"Date of Birth","field_name":"date_of_birth","data_column":"date_of_birth","type_id":3,"order_index":5},
    {"label":"Profile Picture","field_name":"profile_pic","data_column":"profile_pic","type_id":1,"order_index":6},
    {"label":"Notes","field_name":"notes","data_column":"notes","type_id":8,"order_index":7}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


-- RFQ Core Schema (idempotent)
-- Duplicated from migrations/20250926_rfq_core.sql for new database installs
DO $$ BEGIN
  CREATE EXTENSION IF NOT EXISTS pgcrypto;
EXCEPTION WHEN others THEN NULL; END $$;

CREATE TABLE IF NOT EXISTS rfq_headers (
  rfq_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  org_id uuid NULL,
  department_id uuid NULL,
  type text NOT NULL CHECK (type IN ('RFQ','EOI')),
  rfq_number text NULL,
  numbering_format text NULL,
  title text NOT NULL,
  category text NULL,
  currency text NULL,
  incoterms text NULL,
  summary_markdown text NULL,
  summary_html text NULL,
  publish_at timestamptz NULL,
  due_at timestamptz NOT NULL,
  status text NOT NULL DEFAULT 'draft' CHECK (status IN ('draft','open','paused','closed','awarded','archived')),
  created_by uuid NULL,
  created_at timestamptz NOT NULL DEFAULT now(),
  updatedAt timestamptz NOT NULL DEFAULT now(),
  tender_box_opened_at timestamptz NULL,
  tender_box_opened_by uuid NULL,
  scoring_config jsonb NULL
);
CREATE INDEX IF NOT EXISTS idx_rfq_headers_status_due ON rfq_headers(status, due_at);
CREATE INDEX IF NOT EXISTS idx_rfq_headers_org_type ON rfq_headers(org_id, type);
CREATE UNIQUE INDEX IF NOT EXISTS uq_rfq_org_number ON rfq_headers(org_id, rfq_number) WHERE rfq_number IS NOT NULL;

CREATE TABLE IF NOT EXISTS rfq_sections (
  rfq_section_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  rfq_id uuid NOT NULL REFERENCES rfq_headers(rfq_id) ON DELETE CASCADE,
  section_key text NULL,
  heading text NULL,
  body_markdown text NULL,
  body_html text NULL,
  sort_order int NOT NULL DEFAULT 0,
  include_in_print boolean NOT NULL DEFAULT true,
  include_in_email boolean NOT NULL DEFAULT true,
  created_at timestamptz NOT NULL DEFAULT now(),
  updatedAt timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_rfq_sections_rfq ON rfq_sections(rfq_id);


-- Add SDC endpoint URL if not present (for upgrades)
ALTER TABLE pos_settings
  ADD COLUMN IF NOT EXISTS sdc_endpoint text NULL;
-- Form support on sections
ALTER TABLE rfq_template_sections
  ADD COLUMN IF NOT EXISTS content_type text DEFAULT 'text',
  ADD COLUMN IF NOT EXISTS form_id int NULL,
  ADD COLUMN IF NOT EXISTS elements jsonb NULL;

ALTER TABLE rfq_sections
  ADD COLUMN IF NOT EXISTS content_type text DEFAULT 'text',
  ADD COLUMN IF NOT EXISTS form_id int NULL,
  ADD COLUMN IF NOT EXISTS elements jsonb NULL;

CREATE TABLE IF NOT EXISTS rfq_attachments (
  rfq_attachment_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  rfq_id uuid NOT NULL REFERENCES rfq_headers(rfq_id) ON DELETE CASCADE,
  label text NULL,
  filetype text NULL,
  file_url text NULL,
  include_when text NOT NULL DEFAULT 'always',
  sort_order int NOT NULL DEFAULT 0,
  created_at timestamptz NOT NULL DEFAULT now(),
  updatedAt timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_rfq_attachments_rfq ON rfq_attachments(rfq_id);

CREATE TABLE IF NOT EXISTS rfq_items (
  id bigserial PRIMARY KEY,
  rfq_id uuid NOT NULL REFERENCES rfq_headers(rfq_id) ON DELETE CASCADE,
  description text NOT NULL,
  quantity numeric(14,4) NULL,
  uom text NULL,
  required_specs jsonb NULL,
  delivery_terms text NULL,
  delivery_location text NULL,
  is_optional boolean NOT NULL DEFAULT false,
  item_attachments jsonb NULL,
  created_at timestamptz NOT NULL DEFAULT now(),
  updatedAt timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_rfq_items_rfq ON rfq_items(rfq_id);
CREATE INDEX IF NOT EXISTS idx_rfq_items_specs ON rfq_items USING GIN(required_specs);

CREATE TABLE IF NOT EXISTS rfq_invites (
  invite_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  rfq_id uuid NOT NULL REFERENCES rfq_headers(rfq_id) ON DELETE CASCADE,
  vendor_id uuid NOT NULL REFERENCES vendors(vendor_id) ON DELETE CASCADE,
  contact_id uuid NULL REFERENCES vendor_contacts(vendor_contact_id) ON DELETE SET NULL,
  vendor_user_id uuid NULL REFERENCES users(user_id) ON DELETE SET NULL,
  channel text NULL,
  status text NOT NULL DEFAULT 'invited' CHECK (status IN ('invited','delivered','opened','responded','declined')),
  sent_at timestamptz NULL,
  delivered_at timestamptz NULL,
  opened_at timestamptz NULL,
  responded_at timestamptz NULL,
  declined_reason text NULL,
  reminder_count int NOT NULL DEFAULT 0,
  last_reminder_at timestamptz NULL,
  created_at timestamptz NOT NULL DEFAULT now(),
  updatedAt timestamptz NOT NULL DEFAULT now()
);
CREATE UNIQUE INDEX IF NOT EXISTS uq_rfq_invite_unique ON rfq_invites(rfq_id, vendor_id);
CREATE INDEX IF NOT EXISTS idx_rfq_invites_status ON rfq_invites(rfq_id, status);

CREATE TABLE IF NOT EXISTS vendor_quotes (
  quote_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  rfq_id uuid NOT NULL REFERENCES rfq_headers(rfq_id) ON DELETE CASCADE,
  invite_id uuid NULL REFERENCES rfq_invites(invite_id) ON DELETE SET NULL,
  vendor_id uuid NOT NULL REFERENCES vendors(vendor_id) ON DELETE CASCADE,
  currency text NULL,
  total_amount numeric(14,2) NULL,
  tax_total numeric(14,2) NULL,
  delivery_days int NULL,
  valid_thru date NULL,
  notes text NULL,
  attachments jsonb NULL,
  revision_no int NOT NULL DEFAULT 1,
  submitted_at timestamptz NULL,
  status text NOT NULL DEFAULT 'draft' CHECK (status IN ('draft','submitted','revised','withdrawn','final')),
  created_at timestamptz NOT NULL DEFAULT now(),
  updatedAt timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_vendor_quotes_rfq_vendor ON vendor_quotes(rfq_id, vendor_id);
CREATE INDEX IF NOT EXISTS idx_vendor_quotes_status ON vendor_quotes(rfq_id, status);

CREATE TABLE IF NOT EXISTS vendor_quote_items (
  quote_item_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  quote_id uuid NOT NULL REFERENCES vendor_quotes(quote_id) ON DELETE CASCADE,
  rfq_item_id bigint NULL REFERENCES rfq_items(id) ON DELETE SET NULL,
  is_alternate boolean NOT NULL DEFAULT false,
  alt_label text NULL,
  unit_price numeric(14,4) NULL,
  tax numeric(14,4) NULL,
  lead_time_days int NULL,
  notes text NULL
);
CREATE INDEX IF NOT EXISTS idx_vendor_quote_items_quote ON vendor_quote_items(quote_id);

CREATE TABLE IF NOT EXISTS rfq_awards (
  award_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  rfq_id uuid NOT NULL REFERENCES rfq_headers(rfq_id) ON DELETE CASCADE,
  scope text NOT NULL CHECK (scope IN ('header','item')),
  rfq_item_id bigint NULL REFERENCES rfq_items(id) ON DELETE SET NULL,
  vendor_id uuid NOT NULL REFERENCES vendors(vendor_id) ON DELETE RESTRICT,
  notes text NULL,
  created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_rfq_awards_rfq ON rfq_awards(rfq_id);

CREATE TABLE IF NOT EXISTS rfq_shortlists (
  shortlist_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  rfq_id uuid NOT NULL REFERENCES rfq_headers(rfq_id) ON DELETE CASCADE,
  vendor_id uuid NOT NULL REFERENCES vendors(vendor_id) ON DELETE CASCADE,
  org_id uuid NULL REFERENCES orgs(org_id) ON DELETE SET NULL,
  notes text NULL,
  created_by uuid NULL REFERENCES users(user_id) ON DELETE SET NULL,
  updated_by uuid NULL REFERENCES users(user_id) ON DELETE SET NULL,
  created_at timestamptz NOT NULL DEFAULT now(),
  updatedAt timestamptz NOT NULL DEFAULT now(),
  UNIQUE (rfq_id, vendor_id)
);
CREATE INDEX IF NOT EXISTS idx_rfq_shortlists_rfq ON rfq_shortlists(rfq_id);

CREATE TABLE IF NOT EXISTS rfq_events (
  event_id bigserial PRIMARY KEY,
  rfq_id uuid NOT NULL REFERENCES rfq_headers(rfq_id) ON DELETE CASCADE,
  actor_id uuid NULL,
  actor_type text NOT NULL DEFAULT 'internal',
  type text NOT NULL,
  payload jsonb NOT NULL DEFAULT '{}'::jsonb,
  created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_rfq_events_rfq ON rfq_events(rfq_id, created_at);
CREATE INDEX IF NOT EXISTS idx_rfq_events_payload_gin ON rfq_events USING GIN(payload);

CREATE TABLE IF NOT EXISTS rfq_scoring_notes (
  note_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  rfq_id uuid NOT NULL REFERENCES rfq_headers(rfq_id) ON DELETE CASCADE,
  vendor_id uuid NOT NULL REFERENCES vendors(vendor_id) ON DELETE CASCADE,
  org_id uuid NULL,
  criterion_key text NOT NULL,
  note_text text NULL,
  created_by uuid NULL REFERENCES users(user_id) ON DELETE SET NULL,
  updated_by uuid NULL REFERENCES users(user_id) ON DELETE SET NULL,
  created_at timestamptz NOT NULL DEFAULT now(),
  updatedAt timestamptz NOT NULL DEFAULT now(),
  CONSTRAINT uq_rfq_scoring_notes_key UNIQUE (rfq_id, vendor_id, criterion_key)
);
CREATE INDEX IF NOT EXISTS idx_rfq_scoring_notes_rfq ON rfq_scoring_notes(rfq_id);


-- Approval fields on rfq_headers
ALTER TABLE rfq_headers
  ADD COLUMN IF NOT EXISTS requested_by uuid NULL,
  ADD COLUMN IF NOT EXISTS approval_status text NOT NULL DEFAULT 'draft',
  ADD COLUMN IF NOT EXISTS approval_started_at timestamptz NULL,
  ADD COLUMN IF NOT EXISTS approval_completed_at timestamptz NULL;

-- RFQ approval instances
CREATE TABLE IF NOT EXISTS rfq_approval_instances (
  approval_instance_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  rfq_id               uuid NOT NULL REFERENCES rfq_headers(rfq_id) ON DELETE CASCADE,
  stage_no             int NOT NULL DEFAULT 1,
  approver_user_id     uuid NULL,
  approver_group_id    uuid NULL,
  status               text NOT NULL DEFAULT 'pending',
  decided_at           timestamptz NULL,
  comments             text NULL,
  created_at           timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS rfq_approval_instances_rfq_idx ON rfq_approval_instances(rfq_id);

CREATE TABLE IF NOT EXISTS numbering_sequences (
  org_id uuid NOT NULL,
  type text NOT NULL,
  year int NOT NULL,
  next_seq int NOT NULL DEFAULT 1,
  CONSTRAINT numbering_sequences_unique UNIQUE (org_id, type, year)
);

-- Seed a dashboard page config with the RFQ Template Builder card centered.
-- Only inserts when no dashboard config exists yet.
INSERT INTO page_configs (page, header_title, cards, layout_type)
SELECT 'dashboard', 'Dashboard',
       '[{"text":"RFQ Template Builder","modal":"rfq_template_builder"}]',
       'grid'
WHERE NOT EXISTS (SELECT 1 FROM page_configs WHERE page = 'dashboard' AND isDeleted = false);

-- Reserve Bank of Fiji RFQ Templates Seed (idempotent)
DO $$
DECLARE
  v_tpl uuid;
BEGIN
  ---------------------------------------------------------------------------
  -- General Goods & Services (Default)
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'General Goods & Services (RBF Default)', 'RBF_GS_DEFAULT', 'general',
          'Default RFQ template for general goods and services', true,
          ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  -- Sections
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'background') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'background', 'Background', 'Provide organizational context and objectives of the RFQ.', 10, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'scope') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'scope', 'Scope of Work', 'Describe the scope, locations, and expected outcomes.', 20, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'technical_requirements') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'technical_requirements', 'Technical Requirements', 'List minimum specifications, standards, and compliance requirements.', 30, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'deliverables') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'deliverables', 'Deliverables', 'Define deliverables, documentation, and acceptance criteria.', 40, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'service_levels') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'service_levels', 'Service Levels (SLA)', 'Specify response/restore times, uptime targets, and penalties.', 50, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'pricing') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'pricing', 'Pricing & Validity', 'Provide pricing, currency (FJD), taxes, and validity (days).', 60, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'submission') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'submission', 'Submission Instructions', 'Describe submission method, deadline, and required forms.', 70, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'evaluation') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'evaluation', 'Evaluation Criteria', 'Outline evaluation method and weighting.', 80, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'terms') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'terms', 'Commercial Terms', 'Payment terms, delivery terms (Incoterms if applicable), warranty.', 90, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'confidentiality') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'confidentiality', 'Confidentiality & Ethics', 'Confidentiality, anti-bribery, and code of conduct expectations.', 100, true, true);
  END IF;

  -- Attachments
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Standard RFQ Terms & Conditions (RBF)') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Standard RFQ Terms & Conditions (RBF)', 'pdf', 'templates/rbf/terms_conditions.pdf', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Non-Disclosure Agreement') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Non-Disclosure Agreement', 'pdf', 'templates/rbf/nda.pdf', 'pre_issuance', 20);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Pricing Template') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Pricing Template', 'xlsx', 'templates/rbf/pricing_template.xlsx', 'always', 30);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Code of Conduct & Anti-Bribery') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Code of Conduct & Anti-Bribery', 'pdf', 'templates/rbf/code_of_conduct_anti_bribery.pdf', 'always', 40);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Supplier Registration Form') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Supplier Registration Form', 'docx', 'templates/rbf/supplier_registration_form.docx', 'pre_issuance', 50);
  END IF;

  ---------------------------------------------------------------------------
  -- IT Infrastructure & Hardware
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'IT Infrastructure & Hardware', 'RBF_IT_INFRA', 'it',
          'Servers, network, endpoints, and related hardware', false,
          ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'background';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Environment overview and objectives.', 10, true, true),
      (v_tpl, 'scope', 'Scope of Work', 'Bill of materials, delivery, and installation scope.', 20, true, true),
      (v_tpl, 'technical_requirements', 'Technical Requirements', 'CPU, RAM, storage, certifications, redundancy, power & cooling.', 30, true, true),
      (v_tpl, 'warranty_support', 'Warranty & Support', 'Warranty terms, response and restore targets.', 40, true, true),
      (v_tpl, 'delivery_installation', 'Delivery & Installation', 'Site survey, logistics, racking, labelling.', 50, true, true),
      (v_tpl, 'acceptance_testing', 'Acceptance & Testing', 'UAT/POC criteria, burn-in, documentation.', 60, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Provide unit costs, BoM, and any optional items.', 70, true, true),
      (v_tpl, 'evaluation', 'Evaluation Criteria', 'Method and weighting.', 80, true, true),
      (v_tpl, 'terms', 'Commercial Terms', 'Payment, delivery schedule, liquidated damages.', 90, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'BoM Template') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'BoM Template', 'xlsx', 'templates/rbf/it/bom_template.xlsx', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Rack & Power Standards') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Rack & Power Standards', 'pdf', 'templates/rbf/it/rack_power_standards.pdf', 'always', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- Software & SaaS Procurement
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Software & SaaS', 'RBF_SOFTWARE_SAAS', 'it',
          'Commercial software and SaaS subscriptions', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'functional_requirements';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Business need and stakeholders.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'Modules and user counts.', 20, true, true),
      (v_tpl, 'functional_requirements', 'Functional Requirements', 'Feature checklist and must-haves.', 30, true, true),
      (v_tpl, 'nonfunctional_security', 'Security & Compliance', 'Authentication, encryption, audit, compliance (ISO 27001, PCI if applicable).', 40, true, true),
      (v_tpl, 'data_residency_privacy', 'Data Residency & Privacy', 'Storage location, retention, DPA requirements.', 50, true, true),
      (v_tpl, 'integration_requirements', 'Integration', 'APIs, formats, and systems to integrate.', 60, true, true),
      (v_tpl, 'support_sla', 'Support & SLA', 'Support hours, response/restore commitments.', 70, true, true),
      (v_tpl, 'bcdr', 'BCDR', 'Backups, DR strategy and RTO/RPO.', 80, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Licenses, tiers, seats, implementation costs.', 90, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 100, true, true),
      (v_tpl, 'terms', 'Terms', 'Commercial terms and SLAs.', 110, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Security Questionnaire') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Security Questionnaire', 'xlsx', 'templates/rbf/it/security_questionnaire.xlsx', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Data Processing Agreement') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Data Processing Agreement', 'pdf', 'templates/rbf/legal/dpa.pdf', 'awarded', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- Cybersecurity Services
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Cybersecurity Services', 'RBF_CYBERSEC', 'security',
          'Assessments, GRC, penetration testing, or MSSP', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'methodology_standards';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Security objectives.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'VA/PT/GRC/MDR scope and scale.', 20, true, true),
      (v_tpl, 'methodology_standards', 'Methodology & Standards', 'Follow OWASP, NIST, ISO 27001/2; provide sample reports.', 30, true, true),
      (v_tpl, 'deliverables', 'Deliverables', 'Reports, findings, remediation, workshops.', 40, true, true),
      (v_tpl, 'service_levels', 'Service Levels', 'Engagement timelines and SLAs.', 50, true, true),
      (v_tpl, 'team_quals_clearance', 'Team Qualifications', 'Certifications and clearances.', 60, true, true),
      (v_tpl, 'reporting', 'Reporting', 'Format, cadence, and review.', 70, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Fixed fee or T&M, travel policy.', 80, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 90, true, true),
      (v_tpl, 'confidentiality', 'Confidentiality', 'Handling of sensitive information.', 100, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Sample Report Outline') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Sample Report Outline', 'pdf', 'templates/rbf/security/sample_report_outline.pdf', 'always', 10);
  END IF;

  ---------------------------------------------------------------------------
  -- Financial/Regulatory Consulting & Research
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Financial/Regulatory Consulting & Research', 'RBF_CONSULTING', 'consulting',
          'Policy, market studies, regulatory impact analyses', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'methodology';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background_objectives', 'Background & Objectives', 'Context, research goals and outcomes.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'Tasks, datasets, and stakeholders.', 20, true, true),
      (v_tpl, 'methodology', 'Methodology', 'Approach, rigor, and quality control.', 30, true, true),
      (v_tpl, 'team_experience', 'Team & Experience', 'Experience in financial sector and references.', 40, true, true),
      (v_tpl, 'deliverables_milestones', 'Deliverables & Milestones', 'Reports, timelines, presentations.', 50, true, true),
      (v_tpl, 'governance_reporting', 'Governance & Reporting', 'Review cadence, steering oversight.', 60, true, true),
      (v_tpl, 'ip_rights', 'Intellectual Property', 'Ownership and licensing terms.', 70, true, true),
      (v_tpl, 'pricing', 'Pricing', 'T&M rates or fixed pricing.', 80, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 90, true, true),
      (v_tpl, 'terms', 'Terms', 'Commercial terms.', 100, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Template Workplan') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Template Workplan', 'docx', 'templates/rbf/consulting/workplan_template.docx', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'CV Matrix') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'CV Matrix', 'xlsx', 'templates/rbf/consulting/cv_matrix.xlsx', 'always', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- External Audit Services
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'External Audit Services', 'RBF_AUDIT', 'audit',
          'Financial, IT, or compliance audits', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'standards';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Audit objectives and scope.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'Financial/IT/compliance scope.', 20, true, true),
      (v_tpl, 'standards', 'Standards', 'ISA/ISAE/ISACA or relevant standards.', 30, true, true),
      (v_tpl, 'independence_conflict', 'Independence & Conflict', 'Independence declaration requirements.', 40, true, true),
      (v_tpl, 'team_quals', 'Team Qualifications', 'Qualifications and experience.', 50, true, true),
      (v_tpl, 'deliverables', 'Deliverables', 'Reports and management letters.', 60, true, true),
      (v_tpl, 'timeline', 'Timeline', 'Milestones and schedule.', 70, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Fees and assumptions.', 80, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 90, true, true),
      (v_tpl, 'terms', 'Terms', 'Commercial and confidentiality terms.', 100, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Independence Declaration') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Independence Declaration', 'docx', 'templates/rbf/audit/independence_declaration.docx', 'pre_issuance', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Sample Management Letter') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Sample Management Letter', 'pdf', 'templates/rbf/audit/sample_management_letter.pdf', 'always', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- Banking Equipment & Maintenance
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Banking Equipment & Maintenance', 'RBF_BANK_EQUIP', 'operations',
          'Cash processing equipment, CCTV, safes, and maintenance', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'preventive_maintenance';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Operational context and objectives.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'Supply, installation, and maintenance.', 20, true, true),
      (v_tpl, 'technical_requirements', 'Technical Requirements', 'Models, capacity, certifications.', 30, true, true),
      (v_tpl, 'installation_site_prep', 'Installation & Site Prep', 'Power, network, physical layout.', 40, true, true),
      (v_tpl, 'preventive_maintenance', 'Preventive Maintenance', 'PPM schedules, spares, and SLAs.', 50, true, true),
      (v_tpl, 'spares_warranty', 'Spares & Warranty', 'Spare parts and warranty handling.', 60, true, true),
      (v_tpl, 'training', 'Training', 'Operator and maintenance training.', 70, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Supply, installation, AMC.', 80, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 90, true, true),
      (v_tpl, 'terms', 'Terms', 'Commercial and confidentiality terms.', 100, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Site Survey Checklist') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Site Survey Checklist', 'xlsx', 'templates/rbf/operations/site_survey_checklist.xlsx', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Handover Form') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Handover Form', 'docx', 'templates/rbf/operations/handover_form.docx', 'awarded', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- Cash‑In‑Transit & Secure Logistics (CIT)
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Cash-In-Transit & Secure Logistics', 'RBF_CIT', 'security',
          'CIT services and secure logistics', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'security_compliance';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Cash movement profile and objectives.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'Routes, volumes, time windows.', 20, true, true),
      (v_tpl, 'security_compliance', 'Security & Compliance', 'Personnel vetting, SOPs, certifications.', 30, true, true),
      (v_tpl, 'risk_management', 'Risk Management', 'Threat model, contingencies.', 40, true, true),
      (v_tpl, 'incident_reporting', 'Incident Reporting', 'KPIs and escalation.', 50, true, true),
      (v_tpl, 'insurance_coverage', 'Insurance Coverage', 'Required coverage levels.', 60, true, true),
      (v_tpl, 'service_levels', 'Service Levels', 'OTP and tamper KPIs.', 70, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Route pricing and surcharges.', 80, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 90, true, true),
      (v_tpl, 'terms_confidentiality', 'Terms & Confidentiality', 'Commercial and confidentiality terms.', 100, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Security Vetting Form') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Security Vetting Form', 'docx', 'templates/rbf/security/security_vetting_form.docx', 'pre_issuance', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Incident Template') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Incident Template', 'docx', 'templates/rbf/security/incident_template.docx', 'always', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- Two-Envelope Technical & Financial Proposals
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Two-Envelope Technical & Financial', 'RBF_TECH_FIN_ENVELOPE', 'general',
          'For procurements that require separate technical and financial proposals', false,
          ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'submission_overview';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email, is_required)
    VALUES
      (v_tpl, 'submission_overview', 'Submission Overview',
        'Vendors must submit two separate digital files: **one technical proposal** and **one financial proposal**. Label files clearly (e.g. `VendorName - Technical.pdf` and `VendorName - Financial.xlsx`) and upload them as attachments when responding to this RFQ. Pricing information must be restricted to the financial proposal. Any proposal that combines technical and commercial content may be disqualified.',
        10, true, true, true);
  END IF;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'technical_proposal';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email, is_required)
    VALUES
      (v_tpl, 'technical_proposal', 'Technical Proposal Requirements',
        'Describe the solution, methodology, implementation approach, workplan, team CVs and compliance statements. The technical proposal must **exclude** all pricing or commercial terms. Include evidence of experience, certifications, quality assurance processes, risk management approach, and any mandatory forms (upload as appendices).',
        20, true, true, true);
  END IF;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'financial_proposal';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email, is_required)
    VALUES
      (v_tpl, 'financial_proposal', 'Financial Proposal Requirements',
        'Provide a detailed cost breakdown aligned to the scope. Show unit costs, taxes, optional items and total contract value. State currency (default FJD), payment schedule, validity period, and any assumptions. Do not repeat technical narrative in this document. Clearly reference the corresponding technical proposal sections.',
        30, true, true, true);
  END IF;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'evaluation_method';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'evaluation_method', 'Evaluation & Weighting',
        'The default weighting for this template is **70% technical** and **30% financial**. Evaluation teams should use the compare tab to score the technical proposal against published criteria (such as methodology, team, delivery plan, risk mitigation). Financial proposals are assessed on total cost of ownership and commercial compliance. Document consensus scores in the scoring notes area.',
        40, true, true);
  END IF;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'timeline_clarifications';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'timeline_clarifications', 'Timeline & Clarifications',
        'State the closing date/time, contact point for questions, and process for clarification responses. Remind vendors that late submissions or missing files can result in rejection. Where applicable, require acknowledgement that both documents were submitted on time.',
        50, true, true);
  END IF;

  ---------------------------------------------------------------------------
  -- Facilities & Building Services
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Facilities & Building Services', 'RBF_FACILITIES', 'facilities',
          'HVAC, power, cleaning, and soft services', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'standards_safety';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Facility profile and objectives.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'HVAC, power, cleaning scope.', 20, true, true),
      (v_tpl, 'standards_safety', 'Standards & Safety', 'Applicable standards and safety protocols.', 30, true, true),
      (v_tpl, 'schedules_sla', 'Schedules & SLA', 'PPM schedules and SLAs.', 40, true, true),
      (v_tpl, 'staffing_quals', 'Staffing & Qualifications', 'Minimum staffing and skills.', 50, true, true),
      (v_tpl, 'reporting', 'Reporting', 'Logs, KPIs, and reports.', 60, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Service pricing and options.', 70, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 80, true, true),
      (v_tpl, 'terms', 'Terms', 'Commercial and confidentiality terms.', 90, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'HSE Requirements') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'HSE Requirements', 'pdf', 'templates/rbf/facilities/hse_requirements.pdf', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'PPM Schedule Template') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'PPM Schedule Template', 'xlsx', 'templates/rbf/facilities/ppm_schedule_template.xlsx', 'always', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- Training & Capacity Building
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Training & Capacity Building', 'RBF_TRAINING', 'training',
          'Training programs and capability development', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'learning_objectives';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Audience and training objectives.', 10, true, true),
      (v_tpl, 'learning_objectives', 'Learning Objectives', 'Expected outcomes and competencies.', 20, true, true),
      (v_tpl, 'curriculum_outline', 'Curriculum Outline', 'Modules and durations.', 30, true, true),
      (v_tpl, 'trainer_quals', 'Trainer Qualifications', 'Required experience and certifications.', 40, true, true),
      (v_tpl, 'delivery_method', 'Delivery Method', 'Onsite/online/hybrid details.', 50, true, true),
      (v_tpl, 'materials_ip', 'Materials & IP', 'Ownership of materials and usage rights.', 60, true, true),
      (v_tpl, 'assessment_evaluation', 'Assessment & Evaluation', 'Assessments and feedback instruments.', 70, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Per-learner or program pricing.', 80, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 90, true, true),
      (v_tpl, 'terms', 'Terms', 'Commercial and confidentiality terms.', 100, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Attendance Sheet') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Attendance Sheet', 'xlsx', 'templates/rbf/training/attendance_sheet.xlsx', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Course Evaluation Form') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Course Evaluation Form', 'docx', 'templates/rbf/training/course_evaluation_form.docx', 'awarded', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- EOI: Market Sounding
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'EOI: Market Sounding', 'RBF_EOI_MARKET', 'eoi',
          'Expression of Interest for market sounding', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'interest_statement';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Purpose of EOI and context.', 10, true, true),
      (v_tpl, 'interest_statement', 'Statement of Interest', 'Vendor expression of interest and relevance.', 20, true, true),
      (v_tpl, 'capability_summary', 'Capability Summary', 'Core capabilities and capacity.', 30, true, true),
      (v_tpl, 'relevant_experience', 'Relevant Experience', 'Case studies and references.', 40, true, true),
      (v_tpl, 'indicative_approach', 'Indicative Approach', 'High-level approach and timeline.', 50, true, true),
      (v_tpl, 'submission', 'Submission', 'Instructions and deadline.', 60, true, true),
      (v_tpl, 'shortlisting_criteria', 'Shortlisting Criteria', 'How EOIs will be shortlisted.', 70, true, true);
  END IF;

END $$;

-- ---------------------------------------------------------------------------
-- Vendor Onboarding Wizard (seed)
-- Idempotent: will not duplicate if already present
-- ---------------------------------------------------------------------------
DO $$
DECLARE v_wizard_id INTEGER;
BEGIN
  -- Try to insert the wizard; if sequence is out-of-sync insertion may conflict, so use ON CONFLICT DO NOTHING
  -- Ensure we have a wizard id: if exists, use it; otherwise reserve an unused id and insert with that id
  SELECT id INTO v_wizard_id FROM form_wizards WHERE name = 'Vendor Onboarding Wizard' LIMIT 1;
  IF v_wizard_id IS NULL THEN
    -- compute a free id (max(id)+1) to avoid primary key conflicts when sequences differ
    SELECT COALESCE(MAX(id), 0) + 1 INTO v_wizard_id FROM form_wizards;
  INSERT INTO form_wizards (id, name, description)
  VALUES (v_wizard_id, 'Vendor Onboarding Wizard', 'Public vendor onboarding wizard sequencing vendor, contact, address and documents');
    -- advance sequence if present
    BEGIN
      PERFORM setval('form_wizards_id_seq', (SELECT MAX(id) FROM form_wizards));
    EXCEPTION WHEN undefined_function THEN
      -- sequence may not exist in some environments; ignore
      NULL;
    END;
  END IF;

  -- Ensure legacy capability step is removed if present
  DELETE FROM form_wizard_steps WHERE wizard_id = v_wizard_id AND form_id = 612;

  -- Idempotently insert each step (guard by existence)
  IF NOT EXISTS (SELECT 1 FROM form_wizard_steps WHERE wizard_id = v_wizard_id AND form_id = 110) THEN
    INSERT INTO form_wizard_steps (wizard_id, step_number, form_id) VALUES (v_wizard_id, 1, 110);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM form_wizard_steps WHERE wizard_id = v_wizard_id AND form_id = 610) THEN
    INSERT INTO form_wizard_steps (wizard_id, step_number, form_id) VALUES (v_wizard_id, 2, 610);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM form_wizard_steps WHERE wizard_id = v_wizard_id AND form_id = 611) THEN
    INSERT INTO form_wizard_steps (wizard_id, step_number, form_id) VALUES (v_wizard_id, 3, 611);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM form_wizard_steps WHERE wizard_id = v_wizard_id AND form_id = 613) THEN
    INSERT INTO form_wizard_steps (wizard_id, step_number, form_id) VALUES (v_wizard_id, 4, 613);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM form_wizard_steps WHERE wizard_id = v_wizard_id AND form_id = 614) THEN
    INSERT INTO form_wizard_steps (wizard_id, step_number, form_id) VALUES (v_wizard_id, 5, 614);
  END IF;
END $$;

-- Reserve Bank of Fiji RFQ Templates Seed
-- Idempotent upsert of templates, sections and attachments
-- Applies to PostgreSQL. Safe to re-run.

DO $$
DECLARE
  v_tpl uuid;
BEGIN
  ---------------------------------------------------------------------------
  -- General Goods & Services (Default)
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'General Goods & Services (RBF Default)', 'RBF_GS_DEFAULT', 'general',
          'Default RFQ template for general goods and services', true,
          ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  -- Sections
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'background') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'background', 'Background', 'Provide organizational context and objectives of the RFQ.', 10, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'scope') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'scope', 'Scope of Work', 'Describe the scope, locations, and expected outcomes.', 20, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'technical_requirements') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'technical_requirements', 'Technical Requirements', 'List minimum specifications, standards, and compliance requirements.', 30, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'deliverables') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'deliverables', 'Deliverables', 'Define deliverables, documentation, and acceptance criteria.', 40, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'service_levels') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'service_levels', 'Service Levels (SLA)', 'Specify response/restore times, uptime targets, and penalties.', 50, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'pricing') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'pricing', 'Pricing & Validity', 'Provide pricing, currency (FJD), taxes, and validity (days).', 60, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'submission') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'submission', 'Submission Instructions', 'Describe submission method, deadline, and required forms.', 70, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'evaluation') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'evaluation', 'Evaluation Criteria', 'Outline evaluation method and weighting.', 80, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'terms') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'terms', 'Commercial Terms', 'Payment terms, delivery terms (Incoterms if applicable), warranty.', 90, true, true);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'confidentiality') THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES (v_tpl, 'confidentiality', 'Confidentiality & Ethics', 'Confidentiality, anti-bribery, and code of conduct expectations.', 100, true, true);
  END IF;

  -- Attachments
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Standard RFQ Terms & Conditions (RBF)') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Standard RFQ Terms & Conditions (RBF)', 'pdf', 'templates/rbf/terms_conditions.pdf', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Non-Disclosure Agreement') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Non-Disclosure Agreement', 'pdf', 'templates/rbf/nda.pdf', 'pre_issuance', 20);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Pricing Template') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Pricing Template', 'xlsx', 'templates/rbf/pricing_template.xlsx', 'always', 30);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Code of Conduct & Anti-Bribery') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Code of Conduct & Anti-Bribery', 'pdf', 'templates/rbf/code_of_conduct_anti_bribery.pdf', 'always', 40);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Supplier Registration Form') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Supplier Registration Form', 'docx', 'templates/rbf/supplier_registration_form.docx', 'pre_issuance', 50);
  END IF;

  ---------------------------------------------------------------------------
  -- IT Infrastructure & Hardware
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'IT Infrastructure & Hardware', 'RBF_IT_INFRA', 'it',
          'Servers, network, endpoints, and related hardware', false,
          ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'background';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Environment overview and objectives.', 10, true, true),
      (v_tpl, 'scope', 'Scope of Work', 'Bill of materials, delivery, and installation scope.', 20, true, true),
      (v_tpl, 'technical_requirements', 'Technical Requirements', 'CPU, RAM, storage, certifications, redundancy, power & cooling.', 30, true, true),
      (v_tpl, 'warranty_support', 'Warranty & Support', 'Warranty terms, response and restore targets.', 40, true, true),
      (v_tpl, 'delivery_installation', 'Delivery & Installation', 'Site survey, logistics, racking, labelling.', 50, true, true),
      (v_tpl, 'acceptance_testing', 'Acceptance & Testing', 'UAT/POC criteria, burn-in, documentation.', 60, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Provide unit costs, BoM, and any optional items.', 70, true, true),
      (v_tpl, 'evaluation', 'Evaluation Criteria', 'Method and weighting.', 80, true, true),
      (v_tpl, 'terms', 'Commercial Terms', 'Payment, delivery schedule, liquidated damages.', 90, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'BoM Template') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'BoM Template', 'xlsx', 'templates/rbf/it/bom_template.xlsx', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Rack & Power Standards') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Rack & Power Standards', 'pdf', 'templates/rbf/it/rack_power_standards.pdf', 'always', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- Software & SaaS Procurement
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Software & SaaS', 'RBF_SOFTWARE_SAAS', 'it',
          'Commercial software and SaaS subscriptions', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'functional_requirements';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Business need and stakeholders.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'Modules and user counts.', 20, true, true),
      (v_tpl, 'functional_requirements', 'Functional Requirements', 'Feature checklist and must-haves.', 30, true, true),
      (v_tpl, 'nonfunctional_security', 'Security & Compliance', 'Authentication, encryption, audit, compliance (ISO 27001, PCI if applicable).', 40, true, true),
      (v_tpl, 'data_residency_privacy', 'Data Residency & Privacy', 'Storage location, retention, DPA requirements.', 50, true, true),
      (v_tpl, 'integration_requirements', 'Integration', 'APIs, formats, and systems to integrate.', 60, true, true),
      (v_tpl, 'support_sla', 'Support & SLA', 'Support hours, response/restore commitments.', 70, true, true),
      (v_tpl, 'bcdr', 'BCDR', 'Backups, DR strategy and RTO/RPO.', 80, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Licenses, tiers, seats, implementation costs.', 90, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 100, true, true),
      (v_tpl, 'terms', 'Terms', 'Commercial terms and SLAs.', 110, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Security Questionnaire') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Security Questionnaire', 'xlsx', 'templates/rbf/it/security_questionnaire.xlsx', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Data Processing Agreement') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Data Processing Agreement', 'pdf', 'templates/rbf/legal/dpa.pdf', 'awarded', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- Cybersecurity Services
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Cybersecurity Services', 'RBF_CYBERSEC', 'security',
          'Assessments, GRC, penetration testing, or MSSP', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'methodology_standards';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Security objectives.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'VA/PT/GRC/MDR scope and scale.', 20, true, true),
      (v_tpl, 'methodology_standards', 'Methodology & Standards', 'Follow OWASP, NIST, ISO 27001/2; provide sample reports.', 30, true, true),
      (v_tpl, 'deliverables', 'Deliverables', 'Reports, findings, remediation, workshops.', 40, true, true),
      (v_tpl, 'service_levels', 'Service Levels', 'Engagement timelines and SLAs.', 50, true, true),
      (v_tpl, 'team_quals_clearance', 'Team Qualifications', 'Certifications and clearances.', 60, true, true),
      (v_tpl, 'reporting', 'Reporting', 'Format, cadence, and review.', 70, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Fixed fee or T&M, travel policy.', 80, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 90, true, true),
      (v_tpl, 'confidentiality', 'Confidentiality', 'Handling of sensitive information.', 100, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Sample Report Outline') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Sample Report Outline', 'pdf', 'templates/rbf/security/sample_report_outline.pdf', 'always', 10);
  END IF;

  ---------------------------------------------------------------------------
  -- Financial/Regulatory Consulting & Research
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Financial/Regulatory Consulting & Research', 'RBF_CONSULTING', 'consulting',
          'Policy, market studies, regulatory impact analyses', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'methodology';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background_objectives', 'Background & Objectives', 'Context, research goals and outcomes.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'Tasks, datasets, and stakeholders.', 20, true, true),
      (v_tpl, 'methodology', 'Methodology', 'Approach, rigor, and quality control.', 30, true, true),
      (v_tpl, 'team_experience', 'Team & Experience', 'Experience in financial sector and references.', 40, true, true),
      (v_tpl, 'deliverables_milestones', 'Deliverables & Milestones', 'Reports, timelines, presentations.', 50, true, true),
      (v_tpl, 'governance_reporting', 'Governance & Reporting', 'Review cadence, steering oversight.', 60, true, true),
      (v_tpl, 'ip_rights', 'Intellectual Property', 'Ownership and licensing terms.', 70, true, true),
      (v_tpl, 'pricing', 'Pricing', 'T&M rates or fixed pricing.', 80, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 90, true, true),
      (v_tpl, 'terms', 'Terms', 'Commercial terms.', 100, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Template Workplan') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Template Workplan', 'docx', 'templates/rbf/consulting/workplan_template.docx', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'CV Matrix') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'CV Matrix', 'xlsx', 'templates/rbf/consulting/cv_matrix.xlsx', 'always', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- External Audit Services
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'External Audit Services', 'RBF_AUDIT', 'audit',
          'Financial, IT, or compliance audits', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'standards';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Audit objectives and scope.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'Financial/IT/compliance scope.', 20, true, true),
      (v_tpl, 'standards', 'Standards', 'ISA/ISAE/ISACA or relevant standards.', 30, true, true),
      (v_tpl, 'independence_conflict', 'Independence & Conflict', 'Independence declaration requirements.', 40, true, true),
      (v_tpl, 'team_quals', 'Team Qualifications', 'Qualifications and experience.', 50, true, true),
      (v_tpl, 'deliverables', 'Deliverables', 'Reports and management letters.', 60, true, true),
      (v_tpl, 'timeline', 'Timeline', 'Milestones and schedule.', 70, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Fees and assumptions.', 80, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 90, true, true),
      (v_tpl, 'terms', 'Terms', 'Commercial and confidentiality terms.', 100, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Independence Declaration') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Independence Declaration', 'docx', 'templates/rbf/audit/independence_declaration.docx', 'pre_issuance', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Sample Management Letter') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Sample Management Letter', 'pdf', 'templates/rbf/audit/sample_management_letter.pdf', 'always', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- Banking Equipment & Maintenance
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Banking Equipment & Maintenance', 'RBF_BANK_EQUIP', 'operations',
          'Cash processing equipment, CCTV, safes, and maintenance', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'preventive_maintenance';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Operational context and objectives.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'Supply, installation, and maintenance.', 20, true, true),
      (v_tpl, 'technical_requirements', 'Technical Requirements', 'Models, capacity, certifications.', 30, true, true),
      (v_tpl, 'installation_site_prep', 'Installation & Site Prep', 'Power, network, physical layout.', 40, true, true),
      (v_tpl, 'preventive_maintenance', 'Preventive Maintenance', 'PPM schedules, spares, and SLAs.', 50, true, true),
      (v_tpl, 'spares_warranty', 'Spares & Warranty', 'Spare parts and warranty handling.', 60, true, true),
      (v_tpl, 'training', 'Training', 'Operator and maintenance training.', 70, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Supply, installation, AMC.', 80, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 90, true, true),
      (v_tpl, 'terms', 'Terms', 'Commercial and confidentiality terms.', 100, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Site Survey Checklist') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Site Survey Checklist', 'xlsx', 'templates/rbf/operations/site_survey_checklist.xlsx', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Handover Form') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Handover Form', 'docx', 'templates/rbf/operations/handover_form.docx', 'awarded', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- Cash-In-Transit & Secure Logistics (CIT)
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Cash-In-Transit & Secure Logistics', 'RBF_CIT', 'security',
          'CIT services and secure logistics', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'security_compliance';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Cash movement profile and objectives.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'Routes, volumes, time windows.', 20, true, true),
      (v_tpl, 'security_compliance', 'Security & Compliance', 'Personnel vetting, SOPs, certifications.', 30, true, true),
      (v_tpl, 'risk_management', 'Risk Management', 'Threat model, contingencies.', 40, true, true),
      (v_tpl, 'incident_reporting', 'Incident Reporting', 'KPIs and escalation.', 50, true, true),
      (v_tpl, 'insurance_coverage', 'Insurance Coverage', 'Required coverage levels.', 60, true, true),
      (v_tpl, 'service_levels', 'Service Levels', 'OTP and tamper KPIs.', 70, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Route pricing and surcharges.', 80, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 90, true, true),
      (v_tpl, 'terms_confidentiality', 'Terms & Confidentiality', 'Commercial and confidentiality terms.', 100, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Security Vetting Form') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Security Vetting Form', 'docx', 'templates/rbf/security/security_vetting_form.docx', 'pre_issuance', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Incident Template') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Incident Template', 'docx', 'templates/rbf/security/incident_template.docx', 'always', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- Two-Envelope Technical & Financial Proposals
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Two-Envelope Technical & Financial', 'RBF_TECH_FIN_ENVELOPE', 'general',
          'For procurements that require separate technical and financial proposals', false,
          ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'submission_overview';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email, is_required)
    VALUES
      (v_tpl, 'submission_overview', 'Submission Overview',
        'Vendors must submit two separate digital files: **one technical proposal** and **one financial proposal**. Label files clearly (e.g. `VendorName - Technical.pdf` and `VendorName - Financial.xlsx`) and upload them as attachments when responding to this RFQ. Pricing information must be restricted to the financial proposal. Any proposal that combines technical and commercial content may be disqualified.',
        10, true, true, true);
  END IF;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'technical_proposal';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email, is_required)
    VALUES
      (v_tpl, 'technical_proposal', 'Technical Proposal Requirements',
        'Describe the solution, methodology, implementation approach, workplan, team CVs and compliance statements. The technical proposal must **exclude** all pricing or commercial terms. Include evidence of experience, certifications, quality assurance processes, risk management approach, and any mandatory forms (upload as appendices).',
        20, true, true, true);
  END IF;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'financial_proposal';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email, is_required)
    VALUES
      (v_tpl, 'financial_proposal', 'Financial Proposal Requirements',
        'Provide a detailed cost breakdown aligned to the scope. Show unit costs, taxes, optional items and total contract value. State currency (default FJD), payment schedule, validity period, and any assumptions. Do not repeat technical narrative in this document. Clearly reference the corresponding technical proposal sections.',
        30, true, true, true);
  END IF;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'evaluation_method';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'evaluation_method', 'Evaluation & Weighting',
        'The default weighting for this template is **70% technical** and **30% financial**. Evaluation teams should use the compare tab to score the technical proposal against published criteria (such as methodology, team, delivery plan, risk mitigation). Financial proposals are assessed on total cost of ownership and commercial compliance. Document consensus scores in the scoring notes area.',
        40, true, true);
  END IF;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'timeline_clarifications';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'timeline_clarifications', 'Timeline & Clarifications',
        'State the closing date/time, contact point for questions, and process for clarification responses. Remind vendors that late submissions or missing files can result in rejection. Where applicable, require acknowledgement that both documents were submitted on time.',
        50, true, true);
  END IF;

  ---------------------------------------------------------------------------
  -- Facilities & Building Services
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Facilities & Building Services', 'RBF_FACILITIES', 'facilities',
          'HVAC, power, cleaning, and soft services', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'standards_safety';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Facility profile and objectives.', 10, true, true),
      (v_tpl, 'scope', 'Scope', 'HVAC, power, cleaning scope.', 20, true, true),
      (v_tpl, 'standards_safety', 'Standards & Safety', 'Applicable standards and safety protocols.', 30, true, true),
      (v_tpl, 'schedules_sla', 'Schedules & SLA', 'PPM schedules and SLAs.', 40, true, true),
      (v_tpl, 'staffing_quals', 'Staffing & Qualifications', 'Minimum staffing and skills.', 50, true, true),
      (v_tpl, 'reporting', 'Reporting', 'Logs, KPIs, and reports.', 60, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Service pricing and options.', 70, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 80, true, true),
      (v_tpl, 'terms', 'Terms', 'Commercial and confidentiality terms.', 90, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'HSE Requirements') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'HSE Requirements', 'pdf', 'templates/rbf/facilities/hse_requirements.pdf', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'PPM Schedule Template') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'PPM Schedule Template', 'xlsx', 'templates/rbf/facilities/ppm_schedule_template.xlsx', 'always', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- Training & Capacity Building
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'Training & Capacity Building', 'RBF_TRAINING', 'training',
          'Training programs and capability development', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'learning_objectives';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Audience and training objectives.', 10, true, true),
      (v_tpl, 'learning_objectives', 'Learning Objectives', 'Expected outcomes and competencies.', 20, true, true),
      (v_tpl, 'curriculum_outline', 'Curriculum Outline', 'Modules and durations.', 30, true, true),
      (v_tpl, 'trainer_quals', 'Trainer Qualifications', 'Required experience and certifications.', 40, true, true),
      (v_tpl, 'delivery_method', 'Delivery Method', 'Onsite/online/hybrid details.', 50, true, true),
      (v_tpl, 'materials_ip', 'Materials & IP', 'Ownership of materials and usage rights.', 60, true, true),
      (v_tpl, 'assessment_evaluation', 'Assessment & Evaluation', 'Assessments and feedback instruments.', 70, true, true),
      (v_tpl, 'pricing', 'Pricing', 'Per-learner or program pricing.', 80, true, true),
      (v_tpl, 'evaluation', 'Evaluation', 'Method and weighting.', 90, true, true),
      (v_tpl, 'terms', 'Terms', 'Commercial and confidentiality terms.', 100, true, true);
  END IF;

  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Attendance Sheet') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Attendance Sheet', 'xlsx', 'templates/rbf/training/attendance_sheet.xlsx', 'always', 10);
  END IF;
  IF NOT EXISTS (SELECT 1 FROM rfq_template_attachments WHERE rfq_template_id = v_tpl AND label = 'Course Evaluation Form') THEN
    INSERT INTO rfq_template_attachments (rfq_template_id, label, filetype, file_url, include_when, sort_order)
    VALUES (v_tpl, 'Course Evaluation Form', 'docx', 'templates/rbf/training/course_evaluation_form.docx', 'awarded', 20);
  END IF;

  ---------------------------------------------------------------------------
  -- EOI: Market Sounding
  ---------------------------------------------------------------------------
  INSERT INTO rfq_templates (org_id, name, code, category, description, is_default, distribution_channels)
  VALUES (NULL, 'EOI: Market Sounding', 'RBF_EOI_MARKET', 'eoi',
          'Expression of Interest for market sounding', false, ARRAY['email','portal'])
  ON CONFLICT (code) DO UPDATE
    SET name = EXCLUDED.name,
        category = EXCLUDED.category,
        description = EXCLUDED.description,
        is_default = EXCLUDED.is_default,
        distribution_channels = EXCLUDED.distribution_channels
  RETURNING rfq_template_id INTO v_tpl;

  PERFORM 1 FROM rfq_template_sections WHERE rfq_template_id = v_tpl AND section_key = 'interest_statement';
  IF NOT FOUND THEN
    INSERT INTO rfq_template_sections (rfq_template_id, section_key, heading, body_markdown, sort_order, include_in_print, include_in_email)
    VALUES
      (v_tpl, 'background', 'Background', 'Purpose of EOI and context.', 10, true, true),
      (v_tpl, 'interest_statement', 'Statement of Interest', 'Vendor expression of interest and relevance.', 20, true, true),
      (v_tpl, 'capability_summary', 'Capability Summary', 'Core capabilities and capacity.', 30, true, true),
      (v_tpl, 'relevant_experience', 'Relevant Experience', 'Case studies and references.', 40, true, true),
      (v_tpl, 'indicative_approach', 'Indicative Approach', 'High-level approach and timeline.', 50, true, true),
      (v_tpl, 'submission', 'Submission', 'Instructions and deadline.', 60, true, true),
      (v_tpl, 'shortlisting_criteria', 'Shortlisting Criteria', 'How EOIs will be shortlisted.', 70, true, true);
  END IF;

END $$;

-- ============================================================================
-- INVENTORY MANAGEMENT FORMS (Phase 4 Declarative)
-- ============================================================================

-- Update forms sequence to avoid primary key conflicts
SELECT setval('forms_id_seq', COALESCE((SELECT MAX(id) FROM forms), 0) + 1, false);

-- Delete existing inventory forms if they exist
DELETE FROM forms WHERE name IN (
    'inventory_receive_form',
    'inventory_transfer_form', 
    'inventory_break_bulk_form',
    'inventory_adjustment_form',
    'warehouse_form'
);

-- Inventory Receive Form
INSERT INTO forms (
    name,
    description,
    mapped_table,
    columns,
    layout_type,
    elements
) VALUES (
    'inventory_receive_form',
    'Receive inventory into the system from purchase orders or direct receipts',
    'inventory_receive',
    2,
    'grid',
    '[
        {
            "name": "lpo_number",
            "label": "LPO/PO Number",
            "type": "select-search",
            "required": false,
            "help_text": "Select an LPO to auto-populate products, or leave blank for direct receipt",
            "options_table": "purchase_orders",
            "options_label_column": "order_number",
            "options_value_column": "purchase_order_id",
            "onchange": "inventory:loadPurchaseOrderItems"
        },
        {
            "name": "vendor_id",
            "label": "Vendor/Supplier",
            "type": "select-search",
            "required": true,
            "options_table": "vendors",
            "options_label_column": "vendorname",
            "options_value_column": "vendor_id"
        },
        {
            "name": "branch_id",
            "label": "Receiving Warehouse/Branch",
            "type": "select",
            "required": true,
            "options_table": "branches",
            "options_label_column": "name",
            "options_value_column": "branch_id"
        },
        {
            "name": "delivery_note_number",
            "label": "Delivery Note Number",
            "type": "text",
            "required": false
        },
        {
            "name": "invoice_number",
            "label": "Invoice Number",
            "type": "text",
            "required": false
        },
        {
            "name": "date",
            "label": "Receive Date",
            "type": "date",
            "required": true,
            "default": "today"
        },
        {
            "name": "items",
            "label": "Items to Receive",
            "type": "dynamic-table",
            "required": true,
            "colspan": 2,
            "columns": [
                {
                    "name": "product_id",
                    "label": "Product",
                    "type": "select-search",
                    "options_table": "products",
                    "options_label_column": "name",
                    "options_value_column": "product_id"
                },
                {
                    "name": "quantity_ordered",
                    "label": "Qty Ordered",
                    "type": "number",
                    "readonly": true
                },
                {
                    "name": "quantity_received",
                    "label": "Qty Received",
                    "type": "number",
                    "required": true,
                    "min": 0.01
                },
                {
                    "name": "unit",
                    "label": "Unit",
                    "type": "select",
                    "options": [
                        {"value": "PIECE", "label": "Piece", "display_text": "Piece"},
                        {"value": "PACK", "label": "Pack", "display_text": "Pack"},
                        {"value": "CARTON", "label": "Carton", "display_text": "Carton"},
                        {"value": "BOX", "label": "Box", "display_text": "Box"}
                    ]
                },
                {
                    "name": "unit_cost",
                    "label": "Unit Cost",
                    "type": "number",
                    "step": 0.01
                },
                {
                    "name": "batch_number",
                    "label": "Batch #",
                    "type": "text"
                },
                {
                    "name": "expiry_date",
                    "label": "Expiry Date",
                    "type": "date"
                },
                {
                    "name": "notes",
                    "label": "Notes",
                    "type": "text"
                }
            ],
            "rows": []
        },
        {
            "name": "notes",
            "label": "General Notes",
            "type": "textarea",
            "required": false,
            "colspan": 2
        }
    ]'::jsonb
);

-- Inventory Transfer Form
INSERT INTO forms (
    name,
    description,
    mapped_table,
    columns,
    layout_type,
    elements
) VALUES (
    'inventory_transfer_form',
    'Transfer inventory between warehouses or locations',
    'inventory_transfers',
    2,
    'grid',
    '[
        {
            "name": "from_branch_id",
            "label": "From Warehouse/Branch",
            "type": "select",
            "required": true,
            "options_table": "branches",
            "options_label_column": "name",
            "options_value_column": "branch_id"
        },
        {
            "name": "to_branch_id",
            "label": "To Warehouse/Branch",
            "type": "select",
            "required": true,
            "options_table": "branches",
            "options_label_column": "name",
            "options_value_column": "branch_id"
        },
        {
            "name": "transfer_date",
            "label": "Transfer Date",
            "type": "date",
            "required": true,
            "default": "today"
        },
        {
            "name": "reference_number",
            "label": "Transfer Reference",
            "type": "text",
            "required": false
        },
        {
            "name": "items",
            "label": "Items to Transfer",
            "type": "dynamic-table",
            "required": true,
            "colspan": 2,
            "columns": [
                {
                    "name": "product_id",
                    "label": "Product",
                    "type": "select-search",
                    "options_table": "products",
                    "options_label_column": "name",
                    "options_value_column": "product_id"
                },
                {
                    "name": "batch_number",
                    "label": "Batch Number",
                    "type": "text"
                },
                {
                    "name": "quantity",
                    "label": "Quantity",
                    "type": "number"
                },
                {
                    "name": "unit",
                    "label": "Unit",
                    "type": "select",
                    "options": [
                        {"value": "PIECE", "label": "Piece", "display_text": "Piece"},
                        {"value": "PACK", "label": "Pack", "display_text": "Pack"},
                        {"value": "CARTON", "label": "Carton", "display_text": "Carton"},
                        {"value": "BOX", "label": "Box", "display_text": "Box"}
                    ]
                },
                {
                    "name": "break_bulk",
                    "label": "Break Bulk?",
                    "type": "checkbox"
                },
                {
                    "name": "notes",
                    "label": "Notes",
                    "type": "text"
                }
            ],
            "rows": []
        },
        {
            "name": "notes",
            "label": "Transfer Notes",
            "type": "textarea",
            "required": false,
            "colspan": 2
        }
    ]'::jsonb
);

-- Inventory Break Bulk Form
INSERT INTO forms (
    name,
    description,
    mapped_table,
    columns,
    layout_type,
    elements
) VALUES (
    'inventory_break_bulk_form',
    'Break down bulk items into smaller units',
    'inventory_breaks',
    2,
    'grid',
    '[
        {
            "name": "product_id",
            "label": "Product",
            "type": "select-search",
            "required": true,
            "options_table": "products",
            "options_label_column": "name",
            "options_value_column": "product_id",
            "help_text": "Select the product to break down into smaller units"
        },
        {
            "name": "branch_id",
            "label": "Warehouse/Branch",
            "type": "select",
            "required": true,
            "options_table": "branches",
            "options_label_column": "name",
            "options_value_column": "branch_id"
        },
        {
            "name": "from_unit",
            "label": "From Unit (Bulk)",
            "type": "select",
            "required": true,
            "options": [
                {"value": "CARTON", "label": "Carton", "display_text": "Carton"},
                {"value": "BOX", "label": "Box", "display_text": "Box"},
                {"value": "PACK", "label": "Pack", "display_text": "Pack"},
                {"value": "MASTER", "label": "Master Unit", "display_text": "Master Unit"}
            ],
            "help_text": "The larger unit you are breaking down"
        },
        {
            "name": "to_unit",
            "label": "To Unit (Individual)",
            "type": "select",
            "required": true,
            "options": [
                {"value": "PIECE", "label": "Piece", "display_text": "Piece"},
                {"value": "PACK", "label": "Pack", "display_text": "Pack"},
                {"value": "UNIT", "label": "Base Unit", "display_text": "Base Unit"}
            ],
            "help_text": "The smaller unit you are creating"
        },
        {
            "name": "quantity",
            "label": "Quantity to Break",
            "type": "number",
            "required": true,
            "min": 0.01,
            "help_text": "How many bulk units to break down"
        },
        {
            "name": "batch_number",
            "label": "Batch Number",
            "type": "text",
            "required": false
        },
        {
            "name": "notes",
            "label": "Notes",
            "type": "textarea",
            "required": false,
            "colspan": 2
        }
    ]'::jsonb
);

-- Inventory Adjustment Form
INSERT INTO forms (
    name,
    description,
    mapped_table,
    columns,
    layout_type,
    elements
) VALUES (
    'inventory_adjustment_form',
    'Adjust inventory quantities for stock takes, damage, theft, etc.',
    'inventory_txn',
    2,
    'grid',
    '[
        {
            "name": "inventory_id",
            "label": "Inventory ID",
            "type": "hidden"
        },
        {
            "name": "product_name",
            "label": "Product",
            "type": "text",
            "required": false,
            "readonly": true,
            "visible_when": "inventory_id"
        },
        {
            "name": "product_id",
            "label": "Product",
            "type": "select-search",
            "required": true,
            "options_table": "products",
            "options_label_column": "name",
            "options_value_column": "product_id",
            "visible_when": "!inventory_id"
        },
        {
            "name": "current_qty",
            "label": "Current Stock",
            "type": "number",
            "readonly": true,
            "visible_when": "inventory_id"
        },
        {
            "name": "adjustment_type",
            "label": "Adjustment Type",
            "type": "select",
            "required": true,
            "options": [
                {"value": "increase", "label": "Increase (Add Stock)"},
                {"value": "decrease", "label": "Decrease (Remove Stock)"}
            ]
        },
        {
            "name": "quantity",
            "label": "Adjustment Quantity",
            "type": "number",
            "required": true,
            "min": 0.01
        },
        {
            "name": "branch_id",
            "label": "Warehouse/Branch",
            "type": "select",
            "required": true,
            "options_table": "branches",
            "options_label_column": "name",
            "options_value_column": "branch_id"
        },
        {
            "name": "reason",
            "label": "Reason",
            "type": "select",
            "required": true,
            "options": [
                {"value": "stock_take", "label": "Stock Take Correction"},
                {"value": "damage", "label": "Damaged Goods"},
                {"value": "theft", "label": "Theft/Loss"},
                {"value": "return", "label": "Customer Return"},
                {"value": "expired", "label": "Expired Product"},
                {"value": "other", "label": "Other"}
            ]
        },
        {
            "name": "reference_number",
            "label": "Reference Number",
            "type": "text",
            "required": false
        },
        {
            "name": "notes",
            "label": "Notes/Details",
            "type": "textarea",
            "required": true,
            "colspan": 2
        }
    ]'::jsonb
);

-- Warehouse Form
INSERT INTO forms (
    name,
    description,
    mapped_table,
    columns,
    layout_type,
    elements
) VALUES (
    'warehouse_form',
    'Create and manage warehouse/branch locations',
    'branches',
    2,
    'grid',
    '[
        {
            "name": "name",
            "label": "Warehouse/Branch Name",
            "type": "text",
            "required": true
        },
        {
            "name": "code",
            "label": "Warehouse Code",
            "type": "text",
            "required": true
        },
        {
            "name": "type",
            "label": "Location Type",
            "type": "select",
            "required": true,
            "options": [
                {"value": "warehouse", "label": "Warehouse"},
                {"value": "store", "label": "Store/Outlet"},
                {"value": "branch", "label": "Branch Office"},
                {"value": "transit", "label": "In Transit"}
            ]
        },
        {
            "name": "parent_branch_id",
            "label": "Parent Branch",
            "type": "select",
            "required": false,
            "options_table": "branches",
            "options_label_column": "name",
            "options_value_column": "branch_id",
            "options_where": "isDeleted = false",
            "help_text": "Leave empty for top-level branch. Select a parent to create a child branch (enables automatic inventory transfers between related branches)."
        },
        {
            "name": "address",
            "label": "Address",
            "type": "textarea",
            "required": false,
            "colspan": 2
        }
    ]'::jsonb
);

-- ============================================================================
-- POS Sessions View Permissions
-- ============================================================================
-- Grant select permissions on the enhanced POS sessions view
GRANT SELECT ON pos_sessions_with_details TO PUBLIC;

-- ============================================================================
-- Import/Export Configurations
-- ============================================================================
-- Default import/export configurations for various data types
-- ============================================================================

-- ============================================================================
-- Products Catalog (Generic)
-- ============================================================================
-- Import and export product catalog including all product details
-- Used by: /api/import-export/import/products_catalog and /api/import-export/export/products_catalog
-- ============================================================================
INSERT INTO import_export_configs (name, description, type, table_name, config) VALUES 
(
  'products_catalog',
  'Import and export product catalog including all product details',
  'both',
  'products',
  '{
    "table": "products",
    "primary_key": "product_id",
    "filename": "products_catalog",
    "columns": [
      "product_id",
      "name",
      "description",
      "price",
      "barcode",
      "brand",
      "product_number",
      "category_id",
      "tax_rates"
    ],
    "field_mappings": {
      "Product ID": "product_id",
      "Name": "name",
      "Description": "description",
      "Price": "price",
      "Barcode": "barcode",
      "Brand": "brand",
      "Product Number": "product_number",
      "Category": "category_id",
      "VAT Rate": {"column": "tax_rates", "json_field": "vat"},
      "STT Rate": {"column": "tax_rates", "json_field": "stt"}
    },
    "field_labels": {
      "product_id": "Product ID",
      "name": "Name",
      "description": "Description",
      "price": "Price",
      "barcode": "Barcode",
      "brand": "Brand",
      "product_number": "Product Number"
    },
    "transforms": {
      "price": {
        "type": "number",
        "decimals": 2
      },
      "category_id": {
        "type": "lookup",
        "table": "product_categories",
        "key_column": "name",
        "value_column": "category_id"
      }
    },
    "export_transforms": {
      "price": {
        "type": "number",
        "decimals": 2
      },
      "category_id": {
        "type": "lookup",
        "table": "product_categories",
        "key_column": "category_id",
        "display_column": "name"
      },
      "tax_rates": {
        "type": "json_decode"
      }
    },
    "validations": {
      "name": {
        "required": true,
        "max_length": 255
      },
      "price": {
        "required": false
      }
    },
    "unique_fields": ["barcode", "product_number"],
    "update_existing": true,
    "filters": {
      "isDeleted": false
    },
    "joins": [
      {
        "type": "left",
        "table": "product_categories",
        "first": "products.category_id",
        "operator": "=",
        "second": "product_categories.category_id"
      }
    ],
    "order_by": {
      "name": "ASC"
    }
  }'
) ON CONFLICT (name) DO UPDATE SET
  description = EXCLUDED.description,
  type = EXCLUDED.type,
  table_name = EXCLUDED.table_name,
  config = EXCLUDED.config,
  updatedAt = now();

-- ============================================================================
-- GoFrugal Products Import
-- ============================================================================
-- Import products from GoFrugal POS system CSV export format
-- Handles category extraction and product parsing from GoFrugal structure
-- ============================================================================
INSERT INTO import_export_configs (name, description, type, table_name, config) VALUES 
(
  'products_gofrugal',
  'Import products from GoFrugal POS CSV export format with automatic category detection',
  'import',
  'products',
  '{
    "table": "products",
    "primary_key": "product_id",
    "filename": "products_gofrugal",
    "format": "gofrugal_csv",
    "field_mappings": {
      "Code": "barcode",
      "Name": "name", 
      "Description": "description",
      "Retail": "price",
      "COG": "cost_price"
    },
    "category_detection": {
      "enabled": true,
      "category_row_pattern": "^,Category :,,,,([^,]+),",
      "product_start_pattern": "^,[^,]+,",
      "skip_empty_rows": true,
      "skip_header_rows": 10
    },
    "default_values": {
      "tax_rates": {"vat": "G", "stt": ""},
      "base_unit": "PIECE",
      "isDeleted": false
    },
    "transforms": {
      "price": {
        "type": "number",
        "decimals": 2,
        "default": 0.00
      },
      "cost_price": {
        "type": "number",
        "decimals": 2,
        "default": 0.00
      },
      "barcode": {
        "type": "string",
        "trim": true,
        "required": true
      },
      "name": {
        "type": "string",
        "trim": true,
        "required": true,
        "max_length": 255
      }
    },
    "validations": {
      "name": {
        "required": true,
        "max_length": 255
      },
      "barcode": {
        "required": true,
        "max_length": 100
      },
      "price": {
        "required": false,
        "min": 0
      }
    },
    "unique_fields": ["barcode"],
    "update_existing": true,
    "filters": {
      "isDeleted": false
    },
    "import_options": {
      "create_categories": true,
      "skip_zero_qty": false,
      "auto_assign_org": true
    }
  }'
) ON CONFLICT (name) DO UPDATE SET
  description = EXCLUDED.description,
  type = EXCLUDED.type,
  table_name = EXCLUDED.table_name,
  config = EXCLUDED.config,
  updatedAt = now();

-- ============================================================================
-- Customer Management Forms
-- ============================================================================

-- Customer Type Selection Form (Initial Form)
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  199,
  'Add Customer',
  'Select customer type',
  NULL,
  $json$[
    {"label":"Customer Type","field_name":"customer_type","data_column":"customer_type","type_id":4,"order_index":1,"required":true,"options":[
      {"display_text":"Individual","value":"Individual"},
      {"display_text":"Corporate","value":"Corporate"},
      {"display_text":"Government","value":"Government"}
    ]}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO UPDATE SET
  name = EXCLUDED.name,
  description = EXCLUDED.description,
  elements = EXCLUDED.elements,
  updatedAt = now();

-- Button to open appropriate form based on customer type selection
DELETE FROM form_buttons WHERE form_id = 199 AND label = 'Open Form';
INSERT INTO form_buttons (form_id, label, action_type, action_payload, order_index)
VALUES
  (199, 'Open Form', 'open-form',
   '{"lookupTable":"form_wizard_lookup","lookupField":"customer_type","valueColumn":"name","formColumn":"form_id","prefillFields":["customer_type","Individual","Corporate","Government"]}',
   1
 );

-- Business Customer Form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  200,
  'Business Customer',
  'Register business/corporate customer',
  'customers',
  $json$[
    {"label":"Company Name","field_name":"name","data_column":"name","type_id":1,"order_index":1,"required":true},
    {"label":"Business Registration Number","field_name":"business_reg_number","data_column":"business_reg_number","type_id":1,"order_index":2},
    {"label":"TIN","field_name":"tin","data_column":"tin","type_id":1,"order_index":3},
    {"label":"Email","field_name":"email","data_column":"email","type_id":15,"order_index":4},
    {"label":"Phone Number","field_name":"phone_number","data_column":"phone_number","type_id":1,"order_index":5},
    {"label":"Address","field_name":"address","data_column":"address","type_id":8,"order_index":6},
    {"label":"Contact Person Name","field_name":"contact_person_name","data_column":"contact_person_name","type_id":1,"order_index":7},
    {"label":"Contact Person Phone","field_name":"contact_person_phone","data_column":"contact_person_phone","type_id":1,"order_index":8},
    {"label":"Contact Person Email","field_name":"contact_person_email","data_column":"contact_person_email","type_id":15,"order_index":9},
    {"label":"Industry","field_name":"industry","data_column":"industry","type_id":1,"order_index":10},
    {"label":"Credit Limit","field_name":"credit_limit","data_column":"credit_limit","type_id":2,"order_index":11},
    {"field_name":"customer_type","data_column":"customer_type","type_id":17,"default_value":"business","order_index":12}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Individual Customer Form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  201,
  'Individual Customer',
  'Register individual/personal customer',
  'customers',
  $json$[
    {"label":"First Name","field_name":"first_name","data_column":"name","type_id":1,"order_index":1,"required":true,"transform":"combine_names"},
    {"label":"Last Name","field_name":"last_name","data_column":"name","type_id":1,"order_index":2,"required":true,"transform":"combine_names"},
    {"label":"TIN Number","field_name":"tin","data_column":"tin","type_id":1,"order_index":3},
    {"label":"Email","field_name":"email","data_column":"email","type_id":15,"order_index":4},
    {"label":"Phone Number","field_name":"phone_number","data_column":"phone_number","type_id":1,"order_index":5},
    {"label":"Address","field_name":"address","data_column":"address","type_id":8,"order_index":6},
    {"field_name":"customer_type","data_column":"customer_type","type_id":17,"default_value":"individual","order_index":7}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Government Customer Form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  202,
  'Government Customer',
  'Register government/public sector customer',
  'customers',
  $json$[
    {"label":"Department/Agency Name","field_name":"name","data_column":"name","type_id":1,"order_index":1,"required":true},
    {"label":"Government ID Number","field_name":"business_reg_number","data_column":"business_reg_number","type_id":1,"order_index":2},
    {"label":"TIN","field_name":"tin","data_column":"tin","type_id":1,"order_index":3},
    {"label":"Email","field_name":"email","data_column":"email","type_id":15,"order_index":4},
    {"label":"Phone Number","field_name":"phone_number","data_column":"phone_number","type_id":1,"order_index":5},
    {"label":"Address","field_name":"address","data_column":"address","type_id":8,"order_index":6},
    {"label":"Contact Person Name","field_name":"contact_person_name","data_column":"contact_person_name","type_id":1,"order_index":7},
    {"label":"Contact Person Phone","field_name":"contact_person_phone","data_column":"contact_person_phone","type_id":1,"order_index":8},
    {"label":"Contact Person Email","field_name":"contact_person_email","data_column":"contact_person_email","type_id":15,"order_index":9},
    {"label":"Ministry/Department","field_name":"industry","data_column":"industry","type_id":1,"order_index":10},
    {"label":"Credit Limit","field_name":"credit_limit","data_column":"credit_limit","type_id":2,"order_index":11},
    {"field_name":"customer_type","data_column":"customer_type","type_id":17,"default_value":"government","order_index":12}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- ============================================================================
-- Invoice Form (Declarative)
-- ============================================================================

-- Delete existing form if it exists
DELETE FROM forms WHERE id = 9001;

-- Insert declarative invoice form definition
INSERT INTO forms (id, name, description, mapped_table, columns, layout_type, elements, isdeleted) VALUES (
  9001,
  'Invoice Form',
  'Create and edit invoices with line items, formulas, and sections',
  'invoices',
  1,
  'grid',
  $json$[
    {
      "step": 1,
      "order": 1,
      "layout": {
        "type": "flex",
        "classes": "flex flex-wrap gap-4",
        "gap": "1rem"
      },
      "elements": [
        {
          "name": "customer_id",
          "field_name": "customer_id",
          "label": "Customer",
          "type": "select-search",
          "type_id": 6,
          "width": "flex-1",
          "options_table": "customers",
          "options_label_column": "name",
          "options_value_column": "customer_id",
          "required": true,
          "validation": {"required": true}
        },
        {
          "name": "invoice_date",
          "field_name": "invoice_date",
          "label": "Invoice Date",
          "type": "date",
          "type_id": 8,
          "width": "flex-1",
          "default_value": "today"
        },
        {
          "name": "due_date",
          "field_name": "due_date",
          "label": "Due Date",
          "type": "date",
          "type_id": 8,
          "width": "flex-1"
        }
      ]
    },
    {
      "step": 2,
      "order": 2,
      "layout": {
        "type": "grid",
        "classes": "form-grid",
        "columns": "1fr",
        "gap": "1rem"
      },
      "elements": [
        {
          "name": "line_items",
          "field_name": "line_items",
          "label": "Line Items",
          "type": "dynamic-table",
          "type_id": 15,
          "columns": [
            {
              "name": "name",
              "label": "Item Name",
              "type": "text",
              "width": "25%"
            },
            {
              "name": "description",
              "label": "Description",
              "type": "text",
              "width": "30%"
            },
            {
              "name": "unit_price",
              "label": "Unit Price",
              "type": "number",
              "width": "15%",
              "attrs": {"step": "0.01", "min": "0"}
            },
            {
              "name": "quantity",
              "label": "Quantity",
              "type": "number",
              "width": "10%",
              "attrs": {"step": "1", "min": "1"}
            },
            {
              "name": "total",
              "label": "Total",
              "type": "number",
              "width": "15%",
              "readonly": true,
              "formula": "unit_price * quantity",
              "attrs": {"step": "0.01"}
            }
          ],
          "aggregates": [
            {
              "column": "total",
              "operation": "sum",
              "display": "Grand Total: ${{value}}"
            }
          ],
          "min_rows": 1,
          "add_button_text": "Add Product",
          "row_label_prefix": "Product"
        }
      ]
    },
    {
      "step": 4,
      "order": 4,
      "layout": {
        "type": "flex",
        "classes": "flex flex-wrap gap-4",
        "gap": "1rem"
      },
      "elements": [
        {
          "name": "notes_additional",
          "field_name": "notes_additional",
          "label": "Additional Notes",
          "type": "textarea",
          "type_id": 2,
          "width": "flex-1",
          "rows": 4,
          "placeholder": "Enter additional notes..."
        },
        {
          "name": "payment_terms_details",
          "field_name": "payment_terms_details",
          "label": "Payment Terms Details",
          "type": "textarea",
          "type_id": 2,
          "width": "flex-1",
          "rows": 4,
          "placeholder": "Enter payment terms details..."
        }
      ]
    },
    {
      "name": "submit_btn",
      "type": "button",
      "label": "Save Invoice",
      "classes": ["btn", "btn-primary", "mr-2"],
      "action": "submit"
    },
    {
      "name": "cancel_btn",
      "type": "button",
      "label": "Cancel",
      "classes": ["btn", "btn-ghost"],
      "action": "close"
    }
  ]$json$::jsonb,
  false
);
-- Risk Assessment Hazard form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  76,
  'Risk Assessment Hazard',
  'Identify hazards and controls',
  'risk_assessment_hazards',
  '[{"label":"Hazard Description","field_name":"hazard_description","data_column":"hazard_description","type_id":7,"order_index":1},
    {"label":"Who Might Be Harmed","field_name":"who_might_be_harmed","data_column":"who_might_be_harmed","type_id":1,"order_index":2},
    {"label":"Existing Controls","field_name":"existing_control_measures","data_column":"existing_control_measures","type_id":7,"order_index":3},
    {"label":"Risk Rating Before","field_name":"risk_rating_before","data_column":"risk_rating_before","type_id":2,"order_index":4},
    {"label":"Additional Controls","field_name":"additional_controls","data_column":"additional_controls","type_id":7,"order_index":5},
    {"label":"Residual Risk","field_name":"residual_risk_rating","data_column":"residual_risk_rating","type_id":2,"order_index":6},
    {"label":"Responsible Person","field_name":"responsible_person","data_column":"responsible_person","type_id":1,"order_index":7}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Risk Assessment PPE form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  77,
  'Risk Assessment PPE',
  'Personal protective equipment checklist',
  'risk_assessment_ppe',
  '[{"label":"Checklist Item","field_name":"checklist_item","data_column":"checklist_item","type_id":1,"order_index":1}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Risk Assessment Sign-off form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  78,
  'Risk Assessment Sign-off',
  'Record assessment approvals',
  'risk_assessment_signoffs',
  '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
    {"label":"Position","field_name":"position","data_column":"position","type_id":1,"order_index":2},
    {"label":"Signature","field_name":"signature","data_column":"signature","type_id":7,"order_index":3},
    {"label":"Signed At","field_name":"signed_at","data_column":"signed_at","type_id":3,"order_index":4}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Wizard configuration for risk assessments
INSERT INTO form_wizards (id, name, description, tenant_id, branch_id)
VALUES (4, 'Risk Assessment Wizard', 'Guided risk assessment entry', NULL, NULL)
ON CONFLICT DO NOTHING;

INSERT INTO form_wizard_steps (wizard_id, step_number, form_id, condition_field, condition_value)
VALUES
  (4, 1, 75, NULL, NULL)
ON CONFLICT DO NOTHING;


-- Risk Identification form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  80,
  'Risk Identification',
  'Identify risks',
  'risk_identifications',
  $json$
  [
    {"label":"Risk Description","field_name":"risk_description","data_column":"risk_description","type_id":7,"order_index":1},
    {"label":"Risk category","field_name":"risk_category_id","data_column":"risk_category_id","type_id":4,"options_table":"risk_categories","options_label_column":"name","options_value_column":"id","order_index":2},
    {"label":"Root Cause","field_name":"root_cause","data_column":"root_cause","type_id":1,"order_index":3},
    {"label":"Likelihood","field_name":"likelihood","data_column":"likelihood","type_id":4,"order_index":4,"options":[{"display_text":"1","value":"1"},{"display_text":"2","value":"2"},{"display_text":"3","value":"3"},{"display_text":"4","value":"4"},{"display_text":"5","value":"5"}]},
    {"label":"Impact","field_name":"impact","data_column":"impact","type_id":4,"order_index":5,"options":[{"display_text":"1","value":"1"},{"display_text":"2","value":"2"},{"display_text":"3","value":"3"},{"display_text":"4","value":"4"},{"display_text":"5","value":"5"}]},
    {"label":"Current Controls","field_name":"current_controls","data_column":"current_controls","type_id":7,"order_index":6}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO table_views (form_id, name, columns, sort_by, sort_dir)
VALUES (
  80,
  'Default',
  '["risk_description","risk_category_id","risk_category_name","likelihood","impact",{"field":"risk_rating","formula":"impact * likelihood"}]',
  'risk_description',
  'ASC'
);

/* ---- Risk Category (id 74) – JSON format ---- */
INSERT INTO forms
        (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT  79,
        'Risk Category',
        'Risk classification',
        'risk_categories',
        '[
          {"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
          {"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":2}
         ]',
        NULL,   -- tenant_id
        NULL    -- branch_id
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 79);

-- Form 624: Quick Time Clock Entry
-- Simplified form for quick clock in/out entries with hidden pre-filled fields
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id) VALUES (
  624,
  'Time Clock Entry',
  'Quick clock in/out entry for employees',
  'time_clocks',
  $json$[
    {
      "id": 1,
      "name": "user_id",
      "label": "Employee",
      "type": 16,
      "data_column": "user_id",
      "required": true,
      "order": 1,
      "hidden": true
    },
    {
      "id": 2,
      "name": "clock_type",
      "label": "Clock Type",
      "type": 16,
      "data_column": "clock_type",
      "required": true,
      "order": 2,
      "hidden": true
    },
    {
      "id": 3,
      "name": "clocked_at",
      "label": "Date & Time",
      "type": 10,
      "data_column": "clocked_at",
      "required": true,
      "order": 3
    }
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO UPDATE SET
  name = EXCLUDED.name,
  description = EXCLUDED.description,
  mapped_table = EXCLUDED.mapped_table,
  elements = EXCLUDED.elements;



INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  81
  ,
  'Calendar Category',
  'Manage calendar categories',
  'calendar_categories',
  $json$
  [
    {"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
    {"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":2}
  ]
  $json$::jsonb,
  NULL,
  NULL
)
ON CONFLICT (id) DO NOTHING;


-- Incident Status form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 82, 'Incident Status', 'Manage incident status options', 'ohs_incident_statuses',
       '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
         {"label":"Purpose","field_name":"purpose","data_column":"purpose","type_id":7,"order_index":2}]',
       NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 82);


-- Five Whys form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 83, 'Five Whys', 'Record Five Whys analysis', 'ohs_five_whys',
       $json$
       [
         {"label":"Incident","field_name":"incident_id","data_column":"incident_id","type_id":4,"order_index":1,"options_table":"ohs_incidents","options_label_column":"id","options_value_column":"id"},
         {"label":"Why 1","field_name":"why1","json_column":"whys","type_id":1,"order_index":2},
         {"label":"Why 2","field_name":"why2","json_column":"whys","type_id":1,"order_index":3},
         {"label":"Why 3","field_name":"why3","json_column":"whys","type_id":1,"order_index":4},
         {"label":"Why 4","field_name":"why4","json_column":"whys","type_id":1,"order_index":5},
         {"label":"Why 5","field_name":"why5","json_column":"whys","type_id":1,"order_index":6}
       ]
       $json$::jsonb,
       NULL,
       NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 83);


SELECT setval('calendar_events_id_seq', (SELECT MAX(id) FROM calendar_events));



-- Corrective Action form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 83, 'Corrective Action', 'Track corrective actions for incidents', 'corrective_actions',
       '[{"label":"Incident","field_name":"incident_id","data_column":"incident_id","type_id":4,"order_index":1,"options_table":"ohs_incidents","options_label_column":"short_desc","options_value_column":"id"},
         {"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":2},
         {"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":3},
         {"label":"Steps","field_name":"steps","data_column":"steps","type_id":7,"order_index":4},
         {"label":"Responsible Person","field_name":"responsible_user_id","data_column":"responsible_user_id","type_id":4,"order_index":5,"options_table":"users","options_label_column":"full_name","options_value_column":"id"},
         {"label":"Status","field_name":"status","data_column":"status","type_id":1,"order_index":6}]',
       NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 83);



-- Risk Assessment Type form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  84,
  'Risk Assessment Type',
  'Manage risk assessment classifications',
  'risk_assessment_types',
  '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
    {"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":2},
    {"label":"Form","field_name":"form_id","data_column":"form_id","type_id":4,"options_table":"forms","options_label_column":"name","options_value_column":"id","order_index":3}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Additional risk assessment forms
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  85,
  'Water Treatment Plant Risk Assessment',
  'Assessment of operational and chemical risks in treatment facilities',
  'risk_assessments',
  '[{"field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":1,"order_index":0},
    {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Assessment Date","field_name":"assessment_date","data_column":"assessment_date","type_id":3,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Assessor Names","field_name":"assessor_names","json_column":"form_data","type_id":1,"order_index":4},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":5},
    {"label":"Approver","field_name":"approver_name","json_column":"form_data","type_id":1,"order_index":6},
    {"label":"Work Description","field_name":"work_description","json_column":"form_data","type_id":7,"order_index":7},
    {"label":"Permit Requirements","field_name":"permit_requirements","json_column":"form_data","type_id":7,"order_index":8},
    {"label":"Chemical Used","field_name":"chemical","json_column":"form_data","type_id":1,"order_index":9},
    {"label":"Hazard Identified","field_name":"hazard","json_column":"form_data","type_id":7,"order_index":10},
    {"label":"Risk Rating","field_name":"risk_rating","json_column":"form_data","type_id":2,"order_index":11},
    {"label":"Control Measures","field_name":"controls","json_column":"form_data","type_id":7,"order_index":12}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  86,
  'Pipeline & Infrastructure Risk Assessment',
  'Evaluation of potential failure points across distribution infrastructure',
  'risk_assessments',
  '[{"field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":1,"order_index":0},
    {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Assessment Date","field_name":"assessment_date","data_column":"assessment_date","type_id":3,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Assessor Names","field_name":"assessor_names","json_column":"form_data","type_id":1,"order_index":4},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":5},
    {"label":"Approver","field_name":"approver_name","json_column":"form_data","type_id":1,"order_index":6},
    {"label":"Work Description","field_name":"work_description","json_column":"form_data","type_id":7,"order_index":7},
    {"label":"Permit Requirements","field_name":"permit_requirements","json_column":"form_data","type_id":7,"order_index":8},
    {"label":"Pipe Segment","field_name":"pipe_segment","json_column":"form_data","type_id":1,"order_index":9},
    {"label":"Material Type","field_name":"material","json_column":"form_data","type_id":1,"order_index":10},
    {"label":"Identified Risk","field_name":"risk","json_column":"form_data","type_id":7,"order_index":11},
    {"label":"Failure Likelihood","field_name":"likelihood","json_column":"form_data","type_id":2,"order_index":12},
    {"label":"Mitigation Action","field_name":"action","json_column":"form_data","type_id":7,"order_index":13}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  87,
  'Environmental and Climate Risk Assessment',
  'Assesses environmental vulnerabilities to water supply and treatment',
  'risk_assessments',
  '[{"field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":1,"order_index":0},
    {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Assessment Date","field_name":"assessment_date","data_column":"assessment_date","type_id":3,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Assessor Names","field_name":"assessor_names","json_column":"form_data","type_id":1,"order_index":4},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":5},
    {"label":"Approver","field_name":"approver_name","json_column":"form_data","type_id":1,"order_index":6},
    {"label":"Work Description","field_name":"work_description","json_column":"form_data","type_id":7,"order_index":7},
    {"label":"Permit Requirements","field_name":"permit_requirements","json_column":"form_data","type_id":7,"order_index":8},
    {"label":"Area Assessed","field_name":"area","json_column":"form_data","type_id":1,"order_index":9},
    {"label":"Environmental Risk","field_name":"env_risk","json_column":"form_data","type_id":7,"order_index":10},
    {"label":"Climate Trigger","field_name":"trigger","json_column":"form_data","type_id":1,"order_index":11},
    {"label":"Severity","field_name":"severity","json_column":"form_data","type_id":2,"order_index":12},
    {"label":"Control Plan","field_name":"plan","json_column":"form_data","type_id":7,"order_index":13}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  88,
  'Occupational Health & Safety Risk Assessment',
  'OHS-focused hazard evaluation in operational areas and fieldwork',
  'risk_assessments',
  '[{"field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":1,"order_index":0},
    {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Assessment Date","field_name":"assessment_date","data_column":"assessment_date","type_id":3,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Assessor Names","field_name":"assessor_names","json_column":"form_data","type_id":1,"order_index":4},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":5},
    {"label":"Approver","field_name":"approver_name","json_column":"form_data","type_id":1,"order_index":6},
    {"label":"Work Description","field_name":"work_description","json_column":"form_data","type_id":7,"order_index":7},
    {"label":"Permit Requirements","field_name":"permit_requirements","json_column":"form_data","type_id":7,"order_index":8},
    {"label":"Job Task","field_name":"task","json_column":"form_data","type_id":1,"order_index":9},
    {"label":"Identified Hazard","field_name":"hazard","json_column":"form_data","type_id":7,"order_index":10},
    {"label":"Risk Level","field_name":"risk_level","json_column":"form_data","type_id":2,"order_index":11},
    {"label":"PPE Required","field_name":"ppe","json_column":"form_data","type_id":1,"order_index":12},
    {"label":"First Aid Measures","field_name":"first_aid","json_column":"form_data","type_id":7,"order_index":13}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  89,
  'Cybersecurity & SCADA Risk Assessment',
  'Review of IT security and SCADA operational risk vulnerabilities',
  'risk_assessments',
  '[{"field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":1,"order_index":0},
    {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Assessment Date","field_name":"assessment_date","data_column":"assessment_date","type_id":3,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Assessor Names","field_name":"assessor_names","json_column":"form_data","type_id":1,"order_index":4},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":5},
    {"label":"Approver","field_name":"approver_name","json_column":"form_data","type_id":1,"order_index":6},
    {"label":"Work Description","field_name":"work_description","json_column":"form_data","type_id":7,"order_index":7},
    {"label":"Permit Requirements","field_name":"permit_requirements","json_column":"form_data","type_id":7,"order_index":8},
    {"label":"System/Module","field_name":"system","json_column":"form_data","type_id":1,"order_index":9},
    {"label":"Threat Type","field_name":"threat","json_column":"form_data","type_id":1,"order_index":10},
    {"label":"Vulnerability Description","field_name":"vuln","json_column":"form_data","type_id":7,"order_index":11},
    {"label":"Impact Rating","field_name":"impact","json_column":"form_data","type_id":2,"order_index":12},
    {"label":"Mitigation Strategy","field_name":"strategy","json_column":"form_data","type_id":7,"order_index":13}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  90,
  'Community & Stakeholder Risk Assessment',
  'Analyzes public-facing risks and reputational threats from service issues',
  'risk_assessments',
  '[{"field_name":"risk_assessment_type_id","data_column":"risk_assessment_type_id","type_id":1,"order_index":0},
    {"label":"Title","field_name":"title","data_column":"title","type_id":1,"order_index":1},
    {"label":"Assessment Date","field_name":"assessment_date","data_column":"assessment_date","type_id":3,"order_index":2},
    {"label":"Location","field_name":"location","data_column":"location","type_id":1,"order_index":3},
    {"label":"Assessor Names","field_name":"assessor_names","json_column":"form_data","type_id":1,"order_index":4},
    {"label":"Review Date","field_name":"review_date","data_column":"review_date","type_id":3,"order_index":5},
    {"label":"Approver","field_name":"approver_name","json_column":"form_data","type_id":1,"order_index":6},
    {"label":"Work Description","field_name":"work_description","json_column":"form_data","type_id":7,"order_index":7},
    {"label":"Permit Requirements","field_name":"permit_requirements","json_column":"form_data","type_id":7,"order_index":8},
    {"label":"Community Area","field_name":"community","json_column":"form_data","type_id":1,"order_index":9},
    {"label":"Public Concern","field_name":"concern","json_column":"form_data","type_id":7,"order_index":10},
    {"label":"Likelihood of Escalation","field_name":"escalation","json_column":"form_data","type_id":2,"order_index":11},
    {"label":"Communication Strategy","field_name":"communication","json_column":"form_data","type_id":7,"order_index":12},
    {"label":"Resolution Timeline","field_name":"timeline","json_column":"form_data","type_id":1,"order_index":13}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Default risk assessment types
INSERT INTO risk_assessment_types (id, name, description, form_id, tenant_id, branch_id) VALUES
  (1, 'Water Treatment Plant Risk Assessment', 'Assessment of operational and chemical risks in treatment facilities', 85, NULL, NULL),
  (2, 'Pipeline & Infrastructure Risk Assessment', 'Evaluation of potential failure points across distribution infrastructure', 86, NULL, NULL),
  (3, 'Environmental and Climate Risk Assessment', 'Assesses environmental vulnerabilities to water supply and treatment', 87, NULL, NULL),
  (4, 'Occupational Health & Safety Risk Assessment', 'OHS-focused hazard evaluation in operational areas and fieldwork', 88, NULL, NULL),
  (5, 'Cybersecurity & SCADA Risk Assessment', 'Review of IT security and SCADA operational risk vulnerabilities', 89, NULL, NULL),
  (6, 'Community & Stakeholder Risk Assessment', 'Analyzes public-facing risks and reputational threats from service issues', 90, NULL, NULL)
ON CONFLICT (id) DO NOTHING;


-- Inspection Request form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  99,
  'Inspection Request',
  'Submit request for workplace inspection',
  'inspection_requests',
  $json$
  [
    {"label":"Workplace","field_name":"workplace_id","data_column":"workplace_id","type_id":4,"options_table":"workplace_registrations","options_label_column":"company_name","options_value_column":"id","order_index":1},
    {"label":"Description","field_name":"description","data_column":"description","type_id":7,"order_index":2},
    {"label":"Preferred Date","field_name":"preferred_date","data_column":"preferred_date","type_id":3,"order_index":3}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- WorkCOM Inspection Assignment form and modal
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  100,
  'WorkCOM Inspection Assignment',
  'Assign inspector to a workplace inspection',
  'workplace_inspections',
  $json$
  [
    {"label":"Inspection Request","field_name":"inspection_request_id","data_column":"inspection_request_id","type_id":4,"options_table":"inspection_requests","options_label_column":"id","options_value_column":"id","order_index":1},
    {"label":"Inspector","field_name":"inspector_id","data_column":"inspector_id","type_id":4,"options_table":"users","options_label_column":"full_name","options_value_column":"id","order_index":2,"validation":"{\"filter_columns\":{\"groups.name\":[\"Investigators\"]}}"}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- WorkCOM Inspection Start form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  103,
  'WorkCOM Inspection Start',
  'Select inspection type and workplace',
  'workcom_inspections',
  '[{"label":"Workplace","field_name":"workplace_id","data_column":"workplace_id","type_id":4,"options_table":"workplace_registrations","options_label_column":"company_name","options_value_column":"id","order_index":1},
    {"label":"Inspection Request","field_name":"inspection_request_id","data_column":"inspection_request_id","type_id":4,"options_table":"inspection_requests","options_label_column":"id","options_value_column":"id","order_index":2},
    {"label":"Inspection Type","field_name":"workcom_inspection_type_id","data_column":"inspection_type_id","type_id":4,"options_table":"workcom_inspection_types","options_label_column":"name","options_value_column":"id","order_index":3}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO form_buttons (form_id,label,action_type,action_payload,order_index)
VALUES (
  103,'Open Form','open-form',
  '{"lookupTable":"workcom_inspection_types","lookupField":"workcom_inspection_type_id","valueColumn":"id","formColumn":"form_id","prefillFields":["workcom_inspection_type_id","workplace_id","inspection_request_id"]}',
  1
) ON CONFLICT DO NOTHING;

-- Workplace Notice form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  104,
  'Workplace Notice',
  'Notice of certain workplaces',
  'invoices',
  $json$
  [
    {"label":"Business Name","field_name":"business_name","data_column":"details","json_column":"business_name","type_id":1,"order_index":1},
    {"label":"Trading Name","field_name":"trading_name","data_column":"details","json_column":"trading_name","type_id":1,"order_index":2},
    {"label":"Workplace Address","field_name":"workplace_address","data_column":"details","json_column":"workplace_address","type_id":7,"order_index":3},
    {"label":"Postal Address","field_name":"postal_address","data_column":"details","json_column":"postal_address","type_id":7,"order_index":4},
    {"label":"Commencement Date","field_name":"commencement_date","data_column":"details","json_column":"commencement_date","type_id":3,"order_index":5},
    {"label":"Invoice Template","field_name":"invoice_template_id","data_column":"invoice_template_id","type_id":4,"options_table":"invoice_templates","options_label_column":"name","options_value_column":"id","order_index":6}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Safety Incident Type form and modal
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  105,
  'Safety Incident Type',
  'Define safety incident type',
  'safety_incident_types',
  $json$
  [
    {"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1}
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;




-- Default resource types
INSERT INTO resource_types (code, name, description, tenant_id, branch_id)
VALUES
  ('module', 'Module', 'Application module entry point', NULL, NULL),
  ('table', 'Table', 'Backend table name', NULL, NULL),
  ('form', 'Form', 'Form builder form', NULL, NULL),
  ('wizard', 'Wizard', 'Multi step wizard', NULL, NULL),
  ('chart', 'Chart', 'Chart or report', NULL, NULL),
  ('worksheet', 'Worksheet', 'Spreadsheet worksheet', NULL, NULL),
  ('table_column', 'Table Column', 'Specific table column resource', NULL, NULL)
ON CONFLICT DO NOTHING;



VALUES (
  'Workplace Registration Certificate',
  'workplace.registration.certificate',
  '{"conditions": []}',
  TRUE
);

INSERT INTO workflow_steps (workflow_id, step_order, step_type, config) VALUES
  (
    (SELECT id FROM workflows WHERE name='Workplace Registration Certificate' LIMIT 1),
    1,
    'create_certificate',
    json_build_object(
      'template_id', (SELECT id FROM certificate_templates WHERE name='Basic Certificate' LIMIT 1),
      'submission_id_key', 'id',
      'status', 'issued'
    )
  ),
  ((SELECT id FROM workflows WHERE name='Workplace Registration Certificate' LIMIT 1),2,'generate_certificate_document','{}'),
  ((SELECT id FROM workflows WHERE name='Workplace Registration Certificate' LIMIT 1),3,'queue_notification','{"entity":"form_certificates","record_id":"{certificate_id}","event_type":"update"}'),
  ((SELECT id FROM workflows WHERE name='Workplace Registration Certificate' LIMIT 1),4,'open_modal','{"modal":"Certificates"}');

INSERT INTO workflow_event_triggers (event_name, table_name, trigger_type, operations, field_map)
VALUES (
  'workplace.registration.certificate',
  'workplace_registrations',
  'update',
  '["update"]',
  '{"id":"id"}'
);

SELECT setval('workflow_steps_id_seq', (SELECT MAX(id) FROM workflow_steps));

-- Restore Workplace Registration form and modal

-- Workplace Registration form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  106,
  'Workplace Registration',
  'Record new workplaces',
  'workplace_registrations',
  $json$
 [
  {
    "label": "Name of owner(s) of business",
    "type_id": 16,
    "field_name": "name_of_owners_of_business",
    "order_index": 0,
    "placeholder": "Name of owner(s) of business:"
  },
  {
    "label": "Trading name",
    "type_id": 1,
    "field_name": "trading_name",
    "order_index": 1,
    "placeholder": "Trading name"
  },
  {
    "label": "Address of workplace",
    "type_id": 1,
    "field_name": "address_of_workplace",
    "order_index": 2,
    "placeholder": "Address of workplace"
  },
  {
    "label": "Postal address",
    "type_id": 1,
    "field_name": "postal_address",
    "order_index": 3,
    "placeholder": "Postal address"
  },
  {
    "label": "Date of business commenced operations at these premises",
    "type_id": 3,
    "field_name": "date_of_business_commenced_operations_at_these_premises",
    "order_index": 4,
    "placeholder": "Date of business commenced operations at these premises"
  },
  {
    "label": "Details of ownership of premises",
    "type_id": 8,
    "field_name": "details_of_ownership_of_premises",
    "order_index": 5,
    "placeholder": "Details of ownership of premises"
  },
  {
    "label": "Name & address of Owner of the Building:",
    "type_id": 1,
    "field_name": "name_and_address_of_owner_of_the_building",
    "order_index": 6,
    "placeholder": "Name & address of Owner of the Building"
  },
  {
    "label": "Details of business activity: (Refer to First Schedule)",
    "type_id": 8,
    "field_name": "details_of_business_activiy",
    "order_index": 7,
    "placeholder": "Details of business activity"
  },
  {
    "label": "Main Activity Conducted by Business",
    "type_id": 1,
    "field_name": "main_activity_conducted_by_business",
    "order_index": 8,
    "placeholder": "Main Activity Conducted by Business"
  },
  {
    "label": "Principal Articles to be manufactured repaired or sold",
    "type_id": 1,
    "field_name": "principal_articles_to_be_manufactured_repaired_or_sold",
    "order_index": 9,
    "placeholder": "Principal Articles to be manufactured repaired or sold"
  },
  {
    "label": "Are goods sold at this location:",
    "type_id": 5,
    "field_name": "goods_sold",
    "order_index": 10,
    "placeholder": ""
  },
  {
    "label": "Sales Type",
    "options": [
      {
        "value": "wholesale",
        "display_text": "Wholesale"
      },
      {
        "value": "retail",
        "display_text": "Retail"
      },
      {
        "value": "both",
        "display_text": "Both"
      }
    ],
    "type_id": 4,
    "field_name": "sales_type",
    "order_index": 11,
    "condition_field": "goods_sold",
    "condition_value": "1"
  },
  {
    "label": "Has Site Previously been used as a workplace",
    "type_id": 1,
    "field_name": "has_site_previously_been_used_as_a_workplace",
    "order_index": 12,
    "placeholder": "Has Site Previously been used as a workplace"
  },
  {
    "label": "Name of previous Occupier",
    "type_id": 1,
    "field_name": "name_of_previous_occupier",
    "order_index": 13,
    "placeholder": "Name of previous Occupier"
  },
  {
    "label": "Contact telephone number",
    "type_id": 2,
    "field_name": "contact_telephone_number",
    "order_index": 14,
    "placeholder": "Contact telephone number"
  },
  {
    "label": "Maximum Number of Employees",
    "type_id": 2,
    "field_name": "maximum_number_of_employees",
    "order_index": 14,
    "placeholder": "Maximum Number of Employees"
  },
  {
    "label": "Committee Members",
    "type_id": 8,
    "field_name": "committee_members",
    "order_index": 14,
    "placeholder": "Committee Members"
  },
  {
    "label": "Training Undergone",
    "type_id": 5,
    "field_name": "training_undergone",
    "order_index": 14,
    "placeholder": "Training Undergone"
  },
  {
    "label": "Districts",
    "type_id": 4,
    "field_name": "districts",
    "order_index": 14,
    "placeholder": "Districts",
    "options_table":"districts",
    "options_label_column":"name",
    "options_value_column":"id"
  },
  {
    "label": "OHS Policy",
    "type_id": 9,
    "field_name": "ohs_policy",
    "order_index": 14,
    "placeholder": "OHS Policy"
  },
  {
    "label": "Meeting Minutes",
    "type_id": 9,
    "field_name": "minutes",
    "order_index": 14,
    "placeholder": "Meeting Minutes"
  }
  ]$json$::jsonb,
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


CREATE OR REPLACE FUNCTION notify_notification_queue()
RETURNS trigger AS $$
BEGIN
  PERFORM pg_notify('taf_queue', row_to_json(NEW)::text);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS notification_notify ON notification_queue;
CREATE TRIGGER notification_notify
AFTER INSERT ON notification_queue
FOR EACH ROW EXECUTE PROCEDURE notify_notification_queue();

-- Seed legacy modules referenced in FrontEnd/Dashboard.php
-- Ensure unique names via unique index and idempotent inserts

CREATE UNIQUE INDEX IF NOT EXISTS legacy_resources_name_idx ON legacy_resources (name);

INSERT INTO legacy_resources (name, description, isDeleted) VALUES
  ('SystemSettings', 'Legacy module from Dashboard.php', false),
  ('CountryHolidays', 'Legacy module from Dashboard.php', false),
  ('Calendar', 'Legacy module from Dashboard.php', false),
  ('Logout', 'Legacy module from Dashboard.php', false),
  ('WorkflowInstances', 'Legacy module from Dashboard.php', false),
  ('KanbanBoard', 'Legacy module from Dashboard.php', false),
  ('CustomizeDashboard', 'Legacy module from Dashboard.php', false),
  ('FormBuilder', 'Legacy module from Dashboard.php', false),
  ('DetailViewBuilder', 'Legacy module from Dashboard.php', false),
  ('PageCustomizer', 'Legacy module from Dashboard.php', false),
  ('PageConfigBuilder', 'Legacy module from Dashboard.php', false),
  ('ModuleBuilder', 'Legacy module from Dashboard.php', false),
  ('WorkflowBuilder', 'Legacy module from Dashboard.php', false),
  ('TableBuilder', 'Legacy module from Dashboard.php', false),
  ('TableManager', 'Legacy module from Dashboard.php', false),
  ('ModuleManager', 'Legacy module from Dashboard.php', false),
  ('PermissionsManager', 'Legacy module from Dashboard.php', false),
  ('Employees', 'Employee management module', false),
  ('AutoOrders', 'Manage Auto Orders for Products', false)
ON CONFLICT (name) DO NOTHING;


INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  110,
  'Vendor',
  'Manage Vendors',
  'vendors',
  '[
    {"label":"Vendor Name","field_name":"vendorname","data_column":"vendorname","type_id":1,"order_index":1},
    {"label":"Business Registration Number","field_name":"businessRegNumber","data_column":"businessRegNumber","type_id":1,"order_index":2},
    {"label":"TIN Number","field_name":"tin","data_column":"tin","type_id":1,"order_index":3},
    {"label":"Phone Numbers","field_name":"phone_numbers","type_id":16,"order_index":4,"options_table":"vendor_phone_numbers","options_label_column":"phone_number","options_value_column":"vendor_phone_id","multiple":true},
    {"label":"Emails","field_name":"emails","type_id":16,"order_index":5,"options_table":"vendor_emails","options_label_column":"email","options_value_column":"vendor_email_id","multiple":true}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  620,
  'RFQ Template',
  'Define reusable RFQ templates',
  'rfq_templates',
  '[
    {"label":"Template Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
    {"label":"Template Code","field_name":"code","data_column":"code","type_id":1,"order_index":2,"placeholder":"Optional short code"},
    {"label":"Category","field_name":"category","data_column":"category","type_id":1,"order_index":3},
    {"label":"Default Template","field_name":"is_default","data_column":"is_default","type_id":5,"order_index":4},
    {"label":"Valid From","field_name":"valid_from","data_column":"valid_from","type_id":3,"order_index":5},
    {"label":"Valid Until","field_name":"valid_until","data_column":"valid_until","type_id":3,"order_index":6},
    {"label":"Distribution Channels","field_name":"distribution_channels","data_column":"distribution_channels","type_id":8,"order_index":7,"placeholder":"Comma separated, e.g. email,portal"},
    {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":8}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  621,
  'RFQ Template Section',
  'Manage RFQ template sections',
  'rfq_template_sections',
  '[
    {"label":"Template","field_name":"rfq_template_id","data_column":"rfq_template_id","type_id":13,"order_index":1,"options_table":"rfq_templates","options_label_column":"name","options_value_column":"rfq_template_id","required":true},
    {"label":"Section Key","field_name":"section_key","data_column":"section_key","type_id":1,"order_index":2,"placeholder":"e.g. scope,terms,pricing"},
    {"label":"Heading","field_name":"heading","data_column":"heading","type_id":1,"order_index":3},
    {"label":"Body (Markdown)","field_name":"body_markdown","data_column":"body_markdown","type_id":8,"order_index":4},
    {"label":"Body (HTML)","field_name":"body_html","data_column":"body_html","type_id":8,"order_index":5},
    {"label":"Display Order","field_name":"sort_order","data_column":"sort_order","type_id":2,"order_index":6},
    {"label":"Required","field_name":"is_required","data_column":"is_required","type_id":5,"order_index":7},
    {"label":"Include In Printed PDF","field_name":"include_in_print","data_column":"include_in_print","type_id":5,"order_index":8},
    {"label":"Include In Email","field_name":"include_in_email","data_column":"include_in_email","type_id":5,"order_index":9}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  622,
  'RFQ Template Attachment',
  'Attach standard files to RFQ templates',
  'rfq_template_attachments',
  '[
    {"label":"Template","field_name":"rfq_template_id","data_column":"rfq_template_id","type_id":13,"order_index":1,"options_table":"rfq_templates","options_label_column":"name","options_value_column":"rfq_template_id","required":true},
    {"label":"Label","field_name":"label","data_column":"label","type_id":1,"order_index":2},
    {"label":"File Type","field_name":"filetype","data_column":"filetype","type_id":1,"order_index":3,"placeholder":"e.g. pdf,docx"},
    {"label":"File URL","field_name":"file_url","data_column":"file_url","type_id":7,"order_index":4},
    {"label":"Include When","field_name":"include_when","data_column":"include_when","type_id":4,"order_index":5,"options":[{"label":"Always","value":"always"},{"label":"Awarded","value":"awarded"},{"label":"Pre-Issuance","value":"pre_issuance"}]},
    {"label":"Sort Order","field_name":"sort_order","data_column":"sort_order","type_id":2,"order_index":6}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  610,
  'Vendor Contact',
  'Capture vendor contact records',
  'vendor_contacts',
  '[
    {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":17,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"Contact Name","field_name":"contact_name","data_column":"contact_name","type_id":1,"order_index":2},
    {"label":"Role","field_name":"contact_role","data_column":"contact_role","type_id":1,"order_index":3},
    {"label":"Email","field_name":"email","data_column":"email","type_id":1,"order_index":4},
    {"label":"Phone Number","field_name":"phone_number","data_column":"phone_number","type_id":1,"order_index":5},
    {"label":"Primary Contact","field_name":"is_primary","data_column":"is_primary","type_id":5,"order_index":6},
    {"label":"Notes","field_name":"notes","data_column":"notes","type_id":8,"order_index":7}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  611,
  'Vendor Address',
  'Manage vendor address records',
  'vendor_addresses',
  '[
  {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":17,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"Address Type","field_name":"address_type","data_column":"address_type","type_id":4,"order_index":2,"options":[{"display_text":"Office","value":"office"},{"display_text":"Billing","value":"billing"},{"display_text":"Shipping","value":"shipping"},{"display_text":"Registered","value":"registered"},{"display_text":"Other","value":"other"}]},
    {"label":"Address Line 1","field_name":"line1","data_column":"line1","type_id":1,"order_index":3},
    {"label":"Address Line 2","field_name":"line2","data_column":"line2","type_id":1,"order_index":4},
    {"label":"City","field_name":"city","data_column":"city","type_id":1,"order_index":5},
    {"label":"State / Region","field_name":"state_region","data_column":"state_region","type_id":1,"order_index":6},
    {"label":"Postal Code","field_name":"postal_code","data_column":"postal_code","type_id":1,"order_index":7},
    {"label":"Country","field_name":"country_code","data_column":"country_code","type_id":1,"order_index":8},
    {"label":"Primary Address","field_name":"is_primary","data_column":"is_primary","type_id":5,"order_index":9}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  612,
  'Vendor Capability',
  'Track vendor capabilities and experience',
  'vendor_capabilities',
  '[
    {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"Capability Category","field_name":"capability_category","data_column":"capability_category","type_id":1,"order_index":2},
    {"label":"Capability Description","field_name":"capability_description","data_column":"capability_description","type_id":8,"order_index":3},
    {"label":"Experience (Years)","field_name":"experience_years","data_column":"experience_years","type_id":2,"order_index":4},
    {"label":"Certifications","field_name":"certifications","data_column":"certifications","type_id":8,"order_index":5},
    {"label":"Capacity Notes","field_name":"capacity_notes","data_column":"capacity_notes","type_id":8,"order_index":6},
    {"label":"Competency Score","field_name":"competency_score","data_column":"competency_score","type_id":2,"order_index":7}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  613,
  'Vendor Documents',
  'Collect required compliance documents for vendor onboarding',
  'vendor_documents',
  '[
    {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":17,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"FNPF Compliance Document","field_name":"fnpf_document","type_id":9,"order_index":2,"doc_type":"fnpf_compliance","doc_field":"file_url","widget_options":{"maxFiles":1}},
    {"label":"FNPF Compliance Expiry Date","field_name":"fnpf_validity","type_id":3,"order_index":3,"doc_type":"fnpf_compliance","doc_field":"validity"},
    {"label":"FRCS VAT Clearance Certificate","field_name":"frcs_vat_document","type_id":9,"order_index":4,"doc_type":"frcs_vat_clearance","doc_field":"file_url","widget_options":{"maxFiles":1}},
    {"label":"FRCS VAT Clearance Expiry Date","field_name":"frcs_vat_validity","type_id":3,"order_index":5,"doc_type":"frcs_vat_clearance","doc_field":"validity"},
    {"label":"FRCS Tax Clearance Certificate","field_name":"frcs_tax_document","type_id":9,"order_index":6,"doc_type":"frcs_tax_clearance","doc_field":"file_url","widget_options":{"maxFiles":1}},
    {"label":"FRCS Tax Clearance Expiry Date","field_name":"frcs_tax_validity","type_id":3,"order_index":7,"doc_type":"frcs_tax_clearance","doc_field":"validity"},
    {"label":"FNU Levy Confirmation","field_name":"fnu_levy_document","type_id":9,"order_index":8,"doc_type":"fnu_levy","doc_field":"file_url","widget_options":{"maxFiles":1}},
    {"label":"FNU Levy Expiry Date","field_name":"fnu_levy_validity","type_id":3,"order_index":9,"doc_type":"fnu_levy","doc_field":"validity"},
    {"label":"Business Registration Document","field_name":"business_registration_document","type_id":9,"order_index":10,"doc_type":"business_registration","doc_field":"file_url","widget_options":{"maxFiles":1}},
    {"label":"Business Registration Expiry Date","field_name":"business_registration_validity","type_id":3,"order_index":11,"doc_type":"business_registration","doc_field":"validity"}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  614,
  'Vendor Supporting Document',
  'Track additional vendor supporting materials',
  'vendor_supporting_docs',
  '[
    {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"Document Category","field_name":"type","data_column":"type","type_id":4,"order_index":2,"options":[{"display_text":"Questionnaire","value":"questionnaire"},{"display_text":"Financial","value":"financial"},{"display_text":"Insurance","value":"insurance"},{"display_text":"Policy","value":"policy"},{"display_text":"Other","value":"other"}]},
    {"label":"File Type","field_name":"filetype","data_column":"filetype","type_id":1,"order_index":3},
    {"label":"File URL","field_name":"file_url","data_column":"file_url","type_id":9,"order_index":4},
    {"label":"Validity","field_name":"validity","data_column":"validity","type_id":3,"order_index":5}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  615,
  'Vendor Performance Metric',
  'Log vendor performance reviews',
  'vendor_performance_metrics',
  '[
    {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"Period Start","field_name":"period_start","data_column":"period_start","type_id":3,"order_index":2},
    {"label":"Period End","field_name":"period_end","data_column":"period_end","type_id":3,"order_index":3},
    {"label":"KPI Name","field_name":"kpi_name","data_column":"kpi_name","type_id":1,"order_index":4},
    {"label":"KPI Value","field_name":"kpi_value","data_column":"kpi_value","type_id":2,"order_index":5},
    {"label":"Rating","field_name":"rating","data_column":"rating","type_id":2,"order_index":6},
    {"label":"Reviewer","field_name":"reviewer_id","data_column":"reviewer_id","type_id":4,"order_index":7,"options_table":"users","options_label_column":"full_name","options_value_column":"user_id"},
    {"label":"Comments","field_name":"comments","data_column":"comments","type_id":8,"order_index":8}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  616,
  'Vendor Certificate',
  'Maintain vendor certification records',
  'vendor_certificates',
  '[
    {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"order_index":1,"options_table":"vendors","options_label_column":"vendorname","options_value_column":"vendor_id"},
    {"label":"Certificate Name","field_name":"certificate_name","data_column":"certificate_name","type_id":1,"order_index":2},
    {"label":"Issued At","field_name":"issued_at","data_column":"issued_at","type_id":3,"order_index":3},
    {"label":"Expiry Date","field_name":"expiry_date","data_column":"expiry_date","type_id":3,"order_index":4},
    {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":5}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


-- Customer Management form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 109, 'Customer', 'Manage customer information', 'customers',
'[{"label":"Customer Type","field_name":"customer_type","data_column":"customer_type","type_id":4,"order_index":1,"options":[{"display_text":"Individual","value":"individual"},{"display_text":"Corporate","value":"corporate"},{"display_text":"Government","value":"government"}]},
  {"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":2},
  {"label":"Email","field_name":"email","data_column":"email","type_id":1,"order_index":3},
  {"label":"Phone Number","field_name":"phone_number","data_column":"phone_number","type_id":1,"order_index":4},
  {"label":"Address","field_name":"address","data_column":"address","type_id":1,"order_index":5},
  {"label":"TIN","field_name":"tin","data_column":"tin","type_id":1,"order_index":6},
  {"label":"Risk Rating","field_name":"risk_rating","data_column":"risk_rating","type_id":4,"order_index":7,"options":[{"display_text":"Low","value":"low"},{"display_text":"Medium","value":"medium"},{"display_text":"High","value":"high"}]},
  {"label":"Compliance Status","field_name":"compliance_status","data_column":"compliance_status","type_id":4,"order_index":8,"options":[{"display_text":"Compliant","value":"compliant"},{"display_text":"Non-Compliant","value":"non-compliant"},{"display_text":"Pending","value":"pending"}]}]',
NULL, NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 109);

-- Department Management form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
SELECT 121, 'Department', 'Manage organizational departments', 'departments',
'[{"label":"Department","field_name":"name","data_column":"name","type_id":1,"order_index":1},
  {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":2}]',
NULL, 
NULL
WHERE NOT EXISTS (SELECT 1 FROM forms WHERE id = 121);

-- Default departments
INSERT INTO departments (department_id, name)
SELECT uuid_generate_v7(), 'Human Resources' WHERE NOT EXISTS (SELECT 1 FROM departments WHERE name = 'Human Resources')
UNION ALL
SELECT uuid_generate_v7(), 'Finance' WHERE NOT EXISTS (SELECT 1 FROM departments WHERE name = 'Finance')
UNION ALL
SELECT uuid_generate_v7(), 'IT' WHERE NOT EXISTS (SELECT 1 FROM departments WHERE name = 'IT')
UNION ALL
SELECT uuid_generate_v7(), 'Operations' WHERE NOT EXISTS (SELECT 1 FROM departments WHERE name = 'Operations')
UNION ALL
SELECT uuid_generate_v7(), 'Sales' WHERE NOT EXISTS (SELECT 1 FROM departments WHERE name = 'Sales')
UNION ALL
SELECT uuid_generate_v7(), 'Marketing' WHERE NOT EXISTS (SELECT 1 FROM departments WHERE name = 'Marketing');

-- -- Alter products table to make price numeric
-- ALTER TABLE products ALTER COLUMN price TYPE numeric;

-- Add size column to products table
ALTER TABLE products ADD COLUMN IF NOT EXISTS size text;

-- Product form
INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  111,
  'Product',
  'Manage Products',
  'products',
  '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1,"required":true},
    {"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":2},
    {"label":"Price","field_name":"price","data_column":"price","type_id":1,"order_index":3},
    {"label":"Barcode (GTIN)","field_name":"barcode","data_column":"barcode","type_id":1,"order_index":4},
    {"label":"Product Number","field_name":"product_number","data_column":"product_number","type_id":1,"order_index":5},
    {"label":"Brand","field_name":"brand","data_column":"brand","type_id":1,"order_index":6},
    {"label":"Category","field_name":"category_id","data_column":"category_id","type_id":13,"options_table":"product_categories","options_label_column":"name","options_value_column":"category_id","order_index":7,"required":true},
    {"label":"VAT","field_name":"vat","json_column":"tax_rates","type_id":4,"order_index":8,"options":[{"display_text":"12.5%","value":"G"},{"display_text":"0%","value":"B"}]},
    {"label":"STT","field_name":"stt","json_column":"tax_rates","type_id":4,"order_index":9,"options":[{"display_text":"Not Applicable","value":""},{"display_text":"6%","value":"E"}]},
    {"label":"Size","field_name":"size","data_column":"size","type_id":1,"order_index":10},
    {"label":"Base Unit","field_name":"base_unit","data_column":"base_unit","type_id":4,"order_index":11,"help_text":"Smallest sellable unit (e.g., PIECE, CAN, BOTTLE)","default_value":"PIECE","options":[{"display_text":"Piece","value":"PIECE"},{"display_text":"Can","value":"CAN"},{"display_text":"Bottle","value":"BOTTLE"},{"display_text":"Unit","value":"UNIT"},{"display_text":"Each","value":"EACH"}]},
    {"label":"Master Unit (Level 1)","field_name":"master_unit","data_column":"master_unit","type_id":4,"order_index":12,"help_text":"First bulk level (e.g., CARTON, BOX, PACK)","options":[{"display_text":"None","value":""},{"display_text":"Carton","value":"CARTON"},{"display_text":"Box","value":"BOX"},{"display_text":"Pack","value":"PACK"},{"display_text":"Case","value":"CASE"},{"display_text":"Bag","value":"BAG"}]},
    {"label":"Units per Master","field_name":"units_per_master","data_column":"units_per_master","type_id":2,"order_index":13,"help_text":"How many base units in one master unit (e.g., 24)"},
    {"label":"Master Unit (Level 2)","field_name":"master_unit_2","data_column":"master_unit_2","type_id":4,"order_index":14,"help_text":"Second bulk level (e.g., PALLET) - optional","options":[{"display_text":"None","value":""},{"display_text":"Pallet","value":"PALLET"},{"display_text":"Container","value":"CONTAINER"},{"display_text":"Crate","value":"CRATE"}]},
    {"label":"Units per Master 2","field_name":"units_per_master_2","data_column":"units_per_master_2","type_id":2,"order_index":15,"help_text":"How many master units in one master_unit_2 (e.g., 40 cartons per pallet)"}]',
  NULL,
  NULL
) ON CONFLICT (id) DO UPDATE SET elements = EXCLUDED.elements;

-- Auto Order form
INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  131,
  'Auto Order',
  'Manage Auto Orders for Products',
  'auto_orders',
  '[{"label":"Product","field_name":"product_id","data_column":"product_id","type_id":13,"options_table":"products","options_label_column":"name","options_value_column":"product_id","order_index":1},
    {"label":"Minimum Stock Qty","field_name":"minimum_stock_qty","data_column":"minimum_stock_qty","type_id":2,"order_index":2},
    {"label":"Order Qty","field_name":"order_qty","data_column":"order_qty","type_id":2,"order_index":3}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


-- Software Info form
INSERT INTO forms (id, name, description, mapped_table, elements, tenant_id, branch_id)
VALUES (
  112,
  'Software Info',
  'Software Information',
  'software_info',
  '[{"label":"Manufacturer Name","field_name":"manufacturer_name","data_column":"manufacturer_name","type_id":1,"order_index":1,"default_value":"Cybex PTE Limited."},
    {"label":"Serial Number","field_name":"serial_number","data_column":"serial_number","type_id":1,"order_index":2,"default_value":"CYBEXPTE-ERP-2025-001."},
    {"label":"Software Version","field_name":"software_version","data_column":"software_version","type_id":1,"order_index":3,"default_value":"2025.08"}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


-- Insert default system info record
INSERT INTO software_info (manufacturer_name, serial_number, software_version)
SELECT 'Cybex PTE Limited.', 'CYBEXPTE-ERP-2025-001.', '2025.08'
WHERE NOT EXISTS (SELECT 1 FROM software_info LIMIT 1);

-- POS Settings form
INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  113,
  'POS Settings',
  'Point of Sale Settings',
  'pos_settings',
  '[{"label":"Password","field_name":"password","data_column":"password","type_id":1,"order_index":1,"default_value":"2CBP6HMW"},
    {"label":"PIN","field_name":"pin","data_column":"pin","type_id":1,"order_index":2,"default_value":"3840"},
    {"label":"SDC Base URL","field_name":"sdc_endpoint","data_column":"sdc_endpoint","type_id":1,"order_index":3,"placeholder":"http://devesdc.sandbox.vms.frcs.org.fj:8888/<tenant>/api"},
    {"label":"SDC PIN URL","field_name":"sdc_pin_url","data_column":"sdc_pin_url","type_id":1,"order_index":4,"placeholder":"http://devesdc.sandbox.vms.frcs.org.fj:8888/<tenant>/api/v3/pin"}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;


-- Procurement form
INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  114,
  'Restaurant Product',
  'Manage Restaurant Products',
  'products',
  '[{"label":"Name","field_name":"name","data_column":"name","type_id":1,"order_index":1},
{"label":"Description","field_name":"description","data_column":"description","type_id":8,"order_index":2},
{"label":"Quantity","field_name":"quantity","data_column":"quantity","type_id":1,"order_index":3},
{"label":"Price","field_name":"price","data_column":"price","type_id":1,"order_index":4},
{"label":"Barcode (GTIN)","field_name":"barcode","data_column":"barcode","type_id":1,"order_index":5},
{"label":"Product Number","field_name":"product_number","data_column":"product_number","type_id":1,"order_index":6},
{"label":"Brand","field_name":"brand","data_column":"brand","type_id":1,"order_index":7},
{"label":"Size","field_name":"size","data_column":"size","type_id":1,"order_index":8},
{"label":"Category","field_name":"category_id","data_column":"category_id","type_id":13,"options_table":"product_categories","options_label_column":"name","options_value_column":"category_id","order_index":9},
{"label":"VAT","field_name":"vat","json_column":"tax_rates","type_id":4,"order_index":11,"options":[{"display_text":"12.5%","value":"G"},{"display_text":"0%","value":"A"}]},
{"label":"STT","field_name":"stt","json_column":"tax_rates","type_id":4,"order_index":12,"options":[{"display_text":"Not Applicable","value":""},{"display_text":"6%","value":"E"}]},
{"label":"Ingredients","field_name":"ingredients","type_id":22,"columns":[{"name":"ingredient_id","label":"Ingredient","type":"select-search","options_table":"ingredients","options_label_column":"name","options_value_column":"id"},{"name":"quantity","label":"Quantity","type":"number"},{"name":"units","label":"Units","type":"select","options":[{"display_text":"Pieces","value":"pieces"},{"display_text":"Kg","value":"kg"},{"display_text":"Grams","value":"grams"},{"display_text":"Liters","value":"liters"},{"display_text":"Ml","value":"ml"}]}],"link_table":"ingredients_to_products","link_columns":{"product_id":"id","ingredient_id":"ingredient_id","quantity":"quantity","units":"unit"},"order_index":10}]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Procurement form
INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  115,
  'Procurement',
  'Manage procurement and L.P.O records',
  'procurements',
  '[
    {"label":"L.P.O Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"options_table":"Vendors","options_label_column":"vendorName","options_value_column":"id","order_index":1},
    {"label":"Quotation Number","field_name":"quotation_number","data_column":"quotation_number","type_id":1,"order_index":3},
    {"label":"Invoice Number","field_name":"invoice_number","data_column":"invoice_number","type_id":1,"order_index":4},
    {"label":"Requested By Date","field_name":"requested_by_date","data_column":"requested_by_date","type_id":3,"order_index":5},
    {"label":"Product Barcode","field_name":"product_barcode","data_column":"product_barcode","type_id":1,"order_index":2,"show_product_below":true}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;



-- Vendor Bank Accounts form
INSERT INTO forms (
  id, name, description, mapped_table, elements, tenant_id, branch_id
) VALUES (
  120,
  'Vendor Bank Account',
  'Manage vendor bank account details',
  'vendor_bank_accounts',
  '[
  {"label":"Vendor","field_name":"vendor_id","data_column":"vendor_id","type_id":4,"options_table":"Vendors","options_label_column":"vendorName","options_value_column":"vendor_id","order_index":1},
    {"label":"Account Name","field_name":"account_name","data_column":"account_name","type_id":1,"order_index":2},
    {"label":"Account Number","field_name":"account_number","data_column":"account_number","type_id":1,"order_index":3},
    {"label":"Bank Name","field_name":"bank_name","data_column":"bank_name","type_id":1,"order_index":4},
    {"label":"IFSC/SWIFT Code","field_name":"ifsc_swift","data_column":"ifsc_swift","type_id":1,"order_index":5},
    {"label":"Branch","field_name":"branch","data_column":"branch","type_id":1,"order_index":6},
    {"label":"Account Type","field_name":"account_type","data_column":"account_type","type_id":4,"order_index":7,"options":[{"display_text":"Savings","value":"savings"},{"display_text":"Current","value":"current"},{"display_text":"Other","value":"other"}]},
    {"label":"Active","field_name":"is_active","data_column":"is_active","type_id":5,"order_index":8}
  ]',
  NULL,
  NULL
) ON CONFLICT (id) DO NOTHING;

-- Ingredients form
