Merge branch 'master' into Docker
# Conflicts: # konova/settings.py # konova/sub_settings/django_settings.py
This commit is contained in:
commit
37ed627025
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,3 @@
|
||||
# Project exclude paths
|
||||
/venv/
|
||||
/.idea/
|
||||
*/migrations/
|
@ -12,5 +12,9 @@ class APITokenAdmin(admin.ModelAdmin):
|
||||
readonly_fields = [
|
||||
"token"
|
||||
]
|
||||
search_fields = [
|
||||
"token"
|
||||
]
|
||||
|
||||
|
||||
admin.site.register(APIUserToken, APITokenAdmin)
|
||||
|
23
api/migrations/0001_initial.py
Normal file
23
api/migrations/0001_initial.py
Normal file
@ -0,0 +1,23 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-28 15:48
|
||||
|
||||
from django.db import migrations, models
|
||||
import konova.utils.generators
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='APIUserToken',
|
||||
fields=[
|
||||
('token', models.CharField(default=konova.utils.generators.generate_token, max_length=1000, primary_key=True, serialize=False)),
|
||||
('valid_until', models.DateField(blank=True, help_text='Token is only valid until this date', null=True)),
|
||||
('is_active', models.BooleanField(default=False, help_text='Must be activated by an admin')),
|
||||
],
|
||||
),
|
||||
]
|
@ -14,7 +14,8 @@ from django.db.models import QuerySet
|
||||
from api.utils.serializer.serializer import AbstractModelAPISerializer
|
||||
from codelist.models import KonovaCode
|
||||
from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID, CODELIST_PROCESS_TYPE_ID, \
|
||||
CODELIST_LAW_ID, CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID
|
||||
CODELIST_LAW_ID, CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, \
|
||||
CODELIST_COMPENSATION_ACTION_DETAIL_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID
|
||||
from compensation.models import CompensationAction, UnitChoices, CompensationState
|
||||
from intervention.models import Responsibility, Legal
|
||||
from konova.models import Deadline, DeadlineType
|
||||
@ -323,6 +324,9 @@ class AbstractCompensationAPISerializerV1Mixin:
|
||||
states = []
|
||||
for entry in states_data:
|
||||
biotope_type = entry["biotope"]
|
||||
biotope_details = [
|
||||
self._konova_code_from_json(e, CODELIST_BIOTOPES_EXTRA_CODES_ID) for e in entry["biotope_details"]
|
||||
]
|
||||
surface = float(entry["surface"])
|
||||
|
||||
# Check on validity
|
||||
@ -331,22 +335,22 @@ class AbstractCompensationAPISerializerV1Mixin:
|
||||
|
||||
# If this exact data is already existing, we do not create it new. Instead put it's id in the list of
|
||||
# entries, we will use to set the new actions
|
||||
pre_existing_state = states_manager.filter(
|
||||
state = states_manager.filter(
|
||||
biotope_type__atom_id=biotope_type,
|
||||
surface=surface,
|
||||
).exclude(
|
||||
id__in=states
|
||||
).first()
|
||||
if pre_existing_state is not None:
|
||||
states.append(pre_existing_state.id)
|
||||
if state is not None:
|
||||
states.append(state.id)
|
||||
else:
|
||||
# Create and add id to list
|
||||
new_state = CompensationState.objects.create(
|
||||
state = CompensationState.objects.create(
|
||||
biotope_type=self._konova_code_from_json(biotope_type, CODELIST_BIOTOPES_ID),
|
||||
surface=surface
|
||||
)
|
||||
states.append(new_state.id)
|
||||
|
||||
states.append(state.id)
|
||||
state.biotope_type_details.set(biotope_details)
|
||||
states_manager.set(states)
|
||||
return obj
|
||||
|
||||
@ -364,6 +368,9 @@ class AbstractCompensationAPISerializerV1Mixin:
|
||||
actions = []
|
||||
for entry in actions_data:
|
||||
action = entry["action"]
|
||||
action_details = [
|
||||
self._konova_code_from_json(e, CODELIST_COMPENSATION_ACTION_DETAIL_ID) for e in entry["action_details"]
|
||||
]
|
||||
amount = float(entry["amount"])
|
||||
unit = entry["unit"]
|
||||
comment = entry["comment"]
|
||||
@ -376,7 +383,7 @@ class AbstractCompensationAPISerializerV1Mixin:
|
||||
|
||||
# If this exact data is already existing, we do not create it new. Instead put it's id in the list of
|
||||
# entries, we will use to set the new actions
|
||||
pre_existing_action = obj.actions.filter(
|
||||
action_entry = obj.actions.filter(
|
||||
action_type__atom_id=action,
|
||||
amount=amount,
|
||||
unit=unit,
|
||||
@ -384,17 +391,19 @@ class AbstractCompensationAPISerializerV1Mixin:
|
||||
).exclude(
|
||||
id__in=actions
|
||||
).first()
|
||||
if pre_existing_action is not None:
|
||||
actions.append(pre_existing_action.id)
|
||||
if action_entry is not None:
|
||||
actions.append(action_entry.id)
|
||||
else:
|
||||
# Create and add id to list
|
||||
new_action = CompensationAction.objects.create(
|
||||
action_entry = CompensationAction.objects.create(
|
||||
action_type=self._konova_code_from_json(action, CODELIST_COMPENSATION_ACTION_ID),
|
||||
amount=amount,
|
||||
unit=unit,
|
||||
comment=comment,
|
||||
)
|
||||
actions.append(new_action.id)
|
||||
actions.append(action_entry.id)
|
||||
|
||||
action_entry.action_type_details.set(action_details)
|
||||
obj.actions.set(actions)
|
||||
return obj
|
||||
|
||||
@ -410,6 +419,9 @@ class AbstractCompensationAPISerializerV1Mixin:
|
||||
return [
|
||||
{
|
||||
"biotope": self._konova_code_to_json(entry.biotope_type),
|
||||
"biotope_details": [
|
||||
self._konova_code_to_json(detail) for detail in entry.biotope_type_details.all()
|
||||
],
|
||||
"surface": entry.surface,
|
||||
}
|
||||
for entry in qs
|
||||
@ -427,6 +439,9 @@ class AbstractCompensationAPISerializerV1Mixin:
|
||||
return [
|
||||
{
|
||||
"action": self._konova_code_to_json(entry.action_type),
|
||||
"action_details": [
|
||||
self._konova_code_to_json(detail) for detail in entry.action_type_details.all()
|
||||
],
|
||||
"amount": entry.amount,
|
||||
"unit": entry.unit,
|
||||
"comment": entry.comment,
|
||||
|
@ -35,6 +35,13 @@ class KonovaCodeAdmin(admin.ModelAdmin):
|
||||
"parent",
|
||||
]
|
||||
|
||||
search_fields = [
|
||||
"id",
|
||||
"atom_id",
|
||||
"long_name",
|
||||
"short_name",
|
||||
]
|
||||
|
||||
|
||||
#admin.site.register(KonovaCodeList, KonovaCodeListAdmin)
|
||||
admin.site.register(KonovaCode, KonovaCodeAdmin)
|
||||
|
@ -13,7 +13,8 @@ from codelist.models import KonovaCode, KonovaCodeList
|
||||
from codelist.settings import CODELIST_INTERVENTION_HANDLER_ID, CODELIST_CONSERVATION_OFFICE_ID, \
|
||||
CODELIST_REGISTRATION_OFFICE_ID, CODELIST_BIOTOPES_ID, CODELIST_LAW_ID, CODELIST_COMPENSATION_HANDLER_ID, \
|
||||
CODELIST_COMPENSATION_ACTION_ID, CODELIST_COMPENSATION_ACTION_CLASS_ID, CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID, \
|
||||
CODELIST_BASE_URL, CODELIST_PROCESS_TYPE_ID
|
||||
CODELIST_BASE_URL, CODELIST_PROCESS_TYPE_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID, \
|
||||
CODELIST_COMPENSATION_ACTION_DETAIL_ID
|
||||
from konova.management.commands.setup import BaseKonovaCommand
|
||||
from konova.settings import PROXIES
|
||||
|
||||
@ -33,10 +34,12 @@ class Command(BaseKonovaCommand):
|
||||
CODELIST_CONSERVATION_OFFICE_ID,
|
||||
CODELIST_REGISTRATION_OFFICE_ID,
|
||||
CODELIST_BIOTOPES_ID,
|
||||
CODELIST_BIOTOPES_EXTRA_CODES_ID,
|
||||
CODELIST_LAW_ID,
|
||||
CODELIST_COMPENSATION_HANDLER_ID,
|
||||
CODELIST_COMPENSATION_ACTION_ID,
|
||||
CODELIST_COMPENSATION_ACTION_CLASS_ID,
|
||||
CODELIST_COMPENSATION_ACTION_DETAIL_ID,
|
||||
CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID,
|
||||
CODELIST_PROCESS_TYPE_ID,
|
||||
]
|
||||
|
35
codelist/migrations/0001_initial.py
Normal file
35
codelist/migrations/0001_initial.py
Normal file
@ -0,0 +1,35 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-14 08:36
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='KonovaCode',
|
||||
fields=[
|
||||
('id', models.IntegerField(help_text='Regular Id', primary_key=True, serialize=False)),
|
||||
('atom_id', models.IntegerField(blank=True, help_text='AtomId; Identifies this code uniquely over all NatIT projects; Duplicates possible', null=True)),
|
||||
('short_name', models.CharField(blank=True, help_text='Short version of long name', max_length=500, null=True)),
|
||||
('long_name', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('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_archived', models.BooleanField(default=False, help_text='Whether this code is archived or not')),
|
||||
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='codelist.konovacode')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='KonovaCodeList',
|
||||
fields=[
|
||||
('id', models.IntegerField(help_text='List identifier', primary_key=True, serialize=False)),
|
||||
('codes', models.ManyToManyField(blank=True, help_text='Codes for this list', related_name='code_lists', to='codelist.KonovaCode')),
|
||||
],
|
||||
),
|
||||
]
|
0
codelist/migrations/__init__.py
Normal file
0
codelist/migrations/__init__.py
Normal file
@ -14,11 +14,13 @@ CODELIST_INTERVENTION_HANDLER_ID = 903 # CLMassnahmeträger
|
||||
CODELIST_CONSERVATION_OFFICE_ID = 907 # CLNaturschutzbehörden
|
||||
CODELIST_REGISTRATION_OFFICE_ID = 1053 # CLZulassungsbehörden
|
||||
CODELIST_BIOTOPES_ID = 974 # CL_EIV_Biotoptypen
|
||||
CODELIST_BIOTOPES_EXTRA_CODES_ID = 975 # CLZusatzbezeichnung
|
||||
CODELIST_LAW_ID = 1048 # CLVerfahrensrecht
|
||||
CODELIST_PROCESS_TYPE_ID = 44382 # CLVerfahrenstyp
|
||||
|
||||
CODELIST_COMPENSATION_HANDLER_ID = 1052 # CLEingreifer
|
||||
CODELIST_COMPENSATION_ACTION_ID = 1026 # CLMassnahmedetail
|
||||
CODELIST_COMPENSATION_ACTION_DETAIL_ID = 1035 # CLZusatzmerkmal
|
||||
CODELIST_COMPENSATION_ACTION_CLASS_ID = 1034 # CLMassnahmeklasse
|
||||
CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID = 1028 # CLMassnahmetyp, CEF and stuff
|
||||
CODELIST_COMPENSATION_FUNDING_ID = 1049 # CLKombimassnahme
|
||||
|
@ -2,7 +2,100 @@ from django.contrib import admin
|
||||
|
||||
from compensation.models import Compensation, CompensationAction, CompensationState, Payment, \
|
||||
EcoAccountDeduction, EcoAccount
|
||||
from konova.admin import BaseObjectAdmin
|
||||
from konova.admin import BaseObjectAdmin, BaseResourceAdmin
|
||||
|
||||
|
||||
class AbstractCompensationAdmin(BaseObjectAdmin):
|
||||
list_display = [
|
||||
"id",
|
||||
"identifier",
|
||||
"title",
|
||||
"created",
|
||||
"deleted",
|
||||
]
|
||||
|
||||
def get_fields(self, request, obj=None):
|
||||
return super().get_fields(request, obj) + [
|
||||
"identifier",
|
||||
"title",
|
||||
"comment",
|
||||
"after_states",
|
||||
"before_states",
|
||||
]
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
return super().get_readonly_fields(request, obj) + [
|
||||
"after_states",
|
||||
"before_states",
|
||||
]
|
||||
|
||||
|
||||
class CompensationAdmin(AbstractCompensationAdmin):
|
||||
autocomplete_fields = [
|
||||
"intervention",
|
||||
]
|
||||
|
||||
def get_fields(self, request, obj=None):
|
||||
return super().get_fields(request, obj) + [
|
||||
"is_cef",
|
||||
"is_coherence_keeping",
|
||||
"intervention",
|
||||
]
|
||||
|
||||
|
||||
class EcoAccountAdmin(AbstractCompensationAdmin):
|
||||
list_display = [
|
||||
"id",
|
||||
"identifier",
|
||||
"title",
|
||||
"created",
|
||||
"deleted",
|
||||
]
|
||||
|
||||
filter_horizontal = [
|
||||
"users"
|
||||
]
|
||||
|
||||
def get_fields(self, request, obj=None):
|
||||
return super().get_fields(request, obj) + [
|
||||
"deductable_surface",
|
||||
"users"
|
||||
]
|
||||
|
||||
|
||||
class PaymentAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
"id",
|
||||
"amount",
|
||||
"due_on",
|
||||
]
|
||||
|
||||
|
||||
class EcoAccountDeductionAdmin(BaseResourceAdmin):
|
||||
list_display = [
|
||||
"id",
|
||||
"account",
|
||||
"intervention",
|
||||
"surface",
|
||||
]
|
||||
search_fields = [
|
||||
"account__identifier",
|
||||
"account__title",
|
||||
"intervention__identifier",
|
||||
"intervention__title",
|
||||
"surface",
|
||||
]
|
||||
autocomplete_fields = [
|
||||
"account",
|
||||
"intervention",
|
||||
]
|
||||
|
||||
def get_fields(self, request, obj=None):
|
||||
return super().get_fields(request, obj) + [
|
||||
"account",
|
||||
"intervention",
|
||||
"surface",
|
||||
]
|
||||
|
||||
|
||||
class CompensationStateAdmin(admin.ModelAdmin):
|
||||
@ -23,44 +116,11 @@ class CompensationActionAdmin(admin.ModelAdmin):
|
||||
]
|
||||
|
||||
|
||||
class CompensationAdmin(BaseObjectAdmin):
|
||||
list_display = [
|
||||
"id",
|
||||
"identifier",
|
||||
"title",
|
||||
"created",
|
||||
"deleted",
|
||||
]
|
||||
|
||||
|
||||
class EcoAccountAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
"id",
|
||||
"identifier",
|
||||
"title",
|
||||
]
|
||||
|
||||
|
||||
class PaymentAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
"id",
|
||||
"amount",
|
||||
"due_on",
|
||||
]
|
||||
|
||||
|
||||
class EcoAccountDeductionAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
"id",
|
||||
"account",
|
||||
"intervention",
|
||||
"surface",
|
||||
]
|
||||
|
||||
|
||||
admin.site.register(Compensation, CompensationAdmin)
|
||||
admin.site.register(Payment, PaymentAdmin)
|
||||
admin.site.register(CompensationAction, CompensationActionAdmin)
|
||||
admin.site.register(CompensationState, CompensationStateAdmin)
|
||||
admin.site.register(EcoAccount, EcoAccountAdmin)
|
||||
admin.site.register(EcoAccountDeduction, EcoAccountDeductionAdmin)
|
||||
|
||||
# For a more cleaner admin interface these rarely used admin views are not important for deployment
|
||||
#admin.site.register(Payment, PaymentAdmin)
|
||||
#admin.site.register(CompensationAction, CompensationActionAdmin)
|
||||
#admin.site.register(CompensationState, CompensationStateAdmin)
|
@ -14,7 +14,8 @@ from django.shortcuts import render
|
||||
from django.utils.translation import pgettext_lazy as _con, gettext_lazy as _
|
||||
|
||||
from codelist.models import KonovaCode
|
||||
from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_COMPENSATION_ACTION_ID
|
||||
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 konova.contexts import BaseContext
|
||||
from konova.forms import BaseModalForm, NewDocumentForm
|
||||
@ -127,6 +128,23 @@ class NewStateModalForm(BaseModalForm):
|
||||
}
|
||||
),
|
||||
)
|
||||
biotope_extra = forms.ModelMultipleChoiceField(
|
||||
label=_("Biotope additional type"),
|
||||
label_suffix="",
|
||||
required=False,
|
||||
help_text=_("Select an additional biotope type"),
|
||||
queryset=KonovaCode.objects.filter(
|
||||
is_archived=False,
|
||||
is_leaf=True,
|
||||
code_lists__in=[CODELIST_BIOTOPES_EXTRA_CODES_ID],
|
||||
),
|
||||
widget=autocomplete.ModelSelect2Multiple(
|
||||
url="codes-biotope-extra-type-autocomplete",
|
||||
attrs={
|
||||
"data-placeholder": _("Biotope additional type"),
|
||||
}
|
||||
),
|
||||
)
|
||||
surface = forms.DecimalField(
|
||||
min_value=0.00,
|
||||
decimal_places=2,
|
||||
@ -283,6 +301,23 @@ class NewActionModalForm(BaseModalForm):
|
||||
}
|
||||
),
|
||||
)
|
||||
action_type_details = forms.ModelMultipleChoiceField(
|
||||
label=_("Action Type detail"),
|
||||
label_suffix="",
|
||||
required=False,
|
||||
help_text=_("Select the action type detail"),
|
||||
queryset=KonovaCode.objects.filter(
|
||||
is_archived=False,
|
||||
is_leaf=True,
|
||||
code_lists__in=[CODELIST_COMPENSATION_ACTION_DETAIL_ID],
|
||||
),
|
||||
widget=autocomplete.ModelSelect2Multiple(
|
||||
url="codes-compensation-action-detail-autocomplete",
|
||||
attrs={
|
||||
"data-placeholder": _("Action Type detail"),
|
||||
}
|
||||
),
|
||||
)
|
||||
unit = forms.ChoiceField(
|
||||
label=_("Unit"),
|
||||
label_suffix="",
|
||||
|
115
compensation/migrations/0001_initial.py
Normal file
115
compensation/migrations/0001_initial.py
Normal file
@ -0,0 +1,115 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-14 08:36
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
import konova.models.document
|
||||
import uuid
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Compensation',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('identifier', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('title', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('comment', models.TextField(blank=True, null=True)),
|
||||
('is_cef', models.BooleanField(blank=True, default=False, help_text="Flag if compensation is a 'CEF-Maßnahme'", null=True)),
|
||||
('is_coherence_keeping', models.BooleanField(blank=True, default=False, help_text="Flag if compensation is a 'Kohärenzsicherung'", null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CompensationAction',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('amount', models.FloatField()),
|
||||
('unit', models.CharField(blank=True, choices=[('cm', 'cm'), ('m', 'm'), ('km', 'km'), ('qm', 'm²'), ('ha', 'ha'), ('pcs', 'Pieces')], max_length=100, null=True)),
|
||||
('comment', models.TextField(blank=True, help_text='Additional comment', null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CompensationDocument',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('title', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('date_of_creation', models.DateField()),
|
||||
('comment', models.TextField()),
|
||||
('file', models.FileField(max_length=1000, upload_to=konova.models.document.generate_document_file_upload_path)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CompensationState',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('surface', models.FloatField()),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EcoAccount',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('identifier', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('title', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('comment', models.TextField(blank=True, null=True)),
|
||||
('access_token', models.CharField(blank=True, help_text='Used for sharing access', max_length=255, null=True)),
|
||||
('deductable_surface', models.FloatField(blank=True, default=0, help_text='Amount of deductable surface - can be lower than the total surface due to deduction limitations', null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EcoAccountDeduction',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('surface', models.FloatField(blank=True, help_text='Amount deducted (m²)', null=True, validators=[django.core.validators.MinValueValidator(limit_value=0.0)])),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EcoAccountDocument',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('title', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('date_of_creation', models.DateField()),
|
||||
('comment', models.TextField()),
|
||||
('file', models.FileField(max_length=1000, upload_to=konova.models.document.generate_document_file_upload_path)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Payment',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('amount', models.FloatField(validators=[django.core.validators.MinValueValidator(limit_value=0.0)])),
|
||||
('due_on', models.DateField(blank=True, null=True)),
|
||||
('comment', models.TextField(blank=True, help_text="Refers to german money transfer 'Verwendungszweck'", null=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['-amount'],
|
||||
},
|
||||
),
|
||||
]
|
227
compensation/migrations/0002_auto_20220114_0936.py
Normal file
227
compensation/migrations/0002_auto_20220114_0936.py
Normal file
@ -0,0 +1,227 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-14 08:36
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('intervention', '0001_initial'),
|
||||
('konova', '0001_initial'),
|
||||
('compensation', '0001_initial'),
|
||||
('user', '0001_initial'),
|
||||
('codelist', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='payment',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='payment',
|
||||
name='intervention',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='payments', to='intervention.intervention'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='payment',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccountdocument',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccountdocument',
|
||||
name='instance',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='compensation.ecoaccount'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccountdocument',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccountdeduction',
|
||||
name='account',
|
||||
field=models.ForeignKey(blank=True, help_text='Deducted from', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='deductions', to='compensation.ecoaccount'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccountdeduction',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccountdeduction',
|
||||
name='intervention',
|
||||
field=models.ForeignKey(blank=True, help_text='Deducted for', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='deductions', to='intervention.intervention'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccountdeduction',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='actions',
|
||||
field=models.ManyToManyField(blank=True, help_text="Refers to 'Maßnahmen'", to='compensation.CompensationAction'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='after_states',
|
||||
field=models.ManyToManyField(blank=True, help_text="Refers to 'Zielzustand Biotop'", related_name='_ecoaccount_after_states_+', to='compensation.CompensationState'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='before_states',
|
||||
field=models.ManyToManyField(blank=True, help_text="Refers to 'Ausgangszustand Biotop'", related_name='_ecoaccount_before_states_+', to='compensation.CompensationState'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='deadlines',
|
||||
field=models.ManyToManyField(blank=True, related_name='_ecoaccount_deadlines_+', to='konova.Deadline'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='deleted',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='geometry',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='konova.geometry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='legal',
|
||||
field=models.OneToOneField(blank=True, help_text='Holds data on legal dates or law', null=True, on_delete=django.db.models.deletion.SET_NULL, to='intervention.legal'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='log',
|
||||
field=models.ManyToManyField(blank=True, editable=False, help_text='Keeps all user actions of an object', to='user.UserActionLogEntry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='recorded',
|
||||
field=models.OneToOneField(blank=True, help_text='Holds data on user and timestamp of this action', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='responsible',
|
||||
field=models.OneToOneField(blank=True, help_text="Holds data on responsible organizations ('Zulassungsbehörde', 'Eintragungsstelle') and handler", null=True, on_delete=django.db.models.deletion.SET_NULL, to='intervention.responsibility'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ecoaccount',
|
||||
name='users',
|
||||
field=models.ManyToManyField(help_text='Users having access (data shared with)', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensationstate',
|
||||
name='biotope_type',
|
||||
field=models.ForeignKey(blank=True, limit_choices_to={'code_lists__in': [974], 'is_archived': False, 'is_selectable': True}, null=True, on_delete=django.db.models.deletion.SET_NULL, to='codelist.konovacode'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensationdocument',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensationdocument',
|
||||
name='instance',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='compensation.compensation'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensationdocument',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensationaction',
|
||||
name='action_type',
|
||||
field=models.ForeignKey(blank=True, limit_choices_to={'code_lists__in': [1026], 'is_archived': False, 'is_selectable': True}, null=True, on_delete=django.db.models.deletion.SET_NULL, to='codelist.konovacode'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensationaction',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensationaction',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensation',
|
||||
name='actions',
|
||||
field=models.ManyToManyField(blank=True, help_text="Refers to 'Maßnahmen'", to='compensation.CompensationAction'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensation',
|
||||
name='after_states',
|
||||
field=models.ManyToManyField(blank=True, help_text="Refers to 'Zielzustand Biotop'", related_name='_compensation_after_states_+', to='compensation.CompensationState'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensation',
|
||||
name='before_states',
|
||||
field=models.ManyToManyField(blank=True, help_text="Refers to 'Ausgangszustand Biotop'", related_name='_compensation_before_states_+', to='compensation.CompensationState'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensation',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensation',
|
||||
name='deadlines',
|
||||
field=models.ManyToManyField(blank=True, related_name='_compensation_deadlines_+', to='konova.Deadline'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensation',
|
||||
name='deleted',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensation',
|
||||
name='geometry',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='konova.geometry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensation',
|
||||
name='intervention',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='compensations', to='intervention.intervention'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensation',
|
||||
name='log',
|
||||
field=models.ManyToManyField(blank=True, editable=False, help_text='Keeps all user actions of an object', to='user.UserActionLogEntry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensation',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensation',
|
||||
name='responsible',
|
||||
field=models.OneToOneField(blank=True, help_text="Holds data on responsible organizations ('Zulassungsbehörde', 'Eintragungsstelle') and handler", null=True, on_delete=django.db.models.deletion.SET_NULL, to='intervention.responsibility'),
|
||||
),
|
||||
]
|
35
compensation/migrations/0003_auto_20220202_0846.py
Normal file
35
compensation/migrations/0003_auto_20220202_0846.py
Normal file
@ -0,0 +1,35 @@
|
||||
# Generated by Django 3.1.3 on 2022-02-02 07:46
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('codelist', '0001_initial'),
|
||||
('compensation', '0002_auto_20220114_0936'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='compensationaction',
|
||||
name='action_type_details',
|
||||
field=models.ManyToManyField(blank=True, limit_choices_to={'code_lists__in': [1035], 'is_archived': False, 'is_selectable': True}, related_name='_compensationaction_action_type_details_+', to='codelist.KonovaCode'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='compensationstate',
|
||||
name='biotope_type_details',
|
||||
field=models.ManyToManyField(blank=True, limit_choices_to={'code_lists__in': [975], 'is_archived': False, 'is_selectable': True}, related_name='_compensationstate_biotope_type_details_+', to='codelist.KonovaCode'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='compensationaction',
|
||||
name='action_type',
|
||||
field=models.ForeignKey(blank=True, limit_choices_to={'code_lists__in': [1026], 'is_archived': False, 'is_selectable': True}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='codelist.konovacode'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='compensationstate',
|
||||
name='biotope_type',
|
||||
field=models.ForeignKey(blank=True, limit_choices_to={'code_lists__in': [974], 'is_archived': False, 'is_selectable': True}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='codelist.konovacode'),
|
||||
),
|
||||
]
|
0
compensation/migrations/__init__.py
Normal file
0
compensation/migrations/__init__.py
Normal file
@ -9,7 +9,7 @@ from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from codelist.models import KonovaCode
|
||||
from codelist.settings import CODELIST_COMPENSATION_ACTION_ID
|
||||
from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_COMPENSATION_ACTION_DETAIL_ID
|
||||
from compensation.managers import CompensationActionManager
|
||||
from konova.models import BaseResource
|
||||
|
||||
@ -39,7 +39,18 @@ class CompensationAction(BaseResource):
|
||||
"code_lists__in": [CODELIST_COMPENSATION_ACTION_ID],
|
||||
"is_selectable": True,
|
||||
"is_archived": False,
|
||||
}
|
||||
},
|
||||
related_name='+',
|
||||
)
|
||||
action_type_details = models.ManyToManyField(
|
||||
KonovaCode,
|
||||
blank=True,
|
||||
limit_choices_to={
|
||||
"code_lists__in": [CODELIST_COMPENSATION_ACTION_DETAIL_ID],
|
||||
"is_selectable": True,
|
||||
"is_archived": False,
|
||||
},
|
||||
related_name='+',
|
||||
)
|
||||
amount = models.FloatField()
|
||||
unit = models.CharField(max_length=100, null=True, blank=True, choices=UnitChoices.choices)
|
||||
@ -48,7 +59,7 @@ class CompensationAction(BaseResource):
|
||||
objects = CompensationActionManager()
|
||||
|
||||
def __str__(self):
|
||||
return "{} | {} {}".format(self.action_type, self.amount, self.unit)
|
||||
return f"{self.action_type} | {self.amount} {self.unit}"
|
||||
|
||||
@property
|
||||
def unit_humanize(self):
|
||||
|
@ -95,6 +95,8 @@ class AbstractCompensation(BaseObject, GeoReferencedMixin):
|
||||
comment=form_data["comment"],
|
||||
created=user_action,
|
||||
)
|
||||
comp_action_details = form_data["action_type_details"]
|
||||
comp_action.action_type_details.set(comp_action_details)
|
||||
self.actions.add(comp_action)
|
||||
return comp_action
|
||||
|
||||
@ -114,6 +116,8 @@ class AbstractCompensation(BaseObject, GeoReferencedMixin):
|
||||
biotope_type=form_data["biotope_type"],
|
||||
surface=form_data["surface"],
|
||||
)
|
||||
state_additional_types = form_data["biotope_extra"]
|
||||
state.biotope_type_details.set(state_additional_types)
|
||||
if is_before_state:
|
||||
self.before_states.add(state)
|
||||
else:
|
||||
@ -310,17 +314,19 @@ class Compensation(AbstractCompensation, CEFMixin, CoherenceMixin):
|
||||
)
|
||||
return docs
|
||||
|
||||
def mark_as_edited(self, user: User, request: HttpRequest = None, edit_comment: str = None):
|
||||
def mark_as_edited(self, user: User, request: HttpRequest = None, edit_comment: str = None, reset_recorded: bool = True):
|
||||
""" Performs internal logic for setting the recordedd/checked state of the related intervention
|
||||
|
||||
Args:
|
||||
user (User): The performing user
|
||||
request (HttpRequest): The performing request
|
||||
edit_comment (str): Additional comment for the log entry
|
||||
reset_recorded (bool): Whether the record-state of the object should be reset
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
self.intervention.mark_as_edited(user, request, edit_comment)
|
||||
self.intervention.mark_as_edited(user, request, edit_comment, reset_recorded)
|
||||
|
||||
def is_ready_for_publish(self) -> bool:
|
||||
""" Not inherited by RecordableObjectMixin
|
||||
|
@ -46,7 +46,7 @@ class EcoAccount(AbstractCompensation, ShareableObjectMixin, RecordableObjectMix
|
||||
objects = EcoAccountManager()
|
||||
|
||||
def __str__(self):
|
||||
return "{}".format(self.identifier)
|
||||
return f"{self.identifier} ({self.title})"
|
||||
|
||||
def clean(self):
|
||||
# Deductable surface can not be larger than added states after surface
|
||||
|
@ -8,7 +8,7 @@ Created on: 16.11.21
|
||||
from django.db import models
|
||||
|
||||
from codelist.models import KonovaCode
|
||||
from codelist.settings import CODELIST_BIOTOPES_ID
|
||||
from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID
|
||||
from compensation.managers import CompensationStateManager
|
||||
from konova.models import UuidModel
|
||||
|
||||
@ -26,11 +26,22 @@ class CompensationState(UuidModel):
|
||||
"code_lists__in": [CODELIST_BIOTOPES_ID],
|
||||
"is_selectable": True,
|
||||
"is_archived": False,
|
||||
}
|
||||
},
|
||||
related_name='+',
|
||||
)
|
||||
biotope_type_details = models.ManyToManyField(
|
||||
KonovaCode,
|
||||
blank=True,
|
||||
limit_choices_to={
|
||||
"code_lists__in": [CODELIST_BIOTOPES_EXTRA_CODES_ID],
|
||||
"is_selectable": True,
|
||||
"is_archived": False,
|
||||
},
|
||||
related_name='+',
|
||||
)
|
||||
surface = models.FloatField()
|
||||
|
||||
objects = CompensationStateManager()
|
||||
|
||||
def __str__(self):
|
||||
return "{} | {} m²".format(self.biotope_type, self.surface)
|
||||
return f"{self.biotope_type} | {self.surface} m²"
|
||||
|
@ -24,9 +24,12 @@
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Action type' %}
|
||||
</th>
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Action type details' %}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{% trans 'Amount' context 'Compensation' %}
|
||||
</th>
|
||||
@ -46,9 +49,14 @@
|
||||
<td class="align-middle">
|
||||
{{ action.action_type }}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
{% for detail in action.action_type_details.all %}
|
||||
<div class="mb-2" title="{{detail}}">{{detail.long_name}}</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="align-middle">{{ action.amount|floatformat:2|intcomma }} {{ action.unit_humanize }}</td>
|
||||
<td class="align-middle">{{ action.comment|default_if_none:"" }}</td>
|
||||
<td>
|
||||
<td class="align-middle">
|
||||
{% if is_default_member and has_access %}
|
||||
<button data-form-url="{% url 'compensation:action-remove' obj.id action.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove action' %}">
|
||||
{% fa5_icon 'trash' %}
|
||||
|
@ -29,9 +29,12 @@
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Biotope type' %}
|
||||
</th>
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Biotope additional type' %}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{% trans 'Surface' %}
|
||||
</th>
|
||||
@ -48,8 +51,15 @@
|
||||
<td class="align-middle">
|
||||
{{ state.biotope_type }}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
{% for biotope_extra in state.biotope_type_details.all %}
|
||||
<div class="mb-2" title="{{ biotope_extra }}">
|
||||
{{ biotope_extra.long_name }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="align-middle">{{ state.surface|floatformat:2 }} m²</td>
|
||||
<td>
|
||||
<td class="align-middle">
|
||||
{% if is_default_member and has_access %}
|
||||
<button data-form-url="{% url 'compensation:state-remove' obj.id state.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove state' %}">
|
||||
{% fa5_icon 'trash' %}
|
||||
|
@ -29,9 +29,12 @@
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Biotope type' %}
|
||||
</th>
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Biotope additional type' %}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{% trans 'Surface' %}
|
||||
</th>
|
||||
@ -48,8 +51,15 @@
|
||||
<td class="align-middle">
|
||||
{{ state.biotope_type }}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
{% for biotope_extra in state.biotope_type_details.all %}
|
||||
<div class="mb-2" title="{{ biotope_extra }}">
|
||||
{{ biotope_extra.long_name }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="align-middle">{{ state.surface|floatformat:2 }} m²</td>
|
||||
<td>
|
||||
<td class="align-middle">
|
||||
{% if is_default_member and has_access %}
|
||||
<button data-form-url="{% url 'compensation:state-remove' obj.id state.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove state' %}">
|
||||
{% fa5_icon 'trash' %}
|
||||
|
@ -24,9 +24,12 @@
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Action type' %}
|
||||
</th>
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Action type details' %}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{% trans 'Amount' context 'Compensation' %}
|
||||
</th>
|
||||
@ -46,9 +49,14 @@
|
||||
<td class="align-middle">
|
||||
{{ action.action_type }}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
{% for detail in action.action_type_details.all %}
|
||||
<div class="mb-2" title="{{detail}}">{{detail.long_name}}</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="align-middle">{{ action.amount|floatformat:2|intcomma }} {{ action.unit_humanize }}</td>
|
||||
<td class="align-middle">{{ action.comment|default_if_none:"" }}</td>
|
||||
<td>
|
||||
<td class="align-middle">
|
||||
{% if is_default_member and has_access %}
|
||||
<button data-form-url="{% url 'compensation:acc-action-remove' obj.id action.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove action' %}">
|
||||
{% fa5_icon 'trash' %}
|
||||
|
@ -29,9 +29,12 @@
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Biotope type' %}
|
||||
</th>
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Biotope additional type' %}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{% trans 'Surface' %}
|
||||
</th>
|
||||
@ -48,8 +51,15 @@
|
||||
<td class="align-middle">
|
||||
{{ state.biotope_type }}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
{% for biotope_extra in state.biotope_type_details.all %}
|
||||
<div class="mb-2" title="{{ biotope_extra }}">
|
||||
{{ biotope_extra.long_name }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="align-middle">{{ state.surface|floatformat:2 }} m²</td>
|
||||
<td>
|
||||
<td class="align-middle">
|
||||
{% if is_default_member and has_access %}
|
||||
<button data-form-url="{% url 'compensation:acc-state-remove' obj.id state.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove state' %}">
|
||||
{% fa5_icon 'trash' %}
|
||||
|
@ -29,9 +29,12 @@
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Biotope type' %}
|
||||
</th>
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Biotope additional type' %}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{% trans 'Surface' %}
|
||||
</th>
|
||||
@ -48,8 +51,15 @@
|
||||
<td class="align-middle">
|
||||
{{ state.biotope_type }}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
{% for biotope_extra in state.biotope_type_details.all %}
|
||||
<div class="mb-2" title="{{ biotope_extra }}">
|
||||
{{ biotope_extra.long_name }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="align-middle">{{ state.surface|floatformat:2 }} m²</td>
|
||||
<td>
|
||||
<td class="align-middle">
|
||||
{% if is_default_member and has_access %}
|
||||
<button data-form-url="{% url 'compensation:acc-state-remove' obj.id state.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove state' %}">
|
||||
{% fa5_icon 'trash' %}
|
||||
|
13
ema/admin.py
13
ema/admin.py
@ -1,10 +1,17 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from compensation.admin import CompensationAdmin
|
||||
from compensation.admin import AbstractCompensationAdmin
|
||||
from ema.models import Ema
|
||||
|
||||
|
||||
class EmaAdmin(CompensationAdmin):
|
||||
pass
|
||||
class EmaAdmin(AbstractCompensationAdmin):
|
||||
filter_horizontal = [
|
||||
"users"
|
||||
]
|
||||
|
||||
def get_fields(self, request, obj=None):
|
||||
return super().get_fields(request, obj) + [
|
||||
"users"
|
||||
]
|
||||
|
||||
admin.site.register(Ema, EmaAdmin)
|
||||
|
42
ema/migrations/0001_initial.py
Normal file
42
ema/migrations/0001_initial.py
Normal file
@ -0,0 +1,42 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-14 08:36
|
||||
|
||||
from django.db import migrations, models
|
||||
import konova.models.document
|
||||
import uuid
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Ema',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('identifier', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('title', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('comment', models.TextField(blank=True, null=True)),
|
||||
('access_token', models.CharField(blank=True, help_text='Used for sharing access', max_length=255, null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EmaDocument',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('title', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('date_of_creation', models.DateField()),
|
||||
('comment', models.TextField()),
|
||||
('file', models.FileField(max_length=1000, upload_to=konova.models.document.generate_document_file_upload_path)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
97
ema/migrations/0002_auto_20220114_0936.py
Normal file
97
ema/migrations/0002_auto_20220114_0936.py
Normal file
@ -0,0 +1,97 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-14 08:36
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('intervention', '0001_initial'),
|
||||
('konova', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('compensation', '0002_auto_20220114_0936'),
|
||||
('user', '0001_initial'),
|
||||
('ema', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='emadocument',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='emadocument',
|
||||
name='instance',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='ema.ema'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='emadocument',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ema',
|
||||
name='actions',
|
||||
field=models.ManyToManyField(blank=True, help_text="Refers to 'Maßnahmen'", to='compensation.CompensationAction'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ema',
|
||||
name='after_states',
|
||||
field=models.ManyToManyField(blank=True, help_text="Refers to 'Zielzustand Biotop'", related_name='_ema_after_states_+', to='compensation.CompensationState'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ema',
|
||||
name='before_states',
|
||||
field=models.ManyToManyField(blank=True, help_text="Refers to 'Ausgangszustand Biotop'", related_name='_ema_before_states_+', to='compensation.CompensationState'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ema',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ema',
|
||||
name='deadlines',
|
||||
field=models.ManyToManyField(blank=True, related_name='_ema_deadlines_+', to='konova.Deadline'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ema',
|
||||
name='deleted',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ema',
|
||||
name='geometry',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='konova.geometry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ema',
|
||||
name='log',
|
||||
field=models.ManyToManyField(blank=True, editable=False, help_text='Keeps all user actions of an object', to='user.UserActionLogEntry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ema',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ema',
|
||||
name='recorded',
|
||||
field=models.OneToOneField(blank=True, help_text='Holds data on user and timestamp of this action', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ema',
|
||||
name='responsible',
|
||||
field=models.OneToOneField(blank=True, help_text="Holds data on responsible organizations ('Zulassungsbehörde', 'Eintragungsstelle') and handler", null=True, on_delete=django.db.models.deletion.SET_NULL, to='intervention.responsibility'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ema',
|
||||
name='users',
|
||||
field=models.ManyToManyField(help_text='Users having access (data shared with)', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
0
ema/migrations/__init__.py
Normal file
0
ema/migrations/__init__.py
Normal file
@ -24,9 +24,12 @@
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Action type' %}
|
||||
</th>
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Action type details' %}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{% trans 'Amount' context 'Compensation' %}
|
||||
</th>
|
||||
@ -44,9 +47,14 @@
|
||||
<td class="align-middle">
|
||||
{{ action.action_type }}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
{% for detail in action.action_type_details.all %}
|
||||
<div class="mb-2" title="{{detail}}">{{detail.long_name}}</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="align-middle">{{ action.amount|floatformat:2|intcomma }} {{ action.unit_humanize }}</td>
|
||||
<td class="align-middle">{{ action.comment|default_if_none:"" }}</td>
|
||||
<td>
|
||||
<td class="align-middle">
|
||||
{% if is_default_member and has_access %}
|
||||
<button data-form-url="{% url 'ema:action-remove' obj.id action.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove action' %}">
|
||||
{% fa5_icon 'trash' %}
|
||||
|
@ -29,9 +29,12 @@
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Biotope type' %}
|
||||
</th>
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Biotope additional type' %}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{% trans 'Surface' %}
|
||||
</th>
|
||||
@ -46,8 +49,15 @@
|
||||
<td class="align-middle">
|
||||
{{ state.biotope_type }}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
{% for biotope_extra in state.biotope_type_details.all %}
|
||||
<div class="mb-2" title="{{ biotope_extra }}">
|
||||
{{ biotope_extra.long_name }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="align-middle">{{ state.surface|floatformat:2 }} m²</td>
|
||||
<td>
|
||||
<td class="align-middle">
|
||||
{% if is_default_member and has_access %}
|
||||
<button data-form-url="{% url 'ema:state-remove' obj.id state.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove state' %}">
|
||||
{% fa5_icon 'trash' %}
|
||||
|
@ -29,9 +29,12 @@
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Biotope type' %}
|
||||
</th>
|
||||
<th class="w-25" scope="col">
|
||||
{% trans 'Biotope additional type' %}
|
||||
</th>
|
||||
<th scope="col">
|
||||
{% trans 'Surface' %}
|
||||
</th>
|
||||
@ -46,8 +49,15 @@
|
||||
<td class="align-middle">
|
||||
{{ state.biotope_type }}
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
{% for biotope_extra in state.biotope_type_details.all %}
|
||||
<div class="mb-2" title="{{ biotope_extra }}">
|
||||
{{ biotope_extra.long_name }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td class="align-middle">{{ state.surface|floatformat:2 }} m²</td>
|
||||
<td>
|
||||
<td class="align-middle">
|
||||
{% if is_default_member and has_access %}
|
||||
<button data-form-url="{% url 'ema:state-remove' obj.id state.id %}" class="btn btn-default btn-modal" title="{% trans 'Remove state' %}">
|
||||
{% fa5_icon 'trash' %}
|
||||
|
@ -13,6 +13,26 @@ class InterventionAdmin(BaseObjectAdmin):
|
||||
"deleted",
|
||||
]
|
||||
|
||||
filter_horizontal = [
|
||||
"users"
|
||||
]
|
||||
|
||||
def get_fields(self, request, obj=None):
|
||||
return super().get_fields(request, obj) + [
|
||||
"identifier",
|
||||
"title",
|
||||
"comment",
|
||||
"checked",
|
||||
"recorded",
|
||||
"users",
|
||||
]
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
return super().get_readonly_fields(request, obj) + [
|
||||
"checked",
|
||||
"recorded",
|
||||
]
|
||||
|
||||
|
||||
class InterventionDocumentAdmin(AbstractDocumentAdmin):
|
||||
pass
|
||||
@ -48,7 +68,9 @@ class RevocationAdmin(admin.ModelAdmin):
|
||||
|
||||
|
||||
admin.site.register(Intervention, InterventionAdmin)
|
||||
admin.site.register(Responsibility, ResponsibilityAdmin)
|
||||
admin.site.register(Legal, LegalAdmin)
|
||||
admin.site.register(Revocation, RevocationAdmin)
|
||||
admin.site.register(InterventionDocument, InterventionDocumentAdmin)
|
||||
|
||||
# Outcommented for a cleaner admin backend on production
|
||||
#admin.site.register(Responsibility, ResponsibilityAdmin)
|
||||
#admin.site.register(Legal, LegalAdmin)
|
||||
#admin.site.register(Revocation, RevocationAdmin)
|
||||
#admin.site.register(InterventionDocument, InterventionDocumentAdmin)
|
||||
|
@ -370,7 +370,7 @@ class NewDeductionModalForm(BaseModalForm):
|
||||
|
||||
def save(self):
|
||||
deduction = self.instance.add_deduction(self)
|
||||
self.instance.mark_as_edited(self.user, self.request)
|
||||
self.instance.mark_as_edited(self.user, self.request, reset_recorded=False)
|
||||
return deduction
|
||||
|
||||
|
||||
|
89
intervention/migrations/0001_initial.py
Normal file
89
intervention/migrations/0001_initial.py
Normal file
@ -0,0 +1,89 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-14 08:36
|
||||
|
||||
from django.db import migrations, models
|
||||
import konova.models.document
|
||||
import uuid
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Intervention',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('identifier', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('title', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('comment', models.TextField(blank=True, null=True)),
|
||||
('access_token', models.CharField(blank=True, help_text='Used for sharing access', max_length=255, null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='InterventionDocument',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('title', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('date_of_creation', models.DateField()),
|
||||
('comment', models.TextField()),
|
||||
('file', models.FileField(max_length=1000, upload_to=konova.models.document.generate_document_file_upload_path)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Legal',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('registration_date', models.DateField(blank=True, help_text="Refers to 'Zugelassen am'", null=True)),
|
||||
('binding_date', models.DateField(blank=True, help_text="Refers to 'Bestandskraft am'", null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Responsibility',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('registration_file_number', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('conservation_file_number', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('handler', models.CharField(blank=True, help_text="Refers to 'Eingriffsverursacher' or 'Maßnahmenträger'", max_length=500, null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Revocation',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('date', models.DateField(blank=True, help_text='Revocation from', null=True)),
|
||||
('comment', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RevocationDocument',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('title', models.CharField(blank=True, max_length=500, null=True)),
|
||||
('date_of_creation', models.DateField()),
|
||||
('comment', models.TextField()),
|
||||
('file', models.FileField(max_length=1000, upload_to=konova.models.document.generate_document_file_upload_path)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
136
intervention/migrations/0002_auto_20220114_0936.py
Normal file
136
intervention/migrations/0002_auto_20220114_0936.py
Normal file
@ -0,0 +1,136 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-14 08:36
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('intervention', '0001_initial'),
|
||||
('konova', '0001_initial'),
|
||||
('user', '0001_initial'),
|
||||
('codelist', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='revocationdocument',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='revocationdocument',
|
||||
name='instance',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='document', to='intervention.revocation'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='revocationdocument',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='revocation',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='revocation',
|
||||
name='legal',
|
||||
field=models.ForeignKey(help_text="Refers to 'Widerspruch am'", on_delete=django.db.models.deletion.CASCADE, related_name='revocations', to='intervention.legal'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='revocation',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='responsibility',
|
||||
name='conservation_office',
|
||||
field=models.ForeignKey(blank=True, limit_choices_to={'code_lists__in': [907], 'is_archived': False, 'is_selectable': True}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='codelist.konovacode'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='responsibility',
|
||||
name='registration_office',
|
||||
field=models.ForeignKey(blank=True, limit_choices_to={'code_lists__in': [1053], 'is_archived': False, 'is_selectable': True}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='codelist.konovacode'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='legal',
|
||||
name='laws',
|
||||
field=models.ManyToManyField(blank=True, limit_choices_to={'code_lists__in': [1048], 'is_archived': False, 'is_selectable': True}, to='codelist.KonovaCode'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='legal',
|
||||
name='process_type',
|
||||
field=models.ForeignKey(blank=True, limit_choices_to={'code_lists__in': [44382], 'is_archived': False, 'is_selectable': True}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='codelist.konovacode'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='interventiondocument',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='interventiondocument',
|
||||
name='instance',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='intervention.intervention'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='interventiondocument',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='intervention',
|
||||
name='checked',
|
||||
field=models.OneToOneField(blank=True, help_text='Holds data on user and timestamp of this action', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='intervention',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='intervention',
|
||||
name='deleted',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='intervention',
|
||||
name='geometry',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='konova.geometry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='intervention',
|
||||
name='legal',
|
||||
field=models.OneToOneField(blank=True, help_text='Holds data on legal dates or law', null=True, on_delete=django.db.models.deletion.SET_NULL, to='intervention.legal'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='intervention',
|
||||
name='log',
|
||||
field=models.ManyToManyField(blank=True, editable=False, help_text='Keeps all user actions of an object', to='user.UserActionLogEntry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='intervention',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='intervention',
|
||||
name='recorded',
|
||||
field=models.OneToOneField(blank=True, help_text='Holds data on user and timestamp of this action', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='intervention',
|
||||
name='responsible',
|
||||
field=models.OneToOneField(blank=True, help_text="Holds data on responsible organizations ('Zulassungsbehörde', 'Eintragungsstelle')", null=True, on_delete=django.db.models.deletion.SET_NULL, to='intervention.responsibility'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='intervention',
|
||||
name='users',
|
||||
field=models.ManyToManyField(help_text='Users having access (data shared with)', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
0
intervention/migrations/__init__.py
Normal file
0
intervention/migrations/__init__.py
Normal file
@ -51,7 +51,7 @@ class Intervention(BaseObject, ShareableObjectMixin, RecordableObjectMixin, Chec
|
||||
objects = InterventionManager()
|
||||
|
||||
def __str__(self):
|
||||
return "{} ({})".format(self.identifier, self.title)
|
||||
return f"{self.identifier} ({self.title})"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
""" Custom save functionality
|
||||
@ -250,17 +250,20 @@ class Intervention(BaseObject, ShareableObjectMixin, RecordableObjectMixin, Chec
|
||||
)
|
||||
return deduction
|
||||
|
||||
def mark_as_edited(self, performing_user: User, request: HttpRequest = None, edit_comment: str = None):
|
||||
def mark_as_edited(self, performing_user: User, request: HttpRequest = None, edit_comment: str = None, reset_recorded: bool = True):
|
||||
""" In case the object or a related object changed, internal processes need to be started, such as
|
||||
unrecord and uncheck
|
||||
|
||||
Args:
|
||||
performing_user (User): The user which performed the editing action
|
||||
request (HttpRequest): The used request for this action
|
||||
edit_comment (str): Additional comment for the log entry
|
||||
reset_recorded (bool): Whether the record-state of the object should be reset
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
super().mark_as_edited(performing_user, request)
|
||||
super().mark_as_edited(performing_user, request, edit_comment, reset_recorded)
|
||||
if self.checked:
|
||||
self.set_unchecked()
|
||||
|
||||
|
@ -62,16 +62,35 @@ class DeadlineAdmin(admin.ModelAdmin):
|
||||
]
|
||||
|
||||
|
||||
class BaseObjectAdmin(admin.ModelAdmin):
|
||||
class BaseResourceAdmin(admin.ModelAdmin):
|
||||
fields = [
|
||||
"created",
|
||||
"modified",
|
||||
]
|
||||
readonly_fields = [
|
||||
"modified",
|
||||
"deleted",
|
||||
"created",
|
||||
]
|
||||
|
||||
|
||||
admin.site.register(Geometry, GeometryAdmin)
|
||||
admin.site.register(Parcel, ParcelAdmin)
|
||||
admin.site.register(District, DistrictAdmin)
|
||||
admin.site.register(GeometryConflict, GeometryConflictAdmin)
|
||||
admin.site.register(Deadline, DeadlineAdmin)
|
||||
class BaseObjectAdmin(BaseResourceAdmin):
|
||||
search_fields = [
|
||||
"identifier",
|
||||
"title",
|
||||
]
|
||||
|
||||
def get_fields(self, request, obj=None):
|
||||
return super().get_fields(request, obj) + ["deleted"]
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
return super().get_readonly_fields(request, obj) + [
|
||||
"deleted",
|
||||
]
|
||||
|
||||
|
||||
# Outcommented for a cleaner admin backend on production
|
||||
#admin.site.register(Geometry, GeometryAdmin)
|
||||
#admin.site.register(Parcel, ParcelAdmin)
|
||||
#admin.site.register(District, DistrictAdmin)
|
||||
#admin.site.register(GeometryConflict, GeometryConflictAdmin)
|
||||
#admin.site.register(Deadline, DeadlineAdmin)
|
||||
|
@ -11,7 +11,8 @@ 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_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, CODELIST_PROCESS_TYPE_ID, \
|
||||
CODELIST_BIOTOPES_EXTRA_CODES_ID, CODELIST_COMPENSATION_ACTION_DETAIL_ID
|
||||
from compensation.models import EcoAccount
|
||||
from intervention.models import Intervention
|
||||
|
||||
@ -94,6 +95,7 @@ class KonovaCodeAutocomplete(Select2GroupQuerySetView):
|
||||
* c: Search inside a special codelist
|
||||
|
||||
"""
|
||||
paginate_by = 50
|
||||
|
||||
def order_by(self, qs):
|
||||
""" Orders by a predefined value
|
||||
@ -162,6 +164,24 @@ class CompensationActionCodeAutocomplete(KonovaCodeAutocomplete):
|
||||
)
|
||||
|
||||
|
||||
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(
|
||||
"parent__long_name"
|
||||
)
|
||||
|
||||
|
||||
class BiotopeCodeAutocomplete(KonovaCodeAutocomplete):
|
||||
"""
|
||||
Due to limitations of the django dal package, we need to subclass for each code list
|
||||
@ -192,6 +212,37 @@ class BiotopeCodeAutocomplete(KonovaCodeAutocomplete):
|
||||
return f"{result.long_name} ({result.short_name})"
|
||||
|
||||
|
||||
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(
|
||||
"parent__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
|
||||
|
78
konova/migrations/0001_initial.py
Normal file
78
konova/migrations/0001_initial.py
Normal file
@ -0,0 +1,78 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-14 08:36
|
||||
|
||||
import django.contrib.gis.db.models.fields
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Deadline',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('type', models.CharField(blank=True, choices=[('finished', 'Finished'), ('maintain', 'Maintain'), ('control', 'Control'), ('other', 'Other')], max_length=255, null=True)),
|
||||
('date', models.DateField(blank=True, null=True)),
|
||||
('comment', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='District',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('gmnd', models.CharField(blank=True, help_text='Gemeinde', max_length=1000, null=True)),
|
||||
('krs', models.CharField(blank=True, help_text='Kreis', max_length=1000, null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Geometry',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Parcel',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('gmrkng', models.CharField(blank=True, help_text='Gemarkung', max_length=1000, null=True)),
|
||||
('flrstck_nnr', models.CharField(blank=True, help_text='Flurstücksnenner', max_length=1000, null=True)),
|
||||
('flrstck_zhlr', models.CharField(blank=True, help_text='Flurstückszähler', max_length=1000, null=True)),
|
||||
('flr', models.CharField(blank=True, help_text='Flur', max_length=1000, null=True)),
|
||||
('updated_on', models.DateTimeField(auto_now_add=True)),
|
||||
('district', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='parcels', to='konova.district')),
|
||||
('geometries', models.ManyToManyField(blank=True, related_name='parcels', to='konova.Geometry')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='GeometryConflict',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('detected_on', models.DateTimeField(auto_now_add=True, null=True)),
|
||||
('affected_geometry', models.ForeignKey(help_text='The geometry which came first', on_delete=django.db.models.deletion.CASCADE, related_name='conflicted_by_geometries', to='konova.geometry')),
|
||||
('conflicting_geometry', models.ForeignKey(help_text='The geometry which came second', on_delete=django.db.models.deletion.CASCADE, related_name='conflicts_geometries', to='konova.geometry')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
37
konova/migrations/0002_auto_20220114_0936.py
Normal file
37
konova/migrations/0002_auto_20220114_0936.py
Normal file
@ -0,0 +1,37 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-14 08:36
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('user', '0001_initial'),
|
||||
('konova', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='geometry',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='geometry',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='deadline',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='deadline',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
]
|
0
konova/migrations/__init__.py
Normal file
0
konova/migrations/__init__.py
Normal file
@ -262,12 +262,15 @@ class RecordableObjectMixin(models.Model):
|
||||
|
||||
return action
|
||||
|
||||
def mark_as_edited(self, performing_user: User, request: HttpRequest = None, edit_comment: str = None):
|
||||
def mark_as_edited(self, performing_user: User, request: HttpRequest = None, edit_comment: str = None, reset_recorded: bool = True):
|
||||
""" In case the object or a related object changed, internal processes need to be started, such as
|
||||
unrecord and uncheck
|
||||
|
||||
Args:
|
||||
performing_user (User): The user which performed the editing action
|
||||
request (HttpRequest): The used request for this action
|
||||
edit_comment (str): Additional comment for the log entry
|
||||
reset_recorded (bool): Whether the record-state of the object should be reset
|
||||
|
||||
Returns:
|
||||
|
||||
@ -277,7 +280,7 @@ class RecordableObjectMixin(models.Model):
|
||||
self.log.add(action)
|
||||
self.save()
|
||||
|
||||
if self.recorded:
|
||||
if self.recorded and reset_recorded:
|
||||
action = self.set_unrecorded(performing_user)
|
||||
self.log.add(action)
|
||||
if request:
|
||||
|
@ -11,14 +11,15 @@ https://docs.djangoproject.com/en/3.1/ref/settings/
|
||||
"""
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# Load other settings
|
||||
# Load sub settings
|
||||
# If new settings need to be added as general settings to the whole project, outsource them into new xy_settings files!
|
||||
from konova.sub_settings.django_settings import *
|
||||
from konova.sub_settings.proxy_settings import *
|
||||
from konova.sub_settings.sso_settings import *
|
||||
from konova.sub_settings.table_settings import *
|
||||
from konova.sub_settings.lanis_settings import *
|
||||
from konova.sub_settings.wfs_parcel_settings import *
|
||||
|
||||
proxy = "CHANGE_ME"
|
||||
PROXIES = {
|
||||
"http": proxy,
|
||||
"https": proxy,
|
||||
}
|
||||
|
||||
# ALLOWED FILE UPLOAD DEFINITIONS
|
||||
# Default: Upload into upper folder of code
|
||||
@ -37,57 +38,7 @@ EMA_DOC_PATH = BASE_DOC_PATH + "ema/{}/"
|
||||
# German DateTime string format
|
||||
STRF_DATE_TIME = "%d.%m.%Y %H:%M:%S"
|
||||
|
||||
# Tables
|
||||
RESULTS_PER_PAGE_PARAM = "rpp"
|
||||
PAGE_PARAM = "page"
|
||||
PAGE_SIZE_OPTIONS = [5, 10, 15, 20, 25, 50, 100]
|
||||
PAGE_SIZE_OPTIONS_TUPLES = [
|
||||
(5, 5),
|
||||
(10, 10),
|
||||
(15, 15),
|
||||
(20, 20),
|
||||
(25, 25),
|
||||
(50, 50),
|
||||
(100, 100),
|
||||
]
|
||||
PAGE_SIZE_DEFAULT = 5
|
||||
PAGE_SIZE_MAX = 100
|
||||
PAGE_DEFAULT = 1
|
||||
|
||||
# SSO settings
|
||||
SSO_SERVER_BASE = f"http://{os.environ.get('SSO_HOST')}/"
|
||||
SSO_SERVER = f"{SSO_SERVER_BASE}sso/"
|
||||
SSO_PRIVATE_KEY = "QuziFeih7U8DZvQQ1riPv2MXz0ZABupHED9wjoqZAqeMQaqkqTfxJDRXgSIyASwJ"
|
||||
SSO_PUBLIC_KEY = "AGGK7E8eT5X5u2GD38ygGG3GpAefmIldJiiWW7gldRPqCG1CzmUfGdvPSGDbEY2n"
|
||||
|
||||
# MAPS
|
||||
DEFAULT_LAT = 50.00
|
||||
DEFAULT_LON = 7.00
|
||||
DEFAULT_ZOOM = 8.0
|
||||
DEFAULT_SRID = 4326
|
||||
DEFAULT_SRID_RLP = 25832
|
||||
|
||||
# GROUPS
|
||||
DEFAULT_GROUP = "Default"
|
||||
ZB_GROUP = "Registration office"
|
||||
ETS_GROUP = "Conservation office"
|
||||
|
||||
# Needed to redirect to LANIS
|
||||
## Values to be inserted are [zoom_level, x_coord, y_coord]
|
||||
LANIS_LINK_TEMPLATE = "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/index.php?lang=de&zl={}&x={}&y={}&bl=tk_rlp_tms_grau&bo=1&lo=0.8,0.8,0.8,0.6,0.8,0.8,0.8,0.8,0.8&layers=eiv_f,eiv_l,eiv_p,kom_f,kom_l,kom_p,oek_f,ema_f,mae&service=kartendienste_naturschutz"
|
||||
## This look up table (LUT) defines different zoom levels on the size of the calculate area of a geometry.
|
||||
LANIS_ZOOM_LUT = {
|
||||
1000000000: 6,
|
||||
100000000: 10,
|
||||
10000000: 17,
|
||||
1000000: 20,
|
||||
100000: 25,
|
||||
10000: 28,
|
||||
1000: 30,
|
||||
500: 31,
|
||||
}
|
||||
|
||||
# Parcel WFS settings
|
||||
PARCEL_WFS_BASE_URL = "https://www.geoportal.rlp.de/registry/wfs/519"
|
||||
PARCEL_WFS_USER = "ksp"
|
||||
PARCEL_WFS_PW = "CHANGE_ME"
|
@ -121,18 +121,12 @@ a {
|
||||
|
||||
.card{
|
||||
margin: 0 0.5rem 0.5rem 0;
|
||||
font-size: 12px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.card:hover{
|
||||
box-shadow: 1px 1px 3px var(--rlp-gray-light);
|
||||
}
|
||||
|
||||
.card .card-text{
|
||||
font-size: 12px;
|
||||
max-height: 150px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.qs-box{
|
||||
background-color: var(--rlp-red);
|
||||
color: white;
|
||||
@ -215,6 +209,11 @@ Overwrites bootstrap .btn:focus box shadow color
|
||||
color: var(--rlp-red);
|
||||
}
|
||||
|
||||
.scroll-150{
|
||||
max-height: 150px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scroll-300{
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
@ -230,3 +229,6 @@ No other approach worked to get the autocomplete fields to full width of parent
|
||||
.select2-results__option--highlighted{
|
||||
background-color: var(--rlp-red) !important;
|
||||
}
|
||||
.select2-container--default .select2-results > .select2-results__options{
|
||||
max-height: 500px !important;
|
||||
}
|
@ -32,6 +32,10 @@ SECRET_KEY = '5=9-)2)h$u9=!zrhia9=lj-2#cpcb8=#$7y+)l$5tto$3q(n_+'
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ADMINS = [
|
||||
('KSP-Servicestelle', 'ksp-servicestelle@sgdnord.rlp.de'),
|
||||
]
|
||||
|
||||
ALLOWED_HOSTS = [
|
||||
"127.0.0.1",
|
||||
"localhost",
|
||||
@ -212,41 +216,8 @@ if DEBUG:
|
||||
EMAIL_FILE_PATH = '/tmp/app-messages'
|
||||
|
||||
DEFAULT_FROM_EMAIL = "no-reply@ksp.de" # The default email address for the 'from' element
|
||||
SERVER_EMAIL = DEFAULT_FROM_EMAIL # The default email sender address, which is used by Django to send errors via mail
|
||||
EMAIL_HOST = os.environ.get('SMTP_HOST')
|
||||
EMAIL_REPLY_TO = os.environ.get('SMTP_REAL_REPLY_MAIL')
|
||||
SUPPORT_MAIL_RECIPIENT = EMAIL_REPLY_TO
|
||||
EMAIL_PORT = os.environ.get('SMTP_PORT')
|
||||
|
||||
# LOGGING
|
||||
BASIC_LOGGER = "logger"
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'verbose': {
|
||||
'format': '{levelname} {asctime} {module}: {message}',
|
||||
'style': '{',
|
||||
},
|
||||
'simple': {
|
||||
'format': '{levelname} {message}',
|
||||
'style': '{',
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'log_to_file': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.handlers.RotatingFileHandler',
|
||||
'filename': '{}/logs/error.log'.format(BASE_DIR),
|
||||
'maxBytes': 1024*1024*5, # 5 MB
|
||||
'backupCount': 5,
|
||||
'formatter': 'verbose',
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
BASIC_LOGGER: {
|
||||
'handlers': ['log_to_file'],
|
||||
'level': 'INFO',
|
||||
'propagate': True,
|
||||
},
|
||||
},
|
||||
}
|
29
konova/sub_settings/lanis_settings.py
Normal file
29
konova/sub_settings/lanis_settings.py
Normal file
@ -0,0 +1,29 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 31.01.22
|
||||
|
||||
"""
|
||||
|
||||
# MAPS
|
||||
DEFAULT_LAT = 50.00
|
||||
DEFAULT_LON = 7.00
|
||||
DEFAULT_ZOOM = 8.0
|
||||
DEFAULT_SRID = 4326
|
||||
DEFAULT_SRID_RLP = 25832
|
||||
|
||||
# Needed to redirect to LANIS
|
||||
## Values to be inserted are [zoom_level, x_coord, y_coord]
|
||||
LANIS_LINK_TEMPLATE = "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/index.php?lang=de&zl={}&x={}&y={}&bl=tk_rlp_tms_grau&bo=1&lo=0.8,0.8,0.8,0.6,0.8,0.8,0.8,0.8,0.8&layers=eiv_f,eiv_l,eiv_p,kom_f,kom_l,kom_p,oek_f,ema_f,mae&service=kartendienste_naturschutz"
|
||||
## This look up table (LUT) defines different zoom levels on the size of the calculate area of a geometry.
|
||||
LANIS_ZOOM_LUT = {
|
||||
1000000000: 6,
|
||||
100000000: 10,
|
||||
10000000: 17,
|
||||
1000000: 20,
|
||||
100000: 25,
|
||||
10000: 28,
|
||||
1000: 30,
|
||||
500: 31,
|
||||
}
|
13
konova/sub_settings/proxy_settings.py
Normal file
13
konova/sub_settings/proxy_settings.py
Normal file
@ -0,0 +1,13 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 31.01.22
|
||||
|
||||
"""
|
||||
|
||||
proxy = ""
|
||||
PROXIES = {
|
||||
"http": proxy,
|
||||
"https": proxy,
|
||||
}
|
13
konova/sub_settings/sso_settings.py
Normal file
13
konova/sub_settings/sso_settings.py
Normal file
@ -0,0 +1,13 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 31.01.22
|
||||
|
||||
"""
|
||||
|
||||
# SSO settings
|
||||
SSO_SERVER_BASE = "http://127.0.0.1:8000/"
|
||||
SSO_SERVER = f"{SSO_SERVER_BASE}sso/"
|
||||
SSO_PRIVATE_KEY = "QuziFeih7U8DZvQQ1riPv2MXz0ZABupHED9wjoqZAqeMQaqkqTfxJDRXgSIyASwJ"
|
||||
SSO_PUBLIC_KEY = "AGGK7E8eT5X5u2GD38ygGG3GpAefmIldJiiWW7gldRPqCG1CzmUfGdvPSGDbEY2n"
|
24
konova/sub_settings/table_settings.py
Normal file
24
konova/sub_settings/table_settings.py
Normal file
@ -0,0 +1,24 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 31.01.22
|
||||
|
||||
"""
|
||||
|
||||
# Tables
|
||||
RESULTS_PER_PAGE_PARAM = "rpp"
|
||||
PAGE_PARAM = "page"
|
||||
PAGE_SIZE_OPTIONS = [5, 10, 15, 20, 25, 50, 100]
|
||||
PAGE_SIZE_OPTIONS_TUPLES = [
|
||||
(5, 5),
|
||||
(10, 10),
|
||||
(15, 15),
|
||||
(20, 20),
|
||||
(25, 25),
|
||||
(50, 50),
|
||||
(100, 100),
|
||||
]
|
||||
PAGE_SIZE_DEFAULT = 5
|
||||
PAGE_SIZE_MAX = 100
|
||||
PAGE_DEFAULT = 1
|
12
konova/sub_settings/wfs_parcel_settings.py
Normal file
12
konova/sub_settings/wfs_parcel_settings.py
Normal file
@ -0,0 +1,12 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 31.01.22
|
||||
|
||||
"""
|
||||
|
||||
# Parcel WFS settings
|
||||
PARCEL_WFS_BASE_URL = "https://www.geoportal.rlp.de/registry/wfs/519"
|
||||
PARCEL_WFS_USER = "ksp"
|
||||
PARCEL_WFS_PW = "CHANGE_ME"
|
@ -7,123 +7,13 @@
|
||||
<div id="quickstart" class="col-md px-3">
|
||||
<div class="row px-3">
|
||||
<div class="col-md">
|
||||
<h4>
|
||||
{% trans 'Intervention' %}
|
||||
</h4>
|
||||
<div class="row">
|
||||
<a href="{% url 'intervention:index' %}">
|
||||
<div class="col-sm-5">
|
||||
<div class="qs-box d-flex justify-content-center align-items-center">
|
||||
{% fa5_icon 'pencil-ruler' %}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="col-sm">
|
||||
<div class="col-md mb-2">
|
||||
<div>{% trans 'Total' %}</div>
|
||||
<div class="class badge badge-pill rlp-gd-outline w-100">{{total_intervention_count|intcomma}}</div>
|
||||
{% include 'konova/includes/quickstart/interventions.html' %}
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div>{% trans 'Shared with you' %}</div>
|
||||
<div class="class badge badge-pill rlp-gd-outline w-100">{{user_intervention_count|intcomma}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include 'konova/includes/quickstart/compensations.html' %}
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div class="row my-1">
|
||||
<a href="{% url 'intervention:new' %}">
|
||||
<button class="btn btn-default">{% fa5_icon 'plus' %} {% trans 'Create' %}</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<a href="{% url 'intervention:index' %}">
|
||||
<button class="btn btn-default">{% fa5_icon 'eye' %} {% trans 'Show' %}</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<div class="col-md">
|
||||
<h4>
|
||||
{% trans 'Compensation' %}
|
||||
</h4>
|
||||
<div class="row">
|
||||
<a href="{% url 'compensation:index' %}">
|
||||
<div class="col-sm-5">
|
||||
<div class="qs-box d-flex justify-content-center align-items-center">
|
||||
{% fa5_icon 'leaf' %}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="col-sm">
|
||||
<div class="col-md mb-2">
|
||||
<div>{% trans 'Total' %}</div>
|
||||
<div class="class badge badge-pill rlp-gd-outline w-100">{{total_compensation_count|intcomma}}</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div>{% trans 'Shared with you' %}</div>
|
||||
<div class="class badge badge-pill rlp-gd-outline w-100">{{user_compensation_count|intcomma}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div class="row my-1">
|
||||
<a href="{% url 'compensation:new' %}">
|
||||
<button class="btn btn-default">{% fa5_icon 'plus' %} {% trans 'Create' %}</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<a href="{% url 'compensation:index' %}">
|
||||
<button class="btn btn-default">{% fa5_icon 'eye' %} {% trans 'Show' %}</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-md">
|
||||
<h4>
|
||||
{% trans 'Eco-account' %}
|
||||
</h4>
|
||||
<div class="row">
|
||||
<a href="{% url 'compensation:acc-index' %}">
|
||||
<div class="col-sm-5">
|
||||
<div class="qs-box d-flex justify-content-center align-items-center">
|
||||
{% fa5_icon 'tree' %}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="col-sm">
|
||||
<div class="col-md mb-2">
|
||||
<div>{% trans 'Total' %}</div>
|
||||
<div class="class badge badge-pill rlp-gd-outline w-100">{{total_eco_count|intcomma}}</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div>{% trans 'Shared with you' %}</div>
|
||||
<div class="class badge badge-pill rlp-gd-outline w-100">{{user_eco_count|intcomma}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-lg">
|
||||
<div class="col-sm">
|
||||
<div class="row my-1">
|
||||
<a href="{% url 'compensation:acc-new' %}">
|
||||
<button class="btn btn-default">{% fa5_icon 'plus' %} {% trans 'Create' %}</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<a href="{% url 'compensation:acc-index' %}">
|
||||
<button class="btn btn-default">{% fa5_icon 'eye' %} {% trans 'Show' %}</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
{% include 'konova/includes/quickstart/ecoaccounts.html' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -19,7 +19,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="card-text font-italic">
|
||||
<div class="scroll-150 font-italic">
|
||||
{{obj.comment}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -0,0 +1,37 @@
|
||||
{% load i18n fontawesome_5 humanize %}
|
||||
|
||||
<h4>
|
||||
{% trans 'Compensation' %}
|
||||
</h4>
|
||||
<div class="row">
|
||||
<a class="text-decoration-none" href="{% url 'compensation:index' %}">
|
||||
<div class="col-sm-5">
|
||||
<div class="qs-box d-flex justify-content-center align-items-center">
|
||||
{% fa5_icon 'leaf' %}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="col-sm">
|
||||
<div class="col-md mb-2">
|
||||
<div>{% trans 'Total' %}</div>
|
||||
<div class="class badge badge-pill rlp-gd-outline w-100">{{total_compensation_count|intcomma}}</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div>{% trans 'Shared with you' %}</div>
|
||||
<div class="class badge badge-pill rlp-gd-outline w-100">{{user_compensation_count|intcomma}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div class="row my-1">
|
||||
<a href="{% url 'compensation:new' %}">
|
||||
<button class="btn btn-default">{% fa5_icon 'plus' %} {% trans 'Create' %}</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<a href="{% url 'compensation:index' %}">
|
||||
<button class="btn btn-default">{% fa5_icon 'eye' %} {% trans 'Show' %}</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
42
konova/templates/konova/includes/quickstart/ecoaccounts.html
Normal file
42
konova/templates/konova/includes/quickstart/ecoaccounts.html
Normal file
@ -0,0 +1,42 @@
|
||||
{% load i18n fontawesome_5 humanize %}
|
||||
|
||||
<h4>
|
||||
{% trans 'Eco-account' %}
|
||||
</h4>
|
||||
<div class="row">
|
||||
<a class="text-decoration-none" href="{% url 'compensation:acc-index' %}">
|
||||
<div class="col-sm-5">
|
||||
<div class="qs-box d-flex justify-content-center align-items-center">
|
||||
{% fa5_icon 'tree' %}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="col-sm">
|
||||
<div class="col-md mb-2">
|
||||
<div>{% trans 'Total' %}</div>
|
||||
<div class="class badge badge-pill rlp-gd-outline w-100">{{total_eco_count|intcomma}}</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div>{% trans 'Shared with you' %}</div>
|
||||
<div class="class badge badge-pill rlp-gd-outline w-100">{{user_eco_count|intcomma}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-lg">
|
||||
<div class="col-sm">
|
||||
<div class="row my-1">
|
||||
<a href="{% url 'compensation:acc-new' %}">
|
||||
<button class="btn btn-default">{% fa5_icon 'plus' %} {% trans 'Create' %}</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<a href="{% url 'compensation:acc-index' %}">
|
||||
<button class="btn btn-default">{% fa5_icon 'eye' %} {% trans 'Show' %}</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
@ -0,0 +1,37 @@
|
||||
{% load i18n fontawesome_5 humanize %}
|
||||
|
||||
<h4>
|
||||
{% trans 'Intervention' %}
|
||||
</h4>
|
||||
<div class="row">
|
||||
<a class="text-decoration-none" href="{% url 'intervention:index' %}">
|
||||
<div class="col-sm-5">
|
||||
<div class="qs-box d-flex justify-content-center align-items-center">
|
||||
{% fa5_icon 'pencil-ruler' %}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="col-sm">
|
||||
<div class="col-md mb-2">
|
||||
<div>{% trans 'Total' %}</div>
|
||||
<div class="class badge badge-pill rlp-gd-outline w-100">{{total_intervention_count|intcomma}}</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div>{% trans 'Shared with you' %}</div>
|
||||
<div class="class badge badge-pill rlp-gd-outline w-100">{{user_intervention_count|intcomma}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div class="row my-1">
|
||||
<a href="{% url 'intervention:new' %}">
|
||||
<button class="btn btn-default">{% fa5_icon 'plus' %} {% trans 'Create' %}</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row my-1">
|
||||
<a href="{% url 'intervention:index' %}">
|
||||
<button class="btn btn-default">{% fa5_icon 'eye' %} {% trans 'Show' %}</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
@ -57,3 +57,33 @@ class AutocompleteTestCase(BaseTestCase):
|
||||
)
|
||||
content = json.loads(response.content)
|
||||
self.assertEqual([], content["results"])
|
||||
|
||||
def test_all_autocompletes(self):
|
||||
tests = [
|
||||
"accounts-autocomplete",
|
||||
"interventions-autocomplete",
|
||||
"codes-compensation-action-autocomplete",
|
||||
"codes-compensation-action-detail-autocomplete",
|
||||
"codes-biotope-autocomplete",
|
||||
"codes-biotope-extra-type-autocomplete",
|
||||
"codes-law-autocomplete",
|
||||
"codes-process-type-autocomplete",
|
||||
"codes-registration-office-autocomplete",
|
||||
"codes-conservation-office-autocomplete",
|
||||
"share-user-autocomplete",
|
||||
]
|
||||
for test in tests:
|
||||
self.client.login(username=self.superuser.username, password=self.superuser_pw)
|
||||
user_autocomplete_url = reverse(test)
|
||||
data = {
|
||||
"q": ""
|
||||
}
|
||||
response = self.client.get(
|
||||
user_autocomplete_url,
|
||||
data,
|
||||
)
|
||||
content = json.loads(response.content)
|
||||
try:
|
||||
content["results"]
|
||||
except KeyError:
|
||||
self.fail(f"No results returned for autocomplete {test}")
|
||||
|
@ -20,7 +20,7 @@ from django.urls import path, include
|
||||
from konova.autocompletes import EcoAccountAutocomplete, \
|
||||
InterventionAutocomplete, CompensationActionCodeAutocomplete, BiotopeCodeAutocomplete, LawCodeAutocomplete, \
|
||||
RegistrationOfficeCodeAutocomplete, ConservationOfficeCodeAutocomplete, ProcessTypeCodeAutocomplete, \
|
||||
ShareUserAutocomplete
|
||||
ShareUserAutocomplete, BiotopeExtraCodeAutocomplete, CompensationActionDetailCodeAutocomplete
|
||||
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, remove_deadline_view
|
||||
@ -47,7 +47,9 @@ urlpatterns = [
|
||||
path("atcmplt/eco-accounts", EcoAccountAutocomplete.as_view(), name="accounts-autocomplete"),
|
||||
path("atcmplt/interventions", InterventionAutocomplete.as_view(), name="interventions-autocomplete"),
|
||||
path("atcmplt/codes/comp/action", CompensationActionCodeAutocomplete.as_view(), name="codes-compensation-action-autocomplete"),
|
||||
path("atcmplt/codes/comp/action/detail", CompensationActionDetailCodeAutocomplete.as_view(), name="codes-compensation-action-detail-autocomplete"),
|
||||
path("atcmplt/codes/biotope", BiotopeCodeAutocomplete.as_view(), name="codes-biotope-autocomplete"),
|
||||
path("atcmplt/codes/biotope/extra", BiotopeExtraCodeAutocomplete.as_view(), name="codes-biotope-extra-type-autocomplete"),
|
||||
path("atcmplt/codes/law", LawCodeAutocomplete.as_view(), name="codes-law-autocomplete"),
|
||||
path("atcmplt/codes/prc-type", ProcessTypeCodeAutocomplete.as_view(), name="codes-process-type-autocomplete"),
|
||||
path("atcmplt/codes/reg-off", RegistrationOfficeCodeAutocomplete.as_view(), name="codes-registration-office-autocomplete"),
|
||||
|
@ -5,16 +5,12 @@ Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 09.11.20
|
||||
|
||||
"""
|
||||
import logging
|
||||
|
||||
from django.core.mail import send_mail
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from konova.sub_settings.django_settings import DEFAULT_FROM_EMAIL, EMAIL_REPLY_TO, SUPPORT_MAIL_RECIPIENT
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Mailer:
|
||||
"""
|
||||
|
@ -60,7 +60,7 @@ def home_view(request: HttpRequest):
|
||||
unpublish_on__gte=now,
|
||||
).order_by(
|
||||
"-publish_on"
|
||||
)[:4]
|
||||
)[:3]
|
||||
|
||||
# First fetch all valid objects (undeleted, only newest versions)
|
||||
interventions = Intervention.objects.filter(
|
||||
|
Binary file not shown.
@ -3,9 +3,9 @@
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#: compensation/filters.py:122 compensation/forms/modalForms.py:34
|
||||
#: compensation/forms/modalForms.py:45 compensation/forms/modalForms.py:61
|
||||
#: compensation/forms/modalForms.py:238 compensation/forms/modalForms.py:316
|
||||
#: compensation/filters.py:122 compensation/forms/modalForms.py:35
|
||||
#: compensation/forms/modalForms.py:46 compensation/forms/modalForms.py:62
|
||||
#: compensation/forms/modalForms.py:256 compensation/forms/modalForms.py:351
|
||||
#: intervention/forms/forms.py:52 intervention/forms/forms.py:154
|
||||
#: intervention/forms/forms.py:166 intervention/forms/modalForms.py:125
|
||||
#: intervention/forms/modalForms.py:138 intervention/forms/modalForms.py:151
|
||||
@ -26,7 +26,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-01-28 16:27+0100\n"
|
||||
"POT-Creation-Date: 2022-01-31 12:41+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -95,7 +95,7 @@ msgstr ""
|
||||
#: analysis/templates/analysis/reports/includes/eco_account/amount.html:3
|
||||
#: analysis/templates/analysis/reports/includes/intervention/amount.html:3
|
||||
#: analysis/templates/analysis/reports/includes/old_data/amount.html:3
|
||||
#: compensation/forms/modalForms.py:299
|
||||
#: compensation/forms/modalForms.py:334
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:34
|
||||
#: intervention/templates/intervention/detail/includes/deductions.html:31
|
||||
msgid "Amount"
|
||||
@ -177,8 +177,9 @@ msgstr "Einzelflächen"
|
||||
#: analysis/templates/analysis/reports/includes/intervention/laws.html:23
|
||||
#: analysis/templates/analysis/reports/includes/intervention/laws.html:43
|
||||
#: analysis/templates/analysis/reports/includes/old_data/amount.html:19
|
||||
#: konova/templates/konova/home.html:23 konova/templates/konova/home.html:61
|
||||
#: konova/templates/konova/home.html:100
|
||||
#: konova/templates/konova/includes/quickstart/compensations.html:16
|
||||
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:16
|
||||
#: konova/templates/konova/includes/quickstart/interventions.html:16
|
||||
msgid "Total"
|
||||
msgstr "Insgesamt"
|
||||
|
||||
@ -212,13 +213,13 @@ msgstr "Abbuchungen"
|
||||
|
||||
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:9
|
||||
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:11
|
||||
#: compensation/forms/modalForms.py:133
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:36
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:36
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:36
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-before.html:36
|
||||
#: ema/templates/ema/detail/includes/states-after.html:36
|
||||
#: ema/templates/ema/detail/includes/states-before.html:36
|
||||
#: compensation/forms/modalForms.py:151
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:39
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:39
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:39
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-before.html:39
|
||||
#: ema/templates/ema/detail/includes/states-after.html:39
|
||||
#: ema/templates/ema/detail/includes/states-before.html:39
|
||||
#: intervention/forms/modalForms.py:295
|
||||
msgid "Surface"
|
||||
msgstr "Fläche"
|
||||
@ -240,12 +241,13 @@ msgstr "Kompensationsart"
|
||||
#: analysis/templates/analysis/reports/includes/old_data/amount.html:29
|
||||
#: compensation/tables.py:85
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:19
|
||||
#: konova/templates/konova/home.html:49 templates/navbars/navbar.html:28
|
||||
#: konova/templates/konova/includes/quickstart/compensations.html:4
|
||||
#: templates/navbars/navbar.html:28
|
||||
msgid "Compensation"
|
||||
msgstr "Kompensation"
|
||||
|
||||
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:21
|
||||
#: compensation/forms/modalForms.py:74
|
||||
#: compensation/forms/modalForms.py:75
|
||||
msgid "Payment"
|
||||
msgstr "Zahlung"
|
||||
|
||||
@ -285,7 +287,8 @@ msgstr "Typ"
|
||||
#: intervention/forms/modalForms.py:306 intervention/forms/modalForms.py:313
|
||||
#: intervention/tables.py:89
|
||||
#: intervention/templates/intervention/detail/view.html:19
|
||||
#: konova/templates/konova/home.html:11 templates/navbars/navbar.html:22
|
||||
#: konova/templates/konova/includes/quickstart/interventions.html:4
|
||||
#: templates/navbars/navbar.html:22
|
||||
msgid "Intervention"
|
||||
msgstr "Eingriff"
|
||||
|
||||
@ -293,7 +296,8 @@ msgstr "Eingriff"
|
||||
#: compensation/tables.py:226
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:19
|
||||
#: intervention/forms/modalForms.py:279 intervention/forms/modalForms.py:286
|
||||
#: konova/templates/konova/home.html:88 templates/navbars/navbar.html:34
|
||||
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:4
|
||||
#: templates/navbars/navbar.html:34
|
||||
msgid "Eco-account"
|
||||
msgstr "Ökokonto"
|
||||
|
||||
@ -349,9 +353,9 @@ msgstr "Aussagekräftiger Titel"
|
||||
msgid "Compensation XY; Location ABC"
|
||||
msgstr "Kompensation XY; Flur ABC"
|
||||
|
||||
#: compensation/forms/forms.py:57 compensation/forms/modalForms.py:60
|
||||
#: compensation/forms/modalForms.py:237 compensation/forms/modalForms.py:315
|
||||
#: compensation/templates/compensation/detail/compensation/includes/actions.html:34
|
||||
#: compensation/forms/forms.py:57 compensation/forms/modalForms.py:61
|
||||
#: compensation/forms/modalForms.py:255 compensation/forms/modalForms.py:350
|
||||
#: compensation/templates/compensation/detail/compensation/includes/actions.html:37
|
||||
#: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34
|
||||
#: compensation/templates/compensation/detail/compensation/includes/documents.html:31
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/actions.html:34
|
||||
@ -465,66 +469,80 @@ msgstr "Ökokonto XY; Flur ABC"
|
||||
msgid "Edit Eco-Account"
|
||||
msgstr "Ökokonto bearbeiten"
|
||||
|
||||
#: compensation/forms/modalForms.py:35
|
||||
#: compensation/forms/modalForms.py:36
|
||||
msgid "in Euro"
|
||||
msgstr "in Euro"
|
||||
|
||||
#: compensation/forms/modalForms.py:44
|
||||
#: compensation/forms/modalForms.py:45
|
||||
#: intervention/templates/intervention/detail/includes/payments.html:31
|
||||
msgid "Due on"
|
||||
msgstr "Fällig am"
|
||||
|
||||
#: compensation/forms/modalForms.py:47
|
||||
#: compensation/forms/modalForms.py:48
|
||||
msgid "Due on which date"
|
||||
msgstr "Zahlung wird an diesem Datum erwartet"
|
||||
|
||||
#: compensation/forms/modalForms.py:62 compensation/forms/modalForms.py:239
|
||||
#: compensation/forms/modalForms.py:317 intervention/forms/modalForms.py:152
|
||||
#: compensation/forms/modalForms.py:63 compensation/forms/modalForms.py:257
|
||||
#: compensation/forms/modalForms.py:352 intervention/forms/modalForms.py:152
|
||||
#: konova/forms.py:375
|
||||
msgid "Additional comment, maximum {} letters"
|
||||
msgstr "Zusätzlicher Kommentar, maximal {} Zeichen"
|
||||
|
||||
#: compensation/forms/modalForms.py:75
|
||||
#: compensation/forms/modalForms.py:76
|
||||
msgid "Add a payment for intervention '{}'"
|
||||
msgstr "Neue Ersatzzahlung zu Eingriff '{}' hinzufügen"
|
||||
|
||||
#: compensation/forms/modalForms.py:95
|
||||
#: compensation/forms/modalForms.py:96
|
||||
msgid "If there is no date you can enter, please explain why."
|
||||
msgstr "Falls Sie kein Datum angeben können, erklären Sie bitte weshalb."
|
||||
|
||||
#: compensation/forms/modalForms.py:114 compensation/forms/modalForms.py:126
|
||||
#: compensation/forms/modalForms.py:115 compensation/forms/modalForms.py:127
|
||||
msgid "Biotope Type"
|
||||
msgstr "Biotoptyp"
|
||||
|
||||
#: compensation/forms/modalForms.py:117
|
||||
#: compensation/forms/modalForms.py:118
|
||||
msgid "Select the biotope type"
|
||||
msgstr "Biotoptyp wählen"
|
||||
|
||||
#: compensation/forms/modalForms.py:136 intervention/forms/modalForms.py:297
|
||||
#: compensation/forms/modalForms.py:132 compensation/forms/modalForms.py:144
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:36
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:36
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:36
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-before.html:36
|
||||
#: ema/templates/ema/detail/includes/states-after.html:36
|
||||
#: ema/templates/ema/detail/includes/states-before.html:36
|
||||
msgid "Biotope additional type"
|
||||
msgstr "Zusatzbezeichnung"
|
||||
|
||||
#: compensation/forms/modalForms.py:135
|
||||
msgid "Select an additional biotope type"
|
||||
msgstr "Zusatzbezeichnung wählen"
|
||||
|
||||
#: compensation/forms/modalForms.py:154 intervention/forms/modalForms.py:297
|
||||
msgid "in m²"
|
||||
msgstr ""
|
||||
|
||||
#: compensation/forms/modalForms.py:147
|
||||
#: compensation/forms/modalForms.py:165
|
||||
msgid "New state"
|
||||
msgstr "Neuer Zustand"
|
||||
|
||||
#: compensation/forms/modalForms.py:148
|
||||
#: compensation/forms/modalForms.py:166
|
||||
msgid "Insert data for the new state"
|
||||
msgstr "Geben Sie die Daten des neuen Zustandes ein"
|
||||
|
||||
#: compensation/forms/modalForms.py:155 konova/forms.py:190
|
||||
#: compensation/forms/modalForms.py:173 konova/forms.py:190
|
||||
msgid "Object removed"
|
||||
msgstr "Objekt entfernt"
|
||||
|
||||
#: compensation/forms/modalForms.py:209
|
||||
#: compensation/forms/modalForms.py:227
|
||||
msgid "Deadline Type"
|
||||
msgstr "Fristart"
|
||||
|
||||
#: compensation/forms/modalForms.py:212
|
||||
#: compensation/forms/modalForms.py:230
|
||||
msgid "Select the deadline type"
|
||||
msgstr "Fristart wählen"
|
||||
|
||||
#: compensation/forms/modalForms.py:221
|
||||
#: compensation/forms/modalForms.py:239
|
||||
#: compensation/templates/compensation/detail/compensation/includes/deadlines.html:31
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:31
|
||||
#: ema/templates/ema/detail/includes/deadlines.html:31
|
||||
@ -532,43 +550,43 @@ msgstr "Fristart wählen"
|
||||
msgid "Date"
|
||||
msgstr "Datum"
|
||||
|
||||
#: compensation/forms/modalForms.py:224
|
||||
#: compensation/forms/modalForms.py:242
|
||||
msgid "Select date"
|
||||
msgstr "Datum wählen"
|
||||
|
||||
#: compensation/forms/modalForms.py:251
|
||||
#: compensation/forms/modalForms.py:269
|
||||
msgid "New deadline"
|
||||
msgstr "Neue Frist"
|
||||
|
||||
#: compensation/forms/modalForms.py:252
|
||||
#: compensation/forms/modalForms.py:270
|
||||
msgid "Insert data for the new deadline"
|
||||
msgstr "Geben Sie die Daten der neuen Frist ein"
|
||||
|
||||
#: compensation/forms/modalForms.py:270
|
||||
#: compensation/forms/modalForms.py:288
|
||||
msgid "Action Type"
|
||||
msgstr "Maßnahmentyp"
|
||||
|
||||
#: compensation/forms/modalForms.py:273
|
||||
#: compensation/forms/modalForms.py:291
|
||||
msgid "Select the action type"
|
||||
msgstr "Maßnahmentyp wählen"
|
||||
|
||||
#: compensation/forms/modalForms.py:282
|
||||
#: compensation/templates/compensation/detail/compensation/includes/actions.html:38
|
||||
#: compensation/forms/modalForms.py:300
|
||||
#: compensation/templates/compensation/detail/compensation/includes/actions.html:41
|
||||
#: compensation/templates/compensation/detail/compensation/includes/deadlines.html:38
|
||||
#: compensation/templates/compensation/detail/compensation/includes/documents.html:35
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:40
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:40
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:43
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:43
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/actions.html:38
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:37
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:40
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:34
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:40
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-before.html:40
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:43
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-before.html:43
|
||||
#: ema/templates/ema/detail/includes/actions.html:37
|
||||
#: ema/templates/ema/detail/includes/deadlines.html:37
|
||||
#: ema/templates/ema/detail/includes/documents.html:34
|
||||
#: ema/templates/ema/detail/includes/states-after.html:39
|
||||
#: ema/templates/ema/detail/includes/states-before.html:39
|
||||
#: ema/templates/ema/detail/includes/states-after.html:42
|
||||
#: ema/templates/ema/detail/includes/states-before.html:42
|
||||
#: intervention/templates/intervention/detail/includes/compensations.html:37
|
||||
#: intervention/templates/intervention/detail/includes/deductions.html:38
|
||||
#: intervention/templates/intervention/detail/includes/documents.html:35
|
||||
@ -578,23 +596,31 @@ msgstr "Maßnahmentyp wählen"
|
||||
msgid "Action"
|
||||
msgstr "Aktionen"
|
||||
|
||||
#: compensation/forms/modalForms.py:287
|
||||
#: compensation/forms/modalForms.py:305 compensation/forms/modalForms.py:317
|
||||
msgid "Action Type detail"
|
||||
msgstr "Zusatzmerkmal"
|
||||
|
||||
#: compensation/forms/modalForms.py:308
|
||||
msgid "Select the action type detail"
|
||||
msgstr "Zusatzmerkmal wählen"
|
||||
|
||||
#: compensation/forms/modalForms.py:322
|
||||
msgid "Unit"
|
||||
msgstr "Einheit"
|
||||
|
||||
#: compensation/forms/modalForms.py:290
|
||||
#: compensation/forms/modalForms.py:325
|
||||
msgid "Select the unit"
|
||||
msgstr "Einheit wählen"
|
||||
|
||||
#: compensation/forms/modalForms.py:302
|
||||
#: compensation/forms/modalForms.py:337
|
||||
msgid "Insert the amount"
|
||||
msgstr "Menge eingeben"
|
||||
|
||||
#: compensation/forms/modalForms.py:328
|
||||
#: compensation/forms/modalForms.py:363
|
||||
msgid "New action"
|
||||
msgstr "Neue Maßnahme"
|
||||
|
||||
#: compensation/forms/modalForms.py:329
|
||||
#: compensation/forms/modalForms.py:364
|
||||
msgid "Insert data for the new action"
|
||||
msgstr "Geben Sie die Daten der neuen Maßnahme ein"
|
||||
|
||||
@ -724,13 +750,17 @@ msgid "Action type"
|
||||
msgstr "Maßnahmentyp"
|
||||
|
||||
#: compensation/templates/compensation/detail/compensation/includes/actions.html:31
|
||||
msgid "Action type details"
|
||||
msgstr "Zusatzmerkmale"
|
||||
|
||||
#: compensation/templates/compensation/detail/compensation/includes/actions.html:34
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/actions.html:31
|
||||
#: ema/templates/ema/detail/includes/actions.html:31
|
||||
msgctxt "Compensation"
|
||||
msgid "Amount"
|
||||
msgstr "Menge"
|
||||
|
||||
#: compensation/templates/compensation/detail/compensation/includes/actions.html:53
|
||||
#: compensation/templates/compensation/detail/compensation/includes/actions.html:61
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/actions.html:53
|
||||
#: ema/templates/ema/detail/includes/actions.html:51
|
||||
msgid "Remove action"
|
||||
@ -840,12 +870,12 @@ msgstr "Fehlende Flächenmengen laut Ausgangszustand: "
|
||||
msgid "Biotope type"
|
||||
msgstr "Biotoptyp"
|
||||
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:54
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:54
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:54
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-before.html:54
|
||||
#: ema/templates/ema/detail/includes/states-after.html:52
|
||||
#: ema/templates/ema/detail/includes/states-before.html:52
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:64
|
||||
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:64
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:64
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/states-before.html:64
|
||||
#: ema/templates/ema/detail/includes/states-after.html:62
|
||||
#: ema/templates/ema/detail/includes/states-before.html:62
|
||||
msgid "Remove state"
|
||||
msgstr "Zustand entfernen"
|
||||
|
||||
@ -876,13 +906,13 @@ msgstr "Ist CEF Maßnahme"
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:56
|
||||
#: venv/lib/python3.7/site-packages/django/forms/widgets.py:710
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
msgstr "Ja"
|
||||
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:48
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:58
|
||||
#: venv/lib/python3.7/site-packages/django/forms/widgets.py:711
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
msgstr "Nein"
|
||||
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:53
|
||||
msgid "Is Coherence keeping compensation"
|
||||
@ -1725,21 +1755,6 @@ msgstr ""
|
||||
msgid "English"
|
||||
msgstr ""
|
||||
|
||||
#: konova/templates/konova/home.html:27 konova/templates/konova/home.html:65
|
||||
#: konova/templates/konova/home.html:104
|
||||
msgid "Shared with you"
|
||||
msgstr "Für Sie freigegeben"
|
||||
|
||||
#: konova/templates/konova/home.html:35 konova/templates/konova/home.html:73
|
||||
#: konova/templates/konova/home.html:114
|
||||
msgid "Create"
|
||||
msgstr "Neu"
|
||||
|
||||
#: konova/templates/konova/home.html:40 konova/templates/konova/home.html:78
|
||||
#: konova/templates/konova/home.html:119
|
||||
msgid "Show"
|
||||
msgstr "Anzeigen"
|
||||
|
||||
#: konova/templates/konova/includes/parcels.html:3
|
||||
msgid "Spatial reference"
|
||||
msgstr "Raumreferenz"
|
||||
@ -1764,6 +1779,24 @@ msgstr "Kreis"
|
||||
msgid "Gemarkung"
|
||||
msgstr "Gemarkung"
|
||||
|
||||
#: konova/templates/konova/includes/quickstart/compensations.html:20
|
||||
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:20
|
||||
#: konova/templates/konova/includes/quickstart/interventions.html:20
|
||||
msgid "Shared with you"
|
||||
msgstr "Für Sie freigegeben"
|
||||
|
||||
#: konova/templates/konova/includes/quickstart/compensations.html:28
|
||||
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:30
|
||||
#: konova/templates/konova/includes/quickstart/interventions.html:28
|
||||
msgid "Create"
|
||||
msgstr "Neu"
|
||||
|
||||
#: konova/templates/konova/includes/quickstart/compensations.html:33
|
||||
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:35
|
||||
#: konova/templates/konova/includes/quickstart/interventions.html:33
|
||||
msgid "Show"
|
||||
msgstr "Anzeigen"
|
||||
|
||||
#: konova/templates/konova/widgets/generate-content-input.html:6
|
||||
msgid "Generate new"
|
||||
msgstr "Neu generieren"
|
||||
|
@ -4,11 +4,23 @@ from news.models import ServerMessage
|
||||
|
||||
|
||||
class ServerMessageAdmin(admin.ModelAdmin):
|
||||
readonly_fields = [
|
||||
"modified",
|
||||
"created",
|
||||
]
|
||||
list_display = [
|
||||
"id",
|
||||
"subject",
|
||||
"publish_on",
|
||||
"is_active",
|
||||
]
|
||||
search_fields = [
|
||||
"subject"
|
||||
]
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
obj.save(user=request.user)
|
||||
|
||||
|
||||
admin.site.register(ServerMessage, ServerMessageAdmin)
|
||||
|
||||
|
30
news/migrations/0001_initial.py
Normal file
30
news/migrations/0001_initial.py
Normal file
@ -0,0 +1,30 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-14 08:36
|
||||
|
||||
from django.db import migrations, models
|
||||
import uuid
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ServerMessage',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('subject', models.CharField(max_length=500)),
|
||||
('body', models.TextField()),
|
||||
('is_active', models.BooleanField(default=True)),
|
||||
('publish_on', models.DateTimeField()),
|
||||
('unpublish_on', models.DateTimeField()),
|
||||
('importance', models.CharField(choices=[('default', 'Default'), ('info', 'Info'), ('warning', 'Warning')], max_length=100)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
27
news/migrations/0002_auto_20220114_0936.py
Normal file
27
news/migrations/0002_auto_20220114_0936.py
Normal file
@ -0,0 +1,27 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-14 08:36
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('user', '0001_initial'),
|
||||
('news', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='servermessage',
|
||||
name='created',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='servermessage',
|
||||
name='modified',
|
||||
field=models.ForeignKey(blank=True, help_text='Last modified', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='user.useractionlogentry'),
|
||||
),
|
||||
]
|
0
news/migrations/__init__.py
Normal file
0
news/migrations/__init__.py
Normal file
@ -2,6 +2,7 @@ from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from konova.models import BaseResource
|
||||
from user.models import UserActionLogEntry
|
||||
|
||||
|
||||
class ServerMessageImportance(models.TextChoices):
|
||||
@ -23,3 +24,13 @@ class ServerMessage(BaseResource):
|
||||
publish_on = models.DateTimeField()
|
||||
unpublish_on = models.DateTimeField()
|
||||
importance = models.CharField(max_length=100, choices=ServerMessageImportance.choices)
|
||||
|
||||
def save(self, user=None, *args, **kwargs):
|
||||
user = kwargs.pop("user", None)
|
||||
if user is not None:
|
||||
if self.created is None:
|
||||
self.created = UserActionLogEntry.get_created_action(user)
|
||||
else:
|
||||
self.modified = UserActionLogEntry.get_edited_action(user)
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
@ -10,14 +10,14 @@
|
||||
{{msg.subject}}
|
||||
</h6>
|
||||
<small>{% trans 'Published on' %} {{msg.publish_on}}</small>
|
||||
<article class="card-text">{{msg.body|safe}}</article>
|
||||
<article class="scroll-150">{{msg.body|safe}}</article>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="col-sm-12 col-md-12 col-lg">
|
||||
<div class="card {{msg.importance|bootstrap_cls}} h-100">
|
||||
<a class="w-100 h-100" href="{% url 'news:index' %}">
|
||||
<a class="w-100 h-100 text-decoration-none" href="{% url 'news:index' %}">
|
||||
<div class="card-body d-flex align-items-center justify-content-center h-100">
|
||||
<h5 class="card-title">{% trans 'Older ...' %}</h5>
|
||||
</div>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<small> {% trans 'Published on' %} {{msg.publish_on}}</small>
|
||||
</h5>
|
||||
<small></small>
|
||||
<article class="card-text">{{msg.body|safe}}</article>
|
||||
<article class="scroll-150">{{msg.body|safe}}</article>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
@ -9,7 +9,7 @@
|
||||
<br>
|
||||
{% trans 'the following dataset has just been checked' %}
|
||||
<br>
|
||||
<strong>'{{obj_identifier}}'</strong>
|
||||
<strong>{{obj_identifier}}</strong>
|
||||
<br>
|
||||
{% trans 'This means, the responsible registration office just confirmed the correctness of this dataset.' %}
|
||||
<br>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<br>
|
||||
{% trans 'the following dataset has just been deleted' %}
|
||||
<br>
|
||||
<strong>'{{obj_identifier}}'</strong>
|
||||
<strong>{{obj_identifier}}</strong>
|
||||
<br>
|
||||
{% trans 'If this should not have been happened, please contact us. See the signature for details.' %}
|
||||
<br>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<br>
|
||||
{% trans 'the following dataset has just been recorded' %}
|
||||
<br>
|
||||
<strong>'{{obj_identifier}}'</strong>
|
||||
<strong>{{obj_identifier}}</strong>
|
||||
<br>
|
||||
{% trans 'This means the data is now publicly available, e.g. in LANIS' %}
|
||||
<br>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<br>
|
||||
{% trans 'the following dataset has just been unrecorded' %}
|
||||
<br>
|
||||
<strong>'{{obj_identifier}}'</strong>
|
||||
<strong>{{obj_identifier}}</strong>
|
||||
<br>
|
||||
{% trans 'This means the data is no longer publicly available.' %}
|
||||
<br>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<br>
|
||||
{% trans 'the following dataset has just been shared with you' %}
|
||||
<br>
|
||||
<strong>'{{obj_identifier}}'</strong>
|
||||
<strong>{{obj_identifier}}</strong>
|
||||
<br>
|
||||
{% trans 'This means you can now edit this dataset.' %}
|
||||
{% trans 'The shared dataset appears now by default on your overview for this dataset type.' %}
|
||||
|
@ -9,7 +9,7 @@
|
||||
<br>
|
||||
{% trans 'your shared access, including editing, has been revoked for the dataset ' %}
|
||||
<br>
|
||||
<strong>'{{obj_identifier}}'</strong>
|
||||
<strong>{{obj_identifier}}</strong>
|
||||
<br>
|
||||
{% trans 'However, you are still able to view the dataset content.' %}
|
||||
{% trans 'Please use the provided search filter on the dataset`s overview pages to find them.' %}
|
||||
|
@ -19,6 +19,40 @@ class UserAdmin(admin.ModelAdmin):
|
||||
"last_name",
|
||||
"email",
|
||||
]
|
||||
fields = [
|
||||
"username",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"email",
|
||||
"is_active",
|
||||
"is_staff",
|
||||
"is_superuser",
|
||||
"api_token",
|
||||
"groups",
|
||||
"notifications",
|
||||
"date_joined",
|
||||
"last_login",
|
||||
]
|
||||
search_fields = [
|
||||
"username",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"email",
|
||||
]
|
||||
filter_horizontal = [
|
||||
"groups",
|
||||
"notifications",
|
||||
]
|
||||
readonly_fields = [
|
||||
"date_joined",
|
||||
"last_login",
|
||||
]
|
||||
autocomplete_fields = [
|
||||
"api_token",
|
||||
]
|
||||
exclude = [
|
||||
"user_permissions",
|
||||
]
|
||||
|
||||
|
||||
class UserActionLogEntryAdmin(admin.ModelAdmin):
|
||||
@ -30,6 +64,8 @@ class UserActionLogEntryAdmin(admin.ModelAdmin):
|
||||
]
|
||||
|
||||
|
||||
admin.site.register(UserNotification, UserNotificationAdmin)
|
||||
admin.site.register(UserActionLogEntry, UserActionLogEntryAdmin)
|
||||
admin.site.register(User, UserAdmin)
|
||||
|
||||
# Outcommented for a cleaner admin backend on production
|
||||
#admin.site.register(UserNotification, UserNotificationAdmin)
|
||||
#admin.site.register(UserActionLogEntry, UserActionLogEntryAdmin)
|
||||
|
77
user/migrations/0001_initial.py
Normal file
77
user/migrations/0001_initial.py
Normal file
@ -0,0 +1,77 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-14 08:36
|
||||
|
||||
from django.conf import settings
|
||||
import django.contrib.auth.models
|
||||
import django.contrib.auth.validators
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
import uuid
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='User',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
|
||||
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
|
||||
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
|
||||
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
|
||||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'user',
|
||||
'verbose_name_plural': 'users',
|
||||
'abstract': False,
|
||||
},
|
||||
managers=[
|
||||
('objects', django.contrib.auth.models.UserManager()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserNotification',
|
||||
fields=[
|
||||
('id', models.CharField(choices=[('NOTIFY_ON_SHARED_ACCESS_REMOVED', 'NOTIFY_ON_SHARED_ACCESS_REMOVED'), ('NOTIFY_ON_SHARED_DATA_RECORDED', 'NOTIFY_ON_SHARED_DATA_RECORDED'), ('NOTIFY_ON_SHARED_DATA_DELETED', 'NOTIFY_ON_SHARED_DATA_DELETED'), ('NOTIFY_ON_SHARED_DATA_CHECKED', 'NOTIFY_ON_SHARED_DATA_CHECKED'), ('NOTIFY_ON_SHARED_ACCESS_GAINED', 'NOTIFY_ON_SHARED_ACCESS_GAINED')], max_length=500, primary_key=True, serialize=False)),
|
||||
('name', models.CharField(help_text='Human readable name', max_length=500, unique=True)),
|
||||
('is_active', models.BooleanField(default=True, help_text='Can be toggle to enable/disable this notification for all users')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserActionLogEntry',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
|
||||
('timestamp', models.DateTimeField(auto_now_add=True, help_text='Timestamp of performed action')),
|
||||
('action', models.CharField(blank=True, choices=[('checked', 'Checked'), ('recorded', 'Recorded'), ('unrecorded', 'Unrecorded'), ('created', 'Created'), ('edited', 'Edited'), ('deleted', 'Deleted')], help_text='Short name for performed action - optional', max_length=255, null=True)),
|
||||
('comment', models.CharField(blank=True, help_text='Additional comment on this entry', max_length=255, null=True)),
|
||||
('user', models.ForeignKey(help_text='Performing user', on_delete=django.db.models.deletion.CASCADE, related_name='+', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'ordering': ('-timestamp',),
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='notifications',
|
||||
field=models.ManyToManyField(blank=True, related_name='_user_notifications_+', to='user.UserNotification'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='user_permissions',
|
||||
field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions'),
|
||||
),
|
||||
]
|
20
user/migrations/0002_user_api_token.py
Normal file
20
user/migrations/0002_user_api_token.py
Normal file
@ -0,0 +1,20 @@
|
||||
# Generated by Django 3.1.3 on 2022-01-28 15:50
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('api', '0001_initial'),
|
||||
('user', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='api_token',
|
||||
field=models.OneToOneField(blank=True, help_text="The user's API token", null=True, on_delete=django.db.models.deletion.SET_NULL, to='api.apiusertoken'),
|
||||
),
|
||||
]
|
0
user/migrations/__init__.py
Normal file
0
user/migrations/__init__.py
Normal file
@ -10,6 +10,8 @@ import uuid
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from konova.sub_settings.django_settings import DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT
|
||||
|
||||
|
||||
class UserAction(models.TextChoices):
|
||||
"""
|
||||
@ -49,6 +51,9 @@ class UserActionLogEntry(models.Model):
|
||||
"-timestamp",
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.timestamp.strftime(DEFAULT_DATE_TIME_FORMAT)} | {self.action} | {self.user}"
|
||||
|
||||
@property
|
||||
def action_humanize(self):
|
||||
""" Returns humanized version of enum
|
||||
|
Loading…
Reference in New Issue
Block a user