|
11 | 11 | from ietf.dbtemplate.forms import DBTemplateForm |
12 | 12 | from ietf.group.models import Group, Role |
13 | 13 | from ietf.ietfauth.utils import role_required |
14 | | -from ietf.name.models import RoleName, FeedbackTypeName |
| 14 | +from ietf.name.models import RoleName, FeedbackTypeName, NomineePositionStateName |
15 | 15 | from ietf.nomcom.models import ( NomCom, Nomination, Nominee, NomineePosition, |
16 | 16 | Position, Feedback, ReminderDates ) |
17 | 17 | from ietf.nomcom.utils import (NOMINATION_RECEIPT_TEMPLATE, FEEDBACK_RECEIPT_TEMPLATE, |
18 | 18 | get_user_email, validate_private_key, validate_public_key, |
19 | 19 | make_nomineeposition, make_nomineeposition_for_newperson, |
20 | 20 | create_feedback_email) |
21 | 21 | from ietf.person.models import Email |
22 | | -from ietf.person.fields import SearchableEmailField, SearchablePersonField, SearchablePersonsField |
| 22 | +from ietf.person.fields import (SearchableEmailField, SearchableEmailsField, |
| 23 | + SearchablePersonField, SearchablePersonsField ) |
23 | 24 | from ietf.utils.fields import MultiEmailField |
24 | 25 | from ietf.utils.mail import send_mail |
25 | 26 | from ietf.mailtrigger.utils import gather_address_lists |
@@ -221,14 +222,95 @@ def clean_public_key(self): |
221 | 222 | raise forms.ValidationError('Invalid public key. Error was: %s' % error) |
222 | 223 |
|
223 | 224 |
|
224 | | -class MergeForm(forms.Form): |
| 225 | +class MergeNomineeForm(forms.Form): |
| 226 | + |
| 227 | + primary_email = SearchableEmailField( |
| 228 | + help_text="Select the email of the Nominee record you want to use as the primary record.") |
| 229 | + secondary_emails = SearchableEmailsField( |
| 230 | + help_text="Select all the duplicates that should be consolidated with the primary " |
| 231 | + "Nominee record. Nominations already received with any of these email address " |
| 232 | + "will be moved to show under the primary address." ) |
| 233 | + |
| 234 | + def __init__(self, *args, **kwargs): |
| 235 | + self.nomcom = kwargs.pop('nomcom', None) |
| 236 | + super(MergeNomineeForm, self).__init__(*args, **kwargs) |
| 237 | + |
| 238 | + def clean_primary_email(self): |
| 239 | + email = self.cleaned_data['primary_email'] |
| 240 | + nominees = Nominee.objects.get_by_nomcom(self.nomcom).not_duplicated().filter(email__address=email) |
| 241 | + if not nominees: |
| 242 | + msg = "No nominee with this email exists" |
| 243 | + self._errors["primary_email"] = self.error_class([msg]) |
| 244 | + |
| 245 | + return email |
| 246 | + |
| 247 | + def clean_secondary_emails(self): |
| 248 | + emails = self.cleaned_data['secondary_emails'] |
| 249 | + for email in emails: |
| 250 | + nominees = Nominee.objects.get_by_nomcom(self.nomcom).not_duplicated().filter(email__address=email) |
| 251 | + if not nominees: |
| 252 | + msg = "No nominee with email %s exists" % email |
| 253 | + self._errors["primary_email"] = self.error_class([msg]) |
| 254 | + break |
| 255 | + |
| 256 | + return emails |
| 257 | + |
| 258 | + def clean(self): |
| 259 | + primary_email = self.cleaned_data.get("primary_email") |
| 260 | + secondary_emails = self.cleaned_data.get("secondary_emails") |
| 261 | + if primary_email and secondary_emails: |
| 262 | + if primary_email in secondary_emails: |
| 263 | + msg = "Primary and secondary email address must be differents" |
| 264 | + self._errors["primary_email"] = self.error_class([msg]) |
| 265 | + return self.cleaned_data |
| 266 | + |
| 267 | + def save(self): |
| 268 | + primary_email = self.cleaned_data.get("primary_email") |
| 269 | + secondary_emails = self.cleaned_data.get("secondary_emails") |
| 270 | + |
| 271 | + primary_nominee = Nominee.objects.get_by_nomcom(self.nomcom).get(email__address=primary_email) |
| 272 | + while primary_nominee.duplicated: |
| 273 | + primary_nominee = primary_nominee.duplicated |
| 274 | + secondary_nominees = Nominee.objects.get_by_nomcom(self.nomcom).filter(email__address__in=secondary_emails) |
| 275 | + for nominee in secondary_nominees: |
| 276 | + # move nominations |
| 277 | + nominee.nomination_set.all().update(nominee=primary_nominee) |
| 278 | + # move feedback |
| 279 | + for fb in nominee.feedback_set.all(): |
| 280 | + fb.nominees.remove(nominee) |
| 281 | + fb.nominees.add(primary_nominee) |
| 282 | + # move nomineepositions |
| 283 | + for nominee_position in nominee.nomineeposition_set.all(): |
| 284 | + primary_nominee_positions = NomineePosition.objects.filter(position=nominee_position.position, |
| 285 | + nominee=primary_nominee) |
| 286 | + primary_nominee_position = primary_nominee_positions and primary_nominee_positions[0] or None |
| 287 | + |
| 288 | + if primary_nominee_position: |
| 289 | + # if already a nomineeposition object for a position and nominee, |
| 290 | + # update the nomineepostion of primary nominee with the state |
| 291 | + if nominee_position.state.slug == 'accepted' or primary_nominee_position.state.slug == 'accepted': |
| 292 | + primary_nominee_position.state = NomineePositionStateName.objects.get(slug='accepted') |
| 293 | + primary_nominee_position.save() |
| 294 | + if nominee_position.state.slug == 'declined' and primary_nominee_position.state.slug == 'pending': |
| 295 | + primary_nominee_position.state = NomineePositionStateName.objects.get(slug='declined') |
| 296 | + primary_nominee_position.save() |
| 297 | + else: |
| 298 | + # It is not allowed two or more nomineeposition objects with same position and nominee |
| 299 | + # move nominee_position object to primary nominee |
| 300 | + nominee_position.nominee = primary_nominee |
| 301 | + nominee_position.save() |
| 302 | + |
| 303 | + nominee.duplicated = primary_nominee |
| 304 | + nominee.save() |
| 305 | + |
| 306 | +class MergePersonForm(forms.Form): |
225 | 307 |
|
226 | 308 | primary_person = SearchablePersonField(help_text="Select the person you want the datatracker to keep") |
227 | 309 | duplicate_persons = SearchablePersonsField(help_text="Select all the duplicates that should be merged into the primary person record") |
228 | 310 |
|
229 | 311 | def __init__(self, *args, **kwargs): |
230 | 312 | self.nomcom = kwargs.pop('nomcom', None) |
231 | | - super(MergeForm, self).__init__(*args, **kwargs) |
| 313 | + super(MergePersonForm, self).__init__(*args, **kwargs) |
232 | 314 |
|
233 | 315 | def clean(self): |
234 | 316 | primary_person = self.cleaned_data.get("primary_person") |
@@ -767,6 +849,20 @@ def __init__(self, *args, **kwargs): |
767 | 849 | self.fields['nominee_email'].initial = self.instance.email |
768 | 850 | self.fields['nominee_email'].help_text = "If the address you are looking for does not appear in this list, ask the nominee (or the secretariat) to add the address to their datatracker account and ensure it is marked as active." |
769 | 851 |
|
| 852 | + def clean(self): |
| 853 | + nominee_email = self.cleaned_data.get("nominee_email") |
| 854 | + others = Nominee.objects.filter(email=nominee_email, nomcom=self.instance.nomcom) |
| 855 | + if others.exists(): |
| 856 | + msg = ( "Changing email address for %s (#%s): There already exists a nominee " |
| 857 | + "with email address <%s>: %s -- please use the " |
| 858 | + "<a ref=\"{% url 'ietf.nomcom.views.private_merge_nominee' %}\">Merge Nominee</a> " |
| 859 | + "form instead." % ( |
| 860 | + self.instance.name(), |
| 861 | + self.instance.pk, nominee_email, |
| 862 | + (", ".join( "%s (#%s)" %( n.name(), n.pk) for n in others))) ) |
| 863 | + raise forms.ValidationError(mark_safe(msg)) |
| 864 | + return self.cleaned_data |
| 865 | + |
770 | 866 | def save(self, commit=True): |
771 | 867 | nominee = super(EditNomineeForm, self).save(commit=False) |
772 | 868 | nominee_email = self.cleaned_data.get("nominee_email") |
|
0 commit comments