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 === 'save_department') {
$iddepartment = isset($_POST['iddepartment']) ? (int) $_POST['iddepartment'] : 0;
$idcompany = isset($_POST['idcompany']) ? (int) $_POST['idcompany'] : 0;
$idbrand = !empty($_POST['idbrand']) ? (int) $_POST['idbrand'] : null;
$departmentName = trim($_POST['department_name'] ?? '');
$externalDepartmentCode = trim($_POST['external_department_code'] ?? '');
$status = $_POST['status'] ?? 'active';
$allowedStatuses = ['active', 'inactive'];
if ($idcompany <= 0) {
jsonResponse([
'success' => false,
'message' => 'Company is required.'
]);
}
if ($departmentName === '') {
jsonResponse([
'success' => false,
'message' => 'Department name is required.'
]);
}
if (!in_array($status, $allowedStatuses, true)) {
$status = 'active';
}
/*
* 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.'
]);
}
/*
* If a brand is selected, check that it belongs to the selected 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.'
]);
}
}
if ($iddepartment > 0) {
$sql = "
UPDATE departments
SET
idcompany = :idcompany,
idbrand = :idbrand,
department_name = :department_name,
external_department_code = :external_department_code,
status = :status,
updated_at = NOW()
WHERE iddepartment = :iddepartment
";
$stmt = $db->prepare($sql);
$stmt->execute([
':idcompany' => $idcompany,
':idbrand' => $idbrand,
':department_name' => $departmentName,
':external_department_code' => $externalDepartmentCode !== '' ? $externalDepartmentCode : null,
':status' => $status,
':iddepartment' => $iddepartment,
]);
jsonResponse([
'success' => true,
'message' => 'Department updated successfully.'
]);
}
$sql = "
INSERT INTO departments (
idcompany,
idbrand,
department_name,
external_department_code,
status,
created_at,
updated_at
) VALUES (
:idcompany,
:idbrand,
:department_name,
:external_department_code,
:status,
NOW(),
NOW()
)
";
$stmt = $db->prepare($sql);
$stmt->execute([
':idcompany' => $idcompany,
':idbrand' => $idbrand,
':department_name' => $departmentName,
':external_department_code' => $externalDepartmentCode !== '' ? $externalDepartmentCode : null,
':status' => $status,
]);
jsonResponse([
'success' => true,
'message' => 'Department created successfully.'
]);
}
if ($action === 'get_department') {
$iddepartment = isset($_POST['iddepartment']) ? (int) $_POST['iddepartment'] : 0;
if ($iddepartment <= 0) {
jsonResponse([
'success' => false,
'message' => 'Invalid department id.'
]);
}
$stmt = $db->prepare("
SELECT *
FROM departments
WHERE iddepartment = :iddepartment
LIMIT 1
");
$stmt->execute([':iddepartment' => $iddepartment]);
$department = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$department) {
jsonResponse([
'success' => false,
'message' => 'Department not found.'
]);
}
jsonResponse([
'success' => true,
'department' => $department
]);
}
if ($action === 'change_status') {
$iddepartment = isset($_POST['iddepartment']) ? (int) $_POST['iddepartment'] : 0;
$status = $_POST['status'] ?? 'inactive';
$allowedStatuses = ['active', 'inactive'];
if ($iddepartment <= 0 || !in_array($status, $allowedStatuses, true)) {
jsonResponse([
'success' => false,
'message' => 'Invalid request.'
]);
}
$stmt = $db->prepare("
UPDATE departments
SET status = :status, updated_at = NOW()
WHERE iddepartment = :iddepartment
");
$stmt->execute([
':status' => $status,
':iddepartment' => $iddepartment,
]);
jsonResponse([
'success' => true,
'message' => 'Department status updated successfully.'
]);
}
if ($action === 'delete_department') {
$iddepartment = isset($_POST['iddepartment']) ? (int) $_POST['iddepartment'] : 0;
if ($iddepartment <= 0) {
jsonResponse([
'success' => false,
'message' => 'Invalid department id.'
]);
}
/*
* Safe delete rule:
* Do not delete a department if it has linked users.
*/
$stmt = $db->prepare("
SELECT COUNT(*)
FROM company_users
WHERE iddepartment = :iddepartment
");
$stmt->execute([':iddepartment' => $iddepartment]);
if ((int) $stmt->fetchColumn() > 0) {
jsonResponse([
'success' => false,
'message' => 'This department has linked users. Set it as inactive instead of deleting it.'
]);
}
$stmt = $db->prepare("
DELETE FROM departments
WHERE iddepartment = :iddepartment
");
$stmt->execute([':iddepartment' => $iddepartment]);
jsonResponse([
'success' => true,
'message' => 'Department deleted successfully.'
]);
}
jsonResponse([
'success' => false,
'message' => 'Unknown action.'
]);
} catch (Throwable $e) {
jsonResponse([
'success' => false,
'message' => $e->getMessage()
]);
}
}
/*
* Page data
*/
$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
d.iddepartment,
d.idcompany,
d.idbrand,
d.department_name,
d.external_department_code,
d.status,
d.created_at,
c.company_name,
c.status AS company_status,
b.brand_name,
b.status AS brand_status,
COUNT(DISTINCT cu.idcompanyuser) AS user_count
FROM departments d
INNER JOIN companies c ON c.idcompany = d.idcompany
LEFT JOIN brands b ON b.idbrand = d.idbrand
LEFT JOIN company_users cu ON cu.iddepartment = d.iddepartment
GROUP BY
d.iddepartment,
d.idcompany,
d.idbrand,
d.department_name,
d.external_department_code,
d.status,
d.created_at,
c.company_name,
c.status,
b.brand_name,
b.status
ORDER BY c.company_name ASC, b.brand_name ASC, d.department_name ASC
");
$departments = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (Throwable $e) {
$departments = [];
}
$pageTitle = 'Departments';
?>
= e($pageTitle); ?> - = isset($titlewebsite) ? e($titlewebsite) : 'TRFgo'; ?>
TRFgo Registry
Departments
Manage departments and operational business units for each company.
Departments can optionally be linked to a brand and will later drive TRF visibility and user permissions.
Add Department
$row['status'] === 'active'));
$inactiveDepartments = count(array_filter($departments, fn($row) => $row['status'] === 'inactive'));
?>
Total Departments
= e($totalDepartments); ?>
Active
= e($activeDepartments); ?>
Inactive
= e($inactiveDepartments); ?>
No companies available.
Create at least one company before adding departments.
Department
Company
Brand
External Code
Users
Status
Created
Actions
= e($department['department_name']); ?>
ID: = e($department['iddepartment']); ?>
= e($department['company_name']); ?>
Company status: = e($department['company_status']); ?>
= e($department['brand_name']); ?>
Brand status: = e($department['brand_status']); ?>
Not linked
= !empty($department['external_department_code']) ? e($department['external_department_code']) : '- '; ?>
= e($department['user_count']); ?>
Active
Inactive
= !empty($department['created_at']) ? e(date('d/m/Y', strtotime($department['created_at']))) : '-'; ?>