cadrumo.application.ledger.source_jurisdiction module¶
Where a ledger row’s income is sourced, and when the operator must say so.
Two taxpayer conditions make the source jurisdiction an answer nobody may default. A non-resident taxed under IRNR is taxed on Spanish-source income alone, so which jurisdiction a row belongs to decides whether it is in scope at all. An impatriado under the special regime is taxed on Spanish-source income by the same logic, with foreign-source income segregated out of the base. For both, a row whose jurisdiction was assumed rather than stated is a row assigned to a base by accident.
Everyone else has a declared residency, and for them Spain is the ordinary
answer – but only once a residency HAS been declared. A profile that has
declared none resolves to None, which is the unresolved state rather than a
missing one: impatriado_income_ledger
segregates such a row with a typed unresolved-jurisdiction issue, on the stated
invariant that an unresolved jurisdiction “is NEVER silently coerced to ES”.
That invariant is why this is a decision and not a default. Coercing to ES
for an undeclared profile performed exactly the coercion the aggregation exists
to refuse, so the None never reached the layer built to handle it and
foreign-source income folded into the Spanish base. The stamp is persisted on
the transaction, so the mistake outlived the profile later being completed.
The rule lives here rather than at a command boundary because it is tax law about a taxpayer, not a fact about argv: it answers the same way whichever surface asks, and its consumer – the aggregation above – is in this layer too. What a surface still owns is how it ASKS and how it words a refusal, which is why this returns a typed outcome rather than raising a presentation error.
See also
impatriado_income_ledgerThe aggregation that segregates an unresolved jurisdiction rather than admitting it to the Spanish base.
- SPANISH_SOURCE_JURISDICTION¶
The jurisdiction a declared resident’s row is sourced in absent any other statement. Named rather than spelled inline so the default and the refusals that withhold it cannot drift apart.
- class SourceJurisdictionOutcome(*values)[source]¶
Bases:
StrEnumWhat the taxpayer’s conditions say about this row’s source jurisdiction.
Five members and not three, because the two refusals are different questions to put to an operator and the two answers have different provenance. Collapsing either pair would make a surface guess which it was holding.
- STATED¶
The operator stated it; no profile signal is consulted.
- DEFAULTED¶
A declared residency with no special regime; Spain by default.
- UNRESOLVED¶
No residency declared. NOT a missing answer, and never coerced to Spain.
- REQUIRED_NON_RESIDENT_IRNR¶
the operator must state it.
- Type:
Non-resident under IRNR
- REQUIRED_IMPATRIADO¶
the operator must state it.
- Type:
Impatriado special regime
- OUTCOMES_REQUIRING_AN_OPERATOR_STATEMENT¶
The outcomes that oblige the operator to state a jurisdiction.
Derived by subtraction rather than listed, so it cannot fall behind the enum: everything that neither produces a jurisdiction nor is the unresolved state is, by construction, a question somebody has to answer. A surface wording these refusals reads this rather than rebuilding it, which is also why it exists – learning the set by constructing a resolution per member is not possible, since the ones that carry a value refuse to be built without one.
- class SourceJurisdictionResolution(**data)[source]¶
Bases:
BaseModelOne resolution: what the conditions decided, and the value if there is one.
- Parameters:
data (Any)
- outcome: SourceJurisdictionOutcome¶
- jurisdiction: str | None¶
- resolve_source_jurisdiction(operator_value, *, fiscal_residency, irpf_special_regime)[source]¶
Decide this row’s source jurisdiction from the taxpayer’s conditions.
The order is the rule, not a style. An operator statement wins over every profile signal, because it is the more specific claim and the profile is only ever a default. The two refusals come next and the impatriado refusal is reachable for a taxpayer whose residency is undeclared, so it must be asked before the undeclared path – otherwise an impatriado with an incomplete profile would resolve to
UNRESOLVEDand never be asked the question the regime requires.- Parameters:
operator_value (
str|None) – The jurisdiction the operator stated, orNone.fiscal_residency (
FiscalResidency|None) – The profile’s declared residency, orNonewhen the profile has declared none.irpf_special_regime (
IrpfSpecialRegime|None) – The profile’s declared IRPF special regime, if any.
- Return type:
- Returns:
The resolution, carrying a jurisdiction only where the conditions produce one.