cadrumo.application.aggregation.invoice_devengo module

LIVA art. 75 devengo resolution and period attribution for one invoice record.

Art. 75.Uno binds the general regime to the operation date – when the entrega or prestación actually took place – not to the bank movement or the invoice’s issue date. Art. 75.Dos moves devengo forward to the date of collection for a pago anticipado, “por los importes efectivamente percibidos”, except for the entregas comprendidas en el artículo 25 (an entrega intracomunitaria exenta, which always devengues under art. 75.Uno.8.º regardless of any advance received).

Invoice already carries both cases behind one field: operation_date records the date, and operation_date_role records which of art. 75’s two clauses it answers. The art. 25 exclusion and the “money was actually received” precondition are enforced at construction time on the invoice itself, so a record carrying an ADVANCE_PAYMENT_RECEIVED role that reaches this module is already a legally consistent one; this module supplies nothing beyond reading the fact the invoice already declares and, where the invoice declares nothing, saying so out loud.

That last part is why the resolution is a record and not a date. Not every invoice carries a recorded operation date, so a fallback exists, and a fallback that returns a bare date collapses two structurally different answers – a declared legal fact and a substitute for one – into one indistinguishable return. The issue date is a substitute that agrees with the fact for every operation invoiced inside its own period and diverges exactly at the month and quarter boundaries where attribution changes, so the difference is the whole point. InvoiceDevengoRank carries it.

invoice_devengo_in_period() is the single period-attribution predicate for the invoice catalogue. Every aggregation path that asks “does this invoice belong to this filing period” calls it rather than comparing a date of its own choosing, so the calculate path and the Sheets pull path cannot answer the question differently: there is one implementation and both consume it.

A staged schedule of several partial advance payments, each devengoing separately for its own amount, is not representable by a single date and is not attempted here.

See also

cadrumo.domain.invoices.models.Invoice.operation_date

The recorded devengo-relevant date this module reads.

cadrumo.domain.invoices.models.Invoice.operation_date_role

The discriminator naming which art. 75 clause the date answers.

cadrumo.core.aggregation.InvoiceDevengoRank

The marker naming which source produced the resolved date.

cadrumo.domain.transactions.dates.transaction_eligible_date_span()

The equivalent ledger-transaction-side devengo span, already wired into IVA period attribution.

class InvoiceDevengo(**data)[source]

Bases: BaseModel

The date one invoice files under, and where that date came from.

The two fields are read together or not at all. A consumer that takes devengo_date while ignoring rank has re-created the bare return this record exists to replace, and will treat a proxy as a declared fact at exactly the boundary where the two disagree.

Variables:
  • devengo_date – The resolved LIVA art. 75 devengo date.

  • rank – Which source produced it.

Parameters:

data (Any)

devengo_date: date
rank: InvoiceDevengoRank
resolve_invoice_devengo(invoice)[source]

Return the LIVA art. 75 devengo date for one invoice, with its rank.

Parameters:

invoice (Invoice) – The invoice whose devengo date is being resolved.

Return type:

InvoiceDevengo

Returns:

The recorded operation_date ranked OPERATION_DATE_DECLARED when the invoice carries one – either art. 75.Uno’s operation date or art. 75.Dos’s collection date, both read identically here because the role says WHICH clause supplied the date, not how it is used – otherwise issued_at ranked ISSUE_DATE_PROXY.

invoice_devengo_in_period(invoice, *, period)[source]

Return whether invoice devengues inside period.

The single period-attribution predicate for the invoice catalogue. It selects on the art. 75 devengo date rather than on the issue date, so an operation performed in one quarter and invoiced in the next is declared in the quarter it was performed.

Parameters:
  • invoice (Invoice) – The invoice being attributed.

  • period (Period) – The filing period, which must carry a calendar span.

Return type:

bool

Returns:

Whether the resolved devengo date falls inside the period’s inclusive span.

proxy_attributed_invoice_ids(invoices)[source]

Return the sorted ids of invoices attributed on the issue-date proxy.

The reporting half of the rank. An aggregation path hands it the invoices it actually folded in, and a non-empty result names the records whose period placement rests on a substitute rather than on a recorded devengo date – the set an operator has to see before filing, because those are the records that would move quarter if the real date were recorded.

Parameters:

invoices (Iterable[Invoice]) – The invoices a period’s figures were built from.

Return type:

tuple[str, ...]

Returns:

The sorted invoice ids ranked ISSUE_DATE_PROXY, empty when every contributing invoice declared its own devengo date.

devengo_proxy_attribution_diagnostics(invoices, *, source_kind, resolver_id)[source]

Return the non-blocking advisory for a period built on proxy-ranked invoices.

One shared builder rather than a per-resolver message, so every aggregation path that folds in invoices discloses the substitution in the same words. A path that phrased it for itself would let the same taxpayer see the same condition described two ways depending on which modelo they were filing.

Non-blocking by design. The issue date is the best available attribution and refusing on it would make an ordinary catalogue unfileable; what the operator needs is to know the period placement is a substitution before they file, which is what the advisory says.

Parameters:
  • invoices (Iterable[Invoice]) – The invoices this period’s figures were built from.

  • source_kind (str) – The binding source kind the calling resolver owns.

  • resolver_id (str) – The calling resolver’s id.

Return type:

tuple[CalculationSourceDiagnostic, ...]

Returns:

One advisory naming the proxy-attributed records, or an empty tuple when every contributing invoice declared its own devengo date.