# Copyright (C) 2018-2025 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from datetime import date from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic import DetailView, UpdateView from django.utils.translation import gettext_lazy as _ from django_tables2 import SingleTableView from permission.backends import PermissionBackend from permission.views import ProtectQuerysetMixin, ProtectedCreateView from django.urls import reverse_lazy from .models import Family, Challenge, FamilyMembership, User from .tables import FamilyTable, ChallengeTable, FamilyMembershipTable from .forms import ChallengeUpdateForm, FamilyMembershipForm class FamilyCreateView(ProtectQuerysetMixin, ProtectedCreateView): """ Create family """ model = Family extra_context = {"title": _('Create family')} def get_sample_object(self): return Family( name="", description="Sample family", score=0, rank=0, ) class FamilyListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView): """ List existing Families """ model = Family table_class = FamilyTable extra_context = {"title": _('Families list')} class FamilyDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): """ Display details of a family """ model = Family context_object_name = "family" extra_context = {"title": _('Family detail')} def get_context_data(self, **kwargs): """ Add members list """ context = super().get_context_data(**kwargs) family = self.object # member list family_member = FamilyMembership.objects.filter( family=family, year=date.today().year, ).filter(PermissionBackend.filter_queryset(self.request, FamilyMembership, "view"))\ .order_by("user__username").distinct("user__username") membership_table = FamilyMembershipTable(data=family_member) context['member_list'] = membership_table # Check if the user has the right to create a membership, to display the button. empty_membership = FamilyMembership( family=family, user=User.objects.first(), year=date.today().year, ) context["can_add_members"] = PermissionBackend()\ .has_perm(self.request.user, "family.add_membership", empty_membership) return context class FamilyUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView): """ Update the information of a family. """ model = Family context_object_name = "family" extra_context = {"title": _('Update family')} class FamilyAddMemberView(ProtectQuerysetMixin, ProtectedCreateView): """ Add a membership to a family """ model = FamilyMembership form_class = FamilyMembershipForm template_name = 'family/add_member.html' extra_context = {"title": _("Add a new member to the family")} def get_sample_object(self): if "family_pk" in self.kwargs: family = Family.objects.get(pk=self.kwargs["family_pk"]) else: family = FamilyMembership.objects.get(pk=self.kwargs["pk"]).family return FamilyMembership( user=self.request.user, family=family, year=date.today().year, ) def get_success_url(self): return reverse_lazy('family:family_detail', kwargs={'pk': self.object.family.id}) class ChallengeCreateView(ProtectQuerysetMixin, ProtectedCreateView): """ Create challenge """ model = Challenge extra_context = {"title": _('Create challenge')} def get_sample_object(self): return Challenge( name="", description="Sample challenge", points=0, ) def get_success_url(self): return reverse_lazy('family:challenge_list') class ChallengeListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView): """ List all challenges """ model = Challenge table_class = ChallengeTable extra_context = {"title": _('Challenges list')} class ChallengeDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): """ Display details of a challenge """ model = Challenge context_object_name = "challenge" extra_context = {"title": _('Details of:')} def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) fields = ["name", "description", "points",] fields = dict([(field, getattr(self.object, field)) for field in fields]) context["fields"] = [( Challenge._meta.get_field(field).verbose_name.capitalize(), value) for field, value in fields.items()] context["obtained"] = self.object.obtained context["update"] = PermissionBackend.check_perm(self.request, "family.change_challenge") return context class ChallengeUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView): """ Update the information of a challenge """ model = Challenge context_object_name = "challenge" extra_context = {"title": _('Update challenge')} template_name = 'family/challenge_update.html' form_class = ChallengeUpdateForm def get_success_url(self, **kwargs): self.object.refresh_from_db() return reverse_lazy('family:challenge_detail', kwargs={'pk': self.object.pk})