feat: E-Rechnungs-Vorschau mit Versand, USt-IdNr.-Validierung und Icon-Buttons

- Rechnungsvorschau (CreateInvoiceView): ZUGFeRD-ZIP wird schon vor der
  Vorschau über das PDF Tool erzeugt und das signierte PDF daraus angezeigt;
  "Speichern" heißt jetzt "Senden" und versendet die Rechnung nach dem
  Speichern als E-Rechnung per E-Mail (Status "Versendet")
- USt-IdNr.-Formatvalidierung (VatIdUtil, EU-Länderformate) in Profil-
  Rechnungsdaten sowie Kunde anlegen/bearbeiten, mit Unit-Tests
- Rechnungsliste: Aktions-Buttons durch Icon-Buttons mit Tooltip ersetzt
- Jobs-Seite: CSV-Export als Icon-Button, Filter greifen automatisch,
  "Filter anwenden"-Button entfernt
- Neue Übersetzungsschlüssel in allen 10 Sprachdateien

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 11:06:21 +02:00
co-authored by Claude Fable 5
parent 1741ccc67a
commit 5169527f1f
18 changed files with 398 additions and 65 deletions
@@ -86,6 +86,7 @@ profile.validation.zip.required=Postleitzahl ist erforderlich
profile.validation.city.required=Stadt ist erforderlich
profile.validation.taxnumber.required=Steuernummer ist erforderlich
profile.validation.ustid.required=USt-IdNr. ist erforderlich
profile.validation.ustid.invalid=Ungültiges Format der USt-IdNr. (z. B. DE123456789)
profile.validation.firstname.required=Vorname ist erforderlich
profile.validation.lastname.required=Nachname ist erforderlich
profile.validation.phone.required=Telefonnummer ist erforderlich
@@ -699,6 +700,11 @@ createinvoice.button.save=Speichern
createinvoice.confirm.save.title=Rechnung speichern
createinvoice.confirm.save.message=Diese Rechnung wird dauerhaft gespeichert und kann anschlie\u00dfend nicht mehr ver\u00e4ndert werden. Fortfahren?
createinvoice.confirm.save.confirm=Ja, speichern
createinvoice.button.send=Senden
createinvoice.confirm.send.title=Rechnung senden
createinvoice.confirm.send.message=Diese Rechnung wird dauerhaft gespeichert und als E-Rechnung (ZIP) per E-Mail an den Kunden versendet. Fortfahren?
createinvoice.confirm.send.confirm=Ja, senden
createinvoice.notification.sent=Rechnung {0} wurde als E-Rechnung an {1} versendet
# Invoices
invoices.title=Rechnungen
@@ -75,6 +75,7 @@ profile.validation.zip.required=Postiindeks on kohustuslik
profile.validation.city.required=Linn on kohustuslik
profile.validation.taxnumber.required=Maksunumber on kohustuslik
profile.validation.ustid.required=KMKR nr on kohustuslik
profile.validation.ustid.invalid=KMKR numbri vorming on vale (nt DE123456789)
profile.validation.firstname.required=Eesnimi on kohustuslik
profile.validation.lastname.required=Perekonnanimi on kohustuslik
profile.validation.phone.required=Telefoninumber on kohustuslik
@@ -639,6 +640,11 @@ createinvoice.button.save=Salvesta
createinvoice.confirm.save.title=Arve salvestamine
createinvoice.confirm.save.message=See arve salvestatakse p\u00fcsivalt ja seda ei saa hiljem muuta. Kas j\u00e4tkata?
createinvoice.confirm.save.confirm=Jah, salvesta
createinvoice.button.send=Saada
createinvoice.confirm.send.title=Saada arve
createinvoice.confirm.send.message=Arve salvestatakse jäädavalt ja saadetakse kliendile e-posti teel e-arvena (ZIP). Kas jätkata?
createinvoice.confirm.send.confirm=Jah, saada
createinvoice.notification.sent=Arve {0} saadeti e-arvena aadressile {1}
invoices.title=Arved
invoices.column.number=Number
invoices.column.customer=Klient
@@ -86,6 +86,7 @@ profile.validation.zip.required=Postal code is required
profile.validation.city.required=City is required
profile.validation.taxnumber.required=Tax number is required
profile.validation.ustid.required=VAT ID is required
profile.validation.ustid.invalid=Invalid VAT ID format (e.g. DE123456789)
profile.validation.firstname.required=First name is required
profile.validation.lastname.required=Last name is required
profile.validation.phone.required=Phone number is required
@@ -699,6 +700,11 @@ createinvoice.button.save=Save
createinvoice.confirm.save.title=Save Invoice
createinvoice.confirm.save.message=This invoice will be permanently saved and cannot be modified afterwards. Continue?
createinvoice.confirm.save.confirm=Yes, save
createinvoice.button.send=Send
createinvoice.confirm.send.title=Send Invoice
createinvoice.confirm.send.message=This invoice will be permanently saved and sent to the customer by email as an e-invoice (ZIP). Continue?
createinvoice.confirm.send.confirm=Yes, send
createinvoice.notification.sent=Invoice {0} has been sent as an e-invoice to {1}
# Invoices
invoices.title=Invoices
@@ -85,6 +85,7 @@ profile.validation.zip.required=C\u00f3digo postal es obligatorio
profile.validation.city.required=Ciudad es obligatorio
profile.validation.taxnumber.required=Número fiscal es obligatorio
profile.validation.ustid.required=NIF-IVA es obligatorio
profile.validation.ustid.invalid=Formato de NIF-IVA no válido (p. ej. DE123456789)
profile.validation.firstname.required=Nombre es obligatorio
profile.validation.lastname.required=Apellido es obligatorio
profile.validation.phone.required=N\u00famero de tel\u00e9fono es obligatorio
@@ -696,6 +697,11 @@ createinvoice.button.save=Guardar
createinvoice.confirm.save.title=Guardar factura
createinvoice.confirm.save.message=Esta factura se guardar\u00e1 de forma permanente y no podr\u00e1 ser modificada posteriormente. \u00bfDesea continuar?
createinvoice.confirm.save.confirm=S\u00ed, guardar
createinvoice.button.send=Enviar
createinvoice.confirm.send.title=Enviar factura
createinvoice.confirm.send.message=La factura se guardará de forma permanente y se enviará al cliente por correo electrónico como factura electrónica (ZIP). ¿Continuar?
createinvoice.confirm.send.confirm=Sí, enviar
createinvoice.notification.sent=La factura {0} se ha enviado como factura electrónica a {1}
# Invoices
invoices.title=Facturas
@@ -85,6 +85,7 @@ profile.validation.zip.required=Le code postal est obligatoire
profile.validation.city.required=La ville est obligatoire
profile.validation.taxnumber.required=Le numéro fiscal est obligatoire
profile.validation.ustid.required=Le n° TVA intracommunautaire est obligatoire
profile.validation.ustid.invalid=Format de numéro de TVA invalide (p. ex. DE123456789)
profile.validation.firstname.required=Le pr\u00e9nom est obligatoire
profile.validation.lastname.required=Le nom est obligatoire
profile.validation.phone.required=Le num\u00e9ro de t\u00e9l\u00e9phone est obligatoire
@@ -696,6 +697,11 @@ createinvoice.button.save=Enregistrer
createinvoice.confirm.save.title=Enregistrer la facture
createinvoice.confirm.save.message=Cette facture sera enregistr\u00e9e de mani\u00e8re permanente et ne pourra plus \u00eatre modifi\u00e9e par la suite. Continuer ?
createinvoice.confirm.save.confirm=Oui, enregistrer
createinvoice.button.send=Envoyer
createinvoice.confirm.send.title=Envoyer la facture
createinvoice.confirm.send.message=La facture sera enregistrée définitivement et envoyée au client par e-mail en tant que facture électronique (ZIP). Continuer ?
createinvoice.confirm.send.confirm=Oui, envoyer
createinvoice.notification.sent=La facture {0} a été envoyée en tant que facture électronique à {1}
# Invoices
invoices.title=Factures
@@ -85,6 +85,7 @@ profile.validation.zip.required=Pašto kodas yra privalomas
profile.validation.city.required=Miestas yra privalomas
profile.validation.taxnumber.required=Mokesčių mokėtojo numeris yra privalomas
profile.validation.ustid.required=PVM mokėtojo kodas yra privalomas
profile.validation.ustid.invalid=Neteisingas PVM mokėtojo kodo formatas (pvz., DE123456789)
profile.validation.firstname.required=Vardas yra privalomas
profile.validation.lastname.required=Pavardė yra privaloma
profile.validation.phone.required=Telefono numeris yra privalomas
@@ -698,6 +699,11 @@ createinvoice.button.save=Išsaugoti
createinvoice.confirm.save.title=Išsaugoti sąskaitą
createinvoice.confirm.save.message=Ši sąskaita bus išsaugota visam laikui ir vėliau jos nebebus galima keisti. Tęsti?
createinvoice.confirm.save.confirm=Taip, išsaugoti
createinvoice.button.send=Siųsti
createinvoice.confirm.send.title=Siųsti sąskaitą
createinvoice.confirm.send.message=Sąskaita bus visam laikui išsaugota ir išsiųsta klientui el. paštu kaip e. sąskaita (ZIP). Tęsti?
createinvoice.confirm.send.confirm=Taip, siųsti
createinvoice.notification.sent=Sąskaita {0} išsiųsta kaip e. sąskaita adresu {1}
# Invoices
invoices.title=Sąskaitos faktūros
@@ -85,6 +85,7 @@ profile.validation.zip.required=Pasta indekss ir obligāts
profile.validation.city.required=Pilsēta ir obligāta
profile.validation.taxnumber.required=Nodokļu maksātāja numurs ir obligāts
profile.validation.ustid.required=PVN numurs ir obligāts
profile.validation.ustid.invalid=Nederīgs PVN numura formāts (piem., DE123456789)
profile.validation.firstname.required=Vārds ir obligāts
profile.validation.lastname.required=Uzvārds ir obligāts
profile.validation.phone.required=Tālruņa numurs ir obligāts
@@ -696,6 +697,11 @@ createinvoice.button.save=Saglabāt
createinvoice.confirm.save.title=Saglabāt rēķinu
createinvoice.confirm.save.message=Šis rēķins tiks neatgriezeniski saglabāts un pēc tam to vairs nevarēs mainīt. Turpināt?
createinvoice.confirm.save.confirm=Jā, saglabāt
createinvoice.button.send=Sūtīt
createinvoice.confirm.send.title=Sūtīt rēķinu
createinvoice.confirm.send.message=Rēķins tiks neatgriezeniski saglabāts un nosūtīts klientam pa e-pastu kā e-rēķins (ZIP). Vai turpināt?
createinvoice.confirm.send.confirm=Jā, sūtīt
createinvoice.notification.sent=Rēķins {0} nosūtīts kā e-rēķins uz {1}
# Invoices
invoices.title=Rēķini
@@ -85,6 +85,7 @@ profile.validation.zip.required=Kod pocztowy jest wymagany
profile.validation.city.required=Miasto jest wymagane
profile.validation.taxnumber.required=Numer podatkowy jest wymagany
profile.validation.ustid.required=NIP UE jest wymagany
profile.validation.ustid.invalid=Nieprawidłowy format numeru VAT UE (np. DE123456789)
profile.validation.firstname.required=Imi\u0119 jest wymagane
profile.validation.lastname.required=Nazwisko jest wymagane
profile.validation.phone.required=Numer telefonu jest wymagany
@@ -696,6 +697,11 @@ createinvoice.button.save=Zapisz
createinvoice.confirm.save.title=Zapisz faktur\u0119
createinvoice.confirm.save.message=Ta faktura zostanie trwale zapisana i nie b\u0119dzie mog\u0142a by\u0107 p\u00f3\u017aniej zmieniona. Kontynuowa\u0107?
createinvoice.confirm.save.confirm=Tak, zapisz
createinvoice.button.send=Wyślij
createinvoice.confirm.send.title=Wyślij fakturę
createinvoice.confirm.send.message=Faktura zostanie trwale zapisana i wysłana do klienta e-mailem jako e-faktura (ZIP). Kontynuować?
createinvoice.confirm.send.confirm=Tak, wyślij
createinvoice.notification.sent=Faktura {0} została wysłana jako e-faktura na adres {1}
# Invoices
invoices.title=Faktury
@@ -85,6 +85,7 @@ profile.validation.zip.required=Почтовый индекс обязателе
profile.validation.city.required=Город обязателен
profile.validation.taxnumber.required=Налоговый номер обязателен
profile.validation.ustid.required=Идентификатор плательщика НДС обязателен
profile.validation.ustid.invalid=Неверный формат идентификационного номера НДС (напр. DE123456789)
profile.validation.firstname.required=Имя обязательно
profile.validation.lastname.required=Фамилия обязательна
profile.validation.phone.required=Номер телефона обязателен
@@ -696,6 +697,11 @@ createinvoice.button.save=Сохранить
createinvoice.confirm.save.title=Сохранить счёт
createinvoice.confirm.save.message=Этот счёт будет сохранён навсегда и не может быть изменён впоследствии. Продолжить?
createinvoice.confirm.save.confirm=Да, сохранить
createinvoice.button.send=Отправить
createinvoice.confirm.send.title=Отправить счёт
createinvoice.confirm.send.message=Счёт будет окончательно сохранён и отправлен клиенту по электронной почте как электронный счёт (ZIP). Продолжить?
createinvoice.confirm.send.confirm=Да, отправить
createinvoice.notification.sent=Счёт {0} отправлен как электронный счёт на {1}
# Invoices
invoices.title=Счета
@@ -85,6 +85,7 @@ profile.validation.zip.required=Posta kodu gereklidir
profile.validation.city.required=\u015eehir gereklidir
profile.validation.taxnumber.required=Vergi numarası gereklidir
profile.validation.ustid.required=KDV kimlik no gereklidir
profile.validation.ustid.invalid=Geçersiz KDV kimlik numarası biçimi (örn. DE123456789)
profile.validation.firstname.required=Ad gereklidir
profile.validation.lastname.required=Soyad gereklidir
profile.validation.phone.required=Telefon numaras\u0131 gereklidir
@@ -696,6 +697,11 @@ createinvoice.button.save=Kaydet
createinvoice.confirm.save.title=Faturay\u0131 Kaydet
createinvoice.confirm.save.message=Bu fatura kal\u0131c\u0131 olarak kaydedilecek ve sonras\u0131nda de\u011fi\u015ftirilemeyecektir. Devam edilsin mi?
createinvoice.confirm.save.confirm=Evet, kaydet
createinvoice.button.send=Gönder
createinvoice.confirm.send.title=Faturayı gönder
createinvoice.confirm.send.message=Fatura kalıcı olarak kaydedilecek ve müşteriye e-posta ile e-fatura (ZIP) olarak gönderilecektir. Devam edilsin mi?
createinvoice.confirm.send.confirm=Evet, gönder
createinvoice.notification.sent=Fatura {0}, e-fatura olarak {1} adresine gönderildi
# Invoices
invoices.title=Faturalar