Source code for cadrumo.application.modelo.settlement_casilla
"""Which casilla settles a modelo revision, read from the registry.A declaration's settled result is the number an operator scans a list for, andnaming it is a filing-grade claim: showing the wrong casilla as "the result"misreports what the taxpayer owes. So the answer comes from the registry's own`semantic_role` declaration and from nowhere else -- never from a casillanumber, a position, or a label that reads like a total.Coverage is deliberately narrow and will stay that way until each modelo'ssettlement chain is modelled. `SETTLEMENT_SEMANTIC_ROLES` holds the groundedterminal-liquidación roles, Modelo 100 today; modelo 303's casillas carrypositional roles such as `dr303_23` that name no meaning, so this resolverreturns nothing for them rather than guessing. A caller must render thatabsence as "not available", not as a blank or a zero."""from__future__importannotationsfromcollections.abcimportSequencefromtypingimportTYPE_CHECKING,Final,Protocolfrom...core.errors.hierarchyimportCadrumoErrorifTYPE_CHECKING:from...core.casilla_idimportCasillaIdSETTLEMENT_SEMANTIC_ROLES:Final=frozenset({"irpf_cuota_resultante_autoliquidacion","irpf_resultado_declaracion",})"""Terminal-liquidación `semantic_role` values, per settlement-bearing modelo.Grounded in the #39 settlement-completeness audit: Modelo 100 cuota resultantede la autoliquidación (casilla 0595, the liability before pagos a cuenta) andresultado de la declaración (0670).Modelo 100 today. Extend as further modelos' settlement chains are modelled --and only from the official record design for that modelo, because the wholepoint of reading a declared role is that nobody has to infer which cell is theresult. A modelo absent here yields no settlement casilla, which is a safefalse negative: the surface says it does not know rather than naming a cell onno authority."""DECLARATION_RESULT_SEMANTIC_ROLES:Final=frozenset({"irpf_resultado_declaracion"})"""The roles that name a declaration's FINAL result -- a strict subset of the above.Both settlement roles are terminal-liquidación cells, and both must be computedbefore filing, which is why the advisory watches the whole set. Only one ofthem is the number an operator means by "the result": Modelo 100 declares`irpf_cuota_resultante_autoliquidacion` (casilla 0595) for the liability BEFOREpagos a cuenta, and `irpf_resultado_declaracion` (0670) for what thedeclaration actually settles.Reading the registry is what surfaced this. A first version of this resolvermatched the full settlement set and would have raised ambiguity on M100 -- theonly modelo it covers -- because that revision legitimately declares both."""
[docs]classAmbiguousDeclarationResultError(CadrumoError):"""A revision declares more than one final-result casilla."""
[docs]classSettlementRevisionV1(Protocol):"""The revision surface :func:`declaration_result_casilla_id` reads. Structural rather than the whole :class:`ModeloRevision` because the reader consumes only an id and the casillas' roles. A revision declaring two result casillas is the defect this function refuses, and the shipped registry cannot express it, so the refusal is exercised through a value carrying just this surface. """@propertydefid(self)->str:...@propertydefcasillas(self)->Sequence[SettlementCasillaV1]:...
[docs]defdeclaration_result_casilla_id(revision:SettlementRevisionV1)->CasillaId|None:"""Return the casilla holding this revision's final result, or nothing. Returns `None` for a revision whose casillas declare no result role. That is the ordinary case today -- most modelos are not yet modelled to this depth -- and it is deliberately indistinguishable from "the registry has not said", because it IS that. A caller renders the absence as unknown, never as a blank or a zero. Raises: AmbiguousDeclarationResultError: Two or more casillas claim the result role. A declaration with two results has none, and picking the first would publish one of them as the answer on no grounds; the registry declaration is wrong and must be fixed rather than resolved here. """settling=[casilla.idforcasillainrevision.casillasifcasilla.semantic_roleisnotNoneandcasilla.semantic_roleinDECLARATION_RESULT_SEMANTIC_ROLES]ifnotsettling:returnNoneiflen(settling)>1:raiseAmbiguousDeclarationResultError(f"revision {revision.id!r} declares {len(settling)} final-result casillas "f"({', '.join(sorted(settling))}); a declaration cannot have two results")returnsettling[0]