diff --git a/.env.example b/.env.example index 855246ae4..4667e35fc 100644 --- a/.env.example +++ b/.env.example @@ -80,7 +80,7 @@ ALLOW_REMOTE_USER_AUTH=False LOCATIONS_SEARCH_API="https://api3.geo.admin.ch/rest/services/api/SearchServer" LOCATIONS_SEARCH_API_DETAILS="https://api3.geo.admin.ch/rest/services/api/MapServer/ch.bfs.gebaeude_wohnungs_register/" # Local directory on docker host for temporary storage of archive folders -ARCHIVE_DIR= +ARCHIVE_DIR=archive # Isolated network for print service # This has to be unique for multiple instance on same docker host ISOLATED_NETWORK_NAME=geocity_isolated_1 diff --git a/README.md b/README.md index a052bcfbe..6c41457e2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **[What is Geocity ?](https://geocity-asso.ch)** -**[Features and user guide](https://github.com/yverdon/geocity/wiki)** +**[Features and user guide](https://gitlab.com/geocity/geocity/-/wikis/home)** ## Setting up full Docker non persistent demo diff --git a/geocity/apps/accounts/dootix/adapter.py b/geocity/apps/accounts/dootix/adapter.py index 420e73581..328813581 100644 --- a/geocity/apps/accounts/dootix/adapter.py +++ b/geocity/apps/accounts/dootix/adapter.py @@ -41,6 +41,7 @@ def save_user(self, request, sociallogin: SocialLogin, form=None): address=form.cleaned_data["address"], zipcode=form.cleaned_data["zipcode"], city=form.cleaned_data["city"], + country=form.cleaned_data["country"], phone_first=form.cleaned_data["phone_first"], phone_second=form.cleaned_data["phone_second"], company_name=form.cleaned_data["company_name"], diff --git a/geocity/apps/accounts/forms.py b/geocity/apps/accounts/forms.py index f4161a006..678a4215e 100644 --- a/geocity/apps/accounts/forms.py +++ b/geocity/apps/accounts/forms.py @@ -5,8 +5,9 @@ from django.conf import settings from django.contrib.auth import authenticate from django.contrib.auth.forms import AuthenticationForm, BaseUserCreationForm -from django.core.validators import MaxValueValidator, MinValueValidator, RegexValidator +from django.core.validators import MinValueValidator, RegexValidator from django.utils.translation import gettext_lazy as _ +from django_countries.fields import CountryField from geocity.fields import AddressWidget @@ -226,8 +227,8 @@ def __init__(self, *args, **kwargs): ) zipcode = forms.IntegerField( - label=_("NPA"), - validators=[MinValueValidator(1000), MaxValueValidator(9999)], + label=_("Code postal"), + validators=[MinValueValidator(1)], widget=forms.NumberInput(attrs={"required": "required"}), ) city = forms.CharField( @@ -245,6 +246,7 @@ class Meta: "address", "zipcode", "city", + "country", "phone_first", "phone_second", "company_name", @@ -295,11 +297,11 @@ class SocialSignupForm(SignupForm): ) zipcode = forms.IntegerField( - label=_("NPA"), - min_value=1000, - max_value=9999, + label=_("Code postal"), + min_value=1, widget=forms.NumberInput(attrs={"required": "required"}), ) + city = forms.CharField( max_length=100, label=_("Ville"), @@ -307,6 +309,9 @@ class SocialSignupForm(SignupForm): attrs={"placeholder": "ex: Yverdon", "required": "required"} ), ) + + country = CountryField().formfield(initial="CH") + phone_first = forms.CharField( label=_("Téléphone principal"), max_length=20, @@ -314,7 +319,7 @@ class SocialSignupForm(SignupForm): widget=forms.TextInput(attrs={"placeholder": "ex: 024 111 22 22"}), validators=[ RegexValidator( - regex=r"^(((\+41)\s?)|(0))?(\d{2})\s?(\d{3})\s?(\d{2})\s?(\d{2})$", + regex=r"^(?:\+(?:[0-9] ?){6,14}[0-9]|0\d(?: ?\d){8,13})$", message="Seuls les chiffres et les espaces sont autorisés.", ) ], diff --git a/geocity/apps/accounts/geomapfish/adapter.py b/geocity/apps/accounts/geomapfish/adapter.py index 1a0672514..9ad43c4d0 100644 --- a/geocity/apps/accounts/geomapfish/adapter.py +++ b/geocity/apps/accounts/geomapfish/adapter.py @@ -42,6 +42,7 @@ def save_user(self, request, sociallogin: SocialLogin, form=None): address=form.cleaned_data["address"], zipcode=form.cleaned_data["zipcode"], city=form.cleaned_data["city"], + country=form.cleaned_data["country"], phone_first=form.cleaned_data["phone_first"], phone_second=form.cleaned_data["phone_second"], company_name=form.cleaned_data["company_name"], diff --git a/geocity/apps/accounts/migrations/0020_historicaluserprofile_country_userprofile_country.py b/geocity/apps/accounts/migrations/0020_historicaluserprofile_country_userprofile_country.py new file mode 100644 index 000000000..5a6314239 --- /dev/null +++ b/geocity/apps/accounts/migrations/0020_historicaluserprofile_country_userprofile_country.py @@ -0,0 +1,38 @@ +# Generated by Django 4.2.11 on 2024-05-29 09:09 + +import django_countries.fields +from django.db import migrations + + +def set_country_to_null(apps, schema_editor): + UserProfile = apps.get_model("accounts", "UserProfile") + HistoricalUserProfile = apps.get_model("accounts", "HistoricalUserProfile") + + UserProfile.objects.all().update(country=None) + HistoricalUserProfile.objects.all().update(country=None) + + +class Migration(migrations.Migration): + + dependencies = [ + ("accounts", "0019_administrativeentity_agenda_domain"), + ] + + operations = [ + migrations.AddField( + model_name="historicaluserprofile", + name="country", + field=django_countries.fields.CountryField( + default="CH", max_length=2, null=True, verbose_name="Pays" + ), + ), + migrations.AddField( + model_name="userprofile", + name="country", + field=django_countries.fields.CountryField( + default="CH", max_length=2, null=True, verbose_name="Pays" + ), + ), + # Dont add the default value to the existing users + migrations.RunPython(set_country_to_null), + ] diff --git a/geocity/apps/accounts/migrations/0021_alter_administrativeentity_phone_and_more.py b/geocity/apps/accounts/migrations/0021_alter_administrativeentity_phone_and_more.py new file mode 100644 index 000000000..8267468f2 --- /dev/null +++ b/geocity/apps/accounts/migrations/0021_alter_administrativeentity_phone_and_more.py @@ -0,0 +1,97 @@ +# Generated by Django 4.2.11 on 2024-05-30 08:58 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("accounts", "0020_historicaluserprofile_country_userprofile_country"), + ] + + operations = [ + migrations.AlterField( + model_name="administrativeentity", + name="phone", + field=models.CharField( + blank=True, + max_length=20, + validators=[ + django.core.validators.RegexValidator( + message="Seuls les chiffres et les espaces sont autorisés.", + regex="^(?:\\+(?:[0-9] ?){6,14}[0-9]|0\\d(?: ?\\d){8,13})$", + ) + ], + verbose_name="Téléphone", + ), + ), + migrations.AlterField( + model_name="historicaluserprofile", + name="phone_first", + field=models.CharField( + max_length=20, + validators=[ + django.core.validators.RegexValidator( + message="Seuls les chiffres et les espaces sont autorisés.", + regex="^(?:\\+(?:[0-9] ?){6,14}[0-9]|0\\d(?: ?\\d){8,13})$", + ) + ], + verbose_name="Téléphone principal", + ), + ), + migrations.AlterField( + model_name="historicaluserprofile", + name="phone_second", + field=models.CharField( + blank=True, + max_length=20, + validators=[ + django.core.validators.RegexValidator( + message="Seuls les chiffres et les espaces sont autorisés.", + regex="^(?:\\+(?:[0-9] ?){6,14}[0-9]|0\\d(?: ?\\d){8,13})$", + ) + ], + verbose_name="Téléphone secondaire", + ), + ), + migrations.AlterField( + model_name="historicaluserprofile", + name="zipcode", + field=models.PositiveIntegerField(verbose_name="Code postal"), + ), + migrations.AlterField( + model_name="userprofile", + name="phone_first", + field=models.CharField( + max_length=20, + validators=[ + django.core.validators.RegexValidator( + message="Seuls les chiffres et les espaces sont autorisés.", + regex="^(?:\\+(?:[0-9] ?){6,14}[0-9]|0\\d(?: ?\\d){8,13})$", + ) + ], + verbose_name="Téléphone principal", + ), + ), + migrations.AlterField( + model_name="userprofile", + name="phone_second", + field=models.CharField( + blank=True, + max_length=20, + validators=[ + django.core.validators.RegexValidator( + message="Seuls les chiffres et les espaces sont autorisés.", + regex="^(?:\\+(?:[0-9] ?){6,14}[0-9]|0\\d(?: ?\\d){8,13})$", + ) + ], + verbose_name="Téléphone secondaire", + ), + ), + migrations.AlterField( + model_name="userprofile", + name="zipcode", + field=models.PositiveIntegerField(verbose_name="Code postal"), + ), + ] diff --git a/geocity/apps/accounts/models.py b/geocity/apps/accounts/models.py index 0f1ad8aa7..a1239a217 100644 --- a/geocity/apps/accounts/models.py +++ b/geocity/apps/accounts/models.py @@ -3,12 +3,7 @@ from django.contrib.gis.db import models as geomodels from django.contrib.sites.models import Site from django.core.exceptions import ObjectDoesNotExist, ValidationError -from django.core.validators import ( - FileExtensionValidator, - MaxValueValidator, - MinValueValidator, - RegexValidator, -) +from django.core.validators import FileExtensionValidator, RegexValidator from django.db import models from django.db.models import BooleanField, Count, ExpressionWrapper, Q, UniqueConstraint from django.db.models.signals import post_save @@ -17,6 +12,7 @@ from django.utils.functional import cached_property from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ +from django_countries.fields import CountryField from simple_history.models import HistoricalRecords from taggit.managers import TaggableManager @@ -293,7 +289,7 @@ class AdministrativeEntity(models.Model): max_length=20, validators=[ RegexValidator( - regex=r"^(((\+41)\s?)|(0))?(\d{2})\s?(\d{3})\s?(\d{2})\s?(\d{2})$", + regex=r"^(?:\+(?:[0-9] ?){6,14}[0-9]|0\d(?: ?\d){8,13})$", message="Seuls les chiffres et les espaces sont autorisés.", ) ], @@ -583,19 +579,24 @@ class UserProfile(models.Model): max_length=100, ) zipcode = models.PositiveIntegerField( - _("NPA"), - validators=[MinValueValidator(1000), MaxValueValidator(9999)], + _("Code postal"), ) city = models.CharField( _("Ville"), max_length=100, ) + country = CountryField( + _("Pays"), + null=True, + blank=False, + default="CH", + ) phone_first = models.CharField( _("Téléphone principal"), max_length=20, validators=[ RegexValidator( - regex=r"^(((\+41)\s?)|(0))?(\d{2})\s?(\d{3})\s?(\d{2})\s?(\d{2})$", + regex=r"^(?:\+(?:[0-9] ?){6,14}[0-9]|0\d(?: ?\d){8,13})$", message="Seuls les chiffres et les espaces sont autorisés.", ) ], @@ -606,7 +607,7 @@ class UserProfile(models.Model): max_length=20, validators=[ RegexValidator( - regex=r"^(((\+41)\s?)|(0))?(\d{2})\s?(\d{3})\s?(\d{2})\s?(\d{2})$", + regex=r"^(?:\+(?:[0-9] ?){6,14}[0-9]|0\d(?: ?\d){8,13})$", message="Seuls les chiffres et les espaces sont autorisés.", ) ], diff --git a/geocity/apps/api/serializers.py b/geocity/apps/api/serializers.py index 9a165860f..94c9566fe 100644 --- a/geocity/apps/api/serializers.py +++ b/geocity/apps/api/serializers.py @@ -451,6 +451,7 @@ class Meta: "zipcode", "user_id", "city", + "country", "company_name", "vat_number", "iban", diff --git a/geocity/apps/api/services.py b/geocity/apps/api/services.py index a5e0d6451..75de5266b 100644 --- a/geocity/apps/api/services.py +++ b/geocity/apps/api/services.py @@ -3,6 +3,7 @@ from io import BytesIO from django.conf import settings +from django.core.exceptions import SuspiciousOperation from django.db.models import Q from django.utils.text import get_valid_filename from PIL import Image @@ -22,7 +23,11 @@ def get_mime_type(content): """ Used to retrieve mime type in response.content of request """ - image = Image.open(BytesIO(content)) + try: + image = Image.open(BytesIO(content)) + except: + raise SuspiciousOperation + image_format = image.format mime_type = "image/" + image_format.lower() return mime_type diff --git a/geocity/apps/core/static/css/contactform.css b/geocity/apps/core/static/css/contactform.css index 94ce36ce7..b4c9831c8 100644 --- a/geocity/apps/core/static/css/contactform.css +++ b/geocity/apps/core/static/css/contactform.css @@ -11,3 +11,8 @@ select[readonly] { border: 0; font-weight: bold; } + +.disabled-dropdown { + background-color: #e9ecef; + pointer-events: none; +} diff --git a/geocity/apps/core/static/js/submission_contacts.js b/geocity/apps/core/static/js/submission_contacts.js index adc69c206..adbb68bfd 100644 --- a/geocity/apps/core/static/js/submission_contacts.js +++ b/geocity/apps/core/static/js/submission_contacts.js @@ -1,15 +1,30 @@ let update_form_value = function(item, userprofile) { - if (document.getElementById(`self_contact_${parseInt(item) + 1}`).checked == true) { document.getElementById(`id_form-${item}-first_name`).value = userprofile.first_name; for (const [key, value] of Object.entries(userprofile)) { - document.getElementById(`id_form-${item}-${key}`).value = value; - document.getElementById(`id_form-${item}-${key}`).readOnly = true; + let element = document.getElementById(`id_form-${item}-${key}`); + if (element !== null) { + element.value = value; + // Pseudo disable the dropdown with CSS instead of setting it read-only + if (key === "country") { + element.classList.add("disabled-dropdown"); + } else { + element.readOnly = true; + } + } } } else { for (const [key, value] of Object.entries(userprofile)) { - document.getElementById(`id_form-${item}-${key}`).value = ''; - document.getElementById(`id_form-${item}-${key}`).readOnly = false; + let element = document.getElementById(`id_form-${item}-${key}`); + if (element !== null) { + element.value = ''; + element.readOnly = false; + if (key === "country") { + element.classList.remove("disabled-dropdown"); + } else { + element.readOnly = false; + } + } } } } @@ -17,7 +32,11 @@ let update_form_value = function(item, userprofile) { // Create a label to replace .form-control without .extra-form in classes inside of forms-container window.addEventListener('load', function () { var forms_control = document.querySelectorAll("[id=forms-container] select[class*=form-control]"); - for (form_control of forms_control) { + for (let form_control of forms_control) { + // Skip the country select field + if (form_control.classList.contains("country")) { + continue; + } let elem = document.createElement('label'); let text = form_control.querySelector("option[selected]").text let div = form_control.closest('.col-md-9'); diff --git a/geocity/apps/forms/migrations/0036_alter_formcategory_meta_type.py b/geocity/apps/forms/migrations/0036_alter_formcategory_meta_type.py new file mode 100644 index 000000000..82ee85ae3 --- /dev/null +++ b/geocity/apps/forms/migrations/0036_alter_formcategory_meta_type.py @@ -0,0 +1,31 @@ +# Generated by Django 4.2.11 on 2024-06-03 06:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("forms", "0035_service_fee"), + ] + + operations = [ + migrations.AlterField( + model_name="formcategory", + name="meta_type", + field=models.IntegerField( + choices=[ + (0, "Autres"), + (1, "Chantier"), + (2, "Construction"), + (3, "Événement sportif"), + (4, "Événement culturel"), + (5, "Événement commercial"), + (6, "Dispositif de police"), + ], + default=0, + help_text="Utilisé dans le calendrier afin de filtrer par type d'événement", + verbose_name="Type générique", + ), + ), + ] diff --git a/geocity/apps/forms/models.py b/geocity/apps/forms/models.py index 3d58c8a44..e69a98661 100644 --- a/geocity/apps/forms/models.py +++ b/geocity/apps/forms/models.py @@ -60,7 +60,10 @@ class FormCategory(models.Model): limit_choices_to={"permit_department__is_integrator_admin": True}, ) meta_type = models.IntegerField( - _("Type générique"), choices=META_TYPE_CHOICES, default=META_TYPE_OTHER + _("Type générique"), + choices=META_TYPE_CHOICES, + default=META_TYPE_OTHER, + help_text="Utilisé dans le calendrier afin de filtrer par type d'événement", ) tags = TaggableManager( blank=True, diff --git a/geocity/apps/reports/templates/reports/sections/sectionauthor.html b/geocity/apps/reports/templates/reports/sections/sectionauthor.html index 725123cdd..2d44d7d4a 100644 --- a/geocity/apps/reports/templates/reports/sections/sectionauthor.html +++ b/geocity/apps/reports/templates/reports/sections/sectionauthor.html @@ -18,11 +18,14 @@ Adresse : {{submission.author.userprofile.address}}
{% endif %} {% if submission.author.userprofile.zipcode %} - NPA : {{submission.author.userprofile.zipcode}}
+ Code postal : {{submission.author.userprofile.zipcode}}
{% endif %} {% if submission.author.userprofile.city %} Localité : {{submission.author.userprofile.city}}
{% endif %} + {% if submission.author.userprofile.country %} + Pays : {{submission.author.userprofile.country.name}}
+ {% endif %} {% if submission.author.userprofile.company_name %} Raison sociale : {{submission.author.userprofile.company_name}}
{% endif %} diff --git a/geocity/apps/reports/templates/reports/sections/sectioncontact.html b/geocity/apps/reports/templates/reports/sections/sectioncontact.html index d5d959e06..89d1eec45 100644 --- a/geocity/apps/reports/templates/reports/sections/sectioncontact.html +++ b/geocity/apps/reports/templates/reports/sections/sectioncontact.html @@ -23,11 +23,14 @@ Adresse : {{contact.address}}
{% endif %} {% if contact.zipcode %} - NPA : {{contact.zipcode}}
+ Code postal : {{contact.zipcode}}
{% endif %} {% if contact.city %} Localité : {{contact.city}}
{% endif %} + {% if contact.country %} + Pays : {{contact.country.name}}
+ {% endif %} {% if contact.company_name %} Raison sociale : {{contact.company_name}}
{% endif %} diff --git a/geocity/apps/reports/templates/reports/sections/sectionrecipient.html b/geocity/apps/reports/templates/reports/sections/sectionrecipient.html index ff316c27b..25453b243 100644 --- a/geocity/apps/reports/templates/reports/sections/sectionrecipient.html +++ b/geocity/apps/reports/templates/reports/sections/sectionrecipient.html @@ -13,6 +13,9 @@ {{recipient.last_name}} {{recipient.first_name}}
{{recipient.address}}
{{recipient.zipcode}} {{recipient.city}} + {% if recipient.country %} +
{{recipient.country.name}} + {% endif %} {% endblock %} diff --git a/geocity/apps/submissions/forms.py b/geocity/apps/submissions/forms.py index 903150034..f6fbd939e 100644 --- a/geocity/apps/submissions/forms.py +++ b/geocity/apps/submissions/forms.py @@ -18,15 +18,15 @@ from django.contrib.gis import forms as geoforms from django.core.exceptions import ValidationError from django.core.files import File -from django.core.validators import MaxValueValidator, MinValueValidator, RegexValidator +from django.core.validators import MinValueValidator, RegexValidator from django.db import transaction from django.db.models import Max, Q from django.forms import modelformset_factory from django.urls import reverse from django.utils import timezone -from django.utils.safestring import mark_safe from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ +from django_countries.fields import CountryField from django_select2.forms import Select2MultipleWidget, Select2Widget from geocity.apps.accounts.models import ( @@ -898,8 +898,8 @@ class SubmissionContactForm(forms.ModelForm): "company_name", "vat_number", "address", - "address", "city", + "country", "phone", "zipcode", "email", @@ -934,10 +934,8 @@ class SubmissionContactForm(forms.ModelForm): ), validators=[ RegexValidator( - regex=r"^(((\+41)\s?)|(0))?(\d{2})\s?(\d{3})\s?(\d{2})\s?(\d{2})$", - message=mark_safe( - 'Veuillez saisir un numéro de téléphone suisse valide.' - ), + regex=r"^(?:\+(?:[0-9] ?){6,14}[0-9]|0\d(?: ?\d){8,13})$", + message="Seuls les chiffres et les espaces sont autorisés.", ) ], ) @@ -962,8 +960,8 @@ class SubmissionContactForm(forms.ModelForm): ) zipcode = forms.IntegerField( - label=_("NPA"), - validators=[MinValueValidator(1000), MaxValueValidator(9999)], + label=_("Code postal"), + validators=[MinValueValidator(1)], widget=forms.NumberInput(), ) city = forms.CharField( @@ -975,6 +973,10 @@ class SubmissionContactForm(forms.ModelForm): } ), ) + country = CountryField().formfield( + label=_("Pays"), + widget=forms.Select(attrs={"class": "country"}), + ) company_name = forms.CharField( required=False, label=_("Raison sociale"), diff --git a/geocity/apps/submissions/migrations/0031_contact_country_historicalcontact_country.py b/geocity/apps/submissions/migrations/0031_contact_country_historicalcontact_country.py new file mode 100644 index 000000000..3193e7aeb --- /dev/null +++ b/geocity/apps/submissions/migrations/0031_contact_country_historicalcontact_country.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.11 on 2024-05-29 15:04 + +import django_countries.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("submissions", "0030_alter_servicefeetype_fix_price_editable"), + ] + + operations = [ + migrations.AddField( + model_name="contact", + name="country", + field=django_countries.fields.CountryField( + max_length=2, null=True, verbose_name="Pays" + ), + ), + migrations.AddField( + model_name="historicalcontact", + name="country", + field=django_countries.fields.CountryField( + max_length=2, null=True, verbose_name="Pays" + ), + ), + ] diff --git a/geocity/apps/submissions/migrations/0032_alter_contact_zipcode_and_more.py b/geocity/apps/submissions/migrations/0032_alter_contact_zipcode_and_more.py new file mode 100644 index 000000000..65621c86c --- /dev/null +++ b/geocity/apps/submissions/migrations/0032_alter_contact_zipcode_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.11 on 2024-05-30 08:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("submissions", "0031_contact_country_historicalcontact_country"), + ] + + operations = [ + migrations.AlterField( + model_name="contact", + name="zipcode", + field=models.PositiveIntegerField(verbose_name="Code postal"), + ), + migrations.AlterField( + model_name="historicalcontact", + name="zipcode", + field=models.PositiveIntegerField(verbose_name="Code postal"), + ), + ] diff --git a/geocity/apps/submissions/models.py b/geocity/apps/submissions/models.py index 209c54941..d7e85b386 100644 --- a/geocity/apps/submissions/models.py +++ b/geocity/apps/submissions/models.py @@ -39,6 +39,7 @@ from django.utils.functional import cached_property from django.utils.html import escape, format_html from django.utils.translation import gettext_lazy as _ +from django_countries.fields import CountryField from pdf2image import convert_from_path from PIL import Image from simple_history.models import HistoricalRecords @@ -1461,12 +1462,17 @@ class Contact(models.Model): max_length=100, ) zipcode = models.PositiveIntegerField( - _("NPA"), + _("Code postal"), ) city = models.CharField( _("Ville"), max_length=100, ) + country = CountryField( + _("Pays"), + null=True, + blank=False, + ) phone = models.CharField( _("Téléphone"), max_length=20, diff --git a/geocity/apps/submissions/templates/submissions/_submission_actions.html b/geocity/apps/submissions/templates/submissions/_submission_actions.html index 0cc78aef9..4c89d7415 100644 --- a/geocity/apps/submissions/templates/submissions/_submission_actions.html +++ b/geocity/apps/submissions/templates/submissions/_submission_actions.html @@ -18,7 +18,7 @@

{% translate "" %}

aria-selected="{% if active_form == "amend" %}true{% else %}false{% endif %}">{% translate "Traitement" %} {% endif %} - {% if not submission.is_classified and forms.request_validation %} + {% if not submission.is_classified and forms.request_validation and not submission.validation_by_validators_is_disabled %}