Source code for cadrumo.application.user_profile.usage_ratio_resolution
"""Resolve the usage ratios a deduction runs on, completing them from the censo.LIRPF art. 30.2.5.b, verbatim from the bundled consolidated corpus: b) En los casos en que el contribuyente afecte parcialmente su vivienda habitual al desarrollo de la actividad económica, los gastos de suministros de dicha vivienda, tales como agua, gas, electricidad, telefonía e Internet, en el porcentaje resultante de aplicar el 30 por ciento a la proporción existente entre los metros cuadrados de la vivienda destinados a la actividad respecto a su superficie total, salvo que se pruebe un porcentaje superior o inferior.The second factor is the taxpayer's own measurement, and the taxpayer has alreadydeclared it: ``vivienda_office.office_m2`` and ``vivienda_office.total_m2`` are censo036 facts on their profile. Until this module existed nothing carried that declarationinto the calculation. The ratio had to be typed a second time through``aeat app ledger ratios set``, and a filer who declared their m² and never did thatdeducted NOTHING on utilities -- silently, with no preflight reason for it, where thelaw gave them thirty per cent of their declared proportion.**Deriving here is not new policy.** The censo guard already refuses any storedhome-office ratio that is not exactly the censo-derived one, and a mismatch blockscalculation. So the stored value carries no information the censo does not alreadyhave, and filling an absent one from the censo produces precisely the number the guardwould have insisted on. What it changes is that the taxpayer no longer has to say thesame thing twice for the deduction to exist at all.**It is also not the defect that was just removed.** The retired ``default_ratio``was a REGISTRY constant standing in for a measurement the registry cannot know. Thisis the OPERATOR'S OWN declared measurement, read from the facts they filed. Thedistinction is the whole point: one invents the taxpayer's second factor, the otherreads it.A stored override still wins where one exists, so the escape clause the article endson ("salvo que se pruebe un porcentaje superior o inferior") keeps whatever room thecenso guard allows it -- today, none, which is recorded as an open finding rather thansettled here."""from__future__importannotationsfromdecimalimportDecimalfromtypingimportTYPE_CHECKINGfrom...domain.categories.spending_categoryimportSpendingCategoryfrom...domain.usage_ratios.serviceimportderive_home_office_ratios_from_censofrom..ledger.usage_ratio_repositoryimportUsageRatioProfileLoaderfrom.censo_syncimportbound_raw_afectacion_ratio_for_bucket,raw_afectacion_ratio_for_recordifTYPE_CHECKING:from...domain.calculations.registry.authorityimportPinnedAuthorityOperationfrom...domain.user_profile.valuesimportUserProfileRecord__all__=["resolve_effective_usage_ratios"]
[docs]defresolve_effective_usage_ratios(*,bucket_id:str,year:int,usage_ratio_profile_loader:UsageRatioProfileLoader,operation:PinnedAuthorityOperation,profile_record:UserProfileRecord|None=None,)->dict[SpendingCategory,Decimal]:"""Return the effective usage ratio per category for one bucket and filing year. Stored overrides are authoritative where they exist. Every home-office category the operator has NOT overridden is completed from the censo-declared afectación, when the profile carries the m² to compute it. Args: bucket_id: Profile bucket whose stored ratios and censo facts are read. year: Filing year whose proportionality rules supply the statutory factor (thirty per cent for suministros, none for the ownership costs, which take the raw area proportion under art. 29.2). usage_ratio_profile_loader: Required application-owned read capability for the persisted usage-ratio profile. operation: Generation-pinned authority for governed ratio vocabulary. profile_record: The bucket's profile record when the caller already loaded it; when omitted, the censo facts are read from the bucket. Returns: Category-to-effective-ratio mapping, ready for :class:`~domain.renta.ledger_expenses.RentaDeductibilityContext`. Empty when the operator has stored nothing and declared no dwelling m². Core types: :class:`~cadrumo.domain.user_profile.values.UserProfileRecord`. """stored=dict(usage_ratio_profile_loader(bucket_id=bucket_id,operation=operation).ratios)raw_afectacion_ratio=(bound_raw_afectacion_ratio_for_bucket(bucket_id,operation=operation)ifprofile_recordisNoneelseraw_afectacion_ratio_for_record(profile_record))ifraw_afectacion_ratioisNone:returnstoredderived=derive_home_office_ratios_from_censo(raw_afectacion_ratio,year=year,operation=operation,).ratios# Stored last: an operator override wins over the derivation, and the censo guard# separately holds the two to agreement, so this ordering never silently replaces# a deliberate value with a computed one.return{**derived,**stored}