@fin.cx/einvoice 7.1.0 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/einvoice.d.ts +10 -9
  3. package/dist_ts/einvoice.js +40 -10
  4. package/dist_ts/formats/base/base.decoder.d.ts +6 -6
  5. package/dist_ts/formats/base/base.decoder.js +1 -1
  6. package/dist_ts/formats/base/base.encoder.d.ts +4 -4
  7. package/dist_ts/formats/base/base.validator.d.ts +5 -0
  8. package/dist_ts/formats/base/base.validator.js +28 -1
  9. package/dist_ts/formats/cii/cii.decoder.d.ts +8 -7
  10. package/dist_ts/formats/cii/cii.decoder.js +8 -9
  11. package/dist_ts/formats/cii/cii.encoder.d.ts +7 -7
  12. package/dist_ts/formats/cii/cii.encoder.js +5 -5
  13. package/dist_ts/formats/cii/cii.validator.d.ts +11 -0
  14. package/dist_ts/formats/cii/cii.validator.js +35 -1
  15. package/dist_ts/formats/cii/facturx/facturx.decoder.d.ts +6 -4
  16. package/dist_ts/formats/cii/facturx/facturx.decoder.js +14 -21
  17. package/dist_ts/formats/cii/facturx/facturx.encoder.d.ts +5 -5
  18. package/dist_ts/formats/cii/facturx/facturx.encoder.js +14 -10
  19. package/dist_ts/formats/cii/facturx/facturx.validator.js +8 -4
  20. package/dist_ts/formats/cii/zugferd/zugferd.decoder.d.ts +6 -4
  21. package/dist_ts/formats/cii/zugferd/zugferd.decoder.js +14 -21
  22. package/dist_ts/formats/cii/zugferd/zugferd.encoder.d.ts +4 -4
  23. package/dist_ts/formats/cii/zugferd/zugferd.encoder.js +13 -9
  24. package/dist_ts/formats/cii/zugferd/zugferd.v1.decoder.d.ts +6 -4
  25. package/dist_ts/formats/cii/zugferd/zugferd.v1.decoder.js +14 -21
  26. package/dist_ts/formats/cii/zugferd/zugferd.validator.js +5 -4
  27. package/dist_ts/formats/converters/xml-to-einvoice.converter.d.ts +5 -0
  28. package/dist_ts/formats/converters/xml-to-einvoice.converter.js +11 -2
  29. package/dist_ts/formats/semantic/semantic.adapter.d.ts +0 -8
  30. package/dist_ts/formats/semantic/semantic.adapter.js +5 -34
  31. package/dist_ts/formats/ubl/en16931.ubl.validator.js +5 -1
  32. package/dist_ts/formats/ubl/generic/ubl.encoder.d.ts +4 -4
  33. package/dist_ts/formats/ubl/generic/ubl.encoder.js +13 -14
  34. package/dist_ts/formats/ubl/ubl.decoder.d.ts +8 -7
  35. package/dist_ts/formats/ubl/ubl.decoder.js +11 -8
  36. package/dist_ts/formats/ubl/ubl.encoder.d.ts +7 -7
  37. package/dist_ts/formats/ubl/ubl.encoder.js +5 -5
  38. package/dist_ts/formats/ubl/ubl.validator.d.ts +11 -0
  39. package/dist_ts/formats/ubl/ubl.validator.js +35 -1
  40. package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.d.ts +6 -4
  41. package/dist_ts/formats/ubl/xrechnung/xrechnung.decoder.js +14 -21
  42. package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.d.ts +4 -4
  43. package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.js +6 -6
  44. package/dist_ts/formats/utils/document.typecode.d.ts +18 -0
  45. package/dist_ts/formats/utils/document.typecode.js +52 -0
  46. package/dist_ts/formats/utils/unit.codes.d.ts +40 -0
  47. package/dist_ts/formats/utils/unit.codes.js +193 -0
  48. package/dist_ts/formats/validation/codelist.validator.d.ts +1 -1
  49. package/dist_ts/formats/validation/codelist.validator.js +10 -12
  50. package/dist_ts/formats/validation/en16931.business-rules.validator.js +13 -13
  51. package/dist_ts/formats/validation/validation.types.d.ts +0 -4
  52. package/dist_ts/formats/validation/validation.types.js +1 -28
  53. package/dist_ts/index.d.ts +7 -1
  54. package/dist_ts/index.js +11 -1
  55. package/dist_ts/interfaces/common.d.ts +11 -0
  56. package/dist_ts_install/download-schematron.js +3 -5
  57. package/package.json +7 -7
  58. package/readme.md +99 -2
  59. package/ts/00_commitinfo_data.ts +1 -1
  60. package/ts/einvoice.ts +59 -18
  61. package/ts/formats/base/base.decoder.ts +6 -6
  62. package/ts/formats/base/base.encoder.ts +4 -4
  63. package/ts/formats/base/base.validator.ts +28 -0
  64. package/ts/formats/cii/cii.decoder.ts +18 -14
  65. package/ts/formats/cii/cii.encoder.ts +11 -11
  66. package/ts/formats/cii/cii.validator.ts +47 -0
  67. package/ts/formats/cii/facturx/facturx.decoder.ts +23 -23
  68. package/ts/formats/cii/facturx/facturx.encoder.ts +20 -16
  69. package/ts/formats/cii/facturx/facturx.validator.ts +9 -3
  70. package/ts/formats/cii/zugferd/zugferd.decoder.ts +23 -23
  71. package/ts/formats/cii/zugferd/zugferd.encoder.ts +21 -17
  72. package/ts/formats/cii/zugferd/zugferd.v1.decoder.ts +23 -23
  73. package/ts/formats/cii/zugferd/zugferd.validator.ts +4 -3
  74. package/ts/formats/converters/xml-to-einvoice.converter.ts +11 -1
  75. package/ts/formats/semantic/semantic.adapter.ts +4 -35
  76. package/ts/formats/ubl/en16931.ubl.validator.ts +6 -0
  77. package/ts/formats/ubl/generic/ubl.encoder.ts +29 -24
  78. package/ts/formats/ubl/ubl.decoder.ts +23 -14
  79. package/ts/formats/ubl/ubl.encoder.ts +11 -11
  80. package/ts/formats/ubl/ubl.validator.ts +47 -0
  81. package/ts/formats/ubl/xrechnung/xrechnung.decoder.ts +23 -23
  82. package/ts/formats/ubl/xrechnung/xrechnung.encoder.ts +10 -10
  83. package/ts/formats/utils/document.typecode.ts +62 -0
  84. package/ts/formats/utils/unit.codes.ts +215 -0
  85. package/ts/formats/validation/codelist.validator.ts +12 -23
  86. package/ts/formats/validation/en16931.business-rules.validator.ts +13 -13
  87. package/ts/formats/validation/validation.types.ts +0 -28
  88. package/ts/index.ts +25 -0
  89. package/ts/interfaces/common.ts +17 -0
  90. package/ts/readme.md +3 -2
@@ -62,33 +62,6 @@ export const CodeLists = {
62
62
  ['58', 'SEPA credit transfer'],
63
63
  ['59', 'SEPA direct debit']
64
64
  ])
65
- },
66
- // UNECE Rec 20 Unit codes (subset)
67
- UNECERec20: {
68
- version: '2021',
69
- codes: new Map([
70
- ['C62', 'One (unit)'],
71
- ['DAY', 'Day'],
72
- ['HAR', 'Hectare'],
73
- ['HUR', 'Hour'],
74
- ['KGM', 'Kilogram'],
75
- ['KTM', 'Kilometre'],
76
- ['KWH', 'Kilowatt hour'],
77
- ['LS', 'Lump sum'],
78
- ['LTR', 'Litre'],
79
- ['MIN', 'Minute'],
80
- ['MMT', 'Millimetre'],
81
- ['MON', 'Month'],
82
- ['MTK', 'Square metre'],
83
- ['MTQ', 'Cubic metre'],
84
- ['MTR', 'Metre'],
85
- ['NAR', 'Number of articles'],
86
- ['NPR', 'Number of pairs'],
87
- ['P1', 'Percent'],
88
- ['SET', 'Set'],
89
- ['TNE', 'Tonne (metric ton)'],
90
- ['WEE', 'Week']
91
- ])
92
65
  }
93
66
  };
94
67
  // Business Term (BT) and Business Group (BG) mappings
@@ -178,4 +151,4 @@ export const SemanticModel = {
178
151
  BG31: 'Item information',
179
152
  BG32: 'Item attributes'
180
153
  };
181
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi50eXBlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2Zvcm1hdHMvdmFsaWRhdGlvbi92YWxpZGF0aW9uLnR5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBcUZILHdCQUF3QjtBQUN4QixNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUc7SUFDdkIsMEJBQTBCO0lBQzFCLE9BQU8sRUFBRTtRQUNQLE9BQU8sRUFBRSxNQUFNO1FBQ2YsS0FBSyxFQUFFLElBQUksR0FBRyxDQUFDO1lBQ2IsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSztZQUNwRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLO1NBQ3JFLENBQUM7S0FDSDtJQUVELG1DQUFtQztJQUNuQyxPQUFPLEVBQUU7UUFDUCxPQUFPLEVBQUUsTUFBTTtRQUNmLEtBQUssRUFBRSxJQUFJLEdBQUcsQ0FBQztZQUNiLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSTtZQUN0RSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUk7WUFDdEUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFB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
154
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi50eXBlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2Zvcm1hdHMvdmFsaWRhdGlvbi92YWxpZGF0aW9uLnR5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBcUZILHdCQUF3QjtBQUN4QixNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUc7SUFDdkIsMEJBQTBCO0lBQzFCLE9BQU8sRUFBRTtRQUNQLE9BQU8sRUFBRSxNQUFNO1FBQ2YsS0FBSyxFQUFFLElBQUksR0FBRyxDQUFDO1lBQ2IsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSztZQUNwRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLO1NBQ3JFLENBQUM7S0FDSDtJQUVELG1DQUFtQztJQUNuQyxPQUFPLEVBQUU7UUFDUCxPQUFPLEVBQUUsTUFBTTtRQUNmLEtBQUssRUFBRSxJQUFJLEdBQUcsQ0FBQztZQUNiLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSTtZQUN0RSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUk7WUFDdEUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFB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
@@ -16,6 +16,9 @@ import { PDFEmbedder } from './formats/pdf/pdf.embedder.js';
16
16
  import { PDFExtractor } from './formats/pdf/pdf.extractor.js';
17
17
  import { BaseXMLExtractor, StandardXMLExtractor, AssociatedFilesExtractor, TextXMLExtractor } from './formats/pdf/extractors/index.js';
18
18
  import { FormatDetector } from './formats/utils/format.detector.js';
19
+ import { getAccountingDocType, getDocumentTypeCode, isAccountingDocType } from './formats/utils/document.typecode.js';
20
+ import { en16931UnitCodeList, isEn16931UnitCode } from './formats/utils/unit.codes.js';
21
+ import type { IEn16931UnitCodeList } from './formats/utils/unit.codes.js';
19
22
  import { EInvoiceError, EInvoiceParsingError, EInvoiceValidationError, EInvoicePDFError, EInvoiceFormatError, ErrorRecovery, ErrorContext } from './errors.js';
20
23
  import { FacturXDecoder } from './formats/cii/facturx/facturx.decoder.js';
21
24
  import { FacturXEncoder } from './formats/cii/facturx/facturx.encoder.js';
@@ -24,7 +27,7 @@ import { ZUGFeRDDecoder } from './formats/cii/zugferd/zugferd.decoder.js';
24
27
  import { ZUGFeRDEncoder } from './formats/cii/zugferd/zugferd.encoder.js';
25
28
  import { ZUGFeRDValidator } from './formats/cii/zugferd/zugferd.validator.js';
26
29
  import { ZUGFeRDV1Decoder } from './formats/cii/zugferd/zugferd.v1.decoder.js';
27
- export type { TInvoice, TCreditNote, TDebitNote, TContact, TLetterEnvelope, TDocumentEnvelope, IPdf, ValidationError, ValidationResult, IValidator, ExportFormat, EInvoiceOptions } from './interfaces/common.js';
30
+ export type { TInvoice, TCreditNote, TDebitNote, TSelfBilledInvoice, TAccountingDoc, TAccountingDocType, TAccountingDocEnvelope, TInvoiceDocument, TContact, TLetterEnvelope, TDocumentEnvelope, IPdf, ValidationError, ValidationResult, IValidator, ExportFormat, EInvoiceOptions } from './interfaces/common.js';
28
31
  export { ValidationLevel, InvoiceFormat } from './interfaces/common.js';
29
32
  export { common as interfaces };
30
33
  export { EInvoice };
@@ -36,6 +39,9 @@ export { FacturXDecoder, FacturXEncoder, FacturXValidator };
36
39
  export { ZUGFeRDDecoder, ZUGFeRDEncoder, ZUGFeRDValidator, ZUGFeRDV1Decoder };
37
40
  export { PDFEmbedder, PDFExtractor, BaseXMLExtractor, StandardXMLExtractor, AssociatedFilesExtractor, TextXMLExtractor };
38
41
  export { FormatDetector };
42
+ export { getAccountingDocType, getDocumentTypeCode, isAccountingDocType };
43
+ export { en16931UnitCodeList, isEn16931UnitCode };
44
+ export type { IEn16931UnitCodeList };
39
45
  export { EInvoiceError, EInvoiceParsingError, EInvoiceValidationError, EInvoicePDFError, EInvoiceFormatError, ErrorRecovery, ErrorContext };
40
46
  /**
41
47
  * Validates an XML string against the appropriate format rules
package/dist_ts/index.js CHANGED
@@ -24,6 +24,10 @@ import { PDFExtractor } from './formats/pdf/pdf.extractor.js';
24
24
  import { BaseXMLExtractor, StandardXMLExtractor, AssociatedFilesExtractor, TextXMLExtractor } from './formats/pdf/extractors/index.js';
25
25
  // Import format detector
26
26
  import { FormatDetector } from './formats/utils/format.detector.js';
27
+ // Import the document type code table (BT-3)
28
+ import { getAccountingDocType, getDocumentTypeCode, isAccountingDocType } from './formats/utils/document.typecode.js';
29
+ // Import the EN 16931 unit code list (BR-CL-23)
30
+ import { en16931UnitCodeList, isEn16931UnitCode } from './formats/utils/unit.codes.js';
27
31
  // Import error classes
28
32
  import { EInvoiceError, EInvoiceParsingError, EInvoiceValidationError, EInvoicePDFError, EInvoiceFormatError, ErrorRecovery, ErrorContext } from './errors.js';
29
33
  // Import Factur-X implementation
@@ -56,6 +60,12 @@ export { ZUGFeRDDecoder, ZUGFeRDEncoder, ZUGFeRDValidator, ZUGFeRDV1Decoder };
56
60
  export { PDFEmbedder, PDFExtractor, BaseXMLExtractor, StandardXMLExtractor, AssociatedFilesExtractor, TextXMLExtractor };
57
61
  // Export format detector
58
62
  export { FormatDetector };
63
+ // Export the document type code table, so a consumer that reads or writes BT-3
64
+ // itself does not need a second copy of it
65
+ export { getAccountingDocType, getDocumentTypeCode, isAccountingDocType };
66
+ // Export the EN 16931 unit code list (BR-CL-23: UN/ECE Recommendation 20 with the
67
+ // Recommendation 21 extension), so a consumer can check a unit before it builds a document
68
+ export { en16931UnitCodeList, isEn16931UnitCode };
59
69
  // Export error classes
60
70
  export { EInvoiceError, EInvoiceParsingError, EInvoiceValidationError, EInvoicePDFError, EInvoiceFormatError, ErrorRecovery, ErrorContext };
61
71
  /**
@@ -88,4 +98,4 @@ export function validateXml(xml, level = common.ValidationLevel.SYNTAX) {
88
98
  export function createEInvoice() {
89
99
  return new EInvoice();
90
100
  }
91
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxvQkFBb0I7QUFDcEIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV6QyxvQkFBb0I7QUFDcEIsT0FBTyxLQUFLLE1BQU0sTUFBTSx3QkFBd0IsQ0FBQztBQUVqRCxtQkFBbUI7QUFDbkIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUN4RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUU1RSxzQkFBc0I7QUFDdEIsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzdELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM3RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFakUsMEJBQTBCO0FBQzFCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFbEUsMEJBQTBCO0FBQzFCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFbEUsdUJBQXVCO0FBQ3ZCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDOUQsT0FBTyxFQUNMLGdCQUFnQixFQUNoQixvQkFBb0IsRUFDcEIsd0JBQXdCLEVBQ3hCLGdCQUFnQixFQUNqQixNQUFNLG1DQUFtQyxDQUFDO0FBRTNDLHlCQUF5QjtBQUN6QixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFFcEUsdUJBQXVCO0FBQ3ZCLE9BQU8sRUFDTCxhQUFhLEVBQ2Isb0JBQW9CLEVBQ3BCLHVCQUF1QixFQUN2QixnQkFBZ0IsRUFDaEIsbUJBQW1CLEVBQ25CLGFBQWEsRUFDYixZQUFZLEVBQ2IsTUFBTSxhQUFhLENBQUM7QUFFckIsaUNBQWlDO0FBQ2pDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDMUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFFOUUsZ0NBQWdDO0FBQ2hDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDMUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDOUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUF1Qi9FLE9BQU8sRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFeEUscUNBQXFDO0FBQ3JDLE9BQU8sRUFBRSxNQUFNLElBQUksVUFBVSxFQUFFLENBQUM7QUFFaEMsb0JBQW9CO0FBQ3BCLE9BQU8sRUFBRSxRQUFRLEVBQUUsQ0FBQztBQUVwQixtQkFBbUI7QUFDbkIsT0FBTyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQztBQUU1RCxzQkFBc0I7QUFDdEIsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLENBQUM7QUFFbkQsMEJBQTBCO0FBQzFCLE9BQU8sRUFBRSxjQUFjLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLENBQUM7QUFFNUQsMEJBQTBCO0FBQzFCLE9BQU8sRUFBRSxjQUFjLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLENBQUM7QUFFNUQsaUNBQWlDO0FBQ2pDLE9BQU8sRUFBRSxjQUFjLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLENBQUM7QUFFNUQsZ0NBQWdDO0FBQ2hDLE9BQU8sRUFBRSxjQUFjLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLGdCQUFnQixFQUFFLENBQUM7QUFFOUUsdUJBQXVCO0FBQ3ZCLE9BQU8sRUFDTCxXQUFXLEVBQ1gsWUFBWSxFQUNaLGdCQUFnQixFQUNoQixvQkFBb0IsRUFDcEIsd0JBQXdCLEVBQ3hCLGdCQUFnQixFQUNqQixDQUFDO0FBRUYseUJBQXlCO0FBQ3pCLE9BQU8sRUFBRSxjQUFjLEVBQUUsQ0FBQztBQUUxQix1QkFBdUI7QUFDdkIsT0FBTyxFQUNMLGFBQWEsRUFDYixvQkFBb0IsRUFDcEIsdUJBQXVCLEVBQ3ZCLGdCQUFnQixFQUNoQixtQkFBbUIsRUFDbkIsYUFBYSxFQUNiLFlBQVksRUFDYixDQUFDO0FBRUY7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsV0FBVyxDQUN6QixHQUFXLEVBQ1gsUUFBZ0MsTUFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNO0lBRTdELElBQUksQ0FBQztRQUNILE1BQU0sU0FBUyxHQUFHLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN4RCxPQUFPLFNBQVMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixNQUFNLFlBQVksR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDNUUsT0FBTztZQUNMLEtBQUssRUFBRSxLQUFLO1lBQ1osTUFBTSxFQUFFLENBQUM7b0JBQ1AsSUFBSSxFQUFFLFdBQVc7b0JBQ2pCLE9BQU8sRUFBRSxxQkFBcUIsWUFBWSxFQUFFO2lCQUM3QyxDQUFDO1lBQ0YsS0FBSztTQUNOLENBQUM7SUFDSixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxjQUFjO0lBQzVCLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztBQUN4QixDQUFDIn0=
101
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxvQkFBb0I7QUFDcEIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV6QyxvQkFBb0I7QUFDcEIsT0FBTyxLQUFLLE1BQU0sTUFBTSx3QkFBd0IsQ0FBQztBQUVqRCxtQkFBbUI7QUFDbkIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUN4RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUU1RSxzQkFBc0I7QUFDdEIsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzdELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM3RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFakUsMEJBQTBCO0FBQzFCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFbEUsMEJBQTBCO0FBQzFCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFbEUsdUJBQXVCO0FBQ3ZCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDOUQsT0FBTyxFQUNMLGdCQUFnQixF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
@@ -72,9 +72,20 @@ export interface IPdf {
72
72
  };
73
73
  buffer: Uint8Array;
74
74
  }
75
+ import type { TInvoice, TDebitNote, TSelfBilledInvoice } from '@tsclass/tsclass/dist_ts/finance/index.js';
75
76
  export type { TInvoice } from '@tsclass/tsclass/dist_ts/finance/index.js';
76
77
  export type { TCreditNote } from '@tsclass/tsclass/dist_ts/finance/index.js';
77
78
  export type { TDebitNote } from '@tsclass/tsclass/dist_ts/finance/index.js';
79
+ export type { TSelfBilledInvoice } from '@tsclass/tsclass/dist_ts/finance/index.js';
80
+ export type { TAccountingDoc } from '@tsclass/tsclass/dist_ts/finance/index.js';
81
+ export type { TAccountingDocType } from '@tsclass/tsclass/dist_ts/finance/index.js';
82
+ export type { TAccountingDocEnvelope } from '@tsclass/tsclass/dist_ts/finance/index.js';
83
+ /**
84
+ * The accounting documents that are written as an invoice document: the UBL
85
+ * `Invoice` root and the CII type codes of the invoice family. Only a credit
86
+ * note has a document shape of its own.
87
+ */
88
+ export type TInvoiceDocument = TInvoice | TDebitNote | TSelfBilledInvoice;
78
89
  export type { TContact } from '@tsclass/tsclass/dist_ts/business/index.js';
79
90
  export type { TLetterEnvelope } from '@tsclass/tsclass/dist_ts/business/index.js';
80
91
  export type { TDocumentEnvelope } from '@tsclass/tsclass/dist_ts/business/index.js';
@@ -60,10 +60,8 @@ async function main() {
60
60
  });
61
61
  console.log('\n✅ Schematron download complete!');
62
62
  }
63
- // Run if executed directly. tsrun, which the npm script uses, leaves process.argv
64
- // empty, so a plain comparison against argv[1] would never match and the script
65
- // would exit silently without downloading anything.
66
- const isEntryPoint = !process.argv[1] || import.meta.url === `file://${process.argv[1]}`;
63
+ // Run if executed directly
64
+ const isEntryPoint = import.meta.url === `file://${process.argv[1]}`;
67
65
  if (isEntryPoint) {
68
66
  main().catch(error => {
69
67
  console.error('❌ Script failed:', error);
@@ -71,4 +69,4 @@ if (isEntryPoint) {
71
69
  });
72
70
  }
73
71
  export default main;
74
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG93bmxvYWQtc2NoZW1hdHJvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2luc3RhbGwvZG93bmxvYWQtc2NoZW1hdHJvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsOEJBQThCO0FBRTlCOztHQUVHO0FBRUgsTUFBTSw4QkFBOEIsR0FBRyx3REFBd0QsQ0FBQztBQUVoRyxLQUFLLFVBQVUsZ0JBQWdCO0lBQzdCLE1BQU0sRUFBRSxvQkFBb0IsRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLDhCQUE4QixDQUFDLENBQUM7SUFDOUUsTUFBTSxVQUFVLEdBQUcsSUFBSSxvQkFBb0IsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0lBQzVFLE1BQU0sVUFBVSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQzlCLE9BQU8sVUFBVSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxLQUFLLFVBQVUsSUFBSTtJQUNqQixPQUFPLENBQUMsR0FBRyxDQUFDLHNDQUFzQyxDQUFDLENBQUM7SUFFcEQsTUFBTSxVQUFVLEdBQUcsTUFBTSxnQkFBZ0IsRUFBRSxDQUFDO0lBRTVDLG9DQUFvQztJQUNwQyxPQUFPLENBQUMsR0FBRyxDQUFDLDRDQUE0QyxDQUFDLENBQUM7SUFDMUQsSUFBSSxDQUFDO1FBQ0gsTUFBTSxZQUFZLEdBQUcsTUFBTSxVQUFVLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbEUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsWUFBWSxDQUFDLE1BQU0sZ0JBQWdCLENBQUMsQ0FBQztRQUNqRSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsTUFBTSxZQUFZLEdBQUcsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FB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
72
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG93bmxvYWQtc2NoZW1hdHJvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2luc3RhbGwvZG93bmxvYWQtc2NoZW1hdHJvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsOEJBQThCO0FBRTlCOztHQUVHO0FBRUgsTUFBTSw4QkFBOEIsR0FBRyx3REFBd0QsQ0FBQztBQUVoRyxLQUFLLFVBQVUsZ0JBQWdCO0lBQzdCLE1BQU0sRUFBRSxvQkFBb0IsRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLDhCQUE4QixDQUFDLENBQUM7SUFDOUUsTUFBTSxVQUFVLEdBQUcsSUFBSSxvQkFBb0IsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0lBQzVFLE1BQU0sVUFBVSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQzlCLE9BQU8sVUFBVSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxLQUFLLFVBQVUsSUFBSTtJQUNqQixPQUFPLENBQUMsR0FBRyxDQUFDLHNDQUFzQyxDQUFDLENBQUM7SUFFcEQsTUFBTSxVQUFVLEdBQUcsTUFBTSxnQkFBZ0IsRUFBRSxDQUFDO0lBRTVDLG9DQUFvQztJQUNwQyxPQUFPLENBQUMsR0FBRyxDQUFDLDRDQUE0QyxDQUFDLENBQUM7SUFDMUQsSUFBSSxDQUFDO1FBQ0gsTUFBTSxZQUFZLEdBQUcsTUFBTSxVQUFVLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbEUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsWUFBWSxDQUFDLE1BQU0sZ0JBQWdCLENBQUMsQ0FBQztRQUNqRSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsTUFBTSxZQUFZLEdBQUcsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FB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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fin.cx/einvoice",
3
- "version": "7.1.0",
3
+ "version": "8.1.0",
4
4
  "private": false,
5
5
  "description": "A TypeScript module for creating, manipulating, and embedding XML data within PDF files specifically tailored for electronic invoice (einvoice) packages.",
6
6
  "main": "dist_ts/index.js",
@@ -13,12 +13,12 @@
13
13
  "author": "Task Venture Capital GmbH",
14
14
  "license": "MIT",
15
15
  "devDependencies": {
16
- "@git.zone/tsbuild": "^4.4.2",
17
- "@git.zone/tsbundle": "^2.13.0",
18
- "@git.zone/tsrun": "^2.0.6",
19
- "@git.zone/tstest": "^6.0.0",
16
+ "@git.zone/tsbuild": "^5.0.0",
17
+ "@git.zone/tsbundle": "^2.15.0",
18
+ "@git.zone/tsrun": "^3.0.0",
19
+ "@git.zone/tstest": "^6.2.0",
20
20
  "@push.rocks/smartfile": "^13.1.3",
21
- "@types/node": "^26.4.1"
21
+ "@types/node": "^26.6.1"
22
22
  },
23
23
  "dependencies": {
24
24
  "@push.rocks/smartxml": "^2.1.0",
@@ -67,7 +67,7 @@
67
67
  ],
68
68
  "scripts": {
69
69
  "test": "pnpm run test:unit",
70
- "test:unit": "tstest test/test.cii-xrechnung.node.ts --verbose --logfile --timeout 60 && tstest test/test.einvoice.ts --verbose --logfile --timeout 60 && tstest test/test.decimal.ts --verbose --logfile --timeout 60 && tstest test/test.decimal-currency-calculator.ts --verbose --logfile --timeout 60 && tstest test/test.currency-utils.ts --verbose --logfile --timeout 60 && tstest test/test.en16931-validators.ts --verbose --logfile --timeout 60 && tstest test/test.schematron-validator.ts --verbose --logfile --timeout 60",
70
+ "test:unit": "tstest test/test.cii-xrechnung.node.ts --verbose --logfile --timeout 60 && tstest test/test.einvoice.ts --verbose --logfile --timeout 60 && tstest test/test.decimal.ts --verbose --logfile --timeout 60 && tstest test/test.decimal-currency-calculator.ts --verbose --logfile --timeout 60 && tstest test/test.currency-utils.ts --verbose --logfile --timeout 60 && tstest test/test.en16931-validators.ts --verbose --logfile --timeout 60 && tstest test/test.schematron-validator.ts --verbose --logfile --timeout 60 && tstest test/test.xrechnung-creditnote.node.ts --verbose --logfile --timeout 60 && tstest test/test.accountingdoc-types.node.ts --verbose --logfile --timeout 60 && tstest test/test.en16931-unitcodes.node.ts --verbose --logfile --timeout 60 && tstest test/test.en16931-lineunit.node.ts --verbose --logfile --timeout 60",
71
71
  "test:format": "tstest test/test.format-detection.ts --verbose --logfile --timeout 60",
72
72
  "test:corpus": "tstest test/suite/einvoice_corpus-validation/ --verbose --logfile --timeout 60",
73
73
  "test:performance": "NODE_OPTIONS=--expose-gc tstest test/suite/einvoice_performance/ --verbose --logfile --timeout 60",
package/readme.md CHANGED
@@ -147,6 +147,58 @@ invoice.items = [
147
147
  const xml = await invoice.exportXml('facturx');
148
148
  ```
149
149
 
150
+ ### Credit notes, debit notes and self-billed invoices
151
+
152
+ One class holds every accounting document. `accountingDocType` is the tsclass
153
+ `TAccountingDocType` and defaults to `invoice`; `invoiceType` is an alias for it.
154
+
155
+ ```ts
156
+ import { EInvoice } from '@fin.cx/einvoice';
157
+
158
+ const creditNote = new EInvoice();
159
+ creditNote.accountingDocType = 'creditnote';
160
+ creditNote.relatedDocuments = [{ relationType: 'corrects', documentId: 'INV-2026-001' }];
161
+ ```
162
+
163
+ | `accountingDocType` | Type code (BT-3) | UBL / XRechnung | CII / Factur-X / ZUGFeRD |
164
+ | --- | --- | --- | --- |
165
+ | `invoice` | 380 | `Invoice` with `cbc:InvoiceTypeCode` | `ram:TypeCode` |
166
+ | `creditnote` | 381 | `CreditNote` with `cbc:CreditNoteTypeCode`, `cac:CreditNoteLine`, no `cbc:DueDate` | `ram:TypeCode` |
167
+ | `debitnote` | 383 | `Invoice` with `cbc:InvoiceTypeCode` | `ram:TypeCode` |
168
+ | `self-billed-invoice` | 389 | `Invoice` with `cbc:InvoiceTypeCode` | `ram:TypeCode` |
169
+
170
+ Import reads the type back from the code in UBL, XRechnung, Factur-X and
171
+ ZUGFeRD v2: 383 is a debit note, 389 a self-billed invoice, the credit note
172
+ related codes of EN16931 rule BR-CL-01 (381, 396, 261, ...) a credit note, and
173
+ every other code an invoice, which covers 380, 384 and the invoice related codes
174
+ the envelope has no name for (326, 386, 875, ...). A UBL `CreditNote` root is
175
+ always a credit note. The code itself is not kept: a 384 that is exported again
176
+ is written as 380. A value outside `TAccountingDocType`, a missing one included,
177
+ is refused with an `EInvoiceFormatError` by the `invoiceType` setter and at export.
178
+
179
+ ZUGFeRD v1 is the one exception: a v1 document always reads as `invoice`,
180
+ whatever its type code says, because `ZUGFeRDV1Decoder` does not read the v1
181
+ header at all. This is a known defect and will be fixed separately; until then
182
+ do not rely on the type of an imported ZUGFeRD v1 document.
183
+
184
+ An `EInvoice` is a `TAccountingDoc`, not a `TInvoice`: narrow on
185
+ `accountingDocType` where a function takes one document type only.
186
+
187
+ The table itself is exported, so an application that has to read or write BT-3
188
+ on its own does not need a second copy of it:
189
+
190
+ ```ts
191
+ import {
192
+ getAccountingDocType,
193
+ getDocumentTypeCode,
194
+ isAccountingDocType,
195
+ } from '@fin.cx/einvoice';
196
+
197
+ getDocumentTypeCode('debitnote'); // '383'; throws EInvoiceFormatError for an unknown type
198
+ getAccountingDocType('396'); // 'creditnote'; an unlisted or empty code is 'invoice'
199
+ isAccountingDocType('proforma'); // false
200
+ ```
201
+
150
202
  ### Validate at different levels
151
203
 
152
204
  ```ts
@@ -166,6 +218,48 @@ console.log(business.errors);
166
218
  console.log(business.warnings ?? []);
167
219
  ```
168
220
 
221
+ ### Unit codes (BR-CL-23)
222
+
223
+ A line's `unitType` is written as the unit code of the invoiced quantity (BT-130), so it has to
224
+ be a code EN 16931 admits: UN/ECE Recommendation 20 with the Recommendation 21 extension, as
225
+ business rule BR-CL-23 lists them. Words such as `hours` or `HOURS` are not codes; `HUR` (hour),
226
+ `DAY` (day), `MON` (month), `H87` (piece), `C62` (one), `LS` (lump sum) and package codes such as
227
+ `XPP` are.
228
+
229
+ The business level checks the rule on every document, without a feature flag: the unit codes of
230
+ the invoiced, credited, billed and base quantities (BT-130, BT-150) of UBL, XRechnung, Factur-X and
231
+ ZUGFeRD documents, and the lines of an invoice built in code. A failure is an error with the code
232
+ `BR-CL-23` and the location of the attribute or line. Whitespace around a code in the XML is
233
+ ignored, as in the official rule; the list comparison itself is exact.
234
+
235
+ The list is exported, so an application can check a unit before it builds a document:
236
+
237
+ ```ts
238
+ import { en16931UnitCodeList, isEn16931UnitCode } from '@fin.cx/einvoice';
239
+
240
+ isEn16931UnitCode('HUR'); // true
241
+ isEn16931UnitCode('HOURS'); // false
242
+ isEn16931UnitCode('hur'); // false: codes are compared exactly
243
+ en16931UnitCodeList.codes.length; // 2162, a frozen array in the order of the rule
244
+ en16931UnitCodeList.source; // 'EN 16931 validation artefacts (CEN/TC 434) validation-1.3.16'
245
+ ```
246
+
247
+ The 2162 codes are the BR-CL-23 list of the EN 16931 validation artefacts of CEN/TC 434, release
248
+ validation-1.3.16 (https://github.com/ConnectingEurope/eInvoicing-EN16931), reproduced unaltered.
249
+ The source files are licensed under EUPL-1.2; the codes are those of UN/ECE Recommendations 20 and
250
+ 21.
251
+ `createItem()` gives a line without a unit the code `C62` (one).
252
+
253
+ A line needs a unit (BR-23). A document whose quantity carries no `unitCode` reads with an empty
254
+ `unitType`, never with a unit it did not state, and the business level reports BR-23 with the
255
+ location of the line. An empty `unitType` is written without the attribute, so the unit stays
256
+ absent when the document is exported again.
257
+
258
+ A present but empty attribute, `unitCode=""`, fails BR-CL-23, as in the official rule. It reads
259
+ with an empty `unitType` too, so after a round trip the document fails BR-23 instead. At the
260
+ business level the `EN16931_BUSINESS_RULES` and `CODE_LIST_VALIDATION` flags leave both unit rules
261
+ to the document check, so each line is reported once.
262
+
169
263
  ### Convert between supported XML targets
170
264
 
171
265
  ```ts
@@ -217,7 +311,8 @@ required archival profile.
217
311
  - XRechnung import routes UBL and CII by the namespace-qualified XML root.
218
312
  Missing or invalid document-level invoice IDs and issue dates are rejected.
219
313
  - `FatturaPA` should be documented as detection-only right now.
220
- - `creditnote` / `debitnote` handling exists in parts of the lower-level code, but the high-level `invoiceType` setter on `EInvoice` only accepts `'invoice'`.
314
+ - Credit notes, debit notes and self-billed invoices share the `EInvoice` class; see the type code table above. Credit and debit amounts are written as given, the encoders do not change signs.
315
+ - ZUGFeRD v1 input is detected and routed, but the v1 decoder does not read the v1 header, so such a document always arrives as an `invoice`. Known defect, to be fixed separately.
221
316
 
222
317
  ## Public API overview
223
318
 
@@ -226,6 +321,8 @@ Top-level exports from `@fin.cx/einvoice` include:
226
321
  - `EInvoice`
227
322
  - `createEInvoice()`
228
323
  - `validateXml(xml, level?)`
324
+ - `getDocumentTypeCode(accountingDocType)`, `getAccountingDocType(typeCode)`, `isAccountingDocType(value)`
325
+ - `en16931UnitCodeList`, `isEn16931UnitCode(value)` (the BR-CL-23 unit code list)
229
326
  - `FormatDetector`
230
327
  - `PDFExtractor`, `PDFEmbedder`
231
328
  - `DecoderFactory`, `EncoderFactory`, `ValidatorFactory`
@@ -233,7 +330,7 @@ Top-level exports from `@fin.cx/einvoice` include:
233
330
  - `UBLBase*` and `CIIBase*` extension classes
234
331
  - `FacturX*` and `ZUGFeRD*` format-specific classes
235
332
  - `ValidationLevel`, `InvoiceFormat`
236
- - exported types like `TInvoice`, `ValidationResult`, `ValidationError`, `ExportFormat`, `IPdf`, `EInvoiceOptions`
333
+ - exported types like `TAccountingDoc`, `TAccountingDocType`, `TInvoice`, `TCreditNote`, `TDebitNote`, `TSelfBilledInvoice`, `IEn16931UnitCodeList`, `ValidationResult`, `ValidationError`, `ExportFormat`, `IPdf`, `EInvoiceOptions`
237
334
 
238
335
  ## Validation resources and install-time behavior
239
336
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@fin.cx/einvoice',
6
- version: '7.1.0',
6
+ version: '8.1.0',
7
7
  description: 'A TypeScript module for creating, manipulating, and embedding XML data within PDF files specifically tailored for electronic invoice (einvoice) packages.'
8
8
  }
package/ts/einvoice.ts CHANGED
@@ -1,9 +1,18 @@
1
1
  import * as plugins from './plugins.js';
2
2
 
3
3
  import type { business, finance } from '@tsclass/tsclass';
4
- import type { TInvoice, TAccountingDocItem } from '@tsclass/tsclass/dist_ts/finance/index.js';
4
+ import type { TAccountingDocItem } from '@tsclass/tsclass/dist_ts/finance/index.js';
5
5
  import { InvoiceFormat, ValidationLevel } from './interfaces/common.js';
6
- import type { ValidationResult, ValidationError, EInvoiceOptions, IPdf, ExportFormat } from './interfaces/common.js';
6
+ import type {
7
+ ValidationResult,
8
+ ValidationError,
9
+ EInvoiceOptions,
10
+ IPdf,
11
+ ExportFormat,
12
+ TAccountingDoc,
13
+ TAccountingDocEnvelope,
14
+ TAccountingDocType,
15
+ } from './interfaces/common.js';
7
16
 
8
17
  // Import error classes
9
18
  import {
@@ -22,6 +31,8 @@ import { ValidatorFactory } from './formats/factories/validator.factory.js';
22
31
 
23
32
  // Import format detector
24
33
  import { FormatDetector } from './formats/utils/format.detector.js';
34
+ import { isAccountingDocType } from './formats/utils/document.typecode.js';
35
+ import { meetsUnitCodeRule } from './formats/utils/unit.codes.js';
25
36
 
26
37
  import {
27
38
  FACTURX_ATTACHMENT_DESCRIPTION,
@@ -44,9 +55,10 @@ import type { IEInvoiceMetadata } from './interfaces/en16931-metadata.js';
44
55
  /**
45
56
  * Main class for working with electronic invoices.
46
57
  * Supports various invoice formats including Factur-X, ZUGFeRD, UBL, and XRechnung
47
- * Extends the TInvoice interface for seamless integration with existing systems
58
+ * Implements the tsclass accounting document envelope: one class holds an invoice,
59
+ * a credit note, a debit note or a self-billed invoice, told apart by `accountingDocType`
48
60
  */
49
- export class EInvoice implements TInvoice {
61
+ export class EInvoice implements TAccountingDocEnvelope<TAccountingDocType, {}> {
50
62
  private static sharedPdfEmbedder?: import('./formats/pdf/pdf.embedder.js').PDFEmbedder;
51
63
  private static sharedPdfExtractor?: import('./formats/pdf/pdf.extractor.js').PDFExtractor;
52
64
 
@@ -94,9 +106,9 @@ export class EInvoice implements TInvoice {
94
106
  return invoice;
95
107
  }
96
108
 
97
- // TInvoice interface properties - accounting document structure
109
+ // Accounting document envelope properties
98
110
  public type: 'accounting-doc' = 'accounting-doc';
99
- public accountingDocType: 'invoice' = 'invoice';
111
+ public accountingDocType: TAccountingDocType = 'invoice';
100
112
  public accountingDocId: string = '';
101
113
  public accountingDocStatus: 'draft' | 'issued' | 'paid' | 'canceled' | 'refunded' = 'issued';
102
114
 
@@ -154,19 +166,17 @@ export class EInvoice implements TInvoice {
154
166
  public get invoiceId(): string { return this.accountingDocId; }
155
167
  public set invoiceId(value: string) { this.accountingDocId = value; }
156
168
 
157
- public get invoiceType(): 'invoice' | 'creditnote' | 'debitnote' {
158
- return this.accountingDocType === 'invoice' ? 'invoice' :
159
- this.accountingDocType === 'creditnote' ? 'creditnote' : 'debitnote';
169
+ public get invoiceType(): TAccountingDocType {
170
+ return this.accountingDocType;
160
171
  }
161
- public set invoiceType(value: 'invoice' | 'creditnote' | 'debitnote') {
162
- if (value !== 'invoice' && value !== 'creditnote' && value !== 'debitnote') {
172
+ public set invoiceType(value: TAccountingDocType) {
173
+ if (!isAccountingDocType(value)) {
163
174
  throw new EInvoiceFormatError(
164
175
  `Unsupported invoice type: ${String(value)}`,
165
176
  { unsupportedFeatures: [`invoiceType=${String(value)}`] }
166
177
  );
167
178
  }
168
- // the class implements TInvoice for consumers that build invoices; credit and debit notes reuse the shape with this field widened at runtime
169
- (this as { accountingDocType: 'invoice' | 'creditnote' | 'debitnote' }).accountingDocType = value;
179
+ this.accountingDocType = value;
170
180
  }
171
181
 
172
182
  // Computed properties for convenience
@@ -393,9 +403,9 @@ export class EInvoice implements TInvoice {
393
403
  }
394
404
 
395
405
  /**
396
- * Maps data from a TInvoice to this EInvoice instance
406
+ * Maps data from a decoded accounting document to this EInvoice instance
397
407
  */
398
- private mapFromTInvoice(invoice: TInvoice): void {
408
+ private mapFromTInvoice(invoice: TAccountingDoc): void {
399
409
  // Map all properties from the decoded invoice
400
410
  Object.assign(this, invoice);
401
411
 
@@ -406,9 +416,9 @@ export class EInvoice implements TInvoice {
406
416
  }
407
417
 
408
418
  /**
409
- * Maps this EInvoice instance to a TInvoice
419
+ * Maps this EInvoice instance to the accounting document the encoders take
410
420
  */
411
- private mapToTInvoice(): TInvoice {
421
+ private mapToTInvoice(): TAccountingDoc {
412
422
  const invoice: any = {
413
423
  type: 'accounting-doc',
414
424
  accountingDocType: this.accountingDocType,
@@ -508,6 +518,14 @@ export class EInvoice implements TInvoice {
508
518
  result = this.validateDecodedInvoice(level);
509
519
  }
510
520
 
521
+ // At the business level the document check covers the unit rules (BR-23, BR-CL-23) on every
522
+ // line. The feature flag validators below check the lines again on the decoded model, which
523
+ // cannot tell an absent unit from an empty unitCode="" attribute, so there they would report
524
+ // a second, possibly different rule for the same line. Below the business level the flags
525
+ // are the only unit checks and report them.
526
+ const isDocumentUnitRule = (ruleId: string): boolean =>
527
+ level === ValidationLevel.BUSINESS && (ruleId === 'BR-23' || ruleId === 'BR-CL-23');
528
+
511
529
  // Enhanced validation with feature flags
512
530
  if (options?.featureFlags?.includes('EN16931_BUSINESS_RULES')) {
513
531
  const businessRulesValidator = new EN16931BusinessRulesValidator();
@@ -517,6 +535,7 @@ export class EInvoice implements TInvoice {
517
535
  result.errors = result.errors.concat(
518
536
  businessResults
519
537
  .filter(r => r.severity === 'error')
538
+ .filter(r => !isDocumentUnitRule(r.ruleId))
520
539
  .map(r => ({ code: r.ruleId, message: r.message, field: r.field }))
521
540
  );
522
541
 
@@ -539,6 +558,7 @@ export class EInvoice implements TInvoice {
539
558
  result.errors = result.errors.concat(
540
559
  codeListResults
541
560
  .filter(r => r.severity === 'error')
561
+ .filter(r => !isDocumentUnitRule(r.ruleId))
542
562
  .map(r => ({ code: r.ruleId, message: r.message, field: r.field }))
543
563
  );
544
564
  }
@@ -567,6 +587,27 @@ export class EInvoice implements TInvoice {
567
587
  this.createValidationError(message)
568
588
  );
569
589
 
590
+ if (level === ValidationLevel.BUSINESS) {
591
+ // BR-23 and BR-CL-23: every line has a unit code, and it is a code of UN/ECE Recommendation 20
592
+ // with the Recommendation 21 extension, as the XML validators check it on an exported document
593
+ (invoice.items ?? []).forEach((item, index) => {
594
+ if (!item.unitType) {
595
+ // BR-23: the line has no unit code at all
596
+ errors.push({
597
+ code: 'BR-23',
598
+ message: 'An Invoice line (BG-25) shall have an Invoiced quantity unit of measure code (BT-130)',
599
+ location: `items[${index}].unitType`
600
+ });
601
+ } else if (!meetsUnitCodeRule(item.unitType)) {
602
+ errors.push({
603
+ code: 'BR-CL-23',
604
+ message: `Unit code MUST be coded according to the UN/ECE Recommendation 20 with Rec 21 extension; found "${item.unitType}"`,
605
+ location: `items[${index}].unitType`
606
+ });
607
+ }
608
+ });
609
+ }
610
+
570
611
  return {
571
612
  valid: errors.length === 0,
572
613
  errors,
@@ -784,7 +825,7 @@ export class EInvoice implements TInvoice {
784
825
  position: data.position || this.items.length + 1,
785
826
  name: data.name || '',
786
827
  articleNumber: data.articleNumber,
787
- unitType: data.unitType || 'unit',
828
+ unitType: data.unitType || 'C62',
788
829
  unitQuantity: data.unitQuantity || 1,
789
830
  unitNetPrice: data.unitNetPrice || 0,
790
831
  vatPercentage: data.vatPercentage || 0
@@ -1,4 +1,4 @@
1
- import type { TInvoice } from '../../interfaces/common.js';
1
+ import type { TAccountingDoc } from '../../interfaces/common.js';
2
2
  import { ValidationLevel } from '../../interfaces/common.js';
3
3
  import type { ValidationResult } from '../../interfaces/common.js';
4
4
  import { EInvoiceParsingError } from '../../errors.js';
@@ -17,16 +17,16 @@ export abstract class BaseDecoder {
17
17
  }
18
18
 
19
19
  /**
20
- * Decodes XML into a TInvoice object
21
- * @returns Promise resolving to a TInvoice object
20
+ * Decodes XML into an accounting document: an invoice, a credit note, a debit note or a self-billed invoice
21
+ * @returns Promise resolving to the accounting document
22
22
  */
23
- abstract decode(): Promise<TInvoice>;
23
+ abstract decode(): Promise<TAccountingDoc>;
24
24
 
25
25
  /**
26
26
  * Gets letter data in the standard format
27
- * @returns Promise resolving to a TInvoice object
27
+ * @returns Promise resolving to the accounting document
28
28
  */
29
- public async getLetterData(): Promise<TInvoice> {
29
+ public async getLetterData(): Promise<TAccountingDoc> {
30
30
  return this.decode();
31
31
  }
32
32
 
@@ -1,4 +1,4 @@
1
- import type { TInvoice } from '../../interfaces/common.js';
1
+ import type { TAccountingDoc } from '../../interfaces/common.js';
2
2
 
3
3
  /**
4
4
  * Base encoder class that defines common encoding functionality
@@ -6,9 +6,9 @@ import type { TInvoice } from '../../interfaces/common.js';
6
6
  */
7
7
  export abstract class BaseEncoder {
8
8
  /**
9
- * Encodes a TInvoice object into XML
10
- * @param invoice TInvoice object to encode
9
+ * Encodes an accounting document (invoice, credit note, debit note or self-billed invoice) into XML
10
+ * @param invoice Accounting document to encode
11
11
  * @returns XML string
12
12
  */
13
- abstract encode(invoice: TInvoice): Promise<string>;
13
+ abstract encode(invoice: TAccountingDoc): Promise<string>;
14
14
  }
@@ -61,4 +61,32 @@ export abstract class BaseValidator {
61
61
  location
62
62
  });
63
63
  }
64
+
65
+ /**
66
+ * The path of an element in the document, with the position of each step among its siblings
67
+ * of the same name, for example `/Invoice/cac:InvoiceLine[2]/cbc:InvoicedQuantity`.
68
+ */
69
+ protected locationOf(element: Element): string {
70
+ const steps: string[] = [];
71
+ let current: Element | null = element;
72
+ while (current) {
73
+ const name = current.nodeName;
74
+ let position = 1;
75
+ let count = 0;
76
+ const parent: Node | null = current.parentNode;
77
+ if (parent) {
78
+ for (let child = parent.firstChild; child; child = child.nextSibling) {
79
+ if (child.nodeType === 1 && child.nodeName === name) {
80
+ count++;
81
+ if (child === current) {
82
+ position = count;
83
+ }
84
+ }
85
+ }
86
+ }
87
+ steps.unshift(count > 1 ? `${name}[${position}]` : name);
88
+ current = parent && parent.nodeType === 1 ? parent as Element : null;
89
+ }
90
+ return `/${steps.join('/')}`;
91
+ }
64
92
  }