Commit Graph
59 Commits
Author SHA1 Message Date
Lizandro GuarnizoandClaude Sonnet 4.6 7ac17e29a9 fix: remove duplicate agrupar_por_factura that was overriding the correct one
The second definition (for RIPS 2.0 transacción grouping) was never called
but silently overrode the CMXC ventas grouper, causing grupos_vta to always
be empty (values were dicts, not lists, so isinstance(v, list) was False).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 15:45:56 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 3a0964e4ec fix: generar_factura_venta uses PREFIJO from row, not config default
codigoPrefijo in ventas JSON must be the actual Firebird PREFIJO
(e.g. "CMXC"), not the prefijo_tns_default config value which is
intended for RDA/transaccion. Falls back to default_prefijo if row
has no PREFIJO.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 09:59:40 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 7f2dffc63e fix: group ventas by NUM_FACTURA, not IDRECEPCION
A single CMXC invoice (e.g. CMXC-307) can have multiple receptions.
Previously each reception was sent as a separate ventas, causing TNS
to accept the first and reject the rest with "ya existe" — leaving
only 1/N of the services registered.

Now agrupar_por_factura groups all receptions sharing the same
NUM_FACTURA into one ventas JSON with all their services in
detallePedido. One factura = one send.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-27 17:36:21 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 02b0defef5 fix: ventas CMXC usan NIT_EMPRESA como codTercero en lugar del código de paciente
Las facturas de venta de contratos externos (ej. CMXC) deben ir a nombre
de la empresa referente (NIT sin dígito de verificación), no del paciente.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-24 19:08:02 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 03655427a5 fix(rips): discapacidad siempre 08, diagnostico default Z017 si vacío
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 22:33:59 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 73062af8bc feat: paso 4 ventas en automation + fixes varios
- Automation: agrega Paso 4 (Ventas/Crear) con fetch _SQL_VENTAS,
  filtro por excluded_ventas_set, loop de envío y log de actividad
- Automation: _guardar_envio ahora almacena idrecepcion y contrato
  para que /ventas reconozca registros enviados por automation
- Contratos: corrige NameError en toggle_excluir (faltaba request: Request)
- Ventas: agrega check if not q en send_one y send para evitar TypeError
- Ventas HTML: agrega columna Contrato en la tabla de facturas
- json_generator: normaliza etnia >2 chars a '99' (ej: 999 → 99)
- json_generator: agrega campo ciudadExp usando el mismo cod_ciudad

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 14:29:39 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 6b84ecfd90 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>
2026-07-11 11:16:42 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 6fb18a7af6 revert: especialidad siempre usa el default de config
Revertir el uso de COD_ESPECIALIDAD desde la BD; la especialidad
siempre debe venir del valor configurado (especialidad_default).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 10:23:33 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 3313337672 fix: usar COD_ESPECIALIDAD de la BD en detallePedido
La especialidad ahora toma el valor del campo COD_ESPECIALIDAD de la tabla
MEDICO (ya presente en todos los SELECTs), con fallback al default de config.
El profesional sigue viniendo de configuración en todos los flujos.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 10:19:42 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 2a7553267b Fix tipoDocumento PE/PT: map to single char 'E' for TNS API compatibility
TNS API (C#) expects System.Char for tipoDocumento; "PE" and "PT" caused
400 validation errors. Mapped both to "E" (Cédula Extranjería).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 08:31:33 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 9f2bd5164e feat: opcion 'sin contrato' para enviar numeroContrato null en TNS
- Agrega columna sin_contrato en tabla contratos (migration automatica)
- Contrato 040 marcado excluir=0, sin_contrato=1 en seed
- load_sin_contrato_set() retorna contratos que deben ir con null
- generar_rda_paciente acepta sin_contrato_set y fuerza numeroContrato=null
- Automation paso 2 y 3 pasan sin_contrato_set al generador
- Pagina contratos: columna y toggle "Sin contrato", checkbox en modal editar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 21:22:09 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c2a092c0e7 feat: paso 3 pre-servicios RCXC/SC y limpieza de código copago
- Agrega paso 3 en automatización: envía RDA desde PRESSERV_DIAN (prefijos RCXC/SC) para pacientes EPS con PS_NUM IS NOT NULL
- Filtra paso 2 con PS_NUM IS NULL para separar particulares/empresas de EPS
- Elimina parámetro copago y función _calcular_descuento_pct (código muerto)
- Limpia referencia a d.copago en automation.html (UI paso 3)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 20:43:02 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 8e29e2d04f fix: tipoIngreso siempre "1" (ambulatorio) en todos los flujos
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 16:52:53 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 d9a414396f feat: campo descuento en RDA calculado desde VALORDESC/VALORTOTAL
descuento = round(VALORDESC * 100 / VALORTOTAL, 2), 0 si sin descuento

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 16:52:00 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c5f84aa900 feat: numero de factura con ceros a la izquierda hasta 5 dígitos (zfill 5)
Ejemplo: 355 → 00355, 3726 → 03726
Aplica a todos los flujos: transacción, automation, send-direct, test-rda.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 16:08:38 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 d3a6ab7ab6 fix(tipousuario): contrato 012 no debe ser tratado como particular
El check `"012".lstrip("0") == "12"` causaba false positive marcando
contratos EPS como particulares. Ahora la heurística solo aplica si el
contrato no está en la tabla contratos; si está, el tipo_usuario del mapa
tiene precedencia y también controla es_particular.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 15:06:38 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 0f3a760de4 feat(contratos): tabla de contratos con tipo_usuario por contrato
Agrega tabla `contratos` en SQLite sembrada con los 17 contratos del
laboratorio. `generar_rda_paciente` consulta el mapa contrato→tipoUsuario
como primera prioridad antes de derivar de TIPOUSU/TIPOUSUSISPRO.
Incluye CRUD en /contratos con UI en sidebar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 15:00:21 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 a94e2cce9f feat: omit fechaAutorizacion and vigenciaAutorizacion when numeroAutorizacion is null
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 10:23:42 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 b88d727623 feat: add 5 minutes to fechaHoraEgreso in RDA
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-06 19:44:06 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 235e20e38d feat: remove unused fields from RDA JSON output
Remove codFormaPago, codBanco, descuento from header.
Remove tipoUnidad, descuento, porcentajeIva, impConsumo from detallePedido.
Remove detalleFormaPago entirely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 21:59:02 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 3aa0e09aa6 chore: bump version marker in json_generator
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 09:31:24 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 72973973d4 feat: calculate real discount % from TARIFA vs RELACION.PRECIO
Joins TARIFA using EMPRESA.TARIFA to get the base price per exam,
then calculates descuento = round((sum(TARIFA) - sum(PRECIO)) / sum(TARIFA) * 100)
and sends it as integer percentage in the RDA header encabezado.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 17:26:49 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 15f6ca65db feat: add descuento from RECEPCION.VALORDESC to RDA header
Pulls r.VALORDESC in all SQL queries (automation, test_rda, queries
defaults) and maps it to the top-level descuento field in the
RdaPaciente JSON encabezado.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 17:13:46 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 68aa5e0355 feat: join ITEM on COD_PROTOCOLO to get CUPS_DETALLE as codigoMaterial
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 12:29:33 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 41ee88c1b4 fix: remove rel.DESCUENTO (column does not exist in RELACION table)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 12:26:09 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 d1c1d3205f revert: remove broken ITEM join until correct field name is known
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 12:24:01 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ff08c1b3a8 feat: use ITEM.CUPS_DETALLE as codigoMaterial in RDA
LEFT JOIN ITEM on COD_EXAMEN to get CUPS_DETALLE. Falls back to
COD_EXAMEN if CUPS is empty. Applied to automation, test_rda, and
saved queries in SQLite.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 12:20:22 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 8732db9c1f fix: use Firebird PREFIJO as codigoPrefijo; add debug endpoint to find CUPs field
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 12:07:43 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ed9fead353 fix: remove valor field from detallePedido; filter by PREFIJO in transaccion
- json_generator: remove valor entirely from detalle items (not even 0)
- transaccion: after fetching rows, filter by prefix if user typed full
  factura like "LHXC03726" and query returns PREFIJO column

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 12:00:42 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 1548aadf3c fix: set valor=0 in detallePedido; parse full factura (prefix+number) in search
- json_generator: send valor:0 per item instead of PRECIO from Firebird
- test_rda + transaccion: accept "LHXC03726" format — extracts numeric part
  for NUM_FACTURA and letter prefix for PREFIJO filter when prefix present

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 11:54:08 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 02c2f7a17b fix: combinar fecha+hora separados de Firebird en fechaHoraIngreso
HORAINICIORECEPCION es campo TIME en Firebird — fdb lo devuelve como
datetime.time sin fecha. _fmt_datetime recibía '06:08:29' y lo pasaba
tal cual al JSON. TNS rechazaba por formato inválido.

- _fmt_datetime ahora maneja entrada solo-fecha → agrega 00:00:00
- generar_rda_paciente combina HORAINICIORECEPCION + FECHA_RECEPCION
  antes de llamar _fmt_datetime cuando detecta hora sin fecha

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 20:50:01 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 9d80279114 fix: strip spaces around colons in entire RDA JSON before returning
Adds _clean_times() that recursively walks every string in the result
dict and applies re.sub(r'\s*:\s*', ':'), guaranteeing no "12: 47: 37"
spaces survive to the TNS API regardless of Firebird driver behaviour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 20:16:23 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 9d87c3fa1c fix: usar regex en _fmt_datetime para eliminar espacios en horas de Firebird
re.sub('\s*:\s*', ':') captura cualquier tipo de espacio alrededor
de los dos puntos, incluyendo tipos no-ASCII que .replace() no atrapa.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 20:01:28 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 4aa30c74c1 fix: restaurar codFormaPago en header RDA (campo requerido segun docs)
La documentacion marca CodFormaPago como Requerido=Si. Su ausencia
causaba 'Datos incorrectos' en TNS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 19:23:08 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c7428a196b fix: quitar codFormaPago header, fechaAutorizacion=hoy, descuento de Firebird
- Elimina codFormaPago del header RDA (no va segun JSON de referencia)
- fechaAutorizacion usa fecha de hoy, no la de recepcion
- descuento toma rel.DESCUENTO de Firebird en vez de hardcodeado 0
- Agrega rel.DESCUENTO al SELECT en test_rda y automation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 16:12:48 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 543af23779 fix: restaurar codFormaPago en header RDA (requerido por TNS)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 15:26:35 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c5d6b9857e fix: eliminar espacios en horas de Firebird en fechaHoraIngreso/Egreso/Realizacion
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 15:16:58 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 dd4d012a4b fix: fechaHoraEgreso = fechaHoraRealizacion del ultimo examen
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 15:12:59 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 00bfbaee51 fix: vigenciaAutorizacion siempre 30
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 15:09:43 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 2321771c3e fix: quitar codFormaPago del header RDA, añadir fechaAutorizacion y vigenciaAutorizacion
- Elimina codFormaPago del header principal (queda en detalleFormaPago)
- Añade fechaAutorizacion con la fecha de recepcion (dd/MM/yyyy)
- Añade vigenciaAutorizacion: 0 para particular, 30 para EPS/convenio

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 15:00:17 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 90de09b22c Fix RDA: quitar campos demograficos del RDA (solo van en Tercero); identidadGenero con ceros "01"/"02"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 20:50:39 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 58bdb4ae55 Agrega campos demograficos paciente en RDA y Tercero (etnia, zona, identidadGenero, divPolitica, antecedentes, fechaNac, direccion)
- SQL RDA join PACIENTE para obtener datos demograficos
- generar_rda_paciente: incluye etnia, identidadGenero, zona, divisionPoliticaAdministrativa, antecedentes, fechaNacimiento, direccion
- generar_tercero_api: agrega identidadGenero, divisionPoliticaAdministrativa, antecedentes; default ciudad Cucuta 54001

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 20:49:12 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 bdc0e244fc Fix NameError: mover autorizacion después de definir es_particular
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 20:28:57 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 5c03e58639 Fix contrato particular: usar "012" (como está en TNS y Firebird)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 20:27:01 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 be272296af Fix particular: numeroContrato siempre "12" y sin numeroAutorizacion
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 20:26:42 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 69372a5673 Agrega filtro convenio en automation/transaccion/test-rda y fix particular (contrato 12)
- automation: filtro contrato en SQL pacientes+RDA, numero LHXC en run()
- transaccion: filtro contrato en preview/send-one/send
- test-rda: filtro tipo_usuario (11/07/12), default contrato "12", acepta "12"/"012"
- json_generator: detecta particular por CODCONTRATO "12"/"012" además de NIT_EMPRESA PART; fuerza tipousuario="12", codFormaPago="CLIP", plazoDias="0"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 20:23:00 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 d9d3deef6c Fix colisión de numero de factura en TNS cuando varios IDRECEPCION comparten NUM_FACTURA
- json_generator: agrega parámetro numero_override para usar un número alternativo
- test_rda: detecta si el NUM_FACTURA ya fue enviado exitosamente (sesión o rda_test_log) y usa "{factura}-{idrecepcion}" como numero único en TNS
- transaccion: misma lógica en envío masivo, evita que el segundo IDRECEPCION de la misma factura falle con 409

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 19:50:30 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 7e0c6039b8 Fix profesionalRemisionante con slash y mejora display resultado test-rda
- json_generator: limpia DOCIDMEDICO a solo dígitos (eg "9410/86" → "941086") para que TNS acepte el código
- test_rda.html: resultado con syntax highlight en JSON enviado y respuesta TNS, mejor legibilidad del error TNS, botones Resp.TNS y JSON env. con íconos

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 19:44:46 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 c64a68ec6f Add test-rda page, fix prefijo/remisionante/especialidad for TNS RDA sends
- New /test-rda route: list Firebird candidates with valid contract/factura,
  send individual RDA with auto tercero creation and full result display
- json_generator: use prefijo_tns_default config instead of Firebird PREFIJO,
  add profesionalRemisionante from DOCIDMEDICO or remisionante_default config
- All queries: add DOCIDMEDICO column from MEDICO JOIN
- automation/transaccion: add remisionante_default and prefijo_tns_default params
- config: add remisionante_default (00) and prefijo_tns_default (00) keys
- automation SQL: filter NUM_FACTURA > 0 to skip unbilled records
- config.html: add UI fields for new config keys

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 18:57:54 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 3017c7956e Fix numeroContrato: use EMPRESA.CODCONTRATO from Firebird, sucursal default 00
- Join EMPRESA table in all RDA queries to get CODCONTRATO (TNS contract code)
- Use EMPRESA.CODCONTRATO as numeroContrato instead of raw NIT_EMPRESA
- Especialidad always uses default_especialidad (ignore Firebird COD_ESPECIALIDAD)
- sucursal defaults to '00' (not empty) in config and endpoints
- Fix config template label: especialidad default is TNS code not Firebird code

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 18:01:32 -05:00