diff --git a/ci4/app/Config/Routes.php b/ci4/app/Config/Routes.php
index cd29dcfc..e3b35125 100755
--- a/ci4/app/Config/Routes.php
+++ b/ci4/app/Config/Routes.php
@@ -33,7 +33,7 @@ $routes->group('settings', ['namespace' => 'App\Controllers\Sistema'], function
* --------------------------------------------------------------------
*/
-/* Rutas para configuraciones */
+/* Rutas para tarifas */
$routes->group('tarifas', ['namespace' => 'App\Controllers\Tarifas'], function ($routes) {
/* Cliente */
@@ -54,6 +54,33 @@ $routes->group('tarifas', ['namespace' => 'App\Controllers\Tarifas'], function (
});
+/* Rutas para configuraciones */
+$routes->group('configuracion', ['namespace' => 'App\Controllers\Configuracion'], function ($routes) {
+
+ /* Ubicaciones */
+ $routes->group('ubicaciones', ['namespace' => 'App\Controllers\Configuracion'], function ($routes) {
+
+ $routes->get('', 'Ubicaciones::index', ['as' => 'ubicacionesList']);
+ $routes->match(['get', 'post'], 'add', 'Ubicaciones::add', ['as' => 'ubicacionesAdd']);
+ $routes->match(['get', 'post'], 'edit/(:num)', 'Ubicaciones::edit/$1', ['as' => 'ubicacionesEdit']);
+ $routes->get('delete/(:num)', 'Ubicaciones::delete/$1', ['as' => 'ubicacionesDelete']);
+ $routes->post('datatable', 'Ubicaciones::datatable', ['as' => 'ubicacionesDT']);
+
+ });
+
+ /* Series Factura */
+ $routes->group('series-facturas', ['namespace' => 'App\Controllers\Configuracion'], function ($routes) {
+
+ $routes->get('', 'SeriesFacturas::index', ['as' => 'seriesFacturasList']);
+ $routes->match(['get', 'post'], 'add', 'SeriesFacturas::add', ['as' => 'seriesFacturasAdd']);
+ $routes->match(['get', 'post'], 'edit/(:num)', 'SeriesFacturas::edit/$1', ['as' => 'seriesFacturasEdit']);
+ $routes->get('delete/(:num)', 'SeriesFacturas::delete/$1', ['as' => 'seriesFacturasDelete']);
+ $routes->post('datatable', 'SeriesFacturas::datatable', ['as' => 'seriesFacturasDT']);
+
+ });
+
+});
+
$routes->group('users', ['namespace' => 'App\Controllers\Configuracion'], function ($routes) {
$routes->get('', 'Users::index', ['as' => 'userList']);
diff --git a/ci4/app/Controllers/Configuracion/SeriesFacturas.php b/ci4/app/Controllers/Configuracion/SeriesFacturas.php
new file mode 100644
index 00000000..b5e0faef
--- /dev/null
+++ b/ci4/app/Controllers/Configuracion/SeriesFacturas.php
@@ -0,0 +1,257 @@
+viewData['pageTitle'] = lang('SeriesFacturas.moduleTitle');
+ $this->viewData['usingSweetAlert'] = true;
+
+ // Breadcrumbs (IMN)
+ $this->viewData['breadcrumb'] = [
+ ['title' => lang("App.menu_configuration"), 'route' => "javascript:void(0);", 'active' => false],
+ ['title' => lang("App.menu_series_facturas"), 'route' => route_to('seriesFacturasList'), 'active' => true]
+ ];
+
+ parent::initController($request, $response, $logger);
+ }
+
+
+ public function index()
+ {
+
+ $viewData = [
+ 'currentModule' => static::$controllerSlug,
+ 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('SeriesFacturas.moduleTitle')]),
+ 'seriesFacturasEntity' => new SeriesFacturasEntity(),
+ 'usingServerSideDataTable' => true,
+
+ ];
+
+ $viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
+
+ return view(static::$viewPath . 'viewSeriesFacturasList', $viewData);
+ }
+
+
+ public function add()
+ {
+ if ($this->request->getPost()) :
+
+ $postData = $this->request->getPost();
+
+ $sanitizedData = $this->sanitized($postData, true);
+
+ $noException = true;
+ if ($successfulResult = $this->canValidate()) :
+
+
+ if ($this->canValidate()) :
+ try {
+ $successfulResult = $this->model->skipValidation(true)->save($sanitizedData);
+ } catch (\Exception $e) {
+ $noException = false;
+ $this->dealWithException($e);
+ }
+ else:
+ $this->viewData['errorMessage'] = lang('Basic.global.formErr1', [lang('Basic.global.record')]);
+ $this->session->setFlashdata('formErrors', $this->model->errors());
+ endif;
+
+ $thenRedirect = true; // Change this to false if you want your user to stay on the form after submission
+ endif;
+ if ($noException && $successfulResult) :
+
+ $id = $this->model->db->insertID();
+
+ $message = lang('Basic.global.saveSuccess', [lang('Basic.global.record')]) . '.';
+
+ if ($thenRedirect) :
+ if (!empty($this->indexRoute)) :
+ return redirect()->to(route_to($this->indexRoute))->with('sweet-success', $message);
+ else:
+ return $this->redirect2listView('sweet-success', $message);
+ endif;
+ else:
+ $this->session->setFlashData('sweet-success', $message);
+ endif;
+
+ endif; // $noException && $successfulResult
+
+ endif; // ($requestMethod === 'post')
+
+ $this->viewData['seriesFacturasEntity'] = isset($sanitizedData) ? new SeriesFacturasEntity($sanitizedData) : new SeriesFacturasEntity();
+ $this->viewData['formAction'] = route_to('seriesFacturasAdd');
+ $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('SeriesFacturas.moduleTitle') . ' ' . lang('Basic.global.addNewSuffix');
+
+
+ return $this->displayForm(__METHOD__);
+ } // end function add()
+
+ public function edit($requestedId = null)
+ {
+
+ if ($requestedId == null) :
+ return $this->redirect2listView();
+ endif;
+ $id = filter_var($requestedId, FILTER_SANITIZE_URL);
+ $seriesFacturasEntity = $this->model->find($id);
+
+ if ($seriesFacturasEntity == false) :
+ $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('SeriesFacturas.moduleTitle')), $id]);
+ return $this->redirect2listView('sweet-error', $message);
+ endif;
+
+ if ($this->request->getPost()) :
+
+ $postData = $this->request->getPost();
+
+ $sanitizedData = $this->sanitized($postData, true);
+ if ($this->request->getPost('show_erp') == null) {
+ $sanitizedData['show_erp'] = false;
+ }
+
+ $noException = true;
+ if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) :
+
+ if ($this->canValidate()) :
+ try {
+ $successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData);
+ } catch (\Exception $e) {
+ $noException = false;
+ $this->dealWithException($e);
+ }
+ else:
+ $this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('SeriesFacturas.moduleTitle'))]);
+ $this->session->setFlashdata('formErrors', $this->model->errors());
+
+ endif;
+
+ $seriesFacturasEntity->fill($sanitizedData);
+ $thenRedirect = false;
+ endif;
+ if ($noException && $successfulResult) :
+ $id = $seriesFacturasEntity->id ?? $id;
+ $message = lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.';
+
+ if ($thenRedirect) :
+ if (!empty($this->indexRoute)) :
+ return redirect()->to(route_to($this->indexRoute))->with('sweet-success', $message);
+ else:
+ return $this->redirect2listView('sweet-success', $message);
+ endif;
+ else:
+ $this->session->setFlashData('sweet-success', $message);
+ endif;
+
+ endif; // $noException && $successfulResult
+ endif; // ($requestMethod === 'post')
+
+ $this->viewData['seriesFacturasEntity'] = $seriesFacturasEntity;
+ $this->viewData['formAction'] = route_to('seriesFacturasEdit', $id);
+ $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('SeriesFacturas.moduleTitle') . ' ' . lang('Basic.global.edit3');
+
+ return $this->displayForm(__METHOD__, $id);
+ } // end function edit(...)
+
+
+ public function datatable()
+ {
+ if ($this->request->isAJAX()) {
+ $reqData = $this->request->getPost();
+ if (!isset($reqData['draw']) || !isset($reqData['columns'])) {
+ $errstr = 'No data available in response to this specific request.';
+ $response = $this->respond(Collection::datatable([], 0, 0, $errstr), 400, $errstr);
+ return $response;
+ }
+ $start = $reqData['start'] ?? 0;
+ $length = $reqData['length'] ?? 5;
+ $search = $reqData['search']['value'];
+ $requestedOrder = $reqData['order']['0']['column'] ?? 1;
+ $order = SeriesFacturasModel::SORTABLE[$requestedOrder > 0 ? $requestedOrder : 1];
+ $dir = $reqData['order']['0']['dir'] ?? 'asc';
+
+ $resourceData = $this->model->getResource($search)->orderBy($order, $dir)->limit($length, $start)->get()->getResultObject();
+
+ return $this->respond(Collection::datatable(
+ $resourceData,
+ $this->model->getResource()->countAllResults(),
+ $this->model->getResource($search)->countAllResults()
+ ));
+ } else {
+ return $this->failUnauthorized('Invalid request', 403);
+ }
+ }
+
+ public function allItemsSelect()
+ {
+ if ($this->request->isAJAX()) {
+ $onlyActiveOnes = true;
+ $reqVal = $this->request->getPost('val') ?? 'id';
+ $menu = $this->model->getAllForMenu($reqVal . ', nombre', 'nombre', $onlyActiveOnes, false);
+ $nonItem = new \stdClass;
+ $nonItem->id = '';
+ $nonItem->nombre = '- ' . lang('Basic.global.None') . ' -';
+ array_unshift($menu, $nonItem);
+
+ $newTokenHash = csrf_hash();
+ $csrfTokenName = csrf_token();
+ $data = [
+ 'menu' => $menu,
+ $csrfTokenName => $newTokenHash
+ ];
+ return $this->respond($data);
+ } else {
+ return $this->failUnauthorized('Invalid request', 403);
+ }
+ }
+
+ public function menuItems()
+ {
+ if ($this->request->isAJAX()) {
+ $searchStr = goSanitize($this->request->getPost('searchTerm'))[0];
+ $reqId = goSanitize($this->request->getPost('id'))[0];
+ $reqText = goSanitize($this->request->getPost('text'))[0];
+ $onlyActiveOnes = false;
+ $columns2select = [$reqId ?? 'id', $reqText ?? 'nombre'];
+ $onlyActiveOnes = false;
+ $menu = $this->model->getSelect2MenuItems($columns2select, $columns2select[1], $onlyActiveOnes, $searchStr);
+ $nonItem = new \stdClass;
+ $nonItem->id = '';
+ $nonItem->text = '- ' . lang('Basic.global.None') . ' -';
+ array_unshift($menu, $nonItem);
+
+ $newTokenHash = csrf_hash();
+ $csrfTokenName = csrf_token();
+ $data = [
+ 'menu' => $menu,
+ $csrfTokenName => $newTokenHash
+ ];
+ return $this->respond($data);
+ } else {
+ return $this->failUnauthorized('Invalid request', 403);
+ }
+ }
+
+}
diff --git a/ci4/app/Controllers/Configuracion/Ubicaciones.php b/ci4/app/Controllers/Configuracion/Ubicaciones.php
new file mode 100644
index 00000000..1e22b95a
--- /dev/null
+++ b/ci4/app/Controllers/Configuracion/Ubicaciones.php
@@ -0,0 +1,257 @@
+viewData['pageTitle'] = lang('Ubicaciones.moduleTitle');
+ $this->viewData['usingSweetAlert'] = true;
+
+ // Breadcrumbs (IMN)
+ $this->viewData['breadcrumb'] = [
+ ['title' => lang("App.menu_configuration"), 'route' => "javascript:void(0);", 'active' => false],
+ ['title' => lang("App.menu_ubicaciones"), 'route' => route_to('ubicacionesList'), 'active' => true]
+ ];
+
+ parent::initController($request, $response, $logger);
+ }
+
+
+ public function index()
+ {
+
+ $viewData = [
+ 'currentModule' => static::$controllerSlug,
+ 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Ubicaciones.pais')]),
+ 'ubicacionesEntity' => new UbicacionesEntity(),
+ 'usingServerSideDataTable' => true,
+
+ ];
+
+ $viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class
+
+ return view(static::$viewPath . 'viewUbicacionesList', $viewData);
+ }
+
+
+ public function add()
+ {
+ if ($this->request->getPost()) :
+
+ $postData = $this->request->getPost();
+
+ $sanitizedData = $this->sanitized($postData, true);
+
+ $noException = true;
+ if ($successfulResult = $this->canValidate()) :
+
+
+ if ($this->canValidate()) :
+ try {
+ $successfulResult = $this->model->skipValidation(true)->save($sanitizedData);
+ } catch (\Exception $e) {
+ $noException = false;
+ $this->dealWithException($e);
+ }
+ else:
+ $this->viewData['errorMessage'] = lang('Basic.global.formErr1', [lang('Basic.global.record')]);
+ $this->session->setFlashdata('formErrors', $this->model->errors());
+ endif;
+
+ $thenRedirect = true; // Change this to false if you want your user to stay on the form after submission
+ endif;
+ if ($noException && $successfulResult) :
+
+ $id = $this->model->db->insertID();
+
+ $message = lang('Basic.global.saveSuccess', [lang('Basic.global.record')]) . '.';
+
+ if ($thenRedirect) :
+ if (!empty($this->indexRoute)) :
+ return redirect()->to(route_to($this->indexRoute))->with('sweet-success', $message);
+ else:
+ return $this->redirect2listView('sweet-success', $message);
+ endif;
+ else:
+ $this->session->setFlashData('sweet-success', $message);
+ endif;
+
+ endif; // $noException && $successfulResult
+
+ endif; // ($requestMethod === 'post')
+
+ $this->viewData['ubicacionesEntity'] = isset($sanitizedData) ? new UbicacionesEntity($sanitizedData) : new UbicacionesEntity();
+ $this->viewData['formAction'] = route_to('ubicacionesAdd');
+ $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('Ubicaciones.moduleTitle') . ' ' . lang('Basic.global.addNewSuffix');
+
+
+ return $this->displayForm(__METHOD__);
+ } // end function add()
+
+ public function edit($requestedId = null)
+ {
+
+ if ($requestedId == null) :
+ return $this->redirect2listView();
+ endif;
+ $id = filter_var($requestedId, FILTER_SANITIZE_URL);
+ $ubicacionesEntity = $this->model->find($id);
+
+ if ($ubicacionesEntity == false) :
+ $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Ubicaciones.moduleTitle')), $id]);
+ return $this->redirect2listView('sweet-error', $message);
+ endif;
+
+ if ($this->request->getPost()) :
+
+ $postData = $this->request->getPost();
+
+ $sanitizedData = $this->sanitized($postData, true);
+ if ($this->request->getPost('show_erp') == null) {
+ $sanitizedData['show_erp'] = false;
+ }
+
+ $noException = true;
+ if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) :
+
+ if ($this->canValidate()) :
+ try {
+ $successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData);
+ } catch (\Exception $e) {
+ $noException = false;
+ $this->dealWithException($e);
+ }
+ else:
+ $this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Ubicaciones.moduleTitle'))]);
+ $this->session->setFlashdata('formErrors', $this->model->errors());
+
+ endif;
+
+ $ubicacionesEntity->fill($sanitizedData);
+ $thenRedirect = false;
+ endif;
+ if ($noException && $successfulResult) :
+ $id = $ubicacionesEntity->id ?? $id;
+ $message = lang('Basic.global.updateSuccess', [lang('Basic.global.record')]) . '.';
+
+ if ($thenRedirect) :
+ if (!empty($this->indexRoute)) :
+ return redirect()->to(route_to($this->indexRoute))->with('sweet-success', $message);
+ else:
+ return $this->redirect2listView('sweet-success', $message);
+ endif;
+ else:
+ $this->session->setFlashData('sweet-success', $message);
+ endif;
+
+ endif; // $noException && $successfulResult
+ endif; // ($requestMethod === 'post')
+
+ $this->viewData['ubicacionesEntity'] = $ubicacionesEntity;
+ $this->viewData['formAction'] = route_to('ubicacionesEdit', $id);
+ $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Ubicaciones.moduleTitle') . ' ' . lang('Basic.global.edit3');
+
+ return $this->displayForm(__METHOD__, $id);
+ } // end function edit(...)
+
+
+ public function datatable()
+ {
+ if ($this->request->isAJAX()) {
+ $reqData = $this->request->getPost();
+ if (!isset($reqData['draw']) || !isset($reqData['columns'])) {
+ $errstr = 'No data available in response to this specific request.';
+ $response = $this->respond(Collection::datatable([], 0, 0, $errstr), 400, $errstr);
+ return $response;
+ }
+ $start = $reqData['start'] ?? 0;
+ $length = $reqData['length'] ?? 5;
+ $search = $reqData['search']['value'];
+ $requestedOrder = $reqData['order']['0']['column'] ?? 1;
+ $order = UbicacionesModel::SORTABLE[$requestedOrder > 0 ? $requestedOrder : 1];
+ $dir = $reqData['order']['0']['dir'] ?? 'asc';
+
+ $resourceData = $this->model->getResource($search)->orderBy($order, $dir)->limit($length, $start)->get()->getResultObject();
+
+ return $this->respond(Collection::datatable(
+ $resourceData,
+ $this->model->getResource()->countAllResults(),
+ $this->model->getResource($search)->countAllResults()
+ ));
+ } else {
+ return $this->failUnauthorized('Invalid request', 403);
+ }
+ }
+
+ public function allItemsSelect()
+ {
+ if ($this->request->isAJAX()) {
+ $onlyActiveOnes = true;
+ $reqVal = $this->request->getPost('val') ?? 'id';
+ $menu = $this->model->getAllForMenu($reqVal . ', nombre', 'nombre', $onlyActiveOnes, false);
+ $nonItem = new \stdClass;
+ $nonItem->id = '';
+ $nonItem->nombre = '- ' . lang('Basic.global.None') . ' -';
+ array_unshift($menu, $nonItem);
+
+ $newTokenHash = csrf_hash();
+ $csrfTokenName = csrf_token();
+ $data = [
+ 'menu' => $menu,
+ $csrfTokenName => $newTokenHash
+ ];
+ return $this->respond($data);
+ } else {
+ return $this->failUnauthorized('Invalid request', 403);
+ }
+ }
+
+ public function menuItems()
+ {
+ if ($this->request->isAJAX()) {
+ $searchStr = goSanitize($this->request->getPost('searchTerm'))[0];
+ $reqId = goSanitize($this->request->getPost('id'))[0];
+ $reqText = goSanitize($this->request->getPost('text'))[0];
+ $onlyActiveOnes = false;
+ $columns2select = [$reqId ?? 'id', $reqText ?? 'nombre'];
+ $onlyActiveOnes = false;
+ $menu = $this->model->getSelect2MenuItems($columns2select, $columns2select[1], $onlyActiveOnes, $searchStr);
+ $nonItem = new \stdClass;
+ $nonItem->id = '';
+ $nonItem->text = '- ' . lang('Basic.global.None') . ' -';
+ array_unshift($menu, $nonItem);
+
+ $newTokenHash = csrf_hash();
+ $csrfTokenName = csrf_token();
+ $data = [
+ 'menu' => $menu,
+ $csrfTokenName => $newTokenHash
+ ];
+ return $this->respond($data);
+ } else {
+ return $this->failUnauthorized('Invalid request', 403);
+ }
+ }
+
+}
diff --git a/ci4/app/Entities/Configuracion/SeriesFacturasEntity.php b/ci4/app/Entities/Configuracion/SeriesFacturasEntity.php
new file mode 100644
index 00000000..f2d1f7fc
--- /dev/null
+++ b/ci4/app/Entities/Configuracion/SeriesFacturasEntity.php
@@ -0,0 +1,21 @@
+ null,
+ 'nombre' => null,
+ 'tipo' => 'facturacion', // default value
+ 'formato' => null,
+ 'next' => 1, // default value
+ 'grupo' => 0, // default value
+ 'created_at' => null, // default value
+ 'updated_at' => null, // default value
+ ];
+ protected $casts = [
+
+ ];
+}
diff --git a/ci4/app/Entities/Configuracion/UbicacionesEntity.php b/ci4/app/Entities/Configuracion/UbicacionesEntity.php
new file mode 100644
index 00000000..356f62ff
--- /dev/null
+++ b/ci4/app/Entities/Configuracion/UbicacionesEntity.php
@@ -0,0 +1,16 @@
+ null,
+ 'nombre' => null,
+ 'deleted_at' => null, // default value
+ ];
+ protected $casts = [
+
+ ];
+}
diff --git a/ci4/app/Language/es/App.php b/ci4/app/Language/es/App.php
index 462f8011..15882bbe 100755
--- a/ci4/app/Language/es/App.php
+++ b/ci4/app/Language/es/App.php
@@ -688,7 +688,8 @@ return [
"menu_maquina_defecto" => "Maquinas por defecto",
"menu_papelgenerico" => "Papel generico",
"menu_papelimpresion" => "Papel impresión",
- "menu_seriefactura" => "Series facturas",
+ "menu_series_facturas" => "Series facturas",
+ "menu_ubicaciones" => "Ubicaciones",
"menu_serviciocliente" => "Servicio cliente",
"menu_tamanioformatos" => "Tamaño formatos",
"menu_tamaniolibros" => "Tamaño libros",
diff --git a/ci4/app/Language/es/RolesPermisos.php b/ci4/app/Language/es/RolesPermisos.php
index dd344bfa..9bb17931 100644
--- a/ci4/app/Language/es/RolesPermisos.php
+++ b/ci4/app/Language/es/RolesPermisos.php
@@ -42,6 +42,8 @@ return [
'papelImpresionSection' => 'Papel impresión',
'usuariosSection' => 'Usuarios',
'rolesPermisosSection' => 'Roles y permisos',
+ 'ubicacionesSection' => 'Ubicaciones',
+ 'seriesFacturasSection' => 'Series facturas',
'ajustesSection' => 'Ajustes',
'actividadSection' => 'Accesos',
diff --git a/ci4/app/Language/es/SeriesFacturas.php b/ci4/app/Language/es/SeriesFacturas.php
new file mode 100644
index 00000000..3169eaaf
--- /dev/null
+++ b/ci4/app/Language/es/SeriesFacturas.php
@@ -0,0 +1,24 @@
+ 'ID',
+ 'moduleTitle' => 'Series Facturas',
+ 'nombre' => 'Nombre',
+ 'tipo' => 'Tipo',
+ 'formato' => 'Formato',
+ 'next' => 'Próxima',
+ 'grupo' => 'Grupo',
+ 'validation' => [
+ 'id' => [
+ 'max_length' => 'El campo {field} no puede exceder {param} caracteres en longitud.',
+ ],
+
+ 'nombre' => [
+ 'max_length' => 'El campo {field} no puede exceder {param} caracteres en longitud.',
+ 'required' => 'El campo {field} es obligatorio.',
+ ],
+
+ ],
+
+];
\ No newline at end of file
diff --git a/ci4/app/Language/es/Ubicaciones.php b/ci4/app/Language/es/Ubicaciones.php
new file mode 100644
index 00000000..6146beaf
--- /dev/null
+++ b/ci4/app/Language/es/Ubicaciones.php
@@ -0,0 +1,21 @@
+ 'ID',
+ 'moduleTitle' => 'Ubicaciones',
+ 'nombre' => 'Nombre',
+ 'validation' => [
+ 'id' => [
+ 'max_length' => 'El campo {field} no puede exceder {param} caracteres en longitud.',
+ ],
+
+ 'nombre' => [
+ 'max_length' => 'El campo {field} no puede exceder {param} caracteres en longitud.',
+ 'required' => 'El campo {field} es obligatorio.',
+ ],
+
+ ],
+
+];
\ No newline at end of file
diff --git a/ci4/app/Models/Configuracion/SeriesFacturasModel.php b/ci4/app/Models/Configuracion/SeriesFacturasModel.php
new file mode 100644
index 00000000..0999b0a4
--- /dev/null
+++ b/ci4/app/Models/Configuracion/SeriesFacturasModel.php
@@ -0,0 +1,94 @@
+ "t1.id",
+ 2 => "t1.nombre",
+ 3 => "t1.tipo",
+ 4 => "t1.formato",
+ 5 => "t1.next",
+ 6 => "t1.grupo"
+ ];
+
+ protected $allowedFields = ["nombre", "tipo", "formato", "next", "grupo"];
+ protected $returnType = "App\Entities\Configuracion\SeriesFacturasEntity";
+
+ public static $labelField = "nombre";
+
+ protected $validationRules = [
+ "nombre" => [
+ "label" => "SeriesFacturas.nombre",
+ "rules" => "trim|required|max_length[255]",
+ ],
+ "tipo" => [
+ "label" => "SeriesFacturas.tipo",
+ "rules" => "required",
+ ],
+ "formato" => [
+ "label" => "SeriesFacturas.nombre",
+ "rules" => "trim|required|max_length[255]",
+ ],
+ "next" => [
+ "label" => "SeriesFacturas.next",
+ "rules" => "required",
+ ]
+ ];
+
+ protected $validationMessages = [
+ "nombre" => [
+ "max_length" => "SeriesFacturas.validation.nombre.max_length",
+ "required" => "SeriesFacturas.validation.nombre.required",
+ ],
+ "tipo" => [
+ "required" => "SeriesFacturas.validation.tipo.required",
+ ],
+ "formato" => [
+ "max_length" => "SeriesFacturas.validation.formato.max_length",
+ "required" => "SeriesFacturas.validation.formato.required",
+ ],
+ "next" => [
+ "required" => "SeriesFacturas.validation.next.required",
+ ],
+
+ ];
+
+ /**
+ * Get resource data.
+ *
+ * @param string $search
+ *
+ * @return \CodeIgniter\Database\BaseBuilder
+ */
+ public function getResource(string $search = "")
+ {
+ $builder = $this->db
+ ->table($this->table . " t1")
+ ->select(
+ "t1.id AS id, t1.nombre AS nombre, t1.tipo AS tipo, t1.formato AS formato,
+ t1.next AS next, t1.grupo AS grupo"
+ );
+
+ return empty($search)
+ ? $builder
+ : $builder
+ ->groupStart()
+ ->like("t1.id", $search)
+ ->orLike("t1.nombre", $search)
+ ->orLike("t1.tipo", $search)
+ ->orLike("t1.formato", $search)
+ ->orLike("t1.next", $search)
+ ->orLike("t1.grupo", $search)
+ ->groupEnd();
+ }
+}
diff --git a/ci4/app/Models/Configuracion/UbicacionesModel.php b/ci4/app/Models/Configuracion/UbicacionesModel.php
new file mode 100644
index 00000000..680cbf3f
--- /dev/null
+++ b/ci4/app/Models/Configuracion/UbicacionesModel.php
@@ -0,0 +1,62 @@
+ "t1.id",
+ 2 => "t1.nombre"
+ ];
+
+ protected $allowedFields = ["nombre"];
+ protected $returnType = "App\Entities\Configuracion\UbicacionesEntity";
+
+ public static $labelField = "nombre";
+
+ protected $validationRules = [
+ "nombre" => [
+ "label" => "Paises.nombre",
+ "rules" => "trim|required|max_length[255]",
+ ]
+ ];
+
+ protected $validationMessages = [
+ "nombre" => [
+ "max_length" => "Paises.validation.nombre.max_length",
+ "required" => "Paises.validation.nombre.required",
+ ]
+ ];
+
+ /**
+ * Get resource data.
+ *
+ * @param string $search
+ *
+ * @return \CodeIgniter\Database\BaseBuilder
+ */
+ public function getResource(string $search = "")
+ {
+ $builder = $this->db
+ ->table($this->table . " t1")
+ ->select(
+ "t1.id AS id, t1.nombre AS nombre"
+ );
+
+ return empty($search)
+ ? $builder
+ : $builder
+ ->groupStart()
+ ->like("t1.id", $search)
+ ->orLike("t1.nombre", $search)
+ ->groupEnd();
+ }
+}
diff --git a/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/_seriesFacturasFormItems.php b/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/_seriesFacturasFormItems.php
new file mode 100644
index 00000000..aabdaf4a
--- /dev/null
+++ b/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/_seriesFacturasFormItems.php
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasForm.php b/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasForm.php
new file mode 100644
index 00000000..cd4eaf81
--- /dev/null
+++ b/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasForm.php
@@ -0,0 +1,52 @@
+= $this->include("themes/_commonPartialsBs/datatables") ?>
+= $this->include("themes/_commonPartialsBs/select2bs5") ?>
+= $this->include("themes/_commonPartialsBs/sweetalert") ?>
+= $this->extend('themes/vuexy/main/defaultlayout') ?>
+
+= $this->section("content") ?>
+
+= $this->endSection() ?>
+
+
+
+=$this->section('css') ?>
+
+ ">
+=$this->endSection() ?>
+
+
+= $this->section('additionalExternalJs') ?>
+
+
+
+
+
+
+
+
+=$this->endSection() ?>
+
diff --git a/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasList.php b/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasList.php
new file mode 100644
index 00000000..85ca4f23
--- /dev/null
+++ b/ci4/app/Views/themes/vuexy/form/configuracion/series-facturas/viewSeriesFacturasList.php
@@ -0,0 +1,145 @@
+=$this->include('themes/_commonPartialsBs/datatables') ?>
+= $this->include('themes/_commonPartialsBs/_confirm2delete') ?>
+= $this->include('themes/_commonPartialsBs/sweetalert') ?>
+=$this->extend('themes/vuexy/main/defaultlayout') ?>
+=$this->section('content'); ?>
+
+
+
+
+
+
+ = view('themes/_commonPartialsBs/_alertBoxes'); ?>
+
+
+
+
+ | = lang('SeriesFacturas.nombre') ?> |
+ = lang('SeriesFacturas.tipo') ?> |
+ = lang('SeriesFacturas.formato') ?> |
+ = lang('SeriesFacturas.next') ?> |
+ = lang('SeriesFacturas.grupo') ?> |
+ = lang('Basic.global.Action') ?> |
+
+
+
+
+
+
+
+
+
+
+
+
+=$this->endSection() ?>
+
+
+=$this->section('additionalInlineJs') ?>
+
+ const lastColNr = $('#tableOfSeriesFacturas').find("tr:first th").length - 1;
+ const actionBtns = function(data) {
+ return `
+
+ | `;
+ };
+
+ theTable = $('#tableOfSeriesFacturas').DataTable({
+ processing: true,
+ serverSide: true,
+ autoWidth: true,
+ responsive: true,
+ scrollX: true,
+ lengthMenu: [ 5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500 ],
+ pageLength: 50,
+ lengthChange: true,
+ "dom": 'lfBrtip',
+ "buttons": [
+ 'copy', 'csv', 'excel', 'print', {
+ extend: 'pdfHtml5',
+ orientation: 'landscape',
+ pageSize: 'A4'
+ }
+ ],
+ stateSave: true,
+ order: [[0, 'asc']],
+ language: {
+ url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
+ },
+ ajax : $.fn.dataTable.pipeline( {
+ url: '= route_to('seriesFacturasDT') ?>',
+ method: 'POST',
+ headers: {'X-Requested-With': 'XMLHttpRequest'},
+ async: true,
+ }),
+ columnDefs: [
+ {
+ orderable: false,
+ searchable: false,
+ targets: [lastColNr]
+ }
+ ],
+ columns : [
+ { 'data': 'nombre' },
+ { 'data': 'tipo' },
+ { 'data': 'formato' },
+ { 'data': 'next' },
+ { 'data': 'grupo' },
+ { 'data': actionBtns }
+ ]
+ });
+
+
+ $(document).on('click', '.btn-edit', function(e) {
+ window.location.href = `/configuracion/series-facturas/edit/${$(this).attr('data-id')}`;
+ });
+
+
+ $(document).on('click', '.btn-delete', function(e) {
+ $(".btn-remove").attr('data-id', $(this).attr('data-id'));
+ });
+
+ $(document).on('click', '.btn-remove', function(e) {
+ const dataId = $(this).attr('data-id');
+ const row = $(this).closest('tr');
+ if ($.isNumeric(dataId)) {
+ $.ajax({
+ url: `/configuracion/series-facturas//delete/${dataId}`,
+ method: 'GET',
+ }).done((data, textStatus, jqXHR) => {
+ $('#confirm2delete').modal('toggle');
+ theTable.clearPipeline();
+ theTable.row($(row)).invalidate().draw();
+ popSuccessAlert(data.msg ?? jqXHR.statusText);
+ }).fail((jqXHR, textStatus, errorThrown) => {
+ popErrorAlert(jqXHR.responseJSON.messages.error)
+ })
+ }
+ });
+
+=$this->endSection() ?>
+
+
+=$this->section('css') ?>
+ ">
+=$this->endSection() ?>
+
+
+= $this->section('additionalExternalJs') ?>
+
+
+
+
+
+
+
+=$this->endSection() ?>
+
diff --git a/ci4/app/Views/themes/vuexy/form/configuracion/ubicaciones/_ubicacionesFormItems.php b/ci4/app/Views/themes/vuexy/form/configuracion/ubicaciones/_ubicacionesFormItems.php
new file mode 100644
index 00000000..1f6af855
--- /dev/null
+++ b/ci4/app/Views/themes/vuexy/form/configuracion/ubicaciones/_ubicacionesFormItems.php
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ci4/app/Views/themes/vuexy/form/configuracion/ubicaciones/viewUbicacionesForm.php b/ci4/app/Views/themes/vuexy/form/configuracion/ubicaciones/viewUbicacionesForm.php
new file mode 100644
index 00000000..820d2be6
--- /dev/null
+++ b/ci4/app/Views/themes/vuexy/form/configuracion/ubicaciones/viewUbicacionesForm.php
@@ -0,0 +1,52 @@
+= $this->include("themes/_commonPartialsBs/datatables") ?>
+= $this->include("themes/_commonPartialsBs/select2bs5") ?>
+= $this->include("themes/_commonPartialsBs/sweetalert") ?>
+= $this->extend('themes/vuexy/main/defaultlayout') ?>
+
+= $this->section("content") ?>
+
+= $this->endSection() ?>
+
+
+
+=$this->section('css') ?>
+
+ ">
+=$this->endSection() ?>
+
+
+= $this->section('additionalExternalJs') ?>
+
+
+
+
+
+
+
+
+=$this->endSection() ?>
+
diff --git a/ci4/app/Views/themes/vuexy/form/configuracion/ubicaciones/viewUbicacionesList.php b/ci4/app/Views/themes/vuexy/form/configuracion/ubicaciones/viewUbicacionesList.php
new file mode 100644
index 00000000..7201e18f
--- /dev/null
+++ b/ci4/app/Views/themes/vuexy/form/configuracion/ubicaciones/viewUbicacionesList.php
@@ -0,0 +1,137 @@
+=$this->include('themes/_commonPartialsBs/datatables') ?>
+= $this->include('themes/_commonPartialsBs/_confirm2delete') ?>
+= $this->include('themes/_commonPartialsBs/sweetalert') ?>
+=$this->extend('themes/vuexy/main/defaultlayout') ?>
+=$this->section('content'); ?>
+
+
+
+
+
+
+ = view('themes/_commonPartialsBs/_alertBoxes'); ?>
+
+
+
+
+ | = lang('Ubicaciones.nombre') ?> |
+ = lang('Basic.global.Action') ?> |
+
+
+
+
+
+
+
+
+
+
+
+
+=$this->endSection() ?>
+
+
+=$this->section('additionalInlineJs') ?>
+
+ const lastColNr = $('#tableOfUbicaciones').find("tr:first th").length - 1;
+ const actionBtns = function(data) {
+ return `
+
+ | `;
+ };
+
+ theTable = $('#tableOfUbicaciones').DataTable({
+ processing: true,
+ serverSide: true,
+ autoWidth: true,
+ responsive: true,
+ scrollX: true,
+ lengthMenu: [ 5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500 ],
+ pageLength: 50,
+ lengthChange: true,
+ "dom": 'lfBrtip',
+ "buttons": [
+ 'copy', 'csv', 'excel', 'print', {
+ extend: 'pdfHtml5',
+ orientation: 'landscape',
+ pageSize: 'A4'
+ }
+ ],
+ stateSave: true,
+ order: [[0, 'asc']],
+ language: {
+ url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
+ },
+ ajax : $.fn.dataTable.pipeline( {
+ url: '= route_to('ubicacionesDT') ?>',
+ method: 'POST',
+ headers: {'X-Requested-With': 'XMLHttpRequest'},
+ async: true,
+ }),
+ columnDefs: [
+ {
+ orderable: false,
+ searchable: false,
+ targets: [lastColNr]
+ }
+ ],
+ columns : [
+ { 'data': 'nombre' },
+ { 'data': actionBtns }
+ ]
+ });
+
+
+ $(document).on('click', '.btn-edit', function(e) {
+ window.location.href = `/configuracion/ubicaciones/edit/${$(this).attr('data-id')}`;
+ });
+
+
+ $(document).on('click', '.btn-delete', function(e) {
+ $(".btn-remove").attr('data-id', $(this).attr('data-id'));
+ });
+
+ $(document).on('click', '.btn-remove', function(e) {
+ const dataId = $(this).attr('data-id');
+ const row = $(this).closest('tr');
+ if ($.isNumeric(dataId)) {
+ $.ajax({
+ url: `/configuracion/ubicaciones/delete/${dataId}`,
+ method: 'GET',
+ }).done((data, textStatus, jqXHR) => {
+ $('#confirm2delete').modal('toggle');
+ theTable.clearPipeline();
+ theTable.row($(row)).invalidate().draw();
+ popSuccessAlert(data.msg ?? jqXHR.statusText);
+ }).fail((jqXHR, textStatus, errorThrown) => {
+ popErrorAlert(jqXHR.responseJSON.messages.error)
+ })
+ }
+ });
+
+=$this->endSection() ?>
+
+
+=$this->section('css') ?>
+ ">
+=$this->endSection() ?>
+
+
+= $this->section('additionalExternalJs') ?>
+
+
+
+
+
+
+
+=$this->endSection() ?>
+
diff --git a/ci4/app/Views/themes/vuexy/main/menus/configuracion_menu.php b/ci4/app/Views/themes/vuexy/main/menus/configuracion_menu.php
index 7cfee129..83ca3f39 100644
--- a/ci4/app/Views/themes/vuexy/main/menus/configuracion_menu.php
+++ b/ci4/app/Views/themes/vuexy/main/menus/configuracion_menu.php
@@ -67,6 +67,20 @@ if (
+ user()->can('ubicaciones.menu')) { ?>
+
+
+ user()->can('series-facturas.menu')) { ?>
+
+
\ No newline at end of file