* fixes bug where deduction of a recorded intervention could be deleted from the eco account detail view * improves check_for_recorded_instance() logic * improves rendering of detail view on compensation-like objects to highlight missing data
154 lines
4.5 KiB
Python
154 lines
4.5 KiB
Python
"""
|
|
Author: Michel Peltriaux
|
|
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
|
Contact: ksp-servicestelle@sgdnord.rlp.de
|
|
Created on: 15.08.22
|
|
|
|
"""
|
|
from abc import abstractmethod
|
|
|
|
from django import forms
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from compensation.models import EcoAccount
|
|
from konova.models import BaseObject
|
|
|
|
|
|
class BaseForm(forms.Form):
|
|
"""
|
|
Basic form for that holds attributes needed in all other forms
|
|
"""
|
|
template = None
|
|
action_url = None
|
|
action_btn_label = _("Save")
|
|
form_title = None
|
|
cancel_redirect = None
|
|
form_caption = None
|
|
instance = None # The data holding model object
|
|
request = None
|
|
form_attrs = {} # Holds additional attributes, that can be used in the template
|
|
has_required_fields = False # Automatically set. Triggers hint rendering in templates
|
|
show_cancel_btn = True
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.instance = kwargs.pop("instance", None)
|
|
super().__init__(*args, **kwargs)
|
|
if self.request is not None:
|
|
self.user = self.request.user
|
|
# Check for required fields
|
|
for _field_name, _field_val in self.fields.items():
|
|
if _field_val.required:
|
|
self.has_required_fields = True
|
|
break
|
|
|
|
self.check_for_recorded_instance()
|
|
|
|
@abstractmethod
|
|
def save(self):
|
|
# To be implemented in subclasses!
|
|
pass
|
|
|
|
def disable_form_field(self, field: str):
|
|
"""
|
|
Disables a form field for user editing
|
|
"""
|
|
self.fields[field].widget.attrs["readonly"] = True
|
|
self.fields[field].disabled = True
|
|
self.fields[field].widget.attrs["title"] = _("Not editable")
|
|
|
|
def initialize_form_field(self, field: str, val):
|
|
"""
|
|
Initializes a form field with a value
|
|
"""
|
|
self.fields[field].initial = val
|
|
|
|
def add_placeholder_for_field(self, field: str, val):
|
|
"""
|
|
Adds a placeholder to a field after initialization without the need to redefine the form widget
|
|
|
|
Args:
|
|
field (str): Field name
|
|
val (str): Placeholder
|
|
|
|
Returns:
|
|
|
|
"""
|
|
self.fields[field].widget.attrs["placeholder"] = val
|
|
|
|
def load_initial_data(self, form_data: dict, disabled_fields: list = None):
|
|
""" Initializes form data from instance
|
|
|
|
Inserts instance data into form and disables form fields
|
|
|
|
Returns:
|
|
|
|
"""
|
|
if self.instance is None:
|
|
return
|
|
for k, v in form_data.items():
|
|
self.initialize_form_field(k, v)
|
|
if disabled_fields:
|
|
for field in disabled_fields:
|
|
self.disable_form_field(field)
|
|
|
|
def add_widget_html_class(self, field: str, cls: str):
|
|
""" Adds a HTML class string to the widget of a field
|
|
|
|
Args:
|
|
field (str): The field's name
|
|
cls (str): The new class string
|
|
|
|
Returns:
|
|
|
|
"""
|
|
set_class = self.fields[field].widget.attrs.get("class", "")
|
|
if cls in set_class:
|
|
return
|
|
else:
|
|
set_class += " " + cls
|
|
self.fields[field].widget.attrs["class"] = set_class
|
|
|
|
def remove_widget_html_class(self, field: str, cls: str):
|
|
""" Removes a HTML class string from the widget of a field
|
|
|
|
Args:
|
|
field (str): The field's name
|
|
cls (str): The new class string
|
|
|
|
Returns:
|
|
|
|
"""
|
|
set_class = self.fields[field].widget.attrs.get("class", "")
|
|
set_class = set_class.replace(cls, "")
|
|
self.fields[field].widget.attrs["class"] = set_class
|
|
|
|
def check_for_recorded_instance(self):
|
|
""" Checks if the instance is recorded and runs some special logic if yes
|
|
|
|
If the instance is recorded, the form shall not display any possibility to
|
|
edit any data. Instead, the users should get some information about why they can not edit anything.
|
|
|
|
There are situations where the form should be rendered regularly,
|
|
e.g deduction forms for (recorded) eco accounts.
|
|
|
|
Returns:
|
|
|
|
"""
|
|
is_none = self.instance is None
|
|
is_other_data_type = not isinstance(self.instance, BaseObject)
|
|
|
|
if is_none or is_other_data_type:
|
|
# Do nothing
|
|
return
|
|
|
|
if self.instance.is_recorded:
|
|
self.block_form()
|
|
|
|
def block_form(self):
|
|
"""
|
|
Overwrites template, providing no actions
|
|
|
|
Returns:
|
|
|
|
"""
|
|
self.template = "form/recorded_no_edit.html" |