diff --git a/ci4/app/Controllers/Importadores/ImportadorCatalogo.php b/ci4/app/Controllers/Importadores/ImportadorCatalogo.php
index 1fe91a85..493fc4cb 100644
--- a/ci4/app/Controllers/Importadores/ImportadorCatalogo.php
+++ b/ci4/app/Controllers/Importadores/ImportadorCatalogo.php
@@ -45,7 +45,7 @@ class ImportadorCatalogo extends BaseResourceController
$viewData = [
'currentModule' => static::$controllerSlug,
- 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Catalogo.catalogo')]),
+ 'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Importador.importadorCatalogoTitle')]),
'catalogoLibrosEntity' => new CatalogoLibroEntity(),
'usingServerSideDataTable' => true,
diff --git a/ci4/app/Language/es/Importador.php b/ci4/app/Language/es/Importador.php
index b8982f34..baaf0a1a 100644
--- a/ci4/app/Language/es/Importador.php
+++ b/ci4/app/Language/es/Importador.php
@@ -1,18 +1,21 @@
'Importador desde catálogo',
- 'listingPage' => 'Listado de libros',
- 'catalogo' => 'catálogo',
- 'libro' => 'libro',
+ 'moduleTitle' => 'Importadores',
+ 'importadorCatalogoTitle' => 'Importador desde catálogo',
+ 'catalogo' => 'catálogo',
+ 'input' => 'ISBN',
+ 'descripcion' => 'Título',
+ 'idlinea' => 'Ref. cliente',
+ 'cnt_pedida' => 'Unidades',
+ 'precio_compra' => 'Precio Compra',
+
+ 'libro' => 'libro',
'id' => 'ID',
'clienteId' => 'Cliente',
'cliente' => 'Cliente',
- 'proveedorId' => 'Proveedor',
'userCreatedId' => 'Usuario Creador',
'userUpdateId' => 'Usuario Actualizador',
- 'cubiertaArchivo' => 'Archivo de Cubierta',
- 'cubiertaUrl' => 'URL de Cubierta',
'portada' => 'Portada',
'ancho' => 'Ancho',
'alto' => 'Alto',
@@ -63,7 +66,7 @@ return [
'createdAt' => 'Fecha de Creación',
'updatedAt' => 'Fecha de Actualización',
'deletedAt' => 'Fecha de Eliminación',
-
+
'catalogoLibro' => 'Libro',
'catalogoLibroList' => 'Lista de Libros',
'datosGenerales' => 'Datos generales del libro',
@@ -71,5 +74,5 @@ return [
'configuracionLibro' => 'Configuración del libro',
'ficherosLibro' => 'Ficheros',
'created_by_at' => 'Creado:',
- 'updated_by_at' => 'Actualizado:',
+ 'updated_by_at' => 'Actualizado:',
];
diff --git a/ci4/app/Views/themes/vuexy/form/importador/catalogo/viewImportadorCatalogoTool.php b/ci4/app/Views/themes/vuexy/form/importador/catalogo/viewImportadorCatalogoTool.php
index 30ce4e0d..e812993e 100644
--- a/ci4/app/Views/themes/vuexy/form/importador/catalogo/viewImportadorCatalogoTool.php
+++ b/ci4/app/Views/themes/vuexy/form/importador/catalogo/viewImportadorCatalogoTool.php
@@ -8,7 +8,7 @@
= view('themes/_commonPartialsBs/_alertBoxes'); ?>
@@ -19,18 +19,27 @@
-
+
- | cnt_pedida |
- precio_compra |
- idlinea |
- input |
- descripcion |
- Acción |
+ = lang('Importador.input') ?> |
+ = lang('Importador.idlinea') ?> |
+ = lang('Importador.descripcion') ?> |
+ = lang('Importador.cnt_pedida') ?> |
+ = lang('Importador.precio_compra') ?> |
+ = lang('Basic.global.Action') ?> |
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+
diff --git a/httpdocs/assets/js/safekat/pages/importadores/catalogo/catalogo_tool.js b/httpdocs/assets/js/safekat/pages/importadores/catalogo/catalogo_tool.js
index 4150884d..e72a8bfb 100644
--- a/httpdocs/assets/js/safekat/pages/importadores/catalogo/catalogo_tool.js
+++ b/httpdocs/assets/js/safekat/pages/importadores/catalogo/catalogo_tool.js
@@ -1,12 +1,15 @@
+import Ajax from '../../../components/ajax.js';
+
document.addEventListener('DOMContentLoaded', function () {
- // Columnas requeridas
- const REQUIRED_COLUMNS = ["cnt_pedida", "precio_compra", "idlinea", "input", "descripcion"];
+ // Columnas que espera la tabla (en el orden de HTML)
+ const TABLE_COLUMNS = ["input", "idlinea", "descripcion", "cnt_pedida", "precio_compra"];
let dataTable; // referencia al DataTable
-
- // Inicializa el DataTable vacío
- dataTable = $('#excelTable').DataTable();
+ dataTable = $('#excelTable').DataTable({
+ orderCellsTop: true,
+ fixedHeader: true
+ });
document.getElementById('excelFile').addEventListener('change', function (e) {
const file = e.target.files[0];
@@ -26,38 +29,91 @@ document.addEventListener('DOMContentLoaded', function () {
});
function validateAndLoadDataTable(data) {
+ if (data.length === 0) return;
+
const headers = data[0].map(h => h.toString().trim());
- const missing = REQUIRED_COLUMNS.filter(col => !headers.includes(col));
+ // Crear un índice rápido de nombreColumna => posicion
+ const headerMap = {};
+ headers.forEach((name, idx) => {
+ headerMap[name.toLowerCase()] = idx; // pasar todo a minúsculas para evitar errores
+ });
+
+ // Verificar si todas las columnas requeridas existen
+ const missing = TABLE_COLUMNS.filter(col => !(col in headerMap));
if (missing.length > 0) {
- alert('Faltan las siguientes columnas en el Excel: ' + missing.join(', '));
+ Swal.fire({
+ title: 'Error',
+ text: 'Faltan las siguientes columnas en el Excel: ' + missing.join(', '),
+ icon: 'error',
+ confirmButtonText: 'Aceptar',
+ buttonsStyling: true,
+ customClass: {
+ confirmButton: 'btn btn-danger'
+ }
+ });
dataTable.clear().draw(); // limpia tabla
return;
}
- const indexes = REQUIRED_COLUMNS.map(col => headers.indexOf(col));
-
const rows = [];
for (let i = 1; i < data.length; i++) {
- const rowData = indexes.map(idx => data[i][idx] ?? '');
- rowData.push(''); // Agrega botón
- rows.push(rowData);
+ const row = [];
+
+ TABLE_COLUMNS.forEach(col => {
+ const idx = headerMap[col];
+ row.push(data[i][idx] ?? '');
+ });
+
+ // Agregar botón al final
+ row.push('');
+
+ rows.push(row);
}
dataTable.clear().rows.add(rows).draw();
- // Agregar eventos a los nuevos botones de eliminar
- $('#excelTable tbody').on('click', '.deleteRow', function () {
+ // Agregar eventos dinámicos para eliminar
+ $('#excelTable tbody').off('click', '.deleteRow').on('click', '.deleteRow', function () {
dataTable.row($(this).parents('tr')).remove().draw();
});
}
+ $('#excelTable thead tr:eq(1) th').each(function (i) {
+ const title = $(this).text();
+
+ if (title.trim() !== '') { // Solo si el th tiene título
+ $(this).html('');
+
+ $('input', this).on('keyup change', function () {
+ if (dataTable.column(i).search() !== this.value) {
+ dataTable
+ .column(i)
+ .search(this.value)
+ .draw();
+ }
+ });
+ }
+ });
+
document.getElementById('importBtn').addEventListener('click', function () {
const allData = dataTable.rows().data().toArray();
-
- // Eliminar la última columna (botón) de cada fila
- const rowsToSend = allData.map(row => row.slice(0, -1));
-
+ const rowsToSend = allData.map(row => row.slice(0, -1)); // sin botón
+
+ if (rowsToSend.length === 0) {
+ Swal.fire({
+ title: 'Atención',
+ text: 'No hay datos para importar.',
+ icon: 'warning',
+ confirmButtonText: 'Aceptar',
+ buttonsStyling: true,
+ customClass: {
+ confirmButton: 'btn btn-warning'
+ }
+ });
+ return;
+ }
+
fetch('/importar', {
method: 'POST',
headers: {
@@ -66,9 +122,30 @@ document.addEventListener('DOMContentLoaded', function () {
},
body: JSON.stringify({ data: rowsToSend })
}).then(res => res.json())
- .then(response => {
- alert(response.message);
- });
+ .then(response => {
+ Swal.fire({
+ title: 'Importación exitosa',
+ text: response.message,
+ icon: 'success',
+ confirmButtonText: 'Aceptar',
+ buttonsStyling: true,
+ customClass: {
+ confirmButton: 'btn btn-success'
+ }
+ });
+ })
+ .catch(error => {
+ console.error(error);
+ Swal.fire({
+ title: 'Error',
+ text: 'Hubo un problema al importar los datos.',
+ icon: 'error',
+ confirmButtonText: 'Aceptar',
+ buttonsStyling: true,
+ customClass: {
+ confirmButton: 'btn btn-danger'
+ }
+ });
+ });
});
-
});
\ No newline at end of file