diff --git a/api/utils/serializer/v1/serializer.py b/api/utils/serializer/v1/serializer.py index 66421708..f56db81b 100644 --- a/api/utils/serializer/v1/serializer.py +++ b/api/utils/serializer/v1/serializer.py @@ -14,7 +14,8 @@ from django.db.models import QuerySet 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_LAW_ID, CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, \ + CODELIST_COMPENSATION_ACTION_DETAIL_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID from compensation.models import CompensationAction, UnitChoices, CompensationState from intervention.models import Responsibility, Legal from konova.models import Deadline, DeadlineType @@ -323,6 +324,9 @@ class AbstractCompensationAPISerializerV1Mixin: states = [] for entry in states_data: biotope_type = entry["biotope"] + biotope_details = [ + self._konova_code_from_json(e, CODELIST_BIOTOPES_EXTRA_CODES_ID) for e in entry["biotope_details"] + ] surface = float(entry["surface"]) # Check on validity @@ -331,22 +335,22 @@ class AbstractCompensationAPISerializerV1Mixin: # If this exact data is already existing, we do not create it new. Instead put it's id in the list of # entries, we will use to set the new actions - pre_existing_state = states_manager.filter( + state = states_manager.filter( biotope_type__atom_id=biotope_type, surface=surface, ).exclude( id__in=states ).first() - if pre_existing_state is not None: - states.append(pre_existing_state.id) + if state is not None: + states.append(state.id) else: # Create and add id to list - new_state = CompensationState.objects.create( + state = CompensationState.objects.create( biotope_type=self._konova_code_from_json(biotope_type, CODELIST_BIOTOPES_ID), surface=surface ) - states.append(new_state.id) - + states.append(state.id) + state.biotope_type_details.set(biotope_details) states_manager.set(states) return obj @@ -364,6 +368,9 @@ class AbstractCompensationAPISerializerV1Mixin: actions = [] for entry in actions_data: action = entry["action"] + action_details = [ + self._konova_code_from_json(e, CODELIST_COMPENSATION_ACTION_DETAIL_ID) for e in entry["action_details"] + ] amount = float(entry["amount"]) unit = entry["unit"] comment = entry["comment"] @@ -376,7 +383,7 @@ class AbstractCompensationAPISerializerV1Mixin: # If this exact data is already existing, we do not create it new. Instead put it's id in the list of # entries, we will use to set the new actions - pre_existing_action = obj.actions.filter( + action_entry = obj.actions.filter( action_type__atom_id=action, amount=amount, unit=unit, @@ -384,17 +391,19 @@ class AbstractCompensationAPISerializerV1Mixin: ).exclude( id__in=actions ).first() - if pre_existing_action is not None: - actions.append(pre_existing_action.id) + if action_entry is not None: + actions.append(action_entry.id) else: # Create and add id to list - new_action = CompensationAction.objects.create( + action_entry = CompensationAction.objects.create( action_type=self._konova_code_from_json(action, CODELIST_COMPENSATION_ACTION_ID), amount=amount, unit=unit, comment=comment, ) - actions.append(new_action.id) + actions.append(action_entry.id) + + action_entry.action_type_details.set(action_details) obj.actions.set(actions) return obj @@ -410,6 +419,9 @@ class AbstractCompensationAPISerializerV1Mixin: return [ { "biotope": self._konova_code_to_json(entry.biotope_type), + "biotope_details": [ + self._konova_code_to_json(detail) for detail in entry.biotope_type_details.all() + ], "surface": entry.surface, } for entry in qs @@ -427,6 +439,9 @@ class AbstractCompensationAPISerializerV1Mixin: return [ { "action": self._konova_code_to_json(entry.action_type), + "action_details": [ + self._konova_code_to_json(detail) for detail in entry.action_type_details.all() + ], "amount": entry.amount, "unit": entry.unit, "comment": entry.comment, diff --git a/codelist/management/commands/update_codelist.py b/codelist/management/commands/update_codelist.py index 5bb55b6a..85c90324 100644 --- a/codelist/management/commands/update_codelist.py +++ b/codelist/management/commands/update_codelist.py @@ -13,7 +13,8 @@ from codelist.models import KonovaCode, KonovaCodeList from codelist.settings import CODELIST_INTERVENTION_HANDLER_ID, CODELIST_CONSERVATION_OFFICE_ID, \ CODELIST_REGISTRATION_OFFICE_ID, CODELIST_BIOTOPES_ID, CODELIST_LAW_ID, CODELIST_COMPENSATION_HANDLER_ID, \ CODELIST_COMPENSATION_ACTION_ID, CODELIST_COMPENSATION_ACTION_CLASS_ID, CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID, \ - CODELIST_BASE_URL, CODELIST_PROCESS_TYPE_ID + CODELIST_BASE_URL, CODELIST_PROCESS_TYPE_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID, \ + CODELIST_COMPENSATION_ACTION_DETAIL_ID from konova.management.commands.setup import BaseKonovaCommand from konova.settings import PROXIES @@ -33,10 +34,12 @@ class Command(BaseKonovaCommand): CODELIST_CONSERVATION_OFFICE_ID, CODELIST_REGISTRATION_OFFICE_ID, CODELIST_BIOTOPES_ID, + CODELIST_BIOTOPES_EXTRA_CODES_ID, CODELIST_LAW_ID, CODELIST_COMPENSATION_HANDLER_ID, CODELIST_COMPENSATION_ACTION_ID, CODELIST_COMPENSATION_ACTION_CLASS_ID, + CODELIST_COMPENSATION_ACTION_DETAIL_ID, CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID, CODELIST_PROCESS_TYPE_ID, ] diff --git a/codelist/settings.py b/codelist/settings.py index 15c523ac..598a3a66 100644 --- a/codelist/settings.py +++ b/codelist/settings.py @@ -14,11 +14,13 @@ CODELIST_INTERVENTION_HANDLER_ID = 903 # CLMassnahmeträger CODELIST_CONSERVATION_OFFICE_ID = 907 # CLNaturschutzbehörden CODELIST_REGISTRATION_OFFICE_ID = 1053 # CLZulassungsbehörden CODELIST_BIOTOPES_ID = 974 # CL_EIV_Biotoptypen +CODELIST_BIOTOPES_EXTRA_CODES_ID = 975 # CLZusatzbezeichnung CODELIST_LAW_ID = 1048 # CLVerfahrensrecht CODELIST_PROCESS_TYPE_ID = 44382 # CLVerfahrenstyp CODELIST_COMPENSATION_HANDLER_ID = 1052 # CLEingreifer CODELIST_COMPENSATION_ACTION_ID = 1026 # CLMassnahmedetail +CODELIST_COMPENSATION_ACTION_DETAIL_ID = 1035 # CLZusatzmerkmal CODELIST_COMPENSATION_ACTION_CLASS_ID = 1034 # CLMassnahmeklasse CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID = 1028 # CLMassnahmetyp, CEF and stuff CODELIST_COMPENSATION_FUNDING_ID = 1049 # CLKombimassnahme diff --git a/compensation/forms/modalForms.py b/compensation/forms/modalForms.py index 885db951..dd9f4c70 100644 --- a/compensation/forms/modalForms.py +++ b/compensation/forms/modalForms.py @@ -14,7 +14,8 @@ from django.shortcuts import render from django.utils.translation import pgettext_lazy as _con, gettext_lazy as _ from codelist.models import KonovaCode -from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_COMPENSATION_ACTION_ID +from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID, \ + CODELIST_COMPENSATION_ACTION_DETAIL_ID from compensation.models import CompensationDocument, EcoAccountDocument from konova.contexts import BaseContext from konova.forms import BaseModalForm, NewDocumentForm @@ -127,6 +128,23 @@ class NewStateModalForm(BaseModalForm): } ), ) + biotope_extra = forms.ModelMultipleChoiceField( + label=_("Biotope additional type"), + label_suffix="", + required=False, + help_text=_("Select an additional biotope type"), + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_BIOTOPES_EXTRA_CODES_ID], + ), + widget=autocomplete.ModelSelect2Multiple( + url="codes-biotope-extra-type-autocomplete", + attrs={ + "data-placeholder": _("Biotope additional type"), + } + ), + ) surface = forms.DecimalField( min_value=0.00, decimal_places=2, @@ -283,6 +301,23 @@ class NewActionModalForm(BaseModalForm): } ), ) + action_type_details = forms.ModelMultipleChoiceField( + label=_("Action Type detail"), + label_suffix="", + required=False, + help_text=_("Select the action type detail"), + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_COMPENSATION_ACTION_DETAIL_ID], + ), + widget=autocomplete.ModelSelect2Multiple( + url="codes-compensation-action-detail-autocomplete", + attrs={ + "data-placeholder": _("Action Type detail"), + } + ), + ) unit = forms.ChoiceField( label=_("Unit"), label_suffix="", diff --git a/compensation/models/action.py b/compensation/models/action.py index 35d4c3f7..95fe2807 100644 --- a/compensation/models/action.py +++ b/compensation/models/action.py @@ -9,7 +9,7 @@ from django.db import models from django.utils.translation import gettext_lazy as _ from codelist.models import KonovaCode -from codelist.settings import CODELIST_COMPENSATION_ACTION_ID +from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_COMPENSATION_ACTION_DETAIL_ID from compensation.managers import CompensationActionManager from konova.models import BaseResource @@ -39,7 +39,18 @@ class CompensationAction(BaseResource): "code_lists__in": [CODELIST_COMPENSATION_ACTION_ID], "is_selectable": True, "is_archived": False, - } + }, + related_name='+', + ) + action_type_details = models.ManyToManyField( + KonovaCode, + blank=True, + limit_choices_to={ + "code_lists__in": [CODELIST_COMPENSATION_ACTION_DETAIL_ID], + "is_selectable": True, + "is_archived": False, + }, + related_name='+', ) amount = models.FloatField() unit = models.CharField(max_length=100, null=True, blank=True, choices=UnitChoices.choices) diff --git a/compensation/models/compensation.py b/compensation/models/compensation.py index 66035579..de5a3461 100644 --- a/compensation/models/compensation.py +++ b/compensation/models/compensation.py @@ -95,6 +95,8 @@ class AbstractCompensation(BaseObject, GeoReferencedMixin): comment=form_data["comment"], created=user_action, ) + comp_action_details = form_data["action_type_details"] + comp_action.action_type_details.set(comp_action_details) self.actions.add(comp_action) return comp_action @@ -114,6 +116,8 @@ class AbstractCompensation(BaseObject, GeoReferencedMixin): biotope_type=form_data["biotope_type"], surface=form_data["surface"], ) + state_additional_types = form_data["biotope_extra"] + state.biotope_type_details.set(state_additional_types) if is_before_state: self.before_states.add(state) else: diff --git a/compensation/models/state.py b/compensation/models/state.py index 01aad147..858ac3d1 100644 --- a/compensation/models/state.py +++ b/compensation/models/state.py @@ -8,7 +8,7 @@ Created on: 16.11.21 from django.db import models from codelist.models import KonovaCode -from codelist.settings import CODELIST_BIOTOPES_ID +from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID from compensation.managers import CompensationStateManager from konova.models import UuidModel @@ -26,7 +26,18 @@ class CompensationState(UuidModel): "code_lists__in": [CODELIST_BIOTOPES_ID], "is_selectable": True, "is_archived": False, - } + }, + related_name='+', + ) + biotope_type_details = models.ManyToManyField( + KonovaCode, + blank=True, + limit_choices_to={ + "code_lists__in": [CODELIST_BIOTOPES_EXTRA_CODES_ID], + "is_selectable": True, + "is_archived": False, + }, + related_name='+', ) surface = models.FloatField() diff --git a/compensation/templates/compensation/detail/compensation/includes/actions.html b/compensation/templates/compensation/detail/compensation/includes/actions.html index 92cf45ff..648e777a 100644 --- a/compensation/templates/compensation/detail/compensation/includes/actions.html +++ b/compensation/templates/compensation/detail/compensation/includes/actions.html @@ -24,9 +24,12 @@ - + @@ -46,9 +49,14 @@ + -
+ {% trans 'Action type' %} + {% trans 'Action type details' %} + {% trans 'Amount' context 'Compensation' %} {{ action.action_type }} + {% for detail in action.action_type_details.all %} +
{{detail.long_name}}
+ {% endfor %} +
{{ action.amount|floatformat:2|intcomma }} {{ action.unit_humanize }} {{ action.comment|default_if_none:"" }} + {% if is_default_member and has_access %}