Para la carta porte3.0 también requerimos del catalogo de remolques el cual tendrá los siguientes datos.

  • Id
  • idEmpresa
  • Descripcion
  • subtipo Remolque
  • Placa

Creamos el archivo de migración en App/Database/Migrations/2023-12-06172810_Remolques.php con el siguiente código

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class Remolques extends Migration {

    public function up() {
        // Remolques
        $this->forge->addField([
            'id' => ['type' => 'int', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
            'idEmpresa' => ['type' => 'bigint', 'constraint' => 20, 'null' => true],
            'descripcion' => ['type' => 'varchar', 'constraint' => 64, 'null' => true],
            'subTipoRemolque' => ['type' => 'varchar', 'constraint' => 32, 'null' => true],
            'placa' => ['type' => 'varchar', 'constraint' => 16, 'null' => true],
            'created_at' => ['type' => 'datetime', 'null' => true],
            'updated_at' => ['type' => 'datetime', 'null' => true],
            'deleted_at' => ['type' => 'datetime', 'null' => true],
        ]);
        $this->forge->addKey('id', true);
        $this->forge->createTable('remolques', true);
    }

    public function down() {
        $this->forge->dropTable('remolques', true);
    }

}

Creamos el archivo de modelo App/Models/RemolquesModel.php con el siguiente código

<?php

namespace App\Models;

use CodeIgniter\Model;

class RemolquesModel extends Model {

    protected $table = 'remolques';
    protected $primaryKey = 'id';
    protected $useAutoIncrement = true;
    protected $returnType = 'array';
    protected $useSoftDeletes = true;
    protected $allowedFields = ['id', 'idEmpresa', 'descripcion', 'subTipoRemolque', 'placa', 'updated_at', 'deleted_at', 'created_at'];
    protected $useTimestamps = true;
    protected $createdField = 'created_at';
    protected $deletedField = 'deleted_at';
    protected $validationRules = [
    ];
    protected $validationMessages = [];
    protected $skipValidation = false;

    public function mdlGetRemolques($idEmpresas) {

        $result = $this->db->table('remolques a, empresas b')
                ->select('a.id,a.idEmpresa,a.descripcion,a.subTipoRemolque,a.placa,a.updated_at,a.deleted_at,a.created_at ,b.nombre as nombreEmpresa')
                ->where('a.idEmpresa', 'b.id', FALSE)
                ->whereIn('a.idEmpresa', $idEmpresas);

        return $result;
    }

}

Creamos el archivo de controlador App/Controllers/RemolquesController.php con el siguiente código

<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use \App\Models\{
    RemolquesModel
};
use App\Models\LogModel;
use CodeIgniter\API\ResponseTrait;
use App\Models\EmpresasModel;

class RemolquesController extends BaseController {

    use ResponseTrait;

    protected $log;
    protected $remolques;

    public function __construct() {
        $this->remolques = new RemolquesModel();
        $this->log = new LogModel();
        $this->empresa = new EmpresasModel();
        helper('menu');
        helper('utilerias');
    }

    public function index() {



        helper('auth');

        $idUser = user()->id;
        $titulos["empresas"] = $this->empresa->mdlEmpresasPorUsuario($idUser);

        if (count($titulos["empresas"]) == "0") {

            $empresasID[0] = "0";
        } else {

            $empresasID = array_column($titulos["empresas"], "id");
        }




        if ($this->request->isAJAX()) {
            $datos = $this->remolques->mdlGetRemolques($empresasID);

            return \Hermawan\DataTables\DataTable::of($datos)->toJson(true);
        }
        $titulos["title"] = lang('remolques.title');
        $titulos["subtitle"] = lang('remolques.subtitle');
        return view('remolques', $titulos);
    }

    /**
     * Read Remolques
     */
    public function getRemolques() {

        helper('auth');

        $idUser = user()->id;
        $titulos["empresas"] = $this->empresa->mdlEmpresasPorUsuario($idUser);

        if (count($titulos["empresas"]) == "0") {

            $empresasID[0] = "0";
        } else {

            $empresasID = array_column($titulos["empresas"], "id");
        }


        $idRemolques = $this->request->getPost("idRemolques");
        $datosRemolques = $this->remolques->whereIn('idEmpresa', $empresasID)
                        ->where("id", $idRemolques)->first();
        echo json_encode($datosRemolques);
    }

    /**
     * Save or update Remolques
     */
    public function save() {
        helper('auth');
        $userName = user()->username;
        $idUser = user()->id;
        $datos = $this->request->getPost();
        if ($datos["idRemolques"] == 0) {
            try {
                if ($this->remolques->save($datos) === false) {
                    $errores = $this->remolques->errors();
                    foreach ($errores as $field => $error) {
                        echo $error . " ";
                    }
                    return;
                }
                $dateLog["description"] = lang("vehicles.logDescription") . json_encode($datos);
                $dateLog["user"] = $userName;
                $this->log->save($dateLog);
                echo "Guardado Correctamente";
            } catch (\PHPUnit\Framework\Exception $ex) {
                echo "Error al guardar " . $ex->getMessage();
            }
        } else {
            if ($this->remolques->update($datos["idRemolques"], $datos) == false) {
                $errores = $this->remolques->errors();
                foreach ($errores as $field => $error) {
                    echo $error . " ";
                }
                return;
            } else {
                $dateLog["description"] = lang("remolques.logUpdated") . json_encode($datos);
                $dateLog["user"] = $userName;
                $this->log->save($dateLog);
                echo "Actualizado Correctamente";
                return;
            }
        }
        return;
    }

    /**
     * Delete Remolques
     * @param type $id
     * @return type
     */
    public function delete($id) {
        $infoRemolques = $this->remolques->find($id);
        helper('auth');
        $userName = user()->username;
        if (!$found = $this->remolques->delete($id)) {
            return $this->failNotFound(lang('remolques.msg.msg_get_fail'));
        }
        $this->remolques->purgeDeleted();
        $logData["description"] = lang("remolques.logDeleted") . json_encode($infoRemolques);
        $logData["user"] = $userName;
        $this->log->save($logData);
        return $this->respondDeleted($found, lang('remolques.msg_delete'));
    }

}

Creamos el archivo de la vista en App/Views/remolques.php con el siguiente código

<?= $this->include('julio101290\boilerplate\Views\load\select2') ?>
<?= $this->include('julio101290\boilerplate\Views\load\datatables') ?>
<?= $this->include('julio101290\boilerplate\Views\load\nestable') ?>
<!-- Extend from layout index -->
<?= $this->extend('julio101290\boilerplate\Views\layout\index') ?>

<!-- Section content -->
<?= $this->section('content') ?>

<?= $this->include('modulesRemolques/modalCaptureRemolques') ?>

<!-- SELECT2 EXAMPLE -->
<div class="card card-default">
    <div class="card-header">
        <div class="float-right">
            <div class="btn-group">

                <button class="btn btn-primary btnAddRemolques" data-toggle="modal" data-target="#modalAddRemolques"><i class="fa fa-plus"></i>

                    <?= lang('remolques.add') ?>

                </button>

            </div>
        </div>
    </div>
    <div class="card-body">
        <div class="row">
            <div class="col-md-12">
                <div class="table-responsive">
                    <table id="tableRemolques" class="table table-striped table-hover va-middle tableRemolques">
                        <thead>
                            <tr>

                                <th>#</th>
                                <th><?= lang('remolques.fields.idEmpresa') ?></th>
                                <th><?= lang('remolques.fields.descripcion') ?></th>
                                <th><?= lang('remolques.fields.subTipoRemolque') ?></th>
                                <th><?= lang('remolques.fields.placa') ?></th>
                                <th><?= lang('remolques.fields.updated_at') ?></th>
                                <th><?= lang('remolques.fields.deleted_at') ?></th>
                                <th><?= lang('remolques.fields.created_at') ?></th>

                                <th><?= lang('remolques.fields.actions') ?> </th>

                            </tr>
                        </thead>
                        <tbody>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- /.card -->

<?= $this->endSection() ?>


<?= $this->section('js') ?>
<script>

    /**
     * Cargamos la tabla
     */

    var tableRemolques = $('#tableRemolques').DataTable({
        processing: true,
        serverSide: true,
        responsive: true,
        autoWidth: false,
        order: [[1, 'asc']],

        ajax: {
            url: '<?= base_url('admin/remolques') ?>',
            method: 'GET',
            dataType: "json"
        },
        columnDefs: [{
                orderable: false,
                targets: [8],
                searchable: false,
                targets: [8]

            }],
        columns: [{
                'data': 'id'
            },

            {
                'data': 'idEmpresa'
            },

            {
                'data': 'descripcion'
            },

            {
                'data': 'subTipoRemolque'
            },

            {
                'data': 'placa'
            },

            {
                'data': 'updated_at'
            },

            {
                'data': 'deleted_at'
            },

            {
                'data': 'created_at'
            },

            {
                "data": function (data) {
                    return `<td class="text-right py-0 align-middle">
                         <div class="btn-group btn-group-sm">
                             <button class="btn btn-warning btnEditRemolques" data-toggle="modal" idRemolques="${data.id}" data-target="#modalAddRemolques">  <i class=" fa fa-edit"></i></button>
                             <button class="btn btn-danger btn-delete" data-id="${data.id}"><i class="fas fa-trash"></i></button>
                         </div>
                         </td>`
                }
            }
        ]
    });



    $(document).on('click', '#btnSaveRemolques', function (e) {


        var idRemolques = $("#idRemolques").val();
        var idEmpresa = $("#idEmpresa").val();
        var descripcion = $("#descripcion").val();
        var subTipoRemolque = $("#subTipoRemolque").val();
        var placa = $("#placa").val();

        $("#btnSaveRemolques").attr("disabled", true);

        var datos = new FormData();
        datos.append("idRemolques", idRemolques);
        datos.append("idEmpresa", idEmpresa);
        datos.append("descripcion", descripcion);
        datos.append("subTipoRemolque", subTipoRemolque);
        datos.append("placa", placa);


        $.ajax({

            url: "<?= base_url('admin/remolques/save') ?>",
            method: "POST",
            data: datos,
            cache: false,
            contentType: false,
            processData: false,
            success: function (respuesta) {
                if (respuesta.match(/Correctamente.*/)) {

                    Toast.fire({
                        icon: 'success',
                        title: "Guardado Correctamente"
                    });

                    tableRemolques.ajax.reload();
                    $("#btnSaveRemolques").removeAttr("disabled");


                    $('#modalAddRemolques').modal('hide');
                } else {

                    Toast.fire({
                        icon: 'error',
                        title: respuesta
                    });

                    $("#btnSaveRemolques").removeAttr("disabled");


                }

            }

        }

        )

    });



    /**
     * Carga datos actualizar
     */


    /*=============================================
     EDITAR Remolques
     =============================================*/
    $(".tableRemolques").on("click", ".btnEditRemolques", function () {

        var idRemolques = $(this).attr("idRemolques");

        var datos = new FormData();
        datos.append("idRemolques", idRemolques);

        $.ajax({

            url: "<?= base_url('admin/remolques/getRemolques') ?>",
            method: "POST",
            data: datos,
            cache: false,
            contentType: false,
            processData: false,
            dataType: "json",
            success: function (respuesta) {
                $("#idRemolques").val(respuesta["id"]);

                $("#idEmpresa").val(respuesta["idEmpresa"]);
                $("#idEmpresa").trigger("change");
                $("#descripcion").val(respuesta["descripcion"]);
                $("#subTipoRemolque").val(respuesta["subTipoRemolque"]);
                $("#subTipoRemolque").trigger("change");
                $("#placa").val(respuesta["placa"]);


            }

        })

    })


    /*=============================================
     ELIMINAR remolques
     =============================================*/
    $(".tableRemolques").on("click", ".btn-delete", function () {

        var idRemolques = $(this).attr("data-id");

        Swal.fire({
            title: '<?= lang('boilerplate.global.sweet.title') ?>',
            text: "<?= lang('boilerplate.global.sweet.text') ?>",
            icon: 'warning',
            showCancelButton: true,
            confirmButtonColor: '#3085d6',
            cancelButtonColor: '#d33',
            confirmButtonText: '<?= lang('boilerplate.global.sweet.confirm_delete') ?>'
        })
                .then((result) => {
                    if (result.value) {
                        $.ajax({
                            url: `<?= base_url('admin/remolques') ?>/` + idRemolques,
                            method: 'DELETE',
                        }).done((data, textStatus, jqXHR) => {
                            Toast.fire({
                                icon: 'success',
                                title: jqXHR.statusText,
                            });


                            tableRemolques.ajax.reload();
                        }).fail((error) => {
                            Toast.fire({
                                icon: 'error',
                                title: error.responseJSON.messages.error,
                            });
                        })
                    }
                })
    })

    $(function () {
        $("#modalAddRemolques").draggable();

    });


</script>
<?= $this->endSection() ?>
        

Creamos el archivo para el modal en App/Views/modulesRemolques/modalCaptureRemolques.php con el siguiente código

<!-- Modal Remolques -->
<div class="modal fade" id="modalAddRemolques" tabindex="-1" role="dialog" aria-labelledby="modalAddRemolques" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title"><?= lang('remolques.createEdit') ?></h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <form id="form-remolques" class="form-horizontal">
                    <input type="hidden" id="idRemolques" name="idRemolques" value="0">

                    <div class="form-group row">
                        <label for="idEmpresa" class="col-sm-2 col-form-label"><?= lang('remolques.fields.idEmpresa') ?></label>
                        <div class="col-sm-10">
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="fas fa-pencil-alt"></i></span>
                                </div>


                                <select class="form-control idEmpresa form-controlVehiculos" name="idEmpresa" id="idEmpresa" style="width:80%;">
                                    <option value="0">Seleccione empresa</option>
                                    <?php
                                    foreach ($empresas as $key => $value) {

                                        echo "<option value='$value[id]'>$value[id] - $value[nombre] </option>  ";
                                    }
                                    ?>

                                </select>
                            </div>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="descripcion" class="col-sm-2 col-form-label"><?= lang('remolques.fields.descripcion') ?></label>
                        <div class="col-sm-10">
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="fas fa-pencil-alt"></i></span>
                                </div>
                                <input type="text" name="descripcion" id="descripcion" class="form-control <?= session('error.descripcion') ? 'is-invalid' : '' ?>" value="<?= old('descripcion') ?>" placeholder="<?= lang('remolques.fields.descripcion') ?>" autocomplete="off">
                            </div>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="subTipoRemolque" class="col-sm-2 col-form-label"><?= lang('remolques.fields.subTipoRemolque') ?></label>
                        <div class="col-sm-10">
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="fas fa-pencil-alt"></i></span>
                                </div>

                                <select class="form-control subTipoRemolque form-controlVehiculos" name="subTipoRemolque" id="subTipoRemolque" style="width:80%;">
                                    <option value="0">Seleccione Sup Tipo Remolque</option>
                                    <option value="CTR001">CTR001 - Caballete</option>
                                    <option value="CTR002">CTR002 - Caja</option>
                                    <option value="CTR003">CTR003 - Caja Abierta</option>
                                    <option value="CTR004">CTR004 - Caja Cerrada</option>
                                    <option value="CTR005">CTR005 - Caja De Recolección Con Cargador Frontal</option>
                                    <option value="CTR006">CTR006 - Caja Refrigerada</option>
                                    <option value="CTR007">CTR007 - Caja Seca</option>
                                    <option value="CTR008">CTR008 - Caja Transferencia</option>
                                    <option value="CTR009">CTR009 - Cama Baja o Cuello Ganso</option>
                                    <option value="CTR010">CTR010 - Chasis Portacontenedor</option>
                                    <option value="CTR011">CTR011 - Convencional De Chasis</option>
                                    <option value="CTR012">CTR012 - Equipo Especial</option>
                                    <option value="CTR013">CTR013 - Estacas</option>
                                    <option value="CTR014">CTR014 - Góndola Madrina</option>
                                    <option value="CTR015">CTR015 - Grúa Industrial</option>
                                    <option value="CTR016">CTR016 - Grúa</option>
                                    <option value="CTR017">CTR017 - Integral</option>
                                    <option value="CTR018">CTR018 - Jaula</option>
                                    <option value="CTR019">CTR019 - Media Redila</option>
                                    <option value="CTR020">CTR020 - Pallet o Celdillas</option>
                                    <option value="CTR021">CTR021 - Plataforma</option>
                                    <option value="CTR022">CTR022 - Plataforma Con Grúa</option>
                                    <option value="CTR023">CTR023 - Plataforma Encortinada</option>
                                    <option value="CTR024">CTR024 - Redilas</option>
                                    <option value="CTR025">CTR025 - Refrigerador</option>
                                    <option value="CTR026">CTR026 - Revolvedora</option>
                                    <option value="CTR027">CTR027 - Semicaja</option>
                                    <option value="CTR028">CTR028 - Tanque</option>
                                    <option value="CTR029">CTR029 - Tolva</option>
                                    <option value="CTR031">CTR031 - Volteo</option>
                                    <option value="CTR032">CTR032 - Volteo Desmontable</option>

                                </select>
                            </div>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="placa" class="col-sm-2 col-form-label"><?= lang('remolques.fields.placa') ?></label>
                        <div class="col-sm-10">
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="fas fa-pencil-alt"></i></span>
                                </div>
                                <input type="text" name="placa" id="placa" class="form-control <?= session('error.placa') ? 'is-invalid' : '' ?>" value="<?= old('placa') ?>" placeholder="<?= lang('remolques.fields.placa') ?>" autocomplete="off">
                            </div>
                        </div>
                    </div>


                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal"><?= lang('boilerplate.global.close') ?></button>
                <button type="button" class="btn btn-primary btn-sm" id="btnSaveRemolques"><?= lang('boilerplate.global.save') ?></button>
            </div>
        </div>
    </div>
</div>

<?= $this->section('js') ?>


<script>

    $(document).on('click', '.btnAddRemolques', function (e) {


        $(".form-control").val("");

        $("#idRemolques").val("0");

        $("#idEmpresa").val("0");

        $("#idEmpresa").trigger("change");

        $("#subTipoRemolque").val("0");

        $("#subTipoRemolque").trigger("change");

        $("#btnSaveRemolques").removeAttr("disabled");

    });

    /* 
     * AL hacer click al editar
     */



    $(document).on('click', '.btnEditRemolques', function (e) {


        var idRemolques = $(this).attr("idRemolques");

        //LIMPIAMOS CONTROLES
        $(".form-control").val("");

        $("#idRemolques").val(idRemolques);
        $("#btnGuardarRemolques").removeAttr("disabled");

    });


    $("#idEmpresa").select2();
    $("#subTipoRemolque").select2();

</script>


<?= $this->endSection() ?>
        

Creamos el archivo de languaje en ingles en App/language/en/remolques.php con el siguiente código

<?php

$remolques["logDescription"] = "The remolques was saved with the following data:";
$remolques["logUpdate"] = "The remolques was updated  with the following data:";
$remolques["logDeleted"] = "The remolques was deleted  with the following data:";
$remolques["msg_delete"] = "The remolques was deleted  correctly:";

$remolques["add"] = "Add Remolques";
$remolques["edit"] = "Edit remolques";
$remolques["createEdit"] = "Create / Edit";
$remolques["title"] = "remolques management";
$remolques["subtitle"] = "remolques list";
$remolques["fields"]["idEmpresa"] = "Empresa";
$remolques["fields"]["descripcion"] = "Descripcion";
$remolques["fields"]["subTipoRemolque"] = "SubTipoRemolque";
$remolques["fields"]["placa"] = "Placa";
$remolques["fields"]["updated_at"] = "Updated_at";
$remolques["fields"]["deleted_at"] = "Deleted_at";
$remolques["fields"]["created_at"] = "Created_at";

$remolques["fields"]["actions"] = "Actions";
$remolques["msg"]["msg_insert"] = "The remolques has been correctly added.";
$remolques["msg"]["msg_update"] = "The remolques has been correctly modified.";
$remolques["msg"]["msg_delete"] = "The remolques has been correctly deleted.";
$remolques["msg"]["msg_get"] = "The Remolques has been successfully get.";
$remolques["msg"]["msg_get_fail"] = "The remolques not found or already deleted.";

return $remolques;

Creamos el archivo de lenguaje para español en App/Languaje/es/remolques.php con el siguiente código

<?php

$remolques["logDescription"] = "El registro en remolques fue guardado con los siguientes datos:";
$remolques["logUpdate"] = "El registro en remolques fue actualizado con los siguientes datos:";
$remolques["logDeleted"] = "El registro en remolques fue eliminado con los siguientes datos:";
$remolques["msg_delete"] = "El Registro en remolques fue eliminado correctamente:";
$remolques["add"] = "Agregar Remolques";
$remolques["edit"] = "Editar remolques";
$remolques["createEdit"] = "Crear / Editar";
$remolques["title"] = "Admon. remolques";
$remolques["subtitle"] = "Lista remolques";
$remolques["fields"]["idEmpresa"] = "Empresa";
$remolques["fields"]["descripcion"] = "Descripcion";
$remolques["fields"]["subTipoRemolque"] = "SubTipo Remolque";
$remolques["fields"]["placa"] = "Placa";
$remolques["fields"]["updated_at"] = "Updated_at";
$remolques["fields"]["deleted_at"] = "Deleted_at";
$remolques["fields"]["created_at"] = "Created_at";

$remolques["fields"]["actions"] = "Acciones";
$remolques["msg"]["msg_insert"] = "Registro agregado correctamente.";
$remolques["msg"]["msg_update"] = "Registro modificado correctamente.";
$remolques["msg"]["msg_delete"] = "Registro eliminado correctamente.";
$remolques["msg"]["msg_get"] = "Registro obtenido correctamente.";
$remolques["msg"]["msg_get_fail"] = "Registro no encontrado o eliminado.";
return $remolques;

Metemos las rutas en App/Config/routes.php metemos este código en el grupo admin

$routes->resource('remolques', [
        'filter' => 'permission:remolques-permission',
        'controller' => 'remolquesController',
        'except' => 'show'
    ]);
    $routes->post('remolques/save', 'RemolquesController::save');
    $routes->post('remolques/getRemolques', 'RemolquesController::getRemolques');

Creamos el permiso para acceso al catalogo de remolques con los siguientes datos

Creamos el menú para el acceso al catalogo de remolques con los siguientes datos

Y listo ya tenemos nuestro catalogo de remolques