from django import forms from django.forms.widgets import RadioSelect, CheckboxSelectMultiple from django.forms.formsets import BaseFormSet, formset_factory from django.utils.translation import ugettext_lazy as _ from bda.models import Spectacle from .models import CofProfile, EventCommentValue, CalendarSubscription from .widgets import TriStateCheckbox 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 COFProfileRegistrationForm(forms.ModelForm): member = forms.BooleanField( label=_("Membre du COF"), required=False, ) def save(self, **kwargs): super().save() self.instance.is_cof = True class Meta: model = CofProfile fields = [ "type_cotiz", "mailing", "mailing_bda", "mailing_bda_revente", ] 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']