412 lines
18 KiB
Markdown
412 lines
18 KiB
Markdown
# Benutzer-Spracheinstellung für Dokumente
|
|
|
|
**Datum:** 04.02.2026
|
|
**Bezug:** next-steps.md - Punkt 6: Mehrsprachigkeit: Rechnungen, Provisionen, Lieferscheine
|
|
|
|
## Übersicht
|
|
|
|
Diese Implementierung fügt ein Sprachfeld zu den Benutzerdaten hinzu, damit Benutzer selbst entscheiden können, in welcher Sprache sie ihre Dokumente (Rechnungen, Provisionsabrechnungen, Lieferscheine) erhalten möchten.
|
|
|
|
## Problem
|
|
|
|
Bisher wurde die Sprache für Dokumente immer von der aktuellen Session-Sprache übernommen (`\App::getLocale()`). Das Problem dabei:
|
|
|
|
- Benutzer, die auf Deutsch surfen aber Spanisch bevorzugen, bekommen Dokumente auf Deutsch
|
|
- Die Spracheinstellung ist nicht persistent
|
|
|
|
## Lösung
|
|
|
|
### 1. Datenbankänderung
|
|
|
|
**Migration 1:** `2026_02_04_101805_add_language_to_user_accounts_table.php`
|
|
|
|
```php
|
|
Schema::table('user_accounts', function (Blueprint $table) {
|
|
$table->string('language', 5)->nullable()->after('notice');
|
|
});
|
|
```
|
|
|
|
**Migration 2:** `2026_02_04_102455_change_language_default_on_user_accounts_table.php`
|
|
|
|
Setzt den Default auf NULL (statt 'de'), damit die aktuelle App-Locale (`\App::getLocale()`) als Fallback verwendet wird.
|
|
|
|
### 2. Model-Anpassungen
|
|
|
|
#### UserAccount & ShoppingUser
|
|
|
|
Beide Models haben jetzt:
|
|
|
|
```php
|
|
// Accessor - gibt App-Locale zurück wenn NULL:
|
|
public function getLanguageAttribute($value): string
|
|
{
|
|
return $value ?: \App::getLocale();
|
|
}
|
|
|
|
// Alias für Konsistenz:
|
|
public function getLocale(): string
|
|
{
|
|
return $this->language;
|
|
}
|
|
|
|
// Sprachen werden aus config/localization.php geladen:
|
|
public static function getAvailableLanguages(): array
|
|
{
|
|
$locales = config('localization.supportedLocales', []);
|
|
$languages = [];
|
|
foreach ($locales as $code => $locale) {
|
|
$languages[$code] = $locale['native'] ?? $locale['name'] ?? $code;
|
|
}
|
|
return $languages;
|
|
}
|
|
```
|
|
|
|
### 3. Frontend-Formulare
|
|
|
|
| Formular | Datei | Beschreibung |
|
|
| -------------------- | ----------------------------------------------------------- | ------------------------------------------------ |
|
|
| Berater-Profil | `resources/views/user/user_form.blade.php` | Sprachauswahl zwischen Bankdaten und Steuerdaten |
|
|
| Kunden-Bearbeitung | `resources/views/admin/customer/_edit.blade.php` | Sprachauswahl nach Bemerkungen |
|
|
| Kunden-Detailansicht | `resources/views/admin/customer/_customer_detail.blade.php` | Sprache wird bei Rechnungsadresse angezeigt |
|
|
| Checkout | `resources/views/web/templates/checkout.blade.php` | Sprachauswahl im Bestellformular |
|
|
|
|
### 4. Übersetzungen
|
|
|
|
**account.php** (für Berater-Profil):
|
|
|
|
| Key | DE | EN | ES |
|
|
| -------------------- | ----------------------------------------- | ----------------------------------------------- | --------------------------- |
|
|
| `language_settings` | Spracheinstellungen | Language settings | Configuración de idioma |
|
|
| `preferred_language` | Bevorzugte Sprache | Preferred language | Idioma preferido |
|
|
| `language_hint` | Diese Sprache wird für Ihre Rechnungen... | This language will be used for your invoices... | Este idioma se utilizará... |
|
|
|
|
**customer.php** (für Kunden-Verwaltung):
|
|
|
|
| Key | DE | EN | ES |
|
|
| --------------- | --------------------------------------------------------------- | -------------------------------------------------------- | ---------------------------------------------------- |
|
|
| `language_hint` | Die Rechnungen und Dokumente werden in dieser Sprache erstellt. | Invoices and documents will be created in this language. | Las facturas y documentos se crearán en este idioma. |
|
|
|
|
## Verfügbare Sprachen
|
|
|
|
Die verfügbaren Sprachen werden aus `config/localization.php` unter `supportedLocales` geladen.
|
|
|
|
Aktuell aktiv:
|
|
|
|
- `de` - Deutsch
|
|
- `en` - English
|
|
- `es` - Español
|
|
|
|
## Verhalten
|
|
|
|
### UserAccount (Berater/Consultants)
|
|
|
|
- Benutzer können ihre bevorzugte Sprache im Profil unter "Spracheinstellungen" auswählen
|
|
- `$user->account->language` gibt immer einen Wert zurück (nie NULL dank Accessor)
|
|
- Wird für Provisionsabrechnungen verwendet
|
|
|
|
### ShoppingUser (Kunden)
|
|
|
|
- Berater können bei Kunden eine bevorzugte Sprache hinterlegen
|
|
- Im Checkout kann der Kunde die Sprache selbst wählen
|
|
- `$shopping_user->language` gibt immer einen Wert zurück (nie NULL dank Accessor)
|
|
- Wird für Rechnungen und Lieferscheine verwendet
|
|
|
|
## Geänderte Dateien
|
|
|
|
| Datei | Änderung |
|
|
| ------------------------------------------------------------------------------------------ | -------------------------------------------------- |
|
|
| `database/migrations/2026_02_04_101805_add_language_to_user_accounts_table.php` | Neue Migration - Feld hinzufügen |
|
|
| `database/migrations/2026_02_04_102455_change_language_default_on_user_accounts_table.php` | Default auf NULL ändern |
|
|
| `app/Models/UserAccount.php` | Accessor, `getLocale()`, `getAvailableLanguages()` |
|
|
| `app/Models/ShoppingUser.php` | Accessor, `getAvailableLanguages()` |
|
|
| `resources/views/user/user_form.blade.php` | Sprachauswahl für Berater |
|
|
| `resources/views/admin/customer/_edit.blade.php` | Sprachauswahl für Kunden |
|
|
| `resources/views/admin/customer/_customer_detail.blade.php` | Sprache in Detailansicht |
|
|
| `resources/views/web/templates/checkout.blade.php` | Sprachauswahl im Checkout |
|
|
| `resources/lang/de/account.php` | Neue Übersetzungen |
|
|
| `resources/lang/en/account.php` | Neue Übersetzungen |
|
|
| `resources/lang/es/account.php` | Neue Übersetzungen |
|
|
| `resources/lang/de/customer.php` | Neue Übersetzung `language_hint` |
|
|
| `resources/lang/en/customer.php` | Neue Übersetzung `language_hint` |
|
|
| `resources/lang/es/customer.php` | Neue Übersetzung `language_hint` |
|
|
|
|
## Test
|
|
|
|
### UserAccount (Berater-Profil)
|
|
|
|
1. Als Berater einloggen
|
|
2. Profil bearbeiten (Route: `/user/edit`)
|
|
3. Neue Sektion "Spracheinstellungen" sichtbar
|
|
4. Sprache auswählen und speichern
|
|
5. Prüfen: Feld wird in `user_accounts.language` gespeichert
|
|
|
|
### ShoppingUser (Kunden-Verwaltung)
|
|
|
|
1. Als Berater einloggen
|
|
2. Kunde bearbeiten oder anlegen
|
|
3. Sprachauswahl im Formular sichtbar
|
|
4. Sprache auswählen und speichern
|
|
5. Prüfen: Feld wird in `shopping_users.language` gespeichert
|
|
|
|
### Checkout
|
|
|
|
1. Shop aufrufen und Produkte in den Warenkorb legen
|
|
2. Zur Kasse gehen
|
|
3. Sprachauswahl im Rechnungsadresse-Bereich sichtbar
|
|
4. Sprache auswählen
|
|
5. Bestellung abschließen
|
|
6. Prüfen: Rechnung wird in der gewählten Sprache erstellt
|
|
|
|
## Phase 2: Mehrsprachige PDF-Erstellung
|
|
|
|
### Konzept
|
|
|
|
Für finanzrechtliche Anforderungen wird **immer** ein deutsches Original erstellt. Wenn der Kunde/Benutzer eine andere Sprache bevorzugt, wird zusätzlich eine Kopie in seiner Landessprache generiert.
|
|
|
|
### Dateinamen-Schema
|
|
|
|
| Dokument | Deutsch (Original) | Kundensprache (z.B. ES) |
|
|
| ------------ | ----------------------------------- | -------------------------------------- |
|
|
| Rechnung | `202600123-MIVITA-Rechnung.pdf` | `202600123-MIVITA-Rechnung-es.pdf` |
|
|
| Lieferschein | `202600123-MIVITA-Lieferschein.pdf` | `202600123-MIVITA-Lieferschein-es.pdf` |
|
|
| Gutschrift | `GS202600123-MIVITA-Gutschrift.pdf` | `GS202600123-MIVITA-Gutschrift-es.pdf` |
|
|
|
|
### Implementierung
|
|
|
|
#### Invoice Service (`app/Services/Invoice.php`)
|
|
|
|
Neue Methoden für lokalisierte Dateinamen:
|
|
|
|
```php
|
|
public static function makeInvoiceFilenameLocale($invoice_number, $locale)
|
|
public static function makeDeliveryFilenameLocale($invoice_number, $locale)
|
|
```
|
|
|
|
#### Credit Service (`app/Services/Credit.php`)
|
|
|
|
Neue Methode für lokalisierte Gutschrift-Dateinamen:
|
|
|
|
```php
|
|
public static function makeCreditFilenameLocale($credit_number, $locale)
|
|
```
|
|
|
|
#### InvoiceRepository (`app/Repositories/InvoiceRepository.php`)
|
|
|
|
Die `makePDF()` Methode erstellt jetzt:
|
|
|
|
1. Deutsches Original (immer)
|
|
2. Lokalisierte Kopie (wenn Kundensprache ≠ DE)
|
|
|
|
Neue Helper-Methoden:
|
|
|
|
```php
|
|
private function createPDFFiles(array $data, string $locale)
|
|
private function getTemplateForLocale(string $locale): string
|
|
```
|
|
|
|
#### CreditRepository (`app/Repositories/CreditRepository.php`)
|
|
|
|
Die `create()` Methode erstellt jetzt:
|
|
|
|
1. Deutsches Original (immer)
|
|
2. Lokalisierte Kopie (wenn Benutzersprache ≠ DE)
|
|
|
|
Neue Helper-Methoden:
|
|
|
|
```php
|
|
private function createCreditPDF(array $data, string $path, string $dir, string $filename, string $locale, bool $is_copy)
|
|
private function getTemplateForLocale(string $locale): string
|
|
```
|
|
|
|
### PDF-Templates nach Sprache
|
|
|
|
Die Templates für den PDF-Merger werden automatisch basierend auf der Sprache gewählt.
|
|
|
|
**Konfiguration** in `config/localization.php`:
|
|
|
|
```php
|
|
'availableTemplates' => ['de', 'en', 'es', 'fr'],
|
|
```
|
|
|
|
| Sprache | Template |
|
|
| ----------- | -------------------------------- |
|
|
| Deutsch | `template_invoice_de` |
|
|
| Englisch | `template_invoice_en` |
|
|
| Spanisch | `template_invoice_es` |
|
|
| Französisch | `template_invoice_fr` |
|
|
| Sonstige | `template_invoice_de` (Fallback) |
|
|
|
|
#### UserInvoice Model (`app/Models/UserInvoice.php`)
|
|
|
|
Neue Methoden für lokalisierten Zugriff:
|
|
|
|
```php
|
|
public function getDownloadPathLocale($locale = null, $full = false)
|
|
public function getDownloadPathDeliveryLocale($locale = null, $full = false)
|
|
public function getFilenameLocale($locale = null)
|
|
```
|
|
|
|
#### UserCredit Model (`app/Models/UserCredit.php`)
|
|
|
|
Neue Methoden für lokalisierten Zugriff:
|
|
|
|
```php
|
|
public function getDownloadPathLocale($locale = null, $full = false)
|
|
public function getFilenameLocale($locale = null)
|
|
```
|
|
|
|
#### MailInvoice (`app/Mail/MailInvoice.php`)
|
|
|
|
Versendet **beide Versionen** als Anhänge:
|
|
|
|
1. Deutsches Original (immer)
|
|
2. Lokalisierte Kopie (wenn Kundensprache ≠ DE und Datei existiert)
|
|
|
|
#### MailCredit (`app/Mail/MailCredit.php`)
|
|
|
|
Versendet **beide Versionen** als Anhänge:
|
|
|
|
1. Deutsches Original (immer)
|
|
2. Lokalisierte Kopie (wenn Benutzersprache ≠ DE und Datei existiert)
|
|
|
|
### Kopie-Kennzeichnung in PDFs
|
|
|
|
Lokalisierte Kopien werden mit einem Hinweis über dem Datum gekennzeichnet:
|
|
|
|
| Dokumenttyp | Hinweis (in Kundensprache) |
|
|
| ------------ | -------------------------- |
|
|
| Rechnung | "Invoice copy: EN" |
|
|
| Lieferschein | "Delivery note copy: EN" |
|
|
| Gutschrift | "Credit note copy: EN" |
|
|
|
|
**Übersetzungen** (`resources/lang/*/pdf.php`):
|
|
|
|
| Key | DE | EN | ES |
|
|
| --------------- | ----------------- | ------------------ | --------------------------- |
|
|
| `invoice_copy` | Rechnungskopie | Invoice copy | Copia de factura |
|
|
| `delivery_copy` | Lieferscheinkopie | Delivery note copy | Copia del albarán |
|
|
| `credit_copy` | Gutschriftkopie | Credit note copy | Copia de la nota de crédito |
|
|
|
|
### Geänderte Dateien (Phase 2)
|
|
|
|
| Datei | Änderung |
|
|
| ---------------------------------------- | ------------------------------------------------------------- |
|
|
| `app/Services/Invoice.php` | `makeInvoiceFilenameLocale()`, `makeDeliveryFilenameLocale()` |
|
|
| `app/Services/Credit.php` | `makeCreditFilenameLocale()` |
|
|
| `app/Repositories/InvoiceRepository.php` | Mehrsprachige PDF-Erstellung mit `is_copy` Flag |
|
|
| `app/Repositories/CreditRepository.php` | Mehrsprachige Gutschrift-Erstellung mit `is_copy` Flag |
|
|
| `app/Models/UserInvoice.php` | Lokalisierte Pfad-Methoden |
|
|
| `app/Models/UserCredit.php` | Lokalisierte Pfad-Methoden |
|
|
| `app/Mail/MailInvoice.php` | DE Original + lokalisierte Version als Anhänge |
|
|
| `app/Mail/MailCredit.php` | DE Original + lokalisierte Version als Anhänge |
|
|
| `resources/views/pdf/invoice.blade.php` | Kopie-Hinweis über Datum |
|
|
| `resources/views/pdf/delivery.blade.php` | Kopie-Hinweis über Datum |
|
|
| `resources/views/pdf/credit.blade.php` | Kopie-Hinweis über Datum |
|
|
| `resources/lang/de/pdf.php` | Übersetzungen für Kopie-Hinweise |
|
|
| `resources/lang/en/pdf.php` | Übersetzungen für Kopie-Hinweise |
|
|
| `resources/lang/es/pdf.php` | Übersetzungen für Kopie-Hinweise |
|
|
|
|
### Ablauf nach Implementierung
|
|
|
|
```
|
|
Bestellung → InvoiceRepository::create()
|
|
│
|
|
▼
|
|
makePDF()
|
|
│
|
|
┌────────────┴────────────┐
|
|
│ │
|
|
▼ ▼
|
|
DE PDF (Original) Kundensprach-PDF (Kopie)
|
|
mit "Rechnungskopie: ES"
|
|
│ │
|
|
└────────────┬────────────┘
|
|
│
|
|
▼
|
|
sendInvoiceMail()
|
|
│
|
|
▼
|
|
Anhänge: DE Original + Kundensprach-Kopie
|
|
```
|
|
|
|
### Test
|
|
|
|
1. Kunde mit Spanisch (`es`) als bevorzugte Sprache anlegen
|
|
2. Bestellung für diesen Kunden abschließen
|
|
3. Prüfen:
|
|
- Im Speicherordner existieren beide PDFs: `*-Rechnung.pdf` und `*-Rechnung-es.pdf`
|
|
- Das spanische PDF enthält den Hinweis "Copia de factura: ES" über dem Datum
|
|
- Die E-Mail enthält **beide** Anhänge (DE Original + ES Kopie)
|
|
4. Im Admin sind beide Versionen verfügbar (DE für Finanzamt, ES für Kundenservice)
|
|
|
|
## Phase 3: Admin-Download-Buttons für lokalisierte PDFs
|
|
|
|
### Route-Erweiterung
|
|
|
|
Die `storage_file` Route wurde um einen optionalen `locale` Parameter erweitert:
|
|
|
|
```php
|
|
// routes/shared/common.php
|
|
Route::get('/storage/file/{id}/{from}/{do?}/{locale?}', 'FileController@show')->name('storage_file');
|
|
```
|
|
|
|
### FileController
|
|
|
|
Der Controller unterstützt jetzt den optionalen `locale` Parameter für `invoice`, `delivery` und `credit`:
|
|
|
|
```php
|
|
public function show($id = null, $from = null, $do = 'file', $locale = null)
|
|
```
|
|
|
|
### UserInvoice Model
|
|
|
|
Neue Methoden zur Ermittlung verfügbarer Sprachen:
|
|
|
|
```php
|
|
public function getAvailableLocales(): array // Gibt ['en', 'es'] zurück
|
|
public function hasLocale(string $locale): bool
|
|
```
|
|
|
|
### Angepasste Views
|
|
|
|
| View | Änderung |
|
|
| ------------------------------------------------ | ------------------------------------------- |
|
|
| `resources/views/admin/sales/_detail.blade.php` | Download-Buttons für lokalisierte Versionen |
|
|
| `resources/views/portal/order/_detail.blade.php` | Download-Buttons für lokalisierte Versionen |
|
|
|
|
### Darstellung im Admin
|
|
|
|
Wenn lokalisierte Versionen existieren, werden zusätzliche Buttons angezeigt:
|
|
|
|
- **DE-Button** (ausgefüllt): `<i class="fa fa-download"></i>` - Deutsches Original
|
|
- **Locale-Button** (outline): `<i class="fa fa-download"></i> ES` - Lokalisierte Version
|
|
|
|
### UserCredit Model
|
|
|
|
Neue Methoden zur Ermittlung verfügbarer Sprachen (analog zu UserInvoice):
|
|
|
|
```php
|
|
public function getAvailableLocales(): array // Gibt ['en', 'es'] zurück
|
|
public function hasLocale(string $locale): bool
|
|
```
|
|
|
|
### Angepasste Views für Gutschriften
|
|
|
|
| View/Controller | Änderung |
|
|
| -------------------------------------------------- | -------------------------------------------------------- |
|
|
| `app/Http/Controllers/PaymentCreditController.php` | Download-Buttons für lokalisierte Versionen in Datatable |
|
|
|
|
### Darstellung der Gutschriften im Admin
|
|
|
|
Die Gutschriften-Tabelle (`/admin/payments/credit`) zeigt jetzt:
|
|
|
|
- **DE-Button** (ausgefüllt): `<i class="fa fa-download"></i>` - Deutsches Original
|
|
- **Locale-Button** (outline): `<i class="fa fa-download"></i> ES` - Lokalisierte Version (wenn vorhanden)
|
|
|
|
## Zusammenfassung: Mehrsprachige Dokumente
|
|
|
|
| Dokument | PDF-Erstellung | E-Mail-Anhänge | Admin-Download | Kopie-Hinweis |
|
|
| ------------ | -------------- | -------------- | -------------- | ------------- |
|
|
| Rechnung | ✅ | ✅ | ✅ | ✅ |
|
|
| Lieferschein | ✅ | ✅ | ✅ | ✅ |
|
|
| Gutschrift | ✅ | ✅ | ✅ | ✅ |
|