Merge pull request 'master' (#221) from master into Docker

Reviewed-on: SGD-Nord/konova#221
This commit is contained in:
mpeltriaux 2022-10-12 09:02:49 +02:00
commit 63a308b6cb
18 changed files with 166 additions and 70 deletions

View File

@ -14,6 +14,7 @@ from compensation.forms.mixins import CompensationResponsibleFormMixin, PikCompe
from compensation.models import EcoAccount
from intervention.models import Handler, Responsibility, Legal
from konova.forms import SimpleGeomForm
from konova.forms.modals import RemoveModalForm
from user.models import User, UserActionLogEntry
@ -127,6 +128,8 @@ class NewEcoAccountForm(AbstractCompensationForm, CompensationResponsibleFormMix
# Add the log entry to the main objects log list
acc.log.add(action)
acc.update_deductable_rest()
return acc
@ -209,4 +212,19 @@ class EditEcoAccountForm(NewEcoAccountForm):
# Add the log entry to the main objects log list
self.instance.log.add(action)
self.instance.update_deductable_rest()
return self.instance
class RemoveEcoAccountModalForm(RemoveModalForm):
def is_valid(self):
super_valid = super().is_valid()
has_deductions = self.instance.deductions.exists()
if has_deductions:
self.add_error(
"confirm",
_("The account can not be removed, since there are still deductions.")
)
return super_valid and not has_deductions

View File

@ -74,6 +74,10 @@
{% endif %}
</td>
</tr>
{% empty %}
<div class="alert alert-danger mb-0">
{% trans 'Missing' %}
</div>
{% endfor %}
</tbody>
</table>

View File

@ -68,6 +68,10 @@
{% endif %}
</td>
</tr>
{% empty %}
<div class="alert alert-danger mb-0">
{% trans 'Missing' %}
</div>
{% endfor %}
</tbody>
</table>

View File

@ -68,6 +68,10 @@
{% endif %}
</td>
</tr>
{% empty %}
<div class="alert alert-danger mb-0">
{% trans 'Missing' %}
</div>
{% endfor %}
</tbody>
</table>

View File

@ -73,6 +73,10 @@
{% endif %}
</td>
</tr>
{% empty %}
<div class="alert alert-danger mb-0">
{% trans 'Missing' %}
</div>
{% endfor %}
</tbody>
</table>

View File

@ -68,6 +68,10 @@
{% endif %}
</td>
</tr>
{% empty %}
<div class="alert alert-danger mb-0">
{% trans 'Missing' %}
</div>
{% endfor %}
</tbody>
</table>

View File

@ -68,6 +68,10 @@
{% endif %}
</td>
</tr>
{% empty %}
<div class="alert alert-danger mb-0">
{% trans 'Missing' %}
</div>
{% endfor %}
</tbody>
</table>

View File

@ -47,7 +47,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
"identifier": test_id,
"title": test_title,
"geom": geom_json,
"deductable_surface": test_deductable_surface,
"surface": test_deductable_surface,
"conservation_office": test_conservation_office.id
}
self.client_user.post(new_url, post_data)
@ -61,6 +61,8 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
self.assertEqual(acc.identifier, test_id)
self.assertEqual(acc.title, test_title)
self.assertEqual(acc.deductable_surface, test_deductable_surface)
self.assertEqual(acc.deductable_rest, test_deductable_surface)
self.assert_equal_geometries(acc.geometry.geom, test_geom)
self.assertEqual(acc.log.count(), 1)
@ -84,7 +86,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
new_comment = self.create_dummy_string()
new_geometry = MultiPolygon(srid=4326) # Create an empty geometry
test_conservation_office = self.get_conservation_office_code()
test_deductable_surface = 10005
test_deductable_surface = self.eco_account.deductable_surface + 100
check_on_elements = {
self.eco_account.title: new_title,
@ -110,6 +112,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
self.eco_account.title: new_title,
self.eco_account.identifier: new_identifier,
self.eco_account.deductable_surface: test_deductable_surface,
self.eco_account.deductable_rest: test_deductable_surface,
self.eco_account.comment: new_comment,
}
@ -194,14 +197,14 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
# Perform request --> expect to fail
self.client_user.post(deduct_url, post_data)
# Expect that no deduction has been created
# Expect that no deduction has been created since the eco account is not recorded, yet
self.assertEqual(0, self.eco_account.deductions.count())
self.assertEqual(0, self.intervention.deductions.count())
self.assertEqual(pre_deduction_acc_log_count, 0)
self.assertEqual(pre_deduction_int_log_count, 0)
# Now mock the eco account as it would be recorded (with invalid data)
# Make sure the deductible surface is high enough for the request
# Make sure the deductible surface is valid for the request
self.eco_account.set_recorded(self.superuser)
self.eco_account.refresh_from_db()
self.eco_account.deductable_surface = test_surface + 1.00
@ -216,10 +219,12 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
self.client_user.post(deduct_url, post_data)
# Expect that the deduction has been created
self.eco_account.refresh_from_db()
self.assertEqual(1, self.eco_account.deductions.count())
self.assertEqual(1, self.intervention.deductions.count())
deduction = self.eco_account.deductions.first()
self.assertEqual(deduction.surface, test_surface)
self.assertEqual(self.eco_account.deductable_rest, self.eco_account.deductable_surface - deduction.surface)
self.assertEqual(deduction.account, self.eco_account)
self.assertEqual(deduction.intervention, self.intervention)
@ -262,6 +267,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
self.eco_account.refresh_from_db()
deduction.refresh_from_db()
self.assertEqual(self.eco_account.deductable_rest, self.eco_account.deductable_surface - deduction.surface)
self.assertEqual(num_deductions_intervention, self.intervention.deductions.count())
self.assertEqual(num_deductions_account, self.eco_account.deductions.count())
self.assertEqual(deduction.surface, test_surface)
@ -275,6 +281,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
def test_remove_deduction(self):
intervention = self.deduction.intervention
account = self.deduction.account
deducted_surface = self.deduction.surface
# Prepare url and form data to be posted
new_url = reverse("compensation:acc:remove-deduction", args=(account.id, self.deduction.id))
@ -287,6 +294,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
pre_edit_intervention_log_count = intervention.log.count()
pre_edit_account_log_count = account.log.count()
pre_edit_account_rest = account.deductable_rest
num_deductions_intervention = intervention.deductions.count()
num_deductions_account = account.deductions.count()
@ -297,6 +305,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
self.assertEqual(num_deductions_intervention - 1, intervention.deductions.count())
self.assertEqual(num_deductions_account - 1, account.deductions.count())
self.assertEqual(account.deductable_rest, pre_edit_account_rest + deducted_surface)
# Expect logs to be set
self.assertEqual(pre_edit_intervention_log_count + 1, intervention.log.count())

View File

@ -13,13 +13,12 @@ from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from compensation.forms.eco_account import EditEcoAccountForm, NewEcoAccountForm
from compensation.forms.eco_account import EditEcoAccountForm, NewEcoAccountForm, RemoveEcoAccountModalForm
from compensation.models import EcoAccount
from compensation.tables.eco_account import EcoAccountTable
from konova.contexts import BaseContext
from konova.decorators import shared_access_required, default_group_required, any_group_check, login_required_modal
from konova.forms import SimpleGeomForm
from konova.forms.modals import RemoveModalForm
from konova.settings import ETS_GROUP, DEFAULT_GROUP, ZB_GROUP
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import CANCEL_ACC_RECORDED_OR_DEDUCTED, RECORDED_BLOCKS_EDIT, FORM_INVALID, \
@ -260,7 +259,7 @@ def remove_view(request: HttpRequest, id: str):
messages.info(request, CANCEL_ACC_RECORDED_OR_DEDUCTED)
return redirect("compensation:acc:detail", id=id)
form = RemoveModalForm(request.POST or None, instance=acc, request=request)
form = RemoveEcoAccountModalForm(request.POST or None, instance=acc, request=request)
return form.process_request(
request=request,
msg_success=_("Eco-account removed"),

View File

@ -71,6 +71,10 @@
{% endif %}
</td>
</tr>
{% empty %}
<div class="alert alert-danger mb-0">
{% trans 'Missing' %}
</div>
{% endfor %}
</tbody>
</table>

View File

@ -66,6 +66,10 @@
{% endif %}
</td>
</tr>
{% empty %}
<div class="alert alert-danger mb-0">
{% trans 'Missing' %}
</div>
{% endfor %}
</tbody>
</table>

View File

@ -66,6 +66,10 @@
{% endif %}
</td>
</tr>
{% empty %}
<div class="alert alert-danger mb-0">
{% trans 'Missing' %}
</div>
{% endfor %}
</tbody>
</table>

View File

@ -163,6 +163,10 @@ class NewEcoAccountDeductionModalForm(BaseModalForm):
self.cleaned_data["account"].mark_as_edited(self.user, edit_comment=DEDUCTION_ADDED)
return deduction
def check_for_recorded_instance(self):
# Ignore super() implementation
return
class EditEcoAccountDeductionModalForm(NewEcoAccountDeductionModalForm):
deduction = None
@ -231,6 +235,16 @@ class EditEcoAccountDeductionModalForm(NewEcoAccountDeductionModalForm):
old_account.send_notification_mail_on_deduction_change(data_changes)
return deduction
def check_for_recorded_instance(self):
"""
Extension to super class base method
Returns:
"""
if self.deduction.intervention.is_recorded:
self.block_form()
class RemoveEcoAccountDeductionModalForm(RemoveModalForm):
""" Removing modal form for EcoAccountDeduction
@ -249,4 +263,8 @@ class RemoveEcoAccountDeductionModalForm(RemoveModalForm):
with transaction.atomic():
self.deduction.intervention.mark_as_edited(self.user, edit_comment=DEDUCTION_REMOVED)
self.deduction.account.mark_as_edited(self.user, edit_comment=DEDUCTION_REMOVED)
self.deduction.delete()
self.deduction.delete()
def check_for_recorded_instance(self):
if self.deduction.intervention.is_recorded:
self.block_form()

View File

@ -134,24 +134,21 @@ class BaseForm(forms.Form):
Returns:
"""
from intervention.forms.modals.deduction import NewEcoAccountDeductionModalForm, EditEcoAccountDeductionModalForm, \
RemoveEcoAccountDeductionModalForm
from konova.forms.modals.resubmission_form import ResubmissionModalForm
is_none = self.instance is None
is_other_data_type = not isinstance(self.instance, BaseObject)
is_deduction_form_from_account = isinstance(
self,
(
NewEcoAccountDeductionModalForm,
ResubmissionModalForm,
EditEcoAccountDeductionModalForm,
RemoveEcoAccountDeductionModalForm,
)
) and isinstance(self.instance, EcoAccount)
if is_none or is_other_data_type or is_deduction_form_from_account:
if is_none or is_other_data_type:
# Do nothing
return
if self.instance.is_recorded:
self.template = "form/recorded_no_edit.html"
self.block_form()
def block_form(self):
"""
Overwrites template, providing no actions
Returns:
"""
self.template = "form/recorded_no_edit.html"

View File

@ -83,3 +83,6 @@ class ResubmissionModalForm(BaseModalForm):
self.instance.resubmissions.add(self.resubmission)
return self.resubmission
def check_for_recorded_instance(self):
# Ignore logic in super() implementation
return

View File

@ -187,6 +187,7 @@ class BaseTestCase(TestCase):
eco_account = EcoAccount.objects.create(
identifier="TEST",
title="Test_title",
deductable_surface=500,
legal=lega_data,
responsible=responsible_data,
created=action,

Binary file not shown.

View File

@ -43,7 +43,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-08-25 10:57+0200\n"
"POT-Creation-Date: 2022-10-11 16:39+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -446,37 +446,41 @@ msgstr "Neue Kompensation"
msgid "Edit compensation"
msgstr "Bearbeite Kompensation"
#: compensation/forms/eco_account.py:29 compensation/utils/quality.py:95
#: compensation/forms/eco_account.py:30 compensation/utils/quality.py:95
msgid "Available Surface"
msgstr "Verfügbare Fläche"
#: compensation/forms/eco_account.py:32
#: compensation/forms/eco_account.py:33
msgid "The amount that can be used for deductions"
msgstr "Die für Abbuchungen zur Verfügung stehende Menge"
#: compensation/forms/eco_account.py:41
#: compensation/forms/eco_account.py:42
#: compensation/templates/compensation/detail/eco_account/view.html:67
#: compensation/utils/quality.py:83
msgid "Agreement date"
msgstr "Vereinbarungsdatum"
#: compensation/forms/eco_account.py:43
#: compensation/forms/eco_account.py:44
msgid "When did the parties agree on this?"
msgstr "Wann wurde dieses Ökokonto offiziell vereinbart?"
#: compensation/forms/eco_account.py:69
#: compensation/forms/eco_account.py:70
#: compensation/views/eco_account/eco_account.py:94
msgid "New Eco-Account"
msgstr "Neues Ökokonto"
#: compensation/forms/eco_account.py:78
#: compensation/forms/eco_account.py:79
msgid "Eco-Account XY; Location ABC"
msgstr "Ökokonto XY; Flur ABC"
#: compensation/forms/eco_account.py:140
#: compensation/forms/eco_account.py:141
msgid "Edit Eco-Account"
msgstr "Ökokonto bearbeiten"
#: compensation/forms/eco_account.py:224
msgid "The account can not be removed, since there are still deductions."
msgstr "Das Ökokonto kann nicht entfernt werden, da hierzu noch Abbuchungen vorliegen."
#: compensation/forms/mixins.py:37
#: compensation/templates/compensation/detail/eco_account/view.html:63
#: compensation/templates/compensation/report/eco_account/report.html:20
@ -734,14 +738,14 @@ msgstr ""
msgid "Pieces"
msgstr "Stück"
#: compensation/models/eco_account.py:56
#: compensation/models/eco_account.py:62
msgid ""
"Deductable surface can not be larger than existing surfaces in after states"
msgstr ""
"Die abbuchbare Fläche darf die Gesamtfläche der Zielzustände nicht "
"überschreiten"
#: compensation/models/eco_account.py:63
#: compensation/models/eco_account.py:69
msgid ""
"Deductable surface can not be smaller than the sum of already existing "
"deductions. Please contact the responsible users for the deductions!"
@ -781,19 +785,19 @@ msgid "Not recorded yet"
msgstr "Noch nicht verzeichnet"
#: compensation/tables/compensation.py:166
#: compensation/tables/eco_account.py:150 ema/tables.py:133
#: compensation/tables/eco_account.py:153 ema/tables.py:133
#: intervention/tables.py:164
msgid "Recorded on {} by {}"
msgstr "Am {} von {} verzeichnet worden"
#: compensation/tables/compensation.py:186
#: compensation/tables/eco_account.py:172 ema/tables.py:154
#: compensation/tables/eco_account.py:175 ema/tables.py:154
#: intervention/tables.py:185
msgid "Full access granted"
msgstr "Für Sie freigegeben - Datensatz kann bearbeitet werden"
#: compensation/tables/compensation.py:186
#: compensation/tables/eco_account.py:172 ema/tables.py:154
#: compensation/tables/eco_account.py:175 ema/tables.py:154
#: intervention/tables.py:185
msgid "Access not granted"
msgstr "Nicht freigegeben - Datensatz nur lesbar"
@ -808,7 +812,7 @@ msgstr "Verfügbar"
msgid "Eco Accounts"
msgstr "Ökokonten"
#: compensation/tables/eco_account.py:147
#: compensation/tables/eco_account.py:150
msgid "Not recorded yet. Can not be used for deductions, yet."
msgstr ""
"Noch nicht verzeichnet. Kann noch nicht für Abbuchungen genutzt werden."
@ -876,6 +880,34 @@ msgstr "Keine Zusatzmerkmale"
msgid "Remove action"
msgstr "Maßnahme entfernen"
#: compensation/templates/compensation/detail/compensation/includes/actions.html:79
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:73
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:73
#: compensation/templates/compensation/detail/eco_account/includes/actions.html:78
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:73
#: compensation/templates/compensation/detail/eco_account/includes/states-before.html:73
#: compensation/templates/compensation/detail/eco_account/view.html:58
#: compensation/templates/compensation/detail/eco_account/view.html:62
#: compensation/templates/compensation/detail/eco_account/view.html:66
#: compensation/templates/compensation/detail/eco_account/view.html:70
#: ema/templates/ema/detail/includes/actions.html:76
#: ema/templates/ema/detail/includes/states-after.html:71
#: ema/templates/ema/detail/includes/states-before.html:71
#: ema/templates/ema/detail/view.html:48 ema/templates/ema/detail/view.html:52
#: ema/templates/ema/detail/view.html:56
#: intervention/templates/intervention/detail/view.html:30
#: intervention/templates/intervention/detail/view.html:34
#: intervention/templates/intervention/detail/view.html:38
#: intervention/templates/intervention/detail/view.html:47
#: intervention/templates/intervention/detail/view.html:51
#: intervention/templates/intervention/detail/view.html:55
#: intervention/templates/intervention/detail/view.html:59
#: intervention/templates/intervention/detail/view.html:63
#: intervention/templates/intervention/detail/view.html:100
#: intervention/templates/intervention/detail/view.html:104
msgid "Missing"
msgstr "Fehlend"
#: compensation/templates/compensation/detail/compensation/includes/controls.html:5
#: compensation/templates/compensation/detail/eco_account/includes/controls.html:5
#: ema/templates/ema/detail/includes/controls.html:5
@ -1186,7 +1218,7 @@ msgid "Recorded on"
msgstr "Verzeichnet am"
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:65
#: intervention/forms/modals/deduction.py:173
#: intervention/forms/modals/deduction.py:177
#: intervention/templates/intervention/detail/includes/deductions.html:60
msgid "Edit Deduction"
msgstr "Abbuchung bearbeiten"
@ -1200,25 +1232,6 @@ msgstr "Abbuchung entfernen"
msgid "No surface deductable"
msgstr "Keine Flächenmenge für Abbuchungen eingegeben. Bitte bearbeiten."
#: compensation/templates/compensation/detail/eco_account/view.html:58
#: compensation/templates/compensation/detail/eco_account/view.html:62
#: compensation/templates/compensation/detail/eco_account/view.html:66
#: compensation/templates/compensation/detail/eco_account/view.html:70
#: ema/templates/ema/detail/view.html:48 ema/templates/ema/detail/view.html:52
#: ema/templates/ema/detail/view.html:56
#: intervention/templates/intervention/detail/view.html:30
#: intervention/templates/intervention/detail/view.html:34
#: intervention/templates/intervention/detail/view.html:38
#: intervention/templates/intervention/detail/view.html:47
#: intervention/templates/intervention/detail/view.html:51
#: intervention/templates/intervention/detail/view.html:55
#: intervention/templates/intervention/detail/view.html:59
#: intervention/templates/intervention/detail/view.html:63
#: intervention/templates/intervention/detail/view.html:100
#: intervention/templates/intervention/detail/view.html:104
msgid "Missing"
msgstr "fehlt"
#: compensation/templates/compensation/detail/eco_account/view.html:71
#: ema/templates/ema/detail/view.html:57
msgid "Action handler"
@ -1297,7 +1310,7 @@ msgstr "Ökokonto {} hinzugefügt"
msgid "Eco-Account {} edited"
msgstr "Ökokonto {} bearbeitet"
#: compensation/views/eco_account/eco_account.py:263
#: compensation/views/eco_account/eco_account.py:265
msgid "Eco-account removed"
msgstr "Ökokonto entfernt"
@ -1341,7 +1354,7 @@ msgstr "EMA {} hinzugefügt"
msgid "EMA {} edited"
msgstr "EMA {} bearbeitet"
#: ema/views/ema.py:234
#: ema/views/ema.py:235
msgid "EMA removed"
msgstr "EMA entfernt"
@ -1639,19 +1652,19 @@ msgstr "Eingriff {} hinzugefügt"
msgid "Intervention {} edited"
msgstr "Eingriff {} bearbeitet"
#: intervention/views/intervention.py:249
#: intervention/views/intervention.py:250
msgid "{} removed"
msgstr "{} entfernt"
#: konova/decorators.py:33
#: konova/decorators.py:30
msgid "You need to be staff to perform this action!"
msgstr "Hierfür müssen Sie Mitarbeiter sein!"
#: konova/decorators.py:48
#: konova/decorators.py:45
msgid "You need to be administrator to perform this action!"
msgstr "Hierfür müssen Sie Administrator sein!"
#: konova/decorators.py:66
#: konova/decorators.py:63
msgid ""
"+++ Attention: You are not part of any group. You won't be able to create, "
"edit or do anything. Please contact an administrator. +++"
@ -2210,7 +2223,7 @@ msgstr "{} wurde erfolgreich vom Nutzer {} geprüft! {}"
#: konova/utils/quality.py:32
msgid "missing"
msgstr "fehlt"
msgstr "fehlend"
#: konova/views/home.py:78 templates/navbars/navbar.html:16
msgid "Home"
@ -2663,7 +2676,9 @@ msgstr "Keine Geometrie vorhanden"
#: templates/modal/modal_session_timed_out.html:3
msgid "Your session has timed out. Please reload the page to login."
msgstr "Ihre Sitzung ist aufgrund von Inaktivität abgelaufen. Laden Sie die Seite erneut, um sich wieder einzuloggen."
msgstr ""
"Ihre Sitzung ist aufgrund von Inaktivität abgelaufen. Laden Sie die Seite "
"erneut, um sich wieder einzuloggen."
#: templates/navbars/navbar.html:4
msgid "Kompensationsverzeichnis Service Portal"
@ -2902,7 +2917,7 @@ msgid "Manage teams"
msgstr ""
#: user/templates/user/index.html:61 user/templates/user/team/index.html:19
#: user/views.py:169
#: user/views.py:171
msgid "Teams"
msgstr ""
@ -2974,23 +2989,23 @@ msgstr "Neuer Token generiert. Administratoren sind informiert."
msgid "User API token"
msgstr "API Nutzer Token"
#: user/views.py:180
#: user/views.py:183
msgid "New team added"
msgstr "Neues Team hinzugefügt"
#: user/views.py:194
#: user/views.py:198
msgid "Team edited"
msgstr "Team bearbeitet"
#: user/views.py:208
#: user/views.py:213
msgid "Team removed"
msgstr "Team gelöscht"
#: user/views.py:222
#: user/views.py:228
msgid "You are not a member of this team"
msgstr "Sie sind kein Mitglied dieses Teams"
#: user/views.py:229
#: user/views.py:235
msgid "Left Team"
msgstr "Team verlassen"