Cómo estructuro y pruebo los cálculos de URSSAF e impuesto sobre la renta de MonSuiviCA
Tasas versionadas, hogar fiscal, 199 tests y límites conocidos: cómo organiza MonSuiviCA sus cálculos de URSSAF y de impuesto sobre la renta.
TL;DR
MonSuiviCA reúne sus cálculos de cotizaciones URSSAF y de impuesto sobre la renta en un solo módulo TypeScript. La URSSAF es el organismo francés que recauda las cotizaciones sociales. Su paquete tiene 199 tests, 99 de ellos en el archivo dedicado a este módulo. El 1 de noviembre de 2026, pasan todos.
Todas las cifras de este artículo son las del código a 1 de noviembre de 2026. Describen un software y no constituyen asesoramiento fiscal.
El origen del producto está en el artículo de lanzamiento de MonSuiviCA.
Un solo módulo guarda los números
El archivo packages/shared/src/calculations.ts sirve tanto a la aplicación como a la web comercial. Tres constantes lo estructuran:
TAUX_VERSION: la versión2026-02, la fecha de efecto yretrievedAt, fecha de la última verificación de las tasas (2026-08-06).TAUX: tasas de la Francia metropolitana, reducciones a tanto alzado, umbrales de IVA y topes del régimen, es decir 83 600 € en servicios y 203 100 € en venta.TAUX_ZONES: las tasas por zona fiscal y por sector.
Este es el contenido de TAUX_ZONES, sin el alquiler turístico. SSI es la seguridad social de los autónomos, CIPAV la caja de pensiones de algunas profesiones liberales y DROM los departamentos y regiones franceses de ultramar:
| Zona | Servicios | Venta | Liberal SSI | Liberal CIPAV |
|---|---|---|---|---|
| Francia metropolitana | 21,2 % | 12,3 % | 25,6 % | 23,2 % |
| DROM, menos de 2 años | 3,6 % | 2,1 % | 4,3 % | 7,8 % |
| DROM, de 2 a 3 años | 10,6 % | 6,2 % | 12,8 % | 11,6 % |
| DROM, 4 años o más | 14,2 % | 8,2 % | 17,1 % | 15,5 % |
| Mayotte | 9,1 % | 5,3 % | 12 % | 16,6 % |
Esta centralización responde a un fallo real. Una página de la web comercial mostraba un tope de 77 700 € en su texto y 83 600 € en el resultado de la calculadora situada debajo.
Desde el 31 de agosto de 2026, las páginas leen sus importes en bareme.ts, una capa de presentación sobre el módulo compartido. Un test falla, e indica el archivo y la línea, si un valor antiguo vuelve a su código.
Resolver la tasa correcta
La función getEffectiveUrssafRates elige las tasas de una cuenta en este orden:
- Las tasas personalizadas introducidas en los ajustes.
- Las tasas derivadas de la zona, de la caja y de la ACRE, una ayuda francesa a la creación o adquisición de empresas.
null, que hace que los cálculos vuelvan a las tasas de la Francia metropolitana.
La ACRE se reduce a un multiplicador con fecha. Expresa la parte de la tasa que se conserva, y el código lo elige según la fecha de inicio introducida:
export function getAcreMultiplier(refDate: Date = new Date()): number {
return refDate < new Date('2026-07-01') ? 0.50 : 0.75
}
Con una fecha de inicio del 1 de septiembre de 2026, la tasa de servicios en la Francia metropolitana pasa por tanto del 21,2 % al 15,9 %.
Contar solo lo cobrado
Toda la base de cálculo pasa por isEncaisse. Una factura con el estado attente (pendiente) sale del cálculo de cotizaciones y de impuesto.
La cotización mostrada equivale a la tasa multiplicada por lo cobrado en el periodo declarado, un mes o un trimestre natural, sin alisado anual. En el sector mixto, getRevenueRate aplica la tasa ingreso por ingreso: venta por un lado, servicios por otro.
Calcular el impuesto a nivel del hogar
La renta imponible parte de la facturación, menos una reducción a tanto alzado del 50 % en servicios, 71 % en venta y 34 % en profesiones liberales. Después, la escala se aplica tramo a tramo:
export function calculateIR(taxableIncome: number): number {
let total = 0
for (const b of IR_BRACKETS) {
if (taxableIncome <= b.from) break
total += (Math.min(taxableIncome, b.to) - b.from) * b.rate
}
return total
}
IR_BRACKETS contiene cinco tramos, al 0, 11, 30, 41 y 45 %. Este cálculo aislado se equivoca con un hogar. Veinte mil euros de renta imponible no pesan igual según las partes fiscales y el salario del cónyuge.
Por eso escribí calculateIRFoyer. Devuelve un sobrecoste: el impuesto del hogar con la actividad, menos el impuesto del hogar sin ella. Para 20 000 € de renta imponible y 2 partes, el código da:
- Sin otros ingresos: 0 €.
- Con 60 000 € de otros ingresos: 6 000 €, es decir 10 207,98 € menos 4 207,98 €.
Una tasa personalizada conserva la prioridad, luego viene el hogar y luego la escala sola. El tope del cociente familiar, la deducción para rentas bajas, las reducciones y los créditos fiscales quedan fuera del modelo. El comentario de la función lo dice y califica el resultado de estimación indicativa.
Tres niveles de verificación
La CI ejecuta los tests del paquete compartido en un paso propio. Comprueban tres cosas:
- Valores: cada zona, y la ACRE a ambos lados del 1 de julio de 2026.
- Propiedades: el sobrecoste es igual a la diferencia entre los dos impuestos, nunca es negativo y el hogar cuenta al menos 1 parte.
- Un cerrojo:
bareme.test.tsfija los topes, umbrales de IVA y tasas comprobados en service-public.gouv.fr el 31 de agosto de 2026. Cambiar la escala obliga a modificar también el test.
Este test de valor cubre el caso de 20 000 € con la escala sola:
it('taxes 11% between 11600 and 29579', () => {
// (20000 - 11600) * 0.11
expect(calculateIR(20000)).toBeCloseTo(924, 2)
})
Un script completa el conjunto durante el build de la aplicación web. check-taux-urssaf.js avisa cuando retrievedAt supera los 6 meses, o en cuanto ha pasado un 1 de enero o un 1 de julio desde esa fecha. No detiene el build.
Lo que estos tests no demuestran
Ninguna auditoría contable está demostrada a 1 de noviembre de 2026. La lista de validación por un experto contable de docs/business/formules-comptables.md no tiene ninguna casilla marcada, y el documento sigue con estado de borrador.
La calculadora pública muestra además su límite bajo el resultado, en francés: « Estimation indicative. Impôt calculé sur 1 part fiscale, sans déductions. » Es decir: una estimación indicativa, con el impuesto calculado sobre 1 parte fiscal y sin deducciones.
¿Un problema parecido a este? Cuéntamelo, te respondo en 48 h.