1- import datetime
2-
31from django .conf import settings
42from django import forms
53from django .contrib .formtools .preview import FormPreview , AUTO_ID
108from django .utils .decorators import method_decorator
119from django .shortcuts import render_to_response
1210from django .template .context import RequestContext
13- from django .contrib .sites .models import Site
1411
1512from ietf .dbtemplate .forms import DBTemplateForm
16- from ietf .utils import unaccent
17- from ietf .utils .mail import send_mail , send_mail_text
13+ from ietf .utils .mail import send_mail
1814from ietf .ietfauth .decorators import role_required
1915from ietf .utils import fields as custom_fields
2016from ietf .group .models import Group , Role
2117from ietf .name .models import RoleName , FeedbackType , NomineePositionState
22- from ietf .person .models import Email , Person
18+ from ietf .person .models import Email
2319from ietf .nomcom .models import NomCom , Nomination , Nominee , NomineePosition , \
2420 Position , Feedback , ReminderDates
25- from ietf .nomcom .utils import QUESTIONNAIRE_TEMPLATE , NOMINATION_EMAIL_TEMPLATE , \
26- INEXISTENT_PERSON_TEMPLATE , NOMINEE_EMAIL_TEMPLATE , \
27- NOMINATION_RECEIPT_TEMPLATE , FEEDBACK_RECEIPT_TEMPLATE , \
28- get_user_email , get_hash_nominee_position , get_year_by_nomcom , \
29- HEADER_QUESTIONNAIRE_TEMPLATE , validate_private_key , \
30- validate_public_key
21+ from ietf .nomcom .utils import (NOMINATION_RECEIPT_TEMPLATE , FEEDBACK_RECEIPT_TEMPLATE ,
22+ get_user_email , validate_private_key , validate_public_key ,
23+ get_or_create_nominee )
3124from ietf .nomcom .decorators import nomcom_member_required
3225
3326
@@ -441,37 +434,23 @@ def save(self, commit=True):
441434 comments = self .cleaned_data ['comments' ]
442435 confirmation = self .cleaned_data ['confirmation' ]
443436 nomcom_template_path = '/nomcom/%s/' % self .nomcom .group .acronym
444- nomcom_chair = self .nomcom .group .get_chair ()
445- nomcom_chair_mail = nomcom_chair and nomcom_chair .email .address or None
446-
447- # Create person and email if candidate email does't exist and send email
448- email , created_email = Email .objects .get_or_create (address = candidate_email )
449- if created_email :
450- email .person = Person .objects .create (name = candidate_name ,
451- ascii = unaccent .asciify (candidate_name ),
452- address = candidate_email )
453- email .save ()
454-
455- # Add the nomination for a particular position
456- nominee , created = Nominee .objects .get_or_create (email = email , nomcom = self .nomcom )
457- while nominee .duplicated :
458- nominee = nominee .duplicated
459- nominee_position , nominee_position_created = NomineePosition .objects .get_or_create (position = position , nominee = nominee )
460437
461- # Complete nomination data
462- feedback = Feedback .objects .create (nomcom = self .nomcom ,
463- comments = comments ,
464- type = FeedbackType .objects .get (slug = 'nomina' ),
465- user = self .user )
466- feedback .positions .add (position )
467- feedback .nominees .add (nominee )
468438 author = None
469439 if self .public :
470440 author = get_user_email (self .user )
471441 else :
472442 if nominator_email :
473443 emails = Email .objects .filter (address = nominator_email )
474444 author = emails and emails [0 ] or None
445+ nominee = get_or_create_nominee (self .nomcom , candidate_name , candidate_email , position , author )
446+
447+ # Complete nomination data
448+ feedback = Feedback .objects .create (nomcom = self .nomcom ,
449+ comments = comments ,
450+ type = FeedbackType .objects .get (slug = 'nomina' ),
451+ user = self .user )
452+ feedback .positions .add (position )
453+ feedback .nominees .add (nominee )
475454
476455 if author :
477456 nomination .nominator_email = author .address
@@ -485,87 +464,13 @@ def save(self, commit=True):
485464 if commit :
486465 nomination .save ()
487466
488- if created_email :
489- # send email to secretariat and nomcomchair to warn about the new person
490- subject = 'New person is created'
491- from_email = settings .NOMCOM_FROM_EMAIL
492- to_email = [settings .NOMCOM_ADMIN_EMAIL ]
493- context = {'email' : email .address ,
494- 'fullname' : email .person .name ,
495- 'person_id' : email .person .id }
496- path = nomcom_template_path + INEXISTENT_PERSON_TEMPLATE
497- if nomcom_chair_mail :
498- to_email .append (nomcom_chair_mail )
499- send_mail (None , to_email , from_email , subject , path , context )
500-
501- # send email to nominee
502- if nominee_position_created :
503- subject = 'IETF Nomination Information'
504- from_email = settings .NOMCOM_FROM_EMAIL
505- to_email = email .address
506- domain = Site .objects .get_current ().domain
507- today = datetime .date .today ().strftime ('%Y%m%d' )
508- hash = get_hash_nominee_position (today , nominee_position .id )
509- accept_url = reverse ('nomcom_process_nomination_status' ,
510- None ,
511- args = (get_year_by_nomcom (self .nomcom ),
512- nominee_position .id ,
513- 'accepted' ,
514- today ,
515- hash ))
516- decline_url = reverse ('nomcom_process_nomination_status' ,
517- None ,
518- args = (get_year_by_nomcom (self .nomcom ),
519- nominee_position .id ,
520- 'declined' ,
521- today ,
522- hash ))
523-
524- context = {'nominee' : email .person .name ,
525- 'position' : position .name ,
526- 'domain' : domain ,
527- 'accept_url' : accept_url ,
528- 'decline_url' : decline_url }
529-
530- path = nomcom_template_path + NOMINEE_EMAIL_TEMPLATE
531- send_mail (None , to_email , from_email , subject , path , context )
532-
533- # send email to nominee with questionnaire
534- if nominee_position_created :
535- if self .nomcom .send_questionnaire :
536- subject = '%s Questionnaire' % position
537- from_email = settings .NOMCOM_FROM_EMAIL
538- to_email = email .address
539- context = {'nominee' : email .person .name ,
540- 'position' : position .name }
541- path = '%s%d/%s' % (nomcom_template_path ,
542- position .id , HEADER_QUESTIONNAIRE_TEMPLATE )
543- body = render_to_string (path , context )
544- path = '%s%d/%s' % (nomcom_template_path ,
545- position .id , QUESTIONNAIRE_TEMPLATE )
546- body += '\n \n %s' % render_to_string (path , context )
547- send_mail_text (None , to_email , from_email , subject , body )
548-
549- # send emails to nomcom chair
550- subject = 'Nomination Information'
551- from_email = settings .NOMCOM_FROM_EMAIL
552- to_email = nomcom_chair_mail
553- context = {'nominee' : email .person .name ,
554- 'nominee_email' : email .address ,
555- 'position' : position .name }
556- if author :
557- context .update ({'nominator' : author .person .name ,
558- 'nominator_email' : author .address })
559- path = nomcom_template_path + NOMINATION_EMAIL_TEMPLATE
560- send_mail (None , to_email , from_email , subject , path , context )
561-
562467 # send receipt email to nominator
563468 if confirmation :
564469 if author :
565470 subject = 'Nomination Receipt'
566471 from_email = settings .NOMCOM_FROM_EMAIL
567472 to_email = author .address
568- context = {'nominee' : email .person .name ,
473+ context = {'nominee' : nominee . email .person .name ,
569474 'comments' : comments ,
570475 'position' : position .name }
571476 path = nomcom_template_path + NOMINATION_RECEIPT_TEMPLATE
@@ -795,37 +700,43 @@ def clean_key(self):
795700
796701class PendingFeedbackForm (BaseNomcomForm , forms .ModelForm ):
797702
703+ type = forms .ModelChoiceField (queryset = FeedbackType .objects .all (), widget = forms .RadioSelect , empty_label = 'Unclassified' , required = False )
704+
798705 class Meta :
799706 model = Feedback
800- fields = ('author' , ' type' , 'nominee' )
707+ fields = ('type' , )
801708
802709 def __init__ (self , * args , ** kwargs ):
803710 super (PendingFeedbackForm , self ).__init__ (* args , ** kwargs )
804- self .fields ['type' ].queryset = FeedbackType .objects .exclude (slug = 'nomina' )
711+ try :
712+ self .default_type = FeedbackType .objects .get (slug = settings .DEFAULT_FEEDBACK_TYPE )
713+ except FeedbackType .DoesNotExist :
714+ self .default_type = None
805715
806716 def set_nomcom (self , nomcom , user ):
807717 self .nomcom = nomcom
808718 self .user = user
809- self .fields ['nominee' ] = MultiplePositionNomineeField (nomcom = self .nomcom ,
810- required = True ,
811- widget = forms .SelectMultiple ,
812- help_text = 'Hold down "Control", or "Command" on a Mac, to select more than one.' )
719+ # self.fields['nominee'] = MultiplePositionNomineeField(nomcom=self.nomcom,
720+ # required=True,
721+ # widget=forms.SelectMultiple,
722+ # help_text='Hold down "Control", or "Command" on a Mac, to select more than one.')
813723
814724 def save (self , commit = True ):
815725 feedback = super (PendingFeedbackForm , self ).save (commit = False )
726+ feedback .nomcom = self .nomcom
727+ feedback .user = self .user
728+ feedback .save ()
729+ return feedback
816730
817- author = get_user_email (self .user )
818-
819- if author :
820- feedback .author = author
821-
731+ def move_to_default (self ):
732+ if not self .default_type or self .cleaned_data .get ('type' , None ):
733+ return None
734+ feedback = super (PendingFeedbackForm , self ).save (commit = False )
822735 feedback .nomcom = self .nomcom
823736 feedback .user = self .user
737+ feedback .type = self .default_type
824738 feedback .save ()
825- self .save_m2m ()
826- for (position , nominee ) in self .cleaned_data ['nominee' ]:
827- feedback .nominees .add (nominee )
828- feedback .positions .add (position )
739+ return feedback
829740
830741
831742class ReminderDatesForm (forms .ModelForm ):
@@ -837,3 +748,82 @@ class Meta:
837748 def __init__ (self , * args , ** kwargs ):
838749 super (ReminderDatesForm , self ).__init__ (* args , ** kwargs )
839750 self .fields ['date' ].required = False
751+
752+
753+ class MutableFeedbackForm (forms .ModelForm ):
754+
755+ type = forms .ModelChoiceField (queryset = FeedbackType .objects .all (), widget = forms .HiddenInput )
756+
757+ class Meta :
758+ model = Feedback
759+ fields = ('type' , )
760+
761+ def set_nomcom (self , nomcom , user , instances = None ):
762+ self .nomcom = nomcom
763+ self .user = user
764+ instances = instances or []
765+ self .feedback_type = None
766+ for i in instances :
767+ if i .id == self .instance .id :
768+ self .feedback_type = i .type
769+ break
770+ self .feedback_type = self .feedback_type or self .fields ['type' ].clean (self .fields ['type' ].widget .value_from_datadict (self .data , self .files , self .add_prefix ('type' )))
771+
772+ self .initial ['type' ] = self .feedback_type
773+
774+ if self .feedback_type .slug != 'nomina' :
775+ self .fields ['nominee' ] = MultiplePositionNomineeField (nomcom = self .nomcom ,
776+ required = True ,
777+ widget = forms .SelectMultiple ,
778+ help_text = 'Hold down "Control", or "Command" on a Mac, to select more than one.' )
779+ else :
780+ self .fields ['position' ] = forms .ModelChoiceField (queryset = Position .objects .get_by_nomcom (self .nomcom ).opened (), label = "Position" )
781+ self .fields ['candidate_name' ] = forms .CharField (label = "Candidate name" )
782+ self .fields ['candidate_email' ] = forms .EmailField (label = "Candidate email" )
783+ self .fields ['candidate_phone' ] = forms .CharField (label = "Candidate phone" , required = False )
784+
785+ def save (self , commit = True ):
786+ feedback = super (MutableFeedbackForm , self ).save (commit = False )
787+ if self .instance .type .slug == 'nomina' :
788+ candidate_email = self .cleaned_data ['candidate_email' ]
789+ candidate_name = self .cleaned_data ['candidate_name' ]
790+ candidate_phone = self .cleaned_data ['candidate_phone' ]
791+ position = self .cleaned_data ['position' ]
792+
793+ nominator_email = feedback .author
794+ feedback .save ()
795+
796+ emails = Email .objects .filter (address = nominator_email )
797+ author = emails and emails [0 ] or None
798+
799+ nominee = get_or_create_nominee (self .nomcom , candidate_name , candidate_email , position , author )
800+ feedback .nominees .add (nominee )
801+ feedback .positions .add (position )
802+ Nomination .objects .create (
803+ position = self .cleaned_data .get ('position' ),
804+ candidate_name = candidate_name ,
805+ candidate_email = candidate_email ,
806+ candidate_phone = candidate_phone ,
807+ nominee = nominee ,
808+ comments = feedback ,
809+ nominator_email = nominator_email ,
810+ user = self .user ,
811+ )
812+ return feedback
813+ else :
814+ feedback .save ()
815+ self .save_m2m ()
816+ for (position , nominee ) in self .cleaned_data ['nominee' ]:
817+ feedback .nominees .add (nominee )
818+ feedback .positions .add (position )
819+ return feedback
820+
821+
822+ class FullFeedbackFormSet (forms .models .BaseModelFormSet ):
823+
824+ model = Feedback
825+ extra = 0
826+ max_num = 0
827+ form = MutableFeedbackForm
828+ can_order = False
829+ can_delete = False
0 commit comments