feat: sistema de 3 estados (success/warning/error) para envíos TNS
- _parse_tns_resp retorna 'success'|'warning'|'error' en lugar de bool - 'ya existe/registrado/autorización' → warning (sin reenvío, no es error real) - errores reales → error (con reenvío) - Guarda JSON crudo completo en respuesta_api - logs.html: badge amarillo para warning, verde para success, rojo para error - Filtro de historial incluye opción 'warning' - reenvío en logs.py solo disponible para status='error' - reenvío en logs.py usa misma lógica _parse_tns_resp y soporta ventas Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
a37c1bb7d6
commit
6a452cd950
+15
-12
@@ -12,10 +12,10 @@
|
||||
{% if s.tipo == 'transaccion' %}bg-purple-100 text-purple-700
|
||||
{% elif s.tipo == 'ventas' %}bg-emerald-100 text-emerald-700
|
||||
{% else %}bg-blue-100 text-blue-700{% endif %}">{{ s.tipo }}</span>
|
||||
<span class="{% if s.status == 'success' %}text-green-600{% else %}text-red-600{% endif %} font-bold text-sm">
|
||||
<span class="{% if s.status == 'success' %}text-green-600{% elif s.status == 'warning' %}text-yellow-600{% else %}text-red-600{% endif %} font-bold text-sm">
|
||||
{{ s.cnt }}
|
||||
</span>
|
||||
<span class="text-gray-400 text-xs">{{ 'exitosos' if s.status == 'success' else 'errores' }}</span>
|
||||
<span class="text-gray-400 text-xs">{{ 'enviados' if s.status == 'success' else ('ya existe' if s.status == 'warning' else 'errores') }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="bg-white rounded-lg border border-gray-200 px-4 py-2.5 shadow-sm flex items-center gap-2 text-gray-500 text-sm">
|
||||
@@ -42,8 +42,9 @@
|
||||
<label class="block text-xs font-medium text-gray-500 mb-1">Estado</label>
|
||||
<select name="status" class="px-3 py-1.5 border border-gray-300 rounded-lg text-sm min-w-[120px]">
|
||||
<option value="">Todos</option>
|
||||
<option value="success" {{ 'selected' if filtro_status == 'success' }}>Exitoso</option>
|
||||
<option value="error" {{ 'selected' if filtro_status == 'error' }}>Error</option>
|
||||
<option value="success" {{ 'selected' if filtro_status == 'success' }}>✓ Enviado</option>
|
||||
<option value="warning" {{ 'selected' if filtro_status == 'warning' }}>! Ya existe</option>
|
||||
<option value="error" {{ 'selected' if filtro_status == 'error' }}>✗ Error</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
@@ -109,7 +110,7 @@
|
||||
<tbody>
|
||||
{% for e in envios %}
|
||||
<tr class="border-b border-gray-50 hover:bg-gray-50 transition-colors
|
||||
{% if e.status == 'success' %}bg-green-50/25{% elif e.status == 'error' %}bg-red-50/25{% endif %}">
|
||||
{% if e.status == 'success' %}bg-green-50/25{% elif e.status == 'warning' %}bg-yellow-50/40{% elif e.status == 'error' %}bg-red-50/25{% endif %}">
|
||||
<td class="px-4 py-2.5 text-gray-400 font-mono">{{ e.id }}</td>
|
||||
<td class="px-2 py-2.5">
|
||||
<span class="px-2 py-0.5 rounded text-xs font-medium
|
||||
@@ -123,11 +124,13 @@
|
||||
<td class="px-2 py-2.5 text-gray-500 font-mono">{{ e.idrecepcion or '-' }}</td>
|
||||
<td class="px-2 py-2.5 text-gray-500">{{ e.contrato or '-' }}</td>
|
||||
<td class="px-2 py-2.5">
|
||||
<span class="px-2 py-0.5 rounded text-xs font-medium
|
||||
{% if e.status == 'success' %}bg-green-100 text-green-700
|
||||
{% else %}bg-red-100 text-red-700{% endif %}">
|
||||
{{ '✓ OK' if e.status == 'success' else '✗ Error' }}
|
||||
</span>
|
||||
{% if e.status == 'success' %}
|
||||
<span class="px-2 py-0.5 rounded text-xs font-medium bg-green-100 text-green-700">✓ Enviado</span>
|
||||
{% elif e.status == 'warning' %}
|
||||
<span class="px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-700">! Ya existe</span>
|
||||
{% else %}
|
||||
<span class="px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-700">✗ Error</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-2 py-2.5 text-gray-500">
|
||||
{% if e.mensaje_tns %}
|
||||
@@ -247,9 +250,9 @@ async function verDetalle(id) {
|
||||
const data = await resp.json();
|
||||
if (data.error) { showToast(data.error, 'error'); return; }
|
||||
|
||||
const estadoLabel = data.status === 'success' ? '✓ Exitoso' : '✗ Error';
|
||||
const estadoLabel = data.status === 'success' ? '✓ Enviado' : data.status === 'warning' ? '! Ya existe' : '✗ Error';
|
||||
document.getElementById('modal-titulo').innerHTML =
|
||||
`<i class="fas fa-file-alt mr-2 text-blue-500"></i>Envío #${data.id} — <b>${data.tipo}</b> — <span class="${data.status === 'success' ? 'text-green-600' : 'text-red-600'}">${estadoLabel}</span>`;
|
||||
`<i class="fas fa-file-alt mr-2 text-blue-500"></i>Envío #${data.id} — <b>${data.tipo}</b> — <span class="${data.status === 'success' ? 'text-green-600' : data.status === 'warning' ? 'text-yellow-600' : 'text-red-600'}">${estadoLabel}</span>`;
|
||||
|
||||
const info = [
|
||||
data.factura ? `<span><b>Factura:</b> ${data.factura}</span>` : '',
|
||||
|
||||
Reference in New Issue
Block a user