# 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): `` - Deutsches Original - **Locale-Button** (outline): ` 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): `` - Deutsches Original - **Locale-Button** (outline): ` ES` - Lokalisierte Version (wenn vorhanden) ## Zusammenfassung: Mehrsprachige Dokumente | Dokument | PDF-Erstellung | E-Mail-Anhänge | Admin-Download | Kopie-Hinweis | | ------------ | -------------- | -------------- | -------------- | ------------- | | Rechnung | ✅ | ✅ | ✅ | ✅ | | Lieferschein | ✅ | ✅ | ✅ | ✅ | | Gutschrift | ✅ | ✅ | ✅ | ✅ |