From 659a6d71c54f7e0beb9c7121321cd70f3f93d7ac Mon Sep 17 00:00:00 2001 From: fs Date: Sun, 5 Apr 2026 22:26:25 +0200 Subject: [PATCH] fix(helpdesk): only resolve most recent support code on reassigned tickets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a ticket was reassigned (multiple support codes), all codes were mapped to the current Support_User_Name — replacing the previous agent's name with the new one on older entries. Now: if multiple support codes exist, only the code from the most recent entry is mapped to the current name. Older codes remain as abbreviations, preserving the actual history of who worked on what. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../Service/TicketCommunicationService.php | 81 ++++++++++++++++--- 1 file changed, 71 insertions(+), 10 deletions(-) diff --git a/modules/helpdesk/lib/Module/Helpdesk/Service/TicketCommunicationService.php b/modules/helpdesk/lib/Module/Helpdesk/Service/TicketCommunicationService.php index 34c4fc0..0f6ea49 100644 --- a/modules/helpdesk/lib/Module/Helpdesk/Service/TicketCommunicationService.php +++ b/modules/helpdesk/lib/Module/Helpdesk/Service/TicketCommunicationService.php @@ -933,7 +933,8 @@ class TicketCommunicationService return []; } - $result = []; + // Collect all unique support actor codes + $codes = []; foreach ([...$odataEntries, ...$soapEntries] as $entry) { $actorRole = trim((string) ($entry['actor_role'] ?? '')); if ($actorRole !== 'support') { @@ -941,11 +942,45 @@ class TicketCommunicationService } $actor = strtoupper(trim((string) ($entry['actor'] ?? ''))); if ($actor !== '' && !$this->isContactActorId($actor) && mb_strlen($actor) <= 10) { - $result[$actor] = $supportUserName; + $codes[$actor] = true; } } - return $result; + if ($codes === []) { + return []; + } + + // If only one support code exists, it must be the current user + if (count($codes) === 1) { + return [array_keys($codes)[0] => $supportUserName]; + } + + // Multiple codes (ticket was reassigned): find the code that appears + // in the most recent entry — that's most likely the current assignee. + // Only map that code; leave older codes as abbreviations. + $latestCode = null; + $latestTs = ''; + foreach ([...$odataEntries, ...$soapEntries] as $entry) { + $actorRole = trim((string) ($entry['actor_role'] ?? '')); + if ($actorRole !== 'support') { + continue; + } + $actor = strtoupper(trim((string) ($entry['actor'] ?? ''))); + if (!isset($codes[$actor])) { + continue; + } + $ts = trim((string) ($entry['timestamp_iso'] ?? '')); + if ($ts > $latestTs) { + $latestTs = $ts; + $latestCode = $actor; + } + } + + if ($latestCode !== null) { + return [$latestCode => $supportUserName]; + } + + return []; } /** @@ -965,11 +1000,11 @@ class TicketCommunicationService return []; } - // Map support actor codes to names using ticket assignment data. - // For each entry with a support role, look up the ticket's Support_User_Name - // and map the actor code to that name. This handles tickets with multiple - // support codes (e.g. after reassignment) robustly. - $result = []; + // Group support actor codes per ticket with their latest timestamp. + // For tickets with a single code, map it directly. For tickets with + // multiple codes (reassigned), only map the most recent one. + /** @var array> $codesByTicket ticket_no → [CODE → latest_ts] */ + $codesByTicket = []; foreach ($entries as $entry) { $actorRole = trim((string) ($entry['actor_role'] ?? '')); if ($actorRole !== 'support') { @@ -983,9 +1018,35 @@ class TicketCommunicationService if ($ticketNo === '') { continue; } + $ts = trim((string) ($entry['timestamp_iso'] ?? '')); + if (!isset($codesByTicket[$ticketNo][$actor]) || $ts > $codesByTicket[$ticketNo][$actor]) { + $codesByTicket[$ticketNo][$actor] = $ts; + } + } + + $result = []; + foreach ($codesByTicket as $ticketNo => $codes) { $supportUserName = $supportUserNamesByTicket[$ticketNo] ?? ''; - if ($supportUserName !== '' && !isset($result[$actor])) { - $result[$actor] = $supportUserName; + if ($supportUserName === '') { + continue; + } + + if (count($codes) === 1) { + $result[array_keys($codes)[0]] = $supportUserName; + continue; + } + + // Multiple codes: map only the most recent one + $latestCode = null; + $latestTs = ''; + foreach ($codes as $code => $ts) { + if ($ts > $latestTs) { + $latestTs = $ts; + $latestCode = $code; + } + } + if ($latestCode !== null && !isset($result[$latestCode])) { + $result[$latestCode] = $supportUserName; } }