Skip to content
Snippets Groups Projects
Commit 6279e0ec authored by Tomáš Valenta's avatar Tomáš Valenta
Browse files

finish basic frontend filteirng, tag information, etc.

parent d6a27b78
No related branches found
No related tags found
No related merge requests found
Pipeline #11938 passed
Showing
with 1012 additions and 189 deletions
...@@ -106,6 +106,13 @@ class Signee(models.Model): ...@@ -106,6 +106,13 @@ class Signee(models.Model):
verbose_name = "Jiná smluvní strana" verbose_name = "Jiná smluvní strana"
verbose_name_plural = "Ostatní smluvní strany" verbose_name_plural = "Ostatní smluvní strany"
@property
def url(self) -> str:
return reverse(
"contracts:view_signee",
args=(self.id,)
)
@property @property
def entity_has_public_address(self) -> bool: def entity_has_public_address(self) -> bool:
return self.entity_type in ( return self.entity_type in (
...@@ -181,6 +188,13 @@ class Contractee(models.Model): ...@@ -181,6 +188,13 @@ class Contractee(models.Model):
verbose_name="Role", verbose_name="Role",
) )
@property
def url(self) -> str:
return reverse(
"contracts:view_contractee",
args=(self.id,)
)
class Meta: class Meta:
app_label = "contracts" app_label = "contracts"
...@@ -202,6 +216,13 @@ class ContractType(NameStrMixin, models.Model): ...@@ -202,6 +216,13 @@ class ContractType(NameStrMixin, models.Model):
verbose_name="Jméno", verbose_name="Jméno",
) )
@property
def url(self) -> str:
return reverse(
"contracts:view_contract_type",
args=(self.id,)
)
class Meta: class Meta:
app_label = "contracts" app_label = "contracts"
...@@ -215,6 +236,13 @@ class ContractIssue(NameStrMixin, models.Model): ...@@ -215,6 +236,13 @@ class ContractIssue(NameStrMixin, models.Model):
verbose_name="Jméno", verbose_name="Jméno",
) )
@property
def url(self) -> str:
return reverse(
"contracts:view_contract_issue",
args=(self.id,)
)
class Meta: class Meta:
app_label = "contracts" app_label = "contracts"
...@@ -233,6 +261,13 @@ class ContractFilingArea(NameStrMixin, models.Model): ...@@ -233,6 +261,13 @@ class ContractFilingArea(NameStrMixin, models.Model):
verbose_name="Odpovědná osoba", verbose_name="Odpovědná osoba",
) )
@property
def url(self) -> str:
return reverse(
"contracts:view_contract_filing_area",
args=(self.id,)
)
class Meta: class Meta:
app_label = "contracts" app_label = "contracts"
...@@ -276,8 +311,8 @@ class Contract(NameStrMixin, models.Model): ...@@ -276,8 +311,8 @@ class Contract(NameStrMixin, models.Model):
is_approved = models.BooleanField( is_approved = models.BooleanField(
verbose_name="Je schválená", verbose_name="Je schválená",
help_text=( help_text=(
"Může měnit jen schvalovatel. Pokud je smlouva " "Mohou měnit jen schvalovatelé. Pokud je "
"veřejná, schválením se vypustí ven." "smlouva veřejná, schválením se vypustí ven."
), ),
) )
...@@ -297,6 +332,7 @@ class Contract(NameStrMixin, models.Model): ...@@ -297,6 +332,7 @@ class Contract(NameStrMixin, models.Model):
types = models.ManyToManyField( types = models.ManyToManyField(
ContractType, ContractType,
related_name="contracts",
verbose_name="Typ", verbose_name="Typ",
) )
...@@ -341,6 +377,10 @@ class Contract(NameStrMixin, models.Model): ...@@ -341,6 +377,10 @@ class Contract(NameStrMixin, models.Model):
is_public = models.BooleanField( is_public = models.BooleanField(
verbose_name="Je veřejná", verbose_name="Je veřejná",
help_text=(
"Neveřejné smlouvy nejsou vidět bez přihlášení "
"jako min. tajný čtenář."
)
) )
paper_form_state = models.CharField( paper_form_state = models.CharField(
...@@ -374,6 +414,7 @@ class Contract(NameStrMixin, models.Model): ...@@ -374,6 +414,7 @@ class Contract(NameStrMixin, models.Model):
issues = models.ManyToManyField( issues = models.ManyToManyField(
ContractIssue, ContractIssue,
blank=True, blank=True,
related_name="contracts",
verbose_name="Problémy", verbose_name="Problémy",
help_text='Veřejně nazváno "Poznámky".', help_text='Veřejně nazváno "Poznámky".',
) )
...@@ -403,7 +444,7 @@ class Contract(NameStrMixin, models.Model): ...@@ -403,7 +444,7 @@ class Contract(NameStrMixin, models.Model):
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
blank=True, blank=True,
null=True, null=True,
related_name="filed_contracts", related_name="contracts",
verbose_name="Spisovna", verbose_name="Spisovna",
help_text="Obsah není veřejně přístupný.", help_text="Obsah není veřejně přístupný.",
) )
...@@ -446,6 +487,13 @@ class Contract(NameStrMixin, models.Model): ...@@ -446,6 +487,13 @@ class Contract(NameStrMixin, models.Model):
args=(self.primary_contract.id,), args=(self.primary_contract.id,),
) )
@property
def url(self) -> str:
return reverse(
"contracts:view_contract",
args=(self.id,),
)
def get_public_files(self): def get_public_files(self):
return ContractFile.objects.filter( return ContractFile.objects.filter(
contract=self, contract=self,
......
<table class="table table-auto w-full table--striped table--bordered">
<thead>
<tr>
<td class="font-bold">Název</td>
<td>Typy</td>
<td>Platná</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>
{% for contract in page %}
<tr>
<td>
{% if user.can_view_confidential and not contract.is_public %}
{% include "contracts/includes/private_info_icon.html" %}
{% endif %}
<a
class="underline"
href="{% url "contracts:view_contract" contract.id %}"
>{{ contract.name }}</a>
</td>
<td>
<ul class="flex flex-wrap gap-1.5">
{% for type in contract.types.all %}
<li class="flex">
{% include "contracts/includes/tag.html" with url=type.url icon="ico--folder" content=type.name %}
</li>
{% endfor %}
</ul>
</td>
<td>
<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">
{% 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">
{% 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=signature.signee.url icon="ico--office" content=signature.signee.name %}
{% else %}
{% include "contracts/includes/tag.html" with url=signature.signee.url icon="ico--user" content=signature.signee.name %}
{% endif %}
</li>
{% endfor %}
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include "contracts/includes/pagination.html" with paginator=paginator page=page %}
{% load subtract %}
{% if page.has_other_pages %}
<div class="pagination-container">
<nav class="pagination space-x-1">
<a
class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed btn--inverted-icon"
{% if not page.has_previous %}disabled{% endif %}
{% if page.has_previous %}href="{{ request.path }}?page={{ page.previous_page_number }}"{% endif %}
>
<div class="btn__body-wrap">
<div class="btn__body">Předchozí</div>
<div class="btn__icon">
<i class="ico--chevron-left"></i>
</div>
</div>
</a>
{% if page.previous_page_number != 1 %}
<a
class="btn btn--grey-125 btn--hoveractive btn--to-black btn--condensed hidden md:inline-block"
href="{{ request.path }}?page=1"
>
<div class="btn__body">1</div>
</a>
{% endif %}
{% if page.has_previous and page.previous_page_number != 2 %}
<span class="text-grey-500 hidden md:flex flex-col px-2 justify-center">...</span>
{% endif %}
{% if page.has_previous %}
<a
class="btn btn--grey-125 btn--hoveractive btn--to-black btn--condensed hidden md:inline-block"
href="{{ request.path }}?page={{ page.previous_page_number }}"
>
<div class="btn__body ">{{ page.previous_page_number }}</div>
</a>
{% endif %}
<button class="btn btn--grey-500 btn--condensed hidden md:inline-block">
<div class="btn__body">{{ page.number }}</div>
</button>
{% if page.has_next %}
<a
class="btn btn--grey-125 btn--hoveractive btn--to-black btn--condensed hidden md:inline-block"
href="{{ request.path }}?page={{ page.next_page_number }}"
>
<div class="btn__body ">{{ page.next_page_number }}</div>
</a>
{% endif %}
{% if paginator.num_pages != page.next_page_number and paginator.num_pages|subtract:1 != page.next_page_number %}
<span class="text-grey-500 hidden md:flex flex-col px-2 justify-center">...</span>
{% endif %}
{% comment %}num_pages is equivalent to the last page number{% endcomment %}
{% if paginator.num_pages != page.next_page_number %}
<a
role="button"
class="btn btn--grey-125 btn--hoveractive btn--to-black btn--condensed hidden md:inline-block"
href="{{ request.path }}?page={{ paginator.num_pages }}"
>
<div class="btn__body">{{ paginator.num_pages }}</div>
</a>
{% endif %}
<a
class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed"
{% if not page.has_next %}disabled{% endif %}
{% if page.has_next %}href="{{ request.path }}?page={{ page.next_page_number }}"{% endif %}
>
<div class="btn__body-wrap">
<div class="btn__body">Další</div>
<div class="btn__icon">
<i class="ico--chevron-right"></i>
</div>
</div>
</a>
</nav>
</div>
{% endif %}
<i
class="ico--eye-off text-red-600 mr-2 __tooltipped"
aria-label="Neveřejný údaj"
></i>
{% extends "shared/includes/base.html" %} {% extends "shared/includes/base.html" %}
{% load subtract %}
{% block content %} {% block content %}
<div class="prose max-w-none mb-10"> <div class="prose max-w-none mb-10">
...@@ -8,144 +7,48 @@ ...@@ -8,144 +7,48 @@
Temporibus <i>voluptatum commodi delectus est</i>. Commodi et voluptatem dolor odit occaecati dolore aut. Qui dolor nihil excepturi id. Qui deleniti <i>cupiditate voluptatem aut</i> est dolores eum aliquid. Molestiae blanditiis reiciendis odio provident ipsam voluptas enim suscipit. Temporibus <i>voluptatum commodi delectus est</i>. Commodi et voluptatem dolor odit occaecati dolore aut. Qui dolor nihil excepturi id. Qui deleniti <i>cupiditate voluptatem aut</i> est dolores eum aliquid. Molestiae blanditiis reiciendis odio provident ipsam voluptas enim suscipit.
</p> </p>
</div> </div>
<table class="table table-auto w-full table--striped table--bordered">
<thead>
<tr>
<td class="font-bold">Název</td>
<td>Typy</td>
<td>Platná</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>
{% for contract in page %}
<tr>
<td>
<a
class="underline"
href="{% url "contracts:view_contract" contract.id %}"
>{{ contract.name }}</a>
</td>
<td>
<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" icon="ico--folder" content=type.name %}
</li>
{% endfor %}
</ul>
</td>
<td>
<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">
{% 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">
{% 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>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if page.has_other_pages %}
<div class="pagination-container">
<nav class="pagination space-x-1">
<a
class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed btn--inverted-icon"
{% if not page.has_previous %}disabled{% endif %}
{% if page.has_previous %}href="{% url "contracts:index" %}?page={{ page.previous_page_number }}"{% endif %}
>
<div class="btn__body-wrap">
<div class="btn__body">Předchozí</div>
<div class="btn__icon">
<i class="ico--chevron-left"></i>
</div>
</div>
</a>
{% if page.previous_page_number != 1 %} <div class="flex gap-6 mb-5 text-lg">
<a <a
class="btn btn--grey-125 btn--hoveractive btn--to-black btn--condensed hidden md:inline-block" class="flex gap-2 items-baseline hover:no-underline"
href="{% url "contracts:index" %}?page=1" href="{% url "contracts:view_contract_filing_areas" %}"
> >
<div class="btn__body">1</div> <i class="ico--drawer"></i>
<span class="underline">Spisovny</span>
</a> </a>
{% endif %}
{% if page.has_previous and page.previous_page_number != 2 %}
<span class="text-grey-500 hidden md:flex flex-col px-2 justify-center">...</span>
{% endif %}
{% if page.has_previous %}
<a <a
class="btn btn--grey-125 btn--hoveractive btn--to-black btn--condensed hidden md:inline-block" class="flex gap-2 items-baseline hover:no-underline"
href="{% url "contracts:index" %}?page={{ page.previous_page_number }}" href="{% url "contracts:view_contract_issues" %}"
> >
<div class="btn__body ">{{ page.previous_page_number }}</div> <i class="ico--warning"></i>
<span class="underline">{% if not user.can_view_confidential %}Poznámky{% else %}Problémy{% endif %}</span>
</a> </a>
{% endif %}
<button class="btn btn--grey-500 btn--condensed hidden md:inline-block">
<div class="btn__body">{{ page.number }}</div>
</button>
{% if page.has_next %}
<a <a
class="btn btn--grey-125 btn--hoveractive btn--to-black btn--condensed hidden md:inline-block" class="flex gap-2 items-baseline hover:no-underline"
href="{% url "contracts:index" %}?page={{ page.next_page_number }}" href="{% url "contracts:view_contract_types" %}"
> >
<div class="btn__body ">{{ page.next_page_number }}</div> <i class="ico--folder"></i>
<span class="underline">Typy</span>
</a> </a>
{% endif %}
{% if paginator.num_pages != page.next_page_number and paginator.num_pages|subtract:1 != page.next_page_number %}
<span class="text-grey-500 hidden md:flex flex-col px-2 justify-center">...</span>
{% endif %}
{% comment %}num_pages is equivalent to the last page number{% endcomment %}
{% if paginator.num_pages != page.next_page_number %}
<a <a
role="button" class="flex gap-2 items-baseline hover:no-underline"
class="btn btn--grey-125 btn--hoveractive btn--to-black btn--condensed hidden md:inline-block" href="{% url "contracts:view_contractees" %}"
href="{% url "contracts:index" %}?page={{ paginator.num_pages }}"
> >
<div class="btn__body">{{ paginator.num_pages }}</div> <i class="ico--office"></i>
<span class="underline">Naše smluvní strany</span>
</a> </a>
{% endif %}
<a <a
class="btn btn--icon btn--grey-125 btn--hoveractive btn--to-black btn--condensed" class="flex gap-2 items-baseline hover:no-underline"
{% if not page.has_next %}disabled{% endif %} href="{% url "contracts:view_signees" %}"
{% if page.has_next %}href="{% url "contracts:index" %}?page={{ page.next_page_number }}"{% endif %}
> >
<div class="btn__body-wrap"> <i class="ico--office"></i>
<div class="btn__body">Další</div> <span class="underline">Jiné smluvní strany</span>
<div class="btn__icon">
<i class="ico--chevron-right"></i>
</div>
</div>
</a> </a>
</nav>
</div> </div>
{% endif %}
{% include "contracts/includes/contract_list.html" with page=page paginator=paginator %}
{% endblock %} {% endblock %}
...@@ -2,9 +2,13 @@ ...@@ -2,9 +2,13 @@
{% load subtract markdownify %} {% load subtract markdownify %}
{% block content %} {% block content %}
<h1 class="head-alt-lg mb-10"> <div class="flex gap-4 mb-10">
<i class="ico--file-blank mr-4"></i>{{ contract.name }} <i class="ico--file-blank text-7xl"></i>
</h1> <div>
<h1 class="head-alt-lg">{{ contract.name }}</h1>
<h2 class="head-alt-sm">Smlouva</h2>
</div>
</div>
<table class="table table-auto w-full table--striped table--bordered mb-7"> <table class="table table-auto w-full table--striped table--bordered mb-7">
<tbody> <tbody>
...@@ -25,25 +29,45 @@ ...@@ -25,25 +29,45 @@
<td class="w-4/5 !pl-2.5 !py-1 !pr-1"> <td class="w-4/5 !pl-2.5 !py-1 !pr-1">
<ul class="flex flex-wrap gap-1.5"> <ul class="flex flex-wrap gap-1.5">
{% for type in contract.types.all %} {% for type in contract.types.all %}
<li class="flex"> <li>
{% include "contracts/includes/tag.html" with url="#TODO" icon="ico--folder" content=type.name %} {% include "contracts/includes/tag.html" with url=type.url icon="ico--folder" content=type.name %}
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
</td> </td>
</tr> </tr>
{% if contract.primary_contract %} {% if contract.primary_contract %}
<tr> <tr>
<td class="w-1/5 !p-2.5">Primární smlouva</td> <td class="w-1/5 !p-2.5">Nadřazená smlouva</td>
<td class="w-4/5 !p-2.5"> <td class="w-4/5 !pl-2.5 !py-1 !pr-1">
{% include "contracts/includes/tag.html" with url=contract.primary_contract_url icon="ico--file-blank" content=contract.primary_contract.name %} {% include "contracts/includes/tag.html" with url=contract.primary_contract_url icon="ico--file-blank" content=contract.primary_contract.name %}
</td> </td>
</tr> </tr>
{% endif %} {% endif %}
{% with contract.subcontracts.all as subcontracts %}
{% if subcontracts %}
<tr>
<td class="w-1/5 !p-2.5">Podřazené smlouvy</td>
<td class="w-4/5 !pl-2.5 !py-1 !pr-1">
<ul class="flex gap-1.5">
{% for subcontract in subcontracts %}
<li>
{% include "contracts/includes/tag.html" with url=subcontract.url icon="ico--file-blank" content=subcontract.name %}
</li>
{% endfor %}
</ul>
</td>
</tr>
{% endif %}
{% endwith %}
<tr> <tr>
<td class="w-1/5 !p-2.5">Souhrn</td> <td class="w-1/5 !p-2.5">Souhrn</td>
<td class="w-4/5 !p-2.5">{{ contract.summary }}</td> <td class="w-4/5 !p-2.5">{{ contract.summary }}</td>
</tr> </tr>
{% if user.can_view_confidential %} {% if user.can_view_confidential %}
<tr> <tr>
<td class="w-1/5 !p-2.5">Je veřejná</td> <td class="w-1/5 !p-2.5">Je veřejná</td>
...@@ -100,10 +124,7 @@ ...@@ -100,10 +124,7 @@
<tr> <tr>
<td class="w-1/5 !p-2.5"> <td class="w-1/5 !p-2.5">
<div class="flex items-center"> <div class="flex items-center">
<i {% include "contracts/includes/private_info_icon.html" %}
class="ico--eye-off text-red-600 mr-2 __tooltipped"
aria-label="Neveřejný údaj"
></i>
Neveřejné soubory Neveřejné soubory
</div> </div>
</td> </td>
...@@ -144,7 +165,7 @@ ...@@ -144,7 +165,7 @@
<td class="w-1/5 !p-2.5">Spisovna</td> <td class="w-1/5 !p-2.5">Spisovna</td>
<td class="w-4/5 !pl-2.5 !py-1 !pr-1"> <td class="w-4/5 !pl-2.5 !py-1 !pr-1">
<div class="flex gap-3 items-center"> <div class="flex gap-3 items-center">
{% include "contracts/includes/tag.html" with url="#TODO" icon="ico--drawer" content=contract.filing_area.name %} {% include "contracts/includes/tag.html" with url=contract.filing_area.url icon="ico--drawer" content=contract.filing_area.name %}
</div> </div>
</td> </td>
</tr> </tr>
...@@ -233,7 +254,7 @@ ...@@ -233,7 +254,7 @@
</table> </table>
{% with contract.issues.all as issues %} {% with contract.issues.all as issues %}
{% if issues|length != 0 %} {% if issues or user.can_view_confidential and contract.notes %}
<table class="table table-auto w-full table--striped table--bordered mb-10"> <table class="table table-auto w-full table--striped table--bordered mb-10">
<tbody> <tbody>
<tr> <tr>
...@@ -242,31 +263,30 @@ ...@@ -242,31 +263,30 @@
</td> </td>
</tr> </tr>
{% if issues %}
<tr> <tr>
<td class="w-1/5 !p-2.5">{% if not user.can_view_confidential %}Poznámky{% else %}Problémy{% endif %}</td> <td class="w-1/5 !p-2.5">{% if not user.can_view_confidential %}Poznámky{% else %}Problémy{% endif %}</td>
<td class="w-4/5 !pl-2.5 !py-1 !pr-1"> <td class="w-4/5 !pl-2.5 !py-1 !pr-1">
<ul class="flex gap-2"> <ul class="flex gap-2">
{% for issue in issues %} {% for issue in issues %}
<li> <li>
{% include "contracts/includes/tag.html" with url="#TODO" icon="ico--warning" content=issue.name %} {% include "contracts/includes/tag.html" with url=issue.url icon="ico--warning" content=issue.name %}
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
</td> </td>
</tr> </tr>
{% endif %}
{% if user.can_view_confidential and contract.notes %} {% if user.can_view_confidential and contract.notes %}
<tr> <tr>
<td class="w-1/5 !p-2.5"> <td class="w-1/5 !p-2.5">
<div class="flex items-center"> <div class="flex items-center">
<i {% include "contracts/includes/private_info_icon.html" %}
class="ico--eye-off text-red-600 mr-2 __tooltipped"
aria-label="Neveřejný údaj"
></i>
Interní poznámky Interní poznámky
</div> </div>
</td> </td>
<td class="w-4/5 !p-2.5"> <td class="w-4/5 !p-1.5">
<div class="prose max-w-none"> <div class="prose max-w-none">
{{ contract.notes|markdownify|safe }} {{ contract.notes|markdownify|safe }}
</div> </div>
...@@ -299,6 +319,7 @@ ...@@ -299,6 +319,7 @@
<div class="mb-1"> <div class="mb-1">
<a <a
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" 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"
href="{{ signature.contractee.url }}"
> >
<i class="ico--office mr-2"></i> <i class="ico--office mr-2"></i>
<strong>{{ signature.contractee.name }}</strong> <strong>{{ signature.contractee.name }}</strong>
...@@ -357,6 +378,7 @@ ...@@ -357,6 +378,7 @@
<div class="mb-1"> <div class="mb-1">
<a <a
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" 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"
href="{{ signature.signee.url }}"
> >
<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> <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> <strong>{{ signature.signee.name }}</strong>
...@@ -375,10 +397,7 @@ ...@@ -375,10 +397,7 @@
{% if not signature.signee.entity_has_public_address %} {% if not signature.signee.entity_has_public_address %}
{% if user.can_view_confidential %} {% if user.can_view_confidential %}
<div class="my-2 flex items-center"> <div class="my-2 flex items-center">
<i {% include "contracts/includes/private_info_icon.html" %}<span class="text-gray-500">Máš přístup k celé adrese.</span>
class="ico--eye-off text-red-600 mr-2 __tooltipped"
aria-label="Neveřejný údaj"
></i><span class="text-gray-500">Máš přístup k celé adrese.</span>
</div> </div>
{% else %} {% else %}
<span class="text-gray-500">(zobrazujeme pouze obec)</span> <span class="text-gray-500">(zobrazujeme pouze obec)</span>
......
{% extends "shared/includes/base.html" %}
{% block content %}
<div class="flex gap-4 mb-10">
<i class="ico--drawer text-7xl"></i>
<div>
<h1 class="head-alt-lg">{{ filing_area.name }}</h1>
<h2 class="head-alt-sm">Fyzická spisovna</h2>
</div>
</div>
<h2 class="text-lg font-bold mb-10">
Smlouvy ve spisovně
</h2>
{% include "contracts/includes/contract_list.html" with page=contracts_page paginator=contracts_paginator %}
{% endblock %}
{% extends "shared/includes/base.html" %}
{% block content %}
<div class="flex gap-4 mb-10">
<i class="ico--drawer text-7xl"></i>
<div>
<h1 class="head-alt-lg">Spisovny</h1>
<h2 class="head-alt-sm">Fyzická úložiště smluv</h2>
</div>
</div>
<table class="table table-auto w-full table--striped table--bordered">
<thead>
<tr>
<td class="font-bold">Název</td>
<td>Odpovědná osoba</td>
<td>Počet smluv</td>
</tr>
</thead>
<tbody>
{% for filing_area in page %}
<tr>
<td>
<a
href="{{ filing_area.url }}"
>{{ filing_area.name }}</a>
</td>
<td>
{{ filing_area.person_responsible }}
</td>
<td>
{{ filing_area.contracts.count }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include "contracts/includes/pagination.html" with paginator=paginator page=page %}
{% endblock %}
{% extends "shared/includes/base.html" %}
{% block content %}
<div class="flex gap-4 mb-10">
<i class="ico--warning text-7xl"></i>
<div>
<h1 class="head-alt-lg">{{ issue.name }}</h1>
<h2 class="head-alt-sm">
{% if not user.can_view_confidential %}Poznámka{% else %}Problém{% endif %}
</h2>
</div>
</div>
<h2 class="text-lg font-bold mb-10">
Smlouvy s {% if not user.can_view_confidential %}poznámkou{% else %}problémem{% endif %}
</h2>
{% include "contracts/includes/contract_list.html" with page=contracts_page paginator=contracts_paginator %}
{% endblock %}
{% extends "shared/includes/base.html" %}
{% block content %}
<div class="flex gap-4 mb-10">
<i class="ico--warning text-7xl"></i>
<div>
<h1 class="head-alt-lg">
{% if not user.can_view_confidential %}
Poznámky
{% else %}
Problémy
{% endif %}
</h1>
<h2 class="head-alt-sm">
{% if not user.can_view_confidential %}
ke smlouvám
{% else %}
se smlouvami
{% endif %}
</h2>
</div>
</div>
<table class="table table-auto w-full table--striped table--bordered">
<thead>
<tr>
<td class="font-bold">Název</td>
<td>Počet smluv</td>
</tr>
</thead>
<tbody>
{% for issue in page %}
<tr>
<td>
<a
href="{{ issue.url }}"
>{{ issue.name }}</a>
</td>
<td>
{{ issue.contracts.count }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include "contracts/includes/pagination.html" with paginator=paginator page=page %}
{% endblock %}
{% extends "shared/includes/base.html" %}
{% block content %}
<div class="flex gap-4 mb-10">
<i class="ico--folder text-7xl"></i>
<div>
<h1 class="head-alt-lg">{{ type.name }}</h1>
<h2 class="head-alt-sm">Typ smluv</h2>
</div>
</div>
<h2 class="text-lg font-bold mb-10">
Smlouvy zadaného typu
</h2>
{% include "contracts/includes/contract_list.html" with page=contracts_page paginator=contracts_paginator %}
{% endblock %}
{% extends "shared/includes/base.html" %}
{% block content %}
<div class="flex gap-4 mb-10">
<i class="ico--folder text-7xl"></i>
<div>
<h1 class="head-alt-lg">Typy</h1>
<h2 class="head-alt-sm">smluv</h2>
</div>
</div>
<table class="table table-auto w-full table--striped table--bordered">
<thead>
<tr>
<td class="font-bold">Název</td>
<td>Počet smluv</td>
</tr>
</thead>
<tbody>
{% for type in page %}
<tr>
<td>
<a
href="{{ type.url }}"
>{{ type.name }}</a>
</td>
<td>
{{ type.contracts.count }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include "contracts/includes/pagination.html" with paginator=paginator page=page %}
{% endblock %}
{% extends "shared/includes/base.html" %}
{% block content %}
<div class="flex gap-4 mb-10">
<i class="ico--office text-7xl"></i>
<div>
<h1 class="head-alt-lg">
{{ contractee.name }}{% if contractee.department %}, {{ contractee.department }}{% endif %}
</h1>
<h2 class="head-alt-sm">Naše smluvní strana</h2>
</div>
</div>
<address class="mb-8">
<div>
<strong>{{ contractee.name }}</strong>
{% if contractee.department %}
- {{ contractee.department }}
{% endif %}
{% if contractee.role %}
({{ contractee.role }})
{% endif %}
</div><br>
{{ contractee.address_street_with_number }}<br>
{{ contractee.address_zip }} {{ contractee.address_district }}<br>
{{ contractee.get_address_country_display }}<br>
{% if contractee.ico_number %}
IČO: {{ contractee.ico_number }}<br>
{% endif %}
</address>
<h2 class="text-lg font-bold mb-10">
Smlouvy podepsané touto stranou
</h2>
{% include "contracts/includes/contract_list.html" with page=contracts_page paginator=contracts_paginator %}
{% endblock %}
{% extends "shared/includes/base.html" %}
{% block content %}
<div class="flex gap-4 mb-10">
<i class="ico--office text-7xl"></i>
<div>
<h1 class="head-alt-lg">Smluvní strany</h1>
<h2 class="head-alt-sm">naše</h2>
</div>
</div>
<table class="table table-auto w-full table--striped table--bordered">
<thead>
<tr>
<td class="font-bold">Název</td>
<td>Počet podpisů</td>
</tr>
</thead>
<tbody>
{% for contractee in page %}
<tr>
<td>
<a
href="{{ contractee.url }}"
>
<strong>{{ contractee.name }}</strong>
{% if contractee.department %}
- {{ contractee.department }}
{% endif %}
{% if contractee.role %}
({{ contractee.role }})
{% endif %}
</a>
</td>
<td>
{{ contractee.signatures.count }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include "contracts/includes/pagination.html" with paginator=paginator page=page %}
{% endblock %}
{% extends "shared/includes/base.html" %}
{% block content %}
<div class="flex gap-4 mb-10">
<i class="{% if signee.entity_type == signee.EntityTypes.LEGAL_ENTITY or signee.entity_type == signee.EntityTypes.OTHER %}ico--office{% else %}ico--user{% endif %} text-7xl"></i>
<div>
<h1 class="head-alt-lg">
{{ signee.name }}{% if signee.department %}, {{ signee.department }}{% endif %}
</h1>
<h2 class="head-alt-sm">Jiná smluvní strana</h2>
</div>
</div>
<address class="mb-8">
<div class="mb-1">
<strong>{{ signee.name }}</strong>
{% if signee.department %}
- {{ signee.department }}
{% endif %}
{% if signee.role %}
({{ signee.role }})
{% endif %}
</div>
<div class="mb-1">
{{ signee.get_entity_type_display }}
{% if not signee.entity_has_public_address %}
{% if user.can_view_confidential %}
<div class="my-2 flex items-center">
{% include "contracts/includes/private_info_icon.html" %}
<span class="text-gray-500">Máš přístup k celé adrese.</span>
</div>
{% else %}
<span class="text-gray-500">(zobrazujeme pouze obec)</span>
{% endif %}
{% endif %}
</div>
{% 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>
{% else %}
{{ signee.address_district }}<br>
{% endif %}
{% if signee.ico_number %}
IČO: {{ signee.ico_number }}<br>
{% endif %}
</address>
<h2 class="text-lg font-bold mb-10">
Smlouvy podepsané touto stranou
</h2>
{% include "contracts/includes/contract_list.html" with page=contracts_page paginator=contracts_paginator %}
{% endblock %}
{% extends "shared/includes/base.html" %}
{% block content %}
<div class="flex gap-4 mb-10">
<i class="ico--office text-7xl"></i>
<div>
<h1 class="head-alt-lg">Smluvní strany</h1>
<h2 class="head-alt-sm">ostatní</h2>
</div>
</div>
<table class="table table-auto w-full table--striped table--bordered">
<thead>
<tr>
<td class="font-bold">Název</td>
<td>Počet podpisů</td>
</tr>
</thead>
<tbody>
{% for signee in page %}
<tr>
<td>
<a
href="{{ signee.url }}"
>
<strong>{{ signee.name }}</strong>
{% if signee.department %}
- {{ signee.department }}
{% endif %}
{% if signee.role %}
({{ signee.role }})
{% endif %}
</a>
</td>
<td>
{{ signee.signatures.count }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include "contracts/includes/pagination.html" with paginator=paginator page=page %}
{% endblock %}
...@@ -8,11 +8,67 @@ app_name = "contracts" ...@@ -8,11 +8,67 @@ app_name = "contracts"
urlpatterns = [ urlpatterns = [
path("", views.index, name="index"), path("", views.index, name="index"),
path("contracts/<int:id>", views.view_contract, name="view_contract"), path("contracts/<int:id>", views.view_contract, name="view_contract"),
path(
"contracts/filing-areas/<int:id>",
views.view_contract_filing_area,
name="view_contract_filing_area"
),
path(
"contracts/issues/<int:id>",
views.view_contract_issue,
name="view_contract_issue"
),
path(
"contracts/types/<int:id>",
views.view_contract_type,
name="view_contract_type"
),
path(
"contracts/filing-areas",
views.view_contract_filing_areas,
name="view_contract_filing_areas"
),
path(
"contracts/issues",
views.view_contract_issues,
name="view_contract_issues"
),
path(
"contracts/types",
views.view_contract_types,
name="view_contract_types"
),
path( path(
"contracts/files/<str:pk>", "contracts/files/<str:pk>",
views.ContractFileDownloadView.as_view(), views.ContractFileDownloadView.as_view(),
name="download_contract_file", name="download_contract_file",
), ),
path(
"contractees",
views.view_contractees,
name="view_contractees"
),
path(
"signee",
views.view_signees,
name="view_signees"
),
path(
"contractees/<int:id>",
views.view_contractee,
name="view_contractee"
),
path(
"signee/<int:id>",
views.view_signee,
name="view_signee"
),
path( path(
"contracts/autocomplete", "contracts/autocomplete",
dal.autocomplete.Select2QuerySetView.as_view(model=models.Contract), dal.autocomplete.Select2QuerySetView.as_view(model=models.Contract),
......
...@@ -26,11 +26,26 @@ class ContractFileDownloadView(ObjectDownloadView): ...@@ -26,11 +26,26 @@ class ContractFileDownloadView(ObjectDownloadView):
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def index(request): def get_base_context(request) -> dict:
filter = { return {
"is_approved": True "site_url": settings.SITE_URL,
"user": request.user,
} }
def get_pagination(request, objects) -> tuple:
paginator = Paginator(objects, 25)
page = paginator.get_page(
request.GET.get("page")
)
return page, paginator
def get_paginated_contracts(request, filter: dict = {}) -> tuple:
filter["is_approved"] = True
if not request.user.has_perm("contracts.view_confidential"): if not request.user.has_perm("contracts.view_confidential"):
filter["is_public"] = True filter["is_public"] = True
...@@ -40,20 +55,24 @@ def index(request): ...@@ -40,20 +55,24 @@ def index(request):
.order_by("valid_start_date") .order_by("valid_start_date")
.all() .all()
) )
paginator = Paginator(contracts, 25)
page = paginator.get_page(request.GET.get("page")) page, paginator = get_pagination(request, contracts)
return page, paginator
def index(request):
page, paginator = get_paginated_contracts(request)
return render( return render(
request, request,
"contracts/index.html", "contracts/index.html",
{ {
"site_url": settings.SITE_URL, **get_base_context(request),
"user": request.user,
"title": "Seznam smluv", "title": "Seznam smluv",
"description": "Description", "description": "Description",
"paginator": paginator,
"page": page, "page": page,
"paginator": paginator,
}, },
) )
...@@ -76,10 +95,276 @@ def view_contract(request, id: int): ...@@ -76,10 +95,276 @@ def view_contract(request, id: int):
request, request,
"contracts/view_contract.html", "contracts/view_contract.html",
{ {
"site_url": settings.SITE_URL, **get_base_context(request),
"user": request.user,
"title": contract.name, "title": contract.name,
"description": contract.summary, "description": contract.summary,
"contract": contract, "contract": contract,
}, },
) )
# BEGIN Filtered contract + submodel views
def view_contract_filing_area(request, id: int):
filing_area = (
get_objects_for_user(request.user, "contracts.view_contractfilingarea")
.get(id=id)
)
contracts_page, contracts_paginator = get_paginated_contracts(
request,
{"filing_area": filing_area}
)
return render(
request,
"contracts/view_contract_filing_area.html",
{
**get_base_context(request),
"title": filing_area.name,
"description": (
f"Spisovna smluv - {filing_area.name}, "
f"zodpovědná osoba {filing_area.person_responsible}"
),
"filing_area": filing_area,
"contracts_page": contracts_page,
"contracts_paginator": contracts_paginator,
},
)
def view_contract_issue(request, id: int):
issue = (
get_objects_for_user(request.user, "contracts.view_contractissue")
.get(id=id)
)
contracts_page, contracts_paginator = get_paginated_contracts(
request,
{"issues": issue}
)
return render(
request,
"contracts/view_contract_issue.html",
{
**get_base_context(request),
"title": issue.name,
"description": f"Problém se smlouvami - {issue.name}",
"issue": issue,
"contracts_page": contracts_page,
"contracts_paginator": contracts_paginator,
},
)
def view_contract_type(request, id: int):
type_ = (
get_objects_for_user(request.user, "contracts.view_contracttype")
.get(id=id)
)
contracts_page, contracts_paginator = get_paginated_contracts(
request,
{"types": type_}
)
return render(
request,
"contracts/view_contract_type.html",
{
**get_base_context(request),
"title": type_.name,
"description": f"Typ smluv - {type_.name}",
"type": type_,
"contracts_page": contracts_page,
"contracts_paginator": contracts_paginator,
},
)
def view_contractee(request, id: int):
contractee = (
get_objects_for_user(request.user, "contracts.view_contractee")
.get(id=id)
)
contracts_page, contracts_paginator = get_paginated_contracts(
request,
{"contractee_signatures__contractee": contractee}
)
return render(
request,
"contracts/view_contractee.html",
{
**get_base_context(request),
"title": contractee.name,
"description": f"Naše smluvní strana - {contractee.name}",
"contractee": contractee,
"contracts_page": contracts_page,
"contracts_paginator": contracts_paginator,
},
)
def view_signee(request, id: int):
signee = (
get_objects_for_user(request.user, "contracts.view_signee")
.get(id=id)
)
contracts_page, contracts_paginator = get_paginated_contracts(
request,
{"signee_signatures__signee": signee}
)
return render(
request,
"contracts/view_signee.html",
{
**get_base_context(request),
"title": signee.name,
"description": f"Jiná smluvní strana - {signee.name}",
"signee": signee,
"contracts_page": contracts_page,
"contracts_paginator": contracts_paginator,
},
)
# END Filtered contract + submodel views
# BEGIN Submodel listing views
def view_contract_filing_areas(request):
filing_areas = (
get_objects_for_user(
request.user,
"contracts.view_contractfilingarea",
).
order_by("name")
)
page, paginator = get_pagination(request, filing_areas)
return render(
request,
"contracts/view_contract_filing_areas.html",
{
**get_base_context(request),
"title": "Spisovny",
"description": "Seznam fyzických spisoven, kde jsou ukládány smlouvy.",
"page": page,
"paginator": paginator,
}
)
def view_contract_issues(request):
issues = (
get_objects_for_user(
request.user,
"contracts.view_contractissue",
).
order_by("name")
)
page, paginator = get_pagination(request, issues)
return render(
request,
"contracts/view_contract_issues.html",
{
**get_base_context(request),
"title": (
"Poznámky"
if not request.user.can_view_confidential
else "Problémy"
),
"description": (
"Poznámky ke smlouvám."
if not request.user.can_view_confidential
else "Problémy se smlouvami."
),
"page": page,
"paginator": paginator,
}
)
def view_contract_types(request):
types = (
get_objects_for_user(
request.user,
"contracts.view_contracttype",
).
order_by("name")
)
page, paginator = get_pagination(request, types)
return render(
request,
"contracts/view_contract_types.html",
{
**get_base_context(request),
"title": "Typy",
"description": "Typy smluv.",
"page": page,
"paginator": paginator,
}
)
def view_contractees(request):
contractees = (
get_objects_for_user(
request.user,
"contracts.view_contractee",
).
order_by("name")
)
page, paginator = get_pagination(request, contractees)
return render(
request,
"contracts/view_contractees.html",
{
**get_base_context(request),
"title": "Naše smluvní strany",
"description": "Naše smluvní strany.",
"page": page,
"paginator": paginator,
}
)
def view_signees(request):
contractees = (
get_objects_for_user(
request.user,
"contracts.view_signee",
).
order_by("name")
)
page, paginator = get_pagination(request, contractees)
return render(
request,
"contracts/view_signees.html",
{
**get_base_context(request),
"title": "Jiné smluvní strany",
"description": "Jiné smluvní strany.",
"page": page,
"paginator": paginator,
}
)
# END Submodel listing views
...@@ -220,11 +220,11 @@ ADMIN_INDEX_SHOW_REMAINING_APPS = True ...@@ -220,11 +220,11 @@ ADMIN_INDEX_SHOW_REMAINING_APPS = True
ADMIN_ORDERING = { ADMIN_ORDERING = {
"contracts": [ "contracts": [
"Contract", "Contract",
"Signee",
"Contractee", "Contractee",
"Signee",
"ContractFilingArea",
"ContractType", "ContractType",
"ContractIssue", "ContractIssue",
"ContractFilingArea",
], ],
} }
......
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
<div v-if="show || isLgScreenSize" class="navbar__main navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto"> <div v-if="show || isLgScreenSize" class="navbar__main navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto">
<ul class="navbar-menu text-white"> <ul class="navbar-menu text-white">
<li class="navbar-menu__item"> <li class="navbar-menu__item">
<a href="{% url "contracts:index" %}" data-href="{% url "contracts:index" %}" class="navbar-menu__link">Všechny smlouvy</a> <a href="{% url "contracts:index" %}" data-href="{% url "contracts:index" %}" class="navbar-menu__link">Seznam</a>
</li> </li>
<li class="navbar-menu__item"> <li class="navbar-menu__item">
<a href="#TODO" data-href="#TODO" class="navbar-menu__link">Hledat</a> <a href="#TODO" data-href="#TODO" class="navbar-menu__link">Hledat</a>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment