Skip to main content

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
FieldTypeDescription
id_tratamientobigintPrimary key
id_pacientebigintPatient receiving treatment (required)
id_usuariobigintDentist performing treatment (required)
id_clinicabigintClinic where treatment occurs (required)
id_cat_tratamientosbigintTreatment type from catalog (required)
diagnostico_inicialtextInitial diagnosis notes
precio_finaldecimal(10,2)Final agreed price
fecha_iniciodateTreatment start date
fecha_findateTreatment completion date
estatusenumStatus: 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

FieldTypeDescription
id_cat_tratamientosbigintPrimary key
id_clinicabigintOwning clinic (required)
nombrestringTreatment name (unique per clinic)
descripciontextDetailed description
precio_sugeridodecimal(10,2)Suggested price (baseline)
estatusenumactivo 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:
1

Curso (In Progress)

Default state when treatment begins. Patient is actively receiving care.
2

Finalizado (Completed)

Treatment successfully concluded. fecha_fin should be set.
3

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
]);
  • 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 "\nIndicaciones: {$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

The diagnostico_inicial field is critical for:
  • Clinical decision-making
  • Insurance claims
  • Legal documentation
  • Treatment outcome tracking
Always update fecha_fin when marking a treatment as finalizado:
$tratamiento->update([
    'estatus' => 'finalizado',
    'fecha_fin' => now()
]);
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

Build docs developers (and LLMs) love