Source code for aeat.application.modelo._ledger_evidence_gate
"""Filing-grade ledger evidence gates for modelo lifecycle finish lines.These helpers inspect the :class:`CalculationRevision` evidence bundle beforeverification, export, or local filing lets deductible input IVA proceed."""from__future__importannotationsfromdecimalimportDecimalfromenumimportStrEnumfrom...domain.ivaimport(CUOTA_LESS_M303_IVA_CATEGORIES,InvoiceKind,IvaCategory,IvaFlowDirection,derive_flow_for_classification,is_deducible_flow,)from...domain.modelosimportCalculationRevision,LedgerEvidenceRow,ModeloErrorfrom...domain.transactionsimport(BusinessClassification,TransactionDirection,TransactionLifecycleState,)_EVIDENCE_EXEMPT_IVA_CATEGORIES:frozenset[IvaCategory]=CUOTA_LESS_M303_IVA_CATEGORIES|frozenset({IvaCategory.RECARGO_EQUIVALENCIA,IvaCategory.ERRONEOUS_INVOICE,IvaCategory.UNKNOWN,},)_EVIDENCE_EXPECTING_BUSINESS_STATES:frozenset[BusinessClassification]=frozenset({BusinessClassification.BUSINESS,BusinessClassification.MIXED,},)def_enum_or_none[EnumT:StrEnum](enum_type:type[EnumT],value:str|None)->EnumT|None:ifvalueisNone:returnNonetry:returnenum_type(value)exceptValueError:returnNonedef_row_has_linked_evidence(row:LedgerEvidenceRow)->bool:returnbool(row.purchase_invoice_evidence_id)orbool(row.attachment_ids)def_invoice_kind_for(direction:TransactionDirection|None)->InvoiceKind|None:ifdirectionisTransactionDirection.INCOMING:returnInvoiceKind.ISSUEDifdirectionisTransactionDirection.OUTGOING:returnInvoiceKind.RECEIVEDreturnNonedef_row_flow(row:LedgerEvidenceRow)->IvaFlowDirection|None:direction=_enum_or_none(TransactionDirection,row.direction)invoice_kind=_invoice_kind_for(direction)ifinvoice_kindisNone:returnNonecategory=_enum_or_none(IvaCategory,row.iva_category)ifcategoryisNone:returnIvaFlowDirection.REPERCUTIDOifinvoice_kindisInvoiceKind.ISSUEDelseIvaFlowDirection.SOPORTADOifcategoryin_EVIDENCE_EXEMPT_IVA_CATEGORIES:returnNonereturnderive_flow_for_classification(category=category,invoice_direction=invoice_kind,)
[docs]defledger_evidence_row_missing_deductible_vat_evidence(row:LedgerEvidenceRow)->bool:"""Return whether an evidence row claims deductible IVA without linked proof."""lifecycle_state=_enum_or_none(TransactionLifecycleState,row.lifecycle_state)iflifecycle_stateisnotTransactionLifecycleState.ACTIVE:returnFalsebusiness_classification=_enum_or_none(BusinessClassification,row.business_classification)ifbusiness_classificationnotin_EVIDENCE_EXPECTING_BUSINESS_STATES:returnFalseifrow.iva_amountisNoneorrow.iva_amount<=Decimal("0"):returnFalseif_row_has_linked_evidence(row):returnFalseflow=_row_flow(row)returnflowisnotNoneandis_deducible_flow(flow)
[docs]defdeductible_vat_evidence_gap_transaction_ids(revision:CalculationRevision)->tuple[str,...]:"""Return ledger transaction ids whose bundled evidence cannot support deduction. Args: revision: :class:`CalculationRevision` carrying the ledger filing evidence rows to inspect. """evidence=revision.ledger_filing_evidenceifevidenceisNone:return()returntuple(sorted(row.transaction_idforrowinevidence.rowsifledger_evidence_row_missing_deductible_vat_evidence(row)),)
[docs]defraise_if_deductible_vat_evidence_missing(revision:CalculationRevision,*,error_type:type[ModeloError],surface:str,suggestion:str,)->None:"""Raise ``error_type`` when a finalized revision has unsupported input IVA. Args: revision: :class:`CalculationRevision` whose bundled ledger evidence is checked before the lifecycle finish line. error_type: Modelo error class raised when deductible IVA lacks evidence. surface: Human-readable lifecycle surface used in the refusal message. suggestion: Operator command or action hint attached to the refusal. """transaction_ids=deductible_vat_evidence_gap_transaction_ids(revision)ifnottransaction_ids:returnraiseerror_type(f"deductible VAT rows require linked purchase invoice evidence before {surface}",translated_message="application.modelo.errors.deductible_vat_evidence_missing",context={"calculation_revision_id":revision.calculation_revision_id,"transaction_ids":list(transaction_ids),"reason":"deductible_vat_evidence_missing",},suggestion=suggestion,)