cadrumo.core.identity.tax_id module¶
Spanish tax-identifier validation (NIF / NIE / CIF) returning canonical strings.
The Agencia Tributaria’s identifier algorithm is shared infrastructure
across multiple subpackages — invoice counterparty checks, encrypted
master-key NIF canaries, sanitiser fixture validation, and CLI preflight
gates. Co-locating the algorithm in core.identity gives
every caller a public, layer-respecting import path.
This module differs from core.identity.documents only in its return
shape: validate_spanish_tax_id() yields the normalised identifier string,
while validate_identity() returns the matching
IdentityDocument enum member. The shape is the ONLY
difference – there is one implementation of the AEAT algorithm and one CIF
leader policy, both in core.identity.documents, and this function
delegates to them rather than restating them. It once did restate them, and the
two copies drifted into disagreeing about whether an ABEH CIF may carry a
letter control; two validators answering one question differently is not a
laxer reading, it is a defect with a second opinion.
Both surfaces raise IdentityError; the shared NIF/NIE
checksum table is defined by core.identity.documents.
- tax_id_identity_token(value)[source]¶
Return the canonical identity form of a tax identifier, without a checksum claim.
The one comparison form for tax identifiers whose bearer is not guaranteed to be Spanish – a non-resident counterparty may carry a foreign identifier, so
validate_spanish_tax_id()’s checksum gate would refuse a legitimately declared row. This function answers only “are these two identifiers the same identifier”, which is what grouping keys, distinct counts, and storage object keys need.Normalisation is trim-and-uppercase and nothing more: it is idempotent, so a value already in canonical form is returned unchanged, and it never silently merges two identifiers that differ in their characters.
Applying it at the model boundary AND at the storage key is the point: when an aggregator groups by the raw value while the repository keys by a normalised one, two canonically-equal identifiers become two rollups but one stored row, so the declared distinct count and the persisted evidence disagree.
- same_tax_identifier(left, right)[source]¶
Return whether two declared identifiers name the same bearer.
The one “is this the same identifier” predicate. It asserts no checksum, which is the whole point: the question is identity, not validity, so a foreign identifier, or a Spanish one whose control character does not check out, must still be comparable. A comparison routed through
validate_spanish_tax_id()answersFalsefor both of those by returning nothing to compare, which reads as “different bearer” when the truth is “unverifiable identifier”.Comparison is on the separator-stripped form (
normalise_nif_iva()), so a printedB-1234567-4matches a storedB12345674. That is deliberately looser thantax_id_identity_token(), which stays trim-and-uppercase because it keys stored objects and must never merge two characters-differ identifiers into one row; this predicate keys nothing.- Parameters:
- Return type:
- Returns:
Trueonly when both sides carry a non-blank value and those values are the same identifier. An absent or blank side answersFalse: absence is not a match, and this predicate must never turn “nothing to compare” into “the same”.
- validate_spanish_tax_id(value, tax_id_format)[source]¶
Validate a Spanish NIF, NIE, or CIF and return its canonical form.
- Parameters:
value (
str) – Raw tax identifier to validate.tax_id_format (
SpanishTaxIdFormat) – Complete authority-supplied format declarations.
- Return type:
- Returns:
The identifier in the package’s separator-stripped normal form –
normalise_nif_iva(), the same formsame_tax_identifier()compares on, so a printedB-1234567-4and a storedB12345674validate to one string rather than two.- Raises:
IdentityError – If the identifier is malformed or the checksum fails.
- TaxIdIdentityToken¶