feat(validation): Implement EN16931 compliance validation types and VAT categories
- Added validation types for EN16931 compliance in `validation.types.ts`, including interfaces for `ValidationResult`, `ValidationOptions`, and `ValidationReport`.
- Introduced `VATCategoriesValidator` in `vat-categories.validator.ts` to validate VAT categories according to EN16931 rules, including detailed checks for standard, zero-rated, exempt, reverse charge, intra-community, export, and out-of-scope services.
- Enhanced `IEInvoiceMetadata` interface in `en16931-metadata.ts` to include additional fields required for full standards compliance, such as delivery information, payment information, allowances, and charges.
- Implemented helper methods for VAT calculations and validation logic to ensure accurate compliance with EN16931 standards.
2025-08-11 12:25:32 +00:00
|
|
|
import * as plugins from '../../plugins.js';
|
|
|
|
import * as path from 'path';
|
|
|
|
import { promises as fs } from 'fs';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Schematron rule sources
|
|
|
|
*/
|
|
|
|
export interface SchematronSource {
|
|
|
|
name: string;
|
|
|
|
version: string;
|
|
|
|
url: string;
|
|
|
|
description: string;
|
|
|
|
format: 'UBL' | 'CII' | 'BOTH';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Official Schematron sources for e-invoicing standards
|
|
|
|
*/
|
|
|
|
export const SCHEMATRON_SOURCES: Record<string, SchematronSource[]> = {
|
|
|
|
EN16931: [
|
|
|
|
{
|
|
|
|
name: 'EN16931-UBL',
|
|
|
|
version: '1.3.14',
|
|
|
|
url: 'https://github.com/ConnectingEurope/eInvoicing-EN16931/raw/master/ubl/schematron/EN16931-UBL-validation.sch',
|
|
|
|
description: 'Official EN16931 validation rules for UBL format',
|
|
|
|
format: 'UBL'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'EN16931-CII',
|
|
|
|
version: '1.3.14',
|
|
|
|
url: 'https://github.com/ConnectingEurope/eInvoicing-EN16931/raw/master/cii/schematron/EN16931-CII-validation.sch',
|
|
|
|
description: 'Official EN16931 validation rules for CII format',
|
|
|
|
format: 'CII'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'EN16931-EDIFACT',
|
|
|
|
version: '1.3.14',
|
|
|
|
url: 'https://github.com/ConnectingEurope/eInvoicing-EN16931/raw/master/edifact/schematron/EN16931-EDIFACT-validation.sch',
|
|
|
|
description: 'Official EN16931 validation rules for EDIFACT format',
|
|
|
|
format: 'CII'
|
|
|
|
}
|
|
|
|
],
|
|
|
|
XRECHNUNG: [
|
|
|
|
{
|
|
|
|
name: 'XRechnung-UBL',
|
|
|
|
version: '3.0.2',
|
2025-08-12 05:14:11 +00:00
|
|
|
url: 'https://github.com/itplr-kosit/xrechnung-schematron/raw/master/src/validation/schematron/ubl/XRechnung-UBL-validation.sch',
|
feat(validation): Implement EN16931 compliance validation types and VAT categories
- Added validation types for EN16931 compliance in `validation.types.ts`, including interfaces for `ValidationResult`, `ValidationOptions`, and `ValidationReport`.
- Introduced `VATCategoriesValidator` in `vat-categories.validator.ts` to validate VAT categories according to EN16931 rules, including detailed checks for standard, zero-rated, exempt, reverse charge, intra-community, export, and out-of-scope services.
- Enhanced `IEInvoiceMetadata` interface in `en16931-metadata.ts` to include additional fields required for full standards compliance, such as delivery information, payment information, allowances, and charges.
- Implemented helper methods for VAT calculations and validation logic to ensure accurate compliance with EN16931 standards.
2025-08-11 12:25:32 +00:00
|
|
|
description: 'XRechnung CIUS validation for UBL',
|
|
|
|
format: 'UBL'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'XRechnung-CII',
|
|
|
|
version: '3.0.2',
|
2025-08-12 05:14:11 +00:00
|
|
|
url: 'https://github.com/itplr-kosit/xrechnung-schematron/raw/master/src/validation/schematron/cii/XRechnung-CII-validation.sch',
|
feat(validation): Implement EN16931 compliance validation types and VAT categories
- Added validation types for EN16931 compliance in `validation.types.ts`, including interfaces for `ValidationResult`, `ValidationOptions`, and `ValidationReport`.
- Introduced `VATCategoriesValidator` in `vat-categories.validator.ts` to validate VAT categories according to EN16931 rules, including detailed checks for standard, zero-rated, exempt, reverse charge, intra-community, export, and out-of-scope services.
- Enhanced `IEInvoiceMetadata` interface in `en16931-metadata.ts` to include additional fields required for full standards compliance, such as delivery information, payment information, allowances, and charges.
- Implemented helper methods for VAT calculations and validation logic to ensure accurate compliance with EN16931 standards.
2025-08-11 12:25:32 +00:00
|
|
|
description: 'XRechnung CIUS validation for CII',
|
|
|
|
format: 'CII'
|
|
|
|
}
|
|
|
|
],
|
|
|
|
PEPPOL: [
|
|
|
|
{
|
|
|
|
name: 'PEPPOL-EN16931-UBL',
|
|
|
|
version: '3.0.17',
|
|
|
|
url: 'https://github.com/OpenPEPPOL/peppol-bis-invoice-3/raw/master/rules/sch/PEPPOL-EN16931-UBL.sch',
|
2025-08-12 05:14:11 +00:00
|
|
|
description: 'PEPPOL BIS Billing 3.0 validation rules for UBL',
|
feat(validation): Implement EN16931 compliance validation types and VAT categories
- Added validation types for EN16931 compliance in `validation.types.ts`, including interfaces for `ValidationResult`, `ValidationOptions`, and `ValidationReport`.
- Introduced `VATCategoriesValidator` in `vat-categories.validator.ts` to validate VAT categories according to EN16931 rules, including detailed checks for standard, zero-rated, exempt, reverse charge, intra-community, export, and out-of-scope services.
- Enhanced `IEInvoiceMetadata` interface in `en16931-metadata.ts` to include additional fields required for full standards compliance, such as delivery information, payment information, allowances, and charges.
- Implemented helper methods for VAT calculations and validation logic to ensure accurate compliance with EN16931 standards.
2025-08-11 12:25:32 +00:00
|
|
|
format: 'UBL'
|
|
|
|
},
|
|
|
|
{
|
2025-08-12 05:14:11 +00:00
|
|
|
name: 'PEPPOL-EN16931-CII',
|
feat(validation): Implement EN16931 compliance validation types and VAT categories
- Added validation types for EN16931 compliance in `validation.types.ts`, including interfaces for `ValidationResult`, `ValidationOptions`, and `ValidationReport`.
- Introduced `VATCategoriesValidator` in `vat-categories.validator.ts` to validate VAT categories according to EN16931 rules, including detailed checks for standard, zero-rated, exempt, reverse charge, intra-community, export, and out-of-scope services.
- Enhanced `IEInvoiceMetadata` interface in `en16931-metadata.ts` to include additional fields required for full standards compliance, such as delivery information, payment information, allowances, and charges.
- Implemented helper methods for VAT calculations and validation logic to ensure accurate compliance with EN16931 standards.
2025-08-11 12:25:32 +00:00
|
|
|
version: '3.0.17',
|
2025-08-12 05:14:11 +00:00
|
|
|
url: 'https://github.com/OpenPEPPOL/peppol-bis-invoice-3/raw/master/rules/sch/PEPPOL-EN16931-CII.sch',
|
|
|
|
description: 'PEPPOL BIS Billing 3.0 validation rules for CII',
|
|
|
|
format: 'CII'
|
feat(validation): Implement EN16931 compliance validation types and VAT categories
- Added validation types for EN16931 compliance in `validation.types.ts`, including interfaces for `ValidationResult`, `ValidationOptions`, and `ValidationReport`.
- Introduced `VATCategoriesValidator` in `vat-categories.validator.ts` to validate VAT categories according to EN16931 rules, including detailed checks for standard, zero-rated, exempt, reverse charge, intra-community, export, and out-of-scope services.
- Enhanced `IEInvoiceMetadata` interface in `en16931-metadata.ts` to include additional fields required for full standards compliance, such as delivery information, payment information, allowances, and charges.
- Implemented helper methods for VAT calculations and validation logic to ensure accurate compliance with EN16931 standards.
2025-08-11 12:25:32 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Schematron downloader and cache manager
|
|
|
|
*/
|
|
|
|
export class SchematronDownloader {
|
|
|
|
private cacheDir: string;
|
|
|
|
private smartfile: any;
|
|
|
|
|
2025-08-12 05:25:50 +00:00
|
|
|
constructor(cacheDir: string = 'assets_downloaded/schematron') {
|
feat(validation): Implement EN16931 compliance validation types and VAT categories
- Added validation types for EN16931 compliance in `validation.types.ts`, including interfaces for `ValidationResult`, `ValidationOptions`, and `ValidationReport`.
- Introduced `VATCategoriesValidator` in `vat-categories.validator.ts` to validate VAT categories according to EN16931 rules, including detailed checks for standard, zero-rated, exempt, reverse charge, intra-community, export, and out-of-scope services.
- Enhanced `IEInvoiceMetadata` interface in `en16931-metadata.ts` to include additional fields required for full standards compliance, such as delivery information, payment information, allowances, and charges.
- Implemented helper methods for VAT calculations and validation logic to ensure accurate compliance with EN16931 standards.
2025-08-11 12:25:32 +00:00
|
|
|
this.cacheDir = cacheDir;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize the downloader
|
|
|
|
*/
|
|
|
|
public async initialize(): Promise<void> {
|
|
|
|
// Ensure cache directory exists
|
|
|
|
this.smartfile = await import('@push.rocks/smartfile');
|
|
|
|
await fs.mkdir(this.cacheDir, { recursive: true });
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Download a Schematron file
|
|
|
|
*/
|
|
|
|
public async download(source: SchematronSource): Promise<string> {
|
|
|
|
const fileName = `${source.name}-v${source.version}.sch`;
|
|
|
|
const filePath = path.join(this.cacheDir, fileName);
|
|
|
|
|
|
|
|
// Check if already cached
|
|
|
|
if (await this.isCached(filePath)) {
|
|
|
|
console.log(`Using cached Schematron: ${fileName}`);
|
|
|
|
return filePath;
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log(`Downloading Schematron: ${source.name} v${source.version}`);
|
|
|
|
|
|
|
|
try {
|
|
|
|
// Download the file
|
|
|
|
const response = await fetch(source.url);
|
|
|
|
if (!response.ok) {
|
|
|
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
const content = await response.text();
|
|
|
|
|
|
|
|
// Validate it's actually Schematron
|
|
|
|
if (!content.includes('schematron') && !content.includes('sch:schema')) {
|
|
|
|
throw new Error('Downloaded file does not appear to be Schematron');
|
|
|
|
}
|
|
|
|
|
|
|
|
// Save to cache
|
|
|
|
await fs.writeFile(filePath, content, 'utf-8');
|
|
|
|
|
|
|
|
// Also save metadata
|
|
|
|
const metaPath = filePath.replace('.sch', '.meta.json');
|
|
|
|
await fs.writeFile(metaPath, JSON.stringify({
|
|
|
|
source: source.name,
|
|
|
|
version: source.version,
|
|
|
|
url: source.url,
|
|
|
|
format: source.format,
|
|
|
|
downloadDate: new Date().toISOString()
|
|
|
|
}, null, 2), 'utf-8');
|
|
|
|
|
|
|
|
console.log(`Successfully downloaded: ${fileName}`);
|
|
|
|
return filePath;
|
|
|
|
} catch (error) {
|
|
|
|
throw new Error(`Failed to download ${source.name}: ${error.message}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Download all Schematron files for a standard
|
|
|
|
*/
|
|
|
|
public async downloadStandard(
|
|
|
|
standard: 'EN16931' | 'XRECHNUNG' | 'PEPPOL'
|
|
|
|
): Promise<string[]> {
|
|
|
|
const sources = SCHEMATRON_SOURCES[standard];
|
|
|
|
if (!sources) {
|
|
|
|
throw new Error(`Unknown standard: ${standard}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
const paths: string[] = [];
|
|
|
|
for (const source of sources) {
|
|
|
|
try {
|
|
|
|
const path = await this.download(source);
|
|
|
|
paths.push(path);
|
|
|
|
} catch (error) {
|
|
|
|
console.warn(`Failed to download ${source.name}: ${error.message}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return paths;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if a file is cached
|
|
|
|
*/
|
|
|
|
private async isCached(filePath: string): Promise<boolean> {
|
|
|
|
try {
|
|
|
|
await fs.access(filePath);
|
|
|
|
|
|
|
|
// Check if file is not empty
|
|
|
|
const stats = await fs.stat(filePath);
|
|
|
|
return stats.size > 0;
|
|
|
|
} catch {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get cached Schematron files
|
|
|
|
*/
|
|
|
|
public async getCachedFiles(): Promise<Array<{
|
|
|
|
path: string;
|
|
|
|
metadata: any;
|
|
|
|
}>> {
|
|
|
|
const files: Array<{ path: string; metadata: any }> = [];
|
|
|
|
|
|
|
|
try {
|
|
|
|
const entries = await fs.readdir(this.cacheDir);
|
|
|
|
|
|
|
|
for (const entry of entries) {
|
|
|
|
if (entry.endsWith('.sch')) {
|
|
|
|
const filePath = path.join(this.cacheDir, entry);
|
|
|
|
const metaPath = filePath.replace('.sch', '.meta.json');
|
|
|
|
|
|
|
|
try {
|
|
|
|
const metadata = JSON.parse(await fs.readFile(metaPath, 'utf-8'));
|
|
|
|
files.push({ path: filePath, metadata });
|
|
|
|
} catch {
|
|
|
|
// No metadata file
|
|
|
|
files.push({ path: filePath, metadata: null });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
console.warn(`Failed to list cached files: ${error.message}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
return files;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clear cache
|
|
|
|
*/
|
|
|
|
public async clearCache(): Promise<void> {
|
|
|
|
try {
|
|
|
|
const entries = await fs.readdir(this.cacheDir);
|
|
|
|
|
|
|
|
for (const entry of entries) {
|
|
|
|
if (entry.endsWith('.sch') || entry.endsWith('.meta.json')) {
|
|
|
|
await fs.unlink(path.join(this.cacheDir, entry));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log('Schematron cache cleared');
|
|
|
|
} catch (error) {
|
|
|
|
console.warn(`Failed to clear cache: ${error.message}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the appropriate Schematron for a format
|
|
|
|
*/
|
|
|
|
public async getSchematronForFormat(
|
|
|
|
standard: 'EN16931' | 'XRECHNUNG' | 'PEPPOL',
|
|
|
|
format: 'UBL' | 'CII'
|
|
|
|
): Promise<string | null> {
|
|
|
|
const sources = SCHEMATRON_SOURCES[standard];
|
|
|
|
if (!sources) return null;
|
|
|
|
|
|
|
|
const source = sources.find(s => s.format === format || s.format === 'BOTH');
|
|
|
|
if (!source) return null;
|
|
|
|
|
|
|
|
return await this.download(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update all cached Schematron files
|
|
|
|
*/
|
|
|
|
public async updateAll(): Promise<void> {
|
|
|
|
console.log('Updating all Schematron files...');
|
|
|
|
|
|
|
|
for (const standard of ['EN16931', 'XRECHNUNG', 'PEPPOL'] as const) {
|
|
|
|
await this.downloadStandard(standard);
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log('All Schematron files updated');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ISO Schematron skeleton URLs
|
|
|
|
* These are needed to compile Schematron to XSLT
|
|
|
|
*/
|
|
|
|
export const ISO_SCHEMATRON_SKELETONS = {
|
|
|
|
'iso_dsdl_include.xsl': 'https://github.com/Schematron/schematron/raw/master/trunk/schematron/code/iso_dsdl_include.xsl',
|
|
|
|
'iso_abstract_expand.xsl': 'https://github.com/Schematron/schematron/raw/master/trunk/schematron/code/iso_abstract_expand.xsl',
|
|
|
|
'iso_svrl_for_xslt2.xsl': 'https://github.com/Schematron/schematron/raw/master/trunk/schematron/code/iso_svrl_for_xslt2.xsl',
|
|
|
|
'iso_schematron_skeleton_for_saxon.xsl': 'https://github.com/Schematron/schematron/raw/master/trunk/schematron/code/iso_schematron_skeleton_for_saxon.xsl'
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Download ISO Schematron skeleton files
|
|
|
|
*/
|
2025-08-12 05:25:50 +00:00
|
|
|
export async function downloadISOSkeletons(targetDir: string = 'assets_downloaded/schematron/iso'): Promise<void> {
|
feat(validation): Implement EN16931 compliance validation types and VAT categories
- Added validation types for EN16931 compliance in `validation.types.ts`, including interfaces for `ValidationResult`, `ValidationOptions`, and `ValidationReport`.
- Introduced `VATCategoriesValidator` in `vat-categories.validator.ts` to validate VAT categories according to EN16931 rules, including detailed checks for standard, zero-rated, exempt, reverse charge, intra-community, export, and out-of-scope services.
- Enhanced `IEInvoiceMetadata` interface in `en16931-metadata.ts` to include additional fields required for full standards compliance, such as delivery information, payment information, allowances, and charges.
- Implemented helper methods for VAT calculations and validation logic to ensure accurate compliance with EN16931 standards.
2025-08-11 12:25:32 +00:00
|
|
|
await fs.mkdir(targetDir, { recursive: true });
|
|
|
|
|
|
|
|
console.log('Downloading ISO Schematron skeleton files...');
|
|
|
|
|
|
|
|
for (const [name, url] of Object.entries(ISO_SCHEMATRON_SKELETONS)) {
|
|
|
|
try {
|
|
|
|
const response = await fetch(url);
|
|
|
|
if (!response.ok) {
|
|
|
|
throw new Error(`HTTP ${response.status}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
const content = await response.text();
|
|
|
|
const filePath = path.join(targetDir, name);
|
|
|
|
await fs.writeFile(filePath, content, 'utf-8');
|
|
|
|
|
|
|
|
console.log(`Downloaded: ${name}`);
|
|
|
|
} catch (error) {
|
|
|
|
console.warn(`Failed to download ${name}: ${error.message}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log('ISO Schematron skeleton download complete');
|
|
|
|
}
|