Fixes to client case show

This commit is contained in:
Simon Pocrnjič
2025-10-07 19:47:54 +02:00
parent f976b4d6ef
commit 175111bed4
8 changed files with 369 additions and 237 deletions
+38 -16
View File
@@ -198,8 +198,10 @@ public function updateContract(ClientCase $clientCase, string $uuid, UpdateContr
// After update/create, if balance_amount changed (and not through a payment), log an activity with before/after
if (array_key_exists('balance_amount', $accountData)) {
$newBalance = (float) optional($contract->account)->fresh()->balance_amount;
if ($newBalance !== $oldBalance) {
// Guard against null account (e.g., if creation failed silently earlier)
$newAccount = $contract->account; // single relationship access
$newBalance = $newAccount ? (float) optional($newAccount->fresh())->balance_amount : $oldBalance;
if ($newAccount && $newBalance !== $oldBalance) {
try {
$currency = optional(\App\Models\PaymentSetting::query()->first())->default_currency ?? 'EUR';
$beforeStr = number_format($oldBalance, 2, ',', '.').' '.$currency;
@@ -244,12 +246,9 @@ public function storeActivity(ClientCase $clientCase, Request $request)
// Map contract_uuid to contract_id within the same client case, if provided
$contractId = null;
if (! empty($attributes['contract_uuid'])) {
$contract = $clientCase->contracts()->where('uuid', $attributes['contract_uuid'])->firstOrFail('id');
$contract = $clientCase->contracts()->where('uuid', $attributes['contract_uuid'])->firstOrFail(['id']);
if ($contract) {
// Prevent attaching a new activity specifically to an archived contract
if (! $contract->active) {
return back()->with('warning', __('contracts.activity_not_allowed_archived'));
}
// Archived contracts are now allowed: link activity regardless of active flag
$contractId = $contract->id;
}
}
@@ -1049,7 +1048,22 @@ public function show(ClientCase $clientCase)
// Prepare contracts and a reference map.
// Only apply active/inactive filtering IF a segment filter is provided.
$contractsQuery = $case->contracts()
->with(['type', 'account', 'objects', 'segments:id,name']);
// Only select lean columns to avoid oversize JSON / headers
->select(['id', 'uuid', 'reference', 'start_date', 'end_date', 'active', 'type_id', 'client_case_id', 'created_at'])
->with([
'type:id,name',
// Use closure for account to avoid ambiguous column names with latestOfMany join
'account' => function ($q) {
$q->select([
'accounts.id',
'accounts.contract_id',
'accounts.type_id',
'accounts.initial_amount',
'accounts.balance_amount',
]);
},
'segments:id,name',
]);
$contractsQuery->orderByDesc('created_at');
@@ -1070,7 +1084,10 @@ public function show(ClientCase $clientCase)
});
}
$contracts = $contractsQuery->get();
// NOTE: If a case has an extremely large number of contracts this can still be heavy.
// Consider pagination or deferred (Inertia lazy) loading. For now, hard-cap to 500 to prevent
// pathological memory / header growth. Frontend can request more via future endpoint.
$contracts = $contractsQuery->limit(500)->get();
$contractRefMap = [];
foreach ($contracts as $c) {
@@ -1080,26 +1097,31 @@ public function show(ClientCase $clientCase)
// Merge client case and contract documents into a single array and include contract reference when applicable
$contractIds = $contracts->pluck('id');
$contractDocs = Document::query()
->select(['id', 'documentable_id', 'documentable_type', 'name', 'file_name', 'original_name', 'extension', 'mime_type', 'size', 'created_at'])
->where('documentable_type', Contract::class)
->when($contractIds->isNotEmpty(), fn ($q) => $q->whereIn('documentable_id', $contractIds))
->orderByDesc('created_at')
->limit(300) // cap to prevent excessive payload; add pagination later if needed
->get()
->map(function ($d) use ($contractRefMap) {
$arr = method_exists($d, 'toArray') ? $d->toArray() : (array) $d;
$arr['contract_reference'] = $contractRefMap[$d->documentable_id] ?? null;
$arr['documentable_type'] = Contract::class;
$arr['contract_uuid'] = optional(Contract::withTrashed()->find($d->documentable_id))->uuid;
return $arr;
});
$caseDocs = $case->documents()->orderByDesc('created_at')->get()->map(function ($d) use ($case) {
$arr = method_exists($d, 'toArray') ? $d->toArray() : (array) $d;
$arr['documentable_type'] = ClientCase::class;
$arr['client_case_uuid'] = $case->uuid;
$caseDocs = $case->documents()
->select(['id', 'documentable_id', 'documentable_type', 'name', 'file_name', 'original_name', 'extension', 'mime_type', 'size', 'created_at'])
->orderByDesc('created_at')
->limit(200)
->get()
->map(function ($d) use ($case) {
$arr = method_exists($d, 'toArray') ? $d->toArray() : (array) $d;
$arr['client_case_uuid'] = $case->uuid;
return $arr;
});
return $arr;
});
$mergedDocs = $caseDocs
->concat($contractDocs)
->sortByDesc('created_at')