Skip to content

Commit

Permalink
Modification des emails de notifications
Browse files Browse the repository at this point in the history
- Reprise des objets
- Ajout du titre du message dans le corps de l'email
- Le message s'affiche à l'écran quand on clique sur le lien de la fiche dans l'email
  • Loading branch information
alanzirek committed Feb 27, 2025
1 parent 5f66c8d commit 817a4f6
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 5 deletions.
7 changes: 7 additions & 0 deletions core/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,10 @@ def _get_object_from_content_type(self, *, object_id, content_type_id):
ModelClass = content_type.model_class()
self._object = get_object_or_404(ModelClass, pk=object_id)
return self._object


class EmailNotificationMixin:
"""Mixin pour les modèles qui peuvent être notifiés par email."""

def get_email_subject(self):
raise NotImplementedError
10 changes: 10 additions & 0 deletions core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,16 @@ def __str__(self):
def get_fiche_url(self):
return self.content_object.get_absolute_url()

def get_email_type_display(self) -> str:
"""Renvoie une version abrégée du type de message pour les emails."""
match self.message_type:
case self.DEMANDE_INTERVENTION:
return "DI"
case self.COMPTE_RENDU:
return "CR sur DI"
case _:
return self.get_message_type_display()


class LienLibre(models.Model):
content_type_1 = models.ForeignKey(ContentType, on_delete=models.PROTECT, related_name="relation_1")
Expand Down
6 changes: 4 additions & 2 deletions core/notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ def _send_message(recipients: list[str], copy: list[str], subject: str, content:
template, _ = EmailTemplate.objects.update_or_create(
name="seves_email_template",
defaults={
"subject": f"Sèves - {message_obj.content_object.numero} - {message_obj.message_type} - {subject}",
"subject": f"[Sèves] {message_obj.content_object.get_email_subject()} - {message_obj.get_email_type_display()}",
"html_content": """
<!DOCTYPE html>
<html>
<div style="font-family: Arial, sans-serif;">
<p style="white-space: pre-wrap; line-height: 1.5;">{{ subject }}</p>
<p style="white-space: pre-wrap; line-height: 1.5;">{{ content }}</p>
<p style="font-weight: bold; margin-top: 20px; margin-bottom: 0px;">{{ message_obj.sender.agent.prenom }} {{ message_obj.sender.agent.nom }}</p>
<p style="margin-top: 0px;">{{ message_obj.sender.agent.structure }}</p>
Expand All @@ -31,8 +32,9 @@ def _send_message(recipients: list[str], copy: list[str], subject: str, content:
template=template,
context={
"message_obj": message_obj,
"subject": subject,
"content": content,
"fiche_url": f"{settings.ROOT_URL}{message_obj.content_object.get_absolute_url()}",
"fiche_url": f"{settings.ROOT_URL}{message_obj.content_object.get_absolute_url_with_message(message_obj.id)}",
},
)

Expand Down
8 changes: 8 additions & 0 deletions sv/models/evenements.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
WithMessageUrlsMixin,
WithFreeLinkIdsMixin,
AllowsSoftDeleteMixin,
EmailNotificationMixin,
)
from core.mixins import WithEtatMixin
from core.models import Document, Message, Contact, Structure, FinSuiviContact
Expand All @@ -30,6 +31,7 @@ class Evenement(
WithMessageUrlsMixin,
WithFreeLinkIdsMixin,
AllowsSoftDeleteMixin,
EmailNotificationMixin,
models.Model,
):
numero_annee = models.IntegerField(verbose_name="Année")
Expand Down Expand Up @@ -92,6 +94,9 @@ def save(self, *args, **kwargs):
def get_absolute_url(self):
return reverse("evenement-details", kwargs={"numero": self.numero})

def get_absolute_url_with_message(self, message_id: int):
return f"{self.get_absolute_url()}?message={message_id}"

def get_update_url(self):
return reverse("evenement-update", kwargs={"pk": self.pk})

Expand Down Expand Up @@ -181,3 +186,6 @@ def add_fin_suivi(self, user):
message_type=Message.FIN_SUIVI,
content_object=self,
)

def get_email_subject(self):
return f"{self.organisme_nuisible.code_oepp} {self.numero}"
17 changes: 15 additions & 2 deletions sv/static/sv/sidebar.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
document.addEventListener('DOMContentLoaded', function () {

function openSidebar(sidebar) {
sidebar.classList.add('open');
document.querySelector('.main-container').classList.add('open');
}

function bindClickToSidebar(clicked_element, sidebar){
clicked_element.addEventListener("click", event => {
event.preventDefault()
document.querySelectorAll(".sidebar").forEach(element=>element.classList.remove('open'))
sidebar.classList.add('open');
document.querySelector('.main-container').classList.add('open')
openSidebar(sidebar);
})
}

Expand All @@ -17,8 +21,16 @@ document.addEventListener('DOMContentLoaded', function () {
document.querySelector('.main-container').classList.toggle('open')
})
})
}

function openMessageFromUrl() {
const urlParams = new URLSearchParams(window.location.search);
const messageId = urlParams.get('message');
if (messageId) {
openSidebar(document.getElementById(`sidebar-message-details-${messageId}`));
}
}

document.querySelectorAll(".fil-de-suivi-sidebar").forEach(element => {
const messageId = element.dataset.messagePk
bindClickToSidebar(element, document.getElementById(`sidebar-message-details-${messageId}`))
Expand All @@ -27,4 +39,5 @@ document.addEventListener('DOMContentLoaded', function () {
bindClickToSidebar(element, document.getElementById('sidebar'))
})
bindAllCloseSidebar()
openMessageFromUrl();
})
37 changes: 36 additions & 1 deletion sv/tests/test_notifications.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import re

import pytest
from django.utils import html
from playwright.sync_api import Page, expect

from core.constants import AC_STRUCTURE, MUS_STRUCTURE, BSV_STRUCTURE
from core.factories import ContactAgentFactory, ContactStructureFactory
Expand Down Expand Up @@ -29,7 +32,8 @@ def create_message_and_notify(
def assert_mail_common(mails, message, evenement):
assert len(mails) == 1
mail = mails[0]
assert mail.subject == f"Sèves - {evenement.numero} - {message.message_type} - {message.title}"
message_type = message.get_email_type_display()
assert mail.subject == f"[Sèves] {evenement.organisme_nuisible.code_oepp} {evenement.numero} - {message_type}"
assert mail.from_email == "[email protected]"
assert message.sender.agent.prenom in mail.body
assert message.sender.agent.nom in mail.body
Expand Down Expand Up @@ -153,3 +157,34 @@ def test_notification_compte_rendu(mailoutbox):
assert message.content in mail.body
assert set(mail.to) == {contact_mus.email, contact_bsv.email}
assert set(mail.cc) == set()


def test_email_contains_correct_link_to_fiche_with_message(mailoutbox):
evenement = EvenementFactory()
message = create_message_and_notify(
message_type=Message.MESSAGE,
object=evenement,
recipients=[ContactAgentFactory()],
)
body = mailoutbox[0].body
url = re.search(r'href="([^"]+)"', body).group(1)
expected_url = f"http://testserver.com{evenement.get_absolute_url_with_message(message.id)}"
assert url == expected_url


def test_open_message_sidebar_when_clicking_on_link(live_server, page: Page, mailoutbox):
evenement = EvenementFactory()
contact = ContactAgentFactory()
message = create_message_and_notify(
message_type=Message.MESSAGE,
object=evenement,
recipients=[contact],
)
body = mailoutbox[0].body
url = re.search(r'href="([^"]+)"', body).group(1)
url = url.replace("http://testserver.com", live_server.url)
page.goto(url)
expect(page.locator(".sidebar").get_by_text(f"De : {message.sender.display_with_agent_unit}")).to_be_visible()
expect(page.locator(".sidebar").get_by_text(f"A : {contact.display_with_agent_unit}")).to_be_visible()
expect(page.locator(".sidebar").get_by_text(message.title)).to_be_visible()
expect(page.locator(".sidebar").get_by_text(message.content)).to_be_visible()

0 comments on commit 817a4f6

Please sign in to comment.