diff --git a/codelist/models.py b/codelist/models.py index de7a2100..8e5de0c9 100644 --- a/codelist/models.py +++ b/codelist/models.py @@ -65,24 +65,23 @@ class KonovaCode(models.Model): ret_val += ", " + self.parent.long_name return ret_val - def add_children(self): + def add_children(self, order_by: str = "long_name"): """ Adds all children (resurcively until leaf) as .children to the KonovaCode Returns: code (KonovaCode): The manipulated KonovaCode instance """ if self.is_leaf: - return None + return self children = KonovaCode.objects.filter( - code_lists__in=self.code_lists.all(), parent=self ).order_by( - "long_name" + order_by ) self.children = children for child in children: - child.add_children() + child.add_children(order_by) return self diff --git a/compensation/forms/modalForms.py b/compensation/forms/modalForms.py index 8404c7ad..d129459d 100644 --- a/compensation/forms/modalForms.py +++ b/compensation/forms/modalForms.py @@ -17,7 +17,8 @@ from codelist.models import KonovaCode 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 intervention.inputs import CompensationActionTreeCheckboxSelectMultiple +from intervention.inputs import CompensationActionTreeCheckboxSelectMultiple, \ + CompensationStateTreeRadioSelect from konova.contexts import BaseContext from konova.forms import BaseModalForm, NewDocumentModalForm, RemoveModalForm from konova.models import DeadlineType @@ -156,22 +157,12 @@ class NewStateModalForm(BaseModalForm): What has been on this area before changes/compensations have been applied and what will be the result ('after')? """ - biotope_type = forms.ModelChoiceField( + biotope_type = forms.MultipleChoiceField( label=_("Biotope Type"), label_suffix="", required=True, help_text=_("Select the biotope type"), - queryset=KonovaCode.objects.filter( - is_archived=False, - is_leaf=True, - code_lists__in=[CODELIST_BIOTOPES_ID], - ), - widget=autocomplete.ModelSelect2( - url="codes-biotope-autocomplete", - attrs={ - "data-placeholder": _("Biotope Type"), - } - ), + widget=CompensationStateTreeRadioSelect(), ) biotope_extra = forms.ModelMultipleChoiceField( label=_("Biotope additional type"), @@ -272,7 +263,7 @@ class EditCompensationStateModalForm(NewStateModalForm): super().__init__(*args, **kwargs) self.form_title = _("Edit state") form_data = { - "biotope_type": self.state.biotope_type, + "biotope_type": self.state.biotope_type.id, "biotope_extra": self.state.biotope_type_details.all(), "surface": self.state.surface, } diff --git a/intervention/inputs.py b/intervention/inputs.py index 34fe0434..a08c0b74 100644 --- a/intervention/inputs.py +++ b/intervention/inputs.py @@ -1,6 +1,6 @@ from django import forms from codelist.models import KonovaCode -from codelist.settings import CODELIST_COMPENSATION_ACTION_ID +from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID class DummyFilterInput(forms.HiddenInput): @@ -38,7 +38,17 @@ class TreeCheckboxSelectMultiple(forms.CheckboxSelectMultiple): """ Provides multiple selection of parent-child data """ - template_name = "konova/widgets/checkbox-tree-select.html" + template_name = "konova/widgets/tree/checkbox/checkbox-tree-select.html" + + class meta: + abstract = True + + +class TreeRadioSelect(forms.RadioSelect): + """ Provides single selection of parent-child data + + """ + template_name = "konova/widgets/tree/radio/radio-tree-select.html" class meta: abstract = True @@ -68,6 +78,30 @@ class KonovaCodeTreeCheckboxSelectMultiple(TreeCheckboxSelectMultiple): return context +class KonovaCodeTreeRadioSelect(TreeRadioSelect): + """ Provides single selection of KonovaCode + + """ + filter = None + + def __init__(self, *args, **kwargs): + self.code_list = kwargs.pop("code_list", None) + self.filter = kwargs.pop("filter", {}) + super().__init__(*args, **kwargs) + + def get_context(self, name, value, attrs): + context = super().get_context(name, value, attrs) + codes = KonovaCode.objects.filter( + **self.filter, + ) + codes = [ + parent_code.add_children() + for parent_code in codes + ] + context["codes"] = codes + return context + + class CompensationActionTreeCheckboxSelectMultiple(KonovaCodeTreeCheckboxSelectMultiple): """ Provides multiple selection of CompensationActions @@ -79,4 +113,31 @@ class CompensationActionTreeCheckboxSelectMultiple(KonovaCodeTreeCheckboxSelectM self.filter = { "code_lists__in": [CODELIST_COMPENSATION_ACTION_ID], "parent": None, - } \ No newline at end of file + } + + +class CompensationStateTreeRadioSelect(KonovaCodeTreeRadioSelect): + """ Provides single selection of CompensationState + + """ + filter = None + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.filter = { + "code_lists__in": [CODELIST_BIOTOPES_ID], + "parent": None, + "is_archived": False, + } + + def get_context(self, name, value, attrs): + context = super().get_context(name, value, attrs) + codes = KonovaCode.objects.filter( + **self.filter, + ) + codes = [ + parent_code.add_children("short_name") + for parent_code in codes + ] + context["codes"] = codes + return context \ No newline at end of file diff --git a/konova/templates/konova/widgets/checkbox-tree-select-content.html b/konova/templates/konova/widgets/tree/checkbox/checkbox-tree-select-content.html similarity index 85% rename from konova/templates/konova/widgets/checkbox-tree-select-content.html rename to konova/templates/konova/widgets/tree/checkbox/checkbox-tree-select-content.html index 31599efa..84f97ece 100644 --- a/konova/templates/konova/widgets/checkbox-tree-select-content.html +++ b/konova/templates/konova/widgets/tree/checkbox/checkbox-tree-select-content.html @@ -10,12 +10,15 @@ {% fa5_icon 'angle-down' %} {% endif %} + {% if code.short_name %} + ({{code.short_name}}) + {% endif %} {{code.long_name}} {% if not code.is_leaf %}