# @casoon/invoice-generator

A TypeScript npm package for generating PDF invoices, XRechnung XML, and ZUGFeRD PDF/A-3 from JSON data.

## 🚀 Features

- ✅ Generate PDF invoices from JSON data
- ✅ XRechnung XML generation
- ✅ ZUGFeRD PDF/A-3 support
- ✅ TypeScript with full type safety
- ✅ DIN 5008 layout standard
- ✅ German and English localization
- ✅ Logo integration
- ✅ Comprehensive tests
- ✅ Simple API

## 📦 Installation

```bash
npm install @casoon/invoice-generator
```

## 🛠️ Usage

### CLI Usage

```bash
# Install globally
npm install -g @casoon/invoice-generator

# Generate PDF from JSON file
invoice-generator --input=data/test-invoice.json --output=invoice.pdf

# Generate PDF and XRechnung XML
invoice-generator --input=data/test-invoice.json --output=invoice.pdf --xml=xrechnung.xml
```

### Simple Usage

```typescript
import { generateFromJSON } from '@casoon/invoice-generator';

// Generate PDF from JSON file
await generateFromJSON(
  './data/test-invoice.json',
  './output/invoice.pdf'
);
```

### Advanced Usage

```typescript
import { 
  generateInvoicePDF, 
  generateInvoicePDFToFile, 
  loadInvoiceData 
} from '@casoon/invoice-generator';

// Load JSON data
const invoiceData = loadInvoiceData('./data/test-invoice.json');

// Generate PDF with custom options
await generateInvoicePDFToFile(
  invoiceData,
  './output/invoice.pdf',
  {
    template: 'default',
    language: 'de',
    includeLogo: true,
    logoPath: './logo.png'
  }
);

// Generate PDF as buffer
const pdfBuffer = await generateInvoicePDF(invoiceData);
```

### Direct Usage with Invoice Data

```typescript
import { generateInvoicePDFToFile } from '@casoon/invoice-generator';

const invoice = {
  sender: {
    name: "Max Mustermann",
    company: "Musterfirma GmbH",
    address: {
      street: "Musterstraße 123",
      postalCode: "12345",
      city: "Musterstadt"
    },
    contactInfo: {
      phone: "+49 123 456789",
      mobile: "+49 987 654321",
      email: "max.mustermann@example.com",
      website: "www.musterfirma.de"
    },
    businessOwner: "Max Mustermann",
    vatId: "DE123456789"
  },
  recipient: {
    name: "Testkunde AG",
    address: {
      street: "Teststraße 456",
      postalCode: "54321",
      city: "Teststadt"
    }
  },
  details: {
    invoiceNumber: "RE2025001",
    customerNumber: "K001",
    invoiceDate: "01.02.25",
    deliveryDate: "01.02.25",
    servicePeriod: "01-03/2025",
    dueDate: "08.02.25",
    vatId: "DE123456789"
  },
  salutation: {
    greeting: "Sehr geehrte Damen und Herren,",
    introduction: "wir bedanken uns für Ihren Auftrag und erlauben uns, wie folgt zu berechnen:"
  },
  items: [
    {
      description: "Webhosting Premium, Gebühr für example.com - Premium Hosting mit SSL-Zertifikat",
      quantity: 3,
      unit: "Stück",
      vatRate: 19,
      unitPrice: 25.00,
      total: 75.00,
      currency: "EUR"
    }
  ],
  totals: {
    netAmount: 90.00,
    vatRate: 19.00,
    vatAmount: 17.10,
    grossAmount: 107.10,
    currency: "EUR"
  },
  paymentInfo: {
    paymentTerms: "Zahlbar ohne Abzug bis zum 08.02.25",
    dueDate: "08.02.25",
    bank: "Testbank AG",
    accountHolder: "Max Mustermann",
    iban: "DE12 3456 7890 1234 5678 90",
    bic: "TESTDE12XXX"
  },
  metadata: {
    createdWith: "Invoice Generator",
    creationDate: new Date().toISOString(),
    filename: "test-invoice.json"
  }
};

await generateInvoicePDFToFile(invoice, './output/invoice.pdf');
```

## 📋 JSON Data Format

The package expects JSON data in the following format:

```json
{
  "sender": {
    "name": "Max Mustermann",
    "company": "Musterfirma GmbH",
    "address": {
      "street": "Musterstraße 123",
      "postalCode": "12345",
      "city": "Musterstadt"
    },
    "contactInfo": {
      "phone": "+49 123 456789",
      "mobile": "+49 987 654321",
      "email": "max.mustermann@example.com",
      "website": "www.musterfirma.de"
    },
    "businessOwner": "Max Mustermann",
    "vatId": "DE123456789"
  },
  "recipient": {
    "name": "Testkunde AG",
    "address": {
      "street": "Teststraße 456",
      "postalCode": "54321",
      "city": "Teststadt"
    }
  },
  "details": {
    "invoiceNumber": "RE2025001",
    "customerNumber": "K001",
    "invoiceDate": "01.02.25",
    "deliveryDate": "01.02.25",
    "servicePeriod": "01-03/2025",
    "dueDate": "08.02.25",
    "vatId": "DE123456789"
  },
  "salutation": {
    "greeting": "Sehr geehrte Damen und Herren,",
    "introduction": "wir bedanken uns für Ihren Auftrag und erlauben uns, wie folgt zu berechnen:"
  },
  "items": [
    {
      "description": "Webhosting Premium, Gebühr für example.com - Premium Hosting mit SSL-Zertifikat",
      "quantity": 3,
      "unit": "Stück",
      "vatRate": 19,
      "unitPrice": 25.00,
      "total": 75.00,
      "currency": "EUR"
    }
  ],
  "totals": {
    "netAmount": 90.00,
    "vatRate": 19.00,
    "vatAmount": 17.10,
    "grossAmount": 107.10,
    "currency": "EUR"
  },
  "paymentInfo": {
    "paymentTerms": "Zahlbar ohne Abzug bis zum 08.02.25",
    "dueDate": "08.02.25",
    "bank": "Testbank AG",
    "accountHolder": "Max Mustermann",
    "iban": "DE12 3456 7890 1234 5678 90",
    "bic": "TESTDE12XXX"
  },
  "metadata": {
    "createdWith": "Invoice Generator",
    "creationDate": "2025-02-01T07:30:37Z",
    "filename": "test-invoice.json"
  }
}
```

## ✅ Validation

The package includes comprehensive validation for invoice data:

```typescript
import { validateInvoice, validateEmail, validateIBAN, validateBIC } from '@casoon/invoice-generator';

// Validate complete invoice
const validation = validateInvoice(invoice);
if (!validation.isValid) {
  console.error('Validation errors:', validation.errors);
}

// Validate specific fields
const isValidEmail = validateEmail('test@example.com');
const isValidIBAN = validateIBAN('DE12 3456 7890 1234 5678 90');
const isValidBIC = validateBIC('TESTDE12XXX');
```

## ⚙️ Configuration

### PDFOptions

```typescript
interface PDFOptions {
  outputPath?: string;        // Output path for PDF
  template?: 'default' | 'modern' | 'minimal';  // Template variant
  language?: 'de' | 'en';     // Language
  includeLogo?: boolean;      // Include logo
  logoPath?: string;          // Path to logo
}
```

## 🔌 XRechnung Support

Generate XRechnung XML files for German electronic invoicing:

```typescript
import { generateXRechnungXMLFile } from '@casoon/invoice-generator';

// Generate XRechnung XML
await generateXRechnungXMLFile(invoice, './output/xrechnung.xml');
```

## 📄 ZUGFeRD Support

Generate ZUGFeRD PDF/A-3 files with embedded XML:

```typescript
import { ZUGFeRDPDFA3Generator } from '@casoon/invoice-generator';

// Create ZUGFeRD generator
const zugferdGenerator = new ZUGFeRDPDFA3Generator(invoice, {
  profile: 'BASIC',
  version: '2.1.1'
});

// Generate ZUGFeRD PDF/A-3
await zugferdGenerator.generateZUGFeRDPDFA3('./output/zugferd.pdf');
```

## 🧪 Testing

```bash
# Run tests
npm test

# Run tests with coverage
npm run test:coverage
```

## 📁 Project Structure

```
@casoon/invoice-generator/
├── src/
│   ├── types/
│   │   └── invoice.types.ts          # TypeScript types
│   ├── generators/
│   │   ├── pdf-generator.ts          # PDF generator
│   │   ├── xml/
│   │   │   └── xrechnung-generator.ts # XRechnung XML generator
│   │   └── zugferd/
│   │       ├── zugferd-generator.ts   # ZUGFeRD generator
│   │       └── zugferd-pdfa3-generator.ts # ZUGFeRD PDF/A-3
│   └── index.ts                      # Main export
├── tests/
│   ├── invoice-generator.test.ts     # Tests
│   └── zugferd-generator.test.ts     # ZUGFeRD tests
├── examples/
│   └── usage-example.ts              # Usage examples
├── data/
│   └── test-invoice.json             # Test data
├── docs/
│   ├── ZUGFeRD-pdf-lib.md           # ZUGFeRD documentation
│   └── npm-publishing.md            # npm publishing guide
├── package.json
├── tsconfig.json
└── README.md
```

## 🔧 Development

```bash
# Install dependencies
npm install

# Build project
npm run build

# Start development server
npm run dev

# Run tests
npm test
```

## 📄 License

MIT

## 🤝 Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## 📞 Support

For questions or issues, please create an issue on GitHub.

## 🗺️ Roadmap

For planned development and features, see [ROADMAP.md](./ROADMAP.md).

## 📋 Changelog

For changes and version history, see [CHANGELOG.md](./CHANGELOG.md).

## 🔗 Related

- [XRechnung Standard](https://www.xoev.de/xrechnung)
- [ZUGFeRD Standard](https://www.ferd-net.de/standards/zugferd/index.html)
- [DIN 5008](https://www.din.de/de/mitwirken/normenausschuesse/naerg/ueber-uns/din-5008) 