fix(core): Fix file import paths and remove markdown syntax from README
This commit is contained in:
parent
e9db94110c
commit
3f91ea44ab
@ -1,5 +1,12 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-01-01 - 1.1.2 - fix(core)
|
||||||
|
Fix file import paths and remove markdown syntax from README
|
||||||
|
|
||||||
|
- Corrected import paths for getInvoice utility
|
||||||
|
- Removed markdown syntax from README
|
||||||
|
- Fixed function parameter usage in encoder class
|
||||||
|
|
||||||
## 2024-12-31 - 1.1.1 - fix(documentation)
|
## 2024-12-31 - 1.1.1 - fix(documentation)
|
||||||
Updated documentation to reflect accurate module description and usage guidance
|
Updated documentation to reflect accurate module description and usage guidance
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
```markdown
|
|
||||||
# @fin.cx/xinvoice
|
# @fin.cx/xinvoice
|
||||||
A module for creating, manipulating, and embedding XML data within PDF files for xinvoice packages.
|
A module for creating, manipulating, and embedding XML data within PDF files for xinvoice packages.
|
||||||
|
|
||||||
@ -186,8 +185,6 @@ This class mimics the behavior of extracting XML to a structured `ILetter` objec
|
|||||||
The entirety of the module facilitates a wide spectrum of invoicing scenarios. From initial creation, embedding, and parsing tasks, to advanced encoding and decoding, every feature is crafted to accommodate complexities inherent in financial document management.
|
The entirety of the module facilitates a wide spectrum of invoicing scenarios. From initial creation, embedding, and parsing tasks, to advanced encoding and decoding, every feature is crafted to accommodate complexities inherent in financial document management.
|
||||||
|
|
||||||
By embracing `@fin.cx/xinvoice`, you simplify the handling of xinvoice-standard documents, fostering seamless integration across different financial processes, thus empowering practitioners with robust, flexible tools for VAT invoices in ZUGFeRD compliance or equivalent digital formats.
|
By embracing `@fin.cx/xinvoice`, you simplify the handling of xinvoice-standard documents, fostering seamless integration across different financial processes, thus empowering practitioners with robust, flexible tools for VAT invoices in ZUGFeRD compliance or equivalent digital formats.
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## License and Legal Information
|
## License and Legal Information
|
||||||
|
|
||||||
|
@ -16,3 +16,7 @@ export const invoices = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const letterObjects = {
|
||||||
|
letter1: await import('./letter/letter1.js'),
|
||||||
|
}
|
211
test/assets/letter/letter1.ts
Normal file
211
test/assets/letter/letter1.ts
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
import * as tsclass from '@tsclass/tsclass';
|
||||||
|
|
||||||
|
const fromContact: tsclass.business.IContact = {
|
||||||
|
name: 'Awesome From Company',
|
||||||
|
type: 'company',
|
||||||
|
description: 'a company that does stuff',
|
||||||
|
address: {
|
||||||
|
streetName: 'Awesome Street',
|
||||||
|
houseNumber: '5',
|
||||||
|
city: 'Bremen',
|
||||||
|
country: 'Germany',
|
||||||
|
postalCode: '28359',
|
||||||
|
},
|
||||||
|
vatId: 'DE12345678',
|
||||||
|
sepaConnection: {
|
||||||
|
bic: 'BPOTBEB1',
|
||||||
|
iban: 'BE01234567891616'
|
||||||
|
},
|
||||||
|
email: 'hello@awesome.company',
|
||||||
|
phone: '+49 421 1234567',
|
||||||
|
fax: '+49 421 1234568',
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const toContact: tsclass.business.IContact = {
|
||||||
|
name: 'Awesome To GmbH',
|
||||||
|
type: 'company',
|
||||||
|
customerNumber: 'LL-CLIENT-123',
|
||||||
|
description: 'a company that does stuff',
|
||||||
|
address: {
|
||||||
|
streetName: 'Awesome Street',
|
||||||
|
houseNumber: '5',
|
||||||
|
city: 'Bremen',
|
||||||
|
country: 'Germany',
|
||||||
|
postalCode: '28359'
|
||||||
|
},
|
||||||
|
vatId: 'BE12345678',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const demoLetter: tsclass.business.ILetter = {
|
||||||
|
versionInfo: {
|
||||||
|
type: 'draft',
|
||||||
|
version: '1.0.0',
|
||||||
|
},
|
||||||
|
accentColor: null,
|
||||||
|
content: {
|
||||||
|
textData: null,
|
||||||
|
timesheetData: null,
|
||||||
|
contractData: {
|
||||||
|
contractDate: Date.now(),
|
||||||
|
id: 'someid'
|
||||||
|
},
|
||||||
|
invoiceData: {
|
||||||
|
id: 'LL-INV-48765',
|
||||||
|
reverseCharge: true,
|
||||||
|
dueInDays: 30,
|
||||||
|
billedBy: fromContact,
|
||||||
|
billedTo: toContact,
|
||||||
|
status: null,
|
||||||
|
deliveryDate: new Date().getTime(),
|
||||||
|
periodOfPerformance: null,
|
||||||
|
printResult: null,
|
||||||
|
currency: 'EUR',
|
||||||
|
notes: [],
|
||||||
|
type: 'debitnote',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
name: 'Item with 19% VAT',
|
||||||
|
unitQuantity: 2,
|
||||||
|
unitNetPrice: 100,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 19,
|
||||||
|
position: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 7% VAT',
|
||||||
|
unitQuantity: 4,
|
||||||
|
unitNetPrice: 100,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 7,
|
||||||
|
position: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 7% VAT',
|
||||||
|
unitQuantity: 3,
|
||||||
|
unitNetPrice: 230,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 7,
|
||||||
|
position: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 21% VAT',
|
||||||
|
unitQuantity: 1,
|
||||||
|
unitNetPrice: 230,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 21,
|
||||||
|
position: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 0% VAT',
|
||||||
|
unitQuantity: 6,
|
||||||
|
unitNetPrice: 230,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 0,
|
||||||
|
position: 4,
|
||||||
|
},{
|
||||||
|
name: 'Item with 19% VAT',
|
||||||
|
unitQuantity: 8,
|
||||||
|
unitNetPrice: 100,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 19,
|
||||||
|
position: 5,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 7% VAT',
|
||||||
|
unitQuantity: 9,
|
||||||
|
unitNetPrice: 100,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 7,
|
||||||
|
position: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 7% VAT',
|
||||||
|
unitQuantity: 4,
|
||||||
|
unitNetPrice: 230,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 7,
|
||||||
|
position: 8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 21% VAT',
|
||||||
|
unitQuantity: 3,
|
||||||
|
unitNetPrice: 230,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 21,
|
||||||
|
position: 9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 0% VAT',
|
||||||
|
unitQuantity: 1,
|
||||||
|
unitNetPrice: 230,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 0,
|
||||||
|
position: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 0% VAT',
|
||||||
|
unitQuantity: 1,
|
||||||
|
unitNetPrice: 230,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 0,
|
||||||
|
position: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 0% VAT',
|
||||||
|
unitQuantity: 1,
|
||||||
|
unitNetPrice: 230,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 0,
|
||||||
|
position: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 0% VAT',
|
||||||
|
unitQuantity: 1,
|
||||||
|
unitNetPrice: 230,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 0,
|
||||||
|
position: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 0% VAT',
|
||||||
|
unitQuantity: 1,
|
||||||
|
unitNetPrice: 230,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 0,
|
||||||
|
position: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 0% VAT',
|
||||||
|
unitQuantity: 1,
|
||||||
|
unitNetPrice: 230,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 0,
|
||||||
|
position: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Item with 0% VAT',
|
||||||
|
unitQuantity: 1,
|
||||||
|
unitNetPrice: 230,
|
||||||
|
unitType: 'hours',
|
||||||
|
vatPercentage: 0,
|
||||||
|
position: 10,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
date: Date.now(),
|
||||||
|
type: 'invoice',
|
||||||
|
needsCoverSheet: false,
|
||||||
|
objectActions: [],
|
||||||
|
pdf: null,
|
||||||
|
from: fromContact,
|
||||||
|
to: toContact,
|
||||||
|
incidenceId: null,
|
||||||
|
language: null,
|
||||||
|
legalContact: null,
|
||||||
|
logoUrl: null,
|
||||||
|
pdfAttachments: null,
|
||||||
|
subject: 'Invoice: LL-INV-48765',
|
||||||
|
}
|
@ -2,7 +2,7 @@ import { tap, expect } from '@push.rocks/tapbundle';
|
|||||||
|
|
||||||
import * as xinvoice from '../ts/index.js';
|
import * as xinvoice from '../ts/index.js';
|
||||||
|
|
||||||
import * as getInvoices from './assets/getinvoice.js';
|
import * as getInvoices from './assets/getasset.js';
|
||||||
|
|
||||||
const test1 = tap.test('XInvoice should correctly embed XML into a PDF', async (tools) => {
|
const test1 = tap.test('XInvoice should correctly embed XML into a PDF', async (tools) => {
|
||||||
// lets setup the XInvoice instance
|
// lets setup the XInvoice instance
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@fin.cx/xinvoice',
|
name: '@fin.cx/xinvoice',
|
||||||
version: '1.1.1',
|
version: '1.1.2',
|
||||||
description: 'A TypeScript module for creating, manipulating, and embedding XML data within PDF files specifically tailored for xinvoice packages.'
|
description: 'A TypeScript module for creating, manipulating, and embedding XML data within PDF files specifically tailored for xinvoice packages.'
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ export class ZugferdXmlEncoder {
|
|||||||
doc.ele('rsm:ExchangedDocumentContext')
|
doc.ele('rsm:ExchangedDocumentContext')
|
||||||
.ele('ram:TestIndicator')
|
.ele('ram:TestIndicator')
|
||||||
.ele('udt:Indicator')
|
.ele('udt:Indicator')
|
||||||
.txt(this.isDraft() ? 'true' : 'false')
|
.txt(this.isDraft(letterArg) ? 'true' : 'false')
|
||||||
.up()
|
.up()
|
||||||
.up()
|
.up()
|
||||||
.up(); // </rsm:ExchangedDocumentContext>
|
.up(); // </rsm:ExchangedDocumentContext>
|
||||||
@ -51,7 +51,7 @@ export class ZugferdXmlEncoder {
|
|||||||
.ele('ram:IssueDateTime')
|
.ele('ram:IssueDateTime')
|
||||||
.ele('udt:DateTimeString', { format: '102' })
|
.ele('udt:DateTimeString', { format: '102' })
|
||||||
// Format 'YYYYMMDD' or 'YYYY-MM-DD'? Depending on standard
|
// Format 'YYYYMMDD' or 'YYYY-MM-DD'? Depending on standard
|
||||||
.txt(this.formatDate(this.letter.date, 'yyyyMMdd'))
|
.txt(this.formatDate(letterArg.date))
|
||||||
.up()
|
.up()
|
||||||
.up();
|
.up();
|
||||||
exchangedDoc.up(); // </rsm:ExchangedDocument>
|
exchangedDoc.up(); // </rsm:ExchangedDocument>
|
||||||
@ -136,8 +136,8 @@ export class ZugferdXmlEncoder {
|
|||||||
const occurrenceEle = actualDeliveryEle.ele('ram:OccurrenceDateTime')
|
const occurrenceEle = actualDeliveryEle.ele('ram:OccurrenceDateTime')
|
||||||
.ele('udt:DateTimeString', { format: '102' });
|
.ele('udt:DateTimeString', { format: '102' });
|
||||||
|
|
||||||
const deliveryDate = invoice.deliveryDate || this.letter.date;
|
const deliveryDate = invoice.deliveryDate || letterArg.date;
|
||||||
occurrenceEle.txt(this.formatDate(deliveryDate, 'yyyyMMdd')).up();
|
occurrenceEle.txt(this.formatDate(deliveryDate)).up();
|
||||||
actualDeliveryEle.up(); // </ram:ActualDeliverySupplyChainEvent>
|
actualDeliveryEle.up(); // </ram:ActualDeliverySupplyChainEvent>
|
||||||
headerTradeDeliveryEle.up(); // </ram:ApplicableHeaderTradeDelivery>
|
headerTradeDeliveryEle.up(); // </ram:ApplicableHeaderTradeDelivery>
|
||||||
|
|
||||||
@ -188,15 +188,15 @@ export class ZugferdXmlEncoder {
|
|||||||
/**
|
/**
|
||||||
* Helper: Determine if the letter is in draft or final.
|
* Helper: Determine if the letter is in draft or final.
|
||||||
*/
|
*/
|
||||||
private isDraft(): boolean {
|
private isDraft(letterArg: plugins.tsclass.business.ILetter): boolean {
|
||||||
return this.letter.versionInfo?.type === 'draft';
|
return letterArg.versionInfo?.type === 'draft';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper: Format date to certain patterns (very minimal example).
|
* Helper: Format date to certain patterns (very minimal example).
|
||||||
* e.g. 'yyyyMMdd' => '20231231'
|
* e.g. 'yyyyMMdd' => '20231231'
|
||||||
*/
|
*/
|
||||||
private formatDate(timestampMs: number, pattern: 'yyyyMMdd'): string {
|
private formatDate(timestampMs: number): string {
|
||||||
const date = new Date(timestampMs);
|
const date = new Date(timestampMs);
|
||||||
const yyyy = date.getFullYear();
|
const yyyy = date.getFullYear();
|
||||||
const mm = String(date.getMonth() + 1).padStart(2, '0');
|
const mm = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user