diff --git a/contracts/admin.py b/contracts/admin.py
index e020611ab798557099a241de696b2aae3c94aea1..264fb42788d820632c060a502af93b91e4ecc925 100644
--- a/contracts/admin.py
+++ b/contracts/admin.py
@@ -1,6 +1,7 @@
 import copy
 import typing
 
+from admin_auto_filters.filters import AutocompleteFilterFactory
 from django.contrib import admin
 from django.contrib.auth.models import Permission
 from django.db import models
@@ -168,11 +169,6 @@ class ContractAdmin(
 ):
     form = ContractAdminForm
 
-    ordering = (
-        "-created_on",
-        "-updated_on",
-        "-name",
-    )
     search_fields = ("name",)
 
     readonly_fields = (
@@ -364,12 +360,15 @@ class ContractAdmin(
         return super().has_change_permission(request, obj)
 
     list_filter = (
-        "types",
+        AutocompleteFilterFactory("Typ", "types"),
+        AutocompleteFilterFactory("Spisovna", "filing_area"),
+        AutocompleteFilterFactory("Problém", "issues"),
+        AutocompleteFilterFactory("Naše smluvná strana", "contractee_signatures__contractee"),
+        AutocompleteFilterFactory("Jiná smluvní strana", "signee_signatures__signee"),
         "is_approved",
         "is_valid",
         "is_public",
         "paper_form_state",
-        "issues",
         ("all_parties_sign_date", DateRangeFilter),
         ("valid_start_date", DateRangeFilter),
         ("valid_end_date", DateRangeFilter),
@@ -385,19 +384,16 @@ class ContractAdmin(
 
 class ContractTypeAdmin(MarkdownxGuardedModelAdmin):
     model = ContractType
-    ordering = ("name",)
     search_fields = ("name",)
 
 
 class ContractIssueAdmin(MarkdownxGuardedModelAdmin):
     model = ContractIssue
-    ordering = ("name",)
     search_fields = ("name",)
 
 
 class ContractFilingAreaAdmin(MarkdownxGuardedModelAdmin):
     model = ContractFilingArea
-    ordering = ("name",)
     search_fields = (
         "name",
         "person_responsible",
@@ -425,7 +421,6 @@ class ContracteeAdmin(OwnPermissionsMixin, MarkdownxGuardedModelAdmin):
         "name",
         "department",
     )
-    ordering = ("name",)
 
 
 class SigneeAdmin(OwnPermissionsMixin, MarkdownxGuardedModelAdmin):
@@ -446,7 +441,6 @@ class SigneeAdmin(OwnPermissionsMixin, MarkdownxGuardedModelAdmin):
         "name",
         "department",
     )
-    ordering = ("name",)
 
     form = SigneeAdminForm
 
diff --git a/contracts/management/commands/import_old_contracts.py b/contracts/management/commands/import_old_contracts.py
index 7a9aa42d8b8feeb7735fea25ba6918fe865abf6d..74c4a69d44ac3880adf75d1be44e2ff8587e90f2 100644
--- a/contracts/management/commands/import_old_contracts.py
+++ b/contracts/management/commands/import_old_contracts.py
@@ -69,6 +69,10 @@ class Command(BaseCommand):
         type_name = string.capwords(type_name)
 
         patterns = (
+            (
+                r"\s\s+",
+                " "
+            ),
             (r" O ", " o "),
             (r" S ", " s "),
             (r" K ", " k "),
@@ -140,10 +144,157 @@ class Command(BaseCommand):
 
         return type_name
 
+    def normalize_department(self, type_name: str) -> str:
+        type_name = type_name.strip()
+
+        patterns = (
+            (
+                r"\s\s+",
+                " "
+            ),
+            (
+                r"^Kraské sdružení Praha$",
+                "Krajské sdružení Praha"
+            ),
+            (
+                r"^republikové předsednictvo$",
+                "Republikové předsednictvo"
+            ),
+            (
+                r"^KS ",
+                "Krajské sdružení "
+            ),
+            (
+                r"^(MS |místní sdružení )",
+                "Místní sdružení "
+            ),
+            (
+                r"^(Ústecký kraj|Ustecký kraj)$",
+                "Krajské sdružení Ústecký kraj"
+            ),
+            (
+                r"^Moravskoslezský kraj$",
+                "Krajské sdružení Moravskoslezský kraj",
+            ),
+            (
+                r"^Karlovarský kraj$",
+                "Krajské sdružení Karlovarský kraj",
+            ),
+            (
+                r"Jihočeská kraj",
+                "Jihočeský kraj",
+            ),
+            (
+                r"^(Krajského |krajské |Kajské )",
+                "Krajské "
+            ),
+            (
+                "^Poslanecký klub České pirátské strany$",
+                "Poslanecký klub"
+            ),
+            (
+                r"Středočeký",
+                "Středočeský"
+            ),
+            (
+                r"^Zahraničního odboru$",
+                "Zahraniční odbor"
+            ),
+            (
+                r"JčK",
+                "Jihočeský kraj"
+            ),
+            (
+                r"SčK",
+                "Středočeský kraj"
+            ),
+            (
+                r"(ÚsK|UsK)",
+                "Ústecký kraj"
+            ),
+            (
+                r"JmK",
+                "Jihomoravský kraj"
+            ),
+            (
+                r"PaK",
+                "Pardubický kraj"
+            ),
+            (
+                r"KhK",
+                "Královehradecký kraj"
+            ),
+            (
+                r"(Prsonální|personální)",
+                "Personální"
+            ),
+            (
+                r"^administrativní ",
+                "Administrativní "
+            ),
+            (
+                r"technický",
+                "Technický"
+            ),
+            (
+                r"Mediálni",
+                "Technický"
+            ),
+            (
+                r"^řešitel ",
+                "Řešitel "
+            ),
+            (
+                r"^předsednictvo ",
+                "Předsednictvo "
+            ),
+            (
+                r"olomoucký",
+                "Olomoucký"
+            ),
+            (
+                r"^místní ",
+                "Místní "
+            ),
+            (
+                r"^celostátní ",
+                "Celostátní "
+            ),
+            (
+                r"odbor",
+                "Odbor"
+            ),
+            (
+                r"PKS",
+                "Předsednictvo krajského sdružení"
+            ),
+            (
+                r"( KS | Krajského sdružení )",
+                " krajského sdružení "
+            ),
+            (
+                r"^(Předsednictvo krajského sdružení |Předsednictvo |Místní předsednictvo )",
+                ""
+            ),
+            (
+                r"ého kraje$",
+                "ý kraj"
+            )
+        )
+
+        for pattern in patterns:
+            type_name = re.sub(pattern[0], pattern[1], type_name)
+
+        return type_name
+
     def normalize_filing_area(self, area_name: str) -> str:
         area_name = string.capwords(area_name)
 
         patterns = (
+            (
+                r"\s\s+",
+                " "
+            ),
             (
                 r"^(Cenrální Spisovna|Censtrální Spisovna|Centrála|Centrálách Archiv Str"
                 r"any|Centrála Strany|Centrální Achiv Strany|Centrální Archiv|Centralni "
@@ -303,6 +454,10 @@ class Command(BaseCommand):
         ).strip()
 
         patterns = (
+            (
+                r"\s\s+",
+                " "
+            ),
             (
                 r"^(1\. Pirátská s\.r\.o|1\.Pirátská s\.r\.o\.)$",
                 "1. Pirátská s.r.o."
@@ -322,7 +477,8 @@ class Command(BaseCommand):
             (
                 (
                     r"^(Křesťanská a demokratická unie – Československá strana lidová|"
-                    r"Křesťansko demokratická unie – Československá strana lidová)$"
+                    r"Křesťansko demokratická unie – Československá strana lidová|Křes"
+                    r"ťanská a demokratická unie - Československá strana lidová)$"
                 ),
                 "Křesťanská a demokratická unie – Československá strana lidová"
             ),
@@ -369,6 +525,34 @@ class Command(BaseCommand):
             (
                 r" (KUdláčková|Kudlláčková)$",
                 " Kudláčková"
+            ),
+            (
+                r"^Jiří knotek$",
+                "Jiří Knotek"
+            ),
+            (
+                r"^JIří Roubíček$",
+                "Jiří Roubíček"
+            ),
+            (
+                r"^Koalice Vlasta\. z\.s\.$",
+                "Koalice Vlasta, z.s."
+            ),
+            (
+                r"^Mikuáš ",
+                "Mikuláš "
+            ),
+            (
+                r"^Strana zelených$",
+                "Strana Zelených"
+            ),
+            (
+                r"^Systemický institut s\.r\.o\.$",
+                "Systemický institut, s.r.o."
+            ),
+            (
+                r"^Adéla hradilová$",
+                "Adéla Hradilová"
             )
         )
 
@@ -428,7 +612,7 @@ class Command(BaseCommand):
                     instance.address_street_with_number = ""
 
                     if "road" in address:
-                        instance.address_street_with_number = address["road"]
+                        instance.address_street_with_number = string.capwords(address["road"])
 
                     if "house_number" in address:
                         instance.address_street_with_number += f" {address['house_number']}"
@@ -436,12 +620,21 @@ class Command(BaseCommand):
                     for address_key, address_value in address.items():
                         match address_key:
                             case "city":
-                                instance.address_district = address_value
+                                if "district" not in address:
+                                    instance.address_district = string.capwords(address_value)
+                            case "house":
+                                if "city" not in address and "district" not in address:
+                                    instance.address_district = string.capwords(address_value)
+                            case "city_district":
+                                instance.address_district = string.capwords(address_value)
                             case "postcode":
-                                instance.address_zip = address_value
+                                instance.address_zip = string.capwords(address_value)
 
                     self.normalization_count += 1
                 case "IČ":
+                    if is_contractee:
+                        continue
+
                     if not isinstance(signing_party_value, int|str):
                         issue_count += 1
                         contract.notes += f"Špatně zadané IČO smluvní strany: {signing_party_value}\n"
@@ -479,6 +672,23 @@ class Command(BaseCommand):
                         )
                         self.normalization_count += 1
 
+                        function = None
+
+                        if "funkce" in signing_party:
+                            if isinstance(signing_party["funkce"], str):
+                                function = signing_party["funkce"]
+                            else:
+                                issue_count += 1
+                                contract.notes += f"Špatně zadaná funkce zástupce smluvní strany: {signing_party['funkce']}\n"
+
+                                if self.verbosity >= 2:
+                                    self.stderr.write(
+                                        self.style.NOTICE(
+                                            f"Contract {slug} has an invalid signing party "
+                                            f"representative function: {signing_party['funkce']}."
+                                        )
+                                    )
+
                         representatives.append(
                             representative_model(
                                 name=signing_party_value
@@ -512,11 +722,40 @@ class Command(BaseCommand):
                                     name=signing_party_value
                                 )
                             )
+                case "orgán":
+                    if not isinstance(signing_party_value, str):
+                        issue_count += 1
+                        contract.notes += f"Špatně zadaný orgán smluvní strany: {signing_party_value}\n"
+
+                        if self.verbosity >= 2:
+                            self.stderr.write(
+                                self.style.NOTICE(
+                                    f"Contract {slug} has an invalid signing party "
+                                    f"department: {signing_party_value}."
+                                )
+                            )
+
+                        continue
+
+                    if signing_party_value in (
+                        "Česká Pirátská strana",
+                        "Česká pirátská strana",
+                    ):
+                        # Irrelevant
+                        continue
+
+                    instance.department = self.normalize_department(signing_party_value)
+                    self.normalization_count += 1
 
         # Do our best to merge signing parties together.
         existing_instance = model.objects.filter(
             (
                 models.Q(name=instance.name)
+                & (
+                    models.Q(department=instance.department)
+                    if instance.department is not None
+                    else models.Q(department__isnull=True)
+                )
                 & (
                     (
                         models.Q(address_street_with_number=instance.address_street_with_number)
@@ -534,7 +773,14 @@ class Command(BaseCommand):
                 )
             )
             | (
-                models.Q(ico_number=instance.ico_number)
+                (
+                    models.Q(ico_number=instance.ico_number)
+                    & (
+                        models.Q(department=instance.department)
+                        if instance.department is not None
+                        else models.Q(department__isnull=True)
+                    )
+                )
                 if instance.ico_number is not None
                 else models.Value(False)
             )
diff --git a/contracts/migrations/0057_alter_contract_options_alter_contractee_options_and_more.py b/contracts/migrations/0057_alter_contract_options_alter_contractee_options_and_more.py
new file mode 100644
index 0000000000000000000000000000000000000000..78898b509d833d2bcee3aaf617b7c950d072f7c1
--- /dev/null
+++ b/contracts/migrations/0057_alter_contract_options_alter_contractee_options_and_more.py
@@ -0,0 +1,37 @@
+# Generated by Django 4.1.4 on 2023-04-23 10:28
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contracts', '0056_rename_contractee_signature_contracteesignaturerepresentative_signature_and_more'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='contract',
+            options={'ordering': ('-created_on', '-updated_on', '-name'), 'permissions': [('approve', 'Schválit / zrušit schválení'), ('view_confidential', 'Zobrazit tajné informace'), ('edit_when_approved', 'Upravit schválené'), ('delete_when_approved', 'Odstranit schválené'), ('edit_others', 'Upravit cizí'), ('delete_others', 'Odstranit cizí'), ('can_edit_contract_settings', 'Can edit Smlouva settings')], 'verbose_name': 'Smlouva', 'verbose_name_plural': 'Smlouvy'},
+        ),
+        migrations.AlterModelOptions(
+            name='contractee',
+            options={'ordering': ['-name', '-department'], 'permissions': [('edit_others', 'Upravit cizí'), ('delete_others', 'Odstranit cizí')], 'verbose_name': 'Naše smluvní strana', 'verbose_name_plural': 'Naše smluvní strany'},
+        ),
+        migrations.AlterModelOptions(
+            name='contractfilingarea',
+            options={'ordering': ['-name'], 'verbose_name': 'Spisovna', 'verbose_name_plural': 'Spisovny'},
+        ),
+        migrations.AlterModelOptions(
+            name='contractissue',
+            options={'ordering': ['-name'], 'verbose_name': 'Problém se smlouvou', 'verbose_name_plural': 'Problémy se smlouvami'},
+        ),
+        migrations.AlterModelOptions(
+            name='contracttype',
+            options={'ordering': ['-name'], 'verbose_name': 'Typ smlouvy', 'verbose_name_plural': 'Typy smluv'},
+        ),
+        migrations.AlterModelOptions(
+            name='signee',
+            options={'ordering': ['-name', '-department'], 'permissions': [('edit_others', 'Upravit cizí'), ('delete_others', 'Odstranit cizí')], 'verbose_name': 'Jiná smluvní strana', 'verbose_name_plural': 'Ostatní smluvní strany'},
+        ),
+    ]
diff --git a/contracts/migrations/0058_alter_contract_options_alter_contractee_options_and_more.py b/contracts/migrations/0058_alter_contract_options_alter_contractee_options_and_more.py
new file mode 100644
index 0000000000000000000000000000000000000000..c17f7b0ea88c220834059e244d1bdf97a1881fba
--- /dev/null
+++ b/contracts/migrations/0058_alter_contract_options_alter_contractee_options_and_more.py
@@ -0,0 +1,37 @@
+# Generated by Django 4.1.4 on 2023-04-23 10:29
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contracts', '0057_alter_contract_options_alter_contractee_options_and_more'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='contract',
+            options={'ordering': ('-created_on', '-updated_on', 'name'), 'permissions': [('approve', 'Schválit / zrušit schválení'), ('view_confidential', 'Zobrazit tajné informace'), ('edit_when_approved', 'Upravit schválené'), ('delete_when_approved', 'Odstranit schválené'), ('edit_others', 'Upravit cizí'), ('delete_others', 'Odstranit cizí'), ('can_edit_contract_settings', 'Can edit Smlouva settings')], 'verbose_name': 'Smlouva', 'verbose_name_plural': 'Smlouvy'},
+        ),
+        migrations.AlterModelOptions(
+            name='contractee',
+            options={'ordering': ['name', 'department'], 'permissions': [('edit_others', 'Upravit cizí'), ('delete_others', 'Odstranit cizí')], 'verbose_name': 'Naše smluvní strana', 'verbose_name_plural': 'Naše smluvní strany'},
+        ),
+        migrations.AlterModelOptions(
+            name='contractfilingarea',
+            options={'ordering': ['name'], 'verbose_name': 'Spisovna', 'verbose_name_plural': 'Spisovny'},
+        ),
+        migrations.AlterModelOptions(
+            name='contractissue',
+            options={'ordering': ['name'], 'verbose_name': 'Problém se smlouvou', 'verbose_name_plural': 'Problémy se smlouvami'},
+        ),
+        migrations.AlterModelOptions(
+            name='contracttype',
+            options={'ordering': ['name'], 'verbose_name': 'Typ smlouvy', 'verbose_name_plural': 'Typy smluv'},
+        ),
+        migrations.AlterModelOptions(
+            name='signee',
+            options={'ordering': ['name', 'department'], 'permissions': [('edit_others', 'Upravit cizí'), ('delete_others', 'Odstranit cizí')], 'verbose_name': 'Jiná smluvní strana', 'verbose_name_plural': 'Ostatní smluvní strany'},
+        ),
+    ]
diff --git a/contracts/models.py b/contracts/models.py
index 2d2b963f962afedda67f5731e77ae2c9ee3cc7dc..aaad5e1e6f86af244bee092cf7f36c26375d277e 100644
--- a/contracts/models.py
+++ b/contracts/models.py
@@ -274,6 +274,8 @@ class Signee(
         verbose_name = "Jiná smluvní strana"
         verbose_name_plural = "Ostatní smluvní strany"
 
+        ordering = ["name", "department"]
+
         permissions = OwnPermissionsMixin.Meta.permissions
 
 
@@ -367,6 +369,8 @@ class Contractee(
         verbose_name = "Naše smluvní strana"
         verbose_name_plural = "Naše smluvní strany"
 
+        ordering = ["name", "department"]
+
         permissions = OwnPermissionsMixin.Meta.permissions
 
 
@@ -383,6 +387,8 @@ class ContractType(ContractCountMixin, NameStrMixin, models.Model):
     class Meta:
         app_label = "contracts"
 
+        ordering = ["name"]
+
         verbose_name = "Typ smlouvy"
         verbose_name_plural = "Typy smluv"
 
@@ -400,6 +406,8 @@ class ContractIssue(ContractCountMixin, NameStrMixin, models.Model):
     class Meta:
         app_label = "contracts"
 
+        ordering = ["name"]
+
         verbose_name = "Problém se smlouvou"
         verbose_name_plural = "Problémy se smlouvami"
 
@@ -422,6 +430,8 @@ class ContractFilingArea(ContractCountMixin, NameStrMixin, models.Model):
     class Meta:
         app_label = "contracts"
 
+        ordering = ["name"]
+
         verbose_name = "Spisovna"
         verbose_name_plural = "Spisovny"
 
@@ -789,6 +799,12 @@ class Contract(NameStrMixin, models.Model):
         verbose_name = "Smlouva"
         verbose_name_plural = "Smlouvy"
 
+        ordering = (
+            "-created_on",
+            "-updated_on",
+            "name",
+        )
+
         permissions = [
             ("approve", "Schválit / zrušit schválení"),
             ("view_confidential", "Zobrazit tajné informace"),
diff --git a/registry/settings/base.py b/registry/settings/base.py
index 15f0ca7001cdb133c88efd3666e6fdba61f893ea..c2f29bd217dd4272ac6a7fdeb5727ef3a17861a3 100644
--- a/registry/settings/base.py
+++ b/registry/settings/base.py
@@ -53,6 +53,7 @@ INSTALLED_APPS = [
     "django.contrib.sessions",
     "django.contrib.messages",
     "django.contrib.staticfiles",
+    "admin_auto_filters",
     "dbsettings",
     "nested_admin",
     "rangefilter",
diff --git a/requirements/base.txt b/requirements/base.txt
index f2f7e257817b7604206a85ea38a40757152f88ae..e4fe2396bd4a6f5a08f1182a3859258f20f97548 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -1,5 +1,6 @@
 clamd==1.0.2
 django==4.1.4
+django-admin-autocomplete-filter==0.7.1
 django-admin-index==2.0.2
 django-admin-interface==0.24.2
 django-admin-rangefilter==0.9.0