cadrumo.application.aggregation.oss_ioss module

Modelo 369 OSS/IOSS source-mesh resolver and candidate validator.

The ledger_oss_aggregation source reads OSS/IOSS-tagged issued invoices through the required application-owned catalogue-read capability and projects them into substrate-classified OssIossLedgerCandidate rows. Pre-classified callers can also pass candidates directly. Each candidate is validated against the destination Member State’s published IVA rate through domain.iva.lookup.lookup_rate() and becomes a registry-ready OssIossLedgerObservation.

Per the OSS / IOSS regulation suite, the IVA amount on each line MUST match the destination Member State’s published rate for the chosen rate tier on the supply date. A persisted IVA amount that disagrees with the lookup is a data-quality blocker: the wrapper rejects it before the registry resolver sees it, so calculation revisions never land on inconsistent ledger facts.

The OssIossLedgerSourceResolver returns a CalculationSourceResolution with resolved binding values, transaction provenance, and non-blocking diagnostics for empty live catalogues or declarable OSS observations that no ledger_oss_aggregation binding consumes.

class OssIossLedgerCandidate(**data)[source]

Bases: BaseModel

One un-validated ledger line tagged with substrate classification.

The candidate is the application-layer hand-off shape: a ledger line carrying the four classification axes the Modelo 369 binding selectors require, plus the base and IVA amounts the bucket persists. The validate_oss_ioss_observation() function turns a candidate into a registry-ready OssIossLedgerObservation once the persisted IVA amount has been checked against the destination MS rate.

Variables:
  • ledger_id – Stable id of the source ledger line.

  • transaction_date – When the supply takes place. Drives the rate lookup.

  • regime – OSS / IOSS Esquema the line is filed under.

  • destination_member_state – Member State of consumption per the OSS / IOSS place-of-supply rules.

  • rate_kind – Substrate rate tier (general / reduced / etc.).

  • invoice_direction – Whether the autónomo issued or received the invoice.

  • transaction_kind – Substrate domain.iva.classification.TransactionKind the line resolves to.

  • base_amount – Taxable base in EUR. Must be non-negative.

  • iva_amount – IVA amount in EUR persisted on the ledger. Must be non-negative.

Parameters:

data (Any)

ledger_id: _LedgerId
transaction_date: date
regime: OssIossRegime
destination_member_state: EUMemberState
rate_kind: IvaRateKind
invoice_direction: InvoiceKind
transaction_kind: TransactionKind
base_amount: Decimal
iva_amount: Decimal
validate_oss_ioss_observation(candidate, *, operation=None)[source]

Validate candidate and return the registry-ready observation.

Looks up the destination Member State’s rate at the supply date, derives the expected IVA amount from base_amount and the looked-up rate, and rejects the candidate if the persisted iva_amount deviates from the derived value by more than CENT.

Parameters:
  • candidate (OssIossLedgerCandidate) – The substrate-classified ledger line to validate.

  • operation (PinnedAuthorityOperation | None) – Existing generation-pinned authority operation. When omitted, one indexed operation is opened at this composition boundary.

Return type:

OssIossLedgerObservation

Returns:

A registry-ready OssIossLedgerObservation carrying the same identifier, supply date, classification axes, base amount, and persisted IVA amount as the candidate.

Raises:

AggregationValidationError – When the persisted IVA amount disagrees with the destination MS rate by more than the one-cent tolerance.

validate_oss_ioss_observations(candidates, *, operation=None)[source]

Validate every candidate; raise on the first failure.

Parameters:
Return type:

tuple[OssIossLedgerObservation, ...]

Returns:

A tuple of registry-ready OssIossLedgerObservation records in input order.

aggregate_oss_ioss_bindings(revision, candidates, *, operation=None)[source]

Validate candidates then resolve every ledger_oss_aggregation binding.

Pipeline:

  1. Each candidate is validated through validate_oss_ioss_observation(), which checks the persisted IVA against the destination MS rate.

  2. The validated observations are handed off to the registry’s resolve_ledger_oss_aggregation_binding_values() resolver, which filters by every binding’s selector and aggregates the matched lines.

Parameters:
Return type:

dict[TypeAliasType, Decimal]

Returns:

A mapping from each binding id on the revision to its aggregated Decimal value.

class OssIossInvoiceProjection(**data)[source]

Bases: BaseModel

The Modelo 369 candidates for a period, beside the invoices they came from.

The invoices ride along because the candidate cannot answer for its own provenance: it carries a resolved devengo date but not whether that date was declared or substituted, and the advisory the resolver owes the operator is about exactly that distinction.

Variables:
  • candidates – The substrate-classified OSS/IOSS ledger lines.

  • contributing_invoices – The invoices at least one candidate came from.

Parameters:

data (Any)

candidates: tuple[OssIossLedgerCandidate, ...]
contributing_invoices: tuple[Invoice, ...]
project_oss_ioss_invoices_from_repositories(*, period, ports)[source]

Project OSS/IOSS-tagged issued invoices into Modelo 369 ledger candidates.

Attribution is by the LIVA art. 75 devengo date through the shared invoice_devengo_in_period() predicate, so an operation performed in one quarter and invoiced in the next is declared in the quarter it was performed, and every path that folds invoices into a period answers that question the same way.

Parameters:
  • period (Period) – Filing period whose date span filters issued invoices.

  • ports (InvoiceCatalogueReadPorts) – Required application-owned catalogue read capabilities for the composed profile bucket.

Return type:

OssIossInvoiceProjection

Returns:

The candidates for the period beside the invoices they were projected from.

oss_ioss_candidates_from_repositories(*, period, ports)[source]

Return only the Modelo 369 candidates for the period.

The narrow accessor for callers that aggregate but emit no diagnostics. Delegates to project_oss_ioss_invoices_from_repositories() rather than repeating its selection, so the two cannot attribute a period differently.

Parameters:
  • period (Period) – Filing period whose date span filters issued invoices.

  • ports (InvoiceCatalogueReadPorts) – Required application-owned catalogue read capabilities for the composed profile bucket.

Return type:

tuple[OssIossLedgerCandidate, ...]

Returns:

A tuple of OssIossLedgerCandidate rows projected from issued invoices devengando in the period.

aggregate_oss_ioss_from_repositories(revision, *, period, ports, operation=None)[source]

Resolve Modelo 369 OSS/IOSS bindings from the live invoice catalogue.

Parameters:
  • revision (ModeloRevision) – The ModeloRevision whose OSS/IOSS bindings are resolved.

  • period (Period) – Filing period whose date span filters issued invoices.

  • ports (InvoiceCatalogueReadPorts) – Required application-owned catalogue read capabilities for the composed profile bucket.

  • operation (PinnedAuthorityOperation | None) – Existing generation-pinned authority operation. When omitted, one indexed operation is opened at this composition boundary.

Return type:

dict[TypeAliasType, Decimal]

class OssIossLedgerSourceResolver(*, ports, candidates=None)[source]

Bases: object

Source mesh resolver for Modelo 369 OSS / IOSS ledger candidates.

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

Validate candidates and return the resolved OSS/IOSS binding values.

Validates every candidate through validate_oss_ioss_observation() then delegates to the registry’s resolve_ledger_oss_aggregation_binding_values to aggregate the matched lines per binding selector.

When the resolver is constructed with explicit candidates, those candidates are folded directly. When candidates is omitted, the live operator path projects OSS/IOSS-tagged issued invoices from the application catalogue read capability into candidates first. If no candidate is available, the resolver still CLAIMS ledger_oss_aggregation (so the binding compiles and is not flagged as a novel source) but surfaces one non-blocking oss_no_live_source advisory per declared OSS binding. This keeps a Modelo 369 OSS cuota from resolving to a SILENT claimed-zero when the catalogue carries no classifiable OSS invoices.

Parameters:

context (CalculationSourceContext) – The CalculationSourceContext carrying the ModeloRevision whose ledger_oss_aggregation bindings should be resolved.

Return type:

CalculationSourceResolution

Returns:

A CalculationSourceResolution with resolved binding values, source transaction ids, and per-observation provenance records — or, when no candidates were supplied, an empty resolution carrying one oss_no_live_source advisory per declared OSS binding when no candidates can be projected.

Raises:

AggregationValidationError – When any candidate’s persisted IVA amount disagrees with the destination Member State rate by more than one cent.