From 3074071dffb42bef7dd08cf67eab642d1507bb15 Mon Sep 17 00:00:00 2001 From: Basile Clement Date: Fri, 27 May 2016 01:04:35 +0200 Subject: [PATCH 01/13] Affiche la debug-toolbar dans Vagrant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ce patch enlève la vérification faite par django-debug-toolbar pour ne s'afficher que si l'IP source est dans l'option de configuration INTERNAL_IPS. Ceci permet son fonctionnement avec Vagrant. Fixes #8. --- cof/settings_dev.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cof/settings_dev.py b/cof/settings_dev.py index b83f09bc..d51f6ec2 100644 --- a/cof/settings_dev.py +++ b/cof/settings_dev.py @@ -148,3 +148,18 @@ AUTHENTICATION_BACKENDS = ( RECAPTCHA_PUBLIC_KEY = "DUMMY" RECAPTCHA_PRIVATE_KEY = "DUMMY" RECAPTCHA_USE_SSL = True + +# On ne veut pas la vérification de INTERNAL_IPS faite par la debug-toolbar car +# cela interfère avec l'utilisation de Vagrant. En effet, l'adresse de la +# machine physique n'est pas forcément connue, et peut difficilement être mise +# dans les INTERNAL_IPS. +def show_toolbar(request): + if not DEBUG: + return False + if request.is_ajax(): + return False + return True + +DEBUG_TOOLBAR_CONFIG = { + 'SHOW_TOOLBAR_CALLBACK': show_toolbar, +} From f6279167846317ef50ca57672623bcf69d53fa0a Mon Sep 17 00:00:00 2001 From: Basile Clement Date: Fri, 27 May 2016 01:06:04 +0200 Subject: [PATCH 02/13] Revert "Affiche la debug-toolbar dans Vagrant" This reverts commit 3074071dffb42bef7dd08cf67eab642d1507bb15. --- cof/settings_dev.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/cof/settings_dev.py b/cof/settings_dev.py index d51f6ec2..b83f09bc 100644 --- a/cof/settings_dev.py +++ b/cof/settings_dev.py @@ -148,18 +148,3 @@ AUTHENTICATION_BACKENDS = ( RECAPTCHA_PUBLIC_KEY = "DUMMY" RECAPTCHA_PRIVATE_KEY = "DUMMY" RECAPTCHA_USE_SSL = True - -# On ne veut pas la vérification de INTERNAL_IPS faite par la debug-toolbar car -# cela interfère avec l'utilisation de Vagrant. En effet, l'adresse de la -# machine physique n'est pas forcément connue, et peut difficilement être mise -# dans les INTERNAL_IPS. -def show_toolbar(request): - if not DEBUG: - return False - if request.is_ajax(): - return False - return True - -DEBUG_TOOLBAR_CONFIG = { - 'SHOW_TOOLBAR_CALLBACK': show_toolbar, -} From 7f18b2f6980c20b97f4d7f32a609304ca6ff9f40 Mon Sep 17 00:00:00 2001 From: Basile Clement Date: Fri, 27 May 2016 01:04:35 +0200 Subject: [PATCH 03/13] Affiche la debug-toolbar dans Vagrant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ce patch enlève la vérification faite par django-debug-toolbar pour ne s'afficher que si l'IP source est dans l'option de configuration INTERNAL_IPS. Ceci permet son fonctionnement avec Vagrant. Fixes #8. --- cof/settings_dev.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cof/settings_dev.py b/cof/settings_dev.py index b83f09bc..d51f6ec2 100644 --- a/cof/settings_dev.py +++ b/cof/settings_dev.py @@ -148,3 +148,18 @@ AUTHENTICATION_BACKENDS = ( RECAPTCHA_PUBLIC_KEY = "DUMMY" RECAPTCHA_PRIVATE_KEY = "DUMMY" RECAPTCHA_USE_SSL = True + +# On ne veut pas la vérification de INTERNAL_IPS faite par la debug-toolbar car +# cela interfère avec l'utilisation de Vagrant. En effet, l'adresse de la +# machine physique n'est pas forcément connue, et peut difficilement être mise +# dans les INTERNAL_IPS. +def show_toolbar(request): + if not DEBUG: + return False + if request.is_ajax(): + return False + return True + +DEBUG_TOOLBAR_CONFIG = { + 'SHOW_TOOLBAR_CALLBACK': show_toolbar, +} From bf59d91613716ffbf3dcae709601285f4eb7a74a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Fri, 27 May 2016 17:52:02 +0200 Subject: [PATCH 04/13] =?UTF-8?q?D=C3=A9place=20les=20formulaires=20vers?= =?UTF-8?q?=20des=20`forms.py`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Les formulaires de chaque application sont désormais dans un fichier `forms.py`. --- bda/forms.py | 39 ++++++ bda/views.py | 39 +----- bda2/forms.py | 39 ++++++ bda2/views.py | 36 +----- bda3/forms.py | 39 ++++++ bda3/views.py | 36 +----- gestioncof/forms.py | 294 +++++++++++++++++++++++++++++++++++++++++++ gestioncof/views.py | 295 +------------------------------------------- 8 files changed, 422 insertions(+), 395 deletions(-) create mode 100644 bda/forms.py create mode 100644 bda2/forms.py create mode 100644 bda3/forms.py create mode 100644 gestioncof/forms.py diff --git a/bda/forms.py b/bda/forms.py new file mode 100644 index 00000000..8a652296 --- /dev/null +++ b/bda/forms.py @@ -0,0 +1,39 @@ +# coding: utf-8 + +from django import forms +from django.forms.models import inlineformset_factory, BaseInlineFormSet +from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution + +class BaseBdaFormSet(BaseInlineFormSet): + def clean(self): + """Checks that no two articles have the same title.""" + super(BaseBdaFormSet, self).clean() + if any(self.errors): + # Don't bother validating the formset unless each form is valid on its own + return + spectacles = [] + for i in range(0, self.total_form_count()): + form = self.forms[i] + if not form.cleaned_data: + continue + spectacle = form.cleaned_data['spectacle'] + delete = form.cleaned_data['DELETE'] + if not delete and spectacle in spectacles: + raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.") + spectacles.append(spectacle) + +class TokenForm(forms.Form): + token = forms.CharField(widget = forms.widgets.Textarea()) + +class SpectacleModelChoiceField(forms.ModelChoiceField): + def label_from_instance(self, obj): + return u"%s le %s (%s) à %.02f€" % (obj.title, obj.date_no_seconds(), obj.location, obj.price) + +class ResellForm(forms.Form): + count = forms.ChoiceField(choices = (("1","1"),("2","2"),)) + spectacle = SpectacleModelChoiceField(queryset = Spectacle.objects.none()) + + def __init__(self, participant, *args, **kwargs): + super(ResellForm, self).__init__(*args, **kwargs) + self.fields['spectacle'].queryset = participant.attributions.all().distinct() + diff --git a/bda/views.py b/bda/views.py index 78ac0c83..f46f468a 100644 --- a/bda/views.py +++ b/bda/views.py @@ -5,8 +5,6 @@ from django.shortcuts import render, get_object_or_404 from django.contrib.auth.decorators import login_required from django.db import models from django.http import Http404 -from django import forms -from django.forms.models import inlineformset_factory, BaseInlineFormSet from django.core import serializers import hashlib @@ -20,23 +18,7 @@ from gestioncof.shared import send_custom_mail from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution from bda.algorithm import Algorithm -class BaseBdaFormSet(BaseInlineFormSet): - def clean(self): - """Checks that no two articles have the same title.""" - super(BaseBdaFormSet, self).clean() - if any(self.errors): - # Don't bother validating the formset unless each form is valid on its own - return - spectacles = [] - for i in range(0, self.total_form_count()): - form = self.forms[i] - if not form.cleaned_data: - continue - spectacle = form.cleaned_data['spectacle'] - delete = form.cleaned_data['DELETE'] - if not delete and spectacle in spectacles: - raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.") - spectacles.append(spectacle) +from bda.forms import BaseBdaFormSet, TokenForm, ResellForm @cof_required def etat_places(request): @@ -117,7 +99,7 @@ def places_ics(request): @cof_required def inscription(request): - if datetime.now() > datetime(2015, 10, 4, 12, 00) and request.user.username != "seguin": + if datetime.now() > datetime(2015, 10, 4, 12, 00): participant, created = Participant.objects.get_or_create(user = request.user) choices = participant.choixspectacle_set.order_by("priority").all() return render(request, "resume_inscription.html", {"error_title": "C'est fini !", "error_description": u"Tirage au sort dans la journée !", "choices": choices}) @@ -207,9 +189,6 @@ def do_tirage(request): else: return render(request, "bda-attrib.html", data) -class TokenForm(forms.Form): - token = forms.CharField(widget = forms.widgets.Textarea()) - @login_required def tirage(request): if request.POST: @@ -220,18 +199,6 @@ def tirage(request): form = TokenForm() return render(request, "bda-token.html", {"form": form}) -class SpectacleModelChoiceField(forms.ModelChoiceField): - def label_from_instance(self, obj): - return u"%s le %s (%s) à %.02f€" % (obj.title, obj.date_no_seconds(), obj.location, obj.price) - -class ResellForm(forms.Form): - count = forms.ChoiceField(choices = (("1","1"),("2","2"),)) - spectacle = SpectacleModelChoiceField(queryset = Spectacle.objects.none()) - - def __init__(self, participant, *args, **kwargs): - super(ResellForm, self).__init__(*args, **kwargs) - self.fields['spectacle'].queryset = participant.attributions.all().distinct() - def do_resell(request, form): spectacle = form.cleaned_data["spectacle"] count = form.cleaned_data["count"] @@ -287,4 +254,4 @@ def liste_spectacles_ics(request): for spectacle in spectacles: spectacle.dtend = spectacle.date + timedelta(seconds=7200) return render(request, "liste_spectacles.ics", - {"spectacles": spectacles}, content_type="text/calendar") \ No newline at end of file + {"spectacles": spectacles}, content_type="text/calendar") diff --git a/bda2/forms.py b/bda2/forms.py new file mode 100644 index 00000000..930e184a --- /dev/null +++ b/bda2/forms.py @@ -0,0 +1,39 @@ +# coding: utf-8 + +from django import forms +from django.forms.models import inlineformset_factory, BaseInlineFormSet +from bda2.models import Spectacle, Participant, ChoixSpectacle, Attribution + +class BaseBdaFormSet(BaseInlineFormSet): + def clean(self): + """Checks that no two articles have the same title.""" + super(BaseBdaFormSet, self).clean() + if any(self.errors): + # Don't bother validating the formset unless each form is valid on its own + return + spectacles = [] + for i in range(0, self.total_form_count()): + form = self.forms[i] + if not form.cleaned_data: + continue + spectacle = form.cleaned_data['spectacle'] + delete = form.cleaned_data['DELETE'] + if not delete and spectacle in spectacles: + raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.") + spectacles.append(spectacle) + +class TokenForm(forms.Form): + token = forms.CharField(widget = forms.widgets.Textarea()) + +class SpectacleModelChoiceField(forms.ModelChoiceField): + def label_from_instance(self, obj): + return u"%s le %s (%s) à %.02f€" % (obj.title, obj.date_no_seconds(), obj.location, obj.price) + +class ResellForm(forms.Form): + count = forms.ChoiceField(choices = (("1","1"),("2","2"),)) + spectacle = SpectacleModelChoiceField(queryset = Spectacle.objects.none()) + + def __init__(self, participant, *args, **kwargs): + super(ResellForm, self).__init__(*args, **kwargs) + self.fields['spectacle'].queryset = participant.attributions.all().distinct() + diff --git a/bda2/views.py b/bda2/views.py index 93d54f62..6e19c7bb 100644 --- a/bda2/views.py +++ b/bda2/views.py @@ -5,8 +5,6 @@ from django.shortcuts import render, get_object_or_404 from django.contrib.auth.decorators import login_required from django.db import models from django.http import Http404 -from django import forms -from django.forms.models import inlineformset_factory, BaseInlineFormSet from django.core import serializers import hashlib @@ -18,24 +16,7 @@ import time from gestioncof.decorators import cof_required, buro_required from bda2.models import Spectacle, Participant, ChoixSpectacle, Attribution from bda2.algorithm import Algorithm - -class BaseBdaFormSet(BaseInlineFormSet): - def clean(self): - """Checks that no two articles have the same title.""" - super(BaseBdaFormSet, self).clean() - if any(self.errors): - # Don't bother validating the formset unless each form is valid on its own - return - spectacles = [] - for i in range(0, self.total_form_count()): - form = self.forms[i] - if not form.cleaned_data: - continue - spectacle = form.cleaned_data['spectacle'] - delete = form.cleaned_data['DELETE'] - if not delete and spectacle in spectacles: - raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.") - spectacles.append(spectacle) +from bda2.forms import BaseBdaFormSet, TokenForm, ResellForm @cof_required def etat_places(request): @@ -185,9 +166,6 @@ def do_tirage(request): else: return render(request, "bda-attrib.html", data) -class TokenForm(forms.Form): - token = forms.CharField(widget = forms.widgets.Textarea()) - @login_required def tirage(request): if request.POST: @@ -198,18 +176,6 @@ def tirage(request): form = TokenForm() return render(request, "bda-token.html", {"form": form}) -class SpectacleModelChoiceField(forms.ModelChoiceField): - def label_from_instance(self, obj): - return u"%s le %s (%s) à %.02f€" % (obj.title, obj.date_no_seconds(), obj.location, obj.price) - -class ResellForm(forms.Form): - count = forms.ChoiceField(choices = (("1","1"),("2","2"),)) - spectacle = SpectacleModelChoiceField(queryset = Spectacle.objects.none()) - - def __init__(self, participant, *args, **kwargs): - super(ResellForm, self).__init__(*args, **kwargs) - self.fields['spectacle'].queryset = participant.attributions.all().distinct() - def do_resell(request, form): spectacle = form.cleaned_data["spectacle"] count = form.cleaned_data["count"] diff --git a/bda3/forms.py b/bda3/forms.py new file mode 100644 index 00000000..616c96b1 --- /dev/null +++ b/bda3/forms.py @@ -0,0 +1,39 @@ +# coding: utf-8 + +from django import forms +from django.forms.models import inlineformset_factory, BaseInlineFormSet +from bda3.models import Spectacle, Participant, ChoixSpectacle, Attribution + +class BaseBdaFormSet(BaseInlineFormSet): + def clean(self): + """Checks that no two articles have the same title.""" + super(BaseBdaFormSet, self).clean() + if any(self.errors): + # Don't bother validating the formset unless each form is valid on its own + return + spectacles = [] + for i in range(0, self.total_form_count()): + form = self.forms[i] + if not form.cleaned_data: + continue + spectacle = form.cleaned_data['spectacle'] + delete = form.cleaned_data['DELETE'] + if not delete and spectacle in spectacles: + raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.") + spectacles.append(spectacle) + +class TokenForm(forms.Form): + token = forms.CharField(widget = forms.widgets.Textarea()) + +class SpectacleModelChoiceField(forms.ModelChoiceField): + def label_from_instance(self, obj): + return u"%s le %s (%s) à %.02f€" % (obj.title, obj.date_no_seconds(), obj.location, obj.price) + +class ResellForm(forms.Form): + count = forms.ChoiceField(choices = (("1","1"),("2","2"),)) + spectacle = SpectacleModelChoiceField(queryset = Spectacle.objects.none()) + + def __init__(self, participant, *args, **kwargs): + super(ResellForm, self).__init__(*args, **kwargs) + self.fields['spectacle'].queryset = participant.attributions.all().distinct() + diff --git a/bda3/views.py b/bda3/views.py index 620f1824..5c237b5d 100644 --- a/bda3/views.py +++ b/bda3/views.py @@ -6,8 +6,6 @@ from django.shortcuts import render, get_object_or_404 from django.contrib.auth.decorators import login_required from django.db import models from django.http import Http404 -from django import forms -from django.forms.models import inlineformset_factory, BaseInlineFormSet from django.core import serializers import hashlib @@ -19,24 +17,7 @@ import time from gestioncof.decorators import cof_required, buro_required from bda3.models import Spectacle, Participant, ChoixSpectacle, Attribution from bda3.algorithm import Algorithm - -class BaseBdaFormSet(BaseInlineFormSet): - def clean(self): - """Checks that no two articles have the same title.""" - super(BaseBdaFormSet, self).clean() - if any(self.errors): - # Don't bother validating the formset unless each form is valid on its own - return - spectacles = [] - for i in range(0, self.total_form_count()): - form = self.forms[i] - if not form.cleaned_data: - continue - spectacle = form.cleaned_data['spectacle'] - delete = form.cleaned_data['DELETE'] - if not delete and spectacle in spectacles: - raise forms.ValidationError("Vous ne pouvez pas vous inscrire deux fois pour le même spectacle.") - spectacles.append(spectacle) +from bda3.forms import BaseBdaFormSet, TokenForm, ResellForm @cof_required def etat_places(request): @@ -186,9 +167,6 @@ def do_tirage(request): else: return render(request, "bda-attrib.html", data) -class TokenForm(forms.Form): - token = forms.CharField(widget = forms.widgets.Textarea()) - @login_required def tirage(request): if request.POST: @@ -199,18 +177,6 @@ def tirage(request): form = TokenForm() return render(request, "bda-token.html", {"form": form}) -class SpectacleModelChoiceField(forms.ModelChoiceField): - def label_from_instance(self, obj): - return u"%s le %s (%s) à %.02f€" % (obj.title, obj.date_no_seconds(), obj.location, obj.price) - -class ResellForm(forms.Form): - count = forms.ChoiceField(choices = (("1","1"),("2","2"),)) - spectacle = SpectacleModelChoiceField(queryset = Spectacle.objects.none()) - - def __init__(self, participant, *args, **kwargs): - super(ResellForm, self).__init__(*args, **kwargs) - self.fields['spectacle'].queryset = participant.attributions.all().distinct() - def do_resell(request, form): spectacle = form.cleaned_data["spectacle"] count = form.cleaned_data["count"] diff --git a/gestioncof/forms.py b/gestioncof/forms.py new file mode 100644 index 00000000..2f0f78ac --- /dev/null +++ b/gestioncof/forms.py @@ -0,0 +1,294 @@ +# coding: utf-8 + +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 gestioncof.models import CofProfile, EventCommentValue +from gestioncof.widgets import TriStateCheckbox +from gestioncof.shared import lock_table, unlock_table, send_custom_mail + +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 + +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) + 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=_(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', + '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", "mailing_bda_revente",) + +class RegistrationUserForm(forms.ModelForm): + def __init__(self, *args, **kw): + super(RegistrationUserForm, self).__init__(*args, **kw) + self.fields['username'].help_text = "" + + class Meta: + model = User + fields = ("username", "first_name", "last_name", "email") + +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", choices = STATUS_CHOICES, widget = RadioSelect) + + def __init__(self, *args, **kwargs): + event = kwargs.pop("event") + self.event = event + registration = kwargs.pop("current_registration", None) + current_choices = registration.options.all() if registration is not None else [] + paid = kwargs.pop("paid", None) + if paid == True: + kwargs["initial"] = {"status":"paid"} + elif paid == False: + kwargs["initial"] = {"status":"wait"} + else: + kwargs["initial"] = {"status":"no"} + super(AdminEventForm, self).__init__(*args, **kwargs) + choices = {} + comments = {} + 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 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 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) + diff --git a/gestioncof/views.py b/gestioncof/views.py index 8d99b071..7aa1d096 100644 --- a/gestioncof/views.py +++ b/gestioncof/views.py @@ -5,21 +5,20 @@ import unicodecsv from django.shortcuts import redirect, get_object_or_404, render from django.http import Http404, HttpResponse from django.core.urlresolvers import reverse -from django.contrib.auth.models import User 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 django.db.models import Max from django.contrib.auth.views import login as django_login_view -from gestioncof.models import Survey, SurveyQuestion, SurveyQuestionAnswer, SurveyAnswer -from gestioncof.models import Event, EventOption, EventOptionChoice, EventRegistration +from gestioncof.models import Survey, SurveyAnswer, SurveyQuestion, SurveyQuestionAnswer +from gestioncof.models import Event, EventRegistration, EventOption, EventOptionChoice from gestioncof.models import EventCommentField, EventCommentValue +from gestioncof.shared import send_custom_mail from gestioncof.models import CofProfile, Clipper from gestioncof.decorators import buro_required, cof_required -from gestioncof.widgets import TriStateCheckbox -from gestioncof.shared import lock_table, unlock_table, send_custom_mail +from gestioncof.forms import UserProfileForm, EventStatusFilterForm, \ + SurveyForm, SurveyStatusFilterForm, RegistrationUserForm, \ + RegistrationProfileForm, AdminEventForm, EventForm import re @@ -61,37 +60,6 @@ def logout(request): 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_'): @@ -156,44 +124,6 @@ def survey(request, survey_id): form = SurveyForm(survey = survey) return render(request, "survey.html", {"survey": survey, "form": form, "success": success, "deleted": deleted, "current_answer": current_answer}) -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) - def get_event_form_choices(event, form): all_choices = [] for option_id, choices_ids in form.choices(): @@ -246,71 +176,6 @@ def event(request, event_id): form = EventForm(event = event) return render(request, "event.html", {"event": event, "form": form, "success": success}) -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) - 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) - def clean_post_for_status(initial): d = initial.copy() for k, v in d.items(): @@ -377,34 +242,6 @@ def survey_status(request, survey_id): answers_count[answer.id] += 1 return render(request, "survey_status.html", {"survey": survey, "user_answers": user_answers, "questions": questions, "answers_count": answers_count, "form": form}) -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', - '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", "mailing_bda_revente",) - @login_required def profile(request): success = False @@ -417,56 +254,6 @@ def profile(request): form = UserProfileForm(instance = request.user.profile) return render(request, "profile.html", {"form": form, "success": success}) -class RegistrationUserForm(forms.ModelForm): - def __init__(self, *args, **kw): - super(RegistrationUserForm, self).__init__(*args, **kw) - self.fields['username'].help_text = "" - - class Meta: - model = User - fields = ("username", "first_name", "last_name", "email") - -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") - def registration_set_ro_fields(user_form, profile_form): user_form.fields['username'].widget.attrs['readonly'] = True profile_form.fields['login_clipper'].widget.attrs['readonly'] = True @@ -506,76 +293,6 @@ def registration_form(request, login_clipper = None, username = None): profile_form = RegistrationProfileForm() return render(request, "registration_form.html", {"user_form": user_form, "profile_form": profile_form, "member": member, "login_clipper": login_clipper}) -STATUS_CHOICES = (('no','Non'), - ('wait','Oui mais attente paiement'), - ('paid','Oui payé'),) -class AdminEventForm(forms.Form): - status = forms.ChoiceField(label = "Inscription", choices = STATUS_CHOICES, widget = RadioSelect) - - def __init__(self, *args, **kwargs): - event = kwargs.pop("event") - self.event = event - registration = kwargs.pop("current_registration", None) - current_choices = registration.options.all() if registration is not None else [] - paid = kwargs.pop("paid", None) - if paid == True: - kwargs["initial"] = {"status":"paid"} - elif paid == False: - kwargs["initial"] = {"status":"wait"} - else: - kwargs["initial"] = {"status":"no"} - super(AdminEventForm, self).__init__(*args, **kwargs) - choices = {} - comments = {} - 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 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 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) - @buro_required def registration_form2(request, login_clipper = None, username = None): events = Event.objects.filter(old = False).all() From 86cf0973c21751f39008663959ed0d0a09600427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 28 May 2016 23:54:21 +0200 Subject: [PATCH 05/13] Corrige un oubli --- gestioncof/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gestioncof/views.py b/gestioncof/views.py index 7aa1d096..307c69c6 100644 --- a/gestioncof/views.py +++ b/gestioncof/views.py @@ -6,9 +6,9 @@ from django.shortcuts import redirect, get_object_or_404, render from django.http import Http404, HttpResponse from django.core.urlresolvers import reverse from django.contrib.auth.decorators import login_required -from django import forms from django.db.models import Max from django.contrib.auth.views import login as django_login_view +from django.contrib.auth.models import User from gestioncof.models import Survey, SurveyAnswer, SurveyQuestion, SurveyQuestionAnswer from gestioncof.models import Event, EventRegistration, EventOption, EventOptionChoice From 6f8f6289badf19d3d89491a9463c14d6810fa241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 28 May 2016 23:56:29 +0200 Subject: [PATCH 06/13] =?UTF-8?q?R=C3=A9pare=20les=20liens=20vers=20les=20?= =?UTF-8?q?images=20dans=20les=20events?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gestioncof/templates/tristate_js.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gestioncof/templates/tristate_js.html b/gestioncof/templates/tristate_js.html index 17b2d09a..af906ebe 100644 --- a/gestioncof/templates/tristate_js.html +++ b/gestioncof/templates/tristate_js.html @@ -2,9 +2,9 @@