cadrumo.application.calculations.relation_prefill module

Relation prefill: resolve registry relations from prior filings.

One of three distinct prefill tiers, NOT to be merged: this is the RELATION tier (cross-revision aggregations declared as relation_prefill providers). The other two are the previous-filing direct-carry tier (application.calculations.binding_prefill) and the AEAT borrador pre-fill tier (the registry aeat_prefilled flag, an AEAT-live source). Each names a different mechanism and source; they share only the word “prefill”.

Sits between the engine and the local observation store. The engine asks “what’s the resolved value of every relation this revision declares?” and this module answers by consulting a RegistrySnapshot to enumerate the declared relations. The same-modelo first-period default resolver reads the relations and bindings declared on one ModeloRevision directly:

  1. Reading the revision’s relations to determine source_modelo, source_revision_selector, source_periods, source_casilla_id, and aggregation.op.

  2. Scanning the local CalculationObservationRepositoryProtocol for prior RegistryModeloObservation filings matching the source quadruple.

  3. Folding the source filings’ casilla values through the declared aggregation op (sum, copy).

  4. Returning a RelationValues record stamped with provenance the apply adapter writes onto the workbook so the pull adapter can detect stale prefills.

When no prior filings exist for a relation, the resolver returns a RelationValue with value=None and provenance="operator_manual" so the engine emits a blank cell the operator must fill by hand.

This is the local-tier prefill. The AEAT-live tier (parsing justificantes from Sede) lives in a separate adapter that produces the same RelationValues shape; callers route between tiers based on the operator’s preferences and the local store’s coverage.

See also

RelationPrefillSourceResolver

Source-mesh adapter that exposes resolved relations as CalculationSourceResolution.

domain.calculations.registry.relations.relation_source_requirements()

Registry authority that derives the source filings required by a relation.

domain.calculations.registry.relations.relation_prefill_bindings_for_period()

Bridge from resolved relation values to declared relation_prefill binding slots.

activity_start_date_for_bucket(bucket_id, *, profile_path_values_reader)[source]

Operator-declared activity-start date for bucket_id, or None.

Reads censo.activity_start_date off the WIZARD-FREE profile projection (ProfilePathValuesReadPort) — the SAME value the cross-period clean-state gate partitions against (the verify gate threads it in as workflow_profile.activity_start_date), so gate and engine share one activity-start source with no wizard-catalogue dependency. Fail-safe: a missing profile or an absent / malformed date returns None — no period is scoped and the resolver keeps its full all-quarters behaviour (never a silent drop).

Return type:

date | None

Parameters:
scoped_relation_source_requirements(snapshot, activity_start_date, *, operation, m111_no_retenciones_periods=None)[source]

Return relation_source_requirements with no-obligation periods scoped out.

A quarterly source period STRICTLY before the operator-declared activity start is a period in which the taxpayer had no filing obligation, so its absence must NOT unresolve the whole fold (the partial-year-start enhancement for a mid-year-start filer). Reuses the cross-period clean-state gate’s _period_strictly_before_activity_start predicate - one shared partition governs both the gate and the relation fold-in (one-aggregation-path; no parallel scoping math). Non-calendar instalment claves (1P/2P/3P) have no date span and are never scoped, so sociedad Modelo 202 cumulation is unaffected. A genuinely-absent IN-SCOPE quarter still unresolves the requirement downstream, preserving no-silent-under-declaration. Returns the requirements unchanged when activity_start_date is None (the common full-year / fail-closed case). Explicit M111 no-retenciones period attestations also scope out only the named source periods: AEAT instructions say no M111 should be presented when no subject rents were paid, so M190 can fold the remaining filed quarters without requiring a nonexistent blank M111.

Core types: RegistrySnapshot.

Return type:

tuple[RegistryFoldRequirement, ...]

Parameters:
resolve_relations_from_local_store(snapshot, *, operation, repository, captured_at=None, modelo_202_first_year_cuota=False, activity_start_date=None, m111_no_retenciones_periods=None, not_applicable_source_modelos=None)[source]

Build a relation-value record from the local observation store.

Parameters:
  • snapshot (RegistrySnapshot) – The RegistrySnapshot whose declared relations are resolved from prior observation records in the local store.

  • operation (PinnedAuthorityOperation) – The caller-owned generation-pinned authority operation used for relation selection and carry-coordinate checks.

  • repository (CalculationObservationRepositoryProtocol) – The composed observation repository capability.

  • captured_at (datetime | None) – Optional timestamp for relation provenance. Defaults to the current clock.

  • modelo_202_first_year_cuota (bool) – When True (IS-3), an otherwise-unresolved Modelo 202 (source_modelo == "202") fold-in relation resolves to 0 instead of None — a first-year IS filer under modalidad cuota (LIS art. 40.2) has no pago-fraccionado obligation. The caller derives this fail-closed (only for a Modelo 200 target); a resolved M202 value is never overridden.

  • activity_start_date (date | None) – When set (IRPF-1), source periods strictly before the operator’s activity start are scoped out of every relation requirement, so a mid-year-start filer folds only the quarters it actually had an obligation for instead of leaving the annual fold unresolved. None (the default / fail-closed case) keeps the full all-quarters behaviour.

  • m111_no_retenciones_periods (frozenset[tuple[int, str]] | None) – Explicit (year, period) M111 no-obligation attestations. Each named source period is removed from M111 relation folds only; unknown/non-M111 periods keep the normal filing-grade requirement.

  • not_applicable_source_modelos (frozenset[str] | None) – Source modelos positively determined as not applicable for this bucket profile. M100’s mutually exclusive M130/M131 pagos-fraccionados relations use this to resolve the absent leg to explicit zero instead of requiring fake zero filings.

Return type:

RelationValues

Returns a RelationValues whose values tuple has one RelationValue per relation declared in the snapshot’s revision, with provenance stamped per entry. Relations the local store cannot resolve get value=None and provenance="operator_manual" so the engine emits a blank cell the operator can fill by hand.

class RelationPrefillSourceResolver(*, repository, profile_read_ports, operation, registry_snapshot=None, captured_at=None)[source]

Bases: object

Source-mesh adapter for local relation_prefill values.

Resolves registry relations through resolve_relations_from_local_store(), materialises resolved relation values into declared target-binding slots, and returns a CalculationSourceResolution carrying relation values, binding values, diagnostics for unresolved formula relations, and provenance for local RegistryModeloObservation filings.

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

Resolve relation_prefill values from the local store for context.

Return type:

CalculationSourceResolution

Returns:

The resolved CalculationSourceResolution carrying relation values, binding values, diagnostics for unresolved formula relations, and provenance for local filings.

Parameters:

context (CalculationSourceContext)