authorizeAbility($request, 'counters.view'); $owner = $this->ownerRef($request); $organization = $this->organization($request); $counters = Counter::owned($owner) ->where('organization_id', $organization->id) ->with(['branch', 'serviceQueues']) ->when(true, fn ($q) => $this->scopeToBranch($request, $q)) ->orderBy('name') ->paginate(20); return view('qms.counters.index', compact('counters', 'organization')); } public function show(Request $request, Counter $counter): View { $this->authorizeAbility($request, 'counters.view'); $this->authorizeOwner($request, $counter); $owner = $this->ownerRef($request); $counter->load(['branch', 'serviceQueues']); $currentTicket = \App\Models\Ticket::owned($owner) ->where('counter_id', $counter->id) ->whereIn('status', ['called', 'serving', 'on_hold']) ->with('serviceQueue') ->latest('called_at') ->first(); $waitingCounts = $counter->serviceQueues->mapWithKeys(function (ServiceQueue $queue) use ($owner) { $count = \App\Models\Ticket::owned($owner) ->where('service_queue_id', $queue->id) ->where('status', 'waiting') ->count(); return [$queue->id => $count]; }); $canManage = app(\App\Services\Qms\QmsPermissions::class)->can($this->member($request), 'counters.manage'); return view('qms.counters.show', compact('counter', 'currentTicket', 'waitingCounts', 'canManage')); } public function create(Request $request): View { $this->authorizeAbility($request, 'counters.manage'); $owner = $this->ownerRef($request); $organization = $this->organization($request); $branches = Branch::owned($owner)->where('organization_id', $organization->id)->where('is_active', true)->orderBy('name')->get(); $queues = ServiceQueue::owned($owner)->where('organization_id', $organization->id)->where('is_active', true)->orderBy('name')->get(); return view('qms.counters.create', compact('organization', 'branches', 'queues')); } public function store(Request $request): RedirectResponse { $this->authorizeAbility($request, 'counters.manage'); $owner = $this->ownerRef($request); $organization = $this->organization($request); $validated = $this->validatedCounter($request); $counter = Counter::create([ 'owner_ref' => $owner, 'organization_id' => $organization->id, 'branch_id' => $validated['branch_id'], 'name' => $validated['name'], 'code' => $validated['code'] ?? null, 'status' => 'available', 'is_active' => true, ]); if (! empty($validated['queue_ids'])) { $counter->serviceQueues()->sync($validated['queue_ids']); } AuditLogger::record($owner, 'counter.created', $organization->id, $owner, Counter::class, $counter->id); return redirect()->route('qms.counters.show', $counter)->with('success', 'Counter created.'); } public function edit(Request $request, Counter $counter): View { $this->authorizeAbility($request, 'counters.manage'); $this->authorizeOwner($request, $counter); $owner = $this->ownerRef($request); return view('qms.counters.edit', [ 'counter' => $counter->load('serviceQueues'), 'branches' => Branch::owned($owner)->where('organization_id', $counter->organization_id)->orderBy('name')->get(), 'queues' => ServiceQueue::owned($owner)->where('organization_id', $counter->organization_id)->orderBy('name')->get(), ]); } public function update(Request $request, Counter $counter): RedirectResponse { $this->authorizeAbility($request, 'counters.manage'); $this->authorizeOwner($request, $counter); $validated = $this->validatedCounter($request); $counter->update([ 'name' => $validated['name'], 'code' => $validated['code'] ?? null, 'branch_id' => $validated['branch_id'], 'is_active' => $request->boolean('is_active', $counter->is_active), ]); $counter->serviceQueues()->sync($validated['queue_ids'] ?? []); AuditLogger::record($this->ownerRef($request), 'counter.updated', $counter->organization_id, $this->ownerRef($request), Counter::class, $counter->id); return redirect()->route('qms.counters.show', $counter)->with('success', 'Counter updated.'); } /** * @return array */ protected function validatedCounter(Request $request): array { return $request->validate([ 'name' => ['required', 'string', 'max:255'], 'code' => ['nullable', 'string', 'max:50'], 'branch_id' => ['required', 'exists:queue_branches,id'], 'queue_ids' => ['nullable', 'array'], 'queue_ids.*' => ['integer', 'exists:queue_service_queues,id'], ]); } }