Merge branch 'main' into feat/festivos-calendar

This commit is contained in:
amazuecos
2025-04-28 02:10:52 +02:00
16 changed files with 751 additions and 81 deletions

View File

@ -0,0 +1,191 @@
import Ajax from '../../../components/ajax.js';
document.addEventListener('DOMContentLoaded', function () {
const TABLE_COLUMNS = ["input", "idlinea", "descripcion", "cnt_pedida", "precio_compra"];
let dataTable;
dataTable = $('#excelTable').DataTable({
orderCellsTop: true,
responsive: true,
scrollX: true,
lengthMenu: [5, 10, 25, 50, 75, 100, 250, 500, 1000, 2500],
pageLength: 25,
lengthChange: true,
dom: 'lfrtip',
language: {
url: "/themes/vuexy/vendor/libs/datatables-sk/plugins/i18n/es-ES.json"
},
order: [[1, 'asc']]
});
document.getElementById('excelFile').addEventListener('change', function (e) {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function (e) {
const data = new Uint8Array(e.target.result);
const workbook = XLSX.read(data, { type: 'array' });
const firstSheet = workbook.Sheets[workbook.SheetNames[0]];
const jsonData = XLSX.utils.sheet_to_json(firstSheet, { header: 1 });
validateAndLoadDataTable(jsonData);
};
reader.readAsArrayBuffer(file);
});
async function validateAndLoadDataTable(data) {
if (data.length === 0) return;
const headers = data[0].map(h => h.toString().trim());
const headerMap = {};
headers.forEach((name, idx) => {
headerMap[name.toLowerCase()] = idx;
});
const missing = TABLE_COLUMNS.filter(col => !(col in headerMap));
if (missing.length > 0) {
Swal.fire({
title: 'Error',
text: 'Faltan las siguientes columnas: ' + missing.join(', '),
icon: 'error',
confirmButtonText: 'Aceptar',
buttonsStyling: true,
customClass: { confirmButton: 'btn btn-danger' }
});
dataTable.clear().draw();
return;
}
const rows = [];
for (let i = 1; i < data.length; i++) {
const rowData = TABLE_COLUMNS.map(col => data[i][headerMap[col]] ?? '');
// Llamar backend para validar la fila
const isValid = await validarFila(rowData);
let checkboxHtml = '';
let actionBtnsHtml = '';
if (isValid) {
checkboxHtml = `<input type="checkbox" class="select-row form-check-input" checked>`;
actionBtnsHtml = `
<div class="d-flex flex-column align-items-start">
<button type="button" class="btn btn-outline-success btn-sm mb-1 importRow">
<i class="fas fa-file-import me-1"></i> Importar
</button>
<button type="button" class="btn btn-outline-danger btn-sm deleteRow">
<i class="fas fa-trash-alt me-1"></i> Eliminar
</button>
</div>
`;
} else {
checkboxHtml = `<input type="checkbox" class="select-row form-check-input" disabled>`;
actionBtnsHtml = `
<div class="d-flex flex-column align-items-start">
<span class="badge rounded-pill bg-danger mb-2">No Apto</span>
<button type="button" class="btn btn-outline-danger btn-sm deleteRow">
<i class="fas fa-trash-alt me-1"></i> Eliminar
</button>
</div>
`;
}
rows.push([checkboxHtml, ...rowData, actionBtnsHtml]);
}
dataTable.clear().rows.add(rows).draw();
setupEventListeners();
}
async function validarFila(rowData) {
try {
const response = await fetch('/importador/catalogo/validar-fila', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': '<?= csrf_hash() ?>'
},
body: JSON.stringify({ fila: rowData })
});
const result = await response.json();
return result.apto === true;
} catch (error) {
console.error('Error validando fila', error);
return false;
}
}
function setupEventListeners() {
$('#excelTable tbody').off('click', '.deleteRow').on('click', '.deleteRow', function () {
dataTable.row($(this).parents('tr')).remove().draw();
});
$('#excelTable tbody').off('click', '.importRow').on('click', '.importRow', function () {
const rowData = dataTable.row($(this).parents('tr')).data();
console.log('Importar esta fila:', rowData);
// Aquí podrías enviar sólo esta fila al servidor si quieres importar individualmente
});
}
document.getElementById('importBtn').addEventListener('click', function () {
const selectedRows = [];
dataTable.rows().every(function () {
const data = this.data();
const checkboxHtml = $(data[0]).find('input.select-row');
if (checkboxHtml.length > 0 && checkboxHtml.is(':checked') && !checkboxHtml.is(':disabled')) {
selectedRows.push(data.slice(1, -1)); // sin checkbox ni botones
}
});
if (selectedRows.length === 0) {
Swal.fire({
title: 'Atención',
text: 'No hay filas aptas seleccionadas para importar.',
icon: 'warning',
confirmButtonText: 'Aceptar',
buttonsStyling: true,
customClass: { confirmButton: 'btn btn-warning' }
});
return;
}
fetch('/importar', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': '<?= csrf_hash() ?>'
},
body: JSON.stringify({ data: selectedRows })
}).then(res => res.json())
.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: 'Error importando datos.',
icon: 'error',
confirmButtonText: 'Aceptar',
buttonsStyling: true,
customClass: { confirmButton: 'btn btn-danger' }
});
});
});
});