diff --git a/db/init.sql b/db/init.sql index 9a02767..50405f2 100644 --- a/db/init.sql +++ b/db/init.sql @@ -1,41 +1,59 @@ +-- Initialize company setup (companies, statuses, folders) and core user management. +-- Designed for multi-tenant applications where each company has isolated data. + +-- Companies Table: Stores information about each client company. CREATE TABLE IF NOT EXISTS companies ( id INT AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(255) NOT NULL, + name VARCHAR(255) NOT NULL UNIQUE, uprn_required BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); +-- Job Statuses Table: Stores custom job statuses defined by each company. CREATE TABLE IF NOT EXISTS job_statuses ( id INT AUTO_INCREMENT PRIMARY KEY, company_id INT NOT NULL, name VARCHAR(255) NOT NULL, is_default BOOLEAN DEFAULT FALSE, sort_order INT DEFAULT 0, - FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE, + UNIQUE KEY (company_id, name) ); +-- Required Folders Table: Stores mandatory folder structures defined by each company. CREATE TABLE IF NOT EXISTS required_folders ( id INT AUTO_INCREMENT PRIMARY KEY, company_id INT NOT NULL, name VARCHAR(255) NOT NULL, - FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS clients ( - id INT AUTO_INCREMENT PRIMARY KEY, - company_id INT NOT NULL, - name VARCHAR(255) NOT NULL, - is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE + FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE, + UNIQUE KEY (company_id, name) ); +-- Users Table: Stores user accounts. Each user belongs to a specific company. CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, company_id INT NOT NULL, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, - role ENUM('admin', 'standard') DEFAULT 'standard', + role ENUM('admin', 'standard') DEFAULT 'standard', -- Admin can manage company settings, standard users manage jobs. + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE ); + +-- Clients Table: Stores clients for each company. Clients can be added, edited, but not deleted. +CREATE TABLE IF NOT EXISTS clients ( + id INT AUTO_INCREMENT PRIMARY KEY, + company_id INT NOT NULL, + name VARCHAR(255) NOT NULL, + contact_person VARCHAR(255) DEFAULT NULL, + email VARCHAR(255) DEFAULT NULL, + phone VARCHAR(255) DEFAULT NULL, + is_active BOOLEAN DEFAULT TRUE, -- Clients can be marked inactive instead of deleted. + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE CASCADE, + UNIQUE KEY (company_id, name) -- Ensure client names are unique per company +); \ No newline at end of file diff --git a/setup.php b/setup.php index 1ee7b1c..5853596 100644 --- a/setup.php +++ b/setup.php @@ -2,79 +2,132 @@ declare(strict_types=1); require_once __DIR__ . '/db/config.php'; +session_start(); + $error = ''; $success = ''; +$step = $_GET['step'] ?? 1; +$companyId = $_SESSION['company_id'] ?? null; + +// Redirect to index if setup is complete and companyId is not in session +if ($step > 1 && !$companyId) { + header('Location: index.php'); + exit; +} if ($_SERVER['REQUEST_METHOD'] === 'POST') { - $companyName = $_POST['company_name'] ?? ''; - $uprnRequired = isset($_POST['uprn_required']) ? 1 : 0; - $statuses = $_POST['statuses'] ?? []; - $folders = $_POST['folders'] ?? []; - $defaultStatusIndex = (int)($_POST['default_status'] ?? 0); + if ($step == 1) { + $companyName = $_POST['company_name'] ?? ''; + $uprnRequired = isset($_POST['uprn_required']) ? 1 : 0; + $statuses = $_POST['statuses'] ?? []; + $folders = $_POST['folders'] ?? []; + $defaultStatusIndex = (int)($_POST['default_status'] ?? 0); - if (empty($companyName)) { - $error = "Company name is required."; - } elseif (empty($statuses)) { - $error = "At least one job status is required."; - } elseif (empty($folders)) { - $error = "At least one required folder is required."; - } else { - try { - db()->beginTransaction(); + if (empty($companyName)) { + $error = "Company name is required."; + } elseif (empty(array_filter($statuses, 'trim'))) { + $error = "At least one job status is required."; + } elseif (empty(array_filter($folders, 'trim'))) { + $error = "At least one required folder is required."; + } else { + try { + db()->beginTransaction(); - // 1. Create Company - $stmt = db()->prepare("INSERT INTO companies (name, uprn_required) VALUES (?, ?)"); - $stmt->execute([$companyName, $uprnRequired]); - $companyId = db()->lastInsertId(); + // 1. Create Company + $stmt = db()->prepare("INSERT INTO companies (name, uprn_required) VALUES (?, ?)"); + $stmt->execute([$companyName, $uprnRequired]); + $companyId = db()->lastInsertId(); + $_SESSION['company_id'] = $companyId; // Store company ID in session for next steps - // 2. Insert Statuses - $stmt = db()->prepare("INSERT INTO job_statuses (company_id, name, is_default, sort_order) VALUES (?, ?, ?, ?)"); - foreach ($statuses as $index => $statusName) { - if (trim($statusName) === '') continue; - $isDefault = ($index === $defaultStatusIndex) ? 1 : 0; - $stmt->execute([$companyId, $statusName, $isDefault, $index]); + // 2. Insert Statuses + $stmt = db()->prepare("INSERT INTO job_statuses (company_id, name, is_default, sort_order) VALUES (?, ?, ?, ?)"); + foreach ($statuses as $index => $statusName) { + $statusName = trim($statusName); + if ($statusName === '') continue; + $isDefault = ($index === $defaultStatusIndex) ? 1 : 0; + $stmt->execute([$companyId, $statusName, $isDefault, $index]); + } + + // 3. Insert Folders + $stmt = db()->prepare("INSERT INTO required_folders (company_id, name) VALUES (?, ?)"); + foreach ($folders as $folderName) { + $folderName = trim($folderName); + if ($folderName === '') continue; + $stmt->execute([$companyId, $folderName]); + } + + // 4. Create first Admin user (simplified for demo) + $adminEmail = 'admin@' . strtolower(str_replace(' ', '', $companyName)) . '.com'; + $stmt = db()->prepare("INSERT INTO users (company_id, name, email, password, role) VALUES (?, ?, ?, ?, ?)"); + $stmt->execute([$companyId, 'Admin User', $adminEmail, password_hash('password123', PASSWORD_DEFAULT), 'admin']); + + db()->commit(); + header('Location: setup.php?step=2'); // Redirect to next step + exit; + } catch (Exception $e) { + db()->rollBack(); + $error = "Database error: " . $e->getMessage(); } + } + } elseif ($step == 2) { + // Step 2: Client Setup + $clientNames = $_POST['client_names'] ?? []; + $contactPeople = $_POST['contact_people'] ?? []; + $clientEmails = $_POST['client_emails'] ?? []; + $clientPhones = $_POST['client_phones'] ?? []; - // 3. Insert Folders - $stmt = db()->prepare("INSERT INTO required_folders (company_id, name) VALUES (?, ?)"); - foreach ($folders as $folderName) { - if (trim($folderName) === '') continue; - $stmt->execute([$companyId, $folderName]); + if (empty(array_filter($clientNames, 'trim'))) { + $error = "At least one client is required."; + } else { + try { + db()->beginTransaction(); + + $stmt = db()->prepare("INSERT INTO clients (company_id, name, contact_person, email, phone) VALUES (?, ?, ?, ?, ?)"); + foreach ($clientNames as $index => $clientName) { + $clientName = trim($clientName); + if ($clientName === '') continue; + $contactPerson = trim($contactPeople[$index] ?? ''); + $clientEmail = trim($clientEmails[$index] ?? ''); + $clientPhone = trim($clientPhones[$index] ?? ''); + + $stmt->execute([$companyId, $clientName, $contactPerson, $clientEmail, $clientPhone]); + } + + db()->commit(); + session_destroy(); // Clear session after successful setup + $success = "Company setup successfully! You can now log in."; + header('Refresh: 2; URL=index.php'); // Redirect to index + exit; + } catch (Exception $e) { + db()->rollBack(); + $error = "Database error: " . $e->getMessage(); } - - // 4. Create first Admin user (simplified for demo) - $stmt = db()->prepare("INSERT INTO users (company_id, name, email, password, role) VALUES (?, ?, ?, ?, ?)"); - $stmt->execute([$companyId, 'Admin User', 'admin@' . strtolower(str_replace(' ', '', $companyName)) . '.com', password_hash('password123', PASSWORD_DEFAULT), 'admin']); - - db()->commit(); - $success = "Company setup successfully! You can now log in."; - header('Refresh: 2; URL=index.php'); - } catch (Exception $e) { - db()->rollBack(); - $error = "Database error: " . $e->getMessage(); } } } + +$pageTitle = "Company Onboarding"; ?>
-