getConnection(); function normalizeNullableInt($value): ?int { return (isset($value) && $value !== '') ? (int)$value : null; } function normalizeIntArray($values): array { if (!is_array($values)) { $values = $values !== null && $values !== '' ? [$values] : []; } return array_values(array_unique(array_filter(array_map('intval', $values)))); } function validateJobSubRoles(PDO $pdo, array $jobSubRoleIds): array { $jobSubRoleIds = normalizeIntArray($jobSubRoleIds); if (!$jobSubRoleIds) { return []; } $placeholders = implode(',', array_fill(0, count($jobSubRoleIds), '?')); $stmt = $pdo->prepare(" SELECT jsr.id FROM job_sub_roles jsr INNER JOIN job_roles jr ON jr.id = jsr.job_role_id WHERE jsr.id IN ($placeholders) AND jsr.is_active = 1 AND jr.is_active = 1 "); $stmt->execute($jobSubRoleIds); $validIds = array_map('intval', $stmt->fetchAll(PDO::FETCH_COLUMN)); sort($validIds); $requestedIds = $jobSubRoleIds; sort($requestedIds); if ($validIds !== $requestedIds) { throw new Exception('Una o più sottomansioni selezionate non sono valide o non sono attive.'); } return $jobSubRoleIds; } function getPrimaryJobRoleAndSubRole(PDO $pdo, array $jobSubRoleIds): array { $jobSubRoleIds = normalizeIntArray($jobSubRoleIds); if (!$jobSubRoleIds) { return [null, null]; } $stmt = $pdo->prepare(" SELECT job_role_id FROM job_sub_roles WHERE id = ? LIMIT 1 "); $stmt->execute([$jobSubRoleIds[0]]); $jobRoleId = $stmt->fetchColumn(); return [$jobRoleId !== false ? (int)$jobRoleId : null, (int)$jobSubRoleIds[0]]; } function saveEmployeeSubRoles(PDO $pdo, int $employeeId, array $jobSubRoleIds): void { $jobSubRoleIds = validateJobSubRoles($pdo, $jobSubRoleIds); $stmtDelete = $pdo->prepare("DELETE FROM employee_job_sub_roles WHERE employee_id = ?"); $stmtDelete->execute([$employeeId]); if (!$jobSubRoleIds) { return; } $stmtInsert = $pdo->prepare(" INSERT INTO employee_job_sub_roles (employee_id, job_sub_role_id, is_primary, created_at) VALUES (?, ?, ?, NOW()) "); foreach ($jobSubRoleIds as $index => $jobSubRoleId) { $stmtInsert->execute([$employeeId, $jobSubRoleId, $index === 0 ? 1 : 0]); } } function getEmployeeSubRoleIds(PDO $pdo, int $employeeId): array { $stmt = $pdo->prepare(" SELECT job_sub_role_id FROM employee_job_sub_roles WHERE employee_id = ? ORDER BY is_primary DESC, id ASC "); $stmt->execute([$employeeId]); return array_map('intval', $stmt->fetchAll(PDO::FETCH_COLUMN)); } function jsonResponse(array $data): void { header('Content-Type: application/json; charset=utf-8'); echo json_encode($data); exit; } function calculateExpiryDate(?int $validityMonths): ?string { if ($validityMonths === null || $validityMonths <= 0) { return null; } return date('Y-m-d', strtotime('+' . $validityMonths . ' months')); } function getCurrentAuthUserId(): ?int { $candidateVariables = ['iduserlogin', 'idUserLogin', 'authUserId', 'userid', 'user_id']; foreach ($candidateVariables as $variableName) { if (isset($GLOBALS[$variableName]) && (int)$GLOBALS[$variableName] > 0) { return (int)$GLOBALS[$variableName]; } } if (isset($_SESSION['auth_user_id']) && (int)$_SESSION['auth_user_id'] > 0) { return (int)$_SESSION['auth_user_id']; } if (isset($_SESSION['user_id']) && (int)$_SESSION['user_id'] > 0) { return (int)$_SESSION['user_id']; } return null; } function assignPpeToEmployee( PDO $pdo, int $employeeId, array $ppeIds, string $notes = '', ?string $assignedDate = null, ?string $deliveredBy = null, ?int $createdBy = null ): int { $ppeIds = array_values(array_unique(array_filter(array_map('intval', $ppeIds)))); if (!$ppeIds) { return 0; } $assignedDate = $assignedDate ?: date('Y-m-d'); $deliveredBy = trim((string)$deliveredBy) !== '' ? trim((string)$deliveredBy) : null; $createdBy = $createdBy ?: getCurrentAuthUserId(); $stmtPpe = $pdo->prepare("SELECT id, validity_months FROM ppe_items WHERE id = ? AND is_active = 1 LIMIT 1"); $stmtExists = $pdo->prepare(" SELECT COUNT(*) FROM employee_ppe_items WHERE employee_id = ? AND ppe_item_id = ? AND status = 'assigned' AND (expiry_date IS NULL OR expiry_date >= CURDATE()) "); $stmtInsert = $pdo->prepare(" INSERT INTO employee_ppe_items (employee_id, ppe_item_id, assigned_date, expiry_date, delivered_by, quantity, status, notes, created_by, created_at, updated_at) VALUES (:employee_id, :ppe_item_id, :assigned_date, :expiry_date, :delivered_by, 1, 'assigned', :notes, :created_by, NOW(), NOW()) "); $inserted = 0; foreach ($ppeIds as $ppeId) { if ($ppeId <= 0) { continue; } $stmtPpe->execute([$ppeId]); $ppe = $stmtPpe->fetch(PDO::FETCH_ASSOC); if (!$ppe) { continue; } $stmtExists->execute([$employeeId, $ppeId]); if ((int)$stmtExists->fetchColumn() > 0) { continue; } $expiryDate = calculateExpiryDate(isset($ppe['validity_months']) ? (int)$ppe['validity_months'] : null); $stmtInsert->execute([ 'employee_id' => $employeeId, 'ppe_item_id' => $ppeId, 'assigned_date' => $assignedDate, 'expiry_date' => $expiryDate, 'delivered_by' => $deliveredBy, 'notes' => $notes !== '' ? $notes : null, 'created_by' => $createdBy, ]); $inserted++; } return $inserted; } /* ========================================== AJAX HANDLERS ========================================== */ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax']) && $_POST['ajax'] == '1') { $action = $_POST['action'] ?? ''; try { if ($action === 'add') { $employee_code = trim($_POST['employee_code'] ?? ''); $first_name = trim($_POST['first_name'] ?? ''); $last_name = trim($_POST['last_name'] ?? ''); $address = trim($_POST['address'] ?? ''); $phone = trim($_POST['phone'] ?? ''); $email = trim($_POST['email'] ?? ''); $department_id = normalizeNullableInt($_POST['department_id'] ?? ''); $job_sub_role_ids = validateJobSubRoles($pdo, $_POST['job_sub_role_ids'] ?? []); [$job_role_id, $job_sub_role_id] = getPrimaryJobRoleAndSubRole($pdo, $job_sub_role_ids); $hire_date = trim($_POST['hire_date'] ?? ''); $status = trim($_POST['status'] ?? 'active'); $auth_user_id = normalizeNullableInt($_POST['auth_user_id'] ?? ''); $role_id = normalizeNullableInt($_POST['role_id'] ?? ''); if ($first_name === '' || $last_name === '') { jsonResponse(['success' => false, 'message' => 'First name and Last name are required.']); } if ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL)) { jsonResponse(['success' => false, 'message' => 'Email non valida.']); } if (!in_array($status, ['active', 'inactive', 'suspended'], true)) { $status = 'active'; } $sql = "INSERT INTO employees (auth_user_id, employee_code, first_name, last_name, address, phone, email, department_id, job_role_id, job_sub_role_id, hire_date, status, created_at, updated_at) VALUES (:auth_user_id, :employee_code, :first_name, :last_name, :address, :phone, :email, :department_id, :job_role_id, :job_sub_role_id, :hire_date, :status, NOW(), NOW())"; $stmt = $pdo->prepare($sql); $stmt->execute([ 'auth_user_id' => $auth_user_id, 'employee_code' => $employee_code !== '' ? $employee_code : null, 'first_name' => $first_name, 'last_name' => $last_name, 'address' => $address !== '' ? $address : null, 'phone' => $phone !== '' ? $phone : null, 'email' => $email !== '' ? $email : null, 'department_id' => $department_id, 'job_role_id' => $job_role_id, 'job_sub_role_id' => $job_sub_role_id, 'hire_date' => $hire_date !== '' ? $hire_date : null, 'status' => $status, ]); $employeeId = (int)$pdo->lastInsertId(); saveEmployeeSubRoles($pdo, $employeeId, $job_sub_role_ids); if ($auth_user_id !== null && $role_id !== null) { $checkRole = $pdo->prepare("SELECT COUNT(*) FROM auth_roles WHERE id = ?"); $checkRole->execute([$role_id]); if ((int)$checkRole->fetchColumn() > 0) { $stmtRole = $pdo->prepare("UPDATE auth_users SET role_id = :role_id, updated_at = NOW() WHERE id = :auth_user_id"); $stmtRole->execute([ 'role_id' => $role_id, 'auth_user_id' => $auth_user_id, ]); } } jsonResponse(['success' => true]); } if ($action === 'edit') { $id = (int)($_POST['id'] ?? 0); $employee_code = trim($_POST['employee_code'] ?? ''); $first_name = trim($_POST['first_name'] ?? ''); $last_name = trim($_POST['last_name'] ?? ''); $address = trim($_POST['address'] ?? ''); $phone = trim($_POST['phone'] ?? ''); $email = trim($_POST['email'] ?? ''); $department_id = normalizeNullableInt($_POST['department_id'] ?? ''); $job_sub_role_ids = validateJobSubRoles($pdo, $_POST['job_sub_role_ids'] ?? []); [$job_role_id, $job_sub_role_id] = getPrimaryJobRoleAndSubRole($pdo, $job_sub_role_ids); $hire_date = trim($_POST['hire_date'] ?? ''); $status = trim($_POST['status'] ?? 'active'); $auth_user_id = normalizeNullableInt($_POST['auth_user_id'] ?? ''); $role_id = normalizeNullableInt($_POST['role_id'] ?? ''); if ($id <= 0) { jsonResponse(['success' => false, 'message' => 'Invalid employee ID.']); } if ($first_name === '' || $last_name === '') { jsonResponse(['success' => false, 'message' => 'First name and Last name are required.']); } if ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL)) { jsonResponse(['success' => false, 'message' => 'Email non valida.']); } if (!in_array($status, ['active', 'inactive', 'suspended'], true)) { $status = 'active'; } $sql = "UPDATE employees SET auth_user_id = :auth_user_id, employee_code = :employee_code, first_name = :first_name, last_name = :last_name, address = :address, phone = :phone, email = :email, department_id = :department_id, job_role_id = :job_role_id, job_sub_role_id = :job_sub_role_id, hire_date = :hire_date, status = :status, updated_at = NOW() WHERE id = :id"; $stmt = $pdo->prepare($sql); $stmt->execute([ 'auth_user_id' => $auth_user_id, 'employee_code' => $employee_code !== '' ? $employee_code : null, 'first_name' => $first_name, 'last_name' => $last_name, 'address' => $address !== '' ? $address : null, 'phone' => $phone !== '' ? $phone : null, 'email' => $email !== '' ? $email : null, 'department_id' => $department_id, 'job_role_id' => $job_role_id, 'job_sub_role_id' => $job_sub_role_id, 'hire_date' => $hire_date !== '' ? $hire_date : null, 'status' => $status, 'id' => $id, ]); saveEmployeeSubRoles($pdo, $id, $job_sub_role_ids); if ($auth_user_id !== null && $role_id !== null) { $checkRole = $pdo->prepare("SELECT COUNT(*) FROM auth_roles WHERE id = ?"); $checkRole->execute([$role_id]); if ((int)$checkRole->fetchColumn() > 0) { $stmtRole = $pdo->prepare("UPDATE auth_users SET role_id = :role_id, updated_at = NOW() WHERE id = :auth_user_id"); $stmtRole->execute([ 'role_id' => $role_id, 'auth_user_id' => $auth_user_id, ]); } } jsonResponse(['success' => true]); } if ($action === 'delete') { $id = (int)($_POST['id'] ?? 0); if ($id <= 0) { jsonResponse(['success' => false, 'message' => 'Invalid employee ID.']); } $stmt = $pdo->prepare("DELETE FROM employees WHERE id = :id"); $stmt->execute(['id' => $id]); jsonResponse(['success' => true]); } if ($action === 'get_employee_skills') { $id = (int)$_POST['id']; if ($id <= 0) { jsonResponse(['success' => false, 'message' => 'Invalid ID']); } $stmt = $pdo->prepare("SELECT skill_id, level FROM employee_skills WHERE employee_id = ?"); $stmt->execute([$id]); $skills = []; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $skills[$row['skill_id']] = $row['level']; } jsonResponse(['success' => true, 'skills' => $skills]); } if ($action === 'save_employee_skills') { $id = (int)$_POST['id']; $skills_json = $_POST['skills'] ?? ''; $skills = json_decode($skills_json, true); if ($id <= 0 || !is_array($skills)) { jsonResponse(['success' => false, 'message' => 'Invalid data']); } $pdo->beginTransaction(); $stmtDelete = $pdo->prepare("DELETE FROM employee_skills WHERE employee_id = ?"); $stmtDelete->execute([$id]); $stmtInsert = $pdo->prepare("INSERT INTO employee_skills (employee_id, skill_id, level) VALUES (?, ?, ?)"); foreach ($skills as $skill_id => $level) { $stmtInsert->execute([$id, (int)$skill_id, $level]); } $pdo->commit(); jsonResponse(['success' => true]); } if ($action === 'get_employee_ppe') { $id = (int)($_POST['id'] ?? 0); if ($id <= 0) { jsonResponse(['success' => false, 'message' => 'Invalid employee ID.']); } $stmtEmp = $pdo->prepare(" SELECT e.id, e.first_name, e.last_name, COALESCE(ejm.job_sub_role_ids, IF(e.job_sub_role_id IS NULL, '', CAST(e.job_sub_role_id AS CHAR))) AS job_sub_role_ids, COALESCE(ejm.job_sub_role_names, jsr.name) AS job_sub_role_name FROM employees e LEFT JOIN ( SELECT ejs.employee_id, GROUP_CONCAT(DISTINCT jsr2.id ORDER BY jr2.name, jsr2.name SEPARATOR ',') AS job_sub_role_ids, GROUP_CONCAT(DISTINCT jsr2.name ORDER BY jr2.name, jsr2.name SEPARATOR ', ') AS job_sub_role_names FROM employee_job_sub_roles ejs INNER JOIN job_sub_roles jsr2 ON jsr2.id = ejs.job_sub_role_id INNER JOIN job_roles jr2 ON jr2.id = jsr2.job_role_id GROUP BY ejs.employee_id ) ejm ON ejm.employee_id = e.id LEFT JOIN job_sub_roles jsr ON jsr.id = e.job_sub_role_id WHERE e.id = ? LIMIT 1 "); $stmtEmp->execute([$id]); $employee = $stmtEmp->fetch(PDO::FETCH_ASSOC); if (!$employee) { jsonResponse(['success' => false, 'message' => 'Dipendente non trovato.']); } $jobSubRoleIds = []; if (!empty($employee['job_sub_role_ids'])) { $jobSubRoleIds = array_values(array_unique(array_filter(array_map('intval', explode(',', $employee['job_sub_role_ids']))))); } $requiredPpe = []; if ($jobSubRoleIds) { $placeholders = implode(',', array_fill(0, count($jobSubRoleIds), '?')); $stmtReq = $pdo->prepare(" SELECT p.id AS ppe_item_id, p.name AS ppe_name, p.category, p.photo, p.standard_reference, p.validity_months, GROUP_CONCAT(DISTINCT jsr.name ORDER BY jsr.name SEPARATOR ', ') AS required_by_subroles FROM job_sub_role_ppe_items jsp INNER JOIN job_sub_roles jsr ON jsr.id = jsp.job_sub_role_id INNER JOIN ppe_items p ON p.id = jsp.ppe_item_id WHERE jsp.job_sub_role_id IN ($placeholders) AND jsp.is_active = 1 AND p.is_active = 1 GROUP BY p.id, p.name, p.category, p.photo, p.standard_reference, p.validity_months ORDER BY p.category ASC, p.name ASC "); $stmtReq->execute($jobSubRoleIds); $requiredPpe = $stmtReq->fetchAll(PDO::FETCH_ASSOC); } $stmtAssigned = $pdo->prepare(" SELECT epi.id AS assignment_id, epi.ppe_item_id, epi.assigned_date, epi.expiry_date, epi.delivered_by, epi.quantity, epi.status, epi.notes, p.name AS ppe_name, p.category, p.photo, p.standard_reference FROM employee_ppe_items epi INNER JOIN ppe_items p ON p.id = epi.ppe_item_id WHERE epi.employee_id = ? ORDER BY FIELD(epi.status, 'assigned', 'expired', 'damaged', 'lost', 'returned'), p.name ASC "); $stmtAssigned->execute([$id]); $assignedPpe = $stmtAssigned->fetchAll(PDO::FETCH_ASSOC); $assignedActiveMap = []; foreach ($assignedPpe as $a) { $isActiveAssignment = ($a['status'] === 'assigned') && (empty($a['expiry_date']) || $a['expiry_date'] >= date('Y-m-d')); if ($isActiveAssignment) { $assignedActiveMap[(int)$a['ppe_item_id']] = $a; } } $requiredStatus = []; foreach ($requiredPpe as $r) { $ppeId = (int)$r['ppe_item_id']; $assignedRow = $assignedActiveMap[$ppeId] ?? null; $requiredStatus[] = [ 'ppe_item_id' => $ppeId, 'ppe_name' => $r['ppe_name'], 'category' => $r['category'], 'standard_reference' => $r['standard_reference'], 'validity_months' => $r['validity_months'], 'required_by_subroles' => $r['required_by_subroles'] ?? '', 'is_assigned' => $assignedRow !== null, 'assignment' => $assignedRow, ]; } jsonResponse([ 'success' => true, 'employee' => $employee, 'required_ppe' => $requiredStatus, 'assigned_ppe' => $assignedPpe, ]); } if ($action === 'assign_missing_employee_ppe') { $id = (int)($_POST['id'] ?? 0); $selectedPpeIds = $_POST['ppe_ids'] ?? []; if ($id <= 0) { jsonResponse(['success' => false, 'message' => 'Invalid employee ID.']); } $stmtEmp = $pdo->prepare("SELECT id FROM employees WHERE id = ? LIMIT 1"); $stmtEmp->execute([$id]); $employee = $stmtEmp->fetch(PDO::FETCH_ASSOC); if (!$employee) { jsonResponse(['success' => false, 'message' => 'Dipendente non trovato.']); } $jobSubRoleIds = getEmployeeSubRoleIds($pdo, $id); if (!$jobSubRoleIds) { $stmtLegacy = $pdo->prepare("SELECT job_sub_role_id FROM employees WHERE id = ? AND job_sub_role_id IS NOT NULL LIMIT 1"); $stmtLegacy->execute([$id]); $legacySubRoleId = $stmtLegacy->fetchColumn(); if ($legacySubRoleId) { $jobSubRoleIds = [(int)$legacySubRoleId]; } } if (!$jobSubRoleIds) { jsonResponse(['success' => false, 'message' => 'Il dipendente non ha sottomansioni collegate.']); } $placeholders = implode(',', array_fill(0, count($jobSubRoleIds), '?')); $stmtReq = $pdo->prepare(" SELECT DISTINCT p.id FROM job_sub_role_ppe_items jsp INNER JOIN ppe_items p ON p.id = jsp.ppe_item_id WHERE jsp.job_sub_role_id IN ($placeholders) AND jsp.is_active = 1 AND p.is_active = 1 "); $stmtReq->execute($jobSubRoleIds); $requiredIds = array_map('intval', $stmtReq->fetchAll(PDO::FETCH_COLUMN)); if (!$selectedPpeIds) { $selectedPpeIds = $requiredIds; } else { $selectedPpeIds = array_values(array_intersect(array_map('intval', $selectedPpeIds), $requiredIds)); } $assignedDate = trim($_POST['assigned_date'] ?? '') ?: date('Y-m-d'); $deliveredBy = trim($_POST['delivered_by'] ?? ''); $notes = trim($_POST['notes'] ?? ''); $inserted = assignPpeToEmployee( $pdo, $id, $selectedPpeIds, $notes !== '' ? $notes : 'Assegnato automaticamente dalle sottomansioni.', $assignedDate, $deliveredBy ); jsonResponse(['success' => true, 'message' => 'DPI obbligatori assegnati: ' . $inserted]); } if ($action === 'assign_employee_ppe') { $id = (int)($_POST['id'] ?? 0); $ppeIds = $_POST['ppe_ids'] ?? []; $assignedDate = trim($_POST['assigned_date'] ?? '') ?: date('Y-m-d'); $deliveredBy = trim($_POST['delivered_by'] ?? ''); $notes = trim($_POST['notes'] ?? ''); if ($id <= 0) { jsonResponse(['success' => false, 'message' => 'Invalid employee ID.']); } $stmtEmp = $pdo->prepare("SELECT id FROM employees WHERE id = ? LIMIT 1"); $stmtEmp->execute([$id]); if (!$stmtEmp->fetchColumn()) { jsonResponse(['success' => false, 'message' => 'Dipendente non trovato.']); } $inserted = assignPpeToEmployee( $pdo, $id, $ppeIds, $notes !== '' ? $notes : 'Assegnato manualmente.', $assignedDate, $deliveredBy ); jsonResponse(['success' => true, 'message' => 'DPI assegnati: ' . $inserted]); } if ($action === 'remove_employee_ppe') { $assignmentId = (int)($_POST['assignment_id'] ?? 0); $employeeId = (int)($_POST['employee_id'] ?? 0); if ($assignmentId <= 0 || $employeeId <= 0) { jsonResponse(['success' => false, 'message' => 'Dati DPI non validi.']); } $stmt = $pdo->prepare(" UPDATE employee_ppe_items SET status = 'returned', updated_at = NOW() WHERE id = ? AND employee_id = ? AND status = 'assigned' "); $stmt->execute([$assignmentId, $employeeId]); jsonResponse(['success' => true, 'message' => 'DPI rimosso dal dipendente.']); } if ($action === 'assign_bulk_employee_ppe') { $employeeIds = $_POST['employee_ids'] ?? []; $ppeIds = $_POST['ppe_ids'] ?? []; $assignedDate = trim($_POST['assigned_date'] ?? '') ?: date('Y-m-d'); $deliveredBy = trim($_POST['delivered_by'] ?? ''); $notes = trim($_POST['notes'] ?? ''); $employeeIds = array_values(array_unique(array_filter(array_map('intval', $employeeIds)))); if (!$employeeIds || !$ppeIds) { jsonResponse(['success' => false, 'message' => 'Seleziona almeno un dipendente e almeno un DPI.']); } $totalInserted = 0; foreach ($employeeIds as $employeeId) { $totalInserted += assignPpeToEmployee( $pdo, $employeeId, $ppeIds, $notes !== '' ? $notes : 'Assegnazione DPI multipla.', $assignedDate, $deliveredBy ); } jsonResponse(['success' => true, 'message' => 'Assegnazioni DPI create: ' . $totalInserted]); } jsonResponse(['success' => false, 'message' => 'Unknown action.']); } catch (Exception $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } jsonResponse(['success' => false, 'message' => $e->getMessage()]); } } /* ========================================== PAGE DATA ========================================== */ $sql = " SELECT e.*, d.name AS department_name, d.color AS department_color, COALESCE(ejm.job_role_names, jr.name) AS job_role_name, COALESCE(ejm.job_sub_role_names, jsr.name) AS job_sub_role_name, COALESCE(ejm.job_sub_role_ids, IF(e.job_sub_role_id IS NULL, '', CAST(e.job_sub_role_id AS CHAR))) AS job_sub_role_ids, au.email AS user_email, au.role_id AS user_role_id, ar.display_name AS role_display_name, ar.name AS role_name, CONCAT(COALESCE(au.first_name, ''), ' ', COALESCE(au.last_name, '')) AS user_fullname FROM employees e LEFT JOIN departments d ON e.department_id = d.id LEFT JOIN ( SELECT ejs.employee_id, GROUP_CONCAT(DISTINCT jr2.name ORDER BY jr2.name SEPARATOR ', ') AS job_role_names, GROUP_CONCAT(DISTINCT jsr2.name ORDER BY jr2.name, jsr2.name SEPARATOR ', ') AS job_sub_role_names, GROUP_CONCAT(DISTINCT jsr2.id ORDER BY jr2.name, jsr2.name SEPARATOR ',') AS job_sub_role_ids FROM employee_job_sub_roles ejs INNER JOIN job_sub_roles jsr2 ON jsr2.id = ejs.job_sub_role_id INNER JOIN job_roles jr2 ON jr2.id = jsr2.job_role_id GROUP BY ejs.employee_id ) ejm ON ejm.employee_id = e.id LEFT JOIN job_roles jr ON jr.id = e.job_role_id LEFT JOIN job_sub_roles jsr ON jsr.id = e.job_sub_role_id LEFT JOIN auth_users au ON e.auth_user_id = au.id LEFT JOIN auth_roles ar ON ar.id = au.role_id ORDER BY e.id DESC "; $stmtEmployees = $pdo->query($sql); $employees = $stmtEmployees->fetchAll(PDO::FETCH_ASSOC); $employeesForSelect = $pdo->query(" SELECT id, first_name, last_name, employee_code, department_id FROM employees ORDER BY last_name, first_name ")->fetchAll(PDO::FETCH_ASSOC); $jobRoles = $pdo->query(" SELECT id, name FROM job_roles WHERE is_active = 1 ORDER BY sort_order, name ")->fetchAll(PDO::FETCH_ASSOC); $jobSubRoles = $pdo->query(" SELECT jsr.id, jsr.job_role_id, jsr.name, jr.name AS job_role_name FROM job_sub_roles jsr INNER JOIN job_roles jr ON jr.id = jsr.job_role_id WHERE jsr.is_active = 1 AND jr.is_active = 1 ORDER BY jr.sort_order ASC, jr.name ASC, jsr.sort_order ASC, jsr.name ASC ")->fetchAll(PDO::FETCH_ASSOC); $jobSubRolesByRole = []; foreach ($jobSubRoles as $subRole) { $jobSubRolesByRole[(int)$subRole['job_role_id']][] = [ 'id' => (int)$subRole['id'], 'name' => $subRole['name'], 'job_role_name' => $subRole['job_role_name'], ]; } $ppeItems = $pdo->query(" SELECT id, name, category, standard_reference FROM ppe_items WHERE is_active = 1 ORDER BY category ASC, name ASC ")->fetchAll(PDO::FETCH_ASSOC); $sqlUsers = " SELECT id, role_id, CONCAT( COALESCE(first_name, ''), ' ', COALESCE(last_name, ''), ' (', email, ')' ) AS label FROM auth_users ORDER BY first_name, last_name, email "; $users = $pdo->query($sqlUsers)->fetchAll(PDO::FETCH_ASSOC); $sqlRoles = " SELECT id, name, display_name FROM auth_roles ORDER BY display_name, name "; $authRoles = $pdo->query($sqlRoles)->fetchAll(PDO::FETCH_ASSOC); $sqlDepartments = " SELECT id, name, code, color FROM departments WHERE is_active = 1 ORDER BY sort_order ASC, name ASC "; $departments = $pdo->query($sqlDepartments)->fetchAll(PDO::FETCH_ASSOC); $sqlSkills = " SELECT s.id, s.name, pl.name as line_name, pl.line_number FROM skills s LEFT JOIN production_lines pl ON s.production_line_id = pl.id ORDER BY IFNULL(pl.line_number, 999), s.name "; $allSkills = $pdo->query($sqlSkills)->fetchAll(PDO::FETCH_ASSOC); ?> Gestione Dipendenti - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?>
Gestione Dipendenti
Elenco Completo
Codice Nome Contatti Reparto Mansioni / Sottomansioni Data Assunzione Stato Azioni
✉️
📞 -
-