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):
|
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",
|
||||||
]
|
]
|
||||||
|
@ -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()
|
||||||
|
@ -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):
|
||||||
|
@ -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",
|
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
@ -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:
|
||||||
|
@ -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>
|
Loading…
Reference in New Issue
Block a user