from django import forms from django.utils.translation import ugettext_lazy as _ from django.contrib.auth.models import User from django.forms.widgets import RadioSelect, CheckboxSelectMultiple from django.forms.formsets import BaseFormSet, formset_factory from django.db.models import Max from django.core.validators import MinLengthValidator from gestioncof.models import CofProfile, EventCommentValue, \ CalendarSubscription, Club from gestioncof.widgets import TriStateCheckbox from gestioncof.shared import lock_table, unlock_table from bda.models import Spectacle class EventForm(forms.Form): def __init__(self, *args, **kwargs): event = kwargs.pop("event") self.event = event current_choices = kwargs.pop("current_choices", None) super(EventForm, self).__init__(*args, **kwargs) choices = {} if current_choices: for choice in current_choices.all(): if choice.event_option.id not in choices: choices[choice.event_option.id] = [choice.id] else: choices[choice.event_option.id].append(choice.id) all_choices = choices for option in event.options.all(): choices = [(choice.id, choice.value) for choice in option.choices.all()] if option.multi_choices: initial = [] if option.id not in all_choices \ else all_choices[option.id] field = forms.MultipleChoiceField( label=option.name, choices=choices, widget=CheckboxSelectMultiple, required=False, initial=initial) else: initial = None if option.id not in all_choices \ else all_choices[option.id][0] field = forms.ChoiceField(label=option.name, choices=choices, widget=RadioSelect, required=False, initial=initial) field.option_id = option.id self.fields["option_%d" % option.id] = field def choices(self): for name, value in self.cleaned_data.items(): if name.startswith('option_'): yield (self.fields[name].option_id, value) class SurveyForm(forms.Form): def __init__(self, *args, **kwargs): survey = kwargs.pop("survey") current_answers = kwargs.pop("current_answers", None) super(SurveyForm, self).__init__(*args, **kwargs) answers = {} if current_answers: for answer in current_answers.all(): if answer.survey_question.id not in answers: answers[answer.survey_question.id] = [answer.id] else: answers[answer.survey_question.id].append(answer.id) for question in survey.questions.all(): choices = [(answer.id, answer.answer) for answer in question.answers.all()] if question.multi_answers: initial = [] if question.id not in answers\ else answers[question.id] field = forms.MultipleChoiceField( label=question.question, choices=choices, widget=CheckboxSelectMultiple, required=False, initial=initial) else: initial = None if question.id not in answers\ else answers[question.id][0] field = forms.ChoiceField(label=question.question, choices=choices, widget=RadioSelect, required=False, initial=initial) field.question_id = question.id self.fields["question_%d" % question.id] = field def answers(self): for name, value in self.cleaned_data.items(): if name.startswith('question_'): yield (self.fields[name].question_id, value) class SurveyStatusFilterForm(forms.Form): def __init__(self, *args, **kwargs): survey = kwargs.pop("survey") super(SurveyStatusFilterForm, self).__init__(*args, **kwargs) for question in survey.questions.all(): for answer in question.answers.all(): name = "question_%d_answer_%d" % (question.id, answer.id) if self.is_bound \ and self.data.get(self.add_prefix(name), None): initial = self.data.get(self.add_prefix(name), None) else: initial = "none" field = forms.ChoiceField( label="%s : %s" % (question.question, answer.answer), choices=[("yes", "yes"), ("no", "no"), ("none", "none")], widget=TriStateCheckbox, required=False, initial=initial) field.question_id = question.id field.answer_id = answer.id self.fields[name] = field def filters(self): for name, value in self.cleaned_data.items(): if name.startswith('question_'): yield (self.fields[name].question_id, self.fields[name].answer_id, value) class EventStatusFilterForm(forms.Form): def __init__(self, *args, **kwargs): event = kwargs.pop("event") super(EventStatusFilterForm, self).__init__(*args, **kwargs) for option in event.options.all(): for choice in option.choices.all(): name = "option_%d_choice_%d" % (option.id, choice.id) if self.is_bound \ and self.data.get(self.add_prefix(name), None): initial = self.data.get(self.add_prefix(name), None) else: initial = "none" field = forms.ChoiceField( label="%s : %s" % (option.name, choice.value), choices=[("yes", "yes"), ("no", "no"), ("none", "none")], widget=TriStateCheckbox, required=False, initial=initial) field.option_id = option.id field.choice_id = choice.id self.fields[name] = field # has_paid name = "event_has_paid" if self.is_bound and self.data.get(self.add_prefix(name), None): initial = self.data.get(self.add_prefix(name), None) else: initial = "none" field = forms.ChoiceField(label="Événement payé", choices=[("yes", "yes"), ("no", "no"), ("none", "none")], widget=TriStateCheckbox, required=False, initial=initial) self.fields[name] = field def filters(self): for name, value in self.cleaned_data.items(): if name.startswith('option_'): yield (self.fields[name].option_id, self.fields[name].choice_id, value) elif name == "event_has_paid": yield ("has_paid", None, value) class UserProfileForm(forms.ModelForm): first_name = forms.CharField(label=_('Prénom'), max_length=30) last_name = forms.CharField(label=_('Nom'), max_length=30) def __init__(self, *args, **kw): super(UserProfileForm, self).__init__(*args, **kw) self.fields['first_name'].initial = self.instance.user.first_name self.fields['last_name'].initial = self.instance.user.last_name def save(self, *args, **kw): super(UserProfileForm, self).save(*args, **kw) self.instance.user.first_name = self.cleaned_data.get('first_name') self.instance.user.last_name = self.cleaned_data.get('last_name') self.instance.user.save() class Meta: model = CofProfile fields = ["first_name", "last_name", "phone", "mailing_cof", "mailing_bda", "mailing_bda_revente"] class RegistrationUserForm(forms.ModelForm): def __init__(self, *args, **kw): super(RegistrationUserForm, self).__init__(*args, **kw) self.fields['username'].help_text = "" def force_long_username(self): self.fields['username'].validators = [MinLengthValidator(9)] class Meta: model = User fields = ("username", "first_name", "last_name", "email") class RegistrationPassUserForm(RegistrationUserForm): """ Formulaire pour changer le mot de passe d'un utilisateur. """ password1 = forms.CharField(label=_('Mot de passe'), widget=forms.PasswordInput) password2 = forms.CharField(label=_('Confirmation du mot de passe'), widget=forms.PasswordInput) def clean_password2(self): pass1 = self.cleaned_data['password1'] pass2 = self.cleaned_data['password2'] if pass1 and pass2: if pass1 != pass2: raise forms.ValidationError(_('Mots de passe non identiques.')) return pass2 def save(self, commit=True, *args, **kwargs): user = super(RegistrationPassUserForm, self).save(commit, *args, **kwargs) user.set_password(self.cleaned_data['password2']) if commit: user.save() return user class RegistrationProfileForm(forms.ModelForm): def __init__(self, *args, **kw): super(RegistrationProfileForm, self).__init__(*args, **kw) self.fields['mailing_cof'].initial = True self.fields['mailing_bda'].initial = True self.fields['mailing_bda_revente'].initial = True self.fields['num'].widget.attrs['readonly'] = True self.fields.keyOrder = [ 'login_clipper', 'phone', 'occupation', 'departement', 'is_cof', 'num', 'type_cotiz', 'mailing_cof', 'mailing_bda', 'mailing_bda_revente', 'comments' ] def save(self, *args, **kw): instance = super(RegistrationProfileForm, self).save(*args, **kw) if instance.is_cof and not instance.num: # Generate new number try: lock_table(CofProfile) aggregate = CofProfile.objects.aggregate(Max('num')) instance.num = aggregate['num__max'] + 1 instance.save() self.cleaned_data['num'] = instance.num self.data['num'] = instance.num finally: unlock_table(CofProfile) return instance class Meta: model = CofProfile fields = ("login_clipper", "num", "phone", "occupation", "departement", "is_cof", "type_cotiz", "mailing_cof", "mailing_bda", "mailing_bda_revente", "comments") STATUS_CHOICES = (('no', 'Non'), ('wait', 'Oui mais attente paiement'), ('paid', 'Oui payé'),) class AdminEventForm(forms.Form): status = forms.ChoiceField(label="Inscription", initial="no", choices=STATUS_CHOICES, widget=RadioSelect) def __init__(self, *args, **kwargs): self.event = kwargs.pop("event") registration = kwargs.pop("current_registration", None) current_choices, paid = \ (registration.options.all(), registration.paid) \ if registration is not None else ([], None) if paid is True: kwargs["initial"] = {"status": "paid"} elif paid is False: kwargs["initial"] = {"status": "wait"} else: kwargs["initial"] = {"status": "no"} super(AdminEventForm, self).__init__(*args, **kwargs) choices = {} for choice in current_choices: if choice.event_option.id not in choices: choices[choice.event_option.id] = [choice.id] else: choices[choice.event_option.id].append(choice.id) all_choices = choices for option in self.event.options.all(): choices = [(choice.id, choice.value) for choice in option.choices.all()] if option.multi_choices: initial = [] if option.id not in all_choices\ else all_choices[option.id] field = forms.MultipleChoiceField( label=option.name, choices=choices, widget=CheckboxSelectMultiple, required=False, initial=initial) else: initial = None if option.id not in all_choices\ else all_choices[option.id][0] field = forms.ChoiceField(label=option.name, choices=choices, widget=RadioSelect, required=False, initial=initial) field.option_id = option.id self.fields["option_%d" % option.id] = field for commentfield in self.event.commentfields.all(): initial = commentfield.default if registration is not None: try: initial = registration.comments \ .get(commentfield=commentfield).content except EventCommentValue.DoesNotExist: pass widget = forms.Textarea if commentfield.fieldtype == "text" \ else forms.TextInput field = forms.CharField(label=commentfield.name, widget=widget, required=False, initial=initial) field.comment_id = commentfield.id self.fields["comment_%d" % commentfield.id] = field def choices(self): for name, value in self.cleaned_data.items(): if name.startswith('option_'): yield (self.fields[name].option_id, value) def comments(self): for name, value in self.cleaned_data.items(): if name.startswith('comment_'): yield (self.fields[name].comment_id, value) class BaseEventRegistrationFormset(BaseFormSet): def __init__(self, *args, **kwargs): self.events = kwargs.pop('events') self.current_registrations = kwargs.pop('current_registrations', None) self.extra = len(self.events) super(BaseEventRegistrationFormset, self).__init__(*args, **kwargs) def _construct_form(self, index, **kwargs): kwargs['event'] = self.events[index] if self.current_registrations is not None: kwargs['current_registration'] = self.current_registrations[index] return super(BaseEventRegistrationFormset, self)._construct_form( index, **kwargs) EventFormset = formset_factory(AdminEventForm, BaseEventRegistrationFormset) class CalendarForm(forms.ModelForm): subscribe_to_events = forms.BooleanField( initial=True, label="Événements du COF") subscribe_to_my_shows = forms.BooleanField( initial=True, label="Les spectacles pour lesquels j'ai obtenu une place") other_shows = forms.ModelMultipleChoiceField( label="Spectacles supplémentaires", queryset=Spectacle.objects.filter(tirage__active=True), widget=forms.CheckboxSelectMultiple, required=False) class Meta: model = CalendarSubscription fields = ['subscribe_to_events', 'subscribe_to_my_shows', 'other_shows'] class ClubsForm(forms.Form): """ Formulaire d'inscription d'un membre à plusieurs clubs du COF. """ clubs = forms.ModelMultipleChoiceField( label="Inscriptions aux clubs du COF", queryset=Club.objects.all(), widget=forms.CheckboxSelectMultiple, required=False)