Commit Graph

32 Commits

Author SHA1 Message Date
Horux Dev
7df27ce66d chore: catálogo obligaciones, cierre automático, fixes SAT y facturación
- Catálogo de obligaciones fiscales expandido a 30 entradas con campo requierePago.
- Soporte de frecuencia cuatrimestral en obligaciones y declaraciones.
- Automatización de cierre de obligaciones fiscales desde Documentos › Declaraciones.
- Nuevas tablas obligacion_evidencias, obligacion_periodos estados y declaracion_obligaciones.
- Nuevo servicio obligacion-evidencias.service.ts y endpoints REST.
- Refactor de declaraciones.service.ts para vincular obligaciones y crear evidencias.
- Notificaciones por email para evidencias de obligaciones.
- Adjuntar PDFs en correo de declaración subida.
- Fix drill-down de CFDIs: carga completa al visualizar.
- Fix sincronización SAT: tipos P/N, UUID case-insensitive, no reutilizar requestId.
- Fix suscripciones pending en /configuracion/planes-despacho.
- Fix sugerencias de Clave Producto SAT: importar catálogo y robustecer autocomplete.
- Quitar toggle manual de completado en Configuración › Obligaciones fiscales › Tareas.
- Scripts de soporte para Demo Ventas y utilerías (change-user-email, resend-welcome, import-clave-prod-serv).
- Documentación de cambios en docs/CAMBIOS-2026-05-04.md.
2026-06-22 04:53:59 +00:00
Horux Dev
b217342a96 feat(notificaciones): configuración de notificaciones por rol
- Nueva tabla tenant notification_role_preferences para guardar (email_type, role, enabled).
- Migración 051 aplicada a todos los tenants.
- Backend expone endpoint /notificaciones con matriz de preferencias por rol.
- Filtrado por rol en documento_subido, weekly_update, subscription_expiring,
  alertas_nuevas y recordatorio_proximo.
- Frontend rediseñado como tabla notificación × rol con toggles inmediatos.
2026-06-17 00:04:37 +00:00
Horux Dev
3f3253d41b fix(pagos): permitir pagar plan actual trial_expired y soportar planes >$10k via Preference
- Expone subscription trial_expired en /despachos/me/plan e incluye planPrice.
- Para Business Control/Enterprise (>$10k) genera pago anual único con MP Preference
  en lugar de preapproval recurrente; el webhook activa 1 año de suscripción.
- Muestra CTA de pago en UI cuando la suscripción está trial/trial_expired.
- Agrega campo mp_preference_id a subscriptions y mejora mensajes de error MP.
2026-06-16 22:37:11 +00:00
Horux Dev
b1eaf41681 fix(sat, payments, admin): multiple production fixes
- sat sweep-stale-jobs: increase initial/custom sync threshold 8h→24h to prevent watchdog killing long historical syncs
- sat-client: fix formatDateForSat same-day rejection by auto-adjusting fechaFin
- sat-sync job: check fiel_contribuyente in addition to fiel_credentials for cron eligibility
- database: extend pool idle cleanup from 5min to 12h to prevent pool closure during long syncs
- webhook controller: auto-extend currentPeriodEnd on recurring MercadoPago payments
- invoicing service: auto-send FacturAPI invoice by email after creation
- admin-clientes: fix no-renovaciones detection to include expired trials and deleted subscriptions
2026-06-10 18:11:47 +00:00
Horux Dev
76d3f00f29 debug(alertas): logging en generador y endpoint /automaticas; wrap cada alerta en try/catch 2026-06-01 19:59:57 +00:00
Horux Dev
6e54efe5e4 feat(usuarios): supervisor puede invitar usuarios cliente
- Backend inviteUsuario: permite owner, cfo y supervisor
- Backend valida que supervisor solo pueda invitar rol cliente
- Backend addClienteAcceso: supervisor solo puede asignar contribuyentes
  que tenga visibles (getEntidadesVisibles)
- Frontend: supervisor ve botón Invitar Usuario y solo puede seleccionar
  rol Cliente en el dropdown
2026-05-29 21:32:12 +00:00
Horux Dev
5dd53cebac chore(usuarios): limpiar debug hardcodeado de supervisorNombre 2026-05-29 19:27:59 +00:00
Horux Dev
0de0df9357 fix(usuarios): mostrar nombre del supervisor en dropdown de forma robusta
- Backend: getSupervisor devuelve supervisorNombre desde Prisma
- Frontend: usa SelectTrigger con renderizado manual del label seleccionado
  en lugar de depender de SelectValue, que no siempre encontraba el texto
  del SelectItem cuando el supervisor no estaba en la lista de carteras
2026-05-29 19:03:36 +00:00
Horux Dev
8c9a7b73dc fix(usuarios): agregar import faltante de prisma en getSupervisor 2026-05-29 17:43:13 +00:00
Horux Dev
910c50d870 fix(usuarios): mostrar nombre del supervisor al editar auxiliar
- Backend getSupervisor ahora devuelve supervisorNombre buscando en Prisma
- Frontend usa supervisorNombre para mostrar en Select cuando el supervisor
  no está en la lista de carteras/supervisores
2026-05-29 17:24:18 +00:00
Horux Dev
0439a84e6d feat(contribuyentes): mostrar nombre del supervisor en card 2026-05-29 16:57:04 +00:00
Horux Dev
9b535354fb feat(papeleria): aprobación independiente por cliente
- Agrega migración 050 con columnas de aprobación de cliente
  (requiere_aprobacion_cliente, estado_cliente, aprobado_por_cliente, etc.)
- Backend: endpoints /aprobar-cliente y /rechazar-cliente con validación de permisos
- Backend: list/download permiten acceso a clientes filtrando por entidades visibles
- Backend: notificación por email a clientes cuando se les solicita aprobación
- Frontend: checkbox independiente para solicitar aprobación del cliente
- Frontend: badge de estado combinado (owner + cliente)
- Frontend: botones de aprobar/rechazar para clientes en su propio flujo
2026-05-29 00:36:33 +00:00
Horux Dev
e01422e443 fix(facturacion): filtrar searchConceptos y searchRfcs por contribuyenteId
- searchConceptos: agrega AND c.contribuyente_id =  cuando se recibe contribuyenteId
- searchRfcs: restringe el catálogo global de rfcs a aquellos que aparecen en CFDIs del contribuyente (como emisor o receptor)
- Usa parametrización dinámica (3800099{params.length}) para evitar errores de índice
2026-05-28 21:44:32 +00:00
Horux Dev
2208cee87f fix(impuestos): desactivar JIT en queries con subplans correlacionados
- Agrega helper withJitOff en impuestos.service.ts
- Ejecuta getResumenIva, getIvaMensual y readResumenIvaFromCache con SET LOCAL jit = off
- Evita compilación JIT de ~17s en queries con costo estimado alto

feat(contribuyentes): auto-asignar a cartera del supervisor

- Al crear contribuyente con supervisorUserId, se agrega automáticamente
  a todas las carteras top-level del supervisor

feat(permisos): restricciones de UI por rol en contribuyentes

- Oculta botón Add-ons para roles distintos de owner/cfo
- Oculta botón Eliminar contribuyente para no-owner
- Oculta botón Agregar RFC para auxiliar/visor/cliente/contador

feat(cfdi): ver CFDI desde conceptos y forma de pago en Excel

- Agrega botón Ver CFDI en cada fila de la tabla de Conceptos
- Agrega columna Forma de Pago en export Excel de CFDIs
- Agrega columna Forma de Pago en export individual de CFDI

chore(migraciones): índices GIN para relaciones de activos

- 048: índices btree parciales para activos
- 049: índices GIN para cfdis_relacionados y uuid_relacionado
2026-05-28 02:38:30 +00:00
Horux Dev
929aeec641 feat(declaraciones): supervisor puede crear declaraciones y extras
- Backend: agrega 'supervisor' a ROLES_UPLOAD en documentos.controller.ts
- Frontend: agrega 'supervisor' a ROLES_UPLOAD y ROLES_UPLOAD_EXTRA en
  documentos/page.tsx para habilitar botones de subir declaración,
  comprobante de pago, eliminar y subir PDFs extra
2026-05-25 21:49:01 +00:00
Horux Dev
cbefaa2bf7 refactor(declaraciones): renombrar SUELDOS→ISN, agregar ISH
- Cambia la opción 'SUELDOS' por 'ISN' (Impuesto Sobre Nómina)
- Agrega nueva opción 'ISH' (Impuesto Sobre Hospedaje)
- ISH no cierra alertas ni obligaciones (aún no hay flujo definido)
- ISN mantiene keywords de sueldos/salarios/nómina + agrega 'isn'
- Migración 047: actualiza declaraciones históricas SUELDOS→ISN en BD
2026-05-25 02:35:16 +00:00
Horux Dev
e35eae2a72 refactor(cfdi): descarga masiva de XMLs por filtros en lugar de checkboxes
- Backend: POST /cfdi/download-xmls acepta CfdiFilters, usa getXmlsByFilters con LIMIT 1000
- Frontend: eliminados checkboxes y estado selectedIds; botón Descargar XMLs usa filtros activos
- Si >1000 resultados, muestra confirm() de advertencia pero permite proceder
- Agregada documentación técnica y changelog
2026-05-24 21:40:08 +00:00
Horux Dev
5c940847af feat(cfdi): descarga masiva de XMLs como ZIP, limite 1,000 2026-05-24 21:19:56 +00:00
Horux Dev
f43cb165c6 feat: asignaciones obligaciones/tareas + fixes backend
- Migracion 046: tablas obligacion_asignaciones y tarea_asignaciones
- Servicio y controller de asignaciones (CRUD + listados)
- Fix: enviar correo welcome al invitar usuario nuevo
- Fix: quitar JOIN users de queries tenant (usar Prisma en BD central)
- Fix: req.params.obligacionId correcto en asignaciones controller
- Fix: orden rutas estaticas antes de dinamicas en cartera.routes
- Fix: owner/cfo ven todas las asignaciones en getAsignacionesPorSupervisor
- Fix: validar que entidad pertenezca a cartera padre en subcartera
- Nuevo endpoint GET /carteras/asignaciones/sin-asignar
- Nuevo endpoint GET /tareas/mis-tareas
2026-05-23 23:40:12 +00:00
Horux Dev
1bde570035 feat(facturacion): fecha de emisión personalizable para I, E, T
- Frontend: input datetime-local visible solo para tipos I, E, T
  (no P). Default al día actual a las 12:00. Se resetea al cambiar tipo.
- Frontend: validación en handleSubmit: fecha ≤ ahora y ≥ ahora-72h
- Backend controller: validación idéntica antes de consumir timbre
- Backend servicios: pasa campo 'date' al payload de Facturapi
  cuando viene 'fechaEmision' en el body
- Build y deploy exitosos
2026-05-22 20:11:03 +00:00
Horux Dev
5ba31b7291 fix: personalización logo/color por contribuyente en vez de tenant
- Agrega getCustomizationContribuyente, uploadLogoContribuyente,
  updateColorContribuyente en contribuyente-facturapi.service.ts
- Agrega controllers per-contribuyente en facturacion.controller.ts
- Agrega rutas GET/POST/PUT /contribuyentes/:id/facturapi/customization|logo|color
- Modifica CustomizationSection para recibir contribuyenteId, usar endpoints
  per-contribuyente, y corrige useState mal aplicado a useEffect
- Backend y frontend buildeados y deployados
2026-05-22 18:20:09 +00:00
Horux Dev
46846200da feat(sat): factura global + fecha_efectiva, fallback tenant-contribuyente, fix anio_global typo
Factura Global & fecha_efectiva:
- Migracion 045_factura_global.sql: periodicidad, meses_global, año_global, fecha_efectiva
- sat-parser.service.ts: extrae InformacionGlobal del XML
- sat.service.ts: calcFechaEfectiva con soporte bimestral (periodicidad 05)
- metricas-compute, dashboard, impuestos, cfdi, export, conciliacion, alertas:
  reemplaza fecha_emision-1h por COALESCE(fecha_efectiva, fecha_emision-1h)
- Script recalc-metricas.ts para recalculo manual

Fallback datos fiscales tenant → contribuyente:
- contribuyente.service.ts: fetchTenantFiscalData + mergeContribuyenteWithTenant
  rellena regimenFiscal, codigoPostal y domicilio cuando el contribuyente
  tiene el mismo RFC que el tenant y sus campos estan vacios
- contribuyente.controller.ts y contribuyente-config.controller.ts:
  pasan req.user!.tenantId al servicio

Fix critico SAT sync:
- sat.service.ts: anio_global → año_global en INSERT/UPDATE de CFDIs
  (la migracion creo 'año_global' con tilde; el codigo usaba 'anio_global',
   causando fallo en 100% de inserciones de CFDI)
- determineChunkMonths: salta sondeo si existe job previo con requestIds
- MAX_POLL_ATTEMPTS: 45 → 500 (~8h) para syncs iniciales grandes

Docs:
- docs/sessions/2026-05-22-factura-global-contribuyente-fallback.md
2026-05-22 15:52:10 +00:00
Horux Dev
b5e307e142 fix(facturacion): saldo pendiente PPD + seguridad cancelación multi-contribuyente
- Inicializar saldo_pendiente_mxn al emitir facturas I/PPD vía Facturapi
  (antes quedaba NULL y no aparecían en complemento de pago)
- Validar ownership en cancelación: backend rechaza 403 si el caller
  intenta cancelar una factura de otro contribuyente
- Frontend: ocultar botón cancelar si no se es el emisor de la factura
- Frontend: enviar contribuyenteId en la petición de cancelación
2026-05-20 05:18:34 +00:00
Horux Dev
98e982c260 fix(documentos): capturar timeout SAT en consulta CSF manual
El controller ahora devuelve 504 (gateway timeout) con mensaje claro
en vez de 500 genérico cuando el scraper del SAT excede el tiempo.

Anteriormente solo capturaba errores con 'FIEL' en el mensaje;
los timeouts de page.waitForURL se escapaban como 500.
2026-05-19 21:45:20 +00:00
Horux Dev
0b704e0e27 feat(admin/usuarios): agregar usuario globalmente desde admin
El admin global ahora puede crear usuarios directamente desde
/admin/usuarios sin depender de que un owner los invite.

Backend:
- Nuevo endpoint POST /usuarios/global (controller + service)
- Valida límite de usuarios del plan del tenant destino
- Si el email ya existe, agrega membership al tenant destino
- Si no existe, crea user con temp password + membership
- Schema Zod: email, nombre, role, tenantId, supervisorUserId?

Frontend:
- Botón 'Agregar Usuario' en /admin/usuarios
- Formulario con: nombre, email, rol, empresa
- Hook useCreateUsuarioGlobal con invalidación de queries
2026-05-17 14:32:45 +00:00
Horux Dev
e8aaf9ff15 fix(clientes): crear tenant como despacho desde admin global
Antes, createTenant() solo seteaba nombre, rfc, plan y databaseName.
Ahora registra tenants completos como despachos:

- dbMode: 'MANAGED'
- verticalProfile: CONTABLE | JURIDICO | ARQUITECTURA
- trialEndsAt: +30 días para plan trial
- codigoPostal: opcional (se llena automáticamente de la CSF al subir FIEL)

Frontend:
- Selector de Tipo de Despacho en /clientes
- C.P. omitido del formulario (viene de CSF -> sincronizarDatosFiscales)
- Tipos Tenant y CreateTenantData actualizados

Backend:
- getAllTenants y getTenantById retornan verticalProfile y codigoPostal

Refs: docs/sessions/2026-05-04-fix-clientes-crea-despacho.md
2026-05-17 06:11:29 +00:00
Horux Dev
44d7c796c9 fix: facturapi onboarding, CSF scraper, SAT sync initial, doc notifications
- Auto-update fiscal data on org creation via updateOrgLegalOnCreate
- Add Carta Manifiesto embedded iframe in CSD config page
- Fix CSF scraper: 60s timeout + manual RFC fallback when SAT doesn't auto-populate
- Fix contribuyenteId propagation in constancia frontend hooks/API
- Fix needsInitialSync to check per-contribuyente, not just per-tenant
- Fix documento notifications for global_admin using viewingTenantId
- Extract CSF manually for Carlos Husberto Torres Romero
- Trigger initial SAT sync for Carlos Husberto Torres Romero
- Update org legal data in Facturapi for Carlos Husberto (tax_system 612 + address)

Files changed:
- apps/api/src/controllers/documentos.controller.ts
- apps/api/src/jobs/sat-sync.job.ts
- apps/api/src/services/constancia.service.ts
- apps/api/src/services/contribuyente-facturapi.service.ts
- apps/api/src/services/sat/sat-csf-login.ts
- apps/web/app/(dashboard)/configuracion/csd/page.tsx
- apps/web/lib/api/constancias.ts
- apps/web/lib/hooks/use-constancias.ts
- docs/sessions/2026-05-17-facturapi-csf-sync-notifications.md
2026-05-17 04:28:32 +00:00
Horux Dev
7b1f60cbf2 feat(reportes): rediseño Estado de Resultados vertical con drill-down, análisis horizontal/vertical y export Excel
- Nuevo endpoint GET /reportes/estado-resultados-detallado con cálculo contable:
  * Ventas, Devoluciones, Ventas netas, Costo de ventas, Utilidad bruta,
    Gastos operativos, Utilidad de la operación
  * Fórmula: subtotal_mxn - descuento_mxn (sin impuestos), nómina usa total_mxn
  * Excluye anticipos (uso_cfdi=P01 o clave_prod_serv=84111506)
  * Filtro por régimen fiscal opcional
  * Año anterior calculado automáticamente

- Nuevo endpoint GET /reportes/estado-resultados/drill-down:
  * Nivel 1: resumen agrupado por RFC
  * Nivel 2: CFDIs individuales filtrados por categoría
  * Categorías: ventas, devoluciones, costo-ventas, gastos-operativos

- Nuevo endpoint GET /reportes/estado-resultados/export:
  * Genera Excel con formato condicional (verde/rojo, negritas)

- Frontend:
  * Tabla vertical con % vertical, año anterior y variación %
  * Filas clickeables para drill-down modal de 2 niveles
  * Top 10 Clientes/Proveedores mantenidos debajo
  * Selector de régimen conectado al reporte

- Fix: NaN en total de drill-down nivel 2 por numeric como string en pg
  * Agregado ::float en queries SQL de CFDIs individuales
2026-05-15 22:53:10 +00:00
Horux Dev
69bf7417a8 feat(invitations): reenviar invitaciones pendientes desde admin
Backend:
- client-invitations.service.ts: funcion resendInvitation() que
  genera nuevo token, actualiza expiresAt y reenvia el email.
- Controller + routes: POST /invitations/client/:id/resend

Frontend:
- API client + hook useResendInvitation con invalidacion de cache.
- Pagina /admin/invitar-cliente: boton 'Reenviar' por cada
  invitacion pendiente en la tabla.

Refs: docs/CAMBIOS-2026-05-09.md
2026-05-13 23:19:07 +00:00
Horux Dev
745bc8385b feat(invitations): flujo de invitacion de clientes por email
Backend:
- Nuevo modelo Prisma ClientInvitation con token unico, expiracion
  y estados (pending/accepted/expired).
- Migracion: 20260511213955_add_client_invitations
- Service client-invitations.service.ts: crear invitacion,
  validar token, registrar desde invitacion (reutiliza logica
  de creacion de tenant + usuario de despacho.service).
- Controller + routes: POST /invitations/client (admin),
  GET /invitations/client/validate/:token (publico),
  POST /invitations/client/register/:token (publico),
  GET /invitations/client (admin).
- Email template client-invitation.ts con link a
  /invitacion/registro/{token}.
- Agregado sendClientInvitation a email.service.

Frontend:
- Pagina /invitacion/registro/[token] para que el invitado
  complete registro (nombre, password, despacho, RFC, perfil).
- Pagina /admin/invitar-cliente para que admin global envie
  invitaciones y vea el historial.
- Hooks useCreateInvitation, useValidateInvitationToken,
  useRegisterFromInvitation, useClientInvitations.
- API client lib/api/client-invitations.ts.

Infra:
- PM2 ecosystem.config.js: usa node --import tsx con
  kill_timeout aumentado a 15s para evitar EADDRINUSE.
- React Query retry=2 con delay exponencial para resiliencia.

Refs: docs/CAMBIOS-2026-05-09.md
2026-05-11 22:03:03 +00:00
Horux Dev
9f11a0ba39 feat: facturación primer pago, fixes SAT/MP, autocompletado RFCs/conceptos
Backend:
- Notificación email al admin cuando llega primer pago aprobado (sin factura auto)
- Endpoints GET /pagos-sin-factura y POST /emitir-factura-pago para admin global
- Fix vinculación org Facturapi Horux 360 (69f23a5a242e0af47a41fa0d)
- Fix webhook MP: validación defensiva de x-signature header
- Fix autocompleto RFCs: eliminado filtro por contribuyenteId
- Fix autocompleto conceptos: eliminado filtro por contribuyenteId
- SAT fixes: anti-bot CSF scraper, request reuse, date range fix, stale job thresholds
- SAT sync request reuse across jobs para evitar agotar cuota diaria
- Typo fix MP_ACCESS_TOKEN en .env
- Trial invitations system backend

Frontend:
- Nueva página /admin/facturas-pendientes con tabla y emisión manual
- Métrica 'Facturas pendientes' en /clientes (clickable)
- Navegación onboarding FIEL/CSD corregida
- Sidebar themes sincronizados
- Fix SAT portal migration scraper (NetIQ)
- Trial invitation acceptance pages
2026-05-09 21:56:42 +00:00
b00b677c54 Initial commit - Horux Despachos NL 2026-05-03 16:47:53 -06:00