|
|
|
|
@ -7,6 +7,7 @@ import time
|
|
|
|
|
import unicodedata
|
|
|
|
|
import random
|
|
|
|
|
import string
|
|
|
|
|
import xlsxwriter
|
|
|
|
|
from functools import partial, update_wrapper
|
|
|
|
|
from django.forms.models import BaseInlineFormSet
|
|
|
|
|
|
|
|
|
|
@ -28,6 +29,7 @@ from django.forms import Textarea, RadioSelect, TypedChoiceField, CheckboxInput
|
|
|
|
|
from django.shortcuts import render
|
|
|
|
|
from django.core.exceptions import PermissionDenied, ValidationError
|
|
|
|
|
from .pdf import render_tex, fill_pdf_form, merge_pdfs, serve_pdf
|
|
|
|
|
from .models import WEEKDAYS
|
|
|
|
|
|
|
|
|
|
from contrib.admin import CommonAdminInlineMixin, CommonAdminMixin
|
|
|
|
|
|
|
|
|
|
@ -44,6 +46,7 @@ from mailer.mailutils import send as send_mail, get_echo_link
|
|
|
|
|
from django.conf import settings
|
|
|
|
|
from utils import get_member, RestrictedFileField
|
|
|
|
|
from schwifty import IBAN
|
|
|
|
|
from .pdf import media_path
|
|
|
|
|
|
|
|
|
|
#from easy_select2 import apply_select2
|
|
|
|
|
|
|
|
|
|
@ -791,6 +794,7 @@ class GroupAdminForm(forms.ModelForm):
|
|
|
|
|
self.fields['leiters'].queryset = Member.objects.filter(group__name='Jugendleiter')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class GroupAdmin(CommonAdminMixin, admin.ModelAdmin):
|
|
|
|
|
fields = ['name', 'description', 'year_from', 'year_to', 'leiters', 'contact_email', 'show_website',
|
|
|
|
|
'weekday', ('start_time', 'end_time')]
|
|
|
|
|
@ -798,6 +802,92 @@ class GroupAdmin(CommonAdminMixin, admin.ModelAdmin):
|
|
|
|
|
list_display = ('name', 'year_from', 'year_to')
|
|
|
|
|
inlines = [RegistrationPasswordInline, PermissionOnGroupInline]
|
|
|
|
|
search_fields = ('name',)
|
|
|
|
|
|
|
|
|
|
def get_urls(self):
|
|
|
|
|
urls = super().get_urls()
|
|
|
|
|
|
|
|
|
|
def wrap(view):
|
|
|
|
|
def wrapper(*args, **kwargs):
|
|
|
|
|
return self.admin_site.admin_view(view)(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
wrapper.model_admin = self
|
|
|
|
|
return update_wrapper(wrapper, view)
|
|
|
|
|
|
|
|
|
|
custom_urls = [
|
|
|
|
|
path('action/', self.action_view, name='members_group_action'),
|
|
|
|
|
]
|
|
|
|
|
return custom_urls + urls
|
|
|
|
|
|
|
|
|
|
def action_view(self, request):
|
|
|
|
|
if "group_overview" in request.POST:
|
|
|
|
|
return self.group_overview(request)
|
|
|
|
|
|
|
|
|
|
def group_overview(self, request):
|
|
|
|
|
|
|
|
|
|
if not request.user.has_perm('members.view_group'):
|
|
|
|
|
messages.error(request,
|
|
|
|
|
_("You are not allowed to create a group overview."))
|
|
|
|
|
return HttpResponseRedirect(reverse('admin:%s_%s_changelist' % (self.opts.app_label, self.opts.model_name)))
|
|
|
|
|
|
|
|
|
|
today = f"{datetime.today():%d.%m.%Y}"
|
|
|
|
|
filename = f"gruppenuebersicht_jdav_{settings.SEKTION}_{today}.xlsx"
|
|
|
|
|
workbook = xlsxwriter.Workbook(media_path(filename))
|
|
|
|
|
default = workbook.add_format({'text_wrap' : True, 'border': 1})
|
|
|
|
|
bold = workbook.add_format({'bold': True, 'border': 1})
|
|
|
|
|
title = workbook.add_format({'bold': True, 'font_size': 16, 'align': 'center'})
|
|
|
|
|
right = workbook.add_format({'bold': True, 'align': 'right'})
|
|
|
|
|
worksheet = workbook.add_worksheet()
|
|
|
|
|
|
|
|
|
|
worksheet.merge_range(0, 0, 0, 6, _(f"group overview JDAV {settings.SEKTION}"), title)
|
|
|
|
|
row = 1
|
|
|
|
|
worksheet.write(row, 0, "Gruppe", bold)
|
|
|
|
|
worksheet.write(row, 1, "Wochentag", bold)
|
|
|
|
|
worksheet.write(row, 2, "Uhrzeit", bold)
|
|
|
|
|
worksheet.write(row, 3, "Altersgruppe", bold)
|
|
|
|
|
worksheet.write(row, 4, "TN", bold)
|
|
|
|
|
worksheet.write(row, 5, "JL", bold)
|
|
|
|
|
worksheet.write(row, 6, "Jugendleiter*innen", bold)
|
|
|
|
|
|
|
|
|
|
for group in self.model.objects.all():
|
|
|
|
|
# only official youth groups are on the website
|
|
|
|
|
if not group.show_website:
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
row = row + 1
|
|
|
|
|
wd = f"{WEEKDAYS[group.weekday][1]}" if group.weekday else 'kein Wochentag'
|
|
|
|
|
times = f"{group.start_time:%H:%M} - {group.end_time:%H:%M}" if group.start_time and group.end_time else 'keine Zeiten'
|
|
|
|
|
yl_count = len([member for member in group.member_set.all() if member in group.leiters.all()])
|
|
|
|
|
tn_count = group.member_set.count() - yl_count
|
|
|
|
|
members = f"JG {group.year_from} - {group.year_to}"
|
|
|
|
|
leaders = f"{', '.join([yl.name for yl in group.leiters.all()])}"
|
|
|
|
|
|
|
|
|
|
worksheet.write(row, 0, group.name, default)
|
|
|
|
|
worksheet.write(row, 1, wd, default)
|
|
|
|
|
worksheet.write(row, 2, times, default)
|
|
|
|
|
worksheet.write(row, 3, members, default)
|
|
|
|
|
worksheet.write(row, 4, tn_count, default)
|
|
|
|
|
worksheet.write(row, 5, yl_count, default)
|
|
|
|
|
worksheet.write(row, 6, leaders, default)
|
|
|
|
|
|
|
|
|
|
worksheet.write(row+2, 6, f"Stand: {today}", right)
|
|
|
|
|
# set column width
|
|
|
|
|
worksheet.set_column_pixels(0, 0, 100)
|
|
|
|
|
worksheet.set_column_pixels(1, 1, 80)
|
|
|
|
|
worksheet.set_column_pixels(2, 2, 90)
|
|
|
|
|
worksheet.set_column_pixels(3, 3, 120)
|
|
|
|
|
worksheet.set_column_pixels(4, 4, 20)
|
|
|
|
|
worksheet.set_column_pixels(5, 5, 20)
|
|
|
|
|
worksheet.set_column_pixels(6, 6, 140)
|
|
|
|
|
workbook.close()
|
|
|
|
|
|
|
|
|
|
with open(media_path(filename), 'rb') as xls:
|
|
|
|
|
response = HttpResponse(FileWrapper(xls))
|
|
|
|
|
response['Content-Type'] = 'application/xlsx'
|
|
|
|
|
response['Content-Disposition'] = 'attachment; filename='+filename
|
|
|
|
|
|
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ActivityCategoryAdmin(admin.ModelAdmin):
|
|
|
|
|
|