File size: 2,192 Bytes
c55ab5e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | """RESICO — Régimen Simplificado de Confianza (Mexico), personas físicas.
The simplest and (for most freelancers) cheapest regime. ISR is a flat rate on
*total monthly income* — no deductions enter the ISR calculation. The rate is
chosen by an income bracket (Art. 113-E LISR), and the whole income is taxed at
that single rate (not marginally).
Eligibility caps annual income at $3,500,000 MXN; the engine flags when a user is
near or over the cap.
"""
from __future__ import annotations
from .money import D, money
from .result import CalcResult
from .tax_tables import (
RESICO_ANNUAL_INCOME_CAP_MX,
RESICO_MONTHLY_MX,
TaxTable,
)
def resico_isr_monthly(
monthly_income, table: TaxTable = RESICO_MONTHLY_MX
) -> CalcResult:
"""Flat-rate ISR on total monthly income under RESICO."""
income = D(monthly_income)
if income <= 0:
return CalcResult(
amount=money(0),
label="ISR RESICO (mensual)",
breakdown=[("Ingresos del mes", money(income))],
source=table.source,
effective_year=table.effective_year,
notes=["No income → no ISR this month."],
)
bracket = next(
b for b in table.brackets if b.upper is None or income <= b.upper
)
tax = income * bracket.rate
notes = []
# Projected annual income vs the eligibility cap (rough 12× signal).
projected_annual = income * 12
if projected_annual > RESICO_ANNUAL_INCOME_CAP_MX:
notes.append(
"At this monthly rate, projected annual income exceeds the "
f"${RESICO_ANNUAL_INCOME_CAP_MX:,.0f} RESICO cap — eligibility at risk."
)
return CalcResult(
amount=money(tax),
label="ISR RESICO (mensual)",
breakdown=[
("Ingresos del mes (amparados por CFDI)", money(income)),
("Tasa aplicable", bracket.rate),
],
source=table.source,
effective_year=table.effective_year,
notes=notes,
)
def resico_eligible(annual_income) -> bool:
"""True if annual income is within the RESICO eligibility cap."""
return D(annual_income) <= RESICO_ANNUAL_INCOME_CAP_MX
|