aeat.application.aggregation._impatriado_income_ledger module¶
Repository-backed Modelo 151 impatriado Spanish-source income aggregation.
This is the ledger projection behind the
ledger_impatriado_income_aggregation source for Modelo 151 (régimen
especial de trabajadores desplazados, “Ley Beckham”, art. 93 LIRPF). The annual
entry point aggregate_impatriado_income_ledger_from_repositories() loads a
TransactionCatalogue from the active bucket
through TransactionCatalogueRepository and
delegates to aggregate_impatriado_income_ledger().
Unlike the Modelo 130 / Modelo 100 actividad-económica income pipeline
(_renta_income_ledger), which admits worldwide income into the
resident-IRPF base (LIRPF art. 8), the impatriado base is legally
source-scoped: art. 93.2 taxes the impatriado by the IRNR scope rules, so its
impatriado.base-liquidable-general casilla admits ONLY Spanish-source
income. The declared per-row source_jurisdiction axis — which the CLI
create-boundary gate compels an impatriado profile to supply on every ledger
row — is finally consumed here:
an INCOMING row whose
source_jurisdictionresolves toESfolds into the impatriado base;a foreign-source row (
source_jurisdictionset to any non-EScode) is segregated out of the base and surfaced as a typedImpatriadoIncomeLedgerAggregationIssueReason.BECKHAM_FOREIGN_SOURCE_SEGREGATEDissue carrying the rejected jurisdiction code (art. 93.2 / art. 25.1.f TRLIRNR segregation);a jurisdiction-unresolved row (
source_jurisdiction is None) is NEVER silently coerced toES: it fails loud as the same segregation issue with an unresolved-jurisdiction detail (no-silent-under-declaration).
The impatriado base admits trabajo income — the exact income class the M130
pipeline routes OUT — because the Beckham base is predominantly rendimientos
del trabajo (nómina). The two pipelines are complementary, not shared.
The savings escala (art. 93.2.e.2º → art. 25.1.f TRLIRNR: the parte del ahorro) is out of scope here and blocked on a separate corpus ingest; the base casilla is labelled “excluida la parte del ahorro” to keep that deferral honest.
- class ImpatriadoIncomeLedgerAggregationIssueReason(*values)[source]¶
Bases:
StrEnumMachine-readable reasons why a ledger row did not fold into the impatriado base.
- UNSUPPORTED_DIRECTION¶
- UNSUPPORTED_CURRENCY¶
- UNCLASSIFIED_BUSINESS_STATE¶
- PERSONAL_TRANSACTION¶
- OUTSIDE_PERIOD¶
- UNSUPPORTED_PERIOD¶
- BECKHAM_FOREIGN_SOURCE_SEGREGATED¶
- class ImpatriadoIncomeLedgerAggregationIssue(**data)[source]¶
Bases:
BaseModelTraceable exclusion emitted while aggregating impatriado income ledger rows.
- transaction_id: str¶
- reason: ImpatriadoIncomeLedgerAggregationIssueReason¶
- detail: str¶
- rejected_source_jurisdiction: str | None¶
- class ImpatriadoIncomeObservation(**data)[source]¶
Bases:
BaseModelOne eligible INCOMING Spanish-source income ledger row for the impatriado base.
Carries the typed gross amount and the target casilla id it feeds (
impatriado.base-liquidable-general). The domain registry resolver sums the fiscally computable ingreso (taxable_base_amountwhen the row carries an explicit IVA tagging, elsegross_amount) across all observations for that casilla.source_jurisdictionis retained on the observation for provenance and is"ES"by construction: a foreign or unresolved jurisdiction is segregated into an issue before an observation is ever emitted.- Parameters:
- transaction_id: str¶
- target_casilla_id: CasillaId¶
- gross_amount: Decimal¶
- taxable_base_amount: Decimal | None¶
- filing_date: date¶
- source_jurisdiction: str¶
- class ImpatriadoIncomeLedgerAggregation(**data)[source]¶
Bases:
BaseModelAnnual Spanish-source income observations for one Modelo 151 ejercicio.
out_of_window_summaryis populated by repository-backed date partitions. Full-catalogue aggregation keeps row-level issues because every transaction is already loaded for classification.- Parameters:
modelo (str)
period (Period)
observations (Sequence[ImpatriadoIncomeObservation])
out_of_window_summary (OutOfWindowTransactionSummary | None)
casilla_aggregation (CasillaAggregation)
- modelo: str¶
- period: Period¶
- observations: Sequence[ImpatriadoIncomeObservation]¶
- issues: Sequence[ImpatriadoIncomeLedgerAggregationIssue]¶
- out_of_window_summary: OutOfWindowTransactionSummary | None¶
- casilla_aggregation: CasillaAggregation¶
- aggregate_impatriado_income_ledger_from_repositories(*, bucket_id, period, transaction_repository=None)[source]¶
Load the transaction catalogue and aggregate annual impatriado Spanish-source income.
When no protocol-compatible repository override is supplied, this loader uses
TransactionCatalogueRepositoryscoped tobucket_id.Returns an
ImpatriadoIncomeLedgerAggregation.- Return type:
- Parameters:
bucket_id (str)
period (Period)
transaction_repository (TransactionCatalogueRepositoryProtocol | None)
- aggregate_impatriado_income_ledger(transactions, *, bucket_id, period)[source]¶
Aggregate INCOMING Spanish-source income into Modelo 151
impatriado.base-liquidable-general.Applies the impatriado source scope over the FULL ejercicio (Jan 1 to Dec 31 of
period.year): only INCOMING, EUR-denominated rows whose declaredsource_jurisdictionresolves toESfold into the base. Foreign-source and jurisdiction-unresolved rows are segregated intoImpatriadoIncomeLedgerAggregationIssueReason.BECKHAM_FOREIGN_SOURCE_SEGREGATEDissues rather than silently entering (or silently dropping from) the base.- Parameters:
transactions (
TransactionCatalogue) – TheTransactionCatalogueto aggregate.bucket_id (
str) – Bucket identifier carried through to provenance so the aggregation cannot be silently misattributed.period (
Period) – The annualPeriodwhose year anchors the window.
- Return type:
Returns an
ImpatriadoIncomeLedgerAggregationfor the ejercicio.periodmust be the annual period.