Teren-app/app/Services/ClientCaseDataService.php
2025-11-20 18:11:43 +01:00

182 lines
6.6 KiB
PHP

<?php
namespace App\Services;
use App\Models\ClientCase;
use App\Models\Contract;
use App\Models\Document;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
class ClientCaseDataService
{
/**
* Get paginated contracts for a client case with optional segment filtering.
*/
public function getContracts(ClientCase $clientCase, ?int $segmentId = null, int $perPage = 50): LengthAwarePaginator
{
$query = $clientCase->contracts()
->select(['id', 'uuid', 'reference', 'start_date', 'end_date', 'description', 'meta', 'active', 'type_id', 'client_case_id', 'created_at'])
->with([
'type:id,name',
'account' => function ($q) {
$q->select([
'accounts.id',
'accounts.contract_id',
'accounts.type_id',
'accounts.initial_amount',
'accounts.balance_amount',
'accounts.promise_date',
'accounts.created_at',
'accounts.updated_at',
])->orderByDesc('accounts.id');
},
'segments:id,name',
'objects:id,contract_id,reference,name,description,type,created_at',
])
->orderByDesc('created_at');
if (! empty($segmentId)) {
$query->forSegment($segmentId);
}
$perPage = max(1, min(100, $perPage));
return $query->paginate($perPage, ['*'], 'contracts_page')->withQueryString();
}
/**
* Get paginated activities for a client case with optional segment and filter constraints.
*/
public function getActivities(
ClientCase $clientCase,
?int $segmentId = null,
?string $encodedFilters = null,
array $contractIds = [],
int $perPage = 20
): LengthAwarePaginator {
$query = $clientCase->activities()
->with(['action', 'decision', 'contract:id,uuid,reference', 'user:id,name'])
->orderByDesc('created_at');
if (! empty($segmentId)) {
$query->forSegment($segmentId, $contractIds);
}
if (! empty($encodedFilters)) {
$query->withFilters($encodedFilters, $clientCase);
}
$perPage = max(1, min(100, $perPage));
return $query->paginate($perPage, ['*'], 'activities_page')->withQueryString();
}
/**
* Get merged documents from case and its contracts.
*/
public function getDocuments(ClientCase $clientCase, array $contractIds = [], int $perPage = 15): LengthAwarePaginator
{
$query = null;
$caseDocsQuery = Document::query()
->select([
'documents.id',
'documents.uuid',
'documents.documentable_id',
'documents.documentable_type',
'documents.name',
'documents.file_name',
'documents.original_name',
'documents.extension',
'documents.mime_type',
'documents.size',
'documents.created_at',
'documents.is_public',
\DB::raw('NULL as contract_reference'),
\DB::raw('NULL as contract_uuid'),
\DB::raw("'{$clientCase->uuid}' as client_case_uuid"),
\DB::raw('users.name as created_by'),
])
->join('users', 'documents.user_id', '=', 'users.id')
->where('documents.documentable_type', ClientCase::class)
->where('documents.documentable_id', $clientCase->id);
if (! empty($contractIds)) {
// Get contract references for mapping
$contracts = Contract::query()
->whereIn('id', $contractIds)
->get(['id', 'uuid', 'reference'])
->keyBy('id');
$contractDocsQuery = Document::query()
->select([
'documents.id',
'documents.uuid',
'documents.documentable_id',
'documents.documentable_type',
'documents.name',
'documents.file_name',
'documents.original_name',
'documents.extension',
'documents.mime_type',
'documents.size',
'documents.created_at',
'documents.is_public',
'contracts.reference as contract_reference',
'contracts.uuid as contract_uuid',
\DB::raw('NULL as client_case_uuid'),
\DB::raw('users.name as created_by'),
])
->join('users', 'documents.user_id', '=', 'users.id')
->join('contracts', 'documents.documentable_id', '=', 'contracts.id')
->where('documents.documentable_type', Contract::class)
->whereIn('documents.documentable_id', $contractIds);
// Union the queries
$query = $caseDocsQuery->union($contractDocsQuery);
} else {
$query = $caseDocsQuery;
}
return \DB::table(\DB::raw("({$query->toSql()}) as documents"))
->mergeBindings($query->getQuery())
->orderByDesc('created_at')
->paginate($perPage, ['*'], 'documentsPage')
->withQueryString();
}
/**
* Get archive metadata from latest non-reactivate archive setting.
*/
public function getArchiveMeta(): array
{
$latestArchiveSetting = \App\Models\ArchiveSetting::query()
->where('enabled', true)
->where(function ($q) {
$q->whereNull('reactivate')->orWhere('reactivate', false);
})
->orderByDesc('id')
->first();
$archiveSegmentId = optional($latestArchiveSetting)->segment_id;
$relatedArchiveTables = [];
if ($latestArchiveSetting) {
$entities = (array) $latestArchiveSetting->entities;
foreach ($entities as $edef) {
if (isset($edef['related']) && is_array($edef['related'])) {
foreach ($edef['related'] as $rel) {
$relatedArchiveTables[] = $rel;
}
}
}
$relatedArchiveTables = array_values(array_unique($relatedArchiveTables));
}
return [
'archive_segment_id' => $archiveSegmentId,
'related_tables' => $relatedArchiveTables,
];
}
}