Plugin Coches - FacturaScripts

Complete plugin for vehicle management in auto repair shops


🚗 Download Complete Plugin

🚀 What does this Plugin do?

Main Features

  • Complete vehicle management: Create, edit, list and mark as totaled
  • Specialized fields: License plate, make, model, inspection date, totaled status
  • Custom actions: Mark as totaled, change inspection date, quick-creation modal
  • Integration with FacturaScripts: "Coches" menu with custom icons

Technical Features

  • MVC Architecture: Separate Model, View, Controller
  • Database: Optimized table with specific types (boolean for totaled status)
  • Advanced XML views: Includes groups, modals and custom states
  • Extended controllers: Advanced functionality with integrated modals

🔍 Explore the Plugin Components

Select which part of the code you want to analyze in detail:

Car Plugin Components

⚙️ Settings - facturascripts.ini

name = 'PluginCoches'
description = 'Plugin para gestión de vehículos en FacturaScripts'
version = 1.0
min_version = 2024

Configuration File Explanation

  • name: 'PluginCoches' - Unique identifier
  • description: Description shown in the admin panel
  • version: Plugin's initial version
  • min_version: Minimum required FacturaScripts version

🗄️ Data Model - Coche.php

Model Code

<?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';
    }
}

Model Analysis

  • Namespace: FacturaScripts\Plugins\Coches\Model
  • ModelTrait: Provides automatic CRUD methods
  • Properties: Map to the database columns
  • clear() method: Initializes siniestro like false by default
  • primaryColumn(): Define idcoche as the primary key
  • tableName(): Specifies the table 'coches'

🗃️ Database Schema - 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>

Database Structure

  • idcoche (serial): Auto-incrementing primary key
  • matricula (varchar 7): Spanish license plate (7 characters)
  • marca/modelo (varchar 20): Text for make and model
  • fechaitv (date): Date of the last inspection
  • siniestro (boolean): Boolean status (true/false)
  • All NOT NULL: All fields are required

🎮 Controllers

EditCoche.php - Edit Controller

<?php
namespace FacturaScripts\Plugins\Coches\Controller;

use FacturaScripts\Core\Lib\ExtendedController\EditController;

class EditCoche extends EditController
{
    public function getModelClassName(): string
    {
        return 'Coche';
    }
}

Function: Minimalist controller that inherits all functionality from EditController. It only needs to specify which model it handles.

ListCoche.php - List Controller

<?php
namespace FacturaScripts\Plugins\Coches\Controller;

use FacturaScripts\Core\Lib\ExtendedController\ListController;
use FacturaScripts\Dinamic\Model\Coche;
use FacturaScripts\Core\Tools;

class ListCoche extends ListController
{
    public function getPageData(): array
    {
        $page = parent::getPageData();
        $page['title'] = 'Coches';
        $page['menu'] = 'Coches';
        $page['icon'] = 'fas fa-search';
        return $page;
    }

    protected function createViews()
    {
        $this->addView('ListCoche', 'coche', 'coche', 'fas fa-car')
            ->addOrderBy(['idcoche'], 'Creacion', 2)
            ->addSearchFields(['matricula', 'marca', 'modelo']);

        $this->setSettings('ListCoche', 'modalInsert', 'modalCoche');

        $this->addButton('ListCoche',[
            'action' => 'siniestro',
            'type' => 'action',
            'icon' => 'fas fa-exclamation-triangle',
            'label' => 'Baja',
            'color' => 'danger',
            'confirm' => true,
        ]);

        $this->addButton('ListCoche',[
            'action' => 'fechaitv',
            'type' => 'modal',
            'icon' => 'fas fa-exclamation-triangle',
            'label' => 'ITV',
            'color' => 'warning',
            'confirm' => true,
        ]);
    }

    protected function execPreviousAction($action)
    {
        switch($action){
            case 'siniestro':
                $this->siniestro();
                break;
            case 'fechaitv':
                $this->fechaitv();
                break;
            case 'modalCoche':
                $this->modalCoche();
                break;
        }
        return parent::execPreviousAction($action);
    }

    protected function siniestro()
    {
        $codes = $this->request->request->getArray('codes');
        if (empty($codes)){
            Tools::log()->warning('No se han seleccionado coches para marcar como siniestro.');
            return;
        }
        foreach ($codes as $code) {
            $coche = new Coche();
            $coche = $coche->find($code);
            $coche->siniestro=true;
            $coche->save();
            Tools::log()->notice('Marcado como siniestro los coches seleccionados.');
        }
    }

    protected function fechaitv()
    {
        $codes = $this->request->request->getArray('codes');
        if (empty($codes)){
            Tools::log()->warning('No se han seleccionado coches para cambiar la ITV.');
            return;
        }
        foreach ($codes as $code) {
            $coche = new Coche();
            $coche = $coche->find($code);
            $coche->fechaitv = $this->request->request->get('fechaitv');
            $coche->save();
            Tools::log()->notice('ITV cambiada de los coches seleccionados.');
        }
    }

    protected function modalCoche()
    {
        $coche = new Coche();
        $coche->matricula = $this->request->request->get('matricula');
        $coche->marca = $this->request->request->get('marca');
        $coche->modelo = $this->request->request->get('modelo');
        $coche->fechaitv = $this->request->request->get('fechaitv');
        $coche->siniestro = false;
        $coche->save();
        Tools::log()->notice('Vehículo creado con éxito.');
    }
}

Advanced features: Includes custom actions with modals, confirmation buttons, selected-record management, and quick creation via modal.

👁️ XML Views

EditCoche.xml - Edit View

<?xml version='1.0' encoding='UTF-8'?>
<view>
    <columns>
        <group name='coches' numcolumns='8' title='Identificación de vehículos cochiles' icon='fa-globe'>
            <column name='ID' order='10'>
                <widget type='text' fieldname='idcoche' />
            </column>
            <column name='matricula' order='20'>
                <widget type='text' fieldname='matricula' />
            </column>
            <column name='marca' order='30'>
                <widget type='text' fieldname='marca' />
            </column>
            <column name='modelo' order='40'>
                <widget type='text' fieldname='modelo' />
            </column>
            <column name='fechaitv' order='50'>
                <widget type='date' fieldname='fechaitv' />
            </column>
            <column name='siniestro' order='60'>
                <widget type='checkbox' fieldname='siniestro' />
            </column>
        </group>
    </columns>
</view>

Layout with groups: The fields are organized in a group with a title and icon. The group takes up 8/12 columns of the available width.

ListCoche.xml - List View

<?xml version='1.0' encoding='UTF-8'?>
<view>
    <columns>
        <column name='ID' order='10'>
            <widget type='text' fieldname='idcoche' />
        </column>
        <column name='matricula' order='20'>
            <widget type='text' fieldname='matricula' />
        </column>
        <column name='marca' order='30'>
            <widget type='text' fieldname='marca' />
        </column>
        <column name='modelo' order='40'>
            <widget type='text' fieldname='modelo' />
        </column>
        <column name='fechaitv' order='50'>
            <widget type='date' fieldname='fechaitv' />
        </column>
    </columns>
    <rows>
        <row type='status'>
            <option color='danger' fieldname='siniestro'>1</option>
        </row>
        <row type="actions">
            <button type="modal" label="mostrar" color="warning" action="test" />
        </row>
    </rows>
    <modals>
        <group name="modalCoche" title="Modelo de Coche" icon="fas fa-car">
            <column name="ID" numcolumns="12" description="desc-custommer-name">
                <widget type="text" fieldname="idcoche" required="true" />
            </column>
            <column name="Matricula" numcolumns="6">
                <widget type="text" fieldname="matricula" required="true" />
            </column>
            <column name="Marca" numcolumns="6">
                <widget type="text" fieldname="marca" required="true" />
            </column>
            <column name="Modelo" numcolumns="6">
                <widget type="text" fieldname="modelo" required="true" />
            </column>
            <column name="Fecha ITV" numcolumns="6">
                <widget type="date" fieldname="fechaitv" required="true" />
            </column>
            <column name="Siniestro" numcolumns="6">
                <widget type="checkbox" fieldname="siniestro" required="true" />
            </column>
        </group>
        <group name="fechaitv" title="Fecha de ITV" icon="fas fa-car">
            <column name="Fecha ITV" numcolumns="6">
                <widget type="date" fieldname="fechaitv" required="true" />
            </column>
        </group>
    </modals>
</view>

Advanced view: Includes visual states (totaled in red), custom action buttons, and multiple modals for quick creation and specific field editing.

🔄 Plugin Workflow

1. Installation and Activation

  • Copy the PluginCoches folder to /Plugins/
  • Activate from Admin → Plugins
  • The system automatically creates the 'coches' table

2. Navigation

  • A new "Coches" menu appears with a search icon
  • "Coches" submenu for managing vehicles
  • List view with colors for totaled vehicles

3. Advanced Features

  • Quick creation: Modal to add cars without leaving the list
  • Mark as totaled: Red button with confirmation
  • Change Inspection: Specific modal to update dates
  • Search: By license plate, make or model
  • Display: Totaled vehicles highlighted in red

✨ Special Features Implemented

Integrated Modals

  • modalCoche: For quick vehicle creation
  • fechaitv: Specific modal to change the inspection date
  • Configuration with setSettings('modalInsert')
  • required="true" validations on fields

Visual States

  • Row type status to highlight states
  • Color danger for totaled vehicles
  • Condition: fieldname='siniestro' and value 1
  • Immediate visual feedback to the user

Bulk Management

  • Actions on multiple selected records
  • getArray('codes') to get IDs
  • Loop foreach to process each record
  • Informative log messages

🚀 Possible Improvements and Extensions

License Plate Validations

Implement: Validation for Spanish (0000-XXX) or European format.

Benefit: Greater consistency in license plate data.

Client Relationships

Implement: Many-to-One relationship with the clients (owners) table.

Benefit: Complete management of vehicles and their owners.

Maintenance History

Implement: Related table for check-ups and repairs.

Benefit: Complete maintenance history system.