Antes de empezar con el inventario necesitaremos los catálogos principales, uno de ellos es el catalogo de proveedores.

El catalogo es similar al de clientes

Para ello necesitamos en los siguientes campos:

Datos Generales

  • Empresa
  • Nombre
  • Apellido
  • Correo Electrónico
  • Dirección
  • Código Postal
  • Fecha de nacimiento

Datos Extra Facturación

  • Razón social
  • RFC
  • Forma de pago
  • Método de pago
  • Uso CFDI
  • Regimen Fiscal
Leer Mas: Creando CRUD de Proveedores #11

Creamos el archivo de migración App/Database/Migrations/2023-04-21063336_Proveedores con el siguiente codigo

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class Proveedores extends Migration {

    public function up() {
        // Custumers
        $this->forge->addField([
            'id' => ['type' => 'int', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
            'idEmpresa' => ['type' => 'varchar', 'constraint' => 128, 'null' => true],
            'firstname' => ['type' => 'varchar', 'constraint' => 128, 'null' => true],
            'lastname' => ['type' => 'varchar', 'constraint' => 128, 'null' => true],
            'razonSocial' => ['type' => 'varchar', 'constraint' => 512, 'null' => true],
            'taxID' => ['type' => 'varchar', 'constraint' => 64, 'null' => true],
            'email' => ['type' => 'varchar', 'constraint' => 128, 'null' => true],
            'direction' => ['type' => 'varchar', 'constraint' => 1024, 'null' => true],
            'birthdate' => ['type' => 'datetime', 'null' => true],
            'formaPago' => ['type' => 'varchar', 'constraint' => 16, 'null' => true],
            'metodoPago' => ['type' => 'varchar', 'constraint' => 16, 'null' => true],
            'usoCFDI' => ['type' => 'varchar', 'constraint' => 16, 'null' => true],
            'codigoPostal' => ['type' => 'int', 'constraint' => 11, 'unsigned' => true],
            'regimenFiscal' => ['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('proveedores', true);
    }

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

}

Creamos el archivo modelo en App/Models/ProveedoresModel.php con el siguiente código

<?php

namespace App\Models;

use CodeIgniter\Model;

class ProveedoresModel extends Model {

    protected $table = 'proveedores';
    protected $primaryKey = 'id';
    protected $useAutoIncrement = true;
    protected $returnType = 'array';
    protected $useSoftDeletes = true;
    protected $allowedFields = ['id'
        , 'idEmpresa'
        , 'firstname'
        , 'lastname'
        , 'taxID'
        , 'email'
        , 'direction'
        , 'birthdate'
        , 'created_at'
        , 'updated_at'
        , 'deleted_at'
        , 'metodoPago'
        , 'formaPago'
        , 'codigoPostal'
        , 'regimenFiscal'
        , 'razonSocial'
        , 'usoCFDI'];
    protected $useTimestamps = true;
    protected $createdField = 'created_at';
    protected $deletedField = 'deleted_at';
    protected $validationRules = [
    ];
    protected $validationMessages = [];
    protected $skipValidation = false;

    /**
     * Obtener Clientes
     */
    public function mdlGetProveedores($empresas) {


        $resultado = $this->db->table('proveedores a, empresas b')
                ->select('a.id
                    ,a.idEmpresa
                    ,b.nombre as nombreEmpresa
                    ,a.firstname
                    ,a.lastname
                    ,a.taxID
                    ,a.email
                    ,a.direction
                    ,a.birthdate
                    ,a.metodoPago
                    ,a.formaPago
                    ,a.usoCFDI
                    ,a.created_at
                    ,a.updated_at
                    ,a.codigoPostal
                    ,a.regimenFiscal
                    ,a.razonSocial
                    ,a.deleted_at')
                ->where('a.idEmpresa', 'b.id', FALSE)
                ->whereIn('a.idEmpresa', $empresas);

        return $resultado;
    }

}

Creamos el archivo controlador en App/Controllers/ProveedoresController.php con el siguiente código.

<?php

namespace App\Controllers;

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

class ProveedoresController extends BaseController {

    use ResponseTrait;

    protected $log;
    protected $proveedores;
    protected $empresa;

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

    public function index() {


        helper('auth');

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

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

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

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

        if ($this->request->isAJAX()) {
            $datos = $this->proveedores->mdlGetProveedores($empresasID);
            return \Hermawan\DataTables\DataTable::of($datos)->toJson(true);
        }

        $fechaActual = fechaMySQLADateTimeHTML5(fechaHoraActual());

        $titulos["title"] = lang('proveedores.title');
        $titulos["subtitle"] = lang('proveedores.subtitle');
        $titulos["fecha"] = $fechaActual;

        $titulos["formaPago"] = $this->catalogosSAT->formasDePago40()->searchByField("texto", "%%", 99999);
        $titulos["usoCFDI"] = $this->catalogosSAT->usosCfdi40()->searchByField("texto", "%%", 99999);
        $titulos["metodoPago"] = $this->catalogosSAT->metodosDePago40()->searchByField("texto", "%%", 99999);
        $titulos["regimenFiscal"] = $this->catalogosSAT->regimenesFiscales40()->searchByField("texto", "%%", 99999);
        return view('proveedores', $titulos);
    }

    /**
     * Read Custumers
     */
    public function getProveedores() {
        $idProveedor = $this->request->getPost("idProveedor");

        $datosProveedor = $this->proveedores->find($idProveedor);
        echo json_encode($datosProveedor);
    }

    /**
     * Get Custumers via AJax
     */
    public function getProveedoresAjax() {

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

        $response = array();

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

        if (!isset($postData['searchTerm'])) {
            // Fetch record

            $listProveedores = $proveedores->select('id,firstname,lastname')->where("deleted_at", null)
                    ->where('idEmpresa', $idEmpresa)
                    ->orderBy('id')
                    ->orderBy('firstname')
                    ->orderBy('lastname')
                    ->findAll(10);
        } else {
            $searchTerm = $postData['searchTerm'];

            // Fetch record

            $listProveedores = $proveedores->select('id,firstname,lastname')->where("deleted_at", null)
                    ->where('idEmpresa', $idEmpresa)
                    ->groupStart()
                    ->like('firstname', $searchTerm)
                    ->orLike('id', $searchTerm)
                    ->orLike('lastname', $searchTerm)
                    ->groupEnd()
                    ->findAll(10);
        }

        $data = array();
        foreach ($listProveedores as $proveedores) {
            $data[] = array(
                "id" => $proveedores['id'],
                "text" => $proveedores['id'] . ' ' . $proveedores['firstname'] . ' ' . $proveedores['lastname'],
            );
        }

        $response['data'] = $data;

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

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

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

}

Creamos el archivo principal de la vista en App/Views/proveedores.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('modulesProveedores/modalCaptureProveedores') ?>

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

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

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

                </button>

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

                                <th>#</th>

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

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

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

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


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

    /**
     * Cargamos la tabla
     */

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

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

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

            {
                'data': 'nombreEmpresa'
            },

            {
                'data': 'firstname'
            },

            {
                'data': 'lastname'
            },

            {
                'data': 'taxID'
            },

            {
                'data': 'email'
            },

            {
                'data': 'direction'
            },

            {
                'data': 'birthdate'
            },

            {
                'data': 'created_at'
            },

            {
                'data': 'updated_at'
            },

            {
                'data': 'deleted_at'
            },

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







    /**
     * Carga datos actualizar
     */


    /*=============================================
     EDITAR Proveedores
     =============================================*/
    $(".tableProveedores").on("click", ".btnEditProveedores", function () {

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

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

        $.ajax({

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

                $("#idProveedor").val(respuesta["id"]);
                $("#idEmpresaProveedor").val(respuesta["idEmpresa"]);
                $("#idEmpresaProveedor").trigger("change");
                $("#firstname").val(respuesta["firstname"]);
                $("#razonSocial").val(respuesta["razonSocial"]);
                $("#lastname").val(respuesta["lastname"]);
                $("#taxID").val(respuesta["taxID"]);
                $("#email").val(respuesta["email"]);
                $("#direction").val(respuesta["direction"]);
                $("#birthdate").val(respuesta["birthdate"]);

                $("#formaPago").val(respuesta["formaPago"]);
                $("#formaPago").trigger("change");
                $("#metodoPago").val(respuesta["metodoPago"]);
                $("#metodoPago").trigger("change");
                $("#usoCFDI").val(respuesta["usoCFDI"]);
                $("#usoCFDI").trigger("change");

                $("#codigoPostal").val(respuesta["codigoPostal"]);
                $("#regimenFiscal").val(respuesta["regimenFiscal"]);
                $("#regimenFiscal").trigger("change");

            }

        })

    })

    $("#idEmpresaProveedor ").select2();
    /*=============================================
     ELIMINAR proveedores
     =============================================*/
    $(".tableProveedores").on("click", ".btn-delete", function () {

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


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

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

    });


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

Creamos el archivo secundario que contiene el modal en App/Views/modulesProveedores/modalCaptureProveedores.php con el siguiente codigo.

<?= $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('modulesProveedores/modalCaptureProveedores') ?>

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

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

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

                </button>

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

                                <th>#</th>

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

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

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

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


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

    /**
     * Cargamos la tabla
     */

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

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

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

            {
                'data': 'nombreEmpresa'
            },

            {
                'data': 'firstname'
            },

            {
                'data': 'lastname'
            },

            {
                'data': 'taxID'
            },

            {
                'data': 'email'
            },

            {
                'data': 'direction'
            },

            {
                'data': 'birthdate'
            },

            {
                'data': 'created_at'
            },

            {
                'data': 'updated_at'
            },

            {
                'data': 'deleted_at'
            },

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







    /**
     * Carga datos actualizar
     */


    /*=============================================
     EDITAR Proveedores
     =============================================*/
    $(".tableProveedores").on("click", ".btnEditProveedores", function () {

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

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

        $.ajax({

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

                $("#idProveedor").val(respuesta["id"]);
                $("#idEmpresaProveedor").val(respuesta["idEmpresa"]);
                $("#idEmpresaProveedor").trigger("change");
                $("#firstname").val(respuesta["firstname"]);
                $("#razonSocial").val(respuesta["razonSocial"]);
                $("#lastname").val(respuesta["lastname"]);
                $("#taxID").val(respuesta["taxID"]);
                $("#email").val(respuesta["email"]);
                $("#direction").val(respuesta["direction"]);
                $("#birthdate").val(respuesta["birthdate"]);

                $("#formaPago").val(respuesta["formaPago"]);
                $("#formaPago").trigger("change");
                $("#metodoPago").val(respuesta["metodoPago"]);
                $("#metodoPago").trigger("change");
                $("#usoCFDI").val(respuesta["usoCFDI"]);
                $("#usoCFDI").trigger("change");

                $("#codigoPostal").val(respuesta["codigoPostal"]);
                $("#regimenFiscal").val(respuesta["regimenFiscal"]);
                $("#regimenFiscal").trigger("change");

            }

        })

    })

    $("#idEmpresaProveedor ").select2();
    /*=============================================
     ELIMINAR proveedores
     =============================================*/
    $(".tableProveedores").on("click", ".btn-delete", function () {

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


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

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

    });


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

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

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

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

Creamos el archivo de lenguaje en ingles en App/Languaje/en/proveedores.php con el siguiente código.

 <?php

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

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

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

return $proveedores;
        

En App/Config/Routes.php en el grupo admin agregamos las siguientes rutas

    $routes->resource('proveedores', [
        'filter' => 'permission:proveedores-permission',
        'controller' => 'ProveedoresController',
        'except' => 'show'
    ]);
    $routes->post('proveedores/save', 'ProveedoresController::save');
    $routes->post('proveedores/getProveedores', 'ProveedoresController::getProveedores');
    $routes->post('proveedores/getProveedoresAjax', 'ProveedoresController::getProveedoresAjax');

Creamos el menú de proveedores tal cual se ve en la imagen

Creamos el permiso y lo asignamos al rol correspondiente

Y listo ya tenemos nuestro catalogo de proveedores

Video demostrativo