Merged [6486] from rjsparks@nostrum.com:
Slightly more than minimal changes to have questionnaire reminders go only to those nominees who have accepted but have not yet sent in a questionnaire for a given position
- Legacy-Id: 6573
Note: SVN reference [6486] has been migrated to Git commit 2a1b4c7775
This commit is contained in:
parent
c8e7a4a5d4
commit
5f2da7ba9e
|
@ -20,16 +20,12 @@ class Command(BaseCommand):
|
|||
|
||||
def handle(self, *args, **options):
|
||||
for nomcom in NomCom.objects.filter(group__state__slug='active'):
|
||||
for state in ('pending','accepted'):
|
||||
for nominee_position in NomineePosition.objects.filter(nominee__nomcom=nomcom,
|
||||
state=state,
|
||||
nominee__duplicated__isnull=True):
|
||||
if is_time_to_send(nomcom, datetime.date.today(), nominee_position.time.date()):
|
||||
if state=='pending':
|
||||
send_accept_reminder_to_nominee(nominee_position)
|
||||
log('Sent accept reminder to %s' % nominee_position.nominee.email.address)
|
||||
elif state=='accepted':
|
||||
send_questionnaire_reminder_to_nominee(nominee_position)
|
||||
log('Sent questionnaire reminder to %s' % nominee_position.nominee.email.address)
|
||||
else:
|
||||
pass
|
||||
nps = NomineePosition.objects.filter(nominee__nomcom=nomcom,nominee__duplicated__isnull=True)
|
||||
for nominee_position in nps.pending():
|
||||
if is_time_to_send(nomcom, datetime.date.today(), nominee_position.time.date()):
|
||||
send_accept_reminder_to_nominee(nominee_position)
|
||||
log('Sent accept reminder to %s' % nominee_position.nominee.email.address)
|
||||
for nominee_position in nps.accepted().without_questionnaire_response():
|
||||
if is_time_to_send(nomcom, datetime.date.today(), nominee_position.time.date()):
|
||||
send_questionnaire_reminder_to_nominee(nominee_position)
|
||||
log('Sent questionnaire reminder to %s' % nominee_position.nominee.email.address)
|
||||
|
|
|
@ -33,6 +33,13 @@ class NomineePositionQuerySet(QuerySet):
|
|||
def not_duplicated(self):
|
||||
return self.filter(nominee__duplicated__isnull=True)
|
||||
|
||||
def with_questionnaire_response(self):
|
||||
return self.filter(nominee__feedback__type='questio',nominee__feedback__positions=models.F('position')).distinct()
|
||||
|
||||
def without_questionnaire_response(self):
|
||||
with_ids = self.with_questionnaire_response().values_list('id', flat=True)
|
||||
return self.exclude(id__in=with_ids)
|
||||
|
||||
|
||||
class NomineePositionManager(models.Manager, MixinManager):
|
||||
def get_query_set(self):
|
||||
|
|
|
@ -14,6 +14,7 @@ from ietf.utils.mail import outbox
|
|||
|
||||
|
||||
from ietf.person.models import Email, Person
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from ietf.nomcom.test_data import nomcom_test_data, generate_cert, check_comments, \
|
||||
COMMUNITY_USER, CHAIR_USER, \
|
||||
|
@ -657,12 +658,15 @@ class FeedbackTest(TestCase):
|
|||
os.unlink(self.privatekey_file.name)
|
||||
os.unlink(self.cert_file.name)
|
||||
|
||||
class ReminderCommandTest(TestCase):
|
||||
class ReminderTest(TestCase):
|
||||
perma_fixtures = ['names', 'nomcom_templates']
|
||||
|
||||
def setUp(self):
|
||||
nomcom_test_data()
|
||||
self.nomcom = get_nomcom_by_year(NOMCOM_YEAR)
|
||||
self.cert_file, self.privatekey_file = generate_cert()
|
||||
self.nomcom.public_key.storage.location = tempfile.gettempdir()
|
||||
self.nomcom.public_key.save('cert', File(open(self.cert_file.name, 'r')))
|
||||
|
||||
gen = Position.objects.get(nomcom=self.nomcom,name='GEN')
|
||||
rai = Position.objects.get(nomcom=self.nomcom,name='RAI')
|
||||
|
@ -684,6 +688,17 @@ class ReminderCommandTest(TestCase):
|
|||
np = n.nomineeposition_set.get(position=rai)
|
||||
np.time = t_minus_4
|
||||
np.save()
|
||||
n = get_or_create_nominee(self.nomcom,"Nominee 2","nominee2@example.org",gen,None)
|
||||
np = n.nomineeposition_set.get(position=gen)
|
||||
np.state = NomineePositionState.objects.get(slug='accepted')
|
||||
np.time = t_minus_4
|
||||
np.save()
|
||||
feedback = Feedback.objects.create(nomcom=self.nomcom,
|
||||
comments='some non-empty comments',
|
||||
type=FeedbackType.objects.get(slug='questio'),
|
||||
user=User.objects.get(username=CHAIR_USER))
|
||||
feedback.positions.add(gen)
|
||||
feedback.nominees.add(n)
|
||||
|
||||
def test_is_time_to_send(self):
|
||||
self.nomcom.reminder_interval = 4
|
||||
|
@ -714,5 +729,22 @@ class ReminderCommandTest(TestCase):
|
|||
self.assertEqual(len(outbox), messages_before + 1)
|
||||
self.assertTrue('nominee2@example.org' in outbox[-1]['To'])
|
||||
self.assertTrue('please accept' in outbox[-1]['Subject'])
|
||||
|
||||
|
||||
def test_remind_accept_view(self):
|
||||
url = reverse('nomcom_send_reminder_mail', kwargs={'year': NOMCOM_YEAR,'type':'accept'})
|
||||
login_testing_unauthorized(self, CHAIR_USER, url)
|
||||
messages_before=len(outbox)
|
||||
test_data = {'selected': [x.id for x in Nominee.objects.filter(nomcom=self.nomcom)]}
|
||||
response = self.client.post(url, test_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(outbox), messages_before + 2)
|
||||
|
||||
def test_remind_questionnaire_view(self):
|
||||
url = reverse('nomcom_send_reminder_mail', kwargs={'year': NOMCOM_YEAR,'type':'questionnaire'})
|
||||
login_testing_unauthorized(self, CHAIR_USER, url)
|
||||
messages_before=len(outbox)
|
||||
test_data = {'selected': [x.id for x in Nominee.objects.filter(nomcom=self.nomcom)]}
|
||||
response = self.client.post(url, test_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(outbox), messages_before + 1)
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ def send_reminder_to_nominees(nominees,type):
|
|||
addrs.append(nominee_position.nominee.email.address)
|
||||
elif type=='questionnaire':
|
||||
for nominee in nominees:
|
||||
for nominee_position in nominee.nomineeposition_set.accepted():
|
||||
for nominee_position in nominee.nomineeposition_set.accepted().without_questionnaire_response():
|
||||
send_questionnaire_reminder_to_nominee(nominee_position)
|
||||
addrs.append(nominee_position.nominee.email.address)
|
||||
return addrs
|
||||
|
|
|
@ -173,18 +173,26 @@ def send_reminder_mail(request, year, type):
|
|||
mail_path = nomcom_template_path + NOMINEE_ACCEPT_REMINDER_TEMPLATE
|
||||
reminder_description = 'accept (or decline) a nomination'
|
||||
selected_tab = 'send_accept_reminder'
|
||||
state_description = NomineePositionState.objects.get(slug=interesting_state).name
|
||||
elif type=='questionnaire':
|
||||
interesting_state = 'accepted'
|
||||
mail_path = nomcom_template_path + NOMINEE_QUESTIONNAIRE_REMINDER_TEMPLATE
|
||||
reminder_description = 'complete the questionnaire for a nominated position'
|
||||
selected_tab = 'send_questionnaire_reminder'
|
||||
state_description = NomineePositionState.objects.get(slug=interesting_state).name+' but no questionnaire has been received'
|
||||
else:
|
||||
raise Http404
|
||||
|
||||
nominees = Nominee.objects.get_by_nomcom(nomcom).not_duplicated().filter(nomineeposition__state=interesting_state).distinct()
|
||||
annotated_nominees = list(nominees)
|
||||
for nominee in annotated_nominees:
|
||||
nominee.interesting_positions = [x.position.name for x in nominee.nomineeposition_set.all() if x.state.slug==interesting_state]
|
||||
annotated_nominees = []
|
||||
for nominee in nominees:
|
||||
if type=='accept':
|
||||
nominee.interesting_positions = [x.position.name for x in nominee.nomineeposition_set.pending()]
|
||||
else:
|
||||
nominee.interesting_positions = [x.position.name for x in nominee.nomineeposition_set.accepted().without_questionnaire_response()]
|
||||
if nominee.interesting_positions:
|
||||
annotated_nominees.append(nominee)
|
||||
|
||||
mail_template = DBTemplate.objects.filter(group=nomcom.group, path=mail_path)
|
||||
mail_template = mail_template and mail_template[0] or None
|
||||
message = None
|
||||
|
@ -207,7 +215,7 @@ def send_reminder_mail(request, year, type):
|
|||
'mail_template': mail_template,
|
||||
'selected': selected_tab,
|
||||
'reminder_description': reminder_description,
|
||||
'state_description': NomineePositionState.objects.get(slug=interesting_state).name,
|
||||
'state_description': state_description,
|
||||
'message': message}, RequestContext(request))
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue