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

handle colors, update terminology, return expected costs

parent 520eee0c
No related branches found
No related tags found
No related merge requests found
...@@ -53,25 +53,6 @@ class ContractIntentInline(admin.TabularInline): ...@@ -53,25 +53,6 @@ class ContractIntentInline(admin.TabularInline):
class ContractAdmin(MarkdownxGuardedModelAdmin): class ContractAdmin(MarkdownxGuardedModelAdmin):
form = ContractAdminForm form = ContractAdminForm
fields = (
"created_by",
"types",
"valid_start_date",
"valid_end_date",
"legal_state",
"public_state",
"paper_form_state",
"publishing_rejection_comment",
"tender_url",
"identifier",
"issues",
"notes",
"summary",
"primary_contract",
"agreement_url",
"filing_area",
)
readonly_fields = ("created_by",) readonly_fields = ("created_by",)
inlines = ( inlines = (
...@@ -81,6 +62,34 @@ class ContractAdmin(MarkdownxGuardedModelAdmin): ...@@ -81,6 +62,34 @@ class ContractAdmin(MarkdownxGuardedModelAdmin):
ContractIntentInline, ContractIntentInline,
) )
def get_fields(self, request, obj=None):
fields = [
"created_by",
"types",
"valid_start_date",
"valid_end_date",
"legal_state",
"public_state",
"paper_form_state",
"publishing_rejection_comment",
"tender_url",
"identifier",
"issues",
"notes",
"summary",
"primary_contract",
"agreement_url",
"filing_area",
"expected_cost_year",
"expected_cost_month",
"expected_cost_hour",
]
if request.user.is_superuser or request.user.has_perm("approve", self):
fields.append("is_approved")
return fields
def save_model(self, request, obj, form, change) -> None: def save_model(self, request, obj, form, change) -> None:
if obj.created_by is None: if obj.created_by is None:
obj.created_by = request.user obj.created_by = request.user
...@@ -101,10 +110,7 @@ class SigneeRepresentativeInline(admin.TabularInline): ...@@ -101,10 +110,7 @@ class SigneeRepresentativeInline(admin.TabularInline):
class SigneeAdmin(MarkdownxGuardedModelAdmin): class SigneeAdmin(MarkdownxGuardedModelAdmin):
form = SigneeAdminForm form = SigneeAdminForm
inlines = ( inlines = (SigneeRepresentativeInline,)
SigneeRepresentativeInline,
SigneeSignatureInline,
)
class ContracteeRepresentativeInline(admin.TabularInline): class ContracteeRepresentativeInline(admin.TabularInline):
...@@ -113,7 +119,7 @@ class ContracteeRepresentativeInline(admin.TabularInline): ...@@ -113,7 +119,7 @@ class ContracteeRepresentativeInline(admin.TabularInline):
class ContracteeAdmin(MarkdownxGuardedModelAdmin): class ContracteeAdmin(MarkdownxGuardedModelAdmin):
inlines = (ContracteeRepresentativeInline, ContracteeSignatureInline) inlines = (ContracteeRepresentativeInline,)
# END Signing parties # END Signing parties
......
# Generated by Django 4.1.4 on 2023-02-21 05:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('contracts', '0002_contract_is_approved_alter_contract_valid_end_date'),
]
operations = [
migrations.AddField(
model_name='contract',
name='expected_cost_hour',
field=models.IntegerField(blank=True, null=True, verbose_name='Očekávané výdaje (hodina)'),
),
migrations.AddField(
model_name='contract',
name='expected_cost_month',
field=models.IntegerField(blank=True, null=True, verbose_name='Očekávané výdaje (měsíc)'),
),
migrations.AddField(
model_name='contract',
name='expected_cost_year',
field=models.IntegerField(blank=True, null=True, verbose_name='Očekávané výdaje (rok)'),
),
]
# Generated by Django 4.1.4 on 2023-02-21 05:42
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('contracts', '0003_contract_expected_cost_hour_and_more'),
]
operations = [
migrations.AlterModelOptions(
name='contract',
options={'permissions': (('approve', 'Schválit / zrušit schválení'),), 'verbose_name': 'Smlouva', 'verbose_name_plural': 'Smlouvy'},
),
]
# Generated by Django 4.1.4 on 2023-02-21 06:07
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('contracts', '0004_alter_contract_options'),
]
operations = [
migrations.AlterField(
model_name='contract',
name='primary_contract',
field=models.ForeignKey(blank=True, help_text='Např. pro dodatky nebo objednávky u rámcových smluv.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subcontracts', to='contracts.contract', verbose_name='Primární smlouva'),
),
]
import math
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django_countries.fields import CountryField from django_countries.fields import CountryField
...@@ -33,7 +35,38 @@ class RepresentativeMixin: ...@@ -33,7 +35,38 @@ class RepresentativeMixin:
return result return result
class Signee(models.Model): class ColorMixin(models.Model):
color = ColorField(
blank=True,
null=True,
verbose_name="Barva",
)
@property
def color_is_light(self) -> bool:
if self.color is None:
raise ValueError
# https://stackoverflow.com/a/29643643 - Thanks to John1024 and vallentin!
# https://stackoverflow.com/a/58270890 - Thanks to Kardi Teknomo!
hex_color = self.color.lstrip("#")
rgb_color = tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
[r, g, b] = rgb_color
hsp = math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b))
if hsp > 127.5:
return True
else:
return False
class Meta:
abstract = True
class Signee(ColorMixin, models.Model):
name = models.CharField( name = models.CharField(
max_length=256, max_length=256,
verbose_name="Jméno", verbose_name="Jméno",
...@@ -85,12 +118,6 @@ class Signee(models.Model): ...@@ -85,12 +118,6 @@ class Signee(models.Model):
verbose_name="Organizační složka", verbose_name="Organizační složka",
) )
color = ColorField(
blank=True,
null=True,
verbose_name="Barva",
)
class Meta: class Meta:
verbose_name = "Jiná smluvní strana" verbose_name = "Jiná smluvní strana"
verbose_name_plural = "Ostatní smluvní strany" verbose_name_plural = "Ostatní smluvní strany"
...@@ -150,7 +177,7 @@ class SigneeRepresentative(RepresentativeMixin, models.Model): ...@@ -150,7 +177,7 @@ class SigneeRepresentative(RepresentativeMixin, models.Model):
verbose_name_plural = "Zástupci" verbose_name_plural = "Zástupci"
class Contractee(models.Model): class Contractee(ColorMixin, models.Model):
name = models.CharField( name = models.CharField(
max_length=256, max_length=256,
default=settings.DEFAULT_CONTRACTEE_NAME, default=settings.DEFAULT_CONTRACTEE_NAME,
...@@ -195,12 +222,6 @@ class Contractee(models.Model): ...@@ -195,12 +222,6 @@ class Contractee(models.Model):
verbose_name="Organizační složka", verbose_name="Organizační složka",
) )
color = ColorField(
blank=True,
null=True,
verbose_name="Barva",
)
class Meta: class Meta:
verbose_name = "Naše smluvní strana" verbose_name = "Naše smluvní strana"
verbose_name_plural = "Naše smluvní strany" verbose_name_plural = "Naše smluvní strany"
...@@ -420,6 +441,7 @@ class Contract(models.Model): ...@@ -420,6 +441,7 @@ class Contract(models.Model):
null=True, null=True,
related_name="subcontracts", related_name="subcontracts",
verbose_name="Primární smlouva", verbose_name="Primární smlouva",
help_text="Např. pro dodatky nebo objednávky u rámcových smluv."
) # WARNING: Dependent on the type! ) # WARNING: Dependent on the type!
filing_area = models.ForeignKey( filing_area = models.ForeignKey(
...@@ -432,12 +454,26 @@ class Contract(models.Model): ...@@ -432,12 +454,26 @@ class Contract(models.Model):
help_text="Obsah není veřejně přístupný.", help_text="Obsah není veřejně přístupný.",
) # WARNING: Dependent on the type! ) # WARNING: Dependent on the type!
# NOTE: Could we make this into expected_cost_type and expected_cost_amount?
expected_cost_year = models.IntegerField( expected_cost_year = models.IntegerField(
blank=True, blank=True,
null=True, null=True,
verbose_name="Očekávané výdaje (rok)", verbose_name="Očekávané výdaje (rok)",
) )
expected_cost_month = models.IntegerField(
blank=True,
null=True,
verbose_name="Očekávané výdaje (měsíc)",
)
expected_cost_hour = models.IntegerField(
blank=True,
null=True,
verbose_name="Očekávané výdaje (hodina)",
)
is_approved = models.BooleanField( is_approved = models.BooleanField(
verbose_name="Je schválená", verbose_name="Je schválená",
help_text=( help_text=(
...@@ -449,6 +485,10 @@ class Contract(models.Model): ...@@ -449,6 +485,10 @@ class Contract(models.Model):
class Meta: class Meta:
verbose_name = "Smlouva" verbose_name = "Smlouva"
verbose_name_plural = "Smlouvy" verbose_name_plural = "Smlouvy"
permissions = (
("approve", "Schválit / zrušit schválení"),
)
def __str__(self) -> str: def __str__(self) -> str:
return self.identifier return self.identifier
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<thead> <thead>
<tr> <tr>
<td class="font-bold">Identifikace</td> <td class="font-bold">Identifikace</td>
<td>Typ</td> <td>Typy</td>
<td>Právní stav</td> <td>Právní stav</td>
<td>Účinná od</td> <td>Účinná od</td>
<td>Účinná do</td> <td>Účinná do</td>
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
<ul class="flex flex-wrap gap-1.5"> <ul class="flex flex-wrap gap-1.5">
{% for signature in contract.signee_signatures.all %} {% for signature in contract.signee_signatures.all %}
<li <li
class="p-1.5 rounded-sm whitespace-nowrap cursor-pointer {% if not signature.signee.color %}bg-gray-200 duration-100 hover:bg-gray-300{% endif %}" class="p-1.5 rounded-sm whitespace-nowrap cursor-pointer {% if not signature.signee.color %}bg-gray-200 duration-100 hover:bg-gray-300{% endif %}{% if signature.signee.color and not signature.signee.color_is_light %} text-white{% endif %}"
{% if signature.signee.color %}style="background-color:{{ signature.signee.color }}"{% endif %} {% if signature.signee.color %}style="background-color:{{ signature.signee.color }}"{% endif %}
>{{ signature.signee.name }}</li> >{{ signature.signee.name }}</li>
{% endfor %} {% endfor %}
......
...@@ -143,7 +143,8 @@ ...@@ -143,7 +143,8 @@
<address class="mb-3"> <address class="mb-3">
<div class="mb-1"> <div class="mb-1">
<a <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 whitespace-nowrap cursor-pointer not-italic hover:no-underline {% if not signature.contractee.color %}bg-gray-200 duration-100 hover:bg-gray-300{% endif %}{% if signature.contractee.color and not signature.contractee.color_is_light %} text-white{% endif %}"
{% if signature.contractee.color %}style="background-color:{{ signature.contractee.color }}"{% endif %}
> >
<strong>{{ signature.contractee.name }}</strong> <strong>{{ signature.contractee.name }}</strong>
{% if signature.contractee.department %} {% if signature.contractee.department %}
...@@ -192,7 +193,8 @@ ...@@ -192,7 +193,8 @@
<address class="mb-3"> <address class="mb-3">
<div class="mb-1"> <div class="mb-1">
<a <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 whitespace-nowrap cursor-pointer not-italic hover:no-underline {% if not signature.signee.color %}bg-gray-200 duration-100 hover:bg-gray-300{% endif %}{% if signature.signee.color and not signature.signee.color_is_light %} text-white{% endif %}"
{% if signature.signee.color %}style="background-color:{{ signature.signee.color }}"{% endif %}
> >
<strong>{{ signature.signee.name }}</strong> <strong>{{ signature.signee.name }}</strong>
{% if signature.signee.department %} {% if signature.signee.department %}
...@@ -201,7 +203,7 @@ ...@@ -201,7 +203,7 @@
</a> </a>
</div> </div>
{% if signee.is_legal_entity %} {% if signature.signee.is_legal_entity %}
{{ signature.signee.address_street_with_number }}<br> {{ signature.signee.address_street_with_number }}<br>
{{ signature.signee.address_zip }} {{ signature.signee.address_district }}<br> {{ signature.signee.address_zip }} {{ signature.signee.address_district }}<br>
{{ signature.signee.get_address_country_display }}<br> {{ signature.signee.get_address_country_display }}<br>
...@@ -213,7 +215,7 @@ ...@@ -213,7 +215,7 @@
IČO: {{ signature.signee.ico_number }}<br> IČO: {{ signature.signee.ico_number }}<br>
{% endif %} {% endif %}
{% if not signee.is_legal_entity %} {% if not signature.signee.is_legal_entity %}
<span class="block mt-2"> <span class="block mt-2">
<small class="font-thin">(Fyzická osoba, ukazujeme pouze obec.)</small><br> <small class="font-thin">(Fyzická osoba, ukazujeme pouze obec.)</small><br>
</span> </span>
......
...@@ -9,7 +9,7 @@ from .models import Contract ...@@ -9,7 +9,7 @@ from .models import Contract
def index(request): def index(request):
contracts = Contract.objects.filter( contracts = Contract.objects.filter(
is_approved__is=True, is_approved=True,
public_state=Contract.PublicStates.YES, public_state=Contract.PublicStates.YES,
).order_by("valid_start_date").all() ).order_by("valid_start_date").all()
paginator = Paginator(contracts, 25) paginator = Paginator(contracts, 25)
...@@ -36,7 +36,7 @@ def index(request): ...@@ -36,7 +36,7 @@ def index(request):
def view_contract(request, id: int): def view_contract(request, id: int):
contract = Contract.objects.filter( contract = Contract.objects.filter(
is_approved__is=True, is_approved=True,
public_state=Contract.PublicStates.YES, public_state=Contract.PublicStates.YES,
).get(id=id) ).get(id=id)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment