390 lines
12 KiB
Python
390 lines
12 KiB
Python
# -*- encoding: utf-8 -*-
|
|
|
|
""" Funkce pro praci se seznamem nalodenych osob pro administraty / KoDo """
|
|
|
|
from datetime import date, datetime, timedelta # timeSlices
|
|
from collections import OrderedDict
|
|
import csv
|
|
|
|
import django
|
|
from django.http import HttpResponse, HttpResponseRedirect
|
|
from django.template import Template, RequestContext, loader
|
|
from django.shortcuts import render, redirect
|
|
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.urls import reverse
|
|
from django.views.decorators.csrf import ensure_csrf_cookie
|
|
from django import forms
|
|
from django.forms import ModelForm
|
|
from django.contrib import messages
|
|
from django.utils.translation import ugettext_lazy as _
|
|
from django.utils.translation import pgettext, pgettext_lazy
|
|
|
|
from django.db import transaction
|
|
from django.db.models import F
|
|
|
|
from django.core.exceptions import ValidationError
|
|
|
|
import logging
|
|
|
|
from django.conf import settings as appSettings
|
|
|
|
from . import models
|
|
from . import forms
|
|
from . import auth as nalodeni_auth
|
|
|
|
# Logger instance
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def role_required(roles=[]):
|
|
def decorate(func):
|
|
def call(request, *args, **kwargs):
|
|
for r in roles:
|
|
if not r in request.session['site_perms']:
|
|
messages.error(request, "Nedostatečné oprávnění pro přístup. Detaily byly zaznamenány.")
|
|
return HttpResponseRedirect('/')
|
|
result = func(request, *args, **kwargs)
|
|
return result
|
|
return call
|
|
return decorate
|
|
|
|
|
|
def get_AppUser_objects(request):
|
|
''' Zkontroluje, že všechny objekty v 'objs' vyhovují přiděleným rolím.
|
|
Nevyhovující vyřadí.
|
|
'''
|
|
sp = request.session['site_perms']
|
|
if 'sso_kodo' not in sp:
|
|
return models.AppUser.objects.none()
|
|
|
|
if 'sso_admin' in sp:
|
|
return models.AppUser.objects.all()
|
|
|
|
return models.AppUser.objects.filter(district__in=request.session['spc']['dist'])
|
|
|
|
|
|
def get_AppUser_districts(request):
|
|
'''Vrátí dostupné kraje podle rolí.'''
|
|
|
|
if 'sso_admin' in request.session['site_perms']:
|
|
return list(models.AppUser.DISTRICT_CHOICES)
|
|
|
|
rslt = []
|
|
for d in models.AppUser.DISTRICT_CHOICES:
|
|
if d[0] in request.session['spc']['dist']:
|
|
rslt.append(d)
|
|
|
|
return rslt
|
|
|
|
|
|
@ensure_csrf_cookie
|
|
@login_required(login_url="/prihlaseni")
|
|
@role_required(['sso_kodo'])
|
|
def eu2019(request, dist=None):
|
|
if dist is None:
|
|
dist = int(request.POST.get('dist', -1))
|
|
doCsvExport = None != request.POST.get('doCsvExport', None)
|
|
|
|
objs = models.Euro2019Interest.objects.all()
|
|
|
|
districts = [(-1, ' -- vše dostupné -- ')] + get_AppUser_districts(request)
|
|
# filtrujeme jen povolene kraje, nebo vse pro adminy
|
|
if dist != -1 and (dist in request.session['spc']['dist'] or 'sso_admin' in request.session['site_perms']):
|
|
selDist = dist
|
|
objs = objs.filter(district=selDist)
|
|
else:
|
|
selDist = -1
|
|
|
|
if doCsvExport:
|
|
response = HttpResponse(content_type='text/csv')
|
|
response['Content-Disposition'] = 'attachment; filename="eu2019-kraj-%s-%s.csv"' % (selDist, date.today())
|
|
|
|
row_headers = [
|
|
"ID",
|
|
"Vytvořeno",
|
|
"E-mail",
|
|
"Kraj",
|
|
"PSČ",
|
|
"Chci info emailem",
|
|
"Chci rozdávat Listy",
|
|
"Chci se zapojit",
|
|
"Poznámka",
|
|
"Datum souhlasu o.ú.",
|
|
]
|
|
col_count = len(row_headers)
|
|
row_nums = {}
|
|
|
|
writer = csv.writer(response)
|
|
writer.writerow(row_headers)
|
|
for obj in objs:
|
|
row = len(row_headers) * [None]
|
|
row[0] = obj.id
|
|
row[1] = obj.createdStamp
|
|
row[2] = obj.email
|
|
row[3] = obj.get_district_name()
|
|
row[4] = obj.postcode
|
|
row[5] = 1 if obj.want_info else 0
|
|
row[6] = 1 if obj.want_campaign else 0
|
|
row[7] = 1 if obj.want_be_active else 0
|
|
row[8] = obj.note
|
|
row[9] = obj.dc_stamp
|
|
|
|
writer.writerow(row)
|
|
|
|
return response
|
|
|
|
context = {
|
|
'people' : objs,
|
|
'distAvail' : districts,
|
|
'selDist' : selDist,
|
|
}
|
|
return render(request, 'people/eu2019.html', context)
|
|
|
|
|
|
@ensure_csrf_cookie
|
|
@login_required(login_url="/prihlaseni")
|
|
@role_required(['sso_kodo'])
|
|
def confirmed(request, newOnly=False, dist=None):
|
|
""" Zobraz seznam nalodenych pasazeru """
|
|
|
|
dist = dist or int(request.POST.get('dist', -1))
|
|
doCsvExport = None != request.POST.get('doCsvExport', None)
|
|
|
|
objs = get_AppUser_objects(request).order_by('last_name', 'first_name' ,'email')
|
|
objs = objs.filter(status=(models.AppUser.STATUS_NEW if newOnly else models.AppUser.STATUS_REG))
|
|
|
|
districts = [(-1, ' -- vše dostupné -- ')] + get_AppUser_districts(request)
|
|
# filtrujeme jen povolene kraje, nebo vse pro adminy
|
|
if dist != -1 and (dist in request.session['spc']['dist'] or 'sso_admin' in request.session['site_perms']):
|
|
selDist = dist
|
|
objs = objs.filter(district=selDist)
|
|
else:
|
|
selDist = -1
|
|
|
|
if doCsvExport:
|
|
response = HttpResponse(content_type='text/csv')
|
|
response['Content-Disposition'] = 'attachment; filename="nalodeni-kraj-%s-%s.csv"' % (selDist, date.today())
|
|
|
|
row_headers = [
|
|
"ID",
|
|
"Jméno",
|
|
"Příjmení",
|
|
"E-mail registrační",
|
|
"E-mail kontaktní",
|
|
"Telefon",
|
|
"Kraj",
|
|
"PSČ",
|
|
"Město",
|
|
"Druh",
|
|
"Poznámka",
|
|
"Stav",
|
|
"Datum souhlasu o.ú.",
|
|
"Poznámka dovednosti",
|
|
]
|
|
col_count = len(row_headers)
|
|
row_nums = {}
|
|
|
|
for abbr, mdl in [
|
|
('IR',models.InterestRegion ),
|
|
('US',models.UserSkill ),
|
|
('UT',models.UserTopic ), ]:
|
|
for i in mdl.objects.all():
|
|
row_nums[abbr+'_'+str(i.id)] = col_count
|
|
row_headers.append(i.name)
|
|
col_count += 1
|
|
|
|
writer = csv.writer(response)
|
|
writer.writerow(row_headers)
|
|
for obj in objs:
|
|
row = len(row_headers) * [None]
|
|
row[0] = obj.id
|
|
row[1] = obj.first_name
|
|
row[2] = obj.last_name
|
|
row[3] = obj.email
|
|
row[4] = obj.email_contact_active
|
|
row[5] = obj.phone
|
|
row[6] = obj.get_district_name()
|
|
row[7] = obj.postcode
|
|
row[8] = obj.city
|
|
row[9] = obj.KIND_CHOICES_STR[obj.kind]
|
|
row[10] = obj.interestedIn
|
|
row[11] = obj.STATUS_CHOICES_STR[obj.status]
|
|
row[12] = obj.dc_stamp
|
|
row[13] = obj.userform.skills_note if obj.userform else None
|
|
|
|
if obj.userform:
|
|
for abbr, mdl in [
|
|
('IR', obj.userform.regions ),
|
|
('US', obj.userform.skills ),
|
|
('UT', obj.userform.topics ), ]:
|
|
for i in mdl.all():
|
|
row[row_nums[abbr+"_"+str(i.id)]] = "x"
|
|
|
|
writer.writerow(row)
|
|
|
|
return response
|
|
|
|
context = {
|
|
'people' : objs,
|
|
'newOnly' : newOnly,
|
|
'distAvail' : districts,
|
|
'selDist' : selDist,
|
|
}
|
|
return render(request, 'people/list.html', context)
|
|
|
|
|
|
@ensure_csrf_cookie
|
|
@login_required(login_url="/prihlaseni")
|
|
@role_required(['sso_kodo'])
|
|
def pending(request):
|
|
''' List pending registrations from AppRegEmail. '''
|
|
|
|
show_all = request.GET.get("show_all","no") == "yes"
|
|
|
|
if request.method == "POST":
|
|
act = request.POST.get("action", None)
|
|
ids = request.POST.getlist('r[]')
|
|
|
|
objs = models.AppRegEmail.objects.filter(id__in = ids)
|
|
|
|
if act == "token":
|
|
email_counter = 0
|
|
skipped_counter = 0
|
|
for o in objs:
|
|
# kontrola, jestli uživatel již není registrován
|
|
rslt = models.AppUser.objects.filter(email__iexact=o.email.strip())
|
|
if len(rslt) != 0:
|
|
messages.info(request,'Uživatel s emailem %s již je registrován, požadavek na registaci odstraněn.' % o.email)
|
|
o.delete()
|
|
else:
|
|
if not ( o.etStamp and (datetime.now() - o.etStamp).total_seconds() < int(appSettings.TOKEN_VALID_SEC)):
|
|
# token not valid or not sent
|
|
nalodeni_auth.sendRegisterToken(o.email)
|
|
email_counter += 1
|
|
else:
|
|
skipped_counter += 1
|
|
if email_counter > 0:
|
|
messages.info(request,'Registrační emaily odeslány, celkem odesláno %s zpráv.' % email_counter)
|
|
if skipped_counter > 0:
|
|
messages.info(request,'Celkem %s registrací přeskočeno, ještě jsou platné.' % skipped_counter)
|
|
|
|
elif act == "delete":
|
|
objs.delete()
|
|
messages.info(request,'Registrace odstraněny.')
|
|
|
|
tokenValidAfter = datetime.now() - timedelta(seconds=int(appSettings.TOKEN_VALID_SEC))
|
|
|
|
objs = models.AppRegEmail.objects.all()
|
|
if not show_all:
|
|
# zobrazovat pouze nové registrace
|
|
objs = objs.filter(emailToken = None)
|
|
objs = objs.order_by('etStamp')
|
|
|
|
context = {
|
|
'people' : objs,
|
|
'tokenValidAfter' : tokenValidAfter,
|
|
'show_all' : show_all,
|
|
}
|
|
return render(request, 'people/pending.html', context)
|
|
|
|
|
|
|
|
@ensure_csrf_cookie
|
|
@login_required(login_url="/prihlaseni")
|
|
@role_required(['sso_kodo'])
|
|
def update(request):
|
|
ids = request.POST.getlist('r[]')
|
|
val = request.POST.get('setStatus', None)
|
|
|
|
if val and val in ['reg','new']:
|
|
objs = get_AppUser_objects(request).filter(id__in=ids)
|
|
|
|
rec = 0
|
|
for o in objs:
|
|
rec += 1
|
|
o.status = o.STATUS_REG if val == 'reg' else o.STATUS_NEW
|
|
o.save()
|
|
|
|
messages.info(request, 'Upraveno celkem %s záznamů.' % rec)
|
|
|
|
if val == 'new':
|
|
return HttpResponseRedirect('/people/list/')
|
|
elif val == "reg":
|
|
return HttpResponseRedirect('/people/list-new/')
|
|
else:
|
|
messages.error(request, 'Špatný požadavek.')
|
|
|
|
return HttpResponseRedirect('/people/list/')
|
|
|
|
|
|
@login_required(login_url="/prihlaseni")
|
|
@transaction.atomic
|
|
@role_required(['sso_kodo'])
|
|
def person_detail(request, id):
|
|
obj = models.USER_MODEL.objects.get(pk=id)
|
|
|
|
sp = request.session['site_perms']
|
|
sp_sso_kodo = 'sso_kodo' in sp
|
|
sp_sso_admin = 'sso_admin' in sp
|
|
|
|
# Check permissions to edit this object
|
|
if not sp_sso_admin and not obj.district in request.session['spc']['dist']:
|
|
messages.error(request, 'K tomuto záznamu nemáte přístup. ')
|
|
return redirect('nalodeni:people_list')
|
|
|
|
context = {
|
|
'obj' : obj,
|
|
}
|
|
return render(request, 'person/detail.html', context)
|
|
|
|
|
|
@login_required(login_url="/prihlaseni")
|
|
@transaction.atomic
|
|
@role_required(['sso_kodo'])
|
|
def person_edit(request, id):
|
|
obj = models.USER_MODEL.objects.get(pk=id)
|
|
|
|
sp = request.session['site_perms']
|
|
sp_sso_kodo = 'sso_kodo' in sp
|
|
sp_sso_admin = 'sso_admin' in sp
|
|
|
|
# Check permissions to edit this object
|
|
if not sp_sso_admin and not obj.district in request.session['spc']['dist']:
|
|
messages.error(request, 'K tomuto záznamu nemáte přístup. ')
|
|
return redirect('nalodeni:people_list')
|
|
|
|
if obj.ssoUid:
|
|
_form = forms.AppUserSsoForm
|
|
else:
|
|
_form = forms.AppUserForm
|
|
|
|
if request.method == "GET":
|
|
form = _form(instance=obj)
|
|
form.fields['email_contact'].disabled = True
|
|
form.fields['postcode'].required = False
|
|
|
|
elif request.method == "POST":
|
|
with obj.audit_context(request.user) as ac:
|
|
form = _form(request.POST, instance=obj)
|
|
form.fields['email_contact'].disabled = True
|
|
form.fields['postcode'].required = False
|
|
if form.is_valid():
|
|
form.save()
|
|
|
|
messages.info(request, "Údaje byly uloženy.")
|
|
return redirect('nalodeni:person_detail', form.instance.id)
|
|
|
|
else:
|
|
messages.error(request, "Opravte prosím chyby v zadání.")
|
|
raise ac.DataNotSavedException
|
|
else:
|
|
form = None
|
|
|
|
context = {
|
|
'obj' : obj,
|
|
'form' : form,
|
|
'AUTH_SERVER' : appSettings.AUTH_SERVER,
|
|
}
|
|
return render(request, 'person/edit.html', context)
|