Documentation Index Fetch the complete documentation index at: https://mintlify.com/Ary-dev04/DentControl/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The treatment system manages dental procedures from diagnosis through completion. It tracks treatment progress, pricing, status, and integrates with appointments and clinical notes for a complete care workflow.
Treatment Plans Track multi-session treatments from start to finish
Catalog System Clinic-specific treatment catalogs with suggested pricing
Status Tracking Monitor treatments: in progress, completed, or paused
Evolution Notes Document treatment progress with detailed notes
Data Model
The Tratamiento model tracks individual treatment instances for patients.
Database Schema
See migration at ~/workspace/source/database/migrations/2026_02_23_092642_create_tratamiento_table.php:14-56
Schema :: create ( 'tratamiento' , function ( Blueprint $table ) {
$table -> id ( 'id_tratamiento' );
// Relationships
$table -> unsignedBigInteger ( 'id_paciente' );
$table -> unsignedBigInteger ( 'id_usuario' );
$table -> unsignedBigInteger ( 'id_clinica' );
$table -> unsignedBigInteger ( 'id_cat_tratamientos' );
// Clinical information
$table -> text ( 'diagnostico_inicial' ) -> nullable ();
$table -> decimal ( 'precio_final' , 10 , 2 ) -> nullable ();
$table -> date ( 'fecha_inicio' ) -> nullable ();
$table -> date ( 'fecha_fin' ) -> nullable ();
$table -> enum ( 'estatus' , [ 'curso' , 'finalizado' , 'pausado' ])
-> default ( 'curso' );
$table -> timestamps ();
// Foreign keys with cascade
$table -> foreign ( 'id_paciente' )
-> references ( 'id_paciente' ) -> on ( 'paciente' )
-> onDelete ( 'cascade' );
$table -> foreign ( 'id_usuario' )
-> references ( 'id_usuario' ) -> on ( 'usuario' )
-> onDelete ( 'cascade' );
$table -> foreign ( 'id_clinica' )
-> references ( 'id_clinica' ) -> on ( 'clinica' )
-> onDelete ( 'cascade' );
$table -> foreign ( 'id_cat_tratamientos' )
-> references ( 'id_cat_tratamientos' ) -> on ( 'catalogo_tratamientos' )
-> onDelete ( 'cascade' );
});
Model Attributes
See complete model at ~/workspace/source/app/Models/Tratamiento.php:17-27
Field Type Description id_tratamientobigint Primary key id_pacientebigint Patient receiving treatment (required) id_usuariobigint Dentist performing treatment (required) id_clinicabigint Clinic where treatment occurs (required) id_cat_tratamientosbigint Treatment type from catalog (required) diagnostico_inicialtext Initial diagnosis notes precio_finaldecimal(10,2) Final agreed price fecha_iniciodate Treatment start date fecha_findate Treatment completion date estatusenum Status: curso, finalizado, pausado
Relationships
The Tratamiento model connects patients, providers, clinics, and catalogs.
Belongs to Patient
See ~/workspace/source/app/Models/Tratamiento.php:31-34
public function paciente ()
{
return $this -> belongsTo ( Paciente :: class , 'id_paciente' , 'id_paciente' );
}
Belongs to Usuario (Dentist)
See ~/workspace/source/app/Models/Tratamiento.php:36-40
public function usuario ()
{
return $this -> belongsTo ( Usuario :: class , 'id_usuario' , 'id_usuario' );
}
Belongs to Clinic
See ~/workspace/source/app/Models/Tratamiento.php:42-46
public function clinica ()
{
return $this -> belongsTo ( Clinica :: class , 'id_clinica' , 'id_clinica' );
}
Belongs to Treatment Catalog
See ~/workspace/source/app/Models/Tratamiento.php:48-56
public function catalogoTratamiento ()
{
return $this -> belongsTo (
CatalogoTratamiento :: class ,
'id_cat_tratamientos' ,
'id_cat_tratamientos'
);
}
Has Many Appointments
See ~/workspace/source/app/Models/Tratamiento.php:58-62
public function citas ()
{
return $this -> hasMany ( Cita :: class , 'id_tratamiento' , 'id_tratamiento' );
}
A multi-session treatment (e.g., root canal, orthodontics) can have multiple appointments associated with it.
Has Many Evolution Notes
See ~/workspace/source/app/Models/Tratamiento.php:64-67
public function notasEvolucion ()
{
return $this -> hasMany ( NotasEvolucion :: class , 'id_tratamiento' , 'id_tratamiento' );
}
Entity Relationship Diagram
Treatment Catalog
Each clinic maintains its own catalog of available treatments with suggested pricing.
CatalogoTratamientos Schema
See migration at ~/workspace/source/database/migrations/2026_02_23_085812_create_catalogo_tratamientos_table.php:14-34
Schema :: create ( 'catalogo_tratamientos' , function ( Blueprint $table ) {
$table -> id ( 'id_cat_tratamientos' );
$table -> unsignedBigInteger ( 'id_clinica' );
$table -> string ( 'nombre' );
$table -> text ( 'descripcion' ) -> nullable ();
$table -> decimal ( 'precio_sugerido' , 10 , 2 ) -> nullable ();
$table -> enum ( 'estatus' , [ 'activo' , 'baja' ]) -> default ( 'activo' );
$table -> timestamps ();
$table -> foreign ( 'id_clinica' )
-> references ( 'id_clinica' ) -> on ( 'clinica' )
-> onDelete ( 'cascade' );
$table -> unique ([ 'id_clinica' , 'nombre' ]);
});
Catalog Fields
Field Type Description id_cat_tratamientosbigint Primary key id_clinicabigint Owning clinic (required) nombrestring Treatment name (unique per clinic) descripciontext Detailed description precio_sugeridodecimal(10,2) Suggested price (baseline) estatusenum activo or baja
Example Catalog Entries
// Creating treatment catalog entries for a clinic
CatalogoTratamiento :: create ([
'id_clinica' => 1 ,
'nombre' => 'Endodoncia (Conductos)' ,
'descripcion' => 'Tratamiento de conducto radicular' ,
'precio_sugerido' => 3500.00 ,
'estatus' => 'activo'
]);
CatalogoTratamiento :: create ([
'id_clinica' => 1 ,
'nombre' => 'Ortodoncia Completa' ,
'descripcion' => 'Tratamiento ortodóntico con brackets metálicos' ,
'precio_sugerido' => 25000.00 ,
'estatus' => 'activo'
]);
CatalogoTratamiento :: create ([
'id_clinica' => 1 ,
'nombre' => 'Extracción Simple' ,
'descripcion' => 'Extracción de pieza dental sin complicaciones' ,
'precio_sugerido' => 800.00 ,
'estatus' => 'activo'
]);
The unique constraint ['id_clinica', 'nombre'] means each clinic can have an “Ortodoncia” entry, but within a clinic, names must be unique.
Treatment Status Lifecycle
Treatments progress through three states:
Curso (In Progress)
Default state when treatment begins. Patient is actively receiving care.
Finalizado (Completed)
Treatment successfully concluded. fecha_fin should be set.
Pausado (Paused)
Treatment temporarily suspended (patient request, medical reasons, payment issues).
Status Diagram
Managing Status
// Start treatment
$tratamiento = Tratamiento :: create ([
'id_paciente' => $pacienteId ,
'id_usuario' => auth () -> user () -> id_usuario ,
'id_clinica' => auth () -> user () -> id_clinica ,
'id_cat_tratamientos' => $catalogoId ,
'diagnostico_inicial' => 'Caries profunda en molar #16' ,
'precio_final' => 3500.00 ,
'fecha_inicio' => now (),
'estatus' => 'curso'
]);
// Pause treatment
$tratamiento -> update ([ 'estatus' => 'pausado' ]);
// Resume treatment
$tratamiento -> update ([ 'estatus' => 'curso' ]);
// Complete treatment
$tratamiento -> update ([
'estatus' => 'finalizado' ,
'fecha_fin' => now ()
]);
Pricing
The treatment model supports flexible pricing:
Suggested vs Final Price
Precio Sugerido Baseline price from catalog (catalogo_tratamientos.precio_sugerido)
Precio Final Actual negotiated price for this specific treatment instance
Pricing Workflow
// 1. Fetch catalog entry with suggested price
$catalogoTratamiento = CatalogoTratamiento :: find ( $request -> id_cat_tratamientos );
// 2. Use suggested price as default, allow override
$precioFinal = $request -> precio_final ?? $catalogoTratamiento -> precio_sugerido ;
// 3. Create treatment with final price
$tratamiento = Tratamiento :: create ([
'id_cat_tratamientos' => $catalogoTratamiento -> id_cat_tratamientos ,
'precio_final' => $precioFinal ,
// ... other fields
]);
When to Override Precio Sugerido
Insurance coverage adjustments
Patient discounts or payment plans
Complexity variations (e.g., difficult extraction)
Promotional pricing
Senior/student discounts
Creating a Treatment
Typical treatment creation flow:
public function store ( Request $request )
{
$validated = $request -> validate ([
'id_paciente' => 'required|exists:paciente,id_paciente' ,
'id_cat_tratamientos' => 'required|exists:catalogo_tratamientos,id_cat_tratamientos' ,
'diagnostico_inicial' => 'required|string' ,
'precio_final' => 'required|numeric|min:0' ,
'fecha_inicio' => 'required|date' ,
]);
$tratamiento = Tratamiento :: create ([
'id_paciente' => $validated [ 'id_paciente' ],
'id_usuario' => auth () -> user () -> id_usuario ,
'id_clinica' => auth () -> user () -> id_clinica ,
'id_cat_tratamientos' => $validated [ 'id_cat_tratamientos' ],
'diagnostico_inicial' => $validated [ 'diagnostico_inicial' ],
'precio_final' => $validated [ 'precio_final' ],
'fecha_inicio' => $validated [ 'fecha_inicio' ],
'estatus' => 'curso'
]);
return redirect () -> route ( 'tratamientos.show' , $tratamiento -> id_tratamiento )
-> with ( 'success' , 'Tratamiento iniciado correctamente.' );
}
Querying Treatments
Active Treatments for Patient
$tratamientosActivos = Tratamiento :: where ( 'id_paciente' , $pacienteId )
-> where ( 'estatus' , 'curso' )
-> with ([ 'catalogoTratamiento' , 'usuario' ])
-> get ();
Completed Treatments This Month
$tratamientosCompletados = Tratamiento :: where ( 'id_clinica' , $clinicaId )
-> where ( 'estatus' , 'finalizado' )
-> whereMonth ( 'fecha_fin' , now () -> month )
-> whereYear ( 'fecha_fin' , now () -> year )
-> with ([ 'paciente' , 'catalogoTratamiento' ])
-> get ();
Treatments by Type
$ortodoncias = Tratamiento :: whereHas ( 'catalogoTratamiento' , function ( $q ) {
$q -> where ( 'nombre' , 'LIKE' , '%Ortodoncia%' );
})
-> where ( 'id_clinica' , $clinicaId )
-> with ([ 'paciente' , 'usuario' ])
-> get ();
Revenue Summary
$ingresosTotales = Tratamiento :: where ( 'id_clinica' , $clinicaId )
-> where ( 'estatus' , 'finalizado' )
-> sum ( 'precio_final' );
$ingresosPorTipo = Tratamiento :: select (
'id_cat_tratamientos' ,
DB :: raw ( 'COUNT(*) as cantidad' ),
DB :: raw ( 'SUM(precio_final) as total' )
)
-> where ( 'id_clinica' , $clinicaId )
-> where ( 'estatus' , 'finalizado' )
-> groupBy ( 'id_cat_tratamientos' )
-> with ( 'catalogoTratamiento' )
-> get ();
Evolution Notes Integration
Treatments are documented through evolution notes (notas de evolución).
NotasEvolucion Schema
See migration at ~/workspace/source/database/migrations/2026_02_23_093121_create_notas_evolucion_table.php
Schema :: create ( 'notas_evolucion' , function ( Blueprint $table ) {
$table -> id ( 'id_nota' );
$table -> unsignedBigInteger ( 'id_tratamiento' );
$table -> unsignedBigInteger ( 'id_usuario' );
$table -> date ( 'fecha' );
$table -> time ( 'hora' );
$table -> text ( 'nota_texto' );
$table -> text ( 'indicaciones' ) -> nullable ();
$table -> timestamps ();
$table -> foreign ( 'id_tratamiento' )
-> references ( 'id_tratamiento' ) -> on ( 'tratamiento' )
-> onDelete ( 'cascade' );
$table -> foreign ( 'id_usuario' )
-> references ( 'id_usuario' ) -> on ( 'usuario' )
-> onDelete ( 'cascade' );
});
Adding Evolution Notes
See model at ~/workspace/source/app/Models/NotasEvolucion.php:17-24
// After each treatment session, document progress
NotasEvolucion :: create ([
'id_tratamiento' => $tratamientoId ,
'id_usuario' => auth () -> user () -> id_usuario ,
'fecha' => now () -> toDateString (),
'hora' => now () -> toTimeString (),
'nota_texto' => 'Sesión 2 de endodoncia. Instrumentación y obturación de conductos. Paciente toleró bien el procedimiento.' ,
'indicaciones' => 'Tomar ibuprofeno 400mg cada 8 horas por 3 días. Evitar masticar del lado tratado.'
]);
Viewing Treatment Timeline
$tratamiento = Tratamiento :: with ([
'notasEvolucion' => function ( $q ) {
$q -> orderBy ( 'fecha' , 'desc' ) -> orderBy ( 'hora' , 'desc' );
},
'notasEvolucion.usuario'
]) -> find ( $id );
// Display chronological treatment history
foreach ( $tratamiento -> notasEvolucion as $nota ) {
echo "{ $nota -> fecha } { $nota -> hora } - Dr. { $nota -> usuario -> nombre }" ;
echo " \n { $nota -> nota_texto }" ;
if ( $nota -> indicaciones ) {
echo " \n Indicaciones: { $nota -> indicaciones }" ;
}
}
Multi-Session Treatments
Complex treatments require multiple appointments:
// 1. Create treatment plan
$tratamiento = Tratamiento :: create ([
'id_paciente' => $pacienteId ,
'id_cat_tratamientos' => $catalogoId , // e.g., "Root Canal"
'diagnostico_inicial' => 'Necrosis pulpar en molar #36' ,
'precio_final' => 3500.00 ,
'fecha_inicio' => now (),
'estatus' => 'curso'
]);
// 2. Schedule first appointment
$cita1 = Cita :: create ([
'id_tratamiento' => $tratamiento -> id_tratamiento ,
'id_paciente' => $pacienteId ,
'id_usuario' => $dentistaId ,
'fecha' => '2026-03-15' ,
'hora' => '10:00' ,
'motivo_consulta' => 'Endodoncia - Sesión 1: Apertura y conductometría'
]);
// 3. Schedule second appointment
$cita2 = Cita :: create ([
'id_tratamiento' => $tratamiento -> id_tratamiento ,
'id_paciente' => $pacienteId ,
'id_usuario' => $dentistaId ,
'fecha' => '2026-03-22' ,
'hora' => '10:00' ,
'motivo_consulta' => 'Endodoncia - Sesión 2: Instrumentación'
]);
// 4. After each session, add evolution note
// (see Evolution Notes section above)
Best Practices
Never create free-form treatment names. Always reference catalogo_tratamientos for consistency and reporting.
Document Initial Diagnosis
The diagnostico_inicial field is critical for:
Clinical decision-making
Insurance claims
Legal documentation
Treatment outcome tracking
Set Fecha Fin on Completion
Always update fecha_fin when marking a treatment as finalizado: $tratamiento -> update ([
'estatus' => 'finalizado' ,
'fecha_fin' => now ()
]);
Use Evolution Notes Liberally
Document every significant event:
Each appointment/session
Complications or changes in plan
Patient reactions or concerns
Treatment modifications
Use estatus = 'baja' for discontinued treatments instead of deleting
Keep names consistent (e.g., always “Ortodoncia”, not sometimes “Brackets”)
Review and update precio_sugerido periodically
Reporting Queries
Treatments in Progress
$enCurso = Tratamiento :: where ( 'id_clinica' , $clinicaId )
-> where ( 'estatus' , 'curso' )
-> with ([ 'paciente' , 'catalogoTratamiento' , 'usuario' ])
-> get ();
Average Treatment Duration
$duracionPromedio = Tratamiento :: where ( 'id_clinica' , $clinicaId )
-> where ( 'estatus' , 'finalizado' )
-> whereNotNull ( 'fecha_inicio' )
-> whereNotNull ( 'fecha_fin' )
-> selectRaw ( 'AVG(DATEDIFF(fecha_fin, fecha_inicio)) as dias_promedio' )
-> first ()
-> dias_promedio ;
Most Common Treatments
$tratamientosPopulares = Tratamiento :: select (
'id_cat_tratamientos' ,
DB :: raw ( 'COUNT(*) as total' )
)
-> where ( 'id_clinica' , $clinicaId )
-> groupBy ( 'id_cat_tratamientos' )
-> orderBy ( 'total' , 'desc' )
-> with ( 'catalogoTratamiento' )
-> take ( 10 )
-> get ();
Patient Management Manage patients receiving treatments
Appointments Schedule treatment sessions
Clinical Records Document treatment progress