🗄️ Modelo de Datos - Coche.php
Análisis completo del modelo que gestiona la estructura de datos de vehículos
📋 Código Completo del Modelo
<?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
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
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
Funcionalidades que proporciona:
save()- Guardar registro en la base de datosdelete()- Eliminar registro permanentementeloadFromCode()- Cargar por ID de cocheexists()- Verificar existencia en BDclear()- 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
<?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.