From 762d25a87e2225bf0a1b51c8a015bfbaab76042b Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Tue, 6 Aug 2024 15:39:01 +0200 Subject: [PATCH 1/3] # Codelist 288 * introduces 288 to codelist/settings.py * refactors usage from 975 to 288 * enhances rendering of codelist names depending on which name exists (short vs long) --- api/utils/serializer/v1/serializer.py | 5 ++-- codelist/autocomplete/biotope.py | 9 ++++---- .../management/commands/update_codelist.py | 7 +++--- codelist/models.py | 23 ++++++++++++++----- codelist/settings.py | 3 ++- compensation/forms/modals/state.py | 5 ++-- compensation/models/state.py | 6 ++--- 7 files changed, 37 insertions(+), 21 deletions(-) diff --git a/api/utils/serializer/v1/serializer.py b/api/utils/serializer/v1/serializer.py index 8779f4e..03ca0e0 100644 --- a/api/utils/serializer/v1/serializer.py +++ b/api/utils/serializer/v1/serializer.py @@ -16,7 +16,8 @@ from api.utils.serializer.serializer import AbstractModelAPISerializer from codelist.models import KonovaCode from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID, CODELIST_PROCESS_TYPE_ID, \ CODELIST_LAW_ID, CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, \ - CODELIST_COMPENSATION_ACTION_DETAIL_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID, CODELIST_HANDLER_ID + CODELIST_COMPENSATION_ACTION_DETAIL_ID, CODELIST_HANDLER_ID, \ + CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID from compensation.models import CompensationAction, UnitChoices, CompensationState from intervention.models import Responsibility, Legal, Handler from konova.models import Deadline, DeadlineType @@ -347,7 +348,7 @@ class AbstractCompensationAPISerializerV1Mixin: try: biotope_type = entry["biotope"] biotope_details = [ - self._konova_code_from_json(e, CODELIST_BIOTOPES_EXTRA_CODES_ID) for e in entry["biotope_details"] + self._konova_code_from_json(e, CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID) for e in entry["biotope_details"] ] surface = float(entry["surface"]) except KeyError: diff --git a/codelist/autocomplete/biotope.py b/codelist/autocomplete/biotope.py index 5e56b7f..7e8047e 100644 --- a/codelist/autocomplete/biotope.py +++ b/codelist/autocomplete/biotope.py @@ -9,7 +9,8 @@ import collections from django.core.exceptions import ImproperlyConfigured -from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID +from codelist.settings import CODELIST_BIOTOPES_ID, \ + CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID from codelist.autocomplete.base import KonovaCodeAutocomplete from konova.utils.message_templates import UNGROUPED @@ -84,11 +85,11 @@ class BiotopeExtraCodeAutocomplete(KonovaCodeAutocomplete): Due to limitations of the django dal package, we need to subclass for each code list """ group_by_related = "parent" - related_field_name = "long_name" + related_field_name = "short_name" paginate_by = 200 def __init__(self, *args, **kwargs): - self.c = CODELIST_BIOTOPES_EXTRA_CODES_ID + self.c = CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID super().__init__(*args, **kwargs) def order_by(self, qs): @@ -103,7 +104,7 @@ class BiotopeExtraCodeAutocomplete(KonovaCodeAutocomplete): qs (QuerySet): The ordered queryset """ return qs.order_by( - "long_name", + "short_name", ) def get_result_label(self, result): diff --git a/codelist/management/commands/update_codelist.py b/codelist/management/commands/update_codelist.py index d29b272..d514c99 100644 --- a/codelist/management/commands/update_codelist.py +++ b/codelist/management/commands/update_codelist.py @@ -13,7 +13,7 @@ from codelist.settings import CODELIST_INTERVENTION_HANDLER_ID, CODELIST_CONSERV CODELIST_REGISTRATION_OFFICE_ID, CODELIST_BIOTOPES_ID, CODELIST_LAW_ID, CODELIST_HANDLER_ID, \ CODELIST_COMPENSATION_ACTION_ID, CODELIST_COMPENSATION_ACTION_CLASS_ID, CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID, \ CODELIST_BASE_URL, CODELIST_PROCESS_TYPE_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID, \ - CODELIST_COMPENSATION_ACTION_DETAIL_ID + CODELIST_COMPENSATION_ACTION_DETAIL_ID, CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID from konova.management.commands.setup import BaseKonovaCommand from konova.settings import PROXIES @@ -34,6 +34,7 @@ class Command(BaseKonovaCommand): CODELIST_REGISTRATION_OFFICE_ID, CODELIST_BIOTOPES_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID, + CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID, CODELIST_LAW_ID, CODELIST_HANDLER_ID, CODELIST_COMPENSATION_ACTION_ID, @@ -55,7 +56,7 @@ class Command(BaseKonovaCommand): content = result.content.decode("utf-8") root = etree.fromstring(content) items = root.findall("item") - self._write_warning("Found {} codes. Process now...".format(len(items))) + self._write_warning(" Found {} codes. Process now...".format(len(items))) code_list = KonovaCodeList.objects.get_or_create( id=list_id, @@ -74,7 +75,7 @@ class Command(BaseKonovaCommand): if items is None: return else: - self._write_warning(" --- Found {} subcodes. Process now...".format(len(items))) + self._write_warning(" --- Found {} subcodes. Process now...".format(len(items))) for element in items: children = element.find("items") _id = element.find("id").text diff --git a/codelist/models.py b/codelist/models.py index a5b91a3..4821d9a 100644 --- a/codelist/models.py +++ b/codelist/models.py @@ -50,12 +50,23 @@ class KonovaCode(models.Model): def __str__(self, with_parent: bool = True): ret_val = "" - if self.parent and self.parent.long_name and with_parent: - ret_val += self.parent.long_name + " > " - ret_val += self.long_name - if self.short_name and self.short_name != self.long_name: - # Only add short name, if we won't have stupid repition like 'thing a (thing a)' due to misused long-short names - ret_val += f" ({self.short_name})" + + long_name = self.long_name + short_name = self.short_name + + both_names_exist = long_name and short_name + + if both_names_exist: + if with_parent: + if self.parent and self.parent.long_name: + ret_val += self.parent.long_name + " > " + ret_val += long_name + + if short_name and short_name != long_name: + ret_val += f" ({short_name})" + else: + ret_val += str(long_name or short_name) + return ret_val @property diff --git a/codelist/settings.py b/codelist/settings.py index 3bd7032..1032423 100644 --- a/codelist/settings.py +++ b/codelist/settings.py @@ -15,7 +15,8 @@ CODELIST_CONSERVATION_OFFICE_ID = 907 # CLNaturschutzbehörden CODELIST_REGISTRATION_OFFICE_ID = 1053 # CLZulassungsbehörden CODELIST_BIOTOPES_ID = 654 # CL_Biotoptypen CODELIST_AFTER_STATE_BIOTOPES_ID = 974 # CL-KSP_ZielBiotoptypen - USAGE HAS BEEN DROPPED IN 2022 IN FAVOR OF 654 -CODELIST_BIOTOPES_EXTRA_CODES_ID = 975 # CLZusatzbezeichnung +CODELIST_BIOTOPES_EXTRA_CODES_ID = 975 # CLZusatzbezeichnung - Subset of 288. Migration usage 975->288 in 08/2024 +CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID = 288 # CLBiotoptypZusatzcode CODELIST_LAW_ID = 1048 # CLVerfahrensrecht CODELIST_PROCESS_TYPE_ID = 44382 # CLVerfahrenstyp diff --git a/compensation/forms/modals/state.py b/compensation/forms/modals/state.py index 5a1dde5..7340c95 100644 --- a/compensation/forms/modals/state.py +++ b/compensation/forms/modals/state.py @@ -14,7 +14,8 @@ from django.shortcuts import render from django.utils.translation import gettext_lazy as _ from codelist.models import KonovaCode -from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID +from codelist.settings import CODELIST_BIOTOPES_ID, \ + CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID from intervention.inputs import CompensationStateTreeRadioSelect from konova.contexts import BaseContext from konova.forms.modals import RemoveModalForm, BaseModalForm @@ -43,7 +44,7 @@ class NewCompensationStateModalForm(BaseModalForm): queryset=KonovaCode.objects.filter( is_archived=False, is_leaf=True, - code_lists__in=[CODELIST_BIOTOPES_EXTRA_CODES_ID], + code_lists__in=[CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID], ), widget=autocomplete.ModelSelect2Multiple( url="codelist:biotope-extra-type-autocomplete", diff --git a/compensation/models/state.py b/compensation/models/state.py index 77026b5..01fc2aa 100644 --- a/compensation/models/state.py +++ b/compensation/models/state.py @@ -6,10 +6,10 @@ Created on: 16.11.21 """ from django.db import models -from django.db.models import Q from codelist.models import KonovaCode -from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID +from codelist.settings import CODELIST_BIOTOPES_ID, \ + CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID from compensation.managers import CompensationStateManager from konova.models import UuidModel @@ -34,7 +34,7 @@ class CompensationState(UuidModel): KonovaCode, blank=True, limit_choices_to={ - "code_lists__in": [CODELIST_BIOTOPES_EXTRA_CODES_ID], + "code_lists__in": [CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID], "is_selectable": True, "is_archived": False, }, From 81663db65c8e4fbc6ae9fd50e50284cd5d7f3646 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 7 Aug 2024 09:12:38 +0200 Subject: [PATCH 2/3] # Migration list 975->288 * adds migration for app codelist to migrate existing biotope type details codes from list 975 to 288 depending on their atomID * improves rendering of action and biotope type details on frontend for KOM, OEK and EMA * refactors KonovaCode str() rendering --- codelist/autocomplete/biotope.py | 3 ++ .../migrations/0002_migrate_975_to_288.py | 49 +++++++++++++++++++ codelist/models.py | 13 +++-- .../detail/compensation/includes/actions.html | 2 +- .../compensation/includes/states-after.html | 2 +- .../compensation/includes/states-before.html | 2 +- .../detail/eco_account/includes/actions.html | 2 +- .../eco_account/includes/states-after.html | 2 +- .../eco_account/includes/states-before.html | 2 +- .../ema/detail/includes/actions.html | 2 +- .../ema/detail/includes/states-after.html | 2 +- .../ema/detail/includes/states-before.html | 2 +- 12 files changed, 69 insertions(+), 14 deletions(-) create mode 100644 codelist/migrations/0002_migrate_975_to_288.py diff --git a/codelist/autocomplete/biotope.py b/codelist/autocomplete/biotope.py index 7e8047e..4fe1e30 100644 --- a/codelist/autocomplete/biotope.py +++ b/codelist/autocomplete/biotope.py @@ -109,3 +109,6 @@ class BiotopeExtraCodeAutocomplete(KonovaCodeAutocomplete): def get_result_label(self, result): return f"{result.long_name} ({result.short_name})" + + def get_selected_result_label(self, result): + return f"{result.parent.short_name} > {result.long_name} ({result.short_name})" \ No newline at end of file diff --git a/codelist/migrations/0002_migrate_975_to_288.py b/codelist/migrations/0002_migrate_975_to_288.py new file mode 100644 index 0000000..cf0d87c --- /dev/null +++ b/codelist/migrations/0002_migrate_975_to_288.py @@ -0,0 +1,49 @@ +# Generated by Django 5.0.7 on 2024-08-06 13:40 + +from django.db import migrations +from django.db.models import Q + +from codelist.settings import CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID + + +def migrate_975_to_288(apps, schema_editor): + KonovaCodeList = apps.get_model('codelist', 'KonovaCodeList') + CompensationState = apps.get_model('compensation', 'CompensationState') + + list_288 = KonovaCodeList.objects.get( + id=CODELIST_BIOTOPES_EXTRA_CODES_FULL_ID + ).codes.all() + + states_with_extra_code = CompensationState.objects.filter( + ~Q(biotope_type_details=None) + ) + + print(f"... Found {states_with_extra_code.count()} biotope state entries") + for state in states_with_extra_code: + extra_codes_975 = state.biotope_type_details.filter( + code_lists__in=[CODELIST_BIOTOPES_EXTRA_CODES_ID] + ) + count_extra_codes_975 = extra_codes_975.count() + if count_extra_codes_975 > 0: + print(f" --> Found {count_extra_codes_975} codes from list 975 in biotope entry {state.id}") + extra_codes_288 = [] + for extra_code_975 in extra_codes_975: + atom_id = extra_code_975.atom_id + codes_from_288 = list_288.filter( + atom_id=atom_id, + ) + extra_codes_288 += codes_from_288 + + state.biotope_type_details.set(extra_codes_288) + print(" --> Migrated to list 288 for all biotope entries") + + +class Migration(migrations.Migration): + + dependencies = [ + ('codelist', '0001_initial'), + ] + + operations = [ + migrations.RunPython(migrate_975_to_288) + ] diff --git a/codelist/models.py b/codelist/models.py index 4821d9a..1bd5da3 100644 --- a/codelist/models.py +++ b/codelist/models.py @@ -25,13 +25,11 @@ class KonovaCode(models.Model): ) short_name = models.CharField( max_length=500, - null=True, blank=True, help_text="Short version of long name", ) long_name = models.CharField( max_length=1000, - null=True, blank=True, help_text="", ) @@ -54,12 +52,17 @@ class KonovaCode(models.Model): long_name = self.long_name short_name = self.short_name - both_names_exist = long_name and short_name + both_names_exist = long_name is not None and short_name is not None if both_names_exist: - if with_parent: - if self.parent and self.parent.long_name: + if with_parent and self.parent: + parent_short_name_exists = self.parent.short_name is not None + parent_long_name_exists = self.parent.long_name is not None + if parent_long_name_exists: ret_val += self.parent.long_name + " > " + elif parent_short_name_exists: + ret_val += self.parent.short_name + " > " + ret_val += long_name if short_name and short_name != long_name: diff --git a/compensation/templates/compensation/detail/compensation/includes/actions.html b/compensation/templates/compensation/detail/compensation/includes/actions.html index e4ec5b6..d832ad1 100644 --- a/compensation/templates/compensation/detail/compensation/includes/actions.html +++ b/compensation/templates/compensation/detail/compensation/includes/actions.html @@ -52,7 +52,7 @@
{% endfor %} {% for detail in action.action_type_details.all %} - {{detail.long_name}} + {{ detail.parent.long_name }} > {{detail.long_name}} {% empty %} {% trans 'No action type details' %} {% endfor %} diff --git a/compensation/templates/compensation/detail/compensation/includes/states-after.html b/compensation/templates/compensation/detail/compensation/includes/states-after.html index dfda6ae..39e6204 100644 --- a/compensation/templates/compensation/detail/compensation/includes/states-after.html +++ b/compensation/templates/compensation/detail/compensation/includes/states-after.html @@ -51,7 +51,7 @@ {{ state.biotope_type.parent.long_name }} {% fa5_icon 'angle-right' %} {{ state.biotope_type.long_name }} ({{state.biotope_type.short_name}})
{% for detail in state.biotope_type_details.all %} - {{detail.long_name}} + {{ detail.parent.short_name }} > {{ detail.long_name }} {% empty %} {% trans 'No biotope type details' %} {% endfor %} diff --git a/compensation/templates/compensation/detail/compensation/includes/states-before.html b/compensation/templates/compensation/detail/compensation/includes/states-before.html index ff3d267..25524c0 100644 --- a/compensation/templates/compensation/detail/compensation/includes/states-before.html +++ b/compensation/templates/compensation/detail/compensation/includes/states-before.html @@ -51,7 +51,7 @@ {{ state.biotope_type.parent.long_name }} {% fa5_icon 'angle-right' %} {{ state.biotope_type.long_name }} ({{state.biotope_type.short_name}})
{% for detail in state.biotope_type_details.all %} - {{detail.long_name}} + {{ detail.parent.short_name }} > {{ detail.long_name }} {% empty %} {% trans 'No biotope type details' %} {% endfor %} diff --git a/compensation/templates/compensation/detail/eco_account/includes/actions.html b/compensation/templates/compensation/detail/eco_account/includes/actions.html index 52f8648..d83820a 100644 --- a/compensation/templates/compensation/detail/eco_account/includes/actions.html +++ b/compensation/templates/compensation/detail/eco_account/includes/actions.html @@ -51,7 +51,7 @@
{% endfor %} {% for detail in action.action_type_details.all %} - {{detail.long_name}} + {{ detail.parent.long_name }} > {{detail.long_name}} {% empty %} {% trans 'No action type details' %} {% endfor %} diff --git a/compensation/templates/compensation/detail/eco_account/includes/states-after.html b/compensation/templates/compensation/detail/eco_account/includes/states-after.html index d188f08..02ac15c 100644 --- a/compensation/templates/compensation/detail/eco_account/includes/states-after.html +++ b/compensation/templates/compensation/detail/eco_account/includes/states-after.html @@ -51,7 +51,7 @@ {{ state.biotope_type.parent.long_name }} {% fa5_icon 'angle-right' %} {{ state.biotope_type.long_name }} ({{state.biotope_type.short_name}})
{% for detail in state.biotope_type_details.all %} - {{detail.long_name}} + {{ detail.parent.short_name }} > {{ detail.long_name }} {% empty %} {% trans 'No biotope type details' %} {% endfor %} diff --git a/compensation/templates/compensation/detail/eco_account/includes/states-before.html b/compensation/templates/compensation/detail/eco_account/includes/states-before.html index 56fe0b0..135c4c0 100644 --- a/compensation/templates/compensation/detail/eco_account/includes/states-before.html +++ b/compensation/templates/compensation/detail/eco_account/includes/states-before.html @@ -51,7 +51,7 @@ {{ state.biotope_type.parent.long_name }} {% fa5_icon 'angle-right' %} {{ state.biotope_type.long_name }} ({{state.biotope_type.short_name}})
{% for detail in state.biotope_type_details.all %} - {{detail.long_name}} + {{ detail.parent.short_name }} > {{ detail.long_name }} {% empty %} {% trans 'No biotope type details' %} {% endfor %} diff --git a/ema/templates/ema/detail/includes/actions.html b/ema/templates/ema/detail/includes/actions.html index 8a77c79..0088bfe 100644 --- a/ema/templates/ema/detail/includes/actions.html +++ b/ema/templates/ema/detail/includes/actions.html @@ -49,7 +49,7 @@
{% endfor %} {% for detail in action.action_type_details.all %} - {{detail.long_name}} + {{ detail.parent.long_name }} > {{detail.long_name}} {% empty %} {% trans 'No action type details' %} {% endfor %} diff --git a/ema/templates/ema/detail/includes/states-after.html b/ema/templates/ema/detail/includes/states-after.html index 0277e02..fbee289 100644 --- a/ema/templates/ema/detail/includes/states-after.html +++ b/ema/templates/ema/detail/includes/states-after.html @@ -49,7 +49,7 @@ {{ state.biotope_type.parent.long_name }} {% fa5_icon 'angle-right' %} {{ state.biotope_type.long_name }} ({{state.biotope_type.short_name}})
{% for detail in state.biotope_type_details.all %} - {{detail.long_name}} + {{ detail.parent.short_name }} > {{ detail.long_name }} {% empty %} {% trans 'No biotope type details' %} {% endfor %} diff --git a/ema/templates/ema/detail/includes/states-before.html b/ema/templates/ema/detail/includes/states-before.html index f0d4edd..a69709a 100644 --- a/ema/templates/ema/detail/includes/states-before.html +++ b/ema/templates/ema/detail/includes/states-before.html @@ -49,7 +49,7 @@ {{ state.biotope_type.parent.long_name }} {% fa5_icon 'angle-right' %} {{ state.biotope_type.long_name }} ({{state.biotope_type.short_name}})
{% for detail in state.biotope_type_details.all %} - {{detail.long_name}} + {{ detail.parent.short_name }} > {{ detail.long_name }} {% empty %} {% trans 'No biotope type details' %} {% endfor %} From e5284cd660c1a4bc32d69dc77cc1233a7c96f1d7 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 7 Aug 2024 09:17:20 +0200 Subject: [PATCH 3/3] # Requirements update * updates some packages in requirements.txt --- requirements.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8d7889c..3b89792 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ billiard==4.2.0 cached-property==1.5.2 celery==5.4.0 certifi==2024.7.4 -cffi==1.17.0rc1 +cffi==1.17.0 chardet==5.2.0 charset-normalizer==3.3.2 click==8.1.7 @@ -14,14 +14,14 @@ click-didyoumean==0.3.1 click-plugins==1.1.1 click-repl==0.3.0 coverage==7.5.4 -cryptography==42.0.8 +cryptography==43.0.0 Deprecated==1.2.14 -Django==5.0.7 +Django==5.0.8 django-autocomplete-light==3.11.0 django-bootstrap-modal-forms==3.0.4 django-bootstrap4==24.3 django-environ==0.11.2 -django-filter==24.2 +django-filter==24.3 django-fontawesome-5==1.0.18 django-oauth-toolkit==2.4.0 django-simple-sso==1.2.0 @@ -29,7 +29,7 @@ django-tables2==2.7.0 et-xmlfile==1.1.0 gunicorn==22.0.0 idna==3.7 -importlib_metadata==8.0.0 +importlib_metadata==8.2.0 itsdangerous==0.24 jwcrypto==1.5.6 kombu==5.4.0rc1 @@ -47,13 +47,13 @@ pypng==0.20220715.0 pyproj==3.6.1 python-dateutil==2.9.0.post0 pytz==2024.1 -PyYAML==6.0.2rc1 +PyYAML==6.0.2 qrcode==7.3.1 redis==5.1.0b6 -requests<2.32.0 +requests==2.32.3 six==1.16.0 soupsieve==2.5 -sqlparse==0.5.0 +sqlparse==0.5.1 typing_extensions==4.12.2 tzdata==2024.1 urllib3==2.2.2