cadrumo.application.aggregation.modelo_bindings module

Repository-backed source-mesh resolvers for modelo registry bindings.

This module is the calculation-facing bridge from bucket-local stores to CalculationSourceResolution. Each resolver owns one BindingSourceKind, reads the active CalculationSourceContext, and materialises binding values declared on the snapshot’s ModeloRevision.

The IVA, Renta income, Renta expense, and M130 gasto resolvers delegate their ledger projection to iva_ledger, renta_income_ledger, renta_ledger, and renta_gasto_ledger. The retenciones resolver reads the dedicated per-perceptor store through retencion_observations_repository. The separate oss_ioss and withholding_source modules follow the same source-mesh contract for Modelo 369 and Modelo 190 detail counts.

Invoice-backed checks use InvoiceCatalogueRepository only as supporting evidence: Modelo 303 domestic IVA remains ledger-owned, while Renta expense aggregation can attach purchase-invoice evidence to transaction rows before producing the shared CalculationSourceResolution.

Declarable observations that no registry binding consumes are reported as source diagnostics rather than silently blanking the filed calculation.

class LedgerIvaAggregationSourceResolver(*, transaction_repository, invoice_catalogue_read_ports, prorrata_register_repository, investment_asset_register=None, investment_asset_profile_id=None)[source]

Bases: object

Resolve ledger_iva_aggregation bindings from the transaction ledger.

Owns BindingSourceKind.LEDGER_IVA_AGGREGATION, projects IVA observations through aggregate_iva_ledger_observations_from_repositories(), and returns a CalculationSourceResolution with source issues, unrouted-observation diagnostics, and transaction provenance.

Parameters:
resolver_id: ClassVar[str]
owned_sources: ClassVar[tuple[BindingSourceKind, ...]]
resolve(context)[source]

Resolve IVA ledger observations for one calculation context.

Return type:

CalculationSourceResolution

Parameters:

context (CalculationSourceContext)

class LedgerRentaIncomeAggregationSourceResolver(*, ports)[source]

Bases: object

Resolve ledger_renta_income_aggregation actividad-income bindings.

Owns BindingSourceKind.LEDGER_RENTA_INCOME_AGGREGATION. Modelo 130 uses the cumulative-quarter income path, while Modelo 100 uses the annual activity-income path over the same ledger eligibility rules.

Parameters:

ports (InvoiceCatalogueReadPorts)

resolver_id: ClassVar[str]
owned_sources: ClassVar[tuple[BindingSourceKind, ...]]
resolve(context)[source]

Resolve Renta activity-income observations for one context.

Return type:

CalculationSourceResolution

Parameters:

context (CalculationSourceContext)

class LedgerImpatriadoIncomeAggregationSourceResolver(*, transaction_repository)[source]

Bases: object

Resolve ledger_impatriado_income_aggregation Modelo 151 base bindings.

Owns BindingSourceKind.LEDGER_IMPATRIADO_INCOME_AGGREGATION. Modelo 151 (régimen especial de impatriados, Ley Beckham) folds only Spanish-source (source_jurisdiction == "ES") income into impatriado.base-liquidable-general over the full ejercicio; every foreign-source or jurisdiction-unresolved row is segregated by the classifier into a typed BECKHAM_FOREIGN_SOURCE_SEGREGATED issue and surfaced as a non-blocking source diagnostic rather than silently admitted or silently dropped (art. 93.2 LIRPF / art. 25.1.f TRLIRNR).

Parameters:

transaction_repository (TransactionCatalogueRepositoryProtocol)

resolver_id: ClassVar[str]
owned_sources: ClassVar[tuple[BindingSourceKind, ...]]
resolve(context)[source]
Return type:

CalculationSourceResolution

Parameters:

context (CalculationSourceContext)

class LedgerIrnrIncomeAggregationSourceResolver(*, transaction_repository)[source]

Bases: object

Resolve the selected-code M210 ledger_irnr_income_aggregation source.

This resolver owns M210 rendimientos_integros only when the persisted gross-income source mode is ledger. It passes the durable official tipo-renta selection through to the classifier rather than using the conceptual rate token, so codes such as 01 and 03 cannot be merged merely because they share a rate concept.

Parameters:

transaction_repository (TransactionCatalogueRepositoryProtocol)

resolver_id: ClassVar[str]
owned_sources: ClassVar[tuple[BindingSourceKind, ...]]
resolve(context)[source]
Return type:

CalculationSourceResolution

Parameters:

context (CalculationSourceContext)

class LedgerRentaGastosPagoFraccionadoAggregationSourceResolver(*, transaction_repository, prorrata_register_repository)[source]

Bases: object

Source mesh resolver for repository-backed M130 deductible-expense (gasto) bindings.

Owns BindingSourceKind.LEDGER_RENTA_GASTOS_PAGO_FRACCIONADO_AGGREGATION. This is the OUTGOING sibling of LedgerRentaIncomeAggregationSourceResolver: it folds deductible business expenses into Modelo 130 casilla 02 over the same cumulative year-to-date quarterly window and emits an unrouted-observation diagnostic for declarable gastos no binding consumes.

Parameters:
resolver_id: ClassVar[str]
owned_sources: ClassVar[tuple[BindingSourceKind, ...]]
resolve(context)[source]

Resolve Renta expense observations for one calculation context.

Return type:

CalculationSourceResolution

Parameters:

context (CalculationSourceContext)

aggregation_period_for_modelo(*, filing_year, code)[source]

Translate a canonical StandardPeriodCode token to a core period.

Accepts only the span-shaped canonical AEAT tokens the calc engine and the CLI ledger filter share: quarters (1T-4T), the annual period (0A), and months (01-12). The result is the typed core Period consumed by ledger filters. Any other token raises AggregationValidationError.

Return type:

Period

Parameters:
  • filing_year (int)

  • code (str)