cadrumo.domain.calculations.registry.rate_box_partition module¶
Rate-box partitions: the two-layer shape a rate-keyed official box requires.
A casilla cannot both feed a computed total and be exported to a rate-specific
AEAT box. The two roles want opposite bindings: rate-BLIND to keep every row in
the total, rate-SPECIFIC to keep the box truthful. The registry expresses the
split as two layers over one selector shape – a rate-blind binding whose
casilla carries no export_refs (the total layer) and its rate-specific
siblings whose casillas do (the box layer).
This module derives those layers from the revision alone, so no consumer has to
name a modelo’s casillas to find them. A ledger-IVA binding’s selector is a set
of axes plus an optional applied_rates narrowing; two bindings that agree on
every other axis and disagree only there are the same quantity read twice, once
whole and once per rate. That agreement is the partition key.
Why the layers can disagree, and why the difference is not an error to hide¶
An observation whose applied_rate is unknown matches the blind binding and
no rate-specific one, deliberately: admitting it would place an unmeasured line
in a box asserting a rate the operator never stated. So the box layer sums to
LESS than the total layer by exactly the amount whose rate was never recorded,
and that difference is a fact about the taxpayer’s ledger rather than a defect
in the calculation.
rate_box_coverage_shortfalls() is the single arithmetic both gates read:
the calculate path raises it as a non-blocking advisory (the operator needs the
number in order to repair the ledger) and the export path refuses on it (a
return whose rate boxes do not account for its declared total is what a human
files, with nothing behind it). Two copies of this subtraction is how the two
gates would come to disagree about the same return, so there is one.
See also
domain.calculations.registry.ledger_iva_bindingsOwns the
applied_ratesselector axis and the deliberate no-match-on-unknown-rate rule this module measures the consequence of.
- class RateBoxPartition(**data)[source]¶
Bases:
RegistryModelOne rate-blind total casilla and the rate-specific casillas breaking it down.
- Parameters:
data (Any)
- total_casilla_id: CasillaId¶
catches every row, including rows with no recorded rate.
- Type:
The rate-blind layer
- box_casilla_ids: tuple[CasillaId, ...]¶
The rate-specific layer, in canonical id order. Each admits exactly the rates its binding declares, so their sum omits every row whose rate is unknown.
- rate_kinds: tuple[str, ...]¶
The semantic tier(s) both layers share, named so an advisory can say WHICH tier holds the unaccounted money rather than only how much.
- fact: str¶
The quantity being partitioned (
iva_amount_sum/base_amount_sum/recargo_amount_sum). Two layers over different facts are different partitions and never share one.
- class RateBoxShortfall(**data)[source]¶
Bases:
RegistryModelA partition whose rate boxes account for less than its rate-blind total.
- Parameters:
data (Any)
- partition: RateBoxPartition¶
- total: Decimal¶
- boxes_total: Decimal¶
- shortfall: Decimal¶
total - boxes_total, strictly positive. The amount sitting in the return that no official rate box accounts for.
- derive_rate_box_partitions(revision)[source]¶
Return every two-layer rate partition the revision declares.
A partition is recognised when the revision’s ledger-IVA bindings contain, for one selector identity, exactly one rate-blind binding (
applied_ratesunset) and at least one rate-specific sibling, each resolving to a declared casilla, where the blind casilla carries NOexport_refsand at least one box casilla does.Each condition removes a way this derivation could otherwise ground a refusal on a filing that is not wrong:
The blind casilla must not export. A casilla that both totals and exports is the un-split shape the two-layer design repairs; it writes its own rate assertion to the record, so reading its siblings as the box layer would measure a coverage gap the artefact does not have.
At least one box casilla must export. Rate-specific casillas reaching no official record assert no rate, so a difference between them and the total is internal bookkeeping, not something a filed artefact gets wrong.
Exactly one blind binding. Two rate-blind siblings mean the selector identity is not the partition axis it is being read as, and the arithmetic downstream would silently pick one of them.
Rate-specific siblings carrying no
export_refsstill count toward the box sum. They are not boxes, but they are money accounted for, and dropping them would overstate the shortfall.Warning
Do not make a gate over rate-asserting casillas consume this function. The convergence looks obviously correct from outside — this is the canonical owner of the rate-box concept — and it silently narrows the gate’s population. What comes back here is only casillas belonging to a FORMED partition, so a rate-pinned casilla whose group formed none is absent by construction. That group is exactly where the severe defect lives: every binding pins a rate, no blind sibling remains, and a row whose rate was never recorded reaches no casilla at all. A gate rebuilt on this output would stop seeing precisely the case it exists for.
rate_box_coverage_shortfalls()returns that residue and is the correct thing to consume when the question is “what was never checked”.- Parameters:
revision (
ModeloRevision) – TheModeloRevisionwhose bindings and casillas are read.- Return type:
- Returns:
Partitions in canonical total-casilla order; empty when the revision declares no rate-specific ledger-IVA binding at all.
- rate_box_coverage_shortfalls(partitions, values)[source]¶
Return the partitions whose rate boxes account for less than their total.
An absent casilla reads as zero, the same reading the export renderer gives it: a casilla the calculation did not populate contributes nothing to the record either.
Only a strictly positive difference is returned. An equal box sum is the healthy state, and a box sum EXCEEDING the total is a different defect (rate boxes whose declared rates overlap, so one row lands in two) that this function deliberately does not claim to detect – reporting it here as a coverage shortfall would name the wrong condition and point the operator at a ledger repair that would not fix it.
- Return type:
- Parameters:
partitions (Sequence[RateBoxPartition])