diff --git a/personalni/templates/personalni/profil/export_lidi.html b/personalni/templates/personalni/profil/export_lidi.html
new file mode 100644
index 00000000..96778449
--- /dev/null
+++ b/personalni/templates/personalni/profil/export_lidi.html
@@ -0,0 +1,88 @@
+{% extends "base.html" %}
+
+
+{% block content %}
+
+
Export lidí
+
+
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/personalni/templates/personalni/profil/orgorozcestnik.html b/personalni/templates/personalni/profil/orgorozcestnik.html
index 2dbc853b..338857ba 100644
--- a/personalni/templates/personalni/profil/orgorozcestnik.html
+++ b/personalni/templates/personalni/profil/orgorozcestnik.html
@@ -107,6 +107,13 @@
+
+Exporty dat lidí v semináří
+
+
+
Nemůžeš najít, co hledáš? Může to být v administračním rozhraní webu.
{% endblock content %}
diff --git a/personalni/urls.py b/personalni/urls.py
index 1805bbfe..9e173aae 100644
--- a/personalni/urls.py
+++ b/personalni/urls.py
@@ -38,6 +38,28 @@ urlpatterns = [
'org/propagace/jak-se-dozvedeli/',
org_required(views.JakSeDozvedeliView.as_view()),
name='jak_se_dozvedeli'
+ ),
+
+ # export dat o řešitelích
+ path(
+ 'profil/exporty_lidi',
+ org_required(views.ExportLidiView.as_view()),
+ name='exporty_lidi',
+ ),
+ path(
+ 'profil/exporty_lidi/get/',
+ org_required(views.get_export_options),
+ name='exporty_lidi_options',
+ ),
+ path(
+ 'profil/exporty_lidi/get_csv_only_one_step/',
+ org_required(views.download_export_csv_only_first_step),
+ name='exporty_lidi_data',
+ ),
+ path(
+ 'profil/exporty_lidi/get_csv//',
+ org_required(views.download_export_csv),
+ name='exporty_lidi_download',
)
]
diff --git a/personalni/views.py b/personalni/views.py
index 49442c2d..49938f29 100644
--- a/personalni/views.py
+++ b/personalni/views.py
@@ -20,13 +20,16 @@ from django.utils import timezone
import personalni.models as m
from soustredeni.models import Soustredeni
from odevzdavatko.models import Hodnoceni
-from tvorba.models import Clanek, Uloha, Tema
+from tvorba.models import Clanek, Uloha, Tema, Cislo, Rocnik
+import tvorba.utils as tvorba_utils
from various.models import Nastaveni
from .forms import PrihlaskaForm, ProfileEditForm, PoMaturiteProfileEditForm
from datetime import date
import logging
import csv
+from enum import Enum
+import json
from various.views.pomocne import formularOKView
from various.autentizace.views import LoginView
@@ -140,7 +143,55 @@ class OrgoRozcestnikView(TemplateView):
#content_type = 'text/plain; charset=UTF8'
#XXX
+
+class PrvniTypExportu(Enum):
+ CISLA = 1
+ ROCNIKU = 2
+ SOUSTREDENI = 4
+class ExportLidiView(TemplateView):
+ template_name = 'personalni/profil/export_lidi.html'
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['typy_exportu'] = json.dumps({member.value: member.name.lower().capitalize() for member in PrvniTypExportu})
+ return context
+
+
+def get_export_options(request, type):
+ if type == PrvniTypExportu.CISLA.value:
+ data = [{"id": c.id, "display": str(c)} for c in Cislo.objects.all()]
+ if type == PrvniTypExportu.ROCNIKU.value:
+ data = [{"id": r.id, "display": str(r)} for r in Rocnik.objects.all()]
+ if type == PrvniTypExportu.SOUSTREDENI.value:
+ data = [{"id": s.id, "display": str(s)} for s in Soustredeni.objects.all()]
+ return HttpResponse(json.dumps(data), content_type='application/json')
+
+def download_export_csv_only_first_step(request, type):
+ if type == 3:
+ response = dataResiteluCsvResponse(tvorba_utils.resitele_co_neodmaturovali())
+ response['Content-Disposition'] = 'attachment; filename="resitele_co_neodmaturovali.csv"'
+ return response
+
+def download_export_csv(request, type, id):
+ if type == PrvniTypExportu.CISLA.value:
+ response = dataResiteluCsvResponse(tvorba_utils.resi_cislo(Cislo.objects.get(id=id)))
+ name = str(Cislo.objects.get(id=id)).replace(" ", "_") + "_resitele_cisla.csv"
+ response['Content-Disposition'] = 'attachment; filename="' + name + '"'
+ return response
+ if type == PrvniTypExportu.ROCNIKU.value:
+ response = dataResiteluCsvResponse(tvorba_utils.resi_v_rocniku(Rocnik.objects.get(id=id)))
+ name = str(Rocnik.objects.get(id=id)).replace(" ", "_") + "_resitele_rocniku.csv"
+ response['Content-Disposition'] = 'attachment; filename="' + name + '"'
+ return response
+ if type == PrvniTypExportu.SOUSTREDENI.value:
+ soustredeni = Soustredeni.objects.get(id=id)
+ organizatori = soustredeni.organizatori.all()
+ organizatoriOsoby = Osoba.objects.filter(org__in=organizatori)
+ response = dataOsobCsvResponse(organizatoriOsoby, columns=("jmeno", "prijmeni", "email", "telefon",))
+ name = str(soustredeni).replace(" ", "_") + "_organizatori_soustredeni.csv"
+ response['Content-Disposition'] = 'attachment; filename="' + name + '"'
+ return response
class ResitelView(LoginRequiredMixin,generic.DetailView):
model = m.Resitel
@@ -470,3 +521,46 @@ def dataResiteluCsvResponse(queryset, columns=None, with_header=True):
writer.writerows(queryset_list)
return response
+
+def dataOsobCsvResponse(queryset, columns=None, with_header=True):
+ """Pomocná funkce pro vracení dat osob jako CSV. Musí dostat správný QuerySet, který dává Ososby"""
+
+ default_columns = (
+ 'id',
+ 'jmeno',
+ 'prijmeni',
+ 'prezdivka',
+ 'email',
+ 'telefon',
+ 'datum_narozeni',
+ 'osloveni',
+ 'ulice',
+ 'mesto',
+ 'psc',
+ 'stat',
+ 'jak_se_dozvedeli',
+ 'poznamka',
+ 'datum_registrace',
+ 'datum_souhlasu_udaje',
+ 'datum_souhlasu_zasilani',
+ )
+
+ if columns is None: columns = default_columns
+
+ def get_field_name(column_name):
+ return column_name
+
+ response = HttpResponse(content_type='text/csv')
+ writer = csv.writer(response)
+
+ # První řádek je záhlaví
+ if with_header:
+ writer.writerow(map(get_field_name, columns))
+
+ # Data:
+ queryset_list = queryset.values_list(*columns)
+ writer.writerows(queryset_list)
+
+ return response
+
+
diff --git a/tvorba/utils.py b/tvorba/utils.py
index c2feadd9..312e83e6 100644
--- a/tvorba/utils.py
+++ b/tvorba/utils.py
@@ -27,6 +27,30 @@ def resi_v_rocniku(rocnik, cislo=None):
reseni__hodnoceni__deadline_body__cislo__rocnik=rocnik,
reseni__hodnoceni__deadline_body__cislo__poradi__lte=cislo.poradi
).distinct()
+
+def resi_cislo(cislo):
+ """ Vrátí seznam řešitelů, co vyřešili nějaký problém v daném čísle.
+ Parametry:
+ cislo (typu Cislo) číslo, ve kterém chci řešitele, co něco odevzdali
+ Výstup:
+ QuerySet objektů typu Resitel
+ """
+
+ return personalni.models.Resitel.objects.filter(
+ reseni__hodnoceni__deadline_body__cislo=cislo
+ ).distinct()
+
+def resitele_co_neodmaturovali():
+ """ Vrátí seznam řešitelů, co ještě neodmaturovali.
+ Pokud ještě není srpen, tak zahrnuje i ty, kteří odmaturovali letos.
+
+ Výstup:
+ QuerySet objektů typu Resitel """
+ from datetime import datetime
+ current_year = datetime.now().year
+ if datetime.now().month < 8:
+ current_year -= 1
+ return personalni.models.Resitel.objects.filter(rok_maturity__gte=current_year)
def aktivniResitele(cislo, pouze_letosni=False):