import { expect, tap } from '@git.zone/tstest/tapbundle'; import { EInvoice } from '../../../ts/index.js'; tap.test('STD-01: EN16931 Core Compliance - should validate EN16931 core standard compliance', async () => { console.log('Testing EN16931 core standard compliance...\n'); // Test 1: Mandatory fields compliance const testMandatoryFields = async () => { console.log('Test 1 - Mandatory fields compliance:'); // Test with missing invoice ID (BR-01 violation) let errorCaught = false; try { const einvoice = new EInvoice(); einvoice.issueDate = new Date(2024, 0, 1); // Missing invoiceId - should fail BR-01 einvoice.from = { type: 'company', name: 'Test Company', description: 'EN16931 compliance test', address: { streetName: 'Test Street', houseNumber: '1', postalCode: '12345', city: 'Test City', country: 'DE' }, status: 'active', foundedDate: { year: 2020, month: 1, day: 1 }, registrationDetails: { vatId: 'DE123456789', registrationId: 'HRB 12345', registrationName: 'Commercial Register' } }; einvoice.to = { type: 'person', name: 'Test', surname: 'Customer', salutation: 'Mr' as const, sex: 'male' as const, title: 'Doctor' as const, description: 'Test customer', address: { streetName: 'Customer Street', houseNumber: '2', postalCode: '54321', city: 'Customer City', country: 'DE' } }; einvoice.items = [{ position: 1, name: 'Test Item', articleNumber: 'TEST-001', unitType: 'EA', unitQuantity: 1, unitNetPrice: 100, vatPercentage: 19 }]; await einvoice.toXmlString('ubl'); } catch (error) { errorCaught = true; const errorMessage = error.message; console.log(` BR-01 (Invoice number mandatory): ${errorMessage.includes('BR-01') ? 'Enforced' : 'Detected'}`); } // Test complete valid invoice let validInvoiceProcessed = false; try { const einvoice = new EInvoice(); einvoice.issueDate = new Date(2024, 0, 1); einvoice.invoiceId = 'EN16931-001'; einvoice.from = { type: 'company', name: 'EN16931 Compliant Company', description: 'EN16931 compliance test', address: { streetName: 'Compliant Street', houseNumber: '1', postalCode: '12345', city: 'Compliant City', country: 'DE' }, status: 'active', foundedDate: { year: 2020, month: 1, day: 1 }, registrationDetails: { vatId: 'DE123456789', registrationId: 'HRB 12345', registrationName: 'Commercial Register' } }; einvoice.to = { type: 'person', name: 'Compliant', surname: 'Customer', salutation: 'Mr' as const, sex: 'male' as const, title: 'Doctor' as const, description: 'Compliant customer', address: { streetName: 'Customer Street', houseNumber: '2', postalCode: '54321', city: 'Customer City', country: 'DE' } }; einvoice.items = [{ position: 1, name: 'Compliant Item', articleNumber: 'EN16931-001', unitType: 'EA', unitQuantity: 1, unitNetPrice: 100, vatPercentage: 19 }]; const xml = await einvoice.toXmlString('ubl'); validInvoiceProcessed = xml.includes('EN16931-001'); console.log(` Complete valid invoice: ${validInvoiceProcessed ? 'Processed' : 'Failed'}`); } catch (error) { console.log(` Complete valid invoice: Failed - ${error.message}`); } return { errorCaught, validInvoiceProcessed }; }; // Test 2: Business rules compliance const testBusinessRulesCompliance = async () => { console.log('\nTest 2 - Business rules compliance:'); const businessRuleTests = [ { name: 'BR-06 (Seller name mandatory)', test: async () => { try { const einvoice = new EInvoice(); einvoice.issueDate = new Date(2024, 0, 1); einvoice.invoiceId = 'BR-06-TEST'; // Missing seller name einvoice.from = { type: 'company', name: '', // Empty name - should fail BR-06 description: 'BR-06 test', address: { streetName: 'Test Street', houseNumber: '1', postalCode: '12345', city: 'Test City', country: 'DE' }, status: 'active', foundedDate: { year: 2020, month: 1, day: 1 }, registrationDetails: { vatId: 'DE123456789', registrationId: 'HRB 12345', registrationName: 'Commercial Register' } }; einvoice.to = { type: 'person', name: 'Test', surname: 'Customer', salutation: 'Mr' as const, sex: 'male' as const, title: 'Doctor' as const, description: 'Test customer', address: { streetName: 'Customer Street', houseNumber: '2', postalCode: '54321', city: 'Customer City', country: 'DE' } }; einvoice.items = [{ position: 1, name: 'Test Item', articleNumber: 'TEST-001', unitType: 'EA', unitQuantity: 1, unitNetPrice: 100, vatPercentage: 19 }]; await einvoice.toXmlString('ubl'); return false; // Should not reach here } catch (error) { return error.message.includes('BR-06') || error.message.includes('name'); } } }, { name: 'BR-07 (Buyer name mandatory)', test: async () => { try { const einvoice = new EInvoice(); einvoice.issueDate = new Date(2024, 0, 1); einvoice.invoiceId = 'BR-07-TEST'; einvoice.from = { type: 'company', name: 'Test Company', description: 'BR-07 test', address: { streetName: 'Test Street', houseNumber: '1', postalCode: '12345', city: 'Test City', country: 'DE' }, status: 'active', foundedDate: { year: 2020, month: 1, day: 1 }, registrationDetails: { vatId: 'DE123456789', registrationId: 'HRB 12345', registrationName: 'Commercial Register' } }; // Missing buyer name einvoice.to = { type: 'person', name: '', // Empty name - should fail BR-07 surname: 'Customer', salutation: 'Mr' as const, sex: 'male' as const, title: 'Doctor' as const, description: 'Test customer', address: { streetName: 'Customer Street', houseNumber: '2', postalCode: '54321', city: 'Customer City', country: 'DE' } }; einvoice.items = [{ position: 1, name: 'Test Item', articleNumber: 'TEST-001', unitType: 'EA', unitQuantity: 1, unitNetPrice: 100, vatPercentage: 19 }]; await einvoice.toXmlString('ubl'); return false; // Should not reach here } catch (error) { return error.message.includes('BR-07') || error.message.includes('name'); } } } ]; let rulesEnforced = 0; for (const rule of businessRuleTests) { try { const enforced = await rule.test(); console.log(` ${rule.name}: ${enforced ? 'Enforced' : 'Not enforced'}`); if (enforced) rulesEnforced++; } catch (error) { console.log(` ${rule.name}: Error - ${error.message}`); } } return { rulesEnforced, totalRules: businessRuleTests.length }; }; // Test 3: Format-specific compliance const testFormatCompliance = async () => { console.log('\nTest 3 - Format-specific compliance:'); const formats = ['ubl', 'cii', 'xrechnung']; let formatsWorking = 0; for (const format of formats) { try { const einvoice = new EInvoice(); einvoice.issueDate = new Date(2024, 0, 1); einvoice.invoiceId = `${format.toUpperCase()}-COMPLIANCE-001`; einvoice.from = { type: 'company', name: `${format.toUpperCase()} Test Company`, description: `Testing ${format} format compliance`, address: { streetName: 'Compliance Street', houseNumber: '1', postalCode: '12345', city: 'Compliance City', country: 'DE' }, status: 'active', foundedDate: { year: 2020, month: 1, day: 1 }, registrationDetails: { vatId: 'DE123456789', registrationId: 'HRB 12345', registrationName: 'Commercial Register' } }; einvoice.to = { type: 'person', name: 'Compliance', surname: 'Customer', salutation: 'Mr' as const, sex: 'male' as const, title: 'Doctor' as const, description: 'Compliance customer', address: { streetName: 'Customer Street', houseNumber: '2', postalCode: '54321', city: 'Customer City', country: 'DE' } }; einvoice.items = [{ position: 1, name: `${format.toUpperCase()} Compliance Item`, articleNumber: `${format.toUpperCase()}-001`, unitType: 'EA', unitQuantity: 1, unitNetPrice: 100, vatPercentage: 19 }]; const xml = await einvoice.toXmlString(format as any); const success = xml.includes(`${format.toUpperCase()}-COMPLIANCE-001`); console.log(` ${format.toUpperCase()} format: ${success ? 'Compliant' : 'Failed'}`); if (success) formatsWorking++; } catch (error) { console.log(` ${format.toUpperCase()} format: Failed - ${error.message}`); } } return { formatsWorking, totalFormats: formats.length }; }; // Test 4: EN16931 mandatory elements presence const testMandatoryElementsPresence = async () => { console.log('\nTest 4 - Mandatory elements presence:'); const einvoice = new EInvoice(); einvoice.issueDate = new Date(2024, 0, 1); einvoice.invoiceId = 'MANDATORY-ELEMENTS-001'; einvoice.from = { type: 'company', name: 'Mandatory Elements Company', description: 'Testing mandatory elements', address: { streetName: 'Mandatory Street', houseNumber: '1', postalCode: '12345', city: 'Mandatory City', country: 'DE' }, status: 'active', foundedDate: { year: 2020, month: 1, day: 1 }, registrationDetails: { vatId: 'DE123456789', registrationId: 'HRB 12345', registrationName: 'Commercial Register' } }; einvoice.to = { type: 'person', name: 'Mandatory', surname: 'Customer', salutation: 'Mr' as const, sex: 'male' as const, title: 'Doctor' as const, description: 'Mandatory customer', address: { streetName: 'Customer Street', houseNumber: '2', postalCode: '54321', city: 'Customer City', country: 'DE' } }; einvoice.items = [{ position: 1, name: 'Mandatory Item', articleNumber: 'MANDATORY-001', unitType: 'EA', unitQuantity: 1, unitNetPrice: 100, vatPercentage: 19 }]; try { const xml = await einvoice.toXmlString('ubl'); // Check for EN16931 mandatory elements const mandatoryElements = [ 'cbc:ID', // BT-1 Invoice number 'cbc:IssueDate', // BT-2 Invoice issue date 'cac:AccountingSupplierParty', // BG-4 Seller 'cac:AccountingCustomerParty', // BG-7 Buyer 'cac:InvoiceLine' // BG-25 Invoice line ]; let elementsPresent = 0; for (const element of mandatoryElements) { if (xml.includes(element)) { elementsPresent++; console.log(` ${element}: Present`); } else { console.log(` ${element}: Missing`); } } return { elementsPresent, totalElements: mandatoryElements.length }; } catch (error) { console.log(` Mandatory elements test failed: ${error.message}`); return { elementsPresent: 0, totalElements: 5 }; } }; // Run all tests const result1 = await testMandatoryFields(); const result2 = await testBusinessRulesCompliance(); const result3 = await testFormatCompliance(); const result4 = await testMandatoryElementsPresence(); console.log('\n=== EN16931 Core Compliance Summary ==='); console.log(`Mandatory field validation: ${result1.errorCaught ? 'Working' : 'Not implemented'}`); console.log(`Valid invoice processing: ${result1.validInvoiceProcessed ? 'Working' : 'Failed'}`); console.log(`Business rules enforced: ${result2.rulesEnforced}/${result2.totalRules}`); console.log(`Format compliance: ${result3.formatsWorking}/${result3.totalFormats}`); console.log(`Mandatory elements: ${result4.elementsPresent}/${result4.totalElements}`); // Test passes if core EN16931 functionality works const coreValidationWorks = result1.errorCaught && result1.validInvoiceProcessed; // BR validation + valid processing const businessRulesWork = result2.rulesEnforced === result2.totalRules; // All business rules enforced const mandatoryElementsWork = result4.elementsPresent === result4.totalElements; // All mandatory elements present expect(coreValidationWorks).toBeTrue(); // Core EN16931 validation must work expect(businessRulesWork).toBeTrue(); // Business rules must be enforced expect(mandatoryElementsWork).toBeTrue(); // All mandatory elements must be present }); tap.start();