From ea8c153a58dbe3a970c8ba252b9ce7c6a22bcb58 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Valenta?= <git@imaniti.org>
Date: Tue, 21 Feb 2023 21:22:41 +0100
Subject: [PATCH] organize fields, expected cost frontend, documentation,
 migrations

---
 README.md                                     |   2 +-
 contracts/admin.py                            |  21 +--
 ..._contract_issues_alter_contract_summary.py |  23 +++
 ...ter_contractee_address_country_and_more.py |  23 +++
 contracts/models.py                           | 151 +++++++++---------
 .../templates/contracts/view_contract.html    |  47 +++++-
 env.example                                   |   3 +-
 registry/settings/base.py                     |   2 +-
 requirements/base.txt                         |   1 -
 shared/templates/shared/includes/base.html    |   2 +-
 10 files changed, 182 insertions(+), 93 deletions(-)
 create mode 100644 contracts/migrations/0006_alter_contract_issues_alter_contract_summary.py
 create mode 100644 contracts/migrations/0007_alter_contractee_address_country_and_more.py

diff --git a/README.md b/README.md
index a2042d0..bf43cb6 100644
--- a/README.md
+++ b/README.md
@@ -21,11 +21,11 @@ Je třeba definovat minimálně následující environment proměnné:
 | --- | --- |
 | `DATABASE_URL` | URL pro připojení k databázi ve formátu `postgresql://username:password@host:5432/database_name` |
 | `SECRET_KEY` | Tajný klíč např. pro šifrování |
+| `DEFAULT_COUNTRY` | Defaultní země podepisujících stran, např. `Česká republika` |
 | `DEFAULT_CONTRACTEE_NAME` | Defaultní jméno naší podepisující strany |
 | `DEFAULT_CONTRACTEE_STREET` | Defaultní ulice a č.p. naší podepisující strany |
 | `DEFAULT_CONTRACTEE_ZIP` | Defaultní PSČ naší podepisující strany |
 | `DEFAULT_CONTRACTEE_DISTRICT` | Defaultní obec naší podepisující strany |
-| `DEFAULT_CONTRACTEE_COUNTRY` | Defaultní země naší podepisující strany, např. `CZ`, `DE` |
 | `DEFAULT_CONTRACTEE_ICO_NUMBER` | Defaultní IČO naší podepisující strany |
 
 V produkci je potřeba:
diff --git a/contracts/admin.py b/contracts/admin.py
index 0b72ac6..2c934f7 100644
--- a/contracts/admin.py
+++ b/contracts/admin.py
@@ -64,29 +64,32 @@ class ContractAdmin(MarkdownxGuardedModelAdmin):
 
     def get_fields(self, request, obj=None):
         fields = [
-            "created_by",
+            "identifier",
             "types",
+            "summary",
             "valid_start_date",
             "valid_end_date",
             "legal_state",
             "public_state",
-            "paper_form_state",
             "publishing_rejection_comment",
+            "paper_form_state",
             "tender_url",
-            "identifier",
-            "issues",
-            "notes",
-            "summary",
-            "primary_contract",
             "agreement_url",
-            "filing_area",
+            "issues",
             "expected_cost_year",
             "expected_cost_month",
             "expected_cost_hour",
+            "filing_area",
+            "primary_contract",
+            "notes",
+            "created_by",
         ]
 
         if request.user.is_superuser or request.user.has_perm("approve", self):
-            fields.append("is_approved")
+            fields.insert(
+                fields.index("summary"),
+                "is_approved",
+            )
 
         return fields
 
diff --git a/contracts/migrations/0006_alter_contract_issues_alter_contract_summary.py b/contracts/migrations/0006_alter_contract_issues_alter_contract_summary.py
new file mode 100644
index 0000000..c6ae7b9
--- /dev/null
+++ b/contracts/migrations/0006_alter_contract_issues_alter_contract_summary.py
@@ -0,0 +1,23 @@
+# Generated by Django 4.1.4 on 2023-02-21 19:13
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contracts', '0005_alter_contract_primary_contract'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='contract',
+            name='issues',
+            field=models.ManyToManyField(blank=True, help_text='Veřejně nazváno "Poznámky".', to='contracts.contractissue', verbose_name='Problémy'),
+        ),
+        migrations.AlterField(
+            model_name='contract',
+            name='summary',
+            field=models.CharField(blank=True, max_length=256, null=True, verbose_name='Sumarizace obsahu smlouvy'),
+        ),
+    ]
diff --git a/contracts/migrations/0007_alter_contractee_address_country_and_more.py b/contracts/migrations/0007_alter_contractee_address_country_and_more.py
new file mode 100644
index 0000000..1c2a4b4
--- /dev/null
+++ b/contracts/migrations/0007_alter_contractee_address_country_and_more.py
@@ -0,0 +1,23 @@
+# Generated by Django 4.1.4 on 2023-02-21 19:34
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contracts', '0006_alter_contract_issues_alter_contract_summary'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='contractee',
+            name='address_country',
+            field=models.CharField(default='CZ', max_length=256, verbose_name='Země'),
+        ),
+        migrations.AlterField(
+            model_name='signee',
+            name='address_country',
+            field=models.CharField(default='CZ', max_length=256, verbose_name='Země'),
+        ),
+    ]
diff --git a/contracts/models.py b/contracts/models.py
index 7575f79..529f85a 100644
--- a/contracts/models.py
+++ b/contracts/models.py
@@ -2,7 +2,6 @@ import math
 
 from django.conf import settings
 from django.db import models
-from django_countries.fields import CountryField
 from colorfield.fields import ColorField
 from markdownx.models import MarkdownxField
 
@@ -94,8 +93,10 @@ class Signee(ColorMixin, models.Model):
         help_text="Viditelné pouze u právnických osob.",
     )  # WARNING: Legal entity status dependent!
 
-    address_country = CountryField(
+    address_country = models.CharField(
+        max_length=256,
         verbose_name="Země",
+        default=settings.DEFAULT_COUNTRY,
     )
 
     ico_number = models.CharField(
@@ -202,9 +203,10 @@ class Contractee(ColorMixin, models.Model):
         verbose_name="PSČ",
     )
 
-    address_country = CountryField(
-        default=settings.DEFAULT_CONTRACTEE_COUNTRY,
+    address_country = models.CharField(
+        max_length=256,
         verbose_name="Země",
+        default=settings.DEFAULT_COUNTRY,
     )
 
     ico_number = models.CharField(
@@ -314,16 +316,60 @@ class ContractFilingArea(NameStrMixin, models.Model):
 
 
 class Contract(models.Model):
+    # BEGIN Automatically set fields
+
+    created_by = models.ForeignKey(
+        settings.AUTH_USER_MODEL,
+        blank=True,
+        null=True,
+        on_delete=models.SET_NULL,
+        related_name="uploaded_contracts",
+        verbose_name="Vytvořena uživatelem",
+        help_text="Informace není veřejně přístupná. Pokud vytváříš novou smlouvu, budeš to ty.",
+    )  # WARNING: exclude in admin
+
+    public_status_set_by = models.ForeignKey(
+        User,
+        on_delete=models.SET_NULL,
+        blank=True,
+        null=True,
+        related_name="public_status_altered_contracts",
+        verbose_name="Zveřejněno / nezveřejněno uživatelem",
+        help_text="Obsah není veřejně přístupný.",
+    )  # WARNING: exclude in admin
+
+    all_parties_sign_date = models.DateField(
+        verbose_name="Datum podpisu všech stran",
+        blank=True,
+        null=True,
+    )  # WARNING: Exclude in admin, autofill
+
+    # END Automatically set fields
+
+    identifier = models.CharField(
+        max_length=128,
+        verbose_name="Identifikační číslo",
+    )
+
     types = models.ManyToManyField(
         ContractType,
         verbose_name="Typ",
     )
 
-    all_parties_sign_date = models.DateField(
-        verbose_name="Datum podpisu všech stran",
+    summary = models.CharField(
+        max_length=256,
         blank=True,
         null=True,
-    )  # WARNING: Exclude in admin, autofill
+        verbose_name="Sumarizace obsahu smlouvy",
+    )
+
+    is_approved = models.BooleanField(
+        verbose_name="Je schválená",
+        help_text=(
+            "Může měnit jen schvalovatel. Pokud je smlouva "
+            "veřejná, zaškrtnutím se vypustí ven."
+        )
+    )
 
     valid_start_date = models.DateField(
         verbose_name="Začátek účinnosti",
@@ -332,16 +378,6 @@ class Contract(models.Model):
         verbose_name="Konec účinnosti",
     )
 
-    created_by = models.ForeignKey(
-        settings.AUTH_USER_MODEL,
-        blank=True,
-        null=True,
-        on_delete=models.SET_NULL,
-        related_name="uploaded_contracts",
-        verbose_name="Vytvořena uživatelem",
-        help_text="Informace není veřejně přístupná. Pokud vytváříš novou smlouvu, budeš to ty.",
-    )  # WARNING: exclude in admin
-
     class LegalStates(models.TextChoices):
         VALID = "valid", "Platná"
         EFFECTIVE = "effective", "Účinná"
@@ -377,16 +413,6 @@ class Contract(models.Model):
         verbose_name="Stav papírové formy",
     )
 
-    public_status_set_by = models.ForeignKey(
-        User,
-        on_delete=models.SET_NULL,
-        blank=True,
-        null=True,
-        related_name="public_status_altered_contracts",
-        verbose_name="Zveřejněno / nezveřejněno uživatelem",
-        help_text="Obsah není veřejně přístupný.",
-    )  # WARNING: exclude in admin
-
     publishing_rejection_comment = models.CharField(
         max_length=65536,
         blank=True,
@@ -409,40 +435,32 @@ class Contract(models.Model):
         verbose_name="Odkaz na schválení",
     )  # WARNING: Dependent on the type!
 
-    identifier = models.CharField(
-        max_length=128,
-        verbose_name="Identifikační číslo",
-    )
-
     issues = models.ManyToManyField(
         ContractIssue,
-        verbose_name="Problémy",
         blank=True,
+        verbose_name="Problémy",
+        help_text="Veřejně nazváno \"Poznámky\".",
     )
 
-    notes = MarkdownxField(
+    # NOTE: Could we make this into expected_cost_type and expected_cost_amount?
+
+    expected_cost_year = models.IntegerField(
         blank=True,
         null=True,
-        verbose_name="Poznámky",
-        help_text="Poznámky jsou viditelné pro všechny, kteří mohou smlouvu spravovat.",
+        verbose_name="Očekávané výdaje (rok)",
     )
-
-    summary = MarkdownxField(
+    
+    expected_cost_month = models.IntegerField(
         blank=True,
         null=True,
-        verbose_name="Rekapitulace",
-        help_text="Obsah není veřejně přístupný.",
+        verbose_name="Očekávané výdaje (měsíc)",
     )
-
-    primary_contract = models.ForeignKey(
-        "Contract",
-        on_delete=models.SET_NULL,  # TODO: Figure out if we want this behavior
+    
+    expected_cost_hour = models.IntegerField(
         blank=True,
         null=True,
-        related_name="subcontracts",
-        verbose_name="Primární smlouva",
-        help_text="Např. pro dodatky nebo objednávky u rámcových smluv."
-    )  # WARNING: Dependent on the type!
+        verbose_name="Očekávané výdaje (hodina)",
+    )
 
     filing_area = models.ForeignKey(
         ContractFilingArea,
@@ -452,36 +470,25 @@ class Contract(models.Model):
         related_name="filed_contracts",
         verbose_name="Spisovna",
         help_text="Obsah není veřejně přístupný.",
-    )  # WARNING: Dependent on the type!
-
-    # NOTE: Could we make this into expected_cost_type and expected_cost_amount?
-
-    expected_cost_year = models.IntegerField(
-        blank=True,
-        null=True,
-        verbose_name="Očekávané výdaje (rok)",
     )
-    
-    expected_cost_month = models.IntegerField(
+
+    primary_contract = models.ForeignKey(
+        "Contract",
+        on_delete=models.SET_NULL,  # TODO: Figure out if we want this behavior
         blank=True,
         null=True,
-        verbose_name="Očekávané výdaje (měsíc)",
-    )
-    
-    expected_cost_hour = models.IntegerField(
+        related_name="subcontracts",
+        verbose_name="Primární smlouva",
+        help_text="Např. pro dodatky nebo objednávky u rámcových smluv."
+    )  # WARNING: Dependent on the type!
+
+    notes = MarkdownxField(
         blank=True,
         null=True,
-        verbose_name="Očekávané výdaje (hodina)",
-    )
-    
-    is_approved = models.BooleanField(
-        verbose_name="Je schválená",
-        help_text=(
-            "Může měnit jen schvalovatel. Pokud je smlouva "
-            "veřejná, zaškrtnutím se vypustí ven."
-        )
+        verbose_name="Poznámky",
+        help_text="Poznámky jsou viditelné pro všechny, kteří mohou smlouvu spravovat.",
     )
-    
+
     class Meta:
         verbose_name = "Smlouva"
         verbose_name_plural = "Smlouvy"
diff --git a/contracts/templates/contracts/view_contract.html b/contracts/templates/contracts/view_contract.html
index 5e99e84..8b084a0 100644
--- a/contracts/templates/contracts/view_contract.html
+++ b/contracts/templates/contracts/view_contract.html
@@ -13,11 +13,30 @@
                 <td class="w-4/5 !p-2.5">
                     <ul class="flex flex-wrap gap-1.5">
                         {% for type in contract.types.all %}
-                            <li class="p-1.5 rounded-sm whitespace-nowrap bg-gray-200">{{ type.name }}</li>
+                            <li class="flex">
+                                <a
+                                    class="p-1.5 rounded-sm whitespace-nowrap bg-gray-200 duration-100 hover:bg-gray-300 hover:no-underline"
+                                    href="#TODO"
+                                >{{ type.name }}</a>
+                            </li>
                         {% endfor %}
                     </ul>
                 </td>
             </tr>
+            {% if contract.primary_contract %}
+                <tr>
+                    <td class="w-1/5 !p-2.5">Primární smlouva</td>
+                    <td class="w-4/5 !p-2.5">
+                        <a
+                            href="{% url "contracts:view_contract" contract.primary_contract.id %}"
+                        >{{ contract.primary_contract.identifier }}</a>
+                    </td>
+                </tr>
+            {% endif %}
+            <tr>
+                <td class="w-1/5 !p-2.5">Souhrn obsahu</td>
+                <td class="w-4/5 !p-2.5">{{ contract.summary }}</td>
+            </tr>
             <tr>
                 <td class="w-1/5 !p-2.5">Začátek účinnosti</td>
                 <td class="w-4/5 !p-2.5">{{ contract.valid_start_date }}</td>
@@ -82,7 +101,7 @@
                 </td>
             </tr>
             <tr>
-                <td class="w-1/5 !p-2.5">Problémy</td>
+                <td class="w-1/5 !p-2.5">Poznámky</td>
                 <td class="w-4/5 !p-2.5">
                     {% with contract.issues.all as issues %}
                         {% if issues|length != 0 %}
@@ -97,13 +116,27 @@
                     {% endwith %}
                 </td>
             </tr>
-            {% if contract.primary_contract %}
+            {% if contract.expected_cost_year %}
                 <tr>
-                    <td class="w-1/5 !p-2.5">Primární smlouva</td>
+                    <td class="w-1/5 !p-2.5">Očekávané náklady (rok)</td>
                     <td class="w-4/5 !p-2.5">
-                        <a
-                            href="{% url "contracts:view_contract" contract.primary_contract.id %}"
-                        >{{ contract.primary_contract.identifier }}</a>
+                        {{ contract.expected_cost_month }} Kč
+                    </td>
+                </tr>
+            {% endif %}
+            {% if contract.expected_cost_month %}
+                <tr>
+                    <td class="w-1/5 !p-2.5">Očekávané náklady (měsíc)</td>
+                    <td class="w-4/5 !p-2.5">
+                        {{ contract.expected_cost_month }} Kč
+                    </td>
+                </tr>
+            {% endif %}
+            {% if contract.expected_cost_hour %}
+                <tr>
+                    <td class="w-1/5 !p-2.5">Očekávané náklady (hodina)</td>
+                    <td class="w-4/5 !p-2.5">
+                        {{ contract.expected_cost_hour }} Kč
                     </td>
                 </tr>
             {% endif %}
diff --git a/env.example b/env.example
index 2ca58dd..081cf4a 100644
--- a/env.example
+++ b/env.example
@@ -8,9 +8,10 @@ OIDC_RP_REALM_URL="http://localhost:8080/realms/master/"
 OIDC_RP_CLIENT_ID=contracts
 OIDC_RP_CLIENT_SECRET=VCn4LVAUc6RGLSup7VaAKsmrKUbWguaP
 
+DEFAULT_COUNTRY="CZ"
+
 DEFAULT_CONTRACTEE_NAME="Česká pirátská strana"
 DEFAULT_CONTRACTEE_STREET="Na Moráni 360/3"
 DEFAULT_CONTRACTEE_ZIP="128 00"
 DEFAULT_CONTRACTEE_DISTRICT="Praha 2"
-DEFAULT_CONTRACTEE_COUNTRY="CZ"
 DEFAULT_CONTRACTEE_ICO_NUMBER="71339698"
diff --git a/registry/settings/base.py b/registry/settings/base.py
index 3d354b1..d0f9fe0 100644
--- a/registry/settings/base.py
+++ b/registry/settings/base.py
@@ -187,5 +187,5 @@ DEFAULT_CONTRACTEE_NAME = env.str("DEFAULT_CONTRACTEE_NAME")
 DEFAULT_CONTRACTEE_STREET = env.str("DEFAULT_CONTRACTEE_STREET")
 DEFAULT_CONTRACTEE_ZIP = env.str("DEFAULT_CONTRACTEE_ZIP")
 DEFAULT_CONTRACTEE_DISTRICT = env.str("DEFAULT_CONTRACTEE_DISTRICT")
-DEFAULT_CONTRACTEE_COUNTRY = env.str("DEFAULT_CONTRACTEE_COUNTRY")
+DEFAULT_COUNTRY = env.str("DEFAULT_COUNTRY")
 DEFAULT_CONTRACTEE_ICO_NUMBER = env.str("DEFAULT_CONTRACTEE_ICO_NUMBER")
diff --git a/requirements/base.txt b/requirements/base.txt
index 62a0fab..00d09ff 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -9,4 +9,3 @@ django-markdownx==4.0.0b1
 django-environ==0.9.0
 django-http-exceptions==1.4.0
 django-guardian==2.4.0
-django-countries==7.5.1
diff --git a/shared/templates/shared/includes/base.html b/shared/templates/shared/includes/base.html
index 6848200..c38dae1 100644
--- a/shared/templates/shared/includes/base.html
+++ b/shared/templates/shared/includes/base.html
@@ -76,7 +76,7 @@
                                         <a href="{% url "contracts:index" %}" data-href="{% url "contracts:index" %}" class="navbar-menu__link">Všechny smlouvy</a>
                                     </li>
                                     <li class="navbar-menu__item">
-                                        <a href="#TODO" data-href="#TODO" class="navbar-menu__link">Hledání</a>
+                                        <a href="#TODO" data-href="#TODO" class="navbar-menu__link">Hledat</a>
                                     </li>
                                     {% if user.is_staff %}
                                         <li class="navbar-menu__item">
-- 
GitLab