cadrumo.domain.modelos.row_models module¶
Typed CLI row models for multi-row informational modelos.
Provides strictly-validated pydantic row shapes for operator-supplied detail rows on modelos whose filing content is a list of repeating records rather than a set of scalar casilla values.
Supported row types:
Modelo184MemberRow— atribución member for modelo 184 (--row miembro nif=X share=Y importe=Z)Modelo232VinculadaRow— operación vinculada for modelo 232 (--row vinculada nif=X tipo_vinculacion=Y importe=Z metodo=M pais=P)Modelo349OperadorRow— operador row for modelo 349 (--row operador codigo_pais=DE nif_comunitario=DE123456789 razon_social=X clave_operacion=E importe=Y) Used when no collectible-invoice ledger exists; maps directly to the operator record layout.Modelo349RectificacionRow— rectificación intracomunitaria for modelo 349 (--row rectificacion codigo_pais=DE nif_comunitario=DE123456789 razon_social=Xclave_operacion=E ejercicio=2025 periodo=2T base_rectificada=Y base_anterior=Z) Used when the operator declares Tipo-2 rectification records directly.Modelo347ContraparteRow— contraparte declarada for modelo 347 (--row contraparte nif=X nombre=Y importe_Q1=Z clave_operacion=A) One row per counterparty. Annual importe threshold check (> €3,005.06) is performed by the CLI validator, not the model, so partial row sets accumulate correctly before final validation.Modelo210AgrupacionRentaRow— one component renta in an annual Modelo 210 agrupación (period0A). The row retains the official two-digit renta code and the statutory grouping keys; it is evidence only and never an alternate arithmetic input.
These models are the CLI boundary layer. They validate operator input
before being carried into detail_rows on the CalculationRevision.
- resolve_detail_row_owning_modelos(*, effective_date)[source]¶
Project registry-declared ownership for every typed detail-row token.
- resolve_detail_bearing_modelos(*, effective_date)[source]¶
Project the registry’s repeated-detail modelo membership declaration.
- class Modelo184MemberRow(**data)[source]¶
Bases:
BaseModelOne (member, clave, subclave) atribución row for Modelo 184.
The socio record’s own diseño repeats per clave or subclave with an importe declared, not per member alone (see the accepted row-shape ADR), so this row’s identity is
(nif, clave, subclave)rather thannifalone – the same shape 349’soperadorrow already carries via itsclave_operacionaxis.Fields mirror the per-record Tipo-2 layout declared in the M184
bindings/0001-bindings.tomlatribucion_member source block.Parity assertions:
nif→member_tax_id(binding: modelo-184-member-row-nif)nombre→member_legal_name(binding: modelo-184-member-row-name)porcentaje→share_percentage(binding: modelo-184-member-row-share)importe→base_imponible_assigned(binding: modelo-184-member-row-base-assigned)pais→country_code(required; never inferred)clave→clave(binding: modelo-184-member-row-clave)subclave→subclave(binding: modelo-184-member-row-subclave)every clave/subclave-conditional field below mirrors its own
modelo-184-member-row-<field>binding.
Deliberately excluded (see the accepted row-shape ADR): the clave-A reducción (its governing article is unresolved), provisiones-gastos- dificil-justificacion (computed from the entity’s own régimen fact, not an operator-declared value), and any clave-E eligibility fact (a tracked gap, no representation in this tree yet).
- Parameters:
data (Any)
- row_type: Literal['miembro']¶
- nif: _NifStr¶
- nombre: _NameStr¶
- pais: _IsoCountryCode | None¶
- porcentaje: Decimal¶
- importe: Decimal¶
- clave: M184Clave¶
- subclave: M184Subclave | None¶
- codigo_provincia: Annotated[str, StringConstraints(strip_whitespace=True, max_length=2)] | None¶
- miembro_a_31_diciembre: bool | None¶
- dias_miembro: int | None¶
- domicilio_fiscal: Annotated[str, StringConstraints(strip_whitespace=True, max_length=40)] | None¶
- naturaleza_inmueble: M184NaturalezaInmueble | None¶
- situacion_inmueble: M184SituacionInmueble | None¶
- referencia_catastral: Annotated[str, StringConstraints(strip_whitespace=True, max_length=20)] | None¶
- clave_declarado: M184ClaveDeclarado | None¶
- porcentaje_titularidad_inmueble: Decimal | None¶
- dias_arrendamiento: int | None¶
- reduccion: Decimal | None¶
- rendimiento_neto_previo_eo: Decimal | None¶
- rendimiento_neto_minorado_agricola_eo: Decimal | None¶
- class Modelo232VinculadaRow(**data)[source]¶
Bases:
BaseModelOne operación vinculada row for Modelo 232.
Fields mirror the related_party_operation binding source declared in
232/revisions/2018-y-siguientes/bindings/0218…0223-*.toml.The three coded fields carry the closed catalogues AEAT’s diseño de registro DR23200 publishes as Tablas A, C and B — off-catalogue codes are refused here rather than travelling into a fichero field that cannot hold them.
Parity assertions:
nif→counterparty_tax_id(binding: modelo-232-related-party-row-nif)nombre→counterparty_legal_name(binding: modelo-232-related-party-row-name)pais→country_code(binding: modelo-232-related-party-row-country)tipo_operacion→operation_kind_code(binding: modelo-232-related-party-row-operation-kind)metodo→transfer_pricing_method_code(binding: modelo-232-related-party-row-tpr-method)importe→amount(binding: modelo-232-related-party-row-amount)
- Parameters:
data (Any)
- row_type: Literal['vinculada']¶
- nif: _NifStr¶
- nombre: _NameStr¶
- pais: _IsoCountryCode¶
- tipo_vinculacion: Annotated[TipoVinculacion | str, BeforeValidator(lambda v: _hydrate_m232_codigo(field_name='tipo_vinculacion', value=v, code_set=TipoVinculacion))]¶
- tipo_operacion: Annotated[TipoOperacionVinculada | str, BeforeValidator(lambda v: _hydrate_m232_codigo(field_name='tipo_operacion', value=v, code_set=TipoOperacionVinculada))]¶
- metodo: Annotated[MetodoValoracion | str, BeforeValidator(lambda v: _hydrate_m232_codigo(field_name='metodo', value=v, code_set=MetodoValoracion))]¶
- importe: Decimal¶
- exception Modelo349CountryPrefixContextError(*, country_code, clave_operacion, filing_year, period, reason)[source]¶
Bases:
CadrumoErrorA Modelo 349 country prefix is invalid for the filing context.
- Parameters:
- Return type:
None
- code¶
- class Modelo349OperadorRow(**data)[source]¶
Bases:
BaseModelOne typed operator row for Modelo 349 manual-entry input.
- Parameters:
data (Any)
- row_type: Literal['operador']¶
- codigo_pais: _IsoCountryCode¶
- nif_comunitario: _NifStr¶
- razon_social: _RequiredNameStr¶
- clave_operacion: Modelo349ClaveOperacionValue¶
- importe: Decimal¶
- class Modelo349RectificacionRow(**data)[source]¶
Bases:
BaseModelOne typed rectification row for Modelo 349 manual-entry input.
- Parameters:
data (Any)
- row_type: Literal['rectificacion']¶
- codigo_pais: _IsoCountryCode¶
- nif_comunitario: _NifStr¶
- razon_social: _RequiredNameStr¶
- clave_operacion: Modelo349ClaveOperacionValue¶
- ejercicio: Annotated[str, StringConstraints(strip_whitespace=True, min_length=4, max_length=4)]¶
- periodo: str¶
- base_rectificada: Decimal¶
- base_anterior: Decimal¶
- validate_m349_nif_format(nif, pais)[source]¶
Return whether
nifhas the NIF-IVA structure Modelo 349 accepts forpais.
- validate_m349_country_prefix_context(*, country_code, clave_operacion, filing_year, period, is_rectification=False, rectified_year=None, rectified_period=None)[source]¶
Validate the post-Brexit
GB/XIprefix rules for one Modelo 349 row.AEAT’s Modelo 349 instructions keep
XIfor Northern Ireland goods operations from the transition year onward and exclude the service keys from it.GBstays valid only for rectifications of pre-transition periods and for the transition year’s first periods, never for service keys. The transition year, first periods and service keys are registry-declared.
- m349_nif_number_for_export(nif, pais)[source]¶
Return the BOE NIF subfield without the separate country-code prefix.
Modelo 349 operator records split the IVA identifier into
codigo_paisandnif_comunitariofields. The CLI accepts and validates the full prefixed IVA identifier for operator ergonomics, but the fixed-width export must write only the number part into positions 78-92.
- class Modelo347ClaveOperacion(*values)[source]¶
Bases:
StrEnumClave de operación declarable on a Modelo 347 counterparty row.
This operation-key type is specific to the M347 row family and is not shared with the registry-owned M349 operation-key shell.
- A¶
- B¶
- C¶
- D¶
- E¶
- F¶
- G¶
- Modelo347ClaveOperacionValue¶
The same code set for a wire or operation payload field.
- class Modelo347ContraparteRow(**data)[source]¶
Bases:
BaseModelOne contraparte declarada row for Modelo 347.
Fields mirror the per-counterparty Tipo-2 record layout declared in
347/revisions/2011-2024.One row per counterparty. The annual total importe (sum of Q1-Q4) must exceed €3,005.06 per RD 1065/2007 art. 33.1.
Parity assertions:
nif→contraparte.nif(counterparty tax id)nombre→contraparte.nombre(legal name)importe_Q1/Q2/Q3/Q4→ quarterly importe slotsclave_operacion→ operation type codepais_codigo→contraparte.pais(ISO 3166-1; None = domestic)
- Parameters:
data (Any)
- row_type: Literal['contraparte']¶
- nif: _NifStr¶
- nombre: _NameStr¶
- importe_Q1: Decimal¶
- importe_Q2: Decimal¶
- importe_Q3: Decimal¶
- importe_Q4: Decimal¶
- clave_operacion: Modelo347ClaveOperacionValue¶
- pais_codigo: _IsoCountryCode | None¶
- class Modelo210AgrupacionRentaRow(**data)[source]¶
Bases:
BaseModelOne typed component row in an annual Modelo 210 grouping.
- Parameters:
data (Any)
- row_type: Literal['agrupacion_renta']¶
- source_id: _RequiredNameStr¶
- tipo_renta_code: _M210OfficialTipoRentaCode¶
- importe: Decimal¶
- tipo_gravamen: UnitProportion¶
- pagador_mode: M210PayerMode¶
- pagador_id: _RequiredNameStr | None¶
- deriva_de_bien_derecho: bool¶
- bien_derecho_id: _RequiredNameStr | None¶
- exception Modelo210AgrupacionRentaRowsError(*, reason, detail)[source]¶
Bases:
CadrumoErrorA Modelo 210 annual grouped-renta set violates row compatibility.
- code¶
- validate_m210_agrupacion_renta_rows(rows, *, effective_date)[source]¶
Validate a grouped-renta row set against one dated registry catalogue.
- Return type:
- Parameters:
rows (Sequence[Modelo210AgrupacionRentaRow])
effective_date (date)
- exception Modelo347ThresholdError(*, nif, total, threshold)[source]¶
Bases:
CadrumoErrorA Modelo 347 contraparte row falls at or below the declarability threshold.
- Parameters:
nif (str)
total (Decimal)
threshold (ResolvedScalarFact)
- Return type:
None
- code¶
Bases:
CadrumoErrorModelo 184 member share percentages do not sum to exactly 100%.
- Parameters:
total (Decimal)
count (int)
- Return type:
None
- validate_m347_threshold(rows, *, effective_date)[source]¶
Enforce the Modelo 347 per-counterparty declarability threshold.
RD 1065/2007 art. 33.1: only counterparties whose annual operations exceed EUR 3,005.06 are declarable. The threshold applies to the SUM of every operation with the same person (same NIF), aggregated across all contraparte rows — not to each row in isolation. A counterparty’s operations may be split across several rows (e.g. entregas and adquisiciones), so a per-row check would wrongly reject a counterparty whose individual rows are each at/below the threshold while their annual aggregate exceeds it (a missed declaration), and would never apply the “same person” threshold the regulation defines.
- Raises:
Modelo347ThresholdError – for the first counterparty (in NIF first-appearance order) whose AGGREGATED annual total is at or below the threshold.
- Return type:
- Parameters:
rows (Sequence[Modelo347ContraparteRow])
effective_date (date)
Enforce that Modelo 184 member share percentages sum to exactly 100%.
Only checked when at least one miembro row is present (partial sets are skipped).
- Raises:
Modelo184ShareSumError – when the share percentages do not total exactly 100.
- Return type:
- Parameters:
rows (Sequence[Modelo184MemberRow])