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,7 +53,17 @@ class ContractIntentInline(admin.TabularInline):
class ContractAdmin(MarkdownxGuardedModelAdmin):
form = ContractAdminForm
fields = (
readonly_fields = ("created_by",)
inlines = (
ContracteeSignatureInline,
SigneeSignatureInline,
ContractFileInline,
ContractIntentInline,
)
def get_fields(self, request, obj=None):
fields = [
"created_by",
"types",
"valid_start_date",
......@@ -70,16 +80,15 @@ class ContractAdmin(MarkdownxGuardedModelAdmin):
"primary_contract",
"agreement_url",
"filing_area",
)
"expected_cost_year",
"expected_cost_month",
"expected_cost_hour",
]
readonly_fields = ("created_by",)
if request.user.is_superuser or request.user.has_perm("approve", self):
fields.append("is_approved")
inlines = (
ContracteeSignatureInline,
SigneeSignatureInline,
ContractFileInline,
ContractIntentInline,
)
return fields
def save_model(self, request, obj, form, change) -> None:
if obj.created_by is None:
......@@ -101,10 +110,7 @@ class SigneeRepresentativeInline(admin.TabularInline):
class SigneeAdmin(MarkdownxGuardedModelAdmin):
form = SigneeAdminForm
inlines = (
SigneeRepresentativeInline,
SigneeSignatureInline,
)
inlines = (SigneeRepresentativeInline,)
class ContracteeRepresentativeInline(admin.TabularInline):
......@@ -113,7 +119,7 @@ class ContracteeRepresentativeInline(admin.TabularInline):
class ContracteeAdmin(MarkdownxGuardedModelAdmin):
inlines = (ContracteeRepresentativeInline, ContracteeSignatureInline)
inlines = (ContracteeRepresentativeInline,)
# 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.db import models
from django_countries.fields import CountryField
......@@ -33,7 +35,38 @@ class RepresentativeMixin:
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(
max_length=256,
verbose_name="Jméno",
......@@ -85,12 +118,6 @@ class Signee(models.Model):
verbose_name="Organizační složka",
)
color = ColorField(
blank=True,
null=True,
verbose_name="Barva",
)
class Meta:
verbose_name = "Jiná smluvní strana"
verbose_name_plural = "Ostatní smluvní strany"
......@@ -150,7 +177,7 @@ class SigneeRepresentative(RepresentativeMixin, models.Model):
verbose_name_plural = "Zástupci"
class Contractee(models.Model):
class Contractee(ColorMixin, models.Model):
name = models.CharField(
max_length=256,
default=settings.DEFAULT_CONTRACTEE_NAME,
......@@ -195,12 +222,6 @@ class Contractee(models.Model):
verbose_name="Organizační složka",
)
color = ColorField(
blank=True,
null=True,
verbose_name="Barva",
)
class Meta:
verbose_name = "Naše smluvní strana"
verbose_name_plural = "Naše smluvní strany"
......@@ -420,6 +441,7 @@ class Contract(models.Model):
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!
filing_area = models.ForeignKey(
......@@ -432,12 +454,26 @@ class Contract(models.Model):
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(
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(
verbose_name="Je schválená",
help_text=(
......@@ -450,6 +486,10 @@ class Contract(models.Model):
verbose_name = "Smlouva"
verbose_name_plural = "Smlouvy"
permissions = (
("approve", "Schválit / zrušit schválení"),
)
def __str__(self) -> str:
return self.identifier
......
......@@ -7,7 +7,7 @@
<thead>
<tr>
<td class="font-bold">Identifikace</td>
<td>Typ</td>
<td>Typy</td>
<td>Právní stav</td>
<td>Účinná od</td>
<td>Účinná do</td>
......@@ -37,7 +37,7 @@
<ul class="flex flex-wrap gap-1.5">
{% for signature in contract.signee_signatures.all %}
<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 %}
>{{ signature.signee.name }}</li>
{% endfor %}
......
......@@ -143,7 +143,8 @@
<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 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>
{% if signature.contractee.department %}
......@@ -192,7 +193,8 @@
<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 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>
{% if signature.signee.department %}
......@@ -201,7 +203,7 @@
</a>
</div>
{% if signee.is_legal_entity %}
{% if signature.signee.is_legal_entity %}
{{ signature.signee.address_street_with_number }}<br>
{{ signature.signee.address_zip }} {{ signature.signee.address_district }}<br>
{{ signature.signee.get_address_country_display }}<br>
......@@ -213,7 +215,7 @@
IČO: {{ signature.signee.ico_number }}<br>
{% endif %}
{% if not signee.is_legal_entity %}
{% if not signature.signee.is_legal_entity %}
<span class="block mt-2">
<small class="font-thin">(Fyzická osoba, ukazujeme pouze obec.)</small><br>
</span>
......
......@@ -9,7 +9,7 @@ from .models import Contract
def index(request):
contracts = Contract.objects.filter(
is_approved__is=True,
is_approved=True,
public_state=Contract.PublicStates.YES,
).order_by("valid_start_date").all()
paginator = Paginator(contracts, 25)
......@@ -36,7 +36,7 @@ def index(request):
def view_contract(request, id: int):
contract = Contract.objects.filter(
is_approved__is=True,
is_approved=True,
public_state=Contract.PublicStates.YES,
).get(id=id)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment