Skip to content

Implement PEPPOL identifier format validations (PEPPOL-COMMON-R*) #35

@fank

Description

@fank

Summary

Implement PEPPOL common identifier format validation rules (PEPPOL-COMMON-R040 through R050).

Background

PEPPOL defines common validation rules for identifier formats across multiple countries. These rules validate organization numbers, GLNs, tax codes, and other business identifiers according to country-specific formats and check digit algorithms.

PR #32 added the rule definitions but not the validation logic.

Rules to Implement

PEPPOL-COMMON-R040: GLN validation

  • Validate GLN (Global Location Number) format
  • Implement GS1 check digit algorithm
  • 13-digit format validation

PEPPOL-COMMON-R041: Norwegian organization number

  • Format: 9 digits
  • Implement modulus 11 check digit validation

PEPPOL-COMMON-R042: Danish CVR (Central Business Register)

  • Format: 8 digits
  • Implement modulus 11 validation with weights (2,7,6,5,4,3,2,1)

PEPPOL-COMMON-R043: Belgian enterprise number

  • Format: 10 digits (0 followed by 9 digits)
  • Implement modulus 97 check digit (BE 0XXX.XXX.XXX format)

PEPPOL-COMMON-R044: Italian IPA Code (Codice Univoco)

  • Format: 6 alphanumeric characters
  • Character set: A-Z, a-z, 0-9

PEPPOL-COMMON-R045 & R046: Italian Tax Code (Codice Fiscale)

  • Format: 16 alphanumeric for individuals or 11 numeric for companies
  • Complex validation with check digit

PEPPOL-COMMON-R047 & R048: Italian VAT Code (Partita IVA)

  • Format: 11 digits
  • Check digit validation

PEPPOL-COMMON-R049: Swedish organization number

  • Format: 10 digits (NNNNNNNNNN or NNNNNN-NNNN)
  • Implement Luhn algorithm check digit

PEPPOL-COMMON-R050: Australian Business Number (ABN)

  • Format: 11 digits
  • Implement ABN check digit algorithm

Implementation

The schematron file already includes helper functions for some validations:

  • u:gln() - GLN validation with GS1 algorithm
  • u:mod11() - Modulus 11 check digit
  • u:mod97-0208() - Belgian modulus 97 check
  • u:checkCodiceIPA() - Italian IPA code check
  • u:checkCF() - Italian Tax Code check

Need to:

  1. Port algorithms to Go (from XSLT in schematron)
  2. Add validation logic to check_peppol.go
  3. Extract identifiers from appropriate Invoice fields
  4. Apply validations based on identifier scheme/type
  5. Add comprehensive test coverage with valid/invalid examples

Example Implementation

// checkGLN validates a Global Location Number using GS1 algorithm
func checkGLN(gln string) bool {
    if len(gln) != 13 {
        return false
    }
    
    // Extract digits and calculate weighted sum
    sum := 0
    for i := 0; i < 12; i++ {
        digit := int(gln[i] - '0')
        if i % 2 == 0 {
            sum += digit * 1
        } else {
            sum += digit * 3
        }
    }
    
    // Check digit calculation
    checkDigit := (10 - (sum % 10)) % 10
    return int(gln[12] - '0') == checkDigit
}

Testing

Need test cases for each rule with:

  • Valid identifiers (should pass)
  • Invalid format (should fail)
  • Invalid check digit (should fail)
  • Edge cases (leading zeros, wrong length, etc.)

References

Related

Part of #24 (PEPPOL BIS Billing 3.0 support)
Depends on #32

Metadata

Metadata

Assignees

No one assigned

    Labels

    PEPPOLPEPPOL BIS Billing 3.0 validation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions