@fin.cx/einvoice
Version:
A TypeScript module for creating, manipulating, and embedding XML data within PDF files specifically tailored for electronic invoice (einvoice) packages.
107 lines • 11.4 kB
JavaScript
import { EN16931UBLValidator } from './en16931.ubl.validator.js';
/**
* XRechnung-specific validator that extends EN16931 validation
* Implements additional German CIUS (Core Invoice Usage Specification) rules
*/
export class XRechnungValidator extends EN16931UBLValidator {
/**
* Validates XRechnung-specific structure requirements
*/
validateStructure() {
// First validate EN16931 structure
let valid = super.validateStructure();
// XRechnung-specific: Check for proper customization ID
const customizationID = this.getText('//cbc:CustomizationID');
if (!customizationID || !customizationID.includes('xrechnung')) {
this.addError('XRECH-STRUCT-1', 'XRechnung customization ID is missing or invalid', '//cbc:CustomizationID');
valid = false;
}
return valid;
}
/**
* Validates XRechnung-specific business rules
*/
validateBusinessRules() {
// First validate EN16931 business rules
let valid = super.validateBusinessRules();
// BR-DE-1: Payment terms (BT-20) or Payment due date (BT-9) shall be provided.
if (!this.exists('//cbc:PaymentDueDate') && !this.exists('//cac:PaymentTerms/cbc:Note')) {
this.addError('BR-DE-1', 'Payment terms or Payment due date shall be provided', '//cac:PaymentTerms');
valid = false;
}
// BR-DE-2: The element "Buyer reference" (BT-10) shall be provided.
if (!this.exists('//cbc:BuyerReference')) {
this.addError('BR-DE-2', 'Buyer reference is required in XRechnung', '//cbc:BuyerReference');
valid = false;
}
// BR-DE-5: In Germany, the element "Seller VAT identifier" (BT-31) shall be provided.
const sellerCountry = this.getText('//cac:AccountingSupplierParty//cac:PostalAddress//cac:Country/cbc:IdentificationCode');
if (sellerCountry === 'DE' && !this.exists('//cac:AccountingSupplierParty//cac:PartyTaxScheme[cac:TaxScheme/cbc:ID="VAT"]/cbc:CompanyID')) {
this.addError('BR-DE-5', 'Seller VAT identifier is required for German sellers', '//cac:AccountingSupplierParty//cac:PartyTaxScheme');
valid = false;
}
// BR-DE-6: In Germany, the element "Buyer VAT identifier" (BT-48) shall be provided.
const buyerCountry = this.getText('//cac:AccountingCustomerParty//cac:PostalAddress//cac:Country/cbc:IdentificationCode');
if (buyerCountry === 'DE' && !this.exists('//cac:AccountingCustomerParty//cac:PartyTaxScheme[cac:TaxScheme/cbc:ID="VAT"]/cbc:CompanyID')) {
this.addError('BR-DE-6', 'Buyer VAT identifier is required for German buyers', '//cac:AccountingCustomerParty//cac:PartyTaxScheme');
valid = false;
}
// BR-DE-7: The element "Seller city" (BT-37) shall be provided.
if (!this.exists('//cac:AccountingSupplierParty//cac:PostalAddress/cbc:CityName')) {
this.addError('BR-DE-7', 'Seller city is required', '//cac:AccountingSupplierParty//cac:PostalAddress');
valid = false;
}
// BR-DE-8: The element "Seller post code" (BT-38) shall be provided.
if (!this.exists('//cac:AccountingSupplierParty//cac:PostalAddress/cbc:PostalZone')) {
this.addError('BR-DE-8', 'Seller post code is required', '//cac:AccountingSupplierParty//cac:PostalAddress');
valid = false;
}
// BR-DE-9: The element "Buyer city" (BT-52) shall be provided.
if (!this.exists('//cac:AccountingCustomerParty//cac:PostalAddress/cbc:CityName')) {
this.addError('BR-DE-9', 'Buyer city is required', '//cac:AccountingCustomerParty//cac:PostalAddress');
valid = false;
}
// BR-DE-10: The element "Buyer post code" (BT-53) shall be provided.
if (!this.exists('//cac:AccountingCustomerParty//cac:PostalAddress/cbc:PostalZone')) {
this.addError('BR-DE-10', 'Buyer post code is required', '//cac:AccountingCustomerParty//cac:PostalAddress');
valid = false;
}
// BR-DE-11: The element "Seller contact telephone number" (BT-42) shall be provided.
if (!this.exists('//cac:AccountingSupplierParty//cac:Contact/cbc:Telephone')) {
this.addError('BR-DE-11', 'Seller contact telephone number is required', '//cac:AccountingSupplierParty//cac:Contact');
valid = false;
}
// BR-DE-12: The element "Seller contact email address" (BT-43) shall be provided.
if (!this.exists('//cac:AccountingSupplierParty//cac:Contact/cbc:ElectronicMail')) {
this.addError('BR-DE-12', 'Seller contact email address is required', '//cac:AccountingSupplierParty//cac:Contact');
valid = false;
}
// BR-DE-13: The element "Buyer electronic address" (BT-49) shall be provided.
if (!this.exists('//cac:AccountingCustomerParty//cac:Party/cbc:EndpointID')) {
this.addError('BR-DE-13', 'Buyer electronic address (EndpointID) is required', '//cac:AccountingCustomerParty//cac:Party');
valid = false;
}
// BR-DE-14: The element "Payment means type code" (BT-81) shall be provided.
if (!this.exists('//cac:PaymentMeans/cbc:PaymentMeansCode')) {
this.addError('BR-DE-14', 'Payment means type code is required', '//cac:PaymentMeans');
valid = false;
}
// BR-DE-15: The element "Invoice line identifier" (BT-126) shall be provided.
const invoiceLines = this.select('//cac:InvoiceLine | //cac:CreditNoteLine', this.doc);
for (let i = 0; i < invoiceLines.length; i++) {
const line = invoiceLines[i];
if (!this.exists('./cbc:ID', line)) {
this.addError('BR-DE-15', `Invoice line ${i + 1} is missing identifier`, `//cac:InvoiceLine[${i + 1}]`);
valid = false;
}
}
// German VAT ID format validation
const supplierVatId = this.getText('//cac:AccountingSupplierParty//cbc:CompanyID[../cac:TaxScheme/cbc:ID="VAT"]');
if (supplierVatId && supplierVatId.startsWith('DE') && !/^DE[0-9]{9}$/.test(supplierVatId)) {
this.addError('BR-DE-VAT', 'German VAT ID format is invalid (must be DE followed by 9 digits)', '//cac:AccountingSupplierParty//cbc:CompanyID');
valid = false;
}
return valid;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieHJlY2hudW5nLnZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2Zvcm1hdHMvdWJsL3hyZWNobnVuZy52YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFakU7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLGtCQUFtQixTQUFRLG1CQUFtQjtJQUN6RDs7T0FFRztJQUNPLGlCQUFpQjtRQUN6QixtQ0FBbUM7UUFDbkMsSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFFdEMsd0RBQXdEO1FBQ3hELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUM5RCxJQUFJLENBQUMsZUFBZSxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQy9ELElBQUksQ0FBQyxRQUFRLENBQ1gsZ0JBQWdCLEVBQ2hCLGtEQUFrRCxFQUNsRCx1QkFBdUIsQ0FDeEIsQ0FBQztZQUNGLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDaEIsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVEOztPQUVHO0lBQ08scUJBQXFCO1FBQzdCLHdDQUF3QztRQUN4QyxJQUFJLEtBQUssR0FBRyxLQUFLLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUUxQywrRUFBK0U7UUFDL0UsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsNkJBQTZCLENBQUMsRUFBRSxDQUFDO1lBQ3hGLElBQUksQ0FBQyxRQUFRLENBQ1gsU0FBUyxFQUNULHFEQUFxRCxFQUNyRCxvQkFBb0IsQ0FDckIsQ0FBQztZQUNGLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDaEIsQ0FBQztR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