7.3 KiB
Modulo de Conciliacion — Spec
Fecha: 2026-04-12 Estado: Aprobado
Objetivo
Permitir al usuario conciliar CFDIs emitidos y recibidos mes a mes, registrando fecha de pago y banco. Solo se permite conciliar del ano actual en adelante.
Modelo de datos (BD tenant — raw SQL)
Tabla bancos (nueva)
CREATE TABLE IF NOT EXISTS bancos (
id SERIAL PRIMARY KEY,
banco VARCHAR(100) NOT NULL,
terminacion_cuenta VARCHAR(4) NOT NULL,
creado_en TIMESTAMP DEFAULT NOW()
);
Tabla conciliaciones (nueva)
CREATE TABLE IF NOT EXISTS conciliaciones (
id SERIAL PRIMARY KEY,
anio VARCHAR(4) NOT NULL,
mes VARCHAR(2) NOT NULL,
id_cfdi INTEGER NOT NULL UNIQUE REFERENCES cfdis(id),
fecha_de_pago DATE NOT NULL,
id_banco INTEGER NOT NULL REFERENCES bancos(id),
creado_en TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_conciliaciones_anio_mes ON conciliaciones(anio, mes);
CREATE INDEX IF NOT EXISTS idx_conciliaciones_id_cfdi ON conciliaciones(id_cfdi);
Columnas en cfdis
conciliado VARCHAR(50)— ya existe. Se actualiza a'true'al conciliar,NULLal desconciliar.id_conciliacion INTEGER REFERENCES conciliaciones(id)— nueva. FK a la conciliacion asociada. NULL si no conciliado.
Al conciliar: se crean registros en conciliaciones, se actualiza cfdis.conciliado = 'true' y cfdis.id_conciliacion = conciliaciones.id.
Al desconciliar: se pone cfdis.conciliado = NULL, cfdis.id_conciliacion = NULL, y se elimina el registro de conciliaciones.
DDL para tenants nuevos
Agregar bancos, conciliaciones en database.ts -> createTables() despues de alertas.
Agregar id_conciliacion INTEGER REFERENCES conciliaciones(id) en la tabla cfdis.
Migracion para tenants existentes
CREATE TABLE IF NOT EXISTS para bancos y conciliaciones, luego ALTER TABLE cfdis ADD COLUMN IF NOT EXISTS id_conciliacion INTEGER REFERENCES conciliaciones(id).
Reglas de negocio
- Solo se concilian CFDIs del ano de alta del tenant en adelante (se obtiene del
createdAtdel tenant en la BD central). Esto permite que una empresa registrada en 2025 pueda conciliar 2025, 2026, etc. anioymesdeconciliacionesse derivan automaticamente defecha_de_pago.- Un CFDI solo puede tener una conciliacion (
id_cfdies UNIQUE en conciliaciones,id_conciliacionen cfdis). - Solo CFDIs vigentes (
status NOT IN ('Cancelado', '0')). - Al conciliar: INSERT en
conciliaciones+ UPDATEcfdisSETconciliado = 'true',id_conciliacion = <id>. - Al desconciliar: UPDATE
cfdisSETconciliado = NULL,id_conciliacion = NULL+ DELETE deconciliaciones. - No se puede eliminar un banco que tenga conciliaciones asociadas.
API endpoints
Conciliacion
| Metodo | Ruta | Descripcion | Auth |
|---|---|---|---|
| GET | /conciliacion |
Lista CFDIs con estado de conciliacion | JWT + Tenant |
| POST | /conciliacion |
Conciliar CFDIs (batch) | JWT + Tenant + admin/contador |
| DELETE | /conciliacion/:id |
Desconciliar un CFDI | JWT + Tenant + admin/contador |
GET /conciliacion
Query params:
tipo:EMITIDO|RECIBIDO(requerido)fechaInicio,fechaFin: rango de fecha de emisionregimen: clave de regimen fiscal (opcional)estado:conciliado|pendiente(opcional, default: todos)
Response: Array de CFDIs con campo adicional conciliacion (null si pendiente, objeto si conciliado):
{
"id": 1,
"uuid": "...",
"rfcEmisor": "...",
"nombreEmisor": "...",
"total": 1000,
"totalMxn": 1000,
"fechaEmision": "...",
"conciliado": "true",
"idConciliacion": 5,
"conciliacion": {
"id": 5,
"fechaDePago": "2026-04-10",
"banco": "BBVA",
"terminacionCuenta": "1234"
}
}
POST /conciliacion
Body:
{
"cfdiIds": [1, 2, 3],
"fechaDePago": "2026-04-10",
"idBanco": 1
}
Logica:
- Validar que todos los CFDIs existen, estan vigentes, y no estan ya conciliados.
- Validar que
fechaDePagoes del ano actual en adelante. - Derivar
anioymesdefechaDePago. - Para cada CFDI: INSERT en
conciliaciones, UPDATEcfdisSETconciliado = 'true',id_conciliacion = <new id>.
DELETE /conciliacion/:id
- Buscar la conciliacion por id.
- UPDATE
cfdisSETconciliado = NULL,id_conciliacion = NULLWHEREid_conciliacion = :id. - DELETE FROM
conciliacionesWHEREid = :id.
Bancos
| Metodo | Ruta | Descripcion | Auth |
|---|---|---|---|
| GET | /bancos |
Listar bancos del tenant | JWT + Tenant |
| POST | /bancos |
Crear banco | JWT + Tenant + admin |
| PUT | /bancos/:id |
Editar banco | JWT + Tenant + admin |
| DELETE | /bancos/:id |
Eliminar banco (si no tiene conciliaciones) | JWT + Tenant + admin |
Frontend
Pagina /conciliacion
Acceso: Feature-gated por conciliacion (Business, Enterprise). Roles: admin y contador (lectura+escritura), visor (solo lectura).
Layout:
[Header: "Conciliacion"]
[Filtros: PeriodSelector | RegimenSelector]
[Tabs: Emitidas | Recibidas]
[Seccion: "Por conciliar" — tabla con checkboxes]
[Barra de accion: Banco (dropdown) + Fecha de pago (date) + Boton "Conciliar"]
[Seccion: "Conciliadas" — tabla con info de conciliacion + boton desconciliar]
Tabla "Por conciliar":
- Checkbox (no visible para visor)
- UUID (corto), Fecha emision, RFC Emisor/Receptor, Nombre, Total MXN, Metodo Pago
- Boton "Ver factura" (CfdiViewerModal)
Tabla "Conciliadas":
- UUID, Fecha emision, RFC, Nombre, Total MXN
- Fecha de pago, Banco (nombre + terminacion)
- Boton "Desconciliar" (no visible para visor)
- Boton "Ver factura"
Flujo de conciliacion:
- Usuario selecciona checkboxes en "Por conciliar"
- Aparece barra de accion sticky en la parte inferior
- Selecciona banco (dropdown de bancos del tenant) y fecha de pago
- Click "Conciliar N facturas"
- Confirmacion -> POST
/conciliacion-> refresh datos
Seccion de bancos en /configuracion
Solo visible para admin. Card con:
- Lista de bancos existentes: Nombre + terminacion + boton eliminar
- Formulario inline: Nombre banco + Terminacion (max 4 digitos) + boton agregar
Navegacion
Agregar "Conciliacion" al sidebar con feature gate conciliacion, visible para admin, contador, visor. Ubicacion: despues de Reportes.
Archivos a crear/modificar
Backend (crear)
apps/api/src/services/conciliacion.service.tsapps/api/src/controllers/conciliacion.controller.tsapps/api/src/routes/conciliacion.routes.tsapps/api/src/services/bancos.service.tsapps/api/src/controllers/bancos.controller.tsapps/api/src/routes/bancos.routes.ts
Backend (modificar)
apps/api/src/app.ts— registrar rutas de conciliacion y bancosapps/api/src/config/database.ts— agregar tablasbancosyconciliacionesencreateTables(), agregarid_conciliacionencfdis
Frontend (crear)
apps/web/app/(dashboard)/conciliacion/page.tsxapps/web/lib/api/conciliacion.tsapps/web/lib/api/bancos.tsapps/web/lib/hooks/use-conciliacion.tsapps/web/lib/hooks/use-bancos.ts
Frontend (modificar)
apps/web/components/layouts/sidebar.tsx(y variantes) — agregar nav itemapps/web/app/(dashboard)/configuracion/page.tsx— agregar seccion de bancos
Migracion
- Aplicar DDL a tenant existente (
horux_ede123456ab1): crear tablas + agregar columna