aeat.adapters.outbound.aeat.sede._censo module

Sede G313 (Mis Datos Censales) read-only censo adapter — data layer.

Owns the strict pydantic envelope (CensoFactSet) and the pure HTML parser (parse_g313_html()) that lift the AEAT G313 result page into a typed boundary value. The live Playwright driver, the raw- HTML persistence path, and the domain.user_profile._values.UserProfileFact provenance wiring are separate concerns that compose with this module; nothing in here performs I/O.

The fact-set covers every field on the G313 (Mis Datos Censales) projection:

  • fiscal address: cadastral reference + habitual-vivienda flag

  • censo section: activity start / end dates, establecimiento type, elected withholding pct (LIRPF Art. 101.5 + RIRPF Art. 95.1/95.2)

  • vivienda_office: total / office m² (LIRPF Art. 30.2 rule 5)

  • activities: IAE epigraph

Every field is optional at the envelope level because G313 returns a sparse projection: a brand-new alta may not have a habitual-vivienda flag yet, an operator who never deducted suministros has no vivienda_office row, etc. The CensoSyncService layer above is where “missing-when-required” is adjudicated, not here.

class CensoFactSet(**data)[source]

Bases: BaseModel

Typed projection of one G313 (Mis Datos Censales) page read.

Every field is optional because G313 returns whatever subset of the censo the operator’s NIF actually has registered. The CensoSyncService layer above is responsible for refusing a partial capture that contradicts a required calculation; the adapter never fabricates a default to fill a hole.

Parameters:
  • fiscal_address_cadastral_reference (str | None)

  • fiscal_address_is_habitual_vivienda (bool | None)

  • activity_start_date (date | None)

  • activity_end_date (date | None)

  • establecimiento_type (str | None)

  • elected_withholding_pct (str | None)

  • vivienda_office_total_m2 (Decimal | None)

  • vivienda_office_office_m2 (Decimal | None)

  • iae_epigraph (str | None)

fiscal_address_cadastral_reference: str | None
fiscal_address_is_habitual_vivienda: bool | None
activity_start_date: date | None
activity_end_date: date | None
establecimiento_type: str | None
elected_withholding_pct: str | None
vivienda_office_total_m2: Decimal | None
vivienda_office_office_m2: Decimal | None
iae_epigraph: str | None
exception CensoParseError(message, *, field, raw)[source]

Bases: SedeError

Raised when a value on the G313 page does not parse against the schema.

Parameters:
Return type:

None

code: ClassVar[ErrorCode]
parse_g313_html(html)[source]

Parse a G313 (Mis Datos Censales) result page into a CensoFactSet.

The parser is deliberately label-driven rather than DOM-structural: AEAT re-shapes the surrounding ZK markup periodically without changing the Spanish field labels, so anchoring on labels gives the longest-lived contract. Each label maps to one field; missing labels yield None on the corresponding attribute.

Raises CensoParseError when a label is present but its value does not parse against the field schema — that is a shape change and must surface to the operator rather than silently drop the value.

Return type:

CensoFactSet

Parameters:

html (str)