diff --git a/contracts/admin.py b/contracts/admin.py
index 558993c133684c25ec56b2ef1b505b406cfdab97..b2c97254357c9d9aeeed5ec89fc1cc47a728fd3d 100644
--- a/contracts/admin.py
+++ b/contracts/admin.py
@@ -10,7 +10,7 @@ from rangefilter.filters import DateRangeFilter
 
 from shared.admin import FieldsetInlineOrder, MarkdownxGuardedModelAdmin
 
-from .forms import ContractAdminForm, ContractFileAdminForm, SigneeAdminForm
+from .forms import ContractAdminForm, ContractFileAdminForm, SigneeAdminForm, AtLeastOneRequiredInlineFormSet
 from .models import (
     Contract,
     Contractee,
@@ -111,7 +111,8 @@ class ContractFileAdmin(
 
 class ContracteeSignatureRepresentativeInline(NestedStackedInline):
     model = ContracteeSignatureRepresentative
-    extra = 0
+    extra = 1
+    formset = AtLeastOneRequiredInlineFormSet
 
 
 class ContracteeSignatureInline(NestedStackedInline):
diff --git a/contracts/forms.py b/contracts/forms.py
index 9453e761d5ee1afb7eb34004eb66bb6f718132ee..e25eea88315d6db1baf0c846cad957e887cdfd9c 100644
--- a/contracts/forms.py
+++ b/contracts/forms.py
@@ -1,10 +1,27 @@
 from django import forms
 from django.core.exceptions import ValidationError
+from django.forms.models import BaseInlineFormSet
 from webpack_loader.loader import WebpackLoader
 
 from .models import Contract, ContracteeSignature, SigneeSignature
 
 
+class AtLeastOneRequiredInlineFormSet(BaseInlineFormSet):
+    def clean(self):
+        """Check that at least one item has been entered."""
+
+        super().clean()
+
+        if any(self.errors):
+            return
+
+        if not any(
+            cleaned_data and not cleaned_data.get('DELETE', False)
+            for cleaned_data in self.cleaned_data
+        ):
+            raise forms.ValidationError("Vyžadován aspoň jeden záznam.")
+
+
 class ContractAdminForm(forms.ModelForm):
     def clean(self):
         clean_data = super().clean()
diff --git a/contracts/migrations/0045_alter_contracteesignaturerepresentative_function.py b/contracts/migrations/0045_alter_contracteesignaturerepresentative_function.py
new file mode 100644
index 0000000000000000000000000000000000000000..365c6ee0bcf2fe1f3a39aed1dd595430505642d8
--- /dev/null
+++ b/contracts/migrations/0045_alter_contracteesignaturerepresentative_function.py
@@ -0,0 +1,19 @@
+# Generated by Django 4.1.4 on 2023-04-16 07:36
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contracts', '0044_alter_contract_tender_url'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='contracteesignaturerepresentative',
+            name='function',
+            field=models.CharField(default='k vyplnění', max_length=256, verbose_name='Funkce'),
+            preserve_default=False,
+        ),
+    ]
diff --git a/contracts/migrations/0046_alter_contract_paper_form_state.py b/contracts/migrations/0046_alter_contract_paper_form_state.py
new file mode 100644
index 0000000000000000000000000000000000000000..c8783c810aebe198a92e06df18493bde7539670b
--- /dev/null
+++ b/contracts/migrations/0046_alter_contract_paper_form_state.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.1.4 on 2023-04-16 07:39
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contracts', '0045_alter_contracteesignaturerepresentative_function'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='contract',
+            name='paper_form_state',
+            field=models.CharField(choices=[('on_the_way', 'Na cestě'), ('sent', 'Odeslaný'), ('mailbox', 'Ve schránce'), ('to_shred', 'Ke skartaci'), ('shredded', 'Skartovaný'), ('stored', 'Uložený'), ('lost', 'Ztracený')], max_length=10, verbose_name='Stav fyzického dokumentu'),
+        ),
+    ]
diff --git a/contracts/models.py b/contracts/models.py
index 0b44dcd4795f8bb2ffd531b132597247f1c9440b..8490179301c0336ca460e90af522e9d5e847d403 100644
--- a/contracts/models.py
+++ b/contracts/models.py
@@ -540,10 +540,15 @@ class Contract(NameStrMixin, models.Model):
         NO = "no", "Neveřejná"
 
     class PaperFormStates(models.TextChoices):
+        ON_THE_WAY = "on_the_way", "Na cestě"
         SENT = "sent", "Odeslaný"
-        STORED = "stored", "Uložený"
+        MAILBOX = "mailbox", "Ve schránce"
+
         TO_SHRED = "to_shred", "Ke skartaci"
         SHREDDED = "shredded", "Skartovaný"
+
+        STORED = "stored", "Uložený"
+
         LOST = "lost", "Ztracený"
 
     legal_state = models.CharField(
@@ -568,7 +573,7 @@ class Contract(NameStrMixin, models.Model):
     )  # WARNING: public status dependent
 
     paper_form_state = models.CharField(
-        max_length=8,
+        max_length=10,
         choices=PaperFormStates.choices,
         verbose_name="Stav fyzického dokumentu",
     )
@@ -950,8 +955,6 @@ class ContracteeSignatureRepresentative(RepresentativeMixin, models.Model):
 
     function = models.CharField(
         max_length=256,
-        blank=True,
-        null=True,
         verbose_name="Funkce",
     )
 
diff --git a/package-lock.json b/package-lock.json
index 025b1d69f0d1f2e0ea2fb7e95ca2c934d985b1d0..9a705a811e46537bc31c60f7b4490b6564d9abf9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,7 +12,7 @@
         "@tailwindcss/typography": "^0.5.9",
         "alertifyjs": "^1.13.1",
         "css-loader": "^6.7.3",
-        "jquery": "^3.6.3",
+        "jquery": "^3.6.4",
         "style-loader": "^3.3.1",
         "tailwindcss": "^3.2.4",
         "tippy.js": "^6.3.7",
diff --git a/package.json b/package.json
index 528abd89974cb7336d6bdfad72908e4ddbc86741..77aef2b96558d980415ba388aad4b1d05651db55 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,7 @@
     "@tailwindcss/typography": "^0.5.9",
     "alertifyjs": "^1.13.1",
     "css-loader": "^6.7.3",
-    "jquery": "^3.6.3",
+    "jquery": "^3.6.4",
     "style-loader": "^3.3.1",
     "tailwindcss": "^3.2.4",
     "tippy.js": "^6.3.7",