Complete Dentistry commercial suite with PMS depth.
Deploy Ladill Care / deploy (push) Successful in 31s
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:
@@ -266,4 +266,131 @@ class CareDentistrySuiteTest extends TestCase
|
||||
->assertSee('Odontogram (FDI)')
|
||||
->assertSee('Afia Darko');
|
||||
}
|
||||
|
||||
public function test_plan_item_cancel_and_reject(): void
|
||||
{
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.plan-items', $this->visit), [
|
||||
'procedure_code' => 'den.fill',
|
||||
'tooth_code' => '16',
|
||||
'priority' => 10,
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$plan = DentalTreatmentPlan::query()->where('patient_id', $this->patient->id)->firstOrFail();
|
||||
$item = $plan->items()->firstOrFail();
|
||||
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.plan-items.cancel', [$this->visit, $item]))
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertSame(DentalPlanItem::STATUS_CANCELLED, $item->fresh()->status);
|
||||
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.plan-items', $this->visit), [
|
||||
'procedure_code' => 'den.cleaning',
|
||||
'priority' => 20,
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.plan.reject', $this->visit), [
|
||||
'rejection_reason' => 'Patient declined',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertSame(DentalTreatmentPlan::STATUS_REJECTED, $plan->fresh()->status);
|
||||
}
|
||||
|
||||
public function test_visit_stage_advance_and_primary_dentition(): void
|
||||
{
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.stage', $this->visit), [
|
||||
'stage' => 'chair',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertSame('chair', $this->visit->fresh()->specialty_stage);
|
||||
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.dentition', $this->visit), [
|
||||
'dentition' => 'primary',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$chart = DentalChart::query()->where('patient_id', $this->patient->id)->firstOrFail();
|
||||
$this->assertSame('primary', $chart->dentition);
|
||||
$this->assertTrue($chart->teeth()->where('tooth_code', '55')->exists());
|
||||
}
|
||||
|
||||
public function test_imaging_void_perio_lab_and_recall(): void
|
||||
{
|
||||
Storage::fake('public');
|
||||
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.images', $this->visit), [
|
||||
'attachment' => UploadedFile::fake()->image('xray.jpg'),
|
||||
'modality' => 'bw',
|
||||
'tooth_codes' => ['16'],
|
||||
'add_fee' => 0,
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$image = \App\Models\DentalImage::query()->where('visit_id', $this->visit->id)->firstOrFail();
|
||||
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.images.void', [$this->visit, $image]))
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertSoftDeleted('care_dental_images', ['id' => $image->id]);
|
||||
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.perio', $this->visit), [
|
||||
'sites' => [
|
||||
['tooth_code' => '16', 'surface' => 'B', 'probing_mm' => 4, 'bleeding' => 1],
|
||||
],
|
||||
'notes' => 'Perio demo',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertDatabaseHas('care_dental_perio_exams', [
|
||||
'patient_id' => $this->patient->id,
|
||||
'visit_id' => $this->visit->id,
|
||||
]);
|
||||
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.lab-cases', $this->visit), [
|
||||
'case_type' => 'crown',
|
||||
'lab_name' => 'City Lab',
|
||||
'tooth_codes' => ['16'],
|
||||
'status' => 'ordered',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$case = \App\Models\DentalLabCase::query()->where('patient_id', $this->patient->id)->firstOrFail();
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.lab-cases.status', [$this->visit, $case]), [
|
||||
'status' => 'received',
|
||||
])
|
||||
->assertRedirect();
|
||||
$this->assertSame('received', $case->fresh()->status);
|
||||
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.recalls', $this->visit), [
|
||||
'due_on' => now()->addMonths(3)->toDateString(),
|
||||
'reason' => 'Check-up',
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$recall = \App\Models\DentalRecall::query()->where('patient_id', $this->patient->id)->firstOrFail();
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.dentistry.recalls.complete', [$this->visit, $recall]))
|
||||
->assertRedirect();
|
||||
$this->assertSame('completed', $recall->fresh()->status);
|
||||
|
||||
$this->actingAs($this->owner)
|
||||
->get(route('care.specialty.dentistry.reports'))
|
||||
->assertOk()
|
||||
->assertSee('Revenue by procedure');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ class CareSpecialtyClinicalTest extends TestCase
|
||||
->assertSee('ABC compromise');
|
||||
}
|
||||
|
||||
public function test_blood_bank_request_and_dentistry_odontogram_save(): void
|
||||
public function test_blood_bank_request_save(): void
|
||||
{
|
||||
[$bbVisit] = $this->activateWithVisit('blood_bank', 'blood_bank');
|
||||
|
||||
@@ -188,68 +188,6 @@ class CareSpecialtyClinicalTest extends TestCase
|
||||
'module_key' => 'blood_bank',
|
||||
'record_type' => 'blood_request',
|
||||
]);
|
||||
|
||||
app(SpecialtyModuleService::class)->activate(
|
||||
$this->organization->fresh(),
|
||||
$this->owner->public_id,
|
||||
'dentistry',
|
||||
);
|
||||
|
||||
$dentalDept = Department::query()
|
||||
->where('branch_id', $this->branch->id)
|
||||
->where('type', 'dental')
|
||||
->firstOrFail();
|
||||
|
||||
$patient = Patient::create([
|
||||
'owner_ref' => $this->owner->public_id,
|
||||
'organization_id' => $this->organization->id,
|
||||
'branch_id' => $this->branch->id,
|
||||
'patient_number' => 'P-CL-2',
|
||||
'first_name' => 'Ama',
|
||||
'last_name' => 'Boateng',
|
||||
'gender' => 'female',
|
||||
'date_of_birth' => '1990-01-01',
|
||||
]);
|
||||
|
||||
$denVisit = Visit::create([
|
||||
'owner_ref' => $this->owner->public_id,
|
||||
'organization_id' => $this->organization->id,
|
||||
'branch_id' => $this->branch->id,
|
||||
'patient_id' => $patient->id,
|
||||
'status' => Visit::STATUS_OPEN,
|
||||
'checked_in_at' => now(),
|
||||
]);
|
||||
|
||||
Appointment::create([
|
||||
'owner_ref' => $this->owner->public_id,
|
||||
'organization_id' => $this->organization->id,
|
||||
'branch_id' => $this->branch->id,
|
||||
'patient_id' => $patient->id,
|
||||
'department_id' => $dentalDept->id,
|
||||
'visit_id' => $denVisit->id,
|
||||
'type' => Appointment::TYPE_WALK_IN,
|
||||
'status' => Appointment::STATUS_WAITING,
|
||||
'scheduled_at' => now(),
|
||||
'waiting_at' => now(),
|
||||
]);
|
||||
|
||||
$this->actingAs($this->owner)
|
||||
->post(route('care.specialty.clinical.save', ['module' => 'dentistry', 'visit' => $denVisit]), [
|
||||
'tab' => 'odontogram',
|
||||
'payload' => [
|
||||
'teeth_affected' => '16, 26',
|
||||
'findings' => 'Caries on occlusal surfaces',
|
||||
'planned_procedures' => 'Fillings',
|
||||
'anesthesia' => 'Local',
|
||||
],
|
||||
])
|
||||
->assertRedirect();
|
||||
|
||||
$this->assertDatabaseHas('care_specialty_clinical_records', [
|
||||
'visit_id' => $denVisit->id,
|
||||
'module_key' => 'dentistry',
|
||||
'record_type' => 'odontogram',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_ophthalmology_uses_eye_exam_form_not_generic_notes(): void
|
||||
|
||||
Reference in New Issue
Block a user