user()->id; $jobs = FieldJob::query() ->where('assigned_user_id', $userId) ->whereNull('completed_at') ->whereNull('cancelled_at') ->with([ 'contract' => function ($q) { $q->with([ 'type:id,name', 'account', 'clientCase.person' => function ($pq) { $pq->with(['addresses', 'phones']); }, 'clientCase.client:id,uuid,person_id', 'clientCase.client.person:id,full_name', ]); }, ]) ->orderByDesc('assigned_at') ->limit(100) ->get(); return Inertia::render('Phone/Index', [ 'jobs' => $jobs, 'view_mode' => 'assigned', ]); } public function completedToday(Request $request) { $userId = $request->user()->id; $start = now()->startOfDay(); $end = now()->endOfDay(); $jobs = FieldJob::query() ->where('assigned_user_id', $userId) ->whereNull('cancelled_at') ->whereBetween('completed_at', [$start, $end]) ->with([ 'contract' => function ($q) { $q->with([ 'type:id,name', 'account', 'clientCase.person' => function ($pq) { $pq->with(['addresses', 'phones']); }, 'clientCase.client:id,uuid,person_id', 'clientCase.client.person:id,full_name', ]); }, ]) ->orderByDesc('completed_at') ->limit(100) ->get(); return Inertia::render('Phone/Index', [ 'jobs' => $jobs, 'view_mode' => 'completed-today', ]); } public function showCase(\App\Models\ClientCase $clientCase, Request $request) { $userId = $request->user()->id; $completedMode = (bool) $request->boolean('completed'); // Eager load client case with person details $case = \App\Models\ClientCase::query() ->with(['person' => fn ($q) => $q->with(['addresses', 'phones', 'emails', 'bankAccounts'])]) ->findOrFail($clientCase->id); // Determine contracts of this case relevant to the current user // - Normal mode: contracts assigned to me and still active (not completed/cancelled) // - Completed mode (?completed=1): contracts where my field job was completed today if ($completedMode) { $start = now()->startOfDay(); $end = now()->endOfDay(); $contractIds = FieldJob::query() ->where('assigned_user_id', $userId) ->whereNull('cancelled_at') ->whereBetween('completed_at', [$start, $end]) ->whereHas('contract', fn ($q) => $q->where('client_case_id', $case->id)) ->pluck('contract_id') ->unique() ->values(); } else { $contractIds = FieldJob::query() ->where('assigned_user_id', $userId) ->whereNull('completed_at') ->whereNull('cancelled_at') ->whereHas('contract', fn ($q) => $q->where('client_case_id', $case->id)) ->pluck('contract_id') ->unique() ->values(); } $contracts = \App\Models\Contract::query() ->where('client_case_id', $case->id) ->whereIn('id', $contractIds) ->with(['type:id,name', 'account']) ->orderByDesc('created_at') ->get(); // Attach latest object (if any) to each contract as last_object for display if ($contracts->isNotEmpty()) { $byId = $contracts->keyBy('id'); $latestObjects = \App\Models\CaseObject::query() ->whereIn('contract_id', $byId->keys()) ->whereNull('deleted_at') ->select('id', 'reference', 'name', 'description', 'type', 'contract_id', 'created_at') ->orderByDesc('created_at') ->get() ->groupBy('contract_id') ->map(function ($group) { return $group->first(); }); foreach ($latestObjects as $cid => $obj) { if (isset($byId[$cid])) { $byId[$cid]->setAttribute('last_object', $obj); } } } // Build merged documents: case documents + documents of assigned contracts $contractRefMap = []; foreach ($contracts as $c) { $contractRefMap[$c->id] = $c->reference; } $contractDocs = \App\Models\Document::query() ->where('documentable_type', \App\Models\Contract::class) ->whereIn('documentable_id', $contractIds) ->orderByDesc('created_at') ->get() ->map(function ($d) use ($contractRefMap) { $arr = $d->toArray(); $arr['contract_reference'] = $contractRefMap[$d->documentable_id] ?? null; $arr['documentable_type'] = \App\Models\Contract::class; $arr['contract_uuid'] = optional(\App\Models\Contract::withTrashed()->find($d->documentable_id))->uuid; return $arr; }); $caseDocs = $case->documents()->orderByDesc('created_at')->get()->map(function ($d) use ($case) { $arr = $d->toArray(); $arr['documentable_type'] = \App\Models\ClientCase::class; $arr['client_case_uuid'] = $case->uuid; return $arr; }); $documents = $caseDocs->concat($contractDocs)->sortByDesc('created_at')->values(); // Provide minimal types for PersonInfoGrid $types = [ 'address_types' => \App\Models\Person\AddressType::all(), 'phone_types' => \App\Models\Person\PhoneType::all(), ]; // Case activities (compact for phone): latest 20 with relations $activities = $case->activities() ->with(['action', 'decision', 'contract:id,uuid,reference', 'user:id,name']) ->orderByDesc('created_at') ->limit(20) ->get() ->map(function ($a) { $a->setAttribute('user_name', optional($a->user)->name); return $a; }); // Determine segment filters from FieldJobSettings for this case/user context $settingIds = FieldJob::query() ->where('assigned_user_id', $userId) ->whereHas('contract', fn ($q) => $q->where('client_case_id', $case->id)) ->when( $completedMode, function ($q) { $q->whereNull('cancelled_at') ->whereBetween('completed_at', [now()->startOfDay(), now()->endOfDay()]); }, function ($q) { $q->whereNull('completed_at')->whereNull('cancelled_at'); } ) ->pluck('field_job_setting_id') ->filter() ->unique() ->values(); $segmentIds = collect(); if ($settingIds->isNotEmpty()) { $segmentIds = \App\Models\FieldJobSetting::query() ->whereIn('id', $settingIds) ->pluck('segment_id') ->filter() ->unique() ->values(); } // Filter actions and their decisions by the derived segment ids (decisions.segment_id) $actions = \App\Models\Action::query() ->when($segmentIds->isNotEmpty(), function ($q) use ($segmentIds) { // Filter actions by their segment_id matching the FieldJobSetting segment(s) $q->whereIn('segment_id', $segmentIds); }) ->with([ 'decisions' => function ($q) { $q->select('decisions.id', 'decisions.name', 'decisions.color_tag', 'decisions.auto_mail', 'decisions.email_template_id'); }, 'decisions.emailTemplate' => function ($q) { $q->select('id', 'name', 'entity_types', 'allow_attachments'); }, ]) ->get(['id', 'name', 'color_tag', 'segment_id']); return Inertia::render('Phone/Case/Index', [ 'client' => $case->client()->with('person', fn ($q) => $q->with(['addresses', 'phones', 'emails', 'bankAccounts']))->firstOrFail(), 'client_case' => $case, 'contracts' => $contracts, 'documents' => $documents, 'types' => $types, 'account_types' => \App\Models\AccountType::all(), // Provide decisions (filtered by segment) with linked email template metadata (entity_types, allow_attachments) 'actions' => $actions, 'activities' => $activities, 'completed_mode' => $completedMode, ]); } }