add congratulating top 10 members

v1-0-stable
Christian Merten 4 years ago
parent df75c5b324
commit 8df2670138

@ -0,0 +1,48 @@
from django.core.management.base import BaseCommand
from mailer.models import Message
from members.models import Member, annotate_activity_score
from django.db.models import Q
from mailer.mailutils import mail_root, send
import re
CONGRATULATE_MEMBERS_MAX = 10
SENDING_ADDRESS = mail_root
class Command(BaseCommand):
help = 'Congratulates the most active members'
requires_system_checks = False
def handle(self, *args, **options):
qs = annotate_activity_score(Member.objects.all())\
.order_by('_activity_score')[:CONGRATULATE_MEMBERS_MAX]
for position, member in enumerate(qs):
positiontext = "{}. ".format(position + 1) if position > 0 else ""
score = member._activity_score
if score < 5:
level = 1
elif score >= 5 and score < 10:
level = 2
elif score >= 10 and score < 20:
level = 3
elif score >= 20 and score < 30:
level = 4
else:
level = 5
content = "Hallo {}!\n\n"\
"Herzlichen Glückwunsch, du hast im letzten Jahr zu den {} aktivsten "\
"Mitgliedern der JDAV Ludwigsburg gehört! Um genau zu sein beträgt "\
"dein Aktivitäts Wert "\
"des letzten Jahres {} Punkte. Das entspricht {} Kletterer*innen. "\
"Damit warst du im letzten Jahr "\
"das {}aktivste Mitglied der JDAV Ludwigsburg.\n\n"\
"Auf ein weiteres aktives Jahr in der JDAV Ludwigsburg\n"\
"Dein*e Jugendreferent*in".format(member.prename,
CONGRATULATE_MEMBERS_MAX,
score,
level,
positiontext)
send("Herzlichen Glückwunsch {}".format(member.prename),
content, SENDING_ADDRESS, [member.email],
reply_to=["jugendreferent@jdav-ludwigsburgs.de"])

@ -20,7 +20,8 @@ from django.forms import Textarea, RadioSelect, TypedChoiceField
from django.shortcuts import render
from .models import (Member, Group, Freizeit, MemberNoteList, NewMemberOnList, Klettertreff,
KlettertreffAttendee, ActivityCategory, OldMemberOnList, MemberList)
KlettertreffAttendee, ActivityCategory, OldMemberOnList, MemberList,
annotate_activity_score)
from django.conf import settings
#from easy_select2 import apply_select2
@ -85,92 +86,7 @@ class MemberAdmin(admin.ModelAdmin):
def get_queryset(self, request):
queryset = super().get_queryset(request)
one_year_ago = datetime.now() - timedelta(days=365)
queryset = queryset.annotate(
_jugendleiter_freizeit_score_calc=Subquery(
Freizeit.objects.filter(jugendleiter=OuterRef('pk'),
date__gte=one_year_ago)
.values('jugendleiter')
.annotate(cnt=Count('pk', distinct=True))
.values('cnt'),
output_field=IntegerField()
),
# better solution but does not work in production apparently
#_jugendleiter_freizeit_score=Sum(Case(
# When(
# freizeit__date__gte=one_year_ago,
# then=1),
# default=0,
# output_field=IntegerField()
# ),
# distinct=True),
_jugendleiter_klettertreff_score_calc=Subquery(
Klettertreff.objects.filter(jugendleiter=OuterRef('pk'),
date__gte=one_year_ago)
.values('jugendleiter')
.annotate(cnt=Count('pk', distinct=True))
.values('cnt'),
output_field=IntegerField()
),
# better solution but does not work in production apparently
#_jugendleiter_klettertreff_score=Sum(Case(
# When(
# klettertreff__date__gte=one_year_ago,
# then=1),
# default=0,
# output_field=IntegerField()
# ),
# distinct=True),
_freizeit_score_calc=Subquery(
Freizeit.objects.filter(membersonlist__member=OuterRef('pk'),
date__gte=one_year_ago)
.values('membersonlist__member')
.annotate(cnt=Count('pk', distinct=True))
.values('cnt'),
output_field=IntegerField()
),
_klettertreff_score_calc=Subquery(
KlettertreffAttendee.objects.filter(member=OuterRef('pk'),
klettertreff__date__gte=one_year_ago)
.values('member')
.annotate(cnt=Count('pk', distinct=True))
.values('cnt'),
output_field=IntegerField()))
queryset = queryset.annotate(
_jugendleiter_freizeit_score=Case(
When(
_jugendleiter_freizeit_score_calc=None,
then=0
),
default=F('_jugendleiter_freizeit_score_calc'),
output_field=IntegerField()),
_jugendleiter_klettertreff_score=Case(
When(
_jugendleiter_klettertreff_score_calc=None,
then=0
),
default=F('_jugendleiter_klettertreff_score_calc'),
output_field=IntegerField()),
_klettertreff_score=Case(
When(
_klettertreff_score_calc=None,
then=0
),
default=F('_klettertreff_score_calc'),
output_field=IntegerField()),
_freizeit_score=Case(
When(
_freizeit_score_calc=None,
then=0
),
default=F('_freizeit_score_calc'),
output_field=IntegerField()))
queryset = queryset.annotate(
#_activity_score=F('_jugendleiter_freizeit_score')
_activity_score=(F('_klettertreff_score') + 3 * F('_freizeit_score')
+ F('_jugendleiter_klettertreff_score') + 3 * F('_jugendleiter_freizeit_score'))
)
return queryset
return annotate_activity_score(queryset)
def change_view(self, request, object_id, form_url="", extra_context=None):
extra_context = extra_context or {}

@ -1,6 +1,8 @@
from datetime import datetime
from datetime import datetime, timedelta
import uuid
from django.db import models
from django.db.models import TextField, ManyToManyField, ForeignKey, Count,\
Sum, Case, Q, F, When, Value, IntegerField, Subquery, OuterRef
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from django.urls import reverse
@ -373,3 +375,92 @@ class KlettertreffAttendee(models.Model):
class Meta:
verbose_name = _('Member')
verbose_name_plural = _('Members')
def annotate_activity_score(queryset):
one_year_ago = datetime.now() - timedelta(days=365)
queryset = queryset.annotate(
_jugendleiter_freizeit_score_calc=Subquery(
Freizeit.objects.filter(jugendleiter=OuterRef('pk'),
date__gte=one_year_ago)
.values('jugendleiter')
.annotate(cnt=Count('pk', distinct=True))
.values('cnt'),
output_field=IntegerField()
),
# better solution but does not work in production apparently
#_jugendleiter_freizeit_score=Sum(Case(
# When(
# freizeit__date__gte=one_year_ago,
# then=1),
# default=0,
# output_field=IntegerField()
# ),
# distinct=True),
_jugendleiter_klettertreff_score_calc=Subquery(
Klettertreff.objects.filter(jugendleiter=OuterRef('pk'),
date__gte=one_year_ago)
.values('jugendleiter')
.annotate(cnt=Count('pk', distinct=True))
.values('cnt'),
output_field=IntegerField()
),
# better solution but does not work in production apparently
#_jugendleiter_klettertreff_score=Sum(Case(
# When(
# klettertreff__date__gte=one_year_ago,
# then=1),
# default=0,
# output_field=IntegerField()
# ),
# distinct=True),
_freizeit_score_calc=Subquery(
Freizeit.objects.filter(membersonlist__member=OuterRef('pk'),
date__gte=one_year_ago)
.values('membersonlist__member')
.annotate(cnt=Count('pk', distinct=True))
.values('cnt'),
output_field=IntegerField()
),
_klettertreff_score_calc=Subquery(
KlettertreffAttendee.objects.filter(member=OuterRef('pk'),
klettertreff__date__gte=one_year_ago)
.values('member')
.annotate(cnt=Count('pk', distinct=True))
.values('cnt'),
output_field=IntegerField()))
queryset = queryset.annotate(
_jugendleiter_freizeit_score=Case(
When(
_jugendleiter_freizeit_score_calc=None,
then=0
),
default=F('_jugendleiter_freizeit_score_calc'),
output_field=IntegerField()),
_jugendleiter_klettertreff_score=Case(
When(
_jugendleiter_klettertreff_score_calc=None,
then=0
),
default=F('_jugendleiter_klettertreff_score_calc'),
output_field=IntegerField()),
_klettertreff_score=Case(
When(
_klettertreff_score_calc=None,
then=0
),
default=F('_klettertreff_score_calc'),
output_field=IntegerField()),
_freizeit_score=Case(
When(
_freizeit_score_calc=None,
then=0
),
default=F('_freizeit_score_calc'),
output_field=IntegerField()))
queryset = queryset.annotate(
#_activity_score=F('_jugendleiter_freizeit_score')
_activity_score=(F('_klettertreff_score') + 3 * F('_freizeit_score')
+ F('_jugendleiter_klettertreff_score') + 3 * F('_jugendleiter_freizeit_score'))
)
return queryset

Loading…
Cancel
Save