aeat.application.ledger._ratios module¶
Operator-facing extensions for the aeat app ledger ratios verb-group.
The existing usage-ratio CRUD verbs (list/set/unset) live in
the application-layer ledger actions backed by the domain
usage_ratios module. This module adds two read-only verbs that
close the discoverability and pre-calculate readiness gaps:
eligibleenumerate categories that may carry a user ratio,annotated with their statutory default ratio
validateinspect the persisted profile against eligibility andbound rules; report missing categories per modelo
- class EligibleCategoryRow(**data)[source]¶
Bases:
BaseModelOne row in the
ratios eligiblelisting.default_ratiois None for eligible categories whose proportionality rule does not ship a statutory default; the operator must supply an override before the modelo pre-calculate readiness check passes.- Parameters:
category (SpendingCategory)
proportionality_kind (str)
default_ratio (Decimal | None)
override_present (bool)
- category: SpendingCategory¶
- proportionality_kind: str¶
- default_ratio: Decimal | None¶
- override_present: bool¶
- class RatiosValidationFinding(**data)[source]¶
Bases:
BaseModelOne issue raised by
ratios validatefor an eligible category.- Parameters:
category (SpendingCategory)
kind (str)
detail (str)
- category: SpendingCategory¶
- kind: str¶
- detail: str¶
- class RatiosValidationReport(**data)[source]¶
Bases:
BaseModelResult of
ratios validate. Read-only, emits no bucket event.- Parameters:
bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])
profile_present (bool)
eligible_count (int)
overrides_count (int)
missing_overrides (tuple[SpendingCategory, ...])
findings (tuple[RatiosValidationFinding, ...])
- bucket_id: BucketId¶
- profile_present: bool¶
- eligible_count: int¶
- overrides_count: int¶
- missing_overrides: tuple[SpendingCategory, ...]¶
- findings: tuple[RatiosValidationFinding, ...]¶
- eligible_ratio_categories(profile)[source]¶
Return all eligible categories with their default ratio + override flag.
The output is sorted by canonical category value so callers can diff snapshots without ordering noise. Each row is an
EligibleCategoryRow.- Return type:
- Parameters:
profile (UsageRatioProfile)
- validate_ratios_profile(*, bucket_id, profile, require_overrides_for=())[source]¶
Inspect a profile against eligibility and any required overrides.
require_overrides_foris the set of categories the caller needs explicitly populated (e.g. a modelo’s pre-calculate readiness check). Categories absent fromELIGIBLE_USAGE_RATIO_CATEGORIESraise anot_eligiblefinding rather than silently passing.Returns a
RatiosValidationReport.- Return type:
- Parameters:
bucket_id (str)
profile (UsageRatioProfile)
require_overrides_for (tuple[SpendingCategory, ...])
- list_eligible_ratios_for_bucket(*, bucket_id)[source]¶
Convenience: load the bucket’s profile and project the eligibility report.
Each element is an
EligibleCategoryRowdescribing one spending category’s eligibility and configured ratio.- Return type:
- Parameters:
bucket_id (str)
- validate_ratios_for_bucket(*, bucket_id, require_overrides_for=())[source]¶
Load the bucket’s profile, run validation, and return a
RatiosValidationReport.- Return type:
- Parameters:
bucket_id (str)
require_overrides_for (tuple[SpendingCategory, ...])
- set_usage_ratio(*, bucket_id, category, ratio)[source]¶
Set or replace one per-category usage-ratio override on the bucket.
Loads the bucket’s
UsageRatioProfile, applies the override through the domainwith_ratiovalidator, and persists the result. Returns the prior override value for the category (Nonewhen there was none) so the caller can emit a before/after audit event. Application command boundary for the CLIledger ratios setverb; the CLI no longer calls the domain load/save primitives directly.The load-modify-save runs under the per-bucket
aeat.domain.usage_ratios.usage_ratio_bucket_lock()so two concurrent writers cannot read the same snapshot and lose one another’s override.- Return type:
- Parameters:
bucket_id (str)
category (SpendingCategory)
ratio (Decimal)
- unset_usage_ratio(*, bucket_id, category)[source]¶
Clear one per-category usage-ratio override on the bucket.
Returns the cleared value. Raises
UsageRatioValidationErrorwhen the category carries no persisted override (so the caller can surface a precise “nothing to clear” message). Application command boundary for the CLIledger ratios unsetverb.The load-modify-save runs under the per-bucket
aeat.domain.usage_ratios.usage_ratio_bucket_lock()so a concurrentseton a sibling category cannot be lost by this clear.- Return type:
- Parameters:
bucket_id (str)
category (SpendingCategory)
- class RatiosCensoOverrideWarning(**data)[source]¶
Bases:
BaseModelA non-fatal warning that the operator’s per-category override deviates from the censo-derived value.
The censo is the binding legal source of truth for censo-derived ratios. Operators may still override (e.g. to model a planned afectación change), but the engine emits a typed warning so downstream auditors can review the divergence.
- Parameters:
category (SpendingCategory)
override_ratio (Decimal)
censo_derived_ratio (Decimal)
raw_afectacion_ratio (Decimal)
- category: SpendingCategory¶
- override_ratio: Decimal¶
- censo_derived_ratio: Decimal¶
- raw_afectacion_ratio: Decimal¶
- censo_business_pct_for(category, raw_afectacion_ratio, *, year=2025)[source]¶
Return the legally-effective business_pct for a category from censo.
The per-category projection of
aeat.domain.usage_ratios.derive_home_office_ratios_from_censo(): given a singleSpendingCategoryand the operator’s bound censooffice_m2 / total_m2, returns theraw_afectacion_ratio * statutory_multipliervalue the classify and allocate paths should stamp ontoTransaction.business_pctwhen no operator override is present. ReturnsNonefor categories outside the HOME_OFFICE families or when no censo has been applied yet, signalling to the caller that the operator’s explicit value (or the registry default) governs instead.- Return type:
- Parameters:
category (SpendingCategory)
raw_afectacion_ratio (Decimal | None)
year (int)
- censo_override_warning(*, category, override_ratio, raw_afectacion_ratio, year=2025)[source]¶
Return a typed warning when an override deviates from the censo.
The check is silent for non-HOME_OFFICE categories: only the suministros and ownership home-office families are legally bound to the censo-derived afectación ratio (LIRPF Art. 30.2 rule 5, Ley 6/2017 BOE-A-2017-12544). For HOME_OFFICE categories the helper computes the legally-effective ratio (raw afectación times the rule’s
statutory_multiplier) and compares it againstoverride_ratiofor exact equality. A non-equal pair returns aRatiosCensoOverrideWarning; equal values (and non-home-office categories) returnNone.- Parameters:
category (
SpendingCategory) – The category being overridden viaratios set.override_ratio (
Decimal) – The operator-supplied override.raw_afectacion_ratio (
Decimal) –office_m2 / total_m2from the bound censo snapshot.year (
int) – Registry year whose proportionality rule drives the derivation.
- Return type:
- Returns:
A
RatiosCensoOverrideWarningif a warning should be emitted, otherwiseNone.