authorizeAbility($request, 'prescriptions.view'); $organization = $this->organization($request); $branchScope = app(OrganizationResolver::class)->branchScope($this->member($request)); $prescriptions = $this->prescriptions->list( $this->ownerRef($request), $organization->id, $request->only(['status', 'patient_id']), $branchScope, ); return view('care.prescriptions.index', [ 'organization' => $organization, 'prescriptions' => $prescriptions, 'statuses' => config('care.prescription_statuses'), ]); } public function queue(Request $request): View { $this->authorizeAbility($request, 'prescriptions.view'); $organization = $this->organization($request); $member = $this->member($request); $branchScope = app(OrganizationResolver::class)->branchScope($member); $branchId = (int) ($branchScope ?: \App\Models\Branch::owned($this->ownerRef($request)) ->where('organization_id', $organization->id) ->where('is_active', true) ->orderBy('name') ->value('id')); $queue = $this->prescriptions->pharmacyQueue($this->ownerRef($request), $organization->id); if ($branchScope) { $queue = $queue->filter(fn (Prescription $rx) => (int) ($rx->visit?->branch_id) === $branchScope)->values(); } $drugs = \App\Models\Drug::owned($this->ownerRef($request)) ->where('organization_id', $organization->id) ->where('is_active', true) ->with(['batches' => fn ($q) => $q->where('quantity_on_hand', '>', 0)->orderBy('expiry_date')]) ->orderBy('name') ->get(); $canDispense = app(\App\Services\Care\CarePermissions::class) ->can($member, 'prescriptions.dispense'); return view('care.prescriptions.queue', [ 'organization' => $organization, 'queue' => $queue, 'drugs' => $drugs, 'canDispense' => $canDispense, 'branchId' => $branchId, 'queueIntegration' => $branchId ? $this->queueBridge->listMeta($organization, CareQueueContexts::PHARMACY, $branchId) : ['enabled' => false], ]); } public function callNext(Request $request): RedirectResponse { $this->authorizeAbility($request, 'prescriptions.dispense'); $organization = $this->organization($request); $member = $this->member($request); $branchScope = app(OrganizationResolver::class)->branchScope($member); $branchId = (int) ($request->input('branch_id') ?: $branchScope); abort_unless($branchId > 0, 422); abort_unless($this->queueBridge->isEnabled($organization), 404); $result = $this->queueBridge->callNext($organization, CareQueueContexts::PHARMACY, $branchId, $member); $ticket = $result['ticket'] ?? null; if (! $ticket) { return back()->with('info', 'No prescriptions waiting at your pharmacy service point.'); } return back()->with('success', 'Called '.$ticket['ticket_number'].'.'); } public function serve(Request $request, Prescription $prescription): RedirectResponse { $this->authorizeAbility($request, 'prescriptions.dispense'); $this->authorizePrescription($request, $prescription); $organization = $this->organization($request); abort_unless($this->queueBridge->isEnabled($organization), 404); $ticket = $this->queueBridge->serve($organization, $prescription); if (! $ticket) { return back()->with('error', 'Could not serve pharmacy ticket.'); } return back()->with('success', 'Now serving '.$ticket['ticket_number'].'.'); } public function create(Request $request, Consultation $consultation): View { $this->authorizeAbility($request, 'prescriptions.manage'); $this->authorizeConsultation($request, $consultation); $consultation->load(['patient', 'practitioner']); $practitioners = Practitioner::owned($this->ownerRef($request)) ->where('organization_id', $this->organization($request)->id) ->where('is_active', true) ->orderBy('name') ->get(); return view('care.prescriptions.create', [ 'consultation' => $consultation, 'practitioners' => $practitioners, 'routes' => config('care.medication_routes'), ]); } public function store(Request $request, Consultation $consultation): RedirectResponse { $this->authorizeAbility($request, 'prescriptions.manage'); $this->authorizeConsultation($request, $consultation); $prescription = $this->prescriptions->createFromConsultation( $consultation, $this->ownerRef($request), $this->validatedPrescriptionData($request), $this->ownerRef($request), ); return redirect()->route('care.prescriptions.show', $prescription) ->with('success', 'Prescription created.'); } public function show(Request $request, Prescription $prescription): View { $this->authorizeAbility($request, 'prescriptions.view'); $this->authorizePrescription($request, $prescription); $prescription->load(['patient', 'practitioner', 'items', 'consultation', 'visit']); $canManage = app(\App\Services\Care\CarePermissions::class) ->can($this->member($request), 'prescriptions.manage'); $canDispense = app(\App\Services\Care\CarePermissions::class) ->can($this->member($request), 'prescriptions.dispense'); return view('care.prescriptions.show', [ 'prescription' => $prescription, 'statuses' => config('care.prescription_statuses'), 'routes' => config('care.medication_routes'), 'canManage' => $canManage, 'canDispense' => $canDispense, ]); } public function activate(Request $request, Prescription $prescription): RedirectResponse { $this->authorizeAbility($request, 'prescriptions.manage'); $this->authorizePrescription($request, $prescription); $this->prescriptions->activate($prescription, $this->ownerRef($request), $this->ownerRef($request)); return back()->with('success', 'Prescription activated.'); } public function dispense(Request $request, Prescription $prescription): RedirectResponse { $this->authorizeAbility($request, 'prescriptions.dispense'); $this->authorizePrescription($request, $prescription); $allocations = $request->input('allocations', []); if (! empty($allocations)) { $this->pharmacy->dispensePrescription( $prescription, $this->ownerRef($request), $allocations, $this->ownerRef($request), ); } else { $this->prescriptions->dispense($prescription, $this->ownerRef($request), $this->ownerRef($request)); } return redirect()->route('care.prescriptions.queue') ->with('success', 'Prescription dispensed.'); } public function cancel(Request $request, Prescription $prescription): RedirectResponse { $this->authorizeAbility($request, 'prescriptions.manage'); $this->authorizePrescription($request, $prescription); $this->prescriptions->cancel($prescription, $this->ownerRef($request), $this->ownerRef($request)); return back()->with('success', 'Prescription cancelled.'); } protected function authorizeConsultation(Request $request, Consultation $consultation): void { $this->authorizeOwner($request, $consultation); $consultation->loadMissing('visit'); abort_unless($consultation->visit->organization_id === $this->organization($request)->id, 404); } protected function authorizePrescription(Request $request, Prescription $prescription): void { $this->authorizeOwner($request, $prescription); abort_unless($prescription->organization_id === $this->organization($request)->id, 404); $branchId = app(OrganizationResolver::class)->branchScope($this->member($request)); if ($branchId !== null) { $prescription->loadMissing('visit'); abort_unless($prescription->visit->branch_id === $branchId, 404); } } /** * @return array */ protected function validatedPrescriptionData(Request $request): array { return $request->validate([ 'practitioner_id' => ['nullable', 'integer', 'exists:care_practitioners,id'], 'notes' => ['nullable', 'string', 'max:5000'], 'activate' => ['nullable', 'boolean'], 'items' => ['required', 'array', 'min:1'], 'items.*.is_procedure' => ['nullable', 'boolean'], 'items.*.name' => ['required', 'string', 'max:255'], 'items.*.dosage' => ['nullable', 'string', 'max:100'], 'items.*.frequency' => ['nullable', 'string', 'max:100'], 'items.*.duration' => ['nullable', 'string', 'max:100'], 'items.*.route' => ['nullable', 'string', 'max:50'], 'items.*.quantity' => ['nullable', 'string', 'max:50'], 'items.*.instructions' => ['nullable', 'string', 'max:2000'], ]); } }