diff --git a/backend/locale/en/LC_MESSAGES/django.po b/backend/locale/en/LC_MESSAGES/django.po index dfd613d..3a1ed4e 100644 --- a/backend/locale/en/LC_MESSAGES/django.po +++ b/backend/locale/en/LC_MESSAGES/django.po @@ -2,14 +2,14 @@ msgid "" msgstr "" "Project-Id-Version: tubco-portal\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-03-26 11:56+0000\n" +"POT-Creation-Date: 2026-03-26 12:55+0000\n" "PO-Revision-Date: 2026-03-24 00:00+0000\n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: workflows/app_registry.py:32 workflows/models.py:277 workflows/models.py:358 +#: workflows/app_registry.py:32 workflows/models.py:303 workflows/models.py:384 #: workflows/templates/workflows/onboarding_form.html:25 #: workflows/templates/workflows/requests_dashboard.html:68 #: workflows/templates/workflows/requests_dashboard.html:131 @@ -36,7 +36,7 @@ msgstr "Multi-step form" msgid "E-Mail Routing" msgstr "Email routing" -#: workflows/app_registry.py:43 workflows/models.py:278 workflows/models.py:359 +#: workflows/app_registry.py:43 workflows/models.py:304 workflows/models.py:385 #: workflows/templates/workflows/requests_dashboard.html:78 #: workflows/templates/workflows/requests_dashboard.html:132 msgid "Offboarding" @@ -104,155 +104,167 @@ msgid "PDF Zugriff" msgstr "PDF access" #: workflows/app_registry.py:65 -#: workflows/templates/workflows/branding_settings.html:4 -#: workflows/templates/workflows/branding_settings.html:12 -msgid "Branding" -msgstr "Branding" +#: workflows/templates/workflows/company_config.html:4 +#: workflows/templates/workflows/company_config.html:12 +msgid "Company Config" +msgstr "" #: workflows/app_registry.py:66 -msgid "Logo, Portalname, Farben und PDF-Briefkopf verwalten." -msgstr "Manage logo, portal name, colors, and PDF letterhead." +msgid "" +"Rechtliche Firmendaten, Kontaktpunkte und öffentliche Unternehmenslinks " +"pflegen." +msgstr "" #: workflows/app_registry.py:67 workflows/app_registry.py:76 #: workflows/app_registry.py:85 workflows/app_registry.py:94 #: workflows/app_registry.py:103 workflows/app_registry.py:112 #: workflows/app_registry.py:121 workflows/app_registry.py:130 #: workflows/app_registry.py:139 workflows/app_registry.py:148 -#: workflows/app_registry.py:157 +#: workflows/app_registry.py:157 workflows/app_registry.py:166 msgid "Öffnen" msgstr "Open" #: workflows/app_registry.py:74 +#: workflows/templates/workflows/branding_settings.html:4 +#: workflows/templates/workflows/branding_settings.html:12 +msgid "Branding" +msgstr "Branding" + +#: workflows/app_registry.py:75 +msgid "Logo, Portalname, Farben und PDF-Briefkopf verwalten." +msgstr "Manage logo, portal name, colors, and PDF letterhead." + +#: workflows/app_registry.py:83 #: workflows/templates/workflows/app_registry.html:5 #: workflows/templates/workflows/app_registry.html:13 msgid "App Registry" msgstr "" -#: workflows/app_registry.py:75 +#: workflows/app_registry.py:84 msgid "Apps zentral aktivieren, sortieren und für Kundenauftritte vorbereiten." msgstr "" -#: workflows/app_registry.py:83 +#: workflows/app_registry.py:92 msgid "Integrationen" msgstr "Integrations" -#: workflows/app_registry.py:84 +#: workflows/app_registry.py:93 msgid "Nextcloud- und E-Mail-Setup." msgstr "Nextcloud and email setup." -#: workflows/app_registry.py:92 +#: workflows/app_registry.py:101 #: workflows/templates/workflows/user_management.html:4 #: workflows/templates/workflows/user_management.html:14 msgid "Benutzer & Rollen" msgstr "Users & roles" -#: workflows/app_registry.py:93 +#: workflows/app_registry.py:102 msgid "Benutzer anlegen, Rollen zuweisen und Zugriffe steuern." msgstr "Create users, assign roles, and control access." -#: workflows/app_registry.py:101 workflows/templates/workflows/audit_log.html:4 +#: workflows/app_registry.py:110 workflows/templates/workflows/audit_log.html:4 #: workflows/templates/workflows/audit_log.html:15 msgid "Audit Log" msgstr "" -#: workflows/app_registry.py:102 +#: workflows/app_registry.py:111 msgid "Wichtige Admin-Aktionen nachvollziehen und prüfen." msgstr "" -#: workflows/app_registry.py:110 +#: workflows/app_registry.py:119 #: workflows/templates/workflows/backup_recovery.html:4 #: workflows/templates/workflows/backup_recovery.html:12 msgid "Backup & Recovery" msgstr "Backup & Recovery" -#: workflows/app_registry.py:111 +#: workflows/app_registry.py:120 msgid "Backups erstellen und sicher verifizieren." msgstr "" -#: workflows/app_registry.py:119 +#: workflows/app_registry.py:128 #: workflows/templates/workflows/welcome_emails.html:4 msgid "Welcome E-Mails" msgstr "Welcome Emails" -#: workflows/app_registry.py:120 +#: workflows/app_registry.py:129 msgid "Geplante Welcome Mails verwalten." msgstr "Manage scheduled welcome emails." -#: workflows/app_registry.py:128 +#: workflows/app_registry.py:137 #: workflows/templates/workflows/form_builder.html:4 #: workflows/templates/workflows/form_builder.html:14 msgid "Form Builder" msgstr "Form Builder" -#: workflows/app_registry.py:129 +#: workflows/app_registry.py:138 msgid "Felder, Schritte und Optionen verwalten." msgstr "Manage fields, steps, and options." -#: workflows/app_registry.py:137 +#: workflows/app_registry.py:146 #: workflows/templates/workflows/intro_builder.html:4 #: workflows/templates/workflows/intro_builder.html:17 msgid "Einweisungs-Builder" msgstr "Introduction Builder" -#: workflows/app_registry.py:138 +#: workflows/app_registry.py:147 msgid "Checklistenpunkte für das Einweisungsprotokoll konfigurieren." msgstr "Configure checklist items for the introduction protocol." -#: workflows/app_registry.py:146 workflows/templates/workflows/handbook.html:4 +#: workflows/app_registry.py:155 workflows/templates/workflows/handbook.html:4 #: workflows/templates/workflows/handbook.html:15 msgid "Handbook" msgstr "Handbook" -#: workflows/app_registry.py:147 +#: workflows/app_registry.py:156 msgid "Project wiki and developer documentation in one place." msgstr "Project wiki and developer documentation in one place." -#: workflows/app_registry.py:155 +#: workflows/app_registry.py:164 msgid "Django Admin" msgstr "Django Admin" -#: workflows/app_registry.py:156 +#: workflows/app_registry.py:165 msgid "Vollständige Datenverwaltung." msgstr "Full data management." -#: workflows/app_registry.py:259 +#: workflows/app_registry.py:274 msgid "Nur Platform" msgstr "" -#: workflows/app_registry.py:261 +#: workflows/app_registry.py:276 #: workflows/templates/workflows/app_registry.html:85 msgid "Alle Firmenrollen" msgstr "" -#: workflows/app_registry.py:267 workflows/models.py:80 +#: workflows/app_registry.py:282 workflows/models.py:106 #: workflows/templates/workflows/app_registry.html:43 #: workflows/templates/workflows/app_registry.html:78 msgid "Apps" msgstr "Apps" -#: workflows/app_registry.py:268 +#: workflows/app_registry.py:283 msgid "Wählen Sie den gewünschten Prozess." msgstr "Choose the desired process." -#: workflows/app_registry.py:273 workflows/models.py:81 +#: workflows/app_registry.py:288 workflows/models.py:107 #: workflows/templates/workflows/app_registry.html:44 #: workflows/templates/workflows/app_registry.html:74 msgid "Platform Apps" msgstr "" -#: workflows/app_registry.py:274 +#: workflows/app_registry.py:289 #, fuzzy #| msgid "Konfiguration, Tests und Steuerung." msgid "Produktweite Konfiguration und Produktsteuerung." msgstr "Configuration, tests, and controls." -#: workflows/app_registry.py:279 workflows/models.py:82 +#: workflows/app_registry.py:294 workflows/models.py:108 #: workflows/templates/workflows/app_registry.html:45 #: workflows/templates/workflows/app_registry.html:76 msgid "Admin Apps" msgstr "Admin Apps" -#: workflows/app_registry.py:280 +#: workflows/app_registry.py:295 msgid "Konfiguration, Tests und Steuerung." msgstr "Configuration, tests, and controls." @@ -347,11 +359,11 @@ msgstr "Role:" msgid "Dieser Benutzername ist bereits vergeben." msgstr "This username is already taken." -#: workflows/forms.py:154 workflows/views.py:622 +#: workflows/forms.py:154 workflows/views.py:680 msgid "Ungültige Rolle." msgstr "Invalid role." -#: workflows/forms.py:156 workflows/views.py:625 +#: workflows/forms.py:156 workflows/views.py:683 msgid "Nur Platform Owner dürfen diese Rolle vergeben." msgstr "" @@ -435,261 +447,321 @@ msgstr "" msgid "Das Favicon darf maximal 2 MB groß sein." msgstr "" -#: workflows/forms.py:382 workflows/forms.py:567 +#: workflows/forms.py:267 +#, fuzzy +#| msgid "Firmenname" +msgid "Rechtlicher Firmenname" +msgstr "Company name" + +#: workflows/forms.py:268 +msgid "Straße und Hausnummer" +msgstr "" + +#: workflows/forms.py:269 +msgid "Postleitzahl" +msgstr "" + +#: workflows/forms.py:270 +msgid "Stadt" +msgstr "" + +#: workflows/forms.py:271 +msgid "Land" +msgstr "" + +#: workflows/forms.py:272 workflows/templates/workflows/base_shell.html:27 +msgid "Website" +msgstr "" + +#: workflows/forms.py:273 +msgid "Impressum-URL" +msgstr "" + +#: workflows/forms.py:274 +msgid "Datenschutz-URL" +msgstr "" + +#: workflows/forms.py:275 +msgid "HR-Kontakt" +msgstr "" + +#: workflows/forms.py:276 +msgid "IT-Kontakt" +msgstr "" + +#: workflows/forms.py:277 +#, fuzzy +#| msgid "Operations" +msgid "Operations-Kontakt" +msgstr "Operations" + +#: workflows/forms.py:278 +msgid "Zentrale Telefonnummer" +msgstr "" + +#: workflows/forms.py:279 +msgid "USt-IdNr." +msgstr "" + +#: workflows/forms.py:280 +msgid "Register- oder Handelsnummer" +msgstr "" + +#: workflows/forms.py:419 workflows/forms.py:604 #, python-format msgid "Bitte nutzen Sie das Format name@%(domain)s." msgstr "" -#: workflows/forms.py:404 workflows/forms.py:581 +#: workflows/forms.py:441 workflows/forms.py:618 #, python-format msgid "Bitte verwenden Sie eine @%(domain)s E-Mail-Adresse." msgstr "" -#: workflows/forms.py:489 +#: workflows/forms.py:526 #, python-format msgid "" "Das Übergabedatum muss mindestens %(days)s Tage in der Zukunft liegen " "(frühestens %(date)s)." msgstr "" -#: workflows/models.py:155 workflows/views.py:200 +#: workflows/models.py:181 workflows/views.py:200 msgid "Eingereicht" msgstr "Submitted" -#: workflows/models.py:156 workflows/views.py:201 +#: workflows/models.py:182 workflows/views.py:201 msgid "In Bearbeitung" msgstr "Processing" -#: workflows/models.py:157 workflows/models.py:472 workflows/views.py:202 +#: workflows/models.py:183 workflows/models.py:498 workflows/views.py:202 msgid "Abgeschlossen" msgstr "Completed" -#: workflows/models.py:158 workflows/models.py:412 +#: workflows/models.py:184 workflows/models.py:438 #: workflows/templates/workflows/backup_recovery.html:70 #: workflows/templates/workflows/requests_dashboard.html:222 #: workflows/templates/workflows/welcome_emails.html:108 workflows/views.py:203 msgid "Fehlgeschlagen" msgstr "Failed" -#: workflows/models.py:165 +#: workflows/models.py:191 msgid "Herr" msgstr "" -#: workflows/models.py:165 +#: workflows/models.py:191 msgid "Frau" msgstr "" -#: workflows/models.py:165 +#: workflows/models.py:191 msgid "Divers" msgstr "" -#: workflows/models.py:175 +#: workflows/models.py:201 msgid "befristet" msgstr "" -#: workflows/models.py:175 +#: workflows/models.py:201 msgid "unbefristet" msgstr "" -#: workflows/models.py:238 +#: workflows/models.py:264 #: workflows/templates/workflows/onboarding_intro_session.html:28 #: workflows/templates/workflows/requests_dashboard.html:145 msgid "Abteilung" msgstr "Department" -#: workflows/models.py:239 +#: workflows/models.py:265 msgid "Geräte" msgstr "" -#: workflows/models.py:240 +#: workflows/models.py:266 msgid "Software" msgstr "" -#: workflows/models.py:241 +#: workflows/models.py:267 #, fuzzy #| msgid "Vorgänge" msgid "Zugänge" msgstr "Requests" -#: workflows/models.py:242 +#: workflows/models.py:268 msgid "Workspace-Gruppen" msgstr "" -#: workflows/models.py:243 +#: workflows/models.py:269 msgid "Ressourcen" msgstr "" -#: workflows/models.py:244 +#: workflows/models.py:270 msgid "Telefonnummern" msgstr "" -#: workflows/models.py:270 +#: workflows/models.py:296 msgid "Automatisch" msgstr "" -#: workflows/models.py:271 workflows/views.py:95 +#: workflows/models.py:297 workflows/views.py:95 msgid "Stammdaten" msgstr "Master data" -#: workflows/models.py:272 workflows/views.py:96 +#: workflows/models.py:298 workflows/views.py:96 msgid "Vertrag" msgstr "Contract" -#: workflows/models.py:273 workflows/views.py:97 +#: workflows/models.py:299 workflows/views.py:97 msgid "IT-Setup" msgstr "IT setup" -#: workflows/models.py:274 workflows/views.py:98 +#: workflows/models.py:300 workflows/views.py:98 msgid "Abschluss" msgstr "Finish" -#: workflows/models.py:316 +#: workflows/models.py:342 #, fuzzy #| msgid "Onboarding" msgid "Onboarding: IT" msgstr "Onboarding" -#: workflows/models.py:317 +#: workflows/models.py:343 #, fuzzy #| msgid "Offboarding-Anfrage speichern" msgid "Onboarding: Allgemeine Info" msgstr "Save offboarding request" -#: workflows/models.py:318 +#: workflows/models.py:344 #, fuzzy #| msgid "Onboarding starten" msgid "Onboarding: Visitenkarte" msgstr "Start onboarding" -#: workflows/models.py:319 +#: workflows/models.py:345 #, fuzzy #| msgid "Onboarding" msgid "Onboarding: HR Works" msgstr "Onboarding" -#: workflows/models.py:320 +#: workflows/models.py:346 #, fuzzy #| msgid "Onboarding starten" msgid "Onboarding: Schlüssel" msgstr "Start onboarding" -#: workflows/models.py:321 +#: workflows/models.py:347 msgid "Onboarding: Referenz Anfordernde Person" msgstr "" -#: workflows/models.py:322 +#: workflows/models.py:348 #, fuzzy #| msgid "Welcome E-Mails" msgid "Onboarding: Welcome E-Mail" msgstr "Welcome Emails" -#: workflows/models.py:323 +#: workflows/models.py:349 #, fuzzy #| msgid "Offboarding" msgid "Offboarding: IT" msgstr "Offboarding" -#: workflows/models.py:324 +#: workflows/models.py:350 #, fuzzy #| msgid "Offboarding-Anfrage speichern" msgid "Offboarding: Allgemeine Info" msgstr "Save offboarding request" -#: workflows/models.py:325 +#: workflows/models.py:351 #, fuzzy #| msgid "Offboarding starten" msgid "Offboarding: HR Works Deaktivierung" msgstr "Start offboarding" -#: workflows/models.py:326 +#: workflows/models.py:352 msgid "Offboarding: Referenz Anfordernde Person" msgstr "" -#: workflows/models.py:362 +#: workflows/models.py:388 msgid "Immer" msgstr "" -#: workflows/models.py:363 workflows/models.py:441 +#: workflows/models.py:389 workflows/models.py:467 msgid "Enthält" msgstr "" -#: workflows/models.py:364 workflows/models.py:442 +#: workflows/models.py:390 workflows/models.py:468 msgid "Ist gleich" msgstr "" -#: workflows/models.py:365 +#: workflows/models.py:391 msgid "Ist aktiv/Ja" msgstr "" -#: workflows/models.py:366 +#: workflows/models.py:392 #, fuzzy #| msgid "inaktiv" msgid "Ist inaktiv/Nein" msgstr "inactive" -#: workflows/models.py:408 +#: workflows/models.py:434 #: workflows/templates/workflows/welcome_emails.html:100 msgid "Geplant" msgstr "Scheduled" -#: workflows/models.py:409 +#: workflows/models.py:435 #: workflows/templates/workflows/welcome_emails.html:102 msgid "Pausiert" msgstr "Paused" -#: workflows/models.py:410 +#: workflows/models.py:436 #: workflows/templates/workflows/welcome_emails.html:104 msgid "Abgebrochen" msgstr "Cancelled" -#: workflows/models.py:411 +#: workflows/models.py:437 #: workflows/templates/workflows/welcome_emails.html:106 msgid "Gesendet" msgstr "Sent" -#: workflows/models.py:434 workflows/tasks.py:576 +#: workflows/models.py:460 workflows/tasks.py:576 msgid "Geräte und Arbeitsplatz" msgstr "Devices and workplace" -#: workflows/models.py:435 workflows/tasks.py:577 +#: workflows/models.py:461 workflows/tasks.py:577 msgid "Konten und Berechtigungen" msgstr "Accounts and permissions" -#: workflows/models.py:436 workflows/tasks.py:578 +#: workflows/models.py:462 workflows/tasks.py:578 msgid "Software und Tools" msgstr "Software and tools" -#: workflows/models.py:437 workflows/tasks.py:579 +#: workflows/models.py:463 workflows/tasks.py:579 msgid "Prozesse und Hinweise" msgstr "Processes and notes" -#: workflows/models.py:440 +#: workflows/models.py:466 msgid "Immer anzeigen" msgstr "Always show" -#: workflows/models.py:443 +#: workflows/models.py:469 msgid "Ist Ja / aktiv" msgstr "Is yes / active" -#: workflows/models.py:444 +#: workflows/models.py:470 msgid "Ist Nein / inaktiv" msgstr "Is no / inactive" -#: workflows/models.py:471 +#: workflows/models.py:497 msgid "Entwurf" msgstr "Draft" -#: workflows/models.py:491 +#: workflows/models.py:517 #, fuzzy #| msgid "Nextcloud:" msgid "Nextcloud" msgstr "Nextcloud:" -#: workflows/models.py:492 +#: workflows/models.py:518 msgid "S3" msgstr "" -#: workflows/models.py:493 +#: workflows/models.py:519 msgid "NFS" msgstr "" @@ -1312,7 +1384,7 @@ msgstr "Delete this backup bundle?" #: workflows/templates/workflows/integrations_setup.html:265 #: workflows/templates/workflows/intro_builder.html:66 #: workflows/templates/workflows/intro_builder.html:102 -#: workflows/templates/workflows/requests_dashboard.html:286 +#: workflows/templates/workflows/requests_dashboard.html:288 #: workflows/templates/workflows/user_management.html:127 #: workflows/templates/workflows/welcome_emails.html:70 msgid "Löschen" @@ -1324,28 +1396,36 @@ msgstr "Delete" msgid "Noch keine Backup-Bundles vorhanden." msgstr "No backup bundles available yet." -#: workflows/templates/workflows/base_shell.html:31 +#: workflows/templates/workflows/base_shell.html:28 +msgid "Impressum" +msgstr "" + +#: workflows/templates/workflows/base_shell.html:29 +msgid "Datenschutz" +msgstr "" + +#: workflows/templates/workflows/base_shell.html:38 msgid "Bitte bestätigen" msgstr "" -#: workflows/templates/workflows/base_shell.html:35 +#: workflows/templates/workflows/base_shell.html:42 #: workflows/templates/workflows/welcome_emails.html:134 msgid "Abbrechen" msgstr "Cancel" -#: workflows/templates/workflows/base_shell.html:36 +#: workflows/templates/workflows/base_shell.html:43 msgid "Bestätigen" msgstr "" -#: workflows/templates/workflows/base_shell.html:43 +#: workflows/templates/workflows/base_shell.html:50 msgid "Bitte warten" msgstr "Please wait" -#: workflows/templates/workflows/base_shell.html:44 +#: workflows/templates/workflows/base_shell.html:51 msgid "Aktion läuft" msgstr "Action in progress" -#: workflows/templates/workflows/base_shell.html:45 +#: workflows/templates/workflows/base_shell.html:52 msgid "Die Aktion wird im aktuellen Tab ausgeführt." msgstr "The action is running in the current tab." @@ -1442,6 +1522,64 @@ msgstr "" msgid "Branding speichern" msgstr "Save branding" +#: workflows/templates/workflows/company_config.html:13 +msgid "" +"Strukturierte Firmendaten, Kontaktpunkte und öffentliche Unternehmenslinks " +"zentral pflegen." +msgstr "" + +#: workflows/templates/workflows/company_config.html:23 +#, fuzzy +#| msgid "Firmenname" +msgid "Firmenprofil" +msgstr "Company name" + +#: workflows/templates/workflows/company_config.html:24 +msgid "Rechtlicher Name und zentrale Stammdaten der Firma." +msgstr "" + +#: workflows/templates/workflows/company_config.html:48 +msgid "Adresse & Register" +msgstr "" + +#: workflows/templates/workflows/company_config.html:49 +msgid "Anschrift sowie optionale Register- und Steuerangaben." +msgstr "" + +#: workflows/templates/workflows/company_config.html:77 +msgid "Kontaktpunkte" +msgstr "" + +#: workflows/templates/workflows/company_config.html:78 +msgid "Zentrale Ansprechpartner für HR, IT und Operations." +msgstr "" + +#: workflows/templates/workflows/company_config.html:98 +msgid "Recht & Öffentlichkeit" +msgstr "" + +#: workflows/templates/workflows/company_config.html:99 +msgid "Öffentliche Links für Website, Impressum und Datenschutz." +msgstr "" + +#: workflows/templates/workflows/company_config.html:111 +msgid "" +"Diese Links können später im Portal-Footer oder in öffentlichen Seiten " +"verwendet werden." +msgstr "" + +#: workflows/templates/workflows/company_config.html:115 +msgid "" +"Diese Ebene ist bewusst von Branding getrennt: Hier geht es um strukturierte " +"Firmendaten, nicht um visuelle Gestaltung." +msgstr "" + +#: workflows/templates/workflows/company_config.html:116 +#, fuzzy +#| msgid "Optionen speichern" +msgid "Firmenkonfiguration speichern" +msgstr "Save options" + #: workflows/templates/workflows/form_builder.html:15 msgid "Felder per Drag-and-Drop sortieren und pro Schritt gruppieren." msgstr "Sort fields by drag and drop and group them by step." @@ -2290,7 +2428,7 @@ msgid "Dienstliche E-Mail" msgstr "Work email" #: workflows/templates/workflows/onboarding_intro_session.html:31 -#: workflows/views.py:875 +#: workflows/views.py:933 msgid "Vertragsbeginn" msgstr "Contract start" @@ -2708,25 +2846,25 @@ msgstr "Generate PDF" msgid "Nicht relevant" msgstr "Not relevant" -#: workflows/templates/workflows/requests_dashboard.html:276 +#: workflows/templates/workflows/requests_dashboard.html:277 msgid "Timeline" msgstr "" -#: workflows/templates/workflows/requests_dashboard.html:278 +#: workflows/templates/workflows/requests_dashboard.html:280 msgid "Eintrag erneut verarbeiten?" msgstr "" -#: workflows/templates/workflows/requests_dashboard.html:280 +#: workflows/templates/workflows/requests_dashboard.html:282 msgid "Erneut versuchen" msgstr "" -#: workflows/templates/workflows/requests_dashboard.html:284 +#: workflows/templates/workflows/requests_dashboard.html:286 #, fuzzy #| msgid "Option wirklich löschen?" msgid "Eintrag wirklich löschen?" msgstr "Delete this option?" -#: workflows/templates/workflows/requests_dashboard.html:294 +#: workflows/templates/workflows/requests_dashboard.html:296 msgid "Noch keine Vorgänge vorhanden." msgstr "No requests available yet." @@ -2955,7 +3093,7 @@ msgstr "Devices, software, and access" msgid "Notizen und Freigabe" msgstr "Notes and approval" -#: workflows/views.py:129 workflows/views.py:961 workflows/views.py:966 +#: workflows/views.py:129 workflows/views.py:1019 workflows/views.py:1024 msgid "Sie haben keine Berechtigung für diese Aktion." msgstr "You do not have permission for this action." @@ -3233,17 +3371,32 @@ msgstr "User could not be created. Please check the input." msgid "Portal-Branding wurde gespeichert." msgstr "Save offboarding request" -#: workflows/views.py:595 +#: workflows/views.py:610 +#, fuzzy +#| msgid "" +#| "Benutzer konnte nicht erstellt werden. Bitte prüfen Sie die Eingaben." +msgid "" +"Firmenkonfiguration konnte nicht gespeichert werden. Bitte prüfen Sie die " +"Eingaben." +msgstr "User could not be created. Please check the input." + +#: workflows/views.py:637 +#, fuzzy +#| msgid "Offboarding-Anfrage speichern" +msgid "Firmenkonfiguration wurde gespeichert." +msgstr "Save offboarding request" + +#: workflows/views.py:653 msgid "Benutzer konnte nicht erstellt werden. Bitte prüfen Sie die Eingaben." msgstr "User could not be created. Please check the input." -#: workflows/views.py:608 +#: workflows/views.py:666 #, fuzzy, python-format #| msgid "Benutzer wurde erstellt: %(username)s" msgid "Benutzer wurde erstellt und eingeladen: %(username)s" msgstr "User created: %(username)s" -#: workflows/views.py:630 +#: workflows/views.py:688 #, fuzzy #| msgid "" #| "Der aktuell angemeldete Super Admin kann sich hier nicht selbst sperren " @@ -3254,14 +3407,14 @@ msgid "" msgstr "" "The currently signed-in super admin cannot lock or downgrade themselves here." -#: workflows/views.py:633 +#: workflows/views.py:691 msgid "" "Der aktuell angemeldete Super Admin kann sich hier nicht selbst sperren oder " "herabstufen." msgstr "" "The currently signed-in super admin cannot lock or downgrade themselves here." -#: workflows/views.py:636 +#: workflows/views.py:694 #, fuzzy #| msgid "" #| "Der aktuell angemeldete Super Admin kann sich hier nicht selbst sperren " @@ -3272,7 +3425,7 @@ msgid "" msgstr "" "The currently signed-in super admin cannot lock or downgrade themselves here." -#: workflows/views.py:639 +#: workflows/views.py:697 #, fuzzy #| msgid "" #| "Der aktuell angemeldete Super Admin kann sich hier nicht selbst sperren " @@ -3283,18 +3436,18 @@ msgid "" msgstr "" "The currently signed-in super admin cannot lock or downgrade themselves here." -#: workflows/views.py:656 +#: workflows/views.py:714 #, python-format msgid "Benutzer wurde aktualisiert: %(username)s" msgstr "User updated: %(username)s" -#: workflows/views.py:678 +#: workflows/views.py:736 #, fuzzy, python-format #| msgid "Benutzer wurde erstellt: %(username)s" msgid "Passwort-Reset-Link wurde versendet: %(username)s" msgstr "User created: %(username)s" -#: workflows/views.py:690 +#: workflows/views.py:748 #, fuzzy #| msgid "" #| "Der aktuell angemeldete Super Admin kann sich hier nicht selbst sperren " @@ -3304,7 +3457,7 @@ msgid "" msgstr "" "The currently signed-in super admin cannot lock or downgrade themselves here." -#: workflows/views.py:693 +#: workflows/views.py:751 #, fuzzy #| msgid "" #| "Der aktuell angemeldete Super Admin kann sich hier nicht selbst sperren " @@ -3314,7 +3467,7 @@ msgid "" msgstr "" "The currently signed-in super admin cannot lock or downgrade themselves here." -#: workflows/views.py:696 +#: workflows/views.py:754 #, fuzzy #| msgid "" #| "Der aktuell angemeldete Super Admin kann sich hier nicht selbst sperren " @@ -3323,7 +3476,7 @@ msgid "Der letzte aktive Platform Owner kann nicht gelöscht werden." msgstr "" "The currently signed-in super admin cannot lock or downgrade themselves here." -#: workflows/views.py:699 +#: workflows/views.py:757 #, fuzzy #| msgid "" #| "Der aktuell angemeldete Super Admin kann sich hier nicht selbst sperren " @@ -3332,121 +3485,121 @@ msgid "Der letzte aktive Super Admin kann nicht gelöscht werden." msgstr "" "The currently signed-in super admin cannot lock or downgrade themselves here." -#: workflows/views.py:712 +#: workflows/views.py:770 #, fuzzy, python-format #| msgid "Benutzer wurde erstellt: %(username)s" msgid "Benutzer wurde gelöscht: %(username)s" msgstr "User created: %(username)s" -#: workflows/views.py:799 +#: workflows/views.py:857 #, python-format msgid "Backup wurde erstellt: %(name)s" msgstr "" -#: workflows/views.py:801 +#: workflows/views.py:859 #, python-format msgid "Backup konnte nicht erstellt werden: %(error)s" msgstr "" -#: workflows/views.py:817 +#: workflows/views.py:875 #, python-format msgid "Backup wurde verifiziert: %(name)s" msgstr "" -#: workflows/views.py:819 +#: workflows/views.py:877 #, python-format msgid "Backup-Verifikation fehlgeschlagen: %(error)s" msgstr "" -#: workflows/views.py:835 +#: workflows/views.py:893 #, python-format msgid "Backup wurde gelöscht: %(name)s" msgstr "" -#: workflows/views.py:837 +#: workflows/views.py:895 #, python-format msgid "Backup konnte nicht gelöscht werden: %(error)s" msgstr "" -#: workflows/views.py:863 +#: workflows/views.py:921 #, fuzzy #| msgid "Anfrage gespeichert" msgid "Anfrage erstellt" msgstr "Request saved" -#: workflows/views.py:865 +#: workflows/views.py:923 #, fuzzy, python-format #| msgid "Sitzungsstatus" msgid "Status: %(status)s" msgstr "Session status" -#: workflows/views.py:877 +#: workflows/views.py:935 #, fuzzy #| msgid "Geplant für" msgid "Geplanter Start" msgstr "Scheduled for" -#: workflows/views.py:887 +#: workflows/views.py:945 msgid "Geräteübergabe / Hardware-Abholung" msgstr "" -#: workflows/views.py:889 +#: workflows/views.py:947 msgid "Geplanter Hardware-Termin" msgstr "" -#: workflows/views.py:898 +#: workflows/views.py:956 #, fuzzy #| msgid "Noch nicht verfügbar" msgid "PDF verfügbar" msgstr "Not available yet" -#: workflows/views.py:924 +#: workflows/views.py:982 #, fuzzy #| msgid "Einweisung" msgid "Einweisungssitzung" msgstr "Introduction" -#: workflows/views.py:936 +#: workflows/views.py:994 #, fuzzy #| msgid "Welcome E-Mails" msgid "Welcome E-Mail" msgstr "Welcome Emails" -#: workflows/views.py:975 +#: workflows/views.py:1033 msgid "Keine Einträge ausgewählt." msgstr "No entries selected." -#: workflows/views.py:1018 +#: workflows/views.py:1076 #, python-format msgid "%(count)s Eintrag/Einträge gelöscht." msgstr "%(count)s entry/entries deleted." -#: workflows/views.py:1020 +#: workflows/views.py:1078 #, python-format msgid "%(count)s Auswahl(en) konnten nicht verarbeitet werden." msgstr "%(count)s selection(s) could not be processed." -#: workflows/views.py:1022 +#: workflows/views.py:1080 msgid "Keine passenden Einträge gefunden." msgstr "No matching entries found." -#: workflows/views.py:1250 +#: workflows/views.py:1308 msgid "Einweisungs- und Übergabeprotokoll wurde erzeugt." msgstr "Introduction and handover protocol was generated." -#: workflows/views.py:1267 +#: workflows/views.py:1325 msgid "Einweisungsprotokoll aus Live-Status wurde erzeugt." msgstr "Introduction protocol from live status was generated." -#: workflows/views.py:1296 +#: workflows/views.py:1354 msgid "Einweisung wurde zurückgesetzt." msgstr "Introduction was reset." -#: workflows/views.py:1310 +#: workflows/views.py:1368 msgid "Einweisung wurde als abgeschlossen gespeichert." msgstr "Introduction was saved as completed." -#: workflows/views.py:1323 +#: workflows/views.py:1381 msgid "Einweisung wurde als Entwurf gespeichert." msgstr "Introduction was saved as draft." diff --git a/backend/workflows/admin.py b/backend/workflows/admin.py index e1e0660..21860b3 100644 --- a/backend/workflows/admin.py +++ b/backend/workflows/admin.py @@ -3,7 +3,7 @@ from django.conf import settings from django import forms from .emailing import send_system_email -from .models import AdminAuditLog, EmployeeProfile, FormFieldConfig, FormOption, IntroChecklistItem, NotificationRule, NotificationTemplate, OffboardingRequest, OnboardingIntroductionSession, OnboardingRequest, PortalAppConfig, PortalBranding, ScheduledWelcomeEmail, SystemEmailConfig, WorkflowConfig +from .models import AdminAuditLog, EmployeeProfile, FormFieldConfig, FormOption, IntroChecklistItem, NotificationRule, NotificationTemplate, OffboardingRequest, OnboardingIntroductionSession, OnboardingRequest, PortalAppConfig, PortalBranding, PortalCompanyConfig, ScheduledWelcomeEmail, SystemEmailConfig, WorkflowConfig @admin.register(EmployeeProfile) @@ -25,6 +25,11 @@ class PortalBrandingAdmin(admin.ModelAdmin): list_display = ('name', 'portal_title', 'company_name', 'company_domain', 'support_email', 'default_language', 'updated_at') +@admin.register(PortalCompanyConfig) +class PortalCompanyConfigAdmin(admin.ModelAdmin): + list_display = ('name', 'legal_company_name', 'website_url', 'hr_contact_email', 'it_contact_email', 'updated_at') + + @admin.register(PortalAppConfig) class PortalAppConfigAdmin(admin.ModelAdmin): list_display = ( diff --git a/backend/workflows/app_registry.py b/backend/workflows/app_registry.py index 781ad8b..d65d47b 100644 --- a/backend/workflows/app_registry.py +++ b/backend/workflows/app_registry.py @@ -58,6 +58,15 @@ APP_DEFINITIONS: tuple[AppDefinition, ...] = ( accent='APP', tags=(_('Suche'), _('Status'), _('PDF Zugriff')), ), + AppDefinition( + key='company_config', + section=PortalAppConfig.SECTION_PLATFORM, + route_name='portal_company_config_page', + title=_('Company Config'), + description=_('Rechtliche Firmendaten, Kontaktpunkte und öffentliche Unternehmenslinks pflegen.'), + action_label=_('Öffnen'), + capability='manage_company_config', + ), AppDefinition( key='branding', section=PortalAppConfig.SECTION_PLATFORM, @@ -185,6 +194,12 @@ DEFAULT_ROLE_VISIBILITY = { ROLE_IT_STAFF: False, ROLE_STAFF: False, }, + 'company_config': { + ROLE_SUPER_ADMIN: False, + ROLE_ADMIN: False, + ROLE_IT_STAFF: False, + ROLE_STAFF: False, + }, 'app_registry': { ROLE_SUPER_ADMIN: False, ROLE_ADMIN: False, diff --git a/backend/workflows/branding.py b/backend/workflows/branding.py index 94759b0..94c2022 100644 --- a/backend/workflows/branding.py +++ b/backend/workflows/branding.py @@ -7,7 +7,7 @@ from django.conf import settings from django.templatetags.static import static from django.utils.translation import get_language -from .models import PortalBranding +from .models import PortalBranding, PortalCompanyConfig def get_portal_branding() -> PortalBranding: @@ -32,6 +32,26 @@ def get_portal_branding() -> PortalBranding: return branding +def get_portal_company_config() -> PortalCompanyConfig: + company_config, _ = PortalCompanyConfig.objects.get_or_create( + name='Default', + defaults={ + 'legal_company_name': 'TUBCO GmbH', + 'country': 'Deutschland', + 'website_url': '', + 'imprint_url': '', + 'privacy_url': '', + 'hr_contact_email': '', + 'it_contact_email': '', + 'operations_contact_email': '', + 'phone_number': '', + 'vat_id': '', + 'registration_number': '', + }, + ) + return company_config + + def get_company_email_domain() -> str: branding = get_portal_branding() domain = (branding.company_domain or '').strip().lower().lstrip('@') @@ -72,6 +92,7 @@ def get_portal_letterhead_path() -> Path: def get_branding_context() -> dict[str, object]: branding = get_portal_branding() + company_config = get_portal_company_config() lang = (get_language() or branding.default_language or 'de').split('-')[0] footer_text = (branding.footer_text_en or '').strip() if lang == 'en' else '' legal_notice = (branding.legal_notice_en or '').strip() if lang == 'en' else '' @@ -97,6 +118,21 @@ def get_branding_context() -> dict[str, object]: 'portal_has_custom_logo': bool(branding.logo_image), 'portal_has_custom_letterhead': bool(branding.pdf_letterhead), 'portal_has_custom_favicon': bool(branding.favicon_image), + 'portal_company_config': company_config, + 'portal_company_legal_name': company_config.legal_company_name or branding.company_name, + 'portal_company_street': company_config.street_address, + 'portal_company_postal_code': company_config.postal_code, + 'portal_company_city': company_config.city, + 'portal_company_country': company_config.country, + 'portal_company_website_url': company_config.website_url, + 'portal_company_imprint_url': company_config.imprint_url, + 'portal_company_privacy_url': company_config.privacy_url, + 'portal_company_hr_contact_email': company_config.hr_contact_email, + 'portal_company_it_contact_email': company_config.it_contact_email, + 'portal_company_operations_contact_email': company_config.operations_contact_email, + 'portal_company_phone_number': company_config.phone_number, + 'portal_company_vat_id': company_config.vat_id, + 'portal_company_registration_number': company_config.registration_number, } diff --git a/backend/workflows/forms.py b/backend/workflows/forms.py index 5aaabc4..74fdf94 100644 --- a/backend/workflows/forms.py +++ b/backend/workflows/forms.py @@ -8,7 +8,7 @@ from django.utils.translation import get_language, gettext as _, gettext_lazy from .branding import get_company_email_domain from .form_builder import apply_form_field_config -from .models import EmployeeProfile, FormOption, OffboardingRequest, OnboardingRequest, PortalBranding, WorkflowConfig +from .models import EmployeeProfile, FormOption, OffboardingRequest, OnboardingRequest, PortalBranding, PortalCompanyConfig, WorkflowConfig from .roles import ROLE_ADMIN, ROLE_GROUP_NAMES, ROLE_IT_STAFF, ROLE_LABELS, ROLE_PLATFORM_OWNER, ROLE_STAFF, ROLE_SUPER_ADMIN, assign_user_role @@ -244,6 +244,43 @@ class PortalBrandingForm(forms.ModelForm): return favicon +class PortalCompanyConfigForm(forms.ModelForm): + class Meta: + model = PortalCompanyConfig + fields = [ + 'legal_company_name', + 'street_address', + 'postal_code', + 'city', + 'country', + 'website_url', + 'imprint_url', + 'privacy_url', + 'hr_contact_email', + 'it_contact_email', + 'operations_contact_email', + 'phone_number', + 'vat_id', + 'registration_number', + ] + labels = { + 'legal_company_name': gettext_lazy('Rechtlicher Firmenname'), + 'street_address': gettext_lazy('Straße und Hausnummer'), + 'postal_code': gettext_lazy('Postleitzahl'), + 'city': gettext_lazy('Stadt'), + 'country': gettext_lazy('Land'), + 'website_url': gettext_lazy('Website'), + 'imprint_url': gettext_lazy('Impressum-URL'), + 'privacy_url': gettext_lazy('Datenschutz-URL'), + 'hr_contact_email': gettext_lazy('HR-Kontakt'), + 'it_contact_email': gettext_lazy('IT-Kontakt'), + 'operations_contact_email': gettext_lazy('Operations-Kontakt'), + 'phone_number': gettext_lazy('Zentrale Telefonnummer'), + 'vat_id': gettext_lazy('USt-IdNr.'), + 'registration_number': gettext_lazy('Register- oder Handelsnummer'), + } + + class OnboardingRequestForm(forms.ModelForm): first_name = forms.CharField(label='Vorname', required=False) last_name = forms.CharField(label='Nachname', required=False) diff --git a/backend/workflows/migrations/0042_portalcompanyconfig.py b/backend/workflows/migrations/0042_portalcompanyconfig.py new file mode 100644 index 0000000..a30276b --- /dev/null +++ b/backend/workflows/migrations/0042_portalcompanyconfig.py @@ -0,0 +1,39 @@ +# Generated by Django 5.1.5 on 2026-03-26 12:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('workflows', '0041_portalappconfig_visible_to_admin_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='PortalCompanyConfig', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(default='Default', max_length=80, unique=True)), + ('legal_company_name', models.CharField(blank=True, default='', max_length=255)), + ('street_address', models.CharField(blank=True, default='', max_length=255)), + ('postal_code', models.CharField(blank=True, default='', max_length=50)), + ('city', models.CharField(blank=True, default='', max_length=120)), + ('country', models.CharField(blank=True, default='Deutschland', max_length=120)), + ('website_url', models.URLField(blank=True, default='')), + ('imprint_url', models.URLField(blank=True, default='')), + ('privacy_url', models.URLField(blank=True, default='')), + ('hr_contact_email', models.EmailField(blank=True, default='', max_length=254)), + ('it_contact_email', models.EmailField(blank=True, default='', max_length=254)), + ('operations_contact_email', models.EmailField(blank=True, default='', max_length=254)), + ('phone_number', models.CharField(blank=True, default='', max_length=80)), + ('vat_id', models.CharField(blank=True, default='', max_length=80)), + ('registration_number', models.CharField(blank=True, default='', max_length=120)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name': 'Portal Company Config', + 'verbose_name_plural': 'Portal Company Config', + }, + ), + ] diff --git a/backend/workflows/models.py b/backend/workflows/models.py index 5b0852c..841bbe4 100644 --- a/backend/workflows/models.py +++ b/backend/workflows/models.py @@ -72,6 +72,32 @@ class PortalBranding(models.Model): return self.portal_title or self.company_name or self.name +class PortalCompanyConfig(models.Model): + name = models.CharField(max_length=80, default='Default', unique=True) + legal_company_name = models.CharField(max_length=255, blank=True, default='') + street_address = models.CharField(max_length=255, blank=True, default='') + postal_code = models.CharField(max_length=50, blank=True, default='') + city = models.CharField(max_length=120, blank=True, default='') + country = models.CharField(max_length=120, blank=True, default='Deutschland') + website_url = models.URLField(blank=True, default='') + imprint_url = models.URLField(blank=True, default='') + privacy_url = models.URLField(blank=True, default='') + hr_contact_email = models.EmailField(blank=True, default='') + it_contact_email = models.EmailField(blank=True, default='') + operations_contact_email = models.EmailField(blank=True, default='') + phone_number = models.CharField(max_length=80, blank=True, default='') + vat_id = models.CharField(max_length=80, blank=True, default='') + registration_number = models.CharField(max_length=120, blank=True, default='') + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + verbose_name = 'Portal Company Config' + verbose_name_plural = 'Portal Company Config' + + def __str__(self) -> str: + return self.legal_company_name or self.name + + class PortalAppConfig(models.Model): SECTION_APP = 'app' SECTION_PLATFORM = 'platform' diff --git a/backend/workflows/roles.py b/backend/workflows/roles.py index e8841e5..437896d 100644 --- a/backend/workflows/roles.py +++ b/backend/workflows/roles.py @@ -29,8 +29,10 @@ ROLE_LABELS = { CAPABILITIES = { 'manage_users': {ROLE_PLATFORM_OWNER, ROLE_SUPER_ADMIN}, 'manage_product_branding': {ROLE_PLATFORM_OWNER}, + 'manage_company_config': {ROLE_PLATFORM_OWNER}, 'manage_app_registry': {ROLE_PLATFORM_OWNER}, - 'access_requests_dashboard': {ROLE_PLATFORM_OWNER, ROLE_SUPER_ADMIN, ROLE_ADMIN, ROLE_IT_STAFF}, + 'access_requests_dashboard': {ROLE_PLATFORM_OWNER, ROLE_SUPER_ADMIN, ROLE_ADMIN, ROLE_IT_STAFF, ROLE_STAFF}, + 'view_request_timeline': {ROLE_PLATFORM_OWNER, ROLE_SUPER_ADMIN, ROLE_ADMIN, ROLE_IT_STAFF}, 'run_intro_session': {ROLE_PLATFORM_OWNER, ROLE_SUPER_ADMIN, ROLE_ADMIN, ROLE_IT_STAFF}, 'generate_intro_pdfs': {ROLE_PLATFORM_OWNER, ROLE_SUPER_ADMIN, ROLE_ADMIN, ROLE_IT_STAFF}, 'retry_requests': {ROLE_PLATFORM_OWNER, ROLE_SUPER_ADMIN, ROLE_ADMIN, ROLE_IT_STAFF}, @@ -124,9 +126,11 @@ def template_role_context(user) -> dict[str, object]: 'role_key': role_key, 'role_label': str(ROLE_LABELS[role_key]), 'can_manage_product_branding': user_has_capability(user, 'manage_product_branding'), + 'can_manage_company_config': user_has_capability(user, 'manage_company_config'), 'can_manage_app_registry': user_has_capability(user, 'manage_app_registry'), 'can_manage_users': user_has_capability(user, 'manage_users'), 'can_access_requests_dashboard': user_has_capability(user, 'access_requests_dashboard'), + 'can_view_request_timeline': user_has_capability(user, 'view_request_timeline'), 'can_run_intro_session': user_has_capability(user, 'run_intro_session'), 'can_generate_intro_pdfs': user_has_capability(user, 'generate_intro_pdfs'), 'can_retry_requests': user_has_capability(user, 'retry_requests'), diff --git a/backend/workflows/static/workflows/css/app_chrome.css b/backend/workflows/static/workflows/css/app_chrome.css index 8ba66d8..6179816 100644 --- a/backend/workflows/static/workflows/css/app_chrome.css +++ b/backend/workflows/static/workflows/css/app_chrome.css @@ -141,6 +141,29 @@ line-height: 1.5; } +.app-site-footer-links { + margin-top: 8px; + display: flex; + gap: 12px; + justify-content: center; + flex-wrap: wrap; +} + +.app-site-footer-links a { + color: #1f3a5f; + font-size: 12px; + font-weight: 700; + text-decoration: none; + transition: + color var(--motion-fast) var(--motion-ease), + transform var(--motion-fast) var(--motion-ease); +} + +.app-site-footer-links a:hover { + color: var(--app-brand-blue); + transform: translateY(-1px); +} + @media (max-width: 900px) { .app-header, .app-header-in-shell { diff --git a/backend/workflows/templates/workflows/app_registry.html b/backend/workflows/templates/workflows/app_registry.html index d34155e..5c07e5a 100644 --- a/backend/workflows/templates/workflows/app_registry.html +++ b/backend/workflows/templates/workflows/app_registry.html @@ -197,7 +197,7 @@ {% endblock %} -{% block extra_js %} +{% block extra_scripts %}