diff --git a/config/locales/doorkeeper.de.yml b/config/locales/doorkeeper.de.yml
index 4c6cf9fcb..4dd84b1de 100644
--- a/config/locales/doorkeeper.de.yml
+++ b/config/locales/doorkeeper.de.yml
@@ -65,12 +65,15 @@ de:
authorize: 'Autorisieren'
deny: 'Ablehnen'
error:
+ go_back: 'Zurück'
title: 'Ein Fehler ist aufgetreten'
new:
title: 'Autorisierung erforderlich'
prompt: '%{client_name} Zugriff auf dein Konto erlauben?'
able_to: 'Diese Anwendung kann Folgendes tun'
show:
+ authorization_code_label: 'Autorisierungscode:'
+ copy_instructions: 'Kopiere diesen Code und füge ihn in der Anwendung ein.'
title: 'Autorisierungscode'
form_post:
title: 'Dieses Formular absenden'
diff --git a/config/locales/models/coinstats_item/de.yml b/config/locales/models/coinstats_item/de.yml
index d56bc04aa..ee9307f5e 100644
--- a/config/locales/models/coinstats_item/de.yml
+++ b/config/locales/models/coinstats_item/de.yml
@@ -6,7 +6,7 @@ de:
importing_wallets: Wallets werden von CoinStats importiert...
checking_configuration: Wallet-Konfiguration wird geprüft...
wallets_need_setup:
- one: "1 Wallet muss eingerichtet werden..."
+ one: "%{count} Wallet muss eingerichtet werden..."
other: "%{count} Wallets müssen eingerichtet werden..."
processing_holdings: Bestände werden verarbeitet...
calculating_balances: Salden werden berechnet...
diff --git a/config/locales/models/user/de.yml b/config/locales/models/user/de.yml
index 5e3474af0..96a262371 100644
--- a/config/locales/models/user/de.yml
+++ b/config/locales/models/user/de.yml
@@ -4,8 +4,8 @@ de:
attributes:
user:
email: E-Mail
- family: Familie
- family_id: Familie
+ family: "%{moniker}"
+ family_id: "%{moniker}"
first_name: Vorname
last_name: Nachname
password: Passwort
@@ -18,4 +18,3 @@ de:
cannot_deactivate_admin_with_other_users: Admin kann das Konto nicht löschen, solange noch andere Benutzer vorhanden sind Bitte zuerst alle Mitglieder löschen
profile_image:
invalid_file_size: Dateigröße muss kleiner als %{max_megabytes}MB sein
-
diff --git a/config/locales/views/binance_items/de.yml b/config/locales/views/binance_items/de.yml
index 391f67c30..288ff74cd 100644
--- a/config/locales/views/binance_items/de.yml
+++ b/config/locales/views/binance_items/de.yml
@@ -17,6 +17,7 @@ de:
one: "%{count} Konto verfügbar"
other: "%{count} Konten verfügbar"
select_all: Alle auswählen
+ historical_import: Verlaufsimport
import_selected: Ausgewählte importieren
cancel: Abbrechen
creating: Importiere...
diff --git a/config/locales/views/enable_banking_items/de.yml b/config/locales/views/enable_banking_items/de.yml
index 2b5b6da58..f31d16938 100644
--- a/config/locales/views/enable_banking_items/de.yml
+++ b/config/locales/views/enable_banking_items/de.yml
@@ -110,6 +110,7 @@ de:
creating_accounts: Konten werden angelegt …
header_subtitle: Wähl die passende Kontoart für deine importierten Konten
historical_data_range: 'Zeitraum der Historie:'
+ psd2_savings_notice: 'Hinweis: Einige regulierte französische Sparkonten (Livret A, PEL, LEP, LDDS) sind über Open Banking (PSD2) nur eingeschränkt oder gar nicht verfügbar. Wenn ein Sparkonto fehlt, kannst du es manuell hinzufügen.'
sync_start_date_help: Wähl, wie weit zurück die Transaktionshistorie geholt werden soll. Verfügbar sind maximal 2 Jahre.
sync_start_date_label: 'Transaktionen synchronisieren ab:'
title: Enable-Banking-Konten einrichten
diff --git a/config/locales/views/goals/de.yml b/config/locales/views/goals/de.yml
index d97858d92..a00cdca1d 100644
--- a/config/locales/views/goals/de.yml
+++ b/config/locales/views/goals/de.yml
@@ -94,11 +94,13 @@ de:
heading: Archiviert
chips:
all: Alle
+ aria: Ziele nach Status filtern
behind: Hinter Plan
completed: Erreicht
no_target_date: Offen
on_track: Im Plan
paused: Pausiert
+ chips_aria: Ziele nach Status filtern
empty_filtered: Kein Ziel passt.
goals_section:
heading: Ziele
@@ -152,6 +154,9 @@ de:
pause:
invalid_transition: Dieses Ziel lässt sich in seinem aktuellen Zustand nicht pausieren.
success: Ziel pausiert.
+ perform_transition!:
+ invalid_transition: Ziel kann nicht in diesen Status wechseln.
+ success: Ziel aktualisiert.
reopen:
invalid_transition: Dieses Ziel lässt sich in seinem aktuellen Zustand nicht wieder öffnen.
success: Ziel wieder geöffnet.
diff --git a/config/locales/views/indexa_capital_items/de.yml b/config/locales/views/indexa_capital_items/de.yml
index 184e8e8fc..0bd9b469d 100644
--- a/config/locales/views/indexa_capital_items/de.yml
+++ b/config/locales/views/indexa_capital_items/de.yml
@@ -42,12 +42,12 @@ de:
fields:
api_token:
label: "API-Token"
- description: "Ihr schreibgeschützter API-Token aus dem IndexaCapital Dashboard"
+ description: "Dein schreibgeschützter API-Token aus dem IndexaCapital Dashboard"
placeholder_new: "API-Token hier einfügen"
placeholder_update: "Neuen API-Token zum Aktualisieren eingeben"
username:
label: "Benutzername"
- description: "Ihr IndexaCapital Benutzername/E-Mail"
+ description: "Dein IndexaCapital Benutzername/E-Mail"
placeholder_new: "Benutzername hier einfügen"
placeholder_update: "Neuen Benutzernamen zum Aktualisieren eingeben"
document:
@@ -57,7 +57,7 @@ de:
placeholder_update: "Neue Dokument-ID zum Aktualisieren eingeben"
password:
label: "Passwort"
- description: "Ihr IndexaCapital Passwort"
+ description: "Dein IndexaCapital Passwort"
placeholder_new: "Passwort hier einfügen"
placeholder_update: "Neues Passwort zum Aktualisieren eingeben"
diff --git a/config/locales/views/invitation_mailer/de.yml b/config/locales/views/invitation_mailer/de.yml
index 674ac4d53..a1e6c91fd 100644
--- a/config/locales/views/invitation_mailer/de.yml
+++ b/config/locales/views/invitation_mailer/de.yml
@@ -3,6 +3,6 @@ de:
invitation_mailer:
invite_email:
accept_button: Einladung annehmen
- body: "%{inviter} hat dich eingeladen, der Familie %{family} auf %{product_name} beizutreten."
+ body: "%{inviter} hat dich eingeladen, der %{family} %{moniker} auf %{product_name} beizutreten."
expiry_notice: Diese Einladung läuft in %{days} Tagen ab.
greeting: Willkommen bei %{product_name}!
diff --git a/config/locales/views/invitations/de.yml b/config/locales/views/invitations/de.yml
index a53e48439..03fa58187 100644
--- a/config/locales/views/invitations/de.yml
+++ b/config/locales/views/invitations/de.yml
@@ -24,5 +24,5 @@ de:
role_label: Rolle
role_member: Mitglied
submit: Einladung senden
- subtitle: Lad jemanden in deine %{moniker} ein
+ subtitle: Lad jemanden in dein %{moniker}-Konto auf %{product_name} ein
title: Jemanden einladen
diff --git a/config/locales/views/kraken_items/de.yml b/config/locales/views/kraken_items/de.yml
index c16449ed1..341d28654 100644
--- a/config/locales/views/kraken_items/de.yml
+++ b/config/locales/views/kraken_items/de.yml
@@ -8,7 +8,7 @@ de:
description: "Mit %{name} verknüpfen"
create:
default_name: Kraken
- success: Erfolgreich mit Kraken verbunden. Ihr Börsenkonto wird synchronisiert.
+ success: Erfolgreich mit Kraken verbunden. Dein Börsenkonto wird synchronisiert.
update:
success: Kraken-Verbindung erfolgreich aktualisiert.
destroy:
@@ -66,7 +66,7 @@ de:
status_never: Noch nie synchronisiert
delete: Löschen
no_accounts_title: Keine Konten gefunden
- no_accounts_message: Ihr Kraken-Börsenkonto erscheint hier nach der Synchronisierung.
+ no_accounts_message: Dein Kraken-Börsenkonto erscheint hier nach der Synchronisierung.
setup_needed: Konto bereit zum Import
setup_description: Importier diese Kraken-Verbindung als Krypto-Börsenkonto.
setup_action: Konto importieren
diff --git a/config/locales/views/lunchflow_items/de.yml b/config/locales/views/lunchflow_items/de.yml
index 3f7a7618d..ff02c4b7f 100644
--- a/config/locales/views/lunchflow_items/de.yml
+++ b/config/locales/views/lunchflow_items/de.yml
@@ -20,6 +20,7 @@ de:
other: "%{count} Konten mit leerem Namen können nicht verknüpft werden"
link_failed: Konten konnten nicht verknüpft werden
no_accounts_selected: Bitte wähle mindestens ein Konto aus
+ no_api_key: Der Lunch-Flow-API-Key ist nicht eingerichtet. Richte ihn in den Einstellungen ein.
partial_invalid: "%{created_count} Konto/Konten verknüpft, %{already_linked_count} waren bereits verknüpft, %{invalid_count} hatten ungültige Namen"
partial_success: "%{created_count} Konto/Konten erfolgreich verknüpft. %{already_linked_count} Konto/Konten waren bereits verknüpft: %{already_linked_names}"
success:
@@ -50,6 +51,7 @@ de:
link_accounts: Ausgewählte Konten verknüpfen
no_accounts_found: Keine Konten gefunden. Bitte überprüfe deine API-Key-Konfiguration.
no_api_key: Lunch‑Flow-API-Schlüssel ist nicht konfiguriert. Bitte konfiguriere ihn in den Einstellungen.
+ no_credentials_configured: Richte zuerst deine Lunch-Flow-Zugangsdaten in den Anbietereinstellungen ein.
no_name_placeholder: "(Kein Name)"
title: Lunch‑Flow-Konten auswählen
select_existing_account:
@@ -63,6 +65,7 @@ de:
no_account_specified: Kein Konto angegeben
no_accounts_found: Keine Lunch‑Flow-Konten gefunden. Bitte überprüfe deine API-Key-Konfiguration.
no_api_key: Lunch‑Flow-API-Schlüssel ist nicht konfiguriert. Bitte konfiguriere ihn in den Einstellungen.
+ no_credentials_configured: Richte zuerst deine Lunch-Flow-Zugangsdaten in den Anbietereinstellungen ein.
no_name_placeholder: "(Kein Name)"
title: "%{account_name} mit Lunch‑Flow verknüpfen"
link_existing_account:
@@ -72,6 +75,7 @@ de:
lunchflow_account_already_linked: Dieses Lunch‑Flow-Konto ist bereits mit einem anderen Konto verknüpft
lunchflow_account_not_found: Lunch‑Flow-Konto nicht gefunden
missing_parameters: Erforderliche Parameter fehlen
+ no_api_key: Der Lunch-Flow-API-Key ist nicht eingerichtet. Richte ihn in den Anbietereinstellungen ein.
success: "%{account_name} erfolgreich mit Lunch‑Flow verknüpft"
setup_accounts:
account_type_label: "Kontotyp:"
diff --git a/config/locales/views/merchants/de.yml b/config/locales/views/merchants/de.yml
index 8a368cce3..53a67251a 100644
--- a/config/locales/views/merchants/de.yml
+++ b/config/locales/views/merchants/de.yml
@@ -19,9 +19,9 @@ de:
merge: Händler zusammenführen
title: Händler
family_title: Händler deiner %{moniker}
- family_empty: Noch keine Händler der Familie vorhanden
+ family_empty: Noch keine Händler der %{moniker} vorhanden
provider_title: Anbieter-Händler
- provider_empty: Noch keine Anbieter-Händler mit dieser Familie verbunden
+ provider_empty: Noch keine Anbieter-Händler mit dieser %{moniker} verbunden
provider_read_only: Anbieter-Händler werden von deinen verbundenen Instituten synchronisiert. Sie lassen sich hier nicht bearbeiten.
provider_info: Diese Händler wurden automatisch von deinen Bankverbindungen oder der KI erkannt. Du kannst sie bearbeiten, um deine eigene Kopie zu erstellen, oder sie entfernen, um sie von deinen Transaktionen zu trennen.
unlinked_title: Kürzlich getrennt
diff --git a/config/locales/views/questrade_items/de.yml b/config/locales/views/questrade_items/de.yml
index 0575d953e..613e91b99 100644
--- a/config/locales/views/questrade_items/de.yml
+++ b/config/locales/views/questrade_items/de.yml
@@ -49,7 +49,11 @@ de:
loading_message: Questrade-Konten werden geladen …
loading_title: Wird geladen
panel:
+ disconnect: Trennen
+ disconnect_confirm: Diese Questrade-Verbindung wirklich trennen? Dadurch werden alle synchronisierten Kontodaten entfernt.
+ eyebrow: Questrade
field_descriptions: 'Erläuterung der Felder:'
+ help_text: Sure nutzt diese Zugangsdaten nur, um deine Questrade-Konten, Bestände und Aktivitäten zu synchronisieren.
fields:
api_server:
description: Dein Questrade-API-Server
@@ -68,6 +72,13 @@ de:
setup_instructions: 'So richtest du es ein:'
status_configured_html: Eingerichtet und einsatzbereit. Im Reiter Konten verwaltest und richtest du Konten ein.
status_not_configured: Nicht eingerichtet
+ steps:
+ s1_html: Öffne dein Questrade-Dashboard.
+ s2: Erstelle oder kopiere deine API-Zugangsdaten.
+ s3_html: Füge den Refresh Token und den API-Server unten ein.
+ s4: Speichere die Verbindung.
+ s5: Starte einen Sync, um Konten zu finden.
+ s6: Richte die gefundenen Konten im Konten-Reiter ein.
step_1: Öffne dein Questrade-Dashboard und hol dir deine Zugangsdaten
step_2: Trag die Zugangsdaten unten ein und klick auf Speichern
step_3: Nach erfolgreicher Verbindung richtest du im Reiter „Konten“ die neuen Konten ein
@@ -115,15 +126,21 @@ de:
all_accounts_already_linked: Alle Questrade-Konten sind bereits verknüpft
api_error: 'API-Fehler: %{message}'
balance_label: 'Saldo:'
+ buttons:
+ cancel: Abbrechen
+ link: Verknüpfen
cancel: Abbrechen
cancel_button: Abbrechen
configure_name_in_provider: Import nicht möglich – hinterleg den Kontonamen in Questrade
connect_hint: Verbinde ein Questrade-Konto, um den automatischen Abgleich zu nutzen.
description: Wähl ein Questrade-Konto, das mit diesem Konto verknüpft werden soll. Transaktionen werden automatisch abgeglichen und Dubletten entfernt.
+ dialog_title: Mit einem Questrade-Konto verknüpfen
header: Mit Questrade verknüpfen
link_account: Konto verknüpfen
link_button: Dieses Konto verknüpfen
+ linking_label: Verknüpft wird
linking_to: 'Wird verknüpft mit:'
+ none_available: Keine unverknüpften Questrade-Konten verfügbar.
no_account_specified: Kein Konto angegeben
no_accounts: Keine unverknüpften Questrade-Konten gefunden.
no_accounts_found: Keine Questrade-Konten gefunden. Prüf die Konfiguration deines API-Keys.
@@ -132,9 +149,11 @@ de:
no_name_placeholder: "(kein Name)"
settings_link: Zu den Anbietereinstellungen
subtitle: Ein Questrade-Konto wählen
+ page_title: Questrade-Konto verknüpfen
title: "%{account_name} mit Questrade verknüpfen"
setup_accounts:
account_type_label: 'Kontoart:'
+ all_linked: Alle Questrade-Konten sind bereits eingerichtet.
account_types:
credit_card: Kreditkarte
crypto: Krypto-Konto
@@ -149,6 +168,10 @@ de:
all_accounts_linked: Alle deine Questrade-Konten sind bereits eingerichtet.
api_error: 'API-Fehler: %{message}'
balance: Saldo
+ buttons:
+ cancel: Abbrechen
+ create: Konten anlegen
+ done: Fertig
cancel: Abbrechen
choose_account_type: 'Wähl für jedes Questrade-Konto die passende Kontoart:'
create_accounts: Konten anlegen
@@ -156,6 +179,8 @@ de:
creating_accounts: Konten werden angelegt …
fetch_failed: Konten ließen sich nicht abrufen
historical_data_range: 'Zeitraum der Historie:'
+ dialog_title: Deine Questrade-Konten einrichten
+ import_as: Importieren als
import_selected: Gewählte Konten importieren
instructions: Wähl die Konten, die du aus Questrade importieren willst. Du kannst mehrere auswählen.
no_accounts: Aus dieser Questrade-Verbindung gibt es keine unverknüpften Konten.
@@ -163,6 +188,7 @@ de:
no_api_key: Der Questrade-API-Key ist nicht eingerichtet. Prüf deine Verbindungseinstellungen.
select_all: Alle auswählen
subtitle: Wähl die passende Kontoart für deine importierten Konten
+ page_title: Questrade-Konten einrichten
subtype_labels:
credit_card: ''
crypto: ''
@@ -203,6 +229,10 @@ de:
sync_start_date_help: Wähl, wie weit zurück die Transaktionshistorie geholt werden soll.
sync_start_date_label: 'Transaktionen synchronisieren ab:'
title: Questrade-Konten einrichten
+ types:
+ depository: Giro- oder Sparkonto
+ investment: Investmentkonto
+ skip: Überspringen
setup_required:
go_to_provider_settings: Zu den Anbietereinstellungen
not_configured_description: Leg deine Questrade-Verbindung in den Anbietereinstellungen an und komm dann hierher zurück, um Konten zu verknüpfen.
diff --git a/config/locales/views/registrations/de.yml b/config/locales/views/registrations/de.yml
index f60f7d6ba..8f6427d4a 100644
--- a/config/locales/views/registrations/de.yml
+++ b/config/locales/views/registrations/de.yml
@@ -15,7 +15,7 @@ de:
success: Du hast dich erfolgreich registriert
new:
invitation_message: "%{inviter} hat dich eingeladen als %{role} beizutreten"
- join_family_title: "%{family} beitreten"
+ join_family_title: "%{family} %{moniker} beitreten"
role_admin: Administrator
role_guest: Gast
role_member: Mitglied
diff --git a/config/locales/views/reports/de.yml b/config/locales/views/reports/de.yml
index b1953ad03..3effc1a76 100644
--- a/config/locales/views/reports/de.yml
+++ b/config/locales/views/reports/de.yml
@@ -2,6 +2,7 @@
de:
reports:
index:
+ period_aria: Berichtszeitraum
title: Berichte
subtitle: Umfassende Einblicke in deine finanzielle Situation
export: CSV exportieren
diff --git a/config/locales/views/settings/de.yml b/config/locales/views/settings/de.yml
index 5f8c7829c..904931df0 100644
--- a/config/locales/views/settings/de.yml
+++ b/config/locales/views/settings/de.yml
@@ -23,7 +23,7 @@ de:
payments:
show:
page_title: Zahlung
- subscription_subtitle: Aktualisiere dein Abonnement und deine Zahlungsdetails
+ subscription_subtitle: Aktualisiere deine Kreditkartendaten
subscription_title: Abonnement verwalten
choose_level: Stufe wählen
contributions_note: Beiträge zu %{product_name} erscheinen hier.
@@ -177,6 +177,10 @@ de:
encryption_warning:
generate: 'Einen Satz erzeugst du mit: bin/rails db:encryption:init'
intro: 'Sensible Daten wie API-Keys, Anbieter-Tokens, MFA-Geheimnisse und personenbezogene Angaben liegen unverschlüsselt auf der Platte. Setze diese Schlüssel in deinen Umgebungsvariablen oder Rails-Credentials, um die Verschlüsselung einzuschalten:'
+ keys:
+ - ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY
+ - ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY
+ - ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT
title: Verschlüsselungsschlüssel fehlen
settings_nav:
accounts_label: Konten
diff --git a/config/locales/views/shared/de.yml b/config/locales/views/shared/de.yml
index 54d4b0788..a672888d1 100644
--- a/config/locales/views/shared/de.yml
+++ b/config/locales/views/shared/de.yml
@@ -34,6 +34,7 @@ de:
message: Neue Daten verfügbar
refresh: Aktualisieren
transaction_tabs:
+ aria: Transaktionstyp
expense: Ausgabe
income: Einnahme
transfer: Überweisung
diff --git a/config/locales/views/simplefin_items/de.yml b/config/locales/views/simplefin_items/de.yml
index 1e71dd8c6..68685f5b4 100644
--- a/config/locales/views/simplefin_items/de.yml
+++ b/config/locales/views/simplefin_items/de.yml
@@ -86,7 +86,7 @@ de:
all_skipped: "Alle Konten wurden übersprungen. Es wurden keine Konten erstellt."
no_accounts: "Keine Konten zum Einrichten."
success:
- one: "Ein SimpleFIN-Konto erfolgreich erstellt! Deine Transaktionen und Positionen werden im Hintergrund importiert."
+ one: "%{count} SimpleFIN-Konto erfolgreich erstellt! Deine Transaktionen und Positionen werden im Hintergrund importiert."
other: "%{count} SimpleFIN-Konten erfolgreich erstellt! Deine Transaktionen und Positionen werden im Hintergrund importiert."
stale_accounts_processed: "Veraltete Konten: %{deleted} gelöscht, %{moved} verschoben."
stale_accounts_errors:
diff --git a/config/locales/views/simplefin_items/en.yml b/config/locales/views/simplefin_items/en.yml
index c5c1100b3..9e187c922 100644
--- a/config/locales/views/simplefin_items/en.yml
+++ b/config/locales/views/simplefin_items/en.yml
@@ -30,7 +30,7 @@ en:
label: "SimpleFIN Setup Token:"
placeholder: "Paste your SimpleFIN setup token here..."
help_text: "The token should be a long string starting with letters and numbers"
- title: Update SimpleFin Connection
+ title: Update SimpleFIN Connection
header_subtitle: Get a new setup token to reconnect your SimpleFIN account
connection_needs_update: "Your SimpleFIN connection needs to be updated:"
step_1_html: "Visit SimpleFIN Bridge to create a new setup token"
@@ -39,9 +39,9 @@ en:
update: Update
cancel: Cancel
setup_accounts:
- title: Set Up Your SimpleFin Accounts
+ title: Set Up Your SimpleFIN Accounts
header_subtitle: Choose the correct account types for your imported accounts
- choose_account_type: "Choose the correct account type for each SimpleFin account:"
+ choose_account_type: "Choose the correct account type for each SimpleFIN account:"
account_type_checking_savings: Checking or Savings
account_type_checking_savings_desc: Regular bank accounts
account_type_credit_card: Credit Card
@@ -53,7 +53,7 @@ en:
account_type_other_asset: Other Asset
account_type_other_asset_desc: Everything else
transaction_history_title: "Transaction History:"
- transaction_history_description_html: "SimpleFin typically provides 60-90 days of transaction history, depending on your bank. After initial setup, new transactions will sync automatically going forward. Historical data availability varies by institution and account type."
+ transaction_history_description_html: "SimpleFIN typically provides 60-90 days of transaction history, depending on your bank. After initial setup, new transactions will sync automatically going forward. Historical data availability varies by institution and account type."
account_type_label: "Account Type:"
create_accounts: Create Accounts
creating_accounts: Creating Accounts...
diff --git a/config/locales/views/valuations/de.yml b/config/locales/views/valuations/de.yml
index 731553d60..b936c0481 100644
--- a/config/locales/views/valuations/de.yml
+++ b/config/locales/views/valuations/de.yml
@@ -14,6 +14,8 @@ de:
valuations: Wert
value: Wert
new:
+ amount: Betrag
+ submit: Kontostand hinzufügen
title: Neuer Kontostand
show:
amount: Betrag
@@ -38,8 +40,8 @@ de:
title: Saldo aktualisieren
update: Aktualisieren
confirmation_contents:
- action_set: 'Neu:'
- action_update: 'Geändert:'
+ action_set: gesetzt
+ action_update: aktualisiert
account_balance: Kontostand
asset_value: Vermögenswert
balance: Saldo
@@ -53,7 +55,7 @@ de:
"on": am
property_value: Immobilienwert
recalculate_notice: Alle späteren Transaktionen und Salden werden auf Basis dieser %{change_or_update} neu berechnet.
- this_will: Damit wird der Kontowert zum
+ this_will: Damit wird der Kontowert %{action_verb} am
to: auf
to_colon: 'auf:'
total_account_value: Gesamtwert des Kontos
diff --git a/config/locales/views/wise_items/de.yml b/config/locales/views/wise_items/de.yml
index 296839bef..e313a6f5c 100644
--- a/config/locales/views/wise_items/de.yml
+++ b/config/locales/views/wise_items/de.yml
@@ -84,6 +84,7 @@ de:
description: Wähl das Wise-Währungsguthaben, das mit diesem Konto verknüpft werden soll. Transaktionen werden automatisch abgeglichen.
link_account: Guthaben verknüpfen
no_accounts_found: Keine unverknüpften Wise-Guthaben gefunden.
+ not_found: Wise-Guthaben nicht gefunden.
title: "%{account_name} mit Wise verknüpfen"
select_profiles:
already_connected_label: Bereits verbunden
diff --git a/test/i18n_test.rb b/test/i18n_test.rb
index 51e7f4807..3b2fd8ea5 100644
--- a/test/i18n_test.rb
+++ b/test/i18n_test.rb
@@ -1,13 +1,62 @@
require "i18n/tasks"
+require "pathname"
+require "set"
+require "yaml"
# We're currently skipping some i18n tests to speed up development. Eventually, we'll make a dedicated
# project for getting i18n working. More details on that here:
# https://github.com/maybe-finance/maybe/issues/1225
class I18nTest < ActiveSupport::TestCase
+ GERMAN_COVERAGE_GLOBS = [
+ "config/locales/breadcrumbs/*.yml",
+ "config/locales/doorkeeper.*.yml",
+ "config/locales/mailers/**/*.yml",
+ "config/locales/models/**/*.yml",
+ "config/locales/views/**/*.yml"
+ ]
+
def setup
@i18n = I18n::Tasks::BaseTask.new
end
+ def test_german_locale_files_parse
+ german_locale_paths.each do |path|
+ assert_nothing_raised do
+ YAML.load_file(path, aliases: true)
+ end
+ end
+ end
+
+ def test_german_app_locale_covers_english_keys
+ missing_keys = english_app_locale_leaves.keys.filter_map do |key|
+ key unless translation_present?(german_app_locale_tree, key)
+ end
+
+ assert_empty missing_keys.sort, "Missing German i18n keys:\n#{missing_keys.sort.join("\n")}"
+ end
+
+ def test_german_app_locale_interpolations_match_english
+ mismatches = english_app_locale_leaves.filter_map do |key, english_value|
+ next unless english_value.is_a?(String)
+
+ german_value = translation_at(german_app_locale_tree, key)
+ next if german_value.nil?
+
+ expected_interpolations = interpolation_keys(english_value)
+ german_values =
+ if german_value.is_a?(Hash)
+ flatten_leaves(german_value).values.grep(String)
+ else
+ [ german_value ]
+ end
+
+ bad_values = german_values.reject { |value| interpolation_keys(value) == expected_interpolations }
+ "#{key}: expected #{expected_interpolations.to_a.sort}, got #{bad_values.map { |value| interpolation_keys(value).to_a.sort }.uniq}" if bad_values.any?
+ end
+
+ assert_empty mismatches, "German i18n interpolation mismatches:\n#{mismatches.join("\n")}"
+ end
+
def test_no_missing_keys
skip "Skipping missing keys test"
missing_keys = @i18n.missing_keys(locales: [ :en ])
@@ -38,4 +87,74 @@ class I18nTest < ActiveSupport::TestCase
"Please run `i18n-tasks check-consistent-interpolations' to show them"
assert_empty inconsistent_interpolations, error_message
end
+
+ private
+ def english_app_locale_leaves
+ @english_app_locale_leaves ||= flatten_leaves(english_app_locale_tree)
+ end
+
+ def english_app_locale_tree
+ @english_app_locale_tree ||= locale_tree("en")
+ end
+
+ def german_app_locale_tree
+ @german_app_locale_tree ||= locale_tree("de")
+ end
+
+ def german_locale_paths
+ @german_locale_paths ||= locale_paths.select { |path| path.basename.to_s.match?(/(^|[._-])de\.yml\z/) }
+ end
+
+ def locale_tree(locale)
+ locale_paths.each_with_object({}) do |path, tree|
+ data = YAML.load_file(path, aliases: true) || {}
+ deep_merge!(tree, data.fetch(locale, {}))
+ end
+ end
+
+ def locale_paths
+ @locale_paths ||= GERMAN_COVERAGE_GLOBS.flat_map { |glob| Pathname.pwd.glob(glob) }.uniq
+ end
+
+ def deep_merge!(target, source)
+ source.each do |key, value|
+ if target[key].is_a?(Hash) && value.is_a?(Hash)
+ deep_merge!(target[key], value)
+ else
+ target[key] = value
+ end
+ end
+
+ target
+ end
+
+ def flatten_leaves(value, prefix = [], result = {})
+ case value
+ when Hash
+ value.each { |key, child| flatten_leaves(child, prefix + [ key.to_s ], result) }
+ else
+ result[prefix.join(".")] = value
+ end
+
+ result
+ end
+
+ def translation_at(tree, key)
+ key.split(".").reduce(tree) do |current, segment|
+ return nil unless current.is_a?(Hash) && current.key?(segment)
+
+ current[segment]
+ end
+ end
+
+ def translation_present?(tree, key)
+ value = translation_at(tree, key)
+ return false if value.nil?
+
+ true
+ end
+
+ def interpolation_keys(value)
+ value.scan(/%\{([^}]+)\}/).flatten.to_set
+ end
end