aeat.application.modelo._taxation_comparison module¶
Conjunta vs. individual taxation comparison for Modelo 100 (IRPF).
Runs the registry engine twice – once with declaration_type=2
(tributación conjunta, Art. 82-84 LIRPF) and once with
declaration_type=1 (tributación individual) – over identical
casilla inputs and profile bindings, then surfaces the cuota
differential so married couples can pick the lower-tax regime.
This is a pure, ephemeral operation: no work unit is required and no
revision is persisted. The caller supplies all inputs explicitly via a
RegistrySnapshot; the registry
formula engine evaluates both paths and returns a typed
TaxationComparisonResult.
Scope honesty (ADR 2026-07-01-tributacion-conjunta-individual-adr): the
individual run reuses the single input set assembled for the unidad familiar
and only flips declaration_type to 1, so it faithfully models a
single-earner household. It does not compute two separate spouse returns; a
genuine two-earner individual comparison requires a per-spouse income axis that
is absent at HEAD (the deferred second slice). Every result therefore carries
individual_branch_single_earner_only and an
individual_branch_caveat so no surface presents the individual figure as
authoritative for a two-earner couple.
The comparison is snapshot-grounded. It resolves the result casillas by their
declared semantic roles, refuses ambiguous role matches before choosing a
CasillaId, and requires the
revision’s profile-declaration-type binding so the stored profile value can
be replaced independently for each run.
compare_taxation_for_work_unit() is the high-level entry point for CLI
use: it resolves the registry snapshot and profile bindings from an existing
work unit, deliberately excludes the stored declaration-type value, and delegates
to compare_taxation_modes().
See also
_semantic_role_resolution:Provides the canonical semantic-role-to-casilla resolver and ambiguity refusal used for the cuota resultante and cuota diferencial roles.
_binding_resolution:Supplies the profile-bound values used by the work-unit entry point.
_work_addressing:Resolves natural or exact work addresses before CLI comparison.
- INDIVIDUAL_BRANCH_SINGLE_EARNER_CAVEAT¶
Honesty scope caveat for the individual filing branch (ADR
2026-07-01-tributacion-conjunta-individual-adr). The individual run reuses the single input set assembled for the unidad familiar and merely flipsdeclaration_typeto 1, so it faithfully models only a single-earner household. It does NOT compute two separate spouse returns (each on that spouse’s own income); a genuine two-earner individual comparison requires a per-spouse income attribution axis that does not exist at HEAD. Surfacing this statement keeps the comparator from presenting an unfaithful two-earner figure as authoritative (no-silent-under-declaration/aeat-safety-legal-gates).
- class TaxationRecommendation(*values)[source]¶
Bases:
StrEnumRecommended filing mode based on the computed cuota differential.
The enum reports the lower-tax path after applying the materiality threshold, or
INDIFFERENTwhen the two calculated results differ by less than one euro.- CONJUNTA¶
- INDIVIDUAL¶
- INDIFFERENT¶
- class TaxationComparisonResult(**data)[source]¶
Bases:
BaseModelTyped result of a conjunta-vs-individual comparison run.
All cuota amounts are in euros (
Decimalrounded to 2dp by the registry formula engine). Positive values are amounts to pay (a ingresar); negative values are amounts to refund (a devolver).*_cuota_resultantecarries the Modelo 100 cuota resultante de la autoliquidación semantic role, while*_resultadocarries the cuota diferencial/result role used to computedelta_resultadoand the recommendation.- Parameters:
filing_year (int)
modelo (str)
revision (str)
conjunta_cuota_resultante (Decimal)
individual_cuota_resultante (Decimal)
conjunta_resultado (Decimal)
individual_resultado (Decimal)
delta_resultado (Decimal)
recommendation (TaxationRecommendation)
recommendation_reason (str)
individual_branch_single_earner_only (bool)
individual_branch_caveat (str)
- filing_year: int¶
- modelo: str¶
- revision: str¶
- conjunta_cuota_resultante: Decimal¶
- individual_cuota_resultante: Decimal¶
- conjunta_resultado: Decimal¶
- individual_resultado: Decimal¶
- delta_resultado: Decimal¶
- recommendation: TaxationRecommendation¶
- recommendation_reason: str¶
- individual_branch_single_earner_only: bool¶
- individual_branch_caveat: str¶
- compare_taxation_modes(snapshot, *, inputs, binding_values, enum_binding_values, relation_values=None, date_binding_values=None, date_context=None)[source]¶
Run the registry engine for conjunta and individual, then diff the results.
The function is pure and does not read, create, or persist work units. It requires the caller to provide a loaded
RegistrySnapshot, casilla inputs, and already-resolved profile bindings. It then injectsdeclaration_typeseparately for the conjunta and individual runs and compares the calculated cuota diferencial/result casilla.- Parameters:
snapshot (
RegistrySnapshot) – TheRegistrySnapshotwhose revision is executed for both conjunta and individual taxation modes.inputs (
Mapping[TypeAliasType,Decimal]) – Casilla input values shared across both runs.binding_values (
Mapping[TypeAliasType,Decimal]) – Pre-resolved Decimal binding values; must include all profile-sourced bindings exceptdeclaration_type.enum_binding_values (
Mapping[TypeAliasType,str]) – Pre-resolved string enum binding values.relation_values (
Mapping[TypeAliasType,Decimal] |None) – Optional cross-revision aggregation values.date_binding_values (
Mapping[TypeAliasType,date] |None) – Optional date-typed binding values.date_context (
Mapping[str,date] |None) – Optional date context for temporal casilla resolution.
- Return type:
- Returns:
A
TaxationComparisonResultwith both run outcomes, the signedindividual - conjuntadelta, and the recommendation after the one-euro materiality threshold.
The caller must supply all profile-sourced bindings (CCAA, birth date, etc.) that the revision needs, except
declaration_type: this function injectsdeclaration_type=2for the conjunta run anddeclaration_type=1for the individual run automatically.Raises
TaxationComparisonErrorwhen the revision does not declare adeclaration_typebinding or lacks the cuota casillas required to build the differential. Ambiguous semantic-role casillas are also refused through the same error type.
- exception TaxationComparisonError(message=None, *, context=None, suggestion=None, translated_message=None)[source]¶
Bases:
CoreErrorRaised when a conjunta-vs-individual comparison cannot be performed.
Covers unsupported revisions, missing declaration-type bindings, missing result casillas, and ambiguous semantic-role resolution.
- Parameters:
- Return type:
None
- code: ClassVar[ErrorCode]¶
- compare_taxation_for_work_unit(work_unit_id)[source]¶
Run conjunta-vs-individual comparison for an existing Modelo 100 work unit.
Resolves the registry snapshot and all profile-sourced bindings from the stored work unit, then delegates to
compare_taxation_modes(). Thedeclaration_typebinding is injected by the comparison engine; the stored profile value is intentionally ignored so both paths are always evaluated.- Return type:
- Returns:
A
TaxationComparisonResultwith the conjunta and individual calculation outcomes.- Parameters:
work_unit_id (str)
Raises
TaxationComparisonErrorwhen the work unit’s modelo does not support the comparison (e.g. not Modelo 100). RaisesWorkUnitNotFoundErrorwhenwork_unit_iddoes not exist in the active bucket.See also
compare_taxation_modes():Performs the pure snapshot comparison after this function resolves work-unit state.
- compare_taxation_for_work_address(address)[source]¶
Run conjunta-vs-individual comparison for a natural or exact work address.
- Parameters:
address (
object) – TheModeloWorkAddressselected by CLI work-address parsing.- Return type:
- Returns:
A
TaxationComparisonResultfor the resolved work unit.