# @isa/oms/utils/translation
A lightweight translation utility library for OMS receipt types providing human-readable German translations through both service-based and pipe-based interfaces.
## Overview
The OMS Translation utility library provides a simple, extensible translation system for the OMS `ReceiptType` enum. It offers a clean abstraction for translating receipt type codes (numeric enums) into human-readable German text, with support for custom translation overrides via Angular's dependency injection system. The library includes both a service for programmatic translations and an Angular pipe for declarative template usage.
## Table of Contents
- [Features](#features)
- [Quick Start](#quick-start)
- [Core Concepts](#core-concepts)
- [API Reference](#api-reference)
- [Usage Examples](#usage-examples)
- [Receipt Types](#receipt-types)
- [Custom Translations](#custom-translations)
- [Testing](#testing)
- [Architecture Notes](#architecture-notes)
## Features
- **13 receipt type translations** - Complete German translation coverage for all OMS receipt types
- **Service-based translation** - `ReceiptTypeTranslationService` for programmatic use
- **Angular pipe** - `omsReceiptTypeTranslation` pipe for template-based translation
- **Dependency injection** - Full DI support with `providedIn: 'root'`
- **Custom overrides** - Replace default translations with custom implementations
- **Fallback handling** - Automatic enum name fallback for missing translations
- **Type-safe** - Strongly typed translation dictionary with TypeScript
- **Zero configuration** - Works out of the box with sensible defaults
- **Lightweight** - Minimal dependencies, purely translation focused
## Quick Start
### 1. Import and Use the Service
```typescript
import { Component, inject } from '@angular/core';
import { ReceiptTypeTranslationService } from '@isa/oms/utils/translation';
import { ReceiptType } from '@isa/oms/data-access';
@Component({
selector: 'app-receipt-display',
template: '...'
})
export class ReceiptDisplayComponent {
#translationService = inject(ReceiptTypeTranslationService);
displayReceiptType(type: ReceiptType): void {
const translation = this.#translationService.translate(type);
console.log(translation); // Output: "Lieferschein"
}
}
```
### 2. Use the Pipe in Templates
```typescript
import { Component } from '@angular/core';
import { ReceiptTypeTranslationPipe } from '@isa/oms/utils/translation';
import { ReceiptType } from '@isa/oms/data-access';
@Component({
selector: 'app-receipt-list',
standalone: true,
imports: [ReceiptTypeTranslationPipe],
template: `
{{ receiptType | omsReceiptTypeTranslation }}
`
})
export class ReceiptListComponent {
receiptType = ReceiptType.ShippingNote; // Displays: "Lieferschein"
}
```
### 3. Simple Example with Multiple Types
```typescript
import { Component, inject } from '@angular/core';
import { ReceiptTypeTranslationPipe } from '@isa/oms/utils/translation';
import { ReceiptType } from '@isa/oms/data-access';
@Component({
selector: 'app-receipt-types',
standalone: true,
imports: [ReceiptTypeTranslationPipe],
template: `
@for (type of receiptTypes; track type) {
{{ type | omsReceiptTypeTranslation }}
}
`
})
export class ReceiptTypesComponent {
receiptTypes = [
ReceiptType.ShippingNote, // "Lieferschein"
ReceiptType.Invoice, // "Rechnung"
ReceiptType.CreditNote, // "Gutschrift"
ReceiptType.ReturnReceipt // "Retourenbeleg"
];
}
```
## Core Concepts
### Translation Dictionary
The library provides a default translation dictionary mapping each `ReceiptType` enum value to its German translation:
```typescript
const receiptTypeTranslations = {
[ReceiptType.NotSet]: 'Nicht gesetzt',
[ReceiptType.ShippingNote]: 'Lieferschein',
[ReceiptType.CreditNote]: 'Gutschrift',
[ReceiptType.CollectiveShippingNote]: 'Sammellieferschein',
[ReceiptType.CollectiveCreditNote]: 'Sammelgutschrift',
[ReceiptType.BonusCardCollectiveShippingNote]: 'Bonuskarte Sammellieferschein',
[ReceiptType.BonusCardCollectiveCreditNote]: 'Bonuskarte Sammelgutschrift',
[ReceiptType.PaymentReceipt]: 'Zahlungsbeleg',
[ReceiptType.Invoice]: 'Rechnung',
[ReceiptType.CollectiveInvoice]: 'Sammelrechnung',
[ReceiptType.ProformaInvoice]: 'Proforma-Rechnung',
[ReceiptType.CashReceipt]: 'Kassenbeleg',
[ReceiptType.ReturnReceipt]: 'Retourenbeleg',
};
```
### ReceiptType Enum Structure
The `ReceiptType` enum from `@isa/oms/data-access` uses bit flag values:
```typescript
export enum ReceiptType {
NotSet = 0, // No receipt type set
ShippingNote = 1, // Standard shipping document
CreditNote = 2, // Credit/refund document
CollectiveShippingNote = 4, // Batch shipping document
CollectiveCreditNote = 8, // Batch credit document
BonusCardCollectiveShippingNote = 16, // Bonus card batch shipping
BonusCardCollectiveCreditNote = 32, // Bonus card batch credit
PaymentReceipt = 64, // Payment confirmation
Invoice = 128, // Customer invoice
CollectiveInvoice = 256, // Batch invoice
ProformaInvoice = 512, // Pro forma invoice
CashReceipt = 1024, // Cash register receipt
ReturnReceipt = 2048, // Return/remission receipt
}
```
**Note**: While the enum uses bit flag values (powers of 2), the current implementation treats them as discrete values, not as combinable flags. Each receipt has a single type.
### Dependency Injection Pattern
The library uses Angular's dependency injection system with an `InjectionToken`:
```typescript
export const RECEIPT_TYPE_TRANSLATION = new InjectionToken(
'RECEIPT_TYPE_TRANSLATION',
{
factory() {
return receiptTypeTranslations; // Default translations
},
}
);
```
This pattern enables:
1. **Default behavior** - Automatic injection of default translations
2. **Custom overrides** - Provide custom translations at any level (root, module, component)
3. **Testability** - Easy mocking in unit tests
4. **Type safety** - TypeScript ensures translation completeness
### Fallback Mechanism
The service includes intelligent fallback handling:
```typescript
translate(type: ReceiptType): string {
return this.#translation[type] ?? ReceiptType[type];
}
```
**Behavior**:
- **Translation exists**: Returns the German translation
- **Translation missing**: Returns the enum name as a string (e.g., "ShippingNote")
- **Invalid type**: Returns the numeric value as a string (e.g., "999")
This ensures the system never crashes, even with unexpected or new receipt types.
## API Reference
### ReceiptTypeTranslationService
Main service for programmatic receipt type translation.
#### `translate(type: ReceiptType): string`
Translates a receipt type enum value to its German text representation.
**Parameters:**
- `type: ReceiptType` - The receipt type enum value to translate
**Returns:** `string` - German translation, or enum name if translation missing
**Example:**
```typescript
import { inject } from '@angular/core';
import { ReceiptTypeTranslationService } from '@isa/oms/utils/translation';
import { ReceiptType } from '@isa/oms/data-access';
const service = inject(ReceiptTypeTranslationService);
service.translate(ReceiptType.Invoice); // "Rechnung"
service.translate(ReceiptType.ShippingNote); // "Lieferschein"
service.translate(ReceiptType.NotSet); // "Nicht gesetzt"
```
**Fallback behavior:**
```typescript
// Missing translation
service.translate(999 as ReceiptType); // "999"
// All standard types have translations
service.translate(ReceiptType.CashReceipt); // "Kassenbeleg"
```
### ReceiptTypeTranslationPipe
Angular pipe for declarative template-based translation.
#### `transform(value?: ReceiptType): string`
**Pipe Name:** `omsReceiptTypeTranslation`
**Parameters:**
- `value?: ReceiptType` - Receipt type to translate (defaults to `ReceiptType.NotSet`)
**Returns:** `string` - German translation
**Example:**
```typescript
import { Component } from '@angular/core';
import { ReceiptTypeTranslationPipe } from '@isa/oms/utils/translation';
import { ReceiptType } from '@isa/oms/data-access';
@Component({
selector: 'app-example',
standalone: true,
imports: [ReceiptTypeTranslationPipe],
template: `
{{ receiptType | omsReceiptTypeTranslation }}{{ undefined | omsReceiptTypeTranslation }}
@if (receipt) {
{{ receipt.type | omsReceiptTypeTranslation }}
}
`
})
export class ExampleComponent {
receiptType = ReceiptType.Invoice;
}
```
### Types and Tokens
#### `ReceiptTypeTranslation`
Type representing the translation dictionary structure.
```typescript
export type ReceiptTypeTranslation = {
[ReceiptType.NotSet]: string;
[ReceiptType.ShippingNote]: string;
[ReceiptType.CreditNote]: string;
[ReceiptType.CollectiveShippingNote]: string;
[ReceiptType.CollectiveCreditNote]: string;
[ReceiptType.BonusCardCollectiveShippingNote]: string;
[ReceiptType.BonusCardCollectiveCreditNote]: string;
[ReceiptType.PaymentReceipt]: string;
[ReceiptType.Invoice]: string;
[ReceiptType.CollectiveInvoice]: string;
[ReceiptType.ProformaInvoice]: string;
[ReceiptType.CashReceipt]: string;
[ReceiptType.ReturnReceipt]: string;
};
```
#### `RECEIPT_TYPE_TRANSLATION`
Injection token for providing custom translations.
```typescript
export const RECEIPT_TYPE_TRANSLATION: InjectionToken;
```
### Provider Functions
#### `provideReceiptTypeTranslation(translation: ReceiptTypeTranslation): Provider[]`
Creates providers for custom receipt type translations.
**Parameters:**
- `translation: ReceiptTypeTranslation` - Custom translation dictionary
**Returns:** `Provider[]` - Angular providers array
**Example:**
```typescript
import { provideReceiptTypeTranslation } from '@isa/oms/utils/translation';
import { ReceiptType } from '@isa/oms/data-access';
const customTranslations = {
[ReceiptType.NotSet]: 'Kein Typ',
[ReceiptType.ShippingNote]: 'Versandschein',
[ReceiptType.Invoice]: 'Faktura',
// ... other translations
};
export const appConfig = {
providers: [
provideReceiptTypeTranslation(customTranslations)
]
};
```
## Usage Examples
### Basic Template Usage
```typescript
import { Component } from '@angular/core';
import { ReceiptTypeTranslationPipe } from '@isa/oms/utils/translation';
import { ReceiptType } from '@isa/oms/data-access';
@Component({
selector: 'app-receipt-header',
standalone: true,
imports: [ReceiptTypeTranslationPipe],
template: `