authorizeAbility($request, 'appointments.manage'); $this->authorizeVisit($request, $visit); $organization = $this->organization($request); abort_unless($this->features->enabled($organization, CareFeatures::WORKFLOW_ENGINE), 404); $validated = $request->validate([ 'to_code' => ['nullable', 'string', 'max:100'], ]); if (! $this->workflows->canManuallyAdvance($visit)) { return back()->with('error', 'Complete this clinical service from its own workspace before advancing the visit.'); } try { $advance = $this->workflows->advance($visit, $validated['to_code'] ?? null); } catch (\DomainException $e) { return back()->with('error', $e->getMessage()); } if ($advance === null) { return back()->with('info', 'This visit has no next workflow stage.'); } AuditLogger::record( $this->ownerRef($request), 'visit.workflow_advanced', $visit->organization_id, $this->ownerRef($request), VisitStageAdvance::class, $advance->id, ['stage_code' => $advance->stage_code, 'status' => $advance->status], ); $this->queueRelease->releaseCurrent($organization, $visit); $message = $advance->isBlocked() ? "Visit moved to {$advance->stage?->name}; financial clearance is required before service." : "Visit moved to {$advance->stage?->name}."; return back()->with($advance->isBlocked() ? 'warning' : 'success', $message); } protected function authorizeVisit(Request $request, Visit $visit): void { $this->authorizeOwner($request, $visit); abort_unless($visit->organization_id === $this->organization($request)->id, 404); $branchId = app(OrganizationResolver::class)->branchScope($this->member($request)); if ($branchId !== null && $visit->branch_id !== $branchId) { abort(404); } } }