aeat.application.modelo._calculate_input module

Typed input bundle and validation for modelo work calculation.

This module converts CLI override tokens into a WorkCalculateInputBundle, resolves the active work unit’s ModeloRevision, and validates canonical CasillaId values, binding channels, relation ids, and shortcut-derived semantic-role casillas before the calculate service persists a CalculationRevision.

The application result pairs that persisted revision with its parent WorkUnit and any non-blocking CalculationSourceDiagnostic rows surfaced by bucket aggregation or post-calculation advisory collectors.

See also

aeat.entrypoints.cli._modelo_work_calculate_cli.register_work_calculate_commands():

Parses the operator-facing modelo work calculate command and calls this module to build the input bundle.

aeat.application.modelo.calculate_modelo_revision_from_bucket_aggregation_with_diagnostics():

Consumes the validated bundle and persists the draft calculation revision.

aeat.application.modelo._calculation_resolution:

Merges caller, backend, profile, relation, and borrador channels before registry-engine execution.

aeat.application.modelo._semantic_role_resolution.casilla_id_for_unique_semantic_role():

Resolves shortcut inputs onto the unique casilla declared by a revision.

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

Bases: ModeloError, ValueError

Raised when operator-supplied modelo calculation inputs are invalid.

Parameters:
  • message (str | None)

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

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

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

Bases: ModeloCalculateInputError

Raised when detail rows violate modelo calculation preconditions.

Parameters:
  • message (str | None)

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

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

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

Bases: ModeloCalculateInputError

Raised when a calculation override value is not decimal-shaped.

Parameters:
  • message (str | None)

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

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

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

Bases: ModeloCalculateInputError

Raised when a --casilla override targets a text casilla with an empty value.

Parameters:
  • message (str | None)

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

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

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

Bases: ModeloCalculateInputError

Raised when a casilla override cannot be resolved for the active revision.

Parameters:
  • message (str | None)

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

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

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

Bases: ModeloCalculateInputError

Raised when a --binding override cannot be resolved for the active revision.

Parameters:
  • message (str | None)

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

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

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

Bases: ModeloCalculateInputError

Raised when a --relation override cannot be resolved for the active revision.

Parameters:
  • message (str | None)

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

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

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

Bases: ModeloCalculateInputError

Raised when grouped calculation shortcut inputs are incomplete.

Parameters:
  • message (str | None)

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

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

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

Bases: ModeloCalculateInputError

Raised when a registry revision lacks a semantic-role target required by a shortcut.

Parameters:
  • message (str | None)

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

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

code: ClassVar[ErrorCode]
class WorkCalculateInputBundle(casilla_inputs, text_casilla_inputs, binding_values, enum_binding_values, relation_values, detail_rows, borrador_snapshot_id, shortcut_diagnostics=())[source]

Bases: object

Application-facing input channels for one modelo work calculate run.

The bundle is the handoff from CLI parsing to application calculation. It separates manual casilla inputs, text casilla inputs, decimal binding overrides, enum binding overrides, relation values, typed detail rows, and the optional borrador snapshot id so each downstream channel keeps its registry-declared type. text_casilla_inputs carries operator-supplied data_type = "text" casilla values (e.g. Modelo 210’s tipo_renta) on a channel parallel to casilla_inputs: the registry engine’s calculate_registry_snapshot(text_inputs=...) reads it for categorical formula dispatch, and it rides into the persisted CalculationRevision input_values_by_casilla_id field so the verification layer’s required-casilla and casilla_equals_implies_nonzero predicate checks can see it. It is never folded into the Decimal casilla_values projection.

Parameters:
casilla_inputs: Mapping[TypeAliasType, Decimal]
text_casilla_inputs: Mapping[TypeAliasType, str]
binding_values: Mapping[TypeAliasType, Decimal]
enum_binding_values: Mapping[TypeAliasType, str]
relation_values: Mapping[TypeAliasType, Decimal]
detail_rows: tuple[Modelo184MemberRow | Modelo232VinculadaRow | Modelo349OperadorRow | Modelo349RectificacionRow | Modelo347ContraparteRow, ...]
borrador_snapshot_id: str | None
shortcut_diagnostics: tuple[CalculationSourceDiagnostic, ...]

Non-blocking advisories raised while resolving shortcut inputs.

Carries the DT 12ª apartado-4 window diagnostics (apply_calculation_shortcut_inputs()) so the calculate service can fold them into its source_diagnostics / source_advisories channel. The shortcut path is the only site with the contingencia/rescate year facts, so the advisory originates here and rides the bundle to the operator surface.

classmethod build(*, casilla_inputs, binding_values, enum_binding_values, relation_values, detail_rows, borrador_snapshot_id, text_casilla_inputs=None, shortcut_diagnostics=())[source]

Freeze CLI-assembled mappings before crossing into calculation services.

Returns:

The frozen calculate input bundle.

Return type:

WorkCalculateInputBundle

Parameters:
optional_binding_values()[source]

Return decimal binding values using the calculation-service optional contract.

Return type:

Mapping[TypeAliasType, Decimal] | None

optional_enum_binding_values()[source]

Return enum binding values using the calculation-service optional contract.

Return type:

Mapping[TypeAliasType, str] | None

optional_relation_values()[source]

Return relation values using the calculation-service optional contract.

Return type:

Mapping[TypeAliasType, Decimal] | None

optional_text_casilla_inputs()[source]

Return text casilla inputs using the calculation-service optional contract.

Return type:

Mapping[TypeAliasType, str] | None

class Modelo202ModalitySummary(modality, reason)[source]

Bases: object

Application summary of the Modelo 202 Art. 40.2 / 40.3 modality.

The calculate CLI includes this advisory when the work unit is a Modelo 202 calculation so the operator can see which registry modality the profile selected and why.

Parameters:
modality: str
reason: str
class ModeloAuthorizationAdvisorySummary(state)[source]

Bases: object

Application summary for an unauthorized-but-computable modelo.

A modelo can have a local registry engine while still being marked as not authorised for filing. The calculate command keeps the computation path available and carries this advisory for the rendering layer.

Parameters:

state (str)

state: str
class ModeloWorkCalculationServiceResult(revision, work_unit, modality=None, authorization_advisory=None, source_diagnostics=())[source]

Bases: object

Application-owned result for one modelo work calculate command.

revision is the persisted CalculationRevision; work_unit is the parent WorkUnit loaded after persistence so renderers do not have to repeat the lookup. The optional advisory summaries are presentation data derived from registry applicability and authorization metadata.

source_diagnostics carries the NON-blocking CalculationSourceDiagnostic rows the source mesh and post-calculation advisory collectors raised. They include unresolved or deferred binding sources, unrouted ledger observations, and calculate-grade official-box / prior-payment / settlement advisories. The calculate verb succeeded and persisted the revision regardless; surfacing these rows keeps omitted or degraded source evidence operator-visible (no-silent-under-declaration). Each diagnostic’s message carries the evidence needed by the CLI renderer.

Parameters:
revision: CalculationRevision
work_unit: WorkUnit
modality: Modelo202ModalitySummary | None
authorization_advisory: ModeloAuthorizationAdvisorySummary | None
source_diagnostics: tuple[CalculationSourceDiagnostic, ...]
calculate_modelo_work_revision(*, work_unit_id, actor, inputs)[source]

Persist a draft calculation revision as a ModeloWorkCalculationServiceResult.

The function forwards the already validated WorkCalculateInputBundle into the bucket-aggregation calculation path, reloads the parent WorkUnit, and attaches any Modelo 202 modality, authorization, or non-blocking source diagnostics needed by the CLI payload.

See also

aeat.application.modelo.calculate_modelo_revision_from_bucket_aggregation_with_diagnostics():

Runs source aggregation and persists the calculation revision.

aeat.entrypoints.cli._modelo_work_calculate_cli._run_work_calculate():

Calls this service and serialises the result for the operator.

Return type:

ModeloWorkCalculationServiceResult

Parameters:
build_work_calculate_input_bundle(*, work_unit_id, casilla_overrides, binding_overrides, relation_overrides, detail_rows, borrador_snapshot_id, prestacion_inss_exenta=None, meses_trabajo_con_hijo_menor_3=(), rescate_plan_pensiones_capital=None, rescate_plan_pensiones_aportaciones_pre_2007=None, rescate_plan_pensiones_aportaciones_totales=None, rescate_plan_pensiones_tipo=None, rescate_plan_pensiones_contingencia_year=None, rescate_plan_pensiones_rescate_year=None, sal_beneficio_neto=None, sal_reserva_dotada=None, sal_capital_social=None, autoconsumo_promotor_base=None)[source]

Build a WorkCalculateInputBundle from operator-supplied tokens.

The active work unit determines the ModeloRevision used for every validation step. --casilla values must be canonical casilla ids; printed numbers and ambiguous noncanonical references are refused. A --casilla key whose registry CasillaDefinition declares data_type = "text" (e.g. Modelo 210’s tipo_renta) is routed onto the parallel text-casilla channel as a raw, non-empty string instead of being forced through the decimal parser; every other --casilla key keeps the existing decimal-only contract. --binding is routed by the registry-declared channel, so enum bindings stay as strings, decimal bindings are parsed as Decimal, and date-valued profile bindings are rejected with profile guidance. --relation values must match declared relation ids.

Detail rows are checked before engine dispatch, and shortcut flags are translated into semantic-role casilla values or backend-owned bindings by aeat.application.modelo.apply_calculation_shortcut_inputs().

Return type:

WorkCalculateInputBundle

Parameters:
is_detail_casilla_override_key(key)[source]

Return whether key names a reserved detail-row alias, not a scalar casilla.

Return type:

bool

Parameters:

key (str)

modelo_202_modality_for_work_unit(work_unit)[source]

Return a Modelo202ModalitySummary for work_unit when applicable.

Non-Modelo-202 work units return None. For Modelo 202, the active profile projection is passed to the registry applicability helper so the calculate payload can disclose whether Art. 40.2 or Art. 40.3 was selected.

Return type:

Modelo202ModalitySummary | None

Parameters:

work_unit (WorkUnit)

authorization_advisory_for_modelo(modelo)[source]

Return a ModeloAuthorizationAdvisorySummary for an unauthorized-but-computable modelo.

Authorized modelos and modelos without a local calculation engine return None. Unauthorized modelos with an engine return the registry authorization state for non-blocking CLI disclosure.

Return type:

ModeloAuthorizationAdvisorySummary | None

Parameters:

modelo (str)

apply_calculation_shortcut_inputs(*, work_unit_id, casilla_inputs, binding_values, prestacion_inss_exenta=None, meses_trabajo_con_hijo_menor_3=(), rescate_plan_pensiones_capital=None, rescate_plan_pensiones_aportaciones_pre_2007=None, rescate_plan_pensiones_aportaciones_totales=None, rescate_plan_pensiones_tipo=None, rescate_plan_pensiones_contingencia_year=None, rescate_plan_pensiones_rescate_year=None, sal_beneficio_neto=None, sal_reserva_dotada=None, sal_capital_social=None, autoconsumo_promotor_base=None)[source]

Apply backend-owned tax shortcut inputs for a calculation command.

The CLI may parse option strings into typed values, but legal-rule computations, semantic casilla routing, and special binding injection belong to the application layer. INSS maternity/paternity, maternity deduction, DT 12 pension-rescue reduction, and SAL reserve inputs resolve to unique semantic-role casillas. The Modelo 303 autoconsumo-promotor shortcut writes the backend-owned binding consumed by the registry engine.

The DT 12ª pension-rescate shortcut is fact-gated by the apartado-4 time window (LIRPF DT 12ª.4, added by Ley 26/2014). When the operator declares the contingencia year and the window predicate (dt12_regime_window_eligibility()) proves the window CLOSED, the 40% reducción injection is WITHHELD — the legally correct no-régimen result, since applying an out-of-window reducción would be a silent over-reduction (under-declaration of tax per no-silent-under-declaration). When the window is open the reducción injects as usual; when the contingencia year is absent the reducción injects with an unverified-window advisory. Every branch surfaces a non-blocking CalculationSourceDiagnostic; calculate never aborts on the window verdict.

Returns:

resolved casilla inputs, resolved decimal binding values, and the non-blocking DT 12ª window advisory diagnostics (empty when no pension rescate was supplied).

Return type:

A triple

Parameters:
  • work_unit_id (str)

  • casilla_inputs (Mapping[CasillaId, Decimal])

  • binding_values (Mapping[BindingId, Decimal])

  • prestacion_inss_exenta (Decimal | None)

  • meses_trabajo_con_hijo_menor_3 (tuple[tuple[str, int], ...])

  • rescate_plan_pensiones_capital (Decimal | None)

  • rescate_plan_pensiones_aportaciones_pre_2007 (Decimal | None)

  • rescate_plan_pensiones_aportaciones_totales (Decimal | None)

  • rescate_plan_pensiones_tipo (RescateType | None)

  • rescate_plan_pensiones_contingencia_year (int | None)

  • rescate_plan_pensiones_rescate_year (int | None)

  • sal_beneficio_neto (Decimal | None)

  • sal_reserva_dotada (Decimal | None)

  • sal_capital_social (Decimal | None)

  • autoconsumo_promotor_base (Decimal | None)

See also

aeat.application.modelo._semantic_role_resolution.casilla_id_for_unique_semantic_role():

Selects the unique semantic-role casilla for shortcut values.