"""M232 related-party row materialisation into positional casillas.
M232 is an informative-only modelo (Art. 18 LIS) where taxpayers declare
related-party transactions. Rows come from CLI input as ``Modelo232VinculadaRow``
objects and must be materialised into positional casillas on the form.
The form has 5 row slots (vinculada 1-5) for related parties, each with
5 fields (NIF, type_vinculacion, type_operacion, method, importe).
Total positions 144-748 on page_01.
Materialisation maps each row's fields to the registry casilla definitions
declared on the :class:`ModeloRevision` and produces :class:`CasillaObservation`
objects carrying full legal and source provenance from the registry. This is a
CLI-row materialiser on the domain row-model surface, not a registry
``DataBindingDefinition`` family; it consumes the registry symbols it needs
through the registry package facade.
"""
from __future__ import annotations
from decimal import Decimal
from typing import TYPE_CHECKING
from ..calculations.registry import (
CasillaId,
CasillaObservation,
RegistryValidationError,
casillas_by_id,
)
from ._row_models import Modelo232VinculadaRow
if TYPE_CHECKING:
from ..calculations.registry import ModeloRevision
def _extract_row_fields(row: Modelo232VinculadaRow, row_slot: str) -> dict[str, str | Decimal]:
"""Extract field values from a VinculadaRow in declaration order.
Fields map to the registry binding definitions in order:
NIF, tipo_vinculacion, tipo_operacion, metodo, importe.
"""
return {
"nif": row.nif,
"tipo-vinculacion": row.tipo_vinculacion,
"tipo-operacion": row.tipo_operacion,
"metodo-valoracion": row.metodo,
"importe": row.importe,
}
def _resolve_casilla_id_for_field(row_slot: str, field_name: str) -> CasillaId:
"""Map (row_slot, field_name) to the registry casilla ID.
Casilla IDs follow the pattern: {row_slot}-{field_name}
e.g., vinculada-1-nif, vinculada-2-importe, etc.
"""
return f"{row_slot}-{field_name}"