Permission rethinking

* No detailed permissions due to django constraints on model-based permissions
* instead: logic controlled permission by group membership
* adds translations
This commit is contained in:
mipel 2021-07-02 09:30:50 +02:00
parent 206d34afbb
commit 32370a0a7e
6 changed files with 211 additions and 259 deletions

View File

@ -74,6 +74,7 @@ class Compensation(BaseObject):
geometry = models.ForeignKey(Geometry, null=True, blank=True, on_delete=models.SET_NULL) geometry = models.ForeignKey(Geometry, null=True, blank=True, on_delete=models.SET_NULL)
documents = models.ManyToManyField("konova.Document", blank=True) documents = models.ManyToManyField("konova.Document", blank=True)
@staticmethod @staticmethod
def _generate_new_identifier() -> str: def _generate_new_identifier() -> str:
""" Generates a new identifier for the intervention object """ Generates a new identifier for the intervention object

View File

@ -83,18 +83,10 @@ class Command(BaseCommand):
self._write_warning("--- Groups ---") self._write_warning("--- Groups ---")
for group_data in GROUPS_DATA: for group_data in GROUPS_DATA:
name = group_data.get("name") name = group_data.get("name")
perms_data = group_data.get("permissions") Group.objects.get_or_create(
perms_objects = [
Permission.objects.get_or_create(
codename=perm[0],
name=perm[1]
)
for perm in perms_data
]
group = Group.objects.get_or_create(
name=name, name=name,
) )
group.permissions.set(perms_objects) self._write_success(CREATED_TEMPLATE.format(name))
self._break_line() self._break_line()

View File

@ -26,36 +26,14 @@ TEST_ORGANISATION_DATA = [
}, },
] ]
# Groups permissions are declared in konova/settings.py
GROUPS_DATA = [ GROUPS_DATA = [
{ {
"name": _("Default"), "name": _("Default"),
"permissions": [
ADD_INTERVENTION,
EDIT_INTERVENTION,
DELETE_INTERVENTION,
ADD_COMPENSATION,
EDIT_COMPENSATION,
DELETE_COMPENSATION,
ADD_ECOACCOUNT,
EDIT_ECOACCOUNT,
DELETE_ECOACCOUNT,
CREATE_SHARE_LINK,
]
}, },
{ {
"name": _("Registration office"), "name": _("Registration office"),
"permissions": [
VALIDITY_CHECK,
]
}, },
{ {
"name": _("Conservation office"), "name": _("Conservation office"),
"permissions": [
RECORD_DATA,
ADD_EMA,
EDIT_EMA,
DELETE_EMA,
]
}, },
] ]

View File

@ -7,7 +7,7 @@ Created on: 17.11.20
""" """
import uuid import uuid
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User
from django.contrib.gis.db.models import MultiPolygonField from django.contrib.gis.db.models import MultiPolygonField
from django.db import models from django.db import models
@ -43,25 +43,6 @@ class BaseObject(BaseResource):
abstract = True abstract = True
class KonovaPermission(models.Model):
"""
Custom permissions for konova
"""
name = models.CharField(max_length=255, blank=False, null=False)
description = models.TextField()
is_active = models.BooleanField(default=True)
class KonovaGroup(models.Model):
"""
Custom group model
"""
name = models.CharField(max_length=255, null=False, blank=False)
permissions = models.ManyToManyField(KonovaPermission)
class Deadline(BaseResource): class Deadline(BaseResource):
""" """
Defines a deadline, which can be used to define dates with a semantic meaning Defines a deadline, which can be used to define dates with a semantic meaning

Binary file not shown.

View File

@ -3,16 +3,13 @@
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# #
#: konova/forms.py:73 process/forms.py:29 process/forms.py:36 #: konova/forms.py:67
#: process/forms.py:43 process/forms.py:50 process/forms.py:64
#: process/forms.py:70 process/forms.py:76 process/forms.py:90
#: process/forms.py:96
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-18 10:50+0100\n" "POT-Creation-Date: 2021-07-02 09:22+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -22,66 +19,59 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: compensation/tables.py:18 compensation/tables.py:73 intervention/forms.py:26 #: compensation/tables.py:18 compensation/tables.py:68 intervention/forms.py:26
#: intervention/tables.py:19 process/forms.py:28 #: intervention/tables.py:19
msgid "Identifier" msgid "Identifier"
msgstr "Kennung" msgstr "Kennung"
#: compensation/tables.py:23 compensation/tables.py:78 intervention/forms.py:33 #: compensation/tables.py:23 compensation/tables.py:73 intervention/forms.py:33
#: intervention/tables.py:24 process/forms.py:35 process/tables.py:28 #: intervention/tables.py:24
msgid "Title" msgid "Title"
msgstr "Titel" msgstr "Titel"
#: compensation/tables.py:28 intervention/tables.py:29 process/tables.py:80 #: compensation/tables.py:28 compensation/tables.py:78
#: process/tables.py:116 process/templates/process/open.html:8 #: intervention/tables.py:29
#: templates/authenticated-user-navbar.html:17
msgid "Process"
msgstr "Vorgang"
#: compensation/tables.py:33 compensation/tables.py:83
#: intervention/tables.py:34 process/tables.py:52
msgid "Created on" msgid "Created on"
msgstr "Erstellt" msgstr "Erstellt"
#: compensation/tables.py:38 compensation/tables.py:88 #: compensation/tables.py:33 compensation/tables.py:83
#: intervention/tables.py:39 process/tables.py:57 #: intervention/tables.py:34
msgid "Actions" msgid "Actions"
msgstr "Aktionen" msgstr "Aktionen"
#: compensation/tables.py:46 process/templates/process/open.html:57 #: compensation/tables.py:41
msgid "Compensations" msgid "Compensations"
msgstr "Kompensationen" msgstr "Kompensationen"
#: compensation/tables.py:53 compensation/tables.py:103 #: compensation/tables.py:48 compensation/tables.py:98
#: templates/authenticated-user-navbar.html:45 #: templates/authenticated-user-navbar.html:45
msgid "Compensation" msgid "Compensation"
msgstr "Kompensation" msgstr "Kompensation"
#: compensation/tables.py:56 compensation/tables.py:106 #: compensation/tables.py:51 compensation/tables.py:101
#: intervention/tables.py:62 intervention/tables.py:76 process/tables.py:80 #: intervention/tables.py:57 intervention/tables.py:71
#: process/tables.py:119
msgid "Open {}" msgid "Open {}"
msgstr "Öffne {}" msgstr "Öffne {}"
#: compensation/tables.py:61 compensation/tables.py:111 #: compensation/tables.py:56 compensation/tables.py:106
#: intervention/tables.py:80 process/tables.py:123 #: intervention/tables.py:75
msgid "Edit {}" msgid "Edit {}"
msgstr "Bearbeite {}" msgstr "Bearbeite {}"
#: compensation/tables.py:65 compensation/tables.py:115 #: compensation/tables.py:60 compensation/tables.py:110
#: intervention/tables.py:84 process/tables.py:127 #: intervention/tables.py:79
msgid "Delete {}" msgid "Delete {}"
msgstr "Lösche {}" msgstr "Lösche {}"
#: compensation/tables.py:96 #: compensation/tables.py:91
msgid "Eco Accounts" msgid "Eco Accounts"
msgstr "Ökokonten" msgstr "Ökokonten"
#: intervention/forms.py:29 process/forms.py:30 #: intervention/forms.py:29
msgid "Generated automatically if none was given" msgid "Generated automatically if none was given"
msgstr "Wird automatisch erzeugt, falls nicht angegeben" msgstr "Wird automatisch erzeugt, falls nicht angegeben"
#: intervention/forms.py:38 process/forms.py:42 #: intervention/forms.py:38
msgid "Type" msgid "Type"
msgstr "Typ" msgstr "Typ"
@ -105,7 +95,7 @@ msgstr "Eingriffsverursacher"
msgid "Who performs the intervention" msgid "Who performs the intervention"
msgstr "Wer führt den Eingriff durch" msgstr "Wer führt den Eingriff durch"
#: intervention/forms.py:56 organisation/settings.py:19 #: intervention/forms.py:56
msgid "Data provider" msgid "Data provider"
msgstr "Datenbereitsteller" msgstr "Datenbereitsteller"
@ -113,8 +103,7 @@ msgstr "Datenbereitsteller"
msgid "Who provides the data for the intervention" msgid "Who provides the data for the intervention"
msgstr "Wer stellt die Daten für den Eingriff zur Verfügung" msgstr "Wer stellt die Daten für den Eingriff zur Verfügung"
#: intervention/forms.py:63 process/forms.py:56 process/forms.py:82 #: intervention/forms.py:63 templates/authenticated-user-navbar.html:90
#: templates/authenticated-user-navbar.html:90
#: templates/authenticated-user-navbar.html:93 #: templates/authenticated-user-navbar.html:93
msgid "Organization" msgid "Organization"
msgstr "Organisation" msgstr "Organisation"
@ -143,227 +132,140 @@ msgstr "Dateien"
msgid "New intervention" msgid "New intervention"
msgstr "Neuer Eingriff" msgstr "Neuer Eingriff"
#: intervention/forms.py:145 #: intervention/forms.py:145 konova/settings.py:56
msgid "Edit intervention" msgid "Edit intervention"
msgstr "Eingriff bearbeiten" msgstr "Eingriff bearbeiten"
#: intervention/tables.py:47 #: intervention/tables.py:42
msgid "Interventions" msgid "Interventions"
msgstr "Eingriffe" msgstr "Eingriffe"
#: intervention/tables.py:62 intervention/tables.py:73 #: intervention/tables.py:57 intervention/tables.py:68
#: intervention/templates/intervention/open.html:8 #: intervention/templates/intervention/open.html:8
#: process/templates/process/open.html:48
#: templates/authenticated-user-navbar.html:31 #: templates/authenticated-user-navbar.html:31
msgid "Intervention" msgid "Intervention"
msgstr "Eingriff" msgstr "Eingriff"
#: intervention/templates/intervention/open.html:12 #: intervention/templates/intervention/open.html:12
#: process/templates/process/open.html:13
msgid "Edit" msgid "Edit"
msgstr "Bearbeiten" msgstr "Bearbeiten"
#: intervention/views.py:62 #: intervention/views.py:56
msgid ""
"Interventions must be part of a process. Please fill in the missing data for "
"the process"
msgstr ""
"Eingriffe müssen zu einem Vorgang gehören. Bitte geben SIe die fehlenden "
"Daten für den Vorgang ein."
#: intervention/views.py:65
msgid "Intervention {} added" msgid "Intervention {} added"
msgstr "Eingriff {} hinzugefügt" msgstr "Eingriff {} hinzugefügt"
#: intervention/views.py:68 intervention/views.py:121 intervention/views.py:160 #: intervention/views.py:59 intervention/views.py:112
#: process/views.py:69 process/views.py:121 process/views.py:157
msgid "Invalid input" msgid "Invalid input"
msgstr "Eingabe fehlerhaft" msgstr "Eingabe fehlerhaft"
#: intervention/views.py:118 process/views.py:118 #: intervention/views.py:109
msgid "{} edited" msgid "{} edited"
msgstr "{} bearbeitet" msgstr "{} bearbeitet"
#: intervention/views.py:157 #: konova/decorators.py:27
msgid "Intervention {} removed"
msgstr "Eingriff {} gelöscht"
#: konova/decorators.py:34
msgid "You need to be staff to perform this action!" msgid "You need to be staff to perform this action!"
msgstr "Hierfür müssen Sie Mitarbeiter sein!" msgstr "Hierfür müssen Sie Mitarbeiter sein!"
#: konova/decorators.py:49 #: konova/decorators.py:42
msgid "You need to be administrator to perform this action!" msgid "You need to be administrator to perform this action!"
msgstr "Hierfür müssen Sie Administrator sein!" msgstr "Hierfür müssen Sie Administrator sein!"
#: konova/decorators.py:89 #: konova/forms.py:40
msgid "Your current role is not allowed to do this"
msgstr ""
#: konova/forms.py:46
msgid "Not editable" msgid "Not editable"
msgstr "Nicht editierbar" msgstr "Nicht editierbar"
#: konova/forms.py:72 #: konova/forms.py:66
msgid "Confirm" msgid "Confirm"
msgstr "Bestätigen" msgstr "Bestätigen"
#: konova/forms.py:84 #: konova/forms.py:78
msgid "Remove" msgid "Remove"
msgstr "Entferne" msgstr "Entferne"
#: konova/forms.py:86 #: konova/forms.py:80
msgid "You are about to remove {} {}" msgid "You are about to remove {} {}"
msgstr "Sie sind dabei {} {} zu löschen" msgstr "Sie sind dabei {} {} zu löschen"
#: konova/forms.py:106 #: konova/management/commands/setup_data.py:32
msgid "You are working as" msgid "Default"
msgstr "Sie arbeiten gerade als " msgstr ""
#: konova/templates/konova/home.html:11 #: konova/management/commands/setup_data.py:47
msgid "Registration office"
msgstr "Zulassungsbehörde"
#: konova/management/commands/setup_data.py:53
msgid "Conservation office"
msgstr "Naturschutzbehörde"
#: konova/settings.py:55
msgid "Add new intervention"
msgstr "Neuen Eingriff hinzufügen"
#: konova/settings.py:57
msgid "Delete intervention"
msgstr "Eingriff löschen"
#: konova/settings.py:58
msgid "Add new compensation"
msgstr "Neue Kompensation hinzufügen"
#: konova/settings.py:59
msgid "Edit compensation"
msgstr "Kompensation bearbeiten"
#: konova/settings.py:60
msgid "Delete compensation"
msgstr "Kompensation löschen"
#: konova/settings.py:61
msgid "Add new eco account"
msgstr "Neues Ökokonto hinzufügen"
#: konova/settings.py:62
msgid "Edit eco account"
msgstr "Ökokonto"
#: konova/settings.py:63
msgid "Delete eco account"
msgstr "Ökokonto löschen"
#: konova/settings.py:64
msgid "Create share link"
msgstr "Freigabelink erstellen"
#: konova/settings.py:67
msgid "Confirm check on data"
msgstr "Datenprüfung bestätigen"
#: konova/settings.py:70
msgid "Record data"
msgstr "Daten verzeichnen"
#: konova/settings.py:71
msgid "Add new EMA"
msgstr "Neue EMA hinzufügen"
#: konova/settings.py:72
msgid "Edit EMA"
msgstr "Bearbeite EMA"
#: konova/settings.py:73
msgid "Delete EMA"
msgstr "Lösche EMA"
#: konova/templates/kspneo/home.html:11
msgid "Proceed with login" msgid "Proceed with login"
msgstr "Mit Login fortfahren" msgstr "Mit Login fortfahren"
#: konova/templates/konova/home.html:16 #: konova/templates/kspneo/home.html:16
msgid "Logged in as" msgid "Logged in as"
msgstr "Eingeloggt als" msgstr "Eingeloggt als"
#: konova/templates/konova/home.html:18 #: konova/templates/kspneo/home.html:18
msgid "Last login on" msgid "Last login on"
msgstr "Zuletzt eingeloggt am" msgstr "Zuletzt eingeloggt am"
#: konova/views.py:53
msgid "Role changed"
msgstr "Rolle geändert"
#: konova/views.py:55
msgid "Invalid role"
msgstr "Rolle ungültig"
#: organisation/settings.py:13
msgid "Official"
msgstr "Amtlich"
#: organisation/settings.py:14
msgid "Company"
msgstr "Firma"
#: organisation/settings.py:15
msgid "NGO"
msgstr "NGO"
#: organisation/settings.py:20 process/forms.py:49
#: process/templates/process/open.html:23
msgid "Licencing Authority"
msgstr "Zulassungsbehörde"
#: organisation/settings.py:21 process/forms.py:75
#: process/templates/process/open.html:31
msgid "Registration office"
msgstr "Eintragungsstelle"
#: process/forms.py:37
msgid "Proper title of the process"
msgstr "Titel des Vorgangs"
#: process/forms.py:44
msgid "Which process type is this"
msgstr "Welcher Vorgangstyp"
#: process/forms.py:63 process/templates/process/open.html:27
msgid "Licencing document identifier"
msgstr "Aktenzeichen Zulassungsbehörde"
#: process/forms.py:69
msgid "Comment licensing authority"
msgstr "Kommentar Zulassungsbehörde"
#: process/forms.py:89 process/templates/process/open.html:35
msgid "Registration document identifier"
msgstr "Aktenzeichen Eintragungsstelle"
#: process/forms.py:95
msgid "Comment registration office"
msgstr "Kommentar Eintragungsstelle"
#: process/forms.py:104
msgid "Add new process"
msgstr "Neuen Vorgang hinzufügen"
#: process/forms.py:105
msgid "Enter these basic information for the new process."
msgstr "Geben Sie die grundlegenden Informationen für einen neuen Vorgang ein."
#: process/forms.py:146 process/tables.py:47
#: process/templates/process/open.html:39
#: process/templates/process/open.html:41
msgid "Status"
msgstr ""
#: process/forms.py:157
msgid "Edit process"
msgstr "Vorgang bearbeiten"
#: process/settings.py:14
msgid "private"
msgstr "privat"
#: process/settings.py:15
msgid "accessible"
msgstr "bereitgestellt"
#: process/settings.py:16
msgid "licensed"
msgstr "genehmigt"
#: process/settings.py:17
msgid "official"
msgstr "bestandskräftig"
#: process/settings.py:18
msgid "recorded"
msgstr "verzeichnet"
#: process/tables.py:23
msgid "Intervention identifier"
msgstr "Eingriffskennung"
#: process/tables.py:65
msgid "Processes"
msgstr "Vorgänge"
#: process/templates/process/open.html:64
msgid "Add a new compensation"
msgstr "Neue Kompensation hinzufügen"
#: process/templates/process/open.html:66 templates/table.html:16
msgid "New"
msgstr "Neu"
#: process/templates/process/open.html:84
msgid "No compensation"
msgstr "Keine Kompensation"
#: process/views.py:66
msgid ""
"A process is based on an intervention. Please fill in the missing data for "
"this intervention"
msgstr ""
"Ein Vorgang basiert immer auf einem Eingriff. Bitte geben Sie die fehlenden "
"Daten für diesen Eingriff ein"
#: process/views.py:154
msgid "Process {} removed"
msgstr "Vorgang {} gelöscht"
#: process/views.py:191
msgid "{} status changed from {} to {}"
msgstr "{} Status von {} auf {} geändert"
#: process/views.py:212
msgid "Please fill in the data for this compensation"
msgstr ""
#: templates/anonymous-user-navbar.html:7 #: templates/anonymous-user-navbar.html:7
#: templates/authenticated-user-navbar.html:8 #: templates/authenticated-user-navbar.html:8
msgid "Menu" msgid "Menu"
@ -371,11 +273,15 @@ msgstr "Menü"
#: templates/anonymous-user-navbar.html:14 #: templates/anonymous-user-navbar.html:14
#: templates/anonymous-user-navbar.html:15 #: templates/anonymous-user-navbar.html:15
#: templates/authenticated-user-navbar.html:14 templates/base.html:29 #: templates/authenticated-user-navbar.html:14 templates/base.html:25
#: templates/base.html:30 #: templates/base.html:26
msgid "Home" msgid "Home"
msgstr "Home" msgstr "Home"
#: templates/authenticated-user-navbar.html:17
msgid "Process"
msgstr "Vorgang"
#: templates/authenticated-user-navbar.html:20 #: templates/authenticated-user-navbar.html:20
msgid "Process management" msgid "Process management"
msgstr "Vorgangsverwaltung" msgstr "Vorgangsverwaltung"
@ -469,11 +375,11 @@ msgstr "Sie arbeiten gerade als "
msgid "Change..." msgid "Change..."
msgstr "Ändern..." msgstr "Ändern..."
#: templates/base.html:88 #: templates/base.html:84
msgid "About this site" msgid "About this site"
msgstr "" msgstr ""
#: templates/base.html:91 #: templates/base.html:87
msgid "Privacy policy" msgid "Privacy policy"
msgstr "" msgstr ""
@ -493,10 +399,20 @@ msgstr "Speichern"
msgid "New entry" msgid "New entry"
msgstr "Neuer Eintrag" msgstr "Neuer Eintrag"
#: templates/table.html:16
msgid "New"
msgstr "Neu"
#: templates/table.html:31 #: templates/table.html:31
msgid "Results per page" msgid "Results per page"
msgstr "Treffer pro Seite" msgstr "Treffer pro Seite"
#: venv/lib/python3.7/site-packages/bootstrap4/components.py:17
#: venv/lib/python3.7/site-packages/bootstrap4/templates/bootstrap4/form_errors.html:3
#: venv/lib/python3.7/site-packages/bootstrap4/templates/bootstrap4/messages.html:4
msgid "close"
msgstr ""
#: venv/lib/python3.7/site-packages/django/contrib/messages/apps.py:7 #: venv/lib/python3.7/site-packages/django/contrib/messages/apps.py:7
msgid "Messages" msgid "Messages"
msgstr "Nachrichten" msgstr "Nachrichten"
@ -1686,6 +1602,90 @@ msgstr ""
msgid "A fontawesome icon field" msgid "A fontawesome icon field"
msgstr "" msgstr ""
#~ msgid ""
#~ "Interventions must be part of a process. Please fill in the missing data "
#~ "for the process"
#~ msgstr ""
#~ "Eingriffe müssen zu einem Vorgang gehören. Bitte geben SIe die fehlenden "
#~ "Daten für den Vorgang ein."
#~ msgid "Intervention {} removed"
#~ msgstr "Eingriff {} gelöscht"
#~ msgid "You are working as"
#~ msgstr "Sie arbeiten gerade als "
#~ msgid "Role changed"
#~ msgstr "Rolle geändert"
#~ msgid "Invalid role"
#~ msgstr "Rolle ungültig"
#~ msgid "Official"
#~ msgstr "Amtlich"
#~ msgid "Company"
#~ msgstr "Firma"
#~ msgid "NGO"
#~ msgstr "NGO"
#~ msgid "Licencing Authority"
#~ msgstr "Zulassungsbehörde"
#~ msgid "Proper title of the process"
#~ msgstr "Titel des Vorgangs"
#~ msgid "Which process type is this"
#~ msgstr "Welcher Vorgangstyp"
#~ msgid "Licencing document identifier"
#~ msgstr "Aktenzeichen Zulassungsbehörde"
#~ msgid "Comment licensing authority"
#~ msgstr "Kommentar Zulassungsbehörde"
#~ msgid "Registration document identifier"
#~ msgstr "Aktenzeichen Eintragungsstelle"
#~ msgid "Enter these basic information for the new process."
#~ msgstr ""
#~ "Geben Sie die grundlegenden Informationen für einen neuen Vorgang ein."
#~ msgid "Edit process"
#~ msgstr "Vorgang bearbeiten"
#~ msgid "private"
#~ msgstr "privat"
#~ msgid "accessible"
#~ msgstr "bereitgestellt"
#~ msgid "licensed"
#~ msgstr "genehmigt"
#~ msgid "official"
#~ msgstr "bestandskräftig"
#~ msgid "Intervention identifier"
#~ msgstr "Eingriffskennung"
#~ msgid "Processes"
#~ msgstr "Vorgänge"
#~ msgid ""
#~ "A process is based on an intervention. Please fill in the missing data "
#~ "for this intervention"
#~ msgstr ""
#~ "Ein Vorgang basiert immer auf einem Eingriff. Bitte geben Sie die "
#~ "fehlenden Daten für diesen Eingriff ein"
#~ msgid "Process {} removed"
#~ msgstr "Vorgang {} gelöscht"
#~ msgid "{} status changed from {} to {}"
#~ msgstr "{} Status von {} auf {} geändert"
#~ msgid "Process {} added" #~ msgid "Process {} added"
#~ msgstr "Vorgang {} hinzugefügt" #~ msgstr "Vorgang {} hinzugefügt"