mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-25 02:24:26 +00:00
clubs: Handle bulk add of users in clubs and refresh of the form handling
This commit is contained in:
parent
e8ee9122f9
commit
d5ad2c5141
@ -11,7 +11,7 @@
|
|||||||
<td>{% trans %}Since{% endtrans %}</td>
|
<td>{% trans %}Since{% endtrans %}</td>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for m in club.members.filter(end_date=None).order_by('-role').all() %}
|
{% for m in members %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ user_profile_link(m.user) }}</td>
|
<td>{{ user_profile_link(m.user) }}</td>
|
||||||
<td>{{ settings.SITH_CLUB_ROLES[m.role] }}</td>
|
<td>{{ settings.SITH_CLUB_ROLES[m.role] }}</td>
|
||||||
@ -30,6 +30,3 @@
|
|||||||
<p><input type="submit" value="{% trans %}Add{% endtrans %}" /></p>
|
<p><input type="submit" value="{% trans %}Add{% endtrans %}" /></p>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
132
club/views.py
132
club/views.py
@ -33,7 +33,7 @@ from django.core.urlresolvers import reverse, reverse_lazy
|
|||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.utils.translation import ugettext as _t
|
from django.utils.translation import ugettext as _t
|
||||||
from ajax_select.fields import AutoCompleteSelectField
|
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.shortcuts import get_object_or_404, redirect
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
|
|
||||||
@ -44,6 +44,7 @@ from core.views import (
|
|||||||
CanEditPropMixin,
|
CanEditPropMixin,
|
||||||
TabedViewMixin,
|
TabedViewMixin,
|
||||||
PageEditViewBase,
|
PageEditViewBase,
|
||||||
|
DetailFormView,
|
||||||
)
|
)
|
||||||
from core.views.forms import SelectDate, SelectDateTime
|
from core.views.forms import SelectDate, SelectDateTime
|
||||||
from club.models import Club, Membership, Mailing, MailingSubscription
|
from club.models import Club, Membership, Mailing, MailingSubscription
|
||||||
@ -305,7 +306,7 @@ class ClubToolsView(ClubTabsMixin, CanEditMixin, DetailView):
|
|||||||
current_tab = "tools"
|
current_tab = "tools"
|
||||||
|
|
||||||
|
|
||||||
class ClubMemberForm(forms.ModelForm):
|
class ClubMemberForm(forms.Form):
|
||||||
"""
|
"""
|
||||||
Form handling the members of a club
|
Form handling the members of a club
|
||||||
"""
|
"""
|
||||||
@ -313,24 +314,68 @@ class ClubMemberForm(forms.ModelForm):
|
|||||||
error_css_class = "error"
|
error_css_class = "error"
|
||||||
required_css_class = "required"
|
required_css_class = "required"
|
||||||
|
|
||||||
class Meta:
|
users = AutoCompleteSelectMultipleField(
|
||||||
model = Membership
|
"users",
|
||||||
fields = ["user", "role", "start_date", "description"]
|
label=_("Users to add"),
|
||||||
widgets = {"start_date": SelectDate}
|
help_text=_("Search users to add (one or more)."),
|
||||||
|
required=True,
|
||||||
user = AutoCompleteSelectField(
|
|
||||||
"users", required=True, label=_("Select user"), help_text=None
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.club = kwargs.pop("club")
|
||||||
|
self.request_user = kwargs.pop("request_user")
|
||||||
|
super(ClubMemberForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
# Using a ModelForm forces a save and we don't want that
|
||||||
|
# We want the view to process the model creation since they are multiple users
|
||||||
|
self.fields.update(
|
||||||
|
forms.fields_for_model(
|
||||||
|
Membership,
|
||||||
|
fields=("role", "start_date", "description"),
|
||||||
|
widgets={"start_date": SelectDate},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if not self.request_user.is_root:
|
||||||
|
self.fields.pop("start_date")
|
||||||
|
|
||||||
|
def clean_users(self):
|
||||||
"""
|
"""
|
||||||
Overloaded to return the club, and not to a Membership object that has no view
|
Check that the user is not trying to add an user already in the club
|
||||||
"""
|
"""
|
||||||
super(ClubMemberForm, self).save(*args, **kwargs)
|
cleaned_data = super(ClubMemberForm, self).clean()
|
||||||
return self.instance.club
|
users = []
|
||||||
|
for user_id in cleaned_data["users"]:
|
||||||
|
user = User.objects.filter(id=user_id).first()
|
||||||
|
if not user:
|
||||||
|
raise forms.ValidationError(
|
||||||
|
_("One of the selected users doesn't exist", code="invalid")
|
||||||
|
)
|
||||||
|
users.append(user)
|
||||||
|
if self.club.get_membership_for(user):
|
||||||
|
raise forms.ValidationError(
|
||||||
|
_("You can not add the same user twice"), code="invalid"
|
||||||
|
)
|
||||||
|
return users
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
"""
|
||||||
|
Check user rights
|
||||||
|
"""
|
||||||
|
cleaned_data = super(ClubMemberForm, self).clean()
|
||||||
|
request_user = self.request_user
|
||||||
|
membership = self.club.get_membership_for(request_user)
|
||||||
|
print(request_user.is_root)
|
||||||
|
if not (
|
||||||
|
cleaned_data["role"] <= SITH_MAXIMUM_FREE_ROLE
|
||||||
|
or (membership is not None and membership.role >= cleaned_data["role"])
|
||||||
|
or request_user.is_board_member
|
||||||
|
or request_user.is_root
|
||||||
|
):
|
||||||
|
raise forms.ValidationError(_("You do not have the permission to do that"))
|
||||||
|
return cleaned_data
|
||||||
|
|
||||||
|
|
||||||
class ClubMembersView(ClubTabsMixin, CanViewMixin, UpdateView):
|
class ClubMembersView(ClubTabsMixin, CanViewMixin, DetailFormView):
|
||||||
"""
|
"""
|
||||||
View of a club's members
|
View of a club's members
|
||||||
"""
|
"""
|
||||||
@ -341,52 +386,39 @@ class ClubMembersView(ClubTabsMixin, CanViewMixin, UpdateView):
|
|||||||
template_name = "club/club_members.jinja"
|
template_name = "club/club_members.jinja"
|
||||||
current_tab = "members"
|
current_tab = "members"
|
||||||
|
|
||||||
def get_form(self):
|
def get_form_kwargs(self):
|
||||||
"""
|
kwargs = super(ClubMembersView, self).get_form_kwargs()
|
||||||
Here we get a Membership object, but the view handles Club object.
|
kwargs["request_user"] = self.request_user
|
||||||
That's why the save method of ClubMemberForm is overridden.
|
kwargs["club"] = self.get_object()
|
||||||
"""
|
return kwargs
|
||||||
form = super(ClubMembersView, self).get_form()
|
|
||||||
if (
|
def get_context_data(self, *args, **kwargs):
|
||||||
"user" in form.data and form.data.get("user") != ""
|
kwargs = super(ClubMembersView, self).get_context_data(*args, **kwargs)
|
||||||
): # Load an existing membership if possible
|
kwargs["members"] = (
|
||||||
form.instance = (
|
self.get_object().members.filter(end_date=None).order_by("-role").all()
|
||||||
Membership.objects.filter(club=self.object)
|
)
|
||||||
.filter(user=form.data.get("user"))
|
return kwargs
|
||||||
.filter(end_date=None)
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
if form.instance is None: # Instanciate a new membership
|
|
||||||
form.instance = Membership(club=self.object, user=self.request.user)
|
|
||||||
if not self.request.user.is_root:
|
|
||||||
form.fields.pop("start_date", None)
|
|
||||||
return form
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
"""
|
"""
|
||||||
Check user rights
|
Check user rights
|
||||||
"""
|
"""
|
||||||
user = self.request.user
|
resp = super(ClubMembersView, self).form_valid(form)
|
||||||
ms = self.object.get_membership_for(user)
|
|
||||||
if (
|
data = form.clean()
|
||||||
form.cleaned_data["role"] <= SITH_MAXIMUM_FREE_ROLE
|
users = data.pop("users", [])
|
||||||
or (ms is not None and ms.role >= form.cleaned_data["role"])
|
for user in users:
|
||||||
or user.is_board_member
|
Membership(club=self.get_object(), user=user, **data).save()
|
||||||
or user.is_root
|
return resp
|
||||||
):
|
|
||||||
form.save()
|
|
||||||
form = self.form_class()
|
|
||||||
return super(ModelFormMixin, self).form_valid(form)
|
|
||||||
else:
|
|
||||||
form.add_error(None, _("You do not have the permission to do that"))
|
|
||||||
return self.form_invalid(form)
|
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
self.request = request
|
self.request_user = request.user
|
||||||
return super(ClubMembersView, self).dispatch(request, *args, **kwargs)
|
return super(ClubMembersView, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_success_url(self, **kwargs):
|
def get_success_url(self, **kwargs):
|
||||||
return reverse_lazy("club:club_members", kwargs={"club_id": self.club.id})
|
return reverse_lazy(
|
||||||
|
"club:club_members", kwargs={"club_id": self.get_object().id}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ClubOldMembersView(ClubTabsMixin, CanViewMixin, DetailView):
|
class ClubOldMembersView(ClubTabsMixin, CanViewMixin, DetailView):
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-04-22 14:57+0200\n"
|
"POT-Creation-Date: 2019-04-24 03:06+0200\n"
|
||||||
"PO-Revision-Date: 2016-07-18\n"
|
"PO-Revision-Date: 2016-07-18\n"
|
||||||
"Last-Translator: Skia <skia@libskia.so>\n"
|
"Last-Translator: Skia <skia@libskia.so>\n"
|
||||||
"Language-Team: AE info <ae.info@utbm.fr>\n"
|
"Language-Team: AE info <ae.info@utbm.fr>\n"
|
||||||
@ -177,7 +177,7 @@ msgstr "type de cible"
|
|||||||
#: accounting/models.py:313 club/models.py:422
|
#: accounting/models.py:313 club/models.py:422
|
||||||
#: club/templates/club/club_members.jinja:8
|
#: club/templates/club/club_members.jinja:8
|
||||||
#: club/templates/club/club_old_members.jinja:8
|
#: club/templates/club/club_old_members.jinja:8
|
||||||
#: club/templates/club/mailing.jinja:28 club/views.py:111
|
#: club/templates/club/mailing.jinja:28 club/views.py:112
|
||||||
#: counter/templates/counter/cash_summary_list.jinja:32
|
#: counter/templates/counter/cash_summary_list.jinja:32
|
||||||
#: counter/templates/counter/stats.jinja:15
|
#: counter/templates/counter/stats.jinja:15
|
||||||
#: counter/templates/counter/stats.jinja:52
|
#: counter/templates/counter/stats.jinja:52
|
||||||
@ -386,7 +386,7 @@ msgid "Delete"
|
|||||||
msgstr "Supprimer"
|
msgstr "Supprimer"
|
||||||
|
|
||||||
#: accounting/templates/accounting/bank_account_details.jinja:18
|
#: accounting/templates/accounting/bank_account_details.jinja:18
|
||||||
#: club/views.py:128 core/views/user.py:205 sas/templates/sas/picture.jinja:86
|
#: club/views.py:129 core/views/user.py:205 sas/templates/sas/picture.jinja:86
|
||||||
msgid "Infos"
|
msgid "Infos"
|
||||||
msgstr "Infos"
|
msgstr "Infos"
|
||||||
|
|
||||||
@ -405,7 +405,7 @@ msgstr "Nouveau compte club"
|
|||||||
#: accounting/templates/accounting/bank_account_details.jinja:27
|
#: accounting/templates/accounting/bank_account_details.jinja:27
|
||||||
#: accounting/templates/accounting/bank_account_list.jinja:22
|
#: accounting/templates/accounting/bank_account_list.jinja:22
|
||||||
#: accounting/templates/accounting/club_account_details.jinja:58
|
#: accounting/templates/accounting/club_account_details.jinja:58
|
||||||
#: accounting/templates/accounting/journal_details.jinja:89 club/views.py:174
|
#: accounting/templates/accounting/journal_details.jinja:89 club/views.py:175
|
||||||
#: com/templates/com/news_admin_list.jinja:39
|
#: com/templates/com/news_admin_list.jinja:39
|
||||||
#: com/templates/com/news_admin_list.jinja:68
|
#: com/templates/com/news_admin_list.jinja:68
|
||||||
#: com/templates/com/news_admin_list.jinja:115
|
#: com/templates/com/news_admin_list.jinja:115
|
||||||
@ -1070,8 +1070,8 @@ msgstr "Du"
|
|||||||
msgid "To"
|
msgid "To"
|
||||||
msgstr "Au"
|
msgstr "Au"
|
||||||
|
|
||||||
#: club/templates/club/club_sellings.jinja:5 club/views.py:194
|
#: club/templates/club/club_sellings.jinja:5 club/views.py:195
|
||||||
#: club/views.py:478 counter/templates/counter/counter_main.jinja:19
|
#: club/views.py:507 counter/templates/counter/counter_main.jinja:19
|
||||||
#: counter/templates/counter/last_ops.jinja:35
|
#: counter/templates/counter/last_ops.jinja:35
|
||||||
msgid "Sellings"
|
msgid "Sellings"
|
||||||
msgstr "Ventes"
|
msgstr "Ventes"
|
||||||
@ -1097,7 +1097,7 @@ msgstr "unités"
|
|||||||
msgid "Benefit: "
|
msgid "Benefit: "
|
||||||
msgstr "Bénéfice : "
|
msgstr "Bénéfice : "
|
||||||
|
|
||||||
#: club/templates/club/club_sellings.jinja:21 club/views.py:417
|
#: club/templates/club/club_sellings.jinja:21 club/views.py:446
|
||||||
#: core/templates/core/user_account_detail.jinja:18
|
#: core/templates/core/user_account_detail.jinja:18
|
||||||
#: core/templates/core/user_account_detail.jinja:51
|
#: core/templates/core/user_account_detail.jinja:51
|
||||||
#: counter/templates/counter/cash_summary_list.jinja:33 counter/views.py:168
|
#: counter/templates/counter/cash_summary_list.jinja:33 counter/views.py:168
|
||||||
@ -1246,60 +1246,71 @@ msgstr "Aucune page n'existe pour ce club"
|
|||||||
msgid "Club stats"
|
msgid "Club stats"
|
||||||
msgstr "Statistiques du club"
|
msgstr "Statistiques du club"
|
||||||
|
|
||||||
#: club/views.py:138
|
#: club/views.py:139
|
||||||
msgid "Members"
|
msgid "Members"
|
||||||
msgstr "Membres"
|
msgstr "Membres"
|
||||||
|
|
||||||
#: club/views.py:147
|
#: club/views.py:148
|
||||||
msgid "Old members"
|
msgid "Old members"
|
||||||
msgstr "Anciens membres"
|
msgstr "Anciens membres"
|
||||||
|
|
||||||
#: club/views.py:157 core/templates/core/page.jinja:33
|
#: club/views.py:158 core/templates/core/page.jinja:33
|
||||||
msgid "History"
|
msgid "History"
|
||||||
msgstr "Historique"
|
msgstr "Historique"
|
||||||
|
|
||||||
#: club/views.py:165 core/templates/core/base.jinja:121 core/views/user.py:228
|
#: club/views.py:166 core/templates/core/base.jinja:121 core/views/user.py:228
|
||||||
#: sas/templates/sas/picture.jinja:95 trombi/views.py:60
|
#: sas/templates/sas/picture.jinja:95 trombi/views.py:60
|
||||||
msgid "Tools"
|
msgid "Tools"
|
||||||
msgstr "Outils"
|
msgstr "Outils"
|
||||||
|
|
||||||
#: club/views.py:185
|
#: club/views.py:186
|
||||||
msgid "Edit club page"
|
msgid "Edit club page"
|
||||||
msgstr "Éditer la page de club"
|
msgstr "Éditer la page de club"
|
||||||
|
|
||||||
#: club/views.py:201
|
#: club/views.py:202
|
||||||
msgid "Mailing list"
|
msgid "Mailing list"
|
||||||
msgstr "Listes de diffusion"
|
msgstr "Listes de diffusion"
|
||||||
|
|
||||||
#: club/views.py:210 com/views.py:141
|
#: club/views.py:211 com/views.py:141
|
||||||
msgid "Posters list"
|
msgid "Posters list"
|
||||||
msgstr "Liste d'affiches"
|
msgstr "Liste d'affiches"
|
||||||
|
|
||||||
#: club/views.py:220 counter/templates/counter/counter_list.jinja:21
|
#: club/views.py:221 counter/templates/counter/counter_list.jinja:21
|
||||||
#: counter/templates/counter/counter_list.jinja:43
|
#: counter/templates/counter/counter_list.jinja:43
|
||||||
#: counter/templates/counter/counter_list.jinja:59
|
#: counter/templates/counter/counter_list.jinja:59
|
||||||
msgid "Props"
|
msgid "Props"
|
||||||
msgstr "Propriétés"
|
msgstr "Propriétés"
|
||||||
|
|
||||||
#: club/views.py:322 core/views/forms.py:358 counter/views.py:113
|
#: club/views.py:319
|
||||||
#: trombi/views.py:141
|
msgid "Users to add"
|
||||||
msgid "Select user"
|
msgstr "Utilisateurs à ajouter"
|
||||||
msgstr "Choisir un utilisateur"
|
|
||||||
|
|
||||||
#: club/views.py:381 sas/views.py:129 sas/views.py:195 sas/views.py:286
|
#: club/views.py:320 core/views/group.py:63
|
||||||
|
msgid "Search users to add (one or more)."
|
||||||
|
msgstr "Recherche les utilisateurs à ajouter (un ou plus)."
|
||||||
|
|
||||||
|
#: club/views.py:348
|
||||||
|
msgid "One of the selected users doesn't exist"
|
||||||
|
msgstr "Un des utilisateurs sélectionné n'existe pas"
|
||||||
|
|
||||||
|
#: club/views.py:353 core/views/group.py:82
|
||||||
|
msgid "You can not add the same user twice"
|
||||||
|
msgstr "Vous ne pouvez pas ajouter deux fois le même utilisateur"
|
||||||
|
|
||||||
|
#: club/views.py:371 sas/views.py:129 sas/views.py:195 sas/views.py:286
|
||||||
msgid "You do not have the permission to do that"
|
msgid "You do not have the permission to do that"
|
||||||
msgstr "Vous n'avez pas la permission de faire cela"
|
msgstr "Vous n'avez pas la permission de faire cela"
|
||||||
|
|
||||||
#: club/views.py:406 counter/views.py:1481
|
#: club/views.py:435 counter/views.py:1481
|
||||||
msgid "Begin date"
|
msgid "Begin date"
|
||||||
msgstr "Date de début"
|
msgstr "Date de début"
|
||||||
|
|
||||||
#: club/views.py:412 com/views.py:85 com/views.py:221 counter/views.py:1487
|
#: club/views.py:441 com/views.py:85 com/views.py:221 counter/views.py:1487
|
||||||
#: election/views.py:190 subscription/views.py:52
|
#: election/views.py:190 subscription/views.py:52
|
||||||
msgid "End date"
|
msgid "End date"
|
||||||
msgstr "Date de fin"
|
msgstr "Date de fin"
|
||||||
|
|
||||||
#: club/views.py:435 core/templates/core/user_stats.jinja:27
|
#: club/views.py:464 core/templates/core/user_stats.jinja:27
|
||||||
#: counter/views.py:1635
|
#: counter/views.py:1635
|
||||||
msgid "Product"
|
msgid "Product"
|
||||||
msgstr "Produit"
|
msgstr "Produit"
|
||||||
@ -3507,6 +3518,10 @@ msgstr "Parrain"
|
|||||||
msgid "Godchild"
|
msgid "Godchild"
|
||||||
msgstr "Fillot"
|
msgstr "Fillot"
|
||||||
|
|
||||||
|
#: core/views/forms.py:358 counter/views.py:113 trombi/views.py:141
|
||||||
|
msgid "Select user"
|
||||||
|
msgstr "Choisir un utilisateur"
|
||||||
|
|
||||||
#: core/views/forms.py:371 core/views/forms.py:389 election/models.py:24
|
#: core/views/forms.py:371 core/views/forms.py:389 election/models.py:24
|
||||||
#: election/views.py:167
|
#: election/views.py:167
|
||||||
msgid "edit groups"
|
msgid "edit groups"
|
||||||
@ -3525,14 +3540,6 @@ msgstr "Utilisateurs à retirer du groupe"
|
|||||||
msgid "Users to add to group"
|
msgid "Users to add to group"
|
||||||
msgstr "Utilisateurs à ajouter au groupe"
|
msgstr "Utilisateurs à ajouter au groupe"
|
||||||
|
|
||||||
#: core/views/group.py:63
|
|
||||||
msgid "Search users to add (one or more)."
|
|
||||||
msgstr "Recherche les utilisateurs à ajouter (un ou plus)."
|
|
||||||
|
|
||||||
#: core/views/group.py:82
|
|
||||||
msgid "You can not add the same user twice"
|
|
||||||
msgstr "Vous ne pouvez pas ajouter deux fois le même utilisateur"
|
|
||||||
|
|
||||||
#: core/views/user.py:223 trombi/templates/trombi/export.jinja:25
|
#: core/views/user.py:223 trombi/templates/trombi/export.jinja:25
|
||||||
#: trombi/templates/trombi/user_profile.jinja:11
|
#: trombi/templates/trombi/user_profile.jinja:11
|
||||||
msgid "Pictures"
|
msgid "Pictures"
|
||||||
|
Loading…
Reference in New Issue
Block a user