diff --git a/club/forms.py b/club/forms.py index b9b4baaa..abc72df1 100644 --- a/club/forms.py +++ b/club/forms.py @@ -208,15 +208,14 @@ class ClubOldMemberForm(forms.Form): class ClubMemberForm(forms.ModelForm): - """Form handling the members of a club.""" + """Form to add a member to the club, as a board member.""" error_css_class = "error" required_css_class = "required" class Meta: model = Membership - fields = ["user", "role", "description"] - widgets = {"user": AutoCompleteSelectUser} + fields = ["role", "description"] def __init__(self, *args, club: Club, request_user: User, **kwargs): self.club = club @@ -231,22 +230,36 @@ class ClubMemberForm(forms.ModelForm): ] self.instance.club = club + @property + def max_available_role(self): # pragma: no cover + """The greatest role that will be obtainable with this form.""" + # this is unreachable, because it will be overridden by subclasses + return -1 + + +class ClubAddMemberForm(ClubMemberForm): + """Form to add a member to the club, as a board member.""" + + class Meta(ClubMemberForm.Meta): + fields = ["user", *ClubMemberForm.Meta.fields] + widgets = {"user": AutoCompleteSelectUser} + @cached_property def max_available_role(self): """The greatest role that will be obtainable with this form. Admins and the club president can attribute any role. Board members can attribute roles lower than their own. - Other users can attribute curious and member roles. + Other users cannot attribute roles with this form """ if self.request_user.has_perm("club.add_subscription"): return settings.SITH_CLUB_ROLES_ID["President"] membership = self.request_user_membership - if membership is not None and membership.role > settings.SITH_MAXIMUM_FREE_ROLE: - if membership.role == settings.SITH_CLUB_ROLES_ID["President"]: - return membership.role - return membership.role - 1 - return settings.SITH_MAXIMUM_FREE_ROLE + if membership is None or membership.role <= settings.SITH_MAXIMUM_FREE_ROLE: + return -1 + if membership.role == settings.SITH_CLUB_ROLES_ID["President"]: + return membership.role + return membership.role - 1 def clean_user(self): """Check that the user is not trying to add a user already in the club. @@ -264,18 +277,26 @@ class ClubMemberForm(forms.ModelForm): ) return user + +class JoinClubForm(ClubMemberForm): + """Form to join a club.""" + + def __init__(self, *args, club: Club, request_user: User, **kwargs): + super().__init__(*args, club=club, request_user=request_user, **kwargs) + self.instance.user = self.request_user + + @cached_property + def max_available_role(self): + return settings.SITH_MAXIMUM_FREE_ROLE + def clean(self): - """Check user rights for adding a user.""" - cleaned_data = super().clean() - if ( - self.request_user_membership is None - or self.request_user_membership.role <= settings.SITH_MAXIMUM_FREE_ROLE - ) and not self.request_user.has_perm("club.add_membership"): + """Check that the user is subscribed and isn't already in the club.""" + if not self.request_user.is_subscribed: raise forms.ValidationError( - _( - "You cannot add other users to a club " - "if you are not in the club board." - ), - code="invalid", + _("You must be subscribed to join a club"), code="invalid" ) - return cleaned_data + if self.club.get_membership_for(self.request_user): + raise forms.ValidationError( + _("You are already a member of this club"), code="invalid" + ) + return super().clean() diff --git a/club/templates/club/club_members.jinja b/club/templates/club/club_members.jinja index 5e5d02c1..3aa43d56 100644 --- a/club/templates/club/club_members.jinja +++ b/club/templates/club/club_members.jinja @@ -6,23 +6,22 @@ {% endblock %} {% block additional_css %} - {% endblock %} {% block content %} {% block notifications %} - {# Notifications are moved inside the billing info fragment #} + {# Notifications are moved a little bit below #} {% endblock %}