Source code for cadrumo.domain.modelos.m232_row_materialisation

"""M232 related-party row materialisation into positional casillas.

Rows come from CLI input as ``Modelo232VinculadaRow`` objects and are
materialised into the selected revision's positional casillas.  The selected
revision owns the row capacity, field declarations, binding identities, and
export layout; this module retains only the row-materialisation boundary.
"""

from __future__ import annotations

from collections.abc import Callable, Mapping
from datetime import date
from decimal import Decimal
from typing import Final

from ...core.casilla_id import CasillaId
from ...core.time.clock import today_madrid
from ..calculations.registry.authority import PinnedAuthorityOperation, bundled_indexed_authority
from ..calculations.registry.errors import RegistryValidationError
from ..calculations.registry.facts.resolution import (
    MappingFactQuery,
    ResolvedMappingFact,
    required_mapping_entry,
    unique_mapping_tokens,
)
from ..calculations.registry.schema_base import DateAxis
from .row_models import Modelo232VinculadaRow

_FACT_ID: Final = "modelo-232-related-party-row-materialisation-mapping"
_SUBJECT: Final = "Modelo 232 related-party row mapping"

#: How each registry-declared row field reads its value off a row. The registry
#: owns which fields exist and in what order; an undeclared field id is refused.
_ROW_FIELD_READERS: Final[Mapping[str, Callable[[Modelo232VinculadaRow], str | Decimal]]] = {
    "nif": lambda row: row.nif,
    "tipo-vinculacion": lambda row: str(row.tipo_vinculacion),
    "tipo-operacion": lambda row: str(row.tipo_operacion),
    "metodo-valoracion": lambda row: str(row.metodo),
    "importe": lambda row: row.importe,
}


def _resolve_m232_registry_declarations(
    *,
    effective_date: date,
    operation: PinnedAuthorityOperation,
) -> ResolvedMappingFact:
    """Resolve the selected Modelo 232 row declaration and mapping fact."""
    resolved = operation.resolve_governed_fact(
        MappingFactQuery(
            fact_id=_FACT_ID,
            date_axis=DateAxis.FILING_PERIOD,
            effective_date=effective_date,
        ),
    )
    if not isinstance(resolved, ResolvedMappingFact):
        raise TypeError("Modelo 232 row declarations must resolve as a mapping fact")
    return resolved


def _row_capacity(entries: Mapping[str, str], slot_ids: tuple[str, ...]) -> int:
    raw = required_mapping_entry(entries, "row.capacity", subject=_SUBJECT)
    if not raw.isdigit() or int(raw) != len(slot_ids):
        raise RegistryValidationError(f"{_SUBJECT} 'row.capacity' must equal the number of declared row slots")
    return int(raw)






__all__ = [
    "m232_related_party_row_casilla_values",
]