Fix #2231 - Send reminders before long UnavailabilityPeriods expire

A notification is sent to the team secretary and reviewer, if an
unavailability period lasting 30 days or more will end in 3 days.
Commit ready for merge.
 - Legacy-Id: 16704
This commit is contained in:
Sasha Romijn 2019-09-05 11:59:40 +00:00
parent 296b126c70
commit 179c151f9e
4 changed files with 90 additions and 3 deletions

View file

@ -24,7 +24,7 @@ import datetime
from ietf.review.utils import (
review_assignments_needing_reviewer_reminder, email_reviewer_reminder,
review_assignments_needing_secretary_reminder, email_secretary_reminder,
)
email_unavaibility_period_ending_reminder)
today = datetime.date.today()
@ -37,3 +37,5 @@ for assignment, secretary_role in review_assignments_needing_secretary_reminder(
email_secretary_reminder(assignment.review_request, secretary_role)
review_req = assignment.review_request
print("Emailed reminder to {} for review of {} in {} (req. id {})".format(secretary_role.email.address, review_req.doc_id, review_req.team.acronym, review_req.pk))
print('\n'.join(email_unavaibility_period_ending_reminder(today)))

View file

@ -23,7 +23,7 @@ from ietf.review.utils import (
review_assignments_needing_reviewer_reminder, email_reviewer_reminder,
review_assignments_needing_secretary_reminder, email_secretary_reminder,
reviewer_rotation_list,
)
email_unavaibility_period_ending_reminder)
from ietf.name.models import ReviewResultName, ReviewRequestStateName, ReviewAssignmentStateName
import ietf.group.views
from ietf.utils.mail import outbox, empty_outbox
@ -493,6 +493,58 @@ class ReviewTests(TestCase):
self.assertEqual(len(outbox), 1)
self.assertTrue(review_req.doc.name in outbox[0].get_payload(decode=True).decode("utf-8"))
def test_email_unavaibility_period_ending_reminder(self):
review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review",
list_email="reviewteam@ietf.org")
reviewer = RoleFactory(group=review_team, person__user__username='reviewer',
person__user__email='reviewer@example.com',
person__name='Some Reviewer', name_id='reviewer')
secretary = RoleFactory(group=review_team, person__user__username='reviewsecretary',
person__user__email='reviewsecretary@example.com', name_id='secr')
empty_outbox()
today = datetime.date.today()
UnavailablePeriod.objects.create(
team=review_team,
person=reviewer.person,
start_date=today - datetime.timedelta(days=40),
end_date=today + datetime.timedelta(days=3),
availability="unavailable",
)
UnavailablePeriod.objects.create(
team=review_team,
person=reviewer.person,
# This object should be ignored, length is too short
start_date=today - datetime.timedelta(days=20),
end_date=today + datetime.timedelta(days=3),
availability="unavailable",
)
UnavailablePeriod.objects.create(
team=review_team,
person=reviewer.person,
start_date=today - datetime.timedelta(days=40),
# This object should be ignored, end date is too far away
end_date=today + datetime.timedelta(days=4),
availability="unavailable",
)
UnavailablePeriod.objects.create(
team=review_team,
person=reviewer.person,
# This object should be ignored, end date is too close
start_date=today - datetime.timedelta(days=40),
end_date=today + datetime.timedelta(days=2),
availability="unavailable",
)
log = email_unavaibility_period_ending_reminder(today)
self.assertEqual(len(outbox), 1)
self.assertTrue(reviewer.person.email_address() in outbox[0]["To"])
self.assertTrue(secretary.person.email_address() in outbox[0]["To"])
message = outbox[0].get_payload(decode=True).decode("utf-8")
self.assertTrue(reviewer.person.name in message)
self.assertTrue(review_team.acronym in message)
self.assertEqual(len(log), 1)
self.assertTrue(reviewer.person.name in log[0])
self.assertTrue(review_team.acronym in log[0])
class BulkAssignmentTests(TestCase):

View file

@ -395,7 +395,6 @@ def email_reviewer_availability_change(request, team, reviewer_role, msg, by):
"reviewer_overview_url": url,
"reviewer": reviewer_role.person,
"team": team,
"msg": msg,
"by": by,
}, cc=cc)
@ -932,6 +931,33 @@ def make_assignment_choices(email_queryset, review_req):
return [(r["email"].pk, r["label"]) for r in ranking]
def email_unavaibility_period_ending_reminder(remind_date):
reminder_days = 3
end_date = remind_date + datetime.timedelta(days=reminder_days)
min_start_date = end_date - datetime.timedelta(days=30)
periods = UnavailablePeriod.objects.filter(start_date__lte=min_start_date, end_date=end_date)
log = []
for period in periods:
(to, cc) = gather_address_lists('review_availability_changed', group=period.team, reviewer=period.person)
domain = Site.objects.get_current().domain
url = urlreverse("ietf.group.views.reviewer_overview", kwargs={ "group_type": period.team.type_id, "acronym": period.team.acronym })
subject = "Reminder: unavailability period of {} is ending soon".format(period.person)
send_mail(None, to, None, subject, "review/reviewer_unavailability_ending.txt", {
"reviewer_overview_url": "https://{}{}".format(domain, url),
"reviewer": period.person,
"team": period.team,
"reminder_days": reminder_days,
"period_start": period.start_date.isoformat(),
"period_end": period.end_date.isoformat(),
}, cc=cc)
log.append("Emailed reminder to {} for ending of unavailability "
"of {} in {} soon (unavailability period id {})".format(
to, period.person, period.team.acronym,period.pk))
return log
def review_assignments_needing_reviewer_reminder(remind_date):
assignment_qs = ReviewAssignment.objects.filter(
state__in=("assigned", "accepted"),

View file

@ -0,0 +1,7 @@
{% load ietf_filters %}{% autoescape off %}{% filter wordwrap:78 %}
Reviewer {{ reviewer }} in {{ team.acronym }} will become available again in {{ reminder_days }} days.
This ends their unavailability which lasted from {{ period_start }} until {{ period_end }}.
{{ reviewer_overview_url }}
{% endfilter %}{% endautoescape %}