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 @@
-

+

@@ -19,18 +19,27 @@
- +
- - - - - - + + + + + + + + + + + + + + +
cnt_pedidaprecio_compraidlineainputdescripcionAcción
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