From f1c9c414a65c72ad386ac5b6f0bb247f53fe0dc9 Mon Sep 17 00:00:00 2001 From: fs Date: Sun, 5 Apr 2026 22:56:11 +0200 Subject: [PATCH] fix(helpdesk): resolve contactNo from ticket for SOAP file authorization BC's GetTicketFile requires a valid contactNo for authorization. The endpoint now accepts ticketNo, loads the ticket via OData to get Current_Contact_Name, looks up the contact's No, and passes it to the SOAP call. Frontend includes ticketNo in the file download URL. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../pages/helpdesk/ticket-file-data().php | 27 ++++++++++++++++++- .../helpdesk/web/js/helpdesk-communication.js | 2 +- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/modules/helpdesk/pages/helpdesk/ticket-file-data().php b/modules/helpdesk/pages/helpdesk/ticket-file-data().php index aa828bc..55839ef 100644 --- a/modules/helpdesk/pages/helpdesk/ticket-file-data().php +++ b/modules/helpdesk/pages/helpdesk/ticket-file-data().php @@ -17,6 +17,7 @@ if ($request->method() !== 'GET') { } $entryNo = (int) $request->query('entryNo', '0'); +$ticketNo = trim((string) $request->query('ticketNo', '')); $filename = trim((string) $request->query('filename', '')); if ($entryNo <= 0) { @@ -27,9 +28,33 @@ if ($entryNo <= 0) { } $soapGateway = app(BcSoapGateway::class); +$odataGateway = app(\MintyPHP\Module\Helpdesk\Service\BcODataGateway::class); + +// Resolve contactNo from ticket's Current_Contact_Name for SOAP authorization +$contactNo = ''; +if ($ticketNo !== '') { + try { + $ticket = $odataGateway->getTicket($ticketNo); + if (is_array($ticket)) { + $contactName = trim((string) ($ticket['Current_Contact_Name'] ?? '')); + $customerName = trim((string) ($ticket['Company_Contact_Name'] ?? '')); + if ($contactName !== '' && $customerName !== '') { + $contacts = $odataGateway->getContactsForCustomer('', $customerName); + foreach ($contacts as $contact) { + if (trim((string) ($contact['Name'] ?? '')) === $contactName) { + $contactNo = trim((string) ($contact['No'] ?? '')); + break; + } + } + } + } + } catch (\Throwable) { + // Continue without contactNo — SOAP may still work + } +} try { - $result = $soapGateway->getTicketFile($entryNo); + $result = $soapGateway->getTicketFile($entryNo, $contactNo); } catch (\Throwable) { http_response_code(502); Router::json(['ok' => false, 'error' => 'Failed to load file']); diff --git a/modules/helpdesk/web/js/helpdesk-communication.js b/modules/helpdesk/web/js/helpdesk-communication.js index f7f2020..8df1813 100644 --- a/modules/helpdesk/web/js/helpdesk-communication.js +++ b/modules/helpdesk/web/js/helpdesk-communication.js @@ -118,7 +118,7 @@ export function renderCommunicationFeed(entries, options = {}) { // File attachment: render download link and inline image for images if (typeVariant === 'file' && fileDownloadUrl && entry.file_entry_no) { const fileName = entry.file_name || 'attachment'; - const fileUrl = fileDownloadUrl + '?entryNo=' + encodeURIComponent(entry.file_entry_no) + '&filename=' + encodeURIComponent(fileName); + const fileUrl = fileDownloadUrl + '?entryNo=' + encodeURIComponent(entry.file_entry_no) + '&ticketNo=' + encodeURIComponent(ticketNo) + '&filename=' + encodeURIComponent(fileName); const ext = fileName.includes('.') ? fileName.split('.').pop().toLowerCase() : ''; const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp']; const isImage = imageExts.includes(ext);