2021-01-21 20:32:36 +01:00
|
|
|
import csv
|
|
|
|
|
2020-07-06 23:40:56 +02:00
|
|
|
from django.contrib import messages
|
|
|
|
from django.contrib.auth import get_user_model
|
2021-01-21 20:32:36 +01:00
|
|
|
from django.contrib.auth.decorators import permission_required
|
2021-01-27 22:25:58 +01:00
|
|
|
from django.contrib.auth.models import Permission
|
2021-01-21 20:32:36 +01:00
|
|
|
from django.http import HttpResponse
|
2020-07-06 23:40:56 +02:00
|
|
|
from django.shortcuts import get_object_or_404
|
2020-08-24 16:35:07 +02:00
|
|
|
from django.urls import reverse, reverse_lazy
|
2020-07-06 23:40:56 +02:00
|
|
|
from django.utils.translation import gettext_lazy as _
|
2021-10-26 10:26:22 +02:00
|
|
|
from django.views.generic import DeleteView, ListView, RedirectView, TemplateView
|
2020-06-05 17:02:16 +02:00
|
|
|
|
|
|
|
from bds.autocomplete import bds_search
|
2020-07-21 14:49:37 +02:00
|
|
|
from bds.forms import ProfileForm, UserForm, UserFromClipperForm, UserFromScratchForm
|
2020-07-21 14:49:10 +02:00
|
|
|
from bds.mixins import MultipleFormView, StaffRequiredMixin
|
2020-08-28 18:18:54 +02:00
|
|
|
from bds.models import BDSProfile
|
2020-07-01 22:29:07 +02:00
|
|
|
from shared.views import AutocompleteView
|
2020-06-05 17:02:16 +02:00
|
|
|
|
2020-07-06 23:40:56 +02:00
|
|
|
User = get_user_model()
|
|
|
|
|
2020-06-05 17:02:16 +02:00
|
|
|
|
2020-07-01 22:29:07 +02:00
|
|
|
class BDSAutocompleteView(StaffRequiredMixin, AutocompleteView):
|
2020-06-05 17:02:16 +02:00
|
|
|
template_name = "bds/search_results.html"
|
2020-07-01 22:29:07 +02:00
|
|
|
search_composer = bds_search
|
2020-06-07 20:58:33 +02:00
|
|
|
|
|
|
|
|
2020-06-07 21:01:54 +02:00
|
|
|
class Home(StaffRequiredMixin, TemplateView):
|
2020-06-07 20:58:33 +02:00
|
|
|
template_name = "bds/home.html"
|
2020-07-06 23:40:56 +02:00
|
|
|
|
2020-08-28 18:18:54 +02:00
|
|
|
def get_context_data(self, **kwargs):
|
|
|
|
context = super().get_context_data(**kwargs)
|
|
|
|
context["member_count"] = BDSProfile.objects.filter(is_member=True).count()
|
2021-10-26 10:26:22 +02:00
|
|
|
context["nb_expired"] = BDSProfile.expired_members().count()
|
2020-08-28 18:18:54 +02:00
|
|
|
return context
|
|
|
|
|
2020-07-06 23:40:56 +02:00
|
|
|
|
2020-07-21 14:49:10 +02:00
|
|
|
class UserUpdateView(StaffRequiredMixin, MultipleFormView):
|
2020-07-06 23:40:56 +02:00
|
|
|
template_name = "bds/user_update.html"
|
|
|
|
|
2020-07-21 14:49:10 +02:00
|
|
|
form_classes = {
|
|
|
|
"user": UserForm,
|
|
|
|
"profile": ProfileForm,
|
|
|
|
}
|
2020-07-06 23:40:56 +02:00
|
|
|
|
2021-01-27 22:25:58 +01:00
|
|
|
def get_user_initial(self):
|
|
|
|
return {"is_buro": self.get_user_instance().has_perm("bds.is_team")}
|
|
|
|
|
2020-07-21 14:49:10 +02:00
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
self.user = get_object_or_404(User, pk=self.kwargs["pk"])
|
|
|
|
return super().dispatch(request, *args, **kwargs)
|
2020-07-06 23:40:56 +02:00
|
|
|
|
2020-07-21 14:49:10 +02:00
|
|
|
def get_user_instance(self):
|
|
|
|
return self.user
|
2020-07-06 23:40:56 +02:00
|
|
|
|
2020-07-21 14:49:10 +02:00
|
|
|
def get_profile_instance(self):
|
|
|
|
return getattr(self.user, "bds", None)
|
2020-07-06 23:40:56 +02:00
|
|
|
|
2020-07-21 14:49:10 +02:00
|
|
|
def get_success_url(self):
|
|
|
|
return reverse("bds:user.update", args=(self.user.pk,))
|
2020-07-06 23:40:56 +02:00
|
|
|
|
2020-07-21 14:49:10 +02:00
|
|
|
def form_valid(self, forms):
|
|
|
|
user = forms["user"].save()
|
|
|
|
profile = forms["profile"].save(commit=False)
|
2021-01-27 22:25:58 +01:00
|
|
|
perm = Permission.objects.get(content_type__app_label="bds", codename="is_team")
|
|
|
|
if forms["user"].cleaned_data["is_buro"]:
|
|
|
|
user.user_permissions.add(perm)
|
|
|
|
else:
|
|
|
|
user.user_permissions.remove(perm)
|
2020-07-21 14:49:10 +02:00
|
|
|
profile.user = user
|
|
|
|
profile.save()
|
|
|
|
messages.success(self.request, _("Profil mis à jour avec succès !"))
|
2020-07-06 23:40:56 +02:00
|
|
|
|
2020-07-21 14:49:10 +02:00
|
|
|
return super().form_valid(forms)
|
2020-07-06 23:40:56 +02:00
|
|
|
|
2020-07-21 14:49:10 +02:00
|
|
|
def form_invalid(self, forms):
|
|
|
|
messages.error(self.request, _("Veuillez corriger les erreurs ci-dessous"))
|
|
|
|
return super().form_invalid(forms)
|
2020-07-21 14:49:37 +02:00
|
|
|
|
|
|
|
|
|
|
|
class UserCreateView(StaffRequiredMixin, MultipleFormView):
|
|
|
|
template_name = "bds/user_create.html"
|
|
|
|
|
|
|
|
def get_form_classes(self):
|
|
|
|
profile_class = ProfileForm
|
|
|
|
|
|
|
|
if "clipper" in self.kwargs:
|
|
|
|
user_class = UserFromClipperForm
|
|
|
|
else:
|
|
|
|
user_class = UserFromScratchForm
|
|
|
|
|
|
|
|
return {"user": user_class, "profile": profile_class}
|
|
|
|
|
|
|
|
def get_user_initial(self):
|
|
|
|
if "clipper" in self.kwargs:
|
|
|
|
clipper = self.kwargs["clipper"]
|
2020-08-03 14:30:21 +02:00
|
|
|
email = self.request.GET.get("mail", "{}@clipper.ens.fr".format(clipper))
|
2020-07-21 14:49:37 +02:00
|
|
|
fullname = self.request.GET.get("fullname", None)
|
|
|
|
|
|
|
|
if fullname:
|
|
|
|
# Heuristique : le premier mot est le prénom
|
|
|
|
first_name = fullname.split()[0]
|
|
|
|
last_name = " ".join(fullname.split()[1:])
|
|
|
|
else:
|
|
|
|
first_name = ""
|
|
|
|
last_name = ""
|
|
|
|
|
2020-07-26 22:24:41 +02:00
|
|
|
return {
|
|
|
|
"username": clipper,
|
|
|
|
"email": email,
|
|
|
|
"first_name": first_name,
|
|
|
|
"last_name": last_name,
|
|
|
|
}
|
2020-07-06 23:40:56 +02:00
|
|
|
else:
|
2020-07-21 14:49:37 +02:00
|
|
|
return {}
|
2020-07-06 23:40:56 +02:00
|
|
|
|
2020-07-21 14:49:37 +02:00
|
|
|
def get_success_url(self):
|
|
|
|
return reverse("bds:user.update", args=(self.user.pk,))
|
|
|
|
|
|
|
|
def form_valid(self, forms):
|
|
|
|
# On redéfinit self.user pour get_success_url
|
|
|
|
self.user = forms["user"].save()
|
|
|
|
profile = forms["profile"].save(commit=False)
|
|
|
|
profile.user = self.user
|
|
|
|
profile.save()
|
|
|
|
messages.success(self.request, _("Profil créé avec succès !"))
|
|
|
|
|
|
|
|
return super().form_valid(forms)
|
|
|
|
|
|
|
|
def form_invalid(self, forms):
|
|
|
|
messages.error(self.request, _("Veuillez corriger les erreurs ci-dessous"))
|
|
|
|
return super().form_invalid(forms)
|
2020-08-24 16:35:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
class UserDeleteView(StaffRequiredMixin, DeleteView):
|
|
|
|
model = User
|
|
|
|
success_url = reverse_lazy("bds:home")
|
|
|
|
success_message = "Profil supprimé avec succès !"
|
|
|
|
|
|
|
|
def delete(self, request, *args, **kwargs):
|
|
|
|
# SuccessMessageMixin does not work with DeleteView, see :
|
|
|
|
# https://code.djangoproject.com/ticket/21926
|
|
|
|
messages.success(request, self.success_message)
|
|
|
|
|
|
|
|
return super().delete(request, *args, **kwargs)
|
2021-01-21 20:32:36 +01:00
|
|
|
|
|
|
|
|
2021-10-26 10:26:22 +02:00
|
|
|
class ResetMembershipListView(StaffRequiredMixin, ListView):
|
|
|
|
model = BDSProfile
|
|
|
|
template_name = "bds/expired_members.html"
|
|
|
|
|
|
|
|
def get_queryset(self):
|
|
|
|
return BDSProfile.expired_members()
|
|
|
|
|
|
|
|
|
|
|
|
class ResetMembershipView(StaffRequiredMixin, RedirectView):
|
|
|
|
url = reverse_lazy("bds:members.expired")
|
|
|
|
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
|
|
qs = BDSProfile.expired_members()
|
|
|
|
nb = qs.count()
|
|
|
|
|
|
|
|
qs.update(cotisation_period="NO", is_member=False, mails_bds=False)
|
|
|
|
|
|
|
|
messages.success(request, f"{nb} adhésions réinitialisées")
|
|
|
|
|
|
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
|
|
|
|
|
2021-01-21 20:32:36 +01:00
|
|
|
@permission_required("bds.is_team")
|
|
|
|
def export_members(request):
|
|
|
|
response = HttpResponse(content_type="text/csv")
|
|
|
|
response["Content-Disposition"] = "attachment; filename=membres_bds.csv"
|
|
|
|
|
|
|
|
writer = csv.writer(response)
|
|
|
|
for profile in BDSProfile.objects.filter(is_member=True).all():
|
|
|
|
user = profile.user
|
|
|
|
bits = [
|
|
|
|
user.username,
|
|
|
|
user.get_full_name(),
|
|
|
|
user.email,
|
|
|
|
]
|
|
|
|
writer.writerow([str(bit) for bit in bits])
|
|
|
|
|
|
|
|
return response
|