Lock doctors to their assigned patients and hide branch filters.
Deploy Ladill Care / deploy (push) Successful in 1m2s
Deploy Ladill Care / deploy (push) Successful in 1m2s
Doctors no longer see branch/practitioner pickers; queue, appointments, patients, and dashboard only include visits on their linked desk. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -34,21 +34,35 @@ class AppointmentController extends Controller
|
||||
$this->authorizeAbility($request, 'appointments.view');
|
||||
$organization = $this->organization($request);
|
||||
$member = $this->member($request);
|
||||
$branchScope = app(OrganizationResolver::class)->branchScope($member);
|
||||
$resolver = app(OrganizationResolver::class);
|
||||
$branchScope = $resolver->branchScope($member);
|
||||
$practitionerScope = $resolver->practitionerScope($organization, $member);
|
||||
|
||||
$filters = $request->only(['status', 'practitioner_id', 'date', 'patient_id']);
|
||||
if ($practitionerScope !== null) {
|
||||
unset($filters['practitioner_id']);
|
||||
}
|
||||
|
||||
$appointments = $this->appointments->list(
|
||||
$this->ownerRef($request),
|
||||
$organization->id,
|
||||
$request->only(['status', 'practitioner_id', 'date', 'patient_id']),
|
||||
$branchScope,
|
||||
$filters,
|
||||
$practitionerScope === null ? $branchScope : null,
|
||||
$practitionerScope,
|
||||
);
|
||||
|
||||
$practitioners = $this->activePractitioners($request, $organization->id);
|
||||
$practitioners = $practitionerScope === null
|
||||
? $this->activePractitioners($request, $organization->id)
|
||||
: collect();
|
||||
|
||||
$owner = $this->ownerRef($request);
|
||||
$appointmentQuery = Appointment::owned($owner)
|
||||
->where('organization_id', $organization->id)
|
||||
->when($branchScope, fn ($q) => $q->where('branch_id', $branchScope));
|
||||
->where('organization_id', $organization->id);
|
||||
if ($practitionerScope !== null) {
|
||||
$appointmentQuery->whereIn('practitioner_id', $practitionerScope ?: [0]);
|
||||
} elseif ($branchScope) {
|
||||
$appointmentQuery->where('branch_id', $branchScope);
|
||||
}
|
||||
|
||||
$heroStats = [
|
||||
'today' => (clone $appointmentQuery)->whereDate('scheduled_at', today())->count(),
|
||||
@@ -63,6 +77,7 @@ class AppointmentController extends Controller
|
||||
'organization' => $organization,
|
||||
'appointments' => $appointments,
|
||||
'practitioners' => $practitioners,
|
||||
'lockToPractitioner' => $practitionerScope !== null,
|
||||
'statuses' => config('care.appointment_statuses'),
|
||||
'heroStats' => $heroStats,
|
||||
]);
|
||||
|
||||
@@ -109,6 +109,23 @@ class DashboardController extends Controller
|
||||
?Member $member,
|
||||
?int $branchScope,
|
||||
): array {
|
||||
$organization = $this->organization($request);
|
||||
$practitionerScope = app(OrganizationResolver::class)->practitionerScope($organization, $member);
|
||||
|
||||
if ($practitionerScope !== null) {
|
||||
$queue = $this->appointments->queueForPractitioners($owner, $practitionerScope);
|
||||
$inConsultation = Appointment::owned($owner)
|
||||
->where('organization_id', $organizationId)
|
||||
->where('status', Appointment::STATUS_IN_CONSULTATION)
|
||||
->whereIn('practitioner_id', $practitionerScope ?: [0])
|
||||
->with(['patient', 'practitioner', 'consultation'])
|
||||
->orderBy('started_at')
|
||||
->limit(20)
|
||||
->get();
|
||||
|
||||
return [$queue, $inConsultation, $practitionerScope[0] ?? null];
|
||||
}
|
||||
|
||||
$practitioner = null;
|
||||
if ($member) {
|
||||
$practitioner = Practitioner::owned($owner)
|
||||
|
||||
@@ -27,19 +27,34 @@ class PatientController extends Controller
|
||||
{
|
||||
$this->authorizeAbility($request, 'patients.view');
|
||||
$organization = $this->organization($request);
|
||||
$branchScope = app(OrganizationResolver::class)->branchScope($this->member($request));
|
||||
$member = $this->member($request);
|
||||
$resolver = app(OrganizationResolver::class);
|
||||
$branchScope = $resolver->branchScope($member);
|
||||
$practitionerScope = $resolver->practitionerScope($organization, $member);
|
||||
|
||||
$patients = $this->patients->search(
|
||||
$this->ownerRef($request),
|
||||
$organization->id,
|
||||
$request->only(['q', 'patient_number', 'phone', 'national_id', 'date_of_birth']),
|
||||
$branchScope,
|
||||
$practitionerScope === null ? $branchScope : null,
|
||||
$practitionerScope,
|
||||
);
|
||||
|
||||
$owner = $this->ownerRef($request);
|
||||
$patientQuery = Patient::owned($owner)
|
||||
->where('organization_id', $organization->id)
|
||||
->when($branchScope, fn ($q) => $q->where('branch_id', $branchScope));
|
||||
->where('organization_id', $organization->id);
|
||||
if ($practitionerScope !== null) {
|
||||
if ($practitionerScope === []) {
|
||||
$patientQuery->whereRaw('1 = 0');
|
||||
} else {
|
||||
$patientQuery->whereHas(
|
||||
'appointments',
|
||||
fn ($q) => $q->whereIn('practitioner_id', $practitionerScope),
|
||||
);
|
||||
}
|
||||
} elseif ($branchScope) {
|
||||
$patientQuery->where('branch_id', $branchScope);
|
||||
}
|
||||
|
||||
$heroStats = [
|
||||
'total' => (clone $patientQuery)->count(),
|
||||
|
||||
@@ -33,43 +33,84 @@ class QueueController extends Controller
|
||||
$this->authorizeAbility($request, 'appointments.view');
|
||||
$organization = $this->organization($request);
|
||||
$member = $this->member($request);
|
||||
$owner = $this->ownerRef($request);
|
||||
$resolver = app(OrganizationResolver::class);
|
||||
$practitionerScope = $resolver->practitionerScope($organization, $member);
|
||||
$lockToPractitioner = $practitionerScope !== null;
|
||||
|
||||
$branches = $this->branchContext->branches($request, $organization, $member);
|
||||
$branchId = $this->branchContext->resolve($request, $organization, $member);
|
||||
$practitionerId = $request->input('practitioner_id') ? (int) $request->input('practitioner_id') : null;
|
||||
$practitionerId = $lockToPractitioner
|
||||
? ($practitionerScope[0] ?? null)
|
||||
: ($request->input('practitioner_id') ? (int) $request->input('practitioner_id') : null);
|
||||
|
||||
$queueIntegration = ['enabled' => false];
|
||||
if ($branchId && $this->queueBridge->isEnabled($organization)) {
|
||||
// Catch up tickets for every waiting appointment (consultation + specialties).
|
||||
$this->queueBridge->syncMissingAppointmentTickets($organization, $branchId, 100);
|
||||
$queueIntegration = $this->queueBridge->listMeta($organization, CareQueueContexts::CONSULTATION, $branchId);
|
||||
if ($this->queueBridge->isEnabled($organization)) {
|
||||
$syncBranches = $lockToPractitioner
|
||||
? Practitioner::owned($owner)
|
||||
->whereIn('id', $practitionerScope ?: [0])
|
||||
->pluck('branch_id')
|
||||
->map(fn ($id) => (int) $id)
|
||||
->unique()
|
||||
->filter()
|
||||
->values()
|
||||
->all()
|
||||
: array_filter([$branchId]);
|
||||
|
||||
foreach ($syncBranches as $syncBranchId) {
|
||||
$this->queueBridge->syncMissingAppointmentTickets($organization, $syncBranchId, 100);
|
||||
}
|
||||
|
||||
if ($branchId > 0) {
|
||||
$queueIntegration = $this->queueBridge->listMeta($organization, CareQueueContexts::CONSULTATION, $branchId);
|
||||
} elseif ($syncBranches !== []) {
|
||||
$queueIntegration = $this->queueBridge->listMeta(
|
||||
$organization,
|
||||
CareQueueContexts::CONSULTATION,
|
||||
(int) $syncBranches[0],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$queue = $branchId
|
||||
? $this->appointments->queue($this->ownerRef($request), $branchId, $practitionerId)
|
||||
: collect();
|
||||
if ($lockToPractitioner) {
|
||||
$queue = $this->appointments->queueForPractitioners($owner, $practitionerScope ?? []);
|
||||
$inConsultation = Appointment::owned($owner)
|
||||
->where('organization_id', $organization->id)
|
||||
->where('status', Appointment::STATUS_IN_CONSULTATION)
|
||||
->whereIn('practitioner_id', $practitionerScope ?: [0])
|
||||
->with(['patient', 'practitioner', 'consultation'])
|
||||
->orderBy('started_at')
|
||||
->get();
|
||||
} else {
|
||||
$queue = $branchId
|
||||
? $this->appointments->queue($owner, $branchId, $practitionerId)
|
||||
: collect();
|
||||
$inConsultation = Appointment::owned($owner)
|
||||
->where('organization_id', $organization->id)
|
||||
->where('status', Appointment::STATUS_IN_CONSULTATION)
|
||||
->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
|
||||
->when($practitionerId, fn ($q) => $q->where('practitioner_id', $practitionerId))
|
||||
->with(['patient', 'practitioner', 'consultation'])
|
||||
->orderBy('started_at')
|
||||
->get();
|
||||
}
|
||||
|
||||
$inConsultation = Appointment::owned($this->ownerRef($request))
|
||||
$canManageQueue = app(CarePermissions::class)->can($member, 'queue.manage');
|
||||
$canConsult = app(CarePermissions::class)->can($member, 'consultations.manage');
|
||||
|
||||
$todayQuery = Appointment::owned($owner)
|
||||
->where('organization_id', $organization->id)
|
||||
->where('status', Appointment::STATUS_IN_CONSULTATION)
|
||||
->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
|
||||
->when($practitionerId, fn ($q) => $q->where('practitioner_id', $practitionerId))
|
||||
->with(['patient', 'practitioner', 'consultation'])
|
||||
->orderBy('started_at')
|
||||
->get();
|
||||
|
||||
$canManageQueue = app(CarePermissions::class)
|
||||
->can($this->member($request), 'queue.manage');
|
||||
$canConsult = app(CarePermissions::class)
|
||||
->can($this->member($request), 'consultations.manage');
|
||||
->whereDate('scheduled_at', today());
|
||||
if ($lockToPractitioner) {
|
||||
$todayQuery->whereIn('practitioner_id', $practitionerScope ?: [0]);
|
||||
} elseif ($branchId) {
|
||||
$todayQuery->where('branch_id', $branchId);
|
||||
}
|
||||
|
||||
$heroStats = [
|
||||
'waiting' => $queue->count(),
|
||||
'in_consultation' => $inConsultation->count(),
|
||||
'today' => Appointment::owned($this->ownerRef($request))
|
||||
->where('organization_id', $organization->id)
|
||||
->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
|
||||
->whereDate('scheduled_at', today())
|
||||
->count(),
|
||||
'today' => $todayQuery->count(),
|
||||
];
|
||||
|
||||
return view('care.queue.index', [
|
||||
@@ -77,12 +118,15 @@ class QueueController extends Controller
|
||||
'branches' => $branches,
|
||||
'branchId' => $branchId,
|
||||
'canSwitchBranch' => $this->branchContext->canSwitch($member),
|
||||
'practitioners' => Practitioner::owned($this->ownerRef($request))
|
||||
->where('organization_id', $organization->id)
|
||||
->where('is_active', true)
|
||||
->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
|
||||
->orderBy('name')
|
||||
->get(),
|
||||
'lockToPractitioner' => $lockToPractitioner,
|
||||
'practitioners' => $lockToPractitioner
|
||||
? collect()
|
||||
: Practitioner::owned($owner)
|
||||
->where('organization_id', $organization->id)
|
||||
->where('is_active', true)
|
||||
->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
|
||||
->orderBy('name')
|
||||
->get(),
|
||||
'practitionerId' => $practitionerId,
|
||||
'queue' => $queue,
|
||||
'inConsultation' => $inConsultation,
|
||||
@@ -100,7 +144,17 @@ class QueueController extends Controller
|
||||
abort_unless($this->queueBridge->isEnabled($organization), 404);
|
||||
|
||||
$member = $this->member($request);
|
||||
$practitionerScope = app(OrganizationResolver::class)->practitionerScope($organization, $member);
|
||||
$branchId = $this->branchContext->resolve($request, $organization, $member);
|
||||
$practitionerId = $request->input('practitioner_id') ? (int) $request->input('practitioner_id') : null;
|
||||
|
||||
if ($practitionerScope !== null) {
|
||||
abort_unless($practitionerScope !== [], 422);
|
||||
$practitionerId = $practitionerScope[0];
|
||||
$prac = Practitioner::owned($this->ownerRef($request))->find($practitionerId);
|
||||
$branchId = (int) ($prac?->branch_id ?: $branchId);
|
||||
}
|
||||
|
||||
abort_unless($branchId > 0, 422);
|
||||
|
||||
$result = $this->queueBridge->callNext(
|
||||
@@ -108,7 +162,7 @@ class QueueController extends Controller
|
||||
CareQueueContexts::CONSULTATION,
|
||||
$branchId,
|
||||
$member,
|
||||
$request->input('practitioner_id') ? (int) $request->input('practitioner_id') : null,
|
||||
$practitionerId,
|
||||
);
|
||||
$ticket = $result['ticket'] ?? null;
|
||||
if (! $ticket) {
|
||||
|
||||
Reference in New Issue
Block a user