diff --git a/contracts/admin.py b/contracts/admin.py index c8346d4deb2e80750276341c50d4387b83b23b52..010bce2c1e3d41448f320aaf54c0e56449577974 100644 --- a/contracts/admin.py +++ b/contracts/admin.py @@ -2,7 +2,7 @@ from django.contrib import admin from shared.admin import MarkdownxGuardedModelAdmin -from .forms import ContractAdminForm, SigneeAdminForm +from .forms import ContractAdminForm, ContractFileAdminForm, SigneeAdminForm from .models import ( Contract, Contractee, @@ -27,6 +27,10 @@ class IndexHiddenModelAdmin(MarkdownxGuardedModelAdmin): # BEGIN Contracts +class ContractFileAdmin(IndexHiddenModelAdmin): + form = ContractFileAdminForm + + class ContracteeSignatureInline(admin.TabularInline): model = ContracteeSignature extra = 0 @@ -39,6 +43,7 @@ class SigneeSignatureInline(admin.TabularInline): class ContractFileInline(admin.TabularInline): model = ContractFile + form = ContractFileAdminForm extra = 0 @@ -155,6 +160,7 @@ class SigneeAdmin(MarkdownxGuardedModelAdmin): class ContracteeRepresentativeInline(admin.TabularInline): + form = ContractFileAdminForm model = ContracteeRepresentative extra = 0 @@ -176,6 +182,8 @@ for model in ( ): admin.site.register(model, IndexHiddenModelAdmin) +admin.site.register(ContractFile, ContractFileAdmin) + for model in ( ContractIssue, ContractFilingArea, diff --git a/contracts/forms.py b/contracts/forms.py index 5ed21fbfcbc1b79ba3219b33d10cf23f9fc21085..4c1fc92586bae01c09e00860d9e7530feb7969fb 100644 --- a/contracts/forms.py +++ b/contracts/forms.py @@ -23,6 +23,20 @@ class ContractAdminForm(forms.ModelForm): } +class ContractFileAdminForm(forms.ModelForm): + class Media: + js = ( + "shared/admin_contract_file_form.js", + ); + + class Meta: + widgets = { + "name": forms.TextInput(attrs={ + "list": "file-types" + }), + } + + class SigneeAdminForm(forms.ModelForm): class Media: js = ( diff --git a/contracts/models.py b/contracts/models.py index 08970ef9165bd96cb811d63b4460ac9d60107239..4e4b33d28cbdbf98690a4c09f0bb3ce59a7aa9da 100644 --- a/contracts/models.py +++ b/contracts/models.py @@ -33,9 +33,10 @@ class Signee(models.Model): ) class EntityTypes(models.TextChoices): - NATURAL_PERSON = "physical_person", "Fyzická osoba" + NATURAL_PERSON = "natural_person", "Fyzická osoba" LEGAL_ENTITY = "legal_entity", "Právnická osoba" BUSINESS_NATURAL_PERSON = "business_natural_person", "Podnikající fyzická osoba" + OTHER = "other", "Jiné" entity_type = models.CharField( max_length=23, @@ -484,6 +485,12 @@ class Contract(models.Model): permissions = (("approve", "Schválit / zrušit schválení"),) + def get_public_files(self): + return ContractFile.objects.filter( + contract=self, + is_public=True, + ).all() + def __str__(self) -> str: return self.name diff --git a/contracts/templates/contracts/includes/tag.html b/contracts/templates/contracts/includes/tag.html index 94012ee5632cee98e0c93a7c8130e35d10c42348..dd1de6c7b3d62f2b94987986d2bb79e86661487a 100644 --- a/contracts/templates/contracts/includes/tag.html +++ b/contracts/templates/contracts/includes/tag.html @@ -1,4 +1,4 @@ <a - class="p-1.5 rounded-sm text-ellipsis bg-gray-200 duration-100 hover:bg-gray-300 hover:no-underline" + class="p-1.5 rounded-sm text-ellipsis whitespace-nowrap bg-gray-200 duration-100 hover:bg-gray-300 hover:no-underline" href="{{ url }}" >{% if icon %}<i class="{{ icon }} mr-2"></i>{% endif %}{{ content }}</a> diff --git a/contracts/templates/contracts/index.html b/contracts/templates/contracts/index.html index 060643933cfcdbaefa00299a68366b5b729b1628..2e9390683650bc89b2e39924f6db26ea22ee246f 100644 --- a/contracts/templates/contracts/index.html +++ b/contracts/templates/contracts/index.html @@ -14,9 +14,9 @@ <td class="font-bold">Název</td> <td>Typy</td> <td>Platná</td> - <td>Účinná od</td> - <td>Účinná do</td> - <td>Podepsána s</td> + <td class="whitespace-nowrap">Účinná od</td> + <td class="whitespace-nowrap">Účinná do</td> + <td class="whitespace-nowrap">Podepsána s</td> </tr> </thead> <tbody> @@ -31,7 +31,9 @@ <td> <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"> + {% include "contracts/includes/tag.html" with url="#TODO" icon="ico--folder" content=type.name %} + </li> {% endfor %} </ul> </td> @@ -39,12 +41,22 @@ <i class="{% if contract.legal_state == contract.LegalStates.VALID %}ico--checkmark{% else %}ico--cross{% endif %}"></i> </td> <td class="whitespace-nowrap">{{ contract.valid_start_date }}</td> - <td class="whitespace-nowrap">{{ contract.valid_end_date }}</td> + <td class="whitespace-nowrap"> + {% if contract.valid_end_date %} + {{ contract.valid_end_date }} + {% else %} + <span class="text-grey-200">Neurčité</span> + {% endif %} + </td> <td> <ul class="flex flex-wrap gap-1.5"> {% for signature in contract.signee_signatures.all %} <li class="flex"> - {% include "contracts/includes/tag.html" with url="#TODO" content=signature.signee.name %} + {% if signature.signee.entity_type == signature.signee.EntityTypes.LEGAL_ENTITY or signature.signee.entity_type == signature.signee.EntityTypes.OTHER %} + {% include "contracts/includes/tag.html" with url="#TODO" icon="ico--office" content=signature.signee.name %} + {% else %} + {% include "contracts/includes/tag.html" with url="#TODO" icon="ico--user" content=signature.signee.name %} + {% endif %} </li> {% endfor %} </ul> diff --git a/contracts/templates/contracts/view_contract.html b/contracts/templates/contracts/view_contract.html index eb475dea3bcb73fbeda876f9e52e928359e4e7bf..52996e9adbebec8afdd0426d3d43a1ef550edcd7 100644 --- a/contracts/templates/contracts/view_contract.html +++ b/contracts/templates/contracts/view_contract.html @@ -2,7 +2,7 @@ {% load subtract %} {% block content %} - <h1 class="head-alt-lg mb-10">{{ contract.name }}</h1> + <h1 class="head-alt-lg mb-10"><i class="ico--file-blank mr-4"></i>{{ contract.name }}</h1> <table class="table table-auto w-full table--striped table--bordered mb-7"> <tbody> @@ -24,7 +24,7 @@ <ul class="flex flex-wrap gap-1.5"> {% for type in contract.types.all %} <li class="flex"> - {% include "contracts/includes/tag.html" with url="#TODO" content=type.name %} + {% include "contracts/includes/tag.html" with url="#TODO" icon="ico--folder" content=type.name %} </li> {% endfor %} </ul> @@ -51,7 +51,7 @@ <tr> <td class="w-1/5 !p-2.5">Soubory</td> <td class="w-4/5 !p-2.5"> - {% with contract.files.all as files %} + {% with contract.get_public_files as files %} {% if files|length != 0 %} <ul class="flex gap-2"> {% for file in files %} @@ -83,7 +83,13 @@ </tr> <tr> <td class="w-1/5 !p-2.5">Konec účinnosti</td> - <td class="w-4/5 !p-2.5">{{ contract.valid_end_date }}</td> + <td class="w-4/5 !p-2.5"> + {% if contract.valid_end_date %} + {{ contract.valid_end_date }} + {% else %} + <span class="text-grey-200">Neurčitý</span> + {% endif %} + </td> </tr> </tbody> </table> @@ -100,6 +106,21 @@ <td class="w-1/5 !p-2.5">Stav</td> <td class="w-4/5 !p-2.5">{{ contract.get_paper_form_state_display }}</td> </tr> + <tr> + <td class="w-1/5 !p-2.5">Spisovna</td> + <td class="w-4/5 !p-2.5"> + <div class="flex gap-3 items-center"> + <div class="flex"> + {% include "contracts/includes/tag.html" with url="#TODO" icon="ico--drawer" content=contract.filing_area.name %} + </div> + <span>|</span> + <span> + zodpovědná osoba + {{ contract.filing_area.person_responsible }} + </span> + </div> + </td> + </tr> </tbody> </table> @@ -214,14 +235,15 @@ {% with contract.contractee_signatures.all as signatures %} {% if signatures|length != 0 %} - <ul class="mb-5 grid grid-cols-3 gap-2"> + <ul class="mb-5 grid grid-cols-2 gap-2"> {% for signature in signatures %} <li class="p-3 border border-gray-300 rounded-md"> <address class="mb-3"> <div class="mb-1"> <a - class="inline-block p-1.5 mb-1 rounded-sm whitespace-nowrap cursor-pointer not-italic hover:no-underline bg-gray-200 duration-100 hover:bg-gray-300" + class="inline-block p-1.5 mb-1 rounded-sm cursor-pointer not-italic hover:no-underline bg-gray-200 duration-100 hover:bg-gray-300" > + <i class="ico--office mr-2"></i> <strong>{{ signature.contractee.name }}</strong> {% if signature.contractee.department %} - {{ signature.contractee.department }} @@ -266,14 +288,15 @@ {% with contract.signee_signatures.all as signatures %} {% if signatures|length != 0 %} - <ul class="mb-5 grid grid-cols-3 gap-2"> + <ul class="mb-5 grid grid-cols-2 gap-2"> {% for signature in signatures %} <li class="p-3 border border-gray-300 rounded-md"> <address class="mb-3"> <div class="mb-1"> <a - class="inline-block p-1.5 mb-1 rounded-sm whitespace-nowrap cursor-pointer not-italic hover:no-underline bg-gray-200 duration-100 hover:bg-gray-300" + class="inline-block p-1.5 mb-1 rounded-sm cursor-pointer not-italic hover:no-underline bg-gray-200 duration-100 hover:bg-gray-300" > + <i class="{% if signature.signee.entity_type == signature.signee.EntityTypes.LEGAL_ENTITY or signature.signee.entity_type == signature.signee.EntityTypes.OTHER %}ico--office{% else %}ico--user{% endif %} mr-2"></i> <strong>{{ signature.signee.name }}</strong> {% if signature.signee.department %} - {{ signature.signee.department }} diff --git a/static_src/admin/contract_file_form.js b/static_src/admin/contract_file_form.js new file mode 100644 index 0000000000000000000000000000000000000000..38f84779a4fa84d832f7e7d297507c70e1c48f06 --- /dev/null +++ b/static_src/admin/contract_file_form.js @@ -0,0 +1,12 @@ +import $ from "jquery"; + +$(window).ready( + () => { + $("body").append( + `<datalist id="file-types"> + <option value="Původní verze"> + <option value="Anonymizovaná verze"> +</datalist>` + ); + } +); diff --git a/static_src/admin/signee_form.js b/static_src/admin/signee_form.js index d03c7b527efc43d7b3e8a57826295de882e2c907..bb191380dd698752a20bdf7f5a274f403f152aa0 100644 --- a/static_src/admin/signee_form.js +++ b/static_src/admin/signee_form.js @@ -1,25 +1,70 @@ import $ from "jquery"; +const fieldDepartmentValues = new Set([ + "legal_entity", + "other", +]); + $(window).ready( () => { + let isPhysicalPerson = ($("#id_entity_type").find(":selected").val() === "natural_person"); + let isEmpty = ($("#id_entity_type").find(":selected").val() === ""); + $(".field-date_of_birth"). css( "display", ( - ($("#id_is_legal_entity").is(":checked")) ? - "none": "block" + (!isEmpty && isPhysicalPerson) ? + "block" : "none" + ) + ); + $(".field-ico_number"). + css( + "display", + ( + (!isEmpty && !isPhysicalPerson) ? + "block" : "none" + ) + ); + + $(".field-department"). + css( + "display", + ( + (!isEmpty && fieldDepartmentValues.has($("#id_entity_type").find(":selected").val())) ? + "block" : "none" ) ); - $("#id_is_legal_entity").on( + $("#id_entity_type").on( "change", event => { + isEmpty = ($(event.target).val() === ""); + isPhysicalPerson = ($(event.target).val() === "natural_person"); + $(".field-date_of_birth"). css( "display", ( - (event.target.checked) ? - "none" : "block" + (!isEmpty && isPhysicalPerson) ? + "block" : "none" + ) + ); + $(".field-ico_number"). + css( + "display", + ( + (!isEmpty && !isPhysicalPerson) ? + "block" : "none" + ) + ); + + $(".field-department"). + css( + "display", + ( + (!isEmpty && fieldDepartmentValues.has($(event.target).val())) ? + "block" : "none" ) ); } diff --git a/webpack.config.js b/webpack.config.js index ed6269a0038bbebde84fda4b50c1f3c26b47da46..36fbd6cb97829e5cdbdd6749db41042c79fc6279 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -13,6 +13,10 @@ module.exports = { import: path.resolve("static_src", "admin", "contract_form.js"), dependOn: "shared", }, + admin_contract_file_form: { + import: path.resolve("static_src", "admin", "contract_file_form.js"), + dependOn: "shared", + }, admin_signee_form: { import: path.resolve("static_src", "admin", "signee_form.js"), dependOn: "shared",