Skip to content

Commit

Permalink
🚸(dashboard) refactor and modularize consent management templates
Browse files Browse the repository at this point in the history
Split and reorganized the manage consent template into reusable modular components.
Introduced new partial templates for representative and company info, authorizations, and consent date/place.
Retrieves and displays data of entity, user, control_authority and date and place of signature.
Added contractual texts and translates into French.
  • Loading branch information
ssorin committed Feb 3, 2025
1 parent ce08da3 commit e6d90a3
Show file tree
Hide file tree
Showing 14 changed files with 438 additions and 87 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/dashboard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ jobs:
DASHBOARD_CONTROL_AUTHORITY_CITY: Paris
DASHBOARD_CONTROL_AUTHORITY_REPRESENTED_BY: John Doe
DASHBOARD_CONTROL_AUTHORITY_EMAIL: [email protected]
DASHBOARD_CONSENT_DONE_AT: Paris
DASHBOARD_CONSENT_SIGNATURE_LOCATION: Paris
DASHBOARD_CONTACT_EMAIL: [email protected]
steps:
- uses: actions/checkout@v4
- name: Install pipenv
Expand Down Expand Up @@ -108,4 +109,5 @@ jobs:
DASHBOARD_CONTROL_AUTHORITY_CITY: Paris
DASHBOARD_CONTROL_AUTHORITY_REPRESENTED_BY: John Doe
DASHBOARD_CONTROL_AUTHORITY_EMAIL: [email protected]
DASHBOARD_CONSENT_DONE_AT: Paris
DASHBOARD_CONSENT_SIGNATURE_LOCATION: Paris
DASHBOARD_CONTACT_EMAIL: [email protected]
5 changes: 4 additions & 1 deletion env.d/dashboard
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ DASHBOARD_CONTROL_AUTHORITY_CITY=Paris
DASHBOARD_CONTROL_AUTHORITY_REPRESENTED_BY=John Doe
[email protected]

DASHBOARD_CONSENT_DONE_AT=Paris
DASHBOARD_CONSENT_SIGNATURE_LOCATION=Paris

# Email to contact the QualiCharge team
[email protected]
93 changes: 90 additions & 3 deletions src/dashboard/apps/consent/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,102 @@ class ConsentCheckboxInput(CheckboxInput):


class ConsentForm(forms.Form):
"""Save user consent through a checkbox field."""
"""Save user consent through a checkbox field.
Note: all texts of this form (attributes: `label`, `description`, `help_text`)
are intended to appear in a contract and must therefore be in French and
non-translatable.
"""

# Specific authorisation checkbox
is_authorized_signatory = forms.BooleanField(
required=True,
initial=False,
widget=ConsentCheckboxInput(
attrs={
"label": "Le signataire du présent formulaire déclare être dûment "
"habilité par le client pour la signature du présent "
"document.",
},
),
)

allows_measurements = forms.BooleanField(
required=True,
initial=False,
widget=ConsentCheckboxInput(
attrs={
"label": "L'historique des mesures, en kWh,",
"description": "du site (et puissances atteintes et dépassements "
"de puissance) : sur la période souhaitée, de 36 mois "
"maximum à compter de la date de la demande "
"(période limitée à la date de début du contrat)",
},
),
)
allows_daily_index_readings = forms.BooleanField(
required=True,
initial=False,
widget=ConsentCheckboxInput(
attrs={
"label": "L'historique des relevés d'index quotidiens, en kWh, ",
"description": "du site; sur la période souhaitée, de 36 mois maximum "
"à compter de la date de la demande (période limitée "
"à la date de début du contrat)",
},
),
)
allows_max_daily_power = forms.BooleanField(
required=True,
initial=False,
widget=ConsentCheckboxInput(
attrs={
"label": "L'historique de la puissance maximale quotidienne, en kVA "
"ou kWh,",
"description": "du site ; sur la période souhaitée, de 36 mois maximum "
"à compter de la date de la demande (période limitée à "
"la date de début du contrat)",
},
),
)
allows_load_curve = forms.BooleanField(
required=True,
initial=False,
widget=ConsentCheckboxInput(
attrs={
"label": "L'historique de courbe de charge, aux pas restitués "
"par Enedis,",
"description": "du site<sup>1</sup>; sur la période souhaitée, "
"de 24 mois maximum "
"à compter de la date de la demande (période limitée à "
"la date de début du contrat)",
"help_text": "<sup>1</sup> Ensembles de valeurs moyennes horodatées "
"de la puissance active ou réactive soutirée, sur des "
"périodes d'intégrations consécutives et de même durée.",
},
),
)
allows_technical_contractual_data = forms.BooleanField(
required=True,
initial=False,
widget=ConsentCheckboxInput(
attrs={
"label": "Les données techniques et contractuelles disponibles ",
"description": "du site ; Caractéristiques du raccordement, du "
"dispositif de comptage et des informations "
"contractuelles (option tarifaire, puissance "
"souscrite...)",
},
),
)

# Global authorisation checkbox - this field must be in last position.
consent_agreed = forms.BooleanField(
required=True,
initial=False,
widget=ConsentCheckboxInput(
attrs={
"label": _("I agree to give my consent"),
"help_text": _("Please confirm your consent by checking this box."),
"label": _("J'accepte de donner mon consentement"),
},
),
)
2 changes: 1 addition & 1 deletion src/dashboard/apps/consent/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@
"email": "<[email protected]>",
},
)
CONSENT_DONE_AT = getattr(settings, "CONSENT_DONE_AT", "<city>")
CONSENT_SIGNATURE_LOCATION = getattr(settings, "CONSENT_SIGNATURE_LOCATION", "<city>")
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

<label class="fr-label"
{% if widget.attrs.id %}for="{{ widget.attrs.id }}"{% endif %}>
{{ widget.attrs.label }}
<span class="fr-hint-text">{{ widget.attrs.help_text }}</span>
<span>
<strong>{{ widget.attrs.label }}</strong>
{{ widget.attrs.description|safe }}
</span>
<span class="fr-hint-text">{{ widget.attrs.help_text|safe }}</span>
</label>

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{% load i18n %}

{% comment %}
Note: all texts of this page are intended to appear in a contract and must
therefore be in French and non-translatable.
{% endcomment %}

<div class="fr-fieldset__element fr-my-4w">
<legend class="fr-fieldset__legend" id="text-legend">
D. Données à transmettre à la DGEC
</legend>

<p>Par la signature de ce document, <strong>le Client autorise expressément le Tiers à
demander et à recevoir communication auprès d'Enedis</strong>, SA à directoire et à
conseil de surveillance, au capital de 270 037 000 euros, immatriculés au R.C.S
de Nanterre sous le numéro 444 608 442 et dont le siège social est situé Tour
Enedis, 34 place des Corolles, 92070 Paris La Défense Cedex, <strong>des données
cochées ci-dessous, sous réserve de disponibilité</strong> :
</p>

{% for field in form %}

{% if forloop.last %}
{% comment %}
These paragraphs are located just before the `global consent checkbox`.
Attention: the `consent_agreed` checkbox must always be positioned last in the corresponding forms.py.
{% endcomment %}
<p>
Usage des données : Suivi de la mise en œuvre de la politique énergétique.
</p>
<p>
La présente autorisation ne peut être cédée et pourra être retirée à tout moment.
Elle est consentie pour toute la période du contrat ou à défaut pour la durée de
12 mois à compter de la date de signature. Les données ainsi acquises sont
détruites dès la fin de validité de la présente autorisation.
<br />
La présente autorisation est conservée pendant <strong>5 ans</strong> à compter
de sa signature conformément à l’article 2224 du code civil et sont destinées à
Enedis qui s’engage à ne pas communiquer ces informations à des tiers sauf
obligation réglementaire.
<br />
Conformément à la loi n°78-17 du 6 janvier 1978 modifiée et au règlement (UE)
n°2016/679 du 27 avril 2016, les informations recueillies sont enregistrées dans
un fichier informatisé par ENEDIS en sa qualité de responsable du traitement à
des fins de gestion et de traçabilité des demandes.
<br />
Vous disposez d’un droit d’accès à vos données, de rectification, d’opposition et
d’effacement pour motifs légitimes.
Vous disposez, également, d’un droit à la limitation du traitement et à la
portabilité des données à caractère personnel vous concernant.
Vous pouvez exercer vos droits à l’adresse suivante : Enedis, 34 place des
Corolles, 92079 Paris La Défense Cedex.
Conformément à la loi "informatique et libertés", vous disposez de la faculté
d’introduire une réclamation auprès de la CNIL.
</p>

{% include "consent/includes/_manage_consents_date_place.html" %}
{% endif %}

<div class="{% if field.errors %}fr-pl-3v{% endif %} fr-mb-6v">
<div class="fr-checkbox-group {% if field.errors %}fr-checkbox-group--error{% endif %}">
{{ field }}
<div class="fr-messages-group" id="consent_agreed-messages" aria-live="assertive">
{% if field.errors %}
{% for error in field.errors %}
<p class="fr-message fr-message--error" id="checkboxes-error-message-error">
{{ error }}
</p>
{% endfor %}
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{% load i18n %}

{% comment %}
Note: all texts of this page are intended to appear in a contract and must
therefore be in French and non-translatable.
{% endcomment %}

{% for entity in entities %}
<div class="fr-fieldset__element fr-my-4w">

<legend class="fr-fieldset__legend">
B. Client raccordé
</legend>

<p>
Merci de vérifier l’exactitude des informations concernant votre structure et le
signataire du présent formulaire.
<br />
En cas d'informations erronées, merci de nous contacter :
<a class="fr-link fr-link--icon-left fr-icon-mail-line"
href="mailto:{{ mailto }}?subject=[QualiCharge] Informations erronées dans le formulaire de gestion des autorisations">
{{ mailto }}
</a>
</p>

<div class="fr-table fr-table--bordered" id="table-bordered-component">
<div class="fr-table__wrapper">
<div class="fr-table__container">
<div class="fr-table__content">
<table>
<caption class="fr-text--md">
Informations sur l'entreprise et le représentant
</caption>
<thead>
<tr>
<th scope="col">
Libellé
</th>
<th scope="col">
Valeur
</th>
</tr>
</thead>
<tbody>
{% with row_number=0 %}
<tr class="fr-table__section">
<td colspan="2"><strong>Informations sur la structure</strong></td>
</tr>
{% include "consent/includes/_table_row.html" with label="Dénomination sociale" value=entity.name row_number=row_number|add:"1" %}
{% include "consent/includes/_table_row.html" with label="Type de structure" value=entity.company_type row_number=row_number|add:"1" %}
{% include "consent/includes/_table_row.html" with label="Forme juridique" value=entity.legal_form row_number=row_number|add:"1" %}
{% include "consent/includes/_table_row.html" with label="Nom commercial" value=entity.trade_name row_number=row_number|add:"1" %}
{% include "consent/includes/_table_row.html" with label="N° d'identification SIRET" value=entity.siret row_number=row_number|add:"1" %}
{% include "consent/includes/_table_row.html" with label="Activité NAF" value=entity.naf row_number=row_number|add:"1" %}
{% include "consent/includes/_table_row.html" with label="Adresse" value=entity.address_1 row_number=row_number|add:"1" %}
{% include "consent/includes/_table_row.html" with label="Complément d'adresse" value=entity.address_2 row_number=row_number|add:"1" %}
{% include "consent/includes/_table_row.html" with label="Code Postale" value=entity.address_zip_code row_number=row_number|add:"1" %}
{% include "consent/includes/_table_row.html" with label="Commune" value=entity.address_city row_number=row_number|add:"1" %}
{# todo: add a field to retrieve this information (+ email and phone) if it doesn't exist #}
{% include "consent/includes/_table_row.html" with label="Nom du titulaire du contrat" value="-" row_number=row_number|add:"1" %}

<tr class="fr-table__section">
<td colspan="2">
<strong>Informations sur le signataire du présent formulaire</strong>
</td>
</tr>
{% include "consent/includes/_table_row.html" with label="Nom" value=request.user.last_name row_number=row_number|add:"1" %}
{% include "consent/includes/_table_row.html" with label="Prénom" value=request.user.first_name row_number=row_number|add:"1" %}
{% include "consent/includes/_table_row.html" with label="E-mail" value=request.user.email row_number=row_number|add:"1" %}
{% endwith %}
</tbody>
</table>
</div>
</div>
</div>
</div>

</div>
{% endfor %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{% load i18n %}

{% comment %}
Note: all texts of this page are intended to appear in a contract and must
therefore be in French and non-translatable.
{% endcomment %}

<div class="fr-fieldset__element fr-my-4w">
<legend class="fr-fieldset__legend" id="text-legend">
A. Points de livraison à valider
</legend>

<p>
Cochez les lignes correspondant aux PRMs pour lesquelles vous autorisez expressément
la DGEC à demander et à recevoir la communication des données mentionnées au point D.
</p>

{# toggle button #}
<div class="fr-checkbox-group fr-mb-2v">
<input type="checkbox" id="toggle-all" name="toggle-all"
aria-describedby="toggle-all-messages"
data-fr-js-checkbox-input="true"
data-fr-js-checkbox-actionee="true">
<label class="fr-label" for="toggle-all"><strong>{% trans "Toggle All" %}</strong></label>
</div>

{# delivery points #}
<div class="consent-wrapper fr-py-6v fr-mb-6v">
<div class="consent-wrapper__inner">
{% for entity in entities %}
<fieldset class="fr-fieldset" id="checkboxes" aria-labelledby="checkboxes-legend checkboxes-messages">
<legend class="fr-fieldset__legend--regular fr-fieldset__legend" id="checkboxes-legend">{{ entity.name }}</legend>

{% for consent in entity.get_consents %}
<div class="fr-fieldset__element">
<div class="fr-checkbox-group">
<input type="checkbox"
name="status"
value="{{ consent.id }}"
id="{{ consent.id }}"
{% if consent.status == 'VALIDATED' %} checked="checked" disabled="disabled"{% endif %}
aria-describedby="{{ consent.id }}-messages"
data-fr-js-checkbox-input="true"
data-fr-js-checkbox-actionee="true" />
<label class="fr-label" for="{{ consent.id }}"
{% if consent.status == 'VALIDATED' %}
title="{% trans "Point de livraison déjà validé." %}"
{% elif consent.status == 'AWAITING' %}
title="{% trans "Point de livraison en attende de validation." %}"
{% endif %}>
{{ consent.delivery_point.provider_assigned_id }}
</label>
<div class="fr-messages-group" id="{{ consent.id }}-messages" aria-live="assertive"></div>
</div>
</div>
{% endfor %}
</fieldset>
{% endfor %}
</div>
</div>

</div>
Loading

0 comments on commit e6d90a3

Please sign in to comment.