eldinosaur's picture
PocketAccountant: custom ledger UI + deterministic agent (engine, ledger, retrieval, classifier)
c55ab5e verified
Raw
History Blame Contribute Delete
2.2 kB
"""IVA — Impuesto al Valor Agregado (Mexico).
IVA is a flow-through tax. Each month you net:
IVA a cargo (payable) = IVA trasladado (collected on sales)
− IVA acreditable (paid on deductible purchases)
− IVA retenido (withheld from you by clients)
A negative result is a *saldo a favor* (credit) you can carry forward or request
back. The model never computes this — it calls ``iva_monthly`` and explains the
``breakdown``.
"""
from __future__ import annotations
from .money import D, money
from .result import CalcResult
from .tax_tables import IVA_BORDER_MX, IVA_STANDARD_MX, IVA_ZERO_MX
def iva_on_amount(amount, rate=IVA_STANDARD_MX) -> CalcResult:
"""IVA charged on a single taxable amount."""
base = D(amount)
iva = base * D(rate)
return CalcResult(
amount=money(iva),
label="IVA sobre el monto",
breakdown=[("Base", money(base)), ("Tasa", D(rate)), ("IVA", money(iva))],
source="LIVA Art. 1",
)
def iva_monthly(
iva_trasladado=0, iva_acreditable=0, iva_retenido=0
) -> CalcResult:
"""Monthly net IVA position.
Positive amount → IVA a cargo (you pay the SAT).
Negative amount → saldo a favor (credit carried forward).
"""
trasladado = D(iva_trasladado)
acreditable = D(iva_acreditable)
retenido = D(iva_retenido)
net = trasladado - acreditable - retenido
if net >= 0:
label = "IVA a cargo (mensual)"
notes = []
else:
label = "Saldo a favor de IVA (mensual)"
notes = ["Negative net → credit; carry forward or request a refund."]
return CalcResult(
amount=money(net),
label=label,
breakdown=[
("IVA trasladado (cobrado en ventas)", money(trasladado)),
("IVA acreditable (pagado en compras)", money(acreditable)),
("IVA retenido por clientes", money(retenido)),
("Neto", money(net)),
],
source="LIVA Art. 5-D",
notes=notes,
)
# Convenience rate lookups so callers don't import tax_tables directly.
RATE_STANDARD = IVA_STANDARD_MX
RATE_BORDER = IVA_BORDER_MX
RATE_ZERO = IVA_ZERO_MX