Files
ladill-care/app/Services/Care/Dentistry/DentalCatalog.php
T
isaaccladandCursor 0edd653187
Deploy Ladill Care / deploy (push) Failing after 36s
Ship commercial Dentistry suite with odontogram and treatment plans.
Replace placeholder clinical forms with patient-level FDI charting, multi-visit plans, procedure-to-bill linking, imaging, reports, and demo seed data.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 16:33:34 +00:00

104 lines
3.8 KiB
PHP

<?php
namespace App\Services\Care\Dentistry;
/**
* FDI adult dentition helpers and catalog labels for dentistry.
*/
class DentalCatalog
{
/** @return list<string> */
public static function adultToothCodes(): array
{
$codes = [];
foreach ([18, 17, 16, 15, 14, 13, 12, 11, 21, 22, 23, 24, 25, 26, 27, 28] as $n) {
$codes[] = (string) $n;
}
foreach ([48, 47, 46, 45, 44, 43, 42, 41, 31, 32, 33, 34, 35, 36, 37, 38] as $n) {
$codes[] = (string) $n;
}
return $codes;
}
/**
* @return array{upper: list<string>, lower: list<string>}
*/
public static function odontogramRows(): array
{
return [
'upper' => ['18', '17', '16', '15', '14', '13', '12', '11', '21', '22', '23', '24', '25', '26', '27', '28'],
'lower' => ['48', '47', '46', '45', '44', '43', '42', '41', '31', '32', '33', '34', '35', '36', '37', '38'],
];
}
/** @return list<string> */
public static function surfaces(): array
{
return ['M', 'O', 'D', 'B', 'L', 'I'];
}
/** @return array<string, string> */
public static function conditions(): array
{
return [
'caries' => 'Caries',
'filled' => 'Filled',
'crown' => 'Crown',
'root_canal' => 'Root canal',
'fracture' => 'Fracture',
'watch' => 'Watch',
'missing' => 'Missing',
'implant' => 'Implant',
];
}
/** @return array<string, string> */
public static function toothStatuses(): array
{
return [
'present' => 'Present',
'missing' => 'Missing',
'extracted' => 'Extracted',
'implant' => 'Implant',
];
}
/** @return array<string, string> */
public static function modalities(): array
{
return [
'pa' => 'Periapical (PA)',
'bw' => 'Bitewing (BW)',
'opg' => 'OPG / panoramic',
'photo' => 'Clinical photo',
];
}
/** @return array<string, array{label: string, amount_minor: int, type: string}> */
public static function defaultServices(): array
{
return [
'den.consult' => ['label' => 'Dental consultation', 'amount_minor' => 5000, 'type' => 'consultation'],
'den.exam' => ['label' => 'Dental examination', 'amount_minor' => 4000, 'type' => 'consultation'],
'den.cleaning' => ['label' => 'Scaling / polishing', 'amount_minor' => 8000, 'type' => 'procedure'],
'den.fill' => ['label' => 'Filling', 'amount_minor' => 12000, 'type' => 'procedure'],
'den.extraction' => ['label' => 'Extraction', 'amount_minor' => 15000, 'type' => 'procedure'],
'den.rct' => ['label' => 'Root canal treatment', 'amount_minor' => 35000, 'type' => 'procedure'],
'den.crown' => ['label' => 'Crown', 'amount_minor' => 45000, 'type' => 'procedure'],
'den.bridge' => ['label' => 'Bridge unit', 'amount_minor' => 40000, 'type' => 'procedure'],
'den.implant_consult' => ['label' => 'Implant consultation', 'amount_minor' => 10000, 'type' => 'consultation'],
'den.perio' => ['label' => 'Periodontal treatment', 'amount_minor' => 20000, 'type' => 'procedure'],
'den.xray_pa' => ['label' => 'Periapical X-ray', 'amount_minor' => 3000, 'type' => 'imaging'],
'den.xray_bw' => ['label' => 'Bitewing X-ray', 'amount_minor' => 3500, 'type' => 'imaging'],
'den.xray_opg' => ['label' => 'OPG / panoramic X-ray', 'amount_minor' => 8000, 'type' => 'imaging'],
'den.photo' => ['label' => 'Clinical photography', 'amount_minor' => 2000, 'type' => 'imaging'],
];
}
public static function isValidToothCode(string $code): bool
{
return in_array($code, self::adultToothCodes(), true);
}
}