# coding: utf-8 from django.shortcuts import redirect, get_object_or_404 from django.http import Http404 from django.core.urlresolvers import reverse from django.contrib.auth.decorators import login_required from django import forms from django.forms.widgets import RadioSelect, CheckboxSelectMultiple from django.utils.translation import ugettext_lazy as _ from gestioncof.models import Survey, SurveyQuestion, SurveyQuestionAnswer, SurveyAnswer from gestioncof.models import Event, EventOption, EventOptionChoice, EventRegistration from gestioncof.models import CofProfile from gestioncof.shared import render_page from gestioncof.decorators import buro_required, cof_required from gestioncof.widgets import TriStateCheckbox @login_required def home(request): data = {"surveys": Survey.objects.filter(survey_open = True).all(), "events": Event.objects.filter(registration_open = True).all()} return render_page(request, data, "home.html") def login(request): if request.user.is_authenticated(): return redirect("gestioncof.views.home") return render_page(request, {}, "login_switch.html") @login_required def logout(request): try: profile = request.user.get_profile() except CofProfile.DoesNotExist: profile, created = CofProfile.objects.get_or_create(user = request.user) if profile.login_clipper: return redirect("django_cas.views.logout") else: return redirect("django.contrib.auth.views.logout") 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) @login_required def survey(request, survey_id): survey = get_object_or_404(Survey, id = survey_id) if not survey.survey_open: raise Http404 success = False deleted = False if request.method == "POST": form = SurveyForm(request.POST, survey = survey) if request.POST.get('delete'): try: current_answer = SurveyAnswer.objects.get(user = request.user, survey = survey) current_answer.delete() current_answer = None except SurveyAnswer.DoesNotExist: current_answer = None form = SurveyForm(survey = survey) success = True deleted = True else: if form.is_valid(): all_answers = [] for question_id, answers_ids in form.answers(): question = get_object_or_404(SurveyQuestion, id = question_id, survey = survey) if type(answers_ids) != list: answers_ids = [answers_ids] if not question.multi_answers and len(answers_ids) > 1: raise Http404 for answer_id in answers_ids: if not answer_id: continue answer_id = int(answer_id) answer = SurveyQuestionAnswer.objects.get( id = answer_id, survey_question = question) all_answers.append(answer) try: current_answer = SurveyAnswer.objects.get(user = request.user, survey = survey) except SurveyAnswer.DoesNotExist: current_answer = SurveyAnswer(user = request.user, survey = survey) current_answer.save() current_answer.answers = all_answers current_answer.save() success = True else: try: current_answer = SurveyAnswer.objects.get(user = request.user, survey = survey) form = SurveyForm(survey = survey, current_answers = current_answer.answers) except SurveyAnswer.DoesNotExist: current_answer = None form = SurveyForm(survey = survey) return render_page(request, {"survey": survey, "form": form, "success": success, "deleted": deleted, "current_answer": current_answer}, "survey.html") class EventForm(forms.Form): def __init__(self, *args, **kwargs): event = kwargs.pop("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) @login_required def event(request, event_id): event = get_object_or_404(Event, id = event_id) if not event.registration_open: raise Http404 success = False if request.method == "POST": form = EventForm(request.POST, event = event) if form.is_valid(): all_choices = [] for option_id, choices_ids in form.choices(): option = get_object_or_404(EventOption, id = option_id, event = event) if type(choices_ids) != list: choices_ids = [choices_ids] if not option.multi_choices and len(choices_ids) > 1: raise Http404 for choice_id in choices_ids: if not choice_id: continue choice_id = int(choice_id) choice = EventOptionChoice.objects.get( id = choice_id, event_option = option) all_choices.append(choice) try: current_registration = EventRegistration.objects.get(user = request.user, event = event) except EventRegistration.DoesNotExist: current_registration = EventRegistration(user = request.user, event = event) current_registration.save() current_registration.options = all_choices current_registration.save() success = True else: try: current_registration = EventRegistration.objects.get(user = request.user, event = event) form = EventForm(event = event, current_choices = current_registration.options) except EventRegistration.DoesNotExist: form = EventForm(event = event) return render_page(request, {"event": event, "form": form, "success": success}, "event.html") @buro_required() def event_status(request, event_id): event = get_object_or_404(Event, id = event_id) registrants = EventRegistration.objects.filter(event = event).all() return render_page(request, {"event": event, "registrants": registrants}, "event_status.html") class SurveyStatusFilterForm(forms.Form): def __init__(self, *args, **kwargs): survey = kwargs.pop("survey") super(SurveyStatusFilterForm, self).__init__(*args, **kwargs) answers = {} 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) choices = {} 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 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) def clean_post_for_status(initial): d = dict(initial) for k, v in d.items(): if k.startswith("id_"): del d[k] if type(v) == list and len(v) >= 1: d[k[3:]] = v[0] else: d[k[3:]] = v return d @buro_required() def event_status(request, event_id): event = get_object_or_404(Event, id = event_id) registrations_query = EventRegistration.objects.filter(event = event) post_data = clean_post_for_status(request.POST) form = EventStatusFilterForm(post_data or None, event = event) if form.is_valid(): for option_id, choice_id, value in form.filters(): choice = get_object_or_404(EventOptionChoice, id = choice_id, event_option__id = option_id) if value == "none": continue if value == "yes": registrations_query = registrations_query.filter(options__id__exact = choice.id) elif value == "no": registrations_query = registrations_query.exclude(options__id__exact = choice.id) user_choices = registrations_query.prefetch_related("user").all() options = EventOption.objects.filter(event = event).all() choices_count = {} for option in options: for choice in option.choices.all(): choices_count[choice.id] = 0 for user_choice in user_choices: for choice in user_choice.options.all(): choices_count[choice.id] += 1 return render_page(request, {"event": event, "user_choices": user_choices, "options": options, "choices_count": choices_count, "form": form}, "event_status.html") @buro_required() def survey_status(request, survey_id): survey = get_object_or_404(Survey, id = survey_id) answers_query = SurveyAnswer.objects.filter(survey = survey) post_data = clean_post_for_status(request.POST) form = SurveyStatusFilterForm(post_data or None, survey = survey) if form.is_valid(): for question_id, answer_id, value in form.filters(): answer = get_object_or_404(SurveyQuestionAnswer, id = answer_id, survey_question__id = question_id) if value == "none": continue if value == "yes": answers_query = answers_query.filter(answers__id__exact = answer.id) elif value == "no": answers_query = answers_query.exclude(answers__id__exact = answer.id) user_answers = answers_query.prefetch_related("user").all() questions = SurveyQuestion.objects.filter(survey = survey).all() answers_count = {} for question in questions: for answer in question.answers.all(): answers_count[answer.id] = 0 for user_answer in user_answers: for answer in user_answer.answers.all(): answers_count[answer.id] += 1 return render_page(request, {"survey": survey, "user_answers": user_answers, "questions": questions, "answers_count": answers_count, "form": form}, "survey_status.html") class UserProfileForm(forms.ModelForm): first_name = forms.CharField(label=_(u'Prénom'), max_length=30) last_name = forms.CharField(label=_(u'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 self.fields.keyOrder = [ 'first_name', 'last_name', 'phone', 'mailing_cof', 'mailing_bda_revente', ] 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 = ("phone", "mailing_cof", "mailing_bda_revente",) @login_required def profile(request): success = False if request.method == "POST": form = UserProfileForm(request.POST, instance = request.user.get_profile()) if form.is_valid(): form.save() success = True else: form = UserProfileForm(instance = request.user.get_profile()) return render_page(request, {"form": form, "success": success}, "profile.html") @login_required def registration(request): data = {"surveys": Survey.objects.filter(survey_open = True).all(), "events": Event.objects.filter(registration_open = True).all()} return render_page(request, data, "registration.html")