# @fin.cx/xinvoice
A module for creating, manipulating, and embedding XML invoice data within PDF files, supporting multiple European electronic invoice standards including ZUGFeRD, Factur-X, EN16931, UBL, and FatturaPA.

## Install

To install `@fin.cx/xinvoice`, you'll need npm (Node Package Manager). Run the following command in your terminal:

```shell
npm install @fin.cx/xinvoice
```

Or if you're using pnpm:

```shell
pnpm add @fin.cx/xinvoice
```

This command fetches the `xinvoice` package from the npm registry and installs it in your project directory.

## Usage

The `@fin.cx/xinvoice` module is designed for handling and embedding XML data specifically tailored for xinvoice formats within PDF files. It streamlines the management of financial documents, typically involving the creation, manipulation, and embedding of structured invoice data. This section will cover a comprehensive usage guide, providing in-depth explanations of using each feature in a TypeScript environment with ESM syntax.

### Setting Up Your TypeScript Environment

Before diving into the module’s functionalities, configure your TypeScript setup to handle ECMAScript modules. Here’s an example of a `tsconfig.json` configuration:

```json
{
  "compilerOptions": {
    "module": "ESNext",
    "target": "ESNext",
    "moduleResolution": "node",
    "strict": true,
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "outDir": "./dist",
    "types": ["node"]
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}
```

This configuration ensures that TypeScript compiles your code using the latest ES module syntax, enabling direct and type-safe imports.

### Importing the `@fin.cx/xinvoice` Module

With your TypeScript environment configured, import the `@fin.cx/xinvoice` module as follows:

```typescript
import { XInvoice } from '@fin.cx/xinvoice';
```

### Core Functionality: XInvoice Class

#### Introduction to XInvoice

The `XInvoice` class stands at the heart of our module, enabling the creation, manipulation, and management of invoices. It allows you to incorporate XML data into PDF files seamlessly, providing a bridge between human-readable PDF formats and machine-readable XML specifications required for financial documents.

#### Creating an XInvoice Instance

To harness the power of `XInvoice`, instantiate it with a path to the necessary file locations for your invoice processing needs:

```typescript
const xInvoice = new XInvoice();
```

Here, we just initialize an `XInvoice` object that we can later configure with necessary inputs.

#### Adding PDF and XML Data

Before embedding XML data into a PDF or extracting such information, provide the `XInvoice` instance with the required PDF and XML data:

```typescript
import { promises as fs } from 'fs';

async function loadFiles() {
  const pdfBuffer = await fs.readFile('./path/to/your/invoice.pdf');
  const xmlString = await fs.readFile('./path/to/your/invoice.xml', 'utf-8');

  await xInvoice.addPdfBuffer(pdfBuffer);
  await xInvoice.addXmlString(xmlString);
}
```

The method `addPdfBuffer` takes a `Buffer` or `Uint8Array` of the PDF file, while `addXmlString` accepts the invoice's XML representation in string format.

#### Embedding XML into PDF

Embedding XML data into a PDF is a significant capability of this module. Once you've loaded the PDF and XML data, invoke the `getXInvoice` method:

```typescript
await xInvoice.getXInvoice();
```

This process attaches the XML to the PDF document, creating a structured combination that can be saved, shared, or further processed.

#### Retrieving Embedded XML from PDF

To access previously embedded XML data from a PDF, use the `getXmlData` method:

```typescript
const embeddedXml = await xInvoice.getXmlData();
console.log(embeddedXml);
```

This method extracts the XML content directly from the PDF file, decoding it into a string.

### Advanced Usage: XML Parsing and Data Extraction

#### Parsing XML into Structured Invoice Data

When dealing with complex financial documents, converting XML into possible structured data reflects prudent practice. If your focus is analyzing invoice contents, the module offers parsing into TypeScript interfaces:

```typescript
const parsedInvoiceData = await xInvoice.getParsedXmlData();
console.log(parsedInvoiceData);
```

The retrieval produces an object conforming to the following structure defined by `IXInvoice`:

```typescript
interface IXInvoice {
  InvoiceNumber: string;
  DateIssued: string;
  Seller: IParty;
  Buyer: IParty;
  Items: IInvoiceItem[];
  TotalAmount: number;
}

interface IParty {
  Name: string;
  Address: IAddress;
  Contact: IContact;
}

interface IAddress {
  Street: string;
  City: string;
  PostalCode: string;
  Country: string;
}

interface IContact {
  Email: string;
  Phone: string;
}

interface IInvoiceItem {
  Description: string;
  Quantity: number;
  UnitPrice: number;
  TotalPrice: number;
}
```

Each invoice object encompasses seller and buyer information, invoice items and their quantities, collectively synthesizing a comprehensive view of the document's content.

### Custom Extensibility: Encoding and Decoding XML

#### Factur-X/ZUGFeRD XML Encoding

Beyond pre-built functionalities, the module supports custom XML encoding of structured data into PDF attachments. Utilize `FacturXEncoder` for generating standards-compliant XML:

```typescript
import { FacturXEncoder } from '@fin.cx/xinvoice';

const encoder = new FacturXEncoder();
const factorXXml = encoder.createFacturXXml(invoiceLetterData);
```

This encoder transforms invoice data into compliant Factur-X/ZUGFeRD XML format, following the European e-invoicing standard EN16931. The encoder handles all the complexities of creating valid XML including proper namespaces, required fields, and structured data elements.

For backward compatibility, you can also use:

```typescript
const zugferdXml = encoder.createZugferdXml(invoiceLetterData);
```

#### XML Decoding for Multiple Invoice Formats

The library supports decoding multiple electronic invoice formats through the `FacturXDecoder` class:

```typescript
import { FacturXDecoder } from '@fin.cx/xinvoice';

const decoder = new FacturXDecoder(xmlString);
const letterData = await decoder.getLetterData();
```

This decoder automatically detects the XML format (ZUGFeRD/Factur-X, UBL, or FatturaPA) and extracts relevant invoice data into a structured `ILetter` object, suitable for custom processing.

#### Circular Encoding and Decoding

A powerful feature of this library is the ability to perform circular encoding and decoding, allowing you to create XML from structured data and then extract the same data back from the XML:

```typescript
// Start with invoice data
const invoiceData = { /* your structured invoice data */ };

// Create XML
const encoder = new FacturXEncoder();
const xml = encoder.createFacturXXml(invoiceData);

// Decode XML back to structured data
const decoder = new FacturXDecoder(xml);
const extractedData = await decoder.getLetterData();

// Now extractedData contains the same information as your original invoiceData
```

This circular capability ensures data integrity throughout the invoice processing lifecycle.

### Supported Invoice Standards

The library currently supports the following electronic invoice standards:

- **ZUGFeRD/Factur-X** - The German and French implementations of the European e-invoicing standard EN16931, based on UN/CEFACT Cross Industry Invoice (CII) XML schema
- **UBL (Universal Business Language)** - An OASIS standard for XML business documents
- **FatturaPA** - The Italian electronic invoicing standard

Each format is automatically detected during decoding, and the encoders create standards-compliant documents that pass validation.

### Testing and Validation

The library includes comprehensive test suites that verify:
- XML creation capabilities
- Format detection logic
- XML encoding/decoding circularity
- Special character handling
- Different invoice types (invoices, credit notes)

You can run the tests using:

```shell
pnpm test
```

### Comprehensive Feature Summary

The entirety of the module facilitates a wide spectrum of invoicing scenarios. Key features include:

1. **PDF Integration**
   - Embed XML invoices in PDF documents
   - Extract XML from existing PDF invoices
   - Handle different XML attachment methods

2. **Encoding & Decoding**
   - Create standards-compliant XML from structured data
   - Parse XML invoices back to structured data
   - Support multiple format standards
   - Circular encoding/decoding integrity

3. **Format Detection**
   - Automatic detection of invoice XML format
   - Support for different XML namespaces
   - Graceful handling of malformed XML

By embracing `@fin.cx/xinvoice`, you simplify the handling of electronic invoice documents, fostering seamless integration across different financial processes, thus empowering practitioners with robust, flexible tools for VAT invoices in ZUGFeRD/Factur-X compliance or equivalent digital formats.

## License and Legal Information

This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. 

**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.

### Trademarks

This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.

### Company Information

Task Venture Capital GmbH  
Registered at District court Bremen HRB 35230 HB, Germany

For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.

By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
