Herramientas Informaticas

Etiqueta: Desarrollo Página 4 de 6

Creando CRUD de Series Electrónicas #10

Ahora para poder timbrar facturas CFDI necesitamos tener un catalogo de series electrónicas.

En el catalogo de series electrónicas vamos a necesitar los siguientes datos

  • Empresa
  • Sucursal
  • Tipo Serie (venta,pago,devolucion,bonificacion)
  • Serie
  • Desde Fecha
  • Hasta Fecha
  • Desde Folio
  • Hasta Folio
  • Ambiente Timbrado
  • Token pruebas
  • Token producción

Primero creamos el archivo de migración App/Database/migrations/2023-10-17120916_Seriesfacturaelectronica.php para la creación de la tabla en la base de datos

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class Seriesfacturaelectronica extends Migration {

    public function up() {
        // Seriesfacturaelectronica
        $this->forge->addField([
            'id' => ['type' => 'int', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
            'idEmpresa' => ['type' => 'bigint', 'constraint' => 20, 'null' => false],
            'sucursal' => ['type' => 'bigint', 'constraint' => 20, 'null' => false],
            'tipoSerie' => ['type' => 'varchar', 'constraint' => 16, 'null' => false],
            'serie' => ['type' => 'varchar', 'constraint' => 16, 'null' => false],
            'desdeFecha' => ['type' => 'date', 'null' => false],
            'hastaFecha' => ['type' => 'date', 'null' => false],
            'desdeFolio' => ['type' => 'bigint', 'constraint' => 20, 'null' => false],
            'hastaFolio' => ['type' => 'bigint', 'constraint' => 20, 'null' => false],
            'ambienteTimbrado' => ['type' => 'varchar', 'constraint' => 32, 'null' => false],
            'tokenPruebas' => ['type' => 'text', 'null' => false],
            'tokenProduccion' => ['type' => 'text', 'null' => false],
            '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('seriesfacturaelectronica', true);
    }

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

}

Creamos el archivo modelo App/Models/SeriesfacturaelectronicaModel.php para el acceso a la tabla

<?php

namespace App\Models;

use CodeIgniter\Model;

class SeriesfacturaelectronicaModel extends Model {

    protected $table = 'seriesfacturaelectronica';
    protected $primaryKey = 'id';
    protected $useAutoIncrement = true;
    protected $returnType = 'array';
    protected $useSoftDeletes = true;
    protected $allowedFields = ['id'
        , 'idEmpresa'
        , 'sucursal'
        , 'tipoSerie'
        , 'serie'
        , 'desdeFecha'
        , 'hastaFecha'
        , 'desdeFolio'
        , 'hastaFolio'
        , 'ambienteTimbrado'
        , 'tokenPruebas'
        , 'tokenProduccion'
        , 'created_at'
        , 'updated_at'
        , 'deleted_at'];
    protected $useTimestamps = true;
    protected $createdField = 'created_at';
    protected $deletedField = 'deleted_at';
    protected $validationRules = [
    ];
    protected $validationMessages = [];
    protected $skipValidation = false;

    public function mdlGetSeriesfacturaelectronica($idEmpresas) {

        $result = $this->db->table('seriesfacturaelectronica a, empresas b, branchoffices c')
                ->select('a.id
                            ,a.idEmpresa
                            ,a.sucursal
                            ,a.tipoSerie
                            ,a.serie
                            ,a.desdeFecha
                            ,a.hastaFecha
                            ,a.desdeFolio
                            ,a.hastaFolio
                            ,a.ambienteTimbrado
                            ,a.tokenPruebas
                            ,a.tokenProduccion
                            ,a.created_at
                            ,a.updated_at
                            ,a.deleted_at 
                            ,b.nombre as nombreEmpresa
                            ,c.name as nombreSucursal
                            ')
                ->where('a.idEmpresa', 'b.id', FALSE)
                ->where('a.sucursal', 'c.id', FALSE)
                ->whereIn('a.idEmpresa', $idEmpresas);

        return $result;
    }

}

Creamos el archivo controlador App/Controllers/SeriesfacturaelectronicaController.php

<?php

namespace App\Controllers;

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

class SeriesfacturaelectronicaController extends BaseController {

    use ResponseTrait;

    protected $log;
    protected $seriesfacturaelectronica;
    protected $sucursales;

    public function __construct() {
        $this->seriesfacturaelectronica = new SeriesfacturaelectronicaModel();
        $this->log = new LogModel();
        $this->empresa = new EmpresasModel();
        $this->sucursales = new BranchofficesModel();
                
        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->seriesfacturaelectronica->mdlGetSeriesfacturaelectronica($empresasID);

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

    /**
     * Read Seriesfacturaelectronica
     */
    public function getSeriesfacturaelectronica() {

        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");
        }


        $idSeriesfacturaelectronica = $this->request->getPost("idSeriesfacturaelectronica");
        $datosSeriesfacturaelectronica = $this->seriesfacturaelectronica->whereIn('idEmpresa', $empresasID)
                        ->where("id", $idSeriesfacturaelectronica)->first();
        
        $datosSucursal = $this->sucursales->select("*")->where("id",$datosSeriesfacturaelectronica["sucursal"])->first();
        
        if($datosSucursal["name"]!=null){
            
            $datosSeriesfacturaelectronica["nombreSucursal"] = $datosSucursal["name"];
            
        }else{
            
            $datosSucursal["name"] =""; 
            
        }
        
        
        echo json_encode($datosSeriesfacturaelectronica);
    }

    /**
     * Save or update Seriesfacturaelectronica
     */
    public function save() {
        helper('auth');
        $userName = user()->username;
        $idUser = user()->id;
        $datos = $this->request->getPost();
        if ($datos["idSeriesfacturaelectronica"] == 0) {
            try {
                if ($this->seriesfacturaelectronica->save($datos) === false) {
                    $errores = $this->seriesfacturaelectronica->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->seriesfacturaelectronica->update($datos["idSeriesfacturaelectronica"], $datos) == false) {
                $errores = $this->seriesfacturaelectronica->errors();
                foreach ($errores as $field => $error) {
                    echo $error . " ";
                }
                return;
            } else {
                $dateLog["description"] = lang("seriesfacturaelectronica.logUpdated") . json_encode($datos);
                $dateLog["user"] = $userName;
                $this->log->save($dateLog);
                echo "Actualizado Correctamente";
                return;
            }
        }
        return;
    }

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

}

Para los archivos de la vista ya se la saben, es un archivo principal en el que incluimos los archivos secundarios

Creamos el archivo principal App/Views/seriesfacturaelectronica.php con el siguiente código

<?= $this->include('load/toggle') ?>
<?= $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('modulesSeriesfacturaelectronica/modalCaptureSeriesfacturaelectronica') ?>

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

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

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

                </button>

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

                                <th>#</th>
                                <th><?= lang('seriesfacturaelectronica.fields.empresa') ?></th>
                                <th><?= lang('seriesfacturaelectronica.fields.sucursal') ?></th>
                                <th>Tipo Serie</th>
                                <th><?= lang('seriesfacturaelectronica.fields.desdeFecha') ?></th>
                                <th><?= lang('seriesfacturaelectronica.fields.hastaFecha') ?></th>
                                <th><?= lang('seriesfacturaelectronica.fields.desdeFolio') ?></th>
                                <th><?= lang('seriesfacturaelectronica.fields.ambienteTimbrado') ?></th>
                                <th><?= lang('seriesfacturaelectronica.fields.tokenPruebas') ?></th>
                                <th><?= lang('seriesfacturaelectronica.fields.tokenProduccion') ?></th>
                                <th><?= lang('seriesfacturaelectronica.fields.created_at') ?></th>
                                <th><?= lang('seriesfacturaelectronica.fields.updated_at') ?></th>
                                <th><?= lang('seriesfacturaelectronica.fields.deleted_at') ?></th>

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

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

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


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

    /**
     * Cargamos la tabla
     */

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

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

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

            {
                'data': 'nombreEmpresa'
            },

            {
                'data': 'nombreSucursal'
            },

            {
                'data': 'tipoSerie'
            },

            {
                'data': 'desdeFecha'
            },

            {
                'data': 'hastaFecha'
            },

            {
                'data': 'desdeFolio'
            },

            {
                'data': 'ambienteTimbrado'
            },

            {
                'data': 'tokenPruebas'
            },

            {
                'data': 'tokenProduccion'
            },

            {
                'data': 'created_at'
            },

            {
                'data': 'updated_at'
            },

            {
                'data': 'deleted_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 btnEditSeriesfacturaelectronica" data-toggle="modal" idSeriesfacturaelectronica="${data.id}" data-target="#modalAddSeriesfacturaelectronica">  <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', '#btnSaveSeriesfacturaelectronica', function (e) {


        var idSeriesfacturaelectronica = $("#idSeriesfacturaelectronica").val();
        var empresa = $("#empresa").val();
        var sucursal = $("#sucursal").val();
        var tipoSerie = $("#tipoSerie").val();
        var serie = $("#serie").val();
        var desdeFecha = $("#desdeFecha").val();
        var hastaFecha = $("#hastaFecha").val();
        var desdeFolio = $("#desdeFolio").val();
        var hastaFolio = $("#hastaFolio").val();

        if ($("#ambienteTimbrado").is(':checked')) {

            var ambienteTimbrado = "on";

        } else {

            var ambienteTimbrado = "off";

        }

        var tokenPruebas = $("#tokenPruebas").val();
        var tokenProduccion = $("#tokenProduccion").val();


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

        var datos = new FormData();
        datos.append("idSeriesfacturaelectronica", idSeriesfacturaelectronica);
        datos.append("idEmpresa", empresa);
        datos.append("sucursal", sucursal);
        datos.append("tipoSerie", tipoSerie);
        datos.append("serie", serie);
        datos.append("desdeFecha", desdeFecha);
        datos.append("hastaFecha", hastaFecha);
        datos.append("desdeFolio", desdeFolio);
        datos.append("hastaFolio", hastaFolio);
        datos.append("ambienteTimbrado", ambienteTimbrado);
        datos.append("tokenPruebas", tokenPruebas);
        datos.append("tokenProduccion", tokenProduccion);


        $.ajax({

            url: "<?= base_url('admin/seriesfacturaelectronica/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"
                    });

                    tableSeriesfacturaelectronica.ajax.reload();
                    $("#btnSaveSeriesfacturaelectronica").removeAttr("disabled");


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

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

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


                }

            }

        }

        )

    });



    /**
     * Carga datos actualizar
     */


    /*=============================================
     EDITAR Seriesfacturaelectronica
     =============================================*/
    $(".tableSeriesfacturaelectronica").on("click", ".btnEditSeriesfacturaelectronica", function () {

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

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

        $.ajax({

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

                $("#empresa").val(respuesta["idEmpresa"]);

                var newOptionSucursal = new Option(respuesta["nombreSucursal"], respuesta["sucursal"], true, true);
                $('#sucursal').append(newOptionSucursal).trigger('change');
                $("#sucursal").val(respuesta["sucursal"]);


                $("#sucursal").val(respuesta["sucursal"]);
                $("#tipoSerie").val(respuesta["tipoSerie"]);
                $("#tipoSerie").trigger("change");
                $("#serie").val(respuesta["serie"]);
                $("#desdeFecha").val(respuesta["desdeFecha"]);
                $("#hastaFecha").val(respuesta["hastaFecha"]);
                $("#desdeFolio").val(respuesta["desdeFolio"]);
                $("#hastaFolio").val(respuesta["hastaFolio"]);

                $("#ambienteTimbrado").bootstrapToggle(respuesta["ambienteTimbrado"]);
                $("#tokenPruebas").val(respuesta["tokenPruebas"]);
                $("#tokenProduccion").val(respuesta["tokenProduccion"]);


            }

        })

    })


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

        var idSeriesfacturaelectronica = $(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/seriesfacturaelectronica') ?>/` + idSeriesfacturaelectronica,
                            method: 'DELETE',
                        }).done((data, textStatus, jqXHR) => {
                            Toast.fire({
                                icon: 'success',
                                title: jqXHR.statusText,
                            });


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

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

    });


    $("#tipoSerie").select2();

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

En el archivo secundario App/Views/modulesSeriesfacturaelectronica/modalCaptureSeriesfacturaelectronica.php

<!-- Modal Seriesfacturaelectronica -->
<div class="modal fade" id="modalAddSeriesfacturaelectronica" tabindex="-1" role="dialog" aria-labelledby="modalAddSeriesfacturaelectronica" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title"><?= lang('seriesfacturaelectronica.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-seriesfacturaelectronica" class="form-horizontal">
                    <input type="hidden" id="idSeriesfacturaelectronica" name="idSeriesfacturaelectronica" value="0">

                    <div class="form-group row">
                        <label for="emitidoRecibido" class="col-sm-2 col-form-label">Empresa</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 empresa" name="empresa" id="empresa" style = "width:80%;">
                                    <option value="0">Seleccione empresa</option>
                                    <?php
                                    foreach ($empresas as $key => $value) {

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

                                </select>

                            </div>
                        </div>
                    </div>

                    <div class="form-group row">
                        <label for="sucursal" class="col-sm-2 col-form-label">Sucursal</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 sucursal" name="sucursal" id="sucursal" style = "width:80%;">
                                    <option value="0">Seleccione sucursal</option>


                                </select>

                            </div>
                        </div>
                    </div>


                    <div class="form-group row">
                        <label for="sucursal" class="col-sm-2 col-form-label">Tipo Serie</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 tipoSerie" name="tipoSerie" id="tipoSerie" style = "width:80%;">
                                    <option value="ven">Venta</option>
                                    <option value="pag">Pago</option>
                                    <option value="dev">Devolución</option>
                                    <option value="bon">Bonificaciónn</option>

                                </select>

                            </div>
                        </div>
                    </div>


                    <div class="form-group row">
                        <label for="desdeFecha" class="col-sm-2 col-form-label"><?= lang('seriesfacturaelectronica.fields.desdeFecha') ?></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="date" name="desdeFecha" id="desdeFecha" class="form-control <?= session('error.desdeFecha') ? 'is-invalid' : '' ?>" value="<?= old('desdeFecha') ?>" placeholder="<?= lang('seriesfacturaelectronica.fields.desdeFecha') ?>" autocomplete="off">
                            </div>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="hastaFecha" class="col-sm-2 col-form-label"><?= lang('seriesfacturaelectronica.fields.hastaFecha') ?></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="date" name="hastaFecha" id="hastaFecha" class="form-control <?= session('error.hastaFecha') ? 'is-invalid' : '' ?>" value="<?= old('hastaFecha') ?>" placeholder="<?= lang('seriesfacturaelectronica.fields.hastaFecha') ?>" autocomplete="off">
                            </div>
                        </div>
                    </div>

                    <div class="form-group row">
                        <label for="serie" class="col-sm-2 col-form-label">Serie</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="serie" id="serie" class="form-control <?= session('error.serie') ? 'is-invalid' : '' ?>" value="<?= old('desdeFolio') ?>" placeholder="Inserte serie" autocomplete="off">
                            </div>
                        </div>
                    </div>


                    <div class="form-group row">
                        <label for="desdeFolio" class="col-sm-2 col-form-label"><?= lang('seriesfacturaelectronica.fields.desdeFolio') ?></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="number" name="desdeFolio" id="desdeFolio" class="form-control <?= session('error.desdeFolio') ? 'is-invalid' : '' ?>" value="<?= old('desdeFolio') ?>" placeholder="<?= lang('seriesfacturaelectronica.fields.desdeFolio') ?>" autocomplete="off">
                            </div>
                        </div>
                    </div>

                    <div class="form-group row">
                        <label for="hastaFolio" class="col-sm-2 col-form-label">Hasta Folio</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="number" name="hastaFolio" id="hastaFolio" class="form-control <?= session('error.desdeFolio') ? 'is-invalid' : '' ?>" value="<?= old('hastaFolio') ?>" placeholder="Hasta Folio" autocomplete="off">
                            </div>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="ambienteTimbrado" class="col-sm-2 col-form-label"><?= lang('seriesfacturaelectronica.fields.ambienteTimbrado') ?></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="checkbox" name="ambienteTimbrado" id="ambienteTimbrado" class="form-control " autocomplete="off" data-width="250" data-height="40" checked data-toggle="toggle" data-on="produccion" data-off="pruebas" data-onstyle="success" data-offstyle="danger">
                            </div>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="tokenPruebas" class="col-sm-2 col-form-label"><?= lang('seriesfacturaelectronica.fields.tokenPruebas') ?></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="tokenPruebas" id="tokenPruebas" class="form-control <?= session('error.tokenPruebas') ? 'is-invalid' : '' ?>" value="<?= old('tokenPruebas') ?>" placeholder="<?= lang('seriesfacturaelectronica.fields.tokenPruebas') ?>" autocomplete="off">
                            </div>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="tokenProduccion" class="col-sm-2 col-form-label"><?= lang('seriesfacturaelectronica.fields.tokenProduccion') ?></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="tokenProduccion" id="tokenProduccion" class="form-control <?= session('error.tokenProduccion') ? 'is-invalid' : '' ?>" value="<?= old('tokenProduccion') ?>" placeholder="<?= lang('seriesfacturaelectronica.fields.tokenProduccion') ?>" 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="btnSaveSeriesfacturaelectronica"><?= lang('boilerplate.global.save') ?></button>
            </div>
        </div>
    </div>
</div>

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


<script>

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


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

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

        $("#empresa").val("0");
        $("#empresa").trigger("change");

        $("#ambienteTimbrado").bootstrapToggle("off");

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

    });

    /* 
     * AL hacer click al editar
     */



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


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

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

        $("#idSeriesfacturaelectronica").val(idSeriesfacturaelectronica);
        $("#btnGuardarSeriesfacturaelectronica").removeAttr("disabled");

    });


    $("#empresa").select2();

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



    $("#sucursal").select2({
        ajax: {
            url: "<?= site_url('admin/sucursales/getSucursalesAjax') ?>",
            type: "post",
            dataType: 'json',
            delay: 250,
            data: function (params) {
                // CSRF Hash
                var csrfName = $('.txt_csrfname').attr('name'); // CSRF Token name
                var csrfHash = $('.txt_csrfname').val(); // CSRF hash
                var idEmpresa = $('.empresa').val(); // CSRF hash

                return {
                    searchTerm: params.term, // search term
                    [csrfName]: csrfHash, // CSRF Token
                    idEmpresa: idEmpresa // search term
                };
            },
            processResults: function (response) {

                // Update CSRF Token
                $('.txt_csrfname').val(response.token);
                return {
                    results: response.data
                };
            },
            cache: true
        }
    });

</script>


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

En las rutas App/config/Routes.php dentro del grupo admin agregamos el siguiente código

    $routes->resource('seriesfacturaelectronica', [
        'filter' => 'permission:seriesfacturaelectronica-permission',
        'controller' => 'seriesfacturaelectronicaController',
        'except' => 'show'
    ]);
    $routes->post('seriesfacturaelectronica/save', 'SeriesfacturaelectronicaController::save');
    $routes->post('seriesfacturaelectronica/getSeriesfacturaelectronica', 'SeriesfacturaelectronicaController::getSeriesfacturaelectronica');

Creamos el menú para las series electrónicas con los siguientes datos

Y listo ya tenemos nuestro CRUD de Series Electronicas

Creando CRUD de sucursales #09

Bien como ya saben para hacer una venta se requiere saber de que sucursal es así como ciertas configuraciones particulares por sucursal como la configuración de las series electrónicas para el timbrado del CFDI, así como los datos que saldran en las impresiones de los reportes, como la dirección etc

Por esta ocasión agregaremos lo siguientes datos, posterior mente se pueden agregar mas si se necesitan

  • Empresa
  • Llave
  • Nombre
  • Colonia
  • Ciudad
  • Diferencia horaria
  • Impuesto
  • Fecha de apertura
  • Telefono
  • Fax
  • Arqueo de caja
Leer Mas: Creando CRUD de sucursales #09

Primeramente creamos el archivo de migración app/database/migrations/2023-02-14110147_Branchoffices.php , se dan cuenta que dice Branchoffice, es por que en su momento lo quise empezar en ingles para practicar

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class Branchoffices extends Migration {

    public function up() {
        // Branchoffices
        $this->forge->addField([
                'id' => ['type' => 'int', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
                'key' => ['type' => 'varchar', 'constraint' => 8, 'null' => false],
                'name' => ['type' => 'varchar', 'constraint' => 256, 'null' => true],
                'cologne' => ['type' => 'varchar', 'constraint' => 64, 'null' => true],
                'city' => ['type' => 'varchar', 'constraint' => 128, 'null' => true],
                'postalCode' => ['type' => 'varchar', 'constraint' => 5, 'null' => true],
                'timeDifference' => ['type' => 'varchar', 'constraint' => 4, 'null' => true],
                'tax' => ['type' => 'varchar', 'constraint' => 4, 'null' => true],
                'dateAp' => ['type' => 'date', 'null'  => true],
                'phone'  => ['type' => 'varchar', 'constraint'  => 16, 'null'  => true],
                'fax'  => ['type' => 'varchar', 'constraint'  => 16, 'null'  => true],
                'companie'  => ['type' => 'varchar', 'constraint'  => 8, 'null'  => true],
                'arqueoCaja'  => ['type' => 'varchar', 'constraint'  => 5, '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('branchoffices', true);
    }

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

}

Una ve creado el archivo ejecutamos el comando que crea la tabla

también necesitamos la tabla de sucursales por usuario app/database/migrations/2023-02-14110147_Branchoffices.php

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class UsuariosSucursal extends Migration
{
    public function up()
    {
        // Usuariosempresa
        $this->forge->addField([
            'id'                    => ['type' => 'int', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
            'idEmpresa'             => ['type' => 'int', 'constraint' => 11, 'null' => true],
            'idSucursal'             => ['type' => 'int', 'constraint' => 11, 'null' => true],
            'idUsuario'             => ['type' => 'int', 'constraint' => 11, 'null' => true],
            'status'             => ['type' => 'varchar', 'constraint' => 8, '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('usuarios_sucursal', true);
    }
    public function down()
    {
        $this->forge->dropTable('usuarios_sucursal', true);
    }
}
php spark migrate

Creamos el archivo app/models/BranchofficeModel.php con los métodos necesarios de lectura y reglas de validación

<?php

namespace App\Models;

use CodeIgniter\Model;

class BranchofficesModel extends Model{

    protected $table      = 'branchoffices';
    protected $primaryKey = 'id';
    protected $useAutoIncrement = true;
    protected $returnType     = 'array';
    protected $useSoftDeletes = true;
    protected $allowedFields = ['id'
    ,'key'
    ,'name'
    ,'cologne'
    ,'city'
    ,'postalCode'
    ,'timeDifference'
    ,'tax'
    ,'dateAp'
    ,'phone'
    ,'fax'
    ,'companie'
    ,'arqueoCaja'
    ,'created_at
    ','deleted_at'
    ,'updated_at'];
    protected $useTimestamps = true;
    protected $createdField  = 'created_at';
    protected $deletedField  = 'deleted_at';

    protected $validationRules    =  [
         'key ' => 'is_unique[branchoffices.key]',

    ];
    protected $validationMessages = [];
    protected $skipValidation     = false;
    
    
        public function mdlSucursalesPorUsuario($usuario){


        $resultado =$this->db->table('branchoffices a, usuarios_sucursal b')
        ->select('a.id,a.name,key,a.created_at,a.updated_at,a.deleted_at')
        ->where('a.id', 'b.idSucursal', FALSE)
        ->where('b.status', 'on')
        ->where('b.idUsuario', $usuario)->get()->getResultArray();

        return $resultado;

    }

}
        

Creamos el archivo del modelo usuarios por sucursal app/model/UsuariosSucursalModel.php

<?php

namespace App\Models;

use CodeIgniter\Model;

class UsuariosSucursalModel extends Model
{
    protected $table      = 'usuarios_sucursal';
    protected $primaryKey = 'id';
    protected $useAutoIncrement = true;
    protected $returnType     = 'array';
    protected $useSoftDeletes = true;
    protected $allowedFields = ['id', 'idEmpresa', 'idSucursal', 'idUsuario', 'status', 'created_at', 'updated_at', 'deleted_at'];
    protected $useTimestamps = true;
    protected $createdField  = 'created_at';
    protected $deletedField  = 'deleted_at';
    protected $validationRules    =  [];
    protected $validationMessages = [];
    protected $skipValidation     = false;


    public function mdlSucursalesPorUsuario($sucursal, $empresasID)
    {

        $result = $this->db->table('users a, usuariosempresa b')
            ->select(
                'ifnull(a.id,0) as id
                ,a.username
                ,b.idEmpresa
                ,' . $sucursal . ' as idSucursal
                ,ifnull((select status 
                            from usuarios_sucursal z
                            where z.idUsuario = a.id
                                and z.idEmpresa=b.idEmpresa
                                    and z.idSucursal=' . $sucursal . '
                                    ),\'off\') as status
                                        
                ,ifnull((select id 
                        from usuarios_sucursal z
                        where z.idUsuario = a.id
                            and z.idEmpresa=b.idEmpresa
                                and z.idSucursal=' . $sucursal . '
                                ),0) as idSucursalUsuario
                '

            )

            ->where('a.id', 'b.idUsuario', FALSE)
            ->where('b.idEmpresa', $empresasID);

        return $result;
    }
}

Creamos el archivo app/controller/BranchofficesController.php

<?php

namespace App\Controllers;

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

class BranchofficesController extends BaseController {

    use ResponseTrait;

    protected $log;
    protected $branchoffices;
    protected $empresas;
    protected $usuariosPorSucursal;

    public function __construct() {
        $this->branchoffices = new BranchofficesModel();
        $this->log = new LogModel();
        $this->empresas = new EmpresasModel();
        $this->usuariosPorSucursal = new UsuariosSucursalModel();
        helper('menu');
    }

    public function index() {

        helper('auth');

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

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

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

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



        if ($this->request->isAJAX()) {




            $datos = $this->branchoffices->select('id
            ,key
            ,name
            ,cologne
            ,city
            ,postalCode
            ,timeDifference
            ,tax,dateAp
            ,phone
            ,fax
            ,companie
            ,created_at
            ,deleted_at
            ,updated_at')->where('deleted_at', null)
            ->whereIn('companie', $empresasID);;

            return \Hermawan\DataTables\DataTable::of($datos)->toJson(true);
        }


       // $empresas = $this->empresas->select("id,nombre")->asObject()->findAll();

       // $titulos["empresas"] = $empresas;
        $titulos["title"] = lang('branchoffices.title');
        $titulos["subtitle"] = lang('branchoffices.subtitle');

        return view('branchoffices', $titulos);
    }

    /**
     * Read Branchoffices
     */
    public function getBranchoffices() {


        $idBranchoffices = $this->request->getPost("idBranchoffices");
        $datosBranchoffices = $this->branchoffices->find($idBranchoffices);

        echo json_encode($datosBranchoffices);
    }

    /**
     * Save or update Branchoffices
     */
    public function save() {


        helper('auth');
        $userName = user()->username;
        $idUser = user()->id;

        $datos = $this->request->getPost();

        if ($datos["idBranchoffices"] == 0) {


            try {


                if ($this->branchoffices->save($datos) === false) {

                    $errores = $this->branchoffices->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->branchoffices->update($datos["idBranchoffices"], $datos) == false) {

                $errores = $this->branchoffices->errors();
                foreach ($errores as $field => $error) {

                    echo $error . " ";
                }

                return;
            } else {

                $dateLog["description"] = lang("branchoffices.logUpdated") . json_encode($datos);
                $dateLog["user"] = $userName;

                $this->log->save($dateLog);
                echo "Actualizado Correctamente";

                return;
            }
        }

        return;
    }

    /**
     * Delete Branchoffices
     * @param type $id
     * @return type
     */
    public function delete($id) {

        $infoBranchoffices = $this->branchoffices->find($id);
        helper('auth');
        $userName = user()->username;

        if (!$found = $this->branchoffices->delete($id)) {
            return $this->failNotFound(lang('branchoffices.msg.msg_get_fail'));
        }



        $logData["description"] = lang("branchoffices.logDeleted") . json_encode($infoBranchoffices);
        $logData["user"] = $userName;

        $this->log->save($logData);
        return $this->respondDeleted($found, lang('branchoffices.msg_delete'));
    }

    public function usuariosPorSucursal($sucursal) {

        helper('auth');

        $idUser = user()->id;

        $datosSucursal = $this->branchoffices->select("companie as empresa")->where("id",$sucursal)->first();

        if(isset($datosSucursal["empresa"])){

            $idEmpresa = $datosSucursal["empresa"];

        }else{

            $idEmpresa = -1;

        }
        

        $usuarios = $this->usuariosPorSucursal->mdlSucursalesPorUsuario($sucursal, $idEmpresa);

        return \Hermawan\DataTables\DataTable::of($usuarios)->toJson(true);
    }

    /**
     * Activar Desactivar Usuario Por Empresa
     */
    public function ActivarDesactivar() {

        $datos = $this->request->getPost();

        if ($datos["id"] > 0) {

            //ACTUALIZA SI  EXISTE

            if ($this->usuariosPorSucursal->update($datos["id"], $datos) === false) {
                $errores = $this->usuariosPorSucursal->errors();
                foreach ($errores as $field => $error) {
                    echo $error . " ";
                }
                return;
            }

            echo "ok";
        } else {

            //INSERTA SI  NO EXISTE
            if ($this->usuariosPorSucursal->save($datos) === false) {

                $errores = $this->usuariosPorSucursal->errors();

                foreach ($errores as $key => $error) {

                    echo $error . " ";
                }

                return;
            }



            echo "ok";
        }
    }

    /**
     * Get Storages via AJax
     */
    public function getSucursalesAjax() {

        $request = service('request');
        $postData = $request->getPost();

        $response = array();

        // Read new token and assign in $response['token']
        $response['token'] = csrf_hash();

        helper('auth');
        $userName = user()->username;
        $idUser = user()->id;

        $sucursalesPorUsuario = $this->usuariosPorSucursal->select("*")
                        ->where("idUsuario", $idUser)
                        ->where("status", "on")->findAll();

        $sucursalesPorUsuario = array_column($sucursalesPorUsuario, "idSucursal");
        if (!isset($postData['searchTerm'])) {
            // Fetch record
            $sucursales = new BranchofficesModel();
            $listSucursales = $sucursales->select('id,key,name')->where("deleted_at", null)
                    ->whereIn("id", $sucursalesPorUsuario)
                    ->where("companie", $postData["idEmpresa"])
                    ->orderBy('id')
                    ->orderBy('key')
                    ->orderBy('name')
                    ->findAll();
        } else {
            $searchTerm = $postData['searchTerm'];

            // Fetch record
            $sucursales = new BranchofficesModel();
            $listSucursales = $sucursales->select('id,key,name')
                    ->where("deleted_at", null)
                    ->whereIn("id", $sucursalesPorUsuario)
                    ->where("companie", $postData["idEmpresa"])
                    ->like('name', $searchTerm)
                    ->orLike('id', $searchTerm)
                    ->orLike('key', $searchTerm)
                    ->findAll();
        }

        $data = array();
        $data[] = array(
            "id" => 0,
            "text" => "0 Todas las sucursales",
        );

        foreach ($listSucursales as $sucursal) {
            $data[] = array(
                "id" => $sucursal['id'],
                "text" => $sucursal['key'] . ' ' . $sucursal['name'],
            );
        }

        $response['data'] = $data;

        return $this->response->setJSON($response);
    }

}

Creamos el archivo del controlador para usuarios por sucursal app/controller/UsuariosSucursalController.php

<?php

namespace App\Controllers;

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

class UsuariosSucursalController extends BaseController {

    use ResponseTrait;

    protected $log;
    protected $usuariosSucursal;

    public function __construct() {
        $this->usuariosSucursal = new UsuariosSucursalModel();
        $this->log = new LogModel();
        helper('menu');
    }

    public function index() {
        if ($this->request->isAJAX()) {
            $datos = $this->usuariosSucursal>select('id,idEmpresa,idSucursal,idUsuario,status,created_at,updated_at,deleted_at')->where('deleted_at', null);
            return \Hermawan\DataTables\DataTable::of($datos)->toJson(true);
        }
        $titulos["title"] = "Usuarios Sucursal";
        $titulos["subtitle"] = "Usuarios Por Sucursal";
        return view('usuariosAlmacen', $titulos);
    }

    /**
     * Read Usuariosempresa
     */
    public function getUsuariosAlmacen() {
        $idUsuariosAlmacen = $this->request->getPost("idUsuariosSucursal");
        $datosUsuariosAlmacen = $this->usuariosAlmacen->find($idUsuariosAlmacen);
        echo json_encode($datosUsuariosAlmacen);
    }

    /**
     * Save or update Usuariosempresa
     */
    public function save() {
        helper('auth');
        $userName = user()->username;
        $idUser = user()->id;
        $datos = $this->request->getPost();
        if ($datos["idUsuariosSucursal"] == 0) {
            try {
                if ($this->usuariosSucursal->save($datos) === false) {
                    $errores = $this->usuariosSucursal->errors();
                    foreach ($errores as $field => $error) {
                        echo $error . " ";
                    }
                    return;
                }
                $dateLog["description"] = "Usuarios Por Sucursal" . 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->usuariosSucursal->update($datos["idUsuariossucursal"], $datos) == false) {
                $errores = $this->usuariosSucursal->errors();
                foreach ($errores as $field => $error) {
                    echo $error . " ";
                }
                return;
            } else {
                $dateLog["description"] = lang("usuariosSucursal.logUpdated") . json_encode($datos);
                $dateLog["user"] = $userName;
                $this->log->save($dateLog);
                echo "Actualizado Correctamente";
                return;
            }
        }
        return;
    }

    /**
     * Delete Usuariosempresa
     * @param type $id
     * @return type
     */
    public function delete($id) {
        $infoUsuariosSucursal = $this->usuariosSucursal->find($id);
        helper('auth');
        $userName = user()->username;
        if (!$found = $this->usuariosSucursal->delete($id)) {
            return $this->failNotFound(lang('usuariosempresa.msg.msg_get_fail'));
        }
        $this->usuariosSucursal->purgeDeleted();
        $logData["description"] = "Datos Anteriores Usuarios Por Sucursal" . json_encode($infoUsuariosSucursal);
        $logData["user"] = $userName;
        $this->log->save($logData);
        return $this->respondDeleted($found, lang('usuariossucursal.msg_delete'));
    }

}

Creamos el archivo principal de la vista de sucursales app/views/branchoffice.php este archivo hará una inclusión a los modales de usuarios por sucursal y captura de sucursales

<?= $this->include('load/toggle') ?>
<?= $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('modulesBranchoffices/modalCaptureBranchoffices') ?>
<?= $this->include('modulesBranchoffices/usuariosSucursalModal') ?>

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

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

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

                </button>

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

                                <th>#</th>
                                <th><?= lang('branchoffices.fields.key') ?></th>
                                <th><?= lang('branchoffices.fields.name') ?></th>
                                <th><?= lang('branchoffices.fields.cologne') ?></th>
                                <th><?= lang('branchoffices.fields.city') ?></th>
                                <th><?= lang('branchoffices.fields.postalCode') ?></th>
                                <th><?= lang('branchoffices.fields.timeDifference') ?></th>
                                <th><?= lang('branchoffices.fields.tax') ?></th>
                                <th><?= lang('branchoffices.fields.dateAp') ?></th>
                                <th><?= lang('branchoffices.fields.phone') ?></th>
                                <th><?= lang('branchoffices.fields.fax') ?></th>
                                <th><?= lang('branchoffices.fields.companie') ?></th>
                                <th><?= lang('branchoffices.fields.created_at') ?></th>
                                <th><?= lang('branchoffices.fields.deleted_at') ?></th>
                                <th><?= lang('branchoffices.fields.updated_at') ?></th>

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

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

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


<?= $this->section('js') ?>
<script>
    /**
     * Cargamos la tabla
     */

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

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

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

            {
                'data': 'key'
            },

            {
                'data': 'name'
            },

            {
                'data': 'cologne'
            },

            {
                'data': 'city'
            },

            {
                'data': 'postalCode'
            },

            {
                'data': 'timeDifference'
            },

            {
                'data': 'tax'
            },

            {
                'data': 'dateAp'
            },

            {
                'data': 'phone'
            },

            {
                'data': 'fax'
            },

            {
                'data': 'companie'
            },

            {
                'data': 'created_at'
            },

            {
                'data': 'deleted_at'
            },

            {
                'data': 'updated_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 btnEditBranchoffices" data-toggle="modal" idBranchoffices="${data.id}" data-target="#modalAddBranchoffices">  <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>
                             <button class="btn btn-success btn-users" data-id="${data.id}" data-toggle="modal" data-target="#modalUsuariosSucursal"><i class="fas fa-users"></i></button>
                         </div>
                         </td>`
                }
            }
        ]
    });



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


        var idBranchoffices = $("#idBranchoffices").val();
        var key = $("#key").val();
        var name = $("#name").val();
        var cologne = $("#cologne").val();
        var city = $("#city").val();
        var postalCode = $("#postalCode").val();
        var timeDifference = $("#timeDifference").val();
        var tax = $("#tax").val();
        var dateAp = $("#dateAp").val();
        var phone = $("#phone").val();
        var fax = $("#fax").val();
        var companie = $("#companie").val();

        if ($("#arqueoCaja").is(':checked')) {

            var arqueoCaja = "on";

        } else {

            var arqueoCaja = "off";

        }


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

        var datos = new FormData();
        datos.append("idBranchoffices", idBranchoffices);
        datos.append("key", key);
        datos.append("name", name);
        datos.append("cologne", cologne);
        datos.append("city", city);
        datos.append("postalCode", postalCode);
        datos.append("timeDifference", timeDifference);
        datos.append("tax", tax);
        datos.append("dateAp", dateAp);
        datos.append("phone", phone);
        datos.append("fax", fax);
        datos.append("companie", companie);
        datos.append("arqueoCaja", arqueoCaja);


        $.ajax({

            url: "<?= base_url('admin/branchoffices/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"
                    });

                    tableBranchoffices.ajax.reload();
                    $("#btnSaveBranchoffices").removeAttr("disabled");


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

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

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


                }

            }

        }

        )

    });



    /**
     * Carga datos actualizar
     */


    /*=============================================
     EDITAR Branchoffices
     =============================================*/
    $(".tableBranchoffices").on("click", ".btnEditBranchoffices", function () {

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

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

        $.ajax({

            url: "<?= base_url('admin/branchoffices/getBranchoffices') ?>",
            method: "POST",
            data: datos,
            cache: false,
            contentType: false,
            processData: false,
            dataType: "json",
            success: function (respuesta) {


                console.log(respuesta["dateAp"]);
                $("#idBranchoffices").val(respuesta["id"]);

                $("#key").val(respuesta["key"]);
                $("#name").val(respuesta["name"]);
                $("#cologne").val(respuesta["cologne"]);
                $("#city").val(respuesta["city"]);
                $("#postalCode").val(respuesta["postalCode"]);
                $("#timeDifference").val(respuesta["timeDifference"]);
                $("#tax").val(respuesta["tax"]);
                $("#dateAp").val(respuesta["dateAp"]);
                $("#phone").val(respuesta["phone"]);
                $("#fax").val(respuesta["fax"]);
                $("#companie").val(respuesta["companie"]);
                $("#companie").trigger("change");

                var arqueoCaja = respuesta["arqueoCaja"];

                if (arqueoCaja == "null" || arqueoCaja == "NULL") {

                    arqueoCaja = respuesta["arqueoCaja"];
                }

                $("#arqueoCaja").bootstrapToggle(arqueoCaja);


            }

        })

    })


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

        var idBranchoffices = $(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/branchoffices') ?>/` + idBranchoffices,
                            method: 'DELETE',
                        }).done((data, textStatus, jqXHR) => {
                            Toast.fire({
                                icon: 'success',
                                title: jqXHR.statusText,
                            });


                            tableBranchoffices.ajax.reload();
                        }).fail((error) => {
                            Toast.fire({
                                icon: 'error',
                                title: error.responseJSON.messages.error,
                            });
                        })
                    }
                })
    })
</script>
<?= $this->endSection() ?>

ahora creamos el archivo app/modulosBranchoffices/modalCaptureBranchoffice.php con el siguiente código

<?= $this->include('load/toggle') ?>
<?= $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('modulesBranchoffices/modalCaptureBranchoffices') ?>
<?= $this->include('modulesBranchoffices/usuariosSucursalModal') ?>

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

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

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

                </button>

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

                                <th>#</th>
                                <th><?= lang('branchoffices.fields.key') ?></th>
                                <th><?= lang('branchoffices.fields.name') ?></th>
                                <th><?= lang('branchoffices.fields.cologne') ?></th>
                                <th><?= lang('branchoffices.fields.city') ?></th>
                                <th><?= lang('branchoffices.fields.postalCode') ?></th>
                                <th><?= lang('branchoffices.fields.timeDifference') ?></th>
                                <th><?= lang('branchoffices.fields.tax') ?></th>
                                <th><?= lang('branchoffices.fields.dateAp') ?></th>
                                <th><?= lang('branchoffices.fields.phone') ?></th>
                                <th><?= lang('branchoffices.fields.fax') ?></th>
                                <th><?= lang('branchoffices.fields.companie') ?></th>
                                <th><?= lang('branchoffices.fields.created_at') ?></th>
                                <th><?= lang('branchoffices.fields.deleted_at') ?></th>
                                <th><?= lang('branchoffices.fields.updated_at') ?></th>

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

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

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


<?= $this->section('js') ?>
<script>
    /**
     * Cargamos la tabla
     */

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

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

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

            {
                'data': 'key'
            },

            {
                'data': 'name'
            },

            {
                'data': 'cologne'
            },

            {
                'data': 'city'
            },

            {
                'data': 'postalCode'
            },

            {
                'data': 'timeDifference'
            },

            {
                'data': 'tax'
            },

            {
                'data': 'dateAp'
            },

            {
                'data': 'phone'
            },

            {
                'data': 'fax'
            },

            {
                'data': 'companie'
            },

            {
                'data': 'created_at'
            },

            {
                'data': 'deleted_at'
            },

            {
                'data': 'updated_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 btnEditBranchoffices" data-toggle="modal" idBranchoffices="${data.id}" data-target="#modalAddBranchoffices">  <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>
                             <button class="btn btn-success btn-users" data-id="${data.id}" data-toggle="modal" data-target="#modalUsuariosSucursal"><i class="fas fa-users"></i></button>
                         </div>
                         </td>`
                }
            }
        ]
    });



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


        var idBranchoffices = $("#idBranchoffices").val();
        var key = $("#key").val();
        var name = $("#name").val();
        var cologne = $("#cologne").val();
        var city = $("#city").val();
        var postalCode = $("#postalCode").val();
        var timeDifference = $("#timeDifference").val();
        var tax = $("#tax").val();
        var dateAp = $("#dateAp").val();
        var phone = $("#phone").val();
        var fax = $("#fax").val();
        var companie = $("#companie").val();

        if ($("#arqueoCaja").is(':checked')) {

            var arqueoCaja = "on";

        } else {

            var arqueoCaja = "off";

        }


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

        var datos = new FormData();
        datos.append("idBranchoffices", idBranchoffices);
        datos.append("key", key);
        datos.append("name", name);
        datos.append("cologne", cologne);
        datos.append("city", city);
        datos.append("postalCode", postalCode);
        datos.append("timeDifference", timeDifference);
        datos.append("tax", tax);
        datos.append("dateAp", dateAp);
        datos.append("phone", phone);
        datos.append("fax", fax);
        datos.append("companie", companie);
        datos.append("arqueoCaja", arqueoCaja);


        $.ajax({

            url: "<?= base_url('admin/branchoffices/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"
                    });

                    tableBranchoffices.ajax.reload();
                    $("#btnSaveBranchoffices").removeAttr("disabled");


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

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

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


                }

            }

        }

        )

    });



    /**
     * Carga datos actualizar
     */


    /*=============================================
     EDITAR Branchoffices
     =============================================*/
    $(".tableBranchoffices").on("click", ".btnEditBranchoffices", function () {

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

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

        $.ajax({

            url: "<?= base_url('admin/branchoffices/getBranchoffices') ?>",
            method: "POST",
            data: datos,
            cache: false,
            contentType: false,
            processData: false,
            dataType: "json",
            success: function (respuesta) {


                console.log(respuesta["dateAp"]);
                $("#idBranchoffices").val(respuesta["id"]);

                $("#key").val(respuesta["key"]);
                $("#name").val(respuesta["name"]);
                $("#cologne").val(respuesta["cologne"]);
                $("#city").val(respuesta["city"]);
                $("#postalCode").val(respuesta["postalCode"]);
                $("#timeDifference").val(respuesta["timeDifference"]);
                $("#tax").val(respuesta["tax"]);
                $("#dateAp").val(respuesta["dateAp"]);
                $("#phone").val(respuesta["phone"]);
                $("#fax").val(respuesta["fax"]);
                $("#companie").val(respuesta["companie"]);
                $("#companie").trigger("change");

                var arqueoCaja = respuesta["arqueoCaja"];

                if (arqueoCaja == "null" || arqueoCaja == "NULL") {

                    arqueoCaja = respuesta["arqueoCaja"];
                }

                $("#arqueoCaja").bootstrapToggle(arqueoCaja);


            }

        })

    })


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

        var idBranchoffices = $(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/branchoffices') ?>/` + idBranchoffices,
                            method: 'DELETE',
                        }).done((data, textStatus, jqXHR) => {
                            Toast.fire({
                                icon: 'success',
                                title: jqXHR.statusText,
                            });


                            tableBranchoffices.ajax.reload();
                        }).fail((error) => {
                            Toast.fire({
                                icon: 'error',
                                title: error.responseJSON.messages.error,
                            });
                        })
                    }
                })
    })
</script>
<?= $this->endSection() ?>

Ahora sigue el código del modal para capturar/editar los datos de la sucursal

<?= $this->include('load/toggle') ?>
<?= $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('modulesBranchoffices/modalCaptureBranchoffices') ?>
<?= $this->include('modulesBranchoffices/usuariosSucursalModal') ?>

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

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

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

                </button>

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

                                <th>#</th>
                                <th><?= lang('branchoffices.fields.key') ?></th>
                                <th><?= lang('branchoffices.fields.name') ?></th>
                                <th><?= lang('branchoffices.fields.cologne') ?></th>
                                <th><?= lang('branchoffices.fields.city') ?></th>
                                <th><?= lang('branchoffices.fields.postalCode') ?></th>
                                <th><?= lang('branchoffices.fields.timeDifference') ?></th>
                                <th><?= lang('branchoffices.fields.tax') ?></th>
                                <th><?= lang('branchoffices.fields.dateAp') ?></th>
                                <th><?= lang('branchoffices.fields.phone') ?></th>
                                <th><?= lang('branchoffices.fields.fax') ?></th>
                                <th><?= lang('branchoffices.fields.companie') ?></th>
                                <th><?= lang('branchoffices.fields.created_at') ?></th>
                                <th><?= lang('branchoffices.fields.deleted_at') ?></th>
                                <th><?= lang('branchoffices.fields.updated_at') ?></th>

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

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

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


<?= $this->section('js') ?>
<script>
    /**
     * Cargamos la tabla
     */

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

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

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

            {
                'data': 'key'
            },

            {
                'data': 'name'
            },

            {
                'data': 'cologne'
            },

            {
                'data': 'city'
            },

            {
                'data': 'postalCode'
            },

            {
                'data': 'timeDifference'
            },

            {
                'data': 'tax'
            },

            {
                'data': 'dateAp'
            },

            {
                'data': 'phone'
            },

            {
                'data': 'fax'
            },

            {
                'data': 'companie'
            },

            {
                'data': 'created_at'
            },

            {
                'data': 'deleted_at'
            },

            {
                'data': 'updated_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 btnEditBranchoffices" data-toggle="modal" idBranchoffices="${data.id}" data-target="#modalAddBranchoffices">  <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>
                             <button class="btn btn-success btn-users" data-id="${data.id}" data-toggle="modal" data-target="#modalUsuariosSucursal"><i class="fas fa-users"></i></button>
                         </div>
                         </td>`
                }
            }
        ]
    });



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


        var idBranchoffices = $("#idBranchoffices").val();
        var key = $("#key").val();
        var name = $("#name").val();
        var cologne = $("#cologne").val();
        var city = $("#city").val();
        var postalCode = $("#postalCode").val();
        var timeDifference = $("#timeDifference").val();
        var tax = $("#tax").val();
        var dateAp = $("#dateAp").val();
        var phone = $("#phone").val();
        var fax = $("#fax").val();
        var companie = $("#companie").val();

        if ($("#arqueoCaja").is(':checked')) {

            var arqueoCaja = "on";

        } else {

            var arqueoCaja = "off";

        }


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

        var datos = new FormData();
        datos.append("idBranchoffices", idBranchoffices);
        datos.append("key", key);
        datos.append("name", name);
        datos.append("cologne", cologne);
        datos.append("city", city);
        datos.append("postalCode", postalCode);
        datos.append("timeDifference", timeDifference);
        datos.append("tax", tax);
        datos.append("dateAp", dateAp);
        datos.append("phone", phone);
        datos.append("fax", fax);
        datos.append("companie", companie);
        datos.append("arqueoCaja", arqueoCaja);


        $.ajax({

            url: "<?= base_url('admin/branchoffices/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"
                    });

                    tableBranchoffices.ajax.reload();
                    $("#btnSaveBranchoffices").removeAttr("disabled");


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

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

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


                }

            }

        }

        )

    });



    /**
     * Carga datos actualizar
     */


    /*=============================================
     EDITAR Branchoffices
     =============================================*/
    $(".tableBranchoffices").on("click", ".btnEditBranchoffices", function () {

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

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

        $.ajax({

            url: "<?= base_url('admin/branchoffices/getBranchoffices') ?>",
            method: "POST",
            data: datos,
            cache: false,
            contentType: false,
            processData: false,
            dataType: "json",
            success: function (respuesta) {


                console.log(respuesta["dateAp"]);
                $("#idBranchoffices").val(respuesta["id"]);

                $("#key").val(respuesta["key"]);
                $("#name").val(respuesta["name"]);
                $("#cologne").val(respuesta["cologne"]);
                $("#city").val(respuesta["city"]);
                $("#postalCode").val(respuesta["postalCode"]);
                $("#timeDifference").val(respuesta["timeDifference"]);
                $("#tax").val(respuesta["tax"]);
                $("#dateAp").val(respuesta["dateAp"]);
                $("#phone").val(respuesta["phone"]);
                $("#fax").val(respuesta["fax"]);
                $("#companie").val(respuesta["companie"]);
                $("#companie").trigger("change");

                var arqueoCaja = respuesta["arqueoCaja"];

                if (arqueoCaja == "null" || arqueoCaja == "NULL") {

                    arqueoCaja = respuesta["arqueoCaja"];
                }

                $("#arqueoCaja").bootstrapToggle(arqueoCaja);


            }

        })

    })


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

        var idBranchoffices = $(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/branchoffices') ?>/` + idBranchoffices,
                            method: 'DELETE',
                        }).done((data, textStatus, jqXHR) => {
                            Toast.fire({
                                icon: 'success',
                                title: jqXHR.statusText,
                            });


                            tableBranchoffices.ajax.reload();
                        }).fail((error) => {
                            Toast.fire({
                                icon: 'error',
                                title: error.responseJSON.messages.error,
                            });
                        })
                    }
                })
    })
</script>
<?= $this->endSection() ?>

Bien ahora en app/config/routes.php agregamos las siguientes rutas dentro del grupo admin

    
    $routes->resource('branchoffices', [
        'filter' => 'permission:branchoffices-permission',
        'controller' => 'branchofficesController',
        'except' => 'show'
    ]);

    $routes->post('branchoffices/save', 'BranchofficesController::save');
    $routes->post('branchoffices/getBranchoffices', 'BranchofficesController::getBranchoffices');

$routes->get('sucursales/usuariosPorSucursal/(:any)', 'BranchofficesController::usuariosPorSucursal/$1');
    $routes->post('sucursales/activarDesactivar', 'BranchofficesController::activarDesactivar');
    $routes->post('sucursales/getSucursalesAjax', 'BranchofficesController::getSucursalesAjax');

Creamos el menú de sucursales con los siguientes datos

Y listo ya tenemos nuestro modulo hecho

Video demostrativo

Creando CRUD de clientes #06

Ya vimos como usar AutoCrud para crear los catálogos, en esta ocasión tambien usamos autocrud, aun así dejaremos el código fuente completo de este modulo

Creamos el archivo modelo al app/models/CustumersModel.php con el siguiente contenido

Leer Mas: Creando CRUD de clientes #06
<?php
namespace App\Models;
use CodeIgniter\Model;
class CustumersModel extends Model{
    protected $table      = 'custumers';
    protected $primaryKey = 'id';
    protected $useAutoIncrement = true;
    protected $returnType     = 'array';
    protected $useSoftDeletes = true;
    protected $allowedFields = ['id','firstname','lastname','taxID','email','direction','birthdate','created_at','updated_at','deleted_at'];
    protected $useTimestamps = true;
    protected $createdField  = 'created_at';
    protected $deletedField  = 'deleted_at';
    protected $validationRules    =  [
    ];
    protected $validationMessages = [];
    protected $skipValidation     = false;
}
        

Creamos nuestro archivo controlador app/controllers/CustumersControllers.php

<?php
 namespace App\Controllers;
 use App\Controllers\BaseController;
 use \App\Models\{CustumersModel};
 use App\Models\LogModel;
 use CodeIgniter\API\ResponseTrait;
 class CustumersController extends BaseController {
     use ResponseTrait;
     protected $log;
     protected $custumers;
     public function __construct() {
         $this->custumers = new CustumersModel();
         $this->log = new LogModel();
         helper('menu');
         helper('utilerias');
     }
     public function index() {
         if ($this->request->isAJAX()) {
             $datos = $this->custumers->select('id,firstname,lastname,taxID,email,direction,birthdate,created_at,updated_at,deleted_at')->where('deleted_at', null);
             return \Hermawan\DataTables\DataTable::of($datos)->toJson(true);
         }


         $fechaActual =  fechaMySQLADateTimeHTML5(fechaHoraActual());

         $titulos["title"] = lang('custumers.title');
         $titulos["subtitle"] = lang('custumers.subtitle');
         $titulos["fecha"] = $fechaActual;
         return view('custumers', $titulos);
     }
     /**
      * Read Custumers
      */
     public function getCustumers() {
         $idCustumers = $this->request->getPost("idCustumers");
         $datosCustumers = $this->custumers->find($idCustumers);
         echo json_encode($datosCustumers);
     }
     /**
      * Save or update Custumers
      */
     public function save() {
         helper('auth');
         $userName = user()->username;
         $idUser = user()->id;
         $datos = $this->request->getPost();
         if ($datos["idCustumers"] == 0) {
             try {
                 if ($this->custumers->save($datos) === false) {
                     $errores = $this->custumers->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->custumers->update($datos["idCustumers"], $datos) == false) {
                 $errores = $this->custumers->errors();
                 foreach ($errores as $field => $error) {
                     echo $error . " ";
                 }
                 return;
             } else {
                 $dateLog["description"] = lang("custumers.logUpdated") . json_encode($datos);
                 $dateLog["user"] = $userName;
                 $this->log->save($dateLog);
                 echo "Actualizado Correctamente";
                 return;
             }
         }
         return;
     }
     /**
      * Delete Custumers
      * @param type $id
      * @return type
      */
     public function delete($id) {
         $infoCustumers = $this->custumers->find($id);
         helper('auth');
         $userName = user()->username;
         if (!$found = $this->custumers->delete($id)) {
             return $this->failNotFound(lang('custumers.msg.msg_get_fail'));
         }
         $this->custumers->purgeDeleted();
         $logData["description"] = lang("custumers.logDeleted") . json_encode($infoCustumers);
         $logData["user"] = $userName;
         $this->log->save($logData);
         return $this->respondDeleted($found, lang('custumers.msg_delete'));
     }
 }
        

Creamos nuestro archivo de la visa en app/views/custumers.php con el siguiente contenido

<?= $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('modulesCustumers/modalCaptureCustumers') ?>

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

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

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

             </button>

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

                             <th>#</th>
                             <th><?= lang('custumers.fields.firstname') ?></th>
<th><?= lang('custumers.fields.lastname') ?></th>
<th><?= lang('custumers.fields.taxID') ?></th>
<th><?= lang('custumers.fields.email') ?></th>
<th><?= lang('custumers.fields.direction') ?></th>
<th><?= lang('custumers.fields.birthdate') ?></th>
<th><?= lang('custumers.fields.created_at') ?></th>
<th><?= lang('custumers.fields.updated_at') ?></th>
<th><?= lang('custumers.fields.deleted_at') ?></th>

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

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

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


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

 /**
  * Cargamos la tabla
  */

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

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

         }],
     columns: [{
             'data': 'id'
         },
        
          
{
    'data': 'firstname'
},
 
{
    'data': 'lastname'
},
 
{
    'data': 'taxID'
},
 
{
    'data': 'email'
},
 
{
    'data': 'direction'
},
 
{
    'data': 'birthdate'
},
 
{
    'data': 'created_at'
},
 
{
    'data': 'updated_at'
},
 
{
    'data': 'deleted_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 btnEditCustumers" data-toggle="modal" idCustumers="${data.id}" data-target="#modalAddCustumers">  <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', '#btnSaveCustumers', function (e) {

     
var idCustumers = $("#idCustumers").val();
var firstname = $("#firstname").val();
var lastname = $("#lastname").val();
var taxID = $("#taxID").val();
var email = $("#email").val();
var direction = $("#direction").val();
var birthdate = $("#birthdate").val();

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

     var datos = new FormData();
    datos.append("idCustumers", idCustumers);
    datos.append("firstname", firstname);
    datos.append("lastname", lastname);
    datos.append("taxID", taxID);
    datos.append("email", email);
    datos.append("direction", direction);
    datos.append("birthdate", birthdate);


     $.ajax({

         url: "<?= route_to('admin/custumers/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"
                 });

                 tableCustumers.ajax.reload();
                 $("#btnSaveCustumers").removeAttr("disabled");


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

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

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

             }

         }

     }

     )

 });



 /**
  * Carga datos actualizar
  */


 /*=============================================
  EDITAR Custumers
  =============================================*/
 $(".tableCustumers").on("click", ".btnEditCustumers", function () {

     var idCustumers = $(this).attr("idCustumers");
        
     var datos = new FormData();
     datos.append("idCustumers", idCustumers);

     $.ajax({

         url: "<?= base_url(route_to('admin/custumers/getCustumers')) ?>",
         method: "POST",
         data: datos,
         cache: false,
         contentType: false,
         processData: false,
         dataType: "json",
         success: function (respuesta) {
             $("#idCustumers").val(respuesta["id"]);
             
             $("#firstname").val(respuesta["firstname"]);
$("#lastname").val(respuesta["lastname"]);
$("#taxID").val(respuesta["taxID"]);
$("#email").val(respuesta["email"]);
$("#direction").val(respuesta["direction"]);
$("#birthdate").val(respuesta["birthdate"]);


         }

     })

 })


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

     var idCustumers = $(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(route_to('admin/custumers')) ?>/` + idCustumers,
                         method: 'DELETE',
                     }).done((data, textStatus, jqXHR) => {
                         Toast.fire({
                             icon: 'success',
                             title: jqXHR.statusText,
                         });


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

 $(function () {
    $("#modalAddCustumers").draggable();
    
});


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

Para el modal creamos el siguiente archivo app/views/modulesCustumers/modalCaptureCustumers.php con el siguiente contenido

<!-- Modal Custumers -->
  <div class="modal fade" id="modalAddCustumers" tabindex="-1" role="dialog" aria-labelledby="modalAddCustumers" aria-hidden="true">
      <div class="modal-dialog modal-lg" role="document">
          <div class="modal-content">
              <div class="modal-header">
                  <h5 class="modal-title"><?= lang('custumers.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-custumers" class="form-horizontal">
                      <input type="hidden" id="idCustumers" name="idCustumers" value="0">

                      <div class="form-group row">
    <label for="firstname" class="col-sm-2 col-form-label"><?= lang('custumers.fields.firstname') ?></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="firstname" id="firstname" class="form-control <?= session('error.firstname') ? 'is-invalid' : '' ?>" value="<?= old('firstname') ?>" placeholder="<?= lang('custumers.fields.firstname') ?>" autocomplete="off">
        </div>
    </div>
</div>
<div class="form-group row">
    <label for="lastname" class="col-sm-2 col-form-label"><?= lang('custumers.fields.lastname') ?></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="lastname" id="lastname" class="form-control <?= session('error.lastname') ? 'is-invalid' : '' ?>" value="<?= old('lastname') ?>" placeholder="<?= lang('custumers.fields.lastname') ?>" autocomplete="off">
        </div>
    </div>
</div>
<div class="form-group row">
    <label for="taxID" class="col-sm-2 col-form-label"><?= lang('custumers.fields.taxID') ?></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="taxID" id="taxID" class="form-control <?= session('error.taxID') ? 'is-invalid' : '' ?>" value="<?= old('taxID') ?>" placeholder="<?= lang('custumers.fields.taxID') ?>" autocomplete="off">
        </div>
    </div>
</div>
<div class="form-group row">
    <label for="email" class="col-sm-2 col-form-label"><?= lang('custumers.fields.email') ?></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="email" id="email" class="form-control <?= session('error.email') ? 'is-invalid' : '' ?>" value="<?= old('email') ?>" placeholder="<?= lang('custumers.fields.email') ?>" autocomplete="off">
        </div>
    </div>
</div>
<div class="form-group row">
    <label for="direction" class="col-sm-2 col-form-label"><?= lang('custumers.fields.direction') ?></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="direction" id="direction" class="form-control <?= session('error.direction') ? 'is-invalid' : '' ?>" value="<?= old('direction') ?>" placeholder="<?= lang('custumers.fields.direction') ?>" autocomplete="off">
        </div>
    </div>
</div>
<div class="form-group row">
    <label for="birthdate" class="col-sm-2 col-form-label"><?= lang('custumers.fields.birthdate') ?></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="datetime-local" name="birthdate" id="birthdate" class="form-control <?= session('error.birthdate') ? 'is-invalid' : '' ?>" value="<?= $fecha ?>" placeholder="<?= lang('custumers.fields.birthdate') ?>" 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="btnSaveCustumers"><?= lang('boilerplate.global.save') ?></button>
              </div>
          </div>
      </div>
  </div>

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


  <script>

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


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

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

          $("#birthdate").val("<?= $fecha ?>");

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

      });

      /* 
       * AL hacer click al editar
       */



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


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

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

          $("#idCustumers").val(idCustumers);
          $("#btnGuardarCustumers").removeAttr("disabled");

      });




  </script>


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

Para la traducción en ingles creamos el archivo app/languaje/es/custumers.php con el siguiente contenido

 <?php

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

$custumers["add"] = "Add Custumers";
$custumers["edit"] = "Edit custumers";
$custumers["createEdit"] = "Create / Edit";
$custumers["title"] = "custumers management";
$custumers["subtitle"] = "custumers list";
$custumers["fields"]["firstname"] = "Firstname";
$custumers["fields"]["lastname"] = "Lastname";
$custumers["fields"]["taxID"] = "TaxID";
$custumers["fields"]["email"] = "Email";
$custumers["fields"]["direction"] = "Direction";
$custumers["fields"]["birthdate"] = "Birthdate";
$custumers["fields"]["created_at"] = "Created_at";
$custumers["fields"]["updated_at"] = "Updated_at";
$custumers["fields"]["deleted_at"] = "Deleted_at";

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

return $custumers;
        

Para nuestra traduccion en español creamos el archivo app/languaje/es/custumers.php

 <?php
$custumers["logDescription"] = "El registro en clientes fue guardado con los siguientes datos:";
$custumers["logUpdate"] = "El registro en clientes fue actualizado con los siguientes datos:";
$custumers["logDeleted"] = "El registro en clientes fue eliminado con los siguientes datos:";
$custumers["msg_delete"] = "El Registro en clientes fue eliminado correctamente:";
$custumers["add"] = "Agregar Cliente";
$custumers["edit"] = "Editar Cliente";
$custumers["createEdit"] = "Crear / Editar";
$custumers["title"] = "Admon. Clientes";
$custumers["subtitle"] = "Lista de Clientes";
$custumers["fields"]["firstname"] = "Nombre";
$custumers["fields"]["lastname"] = "Apellido";
$custumers["fields"]["taxID"] = "RFC";
$custumers["fields"]["email"] = "Correo Electronico";
$custumers["fields"]["direction"] = "Direccion";
$custumers["fields"]["birthdate"] = "Fecha de nacimiento";
$custumers["fields"]["created_at"] = "Fecha de creacion";
$custumers["fields"]["updated_at"] = "Ultima modificacion";
$custumers["fields"]["deleted_at"] = "Fecha de eliminacion";

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

Creamos nuestro archivo de migración en app/databases/migrations/2023-04-21063335_Custumers.php con el siguiente contenido

<?php
    namespace App\Database\Migrations;
    use CodeIgniter\Database\Migration;
    class Custumers extends Migration
    {
    public function up()
    {
     // Custumers
    $this->forge->addField([
        'id'                    => ['type' => 'int', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
        'firstname'             => ['type' => 'varchar', 'constraint' => 128, 'null' => true],
        'lastname'             => ['type' => 'varchar', 'constraint' => 128, 'null' => true],
        'taxID'             => ['type' => 'varchar', 'constraint' => 64, 'null' => true],
        'email'             => ['type' => 'varchar', 'constraint' => 128, 'null' => true],
        'direction'             => ['type' => 'varchar', 'constraint' => 1024, 'null' => true],
        'birthdate'             => ['type' => 'datetime' , '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('custumers', true);
    }
    public function down(){
        $this->forge->dropTable('custumers', true);
        }
    }

Corremos el comando php serve migrate para levantar la tabla custumers

Listo ya solo queda configurar los permisos y menú

Demostración en video

Creando CRUD de categorías usando AutoCrud #05

Ya vimos como crear módulos y catalogo ahora mostraremos como automatizar esa parte del proceso de desarrollo para ser un poco mas eficientes para ello escribimos un código que escribe el código repetitivo

Creamos el archivo app/controller/AutoCrudController.php con el siguiente código

Leer Mas: Creando CRUD de categorías usando AutoCrud #05
<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use App\Controllers\Time;
use CodeIgniter\API\ResponseTrait;
use Faker\Provider\zh_CN\DateTime;

class AutoCrudController extends BaseController {

    use ResponseTrait;

    protected $db;

    public function __construct() {
        $this->db = \Config\Database::connect();
        helper('utilerias');
    }

    public function index($table) {
     /*
       $this->generateModel($table);
       $this->generateController($table);
       $this->generateView($table);
       $this->generateViewModal($table);
       $this->generateLanguage($table);
        */
        $this->generateMigration($table);
       
     //$this->generateLanguageES($table);

        $tableUpCase = ucfirst($table);
        $route = <<<EOF
                 \$routes->resource('$table', [
                                'filter' => 'permission:$table-permission',
                                'controller' => '{$table}Controller',
                                'except' => 'show'
                            ]);
                \$routes->post('$table/save', '{$tableUpCase}Controller::save');
                \$routes->post('{$table}/get{$tableUpCase}', '{$tableUpCase}Controller::get$tableUpCase');
        EOF;

        echo $route;
    }

    /**
     * Generate Model
     */
    public function generateModel($table) {

        $tableUpCase = ucfirst($table);
        $query = $this->db->getFieldNames($table);

        $fields = "";

        foreach ($query as $field) {
            $fields .= "'" . $field . "'" . ",";
        }


        $fields = substr($fields, 0, strlen($fields) - 1);

        $nombreClase = ucfirst($table) . "Model";

        $model = <<<EOF
        <?php
        namespace App\Models;
        use CodeIgniter\Model;
        class $nombreClase extends Model{
            protected \$table      = '$table';
            protected \$primaryKey = 'id';
            protected \$useAutoIncrement = true;
            protected \$returnType     = 'array';
            protected \$useSoftDeletes = true;
            protected \$allowedFields = [$fields];
            protected \$useTimestamps = true;
            protected \$createdField  = 'created_at';
            protected \$deletedField  = 'deleted_at';
            protected \$validationRules    =  [
            ];
            protected \$validationMessages = [];
            protected \$skipValidation     = false;
        }
                
        EOF;

        file_put_contents(ROOTPATH . "app/Models/$nombreClase.php", $model);
    }

    /**
     * Generate Controller
     * 
     */

    /**
     * Generate Controller
     */
    public function generateController($table) {

        $query = $this->db->getFieldNames($table);

        $fields = "";

        foreach ($query as $field) {
            $fields .= $field . ",";
        }


        $fields = substr($fields, 0, strlen($fields) - 1);

        $nameClassModel = ucfirst($table) . "Model";

        $tableUpCase = ucfirst($table);

        $controller = <<<EOF
        <?php
         namespace App\Controllers;
         use App\Controllers\BaseController;
         use \App\Models\{$nameClassModel};
         use App\Models\LogModel;
         use CodeIgniter\API\ResponseTrait;
         class {$tableUpCase}Controller extends BaseController {
             use ResponseTrait;
             protected \$log;
             protected $$table;
             public function __construct() {
                 \$this->$table = new $nameClassModel();
                 \$this->log = new LogModel();
                 helper('menu');
             }
             public function index() {
                 if (\$this->request->isAJAX()) {
                     \$datos = \$this->{$table}->select('$fields')->where('deleted_at', null);
                     return \Hermawan\DataTables\DataTable::of(\$datos)->toJson(true);
                 }
                 \$titulos["title"] = lang('$table.title');
                 \$titulos["subtitle"] = lang('$table.subtitle');
                 return view('$table', \$titulos);
             }
             /**
              * Read $tableUpCase
              */
             public function get$tableUpCase() {
                 \$id$tableUpCase = \$this->request->getPost("id$tableUpCase");
                 \$datos$tableUpCase = \$this->{$table}->find(\$id$tableUpCase);
                 echo json_encode(\$datos$tableUpCase);
             }
             /**
              * Save or update $tableUpCase
              */
             public function save() {
                 helper('auth');
                 \$userName = user()->username;
                 \$idUser = user()->id;
                 \$datos = \$this->request->getPost();
                 if (\$datos["id$tableUpCase"] == 0) {
                     try {
                         if (\$this->{$table}->save(\$datos) === false) {
                             \$errores = \$this->{$table}->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->{$table}->update(\$datos["id$tableUpCase"], \$datos) == false) {
                         \$errores = \$this->{$table}->errors();
                         foreach (\$errores as \$field => \$error) {
                             echo \$error . " ";
                         }
                         return;
                     } else {
                         \$dateLog["description"] = lang("$table.logUpdated") . json_encode(\$datos);
                         \$dateLog["user"] = \$userName;
                         \$this->log->save(\$dateLog);
                         echo "Actualizado Correctamente";
                         return;
                     }
                 }
                 return;
             }
             /**
              * Delete $tableUpCase
              * @param type \$id
              * @return type
              */
             public function delete(\$id) {
                 \$info$tableUpCase = \$this->{$table}->find(\$id);
                 helper('auth');
                 \$userName = user()->username;
                 if (!\$found = \$this->{$table}->delete(\$id)) {
                     return \$this->failNotFound(lang('$table.msg.msg_get_fail'));
                 }
                 \$this->{$table}->purgeDeleted();
                 \$logData["description"] = lang("{$table}.logDeleted") . json_encode(\$info$tableUpCase);
                 \$logData["user"] = \$userName;
                 \$this->log->save(\$logData);
                 return \$this->respondDeleted(\$found, lang('$table.msg_delete'));
             }
         }
                
        EOF;

        file_put_contents(ROOTPATH . "app/Controllers/{$tableUpCase}Controller.php", $controller);
    }

    /**
     * Generate View
     */
    public function generateView($table) {

        $tableUpCase = ucfirst($table);
        $query = $this->db->getFieldNames($table);

        $fields = "";

        $columnaDatatable = "";
        $datosDatatable = "";
        $variablesGuardar1 = "";
        $variablesFormData = "";
        $inputsEdit = "";
        $contador = 0;
        foreach ($query as $field) {
            $fields .= $field . ",";

            if ($contador > 0) {

                $columnaDatatable .= "<th><?= lang('$table.fields.$field') ?></th>" . PHP_EOL;

                $datosDatatable .= <<<EOF
                         
                        {
                            'data': '$field'
                        },
                        EOF . PHP_EOL;
                if ($field <> "created_at" && $field <> "updated_at" && $field <> "deleted_at") {
                    $variablesGuardar1 .= "var $field = $(\"#$field\").val();" . PHP_EOL;
                    $variablesFormData .= "datos.append(\"$field\", $field);" . PHP_EOL;
                    $inputsEdit .= "$(\"#$field\").val(respuesta[\"$field\"]);" . PHP_EOL;
                    ;
                }
            } else {
                $variablesGuardar1 .= <<<EOF
                    
                    var id$tableUpCase = $("#id$tableUpCase").val();
                    EOF . PHP_EOL;

                $variablesFormData .= <<<EOF
                        var datos = new FormData();
                        datos.append("id$tableUpCase", id$tableUpCase);
                        EOF . PHP_EOL;
            }
            $contador++;
        }
        $fields = substr($fields, 0, strlen($fields) - 1);
        $nameClassModel = ucfirst($table) . "Model";
        $view = <<<EOF
        <?= \$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('modules$tableUpCase/modalCapture$tableUpCase') ?>

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

                     <button class="btn btn-primary btnAdd$tableUpCase" data-toggle="modal" data-target="#modalAdd$tableUpCase"><i class="fa fa-plus"></i>

                         <?= lang('$table.add') ?>

                     </button>

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

                                     <th>#</th>
                                     $columnaDatatable
                                     <th><?= lang('$table.fields.actions') ?> </th>

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

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


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

         /**
          * Cargamos la tabla
          */

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

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

                 }],
             columns: [{
                     'data': 'id'
                 },
                
                 $datosDatatable
                 {
                     "data": function (data) {
                         return `<td class="text-right py-0 align-middle">
                                 <div class="btn-group btn-group-sm">
                                     <button class="btn btn-warning btnEdit$tableUpCase" data-toggle="modal" id$tableUpCase="\${data.id}" data-target="#modalAdd$tableUpCase">  <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', '#btnSave$tableUpCase', function (e) {

             $variablesGuardar1
             $("#btnSave$tableUpCase").attr("disabled", true);

             $variablesFormData

             $.ajax({

                 url: "<?= route_to('admin/$table/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"
                         });

                         table$tableUpCase.ajax.reload();
                         $("#btnSave$tableUpCase").removeAttr("disabled");


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

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

                         $("#btnSave$tableUpCase").removeAttr("disabled");
                        

                     }

                 }

             }

             )

         });



         /**
          * Carga datos actualizar
          */


         /*=============================================
          EDITAR $tableUpCase
          =============================================*/
         $(".table$tableUpCase").on("click", ".btnEdit$tableUpCase", function () {

             var id$tableUpCase = $(this).attr("id$tableUpCase");
                
             var datos = new FormData();
             datos.append("id$tableUpCase", id$tableUpCase);

             $.ajax({

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

                 }

             })

         })


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

             var id$tableUpCase = $(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(route_to('admin/$table')) ?>/` + id$tableUpCase,
                                 method: 'DELETE',
                             }).done((data, textStatus, jqXHR) => {
                                 Toast.fire({
                                     icon: 'success',
                                     title: jqXHR.statusText,
                                 });


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

         $(function () {
            $("#modalAdd$tableUpCase").draggable();
            
        });


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

        file_put_contents(ROOTPATH . "app/Views/{$table}.php", $view);
    }

    /**
     * Generate ViewModal
     */
    public function generateViewModal($table) {

        $tableUpCase = ucfirst($table);
        $query = $this->db->getFieldNames($table);

        $fields = "";

        $campos = "";
        $contador = 0;
        foreach ($query as $field) {
            $fields .= $field . ",";

            if ($contador > 0) {




                if ($field <> "created_at" && $field <> "updated_at" && $field <> "deleted_at") {

                    $campos .= <<<EOF
                        <div class="form-group row">
                            <label for="$field" class="col-sm-2 col-form-label"><?= lang('$table.fields.$field') ?></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="$field" id="$field" class="form-control <?= session('error.$field') ? 'is-invalid' : '' ?>" value="<?= old('$field') ?>" placeholder="<?= lang('$table.fields.$field') ?>" autocomplete="off">
                                </div>
                            </div>
                        </div>
                        EOF . PHP_EOL;
                }
            }




            $contador++;
        }


        $fields = substr($fields, 0, strlen($fields) - 1);

        $nameClassModel = ucfirst($table) . "Model";

        $viewModal = <<<EOF
        <!-- Modal $tableUpCase -->
          <div class="modal fade" id="modalAdd$tableUpCase" tabindex="-1" role="dialog" aria-labelledby="modalAdd$tableUpCase" aria-hidden="true">
              <div class="modal-dialog modal-lg" role="document">
                  <div class="modal-content">
                      <div class="modal-header">
                          <h5 class="modal-title"><?= lang('$table.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-$table" class="form-horizontal">
                              <input type="hidden" id="id$tableUpCase" name="id$tableUpCase" value="0">

                              $campos
                
                          </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="btnSave$tableUpCase"><?= lang('boilerplate.global.save') ?></button>
                      </div>
                  </div>
              </div>
          </div>

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


          <script>

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


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

                  $("#id$tableUpCase").val("0");

                  $("#btnSave$tableUpCase").removeAttr("disabled");

              });

              /* 
               * AL hacer click al editar
               */



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


                  var id$tableUpCase = $(this).attr("id$tableUpCase");

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

                  $("#id$tableUpCase").val(id$tableUpCase);
                  $("#btnGuardar$tableUpCase").removeAttr("disabled");

              });




          </script>


          <?= \$this->endSection() ?>
                
        EOF;

        $path = ROOTPATH . "app/Views/modules$tableUpCase/";
        if (!is_dir($path))
            mkdir($path, 0777, TRUE);

        file_put_contents($path . "modalCapture{$tableUpCase}.php", $viewModal);
    }

    /**
     * Generate Languaje EN
     */
    public function generateLanguage($table) {

        $tableUpCase = ucfirst($table);
        $query = $this->db->getFieldNames($table);

        $fields = "";

        $campos = "";
        $contador = 0;
        foreach ($query as $field) {
            $fields .= $field . ",";

            if ($contador > 0) {






                $campos .= "\${$table}[\"fields\"][\"$field\"] = \"" . ucfirst($field) . "\";" . PHP_EOL;
            }




            $contador++;
        }


        $fields = substr($fields, 0, strlen($fields) - 1);

        $nameClassModel = ucfirst($table) . "Model";

        $languaje = <<<EOF
         <?php

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

        \${$table}["add"] = "Add $tableUpCase";
        \${$table}["edit"] = "Edit $table";
        \${$table}["createEdit"] = "Create / Edit";
        \${$table}["title"] = "$table management";
        \${$table}["subtitle"] = "$table list";
        $campos
        \${$table}["fields"]["actions"] = "Actions";
        \${$table}["msg"]["msg_insert"] = "The $table has been correctly added.";
        \${$table}["msg"]["msg_update"] = "The $table has been correctly modified.";
        \${$table}["msg"]["msg_delete"] = "The $table has been correctly deleted.";
        \${$table}["msg"]["msg_get"] = "The $tableUpCase has been successfully get.";
        \${$table}["msg"]["msg_get_fail"] = "The $table not found or already deleted.";

        return $$table;
                
        EOF;

        $path = ROOTPATH . "app/Language/en/";
        if (!is_dir($path))
            mkdir($path, 0777, TRUE);

        file_put_contents($path . "$table.php", $languaje);
    }

    /**
     * Lenguaje ES
     * @param type $table
     */
    public function generateLanguageES($table) {

        $tableUpCase = ucfirst($table);
        $query = $this->db->getFieldNames($table);

        $fields = "";

        $campos = "";
        $contador = 0;
        foreach ($query as $field) {
            $fields .= $field . ",";

            if ($contador > 0) {


                $campos .= "\${$table}[\"fields\"][\"$field\"] = \"" . ucfirst($field) . "\";" . PHP_EOL;
            }




            $contador++;
        }


        $fields = substr($fields, 0, strlen($fields) - 1);

        $nameClassModel = ucfirst($table) . "Model";

        $languaje = <<<EOF
         <?php
        \${$table}["logDescription"] = "El registro en $table fue guardado con los siguientes datos:";
        \${$table}["logUpdate"] = "El registro en $table fue actualizado con los siguientes datos:";
        \${$table}["logDeleted"] = "El registro en $table fue eliminado con los siguientes datos:";
        \${$table}["msg_delete"] = "El Registro en $table fue eliminado correctamente:";
        \${$table}["add"] = "Agregar $tableUpCase";
        \${$table}["edit"] = "Editar $table";
        \${$table}["createEdit"] = "Crear / Editar";
        \${$table}["title"] = "Admon. $table";
        \${$table}["subtitle"] = "Lista $table";
        $campos
         \${$table}["fields"]["actions"] = "Acciones";       
        \${$table}["msg"]["msg_insert"] = "Registro agregado correctamente.";
        \${$table}["msg"]["msg_update"] = "Registro modificado correctamente.";
        \${$table}["msg"]["msg_delete"] = "Registro eliminado correctamente.";
        \${$table}["msg"]["msg_get"] = "Registro obtenido correctamente.";
        \${$table}["msg"]["msg_get_fail"] = "Registro no encontrado o eliminado.";
        return $$table;
                
        EOF;

        $path = ROOTPATH . "app/Language/es/";
        if (!is_dir($path))
            mkdir($path, 0777, TRUE);

        file_put_contents($path . "$table.php", $languaje);
    }

    /**
     * Generate Migration
     * @param type $table
     */
    public function generateMigration($table) {

        $tableUpCase = ucfirst($table);
        $query = $this->db->getFieldData($table);

        $campos = "";
        $contador = 0;
        foreach ($query as $field) {


            
            if ($contador > 0) {

                
                if($field->nullable==1){
                    
                    $nullable="true";
                    
                }   else{
                    
                    $nullable="false";
                    
                } 
                if ($field->name <> "created_at" && $field->name <> "updated_at" && $field->name <> "deleted_at") {
                    $campos .= "'{$field->name}'             => ['type' => '{$field->type}', 'constraint' => {$field->max_length}, 'null' => $nullable]," . PHP_EOL;
                }
            } else {

                    $campos .= "'id'                    => ['type' => 'int', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true]," . PHP_EOL;
            }



            $contador++;
        }




        $nameClassModel = ucfirst($table) . "Model";

        $migration = <<<EOF
            <?php
            namespace App\Database\Migrations;
            use CodeIgniter\Database\Migration;
            class $tableUpCase extends Migration
            {
            public function up()
            {
             // $tableUpCase
            \$this->forge->addField([
                $campos
                '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('$table', true);
            }
            public function down(){
                \$this->forge->dropTable('$table', true);
                }
            }
        EOF;

        $path = ROOTPATH . "app/Database/Migrations/";
        if (!is_dir($path))
            mkdir($path, 0777, TRUE);

        $fechaActual = fechaParaMigraciones(fechaHoraActual());

        file_put_contents($path . "{$fechaActual}_{$tableUpCase}.php", $migration);

        //file_put_contents($path . "2023-02-07-165411_$tableUpCase.php", $viewModal);
    }
    
    

}

Creamos el archivo app/helpers/utilerias_helper.php con el siguiente codigo

<?php

function strMenuActivo($strMenu1, $strMenu2) {
    if ($strMenu1 == $strMenu2) {
        $respuesta = 'class="active"';
    } else {
        $respuesta = "";
    }
    return $respuesta;
}

//SI LA VARIABLE ESTA VACIA O NO SETA DECLARADA MANDARA CERO SIEMPRE, ES COMO EL VAL DE VISUAL BASIC 6.0

function esCero($value) {

    if (empty($value)) {
        return "0";
    } else {
        return $value;
    }
}

//FECHA SQL PARA GUARDAR EN BASE DE DATOS

function fechaSQL($fecha) {

    return date("Ymd", strtotime($fecha));
}

// CONVIERTE FECHA MYSQLDATETIME A HTML5
function fechaMySQLADateTimeHTML5($fecha) {

    return date("Y-m-d", strtotime($fecha)) . "T" . date("H:i:s", strtotime($fecha));
}

function agregarMinutos($fecha, $minutos) {


    return date("Y/m/d h:i:s", strtotime($fecha . "+ $minutos minutes"));

    /*
      $fecha1= new DateTime($fecha);
      $fecha1->add(new DateInterval('PT10H30S'));
      return $date->format('Y-m-d H:i:s') . "\n";
     * 
     */
}

//CONVIERTE LA FECHA EN PERIODO
function fechaPeriodo($fecha) {

    return date("Ym", strtotime($fecha));
}

//OBTIENE FECHA ACTUAL
function fechaActual() {

    return date("Y/m/d");
}

//OBTIENE FECHA HORA ACTUAL

function fechaHoraActual() {

    return date("Y-m-d H:i:s ", time());
}

//DIFERENCIA ENTRE MINUTOS
function diferenciaMinutos($fecha_i, $fecha_f) {
    $minutos = (strtotime($fecha_i) - strtotime($fecha_f)) / 60;

    $minutos = abs($minutos);
    $minutos = floor($minutos);

    return $minutos;
}

function strSellar($llave, $password, $cadenaOriginal) {


    $archivoPem = "/tmp/llave.key.pem";
    $comando = "openssl pkcs8 -inform DER -in $llave -passin pass:$password -out $archivoPem";

    exec($comando);
    $sello = "ok";

    //Sellar
    $archivo = openssl_pkey_get_private(file_get_contents($archivoPem));
    $sig = "";
    openssl_sign($cadenaOriginal, $sig, $archivo, OPENSSL_ALGO_SHA256);

    $sello = base64_encode($sig);

    return $sello;
}

//SOLO DIA
function dia($fecha) {

    return date("d", strtotime($fecha));
}

//SOLO MES
function mes($fecha) {

    return date("m", strtotime($fecha));
}

//SOLO AÑO
function año($fecha) {

    return date("Y", strtotime($fecha));
}

//GENERA UUID
function generaUUID() {


    $uuid = service('uuid');
    $uuid4 = $uuid->uuid4();
    $string = $uuid4->toString();

    return $string;
}

function satinizar($var, $type) {
    switch ($type) {
        case 'html':
            $safe = htmlspecialchars($var);
            break;
        case 'sql':
            $safe = mysql_real_escape_string($var);
            break;
        case 'file':
            $safe = preg_replace('/(\/|-|_)/', '', $var);
            break;
        case 'shell':
            $safe = escapeshellcmd($var);
            break;
        default:
            $safe = htmlspecialchars($var);
    }
    return $safe;
}

function limpiaCadena($cadena) {

    $cadena = str_replace('"', "", $cadena);
    $cadena = str_replace('\n', "", $cadena);
    $cadena = str_replace('\t', "", $cadena);
    $cadena = trim($cadena);

    $cadena = preg_replace("[\n|\r|\n\r]", "", $cadena);

    $descripcion = preg_replace("[\n|\r|\n\r]", "", $descripcion);

    return $cadena;
}


// CONVIERTE FECHA MYSQLDATETIME A HTML5
function fechaParaMigraciones($fecha) {

    return date("Y-m-d", strtotime($fecha)) . date("His", strtotime($fecha));
    
}

En rutas ponemos el siguiente codigo

$routes->get('generateCRUD/(:any)', 'AutoCrudController::index/$1');

Creamos la tabla de categorías

-- phpMyAdmin SQL Dump
-- version 5.0.4
-- https://www.phpmyadmin.net/
--
-- Servidor: 127.0.0.1
-- Tiempo de generación: 21-04-2023 a las 20:19:25
-- Versión del servidor: 10.4.17-MariaDB
-- Versión de PHP: 7.4.15

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Base de datos: `ci4jcpos`
--

-- --------------------------------------------------------

--
-- Estructura de tabla para la tabla `categorias`
--

CREATE TABLE `categorias` (
  `id` int(11) NOT NULL,
  `descripcion` varchar(128) COLLATE utf8mb4_spanish2_ci DEFAULT NULL,
  `deleted_at` datetime DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish2_ci;

--
-- Índices para tablas volcadas
--

--
-- Indices de la tabla `categorias`
--
ALTER TABLE `categorias`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT de las tablas volcadas
--

--
-- AUTO_INCREMENT de la tabla `categorias`
--
ALTER TABLE `categorias`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

Corremos la siguiente URL en el navegador para crear todo el catalogo

http://localhost:8080/admin/generateCRUD/categorias

Esto nos generara los archivos necesarios y ademas la ruta para agregarlo en routes.php


         $routes->resource('categorias', [
                        'filter' => 'permission:categorias-permission',
                        'controller' => 'categoriasController',
                        'except' => 'show'
                    ]);
        $routes->post('categorias/save', 'CategoriasController::save');
        $routes->post('categorias/getCategorias', 'CategoriasController::getCategorias');
Ya solo hacemos los cambios estéticos necesarios, agregamos los permisos necesarios corregimos la ruta en el menú y listo
Video Demostrativo

JCPOS Ultimate – Nuevo Repositorio #1

JCPOS: Una solución de punto de venta en constante evolución

En una reciente transmisión en vivo, el equipo de desarrollo detrás de JCPOS discutió los últimos cambios y mejoras en su solución de punto de venta. JCPOS es un sistema de punto de venta que ha estado en desarrollo desde el 2020, y ha evolucionado constantemente desde entonces para satisfacer las necesidades de sus usuarios.

Uno de los cambios más notables que el equipo ha realizado es el cambio de nombre de JC post a JCPOS. Esto se hizo para mantener la coherencia en el nombre a lo largo de los años, y evitar confusiones al cambiar el nombre cada año.

Otro de los cambios que se discutió en la transmisión fue la reciente publicación del repositorio de JCPOS en Github. Ahora está disponible para que cualquier persona interesada lo pueda descargar y explorar el código fuente. Además, se hizo hincapié en que los usuarios pueden contribuir al proyecto si encuentran algún problema o tienen alguna sugerencia.

El equipo también habló de algunos cambios específicos que han realizado en JCPOS, como la corrección de un problema en la bitácora que no estaba ordenando los botones de manera correcta. También se discutió la implementación de descuentos en las ventas, para asegurarse de que funcionen correctamente. Además, se está trabajando en la corrección de detalles menores, como la ordenación de la lista de ventas.

El equipo de JCPOS también habló sobre su intención de usar Composer para gestionar las dependencias del proyecto, lo que les permitirá mantenerse actualizados con las últimas versiones de las librerías que utilizan. También se mencionó la adición de impuestos a los productos, lo que permitirá la implementación de facturación electrónica en el futuro.

Finalmente, el equipo mencionó a sus patrocinadores y clientes, agradeciendo su apoyo y mencionando que los nombres de los patrocinadores se agregarán al repositorio en el futuro. También se proporcionó información sobre cómo patrocinar el proyecto.

En resumen, JCPOS es un proyecto de punto de venta en constante evolución. El equipo detrás de JCPOS está trabajando constantemente para mejorar la solución, escuchar las necesidades de los usuarios y mantenerse actualizado con las últimas tecnologías y herramientas de desarrollo. Si estás interesado en probar JCPOS o contribuir al proyecto, ¡asegúrate de visitar su repositorio en Github!

Como convertir Web hecha en PHP8 con FrameWork CodeIgniter 4 en una APP de Escritorio

code

git clone https://github.com/electron/electron-quick-start.git

en el archivo package.json lo dejamos de la siguiente manera

	{

	"build": {
	"appId": "com.electron.example",
	"compression": "maximum"
	},
	"name": "XML2PDF CFDI",

	"version": "2.0.0",

	"description": "Una pequeña aplicación para convertir el CFDI XML a PDF",

	"main": "main.js",

	"compression": "maximum",

	"scripts": {

	"***": null,
	"pro:windows": "electron-builder --win"

	},
	"repository": "https://github.com/electron/electron-quick-start",  

	"keywords": [
	"CFDI",
	"XML",
	"PDF",
	"tutorial"
	],
	"author": "Julio Cesar Leyva Rodriguez",
	"license": "CC0-1.0",
	"devDependencies": {
	"electron": "^21.2.3",
	"electron-builder": "^22.14.13",
	"electron-packager": "^17.1.1"
	},
	"dependencies": {
	"modclean": "^3.0.0-beta.1"
	}
	}

en main.js lo dejamos haci lo que hara es cargar la url y levantar el servicio de php

	// Modules to control application life and create native browser window

	const {app, BrowserWindow} = require('electron')

	const path = require('path')

	const exec = require('child_process').exec;

	  
	  

	function execute(command, callback) {

	exec(command, (error, stdout, stderr) => {

	callback(stdout);

	});

	};

	  
	  

	// call the function

	execute('Ejecutar.bat', (output) => {

	console.log(output);

	});

	  

	function createWindow () {

	// Create the browser window.

	const mainWindow = new BrowserWindow({

	width: 800,

	height: 600,

	webPreferences: {

	preload: path.join(__dirname, 'preload.js')

	}

	})

	  

	// and load the index.html of the app.

	mainWindow.setMenu(null)

	mainWindow.loadURL('http://localhost:8097')

	  

	// Open the DevTools.

	// mainWindow.webContents.openDevTools()

	}

	  

	// This method will be called when Electron has finished

	// initialization and is ready to create browser windows.

	// Some APIs can only be used after this event occurs.

	app.whenReady().then(() => {

	createWindow()

	  

	app.on('activate', function () {

	// On macOS it's common to re-create a window in the app when the

	// dock icon is clicked and there are no other windows open.

	if (BrowserWindow.getAllWindows().length === 0) createWindow()

	})

	})

	  

	// Quit when all windows are closed, except on macOS. There, it's common

	// for applications and their menu bar to stay active until the user quits

	// explicitly with Cmd + Q.

	app.on('window-all-closed', function () {

	if (process.platform !== 'darwin') app.quit()

	})

	  

	// In this file you can include the rest of your app's specific main process

	// code. You can also put them in separate files and require them here.

ahora posicionados en la carpeta \electron-quick-start> corremos el siguiente comando

npm install

Después creamos el paquete-ejecutable con el siguiente comando

electron-packager . -platform=win32 -arch=x64 ConversorXMLPDF

y nos genera los archivos necesarios
image

Creamos una carpeta en C: llamada aplicación o como ustedes quieran llamarle y copiamos el contenido, la carpeta del proyecto del codeigniter y los archivos ejecutable de PHP con los que trabajan, pueden copiar los del xampp y con el que debugean a través de netbeans
quedaría de la siguiente forma

image

ConvertidorXMLPDF seria el proyecto en codeigniter, php8 son los binarios necesarios para ejecutar código php, este lo pueden extraer de xampp y lo demas son los archivos de electronJS

Ahora en el archivo de configuración de código igniter en config/app.php en la base URL la dejamos asi

public $baseURL = '[http://localhost:8097/](http://localhost:8097/)';

El archivo Ejecutar.bat es el que va iniciar todo el codeigniter y dentro de el va el siguiente codigo

@echo off

php8\php.exe convertidorXMLPDF/spark serve --port 8097

El archivo Ejecutar.bat se ejecuta automáticamente al abrir el ejecutable

Y listo ahora solo queda hacer el instalador pero lo dejamos para otro manual.

INTRODUCCIÓN – INSTALACIÓN – TUTORIAL VISUAL BASIC 2022

Anteriormente hemos visto como hacer fácil aplicaciones básicas y sencillas en cualquier distribución de GNU/Linux usando Gambas 3.

Ahora haremos la aplicación usando la ultima versión de Visual Basic que esta dentro de la versión community 2022

Como introducción ya deben saber que a estas alturas Gambas3 y Visual Basic Entran a la categoria de entornos RAD (Rapid application development) o en español (desarrollo rapido de aplicacion)

Ventajas de la versión 2022 sobre las anteriores

Como publicar proyecto de gambas3 en la granja de software

Suponiendo que ya esta listo el programa lo que sigue puede ser lo siguiente
1. Crear un simple Ejecutable
2. Crear un paquete de instalación para instalarlo en cualquier distribución de Linux a través de un empaquetado .deb
3. Publicarlo en la granja de software de Gambas3

Lo que haremos es publicarlo en la granja de software

Primero le asignamos un icono al proyecto en las propiedades del proyecto

Aprovechamos para escribir la descripción del proyecto y los autores

Ahora nos vamos al menú Proyecto -> Publicar

Le rellenamos mas datos en caso de ser necesario
Elegimos las etiquetas
Elegimos una captura del programa, esto de mostrara cuando alguien quiera descargar nuestro programa
Elegimos las dependencias
Elegimos si publicarlo con nuestro usuario, aunque se puede publicar bajo el anonimato sin crear usuario en gambasfarm.org

Finalmente le damos Publicar y mostrara el siguiente mensaje comunicándonos de que el proyecto se ha publicado correctamente
Si nos vamos a la granja de software ya estará publicado nuestro proyecto

Como guardar archivos en disco duro con GAMBAS3 File.Save

Ya tenemos las funciones para crear automáticamente los códigos del Modelo/Vista/Controlador para PHP ahora lo que sigue es crear los archivos en el directorio del directorio del proyecto en PHP

Para guardar archivo en Gambas3 usaremos la función File.Save(“ruta donde se va a guardar”,”contenido del archivo”)

Pasos

Le damos doble click al botton para generar el evento _Click
Quedara de la siguiente forma

Insertamos en ese evento el siguiente código

  Dim strModel1 As String
  Dim strControlador As String
  Dim strVista As String 
  
  ' GUARDAR CONFIGURACION

  
  Settings["ruta"] = ruta.SelectedPath
  Settings["tabla"] = txtTabla.Text
  
  ' CREA ARCHIVO DEL MODELO
  strModel1 = creadorModelo.creaModelo()
   
  File.Save(ruta.SelectedPath & "/" & "modelos/" & txtTabla.Text & ".modelo.php", strModel1)
  
  ' CREA ARCHIVO DEL CONTROLADOR
  strControlador = creadorControlador.creaControlador()
  
  File.Save(ruta.SelectedPath & "/" & "controladores/" & txtTabla.Text & ".controlador.php", strControlador)
   
   
  ' CREA ARCHIVO VISTA 
  strVista = creadorVista.creaVista()
  
  File.Save(ruta.SelectedPath & "/" & "vistas/modulos/" & txtTabla.Text & ".php", strVista)
  
  ' MANDAMOS MENSAJE DE QUE TODO SE HA GUARDADO CORRECTAMENTE
  Message.Info("Guardado Correctamente")
Se observa como se usan las funciones para crear el código, por ejemplo, para crear el modelo se usa creadorModelo.creaModelo() y guarda todo el texto/código generado en la variable strModel1

Luego guarda con File.Save en la ruta que seleccionamos con el control llamado “ruta” el texto que esta en strModel

Esta misma lógica se usa para el controlador y la vista

En la siguiente publicación veremos como asignarle un icono al proyecto

Función para crear automáticamente el código de la vista en base a una tabla en MySQL

Ahora solo queda hacer la función para generar automáticamente el código HTML/PHP para la vista del catalogo en base a la nueva tabla.

La lógica es igual solo que es otro texto

Creamos el modulo creadorVista en la carpeta modulos

Insertamos el siguiente codigo

' Gambas module file

Public Function creaVista() As String
  
  Dim strVista As String
  
  Dim conexion As New Connection
  Dim strDatos As String
  


  With conexion
    .Type = "mysql"
    .Port = "3306"
    .Host = Settings["servidor"]
    .User = Settings["usuario"]
    .Password = Settings["password"]
    .Name = Settings["baseDeDatos"]
    .Open()
    End With
    
    Dim $result As Result
    Dim $resultClases As Result
    Dim strLLavePrimaria As String
    
   $result = conexion.Exec("SHOW KEYS FROM  " & FMain.txtTabla.Text & " WHERE Key_name = 'PRIMARY'")
   strLLavePrimaria = $result["Column_name"]
   
   
   conexion.Exec("delete from clases where clase= 'controladores/" & FMain.txtTabla.Text & ".controlador.php'")
   conexion.Exec("delete from clases where clase= 'modelos/" & FMain.txtTabla.Text & ".modelo.php'")
   conexion.Exec("insert into clases(clase) values('controladores/" & FMain.txtTabla.Text & ".controlador.php')")
   conexion.Exec("insert into clases(clase) values( 'modelos/" & FMain.txtTabla.Text & ".modelo.php')")
  
  
   $result = conexion.Exec("describe " & FMain.txtTabla.Text)
  $result = conexion.Exec("describe " & FMain.txtTabla.Text)
  
  
Dim contador As Integer
Dim strEncabezadosTabla As String
Dim strCampos As String
Dim strControlesNuevos As String
Dim strControlesEditar As String
Dim strEditarJS As String
Dim strBloquear As String
Dim strEditarTraeDatos As String

contador = 0
strEncabezadosTabla = ""
strCampos = ""
strControlesNuevos = ""
strEditarJS = ""

While $result.Length > contador
  
  strEncabezadosTabla &= "<th>" & utilerias.strPrimeraMayuscula($result["Field"]) & "</th>" & gb.CrLf 
  
  strCampos &= "<td>'.$value[\"" & $result["Field"] & "\"].'</td>" & gb.CrLf 
  
  If contador > 0

  strControlesNuevos &= "" & "            <!-- ENTRADA PARA " & UCase($result["Field"]) & " --> " & gb.CrLf
  strControlesNuevos &= "" & " " & gb.CrLf
  strControlesNuevos &= "" & "            <div class=\"form-group\"> " & gb.CrLf
  strControlesNuevos &= "" & " " & gb.CrLf
  strControlesNuevos &= "" & "              <div class=\"input-group\"> " & gb.CrLf
  strControlesNuevos &= "" & " " & gb.CrLf
  strControlesNuevos &= "" & "                <span class=\"input-group-addon\">" & utilerias.strPrimeraMayuscula($result["Field"]) & ": </span>  " & gb.CrLf
  strControlesNuevos &= "" & " " & gb.CrLf
  strControlesNuevos &= "" & "                <input type=\"text\" class=\"form-control input-lg\" name=\"nuevo" & utilerias.strPrimeraMayuscula($result["Field"]) & "\" placeholder=\"Ingresar " & utilerias.strPrimeraMayuscula($result["Field"]) & "\" required> " & gb.CrLf
  strControlesNuevos &= "" & " " & gb.CrLf
  strControlesNuevos &= "" & "              </div> " & gb.CrLf
  strControlesNuevos &= "" & " " & gb.CrLf
  strControlesNuevos &= "" & "            </div> " & gb.CrLf
  
  strEditarJS &= "" & "            $(\"#editarDescripcion\").val(respuesta[\"descripcion\"]);" & gb.CrLf

  End If
  
  
  If $result["Key"] == "PRI" 
    strBloquear = "readonly"
    Else
    strBloquear = ""
   End If
    
  
  
  strControlesEditar &= "" & "            <!-- ENTRADA PARA " & UCase($result["Field"]) & " --> " & gb.CrLf
  strControlesEditar &= "" & " " & gb.CrLf
  strControlesEditar &= "" & "            <div class=\"form-group\"> " & gb.CrLf
  strControlesEditar &= "" & " " & gb.CrLf
  strControlesEditar &= "" & "              <div class=\"input-group\"> " & gb.CrLf
  strControlesEditar &= "" & " " & gb.CrLf
  strControlesEditar &= "" & "                <span class=\"input-group-addon\">" & utilerias.strPrimeraMayuscula($result["Field"]) & ": </span>  " & gb.CrLf
  strControlesEditar &= "" & " " & gb.CrLf
  strControlesEditar &= "" & "                <input " & strBloquear & "  type=\"text\" class=\"form-control input-lg\" id=\"editar" & utilerias.strPrimeraMayuscula($result["Field"]) & "\" name=\"editar" & utilerias.strPrimeraMayuscula($result["Field"]) & "\" placeholder=\"Ingresar " & utilerias.strPrimeraMayuscula($result["Field"]) & "\" required> " & gb.CrLf
  strControlesEditar &= "" & " " & gb.CrLf
  strControlesEditar &= "" & "              </div> " & gb.CrLf
  strControlesEditar &= "" & " " & gb.CrLf
  strControlesEditar &= "" & "            </div> " & gb.CrLf
  
  strEditarTraeDatos &= "" & "            $(\"#editar" & utilerias.strPrimeraMayuscula($result["Field"]) & "\").val(respuesta[\"" & $result["Field"] & "\"]); " & gb.CrLf 

  $result.MoveNext
  contador = contador + 1


Wend
  strControlesEditar &= "" & " <input type=\"hidden\" id=\"editar" & utilerias.strPrimeraMayuscula(FMain.txtTabla.text) & "\"  name = \"editar" & utilerias.strPrimeraMayuscula(FMain.txtTabla.text) & "\" > " & gb.CrLf 
  strEncabezadosTabla &= "<th>Acciones</th>" 
  strCampos &= "<td> " & gb.CrLf
  strCampos &= "<div class = \"btn-group\"> " & gb.CrLf
  
  
 
   strCampos &= "                    <button class= \"btn btn-warning btnEditar" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "\" id" & utilerias.strPrimeraMayuscula(FMain.txtTabla.text) & " = \"'.$value[\"id\"].'\" data-toggle = \"modal\" data-target = \"#modalEditar" & Trim(utilerias.strPrimeraMayuscula(FMain.txtTabla.Text)) & "\"> <i class = \"fa fa-pencil\"> </i> </button> " & gb.CrLf
 
strCampos &= "<button class = \"btn btn-danger btnEliminar" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "\" id" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "= \"'.$value[\"id\"].'\"><i class= \"fa fa-times\"></i></button>" & gb.CrLf
 
strCampos &= "</div>" & gb.CrLf
 
strCampos &= "</td> " & gb.CrLf
    
  strVista &= "" & "<?php" & gb.CrLf
  strVista &= "" & gb.CrLf
  strVista &= "" & "if(\"off\" == \"offf\"){" & gb.CrLf
  strVista &= "" & gb.CrLf
  strVista &= "" & "  echo '<script>" & gb.CrLf
  strVista &= "" & gb.CrLf
  strVista &= "" & "    window.location = \"inicio\"; " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "  </script>'; " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "  return; " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "} " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "?> " & gb.CrLf
  strVista &= "" & "<div class=\"content-wrapper\">" & gb.CrLf 
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "  <section class=\"content-header\">" & gb.CrLf 
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "    <h1> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "      Administrar <?php echo  mb_strtolower(preg_replace('/(?<=\\w)(\\p{Lu})/u', ' $1', ' " & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & " ')); ?> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "    </h1> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "    <ol class=\"breadcrumb\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "      <li><a href=\"inicio\"><i class=\"fa fa-dashboard\"></i> Inicio</a></li> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "      <li class=\"active\">Administrar <?php echo  mb_strtolower(preg_replace('/(?<=\\w)(\\p{Lu})/u', ' $1', '" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & " ')); ?></li> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "    </ol> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "  </section> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "  <section class=\"content\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "    <div class=\"box\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "      <div class=\"box-header with-border\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <button class=\"btn btn-primary\" data-toggle=\"modal\" data-target=\"#modalAgregar" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          Agregar <?php echo  mb_strtolower(preg_replace('/(?<=\\w)(\\p{Lu})/u', ' $1', '" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & " ')); ?> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        </button> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "      </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "      <div class=\"box-body\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "       <table class=\"table table-bordered table-striped dt-responsive tablas\" width=\"100%\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <thead> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "         <tr> " & gb.CrLf
  strVista &= "" & " " & strEncabezadosTabla
  strVista &= "" & "         </tr>  " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        </thead> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <tbody> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <?php " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        $item = null; " & gb.CrLf
  strVista &= "" & "        $valor = null; " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        $" & FMain.txtTabla.Text & "= Controlador" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "::ctrMostrar($item, $valor); " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "       foreach ($" & FMain.txtTabla.Text & " as $key => $value){ " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  
  
  
  strVista &= "" & "          echo ' <tr> " & gb.CrLf

  strVista &= "" & strCampos & gb.CrLf

  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "                </tr>'; " & gb.CrLf
  strVista &= "" & "        } " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        ?>  " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        </tbody> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "       </table> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "      </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "    </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "  </section> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "</div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "<!--===================================== " & gb.CrLf
  strVista &= "" & "MODAL <?php echo  mb_strtolower(preg_replace('/(?<=\\w)(\\p{Lu})/u', ' $1', ' " & (FMain.txtTabla.Text) & " ')); ?> " & gb.CrLf
  strVista &= "" & " ======================================--> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "<div id=\"modalAgregar" & utilerias.strPrimeraMayuscula(FMain.txtTabla.text) & "\" class=\"modal fade\" role=\"dialog\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "  <div class=\"modal-dialog\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "    <div class=\"modal-content\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "      <form role=\"form\" method=\"post\" enctype=\"multipart/form-data\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <!--===================================== " & gb.CrLf
  strVista &= "" & "        CABEZA DEL MODAL " & gb.CrLf
  strVista &= "" & "        ======================================--> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <div class=\"modal-header\" style=\"background:#3c8dbc; color:white\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          <button type=\"button\" class=\"close\" data-dismiss=\"modal\">&times;</button> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          <h4 class=\"modal-title\">Agregar <?php echo  mb_strtolower(preg_replace('/(?<=\\w)(\\p{Lu})/u', ' $1', ' " & (FMain.txtTabla.Text) & " ')); ?> </h4> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf

  strVista &= "" & "        </div> " & gb.CrLf
 
  strVista &= "" & "        <!--===================================== " & gb.CrLf
  strVista &= "" & "        CUERPO DEL MODAL " & gb.CrLf
  strVista &= "" & "        ======================================--> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <div class=\"modal-body\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          <div class=\"box-body\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  'strVista &= "" & "            <!-- ENTRADA PARA DESCRIPCION --> " & gb.CrLf
  
    strVista &= "" & " " & strControlesNuevos & gb.CrLf
  
  
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <!--===================================== " & gb.CrLf
  strVista &= "" & "        PIE DEL MODAL " & gb.CrLf
  strVista &= "" & "        ====================================== --> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <div class=\"modal-footer\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          <button type=\"button\" class=\"btn btn-default pull-left\" data-dismiss=\"modal\">Salir</button> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          <button type=\"submit\" class=\"btn btn-primary\">Guardar</button> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <?php " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "           $crear = new Controlador" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "(); " & gb.CrLf
  strVista &= "" & "           $crear ->ctrIngresar(); " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        ?> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "      </form> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "    </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "  </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "</div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "<!--===================================== " & gb.CrLf
  strVista &= "" & "MODAL EDITAR USUARIO " & gb.CrLf
  strVista &= "" & " ======================================--> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "<div id=\"modalEditar" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "\" class=\"modal fade\" role=\"dialog\">" & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "  <div class=\"modal-dialog\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "    <div class=\"modal-content\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "      <form role=\"form\" method=\"post\" enctype=\"multipart/form-data\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <!--===================================== " & gb.CrLf
  strVista &= "" & "        CABEZA DEL MODAL " & gb.CrLf
  strVista &= "" & "        ======================================--> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <div class=\"modal-header\" style=\"background:#3c8dbc; color:white\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          <button type=\"button\" class=\"close\" data-dismiss=\"modal\">&times;</button> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          <h4 class=\"modal-title\">Agregar <?php echo  mb_strtolower(preg_replace('/(?<=\\w)(\\p{Lu})/u', ' $1', ' " & (FMain.txtTabla.Text) & " ')); ?> </h4> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <!--===================================== " & gb.CrLf
  strVista &= "" & "        CUERPO DEL MODAL " & gb.CrLf
  strVista &= "" & "        ======================================--> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <div class=\"modal-body\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          <div class=\"box-body\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "            <!-- ENTRADA PARA DESCRIPCION --> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & strControlesEditar
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <!--===================================== " & gb.CrLf
  strVista &= "" & "        PIE DEL MODAL " & gb.CrLf
  strVista &= "" & "        ======================================--> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        <div class=\"modal-footer\"> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          <button type=\"button\" class=\"btn btn-default pull-left\" data-dismiss=\"modal\">Salir</button> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "          <button type=\"submit\" class=\"btn btn-primary\">Modificar</button> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "     <?php " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "           $editar = new Controlador" & utilerias.strPrimeraMayuscula(FMain.txtTabla.text) & "(); " & gb.CrLf
  strVista &= "" & "           $editar ->ctrEditar(); " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "        ?>  " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "      </form> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "    </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "  </div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "</div> " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "<?php " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "   $borrar = new Controlador" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "(); " & gb.CrLf
  strVista &= "" & "   $borrar ->ctrBorrar(); " & gb.CrLf
  strVista &= "" & " " & gb.CrLf
  strVista &= "" & "?>  " & gb.CrLf
  
  'JAVASCRIPT FUNCIONES
  strVista &= "" & "<script type=\"text/javascript\">" & gb.CrLf
  
    'ELIMINAR
 
  
strVista &= "" & "/*= == == == == == == == == == == == == == == == == == == == == == ==" & gb.CrLf
strVista &= "" & " ELIMINAR " & UCase(FMain.txtTabla.Text) & gb.CrLf
strVista &= "" & " == == == == == == == == == == == == == == == == == == == == == == = */" & gb.CrLf
strVista &= "" & "$(\".tablas\").on(\"click\", \".btnEliminar" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "\", function() {" & gb.CrLf 

strVista &= "" & "    var id" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & " = $(this).attr(\"id" & FMain.txtTabla.Text & "\");" & gb.CrLf

strVista &= "" & "    swal( {" & gb.CrLf
strVista &= "" & "        title: '¿Está seguro de borrar?'," & gb.CrLf
strVista &= "" & "        text: \"¡Si no lo está puede cancelar la accíón!\"," & gb.CrLf
strVista &= "" & "        type: 'warning'," & gb.CrLf
strVista &= "" & "        showCancelButton: true," & gb.CrLf
strVista &= "" & "        confirmButtonColor: '#3085d6'," & gb.CrLf
strVista &= "" & "        cancelButtonColor: '#d33'," & gb.CrLf
strVista &= "" & "        cancelButtonText: 'Cancelar'," & gb.CrLf
strVista &= "" & "       confirmButtonText: 'Si, borrar!'" & gb.CrLf
strVista &= "" & "    }).then(function(result) {" & gb.CrLf
strVista &= "" & "" & gb.CrLf
strVista &= "" & "        if (result.value) {" & gb.CrLf
strVista &= "" & "" & gb.CrLf
strVista &= "" & "            window.location = \"index.php?ruta=" & (FMain.txtTabla.Text) & "&id" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "=\"+id" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "+\"&borrar" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "=borrar\";" & gb.CrLf
strVista &= "" & "" & gb.CrLf
strVista &= "" & "        }" & gb.CrLf
strVista &= "" & "" & gb.CrLf
strVista &= "" & "    })" & gb.CrLf

strVista &= "" & "})" & gb.CrLf


'editar

strVista &= "" & "/* = == == == == == == == == == == == == == == == == == == == == == ==" & gb.CrLf
strVista &= "" & " EDITAR " & gb.CrLf
strVista &= "" & " == == == == == == == == == == == == == == == == == == == == == == = */" & gb.CrLf
strVista &= "" & "$(\".tablas\").on(\"click\", \".btnEditar" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "\", function() {" & gb.CrLf
strVista &= "" & "" & gb.CrLf
strVista &= "" & "    var id" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & " = $(this).attr(\"id" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "\");" & gb.CrLf
strVista &= "" & "  console.log(id" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & ");"
strVista &= "" & "" & gb.CrLf
strVista &= "" & "" & gb.CrLf
strVista &= "" & "    var datos = new FormData();" & gb.CrLf
strVista &= "" & "    datos.append(\"id" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "\", id" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "); " & gb.CrLf 
strVista &= "" & "    datos.append(\"buscar" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "\", \"buscar" & utilerias.strPrimeraMayuscula(FMain.txtTabla.Text) & "\");" & gb.CrLf
strVista &= "" & "   " & gb.CrLf
strVista &= "" & "" & gb.CrLf
strVista &= "" & "    $.ajax( {" & gb.CrLf
strVista &= "" & "" & gb.CrLf
strVista &= "" & "        url:\"controladores/" & FMain.txtTabla.text & ".controlador.php\"," & gb.CrLf
strVista &= "" & "        method:\"POST\"," & gb.CrLf
strVista &= "" & "        data: datos," & gb.CrLf
strVista &= "" & "        cache: false," & gb.CrLf
strVista &= "" & "        contentType: false," & gb.CrLf
strVista &= "" & "        processData: false," & gb.CrLf
strVista &= "" & "       dataType:\"json\"," & gb.CrLf
strVista &= "" & "       success: function(respuesta) {" & gb.CrLf
strVista &= "" & "" & gb.CrLf
strVista &= "" & strEditarTraeDatos & gb.CrLf
strVista &= "" & "            " & gb.CrLf
strVista &= "" & "        }" & gb.CrLf
strVista &= "" & "" & gb.CrLf
strVista &= "" & "    });" & gb.CrLf
strVista &= "" & "" & gb.CrLf
strVista &= "" & "})" & gb.CrLf

  
  strVista &= "" & "</script>" & gb.CrLf
  Return strVista

End

En la siguiente publicación veremos como generar los archivos modelos/vista/Controlador al darle click al botón Crear Catalogo

Página 4 de 6

Creado con WordPress & Tema de Anders Norén