#180 [Compras · 2/4] Facturas, validación contable, costos y CxP
Un solo proceso de compras, desarrollado en cuatro bloques
Esta solicitud forma parte de la mejora del módulo de Compras y contratación para proyectos de CONSOF. El resultado conjunto debe permitir gestionar una operación desde la requisición hasta su cierre, conservando el vínculo entre solicitud, negociación, orden/contrato, ejecución, documentos, costos y pagos.
Los cuatro issues distribuyen el desarrollo del mismo proceso. Deben compartir registros y permitir continuar la operación entre pantallas con los datos ya capturados y las aprobaciones aplicables. Reutilizar los componentes existentes de presupuesto, costos/CxP, tesorería y logística.
La numeración no define una secuencia rígida: el control financiero comienza al confirmar el compromiso; la logística interviene durante la ejecución; anticipos y prepagos pueden preceder a la recepción y facturación.
Bloques: 1. Requisición y contratación #179 · 2. Documentos, costos y CxP #180 · 3. Compromisos y pagos #181 · 4. Logística y alquileres #182.
Alcance de este bloque: recepción y revisión de documentos de la misma operación de compras, cálculo asistido, costos y reconocimiento de CxP. Trae acuerdos/conformidades de #179/#182 y entrega la obligación al #181. El recorrido completo y su prueba conjunta están en #179.
Resultado que necesitamos
Que la información llegue del correo al ERP, se cruce con la compra/servicio recibido y se pueda revisar, liquidar e imputar desde una misma pantalla. Al confirmar la revisión, debe alimentar Gastos, presupuesto y CxP sin volver a digitarla.
Sirley realiza actualmente esta revisión y el cálculo de retenciones. Utilizar permisos configurables de auxiliar contable; la integración con el software externo de la contadora queda fuera de esta entrega.
Pantallas existentes a adaptar según #58: /finance/cuentas-por-pagar/, creación/detalle de CxP y /finance/gastos/. Reutilizar los cálculos y pagos parciales que ya funcionan.
1. Recibir documentos del correo
El ERP debe:
- Conectarse al buzón corporativo de recepción y crear registros en una bandeja con correo original, remitente, asunto, fecha/hora real, adjuntos y estado de importación.
- Separar las facturas de un mismo mensaje y reconocer PDF/XML como representaciones de la misma factura cuando corresponda.
- Extraer o proponer tercero, identificación, tipo/número de documento, fechas, conceptos, valores, impuestos y referencias de orden/corte. Sirley debe poder revisar/corregir antes de confirmar.
- Tratar archivos ilegibles, datos incompletos o extracción no disponible como revisión pendiente; mostrar original y permitir captura asistida. No completar datos por suposición.
- Adjuntar soportes recibidos en correos posteriores al mismo registro. Reutilizar el corte, recepción y aprobaciones que ya existan en el ERP.
- Permitir regularización interna de documentos recibidos excepcionalmente por WhatsApp o físico, conservando fecha original, canal y quién registró.
- Mostrar errores de conexión/importación y permitir reintento sin duplicar documentos. La fecha de importación no reemplaza la de recepción.
El correo es el canal ordinario de cobros; no abrir otro portal de facturas en este alcance. La conexión real requiere que CONSOF configure/autorice el buzón; Indunova debe definir el mecanismo de conexión. Se puede construir la bandeja y probar importación con archivos de prueba antes de activar ese acceso.
2. Bandeja y prevención de duplicados
Mostrar estados: Recibido, Pendiente de clasificar, Pendiente de soporte, Pendiente de recepción/corte, En revisión, Con diferencia, Devuelto/rechazado, Duplicado vinculado, Validado y Cruzado con pago previo. Separar este estado del estado de pago del #181.
Permitir filtrar por tercero, proyecto, tipo, fecha de recepción, vencimiento, responsable y pendiente. Desde cada fila abrir documento original, relación con la operación y revisión.
Detectar duplicados usando identificación del tercero + tipo/número de documento e identificador electrónico cuando exista; contrastar importe/fecha. No deduplicar solo por valor. Un reenvío o carga posterior del mismo documento debe vincularse al existente. Cuentas sin número requieren identificación interna y revisión; dos cobros iguales de servicios distintos no se descartan automáticamente.
Utilizar el maestro de terceros existente (#85). Diferenciar identificación/NIT del tercero y número de factura. Si falta asociación, permitir buscarla y corregirla con historial.
3. Pantalla de revisión y correspondencia
En una sola vista mostrar:
- Documento original y datos extraídos.
- Orden/acuerdo con precios, cantidades, condiciones y proyecto.
- Recepción, servicio, corte o liquidación aceptados.
- Impuestos, retenciones, anticipos, descuentos, retenido y neto.
- Imputación y resultado de la revisión.
El sistema debe comparar y señalar diferencias por línea:
| Modalidad | Información que debe traer automáticamente |
|---|---|
| Bienes | Pedido/OC, cantidades/precios y recepción aceptada del #182 |
| Instalación/contratación | Corte o liquidación aprobado y valor autorizado para facturar del #179 |
| Transporte | Tarifa, viajes ejecutados/confirmados, periodo y extras autorizados |
| Alquiler | Piezas/equipos, cantidades, tarifas, periodos, devoluciones parciales, cortes y cobertura prepagada |
| Contado/ya pagado | Desembolso existente para relacionar, sin crear otro pago |
| Anticipo/caja menor | Entrega, responsable, soportes aplicables y saldo pendiente de cruzar |
Si coincide con una aprobación vigente, reutilizarla. Si difiere, permitir remitir exactamente la cantidad/valor/soporte observado al responsable técnico, presupuestal o documental, con comentario y estado de respuesta. No devolver rutinariamente toda factura a Diego/coordinador/Ximena.
Una recepción parcial no valida automáticamente una factura por el total; mostrar aceptado y pendiente por resolver. Mantener visible la ejecución aceptada sin factura en los controles de #97/#181.
4. Calcular y validar dentro del ERP
Campos editables y resultados visibles según aplicabilidad:
- Concepto por documento y por línea; fecha de causación operativa y tratamiento/naturaleza.
- Base, impuesto facturado, total bruto.
- Tipo de retención, base, tarifa e importe.
- Anticipo amortizado, descuento autorizado, retenido contractual y neto.
- Cuenta/referencia contable si se utiliza y observación del revisor.
Reutilizar los maestros y cálculos existentes. Permitir administrar reglas de base/tarifa y su vigencia, seleccionar la regla aplicable y recalcular al editar. No codificar IVA o retención universal. Sirley debe poder revisar o ajustar con permiso y motivo, conservando valores anteriores. Validar importes, redondeos y coherencia en pantalla y backend.
Diferenciar retención tributaria, retenido contractual, descuento/nota crédito, importe discutido y amortización. Mostrar por separado el importe que se descuenta al proveedor y el saldo/destino tributario cuando corresponda. Los cálculos alimentan el mismo neto y saldo que utiliza #181.
En deducciones dinámicas, mostrar Concepto y Valor en dos columnas en escritorio. Agregar, editar, quitar y guardar varias filas debe conservar cálculos y presentación. Es el pendiente visual del #58; el usuario ya confirmó que la resta funciona.
5. Confirmar obligación e imputación
La acción Confirmar revisión debe:
- Guardar validador, fecha, datos definitivos, documentos y conformidades utilizados.
- Registrar la obligación válida con tercero, origen, importe, vencimiento y saldo, y hacerla disponible al #181.
- Actualizar el costo/imputación del mismo origen en Gastos y #97. Si había ejecución estimada, sustituir/completar ese importe, sin sumarlo otra vez.
- Conservar restricciones de pago por hito/importe y su motivo, sin borrar una obligación válida por falta de caja.
- Impedir que doble clic o reintento creen otra obligación.
Recibir un correo no confirma deuda automáticamente. Esperar a programar o pagar tampoco debe ocultarla. Mostrar por separado documento pendiente de revisión, ejecución sin factura y obligación reconocida. El rol contable debe poder registrar el tratamiento operativo que corresponda a ejecución pendiente de facturación, con sustento, sin fabricar una factura.
Precargar centro de costo del proyecto, capítulo/actividad y concepto. Permitir distribuir entre varios centros/capítulos con suma exacta al importe y control de redondeo. Si cambia la imputación aprobada, registrar el cambio y enviar su validación correspondiente. No volver administrativo un costo porque el material pasó por oficina.
Conservar el detalle de conceptos del registro de Gastos. Una salida por anticipo, depósito, activo, existencias o traslado no debe clasificarse automáticamente como gasto de ejecución. Los movimientos de herramientas propias no generan otro costo de compra.
6. Cruces que debe resolver
- Compra ya pagada: vincular factura a desembolso existente y legalizar; no abrir otra deuda pendiente al proveedor.
- Anticipo: mostrar entregado, amortizado y pendiente; aplicar la amortización del corte/liquidación sin crear otra salida de caja. Comparar factura con ejecución autorizada antes de descontar el anticipo.
- Caja menor: relacionar soportes con fondo/responsable y centro; mostrar saldo por justificar, devolver, reponer o reembolsar. Crear obligación de reembolso solo si hay saldo real a favor del responsable, nunca otra deuda al proveedor ya pagado.
- Alquiler: recibir proforma, traer periodos/cantidades/tarifas, señalar solapamiento con cortes anteriores y diferencias. Al validarla, permitir vincular la factura posterior. Proforma y factura son documentos distintos.
- Prepago de alquiler: aplicar consumo al saldo existente; distinguir depósito reembolsable.
- Devolución/nota crédito: vincular aceptación/documento del proveedor y ajustar solo el importe validado. La devolución física no produce automáticamente una nota crédito o reembolso.
- Daño/faltante/depósito aplicado: registrar sustento y aprobación del ajuste, sin cobrar automáticamente al trabajador ni consumir el depósito por defecto.
7. Requisitos, fechas y consulta
Traer los requisitos por operación/hito del #179 y sus validadores. Permitir aportar, observar, validar y marcar No aplica con motivo; un archivo cargado no queda aprobado automáticamente. Documentos técnicos y laborales/SST deben ir al validador correspondiente, no a una aprobación contable genérica.
Conservar recepción original, revisión, requerimiento de corrección, subsanación y vencimiento. La revisión interna no reinicia el plazo. Configurar alerta al superar dos días hábiles de revisión ordinaria; si el pago vence antes, priorizarlo por ese vencimiento.
Mostrar cierre documental y pendientes posteriores al pago separados del saldo financiero. Un paz y salvo que solo se puede emitir después de cancelar debe poder programarse como posterior, sin bloquear ese mismo pago.
En las vistas actuales:
- Habilitar Ver detalle en Gastos/CxP, con soporte, concepto, revisiones y pagos.
- Mostrar proveedor desde maestro o texto legado; “Pendiente de vincular” si falta relación, nunca None. No fusionar registros por semejanza sin revisión.
- Precargar identificación del tercero y ocultar campo libre cuando se elige un tercero del maestro.
- Mostrar “Sin concepto” si realmente falta el dato histórico y permitir regularizarlo.
- Indicar qué estados incluye cada total filtrado. No sumar recibido sin validar como deuda reconocida ni ocultarlo de la bandeja.
- Mantener búsquedas, etiquetas, tildes y formato COP legibles. Conservar fechas locales de negocio (#120).
8. Pruebas de aceptación
| Prueba | Resultado esperado |
|---|---|
| Correo con PDF/XML y reenvío | Un documento lógico; una obligación como máximo; originales conservados |
| Correo con dos facturas y soporte posterior | Dos registros y soporte vinculado al que corresponde |
| Documento sin orden/proyecto | Pendiente de asociación; corrección trazable, sin dato inventado |
| Corte aprobado y factura con/sin diferencia | Reutiliza validación o remite la diferencia específica |
| Varias retenciones/deducciones | Cálculo consistente, dos columnas y persistencia después de guardar |
| Factura $8M y pago $3M, sin otros ajustes | Costo $8M; saldo $5M; no nuevo costo por pagar |
| Contado, anticipo y caja menor | Cruza movimientos existentes sin volver a pagar/reconocer el mismo importe |
| Factura distribuida en dos proyectos | Suma exacta y conceptos conservados; información visible en #97 |
| Alquiler con dos cortes y devolución parcial | No repite días/piezas facturados; prepago y depósito separados |
| Obligación válida sin caja | Visible por pagar; restricción identificada; vencimiento no reiniciado |
| Histórico | Conceptos, archivos, terceros y pagos conservados, sin duplicar saldos |
Enlaces: Contratación #179, Financiero #181, Logístico #182.
Continuidad: absorbe lo documental/contable de #58 y soportes/cobros de #57. Preservar componentes y correcciones de #25/#31/#59/#75. Dependencias existentes: #85 (tercero), #94/#95 (permisos), #97 (presupuesto). Cada obligación tiene un solo registro: #180 la reconoce y #181 aplica pagos.
Comentarios (5)
🤖 Pre-análisis automático (NOVA) — 🟡 falta información
¡Gracias por reportarlo! Para poder atender su solicitud correctamente y a la primera, necesitamos aclarar algunos puntos. ¿Nos ayuda respondiendo aquí mismo?
- ¿Podrían adjuntar el 'diseño COS de proyectos consolidado el 11/09/2026' y los documentos 'DP-COM-13A/13B/15/16'?
- ¿Podrían adjuntar la documentación del 'mecanismo que Indunova documente y configure con acceso autorizado' para la incorporación del buzón de correo corporativo?
- ¿Podrían proporcionar ejemplos de XML y PDF de facturas para entender la estructura de datos a extraer?
- ¿Podrían proporcionar un ejemplo del 'detalle que hoy Sirley digita en Gastos' para entender los conceptos y campos actuales?
- ¿Podrían especificar las tarifas y bases parametrizables para retenciones, o dónde se definen?
- ¿Podrían adjuntar la definición de los permisos por función y alcance referenciados en #94/#95?
Además, nos ayudaría mucho que adjunte lo siguiente:
- Diseño COS de proyectos consolidado (11/09/2026)
- Documentos DP-COM-13A/13B/15/16
- Documentación del mecanismo de incorporación del buzón de correo corporativo al expediente
- Ejemplos de XML/PDF de facturas
- Ejemplos del detalle que hoy Sirley digita en Gastos
- Listado de tarifas y bases parametrizables para retenciones
- Definición de permisos por función y alcance (referenciados en #94/#95)
Se sustituyeron el título y el cuerpo por funciones verificables: incorporar correo, clasificar documentos, cruzarlos con órdenes/cortes, calcular retenciones y alimentar costos/CxP. El cuerpo contiene los campos y pruebas; no depende de adjuntar documentos internos del procedimiento. Indunova define el mecanismo técnico de conexión al correo; CONSOF habilita el acceso al activarlo. Reutilizar cálculos/maestros existentes y admitir parametrización/revisión asistida de bases y tarifas. Las muestras reales sirven para validar la importación; no se requiere una integración con el software de la contadora. El pendiente visual de deducciones del #58 se conserva.
🟡 Avance parcial — Bloque 2/4 de Compras (180A: recepción, bandeja, dedup, retenciones)
Este issue cubre el bloque completo de documentos/costos/CxP. Se construyó con /modulo en dos mitades (180A + 180B) sobre el spine de Compras de #179. Este comentario cierra 180A; 180B (revisión/correspondencia, confirmación de obligación, cruces, adaptación de finance) sigue en construcción — ver sección "Pendiente" abajo.
Deploy: PR #215 (integración) + PR #216 (hotfix encontrado en smoke) → main → Cloud Run revisión consof-00155-k7n, 100% del tráfico confirmado (gcloud run services describe consof).
Tabla de entregables — 180A
| # | Entregable (issue) | Evidencia | Estado |
|---|---|---|---|
| 1 | §1 Conectarse al buzón, crear bandeja con correo/adjuntos/estado | apps/facturas/conectores/imap.py funcional (IMAP real, mockeado en tests) + poll_buzon — FACTURAS_BUZON_ACTIVO=False confirmado en prod (sin env var → default). Conexión real queda pendiente de que CONSOF/Indunnova autoricen el buzón, tal como pide el issue |
✅ (construido e inactivo por diseño) |
| 2 | §1 "Probar importación con archivos de prueba antes de activar ese acceso" | manage.py importar_muestras — camino de prueba oficial, 3 facturas UBL de muestra |
✅ |
| 3 | §1 Separar facturas de un mismo mensaje, reconocer PDF/XML como misma factura | parser_ubl.py::dividir_zip_en_documentos() + huella_dedup compartida PDF/XML |
✅ |
| 4 | §1 Extraer/proponer tercero, ID, fechas, conceptos, valores, impuestos; revisión antes de confirmar; nunca inventar datos | parser_ubl.py (UBL 2.1 DIAN) + parser_pdf.py (heurísticas, nunca inventa — baja confianza → pendiente_clasificar); triada datos_extraidos/datos_confirmados/origen_campo |
✅ |
| 5 | §1 Regularización manual (WhatsApp/físico) conservando fecha/canal/quién registró | regularizar_documento_manual() + pantalla bandeja/regularizar/ |
✅ |
| 6 | §1 Soportes posteriores al mismo registro | agregar_soporte_posterior() — smokeado en prod vía subida real |
✅ |
| 7 | §2 11 estados de bandeja + filtros (tercero/proyecto/tipo/fecha/vencimiento/responsable/pendiente) | BandejaListView — smokeado /facturas/bandeja/ 200 |
✅ |
| 8 | §2 Detección de duplicados por tercero+tipo/número+identificador electrónico, no solo por valor | services_dedup_c2.py::detectar_duplicados() (cierta/candidata) |
✅ |
| 9 | §2 Reenvío del mismo documento se vincula al existente | vincular_reenvio_identico(sha256) |
✅ |
| 10 | §2 Cuentas sin número → identificación interna + revisión | asegurar_identificador_interno() |
✅ |
| 11 | §2 Corregir asociación con historial | corregir_asociacion() + pantalla documento-asociacion |
✅ |
| 12 | §4 (parcial) Motor de retenciones parametrizable, sin universal hardcodeada, vigencia por regla | masters.calcular_retenciones() + ValorUvt/TipoRetencion/ReglaRetencion (seed real: retefuente 4%/6%/2.5%, reteIVA 15%, reteICA) |
✅ |
| 13 | §4 (parcial) Ajuste manual con motivo obligatorio, conserva valor anterior | AjustarRetencionView — motivo obligatorio validado en form |
✅ |
| 14 | §4 (parcial) Deducciones dinámicas — agregar/editar/quitar, conserva cálculo | AgregarDeduccionView/QuitarDeduccionView |
✅ |
Fuera de alcance de este cierre (180B — issue permanece abierto)
§3 pantalla de revisión/correspondencia (comparación por modalidad bienes/instalación/transporte/alquiler/contado/anticipo), §5 confirmar obligación e imputación (alimenta Gastos/#97/#181), §6 los 7 cruces (pagada/anticipo/caja menor/alquiler/prepago/devolución/daño), §7 requisitos-fechas-consulta y adaptación de vistas Gastos/CxP existentes (#58), §8 las 11 pruebas de aceptación del cuerpo del issue (dependen de §3/§5/§6, no aplican aún).
Smoke prod (revisión consof-00155-k7n)
- Login real
qa_claude, crawl 200 en/facturas/,/facturas/bandeja/,/facturas/bandeja/regularizar/,/facturas/config/buzon/. - Write-smoke real: subida de una factura UBL 2.1 DIAN de muestra (
factura_ubl_001.xml, datos anonimizados) por el endpoint real de upload → apareció en la bandeja con estadoen_revision→ verificado en detalle (/facturas/bandeja/1/) → limpiado consoft_delete()(ORM, no hard-delete, per convención del repo). - Bug encontrado en el smoke y corregido antes de este cierre:
BandejaListViewno filtrabais_active=True— un documento soft-deleted seguía visible en la lista principal, inconsistente conservices_dedup_c2(que sí filtra) y con la convención del resto del repo. Fix + test de regresión en PR #216, ya deployado y re-verificado (el documento de prueba ya no aparece en la bandeja). FACTURAS_BUZON_ACTIVOconfirmadoFalseen prod (sin variable de entorno en el servicio Cloud Run → cae al default). Cero intento de conexión IMAP/Graph real.
Migraciones
masters/0021_retenciones_180.py (seed retenciones real), facturas/0001_initial.py, facturas/0002_retencion_documento_c3.py, accounts/0013_facturas_module_auxiliar_contable.py + 0014. Aplicadas en el deploy, verificadas contra prod (seed de TipoRetencion/ReglaRetencion/ValorUvt real).
Root cause de un bug pre-existente encontrado durante la integración (no específico del cliente, de la suite): la reversa de masters/0021 borraba TipoRetencion antes que las ReglaRetencion que lo referencian (on_delete=PROTECT, no CASCADE como decía el comentario) — rompía en cascada cualquier test que reversara migraciones de commercial/projects más allá de cierto punto (el escenario apareció al combinar 180A con el spine de #179). Corregido antes del PR #215.
Este issue no es reproceso (reproceso_rate.py: "sin cierre nuestro previo").
Sigo con 180B (revisión, confirmación de obligación, cruces, finance UI, conectores) — cierro este bloque acá y continúo.
🟡 Bloque 2/4 de Compras — 180B completo (revisión, obligación, cruces, finance UI, conectores)
Continuación del comentario anterior (180A). Con este comentario, #180 queda funcionalmente completo (ambas mitades desplegadas) — quedan gaps reales documentados abajo, no inventados, que ameritan decisión humana o issue de seguimiento.
Deploy: PR #217 → main → Cloud Run revisión consof-00156-rbs, 100% del tráfico confirmado.
Tabla de entregables — 180B
| # | Entregable (issue) | Evidencia | Estado |
|---|---|---|---|
| 1 | §3 Pantalla de revisión de 5 paneles (documento, orden, recepción, retenciones, imputación) | RevisionDocumentoView — smokeado /facturas/documentos/2/revision/ 200, 5 paneles visibles en el HTML real |
✅ |
| 2 | §3 Correspondencia por modalidad contra #179 (instalación/transporte/alquiler reales; bienes/viajes/devoluciones stub #182) |
traer_contexto_operacion() — corte/transporte/alquiler reales vía services_conector_b9; bienes explícitamente {'pendiente_bloque': '#182'} |
✅ (parcial por diseño, #182 no existe aún) |
| 3 | §3 Reutilizar aprobación vigente si coincide; remitir EXACTO el delta si difiere (nunca la factura completa) | DiferenciaLinea + RemisionRevision dirigida a responsable técnico/presupuestal/documental |
✅ |
| 4 | §3 Recepción parcial ≠ validación total | "aceptado"/"pendiente" como cifras separadas | ✅ |
| 5 | §5 Confirmar revisión: obligación única, idempotente, sin duplicar por doble clic | confirmar_revision() (espejo de crear_cxp_desde_pago_unificado, select_for_update) — verificado en prod: documento real sin proyecto asociado disparó correctamente el guard "pendiente de asociación, sin dato inventado" (exactamente el escenario de §8 fila 3 del propio issue) |
✅ |
| 6 | §5 Imputación multi-centro con suma exacta; sustitución de estimación sin duplicar costo | aplicar_imputacion() — reproduce el escenario financiero de #179 §9 ($4M→neto $2.8M) desde #180; test $3M estimado + $8M real ⇒ $8M, no $11M |
✅ |
| 7 | §5 Restricciones de pago conservadas; nunca borrar obligación por falta de caja | restriccion_pago/restriccion_motivo en AccountsPayable |
✅ |
| 8 | §6 Los 7 cruces (pagado/anticipo/caja menor/alquiler/prepago/nota crédito/daño) | CruceDocumento por tipo, unique_together anti-doble-cruce (verificado con IntegrityError real) |
✅ |
| 9 | §6 Fila 7 (contado+anticipo+caja menor no duplica reconocimiento) y fila 9 (alquiler 2 cortes + devolución parcial) | Tests E2E dedicados con datos reales de #179 (30% anticipo, AmortizacionAnticipo) |
✅ |
| 10 | §7 "Pendiente de vincular" en vez de None; "Sin concepto" con regularización |
Slots _180_cxp_origen_c7.html/_180_gasto_origen_c7.html en CxP/Gastos existentes |
✅ |
| 11 | §7 Plazos con alerta a 2 días hábiles; revisión interna no reinicia el plazo | PlazoRevision + tarea Celery (construida, NO registrada en beat — mismo patrón "configurado e inactivo" que el buzón de 180A) |
✅ (activación de la tarea periódica queda pendiente, sin código nuevo) |
| 12 | §5/§7 Conectores read-only para #181/#182/#97 | /api/v1/facturas/... + signals obligacion_reconocida/costo_imputado/retencion_calculada (verificados: doble confirmación ⇒ 1 sola emisión) |
✅ |
Gaps reales encontrados y documentados (honestos, ninguno inventado)
- ⚠️ §7 "Precargar identificación del tercero y ocultar el campo libre": solo implementable en las pantallas de lista/detalle (donde 180B tiene slots). El formulario de creación/edición de CxP (
accounts_payable_form.html) está locked y no tiene slot — requeriría tocar ese archivo, fuera del alcance seguro de este run. - ⚠️ Detección de solapamiento de alquiler:
CorteOperacionno tiene rango de fechas (solofecha_real), así que el detector solo atrapa coincidencia exacta, no un rango fino. Necesitaría un campo nuevo en #179/#182. - ⚠️
CajaMenor↔Expense: no existe el FK estructural que el propio docstring deCajaMenorenapps/finance/models.pydice que existe ("agregado en Sprint C") — verificado por grep, no está. El cruce de caja menor referenciaCajaMenordirectamente en vez de resolver un movimiento específico. - ℹ️ "Paz y salvo" (§7): no existe como concepto modelado en todo el portafolio hoy. Verificado que nada bloquea un pago por un requisito pendiente (cumple el espíritu "no bloquea"), pero no es una feature diseñada — es ausencia de acoplamiento.
- ℹ️ Estimación de
Expense: la lógica de sustitución (es_estimacion=True→sustituido_por) está implementada y probada, pero ningún flujo actual (#179 ni #180) produce unaExpenseestimada — el camino queda listo pero sin productor real hasta que se decida quién la genera.
Smoke prod (revisión consof-00156-rbs)
- Crawl 200:
/facturas/plazos/,/facturas/documentos/2/revision/(5 paneles reales),/facturas/documentos/2/cruces/. - Write-smoke real: subida de una segunda factura UBL de muestra (
factura_ubl_002.xml) → llamado real aconfirmar_revision()contra la BD de prod → el guard de "documento sin proyecto asociado" se disparó correctamente (reproduce §8 fila 3 del issue en producción real) → documento limpiado consoft_delete(), verificado fuera de la bandeja. FACTURAS_BUZON_ACTIVOsigueFalseen prod (sin variable de entorno).
Este issue no es reproceso (reproceso_rate.py).
Con 180A+180B desplegados, sigo con #181 (proyección de caja, bandeja de pagos) según lo planificado.
✅ Listo para que lo valides — probado por Andrea (Indunnova).
queda bloqueado hasta que david no resuelva dudas con el modulo de compras
Si quedó bien, márcalo como resuelto en tu ticket. Si algo falta, responde aquí mismo.