diff --git a/contracts/admin.py b/contracts/admin.py index 7b4aa4ac1285ec591d5dbb364511ce0a8ed9687e..5ca0426dda33ecdbf59fef291d5abc8b325cad45 100644 --- a/contracts/admin.py +++ b/contracts/admin.py @@ -225,6 +225,7 @@ class ContractAdmin( "fields": [ "cost_amount", "cost_unit", + "cost_unit_other", ] }, ), @@ -414,7 +415,6 @@ class ContracteeAdmin(OwnPermissionsMixin, MarkdownxGuardedModelAdmin): "address_country", "ico_number", "department", - "role", ) search_fields = ( "name", @@ -437,7 +437,6 @@ class SigneeAdmin(OwnPermissionsMixin, MarkdownxGuardedModelAdmin): "ico_number", "date_of_birth", "department", - "role", ) search_fields = ( "name", diff --git a/contracts/migrations/0025_rename_cost_amount_other_contract_cost_unit_other.py b/contracts/migrations/0025_rename_cost_amount_other_contract_cost_unit_other.py new file mode 100644 index 0000000000000000000000000000000000000000..3a3dd3f491bbddf20d9a72d0db6ffdc9c5b6ea25 --- /dev/null +++ b/contracts/migrations/0025_rename_cost_amount_other_contract_cost_unit_other.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.4 on 2023-03-31 06:32 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('contracts', '0024_alter_contract_is_approved'), + ] + + operations = [ + migrations.RenameField( + model_name='contract', + old_name='cost_amount_other', + new_name='cost_unit_other', + ), + ] diff --git a/contracts/migrations/0026_alter_contract_is_public_and_more.py b/contracts/migrations/0026_alter_contract_is_public_and_more.py new file mode 100644 index 0000000000000000000000000000000000000000..9de3e7b5a20a6f3923a4b40fd6641220ed92ac75 --- /dev/null +++ b/contracts/migrations/0026_alter_contract_is_public_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.4 on 2023-03-31 07:54 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contracts', '0025_rename_cost_amount_other_contract_cost_unit_other'), + ] + + operations = [ + migrations.AlterField( + model_name='contract', + name='is_public', + field=models.BooleanField(default=True, help_text='Neveřejné smlouvy nejsou vidět bez přihlášení jako min. tajný čtenář.', verbose_name='Je veřejná'), + ), + migrations.AlterField( + model_name='contractfile', + name='is_public', + field=models.BooleanField(verbose_name='Veřejně dostupný'), + ), + ] diff --git a/contracts/migrations/0027_alter_contractintent_options.py b/contracts/migrations/0027_alter_contractintent_options.py new file mode 100644 index 0000000000000000000000000000000000000000..c2d25c498b22b8f20bf58c3b14bf73e266ea0381 --- /dev/null +++ b/contracts/migrations/0027_alter_contractintent_options.py @@ -0,0 +1,17 @@ +# Generated by Django 4.1.4 on 2023-03-31 08:15 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('contracts', '0026_alter_contract_is_public_and_more'), + ] + + operations = [ + migrations.AlterModelOptions( + name='contractintent', + options={'verbose_name': 'Záměr v Piroplácení', 'verbose_name_plural': 'Záměry v Piroplácení'}, + ), + ] diff --git a/contracts/migrations/0028_remove_contractee_role_remove_signee_role_and_more.py b/contracts/migrations/0028_remove_contractee_role_remove_signee_role_and_more.py new file mode 100644 index 0000000000000000000000000000000000000000..ec4968662e511e774514406ca8a6460e94679352 --- /dev/null +++ b/contracts/migrations/0028_remove_contractee_role_remove_signee_role_and_more.py @@ -0,0 +1,31 @@ +# Generated by Django 4.1.4 on 2023-03-31 08:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contracts', '0027_alter_contractintent_options'), + ] + + operations = [ + migrations.RemoveField( + model_name='contractee', + name='role', + ), + migrations.RemoveField( + model_name='signee', + name='role', + ), + migrations.AddField( + model_name='contracteesignature', + name='role', + field=models.CharField(blank=True, help_text='Např. nájemce', max_length=256, null=True, verbose_name='Role'), + ), + migrations.AddField( + model_name='signeesignature', + name='role', + field=models.CharField(blank=True, help_text='Např. nájemce', max_length=256, null=True, verbose_name='Role'), + ), + ] diff --git a/contracts/migrations/0029_alter_contracteesignature_role_and_more.py b/contracts/migrations/0029_alter_contracteesignature_role_and_more.py new file mode 100644 index 0000000000000000000000000000000000000000..c4fd8548dc78bf6fafb4ae927ceca8dbe8523fe9 --- /dev/null +++ b/contracts/migrations/0029_alter_contracteesignature_role_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.4 on 2023-03-31 08:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contracts', '0028_remove_contractee_role_remove_signee_role_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='contracteesignature', + name='role', + field=models.CharField(blank=True, help_text="Např. 'nájemník'", max_length=256, null=True, verbose_name='Role'), + ), + migrations.AlterField( + model_name='signeesignature', + name='role', + field=models.CharField(blank=True, help_text="Např. 'pronajímatel'", max_length=256, null=True, verbose_name='Role'), + ), + ] diff --git a/contracts/models.py b/contracts/models.py index a3d10c872b0b78f9079723a2b1c82ec4b86a9bf7..4e95760325d08d6b5280e4c09e690c98a3da7795 100644 --- a/contracts/models.py +++ b/contracts/models.py @@ -145,13 +145,6 @@ class Signee(CreatedByMixin, OwnPermissionsMixin, SignatureCountMixin, models.Mo verbose_name="Organizační složka", ) - role = models.CharField( - max_length=256, - blank=True, - null=True, - verbose_name="Role", - ) - @property def url(self) -> str: return reverse("contracts:view_signee", args=(self.id,)) @@ -234,13 +227,6 @@ class Contractee( verbose_name="Organizační složka", ) - role = models.CharField( - max_length=256, - blank=True, - null=True, - verbose_name="Role", - ) - @property def url(self) -> str: return reverse("contracts:view_contractee", args=(self.id,)) @@ -441,18 +427,12 @@ class Contract(NameStrMixin, models.Model): ) is_public = models.BooleanField( + default=True, verbose_name="Je veřejná", help_text=( - "Neveřejné smlouvy nejsou vidět bez přihlášení " "jako min. tajný čtenář." + "Neveřejné smlouvy nejsou vidět bez přihlášení jako min. tajný čtenář." ), ) - - paper_form_state = models.CharField( - max_length=8, - choices=PaperFormStates.choices, - verbose_name="Stav fyzického dokumentu", - ) - publishing_rejection_comment = models.TextField( max_length=65536, blank=True, @@ -461,6 +441,12 @@ class Contract(NameStrMixin, models.Model): help_text="Obsah není veřejně přístupný.", ) # WARNING: public status dependent + paper_form_state = models.CharField( + max_length=8, + choices=PaperFormStates.choices, + verbose_name="Stav fyzického dokumentu", + ) + tender_url = models.URLField( max_length=256, blank=True, @@ -502,7 +488,7 @@ class Contract(NameStrMixin, models.Model): verbose_name="Jednotka nákladů", ) - cost_amount_other = models.CharField( + cost_unit_other = models.CharField( max_length=128, verbose_name="Jednotka nákladů (jiné)", help_text="Je nutno vyplnit v případě, že máš vybranou možnost 'jiné' v jednotce nákladů.", @@ -597,7 +583,7 @@ class Contract(NameStrMixin, models.Model): def clean(self): if ( not self.is_public - and self.publishing_rejection_comment is None + and not self.publishing_rejection_comment ): raise ValidationError( { @@ -606,7 +592,7 @@ class Contract(NameStrMixin, models.Model): ) elif ( self.is_public - and self.publishing_rejection_comment is not None + and self.publishing_rejection_comment ): raise ValidationError( { @@ -614,22 +600,42 @@ class Contract(NameStrMixin, models.Model): } ) + if ( + self.cost_amount is None # 0 is falsy, but a value + and self.cost_unit + ): + raise ValidationError( + { + "cost_unit": "Nemůže být definováno, pokud nejsou zadány náklady." + } + ) + + if ( + self.cost_amount is not None # 0 is falsy, but a value + and not self.cost_unit + ): + raise ValidationError( + { + "cost_amount": "Nemůže být definováno bez jednoty nákladů." + } + ) + if ( self.cost_unit == self.CostUnits.OTHER[1] - and self.cost_amount_other is None + and self.cost_unit_other is None ): raise ValidationError( { - "cost_amount_other": "Musí být definováno, pokud je vybrána jednotka nákladů 'jiné'." + "cost_unit_other": "Musí být definováno, pokud je vybrána jednotka nákladů 'jiné'." } ) elif ( self.cost_unit != self.CostUnits.OTHER[1] - and self.cost_amount_other is not None + and self.cost_unit_other is not None ): raise ValidationError( { - "cost_amount_other": "Nemůže být definováno, pokud není vybrána jednotka nákladů 'jiné'." + "cost_unit_other": "Nemůže být definováno, pokud není vybrána jednotka nákladů 'jiné'." } ) @@ -673,7 +679,6 @@ class ContractFile(NameStrMixin, models.Model): is_public = models.BooleanField( verbose_name="Veřejně dostupný", - default=True, ) file = models.FileField( @@ -721,6 +726,14 @@ class ContracteeSignature(models.Model): verbose_name="Datum podpisu", ) + role = models.CharField( + max_length=256, + blank=True, + null=True, + verbose_name="Role", + help_text="Např. 'nájemník'", + ) + def __str__(self) -> str: return f"{str(self.contractee)} - {self.date}" @@ -750,6 +763,14 @@ class SigneeSignature(models.Model): verbose_name="Datum podpisu", ) + role = models.CharField( + max_length=256, + blank=True, + null=True, + verbose_name="Role", + help_text="Např. 'pronajímatel'", + ) + def __str__(self) -> str: return f"{str(self.signee)} - {self.date}" @@ -841,5 +862,5 @@ class ContractIntent(NameStrMixin, models.Model): class Meta: app_label = "contracts" - verbose_name = "Záměr" - verbose_name_plural = "Záměry" + verbose_name = "Záměr v Piroplácení" + verbose_name_plural = "Záměry v Piroplácení" diff --git a/contracts/templates/contracts/view_contract.html b/contracts/templates/contracts/view_contract.html index 5f847120f2901d2b12917e2295f7a131fd86e732..8165cef52febda514d813fc505339b35baefe265 100644 --- a/contracts/templates/contracts/view_contract.html +++ b/contracts/templates/contracts/view_contract.html @@ -102,10 +102,12 @@ <td class="w-1/5 !p-2.5">Náklady</td> <td class="w-4/5 !p-2.5"> {{ contract.cost_amount }} Kč - {% if contract.cost_unit != contract.CostUnits.TOTAL %} - / {{ contract.get_cost_unit_display.lower }} - {% else %} + {% if contract.cost_unit == contract.CostUnits.TOTAL %} celkem + {% elif contract.cost_unit == contract.CostUnits.OTHER %} + {{ contract.cost_unit_other }} + {% else %} + / {{ contract.get_cost_unit_display.lower }} {% endif %} </td> </tr> @@ -348,8 +350,8 @@ {% if signature.contractee.department %} - {{ signature.contractee.department }} {% endif %} - {% if signature.contractee.role %} - ({{ signature.contractee.role }}) + {% if signature.role %} + ({{ signature.role }}) {% endif %} </a> </div> @@ -408,8 +410,8 @@ {% if signature.signee.department %} - {{ signature.signee.department }} {% endif %} - {% if signature.signee.role %} - ({{ signature.signee.role }}) + {% if signature.role %} + ({{ signature.role }}) {% endif %} </a> </div> diff --git a/contracts/templates/contracts/view_contractee.html b/contracts/templates/contracts/view_contractee.html index b5712eab0446a8619c2182e35377887d7094d9dc..9b2baa9bf1d52fd0899de6f46ce6adc8c0da62dc 100644 --- a/contracts/templates/contracts/view_contractee.html +++ b/contracts/templates/contracts/view_contractee.html @@ -12,22 +12,20 @@ </div> <address class="mb-8"> - <div> + <div class="mb-2"> <strong>{{ contractee.name }}</strong> {% if contractee.department %} - {{ contractee.department }} {% endif %} - {% if contractee.role %} - ({{ contractee.role }}) - {% endif %} - </div><br> + </div> {{ contractee.address_street_with_number }}<br> {{ contractee.address_zip }} {{ contractee.address_district }}<br> - {{ contractee.get_address_country_display }}<br> + {{ contractee.address_country }} {% if contractee.ico_number %} - IČO: {{ contractee.ico_number }}<br> + <br><br> + IČO: {{ contractee.ico_number }} {% endif %} </address> diff --git a/contracts/templates/contracts/view_signee.html b/contracts/templates/contracts/view_signee.html index 00856b663c5863dca48626af3060843ea15a6ecd..9eaa8fbf1ed98234f1fe68462811e195dd3860d7 100644 --- a/contracts/templates/contracts/view_signee.html +++ b/contracts/templates/contracts/view_signee.html @@ -17,16 +17,13 @@ {% if signee.department %} - {{ signee.department }} {% endif %} - {% if signee.role %} - ({{ signee.role }}) - {% endif %} </div> <div class="mb-2"> {{ signee.get_entity_type_display }} </div> - {% if user.can_view_confidential %} + {% if user.can_view_confidential and not signee.entity_has_public_address %} <div class="border !bg-red-100 border-red-200 p-1.5 rounded-md mt-1.5 mb-2 inline-block"> {% endif %} @@ -45,16 +42,22 @@ {% if user.can_view_confidential or signee.entity_has_public_address %} {{ signee.address_street_with_number }}<br> {{ signee.address_zip }} {{ signee.address_district }}<br> - {{ signee.get_address_country_display }}<br> + {{ signee.address_country }} {% else %} - {{ signee.address_district }}<br> + {{ signee.address_district }}, {{ signee.address_country }} {% endif %} {% if signee.ico_number %} - IČO: {{ signee.ico_number }}<br> + <br><br> + <strong>IČO</strong>: {{ signee.ico_number }} + {% endif %} + + {% if user.can_view_confidential and signee.date_of_birth %} + <br><br> + <strong>Datum narození</strong>: {{ signee.date_of_birth }} {% endif %} - {% if user.can_view_confidential %} + {% if user.can_view_confidential and not signee.entity_has_public_address %} </div> {% endif %} </address> diff --git a/contracts/views.py b/contracts/views.py index 0fefc0021021e1aebb2383a0d1500a300711d573..6a4adba7570de32d35fdc4c62c00e680dc9a4fd8 100644 --- a/contracts/views.py +++ b/contracts/views.py @@ -52,14 +52,12 @@ def get_paginated_contracts(request, filter=None) -> tuple: filter = models.Q(is_approved=True) if not request.user.has_perm("contracts.view_confidential"): - filter = filter & ( - models.Q(is_public=True) | - ( - models.Q(created_by=request.user) - if not request.user.is_anonymous - else True - ) - ) + additional_filter = models.Q(is_public=True) + + if not request.user.is_anonymous: + additional_filter = additional_filter | models.Q(created_by=request.user) + + filter = filter & additional_filter contracts = ( get_objects_for_user(request.user, "contracts.view_contract") diff --git a/static_src/admin/contract_form.js b/static_src/admin/contract_form.js index c55f6cf61030a10f070c4f9fef50fed56905053e..2b08c732c7ee4bf0d31cc3d65b8c7b20d8d09a6c 100644 --- a/static_src/admin/contract_form.js +++ b/static_src/admin/contract_form.js @@ -20,14 +20,45 @@ $(window).ready( $("#id_is_public").on( "change", event => { + const publicIsSelected = $(event.target).is(":checked"); + $(".field-publishing_rejection_comment"). css( "display", ( - (!$(event.target).is(":checked")) ? + (!publicIsSelected) ? + "block" : "none" + ) + ); + + if (publicIsSelected) $(".field-publishing_rejection_comment").val(""); + } + ); + + $(".field-cost_unit_other"). + css( + "display", + ( + ($("#id_cost_unit").find(":selected").val() === "other") ? + "block": "none" + ) + ) + + $("#id_cost_unit").on( + "change", + event => { + const otherIsSelected = ($(event.target).find(":selected").val() === "other"); + + $(".field-cost_unit_other"). + css( + "display", + ( + (otherIsSelected) ? "block" : "none" ) ); + + if (!otherIsSelected) $(".field-cost_unit_other").val(""); } );