Procesador RO
Registro de Operaciones · UIF-Perú / SBS
El problema
Una casa de cambio supervisada por la SBS debe reportar cada mes toda operación de divisas por USD 5.000 o más, en un formato oficial de 26 columnas. La información vivía en tres sitios que no se hablaban: un PDF mensual de facturas —entre 48 y 81 páginas, una por página, con formato irregular—, el portal de consulta RUC de SUNAT, de donde salen los datos del representante legal que la factura no trae, y una plantilla Excel con filas ya cargadas a mano que no se podían perder ni duplicar. El proceso era abrir página por página, decidir si supera el umbral, transcribir diez campos, ir a SUNAT a buscar el representante legal, copiar cinco campos más, rellenar once códigos fijos y, al final, reordenar por fecha y renumerar el correlativo.
Arquitectura
PDF mensual (48–81 páginas)
└─ pdfplumber ────────► extracción de texto por página
└─ ¿factura válida? ──no──► omitida, con el motivo al log
└─ parser tolerante ──► 41 formas estructurales
└─ ¿≥ USD 5.000? ──no──► descartada, con su monto al log
└─ InvoiceRecord
└─ SUNAT headless ──► representante legal
└─ merge idempotente + backfill
└─ orden por fecha + renumeración
└─ Excel UIF · 26 columnasDecisiones
El formato de la factura no existe
La línea que describe la operación la escribe a mano quien emite la factura. Al analizar las 386 páginas aparecieron 365 líneas distintas que se reducen a 41 formas estructurales. No hay un formato: hay una distribución de improvisaciones. El parser las cubre todas sin adivinar, incluido un typo del emisor y una factura que ni menciona si es compra o venta.
95 × COMPRA DE N $ TC N N forma dominante
85 × COMPRA $N A TC N N
59 × COMPRA DE N $ AL TC N N
27 × VENTA DE N $ TC N N
4 × COMPRA $N A TC N DE LA FECHA N DE SEPTIEMBRE N
2 × COMPRA DE N $ TC N CON LA FECHA DE N/N/N N
1 × COMOPRA DE N $ TC N N typo del emisor
1 × COMPRA DE N EUROS AL TC N N otra divisa
1 × VENTA $N ATC N N sin espacio
1 × $N A TC N N sin COMPRA ni VENTA
…y 25 formas más de aparición únicaDegradación explícita, nunca adivinanza silenciosa
Si la línea no dice COMPRA ni VENTA, el parser asume COMPRA y emite un aviso nominal para revisión humana. Prefiere una fila marcada a una fila inventada. Lo mismo con las operaciones bajo el umbral: se descartan, pero quedan en el log con su monto. En un reporte fiscalizable, un dato que desaparece sin dejar rastro es peor que un dato erróneo señalado.
[202510] OK E001-4628 | 13/10/2025 | COMPRA USD 20,000.00 | TRANSPORTES ANDINA EXPRESS S.A.C. [202510] OMITIDA E001-4629 | USD 500.00 < 5,000 [202510] OK E001-4639 | 02/10/2025 | VENTA USD 25,000.00 | COMERCIALIZADORA TEXTIL GAMARRA S.A.C. [202510] AVISO E001-4642: Operación COMPRA/VENTA no indicada explícitamente [202510] — se asumió COMPRA. Verificar. [202510] AVISO OMITIDA página 4: N° de comprobante no encontrado (patrón E###-####) [202510] Total facturas extraídas: 18 [202510] Consultando representantes legales en SUNAT... [202510] Consultando SUNAT [1/16]: RUC 20902887752 [202510] Total filas en el archivo: 23 (18 facturas + boletas existentes)
El dato clave no está en el documento
Cinco de las 26 columnas —tipo y número de documento del representante legal, apellidos y nombres— no figuran en ninguna factura: solo existen en el portal de SUNAT. Hay que ir a buscarlas empresa por empresa. La consulta va cacheada y deduplicada, con una sola sesión de navegador para todo el lote y una pausa cortés entre consultas: las 148 filas se resolvieron con 33 consultas.
Idempotencia sobre trabajo humano previo
La plantilla llega con filas cargadas a mano que no se pueden perder ni duplicar. La deduplicación es por comprobante normalizado, así que E001-4801 y 4801-E001 son el mismo: un mes se puede reprocesar las veces que haga falta sin duplicar una sola fila. Y si la plantilla ya tenía filas con RUC pero sin representante legal, el procesador también las completa. No solo agrega lo nuevo: repara lo que estaba a medias.
plantilla de octubre 5 filas (una incompleta) + 18 facturas nuevas + backfill de la fila incompleta + reorden por fecha y renumeración ───────────────────────────────── salida 23 filas
Quien lo usa no abre una terminal
El operador que presenta el reporte no es programador. El pipeline vive detrás de una aplicación de escritorio en Tkinter: se eligen las carpetas, se pulsa un botón y el log aparece en la misma ventana, con cada página, cada aviso y cada consulta a SUNAT a la vista. Sin esa capa, la automatización habría vuelto a depender de alguien de sistemas cada mes.
┌──────────────────────────────────────────────────────────┐ │ Procesador de Registro de Operaciones │ │ Casa de cambio · Formato UIF-Perú / SBS │ ├──────────────────────────────────────────────────────────┤ │ Carpeta con PDFs [ .../input ] [Examinar] │ │ Plantilla Excel [ .../template ] [Examinar] │ │ Carpeta de salida [ .../output ] [Examinar] │ │ Nombre del archivo [ RO_202510.xlsx ] │ │ │ │ [ PROCESAR ] │ ├──────────────────────────────────────────────────────────┤ │ Log de procesamiento │ │ cada página, aviso y consulta a SUNAT queda registrada │ │ │ │ [202510] OK E001-4628 | COMPRA USD 20,000.00 │ │ [202510] OMITIDA E001-4629 | USD 500.00 < 5,000 │ │ [202510] AVISO E001-4642: se asumió COMPRA. Verificar │ │ │ │ [Abrir archivo generado] [Limpiar log] Listo. │ └──────────────────────────────────────────────────────────┘
El resultado, con su reserva
Los volúmenes de este caso están medidos sobre los archivos del proyecto. Los tiempos del proceso manual no: son estimaciones de quien lo hacía, no cronometrajes. Lo digo porque la diferencia entre «medido» y «estimado» es exactamente el tipo de distinción que este proyecto existe para respetar.
manual automatizado
triaje de 386 páginas ≈ 1,5 h automático
transcripción de 148 × 26 campos ≈ 7 h automático
33 consultas de representante legal ≈ 1 h ≈ 3–4 min
dedupe, orden por fecha, renumerado ≈ 2,5 h automático
────────────────────────────────────────────────────────────────
total ≈ 10–12 h ≈ 5 min
(1,5 jornadas) + 15 min de revisiónLa operación decide la dirección del dinero
En una COMPRA la divisa entra y salen soles; en una VENTA es al revés. Invertirlo produce un reporte espejado, perfectamente presentable y completamente falso. El mapeo DE → A se deriva del tipo de operación, no de la posición de los importes en la factura.
El producto
La salida
La salida, para el mismo comprobante
| N° Reg. | Fecha | Depto. | Prov. | Dist. | Tipo doc. | N° doc. | Ap. paterno | Ap. materno | Nombres | País | Ocupación | A favor de | N° RUC | Ap. paterno o razón social | Ap. materno | Nombres | Ocupación | Tipo de fondo | Tipo de op. | Origen | Moneda | Monto | Moneda | Monto | N° comprobante |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 01/10/2025 | 15 | 01 | 22 | 001 | 43•••••• | BENITES | OCHOA | GABRIELA | PE | 004 | 003 | 20901996640 | CONSULTORA FINANCIERA ANDES S.A.C. | — | — | — | 001 | 003 | 099 | USD | 6000.00 | PEN | 20388.00 | B001-1242 |
| 2 | 01/10/2025 | 15 | 01 | 22 | 001 | 43•••••• | BENITES | OCHOA | GABRIELA | PE | 004 | 003 | 20901996640 | CONSULTORA FINANCIERA ANDES S.A.C. | — | — | — | 001 | 003 | 099 | USD | 21000.00 | PEN | 79569.00 | B001-1245 |
| 3 | 01/10/2025 | 15 | 01 | 22 | 001 | 44•••••• | HERRERA | VALDEZ | MONICA PATRICIA | PE | 004 | 003 | 20902114428 | COMERCIALIZADORA TEXTIL GAMARRA S.A.C. | — | — | — | 001 | 003 | 099 | USD | 6200.00 | PEN | 22605.20 | E001-4627 |
| 4 | 01/10/2025 | 15 | 01 | 22 | 001 | 07•••••• | PAREDES | CORDOVA | LUIS ALBERTO | PE | 004 | 003 | 20901224317 | AGENCIA DE ADUANAS MERIDIANO S.A. | — | — | — | 001 | 003 | 099 | USD | 5000.00 | PEN | 17100.00 | E001-4635 |
| 5 | 02/10/2025 | 15 | 01 | 22 | 001 | 44•••••• | HERRERA | VALDEZ | MONICA PATRICIA | PE | 004 | 003 | 20902114428 | COMERCIALIZADORA TEXTIL GAMARRA S.A.C. | — | — | — | 001 | 003 | 099 | PEN | 93450.00 | USD | 25000.00 | E001-4639 |
| 6 | 03/10/2025 | 15 | 01 | 22 | 001 | 46•••••• | SALAZAR | DUENAS | VERONICA | PE | 004 | 003 | 20903114428 | REPRESENTACIONES COMERCIALES ORIENTE S.A.C. | — | — | — | 001 | 003 | 099 | USD | 18000.00 | PEN | 62478.00 | E001-4613 |
| 7 | 04/10/2025 | 15 | 01 | 22 | 001 | 06•••••• | FLORES | AGUILAR | CESAR AUGUSTO | PE | 004 | 003 | 20900884751 | DISTRIBUIDORA COMERCIAL LOS OLIVOS S.A.C. | — | — | — | 001 | 003 | 099 | USD | 8500.00 | PEN | 30328.00 | E001-4602 |
| 8 | 05/10/2025 | 15 | 01 | 22 | 001 | 10•••••• | TAPIA | BUSTAMANTE | OSCAR RAUL | PE | 004 | 003 | 20902887752 | EXPORTACIONES CAFETALERAS CHANCHAMAYO E.I.R.L. | — | — | — | 001 | 003 | 099 | PEN | 33354.00 | USD | 9000.00 | E001-4596 |
8 de las 23 filas de octubre. Las cinco columnas resaltadas no existen en la factura: salieron de una consulta a SUNAT. Datos sintéticos — los RUC llevan dígito verificador inválido a propósito y los documentos van enmascarados, como corresponde a una demo de compliance.
Cifras
- 386
- páginas de PDF procesadasBRIEF — medido sobre los archivos
- 41
- formas estructurales de la línea de operaciónBRIEF — 365 líneas únicas
- 148
- filas generadas en 6 mesesBRIEF — 28/34/24/23/22/17
- 33
- consultas a SUNAT para 148 filasBRIEF — deduplicadas y cacheadas
- 87
- facturas sobre el umbral de USD 5.000BRIEF — medido
- ~1 500
- líneas de códigoBRIEF — medido
Lo que demuestra
| Habilidad | Evidencia |
|---|---|
| Datos sucios del mundo real | 41 formas estructurales cubiertas sin adivinar, incluido un typo del emisor y facturas sin COMPRA/VENTA explícito |
| Criterio en dominio fiscalizable | Nada se descarta en silencio: cada omisión y cada suposición queda en el log con su motivo |
| Idempotencia | Deduplicación por comprobante normalizado y backfill de filas incompletas cargadas a mano |
| Integración con lo que no se puede pedir | Cinco columnas que solo existen en SUNAT, resueltas con scraping cacheado: 148 filas con 33 consultas |
| Reglas de negocio codificadas | Umbral, mapeo DE → A según operación y once códigos fijos aplicados de forma reproducible |
Deuda técnica reconocida
Un case study que solo lista aciertos no resiste una pregunta difícil.
- El scraper depende del DOM del portal SUNAT: un rediseño lo rompe. Falla con aviso, sin corromper la salida.
- Los códigos fijos están cableados para esta empresa —ubigeo, ocupación, tipo de fondo—. Para otra casa de cambio habría que parametrizarlos.
- Las facturas sin COMPRA o VENTA explícito se asumen COMPRA y quedan marcadas para validación manual.