aeat.application.aggregation._iva_ledger module¶
Repository-backed IVA observation projection from ledger catalogues.
This module classifies bucket-local
TransactionCatalogue rows into typed
IvaLedgerObservation records and
binding-ready totals. The source-mesh resolver in _modelo_bindings
then applies the target
ModeloRevision, resolves
ledger_iva_aggregation bindings, and surfaces source diagnostics for ledger
rows that no declared binding consumes.
When the bucket’s cross-period prorrata register resolves an active
general provisional percentage for the filing year, the aggregation result
carries IvaLedgerProrrataApportionment. The binding resolver applies
that percentage only to deducible IVA cuota bindings; bases and output IVA
cuotas stay unapportioned.
The repository-backed entry point constructs a
TransactionCatalogueRepository for the active
bucket when none is supplied. Pre-classified callers can use
IvaLedgerCandidate and aggregate_iva_ledger_candidate_bindings()
to run the same validation and registry binding path.
See also
prorrata_registerPer-ejercicio carry home for the provisional percentage consumed by the IVA ledger apportionment.
LedgerIvaAggregationSourceResolverSource-mesh adapter that calls this projection and records prorrata apportionment provenance.
test_iva_ledger_prorrata_apportionmentRegression coverage proving the active provisional percentage reduces deducible cuotas without reducing bases.
_renta_ledger,_renta_income_ledger,_renta_gasto_ledgerSibling Renta ledger projections.
- class IvaLedgerAggregationIssueReason(*values)[source]¶
Bases:
StrEnumMachine-readable reasons why a ledger row did not produce IVA observations.
The first five values are shared with
RentaLedgerAggregationIssueReasonthrough_shared_issue_reasonsso cross-ledger telemetry can group upstream filter rejections under one key. The remaining values are IVA-specific.- UNSUPPORTED_DIRECTION¶
- UNSUPPORTED_CURRENCY¶
- UNCLASSIFIED_BUSINESS_STATE¶
- PERSONAL_TRANSACTION¶
- OUTSIDE_PERIOD¶
- MISSING_TAXABLE_BASE¶
- MISSING_IVA_AMOUNT¶
- MISSING_IVA_RATE¶
- UNSUPPORTED_IVA_RATE¶
- MISSING_EUR_TAX_SUBSTRATE¶
- INVALID_PRORRATA_REFERENCE¶
- UNSUPPORTED_IVA_CATEGORY¶
- MISSING_COUNTERPARTY_EU_MEMBER_STATE¶
- DOMESTIC_COUNTERPARTY_ON_INTRA_COMMUNITY_TRANSACTION¶
- EU_MEMBER_STATE_ON_EXPORT_TRANSACTION¶
- CASH_ACCOUNTING_EXCLUDED_CATEGORY¶
- class IvaLedgerAggregationIssue(**data)[source]¶
Bases:
BaseModelTraceable exclusion emitted while projecting IVA ledger observations.
- Parameters:
transaction_id (str)
reason (IvaLedgerAggregationIssueReason)
detail (str)
- transaction_id: str¶
- reason: IvaLedgerAggregationIssueReason¶
- detail: str¶
- class ProrrataLedgerReference(**data)[source]¶
Bases:
BaseModelBucket-local ledger row pointer to a legal IVA prorrata reference.
- Parameters:
transaction_id (str)
transaction_date (date)
reference (ProrrataReference)
base_amount (Decimal)
input_iva_amount (Decimal)
- transaction_id: str¶
- transaction_date: date¶
- reference: ProrrataReference¶
- base_amount: Decimal¶
- input_iva_amount: Decimal¶
- class IvaLedgerSectorApportionment(**data)[source]¶
Bases:
BaseModelPer-sector prorrata apportionment for a sectores-diferenciados bucket.
Under LIVA arts. 9.1.c / 101 a taxpayer with differentiated sectors applies the deduction regime separately per sector. Each declared sector carries its own provisional
percentageand its ownregime(a sector may run general while another runs especial); the sector-aware binding resolver applies THIS sector’s apportionment to every deducible cuota whose observation carries the matchingsector_id.See also
SectorDefinitionOperator-declared sector this apportionment resolves for.
- Parameters:
sector_id (str)
percentage (Decimal)
regime (ProrrataRegisterRegime)
- sector_id: str¶
- percentage: Decimal¶
- regime: ProrrataRegisterRegime¶
- class IvaLedgerProrrataApportionment(**data)[source]¶
Bases:
BaseModelProrrata percentage applied to deducible ledger IVA cuotas.
Under
regime == GENERAL(LIVA art. 104) the singlepercentageis applied to every deducible cuota binding. Underregime == ESPECIAL(LIVA art. 106)percentageis the general percentage that applies only to the COMMON-use inputs; exclusively-deductible inputs deduct in full and exclusively-non-deductible inputs deduct nothing, routed per the observation’sinput_classification.When
sector_apportionmentsis non-empty (LIVA arts. 9.1.c / 101), the bucket is sectorized: the top-levelpercentage/regimedescribe the COMMON-use apportionment (art. 104.Dos common percentage, for inputs with noprorrata_sector_id), and eachIvaLedgerSectorApportionmentdescribes one declared sector. Emptysector_apportionmentsis the whole-entity register (byte-identical to the pre-sectores behaviour).See also
ProrrataProvisionalProvenanceRegulated source of the provisional percentage carried on this apportionment.
resolve_iva_ledger_binding_values()Applies the percentage after registry selector resolution.
- Parameters:
percentage (Decimal)
provenance (ProrrataProvisionalProvenance)
regime (ProrrataRegisterRegime)
source_observation_ref (str | None)
authorisation_reference (str | None)
sector_apportionments (tuple[IvaLedgerSectorApportionment, ...])
- percentage: Decimal¶
- provenance: ProrrataProvisionalProvenance¶
- regime: ProrrataRegisterRegime¶
- source_observation_ref: str | None¶
- authorisation_reference: str | None¶
- sector_apportionments: tuple[IvaLedgerSectorApportionment, ...]¶
- class AnnualDeducibleTotalsByRegime(**data)[source]¶
Bases:
BaseModelThe ejercicio’s whole-year deducible IVA cuota under both prorrata regimes.
The settlement input to the LIVA art. 103.Dos.2 +10% mandatory-especial check (
build_prorrata_especial_mandatory_advisory): art. 103.Dos.2 makes prorrata especial obligatory when the deducción under the general regime exceeds the deducción under the especial regime by ten percent or more.deduction_under_generalis mechanically derivable for any bucket (art. 104 applies one whole-entity percentage), so it is always honest; the especial total (art. 106 per-input classification) is honest only when the register regime is ESPECIAL, or when every deducible soportado row of the ejercicio carries a declaredinput_classification—unclassified_deducible_countrecords how many deducible soportado observations are still unclassified, so the caller can decide whether the especial total is honestly computable or the filer must first classify.See also
compute_annual_deducible_totals_by_regime()Builds this record from one annual observation aggregation and two apportionment passes.
- Parameters:
deduction_under_general (Decimal)
deduction_under_especial (Decimal)
unclassified_deducible_count (int)
regime (ProrrataRegisterRegime)
- deduction_under_general: Decimal¶
- deduction_under_especial: Decimal¶
- unclassified_deducible_count: int¶
- regime: ProrrataRegisterRegime¶
- class IvaLedgerInputKind(*values)[source]¶
Bases:
StrEnumBusiness role of a pre-classified IVA ledger candidate.
ADJUSTMENTrows may carry negative bases or cuotas because rectification and regularisation entries reverse or correct prior operations. The registry consumes the resulting signed observation; the model keeps the adjustment axis visible at the application boundary where source provenance still exists.- ORDINARY_OPERATION¶
- ADJUSTMENT¶
- class IvaLedgerCandidate(**data)[source]¶
Bases:
BaseModelOne pre-classified ledger line for generic IVA aggregation.
This is the application hand-off shape for IVA facts that cannot be inferred safely from a bank transaction direction plus a rate: exenciones, no-sujetas, recargo de equivalencia, intra-community reverse-charge operations, imports/exports, and explicit adjustments. Upstream classifiers must supply the authoritative IVA category, rate kind, and flow direction before this layer creates a registry-ready
IvaLedgerObservation.- Parameters:
ledger_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])
transaction_date (date)
category (IvaCategory)
exemption_article (IvaExemptionArticle | None)
rate_kind (IvaRateKind)
flow_direction (IvaFlowDirection)
base_amount (Decimal)
iva_amount (Decimal)
input_kind (IvaLedgerInputKind)
prorrata_reference_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)] | None)
cash_accounting_treatment (IvaCashAccountingTreatment)
- ledger_id: _LedgerId¶
- transaction_date: date¶
- category: IvaCategory¶
- exemption_article: IvaExemptionArticle | None¶
- rate_kind: IvaRateKind¶
- flow_direction: IvaFlowDirection¶
- base_amount: Decimal¶
- iva_amount: Decimal¶
- input_kind: IvaLedgerInputKind¶
- prorrata_reference_id: _LedgerId | None¶
- cash_accounting_treatment: IvaCashAccountingTreatment¶
- class IvaLedgerAggregation(**data)[source]¶
Bases:
BaseModelIVA observations produced from one bucket-local transaction catalogue.
out_of_window_summaryis only populated by repository-backed date partitions. Full-catalogue aggregation continues to emit row-level issues because every transaction is already loaded for classification.- Parameters:
period (Period)
observations (Sequence[IvaLedgerObservation])
prorrata_references (Sequence[ProrrataLedgerReference])
prorrata_apportionment (IvaLedgerProrrataApportionment | None)
issues (Sequence[IvaLedgerAggregationIssue])
out_of_window_summary (OutOfWindowTransactionSummary | None)
- period: Period¶
- observations: Sequence[IvaLedgerObservation]¶
- prorrata_references: Sequence[ProrrataLedgerReference]¶
- prorrata_apportionment: IvaLedgerProrrataApportionment | None¶
- issues: Sequence[IvaLedgerAggregationIssue]¶
- out_of_window_summary: OutOfWindowTransactionSummary | None¶
- art_104_tres_excluded_ledger_ids: tuple[str, ...]¶
- aggregate_iva_ledger_observations_from_repositories(*, bucket_id, period, transaction_repository=None, prorrata_register_repository=None)[source]¶
Load the bucket-local transaction catalogue and project IVA observations.
Returns an
IvaLedgerAggregation.See also
ProrrataRegisterRepositoryRepository consulted for the active general-prorrata provisional percentage when no explicit repository is supplied.
- Return type:
- Parameters:
bucket_id (str)
period (Period)
transaction_repository (TransactionCatalogueRepositoryProtocol | None)
prorrata_register_repository (ProrrataRegisterRepositoryProtocol | None)
- validate_iva_ledger_observation(candidate)[source]¶
Validate a pre-classified IVA candidate and return an
IvaLedgerObservation.The validator does not re-classify the operation and does not derive IVA from the base. It only blocks sentinel categories that are not declarable ledger facts; the category, rate, and flow axes must have been resolved upstream from invoice/operation evidence.
- Return type:
- Parameters:
candidate (IvaLedgerCandidate)
- validate_iva_ledger_observations(candidates)[source]¶
Validate every pre-classified IVA candidate in input order.
Returns a tuple of
IvaLedgerObservationinstances.- Return type:
- Parameters:
candidates (Iterable[IvaLedgerCandidate])
- aggregate_iva_ledger_candidates(candidates, *, period)[source]¶
Project pre-classified IVA candidates into period-scoped observations.
This path complements
aggregate_iva_ledger_observations(), which remains the domestic-rate projection from bank transactions. Pre-classified candidates are required for non-domestic IVA and adjustments because those axes cannot be recovered from a transaction amount or direction without guessing.Returns an
IvaLedgerAggregationcarrying the accepted observations and any period-exclusion issues.- Return type:
- Parameters:
candidates (Iterable[IvaLedgerCandidate])
period (Period)
- aggregate_iva_ledger_candidate_bindings(revision, candidates, *, period, prorrata_apportionment=None)[source]¶
Validate pre-classified candidates and resolve registry bindings.
- Parameters:
revision (
ModeloRevision) – TheModeloRevisionused to resolve binding values.candidates (
Iterable[IvaLedgerCandidate]) – Pre-classifiedIvaLedgerCandidaterows to project into engine binding channels.period (
Period) – The aggregationPeriodwhose date range bounds the candidate set.prorrata_apportionment (
IvaLedgerProrrataApportionment|None) – Optional active general-prorrata percentage to apply to deducible IVA cuota bindings after selector resolution.
- Return type:
- aggregate_iva_ledger_observations(transactions, *, period, prorrata_apportionment=None)[source]¶
Project classified ledger transaction tax facts into an
IvaLedgerAggregation.- Parameters:
transactions (
TransactionCatalogue) – TheTransactionCataloguesupplying active ledger entries.prorrata_apportionment (
IvaLedgerProrrataApportionment|None) – Optional active general-prorrata percentage to apply later to deducible IVA cuota binding values.
- Return type:
- resolve_iva_ledger_binding_values(revision, observations, *, prorrata_apportionment=None)[source]¶
Resolve IVA ledger bindings, applying general-prorrata to deducible cuotas only.
- Parameters:
revision (
ModeloRevision) – TheModeloRevisionwhose IVA ledger bindings are resolved.observations (
Iterable[IvaLedgerObservation]) – TypedIvaLedgerObservationrows to aggregate.prorrata_apportionment (
IvaLedgerProrrataApportionment|None) – OptionalIvaLedgerProrrataApportionmentapplied only to deducible cuota bindings.
- Return type:
Under
regime == GENERALthe single provisional percentage multiplies every deducible cuota binding (LIVA art. 104). Underregime == ESPECIALthe deducible cuota is routed per the observation’sinput_classification(LIVA art. 106.Uno: exclusively-deductible 100%, exclusively-non-deductible 0%, common at the general percentage) by_apply_especial_apportionment(); the general-regime code path is unchanged.See also
resolve_ledger_iva_aggregation_binding_values()Registry selector resolver that produces the unapportioned binding values before this wrapper applies prorrata.
ProrrataRegisterEntrySource record for the active provisional percentage represented by
IvaLedgerProrrataApportionment.
- compute_annual_deducible_totals_by_regime(*, bucket_id, ejercicio, revision, transaction_repository=None, prorrata_register_repository=None)[source]¶
Compute the ejercicio’s deducible IVA cuota under both prorrata regimes.
The plumbing for the LIVA art. 103.Dos.2 +10% mandatory-especial settlement check. Aggregates the ejercicio’s annual IVA observations ONCE (
aggregate_iva_ledger_observations_from_repositories()over the canonical0AannualPeriod), then resolvesresolve_iva_ledger_binding_values()TWICE over the same observations — once with a GENERAL-stamped and once with an ESPECIAL-stampedIvaLedgerProrrataApportionmentat the register’s resolved percentage — and sums the deducible-cuota binding ids under each. One aggregation, two apportionment passes through the one canonical resolver (one-aggregation-path-pull-equals-calculate); no second aggregation implementation is introduced.Returns
Nonewhen no register apportionment resolves for the ejercicio (prorrata inapplicable), when the register is sectorized (LIVA arts. 9.1.c / 101 — the art-103.Dos.2 comparison composes per sector, a named v1 deferral), or when the revision declares no deducible cuota bindings. A negative deducible total (an adjustment-heavy degenerate case the art-103.Dos.2 comparison is undefined over) also returnsNoneso the check stays silent rather than crashing on a non-comparable input.- Parameters:
bucket_id (
str) – Active bucket whose annual ledger and prorrata register are read.ejercicio (
int) – The filing year whose annual deducible totals are computed.revision (
ModeloRevision) – The targetModeloRevisionwhose deducible cuota bindings are summed.transaction_repository (
TransactionCatalogueRepositoryProtocol|None) – Optional catalogue repository (defaults to the active bucket’s).prorrata_register_repository (
ProrrataRegisterRepositoryProtocol|None) – Optional register repository (defaults to the active bucket’s).
- Return type:
See also
AnnualDeducibleTotalsByRegimeThe frozen record returned.
build_prorrata_especial_mandatory_advisory()Consumes the two totals to build the +10% advisory.
- validate_iva_ledger_counterparty_category(transaction)[source]¶
Return the D5 counterparty/category gate
IvaLedgerAggregationIssuefor a ledger transaction.- Return type:
- Parameters:
transaction (Transaction)
- iva_ledger_missing_fact_reasons(transaction)[source]¶
Return missing IVA fact reasons for a transaction without projecting it.
Each element is an
IvaLedgerAggregationIssueReasondescribing one absent required tax fact.- Return type:
- Parameters:
transaction (Transaction)