From 954380ee43cead0e63f82b4c42a1b8f0f316a3b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Valenta?= <git@imaniti.org>
Date: Thu, 8 Feb 2024 14:09:27 +0100
Subject: [PATCH] fix signee validation

---
 contracts/admin.py                            | 10 +++-
 contracts/forms.py                            | 48 +++++++++++++++++--
 .../commands/import_old_contracts.py          |  3 +-
 3 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/contracts/admin.py b/contracts/admin.py
index 96e15ee..2f405d2 100644
--- a/contracts/admin.py
+++ b/contracts/admin.py
@@ -18,10 +18,10 @@ from rangefilter.filters import DateRangeFilter
 from shared.admin import FieldsetInlineOrder, MarkdownxGuardedModelAdmin
 
 from .forms import (
-    AtLeastOneRequiredInlineFormSet,
     ContractAdminForm,
     ContractFileAdminForm,
     SigneeAdminForm,
+    SingnatureRepresentativeFormSet,
 )
 from .models import (
     Contract,
@@ -124,7 +124,13 @@ class ContractFileAdmin(
 class ContracteeSignatureRepresentativeInline(NestedStackedInline):
     model = ContracteeSignatureRepresentative
     extra = 1
-    formset = AtLeastOneRequiredInlineFormSet
+    formset = SingnatureRepresentativeFormSet
+
+    def get_formset(self, request, obj=None, **kwargs):
+        formset = super().get_formset(request, obj, **kwargs)
+        formset.request = request
+
+        return formset
 
 
 class ContracteeSignatureInline(NestedStackedInline):
diff --git a/contracts/forms.py b/contracts/forms.py
index a6a99e7..886767d 100644
--- a/contracts/forms.py
+++ b/contracts/forms.py
@@ -6,7 +6,13 @@ from webpack_loader.loader import WebpackLoader
 from .models import Contract, ContracteeSignature, SigneeSignature
 
 
-class AtLeastOneRequiredInlineFormSet(BaseInlineFormSet):
+class SingnatureRepresentativeFormSet(BaseInlineFormSet):
+    def _construct_form(self, i, **kwargs):
+        form = super()._construct_form(i, **kwargs)
+        form.request = self.request
+
+        return form
+
     def clean(self):
         """Check that at least one item has been entered."""
 
@@ -15,9 +21,45 @@ class AtLeastOneRequiredInlineFormSet(BaseInlineFormSet):
         if any(self.errors):
             return
 
+        signature_position = None
+        signature_id = None
+        excluded_from_check = False
+
+        for form in self.forms:
+            for key, value in form.request.POST.items():
+                attempted_signature_position = key.replace(
+                    "contractee_signatures-", ""
+                ).replace("-id", "")
+
+                if (
+                    attempted_signature_position.isnumeric()
+                    and key.startswith("contractee_signatures-")
+                    and key.endswith("-id")
+                ):
+                    signature_position = int(attempted_signature_position)
+                    signature_id = int(value)
+
+            if signature_id is None or signature_id is None:
+                break
+
+            signature = form.cleaned_data.get("signature")
+
+            if signature is not None:
+                if (
+                    signature.id == signature_id
+                    and form.request.POST.get(
+                        f"contractee_signatures-{signature_position}-DELETE"
+                    )
+                    == "on"
+                ):
+                    excluded_from_check = True
+
+        if excluded_from_check:
+            return
+
         if not any(
-            cleaned_data and not cleaned_data.get("DELETE", False)
-            for cleaned_data in self.cleaned_data
+            form.cleaned_data and not form.cleaned_data.get("DELETE", False)
+            for form in self.forms
         ):
             raise forms.ValidationError("Vyžadován aspoň jeden záznam.")
 
diff --git a/contracts/management/commands/import_old_contracts.py b/contracts/management/commands/import_old_contracts.py
index 312f625..ea613d2 100644
--- a/contracts/management/commands/import_old_contracts.py
+++ b/contracts/management/commands/import_old_contracts.py
@@ -10,9 +10,8 @@ from django.conf import settings
 from django.core.files import File
 from django.core.management.base import BaseCommand
 from django.db import models
-from postal.parser import parse_address
-
 from git import Repo
+from postal.parser import parse_address
 
 from ...models import (
     Contract,
-- 
GitLab