From cb221a80394cffde5fc73e8b7d6c7ee7cd56ad41 Mon Sep 17 00:00:00 2001 From: "r.mubarakzyanov" Date: Sun, 17 May 2026 20:44:37 +0300 Subject: [PATCH] fix initial+refresher --- .../userarea/cron/send_training_reminders.php | 10 ++++++++- public/userarea/employee-profile.php | 22 +++++++++++++++---- public/userarea/include/training_widget.php | 8 +++++++ public/userarea/trainings.php | 9 ++++++++ 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/public/userarea/cron/send_training_reminders.php b/public/userarea/cron/send_training_reminders.php index 8849273..7e35a56 100644 --- a/public/userarea/cron/send_training_reminders.php +++ b/public/userarea/cron/send_training_reminders.php @@ -47,7 +47,8 @@ $sent = 0; $skipped = 0; $errors = 0; -/* Candidate trainings (with optional override reminder + topic default) */ +/* Candidate trainings (with optional override reminder + topic default). + Only the most recent record per (employee, topic) — older history rows skipped. */ $stmt = $pdo->query(" SELECT et.id, et.employee_id, et.completed_date, et.next_due_date, et.reminder_days, et.delivered_by, @@ -60,6 +61,13 @@ $stmt = $pdo->query(" JOIN employees e ON e.id = et.employee_id LEFT JOIN auth_users au ON au.id = e.auth_user_id WHERE et.next_due_date IS NOT NULL + AND NOT EXISTS ( + SELECT 1 FROM employee_trainings et2 + WHERE et2.employee_id = et.employee_id + AND et2.training_topic_id = et.training_topic_id + AND (et2.completed_date > et.completed_date + OR (et2.completed_date = et.completed_date AND et2.id > et.id)) + ) "); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); diff --git a/public/userarea/employee-profile.php b/public/userarea/employee-profile.php index 1861576..a00ef9f 100644 --- a/public/userarea/employee-profile.php +++ b/public/userarea/employee-profile.php @@ -103,6 +103,15 @@ if ($employee) { $stmt->execute(['eid' => $employeeId]); $trainings = $stmt->fetchAll(PDO::FETCH_ASSOC); + // Mark the most recent record per topic — older ones are history, not "expired". + $seenTopics = []; + foreach ($trainings as &$t) { + $tid = (int)$t['training_topic_id']; + $t['_is_latest'] = !isset($seenTopics[$tid]); + $seenTopics[$tid] = true; + } + unset($t); + if ($canEdit) { $trainingTopicsAll = $pdo->query(" SELECT id, name, default_frequency_months, default_reminder_days @@ -270,6 +279,7 @@ function fmtFileSize(?int $bytes): string { .pill-status-success { background: #d1fae5; color: #065f46; } .pill-status-secondary { background: #e5e7eb; color: #374151; } .pill-status-warning { background: #fef3c7; color: #92400e; } + .pill-status-danger { background: #fee2e2; color: #991b1b; } .nav-tabs { border-bottom: 1px solid #e2e8f0; @@ -871,9 +881,11 @@ function fmtFileSize(?int $bytes): string { 'storico', 'label' => 'Storico', 'class' => 'secondary']; $typeLabel = $t['training_type'] === 'refresher' ? 'Aggiornamento' : 'Iniziale'; ?> @@ -918,9 +930,11 @@ function fmtFileSize(?int $bytes): string { 'storico', 'label' => 'Storico', 'class' => 'secondary']; $typeLabel = $t['training_type'] === 'refresher' ? 'Aggiornamento' : 'Iniziale'; ?>
diff --git a/public/userarea/include/training_widget.php b/public/userarea/include/training_widget.php index a125975..62916c6 100644 --- a/public/userarea/include/training_widget.php +++ b/public/userarea/include/training_widget.php @@ -19,6 +19,7 @@ if (!$__trWidgetHr) { return; } +/* Only the most recent record per (employee, topic) — older history rows ignored. */ $__trRows = $pdo->query(" SELECT et.id, et.next_due_date, @@ -27,6 +28,13 @@ $__trRows = $pdo->query(" FROM employee_trainings et JOIN training_topics tt ON tt.id = et.training_topic_id WHERE et.next_due_date IS NOT NULL + AND NOT EXISTS ( + SELECT 1 FROM employee_trainings et2 + WHERE et2.employee_id = et.employee_id + AND et2.training_topic_id = et.training_topic_id + AND (et2.completed_date > et.completed_date + OR (et2.completed_date = et.completed_date AND et2.id > et.id)) + ) ")->fetchAll(PDO::FETCH_ASSOC); $__expiredCount = 0; diff --git a/public/userarea/trainings.php b/public/userarea/trainings.php index 55fc695..3a13667 100644 --- a/public/userarea/trainings.php +++ b/public/userarea/trainings.php @@ -30,6 +30,15 @@ $fDepartmentId = isset($_GET['department_id'])&& $_GET['department_id']!== '' ? ========================================== */ $where = []; $params = []; +// Only the most recent record per (employee, topic) — older initial/refresher +// rows stay as history on the employee profile, not in this overview. +$where[] = "NOT EXISTS ( + SELECT 1 FROM employee_trainings et2 + WHERE et2.employee_id = et.employee_id + AND et2.training_topic_id = et.training_topic_id + AND (et2.completed_date > et.completed_date + OR (et2.completed_date = et.completed_date AND et2.id > et.id)) +)"; if ($fEmployeeId > 0) { $where[] = 'et.employee_id = :eid'; $params['eid'] = $fEmployeeId; } if ($fTopicId > 0) { $where[] = 'et.training_topic_id = :tid'; $params['tid'] = $fTopicId; } if ($fType !== '' && in_array($fType, ['initial', 'refresher'], true)) {