import { tap, expect } from '@git.zone/tstest/tapbundle'; import { EInvoice } from '../../../ts/index.js'; import { InvoiceFormat } from '../../../ts/interfaces/common.js'; import { CorpusLoader } from '../../helpers/corpus.loader.js'; import { PerformanceTracker } from '../../helpers/performance.tracker.instance.js'; import * as path from 'path'; /** * Test ID: STD-10 * Test Description: Country-Specific Extensions * Priority: Medium * * This test validates handling of country-specific extensions to EN16931, * including XRechnung (Germany), FatturaPA (Italy), and PEPPOL BIS variations. */ // Test 1: German XRechnung Extensions tap.test('STD-10: German XRechnung specific requirements', async () => { const invoice = new EInvoice(); // XRechnung specific fields invoice.id = 'XRECHNUNG-001'; invoice.issueDate = new Date(); invoice.metadata = { format: InvoiceFormat.XRECHNUNG, extensions: { 'BT-DE-1': 'Payment conditions text', // German specific 'BT-DE-2': 'Buyer reference', // Leitweg-ID 'BT-DE-3': 'Project reference', 'BT-DE-4': 'Contract reference', 'BT-DE-5': 'Order reference' } }; // Leitweg-ID validation (German routing ID) const leitwegId = '04011000-12345-67'; const leitwegPattern = /^\d{8,12}-\d{1,30}-\d{1,2}$/; expect(leitwegPattern.test(leitwegId)).toBeTrue(); console.log('✓ Valid Leitweg-ID format'); // Bank transfer requirements invoice.paymentTerms = { method: 'SEPA', iban: 'DE89370400440532013000', bic: 'DEUTDEFF', reference: 'RF18539007547034' }; // IBAN validation for Germany const germanIbanPattern = /^DE\d{20}$/; expect(germanIbanPattern.test(invoice.paymentTerms.iban)).toBeTrue(); console.log('✓ Valid German IBAN format'); // XRechnung profile requirements const xrechnungProfiles = [ 'urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.0', 'urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.1', 'urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.2' ]; expect(xrechnungProfiles.length).toBeGreaterThan(0); console.log('✓ XRechnung profile identifiers defined'); }); // Test 2: Italian FatturaPA Extensions tap.test('STD-10: Italian FatturaPA specific requirements', async () => { // FatturaPA specific structure const fatturapaRequirements = { transmissionFormat: { FormatoTrasmissione: 'FPR12', // Private B2B CodiceDestinatario: '0000000', // 7 digits PECDestinatario: 'pec@example.it' }, cedentePrestatore: { DatiAnagrafici: { IdFiscaleIVA: { IdPaese: 'IT', IdCodice: '12345678901' // 11 digits }, CodiceFiscale: 'RSSMRA80A01H501U' // 16 chars } }, documentType: '1.2.1' // Version }; // Validate Italian VAT number const italianVATPattern = /^IT\d{11}$/; const testVAT = 'IT' + fatturapaRequirements.cedentePrestatore.DatiAnagrafici.IdFiscaleIVA.IdCodice; expect(italianVATPattern.test(testVAT)).toBeTrue(); console.log('✓ Valid Italian VAT number format'); // Validate Codice Fiscale const codiceFiscalePattern = /^[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]$/; expect(codiceFiscalePattern.test(fatturapaRequirements.cedentePrestatore.DatiAnagrafici.CodiceFiscale)).toBeTrue(); console.log('✓ Valid Italian Codice Fiscale format'); // Validate Codice Destinatario expect(fatturapaRequirements.transmissionFormat.CodiceDestinatario).toMatch(/^\d{7}$/); console.log('✓ Valid Codice Destinatario format'); // Document numbering requirements const italianInvoiceNumber = '2024/001'; expect(italianInvoiceNumber).toMatch(/^\d{4}\/\d+$/); console.log('✓ Valid Italian invoice number format'); }); // Test 3: French Factur-X Extensions tap.test('STD-10: French Factur-X specific requirements', async () => { const invoice = new EInvoice(); invoice.id = 'FX-FR-001'; invoice.issueDate = new Date(); // French specific requirements const frenchExtensions = { siret: '12345678901234', // 14 digits naf: '6201Z', // NAF/APE code tvaIntracommunautaire: 'FR12345678901', mentionsLegales: 'SARL au capital de 10000 EUR', chorus: { serviceCode: 'SERVICE123', engagementNumber: 'ENG123456' } }; // Validate SIRET (14 digits) expect(frenchExtensions.siret).toMatch(/^\d{14}$/); console.log('✓ Valid French SIRET format'); // Validate French VAT number const frenchVATPattern = /^FR[0-9A-Z]{2}\d{9}$/; expect(frenchVATPattern.test(frenchExtensions.tvaIntracommunautaire)).toBeTrue(); console.log('✓ Valid French VAT number format'); // Validate NAF/APE code expect(frenchExtensions.naf).toMatch(/^\d{4}[A-Z]$/); console.log('✓ Valid French NAF/APE code format'); // Chorus Pro integration (French public sector) if (frenchExtensions.chorus.serviceCode) { console.log('✓ Chorus Pro service code present'); } }); // Test 4: Belgian Extensions tap.test('STD-10: Belgian e-invoicing extensions', async () => { const belgianExtensions = { merchantAgreementReference: 'BE-MERCH-001', vatNumber: 'BE0123456789', bancontact: { enabled: true, reference: 'BC123456' }, languages: ['nl', 'fr', 'de'], // Belgium has 3 official languages regionalCodes: { flanders: 'VL', wallonia: 'WA', brussels: 'BR' } }; // Validate Belgian VAT number (BE followed by 10 digits) expect(belgianExtensions.vatNumber).toMatch(/^BE\d{10}$/); console.log('✓ Valid Belgian VAT number format'); // Language requirements expect(belgianExtensions.languages).toContain('nl'); expect(belgianExtensions.languages).toContain('fr'); console.log('✓ Supports required Belgian languages'); }); // Test 5: Nordic Countries Extensions tap.test('STD-10: Nordic countries specific requirements', async () => { // Swedish requirements const swedishExtensions = { organisationNumber: '1234567890', // 10 digits vatNumber: 'SE123456789001', bankgiro: '123-4567', plusgiro: '12 34 56-7', referenceType: 'OCR', // Swedish payment reference ocrReference: '12345678901234567890' }; // Norwegian requirements const norwegianExtensions = { organisationNumber: '123456789', // 9 digits vatNumber: 'NO123456789MVA', kidNumber: '1234567890123', // Payment reference iban: 'NO9386011117947' }; // Danish requirements const danishExtensions = { cvrNumber: '12345678', // 8 digits eanLocation: '5790000123456', // 13 digits vatNumber: 'DK12345678', nemKonto: true // Danish public payment system }; // Validate formats expect(swedishExtensions.vatNumber).toMatch(/^SE\d{12}$/); console.log('✓ Valid Swedish VAT format'); expect(norwegianExtensions.vatNumber).toMatch(/^NO\d{9}MVA$/); console.log('✓ Valid Norwegian VAT format'); expect(danishExtensions.cvrNumber).toMatch(/^\d{8}$/); console.log('✓ Valid Danish CVR format'); }); // Test 6: PEPPOL BIS Country Variations tap.test('STD-10: PEPPOL BIS country-specific profiles', async () => { const peppolProfiles = { 'PEPPOL-BIS-3.0': 'Base profile', 'PEPPOL-BIS-3.0-AU': 'Australian extension', 'PEPPOL-BIS-3.0-NZ': 'New Zealand extension', 'PEPPOL-BIS-3.0-SG': 'Singapore extension', 'PEPPOL-BIS-3.0-MY': 'Malaysian extension' }; // Country-specific identifiers const countryIdentifiers = { AU: { scheme: '0151', name: 'ABN' }, // Australian Business Number NZ: { scheme: '0088', name: 'NZBN' }, // NZ Business Number SG: { scheme: '0195', name: 'UEN' }, // Unique Entity Number MY: { scheme: '0199', name: 'MyBRN' } // Malaysian Business Registration }; // Test identifier schemes for (const [country, identifier] of Object.entries(countryIdentifiers)) { expect(identifier.scheme).toMatch(/^\d{4}$/); console.log(`✓ ${country}: Valid PEPPOL identifier scheme ${identifier.scheme} (${identifier.name})`); } }); // Test 7: Tax Regime Variations tap.test('STD-10: Country-specific tax requirements', async () => { const countryTaxRequirements = { DE: { standardRate: 19, reducedRate: 7, reverseCharge: 'Steuerschuldnerschaft des Leistungsempfängers' }, FR: { standardRate: 20, reducedRates: [10, 5.5, 2.1], autoliquidation: 'Autoliquidation de la TVA' }, IT: { standardRate: 22, reducedRates: [10, 5, 4], splitPayment: true // Italian split payment mechanism }, ES: { standardRate: 21, reducedRates: [10, 4], canaryIslands: 'IGIC', // Different tax system recargo: true // Equivalence surcharge } }; // Validate tax rates for (const [country, tax] of Object.entries(countryTaxRequirements)) { expect(tax.standardRate).toBeGreaterThan(0); expect(tax.standardRate).toBeLessThan(30); console.log(`✓ ${country}: Valid tax rates defined`); } }); // Test 8: Country-Specific Validation Rules tap.test('STD-10: Country-specific validation rules', async () => { // Test with real corpus files const countryFiles = { DE: await CorpusLoader.loadCategory('CII_XMLRECHNUNG'), IT: await CorpusLoader.loadCategory('FATTURAPA_OFFICIAL') }; // German validation rules if (countryFiles.DE.length > 0) { const germanFile = countryFiles.DE[0]; const xmlBuffer = await CorpusLoader.loadFile(germanFile.path); const xmlString = xmlBuffer.toString('utf-8'); // Check for German-specific elements const hasLeitwegId = xmlString.includes('BuyerReference') || xmlString.includes('BT-10'); if (hasLeitwegId) { console.log('✓ German invoice contains buyer reference (Leitweg-ID)'); } } // Italian validation rules if (countryFiles.IT.length > 0) { const italianFile = countryFiles.IT[0]; const xmlBuffer = await CorpusLoader.loadFile(italianFile.path); const xmlString = xmlBuffer.toString('utf-8'); // Check for Italian-specific structure const hasFatturaPA = xmlString.includes('FatturaElettronica') || xmlString.includes('FormatoTrasmissione'); if (hasFatturaPA) { console.log('✓ Italian invoice follows FatturaPA structure'); } } // Performance summary const tracker = new PerformanceTracker('country-extensions'); const perfSummary = await tracker.getSummary(); if (perfSummary) { console.log('\nCountry Extensions Test Performance:'); console.log(` Average: ${perfSummary.average}ms`); } }); tap.start();