diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 541465166..000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,13 +0,0 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: - - package-ecosystem: "pip" # See documentation for possible values - directory: "/" # Location of package manifests - schedule: - interval: "weekly" - ignore: - - dependency-name: "gdal" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 033efeb17..eae7b505d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,3 +33,8 @@ repos: rev: "22.3.0" hooks: - id: black + # Renovate configuration + - repo: https://github.com/renovatebot/pre-commit-hooks + rev: 35.10.0 + hooks: + - id: renovate-config-validator diff --git a/Dockerfile b/Dockerfile index 5143bbe29..ce6a3a9b4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM sitdocker/geocity-base:v1.3.2.2021 +FROM sitdocker/geocity-base:v2.1.5 ARG ENV diff --git a/geocity/apps/accounts/models.py b/geocity/apps/accounts/models.py index 674a2c121..d4597563b 100644 --- a/geocity/apps/accounts/models.py +++ b/geocity/apps/accounts/models.py @@ -25,13 +25,11 @@ PUBLIC_TYPE_CHOICES = ( ( True, - _("Permettre la saisie à n'importe quel utilisateur disposant d'un compte"), + _("Tout public"), ), ( False, - _( - "Restreindre la saisie aux utilisateurs autorisés de l'entité administrative" - ), + _("Restreint aux utilisateurs autorisés"), ), ) diff --git a/geocity/apps/core/static/css/main.css b/geocity/apps/core/static/css/main.css index 0b2ab13bf..194788554 100644 --- a/geocity/apps/core/static/css/main.css +++ b/geocity/apps/core/static/css/main.css @@ -239,6 +239,10 @@ h5 { font-size: 1.1em; } +.bold { + font-weight: bold; +} + .progress-nav { display: flex; justify-content: center; @@ -556,7 +560,7 @@ th.actions { } .global-search-form-container { - width: 600px; + width: 400px; min-width: 0; } diff --git a/geocity/apps/core/static/js/submission_contacts.js b/geocity/apps/core/static/js/submission_contacts.js index 392621b54..40b19be17 100644 --- a/geocity/apps/core/static/js/submission_contacts.js +++ b/geocity/apps/core/static/js/submission_contacts.js @@ -1,16 +1,29 @@ 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; - } - } else { - for (const [key, value] of Object.entries(userprofile)) { - document.getElementById(`id_form-${item}-${key}`).value = ''; - document.getElementById(`id_form-${item}-${key}`).readOnly = false; - } + 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; } - + } else { + for (const [key, value] of Object.entries(userprofile)) { + document.getElementById(`id_form-${item}-${key}`).value = ''; + document.getElementById(`id_form-${item}-${key}`).readOnly = false; + } + } } + +// Create a label to replace "readonly hidden select" readonly +window.addEventListener('load', function () { + var selects = document.querySelectorAll("select[readonly][hidden]"); + for (select of selects) { + let elem = document.createElement('label'); + let text = select.querySelector("option[selected]").text + let div = select.closest('.col-md-9'); + + elem.innerHTML = text; + elem.classList.add('col-form-label', 'bold'); + div.appendChild(elem); + } +}); diff --git a/geocity/apps/forms/migrations/0018_alter_historicalprice_amount_alter_price_amount.py b/geocity/apps/forms/migrations/0018_alter_historicalprice_amount_alter_price_amount.py new file mode 100644 index 000000000..d92b5897c --- /dev/null +++ b/geocity/apps/forms/migrations/0018_alter_historicalprice_amount_alter_price_amount.py @@ -0,0 +1,36 @@ +# Generated by Django 4.1.7 on 2023-03-10 16:03 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("forms", "0017_field_message_for_notified_services_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="historicalprice", + name="amount", + field=models.DecimalField( + decimal_places=2, + help_text="Un montant de 0 peut être utilisé pour avoir un tarif gratuit", + max_digits=6, + validators=[django.core.validators.MinValueValidator(0)], + verbose_name="Montant", + ), + ), + migrations.AlterField( + model_name="price", + name="amount", + field=models.DecimalField( + decimal_places=2, + help_text="Un montant de 0 peut être utilisé pour avoir un tarif gratuit", + max_digits=6, + validators=[django.core.validators.MinValueValidator(0)], + verbose_name="Montant", + ), + ), + ] diff --git a/geocity/apps/forms/models.py b/geocity/apps/forms/models.py index 58f9bbb03..d872955f0 100644 --- a/geocity/apps/forms/models.py +++ b/geocity/apps/forms/models.py @@ -255,7 +255,13 @@ def clean(self): class Price(models.Model): text = models.CharField(_("Texte"), max_length=255) - amount = models.DecimalField(_("Montant"), max_digits=6, decimal_places=2) + amount = models.DecimalField( + _("Montant"), + max_digits=6, + decimal_places=2, + validators=[MinValueValidator(0)], + help_text=_("Un montant de 0 peut être utilisé pour avoir un tarif gratuit"), + ) currency = models.CharField(_("Devise"), max_length=20, default=default_currency) integrator = models.ForeignKey( Group, diff --git a/geocity/apps/reports/admin.py b/geocity/apps/reports/admin.py index 0d577f33f..3d710fcca 100644 --- a/geocity/apps/reports/admin.py +++ b/geocity/apps/reports/admin.py @@ -5,7 +5,7 @@ from django.utils.translation import gettext_lazy as _ from polymorphic.admin import PolymorphicInlineSupportMixin, StackedPolymorphicInline -from geocity.apps.accounts.admin import IntegratorFilterMixin +from geocity.apps.accounts.admin import IntegratorFilterMixin, filter_for_user from geocity.apps.submissions.models import ComplementaryDocumentType from .models import HeaderFooter, Report, ReportLayout, Section @@ -191,6 +191,13 @@ def formfield_for_manytomany(self, db_field, request, **kwargs): ) return super().formfield_for_manytomany(db_field, request, **kwargs) + def formfield_for_foreignkey(self, db_field, request, **kwargs): + if db_field.name == "layout": + kwargs["queryset"] = filter_for_user( + request.user, ReportLayout.objects.all() + ) + return super().formfield_for_foreignkey(db_field, request, **kwargs) + def save_related(self, request, form, formsets, change): super().save_related(request, form, formsets, change) sections = form.instance.sections.order_by("order").all() diff --git a/geocity/apps/reports/management/commands/add_payment_reports.py b/geocity/apps/reports/management/commands/add_payment_reports.py index 1658cfe31..24fca8c75 100644 --- a/geocity/apps/reports/management/commands/add_payment_reports.py +++ b/geocity/apps/reports/management/commands/add_payment_reports.py @@ -28,6 +28,7 @@ def _create_payment_report(self, group, layout): Date : {{ transaction_data.creation_date }}
Année : {{ transaction_data.creation_date_year }}
Page : 1/1

""", + text_align="right", location="right", ) section_paragraph_1.save() @@ -41,6 +42,7 @@ def _create_payment_report(self, group, layout):

{{request_data.properties.author.first_name}} {{request_data.properties.author.last_name}}
{{request_data.properties.author.address}}
{{request_data.properties.author.zipcode}} {{request_data.properties.author.city}}

""", + text_align="right", location="right", ) section_paragraph_2.save() @@ -110,6 +112,7 @@ def _create_refund_report(self, group, layout): Date : {{ transaction_data.creation_date }}
Année : {{ transaction_data.creation_date_year }}
Page : 1/1

""", + text_align="right", location="right", ) section_paragraph_1.save() @@ -123,6 +126,7 @@ def _create_refund_report(self, group, layout):

{{request_data.properties.author.first_name}} {{request_data.properties.author.last_name}}
{{request_data.properties.author.address}}
{{request_data.properties.author.zipcode}} {{request_data.properties.author.city}}

""", + text_align="right", location="right", ) section_paragraph_2.save() diff --git a/geocity/apps/reports/migrations/0021_remove_section_padding_top_and_more.py b/geocity/apps/reports/migrations/0021_remove_section_padding_top_and_more.py new file mode 100644 index 000000000..627636f35 --- /dev/null +++ b/geocity/apps/reports/migrations/0021_remove_section_padding_top_and_more.py @@ -0,0 +1,125 @@ +# Generated by Django 4.1.7 on 2023-03-20 07:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("reports", "0020_headerfooter_sectionrecipient_and_more"), + ] + + operations = [ + migrations.RemoveField( + model_name="section", + name="padding_top", + ), + migrations.AddField( + model_name="sectionamendproperty", + name="padding_top", + field=models.PositiveIntegerField( + default=0, + help_text="Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte", + verbose_name="Espace vide au dessus", + ), + ), + migrations.AddField( + model_name="sectionauthor", + name="padding_top", + field=models.PositiveIntegerField( + default=0, + help_text="Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte", + verbose_name="Espace vide au dessus", + ), + ), + migrations.AddField( + model_name="sectioncontact", + name="padding_top", + field=models.PositiveIntegerField( + default=0, + help_text="Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte", + verbose_name="Espace vide au dessus", + ), + ), + migrations.AddField( + model_name="sectioncreditor", + name="padding_top", + field=models.PositiveIntegerField( + default=0, + help_text="Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte", + verbose_name="Espace vide au dessus", + ), + ), + migrations.AddField( + model_name="sectiondetail", + name="padding_top", + field=models.PositiveIntegerField( + default=0, + help_text="Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte", + verbose_name="Espace vide au dessus", + ), + ), + migrations.AddField( + model_name="sectionmap", + name="padding_top", + field=models.PositiveIntegerField( + default=0, + help_text="Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte", + verbose_name="Espace vide au dessus", + ), + ), + migrations.AddField( + model_name="sectionparagraph", + name="padding_top", + field=models.PositiveIntegerField( + default=0, + help_text="Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte", + verbose_name="Espace vide au dessus", + ), + ), + migrations.AddField( + model_name="sectionplanning", + name="padding_top", + field=models.PositiveIntegerField( + default=0, + help_text="Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte", + verbose_name="Espace vide au dessus", + ), + ), + migrations.AddField( + model_name="sectionrecipient", + name="padding_top", + field=models.PositiveIntegerField( + default=40, + help_text="Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte", + verbose_name="Espace vide au dessus", + ), + ), + migrations.AddField( + model_name="sectionrecipient", + name="uses_dynamic_recipient", + field=models.BooleanField( + default=True, + help_text="Si le demande est saisie au nom d'une autre personne (requérant) celui-ci sera utilisé", + verbose_name="Destinataire dynamique", + ), + ), + migrations.AddField( + model_name="sectionstatus", + name="padding_top", + field=models.PositiveIntegerField( + default=0, + help_text="Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte", + verbose_name="Espace vide au dessus", + ), + ), + migrations.AddField( + model_name="sectionvalidation", + name="padding_top", + field=models.PositiveIntegerField( + default=0, + help_text="Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte", + verbose_name="Espace vide au dessus", + ), + ), + ] diff --git a/geocity/apps/reports/models.py b/geocity/apps/reports/models.py index 2fe4250a2..d35c7715c 100644 --- a/geocity/apps/reports/models.py +++ b/geocity/apps/reports/models.py @@ -19,6 +19,7 @@ from geocity.apps.accounts.fields import AdministrativeEntityFileField from geocity.apps.accounts.models import AdministrativeEntity +from geocity.apps.submissions.contact_type_choices import * from .fields import BackgroundFileField from .utils import DockerRunFailedError, run_docker_container @@ -218,6 +219,16 @@ class Heading(models.TextChoices): H6 = "h6", _("Titre 6") +def padding_top_field(default=0): + return models.PositiveIntegerField( + _("Espace vide au dessus"), + default=default, + help_text=_( + "Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte" + ), + ) + + class Section(PolymorphicModel): class Meta: verbose_name = _("Paragraphe") @@ -228,13 +239,6 @@ class Meta: Report, on_delete=NON_POLYMORPHIC_CASCADE, related_name="sections" ) order = models.PositiveIntegerField(_("Ordre du paragraphe"), null=True, blank=True) - padding_top = models.PositiveIntegerField( - _("Espace vide au dessus"), - default=0, - help_text=_( - "Espace vide au dessus afin de placer le texte au bon endroit (en pixels). Augmenter la valeur fait descendre le texte" - ), - ) is_new_page = models.BooleanField( _("Nouvelle page"), default=False, @@ -258,6 +262,7 @@ def __str__(self): class SectionMap(Section): + padding_top = padding_top_field() title = models.CharField( _("Titre"), default="Localisation·s", blank=True, max_length=2000 ) @@ -360,6 +365,7 @@ class Location(models.TextChoices): LEFT = "left", _("Gauche") RIGHT = "right", _("Droite") + padding_top = padding_top_field() title = models.CharField(_("Titre"), default="", blank=True, max_length=2000) title_size = models.CharField( _("Taille des titres"), @@ -418,6 +424,7 @@ def prepare_context(self, request, base_context): class SectionContact(Section): + padding_top = padding_top_field() title = models.CharField( _("Titre"), default="Contact·s", blank=True, max_length=2000 ) @@ -436,6 +443,7 @@ class Meta: class SectionAuthor(Section): + padding_top = padding_top_field() title = models.CharField( _("Titre"), default="Auteur·e de la demande", blank=True, max_length=2000 ) @@ -462,6 +470,7 @@ class SectionDetail(Section): (STYLE_1, _("champ (tab) valeur")), ) + padding_top = padding_top_field() title = models.CharField( _("Titre"), default="Propriété·s de la demande", blank=True, max_length=2000 ) @@ -513,6 +522,7 @@ def list_undesired_properties(self): class SectionPlanning(Section): + padding_top = padding_top_field() title = models.CharField( _("Titre"), default="Planning", blank=True, max_length=2000 ) @@ -536,6 +546,7 @@ class Meta: class SectionValidation(Section): + padding_top = padding_top_field() title = models.CharField( _("Titre"), default="Commentaire·s des services", blank=True, max_length=2000 ) @@ -554,6 +565,7 @@ class Meta: class SectionAmendProperty(Section): + padding_top = padding_top_field() title = models.CharField( _("Titre"), default="Commentaire·s du secrétariat", blank=True, max_length=2000 ) @@ -572,6 +584,7 @@ class Meta: class SectionStatus(Section): + padding_top = padding_top_field() title = models.CharField( _("Titre"), default="Statut de la demande", blank=True, max_length=2000 ) @@ -590,6 +603,7 @@ class Meta: class SectionCreditor(Section): + padding_top = padding_top_field() title = models.CharField( _("Titre"), default="Adresse de facturation", blank=True, max_length=2000 ) @@ -608,20 +622,41 @@ class Meta: class SectionRecipient(Section): + padding_top = padding_top_field(default=40) is_recommended = models.BooleanField( _("Recommandée"), default=False, help_text=_('Ajoute le texte "RECOMMANDEE" en première ligne'), ) - - # TODO: Find a way to fix this, to make padding_top at 40 by default only for SectionRecipient - def __init__(self, *args, **kwargs): - self._meta.get_field("padding_top").default = 40 - super().__init__(*args, **kwargs) + uses_dynamic_recipient = models.BooleanField( + _("Destinataire dynamique"), + default=True, + help_text=_( + "Si le demande est saisie au nom d'une autre personne (requérant) celui-ci sera utilisé" + ), + ) class Meta: verbose_name = _("Destinataire") + def _get_dynamic_recipient(self, request, base_context): + contacts = base_context["request_data"]["properties"]["contacts"] + contact_type_requestor = None + requestor = dict(CONTACT_TYPE_CHOICES)[CONTACT_TYPE_REQUESTOR] + if requestor in contacts: + contact_type_requestor = contacts[requestor] + + author = base_context["request_data"]["properties"]["author"] + dynamic_recipient = contact_type_requestor if contact_type_requestor else author + return dynamic_recipient + + def prepare_context(self, request, base_context): + # Return updated context + return { + **super().prepare_context(request, base_context), + "dynamic_recipient": self._get_dynamic_recipient(request, base_context), + } + class HeaderFooter(PolymorphicModel): class Location(models.TextChoices): diff --git a/geocity/apps/reports/templates/reports/sections/sectiondetail.html b/geocity/apps/reports/templates/reports/sections/sectiondetail.html index 8c5041f34..c73768318 100644 --- a/geocity/apps/reports/templates/reports/sections/sectiondetail.html +++ b/geocity/apps/reports/templates/reports/sections/sectiondetail.html @@ -8,11 +8,11 @@ {% if request_data.properties.submission_fields %}
- {% if section.show_form_name %} -

{{form}}

- {% endif %} {% if section.style == 0 %} {% for form, fields in request_data.properties.submission_fields.items %} + {% if section.show_form_name %} +

{{form}}

+ {% endif %} {% for key, field in fields.items %} {% if not key in section.undesired_properties %}
{{key}} : {{field}}
@@ -23,6 +23,9 @@

{{form}}

{% elif section.style == 1 %}
{% for form, fields in request_data.properties.submission_fields.items %} + {% if section.show_form_name %} +

{{form}}

+ {% endif %} {% for key, field in fields.items %} {% if not key in section.undesired_properties %}
{{key}}
diff --git a/geocity/apps/reports/templates/reports/sections/sectionrecipient.html b/geocity/apps/reports/templates/reports/sections/sectionrecipient.html index c4c942865..827305abd 100644 --- a/geocity/apps/reports/templates/reports/sections/sectionrecipient.html +++ b/geocity/apps/reports/templates/reports/sections/sectionrecipient.html @@ -4,16 +4,31 @@
-
- {% if section.is_recommended %} - RECOMMANDEE
- {% endif %} - {% if submission.author.userprofile.company_name %} - {{submission.author.userprofile.company_name}}
- {% endif %} - {{submission.author.last_name}} {{submission.author.first_name}}
- {{submission.author.userprofile.address}}
- {{submission.author.userprofile.zipcode}} {{submission.author.userprofile.city}} -
+ {% if section.uses_dynamic_recipient %} + {% comment %} {{dynamic_recipient}} {% endcomment %} +
+ {% if section.is_recommended %} + RECOMMANDEE
+ {% endif %} + {% if dynamic_recipient.company_name %} + {{dynamic_recipient.company_name}}
+ {% endif %} + {{dynamic_recipient.last_name}} {{dynamic_recipient.first_name}}
+ {{dynamic_recipient.address}}
+ {{dynamic_recipient.zipcode}} {{dynamic_recipient.city}} +
+ {% else %} +
+ {% if section.is_recommended %} + RECOMMANDEE
+ {% endif %} + {% if submission.author.userprofile.company_name %} + {{submission.author.userprofile.company_name}}
+ {% endif %} + {{submission.author.last_name}} {{submission.author.first_name}}
+ {{submission.author.userprofile.address}}
+ {{submission.author.userprofile.zipcode}} {{submission.author.userprofile.city}} +
+ {% endif %}
{% endblock %} diff --git a/geocity/apps/submissions/contact_type_choices.py b/geocity/apps/submissions/contact_type_choices.py new file mode 100644 index 000000000..201be70cd --- /dev/null +++ b/geocity/apps/submissions/contact_type_choices.py @@ -0,0 +1,23 @@ +from django.utils.translation import gettext_lazy as _ + +# Contact types +CONTACT_TYPE_OTHER = 0 +CONTACT_TYPE_REQUESTOR = 1 +CONTACT_TYPE_OWNER = 2 +CONTACT_TYPE_COMPANY = 3 +CONTACT_TYPE_CLIENT = 4 +CONTACT_TYPE_SECURITY = 5 +CONTACT_TYPE_ASSOCIATION = 6 +CONTACT_TYPE_ENGINEER = 7 +CONTACT_TYPE_WORKDIRECTOR = 8 +CONTACT_TYPE_CHOICES = ( + (CONTACT_TYPE_ENGINEER, _("Architecte/Ingénieur")), + (CONTACT_TYPE_ASSOCIATION, _("Association")), + (CONTACT_TYPE_OTHER, _("Autres")), + (CONTACT_TYPE_WORKDIRECTOR, _("Direction des travaux")), + (CONTACT_TYPE_COMPANY, _("Entreprise")), + (CONTACT_TYPE_CLIENT, _("Maître d'ouvrage")), + (CONTACT_TYPE_OWNER, _("Propriétaire")), + (CONTACT_TYPE_REQUESTOR, _("Requérant (si différent de l'auteur de la demande)")), + (CONTACT_TYPE_SECURITY, _("Sécurité")), +) diff --git a/geocity/apps/submissions/forms.py b/geocity/apps/submissions/forms.py index 5187007da..c13425254 100644 --- a/geocity/apps/submissions/forms.py +++ b/geocity/apps/submissions/forms.py @@ -823,7 +823,7 @@ class Meta: fields = ["contact_type"] widgets = { "contact_type": forms.Select( - attrs={"readonly": "readonly", "class": "hide-arrow"} + attrs={"readonly": True, "hidden": True, "class": "hide-arrow"} ), } diff --git a/geocity/apps/submissions/management/commands/fixturize.py b/geocity/apps/submissions/management/commands/fixturize.py index 9aaa44bdd..ee406a46a 100644 --- a/geocity/apps/submissions/management/commands/fixturize.py +++ b/geocity/apps/submissions/management/commands/fixturize.py @@ -16,6 +16,7 @@ from geocity.apps.accounts.users import get_integrator_permissions from geocity.apps.forms.models import * from geocity.apps.reports.models import * +from geocity.apps.submissions.contact_type_choices import * from geocity.apps.submissions.models import * # import fixturize file diff --git a/geocity/apps/submissions/models.py b/geocity/apps/submissions/models.py index 2dd61bb6f..398303803 100644 --- a/geocity/apps/submissions/models.py +++ b/geocity/apps/submissions/models.py @@ -34,30 +34,9 @@ from geocity.apps.forms.models import Field, Form, FormCategory from . import fields +from .contact_type_choices import * from .payments.models import SubmissionPrice -# Contact types -CONTACT_TYPE_OTHER = 0 -CONTACT_TYPE_REQUESTOR = 1 -CONTACT_TYPE_OWNER = 2 -CONTACT_TYPE_COMPANY = 3 -CONTACT_TYPE_CLIENT = 4 -CONTACT_TYPE_SECURITY = 5 -CONTACT_TYPE_ASSOCIATION = 6 -CONTACT_TYPE_ENGINEER = 7 -CONTACT_TYPE_WORKDIRECTOR = 8 -CONTACT_TYPE_CHOICES = ( - (CONTACT_TYPE_ENGINEER, _("Architecte/Ingénieur")), - (CONTACT_TYPE_ASSOCIATION, _("Association")), - (CONTACT_TYPE_OTHER, _("Autres")), - (CONTACT_TYPE_WORKDIRECTOR, _("Direction des travaux")), - (CONTACT_TYPE_COMPANY, _("Entreprise")), - (CONTACT_TYPE_CLIENT, _("Maître d'ouvrage")), - (CONTACT_TYPE_OWNER, _("Propriétaire")), - (CONTACT_TYPE_REQUESTOR, _("Requérant (si différent de l'auteur de la demande)")), - (CONTACT_TYPE_SECURITY, _("Sécurité")), -) - # Actions ACTION_AMEND = "amend" ACTION_REQUEST_VALIDATION = "request_validation" @@ -497,7 +476,34 @@ def get_absolute_url(relative_url): if settings.SITE_DOMAIN == "localhost" else "" ) - return f"{protocol}://{settings.SITE_DOMAIN}{port}{relative_url}" + + if settings.SITE_DOMAIN: + site_domain = settings.SITE_DOMAIN + else: + id = relative_url.split("/")[-2] + submission = Submission.objects.get(id=id) + site_domain = submission.get_site(use_default=False) + + return f"{protocol}://{site_domain}{port}{relative_url}" + + def get_site(self, use_default=False): + """Get a site for the submission submission given""" + sites = self.administrative_entity.sites.all() + default_site = settings.DEFAULT_SITE + + site_not_excluded = sites.exclude(domain=default_site) + default_site_exists = sites.filter(domain=default_site).exists() + + default_site = default_site if default_site_exists else sites.first() + other_site = ( + site_not_excluded.first() if site_not_excluded.exists() else default_site + ) + + if use_default: + site = default_site + else: + site = other_site + return site def start_inquiry(self): if self.status == self.STATUS_INQUIRY_IN_PROGRESS: @@ -537,7 +543,11 @@ def archive(self, archivist): # include additional documents for document in self.complementary_documents.all(): zip_file.write(document.path, document.name) - + # include user uploaded documents + for document in self.get_appendices_values(): + filename = document.value["val"].split("/")[-1] + path = f"{settings.PRIVATE_MEDIA_ROOT}/{document.value['val']}" + zip_file.write(path, filename) # Reset file pointer tmp_file.seek(0) archived_request = ArchivedSubmission( diff --git a/geocity/apps/submissions/payments/postfinance/processor.py b/geocity/apps/submissions/payments/postfinance/processor.py index 4111a0d3c..a907422ec 100644 --- a/geocity/apps/submissions/payments/postfinance/processor.py +++ b/geocity/apps/submissions/payments/postfinance/processor.py @@ -58,12 +58,12 @@ def create_merchant_transaction(self, request, submission, transaction): - Name: The submission's price's text (description of the price) - Unique ID: The submission's ID - SKU: The submission's original price instance's ID - - Attribute "Compte interne": the internal_accoutn value specified in PaymentSettings + - Attribute "Compte interne": the internal_account value specified in PaymentSettings Returns a dict with the following entries: { "merchant_reference": , - "authorization_timeout_on": , + "authorization_timeout_on": , "payment_page_url": , } """ diff --git a/geocity/apps/submissions/steps.py b/geocity/apps/submissions/steps.py index 104542964..d96a5d29b 100644 --- a/geocity/apps/submissions/steps.py +++ b/geocity/apps/submissions/steps.py @@ -136,7 +136,15 @@ def get_forms_step( if not user.has_perm("submissions.view_private_form"): candidate_forms = candidate_forms.filter(is_public=True) - if candidate_forms.count() <= 1: + if not candidate_forms.count(): + return None + + if candidate_forms.count() == 1 and all( + [ + not candidate_form.has_exceeded_maximum_submissions() + for candidate_form in candidate_forms + ] + ): return None return Step( diff --git a/geocity/apps/submissions/templates/submissions/submission_submit.html b/geocity/apps/submissions/templates/submissions/submission_submit.html index aef9f8c70..8793bcc89 100644 --- a/geocity/apps/submissions/templates/submissions/submission_submit.html +++ b/geocity/apps/submissions/templates/submissions/submission_submit.html @@ -44,77 +44,80 @@
{% trans "Volet de transmission" %}

{% endif %} - {% if not incomplete_steps and should_go_to_payment %} - {% if not submission.get_submission_price %} -
-
- {% blocktrans trimmed %} - Vous devez choisir un tarif à l'étape "Détails" - {% endblocktrans %} -
+ {% if not incomplete_steps %} +

+ +
+

+ {% if should_go_to_payment %} + {% if not submission.get_submission_price %} +
+
+ {% blocktrans trimmed %} + Vous devez choisir un tarif à l'étape "Détails" + {% endblocktrans %} +
+
+
-
- {% trans "Retour" %} + {% else %} +
+
+ {% blocktrans trimmed %} + Avant de continuer, nous vous demandons de vérifier les détails de votre demande pour vous assurer que tout est correct. + Lorsque vous êtes prêt à procéder au paiement, cliquez sur le bouton "Payer maintenant" pour être redirigé vers l'interface de paiement sécurisée. + {% endblocktrans %} +
+
+
+ {% blocktrans trimmed with text=submission.get_submission_price.text amount=submission.get_submission_price.amount currency=submission.get_submission_price.currency %} +

Vous avez sélectionné {{ text }} au prix de + {{ amount }} {{ currency }} +

+ {% endblocktrans %} +
+
+ {% if previous_step.url %} + {% trans "Retour" %} + {% endif %} + + + + {% if has_any_form_with_exceeded_submissions %} + + {{ submission.get_maximum_submissions_message }} + + {% endif %} +
-
+ {% endif %} {% else %} -
-
- {% blocktrans trimmed %} - Avant de continuer, nous vous demandons de vérifier les détails de votre demande pour vous assurer que tout est correct. - Lorsque vous êtes prêt à procéder au paiement, cliquez sur le bouton Payer maintenant pour être redirigé vers l’interface de paiement sécurisée. - {% endblocktrans %} -
-
-
- {% blocktrans trimmed with text=submission.get_submission_price.text amount=submission.get_submission_price.amount currency=submission.get_submission_price.currency %} -

Vous avez sélectionné {{ text }} au prix de - {{ amount }} {{ currency }} -

- {% endblocktrans %} -
-
+
+ {% csrf_token %} + {% buttons %} {% if previous_step.url %} {% trans "Retour" %} {% endif %} - {% if has_any_form_with_exceeded_submissions %} - {{ submission.get_maximum_submissions_message }} + {{ submission.get_maximum_submissions_message }} {% endif %} -
-
+ {% endbuttons %} + {% endif %} {% endif %}

{% trans "Vous trouvez ci-dessous un récapitulatif de votre saisie." %}

- {% if not incomplete_steps and not should_go_to_payment %} -

- -
-

-
- {% csrf_token %} - {% buttons %} - {% if previous_step.url %} - {% trans "Retour" %} - {% endif %} - - {% if has_any_form_with_exceeded_submissions %} - - {{ submission.get_maximum_submissions_message }} - - {% endif %} - {% endbuttons %} -
- {% endif %}
{% submission_summary submission %} diff --git a/geocity/apps/submissions/templatetags/submissions_extras.py b/geocity/apps/submissions/templatetags/submissions_extras.py index 631a471d9..8889d38ba 100644 --- a/geocity/apps/submissions/templatetags/submissions_extras.py +++ b/geocity/apps/submissions/templatetags/submissions_extras.py @@ -11,6 +11,7 @@ from geocity.apps.accounts.models import PermitDepartment from geocity.apps.submissions import forms, models, permissions +from geocity.apps.submissions.contact_type_choices import * register = template.Library() @@ -33,7 +34,7 @@ def basename(value): def get_contacts_summary(submission): - contact_types = dict(models.CONTACT_TYPE_CHOICES) + contact_types = dict(CONTACT_TYPE_CHOICES) contacts = [ ( diff --git a/geocity/apps/submissions/views.py b/geocity/apps/submissions/views.py index b890b2679..036dd8462 100644 --- a/geocity/apps/submissions/views.py +++ b/geocity/apps/submissions/views.py @@ -562,7 +562,6 @@ def handle_amend_form_submission(self, form): ) messages.success(self.request, success_message) - if ( form.instance.status == models.Submission.STATUS_RECEIVED and form.instance.status is not initial_status @@ -1148,8 +1147,14 @@ def submission_select_administrative_entity(request, submission_id=None): limit_to_categories=selectable_categories, ) - # If filter combinations return only one form object, this combination must be set on submission object - if len(candidate_forms) == 1: + # If filter combinations return only one form object that is not exceeded, + # this combination must be set on submission object + if len(candidate_forms) == 1 and all( + [ + not candidate_form.has_exceeded_maximum_submissions() + for candidate_form in candidate_forms + ] + ): submission.forms.set(candidate_forms) steps = get_progress_bar_steps(request=request, submission=submission) diff --git a/geocity/tests/reports/data/test_block_gallery/page-002.expected.png b/geocity/tests/reports/data/test_block_gallery/page-002.expected.png index 42fb4c97e..c5274b72a 100644 Binary files a/geocity/tests/reports/data/test_block_gallery/page-002.expected.png and b/geocity/tests/reports/data/test_block_gallery/page-002.expected.png differ diff --git a/geocity/tests/reports/data/test_block_gallery/page-003.expected.png b/geocity/tests/reports/data/test_block_gallery/page-003.expected.png index 5fcabc255..efc0714a3 100644 Binary files a/geocity/tests/reports/data/test_block_gallery/page-003.expected.png and b/geocity/tests/reports/data/test_block_gallery/page-003.expected.png differ diff --git a/geocity/tests/reports/data/test_pdf_preview/page-000.expected.png b/geocity/tests/reports/data/test_pdf_preview/page-000.expected.png index a2d74e749..9bf27c4f7 100644 Binary files a/geocity/tests/reports/data/test_pdf_preview/page-000.expected.png and b/geocity/tests/reports/data/test_pdf_preview/page-000.expected.png differ diff --git a/geocity/tests/reports/data/test_pdf_preview/page-001.expected.png b/geocity/tests/reports/data/test_pdf_preview/page-001.expected.png index 490e5a840..c9d9436e5 100644 Binary files a/geocity/tests/reports/data/test_pdf_preview/page-001.expected.png and b/geocity/tests/reports/data/test_pdf_preview/page-001.expected.png differ diff --git a/geocity/tests/reports/test_reports.py b/geocity/tests/reports/test_reports.py index fe01fd5e4..957c8ebe4 100644 --- a/geocity/tests/reports/test_reports.py +++ b/geocity/tests/reports/test_reports.py @@ -246,6 +246,7 @@ def test_block_gallery(self): "padding_top": 20, # "is_new_page": bool, "is_recommended": True, + "uses_dynamic_recipient": True, } }, 15: { @@ -253,6 +254,7 @@ def test_block_gallery(self): "padding_top": 50, # "is_new_page": bool, "is_recommended": False, + "uses_dynamic_recipient": False, } }, } diff --git a/renovate.json b/renovate.json new file mode 100644 index 000000000..c2cd24c24 --- /dev/null +++ b/renovate.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:base", + "docker:disable" + ], + "automerge": false, + "baseBranches": ["develop"], + "pip_requirements": { + "enabled": false + }, + "pip-compile": { + "fileMatch": ["requirements.in", "requirements_dev.in"] + }, + "lockFileMaintenance": { + "enabled": true, + "branchTopic": "pip-compile-refresh", + "commitMessageAction": "Refresh pip-compile outputs" + }, + "packageRules": [ + { + "matchPackageNames": [ + "gdal", + "django-bootstrap-datepicker-plus", + "django-bootstrap4", + "django-two-factor-auth", + "django-crispy-forms" + ], + "enabled": false + } + ] +} diff --git a/requirements.in b/requirements.in index d8a532e1b..348d6a2fc 100644 --- a/requirements.in +++ b/requirements.in @@ -7,7 +7,7 @@ django-tables2 django-tables2-column-shifter # Base docker image must be update when GDAL is updated # https://github.com/yverdon/docker-geocity/ -gdal==3.3.2 +gdal==3.6.3 gunicorn html5lib jdcal @@ -24,7 +24,7 @@ djangorestframework djangorestframework-gis django-cors-headers django-constance[database] -django-two-factor-auth[phonenumbers] +django-two-factor-auth[phonenumbers]==1.14.0 django-taggit filetype django-jazzmin @@ -35,7 +35,7 @@ django-allauth # django_wfs3 -> djangorestframework (optional for openapi schema generation, see https://www.django-rest-framework.org/api-guide/schemas/#install-dependencies) pyyaml uritemplate -django-crispy-forms +django-crispy-forms==1.14.0 django-cron django-axes pdf2image @@ -46,3 +46,4 @@ Jinja2 docker django-polymorphic postfinancecheckout +tzdata diff --git a/requirements.txt b/requirements.txt index 6d8d7a246..b3c3cf195 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,26 +1,24 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # pip-compile requirements.in # -asgiref==3.5.2 +asgiref==3.6.0 # via django -backports-zoneinfo==0.2.1 - # via django -beautifulsoup4==4.11.1 +beautifulsoup4==4.11.2 # via # -r requirements.in # django-bootstrap4 -certifi==2022.9.24 +certifi==2022.12.7 # via # postfinancecheckout # requests cffi==1.15.1 # via cryptography -charset-normalizer==2.1.1 +charset-normalizer==3.1.0 # via requests -cryptography==38.0.4 +cryptography==39.0.2 # via # django-rest-knox # jwcrypto @@ -59,7 +57,7 @@ django==4.1.7 # djangorestframework django-admin-sortable2==2.1.4 # via -r requirements.in -django-allauth==0.51.0 +django-allauth==0.52.0 # via -r requirements.in django-axes==5.40.1 # via -r requirements.in @@ -71,7 +69,7 @@ django-ckeditor==6.5.1 # via -r requirements.in django-constance[database]==2.9.1 # via -r requirements.in -django-cors-headers==3.13.0 +django-cors-headers==3.14.0 # via -r requirements.in django-crispy-forms==1.14.0 # via -r requirements.in @@ -81,7 +79,7 @@ django-filter==22.1 # via -r requirements.in django-formtools==2.4 # via django-two-factor-auth -django-ipware==4.0.2 +django-ipware==5.0.0 # via django-axes django-jazzmin==2.6.0 # via -r requirements.in @@ -89,7 +87,7 @@ django-js-asset==2.0.0 # via django-ckeditor django-oauth-toolkit==2.2.0 # via -r requirements.in -django-otp==1.1.4 +django-otp==1.1.6 # via django-two-factor-auth django-phonenumber-field==6.4.0 # via django-two-factor-auth @@ -103,9 +101,9 @@ django-rest-knox==4.2.0 # via -r requirements.in django-simple-captcha==0.5.17 # via -r requirements.in -django-simple-history==3.2.0 +django-simple-history==3.3.0 # via -r requirements.in -django-tables2==2.4.1 +django-tables2==2.5.3 # via # -r requirements.in # django-tables2-column-shifter @@ -128,7 +126,7 @@ et-xmlfile==1.1.0 # via openpyxl filetype==1.2.0 # via -r requirements.in -gdal==3.3.2 +gdal==3.6.3 # via -r requirements.in gunicorn==20.1.0 # via -r requirements.in @@ -142,21 +140,21 @@ jinja2==3.1.2 # via -r requirements.in jwcrypto==1.4.2 # via django-oauth-toolkit -markupsafe==2.1.1 +markupsafe==2.1.2 # via jinja2 oauthlib==3.2.2 # via # django-oauth-toolkit # requests-oauthlib -openpyxl==3.0.10 +openpyxl==3.1.2 # via tablib -packaging==21.3 +packaging==23.0 # via docker -pdf2image==1.16.0 +pdf2image==1.16.3 # via -r requirements.in -phonenumbers==8.13.1 +phonenumbers==8.13.7 # via django-two-factor-auth -pillow==9.3.0 +pillow==9.4.0 # via # -r requirements.in # django-simple-captcha @@ -169,19 +167,19 @@ pycparser==2.21 # via cffi pyjwt[crypto]==2.6.0 # via django-allauth -pyparsing==3.0.9 - # via packaging +pypng==0.20220715.0 + # via qrcode python-dateutil==2.8.2 # via postfinancecheckout python3-openid==3.2.0 # via django-allauth -pytz==2022.6 +pytz==2022.7.1 # via djangorestframework pyyaml==6.0 # via -r requirements.in -qrcode==7.3.1 +qrcode==7.4.2 # via django-two-factor-auth -requests==2.28.1 +requests==2.28.2 # via # -r requirements.in # django-allauth @@ -195,26 +193,30 @@ six==1.16.0 # html5lib # postfinancecheckout # python-dateutil -soupsieve==2.3.2.post1 +soupsieve==2.4 # via beautifulsoup4 sqlparse==0.4.3 # via django -tablib[xlsx]==3.2.1 +tablib[xlsx]==3.3.0 + # via -r requirements.in +typing-extensions==4.5.0 + # via qrcode +tzdata==2022.7 # via -r requirements.in uritemplate==4.1.1 # via -r requirements.in -urllib3==1.26.13 +urllib3==1.26.15 # via # docker # postfinancecheckout # requests webencodings==0.5.1 # via html5lib -websocket-client==1.4.2 +websocket-client==1.5.1 # via docker -whitenoise==6.2.0 +whitenoise==6.4.0 # via -r requirements.in -wrapt==1.14.1 +wrapt==1.15.0 # via deprecated # The following packages are considered to be unsafe in a requirements file: diff --git a/requirements_dev.txt b/requirements_dev.txt index bbb6d7068..b56f17d0f 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,28 +1,24 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # pip-compile requirements_dev.in # -asgiref==3.5.2 +asgiref==3.6.0 # via # -r requirements.txt # django -asttokens==2.0.5 +asttokens==2.2.1 # via stack-data backcall==0.2.0 # via ipython -backports-zoneinfo==0.2.1 - # via - # -r requirements.txt - # django -beautifulsoup4==4.11.1 +beautifulsoup4==4.11.2 # via # -r requirements.txt # django-bootstrap4 build==0.10.0 # via pip-tools -certifi==2022.9.24 +certifi==2022.12.7 # via # -r requirements.txt # postfinancecheckout @@ -33,15 +29,15 @@ cffi==1.15.1 # cryptography cfgv==3.3.1 # via pre-commit -charset-normalizer==2.1.1 +charset-normalizer==3.1.0 # via # -r requirements.txt # requests click==8.1.3 # via pip-tools -coverage==6.4.1 +coverage==7.2.1 # via -r requirements_dev.in -cryptography==38.0.4 +cryptography==39.0.2 # via # -r requirements.txt # django-rest-knox @@ -61,7 +57,7 @@ deprecated==1.2.13 # jwcrypto diffimg==0.3.0 # via -r requirements_dev.in -distlib==0.3.4 +distlib==0.3.6 # via virtualenv django==4.1.7 # via @@ -95,7 +91,7 @@ django==4.1.7 # djangorestframework django-admin-sortable2==2.1.4 # via -r requirements.txt -django-allauth==0.51.0 +django-allauth==0.52.0 # via -r requirements.txt django-axes==5.40.1 # via -r requirements.txt @@ -107,15 +103,15 @@ django-ckeditor==6.5.1 # via -r requirements.txt django-constance[database]==2.9.1 # via -r requirements.txt -django-cors-headers==3.13.0 +django-cors-headers==3.14.0 # via -r requirements.txt django-crispy-forms==1.14.0 # via -r requirements.txt django-cron==0.6.0 # via -r requirements.txt -django-debug-toolbar==3.4.0 +django-debug-toolbar==3.8.1 # via -r requirements_dev.in -django-extensions==3.1.5 +django-extensions==3.2.1 # via -r requirements_dev.in django-filter==22.1 # via -r requirements.txt @@ -123,7 +119,7 @@ django-formtools==2.4 # via # -r requirements.txt # django-two-factor-auth -django-ipware==4.0.2 +django-ipware==5.0.0 # via # -r requirements.txt # django-axes @@ -135,7 +131,7 @@ django-js-asset==2.0.0 # django-ckeditor django-oauth-toolkit==2.2.0 # via -r requirements.txt -django-otp==1.1.4 +django-otp==1.1.6 # via # -r requirements.txt # django-two-factor-auth @@ -157,9 +153,9 @@ django-rest-knox==4.2.0 # via -r requirements.txt django-simple-captcha==0.5.17 # via -r requirements.txt -django-simple-history==3.2.0 +django-simple-history==3.3.0 # via -r requirements.txt -django-tables2==2.4.1 +django-tables2==2.5.3 # via # -r requirements.txt # django-tables2-column-shifter @@ -182,39 +178,39 @@ et-xmlfile==1.1.0 # via # -r requirements.txt # openpyxl -executing==0.8.3 +executing==1.2.0 # via stack-data factory-boy==3.2.1 # via -r requirements_dev.in -faker==13.13.0 +faker==17.6.0 # via # -r requirements_dev.in # factory-boy -filelock==3.7.1 +filelock==3.9.1 # via virtualenv filetype==1.2.0 # via -r requirements.txt -freezegun==1.2.1 +freezegun==1.2.2 # via -r requirements_dev.in -gdal==3.3.2 +gdal==3.6.3 # via -r requirements.txt gunicorn==20.1.0 # via -r requirements.txt html5lib==1.1 # via -r requirements.txt -identify==2.5.1 +identify==2.5.20 # via pre-commit idna==3.4 # via # -r requirements.txt # requests -ipdb==0.13.9 +ipdb==0.13.13 # via -r requirements_dev.in -ipython==8.4.0 +ipython==8.11.0 # via ipdb jdcal==1.4.1 # via -r requirements.txt -jedi==0.18.1 +jedi==0.18.2 # via ipython jinja2==3.1.2 # via -r requirements.txt @@ -222,57 +218,57 @@ jwcrypto==1.4.2 # via # -r requirements.txt # django-oauth-toolkit -markupsafe==2.1.1 +markupsafe==2.1.2 # via # -r requirements.txt # jinja2 -matplotlib-inline==0.1.3 +matplotlib-inline==0.1.6 # via ipython -nodeenv==1.6.0 +nodeenv==1.7.0 # via pre-commit oauthlib==3.2.2 # via # -r requirements.txt # django-oauth-toolkit # requests-oauthlib -openpyxl==3.0.10 +openpyxl==3.1.2 # via # -r requirements.txt # tablib -packaging==21.3 +packaging==23.0 # via # -r requirements.txt # build # docker parso==0.8.3 # via jedi -pdf2image==1.16.0 +pdf2image==1.16.3 # via # -r requirements.txt # -r requirements_dev.in pexpect==4.8.0 # via ipython -phonenumbers==8.13.1 +phonenumbers==8.13.7 # via # -r requirements.txt # django-two-factor-auth pickleshare==0.7.5 # via ipython -pillow==9.3.0 +pillow==9.4.0 # via # -r requirements.txt # diffimg # django-simple-captcha # pdf2image -pip-tools==6.12.2 +pip-tools==6.12.3 # via -r requirements_dev.in -platformdirs==2.5.2 +platformdirs==3.1.1 # via virtualenv postfinancecheckout==3.4.0 # via -r requirements.txt -pre-commit==3.0.4 +pre-commit==3.1.1 # via -r requirements_dev.in -prompt-toolkit==3.0.29 +prompt-toolkit==3.0.38 # via ipython psycopg2-binary==2.9.5 # via -r requirements.txt @@ -284,16 +280,16 @@ pycparser==2.21 # via # -r requirements.txt # cffi -pygments==2.12.0 +pygments==2.14.0 # via ipython pyjwt[crypto]==2.6.0 # via # -r requirements.txt # django-allauth -pyparsing==3.0.9 +pypng==0.20220715.0 # via # -r requirements.txt - # packaging + # qrcode pyproject-hooks==1.0.0 # via build python-dateutil==2.8.2 @@ -306,7 +302,7 @@ python3-openid==3.2.0 # via # -r requirements.txt # django-allauth -pytz==2022.6 +pytz==2022.7.1 # via # -r requirements.txt # djangorestframework @@ -314,11 +310,11 @@ pyyaml==6.0 # via # -r requirements.txt # pre-commit -qrcode==7.3.1 +qrcode==7.4.2 # via # -r requirements.txt # django-two-factor-auth -requests==2.28.1 +requests==2.28.2 # via # -r requirements.txt # django-allauth @@ -335,8 +331,7 @@ six==1.16.0 # html5lib # postfinancecheckout # python-dateutil - # virtualenv -soupsieve==2.3.2.post1 +soupsieve==2.4 # via # -r requirements.txt # beautifulsoup4 @@ -345,45 +340,50 @@ sqlparse==0.4.3 # -r requirements.txt # django # django-debug-toolbar -stack-data==0.2.0 +stack-data==0.6.2 # via ipython -tablib[xlsx]==3.2.1 +tablib[xlsx]==3.3.0 # via -r requirements.txt -toml==0.10.2 - # via ipdb tomli==2.0.1 # via # build + # ipdb # pyproject-hooks -traitlets==5.2.2.post1 +traitlets==5.9.0 # via # ipython # matplotlib-inline +typing-extensions==4.5.0 + # via + # -r requirements.txt + # qrcode +tzdata==2022.7 + # via -r requirements.txt uritemplate==4.1.1 # via -r requirements.txt -urllib3==1.26.13 +urllib3==1.26.15 # via # -r requirements.txt # docker # postfinancecheckout # requests -virtualenv==20.14.1 +virtualenv==20.21.0 # via pre-commit -wcwidth==0.2.5 +wcwidth==0.2.6 # via prompt-toolkit webencodings==0.5.1 # via # -r requirements.txt # html5lib -websocket-client==1.4.2 +websocket-client==1.5.1 # via # -r requirements.txt # docker -wheel==0.37.1 +wheel==0.40.0 # via pip-tools -whitenoise==6.2.0 +whitenoise==6.4.0 # via -r requirements.txt -wrapt==1.14.1 +wrapt==1.15.0 # via # -r requirements.txt # deprecated diff --git a/services/pdf/requirements.in b/services/pdf/requirements.in new file mode 100644 index 000000000..3673d7823 --- /dev/null +++ b/services/pdf/requirements.in @@ -0,0 +1,2 @@ +weasyprint +requests diff --git a/services/pdf/requirements.txt b/services/pdf/requirements.txt index 6897c71c0..90b2b5d67 100644 --- a/services/pdf/requirements.txt +++ b/services/pdf/requirements.txt @@ -1,2 +1,49 @@ -weasyprint==55.0 +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# pip-compile services/pdf/requirements.in +# +brotli==1.0.9 + # via fonttools +certifi==2022.12.7 + # via requests +cffi==1.15.1 + # via weasyprint +charset-normalizer==2.0.12 + # via requests +cssselect2==0.7.0 + # via weasyprint +fonttools[woff]==4.39.2 + # via weasyprint +html5lib==1.1 + # via weasyprint +idna==3.4 + # via requests +pillow==9.4.0 + # via weasyprint +pycparser==2.21 + # via cffi +pydyf==0.5.0 + # via weasyprint +pyphen==0.13.2 + # via weasyprint requests==2.27.1 + # via -r services/pdf/requirements.in +six==1.16.0 + # via html5lib +tinycss2==1.2.1 + # via + # cssselect2 + # weasyprint +urllib3==1.26.15 + # via requests +weasyprint==55.0 + # via -r services/pdf/requirements.in +webencodings==0.5.1 + # via + # cssselect2 + # html5lib + # tinycss2 +zopfli==0.2.2 + # via fonttools