Keep consultation context on nested clinical pages and add Call again on patient queue cards.
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>
This commit is contained in:
isaacclad
2026-07-17 17:48:34 +00:00
co-authored by Cursor
parent e73b39b678
commit 94e53d05bf
21 changed files with 615 additions and 30 deletions
@@ -12,6 +12,7 @@ use App\Models\Visit;
use App\Services\Care\AssessmentService;
use App\Services\Care\CareFeatures;
use App\Services\Care\CarePermissions;
use App\Services\Care\ConsultationReturnContext;
use App\Services\Care\FhirAssessmentExporter;
use App\Services\Care\OrganizationResolver;
use Illuminate\Http\JsonResponse;
@@ -54,6 +55,7 @@ class AssessmentController extends Controller
'statuses' => config('care.assessment_statuses'),
'categories' => config('care.assessment_template_categories'),
'filters' => $request->only(['status', 'template_code', 'category']),
'returnConsultation' => app(ConsultationReturnContext::class)->resolve($request, (int) $patient->id),
]);
}
@@ -111,8 +113,13 @@ class AssessmentController extends Controller
$context,
);
$return = app(ConsultationReturnContext::class);
return redirect()
->route('care.assessments.show', $assessment)
->route('care.assessments.show', array_filter([
'assessment' => $assessment,
...$return->routeQuery($request),
]))
->with('success', 'Assessment started.');
}
@@ -141,8 +148,14 @@ class AssessmentController extends Controller
],
);
$return = app(ConsultationReturnContext::class);
$return->remember($consultation);
return redirect()
->route('care.assessments.show', $assessment)
->route('care.assessments.show', array_filter([
'assessment' => $assessment,
...$return->query($consultation),
]))
->with('success', 'Assessment started.');
}
@@ -177,11 +190,15 @@ class AssessmentController extends Controller
}
}
$return = app(ConsultationReturnContext::class);
return view('care.assessments.show', [
'assessment' => $assessment,
'answersByCode' => $answersByCode,
'canEdit' => $canEdit,
'statuses' => config('care.assessment_statuses'),
'returnConsultation' => $return->resolve($request, (int) $assessment->patient_id)
?? $return->resolveLinked($request, $assessment->consultation),
]);
}
@@ -205,8 +222,13 @@ class AssessmentController extends Controller
array_key_exists('notes', $validated) ? $validated['notes'] : null,
);
$return = app(ConsultationReturnContext::class);
return redirect()
->route('care.assessments.show', $assessment)
->route('care.assessments.show', array_filter([
'assessment' => $assessment,
...$return->routeQuery($request),
]))
->with('success', 'Assessment saved.');
}
@@ -240,8 +262,13 @@ class AssessmentController extends Controller
$this->ownerRef($request),
);
$return = app(ConsultationReturnContext::class);
return redirect()
->route('care.assessments.show', $assessment)
->route('care.assessments.show', array_filter([
'assessment' => $assessment,
...$return->routeQuery($request),
]))
->with('success', 'Assessment completed.');
}
+16 -2
View File
@@ -5,10 +5,12 @@ namespace App\Http\Controllers\Care;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Care\Concerns\ScopesToAccount;
use App\Models\Bill;
use App\Models\Consultation;
use App\Models\Visit;
use App\Services\Care\BillService;
use App\Services\Care\CareQueueBridge;
use App\Services\Care\CareQueueContexts;
use App\Services\Care\ConsultationReturnContext;
use App\Services\Care\OrganizationResolver;
use App\Services\Payments\MerchantGatewayService;
use Illuminate\Http\RedirectResponse;
@@ -100,8 +102,12 @@ class BillController extends Controller
$bill = $this->bills->generateFromVisit($visit, $this->ownerRef($request), $this->ownerRef($request));
return redirect()->route('care.bills.show', $bill)
->with('success', 'Bill generated from visit.');
$return = app(ConsultationReturnContext::class);
return redirect()->route('care.bills.show', array_filter([
'bill' => $bill,
...$return->routeQuery($request),
]))->with('success', 'Bill generated from visit.');
}
public function show(Request $request, Bill $bill): View
@@ -124,6 +130,12 @@ class BillController extends Controller
->except(['gateway'])
->all();
$return = app(ConsultationReturnContext::class);
$linked = Consultation::query()
->where('visit_id', $bill->visit_id)
->orderByDesc('id')
->first();
return view('care.bills.show', [
'bill' => $bill,
'statuses' => config('care.bill_statuses'),
@@ -135,6 +147,8 @@ class BillController extends Controller
'gatewayConfigured' => $gatewayConfigured,
'gatewayProvider' => $gateway?->provider,
'gatewayLabels' => config('care.payment_gateways'),
'returnConsultation' => $return->resolve($request, (int) $bill->patient_id)
?? $return->resolveLinked($request, $linked),
]);
}
@@ -11,6 +11,7 @@ use App\Models\Assessment;
use App\Models\AssessmentTemplate;
use App\Services\Care\CareFeatures;
use App\Services\Care\CarePermissions;
use App\Services\Care\ConsultationReturnContext;
use App\Services\Care\ConsultationService;
use App\Services\Care\OrganizationResolver;
use App\Services\Care\PathwayService;
@@ -37,6 +38,8 @@ class ConsultationController extends Controller
'investigationRequests.investigationType', 'prescriptions.items',
]);
app(ConsultationReturnContext::class)->remember($consultation);
$permissions = app(CarePermissions::class);
$member = $this->member($request);
$organization = $this->organization($request);
@@ -235,6 +238,8 @@ class ConsultationController extends Controller
$this->ownerRef($request),
);
app(ConsultationReturnContext::class)->forget();
return redirect()->route('care.patients.show', $consultation->patient)
->with('success', 'Consultation completed.');
}
@@ -11,6 +11,7 @@ use App\Models\InvestigationType;
use App\Models\Member;
use App\Services\Care\CareQueueBridge;
use App\Services\Care\CareQueueContexts;
use App\Services\Care\ConsultationReturnContext;
use App\Services\Care\InvestigationService;
use App\Services\Care\OrganizationResolver;
use Illuminate\Http\RedirectResponse;
@@ -149,6 +150,7 @@ class InvestigationController extends Controller
$investigation->load([
'patient', 'investigationType', 'practitioner', 'branch',
'result.values', 'result.attachments', 'assignedMember',
'consultation.patient', 'consultation.appointment',
]);
$canManage = app(\App\Services\Care\CarePermissions::class)
@@ -156,11 +158,15 @@ class InvestigationController extends Controller
$canViewResults = app(\App\Services\Care\CarePermissions::class)
->can($this->member($request), 'lab.results.view');
$return = app(ConsultationReturnContext::class);
return view('care.lab.requests.show', [
'investigation' => $investigation,
'statuses' => config('care.investigation_statuses'),
'canManage' => $canManage,
'canViewResults' => $canViewResults,
'returnConsultation' => $return->resolve($request, (int) $investigation->patient_id)
?? $return->resolveLinked($request, $investigation->consultation),
]);
}
@@ -10,6 +10,7 @@ use App\Models\Patient;
use App\Models\PatientPathway;
use App\Services\Care\CareFeatures;
use App\Services\Care\CarePermissions;
use App\Services\Care\ConsultationReturnContext;
use App\Services\Care\OrganizationResolver;
use App\Services\Care\PathwayService;
use Illuminate\Http\JsonResponse;
@@ -51,6 +52,7 @@ class PathwayController extends Controller
'catalog' => $catalog,
'canManage' => $canManage,
'statuses' => config('care.patient_pathway_statuses'),
'returnConsultation' => app(ConsultationReturnContext::class)->resolve($request, (int) $patient->id),
]);
}
@@ -91,8 +93,13 @@ class PathwayController extends Controller
],
);
$return = app(ConsultationReturnContext::class);
return redirect()
->route('care.pathways.index', $patient)
->route('care.pathways.index', array_filter([
'patient' => $patient,
...$return->routeQuery($request),
]))
->with('success', "Pathway “{$pathway->name}” activated.");
}
@@ -9,6 +9,7 @@ use App\Models\Prescription;
use App\Models\Practitioner;
use App\Services\Care\CareQueueBridge;
use App\Services\Care\CareQueueContexts;
use App\Services\Care\ConsultationReturnContext;
use App\Services\Care\OrganizationResolver;
use App\Services\Care\PharmacyService;
use App\Services\Care\PrescriptionService;
@@ -126,6 +127,8 @@ class PrescriptionController extends Controller
$consultation->load(['patient', 'practitioner']);
app(ConsultationReturnContext::class)->remember($consultation);
$practitioners = Practitioner::owned($this->ownerRef($request))
->where('organization_id', $this->organization($request)->id)
->where('is_active', true)
@@ -151,8 +154,13 @@ class PrescriptionController extends Controller
$this->ownerRef($request),
);
return redirect()->route('care.prescriptions.show', $prescription)
->with('success', 'Prescription created.');
$return = app(ConsultationReturnContext::class);
$return->remember($consultation);
return redirect()->route('care.prescriptions.show', array_filter([
'prescription' => $prescription,
...$return->query($consultation),
]))->with('success', 'Prescription created.');
}
public function show(Request $request, Prescription $prescription): View
@@ -167,12 +175,16 @@ class PrescriptionController extends Controller
$canDispense = app(\App\Services\Care\CarePermissions::class)
->can($this->member($request), 'prescriptions.dispense');
$return = app(ConsultationReturnContext::class);
return view('care.prescriptions.show', [
'prescription' => $prescription,
'statuses' => config('care.prescription_statuses'),
'routes' => config('care.medication_routes'),
'canManage' => $canManage,
'canDispense' => $canDispense,
'returnConsultation' => $return->resolve($request, (int) $prescription->patient_id)
?? $return->resolveLinked($request, $prescription->consultation),
]);
}
@@ -138,6 +138,21 @@ class QueueController extends Controller
return back()->with('success', 'Completed '.$ticket['ticket_number'].'.');
}
public function recall(Request $request, Appointment $appointment): RedirectResponse
{
$this->authorizeAbility($request, 'consultations.manage');
$this->authorizeAppointment($request, $appointment);
$organization = $this->organization($request);
abort_unless($this->queueBridge->isEnabled($organization), 404);
$ticket = $this->queueBridge->recall($organization, $appointment);
if (! $ticket) {
return back()->with('error', 'Could not call patient again.');
}
return back()->with('success', 'Called again '.$ticket['ticket_number'].'.');
}
public function start(Request $request, Appointment $appointment): RedirectResponse
{
$this->authorizeAbility($request, 'consultations.manage');