-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add email reminder sent every 3 monthes to organizations admins…
… having multiple members
- Loading branch information
Showing
11 changed files
with
199 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
itou/companies/migrations/0003_company_active_members_email_reminder_last_sent_at.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Generated by Django 5.0.6 on 2024-06-05 09:52 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
dependencies = [ | ||
("companies", "0002_fix_job_app_contract_type_enum"), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name="company", | ||
name="active_members_email_reminder_last_sent_at", | ||
field=models.DateTimeField( | ||
null=True, verbose_name="date d'envoi du dernier rappel pour vérifier les membres actifs" | ||
), | ||
), | ||
] |
19 changes: 19 additions & 0 deletions
19
itou/institutions/migrations/0002_institution_active_members_email_reminder_last_sent_at.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Generated by Django 5.0.6 on 2024-06-05 09:52 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
dependencies = [ | ||
("institutions", "0001_initial"), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name="institution", | ||
name="active_members_email_reminder_last_sent_at", | ||
field=models.DateTimeField( | ||
null=True, verbose_name="date d'envoi du dernier rappel pour vérifier les membres actifs" | ||
), | ||
), | ||
] |
19 changes: 19 additions & 0 deletions
19
...bers/migrations/0002_prescriberorganization_active_members_email_reminder_last_sent_at.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Generated by Django 5.0.6 on 2024-06-05 09:52 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
dependencies = [ | ||
("prescribers", "0001_initial"), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name="prescriberorganization", | ||
name="active_members_email_reminder_last_sent_at", | ||
field=models.DateTimeField( | ||
null=True, verbose_name="date d'envoi du dernier rappel pour vérifier les membres actifs" | ||
), | ||
), | ||
] |
17 changes: 17 additions & 0 deletions
17
itou/templates/common/emails/check_authorized_members_email_body.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{% extends "layout/base_email_text_body.txt" %} | ||
{% load format_filters %} | ||
{% block body %} | ||
Bonjour, | ||
|
||
En tant qu’administrateur de l’organisation {{ structure.name }}, nous vous invitons à vérifier la liste des membres afin de vous assurer que seuls les collaborateurs qui travaillent au sein de cette organisation puissent accéder à votre espace de travail. | ||
|
||
RDV sur votre espace des emplois de l’inclusion à la rubrique “Gérer les collaborateurs” : | ||
|
||
Si un collaborateur a quitté votre organisation, vous devez le retirer des membres en cliquant sur le bouton d’action situé à droite, puis sur l’option “retirer de la structure”. | ||
|
||
Pour des raisons de sécurité et si la configuration de votre organisation vous le permet, nous vous invitons à nommer plusieurs administrateurs. | ||
|
||
Ce rappel automatique vous sera transmis tous les 3 mois, mais il est vivement recommandé d’effectuer cette action dès qu’un collaborateur quitte votre organisation. | ||
|
||
Cordialement, | ||
{% endblock body %} |
4 changes: 4 additions & 0 deletions
4
itou/templates/common/emails/check_authorized_members_email_subject.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{% extends "layout/base_email_text_subject.txt" %} | ||
{% block subject %} | ||
Rappel sécurité : vérifiez la liste des membres de l’organisation {{ structure.name }} | ||
{% endblock %} |
92 changes: 92 additions & 0 deletions
92
itou/users/management/commands/send_check_authorized_members_email.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import datetime | ||
|
||
from django.db import transaction | ||
from django.db.models import Count, IntegerField, Prefetch, Q | ||
from django.db.models.functions import Coalesce, ExtractDay, ExtractMonth, Least, Mod | ||
from django.utils import timezone | ||
|
||
from itou.companies.models import Company | ||
from itou.institutions.models import Institution | ||
from itou.prescribers.models import PrescriberOrganization | ||
from itou.users.models import User | ||
from itou.users.notifications import OrganizationActiveMembersReminderNotification | ||
from itou.utils.command import BaseCommand | ||
|
||
|
||
class Command(BaseCommand): | ||
""" | ||
Send an email reminder every 3 months asking admins of companies, organizations and institutions | ||
having more than 1 member to review members access and ensure that only authorized members have | ||
access to the organization data. | ||
""" | ||
|
||
def handle(self, *args, **options): | ||
TODAY = datetime.date.today() | ||
|
||
def get_query_for_model(model): | ||
membership_attname = model.members.through._meta.get_field("user").remote_field.name | ||
return ( | ||
model.objects.active() | ||
.prefetch_related( | ||
Prefetch( | ||
"members", | ||
queryset=User.objects.filter( | ||
**{ | ||
"is_active": True, | ||
f"{membership_attname}__is_active": True, | ||
f"{membership_attname}__is_admin": True, | ||
}, | ||
), | ||
to_attr="admin_members", | ||
) | ||
) | ||
.annotate( | ||
last_sent_month_mod3=Mod( | ||
ExtractMonth(Coalesce("active_members_email_reminder_last_sent_at", "created_at")), | ||
3, | ||
output_field=IntegerField(), | ||
), | ||
last_sent_day=Least( | ||
ExtractDay(Coalesce("active_members_email_reminder_last_sent_at", "created_at")), 28 | ||
), | ||
active_members_count=Count( | ||
"members", | ||
filter=Q( | ||
**{ | ||
f"{membership_attname}__is_active": True, | ||
f"{membership_attname}__user__is_active": True, | ||
} | ||
), | ||
), | ||
) | ||
.filter( | ||
last_sent_month_mod3=TODAY.month % 3, | ||
last_sent_day=min(TODAY.day, 28), | ||
active_members_count__gt=1, | ||
) | ||
.order_by("pk") | ||
) | ||
|
||
# Companies | ||
for company in get_query_for_model(Company): | ||
with transaction.atomic(): | ||
for member in self.admin_members: | ||
OrganizationActiveMembersReminderNotification(member, company).send() | ||
company.active_members_email_reminder_last_sent_at = timezone.now() | ||
company.save(update_fields=["active_members_email_reminder_last_sent_at"]) | ||
|
||
# Prescriber organizations | ||
for prescriber_organization in get_query_for_model(PrescriberOrganization): | ||
with transaction.atomic(): | ||
for member in self.admin_members: | ||
OrganizationActiveMembersReminderNotification(member, prescriber_organization).send() | ||
prescriber_organization.active_members_email_reminder_last_sent_at = timezone.now() | ||
prescriber_organization.save(update_fields=["active_members_email_reminder_last_sent_at"]) | ||
|
||
# Institutions | ||
for institution in get_query_for_model(Institution): | ||
with transaction.atomic(): | ||
for member in self.admin_members: | ||
OrganizationActiveMembersReminderNotification(member, institution).send() | ||
institution.active_members_email_reminder_last_sent_at = timezone.now() | ||
institution.save(update_fields=["active_members_email_reminder_last_sent_at"]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from itou.communications import NotificationCategory, registry as notifications_registry | ||
from itou.communications.dispatch import EmailNotification, PrescriberOrEmployerOrLaborInspectorNotification | ||
|
||
|
||
@notifications_registry.register | ||
class OrganizationActiveMembersReminderNotification( | ||
PrescriberOrEmployerOrLaborInspectorNotification, EmailNotification | ||
): | ||
name = "Rappel périodique pour s'assurer que les membres de sa structure sont bien actifs et autorisés" | ||
category = NotificationCategory.MEMBERS_MANAGEMENT | ||
subject_template = "users/email/member_deactivation_email_subject.txt" | ||
body_template = "users/email/member_deactivation_email_body.txt" | ||
can_be_disabled = False |