1
0
Files
breadcrumb-the-shire/modules/helpdesk/lib/Module/Helpdesk/Service/DomainDetailService.php

227 lines
7.7 KiB
PHP
Raw Normal View History

<?php
namespace MintyPHP\Module\Helpdesk\Service;
use MintyPHP\Module\Helpdesk\Repository\HandoverRepository;
use MintyPHP\Module\Helpdesk\Repository\UpdateRepository;
/**
* Service for loading domain detail data (master data, customer, contract, handovers).
*
* Provides loadDomain() for the synchronous page load and loadDomainDetails()
* for the async data endpoint.
*/
class DomainDetailService
{
public function __construct(
private readonly BcODataGateway $bcODataGateway,
private readonly EffectiveHelpdeskSettingsService $settingsGateway,
private readonly HandoverRepository $handoverRepository,
private readonly ?UpdateRepository $updateRepository = null
) {
}
/**
* Load domain master data (1 OData call).
*
* Used by the main page load customer, contract, handovers loaded async.
*
* @api Called from domain($id) action
* @return array{status: string, domain?: array<string, mixed>, error?: string}
*/
public function loadDomain(string $domainNo): array
{
$domainNo = trim($domainNo);
if ($domainNo === '') {
return ['status' => 'not_found'];
}
if (!$this->settingsGateway->isConfigured()) {
return ['status' => 'not_configured', 'error' => 'BC connection not configured'];
}
try {
$domain = $this->bcODataGateway->getDomain($domainNo);
} catch (\Throwable) {
return ['status' => 'error', 'error' => 'BC connection failed'];
}
if ($domain === null) {
return ['status' => 'not_found'];
}
return [
'status' => 'success',
'domain' => $domain,
];
}
/**
* Load all detail data for a domain (for async data endpoint).
*
* @api Called from domain-detail-data endpoint
* @return array{
* ok: bool,
* customer?: array<string, mixed>|null,
* contract?: array<string, mixed>|null,
* handovers?: list<array<string, mixed>>,
* handover_stats?: array{total: int, draft: int, in_progress: int, completed: int, archived: int},
* related_domains?: list<array<string, mixed>>,
* error?: string
* }
*/
public function loadDomainDetails(string $domainNo, string $customerNo, int $tenantId): array
{
$domainNo = trim($domainNo);
$customerNo = trim($customerNo);
if ($domainNo === '') {
return ['ok' => false, 'error' => 'Missing domain number'];
}
$customer = null;
if ($customerNo !== '') {
try {
$customer = $this->bcODataGateway->getCustomer($customerNo);
} catch (\Throwable) {
// Best-effort — continue without customer data
}
}
$contract = $this->loadContractForDomain($domainNo);
$handovers = $this->handoverRepository->findByDomainNo($tenantId, $domainNo);
$handoverStats = $this->aggregateHandoverStats($handovers);
$relatedDomains = [];
if ($customerNo !== '') {
try {
$allCustomerDomains = $this->bcODataGateway->getDomainsForCustomer($customerNo);
$relatedDomains = array_values(array_filter(
$allCustomerDomains,
static fn (array $d): bool => trim((string) ($d['No'] ?? '')) !== $domainNo
));
} catch (\Throwable) {
// Best-effort — continue without related domains
}
}
$updates = [];
if ($this->updateRepository !== null) {
$updates = $this->prepareUpdatesForResponse(
$this->updateRepository->findByDomainNo($tenantId, $domainNo)
);
}
return [
'ok' => true,
'customer' => $customer,
'contract' => $contract,
'handovers' => $this->prepareHandoversForResponse($handovers),
'handover_stats' => $handoverStats,
'updates' => $updates,
'related_domains' => $relatedDomains,
];
}
/**
* Load contract line info for a specific domain from BC.
*
* @return array<string, mixed>|null
*/
private function loadContractForDomain(string $domainNo): ?array
{
try {
$contractLines = $this->bcODataGateway->listDomainContractLines();
} catch (\Throwable) {
return null;
}
foreach ($contractLines as $line) {
$lineNo = trim((string) ($line['No'] ?? ''));
if ($lineNo === $domainNo) {
return [
'contract_type' => trim((string) ($line['PI_Header_Type'] ?? '')),
'contract_no' => trim((string) ($line['Header_No'] ?? '')),
'contract_description' => trim((string) ($line['PI_Header_Description'] ?? '')),
'header_state' => trim((string) ($line['PI_Header_State'] ?? '')),
'line_state' => trim((string) ($line['Line_State'] ?? '')),
];
}
}
return null;
}
/**
* @param list<array<string, mixed>> $handovers
* @return array{total: int, draft: int, in_progress: int, completed: int, archived: int}
*/
private function aggregateHandoverStats(array $handovers): array
{
$stats = ['total' => 0, 'draft' => 0, 'in_progress' => 0, 'completed' => 0, 'archived' => 0];
foreach ($handovers as $handover) {
$stats['total']++;
$status = trim((string) ($handover['status'] ?? ''));
if (isset($stats[$status])) {
$stats[$status]++;
}
}
return $stats;
}
/**
* Prepare update rows for the JSON response.
*
* @param list<array<string, mixed>> $updates
* @return list<array<string, mixed>>
*/
private function prepareUpdatesForResponse(array $updates): array
{
$prepared = [];
foreach ($updates as $update) {
$categoryCode = (string) ($update['category_code'] ?? '');
$status = (string) ($update['status'] ?? '');
$prepared[] = [
'ticket_no' => (string) ($update['ticket_no'] ?? ''),
'category_code' => $categoryCode,
'category_label' => UpdateService::categoryLabel($categoryCode),
'category_variant' => UpdateService::categoryVariant($categoryCode),
'gitea_path' => (string) ($update['gitea_path'] ?? ''),
'status' => $status,
'status_label' => UpdateService::statusLabel($status),
'status_variant' => UpdateService::statusVariant($status),
'created_at' => (string) ($update['created_at'] ?? ''),
];
}
return $prepared;
}
/**
* Prepare handover rows for the JSON response (strip internal fields).
*
* @param list<array<string, mixed>> $handovers
* @return list<array<string, mixed>>
*/
private function prepareHandoversForResponse(array $handovers): array
{
$prepared = [];
foreach ($handovers as $handover) {
$prepared[] = [
'id' => (int) ($handover['id'] ?? 0),
'product_code' => (string) ($handover['product_code'] ?? ''),
'product_name' => (string) ($handover['product_name'] ?? ''),
'product_bc_description' => (string) ($handover['product_bc_description'] ?? ''),
'status' => (string) ($handover['status'] ?? ''),
'created_by_name' => (string) ($handover['created_by_name'] ?? ''),
'created_at' => (string) ($handover['created_at'] ?? ''),
];
}
return $prepared;
}
}