Source code for aeat.domain.contribuyente._marriage_facts
"""Helpers for persisting and reloading marriage_date as profile facts.``marriage_date`` is stored as a single profile fact under``renta_taxpayer.marriage_date``. Three derived integer facts arestored alongside it so the registry binding resolver can look them upby a simple ``profile_key`` selector without a date-channel binding: renta_taxpayer.marriage_date ISO-8601 date string renta_taxpayer.marriage_month_start month int (1-12) when year == filing_year renta_taxpayer.marriage_month_end 12 (always, when married) renta_taxpayer.marriage_full_year 1 when date.year < filing_year, else 0When ``marital_status != 2`` (CASADO) no marriage_date is stored.The derived fact paths exposed here are consumed by registry bindings: renta-20XX-profile-marriage-month-start → casilla 0246 renta-20XX-profile-marriage-month-end → casilla 0247 renta-20XX-profile-marriage-full-year → casilla 0245"""from__future__importannotationsimportrefromdatetimeimportdatefrom...core.errorsimportProfileAnswerTypeErrorfrom...core.parsingimportparse_iso8601_dateas_parse_iso8601_date_MARRIAGE_DATE_PATH="renta_taxpayer.marriage_date"_MONTH_START_PATH="renta_taxpayer.marriage_month_start"_MONTH_END_PATH="renta_taxpayer.marriage_month_end"_FULL_YEAR_PATH="renta_taxpayer.marriage_full_year"
[docs]defmarriage_full_year(marriage_date:date,filing_year:int)->bool:"""True when the marriage predates the filing year (vigente todo el año)."""returnmarriage_date.year<filing_year
[docs]defmarriage_month_start(marriage_date:date,filing_year:int)->int|None:"""Return the first month married in *filing_year*, or None when full-year. When the marriage occurred *before* the filing year the form's casilla 0246 is left at 1 (the standard primer-mes for a full-year marriage). When the marriage occurred *during* the filing year the actual month is returned. When the marriage occurred *after* the filing year (future date) None is returned and no fact is written. """ifmarriage_date.year<filing_year:return1ifmarriage_date.year==filing_year:returnmarriage_date.monthreturnNone
[docs]defmarriage_derived_facts(marriage_date:date,filing_year:int,)->list[tuple[str,str]]:"""Return ``(path, canonical-value-string)`` pairs for all marriage facts. The caller converts these to :class:`domain.user_profile.UserProfileFact` records. All four facts are always emitted when a marriage_date is present; downstream binding resolution ignores facts that no formula consumes. """facts:list[tuple[str,str]]=[(_MARRIAGE_DATE_PATH,marriage_date.isoformat()),]full_year=marriage_full_year(marriage_date,filing_year)month_start=marriage_month_start(marriage_date,filing_year)ifmonth_startisnotNone:facts.append((_FULL_YEAR_PATH,"1"iffull_yearelse"0"))facts.append((_MONTH_START_PATH,str(month_start)))facts.append((_MONTH_END_PATH,"12"))returnfacts
[docs]defmarriage_date_from_facts(facts:dict[str,str])->date|None:"""Reconstruct the marriage date from a flat profile-fact dict. Returns None when ``renta_taxpayer.marriage_date`` is absent. """raw=facts.get(_MARRIAGE_DATE_PATH)ifnotraw:returnNonereturn_parse_iso8601_date(raw)
[docs]defparse_marriage_date_flag(raw:str)->date:"""Parse a ``--taxpayer-marriage-date YYYY-MM-DD`` flag value. Returns a validated :class:`datetime.date`. Raises ``ValueError`` on invalid ISO-8601 format. """stripped=raw.strip()try:result=_parse_iso8601_date(stripped)exceptValueErrorasexc:raiseProfileAnswerTypeError(f"--taxpayer-marriage-date must be YYYY-MM-DD; got: {raw!r}")fromexcifresultisNone:raiseProfileAnswerTypeError(f"--taxpayer-marriage-date must be YYYY-MM-DD; got: {raw!r}")returnresult