Notificaciones Cambio de Estado de Solicitud

This commit is contained in:
2025-06-09 12:15:33 -06:00
parent 7a56ce93ba
commit f1d4b7c98f
3 changed files with 488 additions and 47 deletions

View File

@@ -172,6 +172,7 @@
</div>
</div>
<div style="display: flex; justify-content: right;">
<a href="/IMPORTADORES/configuracion/index" class="btn btn-secondary ms-2" style="margin-right: 10px;">Cancelar</a>
<button type="submit" class="btn btn-primary">💾 Guardar Cambios</button>
</div>
</form>

View File

@@ -147,51 +147,183 @@
function updateRowStatus($row, status) {
const disable = status === '2'; // 2 = Solicitar importación
$row.find('a.btn, button.btn').prop('disabled', disable);
// Si quieres bloquear también el propio select:
// $row.find('.status-select').prop('disabled', disable);
// Opcional: cambiar estilo visual para indicar estado bloqueado
if (disable) {
$row.addClass('table-warning').find('.status-select').addClass('border-warning');
} else {
$row.removeClass('table-warning').find('.status-select').removeClass('border-warning');
}
}
// Al cambiar el select de status
$('#tabla-solicitudes').on('change', '.status-select', function () {
const $sel = $(this);
const id = $sel.data('id');
const status = $sel.val();
const $row = $sel.closest('tr');
// Bloquear botones localmente
updateRowStatus($row, status);
// Función para mostrar loading en el select
function setSelectLoading($select, loading) {
if (loading) {
$select.prop('disabled', true).addClass('border-primary');
$select.closest('tr').find('td').addClass('opacity-75');
} else {
$select.prop('disabled', false).removeClass('border-primary');
$select.closest('tr').find('td').removeClass('opacity-75');
}
}
// Llamada AJAX
$.post(
'/IMPORTADORES/solicitud_importacion/update_status',
{ id: id, status: status },
null,
'json'
)
.done(function(res) {
if (!res.success) {
Swal.fire('Error', 'No se pudo actualizar status', 'error');
} else if (res.numeroPedimentoLocal) {
// Si vino numeroPedimentoLocal, mostramos alerta específica
Swal.fire(
'Importación solicitada',
'Se generó el número de pedimento: ' + res.numeroPedimentoLocal,
'success'
);
// Además podrías actualizar en la tabla la celda de "Pedimento" si quieres:
$row.find('td:nth-child(4)').text(res.numeroPedimentoLocal);
}
// Si success pero no viene numeroPedimentoLocal, no hacemos nada especial.
})
.fail(function() {
Swal.fire('Error', 'No se pudo conectar al servidor', 'error');
});
});
// Al cambiar el select de status
$('#tabla-solicitudes').on('change', '.status-select', function () {
const $sel = $(this);
const id = $sel.data('id');
const status = $sel.val();
const $row = $sel.closest('tr');
const oldStatus = $sel.data('old-status') || $sel.find('option:first').val();
// Guardar el estado anterior para poder revertir si falla
$sel.data('old-status', oldStatus);
// Mostrar loading
setSelectLoading($sel, true);
// Mostrar toast de procesando
Swal.fire({
title: 'Actualizando...',
text: 'Procesando cambio de estado',
icon: 'info',
allowOutsideClick: false,
showConfirmButton: false,
timer: 1000,
timerProgressBar: true
});
// Llamada AJAX con configuración mejorada
$.ajax({
url: '/IMPORTADORES/solicitud_importacion/update_status',
method: 'POST',
data: {
id: id,
status: status
},
dataType: 'json',
timeout: 30000, // 30 segundos timeout
success: function(res) {
console.log('Respuesta del servidor:', res);
if (!res.success) {
// Error del servidor pero respuesta válida
handleUpdateError('Error del servidor: ' + (res.error || 'Error desconocido'), $sel, oldStatus);
return;
}
// Éxito - actualizar UI
updateRowStatus($row, status);
$sel.data('old-status', status); // Actualizar estado guardado
// Mostrar mensaje específico según el resultado
if (res.numeroPedimentoLocal) {
Swal.fire({
title: '¡Importación solicitada!',
text: `Se generó el número de pedimento: ${res.numeroPedimentoLocal}`,
icon: 'success',
confirmButtonText: 'Entendido'
});
// Actualizar la celda del pedimento si existe
const $pedimentoCell = $row.find('td[data-pedimento]');
if ($pedimentoCell.length) {
$pedimentoCell.text(res.numeroPedimentoLocal).addClass('text-success fw-bold');
}
} else if (res.warning) {
// Mostrar advertencia si hay alguna
Swal.fire({
title: 'Estado actualizado',
text: res.warning,
icon: 'warning',
confirmButtonText: 'Entendido'
});
} else {
// Éxito normal
Swal.fire({
title: '¡Actualizado!',
text: 'Estado cambiado correctamente',
icon: 'success',
timer: 2000,
showConfirmButton: false
});
}
},
error: function(xhr, status, error) {
console.error('Error AJAX:', { xhr, status, error });
let errorMessage = 'No se pudo conectar al servidor';
// Mejorar el mensaje de error según el tipo
if (status === 'timeout') {
errorMessage = 'La operación tardó demasiado tiempo. Inténtalo de nuevo.';
} else if (status === 'parsererror') {
errorMessage = 'Error al procesar la respuesta del servidor';
} else if (xhr.status) {
switch(xhr.status) {
case 401:
errorMessage = 'Tu sesión ha expirado. Recarga la página e inicia sesión nuevamente.';
break;
case 403:
errorMessage = 'No tienes permisos para realizar esta acción';
break;
case 404:
errorMessage = 'El servicio no está disponible temporalmente';
break;
case 500:
errorMessage = 'Error interno del servidor. Contacta al administrador.';
break;
default:
errorMessage = `Error del servidor (${xhr.status}): ${xhr.statusText}`;
}
}
handleUpdateError(errorMessage, $sel, oldStatus);
},
complete: function() {
// Quitar loading siempre
setSelectLoading($sel, false);
}
});
});
// Al cargar, aplica bloqueo si ya está en “Solicitar importación
// Función para manejar errores de actualización
function handleUpdateError(message, $select, oldStatus) {
// Revertir el select al estado anterior
$select.val(oldStatus);
// Mostrar error
Swal.fire({
title: 'Error',
text: message,
icon: 'error',
confirmButtonText: 'Entendido'
});
// Log para debugging
console.error('Error al actualizar estado:', message);
}
// Al cargar, aplica bloqueo si ya está en "Solicitar importación"
$('#tabla-solicitudes tbody tr').each(function () {
const $sel = $(this).find('.status-select');
if ($sel.length) updateRowStatus($(this), $sel.val());
if ($sel.length) {
updateRowStatus($(this), $sel.val());
// Guardar estado inicial
$sel.data('old-status', $sel.val());
}
});
// Interceptar errores globales de AJAX para debugging
$(document).ajaxError(function(event, xhr, settings, thrownError) {
if (settings.url.includes('update_status')) {
console.error('AJAX Error Details:', {
url: settings.url,
status: xhr.status,
statusText: xhr.statusText,
responseText: xhr.responseText,
thrownError: thrownError
});
}
});
// Mensajes SweetAlert tras acciones