Merge pull request 'Konova Codelist enhancements' (#9) from master into 3_Payment_date_and_comment
Reviewed-on: SGD-Nord/konova#9
This commit is contained in:
		
						commit
						c2fdad1ab6
					
				@ -16,17 +16,21 @@ class KonovaCodeListAdmin(admin.ModelAdmin):
 | 
			
		||||
class KonovaCodeAdmin(admin.ModelAdmin):
 | 
			
		||||
    list_display = [
 | 
			
		||||
        "id",
 | 
			
		||||
        "atom_id",
 | 
			
		||||
        "parent",
 | 
			
		||||
        "short_name",
 | 
			
		||||
        "long_name",
 | 
			
		||||
        "is_leaf",
 | 
			
		||||
        "is_active",
 | 
			
		||||
        "is_selectable",
 | 
			
		||||
        "is_archived",
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    readonly_fields = [
 | 
			
		||||
        "id",
 | 
			
		||||
        "short_name",
 | 
			
		||||
        "long_name",
 | 
			
		||||
        "is_archived",
 | 
			
		||||
        "is_selectable",
 | 
			
		||||
        "is_leaf",
 | 
			
		||||
        "parent",
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,10 @@ from codelist.settings import CODELIST_INTERVENTION_HANDLER_ID, CODELIST_CONSERV
 | 
			
		||||
    CODELIST_COMPENSATION_ACTION_ID, CODELIST_COMPENSATION_ACTION_CLASS_ID, CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID, \
 | 
			
		||||
    CODELIST_COMPENSATION_COMBINATION_ID, CODELIST_BASE_URL
 | 
			
		||||
 | 
			
		||||
bool_map = {
 | 
			
		||||
    "true": True,
 | 
			
		||||
    "false": False,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Command(BaseCommand):
 | 
			
		||||
    help = "Performs test on collisions using the identifier generation"
 | 
			
		||||
@ -56,41 +60,6 @@ class Command(BaseCommand):
 | 
			
		||||
                    code_list=code_list,
 | 
			
		||||
                    parent=None,
 | 
			
		||||
                )
 | 
			
		||||
                """
 | 
			
		||||
                for element in items:
 | 
			
		||||
                    atom_id = element.find("atomid").text
 | 
			
		||||
                    parent = element.find("vaterid").text
 | 
			
		||||
                    short_name = element.find("shortname").text
 | 
			
		||||
                    long_name = element.find("longname").text
 | 
			
		||||
                    is_archived = bool(element.find("archive").text)
 | 
			
		||||
 | 
			
		||||
                    # If a parent has been set, we need to fetch/create this entry. Otherwise ("0") we ignore it.
 | 
			
		||||
                    if parent == "0":
 | 
			
		||||
                        parent = None
 | 
			
		||||
                    else:
 | 
			
		||||
                        parent = KonovaCode.objects.get_or_create(
 | 
			
		||||
                            id=parent,
 | 
			
		||||
                        )[0]
 | 
			
		||||
 | 
			
		||||
                    code = KonovaCode.objects.get_or_create(
 | 
			
		||||
                        id=atom_id,
 | 
			
		||||
                    )
 | 
			
		||||
                    created = code[1]
 | 
			
		||||
                    if created:
 | 
			
		||||
                        num_created += 1
 | 
			
		||||
                    else:
 | 
			
		||||
                        num_updated += 1
 | 
			
		||||
                    code = code[0]
 | 
			
		||||
                    code.short_name = short_name
 | 
			
		||||
                    code.long_name = long_name
 | 
			
		||||
                    code.parent = parent
 | 
			
		||||
                    code.is_active = is_archived
 | 
			
		||||
 | 
			
		||||
                    code.save()
 | 
			
		||||
                    if code not in code_list.codes.all():
 | 
			
		||||
                        code_list.codes.add(code)
 | 
			
		||||
 | 
			
		||||
                """
 | 
			
		||||
 | 
			
		||||
        except KeyboardInterrupt:
 | 
			
		||||
            self._break_line()
 | 
			
		||||
@ -102,19 +71,24 @@ class Command(BaseCommand):
 | 
			
		||||
        else:
 | 
			
		||||
            for element in items:
 | 
			
		||||
                children = element.find("items")
 | 
			
		||||
                _id = element.find("id").text
 | 
			
		||||
                atom_id = element.find("atomid").text
 | 
			
		||||
                selectable = element.find("selectable").text.lower()
 | 
			
		||||
                selectable = bool_map.get(selectable, False)
 | 
			
		||||
                short_name = element.find("shortname").text
 | 
			
		||||
                long_name = element.find("longname").text
 | 
			
		||||
                is_archived = bool(element.find("archive").text)
 | 
			
		||||
                is_archived = bool_map.get((element.find("archive").text.lower()), False)
 | 
			
		||||
 | 
			
		||||
                code = KonovaCode.objects.get_or_create(
 | 
			
		||||
                    id=atom_id,
 | 
			
		||||
                    id=_id,
 | 
			
		||||
                )
 | 
			
		||||
                code = code[0]
 | 
			
		||||
                code.atom_id = atom_id
 | 
			
		||||
                code.short_name = short_name
 | 
			
		||||
                code.long_name = long_name
 | 
			
		||||
                code.parent = parent
 | 
			
		||||
                code.is_active = is_archived
 | 
			
		||||
                code.is_selectable = selectable
 | 
			
		||||
                code.is_archived = is_archived
 | 
			
		||||
                code.is_leaf = children is None
 | 
			
		||||
 | 
			
		||||
                code.save()
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,12 @@ class KonovaCode(models.Model):
 | 
			
		||||
    """
 | 
			
		||||
    id = models.IntegerField(
 | 
			
		||||
        primary_key=True,
 | 
			
		||||
        help_text="AtomId; Identifies this code uniquely over all NatIT projects"
 | 
			
		||||
        help_text="Regular Id"
 | 
			
		||||
    )
 | 
			
		||||
    atom_id = models.IntegerField(
 | 
			
		||||
        help_text="AtomId; Identifies this code uniquely over all NatIT projects; Duplicates possible",
 | 
			
		||||
        null=True,
 | 
			
		||||
        blank=True,
 | 
			
		||||
    )
 | 
			
		||||
    parent = models.ForeignKey(
 | 
			
		||||
        "KonovaCode",
 | 
			
		||||
@ -30,20 +35,27 @@ class KonovaCode(models.Model):
 | 
			
		||||
        blank=True,
 | 
			
		||||
        help_text="",
 | 
			
		||||
    )
 | 
			
		||||
    is_selectable = models.BooleanField(
 | 
			
		||||
        default=False,
 | 
			
		||||
        help_text="Whether this code shall be used for any select actions or not"
 | 
			
		||||
    )
 | 
			
		||||
    is_leaf = models.BooleanField(
 | 
			
		||||
        default=False,
 | 
			
		||||
        help_text="Whether this code has children or not"
 | 
			
		||||
    )
 | 
			
		||||
    is_active = models.BooleanField(
 | 
			
		||||
    is_archived = models.BooleanField(
 | 
			
		||||
        default=False,
 | 
			
		||||
        help_text="Whether this code is archived or not"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        ret_val = ""
 | 
			
		||||
        if self.parent:
 | 
			
		||||
            ret_val += self.parent.long_name + " > "
 | 
			
		||||
        ret_val += self.long_name
 | 
			
		||||
        if self.short_name:
 | 
			
		||||
            return "{} ({})".format(self.long_name, self.short_name)
 | 
			
		||||
        else:
 | 
			
		||||
            return self.long_name
 | 
			
		||||
            ret_val += " ({})".format(self.short_name)
 | 
			
		||||
        return ret_val
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class KonovaCodeList(models.Model):
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ from django.utils.translation import gettext_lazy as _
 | 
			
		||||
from django.utils.translation import pgettext_lazy as _con
 | 
			
		||||
 | 
			
		||||
from codelist.models import KonovaCode
 | 
			
		||||
from codelist.settings import CODELIST_BIOTOPES_ID
 | 
			
		||||
from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_COMPENSATION_ACTION_ID
 | 
			
		||||
from compensation.models import Payment, CompensationState, CompensationAction, UnitChoices
 | 
			
		||||
from konova.contexts import BaseContext
 | 
			
		||||
from konova.forms import BaseForm, BaseModalForm
 | 
			
		||||
@ -106,7 +106,7 @@ class NewStateModalForm(BaseModalForm):
 | 
			
		||||
        required=True,
 | 
			
		||||
        help_text=_("Select the biotope type"),
 | 
			
		||||
        queryset=KonovaCode.objects.filter(
 | 
			
		||||
            is_active=True,
 | 
			
		||||
            is_archived=False,
 | 
			
		||||
            is_leaf=True,
 | 
			
		||||
            code_lists__in=[CODELIST_BIOTOPES_ID],
 | 
			
		||||
        ),
 | 
			
		||||
@ -278,13 +278,14 @@ class NewActionModalForm(BaseModalForm):
 | 
			
		||||
        required=True,
 | 
			
		||||
        help_text=_("Select the action type"),
 | 
			
		||||
        queryset=KonovaCode.objects.filter(
 | 
			
		||||
            is_active=True,
 | 
			
		||||
            is_archived=False,
 | 
			
		||||
            is_leaf=True,
 | 
			
		||||
            code_lists__in=[CODELIST_COMPENSATION_ACTION_ID],
 | 
			
		||||
        ),
 | 
			
		||||
        widget=autocomplete.ModelSelect2(
 | 
			
		||||
            url="codes-compensation-action-autocomplete",
 | 
			
		||||
            attrs={
 | 
			
		||||
                "data-placeholder": _("Action"),
 | 
			
		||||
                "data-class": "w-100",
 | 
			
		||||
            }
 | 
			
		||||
        ),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,8 @@ from dal_select2.views import Select2QuerySetView
 | 
			
		||||
from django.db.models import Q
 | 
			
		||||
 | 
			
		||||
from codelist.models import KonovaCode
 | 
			
		||||
from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID
 | 
			
		||||
from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID, CODELIST_LAW_ID, \
 | 
			
		||||
    CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID
 | 
			
		||||
from compensation.models import EcoAccount
 | 
			
		||||
from intervention.models import Intervention
 | 
			
		||||
from organisation.models import Organisation
 | 
			
		||||
@ -92,7 +93,8 @@ class KonovaCodeAutocomplete(Select2QuerySetView):
 | 
			
		||||
        if self.request.user.is_anonymous:
 | 
			
		||||
            return KonovaCode.objects.none()
 | 
			
		||||
        qs = KonovaCode.objects.filter(
 | 
			
		||||
            is_active=True,
 | 
			
		||||
            is_archived=False,
 | 
			
		||||
            is_selectable=True,
 | 
			
		||||
            is_leaf=True,
 | 
			
		||||
        ).order_by(
 | 
			
		||||
            "long_name"
 | 
			
		||||
@ -125,3 +127,30 @@ class BiotopeCodeAutocomplete(KonovaCodeAutocomplete):
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        self.c = CODELIST_BIOTOPES_ID
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LawCodeAutocomplete(KonovaCodeAutocomplete):
 | 
			
		||||
    """
 | 
			
		||||
    Due to limitations of the django dal package, we need to subclass for each code list
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        self.c = CODELIST_LAW_ID
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class RegistrationOfficeCodeAutocomplete(KonovaCodeAutocomplete):
 | 
			
		||||
    """
 | 
			
		||||
    Due to limitations of the django dal package, we need to subclass for each code list
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        self.c = CODELIST_REGISTRATION_OFFICE_ID
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ConservationOfficeCodeAutocomplete(KonovaCodeAutocomplete):
 | 
			
		||||
    """
 | 
			
		||||
    Due to limitations of the django dal package, we need to subclass for each code list
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        self.c = CODELIST_CONSERVATION_OFFICE_ID
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
@ -203,4 +203,12 @@ input:focus, textarea:focus, select:focus{
 | 
			
		||||
.scroll-300{
 | 
			
		||||
    max-height: 300px;
 | 
			
		||||
    overflow: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Extends css for django autocomplete light (dal)
 | 
			
		||||
No other approach worked to get the autocomplete fields to full width of parent containers
 | 
			
		||||
*/
 | 
			
		||||
.select2-container{
 | 
			
		||||
    width: 100% !important;
 | 
			
		||||
}
 | 
			
		||||
@ -18,7 +18,8 @@ from django.contrib import admin
 | 
			
		||||
from django.urls import path, include
 | 
			
		||||
 | 
			
		||||
from konova.autocompletes import OrganisationAutocomplete, NonOfficialOrganisationAutocomplete, EcoAccountAutocomplete, \
 | 
			
		||||
    InterventionAutocomplete, CompensationActionCodeAutocomplete, BiotopeCodeAutocomplete
 | 
			
		||||
    InterventionAutocomplete, CompensationActionCodeAutocomplete, BiotopeCodeAutocomplete, LawCodeAutocomplete, \
 | 
			
		||||
    RegistrationOfficeCodeAutocomplete, ConservationOfficeCodeAutocomplete
 | 
			
		||||
from konova.settings import SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY, DEBUG
 | 
			
		||||
from konova.sso.sso import KonovaSSOClient
 | 
			
		||||
from konova.views import logout_view, home_view, get_document_view, remove_document_view, remove_deadline_view
 | 
			
		||||
@ -51,6 +52,9 @@ urlpatterns = [
 | 
			
		||||
    path("atcmplt/interventions", InterventionAutocomplete.as_view(), name="interventions-autocomplete"),
 | 
			
		||||
    path("atcmplt/codes/compensation-action", CompensationActionCodeAutocomplete.as_view(), name="codes-compensation-action-autocomplete"),
 | 
			
		||||
    path("atcmplt/codes/biotope", BiotopeCodeAutocomplete.as_view(), name="codes-biotope-autocomplete"),
 | 
			
		||||
    path("atcmplt/codes/law", LawCodeAutocomplete.as_view(), name="codes-law-autocomplete"),
 | 
			
		||||
    path("atcmplt/codes/reg-off", RegistrationOfficeCodeAutocomplete.as_view(), name="codes-registration-office-autocomplete"),
 | 
			
		||||
    path("atcmplt/codes/cons-off", ConservationOfficeCodeAutocomplete.as_view(), name="codes-conservation-office-autocomplete"),
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
if DEBUG:
 | 
			
		||||
 | 
			
		||||
@ -1,23 +1,25 @@
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
<table class="table">
 | 
			
		||||
    <tbody>
 | 
			
		||||
    {% for field in form %}
 | 
			
		||||
    <tr title="{{ field.help_text }}" class="{% if field.errors %}alert-danger{% endif %}">
 | 
			
		||||
        <th scope="row" class="col-sm-3">
 | 
			
		||||
            <label for="id_{{ field.name }}">{{ field.label }}<span class="label-required">{% if field.field.required %}*{% endif %}</span></label>
 | 
			
		||||
            <small>{{ field.help_text }}</small>
 | 
			
		||||
        </th>
 | 
			
		||||
        <td class="col-sm-9">
 | 
			
		||||
            {{ field }}
 | 
			
		||||
            {% for error in field.errors %}
 | 
			
		||||
            <br>
 | 
			
		||||
            <strong class="invalid">{{ error }}</strong>
 | 
			
		||||
            {% endfor %}
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    {% endfor %}
 | 
			
		||||
    </tbody>
 | 
			
		||||
</table>
 | 
			
		||||
{% if form.has_required_fields %}
 | 
			
		||||
<small>{% trans 'Fields with * are required.' %}</small>
 | 
			
		||||
{% endif %}
 | 
			
		||||
<div class="table-responsive">
 | 
			
		||||
    <table class="table">
 | 
			
		||||
        <tbody>
 | 
			
		||||
        {% for field in form %}
 | 
			
		||||
        <tr title="{{ field.help_text }}" class="{% if field.errors %}alert-danger{% endif %}">
 | 
			
		||||
            <th scope="row" class="col-sm-3">
 | 
			
		||||
                <label for="id_{{ field.name }}">{{ field.label }}<span class="label-required">{% if field.field.required %}*{% endif %}</span></label>
 | 
			
		||||
                <small>{{ field.help_text }}</small>
 | 
			
		||||
            </th>
 | 
			
		||||
            <td class="col-sm-9">
 | 
			
		||||
                {{ field }}
 | 
			
		||||
                {% for error in field.errors %}
 | 
			
		||||
                <br>
 | 
			
		||||
                <strong class="invalid">{{ error }}</strong>
 | 
			
		||||
                {% endfor %}
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        {% endfor %}
 | 
			
		||||
        </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
    {% if form.has_required_fields %}
 | 
			
		||||
    <small>{% trans 'Fields with * are required.' %}</small>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
</div>
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user