nk20/apps/activity/forms.py

123 lines
4.6 KiB
Python
Raw Permalink Normal View History

Update 131 files - /apps/activity/api/serializers.py - /apps/activity/api/urls.py - /apps/activity/api/views.py - /apps/activity/tests/test_activities.py - /apps/activity/__init__.py - /apps/activity/admin.py - /apps/activity/apps.py - /apps/activity/forms.py - /apps/activity/tables.py - /apps/activity/urls.py - /apps/activity/views.py - /apps/api/__init__.py - /apps/api/apps.py - /apps/api/serializers.py - /apps/api/tests.py - /apps/api/urls.py - /apps/api/views.py - /apps/api/viewsets.py - /apps/logs/signals.py - /apps/logs/apps.py - /apps/logs/__init__.py - /apps/logs/api/serializers.py - /apps/logs/api/urls.py - /apps/logs/api/views.py - /apps/member/api/serializers.py - /apps/member/api/urls.py - /apps/member/api/views.py - /apps/member/templatetags/memberinfo.py - /apps/member/__init__.py - /apps/member/admin.py - /apps/member/apps.py - /apps/member/auth.py - /apps/member/forms.py - /apps/member/hashers.py - /apps/member/signals.py - /apps/member/tables.py - /apps/member/urls.py - /apps/member/views.py - /apps/note/api/serializers.py - /apps/note/api/urls.py - /apps/note/api/views.py - /apps/note/models/__init__.py - /apps/note/static/note/js/consos.js - /apps/note/templates/note/mails/negative_balance.txt - /apps/note/templatetags/getenv.py - /apps/note/templatetags/pretty_money.py - /apps/note/tests/test_transactions.py - /apps/note/__init__.py - /apps/note/admin.py - /apps/note/apps.py - /apps/note/forms.py - /apps/note/signals.py - /apps/note/tables.py - /apps/note/urls.py - /apps/note/views.py - /apps/permission/api/serializers.py - /apps/permission/api/urls.py - /apps/permission/api/views.py - /apps/permission/templatetags/perms.py - /apps/permission/tests/test_oauth2.py - /apps/permission/tests/test_permission_denied.py - /apps/permission/tests/test_permission_queries.py - /apps/permission/tests/test_rights_page.py - /apps/permission/__init__.py - /apps/permission/admin.py - /apps/permission/backends.py - /apps/permission/apps.py - /apps/permission/decorators.py - /apps/permission/permissions.py - /apps/permission/scopes.py - /apps/permission/signals.py - /apps/permission/tables.py - /apps/permission/urls.py - /apps/permission/views.py - /apps/registration/tests/test_registration.py - /apps/registration/__init__.py - /apps/registration/apps.py - /apps/registration/forms.py - /apps/registration/tables.py - /apps/registration/tokens.py - /apps/registration/urls.py - /apps/registration/views.py - /apps/treasury/api/serializers.py - /apps/treasury/api/urls.py - /apps/treasury/api/views.py - /apps/treasury/templatetags/escape_tex.py - /apps/treasury/tests/test_treasury.py - /apps/treasury/__init__.py - /apps/treasury/admin.py - /apps/treasury/apps.py - /apps/treasury/forms.py - /apps/treasury/signals.py - /apps/treasury/tables.py - /apps/treasury/urls.py - /apps/treasury/views.py - /apps/wei/api/serializers.py - /apps/wei/api/urls.py - /apps/wei/api/views.py - /apps/wei/forms/surveys/__init__.py - /apps/wei/forms/surveys/base.py - /apps/wei/forms/surveys/wei2021.py - /apps/wei/forms/surveys/wei2022.py - /apps/wei/forms/surveys/wei2023.py - /apps/wei/forms/__init__.py - /apps/wei/forms/registration.py - /apps/wei/management/commands/export_wei_registrations.py - /apps/wei/management/commands/import_scores.py - /apps/wei/management/commands/wei_algorithm.py - /apps/wei/templates/wei/weilist_sample.tex - /apps/wei/tests/test_wei_algorithm_2021.py - /apps/wei/tests/test_wei_algorithm_2022.py - /apps/wei/tests/test_wei_algorithm_2023.py - /apps/wei/tests/test_wei_registration.py - /apps/wei/__init__.py - /apps/wei/admin.py - /apps/wei/apps.py - /apps/wei/tables.py - /apps/wei/urls.py - /apps/wei/views.py - /note_kfet/settings/__init__.py - /note_kfet/settings/base.py - /note_kfet/settings/development.py - /note_kfet/settings/secrets_example.py - /note_kfet/static/js/base.js - /note_kfet/admin.py - /note_kfet/inputs.py - /note_kfet/middlewares.py - /note_kfet/urls.py - /note_kfet/views.py - /note_kfet/wsgi.py - /entrypoint.sh
2024-02-07 01:26:49 +00:00
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
2020-03-27 00:31:54 +00:00
# SPDX-License-Identifier: GPL-3.0-or-later
2020-08-06 12:11:55 +00:00
from datetime import timedelta
2020-08-30 22:13:38 +00:00
from random import shuffle
2020-03-27 00:31:54 +00:00
from bootstrap_datepicker_plus.widgets import DateTimePickerInput
2020-03-27 00:31:54 +00:00
from django import forms
2020-03-27 17:02:22 +00:00
from django.contrib.contenttypes.models import ContentType
2020-08-06 12:11:55 +00:00
from django.utils import timezone
2020-04-19 23:26:53 +00:00
from django.utils.translation import gettext_lazy as _
from member.models import Club
from note.models import Note, NoteUser
from note_kfet.inputs import Autocomplete
from note_kfet.middlewares import get_current_request
2020-08-30 22:13:38 +00:00
from permission.backends import PermissionBackend
2020-03-27 00:31:54 +00:00
2020-03-27 17:02:22 +00:00
from .models import Activity, Guest
2020-03-27 00:31:54 +00:00
class ActivityForm(forms.ModelForm):
2020-08-30 22:13:38 +00:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# By default, the Kfet club is attended
self.fields["attendees_club"].initial = Club.objects.get(name="Kfet")
self.fields["attendees_club"].widget.attrs["placeholder"] = "Kfet"
clubs = list(Club.objects.filter(PermissionBackend
.filter_queryset(get_current_request(), Club, "view")).all())
2020-08-30 22:13:38 +00:00
shuffle(clubs)
self.fields["organizer"].widget.attrs["placeholder"] = ", ".join(club.name for club in clubs[:4]) + ", ..."
def clean_organizer(self):
organizer = self.cleaned_data['organizer']
if not organizer.note.is_active:
self.add_error('organiser', _('The note of this club is inactive.'))
return organizer
def clean_date_end(self):
date_end = self.cleaned_data["date_end"]
date_start = self.cleaned_data["date_start"]
if date_end < date_start:
self.add_error("date_end", _("The end date must be after the start date."))
return date_end
2020-03-27 00:31:54 +00:00
class Meta:
model = Activity
2024-08-01 12:49:52 +00:00
exclude = ('creater', 'valid', 'open', 'opener', )
widgets = {
"organizer": Autocomplete(
model=Club,
attrs={"api_url": "/api/members/club/"},
),
"note": Autocomplete(
2020-03-27 21:48:20 +00:00
model=Note,
attrs={
"api_url": "/api/note/note/",
'placeholder': 'Note de l\'événement sur laquelle envoyer les crédits d\'invitation ...'
},
),
"attendees_club": Autocomplete(
model=Club,
attrs={"api_url": "/api/members/club/"},
),
"date_start": DateTimePickerInput(),
"date_end": DateTimePickerInput(),
}
2020-03-27 17:02:22 +00:00
class GuestForm(forms.ModelForm):
def clean(self):
2020-08-19 09:31:15 +00:00
"""
Someone can be invited as a Guest to an Activity if:
- the activity has not already started.
- the activity is validated.
- the Guest has not already been invited more than 5 times.
- the Guest is already invited.
- the inviter already invited 3 peoples.
"""
cleaned_data = super().clean()
2020-08-06 15:41:30 +00:00
if timezone.now() > timezone.localtime(self.activity.date_start):
self.add_error("inviter", _("You can't invite someone once the activity is started."))
if not self.activity.valid:
self.add_error("inviter", _("This activity is not validated yet."))
one_year = timedelta(days=365)
qs = Guest.objects.filter(
2020-08-06 15:41:30 +00:00
first_name__iexact=cleaned_data["first_name"],
last_name__iexact=cleaned_data["last_name"],
activity__date_start__gte=self.activity.date_start - one_year,
)
if qs.filter(entry__isnull=False).count() >= 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."))
2020-08-06 15:41:30 +00:00
if "inviter" in cleaned_data:
if Guest.objects.filter(inviter=cleaned_data["inviter"], activity=self.activity).count() >= 3:
self.add_error("inviter", _("You can't invite more than 3 people to this activity."))
return cleaned_data
2020-03-27 17:02:22 +00:00
class Meta:
model = Guest
fields = ('last_name', 'first_name', 'inviter', )
widgets = {
"inviter": Autocomplete(
2020-03-27 17:02:22 +00:00
NoteUser,
attrs={
'api_url': '/api/note/note/',
# We don't evaluate the content type at launch because the DB might be not initialized
'api_url_suffix':
2020-03-27 21:48:20 +00:00
lambda: '&polymorphic_ctype=' + str(ContentType.objects.get_for_model(NoteUser).pk),
2020-03-27 17:02:22 +00:00
'placeholder': 'Note ...',
},
),
}