forked from fa/breadcrumb-the-shire
191 lines
6.2 KiB
PHP
191 lines
6.2 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace MintyPHP\Module\Helpdesk\Service;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Service for loading debtor detail data (master data, contacts, tickets).
|
||
|
|
*
|
||
|
|
* Provides both a combined loadDetail() method (legacy) and individual
|
||
|
|
* methods for async loading via data endpoints.
|
||
|
|
*/
|
||
|
|
class DebitorDetailService
|
||
|
|
{
|
||
|
|
public function __construct(
|
||
|
|
private readonly BcODataGateway $bcODataGateway,
|
||
|
|
private readonly HelpdeskSettingsGateway $settingsGateway
|
||
|
|
) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Load only the customer master data (1 OData call).
|
||
|
|
*
|
||
|
|
* Used by the main page load — contacts and tickets are loaded async.
|
||
|
|
*
|
||
|
|
* @return array{status: string, customer?: array<string, mixed>, error?: string}
|
||
|
|
*/
|
||
|
|
public function loadCustomer(string $customerNo): array
|
||
|
|
{
|
||
|
|
$customerNo = trim($customerNo);
|
||
|
|
if ($customerNo === '') {
|
||
|
|
return ['status' => 'not_found'];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!$this->settingsGateway->isConfigured()) {
|
||
|
|
return ['status' => 'not_configured', 'error' => 'BC connection not configured'];
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
$customer = $this->bcODataGateway->getCustomer($customerNo);
|
||
|
|
} catch (\Throwable) {
|
||
|
|
return ['status' => 'error', 'error' => 'BC connection failed'];
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($customer === null) {
|
||
|
|
return ['status' => 'not_found'];
|
||
|
|
}
|
||
|
|
|
||
|
|
return [
|
||
|
|
'status' => 'success',
|
||
|
|
'customer' => $customer,
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Load contacts for a customer (for async data endpoint).
|
||
|
|
*
|
||
|
|
* @return array{ok: bool, contacts?: array<int, array<string, mixed>>, error?: string}
|
||
|
|
*/
|
||
|
|
public function loadContacts(string $customerNo, string $customerName): array
|
||
|
|
{
|
||
|
|
$customerNo = trim($customerNo);
|
||
|
|
$customerName = trim($customerName);
|
||
|
|
|
||
|
|
if ($customerNo === '' || $customerName === '') {
|
||
|
|
return ['ok' => false, 'error' => 'Missing customer number or name'];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!$this->settingsGateway->isConfigured()) {
|
||
|
|
return ['ok' => false, 'error' => 'BC connection not configured'];
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
$contacts = $this->bcODataGateway->getContactsForCustomer($customerNo, $customerName);
|
||
|
|
} catch (\Throwable $e) {
|
||
|
|
return ['ok' => false, 'error' => $e->getMessage()];
|
||
|
|
}
|
||
|
|
|
||
|
|
return ['ok' => true, 'contacts' => $contacts];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Load tickets for a customer (for async data endpoint).
|
||
|
|
*
|
||
|
|
* @return array{ok: bool, tickets?: array<int, array<string, mixed>>, error?: string}
|
||
|
|
*/
|
||
|
|
public function loadTickets(string $customerNo, string $customerName): array
|
||
|
|
{
|
||
|
|
$customerNo = trim($customerNo);
|
||
|
|
$customerName = trim($customerName);
|
||
|
|
|
||
|
|
if ($customerNo === '' || $customerName === '') {
|
||
|
|
return ['ok' => false, 'error' => 'Missing customer number or name'];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!$this->settingsGateway->isConfigured()) {
|
||
|
|
return ['ok' => false, 'error' => 'BC connection not configured'];
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
$tickets = $this->bcODataGateway->getTicketsForCustomer($customerNo, $customerName);
|
||
|
|
} catch (\Throwable $e) {
|
||
|
|
return ['ok' => false, 'error' => $e->getMessage()];
|
||
|
|
}
|
||
|
|
|
||
|
|
return ['ok' => true, 'tickets' => $tickets];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Load activity log for a ticket (for async data endpoint).
|
||
|
|
*
|
||
|
|
* @return array{ok: bool, log?: array<int, array<string, mixed>>, error?: string}
|
||
|
|
*/
|
||
|
|
public function loadTicketLog(string $ticketNo): array
|
||
|
|
{
|
||
|
|
$ticketNo = trim($ticketNo);
|
||
|
|
|
||
|
|
if ($ticketNo === '') {
|
||
|
|
return ['ok' => false, 'error' => 'Missing ticket number'];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!$this->settingsGateway->isConfigured()) {
|
||
|
|
return ['ok' => false, 'error' => 'BC connection not configured'];
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
$log = $this->bcODataGateway->getTicketLog($ticketNo);
|
||
|
|
} catch (\Throwable $e) {
|
||
|
|
return ['ok' => false, 'error' => $e->getMessage()];
|
||
|
|
}
|
||
|
|
|
||
|
|
return ['ok' => true, 'log' => $log];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Load full detail for a debtor: master data, contacts, and tickets.
|
||
|
|
*
|
||
|
|
* @deprecated Use loadCustomer() + async endpoints for contacts/tickets instead.
|
||
|
|
*
|
||
|
|
* @return array{status: string, customer?: array<string, mixed>, contacts?: array<int, array<string, mixed>>, tickets?: array<int, array<string, mixed>>, error?: string, contactsError?: string, ticketsError?: string}
|
||
|
|
*/
|
||
|
|
public function loadDetail(string $customerNo): array
|
||
|
|
{
|
||
|
|
$customerNo = trim($customerNo);
|
||
|
|
if ($customerNo === '') {
|
||
|
|
return ['status' => 'not_found'];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!$this->settingsGateway->isConfigured()) {
|
||
|
|
return ['status' => 'not_configured', 'error' => 'BC connection not configured'];
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
$customer = $this->bcODataGateway->getCustomer($customerNo);
|
||
|
|
} catch (\Throwable) {
|
||
|
|
return ['status' => 'error', 'error' => 'BC connection failed'];
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($customer === null) {
|
||
|
|
return ['status' => 'not_found'];
|
||
|
|
}
|
||
|
|
|
||
|
|
// Load contacts — BC contacts are linked via Company_Name, not customer number.
|
||
|
|
// IntegrationCustomerNo is not filterable in BC OData, so we use the customer name.
|
||
|
|
$contacts = [];
|
||
|
|
$contactsError = '';
|
||
|
|
$customerName = (string) ($customer['Name'] ?? '');
|
||
|
|
try {
|
||
|
|
$contacts = $this->bcODataGateway->getContactsForCustomer($customerNo, $customerName);
|
||
|
|
} catch (\Throwable $e) {
|
||
|
|
$contactsError = $e->getMessage();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Load tickets via PBI_FP_Tickets entity which supports server-side filtering.
|
||
|
|
$tickets = [];
|
||
|
|
$ticketsError = '';
|
||
|
|
try {
|
||
|
|
$tickets = $this->bcODataGateway->getTicketsForCustomer($customerNo, $customerName);
|
||
|
|
} catch (\Throwable $e) {
|
||
|
|
$ticketsError = $e->getMessage();
|
||
|
|
}
|
||
|
|
|
||
|
|
return [
|
||
|
|
'status' => 'success',
|
||
|
|
'customer' => $customer,
|
||
|
|
'contacts' => $contacts,
|
||
|
|
'tickets' => $tickets,
|
||
|
|
'contactsError' => $contactsError,
|
||
|
|
'ticketsError' => $ticketsError,
|
||
|
|
];
|
||
|
|
}
|
||
|
|
}
|