373 lines
14 KiB
Python
373 lines
14 KiB
Python
from django import forms
|
|
from django.db.models import Q
|
|
from django.conf import settings
|
|
from django.core.mail import EmailMessage
|
|
from django.forms.models import BaseModelFormSet
|
|
from django.template.loader import render_to_string
|
|
from django.utils.safestring import mark_safe
|
|
|
|
from ietf.wgchairs.models import WGDelegate
|
|
from ietf.wgchairs.accounts import get_person_for_user
|
|
from ietf.ietfworkflows.utils import get_default_workflow_for_wg, get_workflow_for_wg
|
|
from ietf.idtracker.models import PersonOrOrgInfo
|
|
|
|
from workflows.models import Transition
|
|
|
|
|
|
class RelatedWGForm(forms.Form):
|
|
|
|
can_cancel = False
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.wg = kwargs.pop('wg', None)
|
|
self.user = kwargs.pop('user', None)
|
|
self.message = {}
|
|
super(RelatedWGForm, self).__init__(*args, **kwargs)
|
|
|
|
def get_message(self):
|
|
return self.message
|
|
|
|
def set_message(self, msg_type, msg_value):
|
|
self.message = {'type': msg_type,
|
|
'value': msg_value,
|
|
}
|
|
|
|
|
|
class TagForm(RelatedWGForm):
|
|
|
|
tags = forms.ModelMultipleChoiceField(get_default_workflow_for_wg().annotation_tags.all(),
|
|
widget=forms.CheckboxSelectMultiple)
|
|
|
|
def save(self):
|
|
workflow = get_workflow_for_wg(self.wg)
|
|
workflow.selected_tags.clear()
|
|
for tag in self.cleaned_data['tags']:
|
|
workflow.selected_tags.add(tag)
|
|
return workflow
|
|
|
|
|
|
class StateForm(RelatedWGForm):
|
|
|
|
states = forms.ModelMultipleChoiceField(get_default_workflow_for_wg().states.all(),
|
|
widget=forms.CheckboxSelectMultiple)
|
|
|
|
def update_transitions(self, workflow):
|
|
for transition in workflow.transitions.all():
|
|
if not workflow.selected_states.filter(pk=transition.destination.pk).count():
|
|
transition.delete()
|
|
continue
|
|
for state in transition.states.all():
|
|
if not workflow.selected_states.filter(pk=state.pk).count():
|
|
transition.states.remove(state)
|
|
if not transition.states.count():
|
|
transition.delete()
|
|
continue
|
|
|
|
def save(self):
|
|
workflow = get_workflow_for_wg(self.wg)
|
|
workflow.selected_states.clear()
|
|
for state in self.cleaned_data['states']:
|
|
workflow.selected_states.add(state)
|
|
self.update_transitions(workflow)
|
|
return workflow
|
|
|
|
|
|
class DeleteTransitionForm(RelatedWGForm):
|
|
|
|
transitions = forms.ModelMultipleChoiceField(Transition.objects.all(),
|
|
widget=forms.CheckboxSelectMultiple)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(DeleteTransitionForm, self).__init__(*args, **kwargs)
|
|
workflow = get_workflow_for_wg(self.wg)
|
|
self.fields['transitions'].queryset = self.fields['transitions'].queryset.filter(workflow=workflow)
|
|
|
|
def save(self):
|
|
for transition in self.cleaned_data['transitions']:
|
|
transition.delete()
|
|
|
|
|
|
class TransitionForm(forms.ModelForm):
|
|
|
|
states = forms.ModelMultipleChoiceField(get_default_workflow_for_wg().states.all())
|
|
|
|
class Meta:
|
|
model = Transition
|
|
fields = ('DELETE', 'name', 'states', 'destination', )
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.wg = kwargs.pop('wg', None)
|
|
self.user = kwargs.pop('user', None)
|
|
super(TransitionForm, self).__init__(*args, **kwargs)
|
|
workflow = get_workflow_for_wg(self.wg)
|
|
self.fields['states'].queryset = workflow.selected_states.all()
|
|
self.fields['destination'].queryset = workflow.selected_states.all()
|
|
self.fields['destination'].required = True
|
|
if self.instance.pk:
|
|
self.fields['states'].initial = [i.pk for i in self.instance.states.all()]
|
|
self.instance.workflow = workflow
|
|
|
|
def as_row(self):
|
|
return self._html_output(u'<td>%(errors)s%(field)s%(help_text)s</td>', u'<td colspan="2">%s</td>', '</td>', u'<br />%s', False)
|
|
|
|
def save(self, *args, **kwargs):
|
|
instance = super(TransitionForm, self).save(*args, **kwargs)
|
|
for state in self.cleaned_data['states']:
|
|
state.transitions.add(instance)
|
|
|
|
|
|
class TransitionFormSet(BaseModelFormSet):
|
|
|
|
form = TransitionForm
|
|
can_delete = True
|
|
extra = 2
|
|
max_num = 0
|
|
can_order = False
|
|
model = Transition
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.wg = kwargs.pop('wg', None)
|
|
self.user = kwargs.pop('user', None)
|
|
super(TransitionFormSet, self).__init__(*args, **kwargs)
|
|
|
|
def _construct_form(self, i, **kwargs):
|
|
kwargs = kwargs or {}
|
|
kwargs.update({'wg': self.wg, 'user': self.user})
|
|
return super(TransitionFormSet, self)._construct_form(i, **kwargs)
|
|
|
|
def as_table(self):
|
|
html = u''
|
|
csscl = 'oddrow'
|
|
for form in self.forms:
|
|
html += u'<tr class="%s">' % csscl
|
|
html += form.as_row()
|
|
html += u'</tr>'
|
|
if csscl == 'oddrow':
|
|
csscl = 'evenrow'
|
|
else:
|
|
csscl = 'oddrow'
|
|
return mark_safe(u'\n'.join([unicode(self.management_form), html]))
|
|
|
|
|
|
def workflow_form_factory(request, wg, user):
|
|
|
|
if request.POST.get('update_transitions', None):
|
|
return TransitionFormSet(wg=wg, user=user, data=request.POST)
|
|
elif request.POST.get('update_states', None):
|
|
return StateForm(wg=wg, user=user, data=request.POST)
|
|
return TagForm(wg=wg, user=user, data=request.POST)
|
|
|
|
|
|
class RemoveDelegateForm(RelatedWGForm):
|
|
|
|
delete = forms.MultipleChoiceField()
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(RemoveDelegateForm, self).__init__(*args, **kwargs)
|
|
self.fields['delete'].choices = [(i.pk, i.pk) for i in self.wg.wgdelegate_set.all()]
|
|
|
|
def save(self):
|
|
delegates = self.cleaned_data.get('delete')
|
|
WGDelegate.objects.filter(pk__in=delegates).delete()
|
|
self.set_message('success', 'Delegates removed')
|
|
|
|
|
|
class AddDelegateForm(RelatedWGForm):
|
|
|
|
email = forms.EmailField()
|
|
form_type = forms.CharField(widget=forms.HiddenInput, initial='single')
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(AddDelegateForm, self).__init__(*args, **kwargs)
|
|
self.next_form = self
|
|
|
|
def get_next_form(self):
|
|
return self.next_form
|
|
|
|
def get_person(self, email):
|
|
persons = PersonOrOrgInfo.objects.filter(emailaddress__address=email, iesglogin__isnull=False).distinct()
|
|
if not persons:
|
|
raise PersonOrOrgInfo.DoesNotExist
|
|
if len(persons) > 1:
|
|
raise PersonOrOrgInfo.MultipleObjectsReturned
|
|
return persons[0]
|
|
|
|
def save(self):
|
|
email = self.cleaned_data.get('email')
|
|
try:
|
|
person = self.get_person(email)
|
|
except PersonOrOrgInfo.DoesNotExist:
|
|
self.next_form = NotExistDelegateForm(wg=self.wg, user=self.user, email=email)
|
|
self.next_form.set_message('doesnotexist', 'There is no user with this email allowed to login to the system')
|
|
return
|
|
except PersonOrOrgInfo.MultipleObjectsReturned:
|
|
self.next_form = MultipleDelegateForm(wg=self.wg, user=self.user, email=email)
|
|
self.next_form.set_message('multiple', 'There are multiple users with this email in the system')
|
|
return
|
|
self.create_delegate(person)
|
|
|
|
def create_delegate(self, person):
|
|
(delegate, created) = WGDelegate.objects.get_or_create(wg=self.wg,
|
|
person=person)
|
|
if not created:
|
|
self.set_message('error', 'The email belongs to a person who is already a delegate')
|
|
else:
|
|
self.next_form = AddDelegateForm(wg=self.wg, user=self.user)
|
|
self.next_form.set_message('success', 'A new delegate has been added')
|
|
|
|
|
|
class MultipleDelegateForm(AddDelegateForm):
|
|
|
|
email = forms.EmailField(widget=forms.HiddenInput)
|
|
form_type = forms.CharField(widget=forms.HiddenInput, initial='multiple')
|
|
persons = forms.ChoiceField(widget=forms.RadioSelect, help_text='Please select one person from the list')
|
|
submit_msg = 'Designate as delegate'
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.email = kwargs.pop('email', None)
|
|
super(MultipleDelegateForm, self).__init__(*args, **kwargs)
|
|
if not self.email:
|
|
self.email = self.data.get('email', None)
|
|
self.fields['email'].initial = self.email
|
|
self.fields['persons'].choices = [(i.pk, unicode(i)) for i in PersonOrOrgInfo.objects.filter(emailaddress__address=self.email, iesglogin__isnull=False).distinct().order_by('first_name')]
|
|
|
|
def save(self):
|
|
person_id = self.cleaned_data.get('persons')
|
|
person = PersonOrOrgInfo.objects.get(pk=person_id)
|
|
self.create_delegate(person)
|
|
|
|
|
|
class NotExistDelegateForm(MultipleDelegateForm):
|
|
|
|
email = forms.EmailField(widget=forms.HiddenInput)
|
|
form_type = forms.CharField(widget=forms.HiddenInput, initial='notexist')
|
|
can_cancel = True
|
|
submit_msg = 'Send email to these addresses'
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(NotExistDelegateForm, self).__init__(*args, **kwargs)
|
|
self.email_list = []
|
|
del(self.fields['persons'])
|
|
|
|
def get_email_list(self):
|
|
if self.email_list:
|
|
return self.email_list
|
|
email_list = [self.email]
|
|
email_list.append('IETF Secretariat <iesg-secretary@ietf.org>')
|
|
email_list += ['%s <%s>' % i.person.email() for i in self.wg.wgchair_set.all() if i.person.email()]
|
|
self.email_list = email_list
|
|
return email_list
|
|
|
|
def as_p(self):
|
|
email_list = self.get_email_list()
|
|
info = render_to_string('wgchairs/notexistdelegate.html', {'email_list': email_list})
|
|
return info + super(NotExistDelegateForm, self).as_p()
|
|
|
|
def send_email(self, email, template):
|
|
subject = 'WG Delegate needs system credentials'
|
|
persons = PersonOrOrgInfo.objects.filter(emailaddress__address=self.email).distinct()
|
|
body = render_to_string(template,
|
|
{'chair': get_person_for_user(self.user),
|
|
'delegate_email': self.email,
|
|
'delegate_persons': persons,
|
|
'wg': self.wg,
|
|
})
|
|
mail = EmailMessage(subject=subject,
|
|
body=body,
|
|
to=email,
|
|
from_email=settings.DEFAULT_FROM_EMAIL)
|
|
mail.send()
|
|
|
|
def send_email_to_delegate(self, email):
|
|
self.send_email(email, 'wgchairs/notexistsdelegate_delegate_email.txt')
|
|
|
|
def send_email_to_secretariat(self, email):
|
|
self.send_email(email, 'wgchairs/notexistsdelegate_secretariat_email.txt')
|
|
|
|
def send_email_to_wgchairs(self, email):
|
|
self.send_email(email, 'wgchairs/notexistsdelegate_wgchairs_email.txt')
|
|
|
|
def save(self):
|
|
self.next_form = AddDelegateForm(wg=self.wg, user=self.user)
|
|
if settings.DEBUG:
|
|
self.next_form.set_message('warning', 'Email was not sent cause tool is in DEBUG mode')
|
|
else:
|
|
email_list = self.get_email_list()
|
|
self.send_email_to_delegate([email_list[0]])
|
|
self.send_email_to_secretariat([email_list[1]])
|
|
self.send_email_to_wgchairs(email_list[2:])
|
|
self.next_form.set_message('success', 'Email sent successfully')
|
|
|
|
|
|
def add_form_factory(request, wg, user):
|
|
if request.method != 'POST':
|
|
return AddDelegateForm(wg=wg, user=user)
|
|
|
|
if request.POST.get('form_type', None) == 'multiple':
|
|
return MultipleDelegateForm(wg=wg, user=user, data=request.POST.copy())
|
|
elif request.POST.get('form_type', None) == 'notexist':
|
|
return NotExistDelegateForm(wg=wg, user=user, data=request.POST.copy())
|
|
elif request.POST.get('form_type', None) == 'single':
|
|
return AddDelegateForm(wg=wg, user=user, data=request.POST.copy())
|
|
|
|
return AddDelegateForm(wg=wg, user=user)
|
|
|
|
|
|
class ManagingShepherdForm(forms.Form):
|
|
email = forms.EmailField(required=False)
|
|
is_assign_current = forms.BooleanField(required=False)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
if 'current_person' in kwargs.keys():
|
|
self.current_person = kwargs.pop('current_person')
|
|
return super(ManagingShepherdForm, self).__init__(*args, **kwargs)
|
|
|
|
def clean_email(self):
|
|
email = self.cleaned_data.get('email')
|
|
if not email:
|
|
return None
|
|
|
|
try:
|
|
PersonOrOrgInfo.objects. \
|
|
filter(emailaddress__type__in=["INET", "Prim", ],
|
|
emailaddress__address=email)[:1].get()
|
|
except PersonOrOrgInfo.DoesNotExist:
|
|
if self.cleaned_data.get('is_assign_current'):
|
|
self._send_email(email)
|
|
raise forms.ValidationError("Person with such email does not exist")
|
|
return email
|
|
|
|
def clean(self):
|
|
print self.cleaned_data.get('email') and self.cleaned_data.get('is_assign_current')
|
|
if self.cleaned_data.get('email') and \
|
|
self.cleaned_data.get('is_assign_current'):
|
|
raise forms.ValidationError("You should choose to assign to current \
|
|
person or input the email. Not both at te same time. ")
|
|
|
|
return self.cleaned_data
|
|
|
|
def change_shepherd(self, document, save=True):
|
|
email = self.cleaned_data.get('email')
|
|
if email:
|
|
person = PersonOrOrgInfo.objects. \
|
|
filter(emailaddress__type__in=["INET", "Prim", ],
|
|
emailaddress__address=email)[:1].get()
|
|
else:
|
|
person = self.current_person
|
|
document.shepherd = person
|
|
if save:
|
|
document.save()
|
|
return document
|
|
|
|
def _send_email(self, email,
|
|
template='wgchairs/edit_management_shepherd_email.txt'):
|
|
subject = 'WG Delegate needs system credentials'
|
|
body = render_to_string(template,
|
|
{'email': email,
|
|
})
|
|
mail = EmailMessage(subject=subject,
|
|
body=body,
|
|
to=[email, settings.DEFAULT_FROM_EMAIL, ],
|
|
from_email=settings.DEFAULT_FROM_EMAIL)
|
|
mail.send()
|