aeat.core.aggregation module

Core aggregation taxonomy shared across registry, application, and adapters.

This module owns closed value sets and tiny pydantic carriers only; it does not aggregate ledger rows, calculate casilla values, or perform source resolution. The registry schema imports BindingAggregation, RelationAggregation, and BindingSourceKind to validate TOML authoring input. Application resolvers and adapters import the same BindingSourceKind members so source tokens do not drift through bare strings.

Keep the three axes separate:

class BindingAggregationOp(*values)[source]

Bases: StrEnum

Closed set of aggregation operators a registry binding may declare.

A binding’s aggregation.op selects how the resolver folds the selected source values into the bound casilla value. The members below are the complete set declared on a DataBindingDefinition.aggregation across the registry authoring tree; relation aggregation (copy/sum on a RelationDefinition) and formula-expression operators are a separate, unrelated axis and are not modelled here.

Members:
SUM: Add the selected source values (default for the scalar-folding

families: previous-filing, counterpart, invoice, ledger, withholding).

ROWS: Emit one detail row per selected observation rather than folding

to a scalar (default for the detail-record families: related-party, foreign-asset, atribución, refund).

COPY: Carry a single source value through unchanged; refuses when more

than one source value is selected.

COUNT_DISTINCT: Count the distinct operators/perceptores behind the

selected observations (e.g. Modelo 349 operator counts).

PRIOR_PAGOS_FRACCIONADOS: Modelo 130 cumulative pago-fraccionado carry

that nets the prior positive declaration against the running total.

SUM
ROWS
COPY
COUNT_DISTINCT
PRIOR_PAGOS_FRACCIONADOS
class BindingAggregation(**data)[source]

Bases: BaseModel

Typed aggregation rule carried by a registry DataBindingDefinition.

Placed in core (cross-layer home) because the domain registry schema declares the field and the application/adapter layers read it; the closed BindingAggregationOp set is the only key real binding aggregation mappings carry in the registry authoring tree. The model is strict and frozen, matching the registry schema’s STRICT_FROZEN_CONFIG convention, so an unknown op or a stray extra key is rejected at registry-build validation rather than silently re-parsed at resolve time.

Parameters:

op (BindingAggregationOp)

op: BindingAggregationOp
class RelationAggregationOp(*values)[source]

Bases: StrEnum

Closed set of aggregation operators a registry RelationDefinition may declare.

A relation’s aggregation.op selects how a cross-modelo fold-in folds its matched source filings: COPY carries a single source value through unchanged (the default when a relation declares no aggregation), and SUM adds the matched per-period source values (annual summaries). This is a deliberately separate axis from BindingAggregationOp (which governs DataBindingDefinition folds and carries the binding-only rows / count_distinct / prior_pagos_fraccionados members); the two are not interchanged. The complete set declared across the registry relation tree is copy and sum.

COPY
SUM
class RelationAggregation(**data)[source]

Bases: BaseModel

Typed aggregation rule carried by a registry RelationDefinition.

Placed in core (cross-layer home) because the domain registry schema declares the field and the application/adapter layers read it. The closed RelationAggregationOp set is the only key real relation aggregation mappings carry in the registry authoring tree (every relation declares aggregation = {op = "copy" | "sum"} or none). The model is strict and frozen, matching the registry schema’s STRICT_FROZEN_CONFIG convention, so an unknown op or a stray extra key is rejected at registry-build validation rather than silently re-parsed at resolve time. This is the relation sibling of BindingAggregation; the two op axes are deliberately separate.

Parameters:

op (RelationAggregationOp)

op: RelationAggregationOp
class PeriodKind(*values)[source]

Bases: StrEnum

Authoritative period cadences shared across aggregation and deadline layers.

Placed in core (cross-layer home) so the deadline domain and application aggregation layer can both import without violating the hexagonal direction (domain → core is always legal; domain → application is forbidden).

This lightweight cadence enum is an aggregation/deadline taxonomy, not the public Period classifier. Concrete filing-period values should use Period and its exported PeriodKind, which also distinguishes instalment and extended registry tokens.

MONTHLY
QUARTERLY
ANNUAL
class RowSetGroupingKind(*values)[source]

Bases: StrEnum

Canonical row-set source-kind discriminators for detail-record assembly.

Placed in core (cross-layer home) because both the application assembly layer and the domain registry schema reference these values, and domain → application imports are forbidden under the hexagonal contract.

This is the row-assembly grouping axis consumed in the application layer (_row_set_assembly.py), a separate concept from the binding source token enumerated by BindingSourceKind. For the three detail-record families whose grouping member differs from the binding source token, the correspondence is intentional and explicit; see ROW_SET_GROUPING_FOR_BINDING_SOURCE:

  • BindingSourceKind.WITHHOLDING ("withholding") ↔ WITHHOLDING

  • BindingSourceKind.FOREIGN_ASSET ("foreign_asset") ↔ FOREIGN_ASSET

  • BindingSourceKind.RELATED_PARTY_OPERATION ("related_party_operation") ↔ RELATED_PARTY ("related_party")

  • BindingSourceKind.ATRIBUCION_MEMBER ("atribucion_member") ↔ ATRIBUCION ("atribucion")

  • BindingSourceKind.REFUND_OPERATION ("refund_operation") ↔ REFUND ("refund")

  • BindingSourceKind.DONATIVO_DONOR ("donativo_donor") ↔ DONATIVO ("donativo")

WITHHOLDING
RELATED_PARTY
FOREIGN_ASSET
ATRIBUCION
REFUND
DONATIVO
class BindingSourceKind(*values)[source]

Bases: StrEnum

The single canonical closed set of binding/source-mesh tokens.

Every DataBindingDefinition declares exactly one source drawn from the registry-declared subset of this enum. The same enum also carries mesh-only source decisions such as BORRADOR and IVA_WALLET_DECISION, which are resolved before a registry binding is constructed and are parity-accounted as non-registry members. Per-family frozensets (invoice, ledger, counterpart) are derived from this enum rather than hand-maintained, so a new source token is added in exactly one place.

BEHAVIOUR-PRESERVING LIFT: every member’s string VALUE equals the source token that was previously a bare string (or a RowSetGroupingKind member) in the DataBindingDefinition.source Literal. Those tokens live in registry TOML and may be persisted; a StrEnum serialises to its value, so folding the mixed Literal onto this enum changes the static type without changing any stored or compared string (the modelo-enum-hardening precedent). Do NOT rename a stored token.

This enum is the single canonical source-kind authority across BOTH the registry binding definitions AND the application resolver mesh (phase-2.1 taxonomy unification): the counterpart subset (COUNTERPART_SOURCE_KINDS) is derived from it, and the two grouping members reuse RowSetGroupingKind values so the cross-layer aggregation taxonomy stays consistent; see ROW_SET_GROUPING_FOR_BINDING_SOURCE for the detail-record source-token ↔ grouping-axis mapping.

PROFILE
PREVIOUS_FILING
RELATION_PREFILL
MANUAL_INPUT
LEDGER_OSS_AGGREGATION
LEDGER_IVA_AGGREGATION
LEDGER_RENTA_EXPENSE_AGGREGATION
LEDGER_RENTA_INCOME_AGGREGATION
LEDGER_RENTA_GASTO_AGGREGATION
LEDGER_IMPATRIADO_INCOME_AGGREGATION
RETENCIONES_AGGREGATION
IVA_COMPENSATION_ANNUAL_PARTITION
BIENES_INVERSION_REGULARIZACION
PRORRATA_REGULARIZACION
BORRADOR
IVA_WALLET_DECISION
PAYABLE_INVOICE
COLLECTIBLE_INVOICE
LEDGER_TRANSACTION
PURCHASE_INVOICE_EVIDENCE
WITHHOLDING
FOREIGN_ASSET
RELATED_PARTY_OPERATION
ATRIBUCION_MEMBER
REFUND_OPERATION
DONATIVO_DONOR
ROW_SET_GROUPING_FOR_BINDING_SOURCE: Final[Mapping[BindingSourceKind, RowSetGroupingKind]]

Explicit detail-record binding-source ↔ row-assembly grouping correspondence.

The binding source token (e.g. "related_party_operation") and the row-assembly RowSetGroupingKind value (e.g. "related_party") are distinct strings for the three families whose source token carries the _operation / _member suffix; this mapping makes the relationship explicit so a reader is not misled into assuming the two axes share a value.

INVOICE_BINDING_SOURCE_KINDS: Final[frozenset[BindingSourceKind]]

Invoice-shaped binding source kinds, derived from BindingSourceKind.

counterpart_source_kind(value)[source]

Return value narrowed to the counterpart source-kind subset.

Parameters:

value (object) – A BindingSourceKind member or its stored string value.

Return type:

TypeAliasType

Returns:

The same source kind narrowed to CounterpartSourceKind for counterpart aggregation inputs.

Raises:

ValueError – When value is not a known BindingSourceKind, or is known but outside the counterpart subset.

LEDGER_BINDING_SOURCE_KINDS: Final[frozenset[BindingSourceKind]]

Ledger-aggregation binding source kinds (all six), derived from the enum.

Every binding whose source is a member reads its values from the bucket-scoped ledger (transaction-classified IVA / OSS aggregation, Renta first-slice income/expense aggregation, the M130 pago-fraccionado gasto cumulative aggregation, or the M151 impatriado Spanish-source base aggregation). Cross-domain consumers route through this frozenset so the registry stays the single source of truth for ledger readiness.

class BindingTypedEnumKind(*values)[source]

Bases: StrEnum

The closed set of substrate enum-class names a binding value bridges.

A DataBindingDefinition whose value bridges a closed-membership substrate axis declares typed_enum = one of these members. Each value is the NAME of the closed enum class a consumer routes the binding value through:

  • CENSO_EVENT_KIND ("censo_event_kind") — Modelo 036 censo status.

  • CCAA ("CCAA") — Modelo 100 autonomic-community tax residence.

  • ESTIMACION_DIRECTA_MODALIDAD ("EstimacionDirectaModalidad") — Modelo 100 estimación-directa modality.

  • LEGAL_ENTITY_FORM ("LegalEntityForm") — Modelo 200 legal form.

BEHAVIOUR-PRESERVING LIFT: every member’s string VALUE equals the annotation token that was previously a bare str in DataBindingDefinition.typed_enum. Those tokens live in registry TOML and flow through operator-facing surfaces (bindings list table, the ModeloBindingQueryRow projection, the borrador resolver, the Sheets-pull router); a StrEnum serialises to its value, so narrowing the field from str | None to this enum changes the static type without changing any stored, compared, or emitted string (the modelo-enum-hardening precedent). Do NOT rename a stored token.

Declared in core as a closed value set per the architecture contract; the loader hydrates the registry TOML’s raw token to its member at the schema boundary (see _coerce_typed_enum()). It is the closed-set annotation on the binding, distinct from the engine input_channel (how a formula consumes the value); a binding may carry a typed_enum yet still be a numeric decimal channel.

CENSO_EVENT_KIND
CCAA
ESTIMACION_DIRECTA_MODALIDAD
LEGAL_ENTITY_FORM
class RetencionScheme(*values)[source]

Bases: StrEnum

Closed catalogue of retenciones schemes across the retenciones family.

Each scheme maps to one of the casillas (or grouped casillas) on a retenciones modelo form. The mapping from scheme to modelo lives in the per-modelo entry-point functions; this enum is the union. Declared in core as a closed value set per the architecture contract.

WORK_INCOME and WORK_INCOME_DIRECTOR both fold into the Modelo 111 rendimientos del trabajo block (casillas 01-06) — the form carries a single trabajo block and does not split them — but they carry distinct statutory retención treatments (Modelo 190 separates them by clave A vs E): WORK_INCOME (ordinary empleados) follows the personalised progressive procedure of LIRPF art. 101.1; WORK_INCOME_DIRECTOR (administradores y miembros de consejos de administración) follows the FIXED rate of LIRPF art. 101.2. See work_income_retencion_treatment().

WORK_INCOME
WORK_INCOME_DIRECTOR
ECONOMIC_ACTIVITY
PROFESSIONAL
PRIZE
URBAN_RENTAL
CAPITAL_INTEREST
CAPITAL_DIVIDEND
CAPITAL_OTHER
ADMINISTRADOR_RETENCION_RATE: Final[Decimal]

FIXED retención rate on rendimientos del trabajo perceived “por la condición de administradores y miembros de los consejos de administración, de las juntas que hagan sus veces, y demás miembros de otros órganos representativos”. Binding provision: LIRPF art. 101.2 (Ley 35/2006, BOE-A-2006-20764), developed by RIRPF art. 80.1.3.º (RD 439/2007). Confirmed against the bundled consolidated LIRPF art-101 corpus (“será del 35 por ciento”). This is the GENERAL fixed tipo — distinct from the personalised progressive escala of art. 101.1 (19/24/30/37/45/47 por ciento) that applies to ordinary empleados.

ADMINISTRADOR_RETENCION_REDUCED_RATE: Final[Decimal]

REDUCED fixed retención rate that replaces the 35 % when the administrador/consejero rendimientos proceed from “entidades con un importe neto de la cifra de negocios inferior a 100.000 euros”. Binding provision: LIRPF art. 101.2 segundo inciso (Ley 35/2006), developed by RIRPF art. 80.1.3.º. Confirmed against the bundled consolidated LIRPF art-101 corpus (“el porcentaje de retención e ingreso a cuenta será del 19 por ciento”).

ADMINISTRADOR_RETENCION_REDUCED_INCN_THRESHOLD_EUR: Final[Decimal]

the reduced 19 % administrador rate applies iff the paying entity’s importe neto de la cifra de negocios is STRICTLY below this amount (“inferior a 100.000 euros”); at or above it the general 35 % applies. Binding provision: LIRPF art. 101.2 (Ley 35/2006) / RIRPF art. 80.1.3.º (RD 439/2007).

Type:

LIRPF art. 101.2 INCN ceiling

class WorkIncomeRetencionTreatment(**data)[source]

Bases: BaseModel

Statutory retención treatment for a rendimientos-del-trabajo scheme.

Separates the personalised progressive procedure the law applies to ordinary empleados (LIRPF art. 101.1, developed by RIRPF arts. 80/82-86) from the FIXED rate LIRPF art. 101.2 sets for administradores y miembros de consejos de administración. is_fixed_rate is False for the progressive empleado treatment (the per-perceptor percentage is a personalised computation, so no single rate is carried) and True for the administrador treatment, which carries the general fixed rate plus the reduced rate and its INCN threshold.

A tiny closed carrier per this module’s contract; the rate values are the grounded module constants (ADMINISTRADOR_RETENCION_RATE et al.).

Parameters:
scheme: RetencionScheme
is_fixed_rate: bool
fixed_rate: Decimal | None
fixed_reduced_rate: Decimal | None
fixed_reduced_incn_threshold_eur: Decimal | None
legal_refs: tuple[str, ...]
work_income_retencion_treatment(scheme)[source]

Return the statutory WorkIncomeRetencionTreatment for a work-income scheme.

Returns None for non-work-income schemes (actividades, premios, capital, arrendamiento), which are not governed by the LIRPF art. 101.1/101.2 trabajo procedure. Use it to distinguish the empleado (progressive) treatment from the administrador/consejero (fixed art. 101.2) treatment at the operator boundary.

Return type:

WorkIncomeRetencionTreatment | None

Parameters:

scheme (RetencionScheme)

class RetencionClave(*values)[source]

Bases: StrEnum

Modelo 190 / 193 perceptor clave de percepción (the AEAT clave letter).

Closed catalogue of the retención perceptor clave codes A-L, grounded in the Modelo 190 Diseño de Registros (Orden EHA/3127/2009, actualizada por Orden HAC/1431/2025), campo CLAVE DE PERCEPCIÓN: A trabajo (empleados), B pensionistas y haberes pasivos, C prestaciones o subsidios por desempleo, D prestaciones por desempleo en pago único, E consejeros y administradores, F cursos/conferencias/seminarios y obras, G actividades profesionales, H actividades agrícolas/ganaderas/forestales y empresariales en estimación objetiva, I actividades empresariales / propiedad intelectual e industrial, J imputación de rentas por cesión de derechos de imagen, K premios y aprovechamientos forestales, L rentas exentas y dietas exceptuadas de gravamen. Modelo 193 reuses the A-D letters for its own concepts; the stored clave is the LETTER and its per-modelo meaning is context, so a single letter catalogue covers both. The member name equals its AEAT clave letter (value byte-identical to the stored token). Declared in core as a closed value set per the architecture contract. The M349 / M347 operation “clave” is a DISTINCT taxonomy – see OperationKind349 / OperationKind347, not this enum.

A
B
C
D
E
F
G
H
I
J
K
L
class OperationKind347(*values)[source]

Bases: StrEnum

Modelo 347 operation kinds (clave de operación).

Source: AEAT Modelo 347 instrucciones. Declared in core as a closed value set per the architecture contract.

DELIVERY
ACQUISITION
INSURANCE
RENTAL
SUBSIDY
class OperationKind349(*values)[source]

Bases: StrEnum

Modelo 349 intracomunitarias operation kinds.

Source: AEAT Modelo 349 instrucciones. The clave maps from the underlying directionality (entrega/adquisición) and operation type (bienes/servicios).

INTRA_DELIVERY
INTRA_ACQUISITION
INTRA_SERVICE_OUT
INTRA_SERVICE_IN
TRIANGULAR
class IntracomOperationType(*values)[source]

Bases: StrEnum

Modelo 349 operation-key letters carried by invoice records.

E
H
M
S
T
R
A
ADQUISICION_SERVICIOS
D
C
class ForeignAssetClass(*values)[source]

Bases: StrEnum

Modelo 720 asset classes (clave de tipo de bien).

Source: AEAT Modelo 720 instrucciones. Each clave is declared separately; the declarability gate applies the 50,000 EUR floor to the regulatory obligation block that contains the class after the aggregator runs. Declared in core as a closed value set.

ACCOUNT
SECURITY
COLLECTIVE_INVESTMENT
INSURANCE
REAL_ESTATE
VIRTUAL_CURRENCY