Notificaciones Cambio de Estado de Solicitud
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user