Issue Queue tickets for every waiting appointment when integration is on.
Deploy Ladill Care / deploy (push) Successful in 51s
Deploy Ladill Care / deploy (push) Successful in 51s
Patient queue syncs consultation and specialty waiters; specialty contexts now provision desks so check-in/onboarding no longer leaves half the list on local positions only. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -66,15 +66,16 @@ class CareQueueBridge
|
||||
return $appointment;
|
||||
}
|
||||
|
||||
$point = $this->resolveConsultationPoint($organization, $appointment);
|
||||
$point = $this->resolveAppointmentPoint($organization, $appointment);
|
||||
|
||||
if (CareQueueContexts::usesAssignedRouting($context) && ! $point) {
|
||||
if (CareQueueContexts::usesAssignedRouting($context) && empty($point['counter_uuid'] ?? null)) {
|
||||
$appointment->forceFill([
|
||||
'queue_routing_status' => CareQueueContexts::ROUTING_UNRESOLVED,
|
||||
])->save();
|
||||
Log::info('care.queue_issue_unresolved_assignment', [
|
||||
'appointment_id' => $appointment->id,
|
||||
'practitioner_id' => $appointment->practitioner_id,
|
||||
'context' => $context,
|
||||
]);
|
||||
|
||||
return $appointment->fresh();
|
||||
@@ -280,6 +281,44 @@ class CareQueueBridge
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue Queue tickets for every waiting appointment at a branch (consultation + specialties).
|
||||
*/
|
||||
public function syncMissingAppointmentTickets(Organization $organization, int $branchId, int $limit = 100): int
|
||||
{
|
||||
if (! $this->isEnabled($organization) || $branchId < 1 || $limit < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$owner = (string) $organization->owner_ref;
|
||||
$appointments = Appointment::owned($owner)
|
||||
->where('organization_id', $organization->id)
|
||||
->where('branch_id', $branchId)
|
||||
->whereIn('status', [Appointment::STATUS_WAITING, Appointment::STATUS_CHECKED_IN])
|
||||
->where(function ($q) {
|
||||
$q->whereNull('queue_ticket_uuid')->orWhere('queue_ticket_uuid', '');
|
||||
})
|
||||
->with(['patient', 'organization', 'practitioner', 'visit'])
|
||||
->orderBy('queue_position')
|
||||
->orderBy('waiting_at')
|
||||
->orderBy('checked_in_at')
|
||||
->orderBy('id')
|
||||
->limit($limit)
|
||||
->get();
|
||||
|
||||
$issued = 0;
|
||||
foreach ($appointments as $appointment) {
|
||||
$updated = $this->issueForAppointment($organization, $appointment->fresh([
|
||||
'patient', 'organization', 'practitioner', 'visit',
|
||||
]));
|
||||
if ($updated && filled($updated->queue_ticket_uuid)) {
|
||||
$issued++;
|
||||
}
|
||||
}
|
||||
|
||||
return $issued;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{ticket: ?array<string, mixed>, entity: ?Model, resources: ?array<string, mixed>}
|
||||
*/
|
||||
@@ -405,43 +444,41 @@ class CareQueueBridge
|
||||
/**
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
protected function resolveConsultationPoint(Organization $organization, Appointment $appointment): ?array
|
||||
protected function resolveAppointmentPoint(Organization $organization, Appointment $appointment): ?array
|
||||
{
|
||||
$branchId = (int) $appointment->branch_id;
|
||||
$context = $this->contextForAppointment($organization, $appointment);
|
||||
|
||||
// Assigned-only consultation requires a doctor — leave Unassigned until one is chosen.
|
||||
if (! $appointment->practitioner_id) {
|
||||
return null;
|
||||
$this->provisioner->ensure($organization, $context, $branchId);
|
||||
$organization = $organization->fresh() ?? $organization;
|
||||
|
||||
if ($appointment->practitioner_id) {
|
||||
$point = $this->provisioner->pointForPractitioner(
|
||||
$organization,
|
||||
$branchId,
|
||||
(int) $appointment->practitioner_id,
|
||||
$context,
|
||||
);
|
||||
if ($point && ! empty($point['counter_uuid'])) {
|
||||
return $point;
|
||||
}
|
||||
|
||||
// Refresh points for this context only, then retry the assigned desk.
|
||||
$this->provisioner->ensure($organization, $context, $branchId);
|
||||
$organization = $organization->fresh() ?? $organization;
|
||||
$point = $this->provisioner->pointForPractitioner(
|
||||
$organization,
|
||||
$branchId,
|
||||
(int) $appointment->practitioner_id,
|
||||
$context,
|
||||
);
|
||||
if ($point && ! empty($point['counter_uuid'])) {
|
||||
return $point;
|
||||
}
|
||||
}
|
||||
|
||||
$point = $this->provisioner->pointForPractitioner(
|
||||
$organization,
|
||||
$branchId,
|
||||
(int) $appointment->practitioner_id,
|
||||
);
|
||||
if ($point) {
|
||||
return $point;
|
||||
}
|
||||
|
||||
// Practitioner assigned but point not provisioned yet — refresh this branch only.
|
||||
$this->provisioner->ensure($organization, CareQueueContexts::CONSULTATION, $branchId);
|
||||
|
||||
$point = $this->provisioner->pointForPractitioner(
|
||||
$organization->fresh(),
|
||||
$branchId,
|
||||
(int) $appointment->practitioner_id,
|
||||
);
|
||||
if ($point) {
|
||||
return $point;
|
||||
}
|
||||
|
||||
// Prefer a desk ticket over leaving waiters Unassigned while counters catch up
|
||||
// after demo seed / deferred settings provision.
|
||||
return $this->provisioner->defaultPoint(
|
||||
$organization->fresh(),
|
||||
CareQueueContexts::CONSULTATION,
|
||||
$branchId,
|
||||
);
|
||||
// Prefer a desk ticket over leaving waiters without a Queue number.
|
||||
return $this->provisioner->defaultPoint($organization, $context, $branchId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -458,7 +495,7 @@ class CareQueueBridge
|
||||
): ?array {
|
||||
if ($context === CareQueueContexts::CONSULTATION || CareQueueContexts::isSpecialty($context)) {
|
||||
if ($practitionerId) {
|
||||
return $this->provisioner->pointForPractitioner($organization, $branchId, $practitionerId)
|
||||
return $this->provisioner->pointForPractitioner($organization, $branchId, $practitionerId, $context)
|
||||
?? collect($resources['points'] ?? [])->first(
|
||||
fn ($p) => ($p['kind'] ?? '') === 'practitioner' && (int) ($p['ref_id'] ?? 0) === $practitionerId
|
||||
);
|
||||
@@ -473,7 +510,7 @@ class CareQueueBridge
|
||||
})
|
||||
->first();
|
||||
if ($prac) {
|
||||
return $this->provisioner->pointForPractitioner($organization, $branchId, $prac->id);
|
||||
return $this->provisioner->pointForPractitioner($organization, $branchId, $prac->id, $context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user