Activate Care workflows across check-in and financial clearance.
Deploy Ladill Care / deploy (push) Failing after 1m9s
Deploy Ladill Care / deploy (push) Failing after 1m9s
Enforce service-queue gates, cashier settlements, and clinical stage progression so patient journeys cannot bypass configured payment or authorization rules. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,7 +8,9 @@ use App\Models\InvestigationRequest;
|
||||
use App\Models\Member;
|
||||
use App\Models\Organization;
|
||||
use App\Models\Patient;
|
||||
use App\Models\Practitioner;
|
||||
use App\Models\Prescription;
|
||||
use App\Services\Care\Workflow\WorkflowQueueGate;
|
||||
use App\Services\Queue\QueueClient;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Client\RequestException;
|
||||
@@ -25,6 +27,7 @@ class CareQueueBridge
|
||||
protected CareQueueProvisioner $provisioner,
|
||||
protected PlanService $plans,
|
||||
protected SpecialtyModuleService $specialties,
|
||||
protected WorkflowQueueGate $workflowGate,
|
||||
) {}
|
||||
|
||||
public function isEnabled(Organization $organization): bool
|
||||
@@ -57,7 +60,12 @@ class CareQueueBridge
|
||||
return $appointment;
|
||||
}
|
||||
|
||||
$appointment->loadMissing('visit');
|
||||
$context = $this->contextForAppointment($organization, $appointment);
|
||||
if (! $this->workflowGate->canRelease($organization, $appointment->visit, $context)) {
|
||||
return $appointment;
|
||||
}
|
||||
|
||||
$point = $this->resolveConsultationPoint($organization, $appointment);
|
||||
|
||||
if (CareQueueContexts::usesAssignedRouting($context) && ! $point) {
|
||||
@@ -104,6 +112,10 @@ class CareQueueBridge
|
||||
}
|
||||
|
||||
$prescription->loadMissing(['patient', 'visit']);
|
||||
if (! $this->workflowGate->canRelease($organization, $prescription->visit, CareQueueContexts::PHARMACY)) {
|
||||
return $prescription;
|
||||
}
|
||||
|
||||
$branchId = (int) ($prescription->visit?->branch_id ?? 0);
|
||||
if ($branchId < 1) {
|
||||
return $prescription;
|
||||
@@ -139,10 +151,15 @@ class CareQueueBridge
|
||||
return $request;
|
||||
}
|
||||
|
||||
$request->loadMissing('patient');
|
||||
$request->loadMissing(['patient', 'visit', 'investigationType']);
|
||||
$context = $this->contextForInvestigation($request);
|
||||
if (! $this->workflowGate->canRelease($organization, $request->visit, $context)) {
|
||||
return $request;
|
||||
}
|
||||
|
||||
$ticket = $this->issue(
|
||||
$organization,
|
||||
CareQueueContexts::LABORATORY,
|
||||
$context,
|
||||
(int) $request->branch_id,
|
||||
$request->patient,
|
||||
[
|
||||
@@ -164,6 +181,15 @@ class CareQueueBridge
|
||||
return $request->fresh();
|
||||
}
|
||||
|
||||
public function contextForInvestigation(InvestigationRequest $request): string
|
||||
{
|
||||
$request->loadMissing('investigationType');
|
||||
|
||||
return in_array($request->investigationType?->category, ['xray', 'ultrasound', 'ct', 'mri'], true)
|
||||
? CareQueueContexts::IMAGING
|
||||
: CareQueueContexts::LABORATORY;
|
||||
}
|
||||
|
||||
public function issueForBill(Organization $organization, Bill $bill): ?Bill
|
||||
{
|
||||
if (! $this->isEnabled($organization) || filled($bill->queue_ticket_uuid)) {
|
||||
@@ -174,7 +200,11 @@ class CareQueueBridge
|
||||
return $bill;
|
||||
}
|
||||
|
||||
$bill->loadMissing('patient');
|
||||
$bill->loadMissing(['patient', 'visit']);
|
||||
if (! $this->workflowGate->canRelease($organization, $bill->visit, CareQueueContexts::BILLING)) {
|
||||
return $bill;
|
||||
}
|
||||
|
||||
$ticket = $this->issue(
|
||||
$organization,
|
||||
CareQueueContexts::BILLING,
|
||||
@@ -209,7 +239,8 @@ class CareQueueBridge
|
||||
}
|
||||
|
||||
// Lab/imaging completion → return-to-doctor consultation ticket when practitioner known.
|
||||
if ($fromContext === CareQueueContexts::LABORATORY && $entity instanceof InvestigationRequest) {
|
||||
if (in_array($fromContext, [CareQueueContexts::LABORATORY, CareQueueContexts::IMAGING], true)
|
||||
&& $entity instanceof InvestigationRequest) {
|
||||
$entity->loadMissing(['patient', 'practitioner', 'visit']);
|
||||
$appointment = Appointment::owned($organization->owner_ref)
|
||||
->where('organization_id', $organization->id)
|
||||
@@ -243,7 +274,7 @@ class CareQueueBridge
|
||||
|
||||
return match (true) {
|
||||
$context === CareQueueContexts::PHARMACY => $this->syncMissingPrescriptions($organization, $branchId, $limit),
|
||||
$context === CareQueueContexts::LABORATORY => $this->syncMissingInvestigations($organization, $branchId, $limit),
|
||||
in_array($context, [CareQueueContexts::LABORATORY, CareQueueContexts::IMAGING], true) => $this->syncMissingInvestigations($organization, $context, $branchId, $limit),
|
||||
$context === CareQueueContexts::BILLING => $this->syncMissingBills($organization, $branchId, $limit),
|
||||
default => $this->syncMissingAppointments($organization, $context, $branchId, $limit),
|
||||
};
|
||||
@@ -418,7 +449,7 @@ class CareQueueBridge
|
||||
);
|
||||
}
|
||||
if ($member && $member->role === 'doctor') {
|
||||
$prac = \App\Models\Practitioner::owned($organization->owner_ref)
|
||||
$prac = Practitioner::owned($organization->owner_ref)
|
||||
->where('organization_id', $organization->id)
|
||||
->where('branch_id', $branchId)
|
||||
->where(function ($q) use ($member) {
|
||||
@@ -569,7 +600,7 @@ class CareQueueBridge
|
||||
->where('organization_id', $organization->id)
|
||||
->where('queue_ticket_uuid', $ticketUuid)
|
||||
->first(),
|
||||
$context === CareQueueContexts::LABORATORY => InvestigationRequest::owned($owner)
|
||||
in_array($context, [CareQueueContexts::LABORATORY, CareQueueContexts::IMAGING], true) => InvestigationRequest::owned($owner)
|
||||
->where('organization_id', $organization->id)
|
||||
->where('queue_ticket_uuid', $ticketUuid)
|
||||
->first(),
|
||||
@@ -643,7 +674,7 @@ class CareQueueBridge
|
||||
return $issued;
|
||||
}
|
||||
|
||||
protected function syncMissingInvestigations(Organization $organization, int $branchId, int $limit): int
|
||||
protected function syncMissingInvestigations(Organization $organization, string $context, int $branchId, int $limit): int
|
||||
{
|
||||
$owner = (string) $organization->owner_ref;
|
||||
$requests = InvestigationRequest::owned($owner)
|
||||
@@ -657,13 +688,17 @@ class CareQueueBridge
|
||||
->where(function ($q) {
|
||||
$q->whereNull('queue_ticket_uuid')->orWhere('queue_ticket_uuid', '');
|
||||
})
|
||||
->with('patient')
|
||||
->with(['patient', 'visit', 'investigationType'])
|
||||
->orderBy('id')
|
||||
->limit($limit)
|
||||
->get();
|
||||
|
||||
$issued = 0;
|
||||
foreach ($requests as $request) {
|
||||
if ($this->contextForInvestigation($request) !== $context) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$updated = $this->issueForInvestigation($organization, $request);
|
||||
if ($updated && filled($updated->queue_ticket_uuid)) {
|
||||
$issued++;
|
||||
|
||||
Reference in New Issue
Block a user