diff --git a/.gitignore b/.gitignore index d8265e7c4794bad4d279c544847e7a18eaa8e34e..e5a12d8ccfa4b0e4a98721f448cf7ef670a88c6d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .env __pycache__/ +staticfiles node_modules/* shared/static/* +webpack-stats.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7d3057fa75ee8477355149d9a72eacfbb5732210 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,26 @@ +default_language_version: + python: python3.10 + +exclude: snapshots/ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: trailing-whitespace + exclude: ^.*\.md$ + - id: end-of-file-fixer + - id: debug-statements + - id: mixed-line-ending + args: [--fix=lf] + - id: detect-private-key + - id: check-merge-conflict + + - repo: https://github.com/timothycrosley/isort + rev: 5.12.0 + hooks: + - id: isort + + - repo: https://github.com/psf/black + rev: 23.1.0 + hooks: + - id: black diff --git a/Makefile b/Makefile index c530d3d3d6dee4bd5fd5ba3dc3c715c52c6455ad..10de836a3643e896093cd5ef118041f41c77286a 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,11 @@ install: venv ${VENV}/bin/nodeenv --python-virtualenv --node=19.3.0 ${VENV}/bin/npm install +install-hooks: + pre-commit install --install-hooks + +hooks: + pre-commit run -a build: venv ${VENV}/bin/npm run build diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..93b1e17c4e3aab6b2633c7ee7f06aedb9954ba0d --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# Contract registry + +The Czech Pirate Party's transparent evidence system for its contracts and +information about them. + +## Basic requirements +- `make` +- `python`, 3.9 or newer +- `python-virtualenv` +- A PostgreSQL server + +## Setup + +Copy `env.example` to `.env`. + +Set the ``DATABASE_URL`` environment variable in `.env` to one you can access your database server with. The format should be as per RFC 1738, such as `postgresql://login:password@localhost:5432/database_name`. It's also important to change the ``SECRET_KEY`` variable. + +Then, run the following commands: + +```bash +make venv # Create virtual environment +make install # Install Python and Node.js dependencies +make build # Build static files +``` + +## Running + +To run with the default settings on the port set in `Makefile`, run: + +```bash +make run +``` + +For more customization, it's better practice to run the server starting command directly: + +```bash +source .venv/bin/activate # Load the virtual environment +python manage.py runserver # [ Your settings here ] +``` diff --git a/manage.py b/manage.py index 0e1442be86443cb560d236a8317bc4f0f1416563..45b9a48db1a92054ae621433dceeaf666cb02c0f 100755 --- a/manage.py +++ b/manage.py @@ -6,7 +6,7 @@ import sys def main(): """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'registry.settings') + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "registry.settings") try: from django.core.management import execute_from_command_line except ImportError as exc: @@ -18,5 +18,5 @@ def main(): execute_from_command_line(sys.argv) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/registry/asgi.py b/registry/asgi.py index e1d1af068c04c244397d345195498fa0d029ccb0..97f009382813a650c585c06411700755c138410e 100644 --- a/registry/asgi.py +++ b/registry/asgi.py @@ -11,6 +11,6 @@ import os from django.core.asgi import get_asgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'registry.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "registry.settings") application = get_asgi_application() diff --git a/registry/settings/base.py b/registry/settings/base.py index a7b77458de5e7e9107840a48978606941aec2805..93c9200ab4a598fc91fbc1ba8bd3dc6b759e22ca 100644 --- a/registry/settings/base.py +++ b/registry/settings/base.py @@ -13,8 +13,8 @@ https://docs.djangoproject.com/en/4.0/ref/settings/ import os import pathlib -import environ import dj_database_url +import environ # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = pathlib.Path(__file__).parents[2] @@ -45,7 +45,6 @@ INSTALLED_APPS = [ "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", - "shared", ] @@ -83,9 +82,7 @@ WSGI_APPLICATION = "registry.wsgi.application" # Database # https://docs.djangoproject.com/en/4.0/ref/settings/#databases -DATABASES = { - "default": dj_database_url.config(conn_max_age=600) -} +DATABASES = {"default": dj_database_url.config(conn_max_age=600)} # Password validation diff --git a/registry/urls.py b/registry/urls.py index 13c37f72e62a07f75bfabf6da7f9aba104c04723..417ef5128c133640e46663d4ae520e1aabcf100a 100644 --- a/registry/urls.py +++ b/registry/urls.py @@ -17,5 +17,5 @@ from django.contrib import admin from django.urls import path urlpatterns = [ - path('admin/', admin.site.urls), + path("admin/", admin.site.urls), ] diff --git a/registry/wsgi.py b/registry/wsgi.py index 06fb2293640440935875f76745d3cc20fed4487e..bf93aed3ad371e01acd63817211bb51db3806942 100644 --- a/registry/wsgi.py +++ b/registry/wsgi.py @@ -11,6 +11,6 @@ import os from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'registry.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "registry.settings") application = get_wsgi_application() diff --git a/requirements/base.txt b/requirements/base.txt index 51af94fe4596c5d69ea0b778a705e673e3e31f30..9ebad7d956d7a970d724c15b530da6d155d93b37 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -6,6 +6,6 @@ nodeenv==1.7.0 pirates==0.6.0 django-markdownx==4.0.0b1 django-environ==0.9.0 -django-http-exceptions==1.4.0 +django-http-exceptions==1.4.0 django-guardian==2.4.0 django-countries==7.5.1 diff --git a/shared/apps.py b/shared/apps.py index 87efe0081f84bbf7e0a233e36ae7cdb836755f9e..5bfd5686252535c615aacfaee6665532f54879a1 100644 --- a/shared/apps.py +++ b/shared/apps.py @@ -2,5 +2,5 @@ from django.apps import AppConfig class SharedConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'shared' + default_auto_field = "django.db.models.BigAutoField" + name = "shared" diff --git a/shared/migrations/0001_initial.py b/shared/migrations/0001_initial.py index cbeff1c25e1a3632a2d81a325c506a675b5bb83e..0d45e6af3e395ec6d04e68da404bee7bae83db3e 100644 --- a/shared/migrations/0001_initial.py +++ b/shared/migrations/0001_initial.py @@ -1,199 +1,567 @@ # Generated by Django 4.1.4 on 2023-02-03 04:50 -from django.conf import settings -from django.db import migrations, models import django.db.models.deletion import django.utils.timezone import django_countries.fields import markdownx.models +from django.conf import settings +from django.db import migrations, models class Migration(migrations.Migration): - initial = True dependencies = [ - ('auth', '0012_alter_user_first_name_max_length'), + ("auth", "0012_alter_user_first_name_max_length"), ] operations = [ migrations.CreateModel( - name='User', + name="User", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('sso_id', models.CharField(error_messages={'unique': 'A user with that SSO ID already exists.'}, max_length=150, unique=True, verbose_name='SSO ID')), - ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), - ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), - ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), - ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), - ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), - ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), - ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), - ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "is_superuser", + models.BooleanField( + default=False, + help_text="Designates that this user has all permissions without explicitly assigning them.", + verbose_name="superuser status", + ), + ), + ( + "sso_id", + models.CharField( + error_messages={ + "unique": "A user with that SSO ID already exists." + }, + max_length=150, + unique=True, + verbose_name="SSO ID", + ), + ), + ( + "first_name", + models.CharField( + blank=True, max_length=150, verbose_name="first name" + ), + ), + ( + "last_name", + models.CharField( + blank=True, max_length=150, verbose_name="last name" + ), + ), + ( + "email", + models.EmailField( + blank=True, max_length=254, verbose_name="email address" + ), + ), + ( + "is_staff", + models.BooleanField( + default=False, + help_text="Designates whether the user can log into this admin site.", + verbose_name="staff status", + ), + ), + ( + "is_active", + models.BooleanField( + default=True, + help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.", + verbose_name="active", + ), + ), + ( + "date_joined", + models.DateTimeField( + default=django.utils.timezone.now, verbose_name="date joined" + ), + ), + ( + "groups", + models.ManyToManyField( + blank=True, + help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.", + related_name="user_set", + related_query_name="user", + to="auth.group", + verbose_name="groups", + ), + ), + ( + "user_permissions", + models.ManyToManyField( + blank=True, + help_text="Specific permissions for this user.", + related_name="user_set", + related_query_name="user", + to="auth.permission", + verbose_name="user permissions", + ), + ), ], options={ - 'verbose_name': 'user', - 'verbose_name_plural': 'users', - 'abstract': False, + "verbose_name": "user", + "verbose_name_plural": "users", + "abstract": False, }, ), migrations.CreateModel( - name='Contract', + name="Contract", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('type', models.CharField(choices=[('primary', 'Hlavní'), ('amendment', 'Dodatek'), ('framework_order', 'Objednávka u rámcové smlouvy')], default='primary', max_length=15, verbose_name='Typ')), - ('contains_nda', models.BooleanField(default=False, verbose_name='Obsahuje NDA')), - ('is_anonymized', models.BooleanField(default=False, verbose_name='Je anonymizovaná')), - ('external_signer_signature_date', models.DateField(verbose_name='Datum podpisu druhé strany')), - ('local_signer_signature_date', models.DateField(verbose_name='Datum podpisu naší strany')), - ('all_parties_sign_date', models.DateField(verbose_name='Datum podpisu všech stran')), - ('valid_start_date', models.DateField(verbose_name='Začátek účinnosti')), - ('valid_end_date', models.DateField(verbose_name='Začátek platnosti')), - ('legal_state', models.CharField(choices=[('valid', 'Platná'), ('effective', 'Účinná'), ('not_effective', 'Neúčinná'), ('invalid', 'Neplatná')], max_length=13, verbose_name='Stav právního ujednání')), - ('public_state', models.CharField(choices=[('unknown', 'Nová'), ('yes', 'Zveřejněná'), ('no', 'Neveřejná')], max_length=7, verbose_name='Veřejnost smlouvy')), - ('paper_form_state', models.CharField(choices=[('sent', 'Odeslaná'), ('stored', 'Uložená'), ('to_shred', 'Ke skartaci'), ('shredded', 'Skartovaná')], max_length=8, verbose_name='Stav papírové formy')), - ('publishing_rejection_comment', models.CharField(blank=True, max_length=65536, null=True, verbose_name='Důvod nezveřejnění')), - ('tender_url', models.URLField(blank=True, max_length=256, null=True, verbose_name='Odkaz na výběrové řízení')), - ('identifier', models.CharField(max_length=128, verbose_name='Identifikační číslo')), - ('summary', models.CharField(blank=True, max_length=65536, null=True, verbose_name='Rekapitulace')), - ('contract_file', models.FileField(upload_to='', verbose_name='Smlouva (PDF)')), - ('expected_cost_total', models.IntegerField(verbose_name='Očekáváná celková cena')), - ('expected_cost_year', models.IntegerField(verbose_name='Očekáváná cena za rok')), - ('expected_cost_month', models.IntegerField(verbose_name='Očekáváná cena za měsíc')), - ('expected_cost_hour', models.IntegerField(verbose_name='Očekáváná cena za hodinu')), - ('intent_url', models.URLField(blank=True, max_length=256, null=True, verbose_name='Odkaz na záměr')), - ('agreement_url', models.URLField(blank=True, max_length=256, null=True, verbose_name='Odkaz na schválení')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "type", + models.CharField( + choices=[ + ("primary", "Hlavní"), + ("amendment", "Dodatek"), + ("framework_order", "Objednávka u rámcové smlouvy"), + ], + default="primary", + max_length=15, + verbose_name="Typ", + ), + ), + ( + "contains_nda", + models.BooleanField(default=False, verbose_name="Obsahuje NDA"), + ), + ( + "is_anonymized", + models.BooleanField(default=False, verbose_name="Je anonymizovaná"), + ), + ( + "external_signer_signature_date", + models.DateField(verbose_name="Datum podpisu druhé strany"), + ), + ( + "local_signer_signature_date", + models.DateField(verbose_name="Datum podpisu naší strany"), + ), + ( + "all_parties_sign_date", + models.DateField(verbose_name="Datum podpisu všech stran"), + ), + ( + "valid_start_date", + models.DateField(verbose_name="Začátek účinnosti"), + ), + ("valid_end_date", models.DateField(verbose_name="Začátek platnosti")), + ( + "legal_state", + models.CharField( + choices=[ + ("valid", "Platná"), + ("effective", "Účinná"), + ("not_effective", "Neúčinná"), + ("invalid", "Neplatná"), + ], + max_length=13, + verbose_name="Stav právního ujednání", + ), + ), + ( + "public_state", + models.CharField( + choices=[ + ("unknown", "Nová"), + ("yes", "Zveřejněná"), + ("no", "Neveřejná"), + ], + max_length=7, + verbose_name="Veřejnost smlouvy", + ), + ), + ( + "paper_form_state", + models.CharField( + choices=[ + ("sent", "Odeslaná"), + ("stored", "Uložená"), + ("to_shred", "Ke skartaci"), + ("shredded", "Skartovaná"), + ], + max_length=8, + verbose_name="Stav papírové formy", + ), + ), + ( + "publishing_rejection_comment", + models.CharField( + blank=True, + max_length=65536, + null=True, + verbose_name="Důvod nezveřejnění", + ), + ), + ( + "tender_url", + models.URLField( + blank=True, + max_length=256, + null=True, + verbose_name="Odkaz na výběrové řízení", + ), + ), + ( + "identifier", + models.CharField( + max_length=128, verbose_name="Identifikační číslo" + ), + ), + ( + "summary", + models.CharField( + blank=True, + max_length=65536, + null=True, + verbose_name="Rekapitulace", + ), + ), + ( + "contract_file", + models.FileField(upload_to="", verbose_name="Smlouva (PDF)"), + ), + ( + "expected_cost_total", + models.IntegerField(verbose_name="Očekáváná celková cena"), + ), + ( + "expected_cost_year", + models.IntegerField(verbose_name="Očekáváná cena za rok"), + ), + ( + "expected_cost_month", + models.IntegerField(verbose_name="Očekáváná cena za měsíc"), + ), + ( + "expected_cost_hour", + models.IntegerField(verbose_name="Očekáváná cena za hodinu"), + ), + ( + "intent_url", + models.URLField( + blank=True, + max_length=256, + null=True, + verbose_name="Odkaz na záměr", + ), + ), + ( + "agreement_url", + models.URLField( + blank=True, + max_length=256, + null=True, + verbose_name="Odkaz na schválení", + ), + ), ], options={ - 'verbose_name': 'Smlouva', - 'verbose_name_plural': 'Smlouvy', + "verbose_name": "Smlouva", + "verbose_name_plural": "Smlouvy", }, ), migrations.CreateModel( - name='ContractExternalSigner', + name="ContractExternalSigner", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=256, verbose_name='Jméno')), - ('is_legal_entity', models.BooleanField(verbose_name='Je právnická osoba')), - ('address_street_with_number', models.CharField(max_length=256, verbose_name='Ulice, č.p.')), - ('address_district', models.CharField(max_length=256, verbose_name='Obec')), - ('address_zip', models.CharField(max_length=16, verbose_name='PSČ')), - ('address_country', django_countries.fields.CountryField(max_length=2, verbose_name='Země')), - ('ico_number', models.CharField(blank=True, max_length=16, null=True, verbose_name='IČO')), - ('date_of_birth', models.DateField(blank=True, null=True, verbose_name='Datum narození')), - ('representative_name', models.CharField(blank=True, max_length=256, null=True, verbose_name='Zástupce')), - ('representative_role', models.CharField(blank=True, max_length=256, null=True, verbose_name='Funkce zástupce')), - ('department', models.CharField(blank=True, max_length=128, null=True, verbose_name='Organizační složka')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=256, verbose_name="Jméno")), + ( + "is_legal_entity", + models.BooleanField(verbose_name="Je právnická osoba"), + ), + ( + "address_street_with_number", + models.CharField(max_length=256, verbose_name="Ulice, č.p."), + ), + ( + "address_district", + models.CharField(max_length=256, verbose_name="Obec"), + ), + ("address_zip", models.CharField(max_length=16, verbose_name="PSČ")), + ( + "address_country", + django_countries.fields.CountryField( + max_length=2, verbose_name="Země" + ), + ), + ( + "ico_number", + models.CharField( + blank=True, max_length=16, null=True, verbose_name="IČO" + ), + ), + ( + "date_of_birth", + models.DateField( + blank=True, null=True, verbose_name="Datum narození" + ), + ), + ( + "representative_name", + models.CharField( + blank=True, max_length=256, null=True, verbose_name="Zástupce" + ), + ), + ( + "representative_role", + models.CharField( + blank=True, + max_length=256, + null=True, + verbose_name="Funkce zástupce", + ), + ), + ( + "department", + models.CharField( + blank=True, + max_length=128, + null=True, + verbose_name="Organizační složka", + ), + ), ], options={ - 'verbose_name': 'Druhá smluvní strana', - 'verbose_name_plural': 'Druhé smluvní strany', + "verbose_name": "Druhá smluvní strana", + "verbose_name_plural": "Druhé smluvní strany", }, ), migrations.CreateModel( - name='ContractFilingArea', + name="ContractFilingArea", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=32, verbose_name='Jméno')), - ('person_responsible', models.CharField(max_length=256, verbose_name='Odpovědná osoba')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=32, verbose_name="Jméno")), + ( + "person_responsible", + models.CharField(max_length=256, verbose_name="Odpovědná osoba"), + ), ], options={ - 'verbose_name': 'Spisovna', - 'verbose_name_plural': 'Spisovny', + "verbose_name": "Spisovna", + "verbose_name_plural": "Spisovny", }, ), migrations.CreateModel( - name='ContractIssue', + name="ContractIssue", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=32, verbose_name='Jméno')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=32, verbose_name="Jméno")), ], options={ - 'verbose_name': 'Problém se smlouvou', - 'verbose_name_plural': 'Problémy se smlouvou', + "verbose_name": "Problém se smlouvou", + "verbose_name_plural": "Problémy se smlouvou", }, ), migrations.CreateModel( - name='ContractLocalSigner', + name="ContractLocalSigner", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=256, verbose_name='Jméno')), - ('address_street_with_number', models.CharField(max_length=256, verbose_name='Ulice, č.p.')), - ('address_district', models.CharField(max_length=256, verbose_name='Obec')), - ('address_zip', models.CharField(max_length=16, verbose_name='PSČ')), - ('address_country', django_countries.fields.CountryField(max_length=2, verbose_name='Země')), - ('ico_number', models.CharField(blank=True, max_length=16, null=True, verbose_name='IČO')), - ('color', models.CharField(max_length=6, verbose_name='Barva')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=256, verbose_name="Jméno")), + ( + "address_street_with_number", + models.CharField(max_length=256, verbose_name="Ulice, č.p."), + ), + ( + "address_district", + models.CharField(max_length=256, verbose_name="Obec"), + ), + ("address_zip", models.CharField(max_length=16, verbose_name="PSČ")), + ( + "address_country", + django_countries.fields.CountryField( + max_length=2, verbose_name="Země" + ), + ), + ( + "ico_number", + models.CharField( + blank=True, max_length=16, null=True, verbose_name="IČO" + ), + ), + ("color", models.CharField(max_length=6, verbose_name="Barva")), ], options={ - 'verbose_name': 'Naše smluvní strana', - 'verbose_name_plural': 'Naše smlouvní strany', + "verbose_name": "Naše smluvní strana", + "verbose_name_plural": "Naše smlouvní strany", }, ), migrations.CreateModel( - name='ContractSubtype', + name="ContractSubtype", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=32, verbose_name='Jméno')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=32, verbose_name="Jméno")), ], options={ - 'verbose_name': 'Podtyp smlouvy', - 'verbose_name_plural': 'Podtypy smlouvy', + "verbose_name": "Podtyp smlouvy", + "verbose_name_plural": "Podtypy smlouvy", }, ), migrations.CreateModel( - name='ContractNote', + name="ContractNote", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_date', models.DateTimeField(verbose_name='Datum vytvoření')), - ('content', markdownx.models.MarkdownxField(verbose_name='Obsah')), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contract_notes', to=settings.AUTH_USER_MODEL, verbose_name='Autor')), - ('contract', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shared.contract')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_date", models.DateTimeField(verbose_name="Datum vytvoření")), + ("content", markdownx.models.MarkdownxField(verbose_name="Obsah")), + ( + "author", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="contract_notes", + to=settings.AUTH_USER_MODEL, + verbose_name="Autor", + ), + ), + ( + "contract", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="shared.contract", + ), + ), ], options={ - 'verbose_name': 'Poznámka ke smlouvě', - 'verbose_name_plural': 'Poznámky ke smlouvě', + "verbose_name": "Poznámka ke smlouvě", + "verbose_name_plural": "Poznámky ke smlouvě", }, ), migrations.AddField( - model_name='contract', - name='external_signer', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shared.contractexternalsigner'), + model_name="contract", + name="external_signer", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="shared.contractexternalsigner", + ), ), migrations.AddField( - model_name='contract', - name='filing_area', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='shared.contractfilingarea'), + model_name="contract", + name="filing_area", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="shared.contractfilingarea", + ), ), migrations.AddField( - model_name='contract', - name='issues', - field=models.ManyToManyField(to='shared.contractissue'), + model_name="contract", + name="issues", + field=models.ManyToManyField(to="shared.contractissue"), ), migrations.AddField( - model_name='contract', - name='local_signer', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shared.contractlocalsigner'), + model_name="contract", + name="local_signer", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="shared.contractlocalsigner", + ), ), migrations.AddField( - model_name='contract', - name='primary_contract', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='shared.contract', verbose_name='Hlavní smlouva'), + model_name="contract", + name="primary_contract", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="shared.contract", + verbose_name="Hlavní smlouva", + ), ), migrations.AddField( - model_name='contract', - name='public_status_set_by', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='public_status_altered_contracts', to=settings.AUTH_USER_MODEL, verbose_name='Zveřejněno / nezveřejněno uživatelem'), + model_name="contract", + name="public_status_set_by", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="public_status_altered_contracts", + to=settings.AUTH_USER_MODEL, + verbose_name="Zveřejněno / nezveřejněno uživatelem", + ), ), migrations.AddField( - model_name='contract', - name='subtype', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shared.contractsubtype', verbose_name='Podtyp'), + model_name="contract", + name="subtype", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="shared.contractsubtype", + verbose_name="Podtyp", + ), ), migrations.AddField( - model_name='contract', - name='uploaded_by', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='uploaded_contracts', to=settings.AUTH_USER_MODEL, verbose_name='Nahráno uživatelem'), + model_name="contract", + name="uploaded_by", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="uploaded_contracts", + to=settings.AUTH_USER_MODEL, + verbose_name="Nahráno uživatelem", + ), ), ] diff --git a/shared/migrations/0002_contractlocalsigner_department_and_more.py b/shared/migrations/0002_contractlocalsigner_department_and_more.py index 83f3534982a057a665fb11c3ac4b092cce543e3d..010d1a213b41d265fa8d9b84f5d533e3f5a66cb2 100644 --- a/shared/migrations/0002_contractlocalsigner_department_and_more.py +++ b/shared/migrations/0002_contractlocalsigner_department_and_more.py @@ -1,59 +1,78 @@ # Generated by Django 4.1.4 on 2023-02-03 05:01 -from django.db import migrations, models import django_countries.fields +from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shared', '0001_initial'), + ("shared", "0001_initial"), ] operations = [ migrations.AddField( - model_name='contractlocalsigner', - name='department', - field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Organizační složka'), + model_name="contractlocalsigner", + name="department", + field=models.CharField( + blank=True, max_length=128, null=True, verbose_name="Organizační složka" + ), ), migrations.AddField( - model_name='contractlocalsigner', - name='representative_name', - field=models.CharField(blank=True, max_length=256, null=True, verbose_name='Zástupce'), + model_name="contractlocalsigner", + name="representative_name", + field=models.CharField( + blank=True, max_length=256, null=True, verbose_name="Zástupce" + ), ), migrations.AddField( - model_name='contractlocalsigner', - name='representative_role', - field=models.CharField(blank=True, max_length=256, null=True, verbose_name='Funkce zástupce'), + model_name="contractlocalsigner", + name="representative_role", + field=models.CharField( + blank=True, max_length=256, null=True, verbose_name="Funkce zástupce" + ), ), migrations.AlterField( - model_name='contractlocalsigner', - name='address_country', - field=django_countries.fields.CountryField(default='CZ', max_length=2, verbose_name='Země'), + model_name="contractlocalsigner", + name="address_country", + field=django_countries.fields.CountryField( + default="CZ", max_length=2, verbose_name="Země" + ), ), migrations.AlterField( - model_name='contractlocalsigner', - name='address_district', - field=models.CharField(default='Praha 2', max_length=256, verbose_name='Obec'), + model_name="contractlocalsigner", + name="address_district", + field=models.CharField( + default="Praha 2", max_length=256, verbose_name="Obec" + ), ), migrations.AlterField( - model_name='contractlocalsigner', - name='address_street_with_number', - field=models.CharField(default='Na Moráni 360/3', max_length=256, verbose_name='Ulice, č.p.'), + model_name="contractlocalsigner", + name="address_street_with_number", + field=models.CharField( + default="Na Moráni 360/3", max_length=256, verbose_name="Ulice, č.p." + ), ), migrations.AlterField( - model_name='contractlocalsigner', - name='address_zip', - field=models.CharField(default='128 00', max_length=16, verbose_name='PSČ'), + model_name="contractlocalsigner", + name="address_zip", + field=models.CharField(default="128 00", max_length=16, verbose_name="PSČ"), ), migrations.AlterField( - model_name='contractlocalsigner', - name='ico_number', - field=models.CharField(blank=True, default='71339698', max_length=16, null=True, verbose_name='IČO'), + model_name="contractlocalsigner", + name="ico_number", + field=models.CharField( + blank=True, + default="71339698", + max_length=16, + null=True, + verbose_name="IČO", + ), ), migrations.AlterField( - model_name='contractlocalsigner', - name='name', - field=models.CharField(default='Česká pirátská strana', max_length=256, verbose_name='Jméno'), + model_name="contractlocalsigner", + name="name", + field=models.CharField( + default="Česká pirátská strana", max_length=256, verbose_name="Jméno" + ), ), ] diff --git a/shared/models.py b/shared/models.py index c1dd8791143801eb3d7c99bb371385abaff71e58..6e90b497a5ce692982fb53e26041385f5ef4f5eb 100644 --- a/shared/models.py +++ b/shared/models.py @@ -1,6 +1,5 @@ from django.conf import settings from django.db import models - from django_countries.fields import CountryField from markdownx.models import MarkdownxField from pirates import models as pirates_models @@ -16,12 +15,10 @@ class ContractExternalSigner(models.Model): verbose_name="Jméno", ) - is_legal_entity = models.BooleanField( verbose_name="Je právnická osoba", ) - address_street_with_number = models.CharField( max_length=256, verbose_name="Ulice, č.p.", @@ -41,7 +38,6 @@ class ContractExternalSigner(models.Model): verbose_name="Země", ) - ico_number = models.CharField( max_length=16, blank=True, @@ -55,7 +51,6 @@ class ContractExternalSigner(models.Model): verbose_name="Datum narození", ) # WARNING: Legal entity status dependent! - representative_name = models.CharField( max_length=256, blank=True, @@ -70,7 +65,6 @@ class ContractExternalSigner(models.Model): verbose_name="Funkce zástupce", ) - department = models.CharField( max_length=128, blank=True, @@ -78,7 +72,6 @@ class ContractExternalSigner(models.Model): verbose_name="Organizační složka", ) - class Meta: verbose_name = "Druhá smluvní strana" verbose_name_plural = "Druhé smluvní strany" @@ -91,7 +84,6 @@ class ContractLocalSigner(models.Model): verbose_name="Jméno", ) - address_street_with_number = models.CharField( max_length=256, default=settings.DEFAULT_LCOAL_SIGNER_STREET, @@ -115,7 +107,6 @@ class ContractLocalSigner(models.Model): verbose_name="Země", ) - ico_number = models.CharField( max_length=16, blank=True, @@ -124,7 +115,6 @@ class ContractLocalSigner(models.Model): verbose_name="IČO", ) - representative_name = models.CharField( max_length=256, blank=True, @@ -139,7 +129,6 @@ class ContractLocalSigner(models.Model): verbose_name="Funkce zástupce", ) - department = models.CharField( max_length=128, blank=True, @@ -147,14 +136,12 @@ class ContractLocalSigner(models.Model): verbose_name="Organizační složka", ) - # TODO: Input validation color = models.CharField( - max_length=6, # e.g. "ffffff" + max_length=6, # e.g. "ffffff" verbose_name="Barva", ) - class Meta: verbose_name = "Naše smluvní strana" verbose_name_plural = "Naše smlouvní strany" @@ -166,7 +153,6 @@ class ContractSubtype(models.Model): verbose_name="Jméno", ) - class Meta: verbose_name = "Podtyp smlouvy" verbose_name_plural = "Podtypy smlouvy" @@ -178,7 +164,6 @@ class ContractIssue(models.Model): verbose_name="Jméno", ) - class Meta: verbose_name = "Problém se smlouvou" verbose_name_plural = "Problémy se smlouvou" @@ -195,7 +180,6 @@ class ContractFilingArea(models.Model): verbose_name="Odpovědná osoba", ) - class Meta: verbose_name = "Spisovna" verbose_name_plural = "Spisovny" @@ -220,7 +204,6 @@ class Contract(models.Model): verbose_name="Podtyp", ) - contains_nda = models.BooleanField( default=False, verbose_name="Obsahuje NDA", @@ -231,7 +214,6 @@ class Contract(models.Model): verbose_name="Je anonymizovaná", ) # WARNING: Seems to only be used for amendments - external_signer = models.ForeignKey( ContractExternalSigner, on_delete=models.CASCADE, @@ -255,15 +237,11 @@ class Contract(models.Model): verbose_name="Datum podpisu všech stran", ) # WARNING: Exclude in admin, autofill - - valid_start_date = models.DateField( - verbose_name="Začátek účinnosti" - ) + valid_start_date = models.DateField(verbose_name="Začátek účinnosti") valid_end_date = models.DateField( verbose_name="Začátek platnosti", ) - uploaded_by = models.ForeignKey( User, on_delete=models.CASCADE, @@ -271,7 +249,6 @@ class Contract(models.Model): verbose_name="Nahráno uživatelem", ) - class LegalStates(models.TextChoices): VALID = "valid", "Platná" EFFECTIVE = "effective", "Účinná" @@ -307,7 +284,6 @@ class Contract(models.Model): verbose_name="Stav papírové formy", ) - public_status_set_by = models.ForeignKey( User, on_delete=models.CASCADE, @@ -315,7 +291,6 @@ class Contract(models.Model): verbose_name="Zveřejněno / nezveřejněno uživatelem", ) - publishing_rejection_comment = models.CharField( max_length=65536, blank=True, @@ -323,7 +298,6 @@ class Contract(models.Model): verbose_name="Důvod nezveřejnění", ) - tender_url = models.URLField( max_length=256, blank=True, @@ -331,16 +305,13 @@ class Contract(models.Model): verbose_name="Odkaz na výběrové řízení", ) - identifier = models.CharField( max_length=128, verbose_name="Identifikační číslo", ) - issues = models.ManyToManyField(ContractIssue) - summary = models.CharField( max_length=65536, blank=True, @@ -348,7 +319,6 @@ class Contract(models.Model): verbose_name="Rekapitulace", ) - contract_file = models.FileField( verbose_name="Smlouva (PDF)", ) @@ -361,23 +331,13 @@ class Contract(models.Model): verbose_name="Hlavní smlouva", ) # WARNING: Dependent on the type! + expected_cost_total = models.IntegerField(verbose_name="Očekáváná celková cena") - expected_cost_total = models.IntegerField( - verbose_name="Očekáváná celková cena" - ) + expected_cost_year = models.IntegerField(verbose_name="Očekáváná cena za rok") - expected_cost_year = models.IntegerField( - verbose_name="Očekáváná cena za rok" - ) - - expected_cost_month = models.IntegerField( - verbose_name="Očekáváná cena za měsíc" - ) - - expected_cost_hour = models.IntegerField( - verbose_name="Očekáváná cena za hodinu" - ) + expected_cost_month = models.IntegerField(verbose_name="Očekáváná cena za měsíc") + expected_cost_hour = models.IntegerField(verbose_name="Očekáváná cena za hodinu") intent_url = models.URLField( max_length=256, @@ -393,7 +353,6 @@ class Contract(models.Model): verbose_name="Odkaz na schválení", ) # WARNING: Dependent on the type! - filing_area = models.ForeignKey( ContractFilingArea, on_delete=models.CASCADE, @@ -401,7 +360,6 @@ class Contract(models.Model): null=True, ) # WARNING: Dependent on the type! - class Meta: verbose_name = "Smlouva" verbose_name_plural = "Smlouvy" @@ -413,7 +371,6 @@ class ContractNote(models.Model): on_delete=models.CASCADE, ) - author = models.ForeignKey( User, related_name="contract_notes", @@ -429,7 +386,6 @@ class ContractNote(models.Model): verbose_name="Obsah", ) - class Meta: verbose_name = "Poznámka ke smlouvě" verbose_name_plural = "Poznámky ke smlouvě"