-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #872 from CodingPirates/feature/Inviter-Fra-Ventel…
…ister Inviter fra Ventelister og Deltagere
- Loading branch information
Showing
7 changed files
with
427 additions
and
164 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,282 @@ | ||
from datetime import timedelta | ||
from dateutil.relativedelta import relativedelta | ||
from django import forms | ||
from django.contrib import admin | ||
from django.contrib import messages | ||
|
||
from django.contrib.admin.widgets import AdminDateWidget | ||
from django.db import transaction | ||
from django.utils import timezone | ||
from django.utils.safestring import mark_safe | ||
from django.utils.html import escape | ||
from django.shortcuts import render | ||
|
||
from members.models import ( | ||
Activity, | ||
ActivityInvite, | ||
ActivityParticipant, | ||
Department, | ||
Person, | ||
WaitingList, | ||
) | ||
|
||
|
||
class AdminActions(admin.ModelAdmin): | ||
def invite_many_to_activity_action(modelAdmin, request, queryset): | ||
# Get list of available departments | ||
if request.user.is_superuser or request.user.has_perm( | ||
"members.view_all_persons" | ||
): | ||
department_list_query = Department.objects.all() | ||
else: | ||
department_list_query = Department.objects.filter( | ||
adminuserinformation__user=request.user | ||
) | ||
department_list = [("-", "-")] | ||
for department in department_list_query: | ||
department_list.append((department.id, department.name)) | ||
|
||
# Get list of active and future activities | ||
department_ids = department_list_query.values_list("id", flat=True) | ||
activity_list_query = Activity.objects.filter(end_date__gt=timezone.now()) | ||
if not request.user.is_superuser: | ||
activity_list_query = activity_list_query.filter( | ||
department__in=department_ids | ||
) | ||
activity_list = [("-", "-")] | ||
for activity in activity_list_query: | ||
activity_list.append( | ||
(activity.id, activity.department.name + ", " + activity.name) | ||
) | ||
|
||
# Form used to select department and activity - redundant department is for double check | ||
class MassInvitationForm(forms.Form): | ||
department = forms.ChoiceField(label="Afdeling", choices=department_list) | ||
activity = forms.ChoiceField(label="Aktivitet", choices=activity_list) | ||
expire = forms.DateField( | ||
label="Udløber", | ||
widget=AdminDateWidget(), | ||
initial=timezone.now() + timedelta(days=30 * 3), | ||
) | ||
|
||
# Lookup all the selected persons - to show confirmation list | ||
# Check if it's called from Waiting List | ||
if queryset.model is WaitingList: | ||
q = [wl.person.pk for wl in queryset] | ||
persons = Person.objects.filter(pk__in=q) | ||
# or if it's called from the Participants list | ||
elif queryset.model is ActivityParticipant: | ||
q = [pa.person.pk for pa in queryset] | ||
persons = Person.objects.filter(pk__in=q) | ||
else: | ||
persons = queryset | ||
|
||
context = admin.site.each_context(request) | ||
if persons is None: | ||
q = [wl.person.pk for wl in queryset] | ||
persons = Person.objects.filter(pk__in=q) | ||
# queryset = persons | ||
|
||
context["persons"] = persons | ||
context["queryset"] = queryset | ||
|
||
if request.method == "POST" and "activity" in request.POST: | ||
# Post request with data | ||
mass_invitation_form = MassInvitationForm(request.POST) | ||
context["mass_invitation_form"] = mass_invitation_form | ||
|
||
if ( | ||
mass_invitation_form.is_valid() | ||
and mass_invitation_form.cleaned_data["activity"] != "-" | ||
and mass_invitation_form.cleaned_data["department"] != "-" | ||
): | ||
# Department and Activity selected | ||
activity = Activity.objects.get( | ||
pk=mass_invitation_form.cleaned_data["activity"] | ||
) | ||
|
||
# validate activity belongs to user and matches selected department | ||
if ( | ||
int(mass_invitation_form.cleaned_data["department"]) | ||
in department_ids | ||
): | ||
if activity.department.id == int( | ||
mass_invitation_form.cleaned_data["department"] | ||
): | ||
invited_counter = 0 | ||
persons_too_young = [] | ||
persons_too_old = [] | ||
persons_already_invited = [] | ||
persons_already_participant = [] | ||
persons_invited = [] | ||
|
||
# get list of already created invitations on selected persons | ||
already_invited = Person.objects.filter( | ||
activityinvite__activity=mass_invitation_form.cleaned_data[ | ||
"activity" | ||
], | ||
activityinvite__person__in=persons, | ||
).all() | ||
list(already_invited) # force lookup | ||
already_invited_ids = already_invited.values_list( | ||
"id", flat=True | ||
) | ||
|
||
# get list of current participants on selected persons | ||
already_participant = Person.objects.filter( | ||
activityparticipant__activity=mass_invitation_form.cleaned_data[ | ||
"activity" | ||
], | ||
activityparticipant__person__in=persons, | ||
).all() | ||
list(already_participant) # force lookup | ||
already_participant_ids = already_participant.values_list( | ||
"id", flat=True | ||
) | ||
|
||
# only save if all succeeds | ||
invitation = [] | ||
try: | ||
with transaction.atomic(): | ||
# for current_person in queryset: | ||
for current_person in persons: | ||
# check for already participant | ||
if current_person.id in already_participant_ids: | ||
persons_already_participant.append( | ||
current_person.name | ||
) | ||
|
||
# Check for already invited | ||
elif current_person.id in already_invited_ids: | ||
persons_already_invited.append( | ||
current_person.name | ||
) | ||
|
||
# Check for age constraint: too young ? | ||
elif ( | ||
current_person.birthday | ||
> activity.start_date | ||
- relativedelta(years=activity.min_age) | ||
): | ||
persons_too_young.append(current_person.name) | ||
# Check for age constraint: too old ? | ||
elif ( | ||
current_person.birthday | ||
< activity.start_date | ||
- relativedelta( | ||
years=activity.max_age + 1, days=-1 | ||
) | ||
): | ||
persons_too_old.append(current_person.name) | ||
# Otherwise - person can be invited | ||
else: | ||
invited_counter = invited_counter + 1 | ||
invitation = ActivityInvite( | ||
activity=activity, | ||
person=current_person, | ||
expire_dtm=mass_invitation_form.cleaned_data[ | ||
"expire" | ||
], | ||
) | ||
invitation.save() | ||
persons_invited.append(current_person.name) | ||
|
||
except Exception: | ||
messages.error( | ||
request, | ||
"Fejl - ingen personer blev inviteret! Der var problemer med " | ||
+ (invitation.person.name if invitation else "(n/a)") | ||
+ ". Vær sikker på personen ikke allerede er inviteret og opfylder alderskravet.", | ||
) | ||
return | ||
|
||
# Message about new invites: | ||
invited_text = ( | ||
"<u>" | ||
+ str(invited_counter) | ||
+ " af " | ||
+ str(persons.count()) | ||
+ " valgte personer blev inviteret til " | ||
+ escape(str(activity)) | ||
+ "</u>" | ||
+ (":<br>" if invited_counter else "") | ||
+ escape(", ".join(persons_invited)) | ||
) | ||
|
||
# Message about persons that are already participating in activity: | ||
already_participating_text = "" | ||
if len(persons_already_participant) > 0: | ||
already_participating_text = ( | ||
"<br><u>" | ||
+ str(len(persons_already_participant)) | ||
+ " deltager allerede:</u><br> " | ||
+ escape(", ".join(persons_already_participant)) | ||
) | ||
|
||
# Message about persons that are already invited (and not found as participant) | ||
already_invited_text = "" | ||
if len(persons_already_invited) > 0: | ||
already_invited_text = ( | ||
"<br><u>" | ||
+ str(len(persons_already_invited)) | ||
+ " er allerede inviteret:</u><br> " | ||
+ escape(", ".join(persons_already_invited)) | ||
) | ||
|
||
# Message about person too young to get invited: | ||
persons_too_young_text = "" | ||
if len(persons_too_young) > 0: | ||
persons_too_young_text = ( | ||
"<br><u>" | ||
+ str(len(persons_too_young)) | ||
+ " er under minimumsalder for aktiviteten " | ||
+ "(" | ||
+ str(activity.min_age) | ||
+ " år)" | ||
+ ":</u><br> " | ||
+ escape(", ".join(persons_too_young)) | ||
) | ||
|
||
# Message about person too old to get invited: | ||
persons_too_old_text = "" | ||
if len(persons_too_old) > 0: | ||
persons_too_old_text = ( | ||
"<br><u>" | ||
+ str(len(persons_too_old)) | ||
+ " er over maximumsalder for aktiviteten " | ||
+ "(" | ||
+ str(activity.max_age) | ||
+ " år) " | ||
+ ":</u><br> " | ||
+ escape(", ".join(persons_too_old)) | ||
) | ||
|
||
messages.success( | ||
request, | ||
mark_safe( | ||
invited_text | ||
+ already_participating_text | ||
+ already_invited_text | ||
+ persons_too_young_text | ||
+ persons_too_old_text, | ||
), | ||
) | ||
return | ||
|
||
else: | ||
messages.error( | ||
request, | ||
"Valgt aktivitet stemmer ikke overens med valgt afdeling", | ||
) | ||
return | ||
else: | ||
messages.error(request, "Du kan kun invitere til egne afdelinger") | ||
return | ||
else: | ||
context["mass_invitation_form"] = MassInvitationForm() | ||
|
||
return render(request, "admin/invite_many_to_activity.html", context) | ||
|
||
invite_many_to_activity_action.short_description = ( | ||
"Inviter valgte personer til en aktivitet" | ||
) |
Oops, something went wrong.