cadrumo.application.aggregation._models module

Strict boundary models for financial transaction aggregation.

Carries the per-casilla CasillaProvenance trace, the aggregated CasillaAggregation ledger shape, and LedgerAggregationResultBase, the shared envelope every ledger-projection aggregation result (renta income, renta gasto, IRNR income, impatriado income, and the Modelo 100 first-slice expense aggregation) subclasses. These models import the canonical core.period.Period; period construction and date-span authority live in core, not in an application-layer wrapper.

class CasillaProvenance(**data)[source]

Bases: BaseModel

Transaction trace backing one (casilla, category) subtotal.

Variables:
  • casilla_id – Target canonical casilla id (e.g. "02").

  • transaction_ids – Sorted, frozen tuple of contributing transaction IDs.

  • subtotal – Sum of contributions for this casilla/category pair.

  • category_id – Optional category identifier when the contribution came from an expense bucket.

Parameters:

data (Any)

casilla_id: TypeAliasType
transaction_ids: Sequence[str]
subtotal: Decimal
category_id: Optional[Annotated[SpendingCategory]]
class CasillaAggregation(**data)[source]

Bases: BaseModel

Aggregated casilla ledger for one modelo and period.

Variables:
  • modelo – Modelo identifier (ModeloCode.value) the totals belong to.

  • period – The Period covered.

  • casilla_values – Mapping of canonical casilla id to summed Decimal value, sorted and frozen.

  • provenance – Tuple of CasillaProvenance rows tracing each contribution back to its source transactions.

Parameters:

data (Any)

modelo: str
period: Period
casilla_values: Mapping[TypeAliasType, Decimal]
provenance: Sequence[CasillaProvenance]
class LedgerAggregationResultBase(**data)[source]

Bases: BaseModel, Generic

Shared envelope for one ledger-projection aggregation result.

The PEP 695 type parameters are bounded to strict pydantic models, and concrete projection subclasses specialise this envelope in their own modules. This module deliberately evaluates annotations eagerly (no postponed __future__ annotations): a PEP 695 parameter exists only in the class scope, so a postponed Sequence[ObservationT] string cannot be resolved when a subclass in another module parametrises this base, and the subclass is left incomplete until its first use fails.

Every ledger-projection family (renta income, renta gasto, IRNR income, impatriado income, and the Modelo 100 first-slice expense aggregation) resolves to the same shape: a modelo/period pair, the typed observations and issues the projection produced, and the CasillaAggregation those observations fold into. _validate_casilla_period cross-checks the envelope’s own modelo/period against the fold it carries, so the two can never silently drift apart.

out_of_window_summary is deliberately NOT declared here even though four of the five known subclasses carry it: the Modelo 100 first-slice expense aggregation has no repository-backed date partition and never had this field. Lifting it into this base would silently WIDEN that subclass’s extra="forbid" accepted-input surface (a previously-refused keyword would validate) and add a key to its model_dump() output that was never there. Each subclass that needs it declares it itself, exactly as it did before this extraction.

A subclass’s own extra fields (e.g. a selected official code, a profile year) always follow every field declared here, per ordinary pydantic field-declaration inheritance – this can reorder a field that, before this extraction, was declared between period and observations. Verified inert for the five current subclasses: none is persisted, hashed, or compared via model_dump_json() string equality anywhere in this codebase, so the reordering changes no observable behaviour.

Parameters:
modelo: str
period: Period
observations: Sequence[TypeVar(ObservationT, bound= BaseModel)]
issues: Sequence[TypeVar(IssueT, bound= BaseModel)]
casilla_aggregation: CasillaAggregation