mirror of
https://git.imnavajas.es/jjimenez/safekat.git
synced 2025-07-25 22:52:08 +00:00
Primera version del importador RAMA
This commit is contained in:
@ -19,6 +19,18 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
order: [[1, 'asc']]
|
||||
});
|
||||
|
||||
// Crear filtros por columna en el segundo <tr>
|
||||
$('#excelTable thead tr:eq(1) th').each(function (i) {
|
||||
if (![0, 6, 7].includes(i)) { // No poner input en Checkbox, Notas ni Acciones
|
||||
$(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('excelFile').addEventListener('change', function (e) {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
@ -64,38 +76,39 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const rowData = TABLE_COLUMNS.map(col => data[i][headerMap[col]] ?? '');
|
||||
|
||||
// Llamar backend para validar la fila
|
||||
const isValid = await validarFila(rowData);
|
||||
const result = await validarFila(rowData);
|
||||
|
||||
let checkboxHtml = '';
|
||||
let actionBtnsHtml = '';
|
||||
let notaHtml = '';
|
||||
|
||||
if (isValid) {
|
||||
if (result.apto) {
|
||||
checkboxHtml = `<input type="checkbox" class="select-row form-check-input" checked>`;
|
||||
|
||||
notaHtml = '';
|
||||
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>
|
||||
`;
|
||||
<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>`;
|
||||
|
||||
notaHtml = `<span class="badge bg-danger">${result.reason}</span>`;
|
||||
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>
|
||||
`;
|
||||
<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]);
|
||||
rows.push([checkboxHtml, ...rowData, notaHtml, actionBtnsHtml]);
|
||||
}
|
||||
|
||||
dataTable.clear().rows.add(rows).draw();
|
||||
@ -114,11 +127,10 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
body: JSON.stringify({ fila: rowData })
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
return result.apto === true;
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error('Error validando fila', error);
|
||||
return false;
|
||||
return { apto: false, reason: 'Error conexión' };
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,25 +139,92 @@ document.addEventListener('DOMContentLoaded', 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
|
||||
});
|
||||
}
|
||||
$('#excelTable tbody').off('click', '.importRow').on('click', '.importRow', async function () {
|
||||
const $row = $(this).closest('tr');
|
||||
const rowData = dataTable.row($row).data();
|
||||
if (!rowData) return;
|
||||
|
||||
document.getElementById('importBtn').addEventListener('click', function () {
|
||||
const selectedRows = [];
|
||||
const fila = rowData.slice(1, 6); // solo datos de negocio
|
||||
|
||||
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
|
||||
try {
|
||||
const response = await fetch('/importador/catalogo/importar-fila', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': '<?= csrf_hash() ?>'
|
||||
},
|
||||
body: JSON.stringify({ fila: fila })
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (response.ok && result.status === 200) {
|
||||
const skUrl = result.data?.sk_url ?? null;
|
||||
|
||||
// Actualizar campo "Notas" con el enlace
|
||||
if (skUrl) {
|
||||
const notasHtml = `<a href="${skUrl}" target="_blank" class="btn btn-sm btn-secondary">Ver presupuesto</a>`;
|
||||
// La columna de notas es la posición 6 (índice 6)
|
||||
rowData[6] = notasHtml;
|
||||
dataTable.row($row).data(rowData).draw(false); // Redibujar la fila SIN perder scroll ni filtros
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
title: 'Importado correctamente',
|
||||
html: skUrl
|
||||
? `La fila se importó exitosamente.<br><br><a href="${skUrl}" target="_blank" class="btn btn-primary mt-2">Ver presupuesto</a>`
|
||||
: 'La fila se importó exitosamente.',
|
||||
icon: 'success',
|
||||
confirmButtonText: 'Aceptar',
|
||||
buttonsStyling: true,
|
||||
customClass: { confirmButton: 'btn btn-success' }
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: result.message ?? 'Hubo un error al importar esta fila.',
|
||||
icon: 'error',
|
||||
confirmButtonText: 'Aceptar',
|
||||
buttonsStyling: true,
|
||||
customClass: { confirmButton: 'btn btn-danger' }
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error en la llamada a importar-fila:', error);
|
||||
Swal.fire({
|
||||
title: 'Error',
|
||||
text: 'Error de comunicación con el servidor.',
|
||||
icon: 'error',
|
||||
confirmButtonText: 'Aceptar',
|
||||
buttonsStyling: true,
|
||||
customClass: { confirmButton: 'btn btn-danger' }
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (selectedRows.length === 0) {
|
||||
|
||||
// Select All funcional
|
||||
$('#selectAll').off('change').on('change', function () {
|
||||
const checked = $(this).is(':checked');
|
||||
$('#excelTable tbody input.select-row:enabled').prop('checked', checked);
|
||||
});
|
||||
}
|
||||
|
||||
/* Importacion */
|
||||
document.getElementById('importBtn').addEventListener('click', function () {
|
||||
const filasAptas = [];
|
||||
|
||||
dataTable.rows().every(function () {
|
||||
const rowNode = this.node();
|
||||
const checkbox = $(rowNode).find('input.select-row');
|
||||
|
||||
if (checkbox.length > 0 && checkbox.is(':checked') && !checkbox.is(':disabled')) {
|
||||
const rowData = this.data();
|
||||
filasAptas.push({ fila: rowData.slice(1, 6), rowNode: rowNode, rowData: rowData });
|
||||
}
|
||||
});
|
||||
|
||||
if (filasAptas.length === 0) {
|
||||
Swal.fire({
|
||||
title: 'Atención',
|
||||
text: 'No hay filas aptas seleccionadas para importar.',
|
||||
@ -157,35 +236,66 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
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' }
|
||||
});
|
||||
Swal.fire({
|
||||
title: '¿Confirmar importación?',
|
||||
text: `Se van a importar ${filasAptas.length} filas.`,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Sí, importar',
|
||||
cancelButtonText: 'Cancelar',
|
||||
reverseButtons: true,
|
||||
buttonsStyling: true,
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary',
|
||||
cancelButton: 'btn btn-secondary'
|
||||
}
|
||||
}).then(async (result) => {
|
||||
if (!result.isConfirmed) return;
|
||||
|
||||
for (const fila of filasAptas) {
|
||||
try {
|
||||
const response = await fetch('/importador/catalogo/importar-fila', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': '<?= csrf_hash() ?>'
|
||||
},
|
||||
body: JSON.stringify({ fila: fila.fila })
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (response.ok && result.status === 200) {
|
||||
const skUrl = result.data?.sk_url ?? null;
|
||||
|
||||
if (skUrl) {
|
||||
fila.rowData[6] = `<a href="${skUrl}" target="_blank" class="btn btn-sm btn-primary">Ver presupuesto</a>`;
|
||||
} else {
|
||||
fila.rowData[6] = `<span class="badge bg-success">Importado</span>`;
|
||||
}
|
||||
} else {
|
||||
fila.rowData[6] = `<span class="badge bg-danger">${result.message ?? 'Error desconocido'}</span>`;
|
||||
}
|
||||
|
||||
dataTable.row(fila.rowNode).data(fila.rowData).draw(false);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error importando fila:', error);
|
||||
fila.rowData[6] = `<span class="badge bg-danger">Error de comunicación</span>`;
|
||||
dataTable.row(fila.rowNode).data(fila.rowData).draw(false);
|
||||
}
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
title: 'Importación finalizada',
|
||||
text: 'Se han procesado todas las filas seleccionadas.',
|
||||
icon: 'success',
|
||||
confirmButtonText: 'Aceptar',
|
||||
buttonsStyling: true,
|
||||
customClass: { confirmButton: 'btn btn-success' }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user