kpsul/gestioncof/views.py
Basile Clement fb16276ee3 Merge branch 'Kerl/fusion_bda' into 'master'
Kerl/fusion bda

Ce patch fusionne les trois applications `bda`, `bda2`, `bda3` existantes en une seule qui peut gérer autant de tirage que souhaité par le BdA.

Après avoir appliqué ce patch, il est nécessaire d'effectuer les migrations qui vont avec : `python manage.py migrate`

Fixes #3 

See merge request !17
2016-06-07 23:38:24 +02:00

523 lines
24 KiB
Python

# coding: utf-8
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.decorators import login_required
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 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.forms import UserProfileForm, EventStatusFilterForm, \
SurveyForm, SurveyStatusFilterForm, RegistrationUserForm, \
RegistrationProfileForm, AdminEventForm, EventForm
from bda.models import Tirage
import re
@login_required
def home(request):
data = {"surveys": Survey.objects.filter(old=False).all(),
"events": Event.objects.filter(old=False).all(),
"open_surveys": Survey.objects.filter(survey_open=True, old=False).all(),
"open_events": Event.objects.filter(registration_open=True, old=False).all(),
"open_tirages": Tirage.objects.filter(active=True).all()}
return render(request, "home.html", data)
def login(request):
if request.user.is_authenticated():
return redirect("gestioncof.views.home")
return render(request, "login_switch.html", {})
def login_ext(request):
if request.method == "POST" and "username" in request.POST:
try:
user = User.objects.get(username = request.POST["username"])
if not user.has_usable_password() or user.password in ("","!"):
profile, created = CofProfile.objects.get_or_create(user = user)
if profile.login_clipper:
return render(request, "error.html", {"error_type": "use_clipper_login"})
else:
return render(request, "error.html", {"error_type": "no_password"})
except User.DoesNotExist:
pass
return django_login_view(request, template_name = 'login.html')
@login_required
def logout(request):
try:
profile = request.user.profile
except CofProfile.DoesNotExist:
profile, created = CofProfile.objects.get_or_create(user = request.user)
if profile.login_clipper:
return redirect("django_cas_ng.views.logout")
else:
return redirect("django.contrib.auth.views.logout")
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(request, "survey.html", {"survey": survey, "form": form, "success": success, "deleted": deleted, "current_answer": current_answer})
def get_event_form_choices(event, form):
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)
return all_choices
def update_event_form_comments(event, form, registration):
for commentfield_id, value in form.comments():
field = get_object_or_404(EventCommentField, id = commentfield_id,
event = event)
if value == field.default:
continue
(storage, _) = EventCommentValue.objects.get_or_create(commentfield = field,
registration = registration)
storage.content = value
storage.save()
@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 = get_event_form_choices(event, form)
(current_registration, _) = EventRegistration.objects.get_or_create(user = request.user, event = event)
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(request, "event.html", {"event": event, "form": form, "success": success})
def clean_post_for_status(initial):
d = initial.copy()
for k, v in d.items():
if k.startswith("id_"):
del d[k]
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():
if option_id == "has_paid":
if value == "yes":
registrations_query = registrations_query.filter(paid = True)
elif value == "no":
registrations_query = registrations_query.filter(paid = False)
continue
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(request, "event_status.html", {"event": event, "user_choices": user_choices, "options": options, "choices_count": choices_count, "form": form})
@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(request, "survey_status.html", {"survey": survey, "user_answers": user_answers, "questions": questions, "answers_count": answers_count, "form": form})
@login_required
def profile(request):
success = False
if request.method == "POST":
form = UserProfileForm(request.POST, instance = request.user.profile)
if form.is_valid():
form.save()
success = True
else:
form = UserProfileForm(instance = request.user.profile)
return render(request, "profile.html", {"form": form, "success": success})
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
@buro_required
def registration_form(request, login_clipper = None, username = None):
member = None
if login_clipper:
clipper = get_object_or_404(Clipper, username = login_clipper)
try: # check if the given user is already registered
member = User.objects.filter(username = login_clipper).get()
username = member.username
login_clipper = None
except User.DoesNotExist:
# new user, but prefill
user_form = RegistrationUserForm()
profile_form = RegistrationProfileForm()
user_form.fields['username'].initial = login_clipper
user_form.fields['email'].initial = login_clipper + "@clipper.ens.fr"
profile_form.fields['login_clipper'].initial = login_clipper
if clipper.fullname:
bits = clipper.fullname.split(" ")
user_form.fields['first_name'].initial = bits[0]
if len(bits) > 1:
user_form.fields['last_name'].initial = " ".join(bits[1:])
registration_set_ro_fields(user_form, profile_form)
if username:
member = get_object_or_404(User, username = username)
(profile, _) = CofProfile.objects.get_or_create(user = member)
# already existing, prefill
user_form = RegistrationUserForm(instance = member)
profile_form = RegistrationProfileForm(instance = profile)
registration_set_ro_fields(user_form, profile_form)
elif not login_clipper:
# new user
user_form = RegistrationUserForm()
profile_form = RegistrationProfileForm()
return render(request, "registration_form.html", {"user_form": user_form, "profile_form": profile_form, "member": member, "login_clipper": login_clipper})
@buro_required
def registration_form2(request, login_clipper = None, username = None):
events = Event.objects.filter(old = False).all()
member = None
if login_clipper:
clipper = get_object_or_404(Clipper, username = login_clipper)
try: # check if the given user is already registered
member = User.objects.filter(username = login_clipper).get()
username = member.username
login_clipper = None
except User.DoesNotExist:
# new user, but prefill
user_form = RegistrationUserForm()
profile_form = RegistrationProfileForm()
event_forms = [AdminEventForm(event = event) for event in events]
user_form.fields['username'].initial = login_clipper
user_form.fields['email'].initial = login_clipper + "@clipper.ens.fr"
profile_form.fields['login_clipper'].initial = login_clipper
if clipper.fullname:
bits = clipper.fullname.split(" ")
user_form.fields['first_name'].initial = bits[0]
if len(bits) > 1:
user_form.fields['last_name'].initial = " ".join(bits[1:])
registration_set_ro_fields(user_form, profile_form)
if username:
member = get_object_or_404(User, username = username)
(profile, _) = CofProfile.objects.get_or_create(user = member)
# already existing, prefill
user_form = RegistrationUserForm(instance = member)
profile_form = RegistrationProfileForm(instance = profile)
registration_set_ro_fields(user_form, profile_form)
event_forms = []
for event in events:
try:
current_registration = EventRegistration.objects.get(user = member, event = event)
form = AdminEventForm(event = event, current_registration = current_registration, paid = current_registration.paid)
except EventRegistration.DoesNotExist:
form = AdminEventForm(event = event)
event_forms.append(form)
elif not login_clipper:
# new user
user_form = RegistrationUserForm()
profile_form = RegistrationProfileForm()
event_forms = [AdminEventForm(event = event) for event in events]
return render(request, "registration_form.html", {"user_form": user_form, "profile_form": profile_form, "member": member, "login_clipper": login_clipper, "event_forms": event_forms})
@buro_required
def registration(request):
if request.POST:
request_dict = request.POST.copy()
if "num" in request_dict:
del request_dict["num"]
success = False
user_form = RegistrationUserForm(request_dict)
profile_form = RegistrationProfileForm(request_dict)
events = Event.objects.filter(old = False).all()
event_forms = [AdminEventForm(request_dict, event = event) for event in events]
user_form.is_valid()
profile_form.is_valid()
for event_form in event_forms: event_form.is_valid()
member = None
login_clipper = None
if "user_exists" in request_dict and request_dict["user_exists"]:
username = request_dict["username"]
try:
member = User.objects.filter(username = username).get()
(profile, _) = CofProfile.objects.get_or_create(user = member)
user_form = RegistrationUserForm(request_dict, instance = member)
profile_form = RegistrationProfileForm(request_dict, instance = profile)
except User.DoesNotExist:
try:
clipper = Clipper.objects.filter(username = username).get()
login_clipper = clipper.username
except Clipper.DoesNotExist:
pass
for form in event_forms:
if not form.is_valid(): break
if form.cleaned_data['status'] == 'no': continue
all_choices = get_event_form_choices(form.event, form)
if user_form.is_valid() and profile_form.is_valid() and not any([not form.is_valid() for form in event_forms]):
member = user_form.save()
(profile, _) = CofProfile.objects.get_or_create(user = member)
was_cof = profile.is_cof
request_dict["num"] = profile.num
profile_form = RegistrationProfileForm(request_dict, instance = profile)
profile_form.is_valid()
profile_form.save()
(profile, _) = CofProfile.objects.get_or_create(user = member)
if profile.is_cof and not was_cof:
send_custom_mail(member, "bienvenue")
for form in event_forms:
if form.cleaned_data['status'] == 'no':
try:
current_registration = EventRegistration.objects.get(user = member, event = form.event)
current_registration.delete()
except EventRegistration.DoesNotExist:
pass
continue
all_choices = get_event_form_choices(form.event, form)
(current_registration, created_reg) = EventRegistration.objects.get_or_create(user = member, event = form.event)
update_event_form_comments(event, form, current_registration)
current_registration.options = all_choices
current_registration.paid = (form.cleaned_data['status'] == 'paid')
current_registration.save()
if event.title == "Mega 15" and created_reg:
field = EventCommentField.objects.get(event = event, name = "Commentaires")
try:
comments = EventCommentValue.objects.get(commentfield = field, registration = current_registration).content
except EventCommentValue.DoesNotExist:
comments = field.default
send_custom_mail(member, "mega", {"remarques": comments})
success = True
return render(request, "registration_post.html", {"success": success, "user_form": user_form, "profile_form": profile_form, "member": member, "login_clipper": login_clipper, "event_forms": event_forms})
else:
return render(request, "registration.html")
@buro_required
def export_members(request):
response = HttpResponse(content_type = 'text/csv')
response['Content-Disposition'] = 'attachment; filename=membres_cof.csv'
writer = unicodecsv.UnicodeWriter(response)
for profile in CofProfile.objects.filter(is_cof = True).all():
user = profile.user
bits = [profile.num, user.username, user.first_name, user.last_name, user.email, profile.phone, profile.occupation, profile.departement, profile.type_cotiz]
writer.writerow([unicode(bit) for bit in bits])
return response
@buro_required
def csv_export_mega(filename, qs):
response = HttpResponse(content_type = 'text/csv')
response['Content-Disposition'] = 'attachment; filename=' + filename
writer = unicodecsv.UnicodeWriter(response)
for reg in qs.all():
user = reg.user
profile = user.profile
comments = "---".join([comment.content for comment in reg.comments.all()])
bits = [user.username, user.first_name, user.last_name, user.email, profile.phone, profile.num, profile.comments if profile.comments else "", comments]
writer.writerow([unicode(bit) for bit in bits])
return response
@buro_required
def export_mega_remarksonly(request):
filename = 'remarques_mega_2015.csv'
response = HttpResponse(content_type = 'text/csv')
response['Content-Disposition'] = 'attachment; filename=' + filename
writer = unicodecsv.UnicodeWriter(response)
event = Event.objects.get(title = "Mega 15")
commentfield = event.commentfields.get(name = "Commentaires")
for val in commentfield.values.all():
reg = val.registration
user = reg.user
profile = user.profile
bits = [user.username, user.first_name, user.last_name, user.email, profile.phone, profile.num, profile.comments, val.content]
writer.writerow([unicode(bit) for bit in bits])
return response
@buro_required
def export_mega_bytype(request, type):
types = {"orga-actif": "Orga élève",
"orga-branleur": "Orga étudiant",
"conscrit-eleve": "Conscrit élève",
"conscrit-etudiant": "Conscrit étudiant"}
if type not in types:
raise Http404
event = Event.objects.get(title = "Mega 15")
type_option = event.options.get(name = "Type")
participant_type = type_option.choices.get(value = types[type]).id
qs = EventRegistration.objects.filter(event = event).filter(options__id__exact = participant_type)
return csv_export_mega(type + '_mega_2015.csv', qs)
@buro_required
def export_mega_orgas(request):
event = Event.objects.get(title = "Mega 15")
type_option = event.options.get(name = "Type")
participant_type_a = type_option.choices.get(value = "Conscrit étudiant").id
participant_type_b = type_option.choices.get(value = "Conscrit élève").id
qs = EventRegistration.objects.filter(event = event).exclude(options__id__in = (participant_type_a, participant_type_b))
return csv_export_mega('orgas_mega_15.csv', qs)
@buro_required
def export_mega_participants(request):
event = Event.objects.get(title = "Mega 15")
type_option = event.options.get(name = "Type")
participant_type_a = type_option.choices.get(value = "Conscrit étudiant").id
participant_type_b = type_option.choices.get(value = "Conscrit élève").id
qs = EventRegistration.objects.filter(event = event).filter(options__id__in = (participant_type_a, participant_type_b))
return csv_export_mega('participants_mega_15.csv', qs)
@buro_required
def export_mega(request):
event = Event.objects.filter(title = "Mega 15")
qs = EventRegistration.objects.filter(event = event).order_by("user__username")
return csv_export_mega('all_mega_2015.csv', qs)
@buro_required
def utile_cof(request):
return render(request, "utile_cof.html", {})
@buro_required
def utile_bda(request):
tirages = Tirage.objects.all()
return render(request, "utile_bda.html", {'tirages': tirages})
@buro_required
def liste_bdadiff(request):
titre = "BdA diffusion"
personnes = CofProfile.objects.filter(mailing_bda = True, is_cof = True).all()
return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes})
@buro_required
def liste_bdarevente(request):
titre = "BdA revente"
personnes = CofProfile.objects.filter(mailing_bda_revente = True, is_cof = True).all()
return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes})
@buro_required
def liste_diffcof(request):
titre = "Diffusion COF"
personnes = CofProfile.objects.filter(mailing_cof = True, is_cof = True).all()
return render(request, "liste_mails.html", {"titre": titre, "personnes": personnes})