81 lines
4.2 KiB
PHP
81 lines
4.2 KiB
PHP
<?php
|
|
/**
|
|
* Erinnerung an den Bearbeiter: Wartet ein ihm zugewiesenes Ticket seit mehreren Arbeitsstunden auf eine Antwort, bekommt er einen Hinweis
|
|
* (Push auf die Android-App und im Browser, auf Wunsch auch per E-Mail), bevor die SLA-Frist reißt. Pro Kundennachricht gibt es nur eine
|
|
* Erinnerung. Gezählt wird in Arbeitszeit (Geschäftszeiten und Feiertage aus der SLA-Einstellung, sonst die Uhr).
|
|
* Läuft im Hintergrundjob „SLA-Prüfung“ (cron/check_sla.php, alle 15 Minuten).
|
|
*/
|
|
|
|
function wait_reminder_enabled(): bool
|
|
{
|
|
return get_setting('wait_reminder_enabled', '1') === '1';
|
|
}
|
|
|
|
function wait_reminder_hours(): int
|
|
{
|
|
return max(1, min(72, (int) get_setting('wait_reminder_hours', '4')));
|
|
}
|
|
|
|
function wait_reminder_email(): bool
|
|
{
|
|
return get_setting('wait_reminder_email', '0') === '1';
|
|
}
|
|
|
|
/**
|
|
* Prüft alle zugewiesenen, unbeantworteten Tickets und erinnert die Bearbeiter.
|
|
* @return array{checked:int,sent:int,log:string[]}
|
|
*/
|
|
function wait_reminders_run(PDO $pdo, ?string $now = null): array
|
|
{
|
|
$res = ['checked' => 0, 'sent' => 0, 'log' => []];
|
|
if (!wait_reminder_enabled()) return $res;
|
|
$now = $now ?? db_now();
|
|
$needSeconds = wait_reminder_hours() * 3600;
|
|
$snooze = function_exists('ticket_not_snoozed_sql') ? ticket_not_snoozed_sql('t') : '1=1';
|
|
|
|
$stmt = $pdo->prepare(
|
|
"SELECT t.*, s.name AS staff_name, s.email AS staff_email,
|
|
COALESCE((SELECT MAX(th.created_at) FROM ticket_threads th WHERE th.ticket_id = t.id AND th.author_type = 'customer'), t.created_at) AS last_customer_at
|
|
FROM tickets t
|
|
JOIN staff s ON s.id = t.assigned_staff_id AND s.is_active = 1
|
|
WHERE t.status = 'open' AND t.is_spam = 0 AND t.merged_into IS NULL AND t.source <> 'staff'
|
|
AND t.sla_paused_at IS NULL AND t.is_overdue = 0
|
|
AND (t.resolution_due_at IS NULL OR t.resolution_due_at > ?)
|
|
AND {$snooze}
|
|
ORDER BY t.id
|
|
LIMIT 500"
|
|
);
|
|
$stmt->execute([$now]);
|
|
$mark = $pdo->prepare('UPDATE tickets SET wait_reminded_at = ?, updated_at = updated_at WHERE id = ?');
|
|
|
|
foreach ($stmt->fetchAll() as $t) {
|
|
$res['checked']++;
|
|
$since = (string) $t['last_customer_at'];
|
|
// Pro Kundennachricht nur eine Erinnerung
|
|
if (!empty($t['wait_reminded_at']) && (string) $t['wait_reminded_at'] >= $since) continue;
|
|
$waited = ticket_sla_working_seconds_between($since, $now);
|
|
if ($waited < $needSeconds) continue;
|
|
|
|
$mark->execute([$now, (int) $t['id']]);
|
|
$hours = (int) floor($waited / 3600);
|
|
$assigned = (int) $t['assigned_staff_id'];
|
|
log_activity($pdo, (int) $t['id'], null, "Erinnerung an den Bearbeiter: wartet seit {$hours} Std. auf Antwort");
|
|
if (function_exists('fcm_notify_staff') && fcm_configured()) {
|
|
fcm_notify_staff([$assigned], fcm_data('ticket_wait', $t), (int) $t['department_id']);
|
|
}
|
|
if (function_exists('push_to_staff')) {
|
|
[$title, $body] = function_exists('fcm_message') ? fcm_message('ticket_wait', $t) : ['Ticket wartet auf Antwort', '#' . $t['ticket_number']];
|
|
try { push_to_staff($assigned, $title, $body, '/staff/ticket_view.php?n=' . urlencode((string) $t['ticket_number'])); } catch (Throwable $e) { error_log('wait_reminder push: ' . $e->getMessage()); }
|
|
}
|
|
if (wait_reminder_email() && trim((string) $t['staff_email']) !== '') {
|
|
$url = base_url() . '/staff/ticket_view.php?n=' . urlencode((string) $t['ticket_number']);
|
|
$inner = email_p('Hallo ' . e(explode(' ', trim((string) $t['staff_name']))[0]) . ', das Ticket <strong>#' . e((string) $t['ticket_number']) . '</strong> „' . e(mb_strimwidth((string) $t['subject'], 0, 80, '…')) . '“ wartet seit etwa ' . $hours . ' Stunden auf deine Antwort.')
|
|
. email_button('Ticket öffnen', $url);
|
|
email_send_and_log((string) $t['staff_email'], 'Ticket #' . $t['ticket_number'] . ' wartet auf deine Antwort', email_wrap($inner), null, 'Erinnerung-an-Bearbeiter-Mail', (string) $t['ticket_number']);
|
|
}
|
|
$res['sent']++;
|
|
$res['log'][] = "[ok] Erinnerung an {$t['staff_name']}: Ticket #{$t['ticket_number']} wartet seit {$hours} Std.";
|
|
}
|
|
return $res;
|
|
}
|