import csv from django.contrib import messages from django.contrib.auth import get_user_model from django.contrib.auth.decorators import permission_required from django.contrib.auth.models import Permission from django.http import HttpResponse from django.shortcuts import get_object_or_404 from django.urls import reverse, reverse_lazy from django.utils.translation import gettext_lazy as _ from django.views.generic import DeleteView, ListView, RedirectView, TemplateView from bds.autocomplete import bds_search from bds.forms import ProfileForm, UserForm, UserFromClipperForm, UserFromScratchForm from bds.mixins import MultipleFormView, StaffRequiredMixin from bds.models import BDSProfile from shared.views import AutocompleteView User = get_user_model() class BDSAutocompleteView(StaffRequiredMixin, AutocompleteView): template_name = "bds/search_results.html" search_composer = bds_search class Home(StaffRequiredMixin, TemplateView): template_name = "bds/home.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["member_count"] = BDSProfile.objects.filter(is_member=True).count() context["nb_expired"] = BDSProfile.expired_members().count() return context class UserUpdateView(StaffRequiredMixin, MultipleFormView): template_name = "bds/user_update.html" form_classes = { "user": UserForm, "profile": ProfileForm, } def get_user_initial(self): return {"is_buro": self.get_user_instance().has_perm("bds.is_team")} def dispatch(self, request, *args, **kwargs): self.user = get_object_or_404(User, pk=self.kwargs["pk"]) return super().dispatch(request, *args, **kwargs) def get_user_instance(self): return self.user def get_profile_instance(self): return getattr(self.user, "bds", None) def get_success_url(self): return reverse("bds:user.update", args=(self.user.pk,)) def form_valid(self, forms): user = forms["user"].save() profile = forms["profile"].save(commit=False) 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) profile.user = user profile.save() messages.success(self.request, _("Profil mis à jour 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) 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"] email = self.request.GET.get("mail", "{}@clipper.ens.fr".format(clipper)) 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 = "" return { "username": clipper, "email": email, "first_name": first_name, "last_name": last_name, } else: return {} 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) 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) 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) @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