feat: módulo de facturas venta (Ventas/Crear) para contrato 040

- generar_factura_venta en json_generator.py con mapeo completo del JSON
- Queries default tipo 'ventas' (por fecha y por número) filtradas a contrato 040
- Ruta /ventas con preview, send-one y send masivo
- Template ventas.html con tabla, resumen y modal JSON
- Link en navegación lateral

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-11 11:16:42 -05:00
co-authored by Claude Sonnet 4.6
parent 6fb18a7af6
commit 6b84ecfd90
6 changed files with 772 additions and 2 deletions
+69 -1
View File
@@ -2,7 +2,7 @@ import re as _re
from collections import defaultdict
from datetime import datetime, date, timedelta
from typing import Optional
# v1.4.0
# v1.5.0
# ── helpers de formato de fecha ──────────────────────────────────────────────
@@ -245,6 +245,74 @@ def generar_rda_paciente(rows: list, default_profesional: str = "", default_espe
return _clean_times(result)
# ── Ventas/Crear ─────────────────────────────────────────────────────────────
def generar_factura_venta(rows: list, default_vendedor: str = "00",
default_prefijo: str = "00", numero_override: str = "") -> dict:
if not rows:
return {}
h = rows[0]
num_fac = (numero_override if numero_override else str(h.get("NUM_FACTURA") or "")).zfill(5)
fecha = _fmt_fecha(h.get("FECHA_RECEPCION"))
detalle_pedido = []
for row in rows:
precio = float(row.get("PRECIO_TARIFA") or row.get("PRECIO") or 0)
detalle_pedido.append({
"codMat": str(row.get("CUPS") or row.get("COD_EXAMEN") or "").strip(),
"codBodega": "00",
"codTalla": "",
"codColor": "",
"cantidad": 1,
"tipoUnidad": "M",
"descuento": 0,
"descuentoValor": 0,
"precioExcento": precio,
"centrosCostos": "00",
"porcIva": 0,
"valor": precio,
"impConsumo": 0,
"observacion": "",
"lote": "",
"fechaVenceLote": "",
"nroDocumento": "",
"itemsSerial": [],
"tipoSerial": "",
})
return _clean_times({
"codigoPrefijo": default_prefijo or "00",
"numero": num_fac,
"numeroFactura": num_fac,
"fecha": fecha,
"kardexId": 0,
"codigoPedido": "",
"nombreCliente": "",
"codTercero": str(h.get("COD_PACIENTE") or "").strip(),
"codVendedor": default_vendedor or "00",
"codDespachar": "00",
"codFormaPago": "CO",
"codBanco": "00",
"fechaVence": fecha,
"fechaEntrega": fecha,
"plazoDias": 30,
"observacion": "",
"latitud": "",
"longitud": "",
"motivo": "",
"numeroFacturaDevolucion": "",
"tipoOperacion": "",
"codigoCentroCosto": "00",
"codigoArea": "00",
"terminal": "00",
"detallePedido": detalle_pedido,
"detalleFormaPago": [],
"asentar": 0,
"detalleDescuentos": [],
})
# ── funciones legacy RIPS 2.0 (se mantienen) ─────────────────────────────────
def generar_terceros(row: dict) -> dict: