PocketAccountant / src /engine /tax_tables.py
eldinosaur's picture
English-default UI + bilingual agent + USA tax support (Schedule C/SE/federal) and expanded US+EN regulation corpus
56ed47e verified
Raw
History Blame Contribute Delete
5.21 kB
"""Versioned, dated tax tables.
CRITICAL DESIGN RULE: every rate and bracket lives here, tagged with the year and
the official source it came from. The math modules never hard-code a number. When
the SAT or IRS publishes new tables, you edit *this file only* — and the
``effective_year`` / ``source`` metadata travels with the result so the UI can tell
the user exactly which year's rules were applied.
⚠️ The values below are transcribed for development and MUST be verified against the
official Diario Oficial de la Federación (Mexico) / IRS Rev. Proc. publications
before any real filing. They are illustrative defaults, not tax advice.
"""
from __future__ import annotations
from dataclasses import dataclass
from decimal import Decimal
from typing import Optional, Sequence
from .money import D
@dataclass(frozen=True)
class Bracket:
"""A progressive-tax bracket.
``upper`` is ``None`` for the open-ended top bracket. ``fixed_fee`` is the
"cuota fija" / cumulative tax at the start of the bracket; ``rate`` applies to
the income *in excess of* ``lower``.
"""
lower: Decimal
upper: Optional[Decimal]
fixed_fee: Decimal
rate: Decimal # fraction, e.g. Decimal("0.0192")
def contains(self, base: Decimal) -> bool:
if base < self.lower:
return False
return self.upper is None or base <= self.upper
@dataclass(frozen=True)
class FlatBracket:
"""A RESICO-style bracket: a single rate applied to the *whole* amount."""
upper: Optional[Decimal] # inclusive ceiling; None for the top bracket
rate: Decimal
@dataclass(frozen=True)
class TaxTable:
name: str
effective_year: int
source: str
brackets: Sequence[object]
def _b(lower, upper, fixed_fee, rate) -> Bracket:
return Bracket(
D(lower),
None if upper is None else D(upper),
D(fixed_fee),
D(rate),
)
def _f(upper, rate) -> FlatBracket:
return FlatBracket(None if upper is None else D(upper), D(rate))
# --- Mexico · ISR · Persona Física · monthly provisional tarifa -------------
# Artículo 96 LISR (monthly). Values shown are the 2024 monthly tariff.
# SOURCE: DOF — verify the current year before filing.
ISR_MONTHLY_MX_2024 = TaxTable(
name="ISR mensual personas físicas (Art. 96 LISR)",
effective_year=2024,
source="DOF — tarifa mensual ISR 2024 (verify)",
brackets=[
_b("0.01", "746.04", "0.00", "0.0192"),
_b("746.05", "6332.05", "14.32", "0.0640"),
_b("6332.06", "11128.01", "371.83", "0.1088"),
_b("11128.02", "12935.82", "893.63", "0.1600"),
_b("12935.83", "15487.71", "1182.88", "0.1792"),
_b("15487.72", "31236.49", "1640.18", "0.2136"),
_b("31236.50", "49233.00", "5004.12", "0.2352"),
_b("49233.01", "93993.90", "9236.89", "0.3000"),
_b("93993.91", "125325.20", "22665.17", "0.3200"),
_b("125325.21", "375975.61", "32691.18", "0.3400"),
_b("375975.62", None, "117912.32", "0.3500"),
],
)
# --- Mexico · RESICO · Persona Física · monthly flat rate on income ----------
# Artículo 113-E LISR. Rate applies to total monthly CFDI-backed income.
# Annual income cap for eligibility: $3,500,000 MXN.
RESICO_MONTHLY_MX = TaxTable(
name="ISR RESICO personas físicas (Art. 113-E LISR)",
effective_year=2024,
source="LISR Art. 113-E (verify)",
brackets=[
_f("25000.00", "0.0100"),
_f("50000.00", "0.0110"),
_f("83333.33", "0.0150"),
_f("208333.33", "0.0200"),
_f(None, "0.0250"), # up to the $3.5M/yr eligibility cap
],
)
RESICO_ANNUAL_INCOME_CAP_MX = D("3500000.00")
# --- Mexico · IVA rates ------------------------------------------------------
IVA_STANDARD_MX = D("0.16")
IVA_BORDER_MX = D("0.08") # región fronteriza (estímulo)
IVA_ZERO_MX = D("0.00") # exports, basic foods, medicines (tasa 0%)
# Retenciones — persona física providing professional services to a persona moral
ISR_RETENTION_PROF_SERVICES_MX = D("0.10") # 10% ISR
IVA_RETENTION_PROF_SERVICES_MX = D("0.106667") # two-thirds of 16% IVA
# --- USA · Federal income tax · 2024 · single filer -------------------------
# SOURCE: IRS Rev. Proc. 2023-34 (verify for the year you file).
US_FEDERAL_INCOME_SINGLE_2024 = TaxTable(
name="US federal income tax — single (2024)",
effective_year=2024,
source="IRS Rev. Proc. 2023-34 (verify)",
brackets=[
_b("0", "11600", "0", "0.10"),
_b("11600", "47150", "1160.00", "0.12"),
_b("47150", "100525", "5426.00", "0.22"),
_b("100525", "191950", "17168.50", "0.24"),
_b("191950", "243725", "39110.50", "0.32"),
_b("243725", "609350", "55678.50", "0.35"),
_b("609350", None, "183647.25", "0.37"),
],
)
# USA · Self-employment tax (Schedule SE)
SE_NET_EARNINGS_FACTOR = D("0.9235") # 92.35% of net profit is subject to SE tax
SE_SOCIAL_SECURITY_RATE = D("0.124")
SE_MEDICARE_RATE = D("0.029")
SE_SOCIAL_SECURITY_WAGE_BASE_2024 = D("168600")
SE_MINIMUM_NET_EARNINGS = D("400") # below this, no SE tax is due
# USA · standard deduction (single filer, 2024)
US_STANDARD_DEDUCTION_SINGLE_2024 = D("14600")