Ya tenemos nuestros menús creados ahora sigue meter los catálogos de configuración, el primero seria el catalogo de empresas en el cual se van a capturar los datos de la empresa como nombre, razón social, domicilio logo y datos de facturación del SAT, estos datos saldrán en las impresiones de cotizaciones, ventas y reportes.
Primero para hacer los datatables mas fácil instalamos el paquete de hermawan/codeigniter4-datatables esto solo lo haremos una vez y nos servira para los demás catálogos para instalarlo corremos el siguiente código en nuestro proyecto
composer require hermawan/codeigniter4-datatables
Luego en app/config/autoload.php en la variable $psr4 agregamos el namespace
public $psr4 = [
APP_NAMESPACE => APPPATH, // For custom app namespace
'Config' => APPPATH . 'Config',
'Hermawan\DataTables' => APPPATH .'ThirdParty/codeigniter4-datatables/src', // <-- namespace for this library
];
Ahora para obtener todos los catálogos del SAT instalamos el paquete de phpcfdi/sat-catalogos
composer require phpcfdi/sat-catalogos
El archivo de app/controller/BaseController.php quedaria de la siguiente forma para poder utilizar los catalogos del SAT en todo momento.
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use CodeIgniter\HTTP\CLIRequest;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
use PhpCfdi\SatCatalogos\Factory;
/**
* Class BaseController
*
* BaseController provides a convenient place for loading components
* and performing functions that are needed by all your controllers.
* Extend this class in any new controllers:
* class Home extends BaseController
*
* For security be sure to declare any new methods as protected or private.
*/
abstract class BaseController extends Controller
{
/**
* Instance of the main Request object.
*
* @var CLIRequest|IncomingRequest
*/
protected $request;
/**
* An array of helpers to be loaded automatically upon
* class instantiation. These helpers will be available
* to all other controllers that extend BaseController.
*
* @var array
*/
protected $helpers = [];
public $catalogosSAT;
/**
* Constructor.
*/
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
// Do Not Edit This Line
parent::initController($request, $response, $logger);
// Preload any models, libraries, etc, here.
// E.g.: $this->session = \Config\Services::session();
$dsn = "sqlite:".ROOTPATH."writable\database\catalogossat.db";
$factory = new Factory();
$satCatalogos = $factory->catalogosFromDsn($dsn);
$this->catalogosSAT = $satCatalogos;
}
}
Si se dan cuenta nosotros tenemos un archivo en writable/database/catalogossat.db para generar el archivo de base de datos SQLITE con los datos que proporciona el SAT tenemos el siguiente script en PHP, cortesía de nuestro amigo Rene
<?php
if(file_exists ( 'sat.db' )){
unlink('sat.db' );
}
$sat = new SQLite3('sat.db');
$list = "https://raw.githubusercontent.com/phpcfdi/resources-sat-catalogs/master/database/tables.list";
$schema = "https://raw.githubusercontent.com/phpcfdi/resources-sat-catalogs/master/database/schemas/";
$data = "https://raw.githubusercontent.com/phpcfdi/resources-sat-catalogs/master/database/data/";
$listaText = file_get_contents($list);
$lines = array_filter(array_map('trim',explode("\n", $listaText)));
foreach ($lines as $line) {
echo "\x1b[33m" . $line . "\x1b[0m \n";
$schemaText = file_get_contents($schema . $line . ".sql");
echo $schemaText . "\n";
$sat->exec($schemaText);
$dataText = file_get_contents($data . $line . ".sql");
$dataLines = array_filter(array_map('trim',explode("\n", $dataText)));
foreach ($dataLines as $dataLine) {
echo "\x1b[2m" . $dataLine . "\x1b[0m \n";
$sat->exec($dataLine);
}
echo "\x1b[32m data done\n \x1b[0m \n";
}
Ahora si los archivos del catalogo, creamos el archivo app/controller/EmpresasController.php con el siguiente contenido
<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use \App\Models\EmpresasModel;
use App\Models\LogModel;
use CodeIgniter\API\ResponseTrait;
class EmpresasController extends BaseController {
use ResponseTrait;
protected $log;
protected $empresas;
public function __construct() {
$this->empresas = new EmpresasModel();
$this->log = new LogModel();
helper('menu', 'filesystem');
}
public function index() {
if ($this->request->isAJAX()) {
$datos = $this->empresas->select('id,nombre,direccion,rfc,telefono,correoElectronico,'
. 'diasEntrega,caja,logo,certificado,archivoKey,contraCertificado,regimenFiscal,razonSocial,codigoPostal,'
. 'CURP,created_at,updated_at')->where('deleted_at', null);
return \Hermawan\DataTables\DataTable::of($datos)->toJson(true);
}
$regimenesFiscales = $this->catalogosSAT->regimenesFiscales40()->searchByField("texto", "%%", 1000);
$titulos["title"] = lang('empresas.title');
$titulos["subtitle"] = lang('empresas.subtitle');
$titulos["regimenesFiscales"] = $regimenesFiscales;
//$data["data"] = $datos;
return view('empresas', $titulos);
}
/**
* Read Vehicle
*/
public function obtenerEmpresa() {
$idEmpresa = $this->request->getPost("idEmpresa");
$datosEmpresa = $this->empresas->find($idEmpresa);
echo json_encode($datosEmpresa);
}
/**
* Save or update Vehicle
*/
public function save() {
helper('auth');
$userName = user()->username;
$idUser = user()->id;
$datos = $this->request->getPost();
unset($datos["certificado"]);
unset($datos["archivoKey"]);
unset($datos["logo"]);
$certificado = $this->request->getFile('certificado');
$archivoKey = $this->request->getFile('archivoKey');
$logo = $this->request->getFile('logo');
if ($certificado <> null) {
if ($certificado->getClientExtension() <> "cer") {
return lang("empresas.certExtensionIncorrect");
}
$datos["certificado"] = $datos["rfc"] . "_certificado.cer";
}
if ($archivoKey <> null) {
if ($archivoKey->getClientExtension() <> "key") {
return lang("empresas.keyFileExtensionIncorrect");
}
$datos["archivoKey"] = $datos["rfc"] . "_certificado.key";
}
if ($logo) {
if ($logo->getClientExtension() <> "png") {
return lang("empresas.pngFileExtensionIncorrect");
}
$datos["logo"] = $datos["rfc"] . "_logo.png";
}
if ($datos["idEmpresa"] == 0) {
try {
if ($this->empresas->save($datos) === false) {
$errores = $this->empresas->errors();
foreach ($errores as $field => $error) {
echo $error . " ";
}
return;
}
$dateLog["description"] = lang("empresas.logDescription") . json_encode($datos);
$dateLog["user"] = $userName;
$this->log->save($dateLog);
if ($certificado <> null) {
$certificado->move(WRITEPATH . "uploads\certificates", $datos["rfc"] . "_certificado.cer");
}
if ($archivoKey <> null) {
$archivoKey->move(WRITEPATH . "uploads\certificates", $datos["rfc"] . "_certificado.key");
}
if ($logo <> null) {
$logo->move("images\logo", $datos["rfc"] . "_logo.png");
}
echo "Guardado Correctamente";
} catch (\PHPUnit\Framework\Exception $ex) {
echo "Error al guardar " . $ex->getMessage();
}
} else {
$datosAnteriores = $this->empresas->find($datos["idEmpresa"]);
if ($this->empresas->update($datos["idEmpresa"], $datos) == false) {
$errores = $this->empresas->errors();
foreach ($errores as $field => $error) {
echo $error . " ";
}
return;
} else {
if ($certificado <> null) {
unlink(WRITEPATH . "uploads\certificates\\" . $datosAnteriores["rfc"] . "_certificado.cer");
$certificado->move(WRITEPATH . "uploads\certificates", $datos["rfc"] . "_certificado.cer");
}
if ($archivoKey <> null) {
unlink(WRITEPATH . "uploads\certificates\\" . $datosAnteriores["rfc"] . "_certificado.key");
$archivoKey->move(WRITEPATH . "uploads\certificates", $datos["rfc"] . "_certificado.key");
}
if ($logo <> null) {
unlink("images\logo\\" . $datosAnteriores["rfc"] . "_logo.png");
$logo->move("images\logo", $datos["rfc"] . "_logo.png");
}
$dateLog["description"] = lang("empresas.logUpdated") . json_encode($datosAnteriores);
$dateLog["user"] = $userName;
$this->log->save($dateLog);
echo "Actualizado Correctamente";
return;
}
}
return;
}
/**
* Delete Empresas
* @param type $id
* @return type
*/
public function delete($id) {
$infoEmpresa = $this->empresas->find($id);
helper('auth');
$userName = user()->username;
if (!$found = $this->empresas->delete($id)) {
return $this->failNotFound(lang('empresas.msg.msg_get_fail'));
}
$logData["description"] = lang("empresas.logDeleted") . json_encode($infoEmpresa);
$logData["user"] = $userName;
if(file_exists(WRITEPATH . "uploads\certificates\\" . $infoEmpresa["rfc"] . "_certificado.cer")){
unlink(WRITEPATH . "uploads\certificates\\" . $infoEmpresa["rfc"] . "_certificado.cer");
}
if(file_exists(WRITEPATH . "uploads\certificates\\" . $infoEmpresa["rfc"] . "_certificado.key")){
unlink(WRITEPATH . "uploads\certificates\\" . $infoEmpresa["rfc"] . "_certificado.key");
}
if(file_exists("images\logo\\" . $infoEmpresa["rfc"] . "_logo.png")){
unlink("images\logo\\" . $infoEmpresa["rfc"] . "_logo.png");
}
$this->empresas->purgeDeleted();
$this->log->save($logData);
return $this->respondDeleted($found, lang('empresas.msg_delete'));
}
}
Para crear el modelo creamos el archivo app/models/EmpresasModel.php con el siguiente contenido
<?php
namespace App\Models;
use CodeIgniter\Model;
/**
* @method User|null first()
*/
class EmpresasModel extends Model {
protected $table = 'empresas';
protected $primaryKey = 'id';
protected $useSoftDeletes = true;
protected $allowedFields = [
'id', 'nombre', 'direccion', 'rfc', 'telefono', 'correoElectronico', 'diasEntrega',
'caja', 'logo', 'certificado', 'archivoKey', 'contraCertificado', 'regimenFiscal', 'razonSocial', 'CURP',
'codigoPostal', 'created_at ', 'updated_at ', 'deleted_at'
];
protected $useTimestamps = true;
protected $validationRules = [
'correoElectronico' => 'required|valid_email',
'razonSocial ' => 'required|alpha_numeric_punct|min_length[3]|is_unique[empresas.razonSocial]',
'rfc ' => 'is_unique[empresas.rfc]',
];
protected $validationMessages = [];
protected $skipValidation = false;
}
Ahora los archivos de la vista, creamos el archivo principal de la vista en app/views/empresas.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('modulosEmpresas/modalCapturaEmpresas') ?>
<!-- SELECT2 EXAMPLE -->
<div class="card card-default">
<div class="card-header">
<div class="float-right">
<div class="btn-group">
<button class="btn btn-primary btnAddEmpresa" data-toggle="modal" data-target="#modalAddEmpresa"><i class="fa fa-plus"></i>
<?= lang('empresas.add') ?>
</button>
</div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-12">
<div class="table-responsive">
<table id="tableEmpresas" class="table table-striped table-hover va-middle tableEmpresas">
<thead>
<tr>
<th>#</th>
<th><?= lang('empresas.fields.nombre') ?></th>
<th><?= lang('empresas.fields.direccion') ?></th>
<th><?= lang('empresas.fields.rfc') ?></th>
<th><?= lang('empresas.fields.logo') ?></th>
<th><?= lang('empresas.fields.regimenFiscal') ?></th>
<th><?= lang('empresas.fields.razonSocial') ?></th>
<th><?= lang('empresas.fields.codigoPostal') ?></th>
<th><?= lang('empresas.fields.CURP') ?></th>
<th><?= lang('empresas.fields.Created_at') ?></th>
<th><?= lang('empresas.fields.Update_At') ?></th>
<th><?= lang('empresas.fields.acciones') ?> </th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- /.card -->
<?= $this->endSection() ?>
<?= $this->section('js') ?>
<script>
/**
* Cargamos la tabla
*/
var tableEmpresas = $('#tableEmpresas').DataTable({
processing: true,
serverSide: true,
responsive: true,
autoWidth: false,
order: [[1, 'asc']],
ajax: {
url: '<?= base_url(route_to('admin/empresas')) ?>',
method: 'GET',
dataType: "json"
},
columnDefs: [{
orderable: false,
targets: [12],
searchable: false,
targets: [12]
}],
columns: [{
'data': 'id'
},
{
'data': 'nombre'
},
{
'data': 'direccion'
},
{
'data': 'rfc'
},
{
'data': 'logo'
},
{
'data': 'regimenFiscal'
},
{
'data': 'razonSocial'
},
{
'data': 'codigoPostal'
},
{
'data': 'CURP'
},
{
'data': 'created_at'
},
{
'data': 'updated_at'
},
{
'data': 'CURP'
},
{
"data": function (data) {
return `<td class="text-right py-0 align-middle">
<div class="btn-group btn-group-sm">
<button class="btn btn-warning btnEditEmpresa" data-toggle="modal" idEmpresa="${data.id}" data-target="#modalAddEmpresa"> <i class=" fa fa-edit"></i></button>
<button class="btn btn-danger btn-delete" data-id="${data.id}"><i class="fas fa-trash"></i></button>
</div>
</td>`
}
}
]
});
$(document).on('click', '#btnSaveEmpresa', function (e) {
var idEmpresa = $("#idEmpresa").val();
var nombre = $("#nombre").val();
var direccion = $("#direccion").val();
var telefono = $("#telefono").val();
var correoElectronico = $("#correoElectronico").val();
var razonSocial = $("#razonSocial").val();
var rfc = $("#rfc").val();
var CURP = $("#CURP").val();
var regimenFiscal = $("#regimenFiscal").val();
var codigoPostal = $("#codigoPostal").val();
var certificado = $("#certificado").prop("files")[0];
var archivoKey = $("#archivoKey").prop("files")[0];
var contraCertificado = $("#contraCertificado").val();
var logo = $("#logo").prop("files")[0];
$("#btnSaveEmpresa").attr("disabled", true);
var datos = new FormData();
datos.append("idEmpresa", idEmpresa);
datos.append("nombre", nombre);
datos.append("direccion", direccion);
datos.append("telefono", telefono);
datos.append("correoElectronico", correoElectronico);
datos.append("razonSocial", razonSocial);
datos.append("codigoPostal", codigoPostal);
datos.append("rfc", rfc);
datos.append("CURP", CURP);
datos.append("regimenFiscal", regimenFiscal);
datos.append("certificado", certificado);
datos.append("archivoKey", archivoKey);
datos.append("contraCertificado", contraCertificado);
datos.append("logo", logo);
$.ajax({
url: "<?= route_to('admin/empresas/save') ?>",
method: "POST",
data: datos,
cache: false,
contentType: false,
processData: false,
//dataType:"json",
success: function (respuesta) {
if (respuesta.match(/Correctamente.*/)) {
Toast.fire({
icon: 'success',
title: "<?= lang('empresas..msg.msg_save') ?>"
});
tableEmpresas.ajax.reload();
$("#btnSaveEmpresa").removeAttr("disabled");
$('#modalAddEmpresa').modal('hide');
} else {
Toast.fire({
icon: 'error',
title: respuesta
});
$("#btnSaveEmpresa").removeAttr("disabled");
// $('#modalAgregarPaciente').modal('hide');
}
}
}
)
});
/**
* Carga datos actualizar
*/
/*=============================================
EDITAR PACIENTE
=============================================*/
$(".tableEmpresas").on("click", ".btnEditEmpresa", function () {
var idEmpresa = $(this).attr("idEmpresa");
var datos = new FormData();
datos.append("idEmpresa", idEmpresa);
$.ajax({
url: "<?= base_url('admin/empresas/obtenerEmpresa') ?>",
method: "POST",
data: datos,
cache: false,
contentType: false,
processData: false,
dataType: "json",
success: function (respuesta) {
console.log(respuesta);
$("#idEmpresa").val(respuesta["id"]);
$("#nombre").val(respuesta["nombre"]);
$("#direccion").val(respuesta["direccion"]);
$("#rfc").val(respuesta["rfc"]);
$("#telefono").val(respuesta["telefono"]);
$("#diasEntrega").val(respuesta["diasEntrega"]);
$("#caja").val(respuesta["caja"]);
$("#contraCertificado").val(respuesta["contraCertificado"]);
$("#regimenFiscal").val(respuesta["regimenFiscal"]);
$("#regimenFiscal").trigger("change");
$("#razonSocial ").val(respuesta["razonSocial"]);
$("#codigoPostal").val(respuesta["codigoPostal"]);
$("#CURP").val(respuesta["CURP"]);
$("#correoElectronico").val(respuesta["correoElectronico"]);
if (respuesta["logo"] != "") {
$(".previsualizarLogo").attr('src', '<?= base_URL("images/logo") ?>' + '/' + respuesta["logo"]);
}
}
})
})
/*=============================================
ELIMINAR PACIENTE
=============================================*/
$(".tableEmpresas").on("click", ".btn-delete", function () {
var idEmpresa = $(this).attr("data-id");
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: `<?= base_url('admin/empresas') ?>/` + idEmpresa,
method: 'DELETE',
}).done((data, textStatus, jqXHR) => {
Toast.fire({
icon: 'success',
title: jqXHR.statusText,
});
tableEmpresas.ajax.reload();
}).fail((error) => {
Toast.fire({
icon: 'error',
title: error.responseJSON.messages.error,
});
})
}
})
});
$('#regimenFiscal').select2();
/*=============================================
SUBIENDO LA FOTO DEL USUARIO
=============================================*/
$(".logo").change(function () {
var imagen = this.files[0];
/*=============================================
VALIDAMOS EL FORMATO DE LA IMAGEN SEA JPG O PNG
=============================================*/
if (imagen["type"] != "image/png") {
$(".logo").val("");
Toast.fire({
icon: 'error',
title: "<?= lang('empresas.imagenesFormato') ?>",
});
} else if (imagen["size"] > 2000000) {
$(".logo").val("");
Toast.fire({
icon: 'error',
title: "<?= lang('empresas.imagenesPeso') ?>",
});
} else {
var datosImagen = new FileReader;
datosImagen.readAsDataURL(imagen);
$(datosImagen).on("load", function (event) {
var rutaImagen = event.target.result;
$(".previsualizarLogo").attr("src", rutaImagen);
})
}
})
</script>
<?= $this->endSection() ?>
Ahora los archivos de la vista creamos el archivo app/views/modulosEmpresas/facturacionEmpresa.php y dentro de el metemos el siguiente código
<p>
<h3>Datos Facturación</h3>
<div class="form-group row">
<label for="inputName" class="col-sm-2 col-form-label"><?= lang('empresas.fields.razonSocial') ?></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="razonSocial" id="razonSocial" class="form-control <?= session('error.razonSocial') ? 'is-invalid' : '' ?>" value="<?= old('razonSocial') ?>" placeholder="<?= lang('empresas.fields.razonSocial') ?>" autocomplete="off">
</div>
</div>
</div>
<div class="form-group row">
<label for="codigoPostal" class="col-sm-2 col-form-label"><?= lang('empresas.fields.codigoPostal') ?></label>
<div class="col-sm-10">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-location-arrow"></i></span>
</div>
<input type="text" name="codigoPostal" id="codigoPostal"class="form-control <?= session('error.codigoPostal') ? 'is-invalid' : '' ?>" value="<?= old('codigoPostal') ?>" placeholder="<?= lang('empresas.fields.codigoPostal') ?>" autocomplete="off">
</div>
</div>
</div>
<div class="form-group row">
<label for="rfc" class="col-sm-2 col-form-label"><?= lang('empresas.fields.rfc') ?></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="rfc" id="rfc" class="form-control <?= session('error.rfc') ? 'is-invalid' : '' ?>" value="<?= old('rfc') ?>" placeholder="<?= lang('empresas.fields.rfc') ?>" autocomplete="off">
</div>
</div>
</div>
<div class="form-group row">
<label for="CURP" class="col-sm-2 col-form-label"><?= lang('empresas.fields.CURP') ?></label>
<div class="col-sm-10">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="far fa-id-card"></i></span>
</div>
<input type="text" name="CURP" id="CURP" class="form-control <?= session('error.CURP') ? 'is-invalid' : '' ?>" value="<?= old('CURP') ?>" placeholder="<?= lang('empresas.fields.CURP') ?>" autocomplete="off">
</div>
</div>
</div>
<div class="form-group row">
<label for="inputSkills" class="col-sm-2 col-form-label"><?= lang('empresas.fields.regimenFiscal') ?></label>
<div class="col-sm-8">
<select class="form-control select" name="regimenFiscal" id="regimenFiscal" style="width: 100%;">
<option value="0"><?= lang('empresas.fields.regimenFiscalOpcion') ?></option>
<?php
foreach ($regimenesFiscales as $key => $value) {
echo '<option value="' . $value->id() . '">' . $value->id() . ' - ' . $value->texto() . '</option>';
}
?>
</select>
</div>
</div>
<div class="form-group row">
<label for="certificado" class="col-sm-2 col-form-label"><?= lang('empresas.fields.certificado') ?></label>
<div class="col-sm-10">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-award"></i></span>
</div>
<input type="file" name="certificado" id="certificado" class="form-control <?= session('error.certificado') ? 'is-invalid' : '' ?>" value="<?= old('certificado') ?>" placeholder="<?= lang('empresas.fields.correoElectronico') ?>" autocomplete="off">
</div>
</div>
</div>
<div class="form-group row">
<label for="archivoKey" class="col-sm-2 col-form-label"><?= lang('empresas.fields.archivoKey') ?></label>
<div class="col-sm-10">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-key"></i></span>
</div>
<input type="file" name="archivoKey" id="archivoKey" class="form-control <?= session('error.certificado') ? 'is-invalid' : '' ?>" value="<?= old('archivoKey') ?>" placeholder="<?= lang('empresas.fields.archivoKey') ?>" autocomplete="off">
</div>
</div>
</div>
<div class="form-group row">
<label for="contraCertificado" class="col-sm-2 col-form-label"><?= lang('empresas.fields.contraCertificado') ?></label>
<div class="col-sm-10">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-unlock"></i></span>
</div>
<input type="text" name="contraCertificado" id="contraCertificado" class="form-control <?= session('error.contraCertificado') ? 'is-invalid' : '' ?>" value="<?= old('contraCertificado') ?>" placeholder="<?= lang('empresas.fields.contraCertificado') ?>" autocomplete="off">
</div>
</div>
</div>
</p>
Ahora los archivos de la vista creamos el archivo app/views/modulosEmpresas/generalesEmpresa.php y dentro de el metemos el siguiente código
<p>
<h3>Datos Generales</h3>
<div class="form-group row">
<label for="inputName" class="col-sm-2 col-form-label"><?= lang('empresas.fields.nombre') ?></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="hidden" name="idEmpresa" id="idEmpresa" value="0">
<input type="text" name="nombre" id="nombre" class="form-control <?= session('error.nombre') ? 'is-invalid' : '' ?>" value="<?= old('nombre') ?>" placeholder="<?= lang('empresas.fields.nombre') ?>" autocomplete="off">
</div>
</div>
</div>
<div class="form-group row">
<label for="inputName" class="col-sm-2 col-form-label"><?= lang('empresas.fields.direccion') ?></label>
<div class="col-sm-10">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-location-arrow"></i></span>
</div>
<input type="text" name="direccion" id="direccion"class="form-control <?= session('error.direccion') ? 'is-invalid' : '' ?>" value="<?= old('direccion') ?>" placeholder="<?= lang('empresas.fields.direccion') ?>" autocomplete="off">
</div>
</div>
</div>
<div class="form-group row">
<label for="telefono" class="col-sm-2 col-form-label"><?= lang('empresas.fields.telefono') ?></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.telefono') ? 'is-invalid' : '' ?>" value="<?= old('telefono') ?>" placeholder="<?= lang('empresas.fields.telefono') ?>" autocomplete="off">
</div>
</div>
</div>
<div class="form-group row">
<label for="correoElectronico" class="col-sm-2 col-form-label"><?= lang('empresas.fields.correoElectronico') ?></label>
<div class="col-sm-10">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="far 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('empresas.fields.correoElectronico') ?>" autocomplete="off">
</div>
</div>
</div>
</p>
Ahora los archivos de la vista creamos el archivo app/views/modulosEmpresas/logosEmpresa.php y dentro de el metemos el siguiente código
<p>
<h3>Imagenes</h3>
<div class="form-group">
<div class="panel"><?= lang("empresas.fields.logo") ?></div>
<input type="file" class="logo" name="logo" id="logo">
<p class="help-block"><?= lang("empresas.imagenesPesoMaximo") ?></p>
<img src="<?= base_url("images/logo/anonymous.png") ?>" class="img-thumbnail previsualizarLogo" width="100px">
<input type="hidden" name="logoActual" id="logoActual">
</div>
</p>
Ahora los archivos de la vista creamos el archivo app/views/modulosEmpresas/modalCapturaEmpresas.php y dentro de el metemos el siguiente código
<!-- Modal Empresas -->
<div class="modal fade" id="modalAddEmpresa" tabindex="-1" role="dialog" aria-labelledby="modalAddEmpresa" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?= lang('empresas.createEdit') ?></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="home-tab" data-toggle="tab" data-target="#generales" type="button" role="tab" aria-controls="home" aria-selected="true">Generales</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="profile-tab" data-toggle="tab" data-target="#datosFacturacion" type="button" role="tab" aria-controls="profile" aria-selected="false">Facturacion</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="contact-tab" data-toggle="tab" data-target="#contact" type="button" role="tab" aria-controls="contact" aria-selected="false">Logos / Imagenes</button>
</li>
</ul>
<form id="form-empresa" class="form-horizontal">
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="generales" role="tabpanel" aria-labelledby="generales">
<?= $this->include('modulosEmpresas/generalesEmpresa') ?>
</div>
<div class="tab-pane fade" id="datosFacturacion" role="tabpanel" aria-labelledby="datosFacturacion">
<?= $this->include('modulosEmpresas/facturacionEmpresa') ?>
</div>
<div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">
<?= $this->include('modulosEmpresas/logosEmpresa') ?>
</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="btnSaveEmpresa"><?= lang('boilerplate.global.save') ?></button>
</div>
</div>
</div>
</div>
<?= $this->section('js') ?>
<script>
$(document).on('click', '.btnAddEmpresa', function (e) {
console.log("asd");
$(".form-control").val("");
$("#idEmpresa").val("0");
$(".previsualizarLogo").attr('src','<?= base_URL("images/logo") ?>/anonymous.png' );
$("#btnSaveEmpresa").removeAttr("disabled");
});
/*
* AL hacer click al editar
*/
$(document).on('click', '.btnEditarEmpresa', function (e) {
var idEmpresa = $(this).attr("idEmpresa");
//LIMPIAMOS CONTROLES
$(".form-control").val("");
$("#idEmpresa").val(idEmpresa);
$("#btnGuardarEmpresa").removeAttr("disabled");
});
</script>
<?= $this->endSection() ?>
En el archivo app/config/routes.php quedaria de la siguiente forma
$routes->group('admin', function ($routes) {
$routes->resource('empresas', [
'filter' => 'permission:empresas-permisos',
'controller' => 'EmpresasController',
'except' => 'show'
]);
$routes->post('empresas/save', 'EmpresasController::save');
$routes->post('empresas/obtenerEmpresa', 'EmpresasController::obtenerEmpresa');
});
En los archivos de lenguaje para ingles creamos el archivo app/Language/en/empresas.php con el siguiente contenido
<?php
$empresas["logDescription"] = "The companie was saved with the following data:";
$empresas["logUpdate"] = "The companie was updated with the following data:";
$empresas["logDeleted"] = "The companie was deleted with the following data:";
$empresas["msg_delete"] = "The companie was deleted correctly:";
$empresas["add"] = "Add companie";
$empresas["edit"] = "Edit companie";
$empresas["createEdit"] = "Create / Edith";
$empresas["title"] = "companie management";
$empresas["subtitle"] = "companie list";
$empresas["fields"]["nombre"] = "Name";
$empresas["fields"]["direccion"] = "direction";
$empresas["fields"]["rfc"] = "RFC";
$empresas["fields"]["logo"] = "logo";
$empresas["fields"]["certificado"] = "certificate";
$empresas["fields"]["archivoKey"] = "KeyFile";
$empresas["fields"]["contraCertificado"] = "Password Certificate";
$empresas["fields"]["regimenFiscal"] = "Tax Regime";
$empresas["fields"]["regimenFiscalOpcion"] = "Select tax regime";
$empresas["fields"]["razonSocial "] = "Business name";
$empresas["fields"]["codigoPostal "] = "Postal Code ";
$empresas["fields"]["CURP"] = "CURP";
$empresas["fields"]["Created_at"] = "Created At";
$empresas["fields"]["Update_At"] = "Update At";
$empresas["msg"]["msg_save"] = "The companie has been correctly saved.";
$empresas["msg"]["msg_insert"] = "The companie has been correctly added.";
$empresas["msg"]["msg_update"] = "The companie has been correctly modified.";
$empresas["msg"]["msg_delete"] = "The companie has been correctly deleted.";
$empresas["msg"]["msg_get"] = "The companie has been successfully get.";
$empresas["msg"]["msg_get_fail"] = "The vehicle not found or already deleted.";
$empresas["imagenesFormato"] = "The image must be in PNG format!";
$empresas["imagenesPeso"] = "The image must not be larger than 2MB!";
$empresas["imagenesPesoMaximo"] = "Maximum weight of the photo 1MB";
$empresas["certExtensionIncorrect"] = "Extensión certificate incorrect";
$empresas["keyFileExtensionIncorrect"] = "Extensión key file incorrect";
$empresas["pngFileExtensionIncorrect"] = "This image not is PNG";
return $empresas;
En los archivos de lenguaje para ingles creamos el archivo app/Language/es/empresas.php con el siguiente contenido
<?php
$empresas["logDescription"] = "El Empresa ha sido guardado con los siguientes datos:";
$empresas["logUpdate"] = "EL Empresa ha sido actualizado con los siguientes datos";
$empresas["logDeleted"] = "El Empresa ha sido eliminado con los siguientes datos:";
$empresas["add"] = "Agregar Empresa";
$empresas["edit"] = "Editar Empresa";
$empresas["createEdit"] = "Crear / Editar";
$empresas["title"] = "Administración de Empresas";
$empresas["subtitle"] = "Lista de Empresas";
$empresas["fields"]["nombre"] = "Nombre";
$empresas["fields"]["direccion"] = "Direccion";
$empresas["fields"]["rfc"] = "RFC";
$empresas["fields"]["logo"] = "Logo";
$empresas["fields"]["certificado"] = "Certificado";
$empresas["fields"]["archivoKey"] = "Archivo Key";
$empresas["fields"]["telefono"] = "Telefono";
$empresas["fields"]["contraCertificado"] = "Contra Certificado";
$empresas["fields"]["regimenFiscal"] = "Regimen Fiscal";
$empresas["fields"]["regimenFiscalOpcion"] = "Seleccionar regimen fiscal";
$empresas["fields"]["razonSocial"] = "Razon Social";
$empresas["fields"]["codigoPostal"] = "Código Postal";
$empresas["fields"]["CURP"] = "CURP";
$empresas["fields"]["correoElectronico"] = "Correo Electronico";
$empresas["fields"]["acciones"] = "Acciones";
$empresas["msg"]["msg_save"] = "La Empresa ha sido correctamente guardada.";
$empresas["msg"]["msg_insert"] = "La Empresa ha sido correctamente agregado.";
$empresas["msg"]["msg_update"] = "La Empresa ha sido correctamente actualizado.";
$empresas["msg"]["msg_delete"] = "La Empresa ha sido correctamente eliminado.";
$empresas["msg"]["msg_get"] = "La Empresa ha sido correctamente obtenido.";
$empresas["msg"]["msg_get_fail"] = "No se encontro Empresa o fue eliminado.";
// Validations
$empresas["imagenesFormato"] = "¡La imagen debe estar en formato PNG!";
$empresas["imagenesPeso"] = "¡La imagen no debe pesar más de 2MB!";
$empresas["imagenesPesoMaximo"] = "Peso máximo de la foto 1MB";
$empresas["certExtensionIncorrect"] = "Extensión del certificado incorrecto";
$empresas["keyFileExtensionIncorrect"] = "Extensión del archivo key incorrecto";
$empresas["pngFileExtensionIncorrect"] = "Solo se permiten imagenes con formato png";
return $empresas;
Creamos el siguiente directorio para las imagenes, public/images/logo
Creamos el archivo app/databe/migrations/2023-02-14001801_Empresas.php con el siguiente contenido, este nos servirá para crear la tabla
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class Empresas extends Migration {
public function up() {
// Empresas
$this->forge->addField([
'id' => ['type' => 'int', 'constraint' => 11, 'unsigned' => true, 'auto_increment' => true],
'nombre' => ['type' => 'varchar', 'constraint' => 500, 'null' => false],
'direccion' => ['type' => 'varchar', 'constraint' => 30, 'null' => true],
'rfc' => ['type' => 'varchar', 'constraint' => 14, 'null' => false],
'telefono' => ['type' => 'varchar', 'constraint' => 255, 'null' => true],
'correoElectronico' => ['type' => 'varchar', 'constraint' => 256, 'null' => true],
'diasEntrega' => ['type' => 'varchar', 'constraint' => 8, 'null' => true],
'caja' => ['type' => 'varchar', 'constraint' => 255, 'null' => true],
'logo' => ['type' => 'varchar', 'constraint' => 1024, 'null' => true],
'certificado' => ['type' => 'varchar', 'constraint' => 1024, 'null' => true],
'archivoKey' => ['type' => 'varchar', 'constraint' => 68, 'null' => true],
'contraCertificado' => ['type' => 'varchar', 'constraint' => 68, 'null' => true],
'regimenFiscal' => ['type' => 'varchar', 'constraint' => 68, 'null' => true],
'razonSocial' => ['type' => 'varchar', 'constraint' => 68, 'null' => true],
'codigoPostal' => ['type' => 'varchar', 'constraint' => 68, 'null' => true],
'CURP' => ['type' => 'varchar', 'constraint' => 68, '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('empresas', true);
}
public function down() {
$this->forge->dropTable('empresas', true);
}
}
Creamos el modelo para la bitacora app/models/LogModel.php con el siguiente contenido
<?php
namespace App\Models;
use CodeIgniter\Model;
class LogModel extends Model
{
protected $table = 'log';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $returnType = 'array';
protected $useSoftDeletes = true;
protected $allowedFields = ['id','description', 'user',"created_at","updated_at"];
protected $useTimestamps = true;
protected $createdField = 'created_at';
protected $deletedField = 'deleted_at';
protected $validationRules = [];
protected $validationMessages = [];
protected $skipValidation = false;
}
Creamos el archivo de migración para LogModel en app/database/migration/2023-02-07-165412_Log.php con el siguiente contenido
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class Log extends Migration
{
public function up()
{
$this->forge->addField([
'id' => [
'type' => 'INT',
'constraint' => 5,
'unsigned' => true,
'auto_increment' => true,
],
'description' => [
'type' => 'VARCHAR',
'constraint' => '256',
],
'user' => [
'type' => 'TEXT',
'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('log', true);
}
public function down()
{
$this->forge->dropTable('log');
}
}
Por ultimo corremos el siguiente código en la terminal para correr la migración y así nos genere la tabla empresas y bitacora en la base de datos
php spark migrate
