Deploy Ladill Care / deploy (push) Successful in 1m7s
Doctors can return to the active consultation from forms, lab, prescriptions, pathways, and bills; queue cards can re-announce called/serving tickets via the existing Queue recall bridge. Co-authored-by: Cursor <cursoragent@cursor.com>
147 lines
4.1 KiB
PHP
147 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Care;
|
|
|
|
use App\Models\Consultation;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Str;
|
|
|
|
/**
|
|
* Preserves "serving from consultation" context when doctors navigate to nested
|
|
* forms (prescriptions, assessments, lab requests, pathways, bills).
|
|
*
|
|
* Preference order: explicit ?from_consultation= query → session remembered on
|
|
* consultation show. Direct access without either shows no consultation chrome.
|
|
*/
|
|
class ConsultationReturnContext
|
|
{
|
|
public const QUERY_KEY = 'from_consultation';
|
|
|
|
public const SESSION_KEY = 'care.from_consultation';
|
|
|
|
public function remember(Consultation $consultation): void
|
|
{
|
|
if ($consultation->status === Consultation::STATUS_COMPLETED) {
|
|
$this->forget();
|
|
|
|
return;
|
|
}
|
|
|
|
session([self::SESSION_KEY => $consultation->uuid]);
|
|
}
|
|
|
|
public function forget(): void
|
|
{
|
|
session()->forget(self::SESSION_KEY);
|
|
}
|
|
|
|
public function uuidFrom(Request $request): ?string
|
|
{
|
|
foreach ([
|
|
$request->query(self::QUERY_KEY),
|
|
$request->input(self::QUERY_KEY),
|
|
session(self::SESSION_KEY),
|
|
] as $candidate) {
|
|
if (is_string($candidate) && Str::isUuid($candidate)) {
|
|
return $candidate;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Capture an explicit from_consultation posted/queried value into session
|
|
* so subsequent redirects keep the serving flow.
|
|
*/
|
|
public function capture(Request $request): void
|
|
{
|
|
$uuid = $request->query(self::QUERY_KEY) ?? $request->input(self::QUERY_KEY);
|
|
if (is_string($uuid) && Str::isUuid($uuid)) {
|
|
session([self::SESSION_KEY => $uuid]);
|
|
}
|
|
}
|
|
|
|
public function resolve(Request $request, ?int $patientId = null): ?Consultation
|
|
{
|
|
$this->capture($request);
|
|
|
|
$uuid = $this->uuidFrom($request);
|
|
if ($uuid === null) {
|
|
return null;
|
|
}
|
|
|
|
$consultation = Consultation::query()
|
|
->where('uuid', $uuid)
|
|
->with(['patient', 'appointment'])
|
|
->first();
|
|
|
|
if (! $consultation) {
|
|
return null;
|
|
}
|
|
|
|
if ($patientId !== null && (int) $consultation->patient_id !== $patientId) {
|
|
return null;
|
|
}
|
|
|
|
return $consultation;
|
|
}
|
|
|
|
/**
|
|
* Resolve from an explicit linked consultation (e.g. prescription.consultation)
|
|
* only when the doctor is already in a serving flow for that consultation.
|
|
*/
|
|
public function resolveLinked(Request $request, ?Consultation $linked): ?Consultation
|
|
{
|
|
if (! $linked) {
|
|
return null;
|
|
}
|
|
|
|
$active = $this->resolve($request, (int) $linked->patient_id);
|
|
if ($active && $active->id === $linked->id) {
|
|
return $active;
|
|
}
|
|
|
|
// Nested under consultation route (create prescription) or still in progress
|
|
// with an explicit query/session match already handled above. For linked
|
|
// records opened mid-flow without query (POST redirect), prefer the linked
|
|
// consultation when session matches its uuid.
|
|
$uuid = $this->uuidFrom($request);
|
|
if ($uuid !== null && $linked->uuid === $uuid) {
|
|
$linked->loadMissing(['patient', 'appointment']);
|
|
|
|
return $linked;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @return array{from_consultation: string}
|
|
*/
|
|
public function query(Consultation $consultation): array
|
|
{
|
|
return [self::QUERY_KEY => $consultation->uuid];
|
|
}
|
|
|
|
public function withQuery(string $url, Consultation $consultation): string
|
|
{
|
|
$separator = str_contains($url, '?') ? '&' : '?';
|
|
|
|
return $url.$separator.self::QUERY_KEY.'='.urlencode($consultation->uuid);
|
|
}
|
|
|
|
/**
|
|
* Route parameters to keep return context on redirects (empty when none).
|
|
*
|
|
* @return array<string, string>
|
|
*/
|
|
public function routeQuery(Request $request): array
|
|
{
|
|
$this->capture($request);
|
|
$uuid = $this->uuidFrom($request);
|
|
|
|
return $uuid ? [self::QUERY_KEY => $uuid] : [];
|
|
}
|
|
}
|