aeat.domain.bienes_inversion package

Capital-goods IVA deduction-regularización register and annual/disposal computes.

Models the LIVA arts. 107-110 regularización de deducciones por bienes de inversión: a durable, cross-year BienesInversionIvaRegister, one BienInversionIvaRecord per capital good, the pure art-109 RegularizacionAnualResult computed for each supplied definitive prorrata percentage, and the pure art-110 RegularizacionTransmisionResult computed for a good disposed of during its regularisation window.

The register is a taxpayer-fact store (owned goods, acquisition year, cuota soportada, initial definitive prorrata percentage), sibling to domain.iva_compensation; the regulatory constants it consumes (the 4/9-year windows, the over-10-point gate, and the /5, /10 divisors) live in the central authoring surface core.external_constants, grounded verbatim in the bundled consolidated LIVA corpus.

Register-wide projection returns RegistroRegularizacionResult for the ordinary annual art-109 path: each art-108-eligible in-window good (not yet disposed of) is either computed into the proposed Modelo 303 casilla 43 / Modelo 390 regularización value when the current-year definitive prorrata fact is available, or reported as pending that separate input. A good recorded as disposed of in the projected year routes instead through compute_registro_transmisiones(), which folds the art-110 single (“única”) regularización for every remaining window year into the same casilla-43 total; art-110 carries no pending state — the disposal regime and acquisition-year facts are already on the record, so every disposed good is always computed. This domain module does not read the secure-object store or derive prorrata; application and persistence layers supply those facts.

See also

application.bienes_inversion

Profile-scoped service that declares and lists the persisted register.

adapters.persistence.profile.bienes_inversion

FINANCIAL secure-object repository that stores the register singleton.

application.calculations

Source resolver and advisory projection surfaces for the bienes_inversion_regularizacion calculation source.

domain.iva

Legal prorrata substrate that supplies the separate definitive percentage input; usage ratios are not a substitute.

exception BienInversionRecordError(message=None, *, context=None, suggestion=None, translated_message=None)[source]

Bases: AeatError

Raised when a bien-de-inversión register record is structurally invalid.

Parameters:
  • message (str | None)

  • context (dict[str, object] | None)

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

code: ClassVar[ErrorCode]
exception BienInversionValidationError(message=None, *, context=None, suggestion=None, translated_message=None)[source]

Bases: BienInversionRecordError, ValueError

Raised when a bien-de-inversión record fails Pydantic validation.

Parameters:
  • message (str | None)

  • context (Mapping[str, object] | None)

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

code: ClassVar[ErrorCode]
BIENES_INVERSION_SCHEMA_VERSION

Forward-compatible schema version stamped onto every record in this module.

class BienInversionKind(*values)[source]

Bases: StrEnum

LIVA art. 107 regularisation-window taxonomy for a capital good.

Distinct from the LIS art. 12 domain.contribuyente.assets.AssetClass amortization taxonomy: this axis is the mueble-4yr / inmueble-9yr LIVA regularisation window (art. 107.Uno vs art. 107.Tres), not a depreciation coefficient family.

MUEBLE
INMUEBLE
property ventana_anos: int

Count of following calendar years in the art-107 regularisation window.

property divisor: Decimal

Art-109 per-year regularisation divisor (5 mueble / 10 inmueble).

class BienInversionDisposalRegime(*values)[source]

Bases: StrEnum

LIVA art. 110 disposal (transmisión) regime.

SUJETA_NO_EXENTA imputes the remaining window years at a 100% deduction percentage (capped at the amount originally deducted); EXENTA_O_NO_SUJETA imputes them at 0%.

SUJETA_NO_EXENTA
EXENTA_O_NO_SUJETA
class BienInversionDisposal(**data)[source]

Bases: BaseModel

Optional art-110 disposal event carried on a register record.

Variables:
Parameters:
year: int
regime: BienInversionDisposalRegime
class BienInversionIvaRecord(**data)[source]

Bases: BaseModel

One capital good tracked for LIVA arts. 107-110 IVA regularización.

Strict, frozen, no extra fields. Carries the taxpayer facts the art-109 annual compute needs (acquisition year, cuota soportada, initial-year definitive prorrata percentage, mueble/inmueble window) plus an optional cross-reference to an domain.contribuyente.assets.AssetRecord to avoid double data-entry, and the art-108 concept-eligibility flag.

Variables:
  • identifier – Stable natural key chosen by the operator.

  • description – Free-text human description.

  • acquisition_year – Calendar year the good was acquired / put into use.

  • cuota_soportada – Total input IVA (cuota repercutida) borne on the acquisition. Strictly positive.

  • prorrata_inicial_pct – Definitive deduction percentage (0-100) that prevailed in the acquisition year — the baseline art-109 compares each later year’s definitive percentage against.

  • kindBienInversionKind — the mueble/inmueble regularisation window.

  • art108_elegible – Whether the good qualifies as a bien de inversión under LIVA art. 108 (value at/above the escaso-valor threshold, normally used over a year as an instrument of work). False marks a good the operator recorded but which is excluded from regularisation.

  • asset_record_ref – Optional identifier of the sibling domain.contribuyente.assets.AssetRecord. Cross-reference only; this register — not the assets ledger — is the LIVA authority.

  • disposal – Optional BienInversionDisposal (art-110). When present, the good is routed through the art-110 single (“única”) regularización (compute_registro_transmisiones()) in its disposal year instead of the ordinary annual art-109 comparison.

  • schema_version – Forward-compatible schema version. "1".

Parameters:
identifier: str
description: str
acquisition_year: int
cuota_soportada: Decimal
prorrata_inicial_pct: Decimal
kind: BienInversionKind
art108_elegible: bool
asset_record_ref: str | None
disposal: BienInversionDisposal | None
schema_version: str
property deduccion_efectuada: Decimal

Deduction actually made in the acquisition year (cuota × prorrata inicial).

is_within_regularization_window(regularization_year)[source]

Whether regularization_year is one of the art-107 following window years.

The window is the ventana_anos calendar years following acquisition (art. 107.Uno “los cuatro años naturales siguientes” / art. 107.Tres “los nueve años naturales siguientes”). The acquisition year itself is excluded: that is the year the original deduction was made, not a regularisation year.

Return type:

bool

Parameters:

regularization_year (int)

remaining_regularization_years(disposal_year)[source]

Count of art-110 “años que resten” from disposal_year to window end.

Art. 110.Uno: “se efectuará una regularización única por el tiempo de dicho período que quede por transcurrir”, counting the disposal year itself and every later year through the last window year (inclusive). A disposal in the acquisition year itself counts the full window (the deduction was never regularised, so every following window year remains to transcur).

Return type:

int

Parameters:

disposal_year (int)

class RegularizacionDireccion(*values)[source]

Bases: StrEnum

Direction of an art-109 annual regularisation quotient.

INGRESO — the acquisition-year deduction exceeded what the current year’s percentage would allow: an ingreso complementario (repay). DEDUCCION — the current year allows more: a deducción complementaria (claim more). NINGUNA — the over-10-point gate did not fire, or the good is out of window.

INGRESO
DEDUCCION
NINGUNA
class RegularizacionAnualResult(**data)[source]

Bases: BaseModel

Outcome of the art-109 single-good annual regularización compute.

Variables:
  • aplica – Whether the art-107 over-10-point gate fired (a regularisation is due).

  • diferencia_puntos – Absolute percentage-point difference between the current year’s definitive percentage and the acquisition-year one.

  • divisor – Art-109 divisor applied (5 mueble / 10 inmueble).

  • importe – The regularisation quotient (deducción efectuada − deducción que procedería) ÷ divisor, rounded to cents. Positive = ingreso complementario, negative = deducción complementaria; 0.00 when the gate did not fire.

  • direccionRegularizacionDireccion describing importe’s sign.

Parameters:
aplica: bool
diferencia_puntos: Decimal
divisor: Decimal
importe: Decimal
direccion: RegularizacionDireccion
compute_regularizacion_anual(*, cuota_soportada, prorrata_inicial_pct, prorrata_anio_pct, kind)[source]

Compute the LIVA art-109 annual regularización for one capital good.

Implements the art-109 procedure verbatim:

1.º the deduction that would apply if the cuota were borne in the year

considered — cuota_soportada × prorrata_anio_pct;

2.º subtract it from the deduction actually made in the acquisition year —

cuota_soportada × prorrata_inicial_pct;

3.º divide the (positive or negative) difference by 5, or by 10 for land and

buildings; the quotient is the ingreso / deducción complementaria.

The art-107.Uno gate applies: the regularisation is practised only when the absolute difference between the two definitive percentages is strictly greater than core.external_constants.IVA_BIEN_INVERSION_REGULARIZACION_UMBRAL_PUNTOS (10 points). When the gate does not fire, importe is 0.00 and direccion is RegularizacionDireccion.NINGUNA.

Both percentages are supplied as inputs; deriving the current-year definitive percentage (LIVA arts. 102-106) is a separate registry/materialisation concern and this function stays independent of it.

Parameters:
  • cuota_soportada (Decimal) – Total input IVA borne on acquisition (strictly positive).

  • prorrata_inicial_pct (Decimal) – Definitive deduction percentage of the acquisition year (0-100).

  • prorrata_anio_pct (Decimal) – Definitive deduction percentage of the regularisation year (0-100).

  • kind (BienInversionKind) – BienInversionKind selecting the divisor.

Return type:

RegularizacionAnualResult

Returns:

A RegularizacionAnualResult.

Raises:

BienInversionValidationError – On a non-positive cuota or an out-of-range percentage.

class RegularizacionTransmisionResult(**data)[source]

Bases: BaseModel

Outcome of the art-110 single-final (“única”) disposal regularización.

Variables:
  • regimeBienInversionDisposalRegime applied.

  • anos_restantes – Count of window years — the disposal year plus every later year through window expiry — the single regularización covers (art. 110.Uno “el tiempo de dicho período que quede por transcurrir”).

  • divisor – Art-109 divisor applied (5 mueble / 10 inmueble), carried into the art-110 single computation per art. 110.Uno’s cross-reference to the art-109 procedure.

  • importe_sin_limite – The signed quotient before the regla-1ª cap, i.e. (deducción efectuada deducción imputada) × años_restantes ÷ divisor.

  • importeimporte_sin_limite after applying the regla-1ª cap — a negative (DEDUCCION / additional-deduction) result never exceeds -cuota_devengada_entrega in magnitude, when supplied; equals importe_sin_limite unqualified for regla 2ª (no cap applies there) and for a non-negative regla-1ª result.

  • direccionRegularizacionDireccion describing importe’s sign.

  • capped – Whether the regla-1ª cap reduced importe_sin_limite’s magnitude.

Parameters:
regime: BienInversionDisposalRegime
anos_restantes: int
divisor: Decimal
importe_sin_limite: Decimal
importe: Decimal
direccion: RegularizacionDireccion
capped: bool
compute_regularizacion_transmision(*, cuota_soportada, prorrata_inicial_pct, anos_restantes, kind, regime, cuota_devengada_entrega=None)[source]

Compute the LIVA art-110 single (“única”) disposal regularización.

Art. 110.Uno: on a disposal (entrega) during the regularisation window, a SINGLE regularización is practised for the window time remaining (the disposal year plus every later window year), applying the art-109 procedure once over that whole remaining span rather than year by year:

Regla 1.ª (entrega sujeta y no exenta — or an exempt/non-subject entrega that itself originates a deduction right, e.g. exports / intra-EU supplies, per the art. 110.Uno final paragraph): the good is deemed used 100% in deduction-generating operations for every remaining year, which typically yields a negative (additional-deduction) quotient since the imputed 100% usually exceeds the acquisition-year percentage. Art. 110.Uno caps the MAGNITUDE of that additional deduction at the cuota devengada on the disposal itself (“no será deducible la diferencia … y el importe de la cuota devengada por la entrega del bien”) — applied via cuota_devengada_entrega when supplied.

Regla 2.ª (entrega exenta o no sujeta, without its own deduction right — the ordinary case): the good is deemed used 0% for every remaining year. No cap applies (the result is a repayment of previously-taken deduction, never an additional one).

Both reglas apply the SAME art-109 quotient — (deducción efectuada − deducción imputada) ÷ divisor — but multiply the per-year difference by anos_restantes before dividing, since art. 110.Uno folds every remaining window year into one regularización rather than repeating art-109 per year. Unlike compute_regularizacion_anual(), art. 110 carries no diferencia-de-puntos gate: a disposal always triggers the single regularización regardless of how close the imputed percentage is to the acquisition-year one (the disposal itself, not a percentage drift, is what obliges it).

Parameters:
  • cuota_soportada (Decimal) – Total input IVA borne on acquisition (strictly positive).

  • prorrata_inicial_pct (Decimal) – Definitive deduction percentage of the acquisition year (0-100).

  • anos_restantes (int) – Count of remaining window years the single regularización covers; see BienInversionIvaRecord.remaining_regularization_years(). Must be strictly positive (a disposal outside the window has nothing left to regularise and is a caller-level concern, not this function’s).

  • kind (BienInversionKind) – BienInversionKind selecting the divisor.

  • regime (BienInversionDisposalRegime) – BienInversionDisposalRegime selecting regla 1ª (100% imputation, capped) or regla 2ª (0% imputation, uncapped).

  • cuota_devengada_entrega (Decimal | None) – The cuota devengada on the disposal itself, applied as the regla-1ª cap. None leaves regla 1ª uncapped (the caller has not supplied the disposal’s own cuota devengada yet).

Return type:

RegularizacionTransmisionResult

Returns:

A RegularizacionTransmisionResult.

Raises:

BienInversionValidationError – On a non-positive cuota, an out-of-range percentage, a non-positive anos_restantes, or a negative cuota_devengada_entrega.

class BienesInversionIvaRegister(**data)[source]

Bases: BaseModel

Encrypted JSON document holding the per-good IVA regularización register.

Variables:
  • schema_version – Forward-compatible schema version. "1".

  • records – Tuple of BienInversionIvaRecord rows.

Parameters:
schema_version: str
records: tuple[BienInversionIvaRecord, ...]
in_window_records(regularization_year)[source]

Return each art-108-eligible BienInversionIvaRecord in-window for the year.

A good disposed of AT OR BEFORE regularization_year is excluded: art. 110.Uno’s single (“única”) regularización supersedes the ordinary annual art-109 comparison from the disposal year onward — see disposed_records() and compute_registro_transmisiones() for the disposal path.

Return type:

tuple[BienInversionIvaRecord, ...]

Parameters:

regularization_year (int)

disposed_records(disposal_year)[source]

Return each art-108-eligible good whose art-110 disposal falls in disposal_year.

Only a disposal that still leaves window time to regularise is included (BienInversionIvaRecord.remaining_regularization_years() strictly positive); a disposal recorded outside the window has nothing left to regularise under art. 110.

Return type:

tuple[BienInversionIvaRecord, ...]

Parameters:

disposal_year (int)

class RegistroRegularizacionRow(**data)[source]

Bases: BaseModel

One good’s contribution to the annual register-wide regularización.

Variables:
  • identifier – The record identifier.

  • kindBienInversionKind of the good.

  • prorrata_anio_pct – The definitive percentage supplied for the year, or None when the caller could not supply it (the good is reported but not yet computed because the prorrata-definitiva input is absent).

  • result – The RegularizacionAnualResult, or None when prorrata_anio_pct was absent.

Parameters:
identifier: str
kind: BienInversionKind
prorrata_anio_pct: Decimal | None
result: RegularizacionAnualResult | None
class RegistroRegularizacionResult(**data)[source]

Bases: BaseModel

Register-wide art-109 regularización projection for one year.

Variables:
  • regularizacion_year – The year the projection covers.

  • rows – Per-good RegistroRegularizacionRow entries for every in-window, art-108-eligible good.

  • proposed_casilla_43 – The signed sum of every computed importe (art-109 step 3), the value proposed for Modelo 303 casilla 43 / the Modelo 390 regularización field. Positive = net ingreso, negative = net deducción complementaria. Rows without a supplied percentage contribute nothing.

  • computed_count – Number of goods whose regularización was actually computed (a percentage was supplied and the gate fired).

  • pending_percentage_count – Number of in-window goods for which no current-year definitive percentage was supplied.

Parameters:
regularizacion_year: int
rows: tuple[RegistroRegularizacionRow, ...]
proposed_casilla_43: Decimal
computed_count: int
pending_percentage_count: int
compute_registro_regularizacion(register, *, regularizacion_year, prorrata_definitiva_by_identifier)[source]

Project the register onto its annual art-109 regularización for a year.

Iterates every art-108-eligible, in-window good; for each good whose current-year definitive percentage is supplied in prorrata_definitiva_by_identifier, runs compute_regularizacion_anual() and folds the signed importe into the proposed casilla-43 total. Goods without a supplied percentage are reported as pending rather than silently dropped.

Parameters:
Return type:

RegistroRegularizacionResult

Returns:

A RegistroRegularizacionResult.

class RegistroTransmisionRow(**data)[source]

Bases: BaseModel

One disposed good’s contribution to the art-110 single regularización.

Variables:
Parameters:
identifier: str
kind: BienInversionKind
disposal_year: int
result: RegularizacionTransmisionResult
class RegistroTransmisionesResult(**data)[source]

Bases: BaseModel

Register-wide art-110 single-regularización projection for one disposal year.

Variables:
  • disposal_year – The year every included disposal occurred in.

  • rows – Per-good RegistroTransmisionRow entries for every art-108-eligible good disposed of in disposal_year with window time remaining.

  • proposed_casilla_43 – The signed sum of every row’s importe — the value proposed for Modelo 303 casilla 43 / the Modelo 390 regularización field for the disposals in this year. Positive = net ingreso, negative = net deducción complementaria.

  • computed_count – Number of disposed goods included in the projection.

Parameters:
disposal_year: int
rows: tuple[RegistroTransmisionRow, ...]
proposed_casilla_43: Decimal
computed_count: int
compute_registro_transmisiones(register, *, disposal_year, cuota_devengada_entrega_by_identifier=None)[source]

Project the register onto its art-110 single (“única”) regularización for a year.

Iterates every art-108-eligible good recorded as disposed of in disposal_year with window time remaining (BienesInversionIvaRegister.disposed_records()); for each, computes compute_regularizacion_transmision() over the remaining window years and folds the signed importe into the proposed casilla-43 total.

Unlike compute_registro_regularizacion(), a disposal has no pending state analogous to a missing current-year prorrata-definitiva input: every disposal fact the register carries (acquisition-year percentage, cuota soportada, disposal regime) is already on the record, so every disposed good is always computed.

Parameters:
Return type:

RegistroTransmisionesResult

Returns:

A RegistroTransmisionesResult.