From 6a2dd860fa2dfd333b42741479cd0e50b5c01216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Pocrnji=C4=8D?= Date: Thu, 15 Jan 2026 21:16:26 +0100 Subject: [PATCH] Mass archiving added to segment view show --- app/Http/Controllers/ClientCaseContoller.php | 150 +++++++++++++++++++ resources/js/Pages/Segments/Show.vue | 139 ++++++++++++++++- routes/web.php | 1 + 3 files changed, 282 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/ClientCaseContoller.php b/app/Http/Controllers/ClientCaseContoller.php index fe6ec73..b28f856 100644 --- a/app/Http/Controllers/ClientCaseContoller.php +++ b/app/Http/Controllers/ClientCaseContoller.php @@ -1585,6 +1585,156 @@ public function archiveContract(ClientCase $clientCase, string $uuid, Request $r ); } + /** + * Archive multiple contracts in a batch operation + */ + public function archiveBatch(Request $request) + { + $validated = $request->validate([ + 'contracts' => 'required|array', + 'contracts.*' => 'required|uuid|exists:contracts,uuid', + 'reactivate' => 'boolean', + ]); + + $reactivate = $validated['reactivate'] ?? false; + + // Get archive setting + $setting = \App\Models\ArchiveSetting::query() + ->where('enabled', true) + ->whereIn('strategy', ['immediate', 'manual']) + ->where('reactivate', $reactivate) + ->orderByDesc('id') + ->first(); + + if (! $setting) { + \Log::warning('No archive settings found for batch archive'); + return back()->with('flash', [ + 'error' => 'No archive settings found', + ]); + } + + $executor = app(\App\Services\Archiving\ArchiveExecutor::class); + $successCount = 0; + $skippedCount = 0; + $errors = []; + + foreach ($validated['contracts'] as $contractUuid) { + try { + $contract = Contract::where('uuid', $contractUuid)->firstOrFail(); + + // Skip if contract is already archived (active = 0) + if (!$contract->active) { + $skippedCount++; + continue; + } + + $clientCase = $contract->clientCase; + + $context = [ + 'contract_id' => $contract->id, + 'client_case_id' => $clientCase->id, + 'account_id' => $contract->account->id ?? null, + ]; + + // Execute archive setting + $executor->executeSetting($setting, $context, \Auth::id()); + + // Transaction for segment updates and activity logging + \DB::transaction(function () use ($contract, $clientCase, $setting, $reactivate) { + // Create activity log + if ($setting->action_id && $setting->decision_id) { + $activityData = [ + 'client_case_id' => $clientCase->id, + 'action_id' => $setting->action_id, + 'decision_id' => $setting->decision_id, + 'note' => ($reactivate) + ? "Ponovno aktivirana pogodba $contract->reference" + : "Arhivirana pogodba $contract->reference", + ]; + + try { + \App\Models\Activity::create($activityData); + } catch (Exception $e) { + \Log::warning('Activity could not be created during batch archive'); + } + } + + // Move to archive segment if specified + if ($setting->segment_id) { + $segmentId = $setting->segment_id; + + // Deactivate all current segments + $contract->segments() + ->allRelatedIds() + ->map(fn (int $val) => $contract->segments()->updateExistingPivot($val, [ + 'active' => false, + 'updated_at' => now(), + ])); + + // Activate archive segment + if ($contract->attachedSegments()->find($segmentId)->pluck('id')->isNotEmpty()) { + $contract->attachedSegments()->updateExistingPivot($segmentId, [ + 'active' => true, + 'updated_at' => now(), + ]); + } else { + $contract->segments()->attach($segmentId, [ + 'active' => true, + 'created_at' => now(), + 'updated_at' => now(), + ]); + } + } + + // Cancel pending field jobs + $contract->fieldJobs() + ->whereNull('completed_at') + ->whereNull('cancelled_at') + ->update([ + 'cancelled_at' => date('Y-m-d'), + 'updated_at' => now(), + ]); + }); + + $successCount++; + } catch (Exception $e) { + \Log::error('Error archiving contract in batch', [ + 'uuid' => $contractUuid, + 'error' => $e->getMessage(), + ]); + $errors[] = [ + 'uuid' => $contractUuid, + 'error' => $e->getMessage(), + ]; + } + } + + if (count($errors) > 0) { + $message = "Archived $successCount contracts"; + if ($skippedCount > 0) { + $message .= ", skipped $skippedCount already archived"; + } + $message .= ", " . count($errors) . " failed"; + + return back()->with('flash', [ + 'error' => $message, + 'details' => $errors, + ]); + } + + $message = $reactivate + ? "Successfully reactivated $successCount contracts" + : "Successfully archived $successCount contracts"; + + if ($skippedCount > 0) { + $message .= " ($skippedCount already archived)"; + } + + return back()->with('flash', [ + 'success' => $message, + ]); + } + /** * Emergency: recreate a missing / soft-deleted person for a client case and re-link related data. */ diff --git a/resources/js/Pages/Segments/Show.vue b/resources/js/Pages/Segments/Show.vue index d218f35..54bd8e0 100644 --- a/resources/js/Pages/Segments/Show.vue +++ b/resources/js/Pages/Segments/Show.vue @@ -1,10 +1,11 @@