5.1 KiB
Sesión: Facturación — Personalización CSD, Fecha Emisión, Precio sin IVA, Cuenta Predial
Fecha: 2026-05-22
Commits: 5ba31b7 → 1bde570 → 0c8ae05 → a91a2f4
1. Fix: Personalización logo/color por contribuyente (no tenant)
Problema
En /configuracion/csd, al modificar logo y color para un contribuyente específico, los cambios aplicaban al tenant-level (Horux 360) en lugar de la org Facturapi del contribuyente seleccionado.
Root cause
CustomizationSection usaba endpoints hardcodeados /facturacion/logo, /facturacion/color, /facturacion/customization — todos a nivel tenant. No usaba selectedContribuyenteId.
Solución
- Backend (
contribuyente-facturapi.service.ts): 3 nuevas funciones:getCustomizationContribuyente(pool, contribuyenteId)uploadLogoContribuyente(pool, contribuyenteId, logoBase64)updateColorContribuyente(pool, contribuyenteId, color)
- Backend (
facturacion.controller.ts): 3 controllers per-contribuyente - Backend (
contribuyente.routes.ts): nuevas rutas:GET /contribuyentes/:id/facturapi/customizationPOST /contribuyentes/:id/facturapi/logoPUT /contribuyentes/:id/facturapi/color
- Frontend (
configuracion/csd/page.tsx):CustomizationSectionahora recibecontribuyenteIdcomo prop- Usa endpoints per-contribuyente
- Corregido
useStatemal aplicado →useEffect queryKeyincluyecontribuyenteIdpara evitar caché cruzada
2. Fecha de emisión personalizada (I, E, T)
Requerimiento
En facturas tipo I (Ingreso), E (Egreso) y T (Traslado), permitir modificar la fecha de emisión:
- Máximo 72 horas en el pasado
- No fechas a futuro
- Default: día actual a las 12:00
Cambios
- Frontend (
facturacion/page.tsx):- Nuevo estado
fechaEmisioncon default a fecha actual 12:00 - Input
datetime-localvisible solo para I, E, T (no P) - Validación en
handleSubmit:now - 72h ≤ fecha ≤ now
- Nuevo estado
- Frontend (
lib/api/facturacion.ts):fechaEmision?: stringenInvoiceData - Backend (
facturacion.controller.ts):- Validación idéntica antes de consumir timbre (evita gastar timbres si fecha inválida)
- Backend (
facturapi.service.ts+contribuyente-facturapi.service.ts):- Si viene
fechaEmision, se envía comodate(ISO 8601) en el payload de Facturapi
- Si viene
Nota: Facturapi no documenta explícitamente
datepara invoices I/E/T, pero el SDK aceptaRecord<string, any>. Si Facturapi lo rechaza, el error 400 se propaga al usuario sin consumir timbre.
3. Precio unitario sin IVA (subtotal)
Problema
El campo "Precio Unitario" esperaba que el usuario ingresara el precio con IVA incluido. El frontend dividía internamente price / (1 + tasa_iva) para calcular la base.
Solución
- Frontend (
facturacion/page.tsx):- Label cambiado:
"Precio Unitario (IVA incluido)"→"Precio Unitario (sin IVA)" - Eliminada la división
/(1+trasladoRates)encalcConcepto() - Ahora
priceingresado por el usuario es directamente la base - Subtotal, traslados y retenciones se calculan sobre esa base
- Label cambiado:
- Frontend (
facturacion/page.tsx):taxIncluded: true→taxIncluded: falseen payload - Backend (
facturapi.service.ts+contribuyente-facturapi.service.ts):tax_included: item.taxIncluded ?? true→tax_included: item.taxIncluded ?? false
4. Cuenta Predial para régimen 606 (Arrendamiento)
Contexto
El SAT exige el nodo CuentaPredial en CFDI de arrendamiento (CFF Art. 29-A, RLISR Art. 199). Facturapi expone property_tax_account en el tipo InvoiceItem del SDK.
Cambios
- Frontend (
facturacion/page.tsx):- Nueva sección "Datos del Inmueble" visible solo cuando
emisorRegimen === '606' - Ubicada antes de la card de Conceptos
- Input "No. Cuenta Predial" (alfanumérico, mayúsculas, max 150)
- Se resetea al cambiar de contribuyente
- Nueva sección "Datos del Inmueble" visible solo cuando
- Frontend (
lib/api/facturacion.ts):cuentaPredial?: stringenInvoiceData - Backend (
facturapi.service.ts+contribuyente-facturapi.service.ts):- Al mapear items, agrega
property_tax_accounta nivel de cada item:...(data.cuentaPredial ? { property_tax_account: data.cuentaPredial } : {})
- Al mapear items, agrega
Archivos modificados en esta sesión
| Archivo | Cambio |
|---|---|
apps/web/app/(dashboard)/configuracion/csd/page.tsx |
CustomizationSection per-contribuyente |
apps/web/app/(dashboard)/facturacion/page.tsx |
Fecha emisión, precio sin IVA, cuenta predial |
apps/web/lib/api/facturacion.ts |
fechaEmision, cuentaPredial en InvoiceData |
apps/api/src/controllers/facturacion.controller.ts |
Validación fecha emisión; controllers customization per-contribuyente |
apps/api/src/routes/contribuyente.routes.ts |
Rutas customization per-contribuyente |
apps/api/src/services/contribuyente-facturapi.service.ts |
getCustomizationContribuyente, uploadLogoContribuyente, updateColorContribuyente, property_tax_account |
apps/api/src/services/facturapi.service.ts |
property_tax_account, date en payload |