diff --git a/contracts/admin.py b/contracts/admin.py
index 593e03216894c850170f3fc8b922ac7ac40155e9..d80d314b534322dad59af72d9c5df6ea1c9dcee9 100644
--- a/contracts/admin.py
+++ b/contracts/admin.py
@@ -42,16 +42,14 @@ class IndexHiddenModelAdmin(MarkdownxGuardedModelAdmin):
 def permissions_mixin_factory(
     change_permission: str,
     delete_permission: str,
-    obj_conditional: typing.Callable,
-    change_attr_func: typing.Callable = lambda obj: obj,
-    delete_attr_func: typing.Callable = lambda obj: obj,
+    obj_conditional: typing.Callable = lambda request, obj: True
 ) -> object:
     class Mixin:
         def has_change_permission(self, request, obj=None) -> bool:
             if (
                 obj is not None
                 and obj_conditional(request, obj)
-                and not request.user.has_perm(change_permission, change_attr_func(obj))
+                and not request.user.has_perm(change_permission)
             ):
                 return False
 
@@ -61,7 +59,7 @@ def permissions_mixin_factory(
             if (
                 obj is not None
                 and obj_conditional(request, obj)
-                and not request.user.has_perm(delete_permission, delete_attr_func(obj))
+                and not request.user.has_perm(change_permission)
             ):
                 return False
 
@@ -70,14 +68,14 @@ def permissions_mixin_factory(
     return Mixin
 
 
-get_obj_contract = lambda obj: obj.contract
+get_obj_contract = lambda request, obj: obj.contract
 
 
 class OwnPermissionsMixin(
     permissions_mixin_factory(
         "contracts.edit_others",
         "contracts.delete_others",
-        lambda request, obj: obj.created_by != request.user,
+        obj_conditional=lambda request, obj: obj.created_by != request.user,
     )
 ):
     def save_model(self, request, obj, form, change):
@@ -90,18 +88,14 @@ class OwnPermissionsMixin(
 ParentContractApprovedPermissionsMixin = permissions_mixin_factory(
     "contracts.edit_when_approved",
     "contracts.delete_when_approved",
-    lambda request, obj: get_obj_contract(obj).is_approved,
-    get_obj_contract,
-    get_obj_contract,
+    obj_conditional=lambda request, obj: get_obj_contract(obj).is_approved,
 )
 
 
 ParentContractOwnPermissionsMixin = permissions_mixin_factory(
     "contracts.edit_others",
     "contracts.delete_others",
-    lambda request, obj: get_obj_contract(obj).created_by != request.user,
-    get_obj_contract,
-    get_obj_contract,
+    obj_conditional=lambda request, obj: get_obj_contract(obj).created_by != request.user,
 )
 
 
@@ -162,7 +156,7 @@ class ContractAdmin(
     permissions_mixin_factory(
         "contracts.edit_when_approved",
         "contracts.delete_when_approved",
-        lambda request, obj: obj.is_approved,
+        obj_conditional=lambda request, obj: obj.is_approved,
     ),
     MarkdownxGuardedModelAdmin,
     NestedModelAdmin,
@@ -494,8 +488,8 @@ class SigneeAdmin(OwnPermissionsMixin, MarkdownxGuardedModelAdmin):
     load_ares_data_button.short_description = "ARES"
 
 
-get_obj_signee_contract = lambda obj: obj.signee.contract
-get_obj_contractee_contract = lambda obj: obj.contractee.contract
+get_obj_signee_contract = lambda request, obj: obj.signee.contract
+get_obj_contractee_contract = lambda request, obj: obj.contractee.contract
 
 
 class SigneeSignatureRepresentativeAdmin(
@@ -503,17 +497,12 @@ class SigneeSignatureRepresentativeAdmin(
     permissions_mixin_factory(
         "contracts.edit_when_approved",
         "contracts.delete_when_approved",
-        lambda request, obj: get_obj_signee_contract(obj).is_approved,
-        get_obj_signee_contract,
-        get_obj_signee_contract,
+        obj_conditional=lambda request, obj: get_obj_signee_contract(obj).is_approved,
     ),
     permissions_mixin_factory(
         "contracts.edit_others",
         "contracts.delete_others",
-        lambda request, obj: get_obj_contractee_contract(obj).created_by
-        != request.user,
-        get_obj_signee_contract,
-        get_obj_signee_contract,
+        obj_conditional=lambda request, obj: get_obj_contractee_contract(obj).created_by != request.user,
     ),
 ):
     pass
@@ -524,17 +513,12 @@ class ContracteeSignatureRepresentativeAdmin(
     permissions_mixin_factory(
         "contracts.edit_when_approved",
         "contracts.delete_when_approved",
-        lambda request, obj: get_obj_contractee_contract(obj).is_approved,
-        get_obj_contractee_contract,
-        get_obj_contractee_contract,
+        obj_conditional=lambda request, obj: get_obj_contractee_contract(obj).is_approved,
     ),
     permissions_mixin_factory(
         "contracts.edit_others",
         "contracts.delete_others",
-        lambda request, obj: get_obj_contractee_contract(obj).created_by
-        != request.user,
-        get_obj_contractee_contract,
-        get_obj_contractee_contract,
+        obj_conditional=lambda request, obj: get_obj_contractee_contract(obj).created_by != request.user,
     ),
 ):
     pass
diff --git a/contracts/migrations/0059_alter_contract_is_valid.py b/contracts/migrations/0059_alter_contract_is_valid.py
new file mode 100644
index 0000000000000000000000000000000000000000..df29dad1e83e8eb129a54642ba1ab5af5a3fbd6b
--- /dev/null
+++ b/contracts/migrations/0059_alter_contract_is_valid.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.1.4 on 2023-05-01 20:29
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contracts', '0058_alter_contract_options_alter_contractee_options_and_more'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='contract',
+            name='is_valid',
+            field=models.BooleanField(default=False, help_text='Právní vztah vyplývající ze smlouvy je aktuálně účinný a platný', verbose_name='Je právně platná'),
+        ),
+    ]
diff --git a/contracts/models.py b/contracts/models.py
index 114c3da823e855598c227c9bca478ea86296fdf9..5e9719e79202e770c039ae56195f6491da9d5ba6 100644
--- a/contracts/models.py
+++ b/contracts/models.py
@@ -564,6 +564,7 @@ class Contract(NameStrMixin, models.Model):
     is_valid = models.BooleanField(
         default=False,
         verbose_name="Je právně platná",
+        help_text="Právní vztah vyplývající ze smlouvy je aktuálně účinný a platný",
     )
 
     is_public = models.BooleanField(