Activate Care workflows across check-in and financial clearance.
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:
isaacclad
2026-07-17 21:13:06 +00:00
co-authored by Cursor
parent 86bfce1e17
commit 3ee59a0956
38 changed files with 1953 additions and 107 deletions
@@ -2,15 +2,21 @@
namespace App\Http\Controllers\Care;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Care\Concerns\ScopesToAccount;
use App\Http\Controllers\Controller;
use App\Models\Appointment;
use App\Models\Branch;
use App\Models\Department;
use App\Models\Organization;
use App\Models\Patient;
use App\Models\Practitioner;
use App\Services\Care\AppointmentService;
use App\Services\Care\CareFeatures;
use App\Services\Care\CarePermissions;
use App\Services\Care\OrganizationResolver;
use App\Services\Care\Workflow\WorkflowEngine;
use App\Services\Care\Workflow\WorkflowQueueGate;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
@@ -108,6 +114,11 @@ class AppointmentController extends Controller
$this->ownerRef($request),
);
if (app(CareFeatures::class)->enabled($organization, CareFeatures::WORKFLOW_ENGINE)) {
return redirect()->route('care.appointments.show', $appointment)
->with('success', 'Walk-in checked in. Complete the current patient journey stage before Queue release.');
}
return redirect()->route('care.queue.index')
->with('success', 'Walk-in added to queue.');
}
@@ -119,16 +130,47 @@ class AppointmentController extends Controller
$appointment->load(['patient', 'practitioner', 'branch', 'department', 'visit', 'consultation']);
$canManage = app(\App\Services\Care\CarePermissions::class)
$canManage = app(CarePermissions::class)
->can($this->member($request), 'appointments.manage');
$canConsult = app(\App\Services\Care\CarePermissions::class)
$canConsult = app(CarePermissions::class)
->can($this->member($request), 'consultations.manage');
$canViewBills = app(CarePermissions::class)
->can($this->member($request), 'bills.view');
$organization = $this->organization($request);
$workflowEnabled = $appointment->visit
&& app(CareFeatures::class)->enabled($organization, CareFeatures::WORKFLOW_ENGINE);
$workflowEngine = app(WorkflowEngine::class);
$currentAdvance = $workflowEnabled
? $workflowEngine->refreshGate($appointment->visit)
: null;
$currentObligation = $currentAdvance?->stage
? $appointment->visit->financialObligations()
->where('workflow_stage_id', $currentAdvance->stage->id)
->latest('id')
->first()
: null;
$canStartConsultation = $canConsult && (! $workflowEnabled || app(WorkflowQueueGate::class)->canRelease(
$organization,
$appointment->visit,
$this->appointments->queueContextFor($organization, $appointment),
));
return view('care.appointments.show', [
'appointment' => $appointment,
'statuses' => config('care.appointment_statuses'),
'canManage' => $canManage,
'canConsult' => $canConsult,
'canViewBills' => $canViewBills,
'canStartConsultation' => $canStartConsultation,
'workflowEnabled' => $workflowEnabled,
'currentAdvance' => $currentAdvance,
'currentObligation' => $currentObligation,
'workflowHistory' => $workflowEnabled
? $appointment->visit->stageAdvances()->with('stage')->orderBy('id')->get()
: collect(),
'canAdvanceWorkflow' => $canManage
&& $workflowEnabled
&& $workflowEngine->canManuallyAdvance($appointment->visit),
]);
}
@@ -137,7 +179,12 @@ class AppointmentController extends Controller
$this->authorizeAbility($request, 'appointments.manage');
$this->authorizeAppointment($request, $appointment);
$this->appointments->checkIn($appointment, $this->ownerRef($request), $this->ownerRef($request));
$appointment = $this->appointments->checkIn($appointment, $this->ownerRef($request), $this->ownerRef($request));
if (app(CareFeatures::class)->enabled($this->organization($request), CareFeatures::WORKFLOW_ENGINE)) {
return redirect()->route('care.appointments.show', $appointment)
->with('success', 'Patient checked in. Complete the current patient journey stage before Queue release.');
}
return redirect()->route('care.queue.index')
->with('success', 'Patient checked in and added to queue.');
@@ -177,7 +224,7 @@ class AppointmentController extends Controller
/**
* @return array<string, mixed>
*/
protected function formData(Request $request, \App\Models\Organization $organization): array
protected function formData(Request $request, Organization $organization): array
{
$ownerRef = $this->ownerRef($request);
$branchQuery = Branch::owned($ownerRef)->where('organization_id', $organization->id)->where('is_active', true);
@@ -214,7 +261,7 @@ class AppointmentController extends Controller
}
/**
* @return \Illuminate\Database\Eloquent\Collection<int, Practitioner>
* @return Collection<int, Practitioner>
*/
protected function activePractitioners(Request $request, int $organizationId)
{