0 ? task_cert_view_url('admin.task_form', ['id' => $taskId]) : task_cert_view_url('admin.task_form'); $taskDetailUrl = task_cert_view_url('admin.task_detail'); $approvalDecisionUrl = task_cert_base_url() . '/endpoints/admin/approval_decision.php'; $resetAssignmentUrl = task_cert_base_url() . '/endpoints/admin/reset_assignment_progress.php'; $resetCycleUrl = task_cert_base_url() . '/endpoints/admin/reset_cycle_progress.php'; $markCompletedMethodsUrl = task_cert_base_url() . '/endpoints/admin/mark_completed_methods.php'; $markCompletedUrl = task_cert_base_url() . '/endpoints/admin/mark_completed.php'; $csrfToken = (string) ($csrf_token ?? ''); $filters = is_array($dashboard['filters'] ?? null) ? $dashboard['filters'] : []; $cycleOptions = is_array($dashboard['cycle_options'] ?? null) ? $dashboard['cycle_options'] : []; $selectedCycleKey = (string) ($dashboard['selected_cycle_key'] ?? ''); $cycleSelectionWarning = trim((string) ($dashboard['cycle_selection_warning'] ?? '')); $activeTabKey = (string) ($dashboard['active_tab_key'] ?? 'overview'); $showCycleSelector = (bool) ($dashboard['show_cycle_selector'] ?? true); $exportMode = (string) ($dashboard['export_mode'] ?? 'cycle'); $canExportAnswers = (bool) ($dashboard['can_export_answers'] ?? false); $tabIndexMap = [ 'overview' => '0', 'approvals' => '1', 'answers' => '2', // Backward-Kompatibilität: alte Tab-Keys zeigen auf Übersicht 'todo' => '0', 'completed' => '0', 'overdue' => '0', ]; // Status-Vorfilter aus altem Tab-Key ableiten $initialStatusFilter = ''; if ($activeTabKey === 'todo') { $initialStatusFilter = 'open'; } elseif ($activeTabKey === 'completed') { $initialStatusFilter = 'completed'; } elseif ($activeTabKey === 'overdue') { $initialStatusFilter = 'overdue'; } $activeTabIndex = $tabIndexMap[$activeTabKey] ?? '0'; $kpis = is_array($dashboard['kpis'] ?? null) ? $dashboard['kpis'] : []; $methodStats = is_array($dashboard['method_stats'] ?? null) ? $dashboard['method_stats'] : []; $todoRows = is_array($dashboard['todo_rows'] ?? null) ? $dashboard['todo_rows'] : []; $completedRows = is_array($dashboard['completed_rows'] ?? null) ? $dashboard['completed_rows'] : []; $approvalRows = is_array($dashboard['approval_rows'] ?? null) ? $dashboard['approval_rows'] : []; $overdueRows = is_array($dashboard['overdue_rows'] ?? null) ? $dashboard['overdue_rows'] : []; $submissionRows = is_array($dashboard['submission_rows'] ?? null) ? $dashboard['submission_rows'] : []; // Zusammengeführte Zeilen für die Übersicht-Grid-Tabelle $mergedRows = []; $seenAssignmentIds = []; $todoAssignmentIds = []; foreach ($todoRows as $row) { $assignmentId = (int) ($row['id'] ?? 0); if ($assignmentId > 0 && isset($seenAssignmentIds[$assignmentId])) { continue; } $seenAssignmentIds[$assignmentId] = true; $todoAssignmentIds[$assignmentId] = true; $graceUntilRaw = trim((string) ($row['grace_until'] ?? '')); $graceBadgeHtml = ''; if ($graceUntilRaw !== '') { try { $graceUntilDt = new DateTimeImmutable($graceUntilRaw); if ((new DateTimeImmutable()) < $graceUntilDt) { $graceBadgeHtml = 'Karenz bis ' . TaskCertView::e($graceUntilDt->format('d.m.Y')) . ''; } } catch (Throwable $e) { // ignore } } $todoActionHtml = ''; if ($assignmentId > 0) { $todoActionHtml = ''; } $mergedRows[] = [ 'contact_name' => (string) ($row['contact_name'] ?? '-'), 'contact_email' => (string) ($row['contact_email'] ?? ''), '_row_group' => 'todo', '_row_group_label' => 'Offen', 'status' => (string) ($row['status'] ?? ''), 'status_label' => '', 'assigned_at_sort' => (string) ($row['created_at'] ?? ''), 'due_at_sort' => (string) ($row['due_at'] ?? ''), 'completed_at_sort' => null, 'overdue_at_sort' => (string) ($row['overdue_at'] ?? ''), 'escalation_level' => (int) ($row['escalation_level'] ?? 0), 'grace_badge_html' => $graceBadgeHtml, 'last_activity_sort' => (string) ($row['last_submitted_at'] ?? ''), 'certificate_label' => null, 'certificate_code' => null, 'valid_until_sort' => null, 'cycle_key' => (string) ($row['cycle_key'] ?? ''), '_row_html_action' => $todoActionHtml, ]; } foreach ($completedRows as $row) { $completedAssignmentId = (int) ($row['id'] ?? 0); if ($completedAssignmentId > 0 && isset($seenAssignmentIds[$completedAssignmentId])) { continue; } if ($completedAssignmentId > 0) { $seenAssignmentIds[$completedAssignmentId] = true; } $certStatus = (string) ($row['certificate_status'] ?? ''); $actionHtml = ''; if ($completedAssignmentId > 0) { $actionHtml = ''; } $mergedRows[] = [ 'contact_name' => (string) ($row['contact_name'] ?? '-'), 'contact_email' => (string) ($row['contact_email'] ?? ''), '_row_group' => 'completed', '_row_group_label' => 'Erledigt', 'status' => 'completed', 'status_label' => '', 'assigned_at_sort' => null, 'due_at_sort' => null, 'completed_at_sort' => (string) ($row['completed_at'] ?? ''), 'overdue_at_sort' => null, 'escalation_level' => null, 'grace_badge_html' => '', 'last_activity_sort' => null, 'certificate_label' => '', 'certificate_code' => (string) ($row['certificate_code'] ?? ''), 'valid_until_sort' => (string) ($row['certificate_valid_until'] ?? ''), 'cycle_key' => (string) ($row['cycle_key'] ?? ''), '_row_html_action' => $actionHtml, ]; // Zertifikat-Label setzen $lastIdx = count($mergedRows) - 1; if ((int) ($row['certificate_id'] ?? 0) > 0) { $mergedRows[$lastIdx]['certificate_label'] = $certStatus; } } foreach ($overdueRows as $row) { $assignmentId = (int) ($row['id'] ?? 0); if ($assignmentId > 0 && isset($seenAssignmentIds[$assignmentId])) { continue; // Bereits in Todo- oder Completed-Zeilen enthalten } if ($assignmentId > 0) { $seenAssignmentIds[$assignmentId] = true; } $overdueActionHtml = ''; if ($assignmentId > 0) { $overdueActionHtml = ''; } $mergedRows[] = [ 'contact_name' => (string) ($row['contact_name'] ?? '-'), 'contact_email' => (string) ($row['contact_email'] ?? ''), '_row_group' => 'overdue', '_row_group_label' => 'Überfällig', 'status' => (string) ($row['status'] ?? ''), 'status_label' => '', 'assigned_at_sort' => null, 'due_at_sort' => (string) ($row['due_at'] ?? ''), 'completed_at_sort' => null, 'overdue_at_sort' => (string) ($row['overdue_at'] ?? ''), 'escalation_level' => (int) ($row['escalation_level'] ?? 0), 'grace_badge_html' => '', 'last_activity_sort' => (string) ($row['last_submitted_at'] ?? ''), 'certificate_label' => null, 'certificate_code' => null, 'valid_until_sort' => null, 'cycle_key' => '', '_row_html_action' => $overdueActionHtml, ]; } $statusLabelMap = TaskCertConstants::assignmentStatusLabels(); $methodLabelMap = TaskCertConstants::methodLabels(); $submissionStatusLabelMap = TaskCertConstants::submissionStatusLabels(); $certificateStatusLabelMap = TaskCertConstants::certificateStatusLabels(); // Status- und Zertifikat-Labels in die mergedRows einfügen foreach ($mergedRows as &$mergedRow) { $s = $mergedRow['status'] ?? ''; if ($mergedRow['status_label'] === '' && $s !== '') { $mergedRow['status_label'] = $statusLabelMap[$s] ?? $s; } $cl = $mergedRow['certificate_label'] ?? null; if ($cl !== null && $cl !== '' && isset($certificateStatusLabelMap[$cl])) { $mergedRow['certificate_label'] = $certificateStatusLabelMap[$cl]; } } unset($mergedRow); $mergedRowsJson = json_encode($mergedRows, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_UNESCAPED_UNICODE); // Antworten-Zeilen für Grid.js aufbereiten $downloadFileUrl = task_cert_base_url() . '/endpoints/admin/download_submission_file.php'; $answersGridRows = []; foreach ($submissionRows as $subRow) { $subStatus = (string) ($subRow['status'] ?? ''); $methodType = (string) ($subRow['method_type'] ?? ''); $answerItems = is_array($subRow['answer_items'] ?? null) ? $subRow['answer_items'] : []; $detailHtml = ''; if ($answerItems !== []) { $detailHtml = '
| Mitarbeiter | Methode | Einreichungsstatus | Eingereicht am | Zuweisungsstatus | Fällig am | Aktion |
|---|---|---|---|---|---|---|
|
|
0): ?>
|
|||||
| Keine Freigaben im aktuellen Filter. | ||||||