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

organize fields, expected cost frontend, documentation, migrations

parent 86058eb0
No related branches found
No related tags found
No related merge requests found
......@@ -21,11 +21,11 @@ Je třeba definovat minimálně následující environment proměnné:
| --- | --- |
| `DATABASE_URL` | URL pro připojení k databázi ve formátu `postgresql://username:password@host:5432/database_name` |
| `SECRET_KEY` | Tajný klíč např. pro šifrování |
| `DEFAULT_COUNTRY` | Defaultní země podepisujících stran, např. `Česká republika` |
| `DEFAULT_CONTRACTEE_NAME` | Defaultní jméno naší podepisující strany |
| `DEFAULT_CONTRACTEE_STREET` | Defaultní ulice a č.p. naší podepisující strany |
| `DEFAULT_CONTRACTEE_ZIP` | Defaultní PSČ naší podepisující strany |
| `DEFAULT_CONTRACTEE_DISTRICT` | Defaultní obec naší podepisující strany |
| `DEFAULT_CONTRACTEE_COUNTRY` | Defaultní země naší podepisující strany, např. `CZ`, `DE` |
| `DEFAULT_CONTRACTEE_ICO_NUMBER` | Defaultní IČO naší podepisující strany |
V produkci je potřeba:
......
......@@ -64,29 +64,32 @@ class ContractAdmin(MarkdownxGuardedModelAdmin):
def get_fields(self, request, obj=None):
fields = [
"created_by",
"identifier",
"types",
"summary",
"valid_start_date",
"valid_end_date",
"legal_state",
"public_state",
"paper_form_state",
"publishing_rejection_comment",
"paper_form_state",
"tender_url",
"identifier",
"issues",
"notes",
"summary",
"primary_contract",
"agreement_url",
"filing_area",
"issues",
"expected_cost_year",
"expected_cost_month",
"expected_cost_hour",
"filing_area",
"primary_contract",
"notes",
"created_by",
]
if request.user.is_superuser or request.user.has_perm("approve", self):
fields.append("is_approved")
fields.insert(
fields.index("summary"),
"is_approved",
)
return fields
......
# Generated by Django 4.1.4 on 2023-02-21 19:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('contracts', '0005_alter_contract_primary_contract'),
]
operations = [
migrations.AlterField(
model_name='contract',
name='issues',
field=models.ManyToManyField(blank=True, help_text='Veřejně nazváno "Poznámky".', to='contracts.contractissue', verbose_name='Problémy'),
),
migrations.AlterField(
model_name='contract',
name='summary',
field=models.CharField(blank=True, max_length=256, null=True, verbose_name='Sumarizace obsahu smlouvy'),
),
]
# Generated by Django 4.1.4 on 2023-02-21 19:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('contracts', '0006_alter_contract_issues_alter_contract_summary'),
]
operations = [
migrations.AlterField(
model_name='contractee',
name='address_country',
field=models.CharField(default='CZ', max_length=256, verbose_name='Země'),
),
migrations.AlterField(
model_name='signee',
name='address_country',
field=models.CharField(default='CZ', max_length=256, verbose_name='Země'),
),
]
......@@ -2,7 +2,6 @@ import math
from django.conf import settings
from django.db import models
from django_countries.fields import CountryField
from colorfield.fields import ColorField
from markdownx.models import MarkdownxField
......@@ -94,8 +93,10 @@ class Signee(ColorMixin, models.Model):
help_text="Viditelné pouze u právnických osob.",
) # WARNING: Legal entity status dependent!
address_country = CountryField(
address_country = models.CharField(
max_length=256,
verbose_name="Země",
default=settings.DEFAULT_COUNTRY,
)
ico_number = models.CharField(
......@@ -202,9 +203,10 @@ class Contractee(ColorMixin, models.Model):
verbose_name="PSČ",
)
address_country = CountryField(
default=settings.DEFAULT_CONTRACTEE_COUNTRY,
address_country = models.CharField(
max_length=256,
verbose_name="Země",
default=settings.DEFAULT_COUNTRY,
)
ico_number = models.CharField(
......@@ -314,16 +316,60 @@ class ContractFilingArea(NameStrMixin, models.Model):
class Contract(models.Model):
# BEGIN Automatically set fields
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name="uploaded_contracts",
verbose_name="Vytvořena uživatelem",
help_text="Informace není veřejně přístupná. Pokud vytváříš novou smlouvu, budeš to ty.",
) # WARNING: exclude in admin
public_status_set_by = models.ForeignKey(
User,
on_delete=models.SET_NULL,
blank=True,
null=True,
related_name="public_status_altered_contracts",
verbose_name="Zveřejněno / nezveřejněno uživatelem",
help_text="Obsah není veřejně přístupný.",
) # WARNING: exclude in admin
all_parties_sign_date = models.DateField(
verbose_name="Datum podpisu všech stran",
blank=True,
null=True,
) # WARNING: Exclude in admin, autofill
# END Automatically set fields
identifier = models.CharField(
max_length=128,
verbose_name="Identifikační číslo",
)
types = models.ManyToManyField(
ContractType,
verbose_name="Typ",
)
all_parties_sign_date = models.DateField(
verbose_name="Datum podpisu všech stran",
summary = models.CharField(
max_length=256,
blank=True,
null=True,
) # WARNING: Exclude in admin, autofill
verbose_name="Sumarizace obsahu smlouvy",
)
is_approved = models.BooleanField(
verbose_name="Je schválená",
help_text=(
"Může měnit jen schvalovatel. Pokud je smlouva "
"veřejná, zaškrtnutím se vypustí ven."
)
)
valid_start_date = models.DateField(
verbose_name="Začátek účinnosti",
......@@ -332,16 +378,6 @@ class Contract(models.Model):
verbose_name="Konec účinnosti",
)
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name="uploaded_contracts",
verbose_name="Vytvořena uživatelem",
help_text="Informace není veřejně přístupná. Pokud vytváříš novou smlouvu, budeš to ty.",
) # WARNING: exclude in admin
class LegalStates(models.TextChoices):
VALID = "valid", "Platná"
EFFECTIVE = "effective", "Účinná"
......@@ -377,16 +413,6 @@ class Contract(models.Model):
verbose_name="Stav papírové formy",
)
public_status_set_by = models.ForeignKey(
User,
on_delete=models.SET_NULL,
blank=True,
null=True,
related_name="public_status_altered_contracts",
verbose_name="Zveřejněno / nezveřejněno uživatelem",
help_text="Obsah není veřejně přístupný.",
) # WARNING: exclude in admin
publishing_rejection_comment = models.CharField(
max_length=65536,
blank=True,
......@@ -409,40 +435,32 @@ class Contract(models.Model):
verbose_name="Odkaz na schválení",
) # WARNING: Dependent on the type!
identifier = models.CharField(
max_length=128,
verbose_name="Identifikační číslo",
)
issues = models.ManyToManyField(
ContractIssue,
verbose_name="Problémy",
blank=True,
verbose_name="Problémy",
help_text="Veřejně nazváno \"Poznámky\".",
)
notes = MarkdownxField(
# NOTE: Could we make this into expected_cost_type and expected_cost_amount?
expected_cost_year = models.IntegerField(
blank=True,
null=True,
verbose_name="Poznámky",
help_text="Poznámky jsou viditelné pro všechny, kteří mohou smlouvu spravovat.",
verbose_name="Očekávané výdaje (rok)",
)
summary = MarkdownxField(
expected_cost_month = models.IntegerField(
blank=True,
null=True,
verbose_name="Rekapitulace",
help_text="Obsah není veřejně přístupný.",
verbose_name="Očekávané výdaje (měsíc)",
)
primary_contract = models.ForeignKey(
"Contract",
on_delete=models.SET_NULL, # TODO: Figure out if we want this behavior
expected_cost_hour = models.IntegerField(
blank=True,
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!
verbose_name="Očekávané výdaje (hodina)",
)
filing_area = models.ForeignKey(
ContractFilingArea,
......@@ -452,34 +470,23 @@ class Contract(models.Model):
related_name="filed_contracts",
verbose_name="Spisovna",
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(
primary_contract = models.ForeignKey(
"Contract",
on_delete=models.SET_NULL, # TODO: Figure out if we want this behavior
blank=True,
null=True,
verbose_name="Očekávané výdaje (měsíc)",
)
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!
expected_cost_hour = models.IntegerField(
notes = MarkdownxField(
blank=True,
null=True,
verbose_name="Očekávané výdaje (hodina)",
)
is_approved = models.BooleanField(
verbose_name="Je schválená",
help_text=(
"Může měnit jen schvalovatel. Pokud je smlouva "
"veřejná, zaškrtnutím se vypustí ven."
)
verbose_name="Poznámky",
help_text="Poznámky jsou viditelné pro všechny, kteří mohou smlouvu spravovat.",
)
class Meta:
......
......@@ -13,11 +13,30 @@
<td class="w-4/5 !p-2.5">
<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">
<a
class="p-1.5 rounded-sm whitespace-nowrap bg-gray-200 duration-100 hover:bg-gray-300 hover:no-underline"
href="#TODO"
>{{ type.name }}</a>
</li>
{% endfor %}
</ul>
</td>
</tr>
{% if contract.primary_contract %}
<tr>
<td class="w-1/5 !p-2.5">Primární smlouva</td>
<td class="w-4/5 !p-2.5">
<a
href="{% url "contracts:view_contract" contract.primary_contract.id %}"
>{{ contract.primary_contract.identifier }}</a>
</td>
</tr>
{% endif %}
<tr>
<td class="w-1/5 !p-2.5">Souhrn obsahu</td>
<td class="w-4/5 !p-2.5">{{ contract.summary }}</td>
</tr>
<tr>
<td class="w-1/5 !p-2.5">Začátek účinnosti</td>
<td class="w-4/5 !p-2.5">{{ contract.valid_start_date }}</td>
......@@ -82,7 +101,7 @@
</td>
</tr>
<tr>
<td class="w-1/5 !p-2.5">Problémy</td>
<td class="w-1/5 !p-2.5">Poznámky</td>
<td class="w-4/5 !p-2.5">
{% with contract.issues.all as issues %}
{% if issues|length != 0 %}
......@@ -97,13 +116,27 @@
{% endwith %}
</td>
</tr>
{% if contract.primary_contract %}
{% if contract.expected_cost_year %}
<tr>
<td class="w-1/5 !p-2.5">Primární smlouva</td>
<td class="w-1/5 !p-2.5">Očekávané náklady (rok)</td>
<td class="w-4/5 !p-2.5">
<a
href="{% url "contracts:view_contract" contract.primary_contract.id %}"
>{{ contract.primary_contract.identifier }}</a>
{{ contract.expected_cost_month }} Kč
</td>
</tr>
{% endif %}
{% if contract.expected_cost_month %}
<tr>
<td class="w-1/5 !p-2.5">Očekávané náklady (měsíc)</td>
<td class="w-4/5 !p-2.5">
{{ contract.expected_cost_month }} Kč
</td>
</tr>
{% endif %}
{% if contract.expected_cost_hour %}
<tr>
<td class="w-1/5 !p-2.5">Očekávané náklady (hodina)</td>
<td class="w-4/5 !p-2.5">
{{ contract.expected_cost_hour }} Kč
</td>
</tr>
{% endif %}
......
......@@ -8,9 +8,10 @@ OIDC_RP_REALM_URL="http://localhost:8080/realms/master/"
OIDC_RP_CLIENT_ID=contracts
OIDC_RP_CLIENT_SECRET=VCn4LVAUc6RGLSup7VaAKsmrKUbWguaP
DEFAULT_COUNTRY="CZ"
DEFAULT_CONTRACTEE_NAME="Česká pirátská strana"
DEFAULT_CONTRACTEE_STREET="Na Moráni 360/3"
DEFAULT_CONTRACTEE_ZIP="128 00"
DEFAULT_CONTRACTEE_DISTRICT="Praha 2"
DEFAULT_CONTRACTEE_COUNTRY="CZ"
DEFAULT_CONTRACTEE_ICO_NUMBER="71339698"
......@@ -187,5 +187,5 @@ DEFAULT_CONTRACTEE_NAME = env.str("DEFAULT_CONTRACTEE_NAME")
DEFAULT_CONTRACTEE_STREET = env.str("DEFAULT_CONTRACTEE_STREET")
DEFAULT_CONTRACTEE_ZIP = env.str("DEFAULT_CONTRACTEE_ZIP")
DEFAULT_CONTRACTEE_DISTRICT = env.str("DEFAULT_CONTRACTEE_DISTRICT")
DEFAULT_CONTRACTEE_COUNTRY = env.str("DEFAULT_CONTRACTEE_COUNTRY")
DEFAULT_COUNTRY = env.str("DEFAULT_COUNTRY")
DEFAULT_CONTRACTEE_ICO_NUMBER = env.str("DEFAULT_CONTRACTEE_ICO_NUMBER")
......@@ -9,4 +9,3 @@ django-markdownx==4.0.0b1
django-environ==0.9.0
django-http-exceptions==1.4.0
django-guardian==2.4.0
django-countries==7.5.1
......@@ -76,7 +76,7 @@
<a href="{% url "contracts:index" %}" data-href="{% url "contracts:index" %}" class="navbar-menu__link">Všechny smlouvy</a>
</li>
<li class="navbar-menu__item">
<a href="#TODO" data-href="#TODO" class="navbar-menu__link">Hledání</a>
<a href="#TODO" data-href="#TODO" class="navbar-menu__link">Hledat</a>
</li>
{% if user.is_staff %}
<li class="navbar-menu__item">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment