Add duplicated field for nominees, it is necesary when chair marks duplicate nominations

Change questionnaires field in NomineePosition model to manytomany, becouse it is necessary whe chair marks duplicate nominations.
Add timestamp in NomineePosition objects to see wich nomineeposition object is the last one.
Better merge nominations, update questionnaires and state of primary nomineposition object
See #930
 - Legacy-Id: 5187
This commit is contained in:
Emilio Jiménez 2013-01-15 16:14:00 +00:00
parent 69a93c9f92
commit bf0747a8e9
5 changed files with 70 additions and 27 deletions

View file

@ -203,7 +203,7 @@ class MergeForm(BaseNomcomForm, forms.Form):
def clean_primary_email(self):
email = self.cleaned_data['primary_email']
nominees = Nominee.objects.filter(email__address=email,
nomine_position__nomcom=self.nomcom)
nominee_position__nomcom=self.nomcom)
if not nominees:
msg = "Does not exist a nomiee with this email"
self._errors["primary_email"] = self.error_class([msg])
@ -215,7 +215,7 @@ class MergeForm(BaseNomcomForm, forms.Form):
emails = get_list(data)
for email in emails:
nominees = Nominee.objects.filter(email__address=email,
nomine_position__nomcom=self.nomcom)
nominee_position__nomcom=self.nomcom)
if not nominees:
msg = "Does not exist a nomiee with email %s" % email
self._errors["primary_email"] = self.error_class([msg])
@ -237,9 +237,9 @@ class MergeForm(BaseNomcomForm, forms.Form):
secondary_emails = get_list(self.cleaned_data.get("secondary_emails"))
primary_nominee = Nominee.objects.get(email__address=primary_email,
nomine_position__nomcom=self.nomcom)
nominee_position__nomcom=self.nomcom)
secondary_nominees = Nominee.objects.filter(email__address__in=secondary_emails,
nomine_position__nomcom=self.nomcom)
nominee_position__nomcom=self.nomcom)
for nominee in secondary_nominees:
# move nominations
nominee.nomination_set.all().update(nominee=primary_nominee)
@ -247,13 +247,30 @@ class MergeForm(BaseNomcomForm, forms.Form):
nominee.feedback_set.all().update(nominee=primary_nominee)
# move nomineepositions
for nominee_position in nominee.nomineeposition_set.all():
if not NomineePosition.objects.filter(position=nominee_position.position,
nominee=primary_nominee):
primary_nominee_positions = NomineePosition.objects.filter(position=nominee_position.position,
nominee=primary_nominee)
primary_nominee_position = primary_nominee_positions and primary_nominee_positions[0] or None
if primary_nominee_position:
# if already a nomineeposition object for a position and nominee,
# update the nomineepostion of primary nominee with the state and questionnaire
if nominee_position.time > primary_nominee_position.time:
primary_nominee_position.state = nominee_position.state
primary_nominee_position.save()
questionnaires = nominee_position.questionnaires.all()
if questionnaires:
primary_nominee_position.questionnaires.add(*questionnaires)
else:
# It is not allowed two or more nomineeposition objects with same position and nominee
# move nominee_position object to primary nominee
nominee_position.nominee = primary_nominee
nominee_position.save()
secondary_nominees.delete()
nominee.duplicated = primary_nominee
nominee.save()
secondary_nominees.update(duplicated=primary_nominee)
class NominateForm(BaseNomcomForm, forms.ModelForm):

View file

@ -1,13 +1,13 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'NomCom'
db.create_table('nomcom_nomcom', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
@ -34,6 +34,7 @@ class Migration(SchemaMigration):
db.create_table('nomcom_nominee', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('email', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['person.Email'])),
('duplicated', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['nomcom.Nominee'], null=True, blank=True)),
))
db.send_create_signal('nomcom', ['Nominee'])
@ -43,13 +44,21 @@ class Migration(SchemaMigration):
('position', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['nomcom.Position'])),
('nominee', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['nomcom.Nominee'])),
('state', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['name.NomineePositionState'])),
('questionnaire', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='questionnaire', null=True, to=orm['nomcom.Feedback'])),
('time', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
))
db.send_create_signal('nomcom', ['NomineePosition'])
# Adding unique constraint on 'NomineePosition', fields ['position', 'nominee']
db.create_unique('nomcom_nomineeposition', ['position_id', 'nominee_id'])
# Adding M2M table for field questionnaires on 'NomineePosition'
db.create_table('nomcom_nomineeposition_questionnaires', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('nomineeposition', models.ForeignKey(orm['nomcom.nomineeposition'], null=False)),
('feedback', models.ForeignKey(orm['nomcom.feedback'], null=False))
))
db.create_unique('nomcom_nomineeposition_questionnaires', ['nomineeposition_id', 'feedback_id'])
# Adding M2M table for field feedback on 'NomineePosition'
db.create_table('nomcom_nomineeposition_feedback', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
@ -75,7 +84,7 @@ class Migration(SchemaMigration):
# Adding model 'Feedback'
db.create_table('nomcom_feedback', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('author', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('author', self.gf('django.db.models.fields.EmailField')(max_length=75, blank=True)),
('position', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['nomcom.Position'])),
('nominee', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['nomcom.Nominee'])),
('comments', self.gf('ietf.nomcom.fields.EncryptedTextField')()),
@ -84,8 +93,9 @@ class Migration(SchemaMigration):
))
db.send_create_signal('nomcom', ['Feedback'])
def backwards(self, orm):
def backwards(self, orm):
# Removing unique constraint on 'NomineePosition', fields ['position', 'nominee']
db.delete_unique('nomcom_nomineeposition', ['position_id', 'nominee_id'])
@ -101,6 +111,9 @@ class Migration(SchemaMigration):
# Deleting model 'NomineePosition'
db.delete_table('nomcom_nomineeposition')
# Removing M2M table for field questionnaires on 'NomineePosition'
db.delete_table('nomcom_nomineeposition_questionnaires')
# Removing M2M table for field feedback on 'NomineePosition'
db.delete_table('nomcom_nomineeposition_feedback')
@ -110,6 +123,7 @@ class Migration(SchemaMigration):
# Deleting model 'Feedback'
db.delete_table('nomcom_feedback')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
@ -327,7 +341,7 @@ class Migration(SchemaMigration):
},
'nomcom.feedback': {
'Meta': {'object_name': 'Feedback'},
'author': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'author': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'comments': ('ietf.nomcom.fields.EncryptedTextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'nominee': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Nominee']"}),
@ -355,9 +369,10 @@ class Migration(SchemaMigration):
},
'nomcom.nominee': {
'Meta': {'object_name': 'Nominee'},
'duplicated': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Nominee']", 'null': 'True', 'blank': 'True'}),
'email': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['person.Email']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'nomine_position': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['nomcom.Position']", 'through': "orm['nomcom.NomineePosition']", 'symmetrical': 'False'})
'nominee_position': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['nomcom.Position']", 'through': "orm['nomcom.NomineePosition']", 'symmetrical': 'False'})
},
'nomcom.nomineeposition': {
'Meta': {'unique_together': "(('position', 'nominee'),)", 'object_name': 'NomineePosition'},
@ -365,8 +380,9 @@ class Migration(SchemaMigration):
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'nominee': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Nominee']"}),
'position': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['nomcom.Position']"}),
'questionnaire': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'questionnaire'", 'null': 'True', 'to': "orm['nomcom.Feedback']"}),
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.NomineePositionState']"})
'questionnaires': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'questionnaires'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['nomcom.Feedback']"}),
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['name.NomineePositionState']"}),
'time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
},
'nomcom.position': {
'Meta': {'object_name': 'Position'},

View file

@ -62,7 +62,8 @@ class Nomination(models.Model):
class Nominee(models.Model):
email = models.ForeignKey(Email)
nomine_position = models.ManyToManyField('Position', through='NomineePosition')
nominee_position = models.ManyToManyField('Position', through='NomineePosition')
duplicated = models.ForeignKey('Nominee', blank=True, null=True)
class Meta:
verbose_name_plural = 'Nominees'
@ -76,10 +77,11 @@ class NomineePosition(models.Model):
position = models.ForeignKey('Position')
nominee = models.ForeignKey('Nominee')
state = models.ForeignKey(NomineePositionState)
questionnaire = models.ForeignKey('Feedback',
related_name='questionnaire',
blank=True, null=True)
questionnaires = models.ManyToManyField('Feedback',
related_name='questionnaires',
blank=True, null=True)
feedback = models.ManyToManyField('Feedback', blank=True, null=True)
time = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'Nominee position'

View file

@ -2,6 +2,7 @@ import tempfile
import os
from django.contrib.auth.models import User
from django.core.files import File
from django.conf import settings
from ietf.utils.pipe import pipe
@ -15,6 +16,7 @@ CHAIR_USER = 'chair'
MEMBER_USER = 'member'
SECRETARIAT_USER = 'secretariat'
EMAIL_DOMAIN = '@example.com'
NOMCOM_YEAR = "2013"
USERS = [COMMUNITY_USER, CHAIR_USER, MEMBER_USER, SECRETARIAT_USER]
@ -98,10 +100,13 @@ def nomcom_test_data():
group, created = Group.objects.get_or_create(name='IAB/IESG Nominating Committee 2013/2014',
state_id='active',
type_id='nomcom',
acronym='nomcom2013')
acronym='nomcom%s' % NOMCOM_YEAR)
nomcom, created = NomCom.objects.get_or_create(group=group)
secretariat, created = Group.objects.get_or_create(name="Secretariat",
cert_file, privatekey_file = generate_cert()
nomcom.public_key.save('cert', File(open(cert_file.name, 'r')))
secretariat, created = Group.objects.get_or_create(name=u'IETF Secretariat',
acronym="secretariat",
state_id="active",
type_id="ietf",

View file

@ -14,7 +14,7 @@ from ietf.person.models import Email, Person
from ietf.nomcom.test_data import nomcom_test_data, generate_cert, check_comments, \
COMMUNITY_USER, CHAIR_USER, \
MEMBER_USER, SECRETARIAT_USER, EMAIL_DOMAIN
MEMBER_USER, SECRETARIAT_USER, EMAIL_DOMAIN, NOMCOM_YEAR
from ietf.nomcom.models import NomineePosition, Position, Nominee, \
NomineePositionState, Feedback, FeedbackType, \
Nomination
@ -33,7 +33,7 @@ class NomcomViewsTest(TestCase):
def setUp(self):
nomcom_test_data()
self.cert_file, self.privatekey_file = generate_cert()
self.year = 2013
self.year = NOMCOM_YEAR
# private urls
self.private_index_url = reverse('nomcom_private_index', kwargs={'year': self.year})
@ -133,9 +133,12 @@ class NomcomViewsTest(TestCase):
self.assertEqual(response.status_code, 200)
self.assertContains(response, "info-message-success")
self.assertEqual(Nominee.objects.filter(email__address='nominee2@example.com').count(), 0)
self.assertEqual(Nominee.objects.filter(email__address='nominee3@example.com').count(), 0)
self.assertEqual(Nominee.objects.filter(email__address='nominee4@example.com').count(), 0)
self.assertEqual(Nominee.objects.filter(email__address='nominee2@example.com',
duplicated__isnull=False).count(), 1)
self.assertEqual(Nominee.objects.filter(email__address='nominee3@example.com',
duplicated__isnull=False).count(), 1)
self.assertEqual(Nominee.objects.filter(email__address='nominee4@example.com',
duplicated__isnull=False).count(), 1)
nominee = Nominee.objects.get(email__address='nominee@example.com')
self.assertEqual(Nomination.objects.filter(nominee=nominee).count(), 4)