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, ]; } }