Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into nettoyage-api-publique
Browse files Browse the repository at this point in the history
  • Loading branch information
cedricr authored Mar 21, 2024
2 parents 45a70cf + f354a51 commit e6797e3
Show file tree
Hide file tree
Showing 18 changed files with 606 additions and 56 deletions.
7 changes: 6 additions & 1 deletion config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,15 @@
path("search/", dora.services.views.search, {"di_client": di_client}),
path("stats/event/", dora.stats.views.log_event),
path(
"service-di/<slug:di_id>/",
"services-di/<slug:di_id>/",
dora.services.views.service_di,
{"di_client": di_client},
),
path(
"services-di/<slug:di_id>/share/",
dora.services.views.share_di_service,
{"di_client": di_client},
),
path("admin-division-search/", dora.admin_express.views.search),
path("admin-division-reverse-search/", dora.admin_express.views.reverse_search),
path("admin-division-departments/", dora.admin_express.views.get_departments),
Expand Down
8 changes: 3 additions & 5 deletions dora/core/management/commands/import_structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from dora.core.models import ModerationStatus
from dora.core.notify import send_moderation_notification
from dora.core.validators import validate_full_siret
from dora.core.validators import validate_siret
from dora.services.models import ServiceModel
from dora.services.utils import instantiate_model
from dora.sirene.models import Establishment
Expand Down Expand Up @@ -39,10 +39,8 @@ def to_string_array(strings_list):

class ImportSerializer(serializers.Serializer):
name = serializers.CharField()
siret = serializers.CharField(allow_blank=True, validators=[validate_full_siret])
parent_siret = serializers.CharField(
allow_blank=True, validators=[validate_full_siret]
)
siret = serializers.CharField(allow_blank=True, validators=[validate_siret])
parent_siret = serializers.CharField(allow_blank=True, validators=[validate_siret])
admins = serializers.ListField(child=serializers.EmailField(), allow_empty=True)
labels = serializers.ListField(child=serializers.CharField(), allow_empty=True)
models = serializers.ListField(child=serializers.CharField(), allow_empty=True)
Expand Down
10 changes: 6 additions & 4 deletions dora/core/tests/test_structures_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,22 @@ def test_unknown_siret_wont_create_anything(self):
def test_invalid_siret_wont_create_anything(self):
self.add_row(["foo", "1234", "", "[email protected]", "", ""])
out, err = self.call_command()
self.assertIn("Siret invalide", err)
self.assertIn("Le numéro SIRET doit être composé de 14 chiffres.", err)
self.assertIn("siret", err)
self.assertFalse(Structure.objects.filter(siret="12345").exists())
self.assertFalse(User.objects.filter(email="[email protected]").exists())
self.assertEqual(len(mail.outbox), 0)

def test_invalid_parent_siret_error(self):
self.add_row(["foo", "", "1234", "[email protected]", "", ""])
out, err = self.call_command()
self.assertIn("Siret parent invalide", err)
self.assertIn("Le numéro SIRET doit être composé de 14 chiffres.", err)
self.assertIn("parent_siret", err)

def test_unknown_parent_siret_error(self):
self.add_row(["foo", "", "12345678901234", "[email protected]", "", ""])
out, err = self.call_command()
self.assertIn("Siret parent inconnu", err)
self.assertIn("SIRET parent inconnu", err)

def test_missing_siret_error(self):
self.add_row(["foo", "", "", "[email protected]", "", ""])
Expand All @@ -88,7 +90,7 @@ def test_no_recursive_branch(self):
self.add_row(["foo", "", "12345678901234", "[email protected]", "", ""])
out, err = self.call_command()
self.assertIn(
"Le siret 12345678901234 est une antenne, il ne peut pas être utilisé comme parent",
"Le SIRET 12345678901234 est une antenne, il ne peut pas être utilisé comme parent",
err,
)

Expand Down
17 changes: 12 additions & 5 deletions dora/data_inclusion/mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def is_orientable(service_data: dict) -> bool:
return not blacklisted


def map_service(service_data: dict) -> dict:
def map_service(service_data: dict, is_authenticated: bool) -> dict:
categories = None
subcategories = None
if service_data["thematiques"] is not None:
Expand Down Expand Up @@ -182,7 +182,6 @@ def map_service(service_data: dict) -> dict:
Profil(p)
for p in (set(service_data["profils"]) & {p.value for p in Profil})
]

return {
"access_conditions": None,
"access_conditions_display": None,
Expand Down Expand Up @@ -219,9 +218,15 @@ def map_service(service_data: dict) -> dict:
"concerned_public_display": [p.label for p in profils]
if profils is not None
else None,
"contact_email": service_data["courriel"],
"contact_name": service_data["contact_nom_prenom"],
"contact_phone": service_data["telephone"],
"contact_email": service_data["courriel"]
if service_data["contact_public"] or is_authenticated
else None,
"contact_name": service_data["contact_nom_prenom"]
if service_data["contact_public"] or is_authenticated
else None,
"contact_phone": service_data["telephone"]
if service_data["contact_public"] or is_authenticated
else None,
"creation_date": service_data["date_creation"],
"credentials": service_data["justificatifs"],
"credentials_display": service_data["justificatifs"],
Expand Down Expand Up @@ -275,6 +280,8 @@ def map_service(service_data: dict) -> dict:
"structure_info": {
"name": service_data["structure"]["nom"],
"department": structure_department,
"phone": service_data["structure"]["telephone"],
"email": service_data["structure"]["courriel"],
},
"subcategories": [c.value for c in subcategories]
if subcategories is not None
Expand Down
2 changes: 2 additions & 0 deletions dora/data_inclusion/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ def make_di_service_data(**kwargs) -> dict:
"zone_diffusion_nom": "foo",
"structure": {
"nom": "Rouge Empire",
"telephone": "1234",
"courriel": "[email protected]",
},
},
**kwargs,
Expand Down
83 changes: 83 additions & 0 deletions dora/services/emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.conf import settings
from django.template.loader import render_to_string
from furl import furl
from mjml import mjml2html

from dora.core.emails import send_mail

Expand Down Expand Up @@ -30,6 +31,88 @@ def send_service_feedback_email(service, full_name, email, message):
)


def send_service_sharing_email(
service, sender_name, recipient_email, recipient_kind, is_di
):
cta_link = (
furl(settings.FRONTEND_URL)
/ "services"
/ f"{'di--' if is_di else ''}{service['slug']}"
)
cta_link.add(
{
"mtm_campaign": "FicheService",
"mtm_kwd": "PartagerLaFiche",
}
)

service_email = ""
if service["is_contact_info_public"]:
service_email = (
service["contact_email"] or service["structure_info"]["email"] or ""
)
else:
service_email = service["structure_info"]["email"] or ""

service_phone = ""
if service["is_contact_info_public"]:
service_phone = (
service["contact_phone"] or service["structure_info"]["phone"] or ""
)
else:
service_phone = service["structure_info"]["phone"] or ""

modes = []
if recipient_kind == "professional":
for mode in zip(
service["coach_orientation_modes"] or [],
service["coach_orientation_modes_display"] or [],
):
if mode[0] == "autre":
modes.append(service["coach_orientation_modes_other"] or "")
else:
modes.append(mode[1])
else:
all_beneficiaries_modes = [
mode for mode in service["beneficiaries_access_modes"] or []
]
if "se-presenter" in all_beneficiaries_modes:
modes.append("Se présenter")
if "envoyer-courriel" in all_beneficiaries_modes and service_email:
modes.append(f"Envoyer un mail: {service_email}")
if "telephoner" in all_beneficiaries_modes and service_phone:
modes.append(f"Téléphoner: {service_phone}")
if (
"autre" in all_beneficiaries_modes
and service["beneficiaries_access_modes_other"]
):
modes.append(service["beneficiaries_access_modes_other"])

context = {
"sender_name": sender_name,
"service": service,
"cta_link": cta_link,
"with_legal_info": True,
"with_dora_info": True,
"publics": [s for s in service["concerned_public_display"] or []]
or ["Tous publics"],
"requirements": [
*[ac for ac in service["access_conditions_display"] or []],
*[r for r in service["requirements_display"] or []],
]
or ["Aucun"],
"modes": modes,
"for_beneficiary": recipient_kind == "beneficiary",
}

send_mail(
"On vous a recommandé une solution solidaire",
recipient_email,
mjml2html(render_to_string("sharing-email.mjml", context)),
tags=["service-sharing"],
)


def send_service_reminder_email(
recipient_email, recipient_name, structures_to_update, structures_with_drafts
):
Expand Down
2 changes: 2 additions & 0 deletions dora/services/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ class Meta:
"siret",
"slug",
"url",
"phone",
"email",
]
read_only_fields = [
"city",
Expand Down
94 changes: 94 additions & 0 deletions dora/services/templates/sharing-email.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{% extends "email-base.mjml" %}

{% block preview %}
Découvrez le service « {{ service.name }} » recommandé par {{ sender_name }}.
{% endblock %}

{% block illustration %}
<mj-image src="{% frontend_url %}/emails/illu-orientation.png" alt=""/>
{% endblock %}

{% block title %}
{% if for_beneficiary %}
On vous a recommandé une solution
{% else %}
On vous a recommandé un service
{% endif %}
{% endblock %}

{% block content %}
<p>
<strong>Bonjour,</strong>
</p>

<p>{{ sender_name }} vous a recommandé le service
suivant :
</p>
<div style="color: #555555; background-color: #F0F8FF; border-radius: 12px;
padding: 16px 24px; margin: 24px 0">
<div style="color: #555555, font-size: 14px; line-height: 24px; margin-bottom: 2px">{{ service.structure_info.name }}</div>
<div>
<a href="{{ cta_link }}"
style="color: #000091; font-size: 23px; font-weight: 700; text-decoration-line: none; line-height: 26px">
{{ service.name }}
</a>
</div>
<div style="color: #555555, font-size: 13px; line-height: 24px; margin-top: 6px">
{% if service.address1 %}
{{service.address1}}{% if service.address2 %}, {{ service.address2}}{% endif %},
{{ service.postal_code }} {{ service.city }}
{% endif %}&nbsp;
</div>
</div>


<h2 style="margin-bottom: 8px">
Le public concerné :
</h2>

<ul>
{% for item in publics %}
<li>{{ item }}</li>
{% endfor %}
</ul>

<h2 style="margin-bottom: 8px">
Les critères et compétences :
</h2>

<ul>
{% for item in requirements %}
<li>{{ item }}</li>
{% endfor %}
</ul>


{% if not modes %}
{% if for_beneficiary %}
<h2 style="margin-bottom: 8px">
Comment mobiliser ce service :
</h2>

<p style="color: #ED7D00; font-style: italic;">Demandez de l’aide à votre conseiller ou à un professionnel qui travaille
dans l’insertion pour savoir comment accéder à ce service.</p>
{% endif %}

{% else %}
<h2 style="margin-bottom: 8px">
Comment mobiliser ce service :
</h2>

<ul>
{% for item in modes %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}

{% block cta %}
<mj-button mj-class="cta" href="{{ cta_link }}">
Consulter le service
</mj-button>
<mj-spacer height="24px"/>
{% endblock %}
Loading

0 comments on commit e6797e3

Please sign in to comment.