""" Author: Michel Peltriaux Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany Contact: ksp-servicestelle@sgdnord.rlp.de Created on: 18.08.22 """ from django import forms from django.db import transaction from django.urls import reverse, reverse_lazy from django.utils.translation import gettext_lazy as _ from compensation.forms.compensation import AbstractCompensationForm from compensation.forms.mixins import CompensationResponsibleFormMixin, PikCompensationFormMixin from compensation.models import EcoAccount from intervention.models import Handler, Responsibility, Legal from konova.forms import SimpleGeomForm from konova.forms.modals import RemoveModalForm from konova.utils import validators from user.models import User, UserActionLogEntry class NewEcoAccountForm(AbstractCompensationForm, CompensationResponsibleFormMixin, PikCompensationFormMixin): """ Form for creating eco accounts Inherits from basic AbstractCompensationForm and further form fields from CompensationResponsibleFormMixin """ surface = forms.DecimalField( min_value=0.00, decimal_places=2, label=_("Available Surface"), label_suffix="", required=False, help_text=_("The amount that can be used for deductions"), widget=forms.NumberInput( attrs={ "class": "form-control", "placeholder": "0,00" } ) ) registration_date = forms.DateField( label=_("Agreement date"), label_suffix="", help_text=_("When did the parties agree on this?"), required=False, validators=[validators.reasonable_date], widget=forms.DateInput( attrs={ "type": "date", "class": "form-control", }, format="%d.%m.%Y" ) ) field_order = [ "identifier", "title", "conservation_office", "registration_date", "surface", "conservation_file_number", "is_pik", "handler_type", "handler_detail", "comment", ] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("New Eco-Account") self.action_url = reverse("compensation:acc:new") self.cancel_redirect = reverse("compensation:acc:index") tmp = EcoAccount() identifier = tmp.generate_new_identifier() self.initialize_form_field("identifier", identifier) self.fields["identifier"].widget.attrs["url"] = reverse_lazy("compensation:acc:new-id") self.fields["title"].widget.attrs["placeholder"] = _("Eco-Account XY; Location ABC") 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) registration_date = self.cleaned_data.get("registration_date", None) handler_type = self.cleaned_data.get("handler_type", None) handler_detail = self.cleaned_data.get("handler_detail", None) surface = self.cleaned_data.get("surface", None) conservation_office = self.cleaned_data.get("conservation_office", None) conservation_file_number = self.cleaned_data.get("conservation_file_number", None) is_pik = self.cleaned_data.get("is_pik", None) comment = self.cleaned_data.get("comment", None) # Create log entry action = UserActionLogEntry.get_created_action(user) handler = Handler.objects.create( type=handler_type, detail=handler_detail, ) responsible = Responsibility.objects.create( handler=handler, conservation_file_number=conservation_file_number, conservation_office=conservation_office, ) legal = Legal.objects.create( registration_date=registration_date ) # Finally create main object acc = EcoAccount.objects.create( identifier=identifier, title=title, responsible=responsible, deductable_surface=surface, created=action, modified=action, comment=comment, is_pik=is_pik, legal=legal ) acc.share_with_user(user) # Add the log entry to the main objects log list acc.log.add(action) # Process the geometry form geometry = geom_form.save(action) acc.geometry = geometry acc.save() acc.update_deductable_rest() return acc class EditEcoAccountForm(NewEcoAccountForm): """ Form for editing eco accounts """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("Edit Eco-Account") self.action_url = reverse("compensation:acc:edit", args=(self.instance.id,)) self.cancel_redirect = reverse("compensation:acc:detail", args=(self.instance.id,)) # Initialize form data reg_date = self.instance.legal.registration_date if reg_date is not None: reg_date = reg_date.isoformat() form_data = { "identifier": self.instance.identifier, "title": self.instance.title, "surface": self.instance.deductable_surface, "handler_type": self.instance.responsible.handler.type, "handler_detail": self.instance.responsible.handler.detail, "registration_date": reg_date, "conservation_office": self.instance.responsible.conservation_office, "conservation_file_number": self.instance.responsible.conservation_file_number, "is_pik": self.instance.is_pik, "comment": self.instance.comment, } disabled_fields = [] self.load_initial_data( form_data, disabled_fields ) def is_valid(self): valid = super().is_valid() deductable_surface = self.cleaned_data.get("surface") or 0.0 deduction_surface_sum = self.instance.get_deductions_surface() if deductable_surface < deduction_surface_sum: self.add_error( "surface", _("{}m² have been deducted from this eco account so far. The given value of {} would be too low.").format( deduction_surface_sum, deductable_surface ) ) valid &= False return valid 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) registration_date = self.cleaned_data.get("registration_date", None) handler_type = self.cleaned_data.get("handler_type", None) handler_detail = self.cleaned_data.get("handler_detail", None) surface = self.cleaned_data.get("surface", None) conservation_office = self.cleaned_data.get("conservation_office", None) conservation_file_number = self.cleaned_data.get("conservation_file_number", None) comment = self.cleaned_data.get("comment", None) is_pik = self.cleaned_data.get("is_pik", None) # Create log entry action = UserActionLogEntry.get_edited_action(user) # Update responsible data self.instance.responsible.handler.type = handler_type self.instance.responsible.handler.detail = handler_detail self.instance.responsible.handler.save() self.instance.responsible.conservation_office = conservation_office self.instance.responsible.conservation_file_number = conservation_file_number self.instance.responsible.save() # Update legal data self.instance.legal.registration_date = registration_date self.instance.legal.save() # Update main oject data self.instance.identifier = identifier self.instance.title = title self.instance.deductable_surface = surface self.instance.comment = comment self.instance.is_pik = is_pik self.instance.modified = action self.instance.save() # Add the log entry to the main objects log list self.instance.log.add(action) # Process the geometry form (NOT ATOMIC TRANSACTION DUE TO CELERY!) geometry = geom_form.save(action) self.instance.geometry = geometry self.instance.save() self.instance.update_deductable_rest() return self.instance class RemoveEcoAccountModalForm(RemoveModalForm): def is_valid(self): super_valid = super().is_valid() has_deductions = self.instance.deductions.exists() if has_deductions: self.add_error( "confirm", _("The account can not be removed, since there are still deductions.") ) return super_valid and not has_deductions