Complete Dentistry commercial suite with PMS depth.
Deploy Ladill Care / deploy (push) Successful in 31s

Add plan lifecycle, visit stages with chair/recovery points, primary dentition charting, imaging void, revenue reports, perio exams, lab cases, and recalls.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-18 17:11:15 +00:00
co-authored by Cursor
parent e227f8705f
commit ce782382c5
37 changed files with 2458 additions and 204 deletions
@@ -197,6 +197,31 @@ class SpecialtyModuleController extends Controller
}
$visit = $visit->fresh() ?? $appointment->visit;
if ($visit) {
$stageService = app(\App\Services\Care\SpecialtyVisitStageService::class);
$nextStage = $stageService->stageOnConsultationStart($module);
if ($nextStage && ! $visit->specialty_stage) {
try {
$stageService->setStage(
$organization,
$visit,
$module,
$nextStage,
$owner,
$owner,
);
$visit = $visit->fresh();
} catch (\InvalidArgumentException) {
// Stage map may be empty for some modules.
}
} elseif ($nextStage && $visit->specialty_stage === 'waiting') {
try {
$stageService->setStage($organization, $visit, $module, $nextStage, $owner, $owner);
$visit = $visit->fresh();
} catch (\InvalidArgumentException) {
}
}
}
$clinical = app(SpecialtyClinicalRecordService::class);
$shellTabs = app(SpecialtyShellService::class)->workspaceTabs($module);
$preferredTab = $module === 'dentistry'
@@ -512,6 +537,7 @@ class SpecialtyModuleController extends Controller
$dentalChart = null;
$dentalTeethMap = [];
$dentalPlan = null;
$dentalPlanHistory = collect();
$dentalProcedures = collect();
$dentalImages = collect();
$dentalVisitNote = null;
@@ -521,6 +547,14 @@ class SpecialtyModuleController extends Controller
$dentalStatuses = [];
$dentalSurfaces = [];
$dentalModalities = [];
$dentalDentitions = [];
$dentalPerioExam = null;
$dentalPerioSurfaces = [];
$dentalLabCases = collect();
$dentalLabCaseTypes = [];
$dentalLabCaseStatuses = [];
$dentalRecalls = collect();
$dentalStageCodes = [];
$activeTab = (string) $request->query('tab', array_key_first($shell->workspaceTabs($module)) ?: 'overview');
$clinical = app(SpecialtyClinicalRecordService::class);
@@ -576,10 +610,14 @@ class SpecialtyModuleController extends Controller
$chartService = app(\App\Services\Care\Dentistry\DentalChartService::class);
$planService = app(\App\Services\Care\Dentistry\DentalTreatmentPlanService::class);
$analytics = app(\App\Services\Care\Dentistry\DentalAnalyticsService::class);
$perioService = app(\App\Services\Care\Dentistry\DentalPerioService::class);
$labService = app(\App\Services\Care\Dentistry\DentalLabCaseService::class);
$recallService = app(\App\Services\Care\Dentistry\DentalRecallService::class);
$dentalChart = $chartService->chartForPatient($organization, $workspaceVisit->patient, $owner);
$dentalTeethMap = $chartService->teethMap($dentalChart);
$dentalPlan = $planService->activePlanForPatient($organization, $workspaceVisit->patient, $owner);
$dentalPlanHistory = $planService->plansForPatient($organization, $workspaceVisit->patient, $owner);
$dentalProcedures = \App\Models\DentalProcedure::owned($owner)
->where('visit_id', $workspaceVisit->id)
->orderByDesc('id')
@@ -600,11 +638,20 @@ class SpecialtyModuleController extends Controller
->where('visit_id', $workspaceVisit->id)
->first();
$dentalCatalog = $shell->provisionedServices($organization, 'dentistry');
$dentalRows = \App\Services\Care\Dentistry\DentalCatalog::odontogramRows();
$dentition = $dentalChart->dentition ?: \App\Services\Care\Dentistry\DentalCatalog::DENTITION_ADULT;
$dentalRows = \App\Services\Care\Dentistry\DentalCatalog::odontogramRows($dentition);
$dentalConditions = \App\Services\Care\Dentistry\DentalCatalog::conditions();
$dentalStatuses = \App\Services\Care\Dentistry\DentalCatalog::toothStatuses();
$dentalSurfaces = \App\Services\Care\Dentistry\DentalCatalog::surfaces();
$dentalModalities = \App\Services\Care\Dentistry\DentalCatalog::modalities();
$dentalDentitions = \App\Services\Care\Dentistry\DentalCatalog::dentitions();
$dentalPerioExam = $perioService->latestForPatient($organization, $workspaceVisit->patient, $owner);
$dentalPerioSurfaces = \App\Services\Care\Dentistry\DentalCatalog::perioSurfaces();
$dentalLabCases = $labService->casesForPatient($organization, $workspaceVisit->patient, $owner);
$dentalLabCaseTypes = \App\Services\Care\Dentistry\DentalCatalog::labCaseTypes();
$dentalLabCaseStatuses = \App\Services\Care\Dentistry\DentalCatalog::labCaseStatuses();
$dentalRecalls = $recallService->recallsForPatient($organization, $workspaceVisit->patient, $owner);
$dentalStageCodes = collect($shell->stages('dentistry'))->pluck('code')->all();
$clinicalAlerts = array_merge(
$clinicalAlerts,
@@ -664,6 +711,7 @@ class SpecialtyModuleController extends Controller
'dentalChart' => $dentalChart,
'dentalTeethMap' => $dentalTeethMap,
'dentalPlan' => $dentalPlan,
'dentalPlanHistory' => $dentalPlanHistory,
'dentalProcedures' => $dentalProcedures,
'dentalImages' => $dentalImages,
'dentalVisitNote' => $dentalVisitNote,
@@ -673,6 +721,14 @@ class SpecialtyModuleController extends Controller
'dentalStatuses' => $dentalStatuses,
'dentalSurfaces' => $dentalSurfaces,
'dentalModalities' => $dentalModalities,
'dentalDentitions' => $dentalDentitions,
'dentalPerioExam' => $dentalPerioExam,
'dentalPerioSurfaces' => $dentalPerioSurfaces,
'dentalLabCases' => $dentalLabCases,
'dentalLabCaseTypes' => $dentalLabCaseTypes,
'dentalLabCaseStatuses' => $dentalLabCaseStatuses,
'dentalRecalls' => $dentalRecalls,
'dentalStageCodes' => $dentalStageCodes,
'queueStubs' => $modules->queueStubsFor($organization, $module),
'branchId' => $branchId,
'branchLabel' => $branchLabel,