true, 'brands' => [] ]); } $stmt = $db->prepare(" SELECT idbrand, brand_name, status FROM brands WHERE idcompany = :idcompany ORDER BY brand_name ASC "); $stmt->execute([':idcompany' => $idcompany]); jsonResponse([ 'success' => true, 'brands' => $stmt->fetchAll(PDO::FETCH_ASSOC) ]); } if ($action === 'get_departments_by_company_brand') { $idcompany = isset($_POST['idcompany']) ? (int) $_POST['idcompany'] : 0; $idbrand = !empty($_POST['idbrand']) ? (int) $_POST['idbrand'] : null; if ($idcompany <= 0) { jsonResponse([ 'success' => true, 'departments' => [] ]); } if ($idbrand !== null) { $stmt = $db->prepare(" SELECT iddepartment, department_name, status FROM departments WHERE idcompany = :idcompany AND (idbrand = :idbrand OR idbrand IS NULL) ORDER BY department_name ASC "); $stmt->execute([ ':idcompany' => $idcompany, ':idbrand' => $idbrand, ]); } else { $stmt = $db->prepare(" SELECT iddepartment, department_name, status FROM departments WHERE idcompany = :idcompany ORDER BY department_name ASC "); $stmt->execute([':idcompany' => $idcompany]); } jsonResponse([ 'success' => true, 'departments' => $stmt->fetchAll(PDO::FETCH_ASSOC) ]); } if ($action === 'save_company_user') { $idcompanyuser = isset($_POST['idcompanyuser']) ? (int) $_POST['idcompanyuser'] : 0; $iduser = isset($_POST['iduser']) ? (int) $_POST['iduser'] : 0; $idcompany = isset($_POST['idcompany']) ? (int) $_POST['idcompany'] : 0; $idbrand = !empty($_POST['idbrand']) ? (int) $_POST['idbrand'] : null; $iddepartment = !empty($_POST['iddepartment']) ? (int) $_POST['iddepartment'] : null; $userScope = $_POST['user_scope'] ?? 'company'; $companyRole = $_POST['company_role'] ?? 'viewer'; $status = $_POST['status'] ?? 'active'; $allowedScopes = ['company', 'brand', 'department']; $allowedRoles = ['owner', 'admin', 'manager', 'operator', 'viewer', 'api_user', 'lab_user']; $allowedStatuses = ['active', 'inactive']; if ($iduser <= 0) { jsonResponse([ 'success' => false, 'message' => 'User is required.' ]); } if ($idcompany <= 0) { jsonResponse([ 'success' => false, 'message' => 'Company is required.' ]); } if (!in_array($userScope, $allowedScopes, true)) { $userScope = 'company'; } if (!in_array($companyRole, $allowedRoles, true)) { $companyRole = 'viewer'; } if (!in_array($status, $allowedStatuses, true)) { $status = 'active'; } /* * Scope consistency. */ if ($userScope === 'company') { $idbrand = null; $iddepartment = null; } if ($userScope === 'brand') { if ($idbrand === null) { jsonResponse([ 'success' => false, 'message' => 'Brand is required for brand scope.' ]); } $iddepartment = null; } if ($userScope === 'department') { if ($iddepartment === null) { jsonResponse([ 'success' => false, 'message' => 'Department is required for department scope.' ]); } } /* * Check Vanguard user exists. */ $stmt = $db->prepare(" SELECT COUNT(*) FROM auth_users WHERE id = :iduser "); $stmt->execute([':iduser' => $iduser]); if ((int) $stmt->fetchColumn() === 0) { jsonResponse([ 'success' => false, 'message' => 'Selected Vanguard user does not exist.' ]); } /* * Check company exists. */ $stmt = $db->prepare(" SELECT COUNT(*) FROM companies WHERE idcompany = :idcompany "); $stmt->execute([':idcompany' => $idcompany]); if ((int) $stmt->fetchColumn() === 0) { jsonResponse([ 'success' => false, 'message' => 'Selected company does not exist.' ]); } /* * Check brand belongs to company. */ if ($idbrand !== null) { $stmt = $db->prepare(" SELECT COUNT(*) FROM brands WHERE idbrand = :idbrand AND idcompany = :idcompany "); $stmt->execute([ ':idbrand' => $idbrand, ':idcompany' => $idcompany, ]); if ((int) $stmt->fetchColumn() === 0) { jsonResponse([ 'success' => false, 'message' => 'Selected brand does not belong to the selected company.' ]); } } /* * Check department belongs to company and, if brand is selected, is compatible. */ if ($iddepartment !== null) { if ($idbrand !== null) { $stmt = $db->prepare(" SELECT COUNT(*) FROM departments WHERE iddepartment = :iddepartment AND idcompany = :idcompany AND (idbrand = :idbrand OR idbrand IS NULL) "); $stmt->execute([ ':iddepartment' => $iddepartment, ':idcompany' => $idcompany, ':idbrand' => $idbrand, ]); } else { $stmt = $db->prepare(" SELECT COUNT(*) FROM departments WHERE iddepartment = :iddepartment AND idcompany = :idcompany "); $stmt->execute([ ':iddepartment' => $iddepartment, ':idcompany' => $idcompany, ]); } if ((int) $stmt->fetchColumn() === 0) { jsonResponse([ 'success' => false, 'message' => 'Selected department is not compatible with the selected company/brand.' ]); } } /* * Check duplicate assignment. */ if ($idcompanyuser > 0) { $stmt = $db->prepare(" SELECT COUNT(*) FROM company_users WHERE iduser = :iduser AND idcompany = :idcompany AND ( (idbrand IS NULL AND :idbrand_null = 1) OR idbrand = :idbrand ) AND ( (iddepartment IS NULL AND :iddepartment_null = 1) OR iddepartment = :iddepartment ) AND idcompanyuser <> :idcompanyuser "); $stmt->execute([ ':iduser' => $iduser, ':idcompany' => $idcompany, ':idbrand' => $idbrand, ':idbrand_null' => $idbrand === null ? 1 : 0, ':iddepartment' => $iddepartment, ':iddepartment_null' => $iddepartment === null ? 1 : 0, ':idcompanyuser' => $idcompanyuser, ]); } else { $stmt = $db->prepare(" SELECT COUNT(*) FROM company_users WHERE iduser = :iduser AND idcompany = :idcompany AND ( (idbrand IS NULL AND :idbrand_null = 1) OR idbrand = :idbrand ) AND ( (iddepartment IS NULL AND :iddepartment_null = 1) OR iddepartment = :iddepartment ) "); $stmt->execute([ ':iduser' => $iduser, ':idcompany' => $idcompany, ':idbrand' => $idbrand, ':idbrand_null' => $idbrand === null ? 1 : 0, ':iddepartment' => $iddepartment, ':iddepartment_null' => $iddepartment === null ? 1 : 0, ]); } if ((int) $stmt->fetchColumn() > 0) { jsonResponse([ 'success' => false, 'message' => 'This user already has the same assignment.' ]); } if ($idcompanyuser > 0) { $sql = " UPDATE company_users SET iduser = :iduser, idcompany = :idcompany, idbrand = :idbrand, iddepartment = :iddepartment, user_scope = :user_scope, company_role = :company_role, status = :status, updated_at = NOW() WHERE idcompanyuser = :idcompanyuser "; $stmt = $db->prepare($sql); $stmt->execute([ ':iduser' => $iduser, ':idcompany' => $idcompany, ':idbrand' => $idbrand, ':iddepartment' => $iddepartment, ':user_scope' => $userScope, ':company_role' => $companyRole, ':status' => $status, ':idcompanyuser' => $idcompanyuser, ]); jsonResponse([ 'success' => true, 'message' => 'User assignment updated successfully.' ]); } $sql = " INSERT INTO company_users ( iduser, idcompany, idbrand, iddepartment, user_scope, company_role, status, created_at, updated_at ) VALUES ( :iduser, :idcompany, :idbrand, :iddepartment, :user_scope, :company_role, :status, NOW(), NOW() ) "; $stmt = $db->prepare($sql); $stmt->execute([ ':iduser' => $iduser, ':idcompany' => $idcompany, ':idbrand' => $idbrand, ':iddepartment' => $iddepartment, ':user_scope' => $userScope, ':company_role' => $companyRole, ':status' => $status, ]); jsonResponse([ 'success' => true, 'message' => 'User assigned successfully.' ]); } if ($action === 'get_company_user') { $idcompanyuser = isset($_POST['idcompanyuser']) ? (int) $_POST['idcompanyuser'] : 0; if ($idcompanyuser <= 0) { jsonResponse([ 'success' => false, 'message' => 'Invalid assignment id.' ]); } $stmt = $db->prepare(" SELECT * FROM company_users WHERE idcompanyuser = :idcompanyuser LIMIT 1 "); $stmt->execute([':idcompanyuser' => $idcompanyuser]); $companyUser = $stmt->fetch(PDO::FETCH_ASSOC); if (!$companyUser) { jsonResponse([ 'success' => false, 'message' => 'Assignment not found.' ]); } jsonResponse([ 'success' => true, 'company_user' => $companyUser ]); } if ($action === 'change_status') { $idcompanyuser = isset($_POST['idcompanyuser']) ? (int) $_POST['idcompanyuser'] : 0; $status = $_POST['status'] ?? 'inactive'; $allowedStatuses = ['active', 'inactive']; if ($idcompanyuser <= 0 || !in_array($status, $allowedStatuses, true)) { jsonResponse([ 'success' => false, 'message' => 'Invalid request.' ]); } $stmt = $db->prepare(" UPDATE company_users SET status = :status, updated_at = NOW() WHERE idcompanyuser = :idcompanyuser "); $stmt->execute([ ':status' => $status, ':idcompanyuser' => $idcompanyuser, ]); jsonResponse([ 'success' => true, 'message' => 'Assignment status updated successfully.' ]); } if ($action === 'delete_company_user') { $idcompanyuser = isset($_POST['idcompanyuser']) ? (int) $_POST['idcompanyuser'] : 0; if ($idcompanyuser <= 0) { jsonResponse([ 'success' => false, 'message' => 'Invalid assignment id.' ]); } $stmt = $db->prepare(" DELETE FROM company_users WHERE idcompanyuser = :idcompanyuser "); $stmt->execute([':idcompanyuser' => $idcompanyuser]); jsonResponse([ 'success' => true, 'message' => 'User assignment deleted successfully.' ]); } jsonResponse([ 'success' => false, 'message' => 'Unknown action.' ]); } catch (Throwable $e) { jsonResponse([ 'success' => false, 'message' => $e->getMessage() ]); } } /* * Page data */ $users = []; try { $stmt = $db->query(" SELECT u.id, u.email, u.first_name, u.last_name, u.username, u.status, r.display_name AS role_display_name, r.name AS role_name FROM auth_users u LEFT JOIN auth_roles r ON r.id = u.role_id ORDER BY u.first_name ASC, u.last_name ASC, u.email ASC "); $users = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Throwable $e) { $users = []; } $companies = []; try { $stmt = $db->query(" SELECT idcompany, company_name, status FROM companies ORDER BY company_name ASC "); $companies = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Throwable $e) { $companies = []; } $brands = []; try { $stmt = $db->query(" SELECT idbrand, idcompany, brand_name, status FROM brands ORDER BY brand_name ASC "); $brands = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Throwable $e) { $brands = []; } $departments = []; try { $stmt = $db->query(" SELECT iddepartment, idcompany, idbrand, department_name, status FROM departments ORDER BY department_name ASC "); $departments = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Throwable $e) { $departments = []; } $assignments = []; try { $stmt = $db->query(" SELECT cu.idcompanyuser, cu.iduser, cu.idcompany, cu.idbrand, cu.iddepartment, cu.user_scope, cu.company_role, cu.status, cu.created_at, u.email, u.first_name, u.last_name, u.username, u.status AS user_status, r.display_name AS vanguard_role, c.company_name, c.status AS company_status, b.brand_name, b.status AS brand_status, d.department_name, d.status AS department_status FROM company_users cu INNER JOIN auth_users u ON u.id = cu.iduser LEFT JOIN auth_roles r ON r.id = u.role_id INNER JOIN companies c ON c.idcompany = cu.idcompany LEFT JOIN brands b ON b.idbrand = cu.idbrand LEFT JOIN departments d ON d.iddepartment = cu.iddepartment ORDER BY c.company_name ASC, u.first_name ASC, u.last_name ASC, u.email ASC "); $assignments = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Throwable $e) { $assignments = []; } $pageTitle = 'Company Users'; ?> <?= e($pageTitle); ?> - <?= isset($titlewebsite) ? e($titlewebsite) : 'TRFgo'; ?>
TRFgo Access Control

Company Users

Link Vanguard users to TRFgo companies, brands and departments. Vanguard remains responsible for authentication; this page defines operational access and data visibility.

$row['status'] === 'active')); $companyScopeCount = count(array_filter($assignments, fn($row) => $row['user_scope'] === 'company')); $departmentScopeCount = count(array_filter($assignments, fn($row) => $row['user_scope'] === 'department')); ?>
Assignments
Active
Company Scope
Department Scope
User Assignments

Vanguard users linked to TRFgo operating scopes

No companies available. Create at least one company before assigning users.
No Vanguard users available. Create users in Vanguard before assigning TRFgo access.
User Company Scope Role Vanguard Role Status Created Actions
Company status:
Company
Full company visibility
Brand
Department
/
-'; ?> Active Inactive