cadrumo.application.modelo.profile_export_binding module¶
Profile-sourced values addressed on the exported declaration.
The export-shaped counterpart to the calculation-shaped resolution in
profile_binding. Both read the SAME fact index and the SAME
per-binding resolution – this module adds only the export-side shaping, so a
profile fact cannot mean one thing to the calculation engine and another to the
filed artefact. It is a family module, not a second authority: the fact index
and single-binding resolution stay owned next door and are imported, never
reimplemented.
Split out when profile_binding crossed its module size budget. The
calculation and export halves genuinely are two cohesive concerns over one
shared substrate, which is the split the budget forced and the shape the
per-family binding modules elsewhere in the tree already use.
- compose_legal_full_name(*, surnames, name)[source]¶
Compose a Spanish legal full name from its ordered parts.
AEAT writes an individual’s name surnames-first, and a blank part must not leave a doubled separator behind. This is the single home for that join: the export header path and the dictionary-field resolver below both write the operator’s name onto the same declaration, so two separate joins could disagree on one artefact.
- resolve_profile_export_values(bindings, *, bucket_id, operation, profile_record=None, schema=None)[source]¶
Resolve profile-sourced export values keyed by AEAT’s dictionary field id.
The export-shaped twin of
resolve_profile_sourced_bindings(): same owner, same fact index, same per-binding resolution, different output shape. The calculation side returns typed channels for the engine; this returns the values AEAT’s own dictionary field ids address, which is what the fichero-BOE writer consumes. Keeping both here is what stops a second profile-resolution authority appearing on the export path.Values stay their concrete
UserProfileFactValuetype. The renderer decides a row’s rendering from the Python type it receives, so pre-rendering tostrhere would destroy the distinction it needs.Deliberately does NOT call
_load_profile_facts, and deliberately takes noRegistrySnapshot. That loader adds the engine-derived facts (marriage months, guardería aggregates, mínimo descendientes, anualidades eligibility, state attribution) on top of the stored index. Measured against the real Modelo 100 2024 revision, ZERO of the 32 selectors named by export-addressed bindings is a derived path – every one is a stored fact (identity, spouse, taxpayer, tax residence, declaration type). The derived injectors therefore cannot change a single value this function reads, so requiring a snapshot would be threading an input that provably does not affect the answer. Re-measure before assuming otherwise; if a future revision does declare an export binding on a derived path, route this through the same loader rather than reproducing any part of it.A
repeatingbinding is skipped. Those name array paths (RentaFamilyProfile.ascendants.*/.descendants.*) that nothing in production writes – the real writer is therenta_family.descendienteOBJECT, which carries neitherdeath_datenordisplay_name– and the dictionary writer reuses a child element by tag, so N of them would overwrite one another rather than producing N rows. They are a known structural gap, pinned by test rather than reported at runtime: an advisory firing on every export for a gap no operator can act on is the alert fatigue that makes the real advisories worth ignoring.- Parameters:
bindings (
Sequence[BindingDefinition]) – The revision’s export-addressed profile bindings, as projected onto the schema subview byprofile_export_bindings.bucket_id (
str) – Active profile bucket whose persisted facts are read.operation (
PinnedAuthorityOperation) – Authority operation supplying the profile read and schema.profile_record (
object|None) – Pre-loaded profile record; loaded from the bucket when omitted.schema (
ProfileSchemaDefinition|None) – Pre-loaded profile schema; loaded when omitted.
- Return type:
- Returns:
Dictionary field id to typed value, omitting every binding that resolved to nothing or whose precondition was not met. An absent profile yields an empty mapping – the caller decides whether a missing slot is fatal, since the export layout is what declares a field required.
- resolve_export_identity(*, bucket_id, operation, profile_record=None, schema=None)[source]¶
Derive the presenter and taxpayer identity facts from the stored profile.
PresenterIdentitydeliberately offers no taxpayer-to-presenter fallback of its own, so somebody must decide who is presenting. This is that decision, made once: the operator whose profile is filing IS the presenter. Cadrumo exposes no representative or gestor identity – a filing prepared here belongs to the profile that prepared it – so deriving the presenter from anything else would invent an actor the product has no way to name. When a representative surface does land, it overrides here rather than being threaded through every export caller.The taxpayer facts are read as the four distinct official meanings the producer declares, never as interchangeable aliases. A natural person carries
given_nameandsurnamesand thefull_namecomposed from them throughcompose_legal_full_name(), so the surnames-first join stays the single authority it already is;legal_namestays absent because a natural person has none. Any other entity type carries its registered name as BOTHlegal_nameandfull_nameand nothing else, because an entity has no given name or surnames to split.- Return type:
- Returns:
The presenter/taxpayer pair, or
Nonewhen the profile is absent or declares no usable tax identity.Nonemeans “cannot answer”, and the export path’s own refusal states that far better than a half-built identity would.- Parameters:
bucket_id (str)
operation (PinnedAuthorityOperation)
profile_record (object | None)
schema (ProfileSchemaDefinition | None)
- resolve_declaration_contact(*, bucket_id, operation, profile_record=None, schema=None)[source]¶
Read the “persona con quien relacionarse” the informativa header declares.
Resolved separately from
resolve_export_identity()rather than folded into its tuple: this is a THIRD party in AEAT’s model, distinct from both the taxpayer and the presenter, and under a gestor it is routinely neither of them. Keeping it its own read also leaves both existing callers of the identity pair untouched.- Parameters:
bucket_id (
str) – Active profile bucket.operation (
PinnedAuthorityOperation) – Authority operation supplying the profile read and schema.profile_record (
object|None) – Already-loaded record, when the caller holds one.schema (
ProfileSchemaDefinition|None) – Already-loaded schema, when the caller holds one.
- Return type:
- Returns:
The declared contact. Absent halves stay absent – AEAT writes an unfilled alphanumeric header field to blancos, so a profile that declares no contact still produces a legal filing.