mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
Configurando logica de captacion del Excel
This commit is contained in:
@ -45,7 +45,7 @@ class ImportadorCatalogo extends BaseResourceController
|
|||||||
|
|
||||||
$viewData = [
|
$viewData = [
|
||||||
'currentModule' => static::$controllerSlug,
|
'currentModule' => static::$controllerSlug,
|
||||||
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Catalogo.catalogo')]),
|
'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Importador.importadorCatalogoTitle')]),
|
||||||
'catalogoLibrosEntity' => new CatalogoLibroEntity(),
|
'catalogoLibrosEntity' => new CatalogoLibroEntity(),
|
||||||
'usingServerSideDataTable' => true,
|
'usingServerSideDataTable' => true,
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'moduleTitle' => 'Importador desde catálogo',
|
'moduleTitle' => 'Importadores',
|
||||||
'listingPage' => 'Listado de libros',
|
'importadorCatalogoTitle' => 'Importador desde catálogo',
|
||||||
'catalogo' => 'catálogo',
|
'catalogo' => 'catálogo',
|
||||||
'libro' => 'libro',
|
'input' => 'ISBN',
|
||||||
|
'descripcion' => 'Título',
|
||||||
|
'idlinea' => 'Ref. cliente',
|
||||||
|
'cnt_pedida' => 'Unidades',
|
||||||
|
'precio_compra' => 'Precio Compra',
|
||||||
|
|
||||||
|
'libro' => 'libro',
|
||||||
'id' => 'ID',
|
'id' => 'ID',
|
||||||
'clienteId' => 'Cliente',
|
'clienteId' => 'Cliente',
|
||||||
'cliente' => 'Cliente',
|
'cliente' => 'Cliente',
|
||||||
'proveedorId' => 'Proveedor',
|
|
||||||
'userCreatedId' => 'Usuario Creador',
|
'userCreatedId' => 'Usuario Creador',
|
||||||
'userUpdateId' => 'Usuario Actualizador',
|
'userUpdateId' => 'Usuario Actualizador',
|
||||||
'cubiertaArchivo' => 'Archivo de Cubierta',
|
|
||||||
'cubiertaUrl' => 'URL de Cubierta',
|
|
||||||
'portada' => 'Portada',
|
'portada' => 'Portada',
|
||||||
'ancho' => 'Ancho',
|
'ancho' => 'Ancho',
|
||||||
'alto' => 'Alto',
|
'alto' => 'Alto',
|
||||||
@ -63,7 +66,7 @@ return [
|
|||||||
'createdAt' => 'Fecha de Creación',
|
'createdAt' => 'Fecha de Creación',
|
||||||
'updatedAt' => 'Fecha de Actualización',
|
'updatedAt' => 'Fecha de Actualización',
|
||||||
'deletedAt' => 'Fecha de Eliminación',
|
'deletedAt' => 'Fecha de Eliminación',
|
||||||
|
|
||||||
'catalogoLibro' => 'Libro',
|
'catalogoLibro' => 'Libro',
|
||||||
'catalogoLibroList' => 'Lista de Libros',
|
'catalogoLibroList' => 'Lista de Libros',
|
||||||
'datosGenerales' => 'Datos generales del libro',
|
'datosGenerales' => 'Datos generales del libro',
|
||||||
@ -71,5 +74,5 @@ return [
|
|||||||
'configuracionLibro' => 'Configuración del libro',
|
'configuracionLibro' => 'Configuración del libro',
|
||||||
'ficherosLibro' => 'Ficheros',
|
'ficherosLibro' => 'Ficheros',
|
||||||
'created_by_at' => 'Creado:',
|
'created_by_at' => 'Creado:',
|
||||||
'updated_by_at' => 'Actualizado:',
|
'updated_by_at' => 'Actualizado:',
|
||||||
];
|
];
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<div class="card card-info">
|
<div class="card card-info">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3 class="card-title"><?= lang('Importador.listingPage') ?></h3>
|
<h3 class="card-title"><?= lang('Importador.importadorCatalogoTitle') ?></h3>
|
||||||
</div><!--//.card-header -->
|
</div><!--//.card-header -->
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<?= view('themes/_commonPartialsBs/_alertBoxes'); ?>
|
<?= view('themes/_commonPartialsBs/_alertBoxes'); ?>
|
||||||
@ -19,18 +19,27 @@
|
|||||||
<br>
|
<br>
|
||||||
<button id="importBtn">Importar</button>
|
<button id="importBtn">Importar</button>
|
||||||
|
|
||||||
<table id="excelTable" class="display">
|
<table id="excelTable" class="table table-striped table-hover" style="width: 100%;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>cnt_pedida</th>
|
<th><?= lang('Importador.input') ?></th>
|
||||||
<th>precio_compra</th>
|
<th><?= lang('Importador.idlinea') ?></th>
|
||||||
<th>idlinea</th>
|
<th><?= lang('Importador.descripcion') ?></th>
|
||||||
<th>input</th>
|
<th><?= lang('Importador.cnt_pedida') ?></th>
|
||||||
<th>descripcion</th>
|
<th><?= lang('Importador.precio_compra') ?></th>
|
||||||
<th>Acción</th>
|
<th class="text-nowrap" style="min-width: 85px;"><?= lang('Basic.global.Action') ?></th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,15 @@
|
|||||||
|
import Ajax from '../../../components/ajax.js';
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
|
||||||
// Columnas requeridas
|
// Columnas que espera la tabla (en el orden de HTML)
|
||||||
const REQUIRED_COLUMNS = ["cnt_pedida", "precio_compra", "idlinea", "input", "descripcion"];
|
const TABLE_COLUMNS = ["input", "idlinea", "descripcion", "cnt_pedida", "precio_compra"];
|
||||||
let dataTable; // referencia al DataTable
|
let dataTable; // referencia al DataTable
|
||||||
|
|
||||||
|
dataTable = $('#excelTable').DataTable({
|
||||||
// Inicializa el DataTable vacío
|
orderCellsTop: true,
|
||||||
dataTable = $('#excelTable').DataTable();
|
fixedHeader: true
|
||||||
|
});
|
||||||
|
|
||||||
document.getElementById('excelFile').addEventListener('change', function (e) {
|
document.getElementById('excelFile').addEventListener('change', function (e) {
|
||||||
const file = e.target.files[0];
|
const file = e.target.files[0];
|
||||||
@ -26,38 +29,91 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function validateAndLoadDataTable(data) {
|
function validateAndLoadDataTable(data) {
|
||||||
|
if (data.length === 0) return;
|
||||||
|
|
||||||
const headers = data[0].map(h => h.toString().trim());
|
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) {
|
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
|
dataTable.clear().draw(); // limpia tabla
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const indexes = REQUIRED_COLUMNS.map(col => headers.indexOf(col));
|
|
||||||
|
|
||||||
const rows = [];
|
const rows = [];
|
||||||
for (let i = 1; i < data.length; i++) {
|
for (let i = 1; i < data.length; i++) {
|
||||||
const rowData = indexes.map(idx => data[i][idx] ?? '');
|
const row = [];
|
||||||
rowData.push('<button class="deleteRow">Eliminar</button>'); // Agrega botón
|
|
||||||
rows.push(rowData);
|
TABLE_COLUMNS.forEach(col => {
|
||||||
|
const idx = headerMap[col];
|
||||||
|
row.push(data[i][idx] ?? '');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Agregar botón al final
|
||||||
|
row.push('<button type="button" class="btn btn-danger btn-sm deleteRow">Eliminar</button>');
|
||||||
|
|
||||||
|
rows.push(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
dataTable.clear().rows.add(rows).draw();
|
dataTable.clear().rows.add(rows).draw();
|
||||||
|
|
||||||
// Agregar eventos a los nuevos botones de eliminar
|
// Agregar eventos dinámicos para eliminar
|
||||||
$('#excelTable tbody').on('click', '.deleteRow', function () {
|
$('#excelTable tbody').off('click', '.deleteRow').on('click', '.deleteRow', function () {
|
||||||
dataTable.row($(this).parents('tr')).remove().draw();
|
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 type="text" class="form-control form-control-sm" placeholder="Filtrar..." />');
|
||||||
|
|
||||||
|
$('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 () {
|
document.getElementById('importBtn').addEventListener('click', function () {
|
||||||
const allData = dataTable.rows().data().toArray();
|
const allData = dataTable.rows().data().toArray();
|
||||||
|
const rowsToSend = allData.map(row => row.slice(0, -1)); // sin botón
|
||||||
// Eliminar la última columna (botón) de cada fila
|
|
||||||
const rowsToSend = allData.map(row => row.slice(0, -1));
|
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', {
|
fetch('/importar', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@ -66,9 +122,30 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
},
|
},
|
||||||
body: JSON.stringify({ data: rowsToSend })
|
body: JSON.stringify({ data: rowsToSend })
|
||||||
}).then(res => res.json())
|
}).then(res => res.json())
|
||||||
.then(response => {
|
.then(response => {
|
||||||
alert(response.message);
|
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'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user