Non-COF users can now edit their own profile Contrary to COF users they cannot change their mailing list settings
460 lines
16 KiB
Python
460 lines
16 KiB
Python
from django import forms
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib.auth.forms import AuthenticationForm
|
|
from django.forms.formsets import BaseFormSet, formset_factory
|
|
from django.forms.widgets import CheckboxSelectMultiple, RadioSelect
|
|
from django.utils.translation import ugettext_lazy as _
|
|
from djconfig.forms import ConfigForm
|
|
|
|
from bda.models import Spectacle
|
|
from gestioncof.models import CalendarSubscription, Club, CofProfile, EventCommentValue
|
|
from gestioncof.widgets import TriStateCheckbox
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class ExteAuthenticationForm(AuthenticationForm):
|
|
"""
|
|
Formulaire pour l'authentification des extés : renvoie une erreur si la personne
|
|
qui essaie de s'authentifier n'a pas de mot de passe. L'erreur dépend de si la
|
|
personne a un login clipper ou non.
|
|
"""
|
|
|
|
def clean(self):
|
|
username = self.cleaned_data.get("username")
|
|
|
|
if username is not None:
|
|
try:
|
|
user = User.objects.get(username=username)
|
|
if not user.has_usable_password() or user.password in ("", "!"):
|
|
profile, created = CofProfile.objects.get_or_create(user=user)
|
|
if profile.login_clipper:
|
|
raise forms.ValidationError(
|
|
_("L'utilisateur·ice a un login clipper !"),
|
|
code="has_clipper",
|
|
)
|
|
else:
|
|
raise forms.ValidationError(
|
|
_("L'utilisateur·ice n'a pas de mot de passe"),
|
|
code="no_password",
|
|
)
|
|
except User.DoesNotExist:
|
|
pass
|
|
|
|
return super().clean()
|
|
|
|
|
|
class EventForm(forms.Form):
|
|
def __init__(self, *args, **kwargs):
|
|
event = kwargs.pop("event")
|
|
self.event = event
|
|
current_choices = kwargs.pop("current_choices", None)
|
|
super().__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().__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().__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().__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 UserForm(forms.ModelForm):
|
|
class Meta:
|
|
model = User
|
|
fields = ["first_name", "last_name", "email"]
|
|
|
|
|
|
class PhoneForm(forms.ModelForm):
|
|
class Meta:
|
|
model = CofProfile
|
|
fields = ["phone"]
|
|
|
|
|
|
class ProfileForm(forms.ModelForm):
|
|
class Meta:
|
|
model = CofProfile
|
|
fields = [
|
|
"phone",
|
|
"mailing_cof",
|
|
"mailing_bda",
|
|
"mailing_bda_revente",
|
|
"mailing_unernestaparis",
|
|
]
|
|
|
|
|
|
class RegistrationUserForm(forms.ModelForm):
|
|
def __init__(self, *args, **kw):
|
|
super().__init__(*args, **kw)
|
|
self.fields["username"].help_text = ""
|
|
|
|
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().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().__init__(*args, **kw)
|
|
self.fields["mailing_cof"].initial = True
|
|
self.fields["mailing_bda"].initial = True
|
|
self.fields["mailing_bda_revente"].initial = True
|
|
self.fields["mailing_unernestaparis"].initial = True
|
|
|
|
self.fields.keyOrder = [
|
|
"login_clipper",
|
|
"phone",
|
|
"occupation",
|
|
"departement",
|
|
"is_cof",
|
|
"type_cotiz",
|
|
"mailing_cof",
|
|
"mailing_bda",
|
|
"mailing_bda_revente",
|
|
"mailing_unernestaparis",
|
|
"comments",
|
|
]
|
|
|
|
class Meta:
|
|
model = CofProfile
|
|
fields = (
|
|
"login_clipper",
|
|
"phone",
|
|
"occupation",
|
|
"departement",
|
|
"is_cof",
|
|
"type_cotiz",
|
|
"mailing_cof",
|
|
"mailing_bda",
|
|
"mailing_bda_revente",
|
|
"mailing_unernestaparis",
|
|
"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().__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().__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()._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", required=False
|
|
)
|
|
subscribe_to_my_shows = forms.BooleanField(
|
|
initial=True,
|
|
label="Les spectacles pour lesquels j'ai obtenu une place",
|
|
required=False,
|
|
)
|
|
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,
|
|
)
|
|
|
|
|
|
# ---
|
|
# Announcements banner
|
|
# TODO: move this to the `gestion` app once the supportBDS branch is merged
|
|
# ---
|
|
|
|
|
|
class GestioncofConfigForm(ConfigForm):
|
|
gestion_banner = forms.CharField(
|
|
label=_("Announcements banner"),
|
|
help_text=_("An empty banner disables annoucements"),
|
|
max_length=2048,
|
|
)
|