Herramientas Informaticas

Etiqueta: CODEIGNITER

CI 4.0 MedicalSoft CRUD Para Medicamentos

Ya creamos el CRUD para pacientes, ahora será necesario crear un CRUD para los medicamentos.

Primero creamos la tabla medicamentos, les dejo la exportación desde phpmyadmin

-- phpMyAdmin SQL Dump
-- version 5.0.4
-- https://www.phpmyadmin.net/
--
-- Servidor: 127.0.0.1
-- Tiempo de generación: 06-01-2023 a las 20:37:36
-- 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: `medicalsoft`
--

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

--
-- Estructura de tabla para la tabla `medicamentos`
--

CREATE TABLE `medicamentos` (
  `id` int(11) NOT NULL,
  `descripcion` varchar(256) COLLATE utf8_spanish2_ci NOT NULL,
  `created_at` datetime DEFAULT NULL,
  `deleted_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish2_ci;

--
-- Índices para tablas volcadas
--

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

--
-- AUTO_INCREMENT de las tablas volcadas
--

--
-- AUTO_INCREMENT de la tabla `medicamentos`
--
ALTER TABLE `medicamentos`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
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 */;

Creamos el archivo MedicamentosModel.php en app/models/

<?php

namespace App\Models;

use CodeIgniter\Model;

class MedicamentosModel extends Model
{
    protected $table      = 'medicamentos';
    protected $primaryKey = 'id';

    protected $useAutoIncrement = true;

    protected $returnType     = 'array';
    protected $useSoftDeletes = true;

    protected $allowedFields = ['id','descripcion', 'created_at','updated_at'];

    protected $useTimestamps = true;
    protected $createdField  = 'created_at';
    protected $deletedField  = 'deleted_at';

    protected $validationRules    =  [
        'descripcion'     => 'required|alpha_numeric_space|min_length[3]'
        
    ];
    protected $validationMessages = [];
    protected $skipValidation     = false;
    
   
}

Creamos el archivo MedicamentosController.php en app/controller

<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use App\Models\MedicamentosModel;
use \App\Models\BitacoraModel;
use CodeIgniter\API\ResponseTrait;

class MedicamentosController extends BaseController {

    use ResponseTrait;

    protected $bitacora;
    protected $medicamentos;

    public function __construct() {
        $this->medicamentos = new MedicamentosModel();
        $this->bitacora = new BitacoraModel();
        helper('menu');
    }

    public function index() {


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

            /*
              $start = $this->request->getGet('start');
              $length = $this->request->getGet('length');
              $search = $this->request->getGet('search[value]');
              $order = BitacoraModel::ORDERABLE[$this->request->getGet('order[0][column]')];
              $dir = $this->request->getGet('order[0][dir]');
             */

            $datos = $this->medicamentos->select('id,descripcion,created_at,updated_at')->where('deleted_at', null);
            // $resultado = $this->bitacora->findAll();
            // $this->bitacora->getResource()->countAllResults(),
            // $this->bitacora->getResource($search)->countAllResults()
            //      var_dump($datos);


            return \Hermawan\DataTables\DataTable::of($datos)->add('action', function ($row) {
                                return " <div class=\"btn-group\">
                          
                  <button class=\"btn btn-warning btnEditarMedicamento\" data-toggle=\"modal\" idMedicamento=\"$row->id\" data-target=\"#modalAgregarMedicamentos\">  <i class=\" fa fa-edit \"></i></button>
                  <button class=\"btn btn-danger btnEliminarMedicamento\" idMedicamento=\"$row->id\"><i class=\"fa fa-times\"></i></button></div>";
                            }, 'last')
                            ->toJson();
        }

        $titulos["title"] = lang('medicamentos.title');
        $titulos["subtitle"] = lang('medicamentos.subtitle');

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

    /*
     * Lee paciente
     */

    public function traeMedicamento() {


        $idMedicamento = $this->request->getPost("idMedicamento");
        $datosMedicamento = $this->medicamentos->find($idMedicamento);

        echo json_encode($datosMedicamento);
    }

    /*
     * Guarda o actualiza paciente
     */

    public function guardar() {


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

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

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


            try {


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

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

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

                        echo $error . " ";
                    }

                    return;
                }

                $datosBitacora["descripcion"] = "Se guardo la medicamento con los siguientes datos: " . json_encode($datos);
                $datosBitacora["usuario"] = $userName;

                $this->bitacora->save($datosBitacora);

                echo "Guardado Correctamente";
            } catch (\PHPUnit\Framework\Exception $ex) {


                echo "Error al guardar " . $ex->getMessage();
            }
        } else {


            if ($this->medicamentos->update($datos["idMedicamento"], $datos) == false) {
                
                $errores = $this->medicamentos->errors();
                foreach ($errores as $field => $error) {

                    echo $error . " ";
                }
                
                return;
               
            } else {

                $datosBitacora["descripcion"] = "Se actualizo el medicamento con los siguientes datos: " . json_encode($datos);
                $datosBitacora["usuario"] = $userName;
                $this->bitacora->save($datosBitacora);
                echo "Actualizado Correctamente";

                return;
            }
        }

        return;


    }
    
    
    
     public function delete($id)
    {
        if (!$found = $this->medicamentos->delete($id)) {
            return $this->failNotFound(lang('medicamentos.msg.msg_get_fail'));
        }
        
        $infoMedicamento = $this->medicamentos->find($id);
        
        $datosBitacora["descripcion"] = "Se elimino la medicamento que contenia los siguientes datos ". json_encode($infoMedicamento);
        
        $this->bitacora->save($datosBitacora);
        return $this->respondDeleted($found, lang('medicamentos.msg.msg_delete'));
    }

}

Creamos el archivo de la vista medicamentos.php en app/views

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

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

<?= $this->include('medicamentosModulos\modalCaptura') ?>
<!-- SELECT2 EXAMPLE -->
<div class="card card-default">
    <div class="card-header">
        <div class="float-right">
            <div class="btn-group">

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

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

                </button>

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



                                <th>#</th>
                                <th><?= lang('medicamentos.description') ?></th>
                        
                                <th><?= lang('medicamentos.createdAt') ?></th>
                                <th><?= lang('medicamentos.updateAt') ?></th>
                                <th>Acciones </th>


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

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




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

    /**
     * Cargamos la tabla
     */


    function cargaTabla() {



         $('.tablaMedicamentos').DataTable({
         "ajax": "<?= route_to('admin/medicamentos') ?>",
         "deferRender": true,
         "serverSide": true,
         "retrieve": true,
         "processing": true
         
         });
        
    }


    cargaTabla();



    /**
     * Carga datos actualizar
     */


    /*=============================================
     EDITAR PACIENTE
     =============================================*/
    $(".tablaMedicamentos").on("click", ".btnEditarMedicamento", function () {

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


        console.log("idMedicamento ", idMedicamento);

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

        $.ajax({

            url: "<?= route_to('admin/medicamentos/traerMedicamento') ?>",
            method: "POST",
            data: datos,
            cache: false,
            contentType: false,
            processData: false,
            dataType: "json",
            success: function (respuesta) {
                console.log(respuesta);
                $("#idMedicamento").val(respuesta["id"]);
                $("#descripcion").val(respuesta["descripcion"]);
            
            }

        })

    })


    /*=============================================
     ELIMINAR PACIENTE
     =============================================*/
    $(".tablaMedicamentos").on("click", ".btnEliminarMedicamento", function () {

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


 

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

                           $(".tablaMedicamentos").DataTable().destroy();
                            cargaTabla();
                            //tableUser.ajax.reload();
                        }).fail((error) => {
                            Toast.fire({
                                icon: 'error',
                                title: error.responseJSON.messages.error,
                            });
                        })
                    }
                })
    })




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

Creamos la carpeta en views medicamentosModulos y dentro de ella creamos el archivo modelCaptura.php con el siguiente código

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



                    <div class="form-group row">
                        <label for="inputName" class="col-sm-2 col-form-label"><?= lang('medicamentos.description') ?></label>
                        <div class="col-sm-10">
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="fas fa-pencil-alt"></i></span>
                                </div>
                                <input type="text" name="descripcion" id="descripcion" class="form-control <?= session('error.descripcion ') ? 'is-invalid' : '' ?>" value="<?= old('descripcion') ?>" placeholder="<?= lang('medicamentos.description') ?>" 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="btnGuardarMedicamento"><?= lang('boilerplate.global.save') ?></button>
            </div>
        </div>
    </div>
</div>

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


<script>

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

        console.log("asdasd");
        $(".form-control").val("");

        $("#idMedicamento").val("0");
        
           $("#btnGuardarMedicamento").removeAttr("disabled");

    })

    /* 
     * AL hacer click al editar
     */



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


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

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

        $("#idMedicamento").val(idMedicamento);
        $("#btnGuardarMedicamento").removeAttr("disabled");

    })

    /**
     * Guardar paciente
     */

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

        var idMedicamento = $("#idMedicamento").val();
        var descripcion = $("#descripcion").val();
      


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


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


        $.ajax({

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


                if (respuesta.match(/Correctamente.*/)) {


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


                    $('.tablaMedicamentos').DataTable().destroy();
                    cargaTabla();
                    $("#btnGuardarMedicamento").removeAttr("disabled");

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

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

                    $("#btnGuardarMedicamento").removeAttr("disabled");
                  //  $('#modalAgregarMedicamento').modal('hide');

                }

            }

        }

        )




    });
</script>


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

en app/Languaje/en creamos el archivo medicamentos.php con el siguiente código

<?php

$medicamentos["descrption"] = "Description";

$medicamentos["createdAt"] = "Date Creation";
$medicamentos["updateAt"] = "Date Update";
$medicamentos["add"] = "Add medicine";
$medicamentos["actions"] = "Actions";
$medicamentos["createEdit"] = "Create  / Edit medicine";
$medicamentos["title"] = "Medicine";
$medicamentos["subtitle"] = "List of medicines";

$medicamentos["msg_delete"] = "medicine has deleted .";
$medicamentos["msg_get_fail"] = "The medicine not exist or has deleted.";





return $medicamentos;

en app/Languaje/escreamos el archivo medicamentos.php con el siguiente código

<?php

$medicamentos["description"] = "Descripcion";

$medicamentos["createdAt"] = "Fecha Creación";
$medicamentos["updateAt"] = "Fecha de Modificación";
$medicamentos["add"] = "Agregar Medicamentos";
$medicamentos["actions"] = "Acciones";
$medicamentos["createEdit"] = "Crear  / Editar Medicamentos";
$medicamentos["title"] = "Medicamentos";
$medicamentos["subtitle"] = "Lista de Medicamentos";

$medicamentos["msg_delete"] = "El medicamento ha sido eliminada .";
$medicamentos["msg_get_fail"] = "La medicamento no existe o fue eliminada.";





return $medicamentos;

en el archivo app/config/routes.php agregamos dentro del grupo admin la siguiente rutas

    $routes->resource('medicamentos', [
        'filter' => 'permission:medicamentos-permiso',
        'controller' => 'MedicamentosController',
        'except' => 'show'
    ]);

    $routes->post('medicamentos/guardar', 'MedicamentosController::guardar');

    $routes->post('medicamentos/traerMedicamento', 'MedicamentosController::traeMedicamento');
Y listo ya tenemos nuestro CRUD de medicamentos

CI 4.0 MedicalSoft CRUD Para Pacientes

Ahora veremos como crear el CRUD de pacientes en el framework CodeIgniter 4.0 con los siguientes datos, Nombres, Apellidos, DNI, Correo Electrónico, para ello creamos la siguiente tabla.

Leer Mas: CI 4.0 MedicalSoft CRUD Para Pacientes
-- phpMyAdmin SQL Dump
-- version 5.0.4
-- https://www.phpmyadmin.net/
--
-- Servidor: 127.0.0.1
-- Tiempo de generación: 04-01-2023 a las 18:20:08
-- 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: `medicalsoft`
--

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

--
-- Estructura de tabla para la tabla `pacientes`
--

CREATE TABLE `pacientes` (
  `id` int(11) NOT NULL,
  `nombres` varchar(256) COLLATE utf8_spanish2_ci DEFAULT NULL,
  `apellidos` varchar(256) COLLATE utf8_spanish2_ci DEFAULT NULL,
  `dni` varchar(32) COLLATE utf8_spanish2_ci DEFAULT NULL,
  `telefono` varchar(16) COLLATE utf8_spanish2_ci DEFAULT NULL,
  `correoElectronico` varchar(64) COLLATE utf8_spanish2_ci DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `deleted_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish2_ci;

--
-- Índices para tablas volcadas
--

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

--
-- AUTO_INCREMENT de las tablas volcadas
--

--
-- AUTO_INCREMENT de la tabla `pacientes`
--
ALTER TABLE `pacientes`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
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 */;

Creamos el archivo PacientesModel.php en la carpeta model para el acceso a la tabla de la base de datos

<?php

namespace App\Models;

use CodeIgniter\Model;

class PacientesModel extends Model
{
    protected $table      = 'pacientes';
    protected $primaryKey = 'id';

    protected $useAutoIncrement = true;

    protected $returnType     = 'array';
    protected $useSoftDeletes = true;

    protected $allowedFields = ['id','nombres', 'apellidos','dni','telefono','correoElectronico','created_at','updated_at'];

    protected $useTimestamps = true;
    protected $createdField  = 'created_at';
    protected $deletedField  = 'deleted_at';

    protected $validationRules    =  [
        'nombres'     => 'required|alpha_numeric_space|min_length[3]',
        'apellidos'     => 'required|alpha_numeric_space|min_length[5]',
        'correoElectronico'        => 'required|valid_email|is_unique[users.email]'
        
    ];
    protected $validationMessages = [];
    protected $skipValidation     = false;
    
   
}

Creamos el archivo PacientesController.php alli tendremos la funciones para guardar, leer y modificar, creo que no falta decir que va en la carpeta controller

<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use \App\Models\PacientesModel;
use \App\Models\BitacoraModel;
use CodeIgniter\API\ResponseTrait;

class PacientesController extends BaseController {

    use ResponseTrait;

    protected $bitacora;
    protected $pacientes;

    public function __construct() {
        $this->pacientes = new PacientesModel();
        $this->bitacora = new BitacoraModel();
        helper('menu');
    }

    public function index() {


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

            /*
              $start = $this->request->getGet('start');
              $length = $this->request->getGet('length');
              $search = $this->request->getGet('search[value]');
              $order = BitacoraModel::ORDERABLE[$this->request->getGet('order[0][column]')];
              $dir = $this->request->getGet('order[0][dir]');
             */

            $datos = $this->pacientes->select('id,nombres,apellidos,dni,telefono,correoElectronico,created_at,updated_at')->where('deleted_at', null);
// $resultado = $this->bitacora->findAll();
// $this->bitacora->getResource()->countAllResults(),
// $this->bitacora->getResource($search)->countAllResults()
//      var_dump($datos);


            return \Hermawan\DataTables\DataTable::of($datos)->add('action', function ($row) {
                                return " <div class=\"btn-group\">
                          
                  <button class=\"btn btn-warning btnEditarPaciente\" data-toggle=\"modal\" idPaciente=\"$row->id\" data-target=\"#modalAgregarPaciente\">  <i class=\" fa fa-edit \"></i></button>
                  <button class=\"btn btn-danger btnEliminarPaciente\" idPaciente=\"$row->id\"><i class=\"fa fa-times\"></i></button></div>";
                            }, 'last')
                            ->toJson();
        }

        $titulos["title"] = lang('patients.title');
        $titulos["subtitle"] = lang('patients.subtitle');
        
       
//$data["data"] = $datos;
        return view('pacientes', $titulos);
    }

    /*
     * Lee paciente
     */

    public function traePaciente() {


        $idPaciente = $this->request->getPost("idPaciente");
        $datosPaciente = $this->pacientes->find($idPaciente);

        echo json_encode($datosPaciente);
    }

    /*
     * Guarda o actualiza paciente
     */

    public function guardar() {


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

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

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


            try {


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

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

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

                        echo $error . " ";
                    }

                    return;
                }

                $datosBitacora["descripcion"] = "Se guardo el paciente con los siguientes datos: " . json_encode($datos);
                $datosBitacora["usuario"] = $userName;

                $this->bitacora->save($datosBitacora);

                echo "Guardado Correctamente";
            } catch (\PHPUnit\Framework\Exception $ex) {


                echo "Error al guardar " . $ex->getMessage();
            }
        } else {


            if ($this->pacientes->update($datos["idPaciente"], $datos) == false) {

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

                    echo $error . " ";
                }

                return;
            } else {

                $datosBitacora["descripcion"] = "Se actualizo el paciente con los siguientes datos: " . json_encode($datos);
                $datosBitacora["usuario"] = $userName;
                $this->bitacora->save($datosBitacora);
                echo "Actualizado Correctamente";

                return;
            }
        }

        return;
    }

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

        $infoPaciente = $this->pacientes->find($id);

        $datosBitacora["descripcion"] = "Se elimino el paciente que contenia los siguientes datos " . json_encode($infoPaciente);

        $this->bitacora->save($datosBitacora);
        return $this->respondDeleted($found, lang('patients.msg.msg_delete'));
    }

    /**
     * Trae en formato JSON los pacientes para el select2
     * @return type
     */
    public function traerPacientesAjax() {
        
        $request = service('request');
        $postData = $request->getPost();

        $response = array();

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

        if (!isset($postData['searchTerm'])) {
            // Fetch record
            $pacientes = new PacientesModel();
            $listaPacientes = $pacientes->select('id,nombres,apellidos')
                    ->orderBy('nombres')
                    ->findAll(10);
        } else {
            $searchTerm = $postData['searchTerm'];

            // Fetch record
            $pacientes = new PacientesModel();
            $listaPacientes = $pacientes->select('id,nombres,apellidos')
                    ->where("deleted_at",null)
                    ->like('nombres', $searchTerm)
                    ->orLike('apellidos', $searchTerm)
                    ->orderBy('nombres')
                    ->findAll(10);
        }

        $data = array();
        foreach ($listaPacientes as $paciente) {
            $data[] = array(
                "id" => $paciente['id'],
                "text" => $paciente['nombres'].' '.$paciente['apellidos'],
            );
        }

        $response['data'] = $data;

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

}

En Views creamos el archivo de la vista

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

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

<?= $this->include('pacientesModulos\modalCaptura') ?>
<!-- SELECT2 EXAMPLE -->
<div class="card card-default">
    <div class="card-header">
        <div class="float-right">
            <div class="btn-group">

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

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

                </button>

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



                                <th>#</th>
                                <th><?= lang('patients.names') ?></th>
                                <th><?= lang('patients.lastName') ?></th>
                                <th><?= lang('patients.dni') ?></th>
                                <th><?= lang('patients.phone') ?></th>
                                <th><?= lang('patients.email') ?></th>
                                <th><?= lang('patients.createdAt') ?></th>
                                <th><?= lang('patients.updateAt') ?></th>
                                <th>Acciones </th>


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

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




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

    /**
     * Cargamos la tabla
     */


    function cargaTabla() {



         $('.tablaPacientes').DataTable({
         "ajax": "<?= route_to('admin/pacientes') ?>",
         "deferRender": true,
         "serverSide": true,
         "retrieve": true,
         "processing": true
         
         });
        
    }


    cargaTabla();



    /**
     * Carga datos actualizar
     */


    /*=============================================
     EDITAR PACIENTE
     =============================================*/
    $(".tablaPacientes").on("click", ".btnEditarPaciente", function () {

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


        console.log("paciente ", idPaciente);

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

        $.ajax({

            url: "<?= route_to('admin/pacientes/traerPaciente') ?>",
            method: "POST",
            data: datos,
            cache: false,
            contentType: false,
            processData: false,
            dataType: "json",
            success: function (respuesta) {
                console.log(respuesta);
                $("#idPaciente").val(respuesta["id"]);
                $("#nombres").val(respuesta["nombres"]);
                $("#apellidos").val(respuesta["apellidos"]);
                $("#correoElectronico").val(respuesta["correoElectronico"]);
                $("#telefono").val(respuesta["telefono"]);
                $("#dni").val(respuesta["dni"]);

            }

        })

    })


    /*=============================================
     ELIMINAR PACIENTE
     =============================================*/
    $(".tablaPacientes").on("click", ".btnEliminarPaciente", function () {

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


        console.log("eliminar");

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

                           $(".tablaPacientes").DataTable().destroy();
                            cargaTabla();
                            //tableUser.ajax.reload();
                        }).fail((error) => {
                            Toast.fire({
                                icon: 'error',
                                title: error.responseJSON.messages.error,
                            });
                        })
                    }
                })
    })




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

En views creamos la carpeta pacientesModulos y dentro de esa capeta creamos el archivo modalCaptura.php con la siguiente código

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



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

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

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

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

                    <div class="form-group row">
                        <label for="correoElectronico" class="col-sm-2 col-form-label"><?= lang('patients.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-envelope"></i></span>
                                </div>
                                <input type="text" name="correoElectronico" id="correoElectronico" class="form-control <?= session('error.correoElectronico') ? 'is-invalid' : '' ?>" value="<?= old('correoElectronico') ?>" placeholder="<?= lang('patients.email') ?>" 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="btnGuardarPaciente"><?= lang('boilerplate.global.save') ?></button>
            </div>
        </div>
    </div>
</div>

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


<script>

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

        console.log("asdasd");
        $(".form-control").val("");

        $("#idPaciente").val("0");
        
           $("#btnGuardarPaciente").removeAttr("disabled");

    })

    /* 
     * AL hacer click al editar
     */



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


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

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

        $("#idPaciente").val(idPaciente);
        $("#btnGuardarPaciente").removeAttr("disabled");

    })

    /**
     * Guardar paciente
     */

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

        var idPaciente = $("#idPaciente").val();
        var nombres = $("#nombres").val();
        var apellidos = $("#apellidos").val();
        var telefono = $("#telefono").val();
        var dni = $("#dni").val();
        var correoElectronico = $("#correoElectronico").val();

        var ajaxPaciente = "ajaxPaciente";


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


        var datos = new FormData();
        datos.append("idPaciente", idPaciente);
        datos.append("nombres", nombres);
        datos.append("apellidos", apellidos);
        datos.append("telefono", telefono);
        datos.append("dni", dni);
        datos.append("correoElectronico", correoElectronico);

        $.ajax({

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


                if (respuesta.match(/Correctamente.*/)) {


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


                    $('.tablaPacientes').DataTable().destroy();
                    cargaTabla();
                    $("#btnGuardarPaciente").removeAttr("disabled");

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

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

                    $("#btnGuardarPaciente").removeAttr("disabled");
                  //  $('#modalAgregarPaciente').modal('hide');

                }

            }

        }

        )




    });
</script>


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

Ahora configuramos las rutas en app/config/routes.php

    $routes->resource('pacientes', [
        'filter' => 'permission:pacientes-permiso',
        'controller' => 'PacientesController',
        'except' => 'show'
    ]);

    $routes->post('pacientes/guardar', 'PacientesController::guardar');

    $routes->post('pacientes/traerPaciente', 'PacientesController::traePaciente');

    $routes->post('pacientes/traerPacientesAjax', 'PacientesController::traerPacientesAjax');

En languaje en la carpeta es creamos el archivo patients con el siguiente codigo

<?php

$patients["names"] = "Firs Name";
$patients["lastName"] = "Last Name";
$patients["dni"] = "CARD ID";
$patients["phone"] = "Phone";
$patients["email"] = "E-Mail";
$patients["createdAt"] = "Date Creation";
$patients["updateAt"] = "Date Update";
$patients["add"] = "Add Patient";
$patients["actions"] = "Actions";
$patients["createEdit"] = "Create  / Edit Patient";
$patients["title"] = "Patient";
$patients["subtitle"] = "List of Patients";

$patients["msg_delete"] = "Patient has deleted .";
$patients["msg_get_fail"] = "The patient not exist or has deleted.";





return $patients;

Y en la carpeta es de español creamos el archivo patients con el siguiente código

<?php

$patients["names"] = "Nombres";
$patients["lastName"] = "Apellidos";
$patients["dni"] = "INE";
$patients["phone"] = "Telefono";
$patients["email"] = "Correo Electronico";
$patients["add"] = "Agregar Paciente";
$patients["updateAt"] = "Fecha Modificacion";
$patients["actions"] = "Acciones";
$patients["createEdit"] = "Crear / Editar Paciente";
$patients["title"] = "Pacientes";
$patients["subtitle"] = "Lista de Pacientes";

$patients["msg_delete"] = "El paciente ha sido eliminado correctamente.";
$patients["msg_get_fail"] = "El paciente no existe o fue eliminado.";




return $patients;
Y listo ya tenemos nuestro CRUD de pacientes

CI 4.0 MedicalSoft Datatable para tabla de Bitacora

Ya vimos como guardar los datos de la bitácora, ahora veremos como usar el datatable con server side para mostrar los datos de guardados en la bitácora

Primero creamos el archivo BitacoraModel.php de la siguiente forma en la carpeta app/model/ aunque a estas altura ya debemos tenerlo

Leer Mas: CI 4.0 MedicalSoft Datatable para tabla de Bitacora
<?php

namespace App\Models;

use CodeIgniter\Model;

class BitacoraModel extends Model
{
    protected $table      = 'bitacora';
    protected $primaryKey = 'id';

    protected $useAutoIncrement = true;

    protected $returnType     = 'array';
    protected $useSoftDeletes = true;

    protected $allowedFields = ['id','descripcion', 'usuario'];

    protected $useTimestamps = true;
    protected $createdField  = 'created_at';
    protected $deletedField  = 'deleted_at';

    protected $validationRules    = [];
    protected $validationMessages = [];
    protected $skipValidation     = false;
    
    
    
    const ORDERABLE = [
        1 => 'id',
        2 => 'descripcion',
        3 => 'usuario',
        4 => 'created_at',
        
    ];

    /**
     * Get resource data.
     *
     * @param string $search
     *
     * @return \CodeIgniter\Database\BaseBuilder
     */
   public function getResource(string $search = '')
    {
        $builder = $this->builder()
            ->select('id, descripcion, usuario, created_at');

        $condition = empty($search)
            ? $builder
            : $builder->groupStart()
                ->like('descripcion', $search)
                ->orLike('Usuario', $search)
                ->orLike('created_at', $search)
            ->groupEnd();

        return $condition->where('deleted_at', null);
    }
}

Para convertir fácilmente el resultado de la consulta SQL del QUERYBUILDER a formato json que usa datatable instalamos en la terminal el siguiente componente de hermawan usando composer

composer require hermawan/codeigniter4-datatables

Creamos el archivo BitacoraController.php con los siguientes, si observamos en la función index vemos que solo con una linea se crea el json

<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use \App\Models\BitacoraModel;
use CodeIgniter\API\ResponseTrait;

class BitacoraController extends BaseController {

    use ResponseTrait;

    protected $bitacora;

    public function __construct() {
        $this->bitacora = new BitacoraModel();
        helper('menu');
    }

    public function index() {


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

            /*
            $start = $this->request->getGet('start');
            $length = $this->request->getGet('length');
            $search = $this->request->getGet('search[value]');
            $order = BitacoraModel::ORDERABLE[$this->request->getGet('order[0][column]')];
            $dir = $this->request->getGet('order[0][dir]');
*/

           $datos = $this->bitacora->select('id,descripcion,usuario,created_at');
           // $resultado = $this->bitacora->findAll();
                                   // $this->bitacora->getResource()->countAllResults(),
                                   // $this->bitacora->getResource($search)->countAllResults()
           return \Hermawan\DataTables\DataTable::of($datos)->toJson();
        }
        
        $titulos["title"] = lang('log.title');
        $titulos["subtitle"] = lang('log.subtitle');
        //$data["data"] = $datos;
        return view('bitacora',$titulos);
    }

    public function tabla() {


        if ($this->request->isAJAX()) {
            $start = $this->request->getGet('start');
            $length = $this->request->getGet('length');
            $search = $this->request->getGet('search[value]');
            $order = BitacoraModel::ORDERABLE[$this->request->getGet('order[0][column]')];
            $dir = $this->request->getGet('order[0][dir]');

            return $this->respond(Collection::datatable(
                                    $this->bitacora->getResource($search)->orderBy($order, $dir)->limit($length, $start)->get()->getResultObject(),
                                    $this->bitacora->getResource()->countAllResults(),
                                    $this->bitacora->getResource($search)->countAllResults()
            ));
        }
    }

}

Creamos la vista en app/views/bitacora.php

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

<!-- Section content -->
<?= $this->section('content') ?>
<!-- SELECT2 EXAMPLE -->
<div class="card card-default">
    <div class="card-header">
        <div class="card-tools">
            <div class="btn-group">


            </div>
        </div>
    </div>
    <div class="card-body">
        <div class="row">
            <div class="col-md-12">
                <div class="table-responsive">
                    <table id="tablaBitacora" class="table table-striped table-hover va-middle tablaBitacora">
                        <thead>
                            <tr>
                                <th>#</th>
                                <th><?= lang('log.description') ?></th>
                                <th><?= lang('log.user') ?></th>
                                <th><?= lang('log.date') ?></th>


                            </tr>
                        </thead>
                        <tbody>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- /.card -->
<?= $this->endSection() ?>

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

/**
 * Cargamos la tabla
 */
$('.tablaBitacora').DataTable( {
    "ajax": "<?= route_to('admin/bitacora/manage') ?>",
    "deferRender": true,
     "serverSide" : true,
  "retrieve": true,
  "processing": true

} )

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

En las rutas app/config/routes.php agregamos la siguiente linea

    /*
     * RUTA BITACORA
     */

    $routes->resource('bitacora', [
        'filter' => 'permission:bitacora-permiso',
        'controller' => 'BitacoraController',
        'except' => 'show'
    ]);
Al final este es el resultado

Crear un Conversor de Facturas XML Mexicanas a PDF en CodeIgniter4

En este pequeño tutorial vamos a mostrar como crear rápidamente un conversor XML a PDF de las facturas electrónicas Mexicanas
Requisitos

  1. Tener instalado la versión mas reciente de Composer
  2. Conocimiento básico de PHP y Programación
  3. Ganas de aprender

Paso uno creamos el proyecto en CodeIgniter 4

composer create-project codeigniter4/appstarter convertidorXMLPDF

Actualizamos

composer update

Instalamos de composer el paquete que convierte el xml PDF

composer require phpcfdi/cfditopdf

creamos el archivo FileUpload.php en controladores

<?php 
namespace App\Controllers;
// use App\Models\FormModel;
use CodeIgniter\Controller;
class FileUpload extends Controller
{
    public function index() 
    {
        return view('home');
    }
    function upload() { 
        helper(['form', 'url','filesystem']);



 
            $xml = $this->request->getFile('file');
           /* $img->move(WRITEPATH . 'uploads');
    
            $data = [
               'name' =>  $img->getName(),
               'type'  => $img->getClientMimeType()
            ];
    
            $save = $db->insert($data);
            print_r('File has successfully uploaded');     */


         //  echo $_FILES['file']['tmp_name'];
            $string = file_get_contents($_FILES['file']['tmp_name']);

         
            // clean cfdi
            $xml = \PhpCfdi\CfdiCleaner\Cleaner::staticClean($string);

            
         
            // create the main node structure
            $comprobante = \CfdiUtils\Nodes\XmlNodeUtils::nodeFromXmlString($xml);

            // create the CfdiData object, it contains all the required information
            $cfdiData = (new \PhpCfdi\CfdiToPdf\CfdiDataBuilder())
                ->build($comprobante);

            // create the converter
            $converter = new \PhpCfdi\CfdiToPdf\Converter(
                new \PhpCfdi\CfdiToPdf\Builders\Html2PdfBuilder()
            );

            // create the invoice as output.pdf
            $converter->createPdfAs($cfdiData,  'output.pdf');
            
                $filename = WRITEPATH . 'uploads\output.pdf';
                
                echo '
                <script type="text/javascript">
                    window.open("/output.pdf" , "_blank");
                  </script>';
                
             
               return view('welcome_message');
                  
                
        }
     
    
}

*Agregamos el formulario en las vistas en este caso al archivo welcome_message.php

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Conversor CFDI!</title>
        <meta name="description" content="Pequeño y poderoso conversor de CFDI XML a PDF hecho en CodeIgnter">
        <meta name="keywords" content="CFDI, CFDI 4.0, CFDI 3.3, Representación Impresa, CodeIgniter, Factura Electrónica"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="shortcut icon" type="image/png" href="/favicon.ico"/>

        <!-- STYLES -->

        <style {csp-style-nonce}>
            * {
                transition: background-color 300ms ease, color 300ms ease;
            }
            *:focus {
                background-color: rgba(221, 72, 20, .2);
                outline: none;
            }
            html, body {
                color: rgba(33, 37, 41, 1);
                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
                font-size: 16px;
                margin: 0;
                padding: 0;
                -webkit-font-smoothing: antialiased;
                -moz-osx-font-smoothing: grayscale;
                text-rendering: optimizeLegibility;
            }
            header {
                background-color: rgba(247, 248, 249, 1);
                padding: .4rem 0 0;
            }
            .menu {
                padding: .4rem 2rem;
            }
            header ul {
                border-bottom: 1px solid rgba(242, 242, 242, 1);
                list-style-type: none;
                margin: 0;
                overflow: hidden;
                padding: 0;
                text-align: right;
            }
            header li {
                display: inline-block;
            }
            header li a {
                border-radius: 5px;
                color: rgba(0, 0, 0, .5);
                display: block;
                height: 44px;
                text-decoration: none;
            }
            header li.menu-item a {
                border-radius: 5px;
                margin: 5px 0;
                height: 38px;
                line-height: 36px;
                padding: .4rem .65rem;
                text-align: center;
            }
            header li.menu-item a:hover,
            header li.menu-item a:focus {
                background-color: rgba(221, 72, 20, .2);
                color: rgba(221, 72, 20, 1);
            }
            header .logo {
                float: left;
                height: 44px;
                padding: .4rem .5rem;
            }
            header .menu-toggle {
                display: none;
                float: right;
                font-size: 2rem;
                font-weight: bold;
            }
            header .menu-toggle button {
                background-color: rgba(221, 72, 20, .6);
                border: none;
                border-radius: 3px;
                color: rgba(255, 255, 255, 1);
                cursor: pointer;
                font: inherit;
                font-size: 1.3rem;
                height: 36px;
                padding: 0;
                margin: 11px 0;
                overflow: visible;
                width: 40px;
            }
            header .menu-toggle button:hover,
            header .menu-toggle button:focus {
                background-color: rgba(221, 72, 20, .8);
                color: rgba(255, 255, 255, .8);
            }
            header .heroe {
                margin: 0 auto;
                max-width: 1100px;
                padding: 1rem 1.75rem 1.75rem 1.75rem;
            }
            header .heroe h1 {
                font-size: 2.5rem;
                font-weight: 500;
            }
            header .heroe h2 {
                font-size: 1.5rem;
                font-weight: 300;
            }
            section {
                margin: 0 auto;
                max-width: 1100px;
                padding: 2.5rem 1.75rem 3.5rem 1.75rem;
            }
            section h1 {
                margin-bottom: 2.5rem;
            }
            section h2 {
                font-size: 120%;
                line-height: 2.5rem;
                padding-top: 1.5rem;
            }
            section pre {
                background-color: rgba(247, 248, 249, 1);
                border: 1px solid rgba(242, 242, 242, 1);
                display: block;
                font-size: .9rem;
                margin: 2rem 0;
                padding: 1rem 1.5rem;
                white-space: pre-wrap;
                word-break: break-all;
            }
            section code {
                display: block;
            }
            section a {
                color: rgba(221, 72, 20, 1);
            }
            section svg {
                margin-bottom: -5px;
                margin-right: 5px;
                width: 25px;
            }
            .further {
                background-color: rgba(247, 248, 249, 1);
                border-bottom: 1px solid rgba(242, 242, 242, 1);
                border-top: 1px solid rgba(242, 242, 242, 1);
            }
            .further h2:first-of-type {
                padding-top: 0;
            }
            footer {
                background-color: rgba(221, 72, 20, .8);
                text-align: center;
            }
            footer .environment {
                color: rgba(255, 255, 255, 1);
                padding: 2rem 1.75rem;
            }
            footer .copyrights {
                background-color: rgba(62, 62, 62, 1);
                color: rgba(200, 200, 200, 1);
                padding: .25rem 1.75rem;
            }
            @media (max-width: 629px) {
                header ul {
                    padding: 0;
                }
                header .menu-toggle {
                    padding: 0 1rem;
                }
                header .menu-item {
                    background-color: rgba(244, 245, 246, 1);
                    border-top: 1px solid rgba(242, 242, 242, 1);
                    margin: 0 15px;
                    width: calc(100% - 30px);
                }
                header .menu-toggle {
                    display: block;
                }
                header .hidden {
                    display: none;
                }
                header li.menu-item a {
                    background-color: rgba(221, 72, 20, .1);
                }
                header li.menu-item a:hover,
                header li.menu-item a:focus {
                    background-color: rgba(221, 72, 20, .7);
                    color: rgba(255, 255, 255, .8);
                }
            }
        </style>
    </head>
    <body>

        <!-- HEADER: MENU + HEROE SECTION -->
        <header>

            <div class="menu">
                <ul>
                    <li class="logo">
                        <a href="https://cesarsystems.com.mx/" target="_blank">
                            <img src="<?php echo base_url();?>/logo.png"
                                 aria-label="Visita mi pagina oficial para mas programas y utilidades!"/></img>
                        </a>
                    </li>
                    <li class="menu-toggle">
                        <button onclick="toggleMenu();">&#9776;</button>
                    </li>
                    <li class="menu-item hidden"><a href="#">Inicio</a></li>
                    <li class="menu-item hidden"><a href="https://cesarsystems.com.mx/" target="_blank">Descargas</a>
                    </li>
                    <li class="menu-item hidden"><a href="https://www.youtube.com/c/rasec555" target="_blank">Comunidad</a></li>
                    <li class="menu-item hidden"><a
                            href="https://patreon.com/user?u=74078772&utm_medium=clipboard_copy&utm_source=copyLink&utm_campaign=creatorshare_creator" target="_blank">Patrocinar</a>
                    </li>
                </ul>
            </div>

            <div class="heroe">

                <h1>Bienvenido a Conversor XML A PDF V2</h1>

                <h2>Un simple software para convertir los CFDI XML a PDF</h2>

            </div>

        </header>

        <!-- CONTENT -->

        <section>

            <h1>Acerca de este programa</h1>

            <p>Este programa toma los archivos XML de la factura 3.3 o 4.0 para convertirlos a una representación generica impresa de un Comprobante Fiscal Digital</p>

            <p>Para convertir el XML a PDF puede arrastrar el archivo XML en el Boton llamado "Seleccionar archivo" </p>

            <p>En caso de que no salga el PDF asegurate de no tener bloqueado el popup o desbloquealo para esta pagina ya que el pdf saldra en el popup" </p>



            <form method="post" action="<?php echo base_url('FileUpload/upload'); ?>" enctype="multipart/form-data">
                <div class="form-group">
                    <label>Seleccione el archivo XML </label>
                    <input type="file" name="file" id="file"  accept=".xml" class="form-control">
                </div>
                <div class="form-group">
                    <button type="submit" class="btn btn-danger">Generar PDF</button>
                </div>
            </form>

        </section>

        <div class="further">

            <section>

                <h1>¡Ir por más!</h1>

                <h2>
                    <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'><rect x='32' y='96' width='64' height='368' rx='16' ry='16' style='fill:none;stroke:#000;stroke-linejoin:round;stroke-width:32px'/><line x1='112' y1='224' x2='240' y2='224' style='fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px'/><line x1='112' y1='400' x2='240' y2='400' style='fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px'/><rect x='112' y='160' width='128' height='304' rx='16' ry='16' style='fill:none;stroke:#000;stroke-linejoin:round;stroke-width:32px'/><rect x='256' y='48' width='96' height='416' rx='16' ry='16' style='fill:none;stroke:#000;stroke-linejoin:round;stroke-width:32px'/><path d='M422.46,96.11l-40.4,4.25c-11.12,1.17-19.18,11.57-17.93,23.1l34.92,321.59c1.26,11.53,11.37,20,22.49,18.84l40.4-4.25c11.12-1.17,19.18-11.57,17.93-23.1L445,115C443.69,103.42,433.58,94.94,422.46,96.11Z' style='fill:none;stroke:#000;stroke-linejoin:round;stroke-width:32px'/></svg>
                    Descargas y tutoriales
                </h2>

                <p>Puedes encontrar mas aplicativos, manuales y tutoriales en la siguiente pagina <a href="https://cesarsystems.com.mx/"
                                                target="_blank">Pagina Principal</a> !</p>

                <h2>
                    <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'><path d='M431,320.6c-1-3.6,1.2-8.6,3.3-12.2a33.68,33.68,0,0,1,2.1-3.1A162,162,0,0,0,464,215c.3-92.2-77.5-167-173.7-167C206.4,48,136.4,105.1,120,180.9a160.7,160.7,0,0,0-3.7,34.2c0,92.3,74.8,169.1,171,169.1,15.3,0,35.9-4.6,47.2-7.7s22.5-7.2,25.4-8.3a26.44,26.44,0,0,1,9.3-1.7,26,26,0,0,1,10.1,2L436,388.6a13.52,13.52,0,0,0,3.9,1,8,8,0,0,0,8-8,12.85,12.85,0,0,0-.5-2.7Z' style='fill:none;stroke:#000;stroke-linecap:round;stroke-miterlimit:10;stroke-width:32px'/><path d='M66.46,232a146.23,146.23,0,0,0,6.39,152.67c2.31,3.49,3.61,6.19,3.21,8s-11.93,61.87-11.93,61.87a8,8,0,0,0,2.71,7.68A8.17,8.17,0,0,0,72,464a7.26,7.26,0,0,0,2.91-.6l56.21-22a15.7,15.7,0,0,1,12,.2c18.94,7.38,39.88,12,60.83,12A159.21,159.21,0,0,0,284,432.11' style='fill:none;stroke:#000;stroke-linecap:round;stroke-miterlimit:10;stroke-width:32px'/></svg>
                    Grupos
                </h2>

                <p>Puede seguirnos en los siguientes grupos y redes sociales como <a href="https://www.youtube.com/c/rasec555"
                                      target="_blank">Canal de youtube </a>, 
                                      
                                      <a href="https://t.me/CesarSystems"
                                      target="_blank">Canal de Telegram</a> ,
                                      
                                      <a href="https://twitter.com/JulioLeyvaR"
                                      target="_blank">Twitter</a> ,
                                      
                                       <a href="https://odysee.com/@JulioCesarLeyvaRodriguez:9"
                                      target="_blank">Odysee</a> y
                                      
                                      <a href="https://www.facebook.com/rasec555/"
                                      target="_blank">Facebook</a> 
                
                
                </p>

                <h2>
                    <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'><line x1='176' y1='48' x2='336' y2='48' style='fill:none;stroke:#000;stroke-linecap:round;stroke-miterlimit:10;stroke-width:32px'/><line x1='118' y1='304' x2='394' y2='304' style='fill:none;stroke:#000;stroke-linecap:round;stroke-miterlimit:10;stroke-width:32px'/><path d='M208,48v93.48a64.09,64.09,0,0,1-9.88,34.18L73.21,373.49C48.4,412.78,76.63,464,123.08,464H388.92c46.45,0,74.68-51.22,49.87-90.51L313.87,175.66A64.09,64.09,0,0,1,304,141.48V48' style='fill:none;stroke:#000;stroke-linecap:round;stroke-miterlimit:10;stroke-width:32px'/></svg>
                    Patrocinar
                </h2>

                <p>Puedes apoyar nuestros proyectos en Patreon y obtendras acceso exclusivo a los fuentes mas recientes
                    <a href="https://patreon.com/user?u=74078772&utm_medium=clipboard_copy&utm_source=copyLink&utm_campaign=creatorshare_creator" target="_blank">
                        Unete</a> </p>

            </section>

        </div>

        <!-- FOOTER: DEBUG INFO + COPYRIGHTS -->

        <footer>
            <div class="environment">

                <p>Tiempo de Renderizado {elapsed_time} seconds</p>

            

            </div>

            <div class="copyrights">

                <p>&copy; <?= date('Y') ?> Conversor XML a PDF es un proyecto de código abierto lanzado con la licencia MIT
                    open source licence.</p>

            </div>

        </footer>

        <!-- SCRIPTS -->

        <script>
            function toggleMenu() {
                var menuItems = document.getElementsByClassName('menu-item');
                for (var i = 0; i < menuItems.length; i++) {
                    var menuItem = menuItems[i];
                    menuItem.classList.toggle("hidden");
                }
            }
        </script>

        <!-- -->

    </body>
</html>

Y por último agregamos esto en las rutas

$routes->get('/', 'FileUpload::index');
$routes->match(['get', 'post'], 'FileUpload/upload', 'FileUpload::upload');

y listo pueden ver un ejemplo de como quedo en el siguiente enlace https://xml2pdf.cesarsystems.com.mx/

Conversor CFDI 3.3 4.0 XML A PDF

Esta utilidad hecha en CodeIgniter 4 y usando ElectroJS para la versión de escritorio, nos servirá para poder convertir nuestros XML a la representación impresa de la factura digital.

Para probar el programa en linea pueden entrar en el siguiente enlace https://xml2pdf.cesarsystems.com.mx/

Es posible que la primera vez no funcione ya que el PDF sale en un popup por lo cual tienen que habilitar en el navegador para que permita visualizarlo, en el caso de la versión de escritorio funcionara correctamente.

Es una app muy sencilla pero se se agregaran funciones extras entre mas se descargue y use

Normalmente sale cono una X roja, le dan click y le dan permitir
El resultado final quedaría de esta forma

Dejo ambos enlaces tanto para la App de escritorio como la que esta en linea

CREANDO SISTEMA DE CONSULTORIO MEDICO – INSTALANDO CODEIGNITER 4.1.1 EN PHP8 CAPITULO #1

En esta serie de vídeos veremos como hacer un sistema basico de consultorio medico En este capitulo veremos las caracteristicas de codeigniter hasta su instalación básica cualquier distribución de GNU/Linux basade de Ubuntu 18.04 en este caso es Zorin Linux Core 15.3
0:00 Intro
1:00 Descargar Code Igniter
1:32 Caracteristicas
4:15 Requisitos del Servidor
6:13 Configurando CodeIgniter con Netbeans 12.0
10:30 Instalando Extensiones PHP Necesarias

VK
https://vk.com/id543521033

FACEBOOK
https://www.facebook.com/rasec555

TWITTER
https://twitter.com/Cesar101290

CHANNEL TELEGRAM
https://telegram.me/CesarSystems


PAGINA WEB https://cesarsystems.com.mx/

MOVIL / WHATSAPP

6688612348

Página 5 de 5

Creado con WordPress & Tema de Anders Norén