Konova Codelist enhancements #9

Merged
mpeltriaux merged 1 commits from master into 3_Payment_date_and_comment 2021-08-26 13:20:26 +02:00
8 changed files with 107 additions and 73 deletions

View File

@ -16,17 +16,21 @@ class KonovaCodeListAdmin(admin.ModelAdmin):
class KonovaCodeAdmin(admin.ModelAdmin): class KonovaCodeAdmin(admin.ModelAdmin):
list_display = [ list_display = [
"id", "id",
"atom_id",
"parent", "parent",
"short_name", "short_name",
"long_name", "long_name",
"is_leaf", "is_leaf",
"is_active", "is_selectable",
"is_archived",
] ]
readonly_fields = [ readonly_fields = [
"id", "id",
"short_name", "short_name",
"long_name", "long_name",
"is_archived",
"is_selectable",
"is_leaf", "is_leaf",
"parent", "parent",
] ]

View File

@ -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_ACTION_ID, CODELIST_COMPENSATION_ACTION_CLASS_ID, CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID, \
CODELIST_COMPENSATION_COMBINATION_ID, CODELIST_BASE_URL CODELIST_COMPENSATION_COMBINATION_ID, CODELIST_BASE_URL
bool_map = {
"true": True,
"false": False,
}
class Command(BaseCommand): class Command(BaseCommand):
help = "Performs test on collisions using the identifier generation" help = "Performs test on collisions using the identifier generation"
@ -56,41 +60,6 @@ class Command(BaseCommand):
code_list=code_list, code_list=code_list,
parent=None, 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: except KeyboardInterrupt:
self._break_line() self._break_line()
@ -102,19 +71,24 @@ class Command(BaseCommand):
else: else:
for element in items: for element in items:
children = element.find("items") children = element.find("items")
_id = element.find("id").text
atom_id = element.find("atomid").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 short_name = element.find("shortname").text
long_name = element.find("longname").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( code = KonovaCode.objects.get_or_create(
id=atom_id, id=_id,
) )
code = code[0] code = code[0]
code.atom_id = atom_id
code.short_name = short_name code.short_name = short_name
code.long_name = long_name code.long_name = long_name
code.parent = parent code.parent = parent
code.is_active = is_archived code.is_selectable = selectable
code.is_archived = is_archived
code.is_leaf = children is None code.is_leaf = children is None
code.save() code.save()

View File

@ -10,7 +10,12 @@ class KonovaCode(models.Model):
""" """
id = models.IntegerField( id = models.IntegerField(
primary_key=True, 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( parent = models.ForeignKey(
"KonovaCode", "KonovaCode",
@ -30,20 +35,27 @@ class KonovaCode(models.Model):
blank=True, blank=True,
help_text="", 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( is_leaf = models.BooleanField(
default=False, default=False,
help_text="Whether this code has children or not" help_text="Whether this code has children or not"
) )
is_active = models.BooleanField( is_archived = models.BooleanField(
default=False, default=False,
help_text="Whether this code is archived or not" help_text="Whether this code is archived or not"
) )
def __str__(self): def __str__(self):
ret_val = ""
if self.parent:
ret_val += self.parent.long_name + " > "
ret_val += self.long_name
if self.short_name: if self.short_name:
return "{} ({})".format(self.long_name, self.short_name) ret_val += " ({})".format(self.short_name)
else: return ret_val
return self.long_name
class KonovaCodeList(models.Model): class KonovaCodeList(models.Model):

View File

@ -16,7 +16,7 @@ from django.utils.translation import gettext_lazy as _
from django.utils.translation import pgettext_lazy as _con from django.utils.translation import pgettext_lazy as _con
from codelist.models import KonovaCode 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 compensation.models import Payment, CompensationState, CompensationAction, UnitChoices
from konova.contexts import BaseContext from konova.contexts import BaseContext
from konova.forms import BaseForm, BaseModalForm from konova.forms import BaseForm, BaseModalForm
@ -106,7 +106,7 @@ class NewStateModalForm(BaseModalForm):
required=True, required=True,
help_text=_("Select the biotope type"), help_text=_("Select the biotope type"),
queryset=KonovaCode.objects.filter( queryset=KonovaCode.objects.filter(
is_active=True, is_archived=False,
is_leaf=True, is_leaf=True,
code_lists__in=[CODELIST_BIOTOPES_ID], code_lists__in=[CODELIST_BIOTOPES_ID],
), ),
@ -278,13 +278,14 @@ class NewActionModalForm(BaseModalForm):
required=True, required=True,
help_text=_("Select the action type"), help_text=_("Select the action type"),
queryset=KonovaCode.objects.filter( queryset=KonovaCode.objects.filter(
is_active=True, is_archived=False,
is_leaf=True,
code_lists__in=[CODELIST_COMPENSATION_ACTION_ID],
), ),
widget=autocomplete.ModelSelect2( widget=autocomplete.ModelSelect2(
url="codes-compensation-action-autocomplete", url="codes-compensation-action-autocomplete",
attrs={ attrs={
"data-placeholder": _("Action"), "data-placeholder": _("Action"),
"data-class": "w-100",
} }
), ),
) )

View File

@ -9,7 +9,8 @@ from dal_select2.views import Select2QuerySetView
from django.db.models import Q from django.db.models import Q
from codelist.models import KonovaCode 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 compensation.models import EcoAccount
from intervention.models import Intervention from intervention.models import Intervention
from organisation.models import Organisation from organisation.models import Organisation
@ -92,7 +93,8 @@ class KonovaCodeAutocomplete(Select2QuerySetView):
if self.request.user.is_anonymous: if self.request.user.is_anonymous:
return KonovaCode.objects.none() return KonovaCode.objects.none()
qs = KonovaCode.objects.filter( qs = KonovaCode.objects.filter(
is_active=True, is_archived=False,
is_selectable=True,
is_leaf=True, is_leaf=True,
).order_by( ).order_by(
"long_name" "long_name"
@ -125,3 +127,30 @@ class BiotopeCodeAutocomplete(KonovaCodeAutocomplete):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.c = CODELIST_BIOTOPES_ID self.c = CODELIST_BIOTOPES_ID
super().__init__(*args, **kwargs) 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)

View File

@ -203,4 +203,12 @@ input:focus, textarea:focus, select:focus{
.scroll-300{ .scroll-300{
max-height: 300px; max-height: 300px;
overflow: auto; 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;
} }

View File

@ -18,7 +18,8 @@ from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from konova.autocompletes import OrganisationAutocomplete, NonOfficialOrganisationAutocomplete, EcoAccountAutocomplete, \ 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.settings import SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY, DEBUG
from konova.sso.sso import KonovaSSOClient from konova.sso.sso import KonovaSSOClient
from konova.views import logout_view, home_view, get_document_view, remove_document_view, remove_deadline_view 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/interventions", InterventionAutocomplete.as_view(), name="interventions-autocomplete"),
path("atcmplt/codes/compensation-action", CompensationActionCodeAutocomplete.as_view(), name="codes-compensation-action-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/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: if DEBUG:

View File

@ -1,23 +1,25 @@
{% load i18n %} {% load i18n %}
<table class="table"> <div class="table-responsive">
<tbody> <table class="table">
{% for field in form %} <tbody>
<tr title="{{ field.help_text }}" class="{% if field.errors %}alert-danger{% endif %}"> {% for field in form %}
<th scope="row" class="col-sm-3"> <tr title="{{ field.help_text }}" class="{% if field.errors %}alert-danger{% endif %}">
<label for="id_{{ field.name }}">{{ field.label }}<span class="label-required">{% if field.field.required %}*{% endif %}</span></label> <th scope="row" class="col-sm-3">
<small>{{ field.help_text }}</small> <label for="id_{{ field.name }}">{{ field.label }}<span class="label-required">{% if field.field.required %}*{% endif %}</span></label>
</th> <small>{{ field.help_text }}</small>
<td class="col-sm-9"> </th>
{{ field }} <td class="col-sm-9">
{% for error in field.errors %} {{ field }}
<br> {% for error in field.errors %}
<strong class="invalid">{{ error }}</strong> <br>
{% endfor %} <strong class="invalid">{{ error }}</strong>
</td> {% endfor %}
</tr> </td>
{% endfor %} </tr>
</tbody> {% endfor %}
</table> </tbody>
{% if form.has_required_fields %} </table>
<small>{% trans 'Fields with * are required.' %}</small> {% if form.has_required_fields %}
{% endif %} <small>{% trans 'Fields with * are required.' %}</small>
{% endif %}
</div>