diff --git a/compensation/forms/modalForms.py b/compensation/forms/modalForms.py index 18e6061..a6e7df2 100644 --- a/compensation/forms/modalForms.py +++ b/compensation/forms/modalForms.py @@ -21,7 +21,7 @@ from konova.contexts import BaseContext from konova.forms import BaseModalForm, NewDocumentForm, RemoveModalForm from konova.models import DeadlineType from konova.utils.message_templates import FORM_INVALID, ADDED_COMPENSATION_STATE, ADDED_DEADLINE, \ - ADDED_COMPENSATION_ACTION + ADDED_COMPENSATION_ACTION, PAYMENT_EDITED class NewPaymentForm(BaseModalForm): @@ -103,6 +103,32 @@ class NewPaymentForm(BaseModalForm): return pay +class EditPaymentModalForm(NewPaymentForm): + """ Form handling edit for Payment + + """ + payment = None + + def __init__(self, *args, **kwargs): + self.payment = kwargs.pop("payment", None) + super().__init__(*args, **kwargs) + form_date = { + "amount": self.payment.amount, + "due": str(self.payment.due_on), + "comment": self.payment.comment, + } + self.load_initial_data(form_date, disabled_fields=[]) + + def save(self): + payment = self.payment + payment.amount = self.cleaned_data.get("amount", None) + payment.due_on = self.cleaned_data.get("due", None) + payment.comment = self.cleaned_data.get("comment", None) + payment.save() + self.instance.mark_as_edited(self.user, self.request, edit_comment=PAYMENT_EDITED) + return payment + + class RemovePaymentModalForm(RemoveModalForm): """ Removing modal form for Payment diff --git a/compensation/tests/compensation/test_views.py b/compensation/tests/compensation/test_views.py index 4039496..465a102 100644 --- a/compensation/tests/compensation/test_views.py +++ b/compensation/tests/compensation/test_views.py @@ -117,7 +117,7 @@ class CompensationViewTestCase(BaseViewTestCase): def test_logged_in_no_groups_unshared(self): """ Check correct status code for all requests - Assumption: User logged in and has no groups and data is shared + Assumption: User logged in and has no groups and data is not shared Returns: diff --git a/compensation/tests/payment/__init__.py b/compensation/tests/payment/__init__.py new file mode 100644 index 0000000..b90ce20 --- /dev/null +++ b/compensation/tests/payment/__init__.py @@ -0,0 +1,7 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 09.02.22 + +""" diff --git a/compensation/tests/payment/test_views.py b/compensation/tests/payment/test_views.py new file mode 100644 index 0000000..69130e8 --- /dev/null +++ b/compensation/tests/payment/test_views.py @@ -0,0 +1,154 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 09.02.22 + +""" +from django.urls import reverse +from django.test.client import Client + +from compensation.models import Payment +from konova.settings import DEFAULT_GROUP +from konova.tests.test_views import BaseViewTestCase + + +class PaymentViewTestCase(BaseViewTestCase): + + @classmethod + def setUpTestData(cls) -> None: + super().setUpTestData() + + cls.payment = Payment.objects.get_or_create( + intervention=cls.intervention, + amount=1, + due_on="2020-01-01", + comment="Testcomment" + )[0] + + cls.new_url = reverse("compensation:pay:new", args=(cls.intervention.id,)) + cls.edit_url = reverse("compensation:pay:edit", args=(cls.intervention.id, cls.payment.id)) + cls.remove_url = reverse("compensation:pay:remove", args=(cls.intervention.id, cls.payment.id)) + + def test_anonymous_user(self): + """ Check correct status code for all requests + + Assumption: User not logged in + + Returns: + + """ + client = Client() + + success_urls = [ + ] + fail_urls = [ + self.new_url, + self.edit_url, + self.remove_url, + ] + + self.assert_url_success(client, success_urls) + self.assert_url_fail(client, fail_urls) + + def test_logged_in_no_groups_shared(self): + """ Check correct status code for all requests + + Assumption: User logged in and has no groups and data is shared + + Returns: + + """ + client = Client() + client.login(username=self.superuser.username, password=self.superuser_pw) + self.superuser.groups.set([]) + self.intervention.share_with_list([self.superuser]) + + # Since the user has no groups, it does not matter that data has been shared. There SHOULD not be any difference + # to a user without access, since the important permissions are missing + success_urls = [ + ] + fail_urls = [ + self.new_url, + self.edit_url, + self.remove_url, + ] + + self.assert_url_success(client, success_urls) + self.assert_url_fail(client, fail_urls) + + def test_logged_in_no_groups_unshared(self): + """ Check correct status code for all requests + + Assumption: User logged in and has no groups and data is not shared + + Returns: + + """ + client = Client() + client.login(username=self.superuser.username, password=self.superuser_pw) + self.superuser.groups.set([]) + # Sharing is inherited by base intervention for compensation. Therefore configure the interventions share state + self.intervention.share_with_list([]) + + # Since the user has no groups, it does not matter that data is unshared. There SHOULD not be any difference + # to a user having shared access, since all important permissions are missing + success_urls = [ + ] + fail_urls = [ + self.new_url, + self.edit_url, + self.remove_url, + ] + + self.assert_url_success(client, success_urls) + self.assert_url_fail(client, fail_urls) + + def test_logged_in_default_group_shared(self): + """ Check correct status code for all requests + + Assumption: User logged in, is default group member and data is shared + --> Default group necessary since all base functionalities depend on this group membership + + Returns: + + """ + client = Client() + client.login(username=self.superuser.username, password=self.superuser_pw) + group = self.groups.get(name=DEFAULT_GROUP) + self.superuser.groups.set([group]) + # Sharing is inherited by base intervention for compensation. Therefore configure the interventions share state + self.intervention.share_with_list([self.superuser]) + + success_urls = [ + self.new_url, + self.edit_url, + self.remove_url, + ] + self.assert_url_success(client, success_urls) + + def test_logged_in_default_group_unshared(self): + """ Check correct status code for all requests + + Assumption: User logged in, is default group member and data is NOT shared + --> Default group necessary since all base functionalities depend on this group membership + + Returns: + + """ + client = Client() + client.login(username=self.superuser.username, password=self.superuser_pw) + group = self.groups.get(name=DEFAULT_GROUP) + self.superuser.groups.set([group]) + # Sharing is inherited by base intervention for compensation. Therefore configure the interventions share state + self.intervention.share_with_list([]) + + success_urls = [ + ] + fail_urls = [ + self.new_url, + self.edit_url, + self.remove_url, + ] + self.assert_url_fail(client, fail_urls) + self.assert_url_success(client, success_urls) diff --git a/compensation/tests/payment/test_workflow.py b/compensation/tests/payment/test_workflow.py new file mode 100644 index 0000000..09ff0e6 --- /dev/null +++ b/compensation/tests/payment/test_workflow.py @@ -0,0 +1,125 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 09.02.22 + +""" +from django.core.exceptions import ObjectDoesNotExist +from django.urls import reverse + +from compensation.models import Payment +from konova.tests.test_views import BaseWorkflowTestCase +from user.models import UserAction + + +class PaymentWorkflowTestCase(BaseWorkflowTestCase): + @classmethod + def setUpTestData(cls): + super().setUpTestData() + + # Give the user shared access to the dummy intervention + cls.intervention.share_with(cls.superuser) + + cls.payment = Payment.objects.get_or_create( + intervention=cls.intervention, + amount=1, + due_on="2020-01-01", + comment="Testcomment" + )[0] + + def test_new(self): + """ Test the creation of a payment + + Returns: + + """ + # Prepare url and form data to be posted + new_url = reverse("compensation:pay:new", args=(self.intervention.id,)) + test_amount = 12345 + test_due_on = "1970-01-01" + test_comment = self.create_dummy_string() + post_data = { + "amount": test_amount, + "due": test_due_on, + "comment": test_comment, + } + pre_creation_intervention_log_count = self.intervention.log.count() + num_payments = self.intervention.payments.count() + + self.client_user.post(new_url, post_data) + + self.intervention.refresh_from_db() + + self.assertEqual(num_payments + 1, self.intervention.payments.count()) + new_payment = self.intervention.payments.get(amount=test_amount) + self.assertEqual(new_payment.amount, test_amount) + self.assertEqual(str(new_payment.due_on), test_due_on) + self.assertEqual(new_payment.comment, test_comment) + + # Expect logs to be set + self.assertEqual(pre_creation_intervention_log_count + 1, self.intervention.log.count()) + self.assertEqual(self.intervention.log.first().action, UserAction.EDITED) + + def test_edit(self): + """ Test edit of a payment + + Returns: + + """ + # Prepare url and form data to be posted + new_url = reverse("compensation:pay:edit", args=(self.intervention.id, self.payment.id)) + test_amount = self.payment.amount * 2 + test_due_on = "1970-01-01" + test_comment = self.create_dummy_string() + post_data = { + "amount": test_amount, + "due": test_due_on, + "comment": test_comment, + } + pre_edit_intervention_log_count = self.intervention.log.count() + num_payments = self.intervention.payments.count() + + self.client_user.post(new_url, post_data) + + self.intervention.refresh_from_db() + self.payment.refresh_from_db() + + self.assertEqual(num_payments, self.intervention.payments.count()) + self.assertEqual(self.payment.amount, test_amount) + self.assertEqual(str(self.payment.due_on), test_due_on) + self.assertEqual(self.payment.comment, test_comment) + + # Expect logs to be set + self.assertEqual(pre_edit_intervention_log_count + 1, self.intervention.log.count()) + self.assertEqual(self.intervention.log.first().action, UserAction.EDITED) + + def test_remove(self): + """ Test remove of a payment + + Returns: + + """ + # Prepare url and form data to be posted + new_url = reverse("compensation:pay:remove", args=(self.intervention.id, self.payment.id)) + post_data = { + "confirm": True, + } + pre_remove_intervention_log_count = self.intervention.log.count() + num_payments = self.intervention.payments.count() + + self.client_user.post(new_url, post_data) + + self.intervention.refresh_from_db() + try: + self.payment.refresh_from_db() + self.fail(msg="Payment still exists after delete") + except ObjectDoesNotExist: + pass + + self.assertEqual(num_payments - 1, self.intervention.payments.count()) + + # Expect logs to be set + self.assertEqual(pre_remove_intervention_log_count + 1, self.intervention.log.count()) + self.assertEqual(self.intervention.log.first().action, UserAction.EDITED) + diff --git a/compensation/urls/payment.py b/compensation/urls/payment.py index a400c63..b51384d 100644 --- a/compensation/urls/payment.py +++ b/compensation/urls/payment.py @@ -12,4 +12,5 @@ app_name = "pay" urlpatterns = [ path('/new', new_payment_view, name='new'), path('/remove/', payment_remove_view, name='remove'), + path('/edit/', payment_edit_view, name='edit'), ] diff --git a/compensation/views/payment.py b/compensation/views/payment.py index 7be9bee..2be5455 100644 --- a/compensation/views/payment.py +++ b/compensation/views/payment.py @@ -11,16 +11,17 @@ from django.contrib.auth.decorators import login_required from django.http import HttpRequest from django.shortcuts import get_object_or_404 -from compensation.forms.modalForms import NewPaymentForm, RemovePaymentModalForm +from compensation.forms.modalForms import NewPaymentForm, RemovePaymentModalForm, EditPaymentModalForm from compensation.models import Payment from intervention.models import Intervention -from konova.decorators import default_group_required +from konova.decorators import default_group_required, shared_access_required from konova.forms import RemoveModalForm -from konova.utils.message_templates import PAYMENT_ADDED, PAYMENT_REMOVED +from konova.utils.message_templates import PAYMENT_ADDED, PAYMENT_REMOVED, PAYMENT_EDITED @login_required @default_group_required +@shared_access_required(Intervention, "id") def new_payment_view(request: HttpRequest, id: str): """ Renders a modal view for adding new payments @@ -42,6 +43,7 @@ def new_payment_view(request: HttpRequest, id: str): @login_required @default_group_required +@shared_access_required(Intervention, "id") def payment_remove_view(request: HttpRequest, id: str, payment_id: str): """ Renders a modal view for removing payments @@ -62,3 +64,27 @@ def payment_remove_view(request: HttpRequest, id: str, payment_id: str): redirect_url=reverse("intervention:detail", args=(payment.intervention_id,)) + "#related_data" ) + +@login_required +@default_group_required +@shared_access_required(Intervention, "id") +def payment_edit_view(request: HttpRequest, id: str, payment_id: str): + """ Renders a modal view for editing payments + + Args: + request (HttpRequest): The incoming request + id (str): The intervention's id + payment_id (str): The payment's id + + Returns: + + """ + intervention = get_object_or_404(Intervention, id=id) + payment = get_object_or_404(Payment, id=payment_id) + form = EditPaymentModalForm(request.POST or None, instance=intervention, payment=payment, request=request) + return form.process_request( + request=request, + msg_success=PAYMENT_EDITED, + redirect_url=reverse("intervention:detail", args=(payment.intervention_id,)) + "#related_data" + ) + diff --git a/intervention/templates/intervention/detail/includes/payments.html b/intervention/templates/intervention/detail/includes/payments.html index 205755b..4bf00cd 100644 --- a/intervention/templates/intervention/detail/includes/payments.html +++ b/intervention/templates/intervention/detail/includes/payments.html @@ -54,9 +54,12 @@ {{ pay.comment }} - + {% if is_default_member and has_access %} - + {% endif %} diff --git a/konova/forms.py b/konova/forms.py index ca7ac0e..c05eb42 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -87,7 +87,7 @@ class BaseForm(forms.Form): """ self.fields[field].widget.attrs["placeholder"] = val - def load_initial_data(self, form_data: dict, disabled_fields: list): + def load_initial_data(self, form_data: dict, disabled_fields: list = None): """ Initializes form data from instance Inserts instance data into form and disables form fields @@ -99,8 +99,9 @@ class BaseForm(forms.Form): return for k, v in form_data.items(): self.initialize_form_field(k, v) - for field in disabled_fields: - self.disable_form_field(field) + if disabled_fields: + for field in disabled_fields: + self.disable_form_field(field) def add_widget_html_class(self, field: str, cls: str): """ Adds a HTML class string to the widget of a field diff --git a/konova/utils/message_templates.py b/konova/utils/message_templates.py index 87c22af..b7eb525 100644 --- a/konova/utils/message_templates.py +++ b/konova/utils/message_templates.py @@ -46,6 +46,7 @@ DEADLINE_REMOVED = _("Deadline removed") # PAYMENTS PAYMENT_ADDED = _("Payment added") +PAYMENT_EDITED = _("Payment edited") PAYMENT_REMOVED = _("Payment removed") # REVOCATIONS diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 74f794d..85b75fd 100644 Binary files a/locale/de/LC_MESSAGES/django.mo and b/locale/de/LC_MESSAGES/django.mo differ diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index b97e841..3feeb6d 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -5,7 +5,7 @@ # #: compensation/filters.py:122 compensation/forms/modalForms.py:35 #: compensation/forms/modalForms.py:46 compensation/forms/modalForms.py:62 -#: compensation/forms/modalForms.py:306 compensation/forms/modalForms.py:399 +#: compensation/forms/modalForms.py:329 compensation/forms/modalForms.py:422 #: intervention/forms/forms.py:54 intervention/forms/forms.py:156 #: intervention/forms/forms.py:168 intervention/forms/modalForms.py:124 #: intervention/forms/modalForms.py:137 intervention/forms/modalForms.py:150 @@ -18,15 +18,15 @@ #: konova/filters/mixins.py:270 konova/filters/mixins.py:315 #: konova/filters/mixins.py:353 konova/filters/mixins.py:354 #: konova/filters/mixins.py:385 konova/filters/mixins.py:386 -#: konova/forms.py:140 konova/forms.py:241 konova/forms.py:312 -#: konova/forms.py:356 konova/forms.py:366 konova/forms.py:379 -#: konova/forms.py:391 konova/forms.py:409 user/forms.py:42 +#: konova/forms.py:141 konova/forms.py:242 konova/forms.py:313 +#: konova/forms.py:357 konova/forms.py:367 konova/forms.py:380 +#: konova/forms.py:392 konova/forms.py:410 user/forms.py:42 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-02-08 15:16+0100\n" +"POT-Creation-Date: 2022-02-09 09:50+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -75,7 +75,7 @@ msgstr "Bericht generieren" msgid "Select a timespan and the desired conservation office" msgstr "Wählen Sie die Zeitspanne und die gewünschte Eintragungsstelle" -#: analysis/forms.py:69 konova/forms.py:188 +#: analysis/forms.py:69 konova/forms.py:189 msgid "Continue" msgstr "Weiter" @@ -95,7 +95,7 @@ msgstr "" #: analysis/templates/analysis/reports/includes/eco_account/amount.html:3 #: analysis/templates/analysis/reports/includes/intervention/amount.html:3 #: analysis/templates/analysis/reports/includes/old_data/amount.html:3 -#: compensation/forms/modalForms.py:383 +#: compensation/forms/modalForms.py:406 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:34 #: intervention/templates/intervention/detail/includes/deductions.html:31 msgid "Amount" @@ -152,7 +152,7 @@ msgstr "Geprüft" #: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:9 #: analysis/templates/analysis/reports/includes/intervention/laws.html:20 #: analysis/templates/analysis/reports/includes/old_data/amount.html:18 -#: compensation/tables.py:46 compensation/tables.py:219 +#: compensation/tables.py:46 compensation/tables.py:222 #: compensation/templates/compensation/detail/compensation/view.html:77 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31 #: compensation/templates/compensation/detail/eco_account/view.html:44 @@ -213,7 +213,7 @@ msgstr "Abbuchungen" #: analysis/templates/analysis/reports/includes/eco_account/deductions.html:9 #: analysis/templates/analysis/reports/includes/eco_account/deductions.html:11 -#: compensation/forms/modalForms.py:167 +#: compensation/forms/modalForms.py:190 #: compensation/templates/compensation/detail/compensation/includes/states-after.html:36 #: compensation/templates/compensation/detail/compensation/includes/states-before.html:36 #: compensation/templates/compensation/detail/eco_account/includes/states-after.html:36 @@ -239,7 +239,6 @@ msgstr "Kompensationsart" #: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:15 #: analysis/templates/analysis/reports/includes/old_data/amount.html:29 -#: compensation/tables.py:90 #: compensation/templates/compensation/detail/compensation/view.html:19 #: konova/templates/konova/includes/quickstart/compensations.html:4 #: templates/navbars/navbar.html:28 @@ -284,8 +283,8 @@ msgid "Type" msgstr "Typ" #: analysis/templates/analysis/reports/includes/old_data/amount.html:24 -#: intervention/forms/modalForms.py:322 intervention/forms/modalForms.py:329 -#: intervention/tables.py:88 +#: compensation/tables.py:89 intervention/forms/modalForms.py:322 +#: intervention/forms/modalForms.py:329 intervention/tables.py:88 #: intervention/templates/intervention/detail/view.html:19 #: konova/templates/konova/includes/quickstart/interventions.html:4 #: templates/navbars/navbar.html:22 @@ -293,7 +292,7 @@ msgid "Intervention" msgstr "Eingriff" #: analysis/templates/analysis/reports/includes/old_data/amount.html:34 -#: compensation/tables.py:263 +#: compensation/tables.py:266 #: compensation/templates/compensation/detail/eco_account/view.html:19 #: intervention/forms/modalForms.py:295 intervention/forms/modalForms.py:302 #: konova/templates/konova/includes/quickstart/ecoaccounts.html:4 @@ -314,7 +313,7 @@ msgid "Show only unrecorded" msgstr "Nur unverzeichnete anzeigen" #: compensation/forms/forms.py:32 compensation/tables.py:25 -#: compensation/tables.py:194 ema/tables.py:29 intervention/forms/forms.py:28 +#: compensation/tables.py:197 ema/tables.py:29 intervention/forms/forms.py:28 #: intervention/tables.py:24 #: intervention/templates/intervention/detail/includes/compensations.html:30 msgid "Identifier" @@ -326,7 +325,7 @@ msgid "Generated automatically" msgstr "Automatisch generiert" #: compensation/forms/forms.py:44 compensation/tables.py:30 -#: compensation/tables.py:199 +#: compensation/tables.py:202 #: compensation/templates/compensation/detail/compensation/includes/documents.html:28 #: compensation/templates/compensation/detail/compensation/view.html:31 #: compensation/templates/compensation/detail/eco_account/includes/documents.html:28 @@ -341,7 +340,7 @@ msgstr "Automatisch generiert" #: intervention/templates/intervention/detail/includes/documents.html:28 #: intervention/templates/intervention/detail/view.html:31 #: intervention/templates/intervention/report/report.html:12 -#: konova/forms.py:355 +#: konova/forms.py:356 msgid "Title" msgstr "Bezeichnung" @@ -354,7 +353,7 @@ msgid "Compensation XY; Location ABC" msgstr "Kompensation XY; Flur ABC" #: compensation/forms/forms.py:57 compensation/forms/modalForms.py:61 -#: compensation/forms/modalForms.py:305 compensation/forms/modalForms.py:398 +#: compensation/forms/modalForms.py:328 compensation/forms/modalForms.py:421 #: compensation/templates/compensation/detail/compensation/includes/actions.html:35 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34 #: compensation/templates/compensation/detail/compensation/includes/documents.html:31 @@ -368,11 +367,11 @@ msgstr "Kompensation XY; Flur ABC" #: intervention/templates/intervention/detail/includes/documents.html:31 #: intervention/templates/intervention/detail/includes/payments.html:34 #: intervention/templates/intervention/detail/includes/revocation.html:38 -#: konova/forms.py:390 konova/templates/konova/includes/comment_card.html:16 +#: konova/forms.py:391 konova/templates/konova/includes/comment_card.html:16 msgid "Comment" msgstr "Kommentar" -#: compensation/forms/forms.py:59 compensation/forms/modalForms.py:400 +#: compensation/forms/forms.py:59 compensation/forms/modalForms.py:423 #: intervention/forms/forms.py:182 msgid "Additional comment" msgstr "Zusätzlicher Kommentar" @@ -483,8 +482,8 @@ msgstr "Fällig am" msgid "Due on which date" msgstr "Zahlung wird an diesem Datum erwartet" -#: compensation/forms/modalForms.py:63 compensation/forms/modalForms.py:307 -#: intervention/forms/modalForms.py:151 konova/forms.py:392 +#: compensation/forms/modalForms.py:63 compensation/forms/modalForms.py:330 +#: intervention/forms/modalForms.py:151 konova/forms.py:393 msgid "Additional comment, maximum {} letters" msgstr "Zusätzlicher Kommentar, maximal {} Zeichen" @@ -496,47 +495,47 @@ msgstr "Neue Ersatzzahlung zu Eingriff '{}' hinzufügen" msgid "If there is no date you can enter, please explain why." msgstr "Falls Sie kein Datum angeben können, erklären Sie bitte weshalb." -#: compensation/forms/modalForms.py:131 compensation/forms/modalForms.py:143 +#: compensation/forms/modalForms.py:154 compensation/forms/modalForms.py:166 msgid "Biotope Type" msgstr "Biotoptyp" -#: compensation/forms/modalForms.py:134 +#: compensation/forms/modalForms.py:157 msgid "Select the biotope type" msgstr "Biotoptyp wählen" -#: compensation/forms/modalForms.py:148 compensation/forms/modalForms.py:160 +#: compensation/forms/modalForms.py:171 compensation/forms/modalForms.py:183 msgid "Biotope additional type" msgstr "Zusatzbezeichnung" -#: compensation/forms/modalForms.py:151 +#: compensation/forms/modalForms.py:174 msgid "Select an additional biotope type" msgstr "Zusatzbezeichnung wählen" -#: compensation/forms/modalForms.py:170 intervention/forms/modalForms.py:313 +#: compensation/forms/modalForms.py:193 intervention/forms/modalForms.py:313 msgid "in m²" msgstr "" -#: compensation/forms/modalForms.py:181 +#: compensation/forms/modalForms.py:204 msgid "New state" msgstr "Neuer Zustand" -#: compensation/forms/modalForms.py:182 +#: compensation/forms/modalForms.py:205 msgid "Insert data for the new state" msgstr "Geben Sie die Daten des neuen Zustandes ein" -#: compensation/forms/modalForms.py:189 konova/forms.py:190 +#: compensation/forms/modalForms.py:212 konova/forms.py:191 msgid "Object removed" msgstr "Objekt entfernt" -#: compensation/forms/modalForms.py:277 +#: compensation/forms/modalForms.py:300 msgid "Deadline Type" msgstr "Fristart" -#: compensation/forms/modalForms.py:280 +#: compensation/forms/modalForms.py:303 msgid "Select the deadline type" msgstr "Fristart wählen" -#: compensation/forms/modalForms.py:289 +#: compensation/forms/modalForms.py:312 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:31 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:31 #: ema/templates/ema/detail/includes/deadlines.html:31 @@ -544,27 +543,27 @@ msgstr "Fristart wählen" msgid "Date" msgstr "Datum" -#: compensation/forms/modalForms.py:292 +#: compensation/forms/modalForms.py:315 msgid "Select date" msgstr "Datum wählen" -#: compensation/forms/modalForms.py:319 +#: compensation/forms/modalForms.py:342 msgid "New deadline" msgstr "Neue Frist" -#: compensation/forms/modalForms.py:320 +#: compensation/forms/modalForms.py:343 msgid "Insert data for the new deadline" msgstr "Geben Sie die Daten der neuen Frist ein" -#: compensation/forms/modalForms.py:337 +#: compensation/forms/modalForms.py:360 msgid "Action Type" msgstr "Maßnahmentyp" -#: compensation/forms/modalForms.py:340 +#: compensation/forms/modalForms.py:363 msgid "Select the action type" msgstr "Maßnahmentyp wählen" -#: compensation/forms/modalForms.py:349 +#: compensation/forms/modalForms.py:372 #: compensation/templates/compensation/detail/compensation/includes/actions.html:40 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:39 #: compensation/templates/compensation/detail/compensation/includes/documents.html:36 @@ -590,31 +589,31 @@ msgstr "Maßnahmentyp wählen" msgid "Action" msgstr "Aktionen" -#: compensation/forms/modalForms.py:354 compensation/forms/modalForms.py:366 +#: compensation/forms/modalForms.py:377 compensation/forms/modalForms.py:389 msgid "Action Type detail" msgstr "Zusatzmerkmal" -#: compensation/forms/modalForms.py:357 +#: compensation/forms/modalForms.py:380 msgid "Select the action type detail" msgstr "Zusatzmerkmal wählen" -#: compensation/forms/modalForms.py:371 +#: compensation/forms/modalForms.py:394 msgid "Unit" msgstr "Einheit" -#: compensation/forms/modalForms.py:374 +#: compensation/forms/modalForms.py:397 msgid "Select the unit" msgstr "Einheit wählen" -#: compensation/forms/modalForms.py:386 +#: compensation/forms/modalForms.py:409 msgid "Insert the amount" msgstr "Menge eingeben" -#: compensation/forms/modalForms.py:411 +#: compensation/forms/modalForms.py:434 msgid "New action" msgstr "Neue Maßnahme" -#: compensation/forms/modalForms.py:412 +#: compensation/forms/modalForms.py:435 msgid "Insert data for the new action" msgstr "Geben Sie die Daten der neuen Maßnahme ein" @@ -657,35 +656,35 @@ msgstr "" "Es wurde bereits mehr Fläche abgebucht, als Sie nun als abbuchbar einstellen " "wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!" -#: compensation/tables.py:35 compensation/tables.py:204 ema/tables.py:39 +#: compensation/tables.py:35 compensation/tables.py:207 ema/tables.py:39 #: intervention/tables.py:34 konova/filters/mixins.py:98 msgid "Parcel gmrkng" msgstr "Gemarkung" -#: compensation/tables.py:52 compensation/tables.py:225 ema/tables.py:50 +#: compensation/tables.py:52 compensation/tables.py:228 ema/tables.py:50 #: intervention/tables.py:51 msgid "Editable" msgstr "Freigegeben" -#: compensation/tables.py:58 compensation/tables.py:231 ema/tables.py:56 +#: compensation/tables.py:58 compensation/tables.py:234 ema/tables.py:56 #: intervention/tables.py:57 msgid "Last edit" msgstr "Zuletzt bearbeitet" -#: compensation/tables.py:90 compensation/tables.py:263 ema/tables.py:89 +#: compensation/tables.py:89 compensation/tables.py:266 ema/tables.py:89 #: intervention/tables.py:88 msgid "Open {}" msgstr "Öffne {}" -#: compensation/tables.py:111 intervention/tables.py:111 +#: compensation/tables.py:114 intervention/tables.py:111 msgid "Not checked yet" msgstr "Noch nicht geprüft" -#: compensation/tables.py:116 intervention/tables.py:116 +#: compensation/tables.py:119 intervention/tables.py:116 msgid "Checked on {} by {}" msgstr "Am {} von {} geprüft worden" -#: compensation/tables.py:157 +#: compensation/tables.py:160 #: compensation/templates/compensation/detail/compensation/view.html:80 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:58 #: compensation/templates/compensation/detail/eco_account/view.html:47 @@ -695,32 +694,32 @@ msgstr "Am {} von {} geprüft worden" msgid "Not recorded yet" msgstr "Noch nicht verzeichnet" -#: compensation/tables.py:162 compensation/tables.py:323 ema/tables.py:136 +#: compensation/tables.py:165 compensation/tables.py:326 ema/tables.py:136 #: intervention/tables.py:162 msgid "Recorded on {} by {}" msgstr "Am {} von {} verzeichnet worden" -#: compensation/tables.py:186 compensation/tables.py:345 ema/tables.py:159 +#: compensation/tables.py:189 compensation/tables.py:348 ema/tables.py:159 #: intervention/tables.py:185 msgid "Full access granted" msgstr "Für Sie freigegeben - Datensatz kann bearbeitet werden" -#: compensation/tables.py:186 compensation/tables.py:345 ema/tables.py:159 +#: compensation/tables.py:189 compensation/tables.py:348 ema/tables.py:159 #: intervention/tables.py:185 msgid "Access not granted" msgstr "Nicht freigegeben - Datensatz nur lesbar" -#: compensation/tables.py:209 +#: compensation/tables.py:212 #: compensation/templates/compensation/detail/eco_account/view.html:35 #: konova/templates/konova/widgets/progressbar.html:3 msgid "Available" msgstr "Verfügbar" -#: compensation/tables.py:240 +#: compensation/tables.py:243 msgid "Eco Accounts" msgstr "Ökokonten" -#: compensation/tables.py:318 +#: compensation/tables.py:321 msgid "Not recorded yet. Can not be used for deductions, yet." msgstr "" "Noch nicht verzeichnet. Kann noch nicht für Abbuchungen genutzt werden." @@ -822,7 +821,7 @@ msgstr "Dokumente" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:14 #: ema/templates/ema/detail/includes/documents.html:14 #: intervention/templates/intervention/detail/includes/documents.html:14 -#: konova/forms.py:408 +#: konova/forms.py:409 msgid "Add new document" msgstr "Neues Dokument hinzufügen" @@ -1086,17 +1085,17 @@ msgid "Compensation {} edited" msgstr "Kompensation {} bearbeitet" #: compensation/views/compensation.py:159 compensation/views/eco_account.py:161 -#: ema/views.py:230 intervention/views.py:313 +#: ema/views.py:230 intervention/views.py:305 msgid "Edit {}" msgstr "Bearbeite {}" #: compensation/views/compensation.py:238 compensation/views/eco_account.py:317 -#: ema/views.py:191 intervention/views.py:491 +#: ema/views.py:191 intervention/views.py:483 msgid "Log" msgstr "Log" #: compensation/views/compensation.py:487 compensation/views/eco_account.py:590 -#: ema/views.py:477 intervention/views.py:609 +#: ema/views.py:477 intervention/views.py:601 msgid "Report {}" msgstr "Bericht {}" @@ -1117,32 +1116,32 @@ msgid "Eco-account removed" msgstr "Ökokonto entfernt" #: compensation/views/eco_account.py:338 ema/views.py:272 -#: intervention/views.py:562 +#: intervention/views.py:554 msgid "{} unrecorded" msgstr "{} entzeichnet" #: compensation/views/eco_account.py:338 ema/views.py:272 -#: intervention/views.py:562 +#: intervention/views.py:554 msgid "{} recorded" msgstr "{} verzeichnet" #: compensation/views/eco_account.py:663 ema/views.py:543 -#: intervention/views.py:388 +#: intervention/views.py:380 msgid "{} has already been shared with you" msgstr "{} wurde bereits für Sie freigegeben" #: compensation/views/eco_account.py:668 ema/views.py:548 -#: intervention/views.py:393 +#: intervention/views.py:385 msgid "{} has been shared with you" msgstr "{} ist nun für Sie freigegeben" #: compensation/views/eco_account.py:675 ema/views.py:555 -#: intervention/views.py:400 +#: intervention/views.py:392 msgid "Share link invalid" msgstr "Freigabelink ungültig" #: compensation/views/eco_account.py:698 ema/views.py:578 -#: intervention/views.py:423 +#: intervention/views.py:415 msgid "Share settings updated" msgstr "Freigabe Einstellungen aktualisiert" @@ -1314,7 +1313,7 @@ msgstr "Kompensationen und Zahlungen geprüft" msgid "Run check" msgstr "Prüfung vornehmen" -#: intervention/forms/modalForms.py:213 konova/forms.py:474 +#: intervention/forms/modalForms.py:213 konova/forms.py:475 msgid "" "I, {} {}, confirm that all necessary control steps have been performed by " "myself." @@ -1389,6 +1388,10 @@ msgid "Amount" msgstr "Betrag" #: intervention/templates/intervention/detail/includes/payments.html:59 +msgid "Edit payment" +msgstr "Zahlung bearbeitet" + +#: intervention/templates/intervention/detail/includes/payments.html:62 msgid "Remove payment" msgstr "Zahlung entfernen" @@ -1449,23 +1452,19 @@ msgstr "Eingriffe - Übersicht" msgid "Intervention {} added" msgstr "Eingriff {} hinzugefügt" -#: intervention/views.py:252 -msgid "This intervention has {} revocations" -msgstr "Dem Eingriff liegen {} Widersprüche vor" - -#: intervention/views.py:301 +#: intervention/views.py:293 msgid "Intervention {} edited" msgstr "Eingriff {} bearbeitet" -#: intervention/views.py:337 +#: intervention/views.py:329 msgid "{} removed" msgstr "{} entfernt" -#: intervention/views.py:444 +#: intervention/views.py:436 msgid "Check performed" msgstr "Prüfung durchgeführt" -#: intervention/views.py:567 +#: intervention/views.py:559 msgid "There are errors on this intervention:" msgstr "Es liegen Fehler in diesem Eingriff vor:" @@ -1557,73 +1556,73 @@ msgstr "Speichern" msgid "Not editable" msgstr "Nicht editierbar" -#: konova/forms.py:139 konova/forms.py:311 +#: konova/forms.py:140 konova/forms.py:312 msgid "Confirm" msgstr "Bestätige" -#: konova/forms.py:151 konova/forms.py:320 +#: konova/forms.py:152 konova/forms.py:321 msgid "Remove" msgstr "Löschen" -#: konova/forms.py:153 +#: konova/forms.py:154 msgid "You are about to remove {} {}" msgstr "Sie sind dabei {} {} zu löschen" -#: konova/forms.py:240 konova/utils/quality.py:44 konova/utils/quality.py:46 +#: konova/forms.py:241 konova/utils/quality.py:44 konova/utils/quality.py:46 #: templates/form/collapsable/form.html:45 msgid "Geometry" msgstr "Geometrie" -#: konova/forms.py:321 +#: konova/forms.py:322 msgid "Are you sure?" msgstr "Sind Sie sicher?" -#: konova/forms.py:365 +#: konova/forms.py:366 msgid "Created on" msgstr "Erstellt" -#: konova/forms.py:367 +#: konova/forms.py:368 msgid "When has this file been created? Important for photos." msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?" -#: konova/forms.py:378 +#: konova/forms.py:379 #: venv/lib/python3.7/site-packages/django/db/models/fields/files.py:231 msgid "File" msgstr "Datei" -#: konova/forms.py:380 +#: konova/forms.py:381 msgid "Allowed formats: pdf, jpg, png. Max size 15 MB." msgstr "Formate: pdf, jpg, png. Maximal 15 MB." -#: konova/forms.py:426 +#: konova/forms.py:427 msgid "Unsupported file type" msgstr "Dateiformat nicht unterstützt" -#: konova/forms.py:433 +#: konova/forms.py:434 msgid "File too large" msgstr "Datei zu groß" -#: konova/forms.py:442 +#: konova/forms.py:443 msgid "Added document" msgstr "Dokument hinzugefügt" -#: konova/forms.py:465 +#: konova/forms.py:466 msgid "Confirm record" msgstr "Verzeichnen bestätigen" -#: konova/forms.py:473 +#: konova/forms.py:474 msgid "Record data" msgstr "Daten verzeichnen" -#: konova/forms.py:480 +#: konova/forms.py:481 msgid "Confirm unrecord" msgstr "Entzeichnen bestätigen" -#: konova/forms.py:481 +#: konova/forms.py:482 msgid "Unrecord data" msgstr "Daten entzeichnen" -#: konova/forms.py:482 +#: konova/forms.py:483 msgid "I, {} {}, confirm that this data must be unrecorded." msgstr "" "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." @@ -1857,37 +1856,45 @@ msgid "Payment added" msgstr "Zahlung hinzugefügt" #: konova/utils/message_templates.py:49 +msgid "Payment edited" +msgstr "Zahlung bearbeitet" + +#: konova/utils/message_templates.py:50 msgid "Payment removed" msgstr "Zahlung gelöscht" -#: konova/utils/message_templates.py:52 +#: konova/utils/message_templates.py:53 msgid "Revocation added" msgstr "Widerspruch hinzugefügt" -#: konova/utils/message_templates.py:53 +#: konova/utils/message_templates.py:54 msgid "Revocation removed" msgstr "Widerspruch entfernt" -#: konova/utils/message_templates.py:56 +#: konova/utils/message_templates.py:57 msgid "Document '{}' deleted" msgstr "Dokument '{}' gelöscht" -#: konova/utils/message_templates.py:57 +#: konova/utils/message_templates.py:58 msgid "Document added" msgstr "Dokument hinzugefügt" -#: konova/utils/message_templates.py:60 +#: konova/utils/message_templates.py:61 msgid "Edited general data" msgstr "Allgemeine Daten bearbeitet" -#: konova/utils/message_templates.py:61 +#: konova/utils/message_templates.py:62 msgid "Added deadline" msgstr "Frist/Termin hinzugefügt" -#: konova/utils/message_templates.py:64 +#: konova/utils/message_templates.py:65 msgid "Geometry conflict detected with {}" msgstr "Geometriekonflikt mit folgenden Einträgen erkannt: {}" +#: konova/utils/message_templates.py:68 +msgid "This intervention has {} revocations" +msgstr "Dem Eingriff liegen {} Widersprüche vor" + #: konova/utils/messenger.py:70 msgid "{} checked" msgstr "{} geprüft" @@ -3942,9 +3949,6 @@ msgstr "" #~ msgid "No file given!" #~ msgstr "Keine Datei angegeben!" -#~ msgid "Added payment" -#~ msgstr "Zahlung hinzufügen" - #~ msgid "Added state" #~ msgstr "Zustand hinzugefügt"