1
0
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:
Yohann D'ANELLO
2020-03-30 00:42:32 +02:00
parent 691a03ecad
commit fb5796d35e
10 changed files with 279 additions and 158 deletions

View File

@ -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/',

View File

@ -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):

View File

@ -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)

View File

@ -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/',

View File

@ -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/',

View File

@ -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.