Skip to content

Commit

Permalink
Ajouter le code de base pour les notifications
Browse files Browse the repository at this point in the history
Ajout de Django Post office pour la gestion des files d'attentes des
mails.
Ajout de la logique métier en fonction de chaque type de message.
  • Loading branch information
Anto59290 committed Sep 19, 2024
1 parent 7257825 commit be3fe13
Show file tree
Hide file tree
Showing 12 changed files with 346 additions and 10 deletions.
2 changes: 2 additions & 0 deletions core/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MUS_STRUCTURE = "MUS"
BSV_STRUCTURE = "SAS/SDSPV/BSV"
12 changes: 10 additions & 2 deletions core/managers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django.contrib.contenttypes.models import ContentType
from django.db.models import Case, When, Value, IntegerField, QuerySet

from core.constants import MUS_STRUCTURE, BSV_STRUCTURE


class DocumentQueryset(QuerySet):
def order_list(self):
Expand Down Expand Up @@ -28,7 +30,13 @@ def with_structure_and_agent(self):
return self.select_related("structure", "agent")

def get_mus(self):
return self.get(structure__niveau2="MUS")
return self.get(structure__niveau2=MUS_STRUCTURE)

def get_bsv(self):
return self.get(structure__niveau2="SAS/SDSPV/BSV")
return self.get(structure__niveau2=BSV_STRUCTURE)

def has_agent(self):
return self.exclude(agent__isnull=True)

def has_structure(self):
return self.exclude(structure__isnull=True)
2 changes: 1 addition & 1 deletion core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class Message(models.Model):
)
TYPES_TO_FEMINIZE = (NOTE, DEMANDE_INTERVENTION, FIN_SUIVI)
TYPES_WITHOUT_RECIPIENTS = (NOTE, POINT_DE_SITUATION, FIN_SUIVI)
TYPES_WITH_LIMITED_RECIPIENTS = COMPTE_RENDU
TYPES_WITH_LIMITED_RECIPIENTS = (COMPTE_RENDU,)

message_type = models.CharField(max_length=100, choices=MESSAGE_TYPE_CHOICES)
title = models.CharField(max_length=512, verbose_name="Titre")
Expand Down
45 changes: 45 additions & 0 deletions core/notifications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from .post_office_mail import send

from core.constants import MUS_STRUCTURE
from core.models import Message


def _send_message(recipients: list[str], copy: list[str], subject, message):
send(
recipients=recipients,
cc=copy,
sender="[email protected]",
subject=f"SEVES - {subject}",
message=message,
)


def notify_message(instance: Message):
recipients, copy = [], []
message, subject = None, None
if instance.message_type == Message.MESSAGE:
subject = instance.title
message = f"Bonjour,\n Vous avez reçu un message sur SEVES dont voici le contenu : \n {instance.content}"
recipients = [r.email for r in instance.recipients.all()]
copy = [r.email for r in instance.recipients_copy.all()]
elif instance.message_type == Message.COMPTE_RENDU:
subject = instance.title
message = f"Bonjour,\n Vous avez reçu un compte rendu sur demande d'intervention sur SEVES dont voici le contenu : \n {instance.content}"
recipients = [r.email for r in instance.recipients.all()]
elif instance.message_type == Message.DEMANDE_INTERVENTION:
subject = instance.title
message = "Bonjour,\n Vous avez reçu un message sur SEVES."
recipients = [r.email for r in instance.recipients.has_structure()]
copy = [r.email for r in instance.recipients_copy.has_structure()]
elif instance.message_type == Message.POINT_DE_SITUATION:
subject = instance.title
message = "Bonjour,\n Vous avez reçu un nouveau point de suivi sur SEVES."
recipients = [c.email for c in instance.content_object.contacts.has_agent()]
elif instance.message_type == Message.FIN_SUIVI:
subject = instance.title
message = "Bonjour,\n Vous avez reçu un nouveau point de suivi sur SEVES."
recipients = instance.content_object.contacts.has_agent().filter(agent__structure__niveau2=MUS_STRUCTURE)
recipients = [r.email for r in recipients]

if recipients and message:
_send_message(recipients, copy, subject=subject, message=message)
125 changes: 125 additions & 0 deletions core/post_office_mail.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
from django.conf import settings
from django.core.exceptions import ValidationError
from post_office.models import Email, EmailTemplate, PRIORITY
from post_office.settings import (
get_available_backends,
get_log_level,
)
from post_office.signals import email_queued
from post_office.utils import (
create_attachments,
get_email_template,
parse_emails,
parse_priority,
)
from post_office.mail import create


def send(
recipients=None,
sender=None,
template=None,
context=None,
subject="",
message="",
html_message="",
scheduled_time=None,
expires_at=None,
headers=None,
priority=None,
attachments=None,
render_on_delivery=False,
log_level=None,
commit=True,
cc=None,
bcc=None,
language="",
backend="",
):
"""
Taken directly from Django post office in order to add the pk of the email in the headers
"""
try:
recipients = parse_emails(recipients)
except ValidationError as e:
raise ValidationError("recipients: %s" % e.message)

try:
cc = parse_emails(cc)
except ValidationError as e:
raise ValidationError("c: %s" % e.message)

try:
bcc = parse_emails(bcc)
except ValidationError as e:
raise ValidationError("bcc: %s" % e.message)

if sender is None:
sender = settings.DEFAULT_FROM_EMAIL

priority = parse_priority(priority)

if log_level is None:
log_level = get_log_level()

if not commit:
if priority == PRIORITY.now:
raise ValueError("send_many() can't be used with priority = 'now'")
if attachments:
raise ValueError("Can't add attachments with send_many()")

if template:
if subject:
raise ValueError('You can\'t specify both "template" and "subject" arguments')
if message:
raise ValueError('You can\'t specify both "template" and "message" arguments')
if html_message:
raise ValueError('You can\'t specify both "template" and "html_message" arguments')

# template can be an EmailTemplate instance or name
if isinstance(template, EmailTemplate):
template = template
# If language is specified, ensure template uses the right language
if language and template.language != language:
template = template.translated_templates.get(language=language)
else:
template = get_email_template(template, language)

if backend and backend not in get_available_backends().keys():
raise ValueError("%s is not a valid backend alias" % backend)

email = create(
sender,
recipients,
cc,
bcc,
subject,
message,
html_message,
context,
scheduled_time,
expires_at,
headers,
template,
priority,
render_on_delivery,
commit=commit,
backend=backend,
)

if attachments:
attachments = create_attachments(attachments)
email.attachments.add(*attachments)

if email.headers:
email.headers["X-Mailin-Tag"] = email.pk
else:
email.headers = {"X-Mailin-Tag": email.pk}
email.save()

if priority == PRIORITY.now:
email.dispatch(log_level=log_level)
elif commit:
email_queued.send(sender=Email, emails=[email])

return email
3 changes: 2 additions & 1 deletion core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
)
from django.http import HttpResponseRedirect
from django.utils.translation import ngettext

from .notifications import notify_message

from .models import Document, Message, Contact, FinSuiviContact

Expand Down Expand Up @@ -235,6 +235,7 @@ def form_valid(self, form):
response = super().form_valid(form)
self._add_contacts_to_object(form.instance)
self._create_documents(form)
notify_message(form.instance)
messages.success(self.request, "Le message a bien été ajouté.", extra_tags="core messages")
return response

Expand Down
4 changes: 3 additions & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ env =
OIDC_RP_USER_ENDPOINT=
OIDC_RP_JWKS_ENDPOINT=
OIDC_RP_LOGOUT_ENDPOINT=
CACHE_CLASS=django.core.cache.backends.dummy.DummyCache
CACHE_CLASS=django.core.cache.backends.dummy.DummyCache
EMAIL_BACKEND=django.core.mail.backends.locmem.EmailBackend
EMAIL_PRIORITY=now
3 changes: 2 additions & 1 deletion requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ django-storages[s3]
mozilla-django-oidc
django-filter
faker
django-debug-toolbar
django-debug-toolbar
django-post_office
17 changes: 15 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile
# pip-compile requirements.in
#
asgiref==3.7.2
# via django
bleach[css]==6.1.0
# via django-post-office
boto3==1.34.134
# via django-storages
botocore==1.34.134
Expand Down Expand Up @@ -36,6 +38,7 @@ django==5.0.3
# -r requirements.in
# django-debug-toolbar
# django-filter
# django-post-office
# django-storages
# model-bakery
# mozilla-django-oidc
Expand All @@ -46,6 +49,8 @@ django-environ==0.11.2
# via -r requirements.in
django-filter==24.2
# via -r requirements.in
django-post-office==3.9.0
# via -r requirements.in
django-storages[s3]==1.14.3
# via -r requirements.in
djhtml==3.0.6
Expand Down Expand Up @@ -136,7 +141,9 @@ s3transfer==0.10.2
sentry-sdk[django]==2.5.1
# via -r requirements.in
six==1.16.0
# via python-dateutil
# via
# bleach
# python-dateutil
sqlparse==0.4.4
# via
# django
Expand All @@ -145,6 +152,8 @@ static3==0.7.0
# via dj-static
text-unidecode==1.3
# via python-slugify
tinycss2==1.2.1
# via bleach
typing-extensions==4.11.0
# via pyee
urllib3==2.2.1
Expand All @@ -154,6 +163,10 @@ urllib3==2.2.1
# sentry-sdk
virtualenv==20.25.3
# via pre-commit
webencodings==0.5.1
# via
# bleach
# tinycss2

# The following packages are considered to be unsafe in a requirements file:
# setuptools
14 changes: 14 additions & 0 deletions seves/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"sv.apps.SvConfig",
"core.apps.CoreConfig",
"django_filters",
"post_office",
]

MIDDLEWARE = [
Expand Down Expand Up @@ -204,3 +205,16 @@
INSTALLED_APPS.append("debug_toolbar")
MIDDLEWARE.insert(0, "debug_toolbar.middleware.DebugToolbarMiddleware")
INTERNAL_IPS = ["127.0.0.1"]

POST_OFFICE = {
"BACKENDS": {
"default": env("EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend"),
},
"DEFAULT_PRIORITY": env("EMAIL_PRIORITY", default="medium"),
}

if env("EMAIL_HOST", default=None):
EMAIL_HOST = env("EMAIL_HOST")
EMAIL_PORT = env("EMAIL_PORT")
EMAIL_HOST_USER = env("EMAIL_HOST_USER")
EMAIL_HOST_PASSWORD = env("EMAIL_HOST_PASSWORD")
5 changes: 3 additions & 2 deletions sv/tests/test_fiche_detection_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,10 @@ def test_can_add_and_see_note_without_document(live_server, page: Page, fiche_de
def test_can_add_and_see_compte_rendu(live_server, page: Page, fiche_detection: FicheDetection):
page.goto(f"{live_server.url}{fiche_detection.get_absolute_url()}")

Contact.objects.create(structure=Structure.objects.create(niveau1="MUS", niveau2="MUS", libelle="MUS"))
structure = Structure.objects.create(niveau1="MUS", niveau2="MUS", libelle="MUS")
Contact.objects.create(structure=structure, email="[email protected]")
structure = Structure.objects.create(niveau1="SAS/SDSPV/BSV", niveau2="SAS/SDSPV/BSV", libelle="BSV")
Contact.objects.create(structure=structure)
Contact.objects.create(structure=structure, email="[email protected]")
page.get_by_test_id("element-actions").click()
page.get_by_test_id("fildesuivi-actions-compte-rendu").click()

Expand Down
Loading

0 comments on commit be3fe13

Please sign in to comment.