cadrumo.application.user_profile.completeness module

Conditional completeness rules for profile-level filing readiness.

PARTICIPE_CLAVE_BEARING_COUNTRY

The one clave whose Modelo 184 record carries a country at positions 79-80.

The other two claves – residente, and no residente CON establecimiento permanente – require BLANCOS there, so the country is not merely optional for them: the layout prohibits it. Both directions are enforced, because a rule that only asks for the value when it is due leaves the prohibited case to whatever the operator typed.

conditional_profile_required_paths(values)[source]

Return profile paths conditionally required by declared taxpayer facts.

Static schema-required fields are handled by the schema validator and the compiled application profile-key catalogue. This helper owns cross-field completeness: IRNR non-residents must declare their fiscal residence country, and non-EU/EEA IRNR residents must also declare both fiscal representative fields before any filing/modelo work can treat the profile as ready.

A profile declaring any Modelo IVA fact owes the rest of that block. The paths it owes are answered by the domain resolver that refuses without them rather than restated here, because restating them is precisely how the two authorities came apart: the resolver hard-required six facts that no readiness surface asked for, so config profile status reported a profile ready and pointed the operator at a command that refused it.

Return type:

tuple[str, ...]

Parameters:

values (Mapping[str, object])

conditional_profile_missing_required(values)[source]

Return conditionally required profile paths absent from values.

Return type:

tuple[str, ...]

Parameters:

values (Mapping[str, object])

atribucion_socio_missing_country_paths(values)[source]

Return socio country paths the clave requires but the profile omits.

Modelo 184 fills positions 79-80 of the declarado record only for clave 2, so a socio declared a non-resident without a permanent establishment owes a country and one declared under any other clave does not.

Return type:

tuple[str, ...]

Parameters:

values (Mapping[str, object])

atribucion_socio_forbidden_country_paths(values)[source]

Return socio country paths carrying a value the record layout prohibits.

The direction a conditional rule usually omits. Claves 1 and 3 require BLANCOS at positions 79-80, so a country stated under either is not a harmless extra fact: it is a value the layout forbids, and it was the shape a Spanish default produced on the majority case.

A row that declares no clave yet is not judged here. The clave is a required field and its own absence is reported as such; refusing the country as well would report one unfinished row twice and name the wrong field second.

Return type:

tuple[str, ...]

Parameters:

values (Mapping[str, object])

iva_regime_required(values)[source]

Return whether the profile needs an explicit IVA regime fact.

Legal entities and attribution entities keep the existing IVA-regime requirement. A natural-person profile only needs the IVA regime when it declares economic-activity income; a salaried-only, pensioner, or pure-landlord profile must not be forced into GENERAL just to pass profile persistence.

Return type:

bool

Parameters:

values (Mapping[str, object])

profile_value_is_present(value)[source]

Report whether value counts as a filled profile field.

The single presence rule every readiness surface reads. It existed in two incompatible spellings before: the conditional rules below stripped before deciding, as did the profile-key authority behind the CLI status gate, while the schema-required reader and the overview it feeds tested only != "". A required identity holding spaces was therefore complete to the surfaces that persist it and missing to the surface that refuses it – a readiness fork rather than a rendering difference, because the two answers govern different decisions.

Stripping is the direction that resolves it. A whitespace-only value survives no field-level parser in the system, so treating it as filled only defers the refusal to a later boundary that reports it as something other than an empty required field.

Return type:

bool

Parameters:

value (object)

missing_required_field_paths(schema, values)[source]

Report which schema-required field paths a value mapping leaves unsatisfied.

Presence is value-bearing, never fact-bearing, and is decided by the one shared profile_value_is_present() rule rather than restated here.

Return type:

tuple[str, ...]

Parameters:
profile_section_rows(section_key, present)[source]

Group a section’s populated paths by row, in the order a surface should show them.

Row identity is the index segment (socios.0.nif). A repeatable fact written WITHOUT an index is treated as a single implicit row keyed "" rather than ignored, because a producer currently writes one that way.

Shared rather than restated, because the surface that RENDERS a repeatable section and the check that decides which of its fields are missing must agree about how many rows there are and which one each fact belongs to. They did not: the display walked the unindexed path while rows live at section.INDEX.field, so a taxpayer’s socios, activities, properties and usage ratios were each shown as one permanently blank row however many the profile held.

Ordering is the implicit row first, then indices in numeric order, so a row’s position on screen follows its identity rather than the order facts happened to be written. Numeric rather than lexicographic, or row 10 would sort between rows 1 and 2.

Parameters:
  • section_key (str) – The section whose rows are wanted.

  • present (Iterable[str]) – Paths carrying a value, by the shared presence rule. A row whose every fact is blank is therefore not a row here — which is what keeps this reading identical for both callers.

Return type:

dict[str, frozenset[str]]

Returns:

Each row’s identity mapped to the field keys it populates.