* extends codelist settings by compensation handler codelist (differs from regular handler codelist)
392 lines
12 KiB
Python
392 lines
12 KiB
Python
"""
|
|
Author: Michel Peltriaux
|
|
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
|
Contact: michel.peltriaux@sgdnord.rlp.de
|
|
Created on: 07.12.20
|
|
|
|
"""
|
|
import collections
|
|
|
|
from dal_select2.views import Select2QuerySetView, Select2GroupQuerySetView
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
|
|
from konova.utils.message_templates import UNGROUPED
|
|
from user.models import User, Team
|
|
from django.db.models import Q
|
|
|
|
from codelist.models import KonovaCode
|
|
from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID, CODELIST_LAW_ID, \
|
|
CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, CODELIST_PROCESS_TYPE_ID, \
|
|
CODELIST_BIOTOPES_EXTRA_CODES_ID, CODELIST_COMPENSATION_ACTION_DETAIL_ID, CODELIST_HANDLER_ID, \
|
|
CODELIST_COMPENSATION_HANDLER_ID
|
|
from compensation.models import EcoAccount
|
|
from intervention.models import Intervention
|
|
|
|
|
|
class EcoAccountAutocomplete(Select2QuerySetView):
|
|
""" Autocomplete for ecoAccount entries
|
|
|
|
Only returns entries that are already recorded and not deleted
|
|
|
|
"""
|
|
def get_queryset(self):
|
|
if self.request.user.is_anonymous:
|
|
return EcoAccount.objects.none()
|
|
qs = EcoAccount.objects.filter(
|
|
deleted=None,
|
|
recorded__isnull=False,
|
|
).order_by(
|
|
"identifier"
|
|
)
|
|
if self.q:
|
|
qs = qs.filter(
|
|
Q(identifier__icontains=self.q) |
|
|
Q(title__icontains=self.q)
|
|
).distinct()
|
|
return qs
|
|
|
|
|
|
class InterventionAutocomplete(Select2QuerySetView):
|
|
""" Autocomplete for intervention entries
|
|
|
|
Only returns entries that are accessible for the requesting user
|
|
|
|
"""
|
|
def get_queryset(self):
|
|
if self.request.user.is_anonymous:
|
|
return Intervention.objects.none()
|
|
qs = Intervention.objects.filter(
|
|
deleted=None,
|
|
users__in=[self.request.user],
|
|
).order_by(
|
|
"identifier"
|
|
)
|
|
if self.q:
|
|
qs = qs.filter(
|
|
Q(identifier__icontains=self.q) |
|
|
Q(title__icontains=self.q)
|
|
).distinct()
|
|
return qs
|
|
|
|
|
|
class ShareUserAutocomplete(Select2QuerySetView):
|
|
""" Autocomplete for share with single users
|
|
|
|
|
|
"""
|
|
def get_queryset(self):
|
|
if self.request.user.is_anonymous:
|
|
return User.objects.none()
|
|
qs = User.objects.all()
|
|
if self.q:
|
|
# Due to privacy concerns only a full username match will return the proper user entry
|
|
qs = qs.filter(
|
|
Q(username=self.q) |
|
|
Q(email=self.q)
|
|
).distinct()
|
|
qs = qs.order_by("username")
|
|
return qs
|
|
|
|
|
|
class ShareTeamAutocomplete(Select2QuerySetView):
|
|
""" Autocomplete for share with teams
|
|
|
|
"""
|
|
def get_queryset(self):
|
|
if self.request.user.is_anonymous:
|
|
return Team.objects.none()
|
|
qs = Team.objects.all()
|
|
if self.q:
|
|
# Due to privacy concerns only a full username match will return the proper user entry
|
|
qs = qs.filter(
|
|
name__icontains=self.q
|
|
)
|
|
qs = qs.order_by(
|
|
"name"
|
|
)
|
|
return qs
|
|
|
|
|
|
class KonovaCodeAutocomplete(Select2GroupQuerySetView):
|
|
"""
|
|
Provides simple autocomplete functionality for codes
|
|
|
|
Parameter support:
|
|
* q: Search for a word inside long_name of a code
|
|
* c: Search inside a special codelist
|
|
|
|
"""
|
|
paginate_by = 50
|
|
|
|
def order_by(self, qs):
|
|
""" Orders by a predefined value
|
|
|
|
Wrapped in a function to provide inheritance-based different orders
|
|
|
|
Args:
|
|
qs (QuerySet): The queryset to be ordered
|
|
|
|
Returns:
|
|
qs (QuerySet): The ordered queryset
|
|
"""
|
|
return qs.order_by(
|
|
"long_name"
|
|
)
|
|
|
|
def get_queryset(self):
|
|
if self.request.user.is_anonymous:
|
|
return KonovaCode.objects.none()
|
|
qs = KonovaCode.objects.filter(
|
|
is_archived=False,
|
|
is_selectable=True,
|
|
is_leaf=True,
|
|
)
|
|
qs = self.order_by(qs)
|
|
if self.c:
|
|
qs = qs.filter(
|
|
code_lists__in=[self.c],
|
|
)
|
|
if self.q:
|
|
# Remove whitespaces from self.q and split input in all keywords (if multiple given)
|
|
q = dict.fromkeys(self.q.strip().split(" "))
|
|
# Create one filter looking up for all keys where all keywords can be found in the same result
|
|
_filter = Q()
|
|
for keyword in q:
|
|
q_or = Q()
|
|
q_or |= Q(long_name__icontains=keyword)
|
|
q_or |= Q(short_name__icontains=keyword)
|
|
q_or |= Q(parent__long_name__icontains=keyword)
|
|
q_or |= Q(parent__short_name__icontains=keyword)
|
|
q_or |= Q(parent__parent__long_name__icontains=keyword)
|
|
q_or |= Q(parent__parent__short_name__icontains=keyword)
|
|
_filter.add(q_or, Q.AND)
|
|
qs = qs.filter(_filter).distinct()
|
|
return qs
|
|
|
|
def get_result_label(self, result):
|
|
return f"{result.long_name}"
|
|
|
|
def get_selected_result_label(self, result):
|
|
return f"{result.__str__()}"
|
|
|
|
|
|
class CompensationActionCodeAutocomplete(KonovaCodeAutocomplete):
|
|
"""
|
|
Due to limitations of the django dal package, we need to subclass for each code list
|
|
"""
|
|
group_by_related = "parent"
|
|
related_field_name = "long_name"
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.c = CODELIST_COMPENSATION_ACTION_ID
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def order_by(self, qs):
|
|
return qs.order_by(
|
|
"parent__long_name"
|
|
)
|
|
|
|
|
|
class CompensationActionDetailCodeAutocomplete(KonovaCodeAutocomplete):
|
|
"""
|
|
Due to limitations of the django dal package, we need to subclass for each code list
|
|
"""
|
|
group_by_related = "parent"
|
|
related_field_name = "long_name"
|
|
paginate_by = 200
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.c = CODELIST_COMPENSATION_ACTION_DETAIL_ID
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def order_by(self, qs):
|
|
return qs.order_by(
|
|
"long_name"
|
|
)
|
|
|
|
|
|
class BiotopeCodeAutocomplete(KonovaCodeAutocomplete):
|
|
"""
|
|
Due to limitations of the django dal package, we need to subclass for each code list
|
|
"""
|
|
group_by_related = "parent"
|
|
related_field_name = "long_name"
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.c = CODELIST_BIOTOPES_ID
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def order_by(self, qs):
|
|
""" Orders by a predefined value
|
|
|
|
Wrapped in a function to provide inheritance-based different orders
|
|
|
|
Args:
|
|
qs (QuerySet): The queryset to be ordered
|
|
|
|
Returns:
|
|
qs (QuerySet): The ordered queryset
|
|
"""
|
|
return qs.order_by(
|
|
"short_name",
|
|
)
|
|
|
|
def get_result_label(self, result):
|
|
return f"{result.long_name} ({result.short_name})"
|
|
|
|
def get_results(self, context):
|
|
"""Return the options grouped by a common related model.
|
|
|
|
Raises ImproperlyConfigured if self.group_by_name is not configured
|
|
"""
|
|
if not self.group_by_related:
|
|
raise ImproperlyConfigured("Missing group_by_related.")
|
|
|
|
super_groups = collections.OrderedDict()
|
|
|
|
object_list = context['object_list']
|
|
|
|
for result in object_list:
|
|
group = result.parent if result.parent else None
|
|
group_name = f"{group.long_name} ({group.short_name})" if group else UNGROUPED
|
|
super_group = result.parent.parent if result.parent else None
|
|
super_group_name = f"{super_group.long_name} ({super_group.short_name})" if super_group else UNGROUPED
|
|
super_groups.setdefault(super_group_name, {})
|
|
super_groups[super_group_name].setdefault(group_name, [])
|
|
super_groups[super_group_name][group_name].append(result)
|
|
|
|
return [{
|
|
'id': None,
|
|
'text': super_group,
|
|
'children': [{
|
|
"id": None,
|
|
"text": group,
|
|
"children": [{
|
|
'id': self.get_result_value(result),
|
|
'text': self.get_result_label(result),
|
|
'selected_text': self.get_selected_result_label(result),
|
|
} for result in results]
|
|
} for group, results in groups.items()]
|
|
} for super_group, groups in super_groups.items()]
|
|
|
|
|
|
class BiotopeExtraCodeAutocomplete(KonovaCodeAutocomplete):
|
|
"""
|
|
Due to limitations of the django dal package, we need to subclass for each code list
|
|
"""
|
|
group_by_related = "parent"
|
|
related_field_name = "long_name"
|
|
paginate_by = 200
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.c = CODELIST_BIOTOPES_EXTRA_CODES_ID
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def order_by(self, qs):
|
|
""" Orders by a predefined value
|
|
|
|
Wrapped in a function to provide inheritance-based different orders
|
|
|
|
Args:
|
|
qs (QuerySet): The queryset to be ordered
|
|
|
|
Returns:
|
|
qs (QuerySet): The ordered queryset
|
|
"""
|
|
return qs.order_by(
|
|
"long_name",
|
|
)
|
|
|
|
def get_result_label(self, result):
|
|
return f"{result.long_name} ({result.short_name})"
|
|
|
|
|
|
class LawCodeAutocomplete(KonovaCodeAutocomplete):
|
|
"""
|
|
Due to limitations of the django dal package, we need to subclass for each code list
|
|
"""
|
|
group_by_related = "parent"
|
|
related_field_name = "long_name"
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.c = CODELIST_LAW_ID
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def get_result_label(self, result):
|
|
return f"{result.long_name} ({result.short_name})"
|
|
|
|
|
|
class ProcessTypeCodeAutocomplete(KonovaCodeAutocomplete):
|
|
"""
|
|
Due to limitations of the django dal package, we need to subclass for each code list
|
|
"""
|
|
group_by_related = "parent"
|
|
related_field_name = "long_name"
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.c = CODELIST_PROCESS_TYPE_ID
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
|
class RegistrationOfficeCodeAutocomplete(KonovaCodeAutocomplete):
|
|
"""
|
|
Due to limitations of the django dal package, we need to subclass for each code list
|
|
"""
|
|
group_by_related = "parent"
|
|
related_field_name = "long_name"
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.c = CODELIST_REGISTRATION_OFFICE_ID
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def order_by(self, qs):
|
|
return qs.order_by(
|
|
"parent__long_name"
|
|
)
|
|
|
|
|
|
class ConservationOfficeCodeAutocomplete(KonovaCodeAutocomplete):
|
|
"""
|
|
Due to limitations of the django dal package, we need to subclass for each code list
|
|
"""
|
|
group_by_related = "parent"
|
|
related_field_name = "long_name"
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.c = CODELIST_CONSERVATION_OFFICE_ID
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def get_result_label(self, result):
|
|
return f"{result.long_name} ({result.short_name})"
|
|
|
|
|
|
class HandlerCodeAutocomplete(KonovaCodeAutocomplete):
|
|
"""
|
|
Due to limitations of the django dal package, we need to subclass for each code list
|
|
"""
|
|
group_by_related = "parent"
|
|
related_field_name = "long_name"
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.c = CODELIST_HANDLER_ID
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def get_result_label(self, result):
|
|
return result.long_name
|
|
|
|
|
|
class CompensationHandlerCodeAutocomplete(KonovaCodeAutocomplete):
|
|
"""
|
|
Due to limitations of the django dal package, we need to subclass for each code list
|
|
"""
|
|
group_by_related = "parent"
|
|
related_field_name = "long_name"
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.c = CODELIST_COMPENSATION_HANDLER_ID
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def get_result_label(self, result):
|
|
return result.long_name
|
|
|