Merged in [16704] from sasha@dashcare.nl:
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.
- Legacy-Id: 16822
Note: SVN reference [16704] has been migrated to Git commit 179c151f9e
This commit is contained in:
commit
4c3e869d5c
|
@ -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,
|
||||
)
|
||||
send_unavaibility_period_ending_reminder)
|
||||
|
||||
today = datetime.date.today()
|
||||
|
||||
|
@ -37,3 +37,6 @@ 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))
|
||||
|
||||
reminders_sent = send_unavaibility_period_ending_reminder(today)
|
||||
print('\n'.join(reminders_sent))
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
send_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_send_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 = send_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):
|
||||
|
|
|
@ -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 send_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"),
|
||||
|
|
7
ietf/templates/review/reviewer_unavailability_ending.txt
Normal file
7
ietf/templates/review/reviewer_unavailability_ending.txt
Normal 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 %}
|
Loading…
Reference in a new issue