182 lines
6.6 KiB
PHP
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,
|
|
];
|
|
}
|
|
}
|