🗄️ Modelo de Datos - Coche.php

Análisis completo del modelo que gestiona la estructura de datos de vehículos

📋 Código Completo del Modelo

Model/Coche.php
<?php
namespace FacturaScripts\Plugins\Coches\Model;

use FacturaScripts\Core\Template\ModelClass;
use FacturaScripts\Core\Template\ModelTrait;
use FacturaScripts\Core\Tools;

class Coche extends ModelClass
{
    use ModelTrait;

    public $idcoche;
    public $matricula;
    public $marca;
    public $modelo;
    public $fechaitv;
    public $siniestro;

    public function clear(): void
    {
        parent::clear();
        $this->siniestro = false;
    }

    public static function primaryColumn(): string
    {
        return 'idcoche';
    }

    public static function tableName(): string
    {
        return 'coches';
    }
}

🔍 Análisis Detallado del Modelo

📁 Namespace y Imports

namespace FacturaScripts\Plugins\Coches\Model;

Propósito: Organiza el código según la estructura de carpetas del plugin de coches.

  • Sigue el estándar PSR-4 de autoloading
  • Corresponde con la carpeta Model/ dentro de Coches
  • Evita conflictos con otros plugins
  • Importa las clases base necesarias de FacturaScripts

🚗 Clase y Herencia

class Coche extends ModelClass

Ventajas de heredar de ModelClass:

  • CRUD automático (Create, Read, Update, Delete)
  • Validaciones integradas para tipos de datos
  • Gestión automática de fechas y estados
  • Compatibilidad total con el core de FacturaScripts
  • Métodos mágicos para acceso a propiedades

🔄 ModelTrait

use ModelTrait;

Funcionalidades que proporciona:

  • save() - Guardar registro en la base de datos
  • delete() - Eliminar registro permanentemente
  • loadFromCode() - Cargar por ID de coche
  • exists() - Verificar existencia en BD
  • clear() - Limpiar propiedades (sobrescrito)
  • url() - Generar URL para este modelo

🏗️ Estructura de Propiedades del Coche

Propiedad Tipo BD Descripción Restricciones
$idcoche serial Clave primaria auto-incremental 🔑 PRIMARY KEY, NOT NULL
$matricula varchar(7) Matrícula del vehículo (formato español) 🚘 NOT NULL, 7 caracteres máximo
$marca varchar(20) Marca del vehículo (Toyota, Ford, etc.) 🏭 NOT NULL, 20 caracteres máximo
$modelo varchar(20) Modelo específico del vehículo 📐 NOT NULL, 20 caracteres máximo
$fechaitv date Fecha de la última ITV aprobada 📅 NOT NULL, formato YYYY-MM-DD
$siniestro boolean Estado de siniestro (true/false) ⚠️ NOT NULL, valor por defecto: false
🚗

Característica especial: Campo booleano siniestro

El campo $siniestro es de tipo boolean, lo que permite estados binarios claros (true/false). En el método clear() se inicializa como false por defecto para nuevos vehículos.

⚙️ Métodos Esenciales del Modelo Coche

clear() - Inicialización

public function clear(): void
{
    parent::clear();
    $this->siniestro = false;
}

Función: Inicializa las propiedades del modelo a sus valores por defecto.

Característica especial: Sobrescribe el método padre para asegurar que siniestro siempre empiece como false en nuevos registros.

primaryColumn()

public static function primaryColumn(): string
{
    return \'idcoche\';
}

Función: Define qué columna es la clave primaria de la tabla.

Importancia: Esencial para operaciones CRUD, búsquedas y relaciones con otros modelos.

tableName()

public static function tableName(): string
{
    return \'coches\';
}

Función: Especifica el nombre de la tabla en la base de datos.

Convención: Usar plural para nombres de tablas. Aquí 'coches' es el plural español de 'coche'.

💾 Ejemplos de Uso del Modelo Coche

Crear Nuevo Coche

$coche = new Coche();
$coche->matricula = '1234ABC';
$coche->marca = 'Toyota';
$coche->modelo = 'Corolla';
$coche->fechaitv = '2024-12-31';
$coche->siniestro = false;
$coche->save();

Resultado: Se crea un nuevo registro en la tabla 'coches' con ID auto-generado.

Buscar Coche por Matrícula

$coche = new Coche();
$coches = $coche->all();
foreach ($coches as $coche) {
    if ($coche->matricula === '1234ABC') {
        echo "Encontrado: " . $coche->marca . " " . $coche->modelo;
    }
}

Alternativa: Usar loadFromCode(id) para búsqueda directa por ID.

Marcar Coche como Siniestro

$coche = new Coche();
if ($coche->loadFromCode(5)) {
    $coche->siniestro = true;
    $coche->save();
    echo "Coche marcado como siniestro";
}

Uso práctico: Este es el patrón usado en el controlador para la acción 'siniestro'.

🗃️ Esquema de Base de Datos - coches.xml

Table/coches.xml
<?xml version="1.0" encoding="UTF-8"?>
<table>
    <column>
        <name>idcoche</name>
        <type>serial</type>
        <null>NO</null>
    </column>
    <column>
        <name>matricula</name>
        <type>character varying(7)</type>
        <null>NO</null>
    </column>
    <column>
        <name>marca</name>
        <type>character varying(20)</type>
        <null>NO</null>
    </column>
    <column>
        <name>modelo</name>
        <type>character varying(20)</type>
        <null>NO</null>
    </column>
    <column>
        <name>fechaitv</name>
        <type>date</type>
        <null>NO</null>
    </column>
    <column>
        <name>siniestro</name>
        <type>boolean</type>
        <null>NO</null>
    </column>
    <constraint>
        <name>idcoche_pkey</name>
        <type>PRIMARY KEY (idcoche)</type>
    </constraint>
</table>

Análisis del Esquema

🔢 Tipos de Datos Específicos

  • serial: Auto-incremental para IDs únicos
  • varchar(7): Perfecto para matrículas españolas
  • boolean: Ideal para estados binarios
  • date: Para fechas sin componente temporal

🔐 Restricciones de Integridad

  • Todos NOT NULL: Datos completos obligatorios
  • PRIMARY KEY: Garantiza unicidad de IDs
  • Longitudes definidas: Optimiza almacenamiento

⚠️ Problemas Comunes y Soluciones

Error: "Matrícula duplicada"

Causa: Intentar guardar una matrícula que ya existe.

Solución: Agregar índice único en la tabla o verificar antes de guardar.

Error: "Fecha ITV inválida"

Causa: Formato de fecha incorrecto o fecha futura no permitida.

Solución: Validar formato YYYY-MM-DD y lógica de negocio.

Error: "Campo siniestro no acepta null"

Causa: Intentar guardar sin definir el estado de siniestro.

Solución: El método clear() ya inicializa como false. Asegurar su uso.

🚀 Mejoras Posibles para el Modelo Coche

Validaciones Avanzadas

public function test(): bool
{
    if (empty($this->matricula)) {
        Tools::log()->error(\'La matrícula es obligatoria\');
        return false;
    }
    
    // Validar formato de matrícula española
    if (!preg_match(\'/^\d{4}[A-Z]{3}$/\', $this->matricula)) {
        Tools::log()->error(\'Formato de matrícula inválido\');
        return false;
    }
    
    return true;
}

Agregar validaciones específicas para campos como matrícula y fechas.

Relaciones con Propietarios

// Agregar propiedad al modelo
public $codcliente;

// Método para obtener el propietario
public function getCliente()
{
    return (new Cliente())->loadFromCode($this->codcliente);
}

Conectar coches con la tabla de clientes para gestionar propietarios.

Métodos de Utilidad

public function getEdad(): int
{
    return date(\'Y\') - date(\'Y\', strtotime($this->fechaitv));
}

public function necesitaITV(): bool
{
    // ITV cada 2 años para coches
    $diferencia = time() - strtotime($this->fechaitv);
    return ($diferencia > 63072000); // 2 años en segundos
}

Agregar lógica de negocio específica para vehículos.