Compare commits
4 Commits
7ee28e526e
...
ea0a07890c
Author | SHA1 | Date | |
---|---|---|---|
ea0a07890c | |||
78ef1b79af | |||
877a1ca335 | |||
e94dbbd3c8 |
@ -46,6 +46,11 @@ class NewPaymentForm(BaseModalForm):
|
||||
label=_con("money", "Amount"), # contextual translation
|
||||
label_suffix=_(""),
|
||||
help_text=_("in Euro"),
|
||||
widget=forms.NumberInput(
|
||||
attrs={
|
||||
"class": "form-control"
|
||||
}
|
||||
)
|
||||
)
|
||||
due = forms.DateField(
|
||||
label=_("Due on"),
|
||||
@ -56,6 +61,7 @@ class NewPaymentForm(BaseModalForm):
|
||||
attrs={
|
||||
"type": "date",
|
||||
"data-provide": "datepicker",
|
||||
"class": "form-control",
|
||||
},
|
||||
format="%d.%m.%Y"
|
||||
)
|
||||
@ -69,14 +75,11 @@ class NewPaymentForm(BaseModalForm):
|
||||
widget=forms.Textarea(
|
||||
attrs={
|
||||
"rows": 5,
|
||||
"class": "w-100"
|
||||
"class": "form-control"
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
# Define w-100 for all form fields
|
||||
full_width_fields = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.intervention = self.instance
|
||||
@ -155,7 +158,12 @@ class NewStateModalForm(BaseModalForm):
|
||||
label=_("Surface"),
|
||||
label_suffix="",
|
||||
required=True,
|
||||
help_text=_("in m²")
|
||||
help_text=_("in m²"),
|
||||
widget=forms.NumberInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -243,7 +251,7 @@ class NewDeadlineModalForm(BaseModalForm):
|
||||
choices=DeadlineType.choices,
|
||||
widget=forms.Select(
|
||||
attrs={
|
||||
"class": "custom-select"
|
||||
"class": "form-control"
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -256,6 +264,7 @@ class NewDeadlineModalForm(BaseModalForm):
|
||||
attrs={
|
||||
"type": "date",
|
||||
"data-provide": "datepicker",
|
||||
"class": "form-control",
|
||||
},
|
||||
format="%d.%m.%Y"
|
||||
)
|
||||
@ -270,6 +279,7 @@ class NewDeadlineModalForm(BaseModalForm):
|
||||
attrs={
|
||||
"cols": 30,
|
||||
"rows": 5,
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -329,7 +339,7 @@ class NewActionModalForm(BaseModalForm):
|
||||
choices=UnitChoices.choices,
|
||||
widget=forms.Select(
|
||||
attrs={
|
||||
"class": "custom-select"
|
||||
"class": "form-control"
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -340,6 +350,11 @@ class NewActionModalForm(BaseModalForm):
|
||||
help_text=_("Insert the amount"),
|
||||
decimal_places=2,
|
||||
min_value=0.00,
|
||||
widget=forms.NumberInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
comment = forms.CharField(
|
||||
required=False,
|
||||
@ -350,7 +365,7 @@ class NewActionModalForm(BaseModalForm):
|
||||
widget=forms.Textarea(
|
||||
attrs={
|
||||
"rows": 5,
|
||||
"class": "w-100"
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
@ -5,6 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 01.12.20
|
||||
|
||||
"""
|
||||
from django.contrib.auth.models import User
|
||||
from django.http import HttpRequest
|
||||
from django.template.loader import render_to_string
|
||||
from django.urls import reverse
|
||||
@ -148,6 +149,8 @@ class CompensationTable(BaseTable):
|
||||
|
||||
"""
|
||||
html = ""
|
||||
if value is None:
|
||||
value = User.objects.none()
|
||||
has_access = value.filter(
|
||||
username=self.user.username
|
||||
).exists()
|
||||
|
@ -16,7 +16,7 @@ from django.shortcuts import render, get_object_or_404
|
||||
from compensation.forms import NewStateModalForm, NewActionModalForm, NewDeadlineModalForm
|
||||
from compensation.models import EcoAccount, EcoAccountDocument
|
||||
from compensation.tables import EcoAccountTable
|
||||
from intervention.forms import NewDeductionForm
|
||||
from intervention.forms.modalForms import NewDeductionModalForm
|
||||
from konova.contexts import BaseContext
|
||||
from konova.decorators import any_group_check, default_group_required, conservation_office_group_required
|
||||
from konova.forms import RemoveModalForm, SimpleGeomForm, NewDocumentForm, RecordModalForm
|
||||
@ -340,7 +340,7 @@ def new_deduction_view(request: HttpRequest, id: str):
|
||||
|
||||
"""
|
||||
acc = get_object_or_404(EcoAccount, id=id)
|
||||
form = NewDeductionForm(request.POST or None, instance=acc, user=request.user)
|
||||
form = NewDeductionModalForm(request.POST or None, instance=acc, user=request.user)
|
||||
return form.process_request(
|
||||
request,
|
||||
msg_success=_("Deduction added")
|
||||
|
@ -12,7 +12,7 @@ from django.db.models import QuerySet, Q
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from intervention.forms import DummyFilterInput
|
||||
from intervention.inputs import DummyFilterInput
|
||||
from intervention.models import Intervention
|
||||
|
||||
|
||||
|
@ -1,737 +0,0 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 02.12.20
|
||||
|
||||
"""
|
||||
from dal import autocomplete
|
||||
from django import forms
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.gis.geos import Polygon
|
||||
from django.db import transaction
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from codelist.models import KonovaCode
|
||||
from codelist.settings import CODELIST_PROCESS_TYPE_ID, CODELIST_LAW_ID, \
|
||||
CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID
|
||||
from compensation.models import EcoAccountDeduction, EcoAccount
|
||||
from intervention.models import Intervention, Revocation, RevocationDocument, LegalData, ResponsibilityData
|
||||
from konova.forms import BaseForm, BaseModalForm, SimpleGeomForm
|
||||
from konova.settings import ZB_GROUP, ETS_GROUP
|
||||
from konova.utils.general import format_german_float
|
||||
from konova.utils.messenger import Messenger
|
||||
from konova.utils.user_checks import in_group
|
||||
from user.models import UserActionLogEntry, UserAction
|
||||
|
||||
|
||||
class NewInterventionForm(BaseForm):
|
||||
identifier = forms.CharField(
|
||||
label=_("Identifier"),
|
||||
label_suffix="",
|
||||
max_length=255,
|
||||
help_text=_("Generated automatically"),
|
||||
)
|
||||
title = forms.CharField(
|
||||
label=_("Title"),
|
||||
label_suffix="",
|
||||
help_text=_("An explanatory name"),
|
||||
max_length=255,
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"placeholder": _("Construction XY; Location ABC")
|
||||
}
|
||||
)
|
||||
)
|
||||
type = forms.ModelChoiceField(
|
||||
label=_("Process type"),
|
||||
label_suffix="",
|
||||
help_text=_(""),
|
||||
required=False,
|
||||
queryset=KonovaCode.objects.filter(
|
||||
is_archived=False,
|
||||
is_leaf=True,
|
||||
code_lists__in=[CODELIST_PROCESS_TYPE_ID],
|
||||
),
|
||||
widget=autocomplete.ModelSelect2(
|
||||
url="codes-process-type-autocomplete",
|
||||
attrs={
|
||||
}
|
||||
),
|
||||
)
|
||||
laws = forms.ModelMultipleChoiceField(
|
||||
label=_("Law"),
|
||||
label_suffix="",
|
||||
help_text=_("Multiple selection possible"),
|
||||
required=False,
|
||||
queryset=KonovaCode.objects.filter(
|
||||
is_archived=False,
|
||||
is_leaf=True,
|
||||
code_lists__in=[CODELIST_LAW_ID],
|
||||
),
|
||||
widget=autocomplete.ModelSelect2Multiple(
|
||||
url="codes-law-autocomplete",
|
||||
attrs={
|
||||
}
|
||||
),
|
||||
)
|
||||
registration_office = forms.ModelChoiceField(
|
||||
label=_("Registration office"),
|
||||
label_suffix="",
|
||||
required=False,
|
||||
queryset=KonovaCode.objects.filter(
|
||||
is_archived=False,
|
||||
is_leaf=True,
|
||||
code_lists__in=[CODELIST_REGISTRATION_OFFICE_ID],
|
||||
),
|
||||
widget=autocomplete.ModelSelect2(
|
||||
url="codes-registration-office-autocomplete",
|
||||
attrs={
|
||||
}
|
||||
),
|
||||
)
|
||||
conservation_office = forms.ModelChoiceField(
|
||||
label=_("Conservation office"),
|
||||
label_suffix="",
|
||||
required=False,
|
||||
queryset=KonovaCode.objects.filter(
|
||||
is_archived=False,
|
||||
is_leaf=True,
|
||||
code_lists__in=[CODELIST_CONSERVATION_OFFICE_ID],
|
||||
),
|
||||
widget=autocomplete.ModelSelect2(
|
||||
url="codes-conservation-office-autocomplete",
|
||||
attrs={
|
||||
}
|
||||
),
|
||||
)
|
||||
registration_file_number = forms.CharField(
|
||||
label=_("Registration office file number"),
|
||||
label_suffix="",
|
||||
max_length=255,
|
||||
required=False,
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"placeholder": _("ZB-123/ABC.456")
|
||||
}
|
||||
)
|
||||
)
|
||||
conservation_file_number = forms.CharField(
|
||||
label=_("Conservation office file number"),
|
||||
label_suffix="",
|
||||
max_length=255,
|
||||
required=False,
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"placeholder": _("ETS-123/ABC.456")
|
||||
}
|
||||
)
|
||||
)
|
||||
handler = forms.CharField(
|
||||
label=_("Intervention handler"),
|
||||
label_suffix="",
|
||||
max_length=255,
|
||||
required=False,
|
||||
help_text=_("Who performs the intervention"),
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"placeholder": _("Company Mustermann")
|
||||
}
|
||||
)
|
||||
)
|
||||
registration_date = forms.DateField(
|
||||
label=_("Registration date"),
|
||||
label_suffix=_(""),
|
||||
required=False,
|
||||
widget=forms.DateInput(
|
||||
attrs={
|
||||
"type": "date",
|
||||
},
|
||||
format="%d.%m.%Y"
|
||||
)
|
||||
)
|
||||
binding_date = forms.DateField(
|
||||
label=_("Binding on"),
|
||||
label_suffix=_(""),
|
||||
required=False,
|
||||
widget=forms.DateInput(
|
||||
attrs={
|
||||
"type": "date",
|
||||
},
|
||||
format="%d.%m.%Y"
|
||||
)
|
||||
)
|
||||
comment = forms.CharField(
|
||||
label_suffix="",
|
||||
label=_("Comment"),
|
||||
required=False,
|
||||
help_text=_("Additional comment"),
|
||||
widget=forms.Textarea(
|
||||
attrs={
|
||||
"rows": 5,
|
||||
"class": "w-100"
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
# Define w-100 for all form fields
|
||||
full_width_fields = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("New intervention")
|
||||
self.action_url = reverse("intervention:new")
|
||||
self.cancel_redirect = reverse("intervention:index")
|
||||
|
||||
tmp_intervention = Intervention()
|
||||
identifier = tmp_intervention._generate_new_identifier()
|
||||
self.initialize_form_field("identifier", identifier)
|
||||
|
||||
def save(self, user: User, geom_form: SimpleGeomForm):
|
||||
with transaction.atomic():
|
||||
# Fetch data from cleaned POST values
|
||||
identifier = self.cleaned_data.get("identifier", None)
|
||||
title = self.cleaned_data.get("title", None)
|
||||
_type = self.cleaned_data.get("type", None)
|
||||
laws = self.cleaned_data.get("laws", None)
|
||||
handler = self.cleaned_data.get("handler", None)
|
||||
registration_office = self.cleaned_data.get("registration_office", None)
|
||||
conservation_office = self.cleaned_data.get("conservation_office", None)
|
||||
conservation_file_number = self.cleaned_data.get("conservation_file_number", None)
|
||||
registration_file_number = self.cleaned_data.get("registration_file_number", None)
|
||||
binding_date = self.cleaned_data.get("binding_date", None)
|
||||
registration_date = self.cleaned_data.get("registration_date", None)
|
||||
comment = self.cleaned_data.get("comment", None)
|
||||
|
||||
# Create log entry
|
||||
action = UserActionLogEntry.objects.create(
|
||||
user=user,
|
||||
action=UserAction.CREATED,
|
||||
)
|
||||
|
||||
# Create legal data object (without M2M laws first)
|
||||
legal_data = LegalData.objects.create(
|
||||
registration_date=registration_date,
|
||||
binding_date=binding_date,
|
||||
process_type=_type,
|
||||
)
|
||||
# Then add the M2M laws to the object
|
||||
legal_data.laws.set(laws)
|
||||
|
||||
# Create responsible data object
|
||||
responsibility_data = ResponsibilityData.objects.create(
|
||||
registration_office=registration_office,
|
||||
conservation_office=conservation_office,
|
||||
registration_file_number=registration_file_number,
|
||||
conservation_file_number=conservation_file_number,
|
||||
handler=handler,
|
||||
)
|
||||
|
||||
# Process the geometry form
|
||||
geometry = geom_form.save(action)
|
||||
|
||||
# Finally create main object, holding the other objects
|
||||
intervention = Intervention.objects.create(
|
||||
identifier=identifier,
|
||||
title=title,
|
||||
responsible=responsibility_data,
|
||||
legal=legal_data,
|
||||
created=action,
|
||||
geometry=geometry,
|
||||
comment=comment,
|
||||
)
|
||||
|
||||
# Add the log entry to the main objects log list
|
||||
intervention.log.add(action)
|
||||
|
||||
# Add the performing user as the first user having access to the data
|
||||
intervention.users.add(user)
|
||||
return intervention
|
||||
|
||||
|
||||
class EditInterventionForm(NewInterventionForm):
|
||||
""" Subclasses NewInterventionForm
|
||||
|
||||
Simply adds initializing of a provided self.instance object into the form fields
|
||||
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
if self.instance is not None:
|
||||
self.action_url = reverse("intervention:edit", args=(self.instance.id,))
|
||||
self.cancel_redirect = reverse("intervention:open", args=(self.instance.id,))
|
||||
self.form_title = _("Edit intervention")
|
||||
self.form_caption = ""
|
||||
|
||||
# Initialize form data
|
||||
form_data = {
|
||||
"identifier": self.instance.identifier,
|
||||
"title": self.instance.title,
|
||||
"type": self.instance.legal.process_type,
|
||||
"laws": list(self.instance.legal.laws.values_list("id", flat=True)),
|
||||
"handler": self.instance.responsible.handler,
|
||||
"registration_office": self.instance.responsible.registration_office,
|
||||
"registration_file_number": self.instance.responsible.registration_file_number,
|
||||
"conservation_office": self.instance.responsible.conservation_office,
|
||||
"conservation_file_number": self.instance.responsible.conservation_file_number,
|
||||
"registration_date": self.instance.legal.registration_date.isoformat(),
|
||||
"binding_date": self.instance.legal.binding_date.isoformat(),
|
||||
"comment": self.instance.comment,
|
||||
}
|
||||
disabled_fields = [
|
||||
"identifier",
|
||||
]
|
||||
self.load_initial_data(
|
||||
form_data,
|
||||
disabled_fields,
|
||||
)
|
||||
|
||||
def save(self, user: User, geom_form: SimpleGeomForm):
|
||||
""" Overwrite instance with new form data
|
||||
|
||||
Args:
|
||||
user ():
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
with transaction.atomic():
|
||||
identifier = self.cleaned_data.get("identifier", None)
|
||||
title = self.cleaned_data.get("title", None)
|
||||
process_type = self.cleaned_data.get("type", None)
|
||||
laws = self.cleaned_data.get("laws", None)
|
||||
handler = self.cleaned_data.get("handler", None)
|
||||
registration_office = self.cleaned_data.get("registration_office", None)
|
||||
registration_file_number = self.cleaned_data.get("registration_file_number", None)
|
||||
conservation_office = self.cleaned_data.get("conservation_office", None)
|
||||
conservation_file_number = self.cleaned_data.get("conservation_file_number", None)
|
||||
registration_date = self.cleaned_data.get("registration_date", None)
|
||||
binding_date = self.cleaned_data.get("binding_date", None)
|
||||
comment = self.cleaned_data.get("comment", None)
|
||||
|
||||
self.instance.legal.process_type = process_type
|
||||
self.instance.legal.registration_date = registration_date
|
||||
self.instance.legal.binding_date = binding_date
|
||||
self.instance.legal.laws.set(laws)
|
||||
self.instance.legal.save()
|
||||
|
||||
self.instance.responsible.handler = handler
|
||||
self.instance.responsible.registration_office = registration_office
|
||||
self.instance.responsible.registration_file_number = registration_file_number
|
||||
self.instance.responsible.conservation_office = conservation_office
|
||||
self.instance.responsible.conservation_file_number = conservation_file_number
|
||||
self.instance.responsible.save()
|
||||
|
||||
user_action = UserActionLogEntry.objects.create(
|
||||
user=user,
|
||||
timestamp=timezone.now(),
|
||||
action=UserAction.EDITED,
|
||||
)
|
||||
|
||||
geometry = geom_form.save(user_action)
|
||||
self.instance.geometry = geometry
|
||||
self.instance.geometry.save()
|
||||
|
||||
self.instance.log.add(user_action)
|
||||
|
||||
self.instance.identifier = identifier
|
||||
self.instance.title = title
|
||||
self.instance.comment = comment
|
||||
self.instance.modified = user_action
|
||||
self.instance.save()
|
||||
|
||||
return self.instance
|
||||
|
||||
|
||||
class OpenInterventionForm(EditInterventionForm):
|
||||
"""
|
||||
This form is not intended to be used as data-input form. It's used to simplify the rendering of intervention:open
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# Resize map
|
||||
self.fields["geometry"].widget.attrs["map_width"] = 500
|
||||
self.fields["geometry"].widget.attrs["map_height"] = 300
|
||||
|
||||
# Disable all form fields
|
||||
for field in self.fields:
|
||||
self.disable_form_field(field)
|
||||
|
||||
|
||||
class DummyFilterInput(forms.HiddenInput):
|
||||
""" A dummy input widget
|
||||
|
||||
Does not render anything. Can be used to keep filter logic using django_filter without having a pre defined
|
||||
filter widget being rendered to the template.
|
||||
|
||||
"""
|
||||
template_name = "konova/custom_widgets/dummy-filter-input.html"
|
||||
|
||||
|
||||
class TextToClipboardInput(forms.TextInput):
|
||||
template_name = "konova/custom_widgets/text-to-clipboard-input.html"
|
||||
|
||||
|
||||
class ShareInterventionForm(BaseModalForm):
|
||||
url = forms.CharField(
|
||||
label=_("Share link"),
|
||||
label_suffix="",
|
||||
help_text=_("Send this link to users who you want to have writing access on the data"),
|
||||
required=False,
|
||||
widget=TextToClipboardInput(
|
||||
attrs={
|
||||
"readonly": True
|
||||
}
|
||||
)
|
||||
)
|
||||
users = forms.MultipleChoiceField(
|
||||
label=_("Shared with"),
|
||||
label_suffix="",
|
||||
required=True,
|
||||
help_text=_("Remove check to remove access for this user"),
|
||||
widget=forms.CheckboxSelectMultiple(
|
||||
attrs={
|
||||
"class": "list-unstyled",
|
||||
}
|
||||
),
|
||||
choices=[]
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("Share")
|
||||
self.form_caption = _("Share settings for {}").format(self.instance.identifier)
|
||||
self.template = "modal/modal_form.html"
|
||||
|
||||
# Make sure an access_token is set
|
||||
if self.instance.access_token is None:
|
||||
self.instance.generate_access_token()
|
||||
|
||||
self._init_fields()
|
||||
|
||||
def _init_fields(self):
|
||||
""" Wraps initializing of fields
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
# Initialize share_link field
|
||||
self.share_link = self.request.build_absolute_uri(
|
||||
reverse("intervention:share", args=(self.instance.id, self.instance.access_token,))
|
||||
)
|
||||
self.initialize_form_field(
|
||||
"url",
|
||||
self.share_link
|
||||
)
|
||||
|
||||
# Initialize users field
|
||||
# Remove field if user is not in registration or conservation group
|
||||
if not in_group(self.request.user, ZB_GROUP) and not in_group(self.request.user, ETS_GROUP):
|
||||
del self.fields["users"]
|
||||
else:
|
||||
users = self.instance.users.all()
|
||||
choices = []
|
||||
for n in users:
|
||||
choices.append(
|
||||
(n.id, n.username)
|
||||
)
|
||||
self.fields["users"].choices = choices
|
||||
u_ids = list(users.values_list("id", flat=True))
|
||||
self.initialize_form_field(
|
||||
"users",
|
||||
u_ids
|
||||
)
|
||||
|
||||
def save(self):
|
||||
accessing_users = User.objects.filter(
|
||||
id__in=self.cleaned_data["users"]
|
||||
)
|
||||
self.instance.users.set(accessing_users)
|
||||
|
||||
|
||||
class NewRevocationForm(BaseModalForm):
|
||||
date = forms.DateField(
|
||||
label=_("Date"),
|
||||
label_suffix=_(""),
|
||||
help_text=_("Date of revocation"),
|
||||
widget=forms.DateInput(
|
||||
attrs={
|
||||
"type": "date",
|
||||
"data-provide": "datepicker",
|
||||
},
|
||||
format="%d.%m.%Y"
|
||||
)
|
||||
)
|
||||
file = forms.FileField(
|
||||
label=_("Document"),
|
||||
label_suffix=_(""),
|
||||
required=False,
|
||||
help_text=_("Must be smaller than 15 Mb"),
|
||||
widget=forms.FileInput(
|
||||
attrs={
|
||||
"class": "w-75"
|
||||
}
|
||||
)
|
||||
)
|
||||
comment = forms.CharField(
|
||||
required=False,
|
||||
max_length=200,
|
||||
label=_("Comment"),
|
||||
label_suffix=_(""),
|
||||
help_text=_("Additional comment, maximum {} letters").format(200),
|
||||
widget=forms.Textarea(
|
||||
attrs={
|
||||
"cols": 30,
|
||||
"rows": 5,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
# Define w-100 for all form fields
|
||||
full_width_fields = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("Add revocation")
|
||||
self.form_caption = ""
|
||||
self.form_attrs = {
|
||||
"enctype": "multipart/form-data", # important for file upload
|
||||
}
|
||||
|
||||
def save(self):
|
||||
with transaction.atomic():
|
||||
created_action = UserActionLogEntry.objects.create(
|
||||
user=self.user,
|
||||
action=UserAction.CREATED
|
||||
)
|
||||
edited_action = UserActionLogEntry.objects.create(
|
||||
user=self.user,
|
||||
action=UserAction.EDITED
|
||||
)
|
||||
revocation = Revocation.objects.create(
|
||||
date=self.cleaned_data["date"],
|
||||
comment=self.cleaned_data["comment"],
|
||||
created=created_action,
|
||||
)
|
||||
self.instance.modified = edited_action
|
||||
self.instance.save()
|
||||
self.instance.log.add(edited_action)
|
||||
self.instance.legal.revocation = revocation
|
||||
self.instance.legal.save()
|
||||
|
||||
if self.cleaned_data["file"]:
|
||||
RevocationDocument.objects.create(
|
||||
title="revocation_of_{}".format(self.instance.identifier),
|
||||
date_of_creation=self.cleaned_data["date"],
|
||||
comment=self.cleaned_data["comment"],
|
||||
file=self.cleaned_data["file"],
|
||||
instance=revocation
|
||||
)
|
||||
return revocation
|
||||
|
||||
|
||||
class RunCheckForm(BaseModalForm):
|
||||
checked_intervention = forms.BooleanField(
|
||||
label=_("Checked intervention data"),
|
||||
label_suffix="",
|
||||
widget=forms.CheckboxInput(),
|
||||
required=True,
|
||||
)
|
||||
checked_comps = forms.BooleanField(
|
||||
label=_("Checked compensations data and payments"),
|
||||
label_suffix="",
|
||||
widget=forms.CheckboxInput(),
|
||||
required=True
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("Run check")
|
||||
self.form_caption = _("I, {} {}, confirm that all necessary control steps have been performed by myself.").format(self.user.first_name, self.user.last_name)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
""" Perform a validity check based on quality_check() logic
|
||||
|
||||
Returns:
|
||||
result (bool)
|
||||
"""
|
||||
super_result = super().is_valid()
|
||||
# Perform check
|
||||
msgs = self.instance.quality_check()
|
||||
for msg in msgs:
|
||||
self.add_error(
|
||||
"checked_intervention",
|
||||
msg
|
||||
)
|
||||
return super_result and (len(msgs) == 0)
|
||||
|
||||
def save(self):
|
||||
""" Saving logic
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
with transaction.atomic():
|
||||
user_action = UserActionLogEntry.objects.create(
|
||||
user=self.user,
|
||||
action=UserAction.CHECKED
|
||||
)
|
||||
# Replace old checked
|
||||
if self.instance.checked:
|
||||
self.instance.checked.delete()
|
||||
self.instance.checked = user_action
|
||||
self.instance.log.add(user_action)
|
||||
self.instance.save()
|
||||
|
||||
# Send message to the SSO server
|
||||
messenger = Messenger(
|
||||
self.instance.users.all(),
|
||||
type="INFO",
|
||||
)
|
||||
messenger.send_object_checked(
|
||||
self.instance.identifier,
|
||||
self.user,
|
||||
)
|
||||
|
||||
|
||||
class NewDeductionForm(BaseModalForm):
|
||||
""" Form for creating new deduction
|
||||
|
||||
Can be used for Intervention view as well as for EcoAccount views.
|
||||
|
||||
Parameter 'instance' can be an intervention, as well as an ecoAccount.
|
||||
An instance check handles both workflows properly.
|
||||
|
||||
"""
|
||||
account = forms.ModelChoiceField(
|
||||
label=_("Eco-account"),
|
||||
label_suffix="",
|
||||
help_text=_("Only recorded accounts can be selected for deductions"),
|
||||
queryset=EcoAccount.objects.filter(deleted=None),
|
||||
widget=autocomplete.ModelSelect2(
|
||||
url="accounts-autocomplete",
|
||||
attrs={
|
||||
"data-placeholder": _("Eco-account"),
|
||||
"data-minimum-input-length": 3,
|
||||
"readonly": True,
|
||||
}
|
||||
),
|
||||
)
|
||||
surface = forms.DecimalField(
|
||||
min_value=0.00,
|
||||
decimal_places=2,
|
||||
label=_("Surface"),
|
||||
label_suffix="",
|
||||
help_text=_("in m²"),
|
||||
)
|
||||
intervention = forms.ModelChoiceField(
|
||||
label=_("Intervention"),
|
||||
label_suffix="",
|
||||
help_text=_("Only shared interventions can be selected"),
|
||||
queryset=Intervention.objects.filter(deleted=None),
|
||||
widget=autocomplete.ModelSelect2(
|
||||
url="interventions-autocomplete",
|
||||
attrs={
|
||||
"data-placeholder": _("Intervention"),
|
||||
"data-minimum-input-length": 3,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
# Define w-100 for all form fields
|
||||
full_width_fields = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("New Deduction")
|
||||
self.form_caption = _("Enter the information for a new deduction from a chosen eco-account")
|
||||
self.is_intervention_initially = False
|
||||
|
||||
# Add a placeholder for field 'surface' without having to define the whole widget above
|
||||
self.add_placeholder_for_field("surface", "0,00")
|
||||
|
||||
# Check for Intervention or EcoAccount
|
||||
if isinstance(self.instance, Intervention):
|
||||
# Form has been called with a given intervention
|
||||
self.initialize_form_field("intervention", self.instance)
|
||||
self.disable_form_field("intervention")
|
||||
self.is_intervention_initially = True
|
||||
elif isinstance(self.instance, EcoAccount):
|
||||
# Form has been called with a given account --> make it initial in the form and read-only
|
||||
self.initialize_form_field("account", self.instance)
|
||||
self.disable_form_field("account")
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
def is_valid(self):
|
||||
""" Custom validity check
|
||||
|
||||
Makes sure the deduction can not contain more surface than the account still provides
|
||||
|
||||
Returns:
|
||||
is_valid (bool)
|
||||
"""
|
||||
super_result = super().is_valid()
|
||||
if self.is_intervention_initially:
|
||||
acc = self.cleaned_data["account"]
|
||||
else:
|
||||
acc = self.instance
|
||||
|
||||
if not acc.recorded:
|
||||
self.add_error(
|
||||
"account",
|
||||
_("Eco-account {} is not recorded yet. You can only deduct from recorded accounts.").format(acc.identifier)
|
||||
)
|
||||
return False
|
||||
|
||||
# Calculate valid surface
|
||||
sum_surface = acc.get_surface()
|
||||
sum_surface_deductions = acc.get_deductions_surface()
|
||||
rest_surface = sum_surface - sum_surface_deductions
|
||||
form_surface = float(self.cleaned_data["surface"])
|
||||
is_valid_surface = form_surface < rest_surface
|
||||
if not is_valid_surface:
|
||||
self.add_error(
|
||||
"surface",
|
||||
_("The account {} has not enough surface for a deduction of {} m². There are only {} m² left").format(
|
||||
acc.identifier,
|
||||
format_german_float(form_surface),
|
||||
format_german_float(rest_surface),
|
||||
),
|
||||
)
|
||||
return is_valid_surface and super_result
|
||||
|
||||
def save(self):
|
||||
with transaction.atomic():
|
||||
# Create log entry
|
||||
user_action_edit = UserActionLogEntry.objects.create(
|
||||
user=self.user,
|
||||
action=UserAction.EDITED
|
||||
)
|
||||
user_action_create = UserActionLogEntry.objects.create(
|
||||
user=self.user,
|
||||
action=UserAction.CREATED
|
||||
)
|
||||
self.instance.log.add(user_action_edit)
|
||||
self.instance.modified = user_action_edit
|
||||
self.instance.save()
|
||||
|
||||
# Create deductions depending on Intervention or EcoAccount as the initial instance
|
||||
if self.is_intervention_initially:
|
||||
deduction = EcoAccountDeduction.objects.create(
|
||||
intervention=self.instance,
|
||||
account=self.cleaned_data["account"],
|
||||
surface=self.cleaned_data["surface"],
|
||||
created=user_action_create,
|
||||
)
|
||||
else:
|
||||
deduction = EcoAccountDeduction.objects.create(
|
||||
intervention=self.cleaned_data["intervention"],
|
||||
account=self.instance,
|
||||
surface=self.cleaned_data["surface"],
|
||||
created=user_action_create,
|
||||
)
|
||||
return deduction
|
355
intervention/forms/forms.py
Normal file
355
intervention/forms/forms.py
Normal file
@ -0,0 +1,355 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 02.12.20
|
||||
|
||||
"""
|
||||
from dal import autocomplete
|
||||
from django import forms
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import transaction
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from codelist.models import KonovaCode
|
||||
from codelist.settings import CODELIST_PROCESS_TYPE_ID, CODELIST_LAW_ID, \
|
||||
CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID
|
||||
from intervention.inputs import GenerateInput
|
||||
from intervention.models import Intervention, LegalData, ResponsibilityData
|
||||
from konova.forms import BaseForm, SimpleGeomForm
|
||||
from user.models import UserActionLogEntry, UserAction
|
||||
|
||||
|
||||
class NewInterventionForm(BaseForm):
|
||||
identifier = forms.CharField(
|
||||
label=_("Identifier"),
|
||||
label_suffix="",
|
||||
max_length=255,
|
||||
help_text=_("Generated automatically"),
|
||||
widget=GenerateInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"url": reverse_lazy("intervention:new-id"),
|
||||
}
|
||||
)
|
||||
)
|
||||
title = forms.CharField(
|
||||
label=_("Title"),
|
||||
label_suffix="",
|
||||
help_text=_("An explanatory name"),
|
||||
max_length=255,
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"placeholder": _("Construction XY; Location ABC"),
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
type = forms.ModelChoiceField(
|
||||
label=_("Process type"),
|
||||
label_suffix="",
|
||||
help_text=_(""),
|
||||
required=False,
|
||||
queryset=KonovaCode.objects.filter(
|
||||
is_archived=False,
|
||||
is_leaf=True,
|
||||
code_lists__in=[CODELIST_PROCESS_TYPE_ID],
|
||||
),
|
||||
widget=autocomplete.ModelSelect2(
|
||||
url="codes-process-type-autocomplete",
|
||||
attrs={
|
||||
}
|
||||
),
|
||||
)
|
||||
laws = forms.ModelMultipleChoiceField(
|
||||
label=_("Law"),
|
||||
label_suffix="",
|
||||
help_text=_("Multiple selection possible"),
|
||||
required=False,
|
||||
queryset=KonovaCode.objects.filter(
|
||||
is_archived=False,
|
||||
is_leaf=True,
|
||||
code_lists__in=[CODELIST_LAW_ID],
|
||||
),
|
||||
widget=autocomplete.ModelSelect2Multiple(
|
||||
url="codes-law-autocomplete",
|
||||
attrs={
|
||||
}
|
||||
),
|
||||
)
|
||||
registration_office = forms.ModelChoiceField(
|
||||
label=_("Registration office"),
|
||||
label_suffix="",
|
||||
required=False,
|
||||
queryset=KonovaCode.objects.filter(
|
||||
is_archived=False,
|
||||
is_leaf=True,
|
||||
code_lists__in=[CODELIST_REGISTRATION_OFFICE_ID],
|
||||
),
|
||||
widget=autocomplete.ModelSelect2(
|
||||
url="codes-registration-office-autocomplete",
|
||||
attrs={
|
||||
}
|
||||
),
|
||||
)
|
||||
conservation_office = forms.ModelChoiceField(
|
||||
label=_("Conservation office"),
|
||||
label_suffix="",
|
||||
required=False,
|
||||
queryset=KonovaCode.objects.filter(
|
||||
is_archived=False,
|
||||
is_leaf=True,
|
||||
code_lists__in=[CODELIST_CONSERVATION_OFFICE_ID],
|
||||
),
|
||||
widget=autocomplete.ModelSelect2(
|
||||
url="codes-conservation-office-autocomplete",
|
||||
attrs={
|
||||
}
|
||||
),
|
||||
)
|
||||
registration_file_number = forms.CharField(
|
||||
label=_("Registration office file number"),
|
||||
label_suffix="",
|
||||
max_length=255,
|
||||
required=False,
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"placeholder": _("ZB-123/ABC.456"),
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
conservation_file_number = forms.CharField(
|
||||
label=_("Conservation office file number"),
|
||||
label_suffix="",
|
||||
max_length=255,
|
||||
required=False,
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"placeholder": _("ETS-123/ABC.456"),
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
handler = forms.CharField(
|
||||
label=_("Intervention handler"),
|
||||
label_suffix="",
|
||||
max_length=255,
|
||||
required=False,
|
||||
help_text=_("Who performs the intervention"),
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"placeholder": _("Company Mustermann"),
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
registration_date = forms.DateField(
|
||||
label=_("Registration date"),
|
||||
label_suffix=_(""),
|
||||
required=False,
|
||||
widget=forms.DateInput(
|
||||
attrs={
|
||||
"type": "date",
|
||||
"class": "form-control",
|
||||
},
|
||||
format="%d.%m.%Y"
|
||||
)
|
||||
)
|
||||
binding_date = forms.DateField(
|
||||
label=_("Binding on"),
|
||||
label_suffix=_(""),
|
||||
required=False,
|
||||
widget=forms.DateInput(
|
||||
attrs={
|
||||
"type": "date",
|
||||
"class": "form-control",
|
||||
},
|
||||
format="%d.%m.%Y"
|
||||
)
|
||||
)
|
||||
comment = forms.CharField(
|
||||
label_suffix="",
|
||||
label=_("Comment"),
|
||||
required=False,
|
||||
help_text=_("Additional comment"),
|
||||
widget=forms.Textarea(
|
||||
attrs={
|
||||
"rows": 5,
|
||||
"class": "form-control"
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("New intervention")
|
||||
self.action_url = reverse("intervention:new")
|
||||
self.cancel_redirect = reverse("intervention:index")
|
||||
|
||||
tmp_intervention = Intervention()
|
||||
identifier = tmp_intervention._generate_new_identifier()
|
||||
self.initialize_form_field("identifier", identifier)
|
||||
|
||||
def save(self, user: User, geom_form: SimpleGeomForm):
|
||||
with transaction.atomic():
|
||||
# Fetch data from cleaned POST values
|
||||
identifier = self.cleaned_data.get("identifier", None)
|
||||
title = self.cleaned_data.get("title", None)
|
||||
_type = self.cleaned_data.get("type", None)
|
||||
laws = self.cleaned_data.get("laws", None)
|
||||
handler = self.cleaned_data.get("handler", None)
|
||||
registration_office = self.cleaned_data.get("registration_office", None)
|
||||
conservation_office = self.cleaned_data.get("conservation_office", None)
|
||||
conservation_file_number = self.cleaned_data.get("conservation_file_number", None)
|
||||
registration_file_number = self.cleaned_data.get("registration_file_number", None)
|
||||
binding_date = self.cleaned_data.get("binding_date", None)
|
||||
registration_date = self.cleaned_data.get("registration_date", None)
|
||||
comment = self.cleaned_data.get("comment", None)
|
||||
|
||||
# Create log entry
|
||||
action = UserActionLogEntry.objects.create(
|
||||
user=user,
|
||||
action=UserAction.CREATED,
|
||||
)
|
||||
|
||||
# Create legal data object (without M2M laws first)
|
||||
legal_data = LegalData.objects.create(
|
||||
registration_date=registration_date,
|
||||
binding_date=binding_date,
|
||||
process_type=_type,
|
||||
)
|
||||
# Then add the M2M laws to the object
|
||||
legal_data.laws.set(laws)
|
||||
|
||||
# Create responsible data object
|
||||
responsibility_data = ResponsibilityData.objects.create(
|
||||
registration_office=registration_office,
|
||||
conservation_office=conservation_office,
|
||||
registration_file_number=registration_file_number,
|
||||
conservation_file_number=conservation_file_number,
|
||||
handler=handler,
|
||||
)
|
||||
|
||||
# Process the geometry form
|
||||
geometry = geom_form.save(action)
|
||||
|
||||
# Finally create main object, holding the other objects
|
||||
intervention = Intervention.objects.create(
|
||||
identifier=identifier,
|
||||
title=title,
|
||||
responsible=responsibility_data,
|
||||
legal=legal_data,
|
||||
created=action,
|
||||
geometry=geometry,
|
||||
comment=comment,
|
||||
)
|
||||
|
||||
# Add the log entry to the main objects log list
|
||||
intervention.log.add(action)
|
||||
|
||||
# Add the performing user as the first user having access to the data
|
||||
intervention.users.add(user)
|
||||
return intervention
|
||||
|
||||
|
||||
class EditInterventionForm(NewInterventionForm):
|
||||
""" Subclasses NewInterventionForm
|
||||
|
||||
Simply adds initializing of a provided self.instance object into the form fields
|
||||
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
if self.instance is not None:
|
||||
self.action_url = reverse("intervention:edit", args=(self.instance.id,))
|
||||
self.cancel_redirect = reverse("intervention:open", args=(self.instance.id,))
|
||||
self.form_title = _("Edit intervention")
|
||||
self.form_caption = ""
|
||||
|
||||
reg_date = self.instance.legal.registration_date
|
||||
bind_date = self.instance.legal.binding_date
|
||||
if reg_date is not None:
|
||||
reg_date = reg_date.isoformat()
|
||||
if bind_date is not None:
|
||||
bind_date = bind_date.isoformat()
|
||||
|
||||
# Initialize form data
|
||||
form_data = {
|
||||
"identifier": self.instance.identifier,
|
||||
"title": self.instance.title,
|
||||
"type": self.instance.legal.process_type,
|
||||
"laws": list(self.instance.legal.laws.values_list("id", flat=True)),
|
||||
"handler": self.instance.responsible.handler,
|
||||
"registration_office": self.instance.responsible.registration_office,
|
||||
"registration_file_number": self.instance.responsible.registration_file_number,
|
||||
"conservation_office": self.instance.responsible.conservation_office,
|
||||
"conservation_file_number": self.instance.responsible.conservation_file_number,
|
||||
"registration_date": reg_date,
|
||||
"binding_date": bind_date,
|
||||
"comment": self.instance.comment,
|
||||
}
|
||||
disabled_fields = []
|
||||
self.load_initial_data(
|
||||
form_data,
|
||||
disabled_fields
|
||||
)
|
||||
|
||||
def save(self, user: User, geom_form: SimpleGeomForm):
|
||||
""" Overwrite instance with new form data
|
||||
|
||||
Args:
|
||||
user ():
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
with transaction.atomic():
|
||||
identifier = self.cleaned_data.get("identifier", None)
|
||||
title = self.cleaned_data.get("title", None)
|
||||
process_type = self.cleaned_data.get("type", None)
|
||||
laws = self.cleaned_data.get("laws", None)
|
||||
handler = self.cleaned_data.get("handler", None)
|
||||
registration_office = self.cleaned_data.get("registration_office", None)
|
||||
registration_file_number = self.cleaned_data.get("registration_file_number", None)
|
||||
conservation_office = self.cleaned_data.get("conservation_office", None)
|
||||
conservation_file_number = self.cleaned_data.get("conservation_file_number", None)
|
||||
registration_date = self.cleaned_data.get("registration_date", None)
|
||||
binding_date = self.cleaned_data.get("binding_date", None)
|
||||
comment = self.cleaned_data.get("comment", None)
|
||||
|
||||
self.instance.legal.process_type = process_type
|
||||
self.instance.legal.registration_date = registration_date
|
||||
self.instance.legal.binding_date = binding_date
|
||||
self.instance.legal.laws.set(laws)
|
||||
self.instance.legal.save()
|
||||
|
||||
self.instance.responsible.handler = handler
|
||||
self.instance.responsible.registration_office = registration_office
|
||||
self.instance.responsible.registration_file_number = registration_file_number
|
||||
self.instance.responsible.conservation_office = conservation_office
|
||||
self.instance.responsible.conservation_file_number = conservation_file_number
|
||||
self.instance.responsible.save()
|
||||
|
||||
user_action = UserActionLogEntry.objects.create(
|
||||
user=user,
|
||||
timestamp=timezone.now(),
|
||||
action=UserAction.EDITED,
|
||||
)
|
||||
|
||||
geometry = geom_form.save(user_action)
|
||||
self.instance.geometry = geometry
|
||||
self.instance.geometry.save()
|
||||
|
||||
self.instance.log.add(user_action)
|
||||
|
||||
self.instance.identifier = identifier
|
||||
self.instance.title = title
|
||||
self.instance.comment = comment
|
||||
self.instance.modified = user_action
|
||||
self.instance.save()
|
||||
|
||||
return self.instance
|
||||
|
387
intervention/forms/modalForms.py
Normal file
387
intervention/forms/modalForms.py
Normal file
@ -0,0 +1,387 @@
|
||||
"""
|
||||
Author: Michel Peltriaux
|
||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 27.09.21
|
||||
|
||||
"""
|
||||
from dal import autocomplete
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import transaction
|
||||
from django import forms
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from compensation.models import EcoAccount, EcoAccountDeduction
|
||||
from intervention.inputs import TextToClipboardInput
|
||||
from intervention.models import Revocation, RevocationDocument, Intervention
|
||||
from konova.forms import BaseModalForm
|
||||
from konova.settings import ZB_GROUP, ETS_GROUP
|
||||
from konova.utils.general import format_german_float
|
||||
from konova.utils.messenger import Messenger
|
||||
from konova.utils.user_checks import in_group
|
||||
from user.models import UserActionLogEntry, UserAction
|
||||
|
||||
|
||||
class ShareInterventionModalForm(BaseModalForm):
|
||||
url = forms.CharField(
|
||||
label=_("Share link"),
|
||||
label_suffix="",
|
||||
help_text=_("Send this link to users who you want to have writing access on the data"),
|
||||
required=False,
|
||||
widget=TextToClipboardInput(
|
||||
attrs={
|
||||
"readonly": True,
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
users = forms.MultipleChoiceField(
|
||||
label=_("Shared with"),
|
||||
label_suffix="",
|
||||
required=True,
|
||||
help_text=_("Remove check to remove access for this user"),
|
||||
widget=forms.CheckboxSelectMultiple(
|
||||
attrs={
|
||||
"class": "list-unstyled",
|
||||
}
|
||||
),
|
||||
choices=[]
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("Share")
|
||||
self.form_caption = _("Share settings for {}").format(self.instance.identifier)
|
||||
self.template = "modal/modal_form.html"
|
||||
|
||||
# Make sure an access_token is set
|
||||
if self.instance.access_token is None:
|
||||
self.instance.generate_access_token()
|
||||
|
||||
self._init_fields()
|
||||
|
||||
def _init_fields(self):
|
||||
""" Wraps initializing of fields
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
# Initialize share_link field
|
||||
self.share_link = self.request.build_absolute_uri(
|
||||
reverse("intervention:share", args=(self.instance.id, self.instance.access_token,))
|
||||
)
|
||||
self.initialize_form_field(
|
||||
"url",
|
||||
self.share_link
|
||||
)
|
||||
|
||||
# Initialize users field
|
||||
# Remove field if user is not in registration or conservation group
|
||||
if not in_group(self.request.user, ZB_GROUP) and not in_group(self.request.user, ETS_GROUP):
|
||||
del self.fields["users"]
|
||||
else:
|
||||
users = self.instance.users.all()
|
||||
choices = []
|
||||
for n in users:
|
||||
choices.append(
|
||||
(n.id, n.username)
|
||||
)
|
||||
self.fields["users"].choices = choices
|
||||
u_ids = list(users.values_list("id", flat=True))
|
||||
self.initialize_form_field(
|
||||
"users",
|
||||
u_ids
|
||||
)
|
||||
|
||||
def save(self):
|
||||
accessing_users = User.objects.filter(
|
||||
id__in=self.cleaned_data["users"]
|
||||
)
|
||||
self.instance.users.set(accessing_users)
|
||||
|
||||
|
||||
class NewRevocationModalForm(BaseModalForm):
|
||||
date = forms.DateField(
|
||||
label=_("Date"),
|
||||
label_suffix=_(""),
|
||||
help_text=_("Date of revocation"),
|
||||
widget=forms.DateInput(
|
||||
attrs={
|
||||
"type": "date",
|
||||
"data-provide": "datepicker",
|
||||
"class": "form-control",
|
||||
},
|
||||
format="%d.%m.%Y"
|
||||
)
|
||||
)
|
||||
file = forms.FileField(
|
||||
label=_("Document"),
|
||||
label_suffix=_(""),
|
||||
required=False,
|
||||
help_text=_("Must be smaller than 15 Mb"),
|
||||
widget=forms.FileInput(
|
||||
attrs={
|
||||
"class": "form-control-file"
|
||||
}
|
||||
)
|
||||
)
|
||||
comment = forms.CharField(
|
||||
required=False,
|
||||
max_length=200,
|
||||
label=_("Comment"),
|
||||
label_suffix=_(""),
|
||||
help_text=_("Additional comment, maximum {} letters").format(200),
|
||||
widget=forms.Textarea(
|
||||
attrs={
|
||||
"cols": 30,
|
||||
"rows": 5,
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("Add revocation")
|
||||
self.form_caption = ""
|
||||
self.form_attrs = {
|
||||
"enctype": "multipart/form-data", # important for file upload
|
||||
}
|
||||
|
||||
def save(self):
|
||||
with transaction.atomic():
|
||||
created_action = UserActionLogEntry.objects.create(
|
||||
user=self.user,
|
||||
action=UserAction.CREATED
|
||||
)
|
||||
edited_action = UserActionLogEntry.objects.create(
|
||||
user=self.user,
|
||||
action=UserAction.EDITED
|
||||
)
|
||||
revocation = Revocation.objects.create(
|
||||
date=self.cleaned_data["date"],
|
||||
comment=self.cleaned_data["comment"],
|
||||
created=created_action,
|
||||
)
|
||||
self.instance.modified = edited_action
|
||||
self.instance.save()
|
||||
self.instance.log.add(edited_action)
|
||||
self.instance.legal.revocation = revocation
|
||||
self.instance.legal.save()
|
||||
|
||||
if self.cleaned_data["file"]:
|
||||
RevocationDocument.objects.create(
|
||||
title="revocation_of_{}".format(self.instance.identifier),
|
||||
date_of_creation=self.cleaned_data["date"],
|
||||
comment=self.cleaned_data["comment"],
|
||||
file=self.cleaned_data["file"],
|
||||
instance=revocation
|
||||
)
|
||||
return revocation
|
||||
|
||||
|
||||
class RunCheckModalForm(BaseModalForm):
|
||||
checked_intervention = forms.BooleanField(
|
||||
label=_("Checked intervention data"),
|
||||
label_suffix="",
|
||||
widget=forms.CheckboxInput(),
|
||||
required=True,
|
||||
)
|
||||
checked_comps = forms.BooleanField(
|
||||
label=_("Checked compensations data and payments"),
|
||||
label_suffix="",
|
||||
widget=forms.CheckboxInput(),
|
||||
required=True
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("Run check")
|
||||
self.form_caption = _("I, {} {}, confirm that all necessary control steps have been performed by myself.").format(self.user.first_name, self.user.last_name)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
""" Perform a validity check based on quality_check() logic
|
||||
|
||||
Returns:
|
||||
result (bool)
|
||||
"""
|
||||
super_result = super().is_valid()
|
||||
# Perform check
|
||||
msgs = self.instance.quality_check()
|
||||
for msg in msgs:
|
||||
self.add_error(
|
||||
"checked_intervention",
|
||||
msg
|
||||
)
|
||||
return super_result and (len(msgs) == 0)
|
||||
|
||||
def save(self):
|
||||
""" Saving logic
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
with transaction.atomic():
|
||||
user_action = UserActionLogEntry.objects.create(
|
||||
user=self.user,
|
||||
action=UserAction.CHECKED
|
||||
)
|
||||
# Replace old checked
|
||||
if self.instance.checked:
|
||||
self.instance.checked.delete()
|
||||
self.instance.checked = user_action
|
||||
self.instance.log.add(user_action)
|
||||
self.instance.save()
|
||||
|
||||
# Send message to the SSO server
|
||||
messenger = Messenger(
|
||||
self.instance.users.all(),
|
||||
type="INFO",
|
||||
)
|
||||
messenger.send_object_checked(
|
||||
self.instance.identifier,
|
||||
self.user,
|
||||
)
|
||||
|
||||
|
||||
class NewDeductionModalForm(BaseModalForm):
|
||||
""" Form for creating new deduction
|
||||
|
||||
Can be used for Intervention view as well as for EcoAccount views.
|
||||
|
||||
Parameter 'instance' can be an intervention, as well as an ecoAccount.
|
||||
An instance check handles both workflows properly.
|
||||
|
||||
"""
|
||||
account = forms.ModelChoiceField(
|
||||
label=_("Eco-account"),
|
||||
label_suffix="",
|
||||
help_text=_("Only recorded accounts can be selected for deductions"),
|
||||
queryset=EcoAccount.objects.filter(deleted=None),
|
||||
widget=autocomplete.ModelSelect2(
|
||||
url="accounts-autocomplete",
|
||||
attrs={
|
||||
"data-placeholder": _("Eco-account"),
|
||||
"data-minimum-input-length": 3,
|
||||
"readonly": True,
|
||||
}
|
||||
),
|
||||
)
|
||||
surface = forms.DecimalField(
|
||||
min_value=0.00,
|
||||
decimal_places=2,
|
||||
label=_("Surface"),
|
||||
label_suffix="",
|
||||
help_text=_("in m²"),
|
||||
widget=forms.NumberInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
intervention = forms.ModelChoiceField(
|
||||
label=_("Intervention"),
|
||||
label_suffix="",
|
||||
help_text=_("Only shared interventions can be selected"),
|
||||
queryset=Intervention.objects.filter(deleted=None),
|
||||
widget=autocomplete.ModelSelect2(
|
||||
url="interventions-autocomplete",
|
||||
attrs={
|
||||
"data-placeholder": _("Intervention"),
|
||||
"data-minimum-input-length": 3,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("New Deduction")
|
||||
self.form_caption = _("Enter the information for a new deduction from a chosen eco-account")
|
||||
self.is_intervention_initially = False
|
||||
|
||||
# Add a placeholder for field 'surface' without having to define the whole widget above
|
||||
self.add_placeholder_for_field("surface", "0,00")
|
||||
|
||||
# Check for Intervention or EcoAccount
|
||||
if isinstance(self.instance, Intervention):
|
||||
# Form has been called with a given intervention
|
||||
self.initialize_form_field("intervention", self.instance)
|
||||
self.disable_form_field("intervention")
|
||||
self.is_intervention_initially = True
|
||||
elif isinstance(self.instance, EcoAccount):
|
||||
# Form has been called with a given account --> make it initial in the form and read-only
|
||||
self.initialize_form_field("account", self.instance)
|
||||
self.disable_form_field("account")
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
def is_valid(self):
|
||||
""" Custom validity check
|
||||
|
||||
Makes sure the deduction can not contain more surface than the account still provides
|
||||
|
||||
Returns:
|
||||
is_valid (bool)
|
||||
"""
|
||||
super_result = super().is_valid()
|
||||
if self.is_intervention_initially:
|
||||
acc = self.cleaned_data["account"]
|
||||
else:
|
||||
acc = self.instance
|
||||
|
||||
if not acc.recorded:
|
||||
self.add_error(
|
||||
"account",
|
||||
_("Eco-account {} is not recorded yet. You can only deduct from recorded accounts.").format(acc.identifier)
|
||||
)
|
||||
return False
|
||||
|
||||
# Calculate valid surface
|
||||
sum_surface = acc.get_surface()
|
||||
sum_surface_deductions = acc.get_deductions_surface()
|
||||
rest_surface = sum_surface - sum_surface_deductions
|
||||
form_surface = float(self.cleaned_data["surface"])
|
||||
is_valid_surface = form_surface < rest_surface
|
||||
if not is_valid_surface:
|
||||
self.add_error(
|
||||
"surface",
|
||||
_("The account {} has not enough surface for a deduction of {} m². There are only {} m² left").format(
|
||||
acc.identifier,
|
||||
format_german_float(form_surface),
|
||||
format_german_float(rest_surface),
|
||||
),
|
||||
)
|
||||
return is_valid_surface and super_result
|
||||
|
||||
def save(self):
|
||||
with transaction.atomic():
|
||||
# Create log entry
|
||||
user_action_edit = UserActionLogEntry.objects.create(
|
||||
user=self.user,
|
||||
action=UserAction.EDITED
|
||||
)
|
||||
user_action_create = UserActionLogEntry.objects.create(
|
||||
user=self.user,
|
||||
action=UserAction.CREATED
|
||||
)
|
||||
self.instance.log.add(user_action_edit)
|
||||
self.instance.modified = user_action_edit
|
||||
self.instance.save()
|
||||
|
||||
# Create deductions depending on Intervention or EcoAccount as the initial instance
|
||||
if self.is_intervention_initially:
|
||||
deduction = EcoAccountDeduction.objects.create(
|
||||
intervention=self.instance,
|
||||
account=self.cleaned_data["account"],
|
||||
surface=self.cleaned_data["surface"],
|
||||
created=user_action_create,
|
||||
)
|
||||
else:
|
||||
deduction = EcoAccountDeduction.objects.create(
|
||||
intervention=self.cleaned_data["intervention"],
|
||||
account=self.instance,
|
||||
surface=self.cleaned_data["surface"],
|
||||
created=user_action_create,
|
||||
)
|
||||
return deduction
|
32
intervention/inputs.py
Normal file
32
intervention/inputs.py
Normal file
@ -0,0 +1,32 @@
|
||||
from django import forms
|
||||
|
||||
|
||||
class DummyFilterInput(forms.HiddenInput):
|
||||
""" A dummy input widget
|
||||
|
||||
Does not render anything. Can be used to keep filter logic using django_filter without having a pre defined
|
||||
filter widget being rendered to the template.
|
||||
|
||||
"""
|
||||
template_name = "konova/custom_widgets/dummy-filter-input.html"
|
||||
|
||||
|
||||
class TextToClipboardInput(forms.TextInput):
|
||||
template_name = "konova/custom_widgets/text-to-clipboard-input.html"
|
||||
|
||||
|
||||
class GenerateInput(forms.TextInput):
|
||||
"""
|
||||
|
||||
Provides a form group with a button at the end, which generates new content for the input.
|
||||
The url used to fetch new content can be added using the attrs like
|
||||
|
||||
widget=GenerateInput(
|
||||
attrs={
|
||||
"url": reverse_lazy("app_name:view_name")
|
||||
...
|
||||
}
|
||||
)
|
||||
|
||||
"""
|
||||
template_name = "konova/custom_widgets/generate-content-input.html"
|
@ -9,12 +9,13 @@ from django.urls import path
|
||||
|
||||
from intervention.views import index_view, new_view, open_view, edit_view, remove_view, new_document_view, share_view, \
|
||||
create_share_view, remove_revocation_view, new_revocation_view, run_check_view, log_view, new_deduction_view, \
|
||||
record_view, remove_document_view, get_document_view, get_revocation_view
|
||||
record_view, remove_document_view, get_document_view, get_revocation_view, new_id_view
|
||||
|
||||
app_name = "intervention"
|
||||
urlpatterns = [
|
||||
path("", index_view, name="index"),
|
||||
path('new/', new_view, name='new'),
|
||||
path('new/id', new_id_view, name='new-id'),
|
||||
path('<id>', open_view, name='open'),
|
||||
path('<id>/log', log_view, name='log'),
|
||||
path('<id>/edit', edit_view, name='edit'),
|
||||
|
@ -1,11 +1,11 @@
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.http import HttpRequest
|
||||
from django.http import HttpRequest, JsonResponse
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
|
||||
from intervention.forms import NewInterventionForm, EditInterventionForm, ShareInterventionForm, NewRevocationForm, \
|
||||
RunCheckForm, NewDeductionForm
|
||||
from intervention.forms.forms import NewInterventionForm, EditInterventionForm
|
||||
from intervention.forms.modalForms import ShareInterventionModalForm, NewRevocationModalForm, \
|
||||
RunCheckModalForm, NewDeductionModalForm
|
||||
from intervention.models import Intervention, Revocation, InterventionDocument, RevocationDocument
|
||||
from intervention.tables import InterventionTable
|
||||
from konova.contexts import BaseContext
|
||||
@ -13,7 +13,7 @@ from konova.decorators import *
|
||||
from konova.forms import SimpleGeomForm, NewDocumentForm, RemoveModalForm, RecordModalForm
|
||||
from konova.sub_settings.django_settings import DEFAULT_DATE_FORMAT
|
||||
from konova.utils.documents import remove_document, get_document
|
||||
from konova.utils.message_templates import FORM_INVALID, INTERVENTION_INVALID
|
||||
from konova.utils.message_templates import INTERVENTION_INVALID
|
||||
from konova.utils.user_checks import in_group
|
||||
|
||||
|
||||
@ -68,7 +68,10 @@ def new_view(request: HttpRequest):
|
||||
if generated_identifier != intervention.identifier:
|
||||
messages.info(
|
||||
request,
|
||||
_("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier")
|
||||
_("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier").format(
|
||||
generated_identifier,
|
||||
intervention.identifier
|
||||
)
|
||||
)
|
||||
messages.success(request, _("Intervention {} added").format(intervention.identifier))
|
||||
return redirect("intervention:index")
|
||||
@ -80,11 +83,30 @@ def new_view(request: HttpRequest):
|
||||
context = {
|
||||
"data_form": data_form,
|
||||
"geom_form": geom_form,
|
||||
"url": reverse("intervention:new-id")
|
||||
}
|
||||
context = BaseContext(request, context).context
|
||||
return render(request, template, context)
|
||||
|
||||
|
||||
@login_required
|
||||
def new_id_view(request: HttpRequest):
|
||||
""" JSON endpoint
|
||||
|
||||
Provides fetching of free identifiers for e.g. AJAX calls
|
||||
|
||||
"""
|
||||
tmp_intervention = Intervention()
|
||||
identifier = tmp_intervention._generate_new_identifier()
|
||||
while Intervention.objects.filter(identifier=identifier).exists():
|
||||
identifier = tmp_intervention._generate_new_identifier()
|
||||
return JsonResponse(
|
||||
data={
|
||||
"identifier": identifier
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
def new_document_view(request: HttpRequest, id: str):
|
||||
""" Renders a form for uploading new documents
|
||||
@ -221,20 +243,17 @@ def edit_view(request: HttpRequest, id: str):
|
||||
|
||||
"""
|
||||
template = "intervention/new/view.html"
|
||||
# Get object from db
|
||||
intervention = get_object_or_404(Intervention, id=id)
|
||||
# Create forms, initialize with values from db/from POST request
|
||||
data_form = EditInterventionForm(request.POST or None, instance=intervention)
|
||||
geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=intervention)
|
||||
if request.method == "POST":
|
||||
if data_form.is_valid() and geom_form.is_valid():
|
||||
generated_identifier = data_form.cleaned_data.get("identifier", None)
|
||||
# The data form takes the geom form for processing, as well as the performing user
|
||||
intervention = data_form.save(request.user, geom_form)
|
||||
if generated_identifier != intervention.identifier:
|
||||
messages.info(
|
||||
request,
|
||||
_("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier")
|
||||
)
|
||||
messages.success(request, _("Intervention {} added").format(intervention.identifier))
|
||||
return redirect("intervention:index")
|
||||
messages.success(request, _("Intervention {} edited").format(intervention.identifier))
|
||||
return redirect("intervention:open", id=intervention.id)
|
||||
else:
|
||||
messages.error(request, _("Invalid input"))
|
||||
else:
|
||||
@ -342,7 +361,7 @@ def create_share_view(request: HttpRequest, id: str):
|
||||
|
||||
"""
|
||||
intervention = get_object_or_404(Intervention, id=id)
|
||||
form = ShareInterventionForm(request.POST or None, instance=intervention, request=request)
|
||||
form = ShareInterventionModalForm(request.POST or None, instance=intervention, request=request)
|
||||
return form.process_request(
|
||||
request,
|
||||
msg_success=_("Share settings updated")
|
||||
@ -361,7 +380,7 @@ def run_check_view(request: HttpRequest, id: str):
|
||||
|
||||
"""
|
||||
intervention = get_object_or_404(Intervention, id=id)
|
||||
form = RunCheckForm(request.POST or None, instance=intervention, user=request.user)
|
||||
form = RunCheckModalForm(request.POST or None, instance=intervention, user=request.user)
|
||||
return form.process_request(
|
||||
request,
|
||||
msg_success=_("Check performed"),
|
||||
@ -381,7 +400,7 @@ def new_revocation_view(request: HttpRequest, id: str):
|
||||
|
||||
"""
|
||||
intervention = get_object_or_404(Intervention, id=id)
|
||||
form = NewRevocationForm(request.POST or None, request.FILES or None, instance=intervention, user=request.user)
|
||||
form = NewRevocationModalForm(request.POST or None, request.FILES or None, instance=intervention, user=request.user)
|
||||
return form.process_request(
|
||||
request,
|
||||
msg_success=_("Revocation added")
|
||||
@ -425,7 +444,7 @@ def new_deduction_view(request: HttpRequest, id: str):
|
||||
|
||||
"""
|
||||
intervention = get_object_or_404(Intervention, id=id)
|
||||
form = NewDeductionForm(request.POST or None, instance=intervention, user=request.user)
|
||||
form = NewDeductionModalForm(request.POST or None, instance=intervention, user=request.user)
|
||||
return form.process_request(
|
||||
request,
|
||||
msg_success=_("Deduction added")
|
||||
|
@ -43,7 +43,6 @@ class BaseForm(forms.Form):
|
||||
instance = None # The data holding model object
|
||||
form_attrs = {} # Holds additional attributes, that can be used in the template
|
||||
has_required_fields = False # Automatically set. Triggers hint rendering in templates
|
||||
full_width_fields = False # w-100 for all input fields
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.instance = kwargs.pop("instance", None)
|
||||
@ -56,11 +55,6 @@ class BaseForm(forms.Form):
|
||||
self.has_required_fields = True
|
||||
break
|
||||
|
||||
if self.full_width_fields:
|
||||
# Automatically add bootstrap w-100 class for maximum width of form fields in modals
|
||||
for key, val in self.fields.items():
|
||||
self.add_widget_html_class(key, "w-100")
|
||||
|
||||
@abstractmethod
|
||||
def save(self):
|
||||
# To be implemented in subclasses!
|
||||
@ -276,9 +270,9 @@ class SimpleGeomForm(BaseForm):
|
||||
geom = Polygon.from_bbox([0, 0, 0, 0])
|
||||
# Zoom out to a very high level, so the user can see directly that there is no geometry for this entry
|
||||
self.fields["geom"].widget.attrs["default_zoom"] = 1
|
||||
if read_only:
|
||||
self.initialize_form_field("geom", geom)
|
||||
self.area = geom.area
|
||||
if read_only:
|
||||
self.fields["geom"].disabled = True
|
||||
|
||||
def save(self, action: UserActionLogEntry):
|
||||
@ -326,6 +320,11 @@ class NewDocumentForm(BaseModalForm):
|
||||
label=_("Title"),
|
||||
label_suffix=_(""),
|
||||
max_length=500,
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
creation_date = forms.DateField(
|
||||
label=_("Created on"),
|
||||
@ -335,6 +334,7 @@ class NewDocumentForm(BaseModalForm):
|
||||
attrs={
|
||||
"type": "date",
|
||||
"data-provide": "datepicker",
|
||||
"class": "form-control",
|
||||
},
|
||||
format="%d.%m.%Y"
|
||||
)
|
||||
@ -345,7 +345,7 @@ class NewDocumentForm(BaseModalForm):
|
||||
help_text=_("Must be smaller than 15 Mb"),
|
||||
widget=forms.FileInput(
|
||||
attrs={
|
||||
"class": "w-75"
|
||||
"class": "form-control-file",
|
||||
}
|
||||
),
|
||||
)
|
||||
@ -359,6 +359,7 @@ class NewDocumentForm(BaseModalForm):
|
||||
attrs={
|
||||
"cols": 30,
|
||||
"rows": 5,
|
||||
"class": "form-control",
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -370,9 +371,6 @@ class NewDocumentForm(BaseModalForm):
|
||||
Ema: EmaDocument,
|
||||
}
|
||||
|
||||
# Define w-100 for all form fields
|
||||
full_width_fields = True
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("Add new document")
|
||||
|
@ -60,13 +60,7 @@ a {
|
||||
color: var(--rlp-red);
|
||||
}
|
||||
|
||||
input[type=text], input[type=date] {
|
||||
border: 1px solid gray;
|
||||
border-radius: 0.2rem;
|
||||
padding: 0.3rem 0.5rem;
|
||||
}
|
||||
|
||||
input:focus, textarea:focus, select:focus{
|
||||
.form-control:focus{
|
||||
outline: none;
|
||||
border-color: var(--rlp-red);
|
||||
box-shadow: 0 0 3px var(--rlp-red);
|
||||
|
@ -0,0 +1,22 @@
|
||||
{% load i18n fontawesome_5 %}
|
||||
|
||||
<div class="input-group w-100" title="{{ widget.value|stringformat:'s' }}">
|
||||
<input id="gen-id-input" aria-describedby="gen-id-btn" type="{{ widget.type }}" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value|stringformat:'s' }}"{% endif %}{% include "django/forms/widgets/attrs.html" %}>
|
||||
<div class="input-group-append" onclick="fetchNewIdentifier()">
|
||||
<span id="gen-id-btn" class="btn btn-default" value="{% trans 'Generate new' %}" title="{% trans 'Generate new' %}">{% fa5_icon 'dice' %}</span>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function fetchNewIdentifier() {
|
||||
fetch("{{ widget.attrs.url }}")
|
||||
.then(function(response){
|
||||
return response.json();
|
||||
})
|
||||
.then(function(data){
|
||||
document.getElementById("gen-id-input").value = data["identifier"];
|
||||
})
|
||||
.catch(function(error){
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
</script>
|
Binary file not shown.
@ -3,21 +3,22 @@
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#: compensation/filters.py:71 compensation/forms.py:47 compensation/forms.py:52
|
||||
#: compensation/forms.py:67 compensation/forms.py:264 compensation/forms.py:345
|
||||
#: compensation/filters.py:71 compensation/forms.py:47 compensation/forms.py:57
|
||||
#: compensation/forms.py:73 compensation/forms.py:276 compensation/forms.py:363
|
||||
#: intervention/filters.py:26 intervention/filters.py:40
|
||||
#: intervention/filters.py:47 intervention/filters.py:48
|
||||
#: intervention/forms.py:56 intervention/forms.py:151 intervention/forms.py:162
|
||||
#: intervention/forms.py:422 intervention/forms.py:434
|
||||
#: intervention/forms.py:447 konova/forms.py:140 konova/forms.py:250
|
||||
#: konova/forms.py:296 konova/forms.py:331 konova/forms.py:336
|
||||
#: konova/forms.py:348 konova/forms.py:360 konova/forms.py:380 user/forms.py:38
|
||||
#: intervention/forms/forms.py:53 intervention/forms/forms.py:151
|
||||
#: intervention/forms/forms.py:163 intervention/forms/modalForms.py:107
|
||||
#: intervention/forms/modalForms.py:120 intervention/forms/modalForms.py:133
|
||||
#: konova/forms.py:140 konova/forms.py:244 konova/forms.py:294
|
||||
#: konova/forms.py:321 konova/forms.py:331 konova/forms.py:344
|
||||
#: konova/forms.py:356 konova/forms.py:377 user/forms.py:38
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-23 12:46+0200\n"
|
||||
"POT-Creation-Date: 2021-09-27 13:56+0200\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"
|
||||
@ -35,16 +36,16 @@ msgstr "Nur unverzeichnete anzeigen"
|
||||
msgid "in Euro"
|
||||
msgstr "in Euro"
|
||||
|
||||
#: compensation/forms.py:51
|
||||
#: compensation/forms.py:56
|
||||
#: intervention/templates/intervention/detail/includes/payments.html:31
|
||||
msgid "Due on"
|
||||
msgstr "Fällig am"
|
||||
|
||||
#: compensation/forms.py:54
|
||||
#: compensation/forms.py:59
|
||||
msgid "Due on which date"
|
||||
msgstr "Zahlung wird an diesem Datum erwartet"
|
||||
|
||||
#: compensation/forms.py:66 compensation/forms.py:263 compensation/forms.py:344
|
||||
#: compensation/forms.py:72 compensation/forms.py:275 compensation/forms.py:362
|
||||
#: compensation/templates/compensation/detail/compensation/includes/actions.html:34
|
||||
#: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34
|
||||
#: compensation/templates/compensation/detail/compensation/includes/documents.html:31
|
||||
@ -54,115 +55,115 @@ msgstr "Zahlung wird an diesem Datum erwartet"
|
||||
#: ema/templates/ema/detail/includes/actions.html:34
|
||||
#: ema/templates/ema/detail/includes/deadlines.html:34
|
||||
#: ema/templates/ema/detail/includes/documents.html:31
|
||||
#: intervention/forms.py:446
|
||||
#: intervention/forms/forms.py:175 intervention/forms/modalForms.py:132
|
||||
#: intervention/templates/intervention/detail/includes/documents.html:31
|
||||
#: intervention/templates/intervention/detail/includes/payments.html:34
|
||||
#: intervention/templates/intervention/detail/includes/revocation.html:38
|
||||
#: konova/forms.py:359
|
||||
#: konova/forms.py:355
|
||||
msgid "Comment"
|
||||
msgstr "Kommentar"
|
||||
|
||||
#: compensation/forms.py:68 compensation/forms.py:265 compensation/forms.py:346
|
||||
#: intervention/forms.py:448 konova/forms.py:361
|
||||
#: compensation/forms.py:74 compensation/forms.py:277 compensation/forms.py:364
|
||||
#: intervention/forms/modalForms.py:134 konova/forms.py:357
|
||||
msgid "Additional comment, maximum {} letters"
|
||||
msgstr "Zusätzlicher Kommentar, maximal {} Zeichen"
|
||||
|
||||
#: compensation/forms.py:80
|
||||
#: compensation/forms.py:86
|
||||
msgid "Payment"
|
||||
msgstr "Zahlung"
|
||||
|
||||
#: compensation/forms.py:81
|
||||
#: compensation/forms.py:87
|
||||
msgid "Add a payment for intervention '{}'"
|
||||
msgstr "Neue Ersatzzahlung zu Eingriff '{}' hinzufügen"
|
||||
|
||||
#: compensation/forms.py:102
|
||||
#: compensation/forms.py:108
|
||||
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.py:116
|
||||
#: compensation/forms.py:122
|
||||
msgid "Added payment"
|
||||
msgstr "Zahlung hinzufügen"
|
||||
|
||||
#: compensation/forms.py:133 compensation/forms.py:145
|
||||
#: compensation/forms.py:139 compensation/forms.py:151
|
||||
msgid "Biotope Type"
|
||||
msgstr "Biotoptyp"
|
||||
|
||||
#: compensation/forms.py:136
|
||||
#: compensation/forms.py:142
|
||||
msgid "Select the biotope type"
|
||||
msgstr "Biotoptyp wählen"
|
||||
|
||||
#: compensation/forms.py:152
|
||||
#: compensation/forms.py:158
|
||||
#: 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
|
||||
#: intervention/forms.py:587
|
||||
#: intervention/forms/modalForms.py:274
|
||||
msgid "Surface"
|
||||
msgstr "Fläche"
|
||||
|
||||
#: compensation/forms.py:155 intervention/forms.py:589
|
||||
#: compensation/forms.py:161 intervention/forms/modalForms.py:276
|
||||
msgid "in m²"
|
||||
msgstr ""
|
||||
|
||||
#: compensation/forms.py:160
|
||||
#: compensation/forms.py:171
|
||||
msgid "New state"
|
||||
msgstr "Neuer Zustand"
|
||||
|
||||
#: compensation/forms.py:161
|
||||
#: compensation/forms.py:172
|
||||
msgid "Insert data for the new state"
|
||||
msgstr "Geben Sie die Daten des neuen Zustandes ein"
|
||||
|
||||
#: compensation/forms.py:169
|
||||
#: compensation/forms.py:180
|
||||
msgid "Added state"
|
||||
msgstr "Zustand hinzugefügt"
|
||||
|
||||
#: compensation/forms.py:185 konova/forms.py:199
|
||||
#: compensation/forms.py:196 konova/forms.py:193
|
||||
msgid "Object removed"
|
||||
msgstr "Objekt entfernt"
|
||||
|
||||
#: compensation/forms.py:236
|
||||
#: compensation/forms.py:247
|
||||
msgid "Deadline Type"
|
||||
msgstr "Fristart"
|
||||
|
||||
#: compensation/forms.py:239
|
||||
#: compensation/forms.py:250
|
||||
msgid "Select the deadline type"
|
||||
msgstr "Fristart wählen"
|
||||
|
||||
#: compensation/forms.py:248
|
||||
#: compensation/forms.py:259
|
||||
#: 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
|
||||
#: intervention/forms.py:421
|
||||
#: intervention/forms/modalForms.py:106
|
||||
msgid "Date"
|
||||
msgstr "Datum"
|
||||
|
||||
#: compensation/forms.py:251
|
||||
#: compensation/forms.py:262
|
||||
msgid "Select date"
|
||||
msgstr "Datum wählen"
|
||||
|
||||
#: compensation/forms.py:276
|
||||
#: compensation/forms.py:289
|
||||
msgid "New deadline"
|
||||
msgstr "Neue Frist"
|
||||
|
||||
#: compensation/forms.py:277
|
||||
#: compensation/forms.py:290
|
||||
msgid "Insert data for the new deadline"
|
||||
msgstr "Geben Sie die Daten der neuen Frist ein"
|
||||
|
||||
#: compensation/forms.py:294
|
||||
#: compensation/forms.py:307
|
||||
msgid "Added deadline"
|
||||
msgstr "Frist/Termin hinzugefügt"
|
||||
|
||||
#: compensation/forms.py:305
|
||||
#: compensation/forms.py:318
|
||||
msgid "Action Type"
|
||||
msgstr "Maßnahmentyp"
|
||||
|
||||
#: compensation/forms.py:308
|
||||
#: compensation/forms.py:321
|
||||
msgid "Select the action type"
|
||||
msgstr "Maßnahmentyp wählen"
|
||||
|
||||
#: compensation/forms.py:317
|
||||
#: compensation/forms.py:330
|
||||
#: compensation/templates/compensation/detail/compensation/includes/actions.html:37
|
||||
#: compensation/templates/compensation/detail/compensation/includes/deadlines.html:37
|
||||
#: compensation/templates/compensation/detail/compensation/includes/documents.html:34
|
||||
@ -188,33 +189,33 @@ msgstr "Maßnahmentyp wählen"
|
||||
msgid "Action"
|
||||
msgstr "Aktionen"
|
||||
|
||||
#: compensation/forms.py:322
|
||||
#: compensation/forms.py:335
|
||||
msgid "Unit"
|
||||
msgstr "Einheit"
|
||||
|
||||
#: compensation/forms.py:325
|
||||
#: compensation/forms.py:338
|
||||
msgid "Select the unit"
|
||||
msgstr "Einheit wählen"
|
||||
|
||||
#: compensation/forms.py:334
|
||||
#: compensation/forms.py:347
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:34
|
||||
#: intervention/templates/intervention/detail/includes/deductions.html:31
|
||||
msgid "Amount"
|
||||
msgstr "Menge"
|
||||
|
||||
#: compensation/forms.py:337
|
||||
#: compensation/forms.py:350
|
||||
msgid "Insert the amount"
|
||||
msgstr "Menge eingeben"
|
||||
|
||||
#: compensation/forms.py:357
|
||||
#: compensation/forms.py:375
|
||||
msgid "New action"
|
||||
msgstr "Neue Maßnahme"
|
||||
|
||||
#: compensation/forms.py:358
|
||||
#: compensation/forms.py:376
|
||||
msgid "Insert data for the new action"
|
||||
msgstr "Geben Sie die Daten der neuen Maßnahme ein"
|
||||
|
||||
#: compensation/forms.py:377
|
||||
#: compensation/forms.py:395
|
||||
msgid "Added action"
|
||||
msgstr "Maßnahme hinzugefügt"
|
||||
|
||||
@ -257,34 +258,34 @@ msgstr ""
|
||||
"Es wurde bereits mehr Fläche abgebucht, als Sie nun als abbuchbar einstellen "
|
||||
"wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!"
|
||||
|
||||
#: compensation/tables.py:24 compensation/tables.py:164 ema/tables.py:28
|
||||
#: intervention/forms.py:37 intervention/tables.py:23
|
||||
#: compensation/tables.py:25 compensation/tables.py:167 ema/tables.py:28
|
||||
#: intervention/forms/forms.py:27 intervention/tables.py:23
|
||||
#: intervention/templates/intervention/detail/includes/compensations.html:30
|
||||
msgid "Identifier"
|
||||
msgstr "Kennung"
|
||||
|
||||
#: compensation/tables.py:29 compensation/tables.py:169
|
||||
#: compensation/tables.py:30 compensation/tables.py:172
|
||||
#: compensation/templates/compensation/detail/compensation/includes/documents.html:28
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:31
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:28
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:31
|
||||
#: ema/tables.py:33 ema/templates/ema/detail/includes/documents.html:28
|
||||
#: ema/templates/ema/detail/view.html:24 intervention/forms.py:43
|
||||
#: ema/templates/ema/detail/view.html:24 intervention/forms/forms.py:39
|
||||
#: intervention/tables.py:28
|
||||
#: intervention/templates/intervention/detail/includes/compensations.html:33
|
||||
#: intervention/templates/intervention/detail/includes/documents.html:28
|
||||
#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:330
|
||||
#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:320
|
||||
msgid "Title"
|
||||
msgstr "Bezeichnung"
|
||||
|
||||
#: compensation/tables.py:34
|
||||
#: compensation/tables.py:35
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:43
|
||||
#: intervention/tables.py:33
|
||||
#: intervention/templates/intervention/detail/view.html:68 user/models.py:48
|
||||
msgid "Checked"
|
||||
msgstr "Geprüft"
|
||||
|
||||
#: compensation/tables.py:40 compensation/tables.py:179
|
||||
#: compensation/tables.py:41 compensation/tables.py:182
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:57
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:44
|
||||
@ -294,82 +295,82 @@ msgstr "Geprüft"
|
||||
msgid "Recorded"
|
||||
msgstr "Verzeichnet"
|
||||
|
||||
#: compensation/tables.py:46 compensation/tables.py:185 ema/tables.py:44
|
||||
#: compensation/tables.py:47 compensation/tables.py:188 ema/tables.py:44
|
||||
#: intervention/tables.py:51
|
||||
msgid "Editable"
|
||||
msgstr "Freigegeben"
|
||||
|
||||
#: compensation/tables.py:52 compensation/tables.py:191 ema/tables.py:50
|
||||
#: compensation/tables.py:53 compensation/tables.py:194 ema/tables.py:50
|
||||
#: intervention/tables.py:57
|
||||
msgid "Last edit"
|
||||
msgstr "Zuletzt bearbeitet"
|
||||
|
||||
#: compensation/tables.py:61
|
||||
#: compensation/tables.py:62
|
||||
#: intervention/templates/intervention/detail/includes/compensations.html:8
|
||||
msgid "Compensations"
|
||||
msgstr "Kompensationen"
|
||||
|
||||
#: compensation/tables.py:83 compensation/tables.py:222 ema/tables.py:82
|
||||
#: compensation/tables.py:84 compensation/tables.py:225 ema/tables.py:82
|
||||
#: intervention/tables.py:88
|
||||
msgid "Open {}"
|
||||
msgstr "Öffne {}"
|
||||
|
||||
#: compensation/tables.py:83
|
||||
#: compensation/tables.py:84
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:19
|
||||
#: konova/templates/konova/home.html:49 templates/navbar.html:28
|
||||
msgid "Compensation"
|
||||
msgstr "Kompensation"
|
||||
|
||||
#: compensation/tables.py:104 intervention/tables.py:107
|
||||
#: compensation/tables.py:105 intervention/tables.py:107
|
||||
msgid "Not checked yet"
|
||||
msgstr "Noch nicht geprüft"
|
||||
|
||||
#: compensation/tables.py:109 intervention/tables.py:112
|
||||
#: compensation/tables.py:110 intervention/tables.py:112
|
||||
msgid "Checked on {} by {}"
|
||||
msgstr "Am {} von {} geprüft worden"
|
||||
|
||||
#: compensation/tables.py:128
|
||||
#: compensation/tables.py:129
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:60
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:47
|
||||
#: ema/tables.py:101 ema/templates/ema/detail/view.html:31
|
||||
#: intervention/models.py:352 intervention/tables.py:131
|
||||
#: intervention/models.py:379 intervention/tables.py:131
|
||||
#: intervention/templates/intervention/detail/view.html:85
|
||||
msgid "Not recorded yet"
|
||||
msgstr "Noch nicht verzeichnet"
|
||||
|
||||
#: compensation/tables.py:133 compensation/tables.py:260 ema/tables.py:106
|
||||
#: intervention/models.py:357 intervention/tables.py:136
|
||||
#: compensation/tables.py:134 compensation/tables.py:263 ema/tables.py:106
|
||||
#: intervention/models.py:384 intervention/tables.py:136
|
||||
msgid "Recorded on {} by {}"
|
||||
msgstr "Am {} von {} verzeichnet worden"
|
||||
|
||||
#: compensation/tables.py:156 compensation/tables.py:283 ema/tables.py:129
|
||||
#: compensation/tables.py:159 compensation/tables.py:286 ema/tables.py:129
|
||||
#: intervention/tables.py:159
|
||||
msgid "Full access granted"
|
||||
msgstr "Für Sie freigegeben - Datensatz kann bearbeitet werden"
|
||||
|
||||
#: compensation/tables.py:156 compensation/tables.py:283 ema/tables.py:129
|
||||
#: compensation/tables.py:159 compensation/tables.py:286 ema/tables.py:129
|
||||
#: intervention/tables.py:159
|
||||
msgid "Access not granted"
|
||||
msgstr "Nicht freigegeben - Datensatz nur lesbar"
|
||||
|
||||
#: compensation/tables.py:174
|
||||
#: compensation/tables.py:177
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:35
|
||||
#: konova/templates/konova/custom_widgets/progressbar.html:3
|
||||
msgid "Available"
|
||||
msgstr "Verfügbar"
|
||||
|
||||
#: compensation/tables.py:200
|
||||
#: compensation/tables.py:203
|
||||
msgid "Eco Accounts"
|
||||
msgstr "Ökokonten"
|
||||
|
||||
#: compensation/tables.py:222
|
||||
#: compensation/tables.py:225
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:19
|
||||
#: intervention/forms.py:571 intervention/forms.py:578
|
||||
#: intervention/forms/modalForms.py:258 intervention/forms/modalForms.py:265
|
||||
#: konova/templates/konova/home.html:88 templates/navbar.html:34
|
||||
msgid "Eco-account"
|
||||
msgstr "Ökokonto"
|
||||
|
||||
#: compensation/tables.py:255
|
||||
#: compensation/tables.py:258
|
||||
msgid "Not recorded yet. Can not be used for deductions, yet."
|
||||
msgstr ""
|
||||
"Noch nicht verzeichnet. Kann noch nicht für Abbuchungen genutzt werden."
|
||||
@ -477,7 +478,7 @@ msgstr "Dokumente"
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:14
|
||||
#: ema/templates/ema/detail/includes/documents.html:14
|
||||
#: intervention/templates/intervention/detail/includes/documents.html:14
|
||||
#: konova/forms.py:379
|
||||
#: konova/forms.py:376
|
||||
msgid "Add new document"
|
||||
msgstr "Neues Dokument hinzufügen"
|
||||
|
||||
@ -582,7 +583,7 @@ msgstr "Zuletzt bearbeitet"
|
||||
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:92
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:91
|
||||
#: ema/templates/ema/detail/view.html:82 intervention/forms.py:355
|
||||
#: ema/templates/ema/detail/view.html:82 intervention/forms/modalForms.py:40
|
||||
#: intervention/templates/intervention/detail/view.html:116
|
||||
msgid "Shared with"
|
||||
msgstr "Freigegeben für"
|
||||
@ -643,19 +644,19 @@ msgid "Missing"
|
||||
msgstr "Fehlt"
|
||||
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:58
|
||||
#: ema/templates/ema/detail/view.html:42 intervention/forms.py:101
|
||||
#: ema/templates/ema/detail/view.html:42 intervention/forms/forms.py:98
|
||||
#: intervention/templates/intervention/detail/view.html:56
|
||||
msgid "Conservation office"
|
||||
msgstr "Eintragungsstelle"
|
||||
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:62
|
||||
#: ema/templates/ema/detail/view.html:46 intervention/forms.py:127
|
||||
#: ema/templates/ema/detail/view.html:46 intervention/forms/forms.py:125
|
||||
#: intervention/templates/intervention/detail/view.html:60
|
||||
msgid "Conservation office file number"
|
||||
msgstr "Aktenzeichen Eintragungsstelle"
|
||||
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:66
|
||||
#: ema/templates/ema/detail/view.html:50 intervention/forms.py:138
|
||||
#: ema/templates/ema/detail/view.html:50 intervention/forms/forms.py:137
|
||||
#: intervention/templates/intervention/detail/view.html:64
|
||||
msgid "Intervention handler"
|
||||
msgstr "Eingriffsverursacher"
|
||||
@ -667,7 +668,7 @@ msgstr ""
|
||||
|
||||
#: compensation/views/compensation_views.py:123
|
||||
#: compensation/views/eco_account_views.py:190 ema/views.py:128
|
||||
#: intervention/views.py:393
|
||||
#: intervention/views.py:428
|
||||
msgid "Log"
|
||||
msgstr "Log"
|
||||
|
||||
@ -677,7 +678,7 @@ msgstr "Kompensation entfernt"
|
||||
|
||||
#: compensation/views/compensation_views.py:163
|
||||
#: compensation/views/eco_account_views.py:289 ema/views.py:250
|
||||
#: intervention/views.py:96
|
||||
#: intervention/views.py:124
|
||||
msgid "Document added"
|
||||
msgstr "Dokument hinzugefügt"
|
||||
|
||||
@ -713,16 +714,16 @@ msgid "Deduction removed"
|
||||
msgstr "Abbuchung entfernt"
|
||||
|
||||
#: compensation/views/eco_account_views.py:210 ema/views.py:171
|
||||
#: intervention/views.py:433
|
||||
#: intervention/views.py:468
|
||||
msgid "{} unrecorded"
|
||||
msgstr "{} entzeichnet"
|
||||
|
||||
#: compensation/views/eco_account_views.py:210 ema/views.py:171
|
||||
#: intervention/views.py:433
|
||||
#: intervention/views.py:468
|
||||
msgid "{} recorded"
|
||||
msgstr "{} verzeichnet"
|
||||
|
||||
#: compensation/views/eco_account_views.py:346 intervention/views.py:415
|
||||
#: compensation/views/eco_account_views.py:346 intervention/views.py:450
|
||||
msgid "Deduction added"
|
||||
msgstr "Abbuchung hinzugefügt"
|
||||
|
||||
@ -774,129 +775,133 @@ msgstr "Gemarkung"
|
||||
msgid "Search for district"
|
||||
msgstr "Nach Gemarkung suchen"
|
||||
|
||||
#: intervention/forms.py:40
|
||||
#: intervention/forms/forms.py:30
|
||||
msgid "Generated automatically"
|
||||
msgstr "Automatisch generiert"
|
||||
|
||||
#: intervention/forms.py:45
|
||||
#: intervention/forms/forms.py:41
|
||||
msgid "An explanatory name"
|
||||
msgstr "Aussagekräftiger Titel"
|
||||
|
||||
#: intervention/forms.py:49
|
||||
#: intervention/forms/forms.py:45
|
||||
msgid "Construction XY; Location ABC"
|
||||
msgstr "Bauvorhaben XY; Flur ABC"
|
||||
|
||||
#: intervention/forms.py:54
|
||||
#: intervention/forms/forms.py:51
|
||||
#: intervention/templates/intervention/detail/view.html:35
|
||||
msgid "Process type"
|
||||
msgstr "Verfahrenstyp"
|
||||
|
||||
#: intervention/forms.py:70
|
||||
#: intervention/forms/forms.py:67
|
||||
#: intervention/templates/intervention/detail/view.html:39
|
||||
msgid "Law"
|
||||
msgstr "Gesetz"
|
||||
|
||||
#: intervention/forms.py:72
|
||||
#: intervention/forms/forms.py:69
|
||||
msgid "Multiple selection possible"
|
||||
msgstr "Mehrfachauswahl möglich"
|
||||
|
||||
#: intervention/forms.py:86
|
||||
#: intervention/forms/forms.py:83
|
||||
#: intervention/templates/intervention/detail/view.html:48
|
||||
msgid "Registration office"
|
||||
msgstr "Zulassungsbehörde"
|
||||
|
||||
#: intervention/forms.py:116
|
||||
#: intervention/forms/forms.py:113
|
||||
#: intervention/templates/intervention/detail/view.html:52
|
||||
msgid "Registration office file number"
|
||||
msgstr "Aktenzeichen Zulassungsbehörde"
|
||||
|
||||
#: intervention/forms.py:122
|
||||
#: intervention/forms/forms.py:119
|
||||
msgid "ZB-123/ABC.456"
|
||||
msgstr ""
|
||||
|
||||
#: intervention/forms.py:133
|
||||
#: intervention/forms/forms.py:131
|
||||
msgid "ETS-123/ABC.456"
|
||||
msgstr ""
|
||||
|
||||
#: intervention/forms.py:142
|
||||
#: intervention/forms/forms.py:141
|
||||
msgid "Who performs the intervention"
|
||||
msgstr "Wer führt den Eingriff durch"
|
||||
|
||||
#: intervention/forms.py:145
|
||||
#: intervention/forms/forms.py:144
|
||||
msgid "Company Mustermann"
|
||||
msgstr "Firma Mustermann"
|
||||
|
||||
#: intervention/forms.py:150
|
||||
#: intervention/forms/forms.py:150
|
||||
#: intervention/templates/intervention/detail/view.html:96
|
||||
msgid "Registration date"
|
||||
msgstr "Datum Zulassung bzw. Satzungsbeschluss"
|
||||
|
||||
#: intervention/forms.py:161
|
||||
#: intervention/forms/forms.py:162
|
||||
#: intervention/templates/intervention/detail/view.html:100
|
||||
msgid "Binding on"
|
||||
msgstr "Datum Bestandskraft"
|
||||
|
||||
#: intervention/forms.py:174
|
||||
#: intervention/forms/forms.py:177
|
||||
msgid "Additional comment"
|
||||
msgstr "Zusätzlicher Kommentar"
|
||||
|
||||
#: intervention/forms/forms.py:188
|
||||
msgid "New intervention"
|
||||
msgstr "Neuer Eingriff"
|
||||
|
||||
#: intervention/forms.py:248
|
||||
#: intervention/forms/forms.py:269
|
||||
msgid "Edit intervention"
|
||||
msgstr "Eingriff bearbeiten"
|
||||
|
||||
#: intervention/forms.py:344
|
||||
#: intervention/forms/modalForms.py:28
|
||||
msgid "Share link"
|
||||
msgstr "Freigabelink"
|
||||
|
||||
#: intervention/forms.py:346
|
||||
#: intervention/forms/modalForms.py:30
|
||||
msgid "Send this link to users who you want to have writing access on the data"
|
||||
msgstr "Andere Nutzer erhalten über diesen Link Zugriff auf die Daten"
|
||||
|
||||
#: intervention/forms.py:358
|
||||
#: intervention/forms/modalForms.py:43
|
||||
msgid "Remove check to remove access for this user"
|
||||
msgstr "Wählen Sie die Nutzer ab, die keinen Zugriff mehr haben sollen"
|
||||
|
||||
#: intervention/forms.py:369
|
||||
#: intervention/forms/modalForms.py:54
|
||||
#: intervention/templates/intervention/detail/includes/controls.html:15
|
||||
msgid "Share"
|
||||
msgstr "Freigabe"
|
||||
|
||||
#: intervention/forms.py:370
|
||||
#: intervention/forms/modalForms.py:55
|
||||
msgid "Share settings for {}"
|
||||
msgstr "Freigabe Einstellungen für {}"
|
||||
|
||||
#: intervention/forms.py:423
|
||||
#: intervention/forms/modalForms.py:108
|
||||
msgid "Date of revocation"
|
||||
msgstr "Datum des Widerspruchs"
|
||||
|
||||
#: intervention/forms.py:433
|
||||
#: intervention/forms/modalForms.py:119
|
||||
#: intervention/templates/intervention/detail/includes/revocation.html:35
|
||||
msgid "Document"
|
||||
msgstr "Dokument"
|
||||
|
||||
#: intervention/forms.py:436 konova/forms.py:349
|
||||
#: intervention/forms/modalForms.py:122 konova/forms.py:345
|
||||
msgid "Must be smaller than 15 Mb"
|
||||
msgstr "Muss kleiner als 15 Mb sein"
|
||||
|
||||
#: intervention/forms.py:459
|
||||
#: intervention/forms/modalForms.py:146
|
||||
#: intervention/templates/intervention/detail/includes/revocation.html:18
|
||||
msgid "Add revocation"
|
||||
msgstr "Widerspruch hinzufügen"
|
||||
|
||||
#: intervention/forms.py:499
|
||||
#: intervention/forms/modalForms.py:186
|
||||
msgid "Checked intervention data"
|
||||
msgstr "Eingriffsdaten geprüft"
|
||||
|
||||
#: intervention/forms.py:505
|
||||
#: intervention/forms/modalForms.py:192
|
||||
msgid "Checked compensations data and payments"
|
||||
msgstr "Kompensationen und Zahlungen geprüft"
|
||||
|
||||
#: intervention/forms.py:513
|
||||
#: intervention/forms/modalForms.py:200
|
||||
#: intervention/templates/intervention/detail/includes/controls.html:19
|
||||
msgid "Run check"
|
||||
msgstr "Prüfung vornehmen"
|
||||
|
||||
#: intervention/forms.py:514 konova/forms.py:433
|
||||
#: intervention/forms/modalForms.py:201 konova/forms.py:430
|
||||
msgid ""
|
||||
"I, {} {}, confirm that all necessary control steps have been performed by "
|
||||
"myself."
|
||||
@ -904,30 +909,30 @@ msgstr ""
|
||||
"Ich, {} {}, bestätige, dass die notwendigen Kontrollschritte durchgeführt "
|
||||
"wurden:"
|
||||
|
||||
#: intervention/forms.py:573
|
||||
#: intervention/forms/modalForms.py:260
|
||||
msgid "Only recorded accounts can be selected for deductions"
|
||||
msgstr "Nur verzeichnete Ökokonten können für Abbuchungen verwendet werden."
|
||||
|
||||
#: intervention/forms.py:592 intervention/forms.py:599
|
||||
#: intervention/forms/modalForms.py:284 intervention/forms/modalForms.py:291
|
||||
#: intervention/tables.py:88
|
||||
#: intervention/templates/intervention/detail/view.html:19
|
||||
#: konova/templates/konova/home.html:11 templates/navbar.html:22
|
||||
msgid "Intervention"
|
||||
msgstr "Eingriff"
|
||||
|
||||
#: intervention/forms.py:594
|
||||
#: intervention/forms/modalForms.py:286
|
||||
msgid "Only shared interventions can be selected"
|
||||
msgstr "Nur freigegebene Eingriffe können gewählt werden"
|
||||
|
||||
#: intervention/forms.py:607
|
||||
#: intervention/forms/modalForms.py:299
|
||||
msgid "New Deduction"
|
||||
msgstr "Neue Abbuchung"
|
||||
|
||||
#: intervention/forms.py:608
|
||||
#: intervention/forms/modalForms.py:300
|
||||
msgid "Enter the information for a new deduction from a chosen eco-account"
|
||||
msgstr "Geben Sie die Informationen für eine neue Abbuchung ein."
|
||||
|
||||
#: intervention/forms.py:644
|
||||
#: intervention/forms/modalForms.py:336
|
||||
msgid ""
|
||||
"Eco-account {} is not recorded yet. You can only deduct from recorded "
|
||||
"accounts."
|
||||
@ -935,7 +940,7 @@ msgstr ""
|
||||
"Ökokonto {} ist noch nicht verzeichnet. Abbuchungen können nur von "
|
||||
"verzeichneten Ökokonten erfolgen."
|
||||
|
||||
#: intervention/forms.py:657
|
||||
#: intervention/forms/modalForms.py:349
|
||||
msgid ""
|
||||
"The account {} has not enough surface for a deduction of {} m². There are "
|
||||
"only {} m² left"
|
||||
@ -943,31 +948,31 @@ msgstr ""
|
||||
"Das Ökokonto {} hat für eine Abbuchung von {} m² nicht ausreichend "
|
||||
"Restfläche. Es stehen noch {} m² zur Verfügung."
|
||||
|
||||
#: intervention/models.py:298
|
||||
#: intervention/models.py:325
|
||||
msgid "Registration office file number missing"
|
||||
msgstr "Aktenzeichen Zulassungsbehörde fehlt"
|
||||
|
||||
#: intervention/models.py:301
|
||||
#: intervention/models.py:328
|
||||
msgid "Conservation office file number missing"
|
||||
msgstr "Aktenzeichen Naturschutzbehörde fehlt"
|
||||
|
||||
#: intervention/models.py:304
|
||||
#: intervention/models.py:331
|
||||
msgid "Responsible data missing"
|
||||
msgstr "Daten zu Verantwortlichen fehlen"
|
||||
|
||||
#: intervention/models.py:318
|
||||
#: intervention/models.py:345
|
||||
msgid "Revocation exists"
|
||||
msgstr "Widerspruch liegt vor"
|
||||
|
||||
#: intervention/models.py:321
|
||||
#: intervention/models.py:348
|
||||
msgid "Registration date missing"
|
||||
msgstr "Datum Zulassung bzw. Satzungsbeschluss fehlt"
|
||||
|
||||
#: intervention/models.py:324
|
||||
#: intervention/models.py:351
|
||||
msgid "Binding on missing"
|
||||
msgstr "Datum Bestandskraft fehlt"
|
||||
|
||||
#: intervention/models.py:326
|
||||
#: intervention/models.py:353
|
||||
msgid "Legal data missing"
|
||||
msgstr "Rechtliche Daten fehlen"
|
||||
|
||||
@ -1040,19 +1045,27 @@ msgstr "Widerspruch entfernen"
|
||||
msgid "Exists"
|
||||
msgstr "vorhanden"
|
||||
|
||||
#: intervention/views.py:67
|
||||
#: intervention/views.py:71
|
||||
msgid ""
|
||||
"The identifier '{}' had to be changed to '{}' since another entry has been "
|
||||
"added in the meanwhile, which uses this identifier"
|
||||
msgstr ""
|
||||
"Die Kennung '{}' musste zu '{}' geändert werden, da ein anderer Eintrag in "
|
||||
"der Zwischenzeit angelegt wurde, welcher diese Kennung nun bereits verwendet"
|
||||
|
||||
#: intervention/views.py:76
|
||||
msgid "Intervention {} added"
|
||||
msgstr "Eingriff {} hinzugefügt"
|
||||
|
||||
#: intervention/views.py:70 intervention/views.py:226
|
||||
#: intervention/views.py:79 intervention/views.py:258
|
||||
msgid "Invalid input"
|
||||
msgstr "Eingabe fehlerhaft"
|
||||
|
||||
#: intervention/views.py:184
|
||||
#: intervention/views.py:212
|
||||
msgid "This intervention has a revocation from {}"
|
||||
msgstr "Es existiert ein Widerspruch vom {}"
|
||||
|
||||
#: intervention/views.py:200
|
||||
#: intervention/views.py:228
|
||||
msgid ""
|
||||
"Remember: This data has not been shared with you, yet. This means you can "
|
||||
"only read but can not edit or perform any actions like running a check or "
|
||||
@ -1062,43 +1075,43 @@ msgstr ""
|
||||
"bedeutet, dass Sie nur lesenden Zugriff hierauf haben und weder bearbeiten, "
|
||||
"noch Prüfungen durchführen oder verzeichnen können."
|
||||
|
||||
#: intervention/views.py:223
|
||||
msgid "{} edited"
|
||||
msgstr "{} bearbeitet"
|
||||
#: intervention/views.py:255
|
||||
msgid "Intervention {} edited"
|
||||
msgstr "Eingriff {} bearbeitet"
|
||||
|
||||
#: intervention/views.py:252
|
||||
#: intervention/views.py:287
|
||||
msgid "{} removed"
|
||||
msgstr "{} entfernt"
|
||||
|
||||
#: intervention/views.py:273
|
||||
#: intervention/views.py:308
|
||||
msgid "Revocation removed"
|
||||
msgstr "Widerspruch entfernt"
|
||||
|
||||
#: intervention/views.py:299
|
||||
#: intervention/views.py:334
|
||||
msgid "{} has already been shared with you"
|
||||
msgstr "{} wurde bereits für Sie freigegeben"
|
||||
|
||||
#: intervention/views.py:304
|
||||
#: intervention/views.py:339
|
||||
msgid "{} has been shared with you"
|
||||
msgstr "{} ist nun für Sie freigegeben"
|
||||
|
||||
#: intervention/views.py:311
|
||||
#: intervention/views.py:346
|
||||
msgid "Share link invalid"
|
||||
msgstr "Freigabelink ungültig"
|
||||
|
||||
#: intervention/views.py:332
|
||||
#: intervention/views.py:367
|
||||
msgid "Share settings updated"
|
||||
msgstr "Freigabe Einstellungen aktualisiert"
|
||||
|
||||
#: intervention/views.py:351
|
||||
#: intervention/views.py:386
|
||||
msgid "Check performed"
|
||||
msgstr "Prüfung durchgeführt"
|
||||
|
||||
#: intervention/views.py:371
|
||||
#: intervention/views.py:406
|
||||
msgid "Revocation added"
|
||||
msgstr "Widerspruch hinzugefügt"
|
||||
|
||||
#: intervention/views.py:438
|
||||
#: intervention/views.py:473
|
||||
msgid "There are errors on this intervention:"
|
||||
msgstr "Es liegen Fehler in diesem Eingriff vor:"
|
||||
|
||||
@ -1127,11 +1140,11 @@ msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!"
|
||||
msgid "Not editable"
|
||||
msgstr "Nicht editierbar"
|
||||
|
||||
#: konova/forms.py:139 konova/forms.py:295
|
||||
#: konova/forms.py:139 konova/forms.py:293
|
||||
msgid "Confirm"
|
||||
msgstr "Bestätige"
|
||||
|
||||
#: konova/forms.py:151 konova/forms.py:304
|
||||
#: konova/forms.py:151 konova/forms.py:302
|
||||
msgid "Remove"
|
||||
msgstr "Löschen"
|
||||
|
||||
@ -1139,48 +1152,48 @@ msgstr "Löschen"
|
||||
msgid "You are about to remove {} {}"
|
||||
msgstr "Sie sind dabei {} {} zu löschen"
|
||||
|
||||
#: konova/forms.py:249 templates/form/main_data_collapse_form.html:47
|
||||
#: konova/forms.py:243 templates/form/main_data_collapse_form.html:47
|
||||
msgid "Geometry"
|
||||
msgstr "Geometrie"
|
||||
|
||||
#: konova/forms.py:305
|
||||
#: konova/forms.py:303
|
||||
msgid "Are you sure?"
|
||||
msgstr "Sind Sie sicher?"
|
||||
|
||||
#: konova/forms.py:335
|
||||
#: konova/forms.py:330
|
||||
msgid "Created on"
|
||||
msgstr "Erstellt"
|
||||
|
||||
#: konova/forms.py:337
|
||||
#: konova/forms.py:332
|
||||
msgid "When has this file been created? Important for photos."
|
||||
msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?"
|
||||
|
||||
#: konova/forms.py:347
|
||||
#: konova/forms.py:343
|
||||
#: venv/lib/python3.7/site-packages/django/db/models/fields/files.py:231
|
||||
msgid "File"
|
||||
msgstr "Datei"
|
||||
|
||||
#: konova/forms.py:410
|
||||
#: konova/forms.py:407
|
||||
msgid "Added document"
|
||||
msgstr "Dokument hinzugefügt"
|
||||
|
||||
#: konova/forms.py:424
|
||||
#: konova/forms.py:421
|
||||
msgid "Confirm record"
|
||||
msgstr "Verzeichnen bestätigen"
|
||||
|
||||
#: konova/forms.py:432
|
||||
#: konova/forms.py:429
|
||||
msgid "Record data"
|
||||
msgstr "Daten verzeichnen"
|
||||
|
||||
#: konova/forms.py:439
|
||||
#: konova/forms.py:436
|
||||
msgid "Confirm unrecord"
|
||||
msgstr "Entzeichnen bestätigen"
|
||||
|
||||
#: konova/forms.py:440
|
||||
#: konova/forms.py:437
|
||||
msgid "Unrecord data"
|
||||
msgstr "Daten entzeichnen"
|
||||
|
||||
#: konova/forms.py:441
|
||||
#: konova/forms.py:438
|
||||
msgid "I, {} {}, confirm that this data must be unrecorded."
|
||||
msgstr ""
|
||||
"Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen."
|
||||
@ -1209,22 +1222,26 @@ msgstr "Wenn meine freigegebenen Daten gelöscht wurden"
|
||||
msgid "On registered data edited"
|
||||
msgstr "Wenn meine freigegebenen Daten bearbeitet wurden"
|
||||
|
||||
#: konova/models.py:190
|
||||
#: konova/models.py:204
|
||||
msgid "Finished"
|
||||
msgstr "Umgesetzt bis"
|
||||
|
||||
#: konova/models.py:191
|
||||
#: konova/models.py:205
|
||||
msgid "Maintain"
|
||||
msgstr "Unterhaltung bis"
|
||||
|
||||
#: konova/models.py:192
|
||||
#: konova/models.py:206
|
||||
msgid "Control"
|
||||
msgstr "Kontrolle am"
|
||||
|
||||
#: konova/models.py:193
|
||||
#: konova/models.py:207
|
||||
msgid "Other"
|
||||
msgstr "Sonstige"
|
||||
|
||||
#: konova/templates/konova/custom_widgets/generate-content-input.html:6
|
||||
msgid "Generate new"
|
||||
msgstr "Neu generieren"
|
||||
|
||||
#: konova/templates/konova/custom_widgets/text-to-clipboard-input.html:6
|
||||
msgid "Copy to clipboard"
|
||||
msgstr "In Zwischenablage kopieren"
|
||||
@ -2720,6 +2737,9 @@ msgstr ""
|
||||
msgid "A fontawesome icon field"
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "{} edited"
|
||||
#~ msgstr "{} bearbeitet"
|
||||
|
||||
#~ msgid "Map"
|
||||
#~ msgstr "Karte"
|
||||
|
||||
@ -2771,9 +2791,6 @@ msgstr ""
|
||||
#~ msgid "Actions"
|
||||
#~ msgstr "Aktionen"
|
||||
|
||||
#~ msgid "Additional comment"
|
||||
#~ msgstr "Zusätzlicher Kommentar"
|
||||
|
||||
#~ msgid "Missing surfaces: "
|
||||
#~ msgstr "Fehlende Flächen: "
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user