mirror of
https://gitlab.crans.org/bde/nk20
synced 2025-06-20 17:41:55 +02:00
Guests can't be invited more than 5 times a year and a member can't invite more than 3 people per activity.
This commit is contained in:
@ -1,11 +1,13 @@
|
||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from datetime import timedelta
|
||||
|
||||
from django import forms
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import gettext as _
|
||||
from member.models import Club
|
||||
from note.models import NoteUser, Note
|
||||
from note_kfet.inputs import DateTimePickerInput, AutocompleteModelSelect
|
||||
from note_kfet.inputs import DateTimePickerInput, Autocomplete
|
||||
|
||||
from .models import Activity, Guest
|
||||
|
||||
@ -15,18 +17,18 @@ class ActivityForm(forms.ModelForm):
|
||||
model = Activity
|
||||
exclude = ('creater', 'valid', 'open', )
|
||||
widgets = {
|
||||
"organizer": AutocompleteModelSelect(
|
||||
"organizer": Autocomplete(
|
||||
model=Club,
|
||||
attrs={"api_url": "/api/members/club/"},
|
||||
),
|
||||
"note": AutocompleteModelSelect(
|
||||
"note": Autocomplete(
|
||||
model=Note,
|
||||
attrs={
|
||||
"api_url": "/api/note/note/",
|
||||
'placeholder': 'Note de l\'événement sur laquelle envoyer les crédits d\'invitation ...'
|
||||
},
|
||||
),
|
||||
"attendees_club": AutocompleteModelSelect(
|
||||
"attendees_club": Autocomplete(
|
||||
model=Club,
|
||||
attrs={"api_url": "/api/members/club/"},
|
||||
),
|
||||
@ -36,11 +38,34 @@ class ActivityForm(forms.ModelForm):
|
||||
|
||||
|
||||
class GuestForm(forms.ModelForm):
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
|
||||
one_year = timedelta(days=365)
|
||||
|
||||
qs = Guest.objects.filter(
|
||||
first_name=cleaned_data["first_name"],
|
||||
last_name=cleaned_data["last_name"],
|
||||
activity__date_start__gte=self.activity.date_start - one_year,
|
||||
)
|
||||
if len(qs) >= 5:
|
||||
self.add_error("last_name", _("This person has been already invited 5 times this year."))
|
||||
|
||||
qs = qs.filter(activity=self.activity)
|
||||
if qs.exists():
|
||||
self.add_error("last_name", _("This person is already invited."))
|
||||
|
||||
qs = Guest.objects.filter(inviter=cleaned_data["inviter"], activity=self.activity)
|
||||
if len(qs) >= 3:
|
||||
self.add_error("inviter", _("You can't invite more than 3 people to this activity."))
|
||||
|
||||
return cleaned_data
|
||||
|
||||
class Meta:
|
||||
model = Guest
|
||||
fields = ('last_name', 'first_name', 'inviter', )
|
||||
widgets = {
|
||||
"inviter": AutocompleteModelSelect(
|
||||
"inviter": Autocomplete(
|
||||
NoteUser,
|
||||
attrs={
|
||||
'api_url': '/api/note/note/',
|
||||
|
@ -1,5 +1,6 @@
|
||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from datetime import timedelta
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
@ -115,6 +116,7 @@ class Entry(models.Model):
|
||||
activity = models.ForeignKey(
|
||||
Activity,
|
||||
on_delete=models.PROTECT,
|
||||
related_name="entries",
|
||||
verbose_name=_("activity"),
|
||||
)
|
||||
|
||||
@ -194,7 +196,7 @@ class Guest(models.Model):
|
||||
inviter = models.ForeignKey(
|
||||
NoteUser,
|
||||
on_delete=models.PROTECT,
|
||||
related_name='+',
|
||||
related_name='guests',
|
||||
verbose_name=_("inviter"),
|
||||
)
|
||||
|
||||
@ -207,9 +209,31 @@ class Guest(models.Model):
|
||||
except AttributeError:
|
||||
return False
|
||||
|
||||
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
|
||||
one_year = timedelta(days=365)
|
||||
|
||||
qs = Guest.objects.filter(
|
||||
first_name=self.first_name,
|
||||
last_name=self.last_name,
|
||||
activity__date_start__gte=self.activity.date_start - one_year,
|
||||
)
|
||||
if len(qs) >= 5:
|
||||
raise ValidationError(_("This person has been already invited 5 times this year."))
|
||||
|
||||
qs = qs.filter(activity=self.activity)
|
||||
if qs.exists():
|
||||
raise ValidationError(_("This person is already invited."))
|
||||
|
||||
qs = Guest.objects.filter(inviter=self.inviter, activity=self.activity)
|
||||
if len(qs) >= 3:
|
||||
raise ValidationError(_("You can't invite more than 3 people to this activity."))
|
||||
|
||||
return super().save(force_insert, force_update, using, update_fields)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("guest")
|
||||
verbose_name_plural = _("guests")
|
||||
unique_together = ("activity", "last_name", "first_name", )
|
||||
|
||||
|
||||
class GuestTransaction(Transaction):
|
||||
|
@ -77,6 +77,11 @@ class ActivityInviteView(LoginRequiredMixin, CreateView):
|
||||
form_class = GuestForm
|
||||
template_name = "activity/activity_invite.html"
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
form = super().get_form(form_class)
|
||||
form.activity = Activity.objects.get(pk=self.kwargs["pk"])
|
||||
return form
|
||||
|
||||
def form_valid(self, form):
|
||||
form.instance.activity = Activity.objects.get(pk=self.kwargs["pk"])
|
||||
return super().form_valid(form)
|
||||
|
@ -7,7 +7,7 @@ from crispy_forms.layout import Layout
|
||||
from django import forms
|
||||
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
|
||||
from django.contrib.auth.models import User
|
||||
from note_kfet.inputs import AutocompleteModelSelect
|
||||
from note_kfet.inputs import Autocomplete
|
||||
from permission.models import PermissionMask
|
||||
|
||||
from .models import Profile, Club, Membership
|
||||
@ -63,7 +63,7 @@ class MembershipForm(forms.ModelForm):
|
||||
# et récupère les noms d'utilisateur valides
|
||||
widgets = {
|
||||
'user':
|
||||
AutocompleteModelSelect(
|
||||
Autocomplete(
|
||||
User,
|
||||
attrs={
|
||||
'api_url': '/api/user/',
|
||||
|
@ -4,7 +4,7 @@
|
||||
from django import forms
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from note_kfet.inputs import AutocompleteModelSelect
|
||||
from note_kfet.inputs import Autocomplete
|
||||
|
||||
from .models import TransactionTemplate, NoteClub
|
||||
|
||||
@ -31,7 +31,7 @@ class TransactionTemplateForm(forms.ModelForm):
|
||||
# forward=(forward.Const('TYPE', 'note_type') où TYPE est dans {user, club, special}
|
||||
widgets = {
|
||||
'destination':
|
||||
AutocompleteModelSelect(
|
||||
Autocomplete(
|
||||
NoteClub,
|
||||
attrs={
|
||||
'api_url': '/api/note/note/',
|
||||
|
@ -10,6 +10,8 @@ from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from polymorphic.models import PolymorphicModel
|
||||
|
||||
from member.models import Club
|
||||
|
||||
"""
|
||||
Defines each note types
|
||||
"""
|
||||
@ -174,6 +176,35 @@ class NoteSpecial(Note):
|
||||
return self.special_type
|
||||
|
||||
|
||||
class NoteCommon(Note):
|
||||
"""
|
||||
A :model:`note.Note` for special accounts, where real money enter or leave the system
|
||||
- bank check
|
||||
- credit card
|
||||
- bank transfer
|
||||
- cash
|
||||
- refund
|
||||
This Type of Note is not associated to a :model:`auth.User` or :model:`member.Club` .
|
||||
"""
|
||||
note_name = models.CharField(
|
||||
max_length=255,
|
||||
unique=True,
|
||||
)
|
||||
|
||||
club = models.ForeignKey(
|
||||
Club,
|
||||
on_delete=models.PROTECT,
|
||||
verbose_name=_("club"),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("common note")
|
||||
verbose_name_plural = _("common notes")
|
||||
|
||||
def __str__(self):
|
||||
return self.note_name
|
||||
|
||||
|
||||
class Alias(models.Model):
|
||||
"""
|
||||
points toward a :model:`note.NoteUser` or :model;`note.NoteClub` instance.
|
||||
|
Reference in New Issue
Block a user