diff --git a/itou/job_applications/models.py b/itou/job_applications/models.py index f2de72e25a..9e8650a79e 100644 --- a/itou/job_applications/models.py +++ b/itou/job_applications/models.py @@ -1085,9 +1085,9 @@ def notifications_new_for_employer(self, employer): @property def notifications_new_for_proxy(self): - return job_application_notifications.JobApplicationNewForPrescriberNotification( + return job_application_notifications.JobApplicationNewForProxyNotification( self.sender, - self.sender_prescriber_organization, + self.sender_prescriber_organization or self.sender_company, job_application=self, ) @@ -1108,9 +1108,9 @@ def notifications_accept_for_job_seeker(self): @property def notifications_accept_for_proxy(self): - return job_application_notifications.JobApplicationAcceptedForPrescriberNotification( + return job_application_notifications.JobApplicationAcceptedForProxyNotification( self.sender, - self.sender_prescriber_organization, + self.sender_prescriber_organization or self.sender_company, job_application=self, ) @@ -1118,7 +1118,7 @@ def notifications_accept_for_proxy(self): def notifications_postpone_for_proxy(self): return job_application_notifications.JobApplicationPostponedForProxyNotification( self.sender, - self.sender_prescriber_organization, + self.sender_prescriber_organization or self.sender_company, job_application=self, ) @@ -1131,9 +1131,9 @@ def notifications_postpone_for_job_seeker(self): @property def notifications_refuse_for_proxy(self): - return job_application_notifications.JobApplicationRefusedForPrescriberNotification( + return job_application_notifications.JobApplicationRefusedForProxyNotification( self.sender, - self.sender_prescriber_organization, + self.sender_prescriber_organization or self.sender_company, job_application=self, ) @@ -1155,7 +1155,7 @@ def notifications_cancel_for_employer(self, canceled_by): def notifications_cancel_for_proxy(self): return job_application_notifications.JobApplicationCanceledNotification( self.sender, - self.sender_prescriber_organization, + self.sender_prescriber_organization or self.sender_company, job_application=self, ) diff --git a/itou/job_applications/notifications.py b/itou/job_applications/notifications.py index 894e184ed1..fd0908973a 100644 --- a/itou/job_applications/notifications.py +++ b/itou/job_applications/notifications.py @@ -19,8 +19,8 @@ class JobApplicationNewForJobSeekerNotification(JobSeekerNotification, EmailNoti @notifications_registry.register -class JobApplicationNewForPrescriberNotification(PrescriberNotification, EmailNotification): - """Notification sent to prescriber when created""" +class JobApplicationNewForProxyNotification(PrescriberOrEmployerNotification, EmailNotification): + """Notification sent to proxy (prescriber or employer/orienter) when created""" name = "Confirmation d’envoi de candidature" category = NotificationCategory.JOB_APPLICATION @@ -71,8 +71,8 @@ class JobApplicationAcceptedForJobSeekerNotification(JobSeekerNotification, Emai @notifications_registry.register -class JobApplicationAcceptedForPrescriberNotification(PrescriberNotification, EmailNotification): - """Notification sent to prescriber when accepted""" +class JobApplicationAcceptedForProxyNotification(PrescriberOrEmployerNotification, EmailNotification): + """Notification sent to proxy (prescriber or employer/orienter) when accepted""" name = "Confirmation d’acceptation de candidature" category = NotificationCategory.JOB_APPLICATION @@ -101,8 +101,8 @@ class JobApplicationRefusedForJobSeekerNotification(JobSeekerNotification, Email @notifications_registry.register -class JobApplicationRefusedForPrescriberNotification(PrescriberNotification, EmailNotification): - """Notification sent to prescriber when refused""" +class JobApplicationRefusedForProxyNotification(PrescriberOrEmployerNotification, EmailNotification): + """Notification sent to proxy (prescriber or employer/orienter) when refused""" name = "Refus de candidature" category = NotificationCategory.JOB_APPLICATION diff --git a/itou/www/apply/views/submit_views.py b/itou/www/apply/views/submit_views.py index 6ff1f98b99..8ebd40bebe 100644 --- a/itou/www/apply/views/submit_views.py +++ b/itou/www/apply/views/submit_views.py @@ -676,7 +676,7 @@ def form_valid(self): for employer in company_recipients: job_application.notifications_new_for_employer(employer).send() job_application.notifications_new_for_job_seeker.send() - if self.request.user.is_prescriber: + if self.request.user.kind in [UserKind.PRESCRIBER, UserKind.EMPLOYER]: job_application.notifications_new_for_proxy.send() finally: # We are done, send to the (mostly) stateless final page as we now have no session. diff --git a/tests/communications/test_dispatch.py b/tests/communications/test_dispatch.py index 8ddc45fd7d..ef2342193e 100644 --- a/tests/communications/test_dispatch.py +++ b/tests/communications/test_dispatch.py @@ -299,6 +299,18 @@ def test_method_send_for_inactive_user(self, email_notification, django_capture_ email_notification(self.user, self.organization).send() assert len(mailoutbox) == 0 + # But we still forward it if the user left his organozation + admin = PrescriberMembershipFactory( + user=PrescriberFactory(), + organization=self.organization, + is_admin=True, + ).user + + with django_capture_on_commit_callbacks(execute=True): + email_notification(self.user, self.organization).send() + assert len(mailoutbox) == 1 + assert mailoutbox[0].to == [admin.email] + class TestProfiledNotification: def setup_method(self): diff --git a/tests/job_applications/tests.py b/tests/job_applications/tests.py index da8a00f92a..513d0a4f65 100644 --- a/tests/job_applications/tests.py +++ b/tests/job_applications/tests.py @@ -960,6 +960,21 @@ def test_cancel_sent_by_prescriber(self, django_capture_on_commit_callbacks, mai assert job_application.job_seeker.get_full_name() in mailoutbox[0].body assert mailoutbox[0].body == mailoutbox[1].body + def test_for_proxy_notification(self, subtests): + employer_job_app = JobApplicationFactory(sent_by_another_employer=True) + prescriber_job_app = JobApplicationFactory(sent_by_authorized_prescriber_organisation=True) + + for transition in ["cancel", "postpone", "refuse", "new", "accept"]: + with subtests.test(transition): + assert ( + getattr(employer_job_app, f"notifications_{transition}_for_proxy").structure + == employer_job_app.sender_company + ) + assert ( + getattr(prescriber_job_app, f"notifications_{transition}_for_proxy").structure + == prescriber_job_app.sender_prescriber_organization + ) + def test_cancel_sent_by_job_seeker(self, django_capture_on_commit_callbacks, mailoutbox): # When sent by jobseeker. job_application = JobApplicationSentByJobSeekerFactory(state=JobApplicationState.ACCEPTED) diff --git a/tests/www/dashboard/__snapshots__/test_edit_user_notifications.ambr b/tests/www/dashboard/__snapshots__/test_edit_user_notifications.ambr index 2f59dc7bf3..9b7ac2ea4d 100644 --- a/tests/www/dashboard/__snapshots__/test_edit_user_notifications.ambr +++ b/tests/www/dashboard/__snapshots__/test_edit_user_notifications.ambr @@ -253,7 +253,7 @@ # --- # name: test_employer_create_update_notification_settings[view queries - disable all notifications] dict({ - 'num_queries': 19, + 'num_queries': 22, 'queries': list([ dict({ 'origin': list([ @@ -606,6 +606,60 @@ LIMIT 21 ''', }), + dict({ + 'origin': list([ + 'EditUserNotificationForm.save[www/dashboard/forms.py]', + 'edit_user_notifications[www/dashboard/views.py]', + ]), + 'sql': ''' + SELECT "communications_notificationrecord"."id", + "communications_notificationrecord"."notification_class", + "communications_notificationrecord"."name", + "communications_notificationrecord"."category", + "communications_notificationrecord"."can_be_disabled", + "communications_notificationrecord"."is_obsolete" + FROM "communications_notificationrecord" + WHERE (NOT ("communications_notificationrecord"."is_obsolete") + AND "communications_notificationrecord"."notification_class" = %s) + LIMIT 21 + ''', + }), + dict({ + 'origin': list([ + 'EditUserNotificationForm.save[www/dashboard/forms.py]', + 'edit_user_notifications[www/dashboard/views.py]', + ]), + 'sql': ''' + SELECT "communications_notificationrecord"."id", + "communications_notificationrecord"."notification_class", + "communications_notificationrecord"."name", + "communications_notificationrecord"."category", + "communications_notificationrecord"."can_be_disabled", + "communications_notificationrecord"."is_obsolete" + FROM "communications_notificationrecord" + WHERE (NOT ("communications_notificationrecord"."is_obsolete") + AND "communications_notificationrecord"."notification_class" = %s) + LIMIT 21 + ''', + }), + dict({ + 'origin': list([ + 'EditUserNotificationForm.save[www/dashboard/forms.py]', + 'edit_user_notifications[www/dashboard/views.py]', + ]), + 'sql': ''' + SELECT "communications_notificationrecord"."id", + "communications_notificationrecord"."notification_class", + "communications_notificationrecord"."name", + "communications_notificationrecord"."category", + "communications_notificationrecord"."can_be_disabled", + "communications_notificationrecord"."is_obsolete" + FROM "communications_notificationrecord" + WHERE (NOT ("communications_notificationrecord"."is_obsolete") + AND "communications_notificationrecord"."notification_class" = %s) + LIMIT 21 + ''', + }), dict({ 'origin': list([ 'EditUserNotificationForm.save[www/dashboard/forms.py]', @@ -635,6 +689,9 @@ %s, %s, %s, + %s, + %s, + %s, %s) AND "communications_disablednotification"."settings_id" = %s) ORDER BY RANDOM() ASC @@ -655,6 +712,9 @@ (%s, %s, %s), (%s, %s, %s), (%s, %s, %s), + (%s, %s, %s), + (%s, %s, %s), + (%s, %s, %s), (%s, %s, %s) RETURNING "communications_disablednotification"."id" ''', }),