Source code for cadrumo.application.aggregation._renta_business_eligibility
"""One business-eligibility predicate for both Renta expense projections.The Modelo 130 gasto pipeline and the annual Modelo 100 first-slice expensepipeline both decide whether a ledger row is a business expense and, if so, atwhat proportion. They decided it with two separate implementations thatdisagreed: M130 honoured an explicit ``actividad_economica`` IRPF category asfull business attribution, while M100 consulted the business classificationalone. A row carrying the activity marker but not yet swept by thebusiness-classification review was therefore accepted by the quarterly pagofraccionado and rejected by the annual declaration built from the same ledger.The divergence itself is legitimate: the quarterly pago fraccionado is aprovisional self-assessment, while the annual declaration is the filing-gradeone and may reasonably demand the review. What was wrong is that thedifference lived in two predicates that could drift independently, and thatthe annual refusal was reported as a generic "unclassified" state -- the samereason a row with no classification signal at all produces -- so the operatorcould not tell that the row WAS activity-marked and needed only review.This module is the one predicate. The annual gate is now a declared argumentof it, and :func:`relies_on_activity_marker` names the state the annualpipeline reports specifically."""from__future__importannotationsfromdecimalimportDecimalfrom...domain.transactions.enumsimportBusinessClassificationfrom...domain.transactions.irpf_categoriesimporthas_activity_irpf_categoryfrom...domain.transactions.modelsimportTransactionfrom.business_proportionimportbusiness_proportion__all__=["relies_on_activity_marker","renta_expense_business_proportion"]_FULL_BUSINESS_PROPORTION=Decimal("1")
[docs]defrelies_on_activity_marker(transaction:Transaction)->bool:"""Return whether eligibility rests only on the explicit actividad marker. True when the row carries the ``actividad_economica`` IRPF category but its business classification alone would not make it a business expense. This is exactly the state the two pipelines answer differently, so it is named once here rather than re-derived at each caller. A reviewed exclusion is never in this state: the operator's final disposition outranks the category tag, and callers short-circuit it before reaching this module. """iftransaction.business_classificationisBusinessClassification.REVIEWED_EXCLUDED:returnFalseifnothas_activity_irpf_category(transaction.irpf_category,direction=transaction.direction):returnFalsereturnbusiness_proportion(transaction.business_classification,transaction.business_pct)isNone
[docs]defrenta_expense_business_proportion(transaction:Transaction,*,accept_activity_marker:bool,)->Decimal|None:"""Return the business-attributed proportion of ``transaction``, or ``None``. Args: transaction: The ledger row under consideration. accept_activity_marker: Whether an explicit ``actividad_economica`` IRPF category alone establishes full business attribution. The Modelo 130 quarterly pago fraccionado passes ``True`` (provisional self-assessment); the annual Modelo 100 first-slice projection passes ``False`` (filing-grade, so it requires the business-classification review to have resolved the row). Returns: The proportion of the row attributable to the business, or ``None`` when the row is not an eligible business expense under the requested policy. """ifaccept_activity_markerandhas_activity_irpf_category(transaction.irpf_category,direction=transaction.direction,):return_FULL_BUSINESS_PROPORTIONreturnbusiness_proportion(transaction.business_classification,transaction.business_pct)