diff --git a/fet2020/finance/forms.py b/fet2020/finance/forms.py index 3e3b20da..3232c990 100644 --- a/fet2020/finance/forms.py +++ b/fet2020/finance/forms.py @@ -21,15 +21,53 @@ class BankDataForm(forms.ModelForm): labels = {"iban": "IBAN", "bic": "BIC", "name": "Kontoinhaber:in"} +def get_cleaned_data(cleaned_data): + resolution = cleaned_data.get("resolution_text") + payer = cleaned_data.get("payer") + + # Check if resolution exists. + if resolution != "": + try: + cleaned_data["resolution"] = Resolution.objects.get( + Q(id=resolution) | Q(name=resolution) + ) + except Exception: + raise ValidationError({"resolution_text": "Es gibt keinen Beschluss mit dieser ID."}) + + # If payer is 'Me', you need name, iban and bic data. + if payer == Bill.Payer.ME: + if cleaned_data.get("name_text") == "": + raise ValidationError({"name_text": "Kontoinhaber:in fehlt bei privater Bezahlung."}) + if cleaned_data.get("iban_text") == "": + raise ValidationError({"iban_text": "IBAN fehlt bei privater Bezahlung."}) + if cleaned_data.get("bic_text") == "": + raise ValidationError({"bic_text": "BIC fehlt bei privater Bezahlung."}) + + # No saving if payer is 'Verein'. + if payer == Bill.Payer.VEREIN: + cleaned_data["name_text"] = "" + cleaned_data["iban_text"] = "" + cleaned_data["bic_text"] = "" + + if cleaned_data.get("only_digital") and cleaned_data.get("file_field") is None: + raise ValidationError({"file_field": "Digitale Rechnung fehlt."}) + + return cleaned_data + + class BillCreateForm(forms.ModelForm): # Bank data - name_text = forms.CharField(max_length=128) - iban_text = forms.CharField(max_length=34) - bic_text = forms.CharField(max_length=11) - saving = forms.BooleanField() + name_text = forms.CharField(required=False, label="Kontoinhaber:in", initial="", max_length=128) + iban_text = forms.CharField(required=False, label="IBAN", initial="", max_length=34) + bic_text = forms.CharField(required=False, label="BIC", initial="", max_length=11) + saving = forms.BooleanField( + required=False, label="Bankdaten für die nächsten Rechnungen speichern.", initial=False + ) # Resolution - resolution_text = forms.CharField(max_length=128) + resolution_text = forms.CharField( + required=False, label="Beschlussnummer", initial="", max_length=128 + ) class Meta: model = Bill @@ -90,87 +128,28 @@ class BillCreateForm(forms.ModelForm): self.fields["bic_text"].initial = bank_data.bic self.fields["saving"].initial = True - self.fields["name_text"].label = "Kontoinhaber:in" - self.fields["name_text"].required = False - - self.fields["iban_text"].label = "IBAN" - self.fields["iban_text"].required = False - - self.fields["bic_text"].label = "BIC" - self.fields["bic_text"].required = False - - self.fields["saving"].label = "Bankdaten speichern." - self.fields["saving"].required = False - - # Resolution fields - self.fields["resolution_text"].label = "Beschlussnummer" - self.fields["resolution_text"].required = False - def clean(self): - cleaned_data = super().clean() - - resolution = cleaned_data.get("resolution_text") - - payer = cleaned_data.get("payer") - name = cleaned_data.get("name_text") - iban = cleaned_data.get("iban_text") - bic = cleaned_data.get("bic_text") - saving = cleaned_data.get("saving") - - only_digital = cleaned_data.get("only_digital") - file_field = cleaned_data.get("file_field") - - # Check if resolution exists. - if resolution != "": - try: - Resolution.objects.get(id=resolution) - except Exception: - raise ValidationError( - f"Es gibt keinen Beschluss mit dieser ID. (Eingegebene ID: {resolution})" - ) - - # Check that amount is valid because invalid amount is a NoneType. - """ - if amount: - if amount > 30 and resolution == "": - raise ValidationError( - "Die Beschlussnummer fehlt, weil der Betrag über 30€ beträgt " - f"(Betrag: {amount}€)." - ) - """ - - # If payer is 'Me', you need name, iban and bic data. - if payer == Bill.Payer.ME: - if name == "" or iban == "" or bic == "": - raise ValidationError( - f"Bankdaten bei privater Bezahlung unvollständig. (Kontoinhaber:in: '{name}', " - f"IBAN: '{iban}', BIC: '{bic}')." - ) - - # No saving if payer is 'Verein' or you don't want to save bank data. - if payer == Bill.Payer.VEREIN or saving is not True: - cleaned_data["name_text"] = "" - cleaned_data["iban_text"] = "" - cleaned_data["bic_text"] = "" - - if only_digital and file_field is None: - raise ValidationError("Digitale Rechnung fehlt.") - - return cleaned_data + return get_cleaned_data(super().clean()) class BillUpdateForm(forms.ModelForm): # Bank data - name_text = forms.CharField(max_length=128) - iban_text = forms.CharField(max_length=34) - bic_text = forms.CharField(max_length=11) - saving = forms.BooleanField() + name_text = forms.CharField(required=False, label="Kontoinhaber:in", initial="", max_length=128) + iban_text = forms.CharField(required=False, label="IBAN", initial="", max_length=34) + bic_text = forms.CharField(required=False, label="BIC", initial="", max_length=11) + saving = forms.BooleanField( + required=False, label="Bankdaten für die nächsten Rechnungen speichern.", initial=False + ) # only digital bill - only_digital_new = forms.BooleanField() + only_digital_new = forms.BooleanField( + required=False, label="Ich habe eine neue digitale Rechnung.", initial=False + ) # Resolution - resolution_text = forms.CharField(max_length=128) + resolution_text = forms.CharField( + required=False, label="Beschlussnummer", initial="", max_length=128 + ) class Meta: model = Bill @@ -232,41 +211,16 @@ class BillUpdateForm(forms.ModelForm): self.fields["name_text"].initial = kwargs["instance"].bankdata.name self.fields["iban_text"].initial = kwargs["instance"].bankdata.iban self.fields["bic_text"].initial = kwargs["instance"].bankdata.bic - self.fields["saving"].initial = True - else: - self.fields["name_text"].initial = "" - self.fields["iban_text"].initial = "" - self.fields["bic_text"].initial = "" - self.fields["saving"].initial = False - - self.fields["name_text"].label = "Kontoinhaber:in" - self.fields["name_text"].required = False - - self.fields["iban_text"].label = "IBAN" - self.fields["iban_text"].required = False - - self.fields["bic_text"].label = "BIC" - self.fields["bic_text"].required = False - - self.fields["saving"].label = "Bankdaten speichern." - self.fields["saving"].required = False - - # only digital bill field - self.fields["only_digital_new"].label = "Ich habe eine neue digitale Rechnung." - self.fields["only_digital_new"].required = False + self.fields["saving"].initial = not kwargs["instance"].bankdata.is_disabled # Resolution fields if kwargs["instance"].resolution: _name = kwargs["instance"].resolution.name self.fields["resolution_text"].initial = _name - self.fields["resolution_text"].label = "Beschlussnummer" - self.fields["resolution_text"].required = False - self.fields["payer"].autofocus = True else: - self.fields["bill_creator"].disabled = True self.fields["date"].disabled = True self.fields["invoice"].disabled = True self.fields["amount"].disabled = True @@ -280,35 +234,21 @@ class BillUpdateForm(forms.ModelForm): # Bank data fields if kwargs["instance"].bankdata: self.fields["name_text"].initial = kwargs["instance"].bankdata.name - self.fields["name_text"].label = "Kontoinhaber:in" self.fields["name_text"].required = True self.fields["iban_text"].initial = kwargs["instance"].bankdata.iban - self.fields["iban_text"].label = "IBAN" self.fields["iban_text"].required = True self.fields["bic_text"].initial = kwargs["instance"].bankdata.bic - self.fields["bic_text"].label = "BIC" self.fields["bic_text"].required = True - self.fields["saving"].initial = True - self.fields["saving"].required = True - else: - self.fields["name_text"].required = False - - self.fields["iban_text"].required = False - - self.fields["bic_text"].required = False - - self.fields["saving"].required = False - self.fields["saving"].initial = False + self.fields["saving"].initial = not kwargs["instance"].bankdata.is_disabled self.fields["name_text"].disabled = True self.fields["iban_text"].disabled = True self.fields["bic_text"].disabled = True self.fields["saving"].disabled = True - self.fields["saving"].label = "Bankdaten sind gespeichert." # Resolution fields if kwargs["instance"].resolution: @@ -316,8 +256,6 @@ class BillUpdateForm(forms.ModelForm): self.fields["resolution_text"].initial = _name self.fields["resolution_text"].disabled = True - self.fields["resolution_text"].label = "Beschlussnummer" - self.fields["resolution_text"].required = False # Comment disabled when bill is cleared or finished if kwargs["instance"].status != Bill.Status.SUBMITTED: @@ -325,6 +263,9 @@ class BillUpdateForm(forms.ModelForm): self.fields["comment"].autofocus = True + def clean(self): + return get_cleaned_data(super().clean()) + class ResolutionCreateForm(forms.ModelForm): class Meta: diff --git a/fet2020/finance/views.py b/fet2020/finance/views.py index 72b592f2..c121f52d 100644 --- a/fet2020/finance/views.py +++ b/fet2020/finance/views.py @@ -18,39 +18,44 @@ from .forms import ( from .models import BankData, Bill, Resolution +def set_bankdata(creator, name, iban, bic, saving): + if name != "" and iban != "" and bic != "": + # Replace whitespaces in iban and bic text. + iban = iban.replace(" ", "") + bic = bic.replace(" ", "") + + obj, created = BankData.objects.get_or_create( + name=name, + iban=iban, + bic=bic, + defaults={"bankdata_creator": creator, "is_disabled": not saving}, + ) + + if saving is True: + # Disable old bank data. + qs = BankData.objects.filter( + ~Q(id=obj.id) & Q(bankdata_creator=obj.bankdata_creator) & Q(is_disabled=False) + ) + qs.update(is_disabled=True) + + return obj + + return None + + class BillCreateView(LoginRequiredMixin, CreateView): form_class = BillCreateForm model = Bill template_name = "finance/bill_create.html" def form_valid(self, form): - # Get or create resolution object - resolution = form.cleaned_data["resolution_text"] - if resolution != "": - obj, created = Resolution.objects.get_or_create( - id=resolution, - defaults={"name": resolution}, - ) - form.instance.resolution = obj - - # Get or create bankdata object. Replace whitespaces in iban and bic text. + # Get or create bankdata object. + creator = form.cleaned_data["bill_creator"] name = form.cleaned_data["name_text"] - iban = form.cleaned_data["iban_text"].replace(" ", "") - bic = form.cleaned_data["bic_text"].replace(" ", "") - if name != "" and iban != "" and bic != "": - obj, created = BankData.objects.get_or_create( - name=name, - iban=iban, - bic=bic, - defaults={"bankdata_creator": form.cleaned_data["bill_creator"]}, - ) - form.instance.bankdata = obj - - # Disable old bank data. - qs = BankData.objects.filter( - ~Q(id=obj.id) & Q(bankdata_creator=obj.bankdata_creator) & Q(is_disabled=False) - ) - qs.update(is_disabled=True) + iban = form.cleaned_data["iban_text"] + bic = form.cleaned_data["bic_text"] + saving = form.cleaned_data["saving"] + form.instance.bankdata = set_bankdata(creator, name, iban, bic, saving) add_log_action(self.request, form, "finance", "bill", True) return super().form_valid(form) @@ -88,13 +93,21 @@ class BillUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView): template_name = "finance/bill_update.html" def form_valid(self, form): - # Set status to submitted if changes are valid and bill is incompleted. if self.object.status == Bill.Status.INCOMPLETE: + # Set status to submitted if changes are valid and bill is incompleted. self.object.status = Bill.Status.SUBMITTED - # Override only_digital db value by value of new only_digital. - if "file_field" in form.changed_data: - self.object.only_digital = form.cleaned_data["only_digital_new"] + # Override only_digital db value by value of new only_digital. + if "file_field" in form.changed_data: + self.object.only_digital = form.cleaned_data["only_digital_new"] + + # Get or create bankdata object. + creator = form.cleaned_data["bill_creator"] + name = form.cleaned_data["name_text"] + iban = form.cleaned_data["iban_text"] + bic = form.cleaned_data["bic_text"] + saving = form.cleaned_data["saving"] + form.instance.bankdata = set_bankdata(creator, name, iban, bic, saving) add_log_action(self.request, form, "finance", "bill", False) return super().form_valid(form) diff --git a/fet2020/templates/finance/bill_update.html b/fet2020/templates/finance/bill_update.html index 32dc9339..621cacca 100644 --- a/fet2020/templates/finance/bill_update.html +++ b/fet2020/templates/finance/bill_update.html @@ -27,17 +27,7 @@ {% include "baseform/select.html" with field=form.payer %} - {% if form.payer.value == object.Payer.ME %} -