# Optimizations and fixes

* drops identifier handling on all edit-forms (identifier editing has been disabled on the frontend for a while now)
* updates test cases
* updates form caption for checking and recording action (less intimidating)
* optimizes district column width
* fixes bug on frontend parcel fetching on detail view
* adds extended tooltip for title column on index tables
* retraslates 'Law' to 'Rechtsgrundlage'
pull/384/head
mpeltriaux 8 months ago
parent d639a4e530
commit 6945b17117

@ -213,7 +213,6 @@ class EditCompensationForm(NewCompensationForm):
action = UserActionLogEntry.get_edited_action(user) action = UserActionLogEntry.get_edited_action(user)
# Fetch data from cleaned POST values # Fetch data from cleaned POST values
identifier = self.cleaned_data.get("identifier", None)
title = self.cleaned_data.get("title", None) title = self.cleaned_data.get("title", None)
intervention = self.cleaned_data.get("intervention", None) intervention = self.cleaned_data.get("intervention", None)
is_cef = self.cleaned_data.get("is_cef", None) is_cef = self.cleaned_data.get("is_cef", None)
@ -221,7 +220,6 @@ class EditCompensationForm(NewCompensationForm):
is_pik = self.cleaned_data.get("is_pik", None) is_pik = self.cleaned_data.get("is_pik", None)
comment = self.cleaned_data.get("comment", None) comment = self.cleaned_data.get("comment", None)
self.instance.identifier = identifier
self.instance.title = title self.instance.title = title
self.instance.intervention = intervention self.instance.intervention = intervention
self.instance.is_cef = is_cef self.instance.is_cef = is_cef

@ -192,7 +192,6 @@ class EditEcoAccountForm(NewEcoAccountForm):
def save(self, user: User, geom_form: SimpleGeomForm): def save(self, user: User, geom_form: SimpleGeomForm):
with transaction.atomic(): with transaction.atomic():
# Fetch data from cleaned POST values # Fetch data from cleaned POST values
identifier = self.cleaned_data.get("identifier", None)
title = self.cleaned_data.get("title", None) title = self.cleaned_data.get("title", None)
registration_date = self.cleaned_data.get("registration_date", None) registration_date = self.cleaned_data.get("registration_date", None)
handler_type = self.cleaned_data.get("handler_type", None) handler_type = self.cleaned_data.get("handler_type", None)
@ -219,7 +218,6 @@ class EditEcoAccountForm(NewEcoAccountForm):
self.instance.legal.save() self.instance.legal.save()
# Update main oject data # Update main oject data
self.instance.identifier = identifier
self.instance.title = title self.instance.title = title
self.instance.deductable_surface = surface self.instance.deductable_surface = surface
self.instance.comment = comment self.instance.comment = comment

@ -315,7 +315,6 @@ class Compensation(AbstractCompensation, CEFMixin, CoherenceMixin, PikMixin):
def get_detail_url_absolute(self): def get_detail_url_absolute(self):
return BASE_URL + self.get_detail_url() return BASE_URL + self.get_detail_url()
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if self.identifier is None or len(self.identifier) == 0: if self.identifier is None or len(self.identifier) == 0:
# Create new identifier is none was given # Create new identifier is none was given

@ -125,10 +125,16 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase):
self.compensation = self.fill_out_compensation(self.compensation) self.compensation = self.fill_out_compensation(self.compensation)
pre_edit_log_count = self.compensation.log.count() pre_edit_log_count = self.compensation.log.count()
self.assertTrue(self.compensation.is_shared_with(self.superuser))
old_identifier = self.compensation.identifier
new_title = self.create_dummy_string() new_title = self.create_dummy_string()
new_identifier = self.create_dummy_string() new_identifier = self.create_dummy_string()
new_comment = self.create_dummy_string() new_comment = self.create_dummy_string()
new_geometry = MultiPolygon(srid=4326) # Create an empty geometry new_geometry = MultiPolygon(
self.compensation.geometry.geom.buffer(10),
srid=self.compensation.geometry.geom.srid
) # Create a geometry which differs from the stored one
geojson = self.create_geojson(new_geometry) geojson = self.create_geojson(new_geometry)
check_on_elements = { check_on_elements = {
@ -151,19 +157,21 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase):
check_on_elements = { check_on_elements = {
self.compensation.title: new_title, self.compensation.title: new_title,
self.compensation.identifier: new_identifier,
self.compensation.comment: new_comment, self.compensation.comment: new_comment,
} }
for k, v in check_on_elements.items(): for k, v in check_on_elements.items():
self.assertEqual(k, v) self.assertEqual(k, v)
self.assert_equal_geometries(self.compensation.geometry.geom, new_geometry) # Expect identifier to not be editable
self.assertEqual(self.compensation.identifier, old_identifier, msg="Identifier was editable!")
# Expect logs to be set # Expect logs to be set
self.assertEqual(pre_edit_log_count + 1, self.compensation.log.count()) self.assertEqual(pre_edit_log_count + 1, self.compensation.log.count())
self.assertEqual(self.compensation.log.first().action, UserAction.EDITED) self.assertEqual(self.compensation.log.first().action, UserAction.EDITED)
self.assert_equal_geometries(self.compensation.geometry.geom, new_geometry)
def test_checkability(self): def test_checkability(self):
""" """
This tests if the checkability of the compensation (which is defined by the linked intervention's checked This tests if the checkability of the compensation (which is defined by the linked intervention's checked

@ -82,6 +82,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
url = reverse("compensation:acc:edit", args=(self.eco_account.id,)) url = reverse("compensation:acc:edit", args=(self.eco_account.id,))
pre_edit_log_count = self.eco_account.log.count() pre_edit_log_count = self.eco_account.log.count()
old_identifier = self.eco_account.identifier
new_title = self.create_dummy_string() new_title = self.create_dummy_string()
new_identifier = self.create_dummy_string() new_identifier = self.create_dummy_string()
new_comment = self.create_dummy_string() new_comment = self.create_dummy_string()
@ -114,7 +115,6 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
check_on_elements = { check_on_elements = {
self.eco_account.title: new_title, self.eco_account.title: new_title,
self.eco_account.identifier: new_identifier,
self.eco_account.deductable_surface: test_deductable_surface, self.eco_account.deductable_surface: test_deductable_surface,
self.eco_account.deductable_rest: test_deductable_surface - deductions_surface, self.eco_account.deductable_rest: test_deductable_surface - deductions_surface,
self.eco_account.comment: new_comment, self.eco_account.comment: new_comment,
@ -123,6 +123,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
for k, v in check_on_elements.items(): for k, v in check_on_elements.items():
self.assertEqual(k, v) self.assertEqual(k, v)
self.assertEqual(self.eco_account.identifier, old_identifier)
self.assert_equal_geometries(self.eco_account.geometry.geom, new_geometry) self.assert_equal_geometries(self.eco_account.geometry.geom, new_geometry)
# Expect logs to be set # Expect logs to be set

@ -133,7 +133,6 @@ class EditEmaForm(NewEmaForm):
def save(self, user: User, geom_form: SimpleGeomForm): def save(self, user: User, geom_form: SimpleGeomForm):
with transaction.atomic(): with transaction.atomic():
# Fetch data from cleaned POST values # Fetch data from cleaned POST values
identifier = self.cleaned_data.get("identifier", None)
title = self.cleaned_data.get("title", None) title = self.cleaned_data.get("title", None)
handler_type = self.cleaned_data.get("handler_type", None) handler_type = self.cleaned_data.get("handler_type", None)
handler_detail = self.cleaned_data.get("handler_detail", None) handler_detail = self.cleaned_data.get("handler_detail", None)
@ -154,7 +153,6 @@ class EditEmaForm(NewEmaForm):
self.instance.responsible.save() self.instance.responsible.save()
# Update main oject data # Update main oject data
self.instance.identifier = identifier
self.instance.title = title self.instance.title = title
self.instance.comment = comment self.instance.comment = comment
self.instance.is_pik = is_pik self.instance.is_pik = is_pik

@ -80,6 +80,7 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase):
self.ema = self.fill_out_ema(self.ema) self.ema = self.fill_out_ema(self.ema)
pre_edit_log_count = self.ema.log.count() pre_edit_log_count = self.ema.log.count()
old_identifier = self.ema.identifier
new_title = self.create_dummy_string() new_title = self.create_dummy_string()
new_identifier = self.create_dummy_string() new_identifier = self.create_dummy_string()
new_comment = self.create_dummy_string() new_comment = self.create_dummy_string()
@ -106,13 +107,13 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase):
check_on_elements = { check_on_elements = {
self.ema.title: new_title, self.ema.title: new_title,
self.ema.identifier: new_identifier,
self.ema.comment: new_comment, self.ema.comment: new_comment,
} }
for k, v in check_on_elements.items(): for k, v in check_on_elements.items():
self.assertEqual(k, v) self.assertEqual(k, v)
self.assertEqual(self.ema.identifier, old_identifier)
self.assert_equal_geometries(self.ema.geometry.geom, new_geometry) self.assert_equal_geometries(self.ema.geometry.geom, new_geometry)
# Expect logs to be set # Expect logs to be set

@ -130,7 +130,7 @@ class EditEmaFormTestCase(BaseTestCase):
self.assertIsNotNone(obj.responsible.handler) self.assertIsNotNone(obj.responsible.handler)
self.assertEqual(obj.responsible.conservation_office, data["conservation_office"]) self.assertEqual(obj.responsible.conservation_office, data["conservation_office"])
self.assertEqual(obj.responsible.conservation_file_number, data["conservation_file_number"]) self.assertEqual(obj.responsible.conservation_file_number, data["conservation_file_number"])
self.assertEqual(obj.identifier, data["identifier"]) self.assertNotEqual(obj.identifier, data["identifier"], msg="Identifier editable via form!")
self.assertEqual(obj.comment, data["comment"]) self.assertEqual(obj.comment, data["comment"])
last_log = obj.log.first() last_log = obj.log.first()

@ -345,7 +345,6 @@ class EditInterventionForm(NewInterventionForm):
""" """
with transaction.atomic(): with transaction.atomic():
identifier = self.cleaned_data.get("identifier", None)
title = self.cleaned_data.get("title", None) title = self.cleaned_data.get("title", None)
process_type = self.cleaned_data.get("type", None) process_type = self.cleaned_data.get("type", None)
laws = self.cleaned_data.get("laws", None) laws = self.cleaned_data.get("laws", None)
@ -379,7 +378,6 @@ class EditInterventionForm(NewInterventionForm):
self.instance.log.add(user_action) self.instance.log.add(user_action)
self.instance.identifier = identifier
self.instance.title = title self.instance.title = title
self.instance.comment = comment self.instance.comment = comment
self.instance.modified = user_action self.instance.modified = user_action

@ -33,7 +33,7 @@ class CheckModalForm(BaseModalForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.form_title = _("Run check") self.form_title = _("Run check")
self.form_caption = _("I, {} {}, confirm that all necessary control steps have been performed by myself.").format(self.user.first_name, self.user.last_name) self.form_caption = _("The necessary control steps have been performed:").format(self.user.first_name, self.user.last_name)
self.valid = False self.valid = False
def _are_deductions_valid(self): def _are_deductions_valid(self):

@ -33,6 +33,11 @@ class InterventionTable(BaseTable, TableRenderMixin, TableOrderMixin):
verbose_name=_("Parcel gmrkng"), verbose_name=_("Parcel gmrkng"),
orderable=False, orderable=False,
accessor="geometry", accessor="geometry",
attrs={
"th": {
"class": "w-25",
}
}
) )
c = tables.Column( c = tables.Column(
verbose_name=_("Checked"), verbose_name=_("Checked"),

@ -39,7 +39,7 @@ def index_view(request: HttpRequest):
""" """
template = "generic_index.html" template = "generic_index.html"
# Filtering by user access is performed in table filter inside of InterventionTableFilter class # Filtering by user access is performed in table filter inside InterventionTableFilter class
interventions = Intervention.objects.filter( interventions = Intervention.objects.filter(
deleted=None, # not deleted deleted=None, # not deleted
).select_related( ).select_related(

@ -27,7 +27,7 @@ class RecordModalForm(BaseModalForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.form_title = _("Record data") self.form_title = _("Record data")
self.form_caption = _("I, {} {}, confirm that all necessary control steps have been performed by myself.").format(self.user.first_name, self.user.last_name) self.form_caption = _("The necessary control steps have been performed:").format(self.user.first_name, self.user.last_name)
# Disable automatic w-100 setting for this type of modal form. Looks kinda strange # Disable automatic w-100 setting for this type of modal form. Looks kinda strange
self.fields["confirm"].widget.attrs["class"] = "" self.fields["confirm"].widget.attrs["class"] = ""

@ -370,6 +370,9 @@ class Geometry(BaseResource):
Returns: Returns:
complexity_factor (float): The estimated complexity complexity_factor (float): The estimated complexity
""" """
if self.geom.empty:
return 0
geom_envelope = self.geom.envelope geom_envelope = self.geom.envelope
diff = geom_envelope - self.geom diff = geom_envelope - self.geom
complexity_factor = 1 - self.geom.area / diff.area complexity_factor = 1 - self.geom.area / diff.area

@ -146,7 +146,6 @@ class BaseTestCase(TestCase):
geometry = Geometry.objects.create() geometry = Geometry.objects.create()
# Finally create main object, holding the other objects # Finally create main object, holding the other objects
intervention = Intervention.objects.create( intervention = Intervention.objects.create(
identifier="TEST",
title="Test_title", title="Test_title",
responsible=responsibility_data, responsible=responsibility_data,
legal=legal_data, legal=legal_data,
@ -174,7 +173,6 @@ class BaseTestCase(TestCase):
geometry = Geometry.objects.create() geometry = Geometry.objects.create()
# Finally create main object, holding the other objects # Finally create main object, holding the other objects
compensation = Compensation.objects.create( compensation = Compensation.objects.create(
identifier="TEST",
title="Test_title", title="Test_title",
intervention=interv, intervention=interv,
created=action, created=action,
@ -200,10 +198,8 @@ class BaseTestCase(TestCase):
responsible_data.handler = handler responsible_data.handler = handler
responsible_data.save() responsible_data.save()
identifier = EcoAccount().generate_new_identifier()
# Finally create main object, holding the other objects # Finally create main object, holding the other objects
eco_account = EcoAccount.objects.create( eco_account = EcoAccount.objects.create(
identifier=identifier,
title="Test_title", title="Test_title",
deductable_surface=500, deductable_surface=500,
legal=lega_data, legal=lega_data,
@ -230,7 +226,6 @@ class BaseTestCase(TestCase):
responsible_data.save() responsible_data.save()
# Finally create main object, holding the other objects # Finally create main object, holding the other objects
ema = Ema.objects.create( ema = Ema.objects.create(
identifier="TEST",
title="Test_title", title="Test_title",
responsible=responsible_data, responsible=responsible_data,
created=action, created=action,
@ -474,7 +469,7 @@ class BaseTestCase(TestCase):
eco_account.save() eco_account.save()
return eco_account return eco_account
def assert_equal_geometries(self, geom1: MultiPolygon, geom2: MultiPolygon): def assert_equal_geometries(self, geom1: MultiPolygon, geom2: MultiPolygon, tolerance = 0.001):
""" Assert for geometries to be equal """ Assert for geometries to be equal
Transforms the geometries to matching srids before checking Transforms the geometries to matching srids before checking
@ -491,7 +486,6 @@ class BaseTestCase(TestCase):
self.assertTrue(True) self.assertTrue(True)
return return
tolerance = 0.001
if geom1.srid != geom2.srid: if geom1.srid != geom2.srid:
# Due to prior possible transformation of any of these geometries, we need to make sure there exists a # Due to prior possible transformation of any of these geometries, we need to make sure there exists a
# transformation from one coordinate system into the other, which is valid # transformation from one coordinate system into the other, which is valid

@ -152,7 +152,7 @@ class RecordModalFormTestCase(BaseTestCase):
) )
self.assertEqual(form.form_title, str(_("Record data"))) self.assertEqual(form.form_title, str(_("Record data")))
self.assertEqual(form.form_caption, str( self.assertEqual(form.form_caption, str(
_("I, {} {}, confirm that all necessary control steps have been performed by myself.").format( _("The necessary control steps have been performed:").format(
self.user.first_name, self.user.first_name,
self.user.last_name self.user.last_name
) )

@ -173,9 +173,13 @@ class TableRenderMixin:
Returns: Returns:
""" """
value_orig = value
max_length = 75 max_length = 75
if len(value) > max_length: if len(value) > max_length:
value = f"{value[:max_length]}..." value = f"{value[:max_length]}..."
value = format_html(
f'<div title="{value_orig}">{value}</div>'
)
return value return value
def render_d(self, value, record: GeoReferencedMixin): def render_d(self, value, record: GeoReferencedMixin):

@ -33,9 +33,6 @@ class GeomParcelsView(LoginRequiredMixin, View):
Returns: Returns:
A rendered piece of HTML A rendered piece of HTML
""" """
# HTTP code 286 states that the HTMX should stop polling for updates
# https://htmx.org/docs/#polling
status_code = 286
template = "konova/includes/parcels/parcel_table_frame.html" template = "konova/includes/parcels/parcel_table_frame.html"
geom = get_object_or_404(Geometry, id=id) geom = get_object_or_404(Geometry, id=id)
@ -49,22 +46,26 @@ class GeomParcelsView(LoginRequiredMixin, View):
waiting_too_long = self._check_waiting_too_long(geom) waiting_too_long = self._check_waiting_too_long(geom)
parcels_are_currently_calculated = ( if geometry_exists and not parcels_are_available and waiting_too_long:
geometry_exists and # Trigger calculation again - process may have failed silently
not parcels_are_available and
geom_parcel_update_started and
not geom_parcel_update_finished
)
if not parcels_are_available and waiting_too_long:
# Trigger calculation again - process may have failed in the background
celery_update_parcels.delay(geom.id) celery_update_parcels.delay(geom.id)
parcels_are_currently_calculated = True parcels_are_currently_calculated = True
else:
parcels_are_currently_calculated = (
geometry_exists and
not parcels_are_available and
geom_parcel_update_started and
not geom_parcel_update_finished
)
if parcels_are_currently_calculated: if parcels_are_currently_calculated:
# Parcels are being calculated right now. Change the status code, so polling stays active for fetching # Parcels are being calculated right now. Change the status code, so polling stays active for fetching
# results after the calculation # results after the calculation
status_code = 200 status_code = 200
else:
# HTTP code 286 states that the HTMX should stop polling for updates
# https://htmx.org/docs/#polling
status_code = 286
if parcels_are_available or not geometry_exists: if parcels_are_available or not geometry_exists:
# Default case: Parcels are calculated or there is no geometry at all # Default case: Parcels are calculated or there is no geometry at all

Binary file not shown.

@ -321,7 +321,7 @@ msgstr ""
#: intervention/templates/intervention/detail/view.html:39 #: intervention/templates/intervention/detail/view.html:39
#: intervention/templates/intervention/report/report.html:20 #: intervention/templates/intervention/report/report.html:20
msgid "Law" msgid "Law"
msgstr "Gesetz" msgstr "Rechtsgrundlage"
#: analysis/templates/analysis/reports/includes/old_data/amount.html:17 #: analysis/templates/analysis/reports/includes/old_data/amount.html:17
#: compensation/templates/compensation/detail/compensation/includes/deadlines.html:33 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:33
@ -1452,11 +1452,9 @@ msgstr "Prüfung vornehmen"
#: intervention/forms/modals/check.py:36 konova/forms/modals/record_form.py:30 #: intervention/forms/modals/check.py:36 konova/forms/modals/record_form.py:30
#: konova/tests/unit/test_forms.py:155 #: konova/tests/unit/test_forms.py:155
msgid "" msgid ""
"I, {} {}, confirm that all necessary control steps have been performed by " "The necessary control steps have been performed:"
"myself."
msgstr "" msgstr ""
"Ich, {} {}, bestätige, dass die notwendigen Kontrollschritte durchgeführt " "Die notwendigen Kontrollschritte wurden durchgeführt:"
"wurden:"
#: intervention/forms/modals/deduction.py:33 #: intervention/forms/modals/deduction.py:33
msgid "Only recorded accounts can be selected for deductions" msgid "Only recorded accounts can be selected for deductions"

Loading…
Cancel
Save