Herramientas Informaticas

Descarga Masiva en PHP CodeIgniter 4 #17

La descarga masiva es un proceso que permite descargar un gran número de archivos o datos de forma simultánea. En el contexto de las facturas electrónicas en México, la descarga masiva se refiere al proceso de descargar un gran número de CFDI de forma simultánea desde el portal del SAT.

Por lo tanto vamos agregar este utilidad utilizando las librerías de https://www.phpcfdi.com/librerias/

Primero crearemos el archivo de migración en App/Database/Migrations/2023-05-27001120_Peticionesdescargamasiva.php con el siguiente código

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class Peticionesdescargamasiva extends Migration {

    public function up() {
        // Peticionesdescargamasiva
        $this->forge->addField([
            'id' => ['type' => 'int', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
            'idEmpresa' => ['type' => 'int', 'constraint' => 11],
            'desdeFecha' => ['type' => 'datetime', 'null' => true],
            'hastaFecha' => ['type' => 'datetime', 'null' => true],
            'emitidoRecibido' => ['type' => 'varchar', 'constraint' => 32, 'null' => true],
            'tipoPeticion' => ['type' => 'varchar', 'constraint' => 16, 'null' => true],
            'uuidPeticion' => ['type' => 'varchar', 'constraint' => 39, 'null' => true],
            'nombreArchivo' => ['type' => 'varchar', 'constraint' => 512, 'null' => true],
            'status' => ['type' => 'varchar', 'constraint' => 128, '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('peticionesdescargamasiva', true);
    }

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

}

Creamos el archivo modelo de la descarga masiva en App/Models/PeticionesdescargamasivaModel.php con el siguiente código

<?php

namespace App\Models;

use CodeIgniter\Model;

class PeticionesdescargamasivaModel extends Model {

    protected $table = 'peticionesdescargamasiva';
    protected $primaryKey = 'id';
    protected $useAutoIncrement = true;
    protected $returnType = 'array';
    protected $useSoftDeletes = true;
    protected $allowedFields = ['id', 'desdeFecha', 'hastaFecha', 'emitidoRecibido'
        , 'tipoPeticion', 'uuidPeticion', 'created_at', 'updated_at', 'deleted_at', 'nombreArchivo', 'status', 'idEmpresa'];
    protected $useTimestamps = true;
    protected $createdField = 'created_at';
    protected $deletedField = 'deleted_at';
    protected $validationRules = [
    ];
    protected $validationMessages = [];
    protected $skipValidation = false;

}

Creamos el archivo controlador de la descarga masiva en App/Controllers/PeticionesdescargamasivaController.php con el siguiente código

<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use \App\Models\{
    PeticionesdescargamasivaModel
};
use App\Models\LogModel;
use App\Models\EmpresasModel;
use App\Models\XmlModel;
use CodeIgniter\API\ResponseTrait;
use PhpCfdi\SatWsDescargaMasiva\RequestBuilder\RequestBuilderInterface;
use PhpCfdi\SatWsDescargaMasiva\RequestBuilder\FielRequestBuilder\Fiel;
use PhpCfdi\SatWsDescargaMasiva\RequestBuilder\FielRequestBuilder\FielRequestBuilder;
use PhpCfdi\SatWsDescargaMasiva\Service;
use PhpCfdi\SatWsDescargaMasiva\Shared\ServiceEndpoints;
use PhpCfdi\SatWsDescargaMasiva\WebClient\Exceptions\SoapFaultError;
use PhpCfdi\SatWsDescargaMasiva\WebClient\GuzzleWebClient;
use PhpCfdi\SatWsDescargaMasiva\Services\Query\QueryParameters;
use PhpCfdi\SatWsDescargaMasiva\Shared\DateTimePeriod;
use PhpCfdi\SatWsDescargaMasiva\RequestBuilder\RequestBuilderException;
use PhpCfdi\SatWsDescargaMasiva\Shared\ComplementoCfdi;
use PhpCfdi\SatWsDescargaMasiva\Shared\DocumentStatus;
use PhpCfdi\SatWsDescargaMasiva\Shared\DocumentType;
use PhpCfdi\SatWsDescargaMasiva\Shared\DownloadType;
use PhpCfdi\SatWsDescargaMasiva\Shared\RequestType;
use PhpCfdi\SatWsDescargaMasiva\Shared\RfcMatch;
use PhpCfdi\SatWsDescargaMasiva\Shared\RfcOnBehalf;
use PhpCfdi\SatWsDescargaMasiva\Shared\Uuid;
use PhpCfdi\SatWsDescargaMasiva\PackageReader\Exceptions\OpenZipFileException;
use PhpCfdi\SatWsDescargaMasiva\PackageReader\CfdiPackageReader;
use PhpCfdi\CfdiToJson\JsonConverter;
use SoapFault;
use PhpCfdi\SatEstadoCfdi\Consumer;
use PhpCfdi\SatEstadoCfdi\Contracts\ConsumerClientInterface;
use PhpCfdi\SatEstadoCfdi\Soap\SoapConsumerClient;

class PeticionesdescargamasivaController extends BaseController {

    use ResponseTrait;

    protected $log;
    protected $peticionesdescargamasiva;
    protected $XMLArchivo;
    protected $empresa;

    public function __construct() {
        $this->peticionesdescargamasiva = new PeticionesdescargamasivaModel();
        $this->log = new LogModel();
        $this->XMLArchivo = new XmlModel();
        $this->empresa = new EmpresasModel();
        helper('menu');
    }

    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");
        }
        // $empresasID = implode(",", $empresasID);

        if ($this->request->isAJAX()) {
            $datos = $this->peticionesdescargamasiva->select('id,desdeFecha
            ,hastaFecha
            ,emitidoRecibido
            ,tipoPeticion
            ,uuidPeticion
            ,created_at
            ,updated_at
            ,deleted_at
            ,nombreArchivo
            ,status')->where('deleted_at', null)->whereIn("idEmpresa", $empresasID);
            return \Hermawan\DataTables\DataTable::of($datos)->toJson(true);
        }
        $titulos["title"] = lang('peticionesdescargamasiva.title');
        $titulos["subtitle"] = lang('peticionesdescargamasiva.subtitle');

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

    /**
     * Read Peticionesdescargamasiva
     */
    public function getPeticionesdescargamasiva() {
        $idPeticionesdescargamasiva = $this->request->getPost("idPeticionesdescargamasiva");
        $datosPeticionesdescargamasiva = $this->peticionesdescargamasiva->find($idPeticionesdescargamasiva);
        echo json_encode($datosPeticionesdescargamasiva);
    }

    /**
     * Save or update Peticionesdescargamasiva
     */
    public function save() {
        helper('auth');
        helper('utilerias');
        $userName = user()->username;
        $idUser = user()->id;
        $datos = $this->request->getPost();

        $datosEmpresa = $this->empresa->find($datos["idEmpresa"]);

        if ($datos["status"] == "descargado") {

            echo "Solicitud ya descargada";

            $zipfile = $datos["nombreArchivo"];

            try {
                $cfdiReader = CfdiPackageReader::createFromFile($zipfile);
            } catch (OpenZipFileException $exception) {
                echo $exception->getMessage(), PHP_EOL;
                return;
            }

            // leer todos los CFDI dentro del archivo ZIP con el UUID como llave
            $datosXML["uuidPaquete"] = $datos["uuidPeticion"];
            $eliminarXML = $this->XMLArchivo->where("uuidPaquete", $datosXML["uuidPaquete"])->delete();
            $this->XMLArchivo->purgeDeleted();

            foreach ($cfdiReader->cfdis() as $uuid => $content) {

                $xml = \PhpCfdi\CfdiCleaner\Cleaner::staticClean($content);

                // 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);

                // VALIDAMOS STATUS EN EL SAT
                try {

                    $client = new SoapConsumerClient();
                    $consumer = new Consumer($client);

                    $cfdiStatus = $consumer->execute($cfdiData->qrUrl());

                    if ($cfdiStatus->document()->isActive()) {
                        $datosXML["status"] = 'vigente';
                    } else {
                        $datosXML["status"] = 'cancelado';
                    }
                } catch (Exception $ex) {
                    
                }

                $tfd = $cfdiData->timbreFiscalDigital();
                $emisor = $cfdiData->emisor();
                $receptor = $cfdiData->receptor();

                $datosXML["base16"] = "0.00";
                $datosXML["totalImpuestos16"] = "0.00";

                $datosXML["base8"] = "0.00";
                $datosXML["totalImpuestos8"] = "0.00";

                $impuestos = $comprobante->searchNode('cfdi:Impuestos');

                if (isset($impuestos)) {

                    $traslados = $impuestos->searchNodes('cfdi:Traslados', 'cfdi:Traslado');

                    foreach ($traslados as $key) {


                        if ($key["TasaOCuota"] == 0.16) {

                            if (isset($key["Base"])) {

                                $datosXML["base16"] = $datosXML["base16"] + $key["Base"];
                            } else {

                                $datosXML["base16"] = $datosXML["base16"] + 0;
                            }

                            $datosXML["totalImpuestos16"] = $datosXML["totalImpuestos16"] + number_format($key["Importe"], 6);
                        }

                        if ($key["TasaOCuota"] == 0.08) {


                            if (isset($key["Base"])) {

                                $datosXML["base8"] = $datosXML["base8"] + $key["Base"];
                            } else {

                                $datosXML["base8"] = $datosXML["base8"] + 0;
                            }



                            $datosXML["totalImpuestos8"] = $datosXML["totalImpuestos8"] + $key["Importe"];
                        }
                    }
                }


                //$tfd['UUID']



                $datosXML["uuidTimbre"] = $tfd['UUID'];
                $datosXML["uuidPaquete"] = $datos["uuidPeticion"];
                $datosXML["idEmpresa"] = $datos["idEmpresa"];
                $datosXML["archivoXML"] = $content;

                //  $jsonXML = JsonConverter::convertToJson($content);
                //  $arregloXML = json_decode($jsonXML, true);
                $datosXML["fecha"] = $comprobante["Fecha"];
                $datosXML["fechaTimbrado"] = $tfd['FechaTimbrado'];
                $datosXML["total"] = $comprobante["Total"];
                $datosXML["tipoComprobante"] = $comprobante["TipoDeComprobante"];

                $datosXML["rfcEmisor"] = $emisor['Rfc'];
                $datosXML["rfcReceptor"] = $receptor['Rfc'];

                $datosXML["nombreEmisor"] = $emisor['Nombre'];
                $datosXML["nombreReceptor"] = $receptor['Nombre'];

                $datosXML["metodoPago"] = $comprobante['MetodoPago'];
                $datosXML["formaPago"] = $comprobante['FormaPago'];
                $datosXML["usoCFDI"] = $receptor['UsoCFDI'];
                $datosXML["exportacion"] = $comprobante['Exportacion'];
                $datosXML["emitidoRecibido"] = $datos['emitidoRecibido'];

                if (isset($comprobante["Serie"])) {

                    $datosXML["serie"] = $comprobante["Serie"];
                } else {

                    $datosXML["serie"] = "";
                }

                if (isset($comprobante["Folio"])) {

                    $datosXML["folio"] = $comprobante["Folio"];
                } else {

                    $datosXML["folio"] = "";
                }

                $totalRen = $this->XMLArchivo->selectCount("id")->where("uuidTimbre", $datosXML["uuidTimbre"])->first();
                $totalRen = $totalRen["id"];
                if ($totalRen == 0) {



                    $this->XMLArchivo->insert($datosXML);
                }
            }
            return;
        }
        $desdeFecha = fechaHoraActualSQL($datos["desdeFecha"]);
        $hastaFecha = fechaHoraActualSQLFinal($datos["hastaFecha"]);

        /**
         * HACER PETICION
         */
        // Creación de la FIEL, puede leer archivos DER (como los envía el SAT) o PEM (convertidos con openssl)
        $rutaLlave = ROOTPATH . "writable/uploads/certificates/$datosEmpresa[archivoKey]";
        $rutaCer = ROOTPATH . "writable/uploads/certificates/$datosEmpresa[certificado]";
        $fiel = Fiel::create(
                        file_get_contents($rutaCer),
                        file_get_contents($rutaLlave),
                        $datosEmpresa["contraCertificado"]
        );

        // verificar que la FIEL sea válida (no sea CSD y sea vigente acorde a la fecha del sistema)
        if (!$fiel->isValid()) {
            return;
        }

        // creación del web client basado en Guzzle que implementa WebClientInterface
        // para usarlo necesitas instalar guzzlehttp/guzzle pues no es una dependencia directa
        $webClient = new GuzzleWebClient();

        // creación del objeto encargado de crear las solicitudes firmadas usando una FIEL
        $requestBuilder = new FielRequestBuilder($fiel);

        // Creación del servicio
        $service = new Service($requestBuilder, $webClient, null, ServiceEndpoints::cfdi());

        try {

            $service->authenticate();

            echo "conectado";
        } catch (SoapFaultError $e) {

            var_dump($e->getMessage());
        }




        // ->withPeriod(DateTimePeriod::createFromValues('2018-02-01 00:00:00', '2018-02-31 23:59:59'))
        //                                                2017-03-01 00:00:00    2015-01-01 12:59:00     
        //   ->withPeriod(DateTimePeriod::createFromValues('2018-02-01 00:00:00','2018-02-28 23:59:59'))
        if ($datos["status"] != "aceptada") {


            if ($datos["status"] == "descargado") {

                echo "Solicitud ya descargada";
                return;
            }

            if ($datos["emitidoRecibido"] == "recibido") {
                $request = QueryParameters::create()
                        ->withPeriod(DateTimePeriod::createFromValues($desdeFecha, $hastaFecha))
                        ->withRequestType(RequestType::xml())
                        ->withDownloadType(DownloadType::received());
            }

            if ($datos["emitidoRecibido"] == "emitido") {
                $request = QueryParameters::create()
                        ->withPeriod(DateTimePeriod::createFromValues($desdeFecha, $hastaFecha))
                        ->withRequestType(RequestType::xml())
                        ->withDownloadType(DownloadType::issued());
            }



            $query = $service->query($request);

            // verificar que el proceso de consulta fue correcto
            if (!$query->getStatus()->isAccepted()) {
                echo "Fallo al presentar la consulta: {$query->getStatus()->getMessage()}";
                $datos["status"] = $query->getStatus()->getMessage();
            } else {

                $datos["status"] = "aceptada";
                // el identificador de la consulta está en $query->getRequestId()
                // echo "Se generó la solicitud {$query->getRequestId()}", PHP_EOL;

                $datos["uuidPeticion"] = $query->getRequestId();
            }
        }

        if ($datos["status"] == "aceptada" && $datos["idPeticionesdescargamasiva"] > 0) {

            $requestId = $datos["uuidPeticion"];
            // Verifica los paquetes
            $verify = $service->verify($requestId);

            // revisar que el proceso de verificación fue correcto
            if (!$verify->getStatus()->isAccepted()) {
                echo "Fallo al verificar la consulta {$requestId}: {$verify->getStatus()->getMessage()}";
                return;
            }

            // revisar que la consulta no haya sido rechazada
            if (!$verify->getCodeRequest()->isAccepted()) {
                echo "La solicitud {$requestId} fue rechazada: {$verify->getCodeRequest()->getMessage()}", PHP_EOL;
                return;
            }

            // revisar el progreso de la generación de los paquetes
            $statusRequest = $verify->getStatusRequest();
            if ($statusRequest->isExpired() || $statusRequest->isFailure() || $statusRequest->isRejected()) {
                echo "La solicitud {$requestId} no se puede completar", PHP_EOL;
                return;
            }
            if ($statusRequest->isInProgress() || $statusRequest->isAccepted()) {
                echo "La solicitud {$requestId} se está procesando", PHP_EOL;
                return;
            }
            if ($statusRequest->isFinished()) {
                echo "La solicitud {$requestId} está lista", PHP_EOL;
            }



            echo "Se encontraron {$verify->countPackages()} paquetes", PHP_EOL;
            foreach ($verify->getPackagesIds() as $packageId) {
                echo " > {$packageId}", PHP_EOL;

                $download = $service->download($packageId);
                if (!$download->getStatus()->isAccepted()) {
                    echo "El paquete {$packageId} no se ha podido descargar: {$download->getStatus()->getMessage()}", PHP_EOL;
                    return;
                }
                $zipfile = "$packageId.zip";
                file_put_contents($zipfile, $download->getPackageContent());
                echo "El paquete {$packageId} se ha almacenado", PHP_EOL;

                $datos["nombreArchivo"] = $zipfile;

                $datos["status"] = "descargado";
            }
        }



        if ($datos["idPeticionesdescargamasiva"] == 0) {
            try {
                if ($this->peticionesdescargamasiva->save($datos) === false) {
                    $errores = $this->peticionesdescargamasiva->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->peticionesdescargamasiva->update($datos["idPeticionesdescargamasiva"], $datos) == false) {
                $errores = $this->peticionesdescargamasiva->errors();
                foreach ($errores as $field => $error) {
                    echo $error . " ";
                }
                return;
            } else {
                $dateLog["description"] = lang("peticionesdescargamasiva.logUpdated") . json_encode($datos);
                $dateLog["user"] = $userName;
                $this->log->save($dateLog);
                echo "Actualizado Correctamente";
                return;
            }
        }
        return;
    }

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

}

Hacemos el archivo de la vista para la descarga masiva App/Views/peticionesdescargamasiva.php con el siguiente código

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

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

<?= $this->include('modulesPeticionesdescargamasiva/modalCapturePeticionesdescargamasiva') ?>

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

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

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

                </button>

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

                                <th>#</th>
                                <th>
                                    <?= lang('peticionesdescargamasiva.fields.desdeFecha') ?>
                                </th>
                                <th>
                                    <?= lang('peticionesdescargamasiva.fields.hastaFecha') ?>
                                </th>
                                <th>
                                    <?= lang('peticionesdescargamasiva.fields.emitidoRecibido') ?>
                                </th>
                                <th>
                                    <?= lang('peticionesdescargamasiva.fields.tipoPeticion') ?>
                                </th>
                                <th>
                                    <?= lang('peticionesdescargamasiva.fields.uuidPeticion') ?>
                                </th>
                                <th>
                                    <?= lang('peticionesdescargamasiva.fields.created_at') ?>
                                </th>
                                <th>
                                    <?= lang('peticionesdescargamasiva.fields.updated_at') ?>
                                </th>
                                <th>
                                    <?= lang('peticionesdescargamasiva.fields.deleted_at') ?>
                                </th>
                                <th>
                                    <?= lang('peticionesdescargamasiva.fields.nombreArchivo') ?>
                                </th>
                                <th>
                                    <?= lang('peticionesdescargamasiva.fields.status') ?>
                                </th>

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

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

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


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

    /**
     * Cargamos la tabla
     */

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

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

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


        {
            'data': 'desdeFecha'
        },

        {
            'data': 'hastaFecha'
        },

        {
            'data': 'emitidoRecibido'
        },

        {
            'data': 'tipoPeticion'
        },

        {
            'data': 'uuidPeticion'
        },

        {
            'data': 'created_at'
        },

        {
            'data': 'updated_at'
        },

        {
            'data': 'deleted_at'
        },

        {
            'data': 'nombreArchivo'
        },

        {
            'data': 'status'
        },

        {
            "data": function (data) {
                return `<td class="text-right py-0 align-middle">
                         <div class="btn-group btn-group-sm">
                             <button class="btn btn-warning btnEditPeticionesdescargamasiva" data-toggle="modal" idPeticionesdescargamasiva="${data.id}" data-target="#modalAddPeticionesdescargamasiva">  <i class=" fa fa-edit"></i></button>
                             <button class="btn btn-success" data-id="${data.id}"> <a href="<?= base_url() ?>${data.nombreArchivo}" download><i class="far fa-arrow-alt-circle-down"></i></a></button>
                         </div>
                         </td>`
            }
        }
        ]
    });



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


        var idPeticionesdescargamasiva = $("#idPeticionesdescargamasiva").val();
        var desdeFecha = $("#desdeFecha").val();
        var hastaFecha = $("#hastaFecha").val();
        var emitidoRecibido = $("#emitidoRecibido").val();
        var tipoPeticion = $("#tipoPeticion").val();
        var uuidPeticion = $("#uuidPeticion").val();
        var nombreArchivo = $("#nombreArchivo").val();
        var status = $("#status").val();
        var idEmpresa = $("#idEmpresa").val();

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

        var datos = new FormData();
        datos.append("idPeticionesdescargamasiva", idPeticionesdescargamasiva);
        datos.append("desdeFecha", desdeFecha);
        datos.append("hastaFecha", hastaFecha);
        datos.append("emitidoRecibido", emitidoRecibido);
        datos.append("tipoPeticion", tipoPeticion);
        datos.append("uuidPeticion", uuidPeticion);
        datos.append("nombreArchivo", nombreArchivo);
        datos.append("status", status);
        datos.append("idEmpresa", idEmpresa);


        $.ajax({

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

                    tablePeticionesdescargamasiva.ajax.reload();
                    $("#btnSavePeticionesdescargamasiva").removeAttr("disabled");


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

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

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


                }

            }

        }

        )

    });



    /**
     * Carga datos actualizar
     */


    /*=============================================
     EDITAR Peticionesdescargamasiva
     =============================================*/
    $(".tablePeticionesdescargamasiva").on("click", ".btnEditPeticionesdescargamasiva", function () {

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

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

        $.ajax({

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

                $("#desdeFecha").val(respuesta["desdeFecha"]);
                $("#hastaFecha").val(respuesta["hastaFecha"]);
                $("#emitidoRecibido").val(respuesta["emitidoRecibido"]);
                $("#emitidoRecibido").trigger("change");
                $("#tipoPeticion").val(respuesta["tipoPeticion"]);
                $("#uuidPeticion").val(respuesta["uuidPeticion"]);
                $("#nombreArchivo").val(respuesta["nombreArchivo"]);
                $("#status").val(respuesta["status"]);
                $("#idEmpresa").val(respuesta["idEmpresa"]);
                $("#idEmpresa").trigger("change");

                $("#desdeFecha").attr("disabled",true);
                $("#hastaFecha").attr("disabled",true);
                $("#emitidoRecibido").attr("disabled",true);
                $("#idEmpresa").attr("disabled",true);


            }

        })

    })


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

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


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

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

    });


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

Agregamos el modal para realizar la descarga App/Views/modulesPeticionesdescargamasiva/modalCapturePeticionesdescargamasiva.php con el siguiente código

<!-- Modal Peticionesdescargamasiva -->
<div class="modal fade" id="modalAddPeticionesdescargamasiva" tabindex="-1" role="dialog" aria-labelledby="modalAddPeticionesdescargamasiva" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title"><?= lang('peticionesdescargamasiva.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-peticionesdescargamasiva" class="form-horizontal">
                    <input type="hidden" id="idPeticionesdescargamasiva" name="idPeticionesdescargamasiva" 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" name="idEmpresa" id="idEmpresa" style = "width:80%;">
                                    <option value="0">Seleccione empresa</option>
                                    <?php
                                    foreach ($empresas as $key => $value) {

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

                                </select>

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

                    <div class="form-group row">
                        <label for="desdeFecha" class="col-sm-2 col-form-label">Desde Fecha</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="desdeFecha" id="desdeFecha" class="form-control <?= session('error.desdeFecha') ? 'is-invalid' : '' ?>" value="<?= old('desdeFecha') ?>" placeholder="<?= lang('peticionesdescargamasiva.fields.desdeFecha') ?>" autocomplete="off">
                            </div>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="hastaFecha" class="col-sm-2 col-form-label">Hasta Fecha</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="hastaFecha" id="hastaFecha" class="form-control <?= session('error.hastaFecha') ? 'is-invalid' : '' ?>" value="<?= old('hastaFecha') ?>" placeholder="<?= lang('peticionesdescargamasiva.fields.hastaFecha') ?>" autocomplete="off">
                            </div>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="emitidoRecibido" class="col-sm-2 col-form-label">Tipo</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" name="emitidoRecibido" id="emitidoRecibido" style = "width:80%;">
                                    <option value="0">Seleccione opciòn</option>
                                    <option value="emitido">Emitido</option>
                                    <option value="recibido">Recibido</option>

                                </select>

                            </div>
                        </div>
                    </div>
                    <div class="form-group row" hidden>
                        <label for="tipoPeticion" class="col-sm-2 col-form-label">Tipo Petición</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" id="tipoPeticion" name="tipoPeticion" style = "width:80%;">

                                    <option value="XML">XML</option>

                                    <option value="META DATA">META DATA</option>
                                </select>

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




                    <div class="form-group row" hidden>
                        <label for="nombreArchivo" class="col-sm-2 col-form-label"><?= lang('peticionesdescargamasiva.fields.nombreArchivo') ?></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="nombreArchivo" id="nombreArchivo" class="form-control <?= session('error.nombreArchivo') ? 'is-invalid' : '' ?>" value="<?= old('nombreArchivo') ?>" placeholder="<?= lang('peticionesdescargamasiva.fields.nombreArchivo') ?>" autocomplete="off">
                            </div>
                        </div>
                    </div>
                    <div class="form-group row" hidden>
                        <label for="status" class="col-sm-2 col-form-label"><?= lang('peticionesdescargamasiva.fields.status') ?></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="status" id="status" class="form-control <?= session('error.status') ? 'is-invalid' : '' ?>" value="<?= old('status') ?>" placeholder="<?= lang('peticionesdescargamasiva.fields.status') ?>" 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="btnSavePeticionesdescargamasiva"><?= lang('boilerplate.global.save') ?></button>
            </div>
        </div>
    </div>
</div>

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


<script>

    $("#emitidoRecibido").select2();
    $("#tipoPeticion").select2();

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


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

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

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

        $("#desdeFecha").removeAttr("disabled");
        $("#hastaFecha").removeAttr("disabled");
        $("#emitidoRecibido").removeAttr("disabled");
        $("#idEmpresa").removeAttr("disabled");
        $("#emitidoRecibido").val("0");
        $("#emitidoRecibido").trigger("change");

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


    });

    /* 
     * AL hacer click al editar
     */



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


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

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

        $("#idPeticionesdescargamasiva").val(idPeticionesdescargamasiva);
        $("#btnGuardarPeticionesdescargamasiva").removeAttr("disabled");

    });
</script>


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

Agregamos la ruta en App/Config/Routes.php en el grupo de admin el siguiente código

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

    $routes->post('peticionesdescargamasiva/save', 'PeticionesdescargamasivaController::save');
    $routes->post('peticionesdescargamasiva/getPeticionesdescargamasiva', 'PeticionesdescargamasivaController::getPeticionesdescargamasiva');

Agregamos el menú con los siguientes datos

Agregamos el permiso con los siguientes datos

Y listo ya tenemos la descarga masiva

Video demostrativo

Anterior

Creando CRUD de choferes en CodeIgniter 4 #16

Siguiente

Modulo para complemento de pago en CodeIgniter 4 PHP 8 #18

5 comentarios

  1. Hola Cesar. Este codigo se podria descargar? Faltan algunas vistas, las del folder julio101290

  2. Y LOS MODELOS ESTAN VICULADOS CON EL CONTROLADOR DE XML , ES DECIR LOS DATOS DE LA FIEL O POR CONTRASENA LAS TOMA DE AHI O DEONDE GUARDAS LOS DATOS PARA LA SOLICITUD CON EL SAT

  3. hola las demas modelos son necesario para la e.firma de lo que pide del sat

Deja un comentario

Creado con WordPress & Tema de Anders Norén

Discover more from Cesar Systems

Subscribe now to keep reading and get access to the full archive.

Continue Reading