cadrumo.application.invoices.simplificada_advisory module

Whether a factura simplificada needs the destinatario’s NIF, and when we cannot tell.

RD 1619/2012 art. 6.1.d case 3.º asks for the destinatario’s NIF on a domestic factura simplificada whose issuer is established in the TAI. Deciding that takes the invoice AND the issuing taxpayer’s profile, so a surface must resolve the profile before it can say anything at all — and the resolution can fail.

The failure is the reason this module exists. The rule was evaluated inside one CLI notice builder that returned an empty list for five different situations: a tax id already present, the predicate answering no, no active bucket, no stored profile, and a profile that would not read. Four of those mean “nothing to advise” and one means “we do not know” — and collapsing them made an operator whose profile store is degraded indistinguishable from one whose invoice is fine. They lose a real legal advisory and are never told the check did not run.

So the states stay distinct here, and a surface decides what to do with each. Saying nothing on SimplificadaTaxIdAdvisory.ISSUER_UNKNOWN remains correct for a notice channel — an advisory whose premise could not be evaluated must not be asserted — but that is now the caller’s decision rather than a distinction the answer had already thrown away.

The legality itself is not restated here. Case 3.º has one authority, simplificada_requires_tax_id_for_domestic_issuer(), and this module resolves the inputs that predicate needs and reports what it answered.

class SimplificadaTaxIdAdvisory(*values)[source]

Bases: StrEnum

What case 3.º has to say about one invoice.

Four answers rather than a boolean, because “no advisory” and “no answer” are different facts about the same invoice and only one of them is good news.

REQUIRED

a domestic ISSUED simplificada with no tax id, from a TAI-established issuer. Advisory weight — never a refusal.

Type:

Case 3.º applies

NOT_REQUIRED

The predicate was evaluated against a resolved profile and answered no.

ALREADY_IDENTIFIED

The invoice already carries a counterparty tax id, so case 3.º has nothing further to ask for and no profile read is needed.

ISSUER_UNKNOWN

The issuing taxpayer could not be resolved — no active bucket, no stored profile, or a profile that would not read — so the establishment half of case 3.º is unknown and the rule was NOT evaluated.

Return the legal references carried by the simplified-invoice fact.

The advisory predicate and the invoice model both consume the dated invoice-simplificada-counterparty-tax-id-applicability mapping. Keep the notice provenance on that same resolved fact instead of repeating one of its legal-reference values in an entrypoint.

Return type:

tuple[str, ...]

Returns:

The fact’s ordered legal-reference identifiers.

Raises:

RegistryValidationError – If the fact does not resolve as a mapping or carries no provenance.

Parameters:

operation (PinnedAuthorityOperation | None)

resolve_simplificada_tax_id_advisory(*, invoice, profile_resolver=None)[source]

Answer case 3.º for invoice, or report that the issuer is unknown.

The tax-id check runs before the profile is resolved. An invoice that already identifies its destinatario satisfies case 3.º whoever issued it, so reading the profile first would turn an answerable invoice into ISSUER_UNKNOWN on a degraded profile store for no reason.

Parameters:
  • invoice (Invoice) – The invoice to evaluate.

  • profile_resolver (Callable[[], TaxpayerProfile | None] | None) – Resolves the issuing taxpayer’s profile, returning None when it cannot be read. Defaults to the active bucket’s.

Return type:

SimplificadaTaxIdAdvisory

Returns:

The advisory state. Only SimplificadaTaxIdAdvisory.REQUIRED is something to tell the operator; SimplificadaTaxIdAdvisory.ISSUER_UNKNOWN says the rule did not run, which is not the same as it passing.

Core types: TaxpayerProfile.