feat(handelsware-datev): Modulseite mit Import, Konten und Einstellungen

- Reiter Import: Vorschau mit neu-Markierung, Buchungsdatum (TTMM) aus dem Dateinamen, Download speichert neue Konten
- Reiter Konten: anlegen, bearbeiten, loeschen mit Rueckfrage, CSV-Import (ersetzt alles, nach Rueckfrage) und -Export
- Reiter Einstellungen nur fuer Administratoren; Texte de/en

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-10-02 11:47:09 +02:00
parent 44c1d4351f
commit 42b89f110b
15 changed files with 1726 additions and 1 deletions
+101
View File
@@ -1698,6 +1698,107 @@
"saved": "Die Einstellungen wurden gespeichert."
}
},
"handelswareDatev": {
"title": "Handelsware",
"description": "Handelswaren-Umsätze aus Excel den Erlöskonten zuordnen und als DATEV-Buchungsdatei herunterladen.",
"tabs": {
"import": "Import",
"accounts": "Konten",
"settings": "Einstellungen"
},
"loading": "Wird geladen …",
"notConfigured": {
"admin": "Standard-Erlöskonto und Startwert Gegenkonto sind noch nicht hinterlegt. Ohne diese Angaben können keine Konten zugeordnet werden.",
"adminAction": "Zu den Einstellungen",
"user": "Ein Administrator muss zuerst Standard-Erlöskonto und Startwert Gegenkonto hinterlegen."
},
"import": {
"dropPlaceholder": "Excel-Datei hierher ziehen oder klicken",
"dropFormats": ".xlsx, Buchungstext in Spalte A, Umsatz in Spalte B, Kopftext in Zelle B1",
"clear": "Datei entfernen",
"checking": "Datei wird geprüft …",
"headerText": "Kopftext",
"exportFilename": "Dateiname des Downloads",
"date": "Buchungsdatum (TTMM)",
"dateHint": "Wird aus dem Dateinamen abgeleitet (letzter Tag des Monats) und kann geändert werden.",
"dateInvalid": "Bitte das Datum als TTMM angeben, zum Beispiel 3103 für den 31.03.",
"columns": {
"text": "Buchungstext",
"amount": "Umsatz",
"sh": "S/H",
"counter": "Gegenkonto",
"date": "Datum",
"revenue": "Erlöskonto"
},
"newBadge": "neu",
"newSummary": "{count, plural, one {Ein neues Konto wird beim Herunterladen gespeichert} other {# neue Konten werden beim Herunterladen gespeichert}}",
"noNewAccounts": "Alle Produkte haben bereits ein Konto.",
"totals": "Summe Soll {debit}, Summe Haben {credit}",
"truncated": "Angezeigt werden die ersten {shown} von {total} Zeilen. Die Datei enthält alle Zeilen.",
"noRows": "Die Datei enthält keine Datenzeilen.",
"rowErrorsTitle": "Fehlerhafte Zeilen",
"rowErrorLine": "Zeile {line}",
"download": "Buchungsdatei herunterladen",
"downloading": "Datei wird erstellt …",
"downloaded": "Die Datei {filename} wurde heruntergeladen. {count, plural, =0 {Es wurden keine neuen Konten gespeichert.} one {Ein neues Konto wurde gespeichert.} other {# neue Konten wurden gespeichert.}}",
"reloadPreview": "Vorschau neu laden"
},
"accounts": {
"name": "Name",
"counter": "Gegenkonto",
"revenue": "Erlöskonto",
"actions": "Aktionen",
"empty": "Es sind noch keine Konten vorhanden.",
"add": "Hinzufügen",
"edit": "Bearbeiten",
"save": "Speichern",
"cancel": "Abbrechen",
"delete": "Löschen",
"deleteConfirm": "Konto „{name}“ wirklich löschen?",
"deleteYes": "Ja, löschen",
"namePlaceholder": "Produktname",
"importCsv": "CSV importieren",
"exportCsv": "CSV exportieren",
"importConfirm": "{count, plural, =0 {Die leere Kontenliste wird} one {Das vorhandene Konto wird} other {Alle # vorhandenen Konten werden}} durch den Inhalt der Datei „{file}“ ersetzt. Fortfahren?",
"importReplace": "Konten ersetzen",
"importDone": "{count, plural, one {Ein Konto wurde importiert.} other {# Konten wurden importiert.}}",
"importErrors": "Die Datei enthält Fehler, es wurde nichts geändert:",
"csvHint": "CSV-Format: Name;Gegenkonto;Konto (Semikolon, UTF-8 oder Windows-1252).",
"invalidNumber": "Gegenkonto und Erlöskonto müssen ganze Zahlen sein.",
"nameRequired": "Bitte einen Namen angeben."
},
"settings": {
"intro": "Diese Angaben gelten für alle Benutzer Ihres Mandanten und werden nur einmal hinterlegt.",
"erloeskonto": "Standard-Erlöskonto",
"erloeskontoHelp": "Wird neuen Konten zugeordnet.",
"startGegenkonto": "Startwert Gegenkonto",
"startGegenkontoHelp": "Erste Nummer, die vergeben wird, wenn die Kontenliste leer ist.",
"numberInvalid": "Bitte eine ganze Zahl von 1 bis 999999999 eingeben.",
"save": "Speichern",
"saving": "Wird gespeichert …",
"saved": "Die Einstellungen wurden gespeichert."
},
"errors": {
"settingsMissing": "Standard-Erlöskonto und Startwert Gegenkonto sind noch nicht hinterlegt.",
"invalidFile": "Die Datei ist keine gültige Excel-Datei.",
"tooManyRows": "Die Datei enthält zu viele Datenzeilen (höchstens 10000).",
"rowErrors": "Die Datei enthält fehlerhafte Zeilen und kann nicht exportiert werden.",
"noRows": "Die Datei enthält keine Datenzeilen.",
"buchungsdatumInvalid": "Das Buchungsdatum muss als TTMM angegeben werden, zum Beispiel 3103.",
"accountsChanged": "Die Kontenliste wurde inzwischen geändert. Bitte laden Sie die Datei erneut, um die Vorschau zu aktualisieren.",
"nameTaken": "Ein Konto mit diesem Namen gibt es bereits.",
"umsatzInvalid": "Der Umsatz ist keine gültige Zahl.",
"csvErrors": "Die CSV-Datei enthält Fehler. Es wurde nichts geändert.",
"newAccountsInvalid": "Die Angaben zu den neuen Konten sind ungültig.",
"nameEmpty": "Der Name fehlt.",
"nameTooLong": "Der Name ist zu lang (höchstens 120 Zeichen).",
"gegenkontoInvalid": "Das Gegenkonto muss eine ganze Zahl von 1 bis 999999999 sein.",
"erloeskontoInvalid": "Das Erlöskonto muss eine ganze Zahl von 1 bis 999999999 sein.",
"missingErloeskonto": "Das Erlöskonto fehlt und es ist kein Standard-Erlöskonto hinterlegt.",
"duplicateName": "Der Name kommt in der Datei mehrfach vor.",
"request": "Die Anfrage ist fehlgeschlagen. Bitte versuchen Sie es erneut."
}
},
"moduleCategories": {
"domain-tools": "Domains",
"security-tools": "Sicherheit",
+101
View File
@@ -1698,6 +1698,107 @@
"saved": "The settings have been saved."
}
},
"handelswareDatev": {
"title": "Merchandise",
"description": "Map merchandise sales from Excel to revenue accounts and download them as a DATEV booking file.",
"tabs": {
"import": "Import",
"accounts": "Accounts",
"settings": "Settings"
},
"loading": "Loading …",
"notConfigured": {
"admin": "The default revenue account and the starting counter account have not been set yet. Without them no accounts can be assigned.",
"adminAction": "Go to settings",
"user": "An administrator has to set the default revenue account and the starting counter account first."
},
"import": {
"dropPlaceholder": "Drag an Excel file here or click",
"dropFormats": ".xlsx, booking text in column A, amount in column B, header text in cell B1",
"clear": "Remove file",
"checking": "Checking file …",
"headerText": "Header text",
"exportFilename": "Download file name",
"date": "Booking date (DDMM)",
"dateHint": "Derived from the file name (last day of the month) and can be changed.",
"dateInvalid": "Please enter the date as DDMM, for example 3103 for 31 March.",
"columns": {
"text": "Booking text",
"amount": "Amount",
"sh": "D/C",
"counter": "Counter account",
"date": "Date",
"revenue": "Revenue account"
},
"newBadge": "new",
"newSummary": "{count, plural, one {One new account will be saved when you download} other {# new accounts will be saved when you download}}",
"noNewAccounts": "All products already have an account.",
"totals": "Total debit {debit}, total credit {credit}",
"truncated": "Showing the first {shown} of {total} rows. The file contains all rows.",
"noRows": "The file contains no data rows.",
"rowErrorsTitle": "Faulty rows",
"rowErrorLine": "Row {line}",
"download": "Download booking file",
"downloading": "Creating file …",
"downloaded": "The file {filename} has been downloaded. {count, plural, =0 {No new accounts were saved.} one {One new account was saved.} other {# new accounts were saved.}}",
"reloadPreview": "Reload preview"
},
"accounts": {
"name": "Name",
"counter": "Counter account",
"revenue": "Revenue account",
"actions": "Actions",
"empty": "There are no accounts yet.",
"add": "Add",
"edit": "Edit",
"save": "Save",
"cancel": "Cancel",
"delete": "Delete",
"deleteConfirm": "Really delete account “{name}”?",
"deleteYes": "Yes, delete",
"namePlaceholder": "Product name",
"importCsv": "Import CSV",
"exportCsv": "Export CSV",
"importConfirm": "{count, plural, =0 {The empty account list is} one {The existing account is} other {All # existing accounts are}} replaced by the content of the file “{file}”. Continue?",
"importReplace": "Replace accounts",
"importDone": "{count, plural, one {One account was imported.} other {# accounts were imported.}}",
"importErrors": "The file contains errors, nothing was changed:",
"csvHint": "CSV format: Name;Counter account;Account (semicolon, UTF-8 or Windows-1252).",
"invalidNumber": "Counter account and revenue account must be whole numbers.",
"nameRequired": "Please enter a name."
},
"settings": {
"intro": "These values apply to all users of your tenant and only have to be set once.",
"erloeskonto": "Default revenue account",
"erloeskontoHelp": "Assigned to new accounts.",
"startGegenkonto": "Starting counter account",
"startGegenkontoHelp": "First number handed out when the account list is empty.",
"numberInvalid": "Please enter a whole number from 1 to 999999999.",
"save": "Save",
"saving": "Saving …",
"saved": "The settings have been saved."
},
"errors": {
"settingsMissing": "The default revenue account and the starting counter account have not been set yet.",
"invalidFile": "The file is not a valid Excel file.",
"tooManyRows": "The file contains too many data rows (10000 at most).",
"rowErrors": "The file contains faulty rows and cannot be exported.",
"noRows": "The file contains no data rows.",
"buchungsdatumInvalid": "The booking date must be given as DDMM, for example 3103.",
"accountsChanged": "The account list has changed in the meantime. Please upload the file again to refresh the preview.",
"nameTaken": "An account with this name already exists.",
"umsatzInvalid": "The amount is not a valid number.",
"csvErrors": "The CSV file contains errors. Nothing was changed.",
"newAccountsInvalid": "The details of the new accounts are invalid.",
"nameEmpty": "The name is missing.",
"nameTooLong": "The name is too long (120 characters at most).",
"gegenkontoInvalid": "The counter account must be a whole number from 1 to 999999999.",
"erloeskontoInvalid": "The revenue account must be a whole number from 1 to 999999999.",
"missingErloeskonto": "The revenue account is missing and no default revenue account is set.",
"duplicateName": "The name appears more than once in the file.",
"request": "The request failed. Please try again."
}
},
"moduleCategories": {
"domain-tools": "Domains",
"security-tools": "Security",
@@ -146,6 +146,8 @@ export const UMLAUT_ALLOWLIST: readonly string[] = [
'Bildausschnitt',
// XFrame-Widget (quick-260921-qd3): „In neuem Tab öffnen“, korrektes Deutsch wie neuen
'neuem',
// quick-261002-fm5: Handelsware („Ein neues Konto wird gespeichert“), korrektes Deutsch
'neues',
// XFrame-Ausschnitt (quick-260922-ge2): korrektes Deutsch mit „ss“
'Ausschnitt',
'Absenderadresse',