]> wagnertech.de Git - SVBaL.git/blob - python/eh_app/views.py
Bug 170 + check feature
[SVBaL.git] / python / eh_app / views.py
1 import os,sys
2
3 from django.contrib.auth.decorators import login_required
4 from django.http import HttpResponse, HttpResponseRedirect, FileResponse
5 from django.shortcuts import render
6 from django.template import loader
7
8 from .AWK import config, routines, util
9 #import .forms 
10 from .forms import (
11     EhmeldungForm, 
12     VorlagenForm, 
13     BeitragForm, 
14     VorlagenVerwaltungForm, 
15     MitgliederForm, 
16     MitgliederAuswahlForm, 
17     DatenfileVerwaltungForm )
18 from eh_app.AWK.pdf_ersteller import PdfErsteller
19
20 from mysite import settings
21 import time
22
23 # Create your views here.
24
25 # change working dir due to relative paths in scripts
26 os.chdir(settings.BASE_DIR)
27
28 try:
29     home = os.environ["HOME"]
30     if os.path.exists(f"{home}/.eclipse/org.eclipse.platform_4.18.0_1473617060_linux_gtk_x86_64/plugins/org.python.pydev.core_8.3.0.202104101217/pysrc/"):
31         # its a eclipse development environment
32         sys.path.append(f"{home}/.eclipse/org.eclipse.platform_4.18.0_1473617060_linux_gtk_x86_64/plugins/org.python.pydev.core_8.3.0.202104101217/pysrc/")
33         import pydevd
34         pydevd.settrace()
35
36 except:
37     pass
38
39 LOGIN_URL = "/eh-app/login"
40
41 def erstelle_datenquelle_liste(data_path):
42     dirlist = None
43     vorlagen_liste = []
44     if os.path.isdir(data_path):
45         dirlist = os.listdir(data_path) # returns list
46     if dirlist:
47         for t in dirlist:
48             vorlagen_liste.append((t,t))
49     return vorlagen_liste
50
51 def erstelle_vorlagen_liste(verein):
52     # Erstelle Vorlagenliste
53     os.chdir(settings.BASE_DIR)
54     dirlist = os.listdir()
55     util.schreibe_log(str(dirlist))
56     dirlist = None
57     vorlagen_liste = []
58     if os.path.isdir("eh_app/templates/"+verein):
59         dirlist = os.listdir("eh_app/templates/"+verein) # returns list
60     if dirlist:
61         for t in dirlist:
62             tpl_name_wo_ext = os.path.splitext(t)[0]
63             vorlagen_liste.append((t,tpl_name_wo_ext))
64     return vorlagen_liste
65
66 def check(request, verein):
67     # überprüft, ob für den gegebenen Verein alles angelegt ist
68     check_erg = {}
69     vconf = config.getInstance(verein)
70     data_path  = vconf.getConfig("data_path")
71     check_erg["data_path"] = "ok"
72     if not data_path:
73         data_path = f"auf /var/mysite/eh_app/{verein}"
74         vconf.setConfig("data_path", data_path)
75         check_erg["data_path"] = f"auf /var/mysite/eh_app/{verein} gesetzt"
76
77     ehappdir  = vconf.getConfig("ehappdir", "/opt/eh_app")
78     vereinchecker = f"{ehappdir}/bin/ehapp-verein-check.sh"
79     check_erg["vereinchecker"] = "ok"
80     if not os.path.exists(vereinchecker):
81         check_erg["vereinchecker"] = "ehapp-verein-check.sh nicht gefunden"
82
83     rc = os.system(f'{vereinchecker} {data_path}')
84     if rc != 0:
85         check_erg["vereinchecker"] = f"ehapp-verein-check.sh fehlgeschlagen: {rc}"
86     
87     template = loader.get_template("check.html")
88     return HttpResponse(template.render(
89         {
90             "verein"    : verein, 
91             "check_erg" : check_erg }, 
92         request))
93
94 @login_required(login_url=LOGIN_URL)
95 def vorlagen_verwalten(request, verein):
96     vorlagen_liste = erstelle_vorlagen_liste(verein)
97     
98     if request.method == 'POST':
99         # Form auswerten
100         form = VorlagenVerwaltungForm(request.POST, request.FILES, vorlagen=vorlagen_liste)
101         if form.is_valid():
102             zu_loschen = form.cleaned_data['vorlagen_zu_loschen']
103             zu_install = request.FILES.get('vorlage_neu', None)
104             routines.vorlagen_verwalten(verein, zu_loschen, zu_install)
105         else:
106             raise RuntimeError(f"Form not valid: {form.errors}")
107         # Verarbeitung in routines.py aufrufen
108
109         # Wenn alles gut gegangen, zurück zum Kassenbrief
110         return HttpResponseRedirect(f'/eh-app/{verein}/kassenbrief')
111     else:
112         vorlagen_form = VorlagenVerwaltungForm(vorlagen=vorlagen_liste)
113         
114     template = loader.get_template("vorlagen_verwalten.html")
115     return HttpResponse(template.render(
116         {
117             "verein" : verein, 
118             "vorlagen_form" : vorlagen_form }, 
119         request))
120
121 @login_required(login_url=LOGIN_URL)
122 def datenquelle_andern(request, verein):
123     cf = config.getInstance(verein)
124     data_path = cf.requireConfig("data_path")
125     ehappdir  = cf.getConfig("ehappdir", "/opt/eh_app")
126     vereinchecker = f"{ehappdir}/bin/ehapp-verein-check.sh"
127     if not os.path.exists(vereinchecker):
128         raise RuntimeError("ehapp-verein-check.sh nicht gefunden: "+vereinchecker)
129
130     rc = os.system(f'{vereinchecker} {data_path}')
131     if rc != 0:
132         raise RuntimeError(f"ehapp-verein-check.sh fehlgeschlagen: {rc}")
133     quellen_path = os.path.join(data_path, "quellen")
134     datenquellen_liste = erstelle_datenquelle_liste(quellen_path)
135     
136     if request.method == 'POST':
137         # Form auswerten
138         form = DatenfileVerwaltungForm(
139             request.POST, 
140             request.FILES, 
141             datenquellen=datenquellen_liste)
142         if form.is_valid():
143             zu_loschen   = form.cleaned_data['dateien_zu_loschen']
144             zu_verwenden = form.cleaned_data['datei_verwendung']
145             zu_install   = request.FILES.get('datei_neu', None)
146             routines.datenquelle_andern(verein, quellen_path, zu_loschen, zu_verwenden, zu_install)
147         else:
148             raise RuntimeError(f"Form not valid: {form.errors}")
149         # Verarbeitung in routines.py aufrufen
150
151         # Wenn alles gut gegangen, zurück zum Kassenbrief
152         letzte_seite = request.POST.get("letzte_seite")
153         return HttpResponseRedirect(f'/eh-app/{verein}/{letzte_seite}')
154     else:
155         form = DatenfileVerwaltungForm(datenquellen=datenquellen_liste)
156         
157     letzte_seite = request.GET.get("letzte_seite") or ""
158     template = loader.get_template("datenquelle_andern.html")
159     return HttpResponse(template.render(
160         {
161             "verein"           : verein, 
162             "datenquelle_form" : form,
163             "letzte_seite"     : letzte_seite }, 
164         request))
165
166 @login_required(login_url=LOGIN_URL)
167 def mitglieder_auswahlen(request, verein):
168     mitglieder = (request.COOKIES.get('mausw2') or "").split(",")
169     config.getInstance(verein) # wird in qmodel gebraucht
170     from eh_app.qmodels import Mitglied
171     mm = Mitglied.objects.all()
172     mitglieder_liste = []
173     for m in mm:
174         mitglieder_liste.append((m.mitgliedsnr, m.nachname+" "+m.vorname))
175
176     if request.method == 'POST':
177         # Form auswerten
178         form = MitgliederAuswahlForm(
179             request.POST, 
180             request.FILES, 
181             mitglieder=mitglieder_liste)
182         if form.is_valid():
183             mg_ausw  = form.cleaned_data['mg_auswahl']
184         else:
185             raise RuntimeError(f"Form not valid: {form.errors}")
186         
187         # Wenn alles gut gegangen, zurück zum Kassenbrief
188         response = HttpResponseRedirect(f'/eh-app/{verein}/kassenbrief')
189         mg_ausw_str = ",".join(mg_ausw)
190         response.set_cookie("mausw2", mg_ausw_str)
191         return response
192     else:
193         mausw_form = MitgliederAuswahlForm(mitglieder=mitglieder_liste, initial={"mg_auswahl":mitglieder})
194         
195     template = loader.get_template("mitglieder_auswahlen.html")
196     return HttpResponse(template.render(
197         {
198             "verein" : verein, 
199             "mausw_form" : mausw_form }, 
200         request))
201
202 @login_required(login_url=LOGIN_URL)
203 def kassenbrief(request, verein):
204     '''
205     GET:
206     Diese Methode liest aus der Config die Einstellungen und zeigt sie an.
207     
208     POST: 
209     Diese Methode lädt die Zusammenfassung
210     
211     ---------------------------------------------------------------
212     Templateauswahl
213     
214     Ausgewähltes Template: <Wert aus Config>
215     Link -> Neue Templates installieren
216     ---------------------------------------------------------------
217     '''
218     
219     mg_ausw = request.COOKIES.get('mausw1') or "leer"
220     mg_zul  = request.COOKIES.get('mausw2') or "leer"
221     alles_ok = True
222     fehlertext_quelle  = ""
223     fehlertext_vorlage = ""
224     fehlertext_beitrag = ""
225     vconf = config.getInstance(verein)
226     datenquelle    = vconf.getConfig("datenquelle")
227     beitrag_basis  = vconf.getConfig("beitrag_basis", 0)
228     beitrag_zusatz = vconf.getConfig("beitrag_zusatz", 0)
229     vorlagen_liste = erstelle_vorlagen_liste(verein)
230     vorlage        = vconf.getConfig("vorlage", "")
231     mausw_form = MitgliederForm(
232         zul=mg_zul,
233         initial={"mg_auswahl"  : mg_ausw,}
234                  )
235     if request.method == 'POST':
236         # Prüfe Datenquelle
237         if not datenquelle:
238             fehlertext_quelle = "Datenquelle auswählen"
239             alles_ok = False
240         
241         # Prüfe Vorlage
242         vorlagen_form = VorlagenForm(request.POST, request.FILES, templates=vorlagen_liste)
243         if not vorlagen_form.is_valid():
244             raise RuntimeError("VorlagenForm invalid: "+str(vorlagen_form.errors))
245         vorlage = vorlagen_form.cleaned_data["vorlagen"]
246         if not vorlage:
247             fehlertext_vorlage = "Bitte Kassenbriefvorlage auswählen"
248             alles_ok = False
249
250         # Prüfe Beiträge
251         beitrag_form = BeitragForm(request.POST, request.FILES)
252         if not beitrag_form.is_valid():
253             raise RuntimeError("BeitragForm invalid: Formular nochmal schicken")
254         beitrag_basis  = beitrag_form.cleaned_data["basisbeitrag"]
255         beitrag_zusatz = beitrag_form.cleaned_data["zusatzbeitrag"]
256         if beitrag_basis == 0 or beitrag_zusatz == 0:
257             fehlertext_beitrag = "Beiträge ausfüllen"
258             alles_ok = False
259
260         routines.aktualisiere_config(vconf, vorlage, beitrag_form.cleaned_data)
261         
262         # Speichere Migliederauswahl in Cookie
263         mausw_form = MitgliederForm(request.POST, request.FILES)
264         if not mausw_form.is_valid():
265             raise RuntimeError("MitgliederForm invalid: "+str(mausw_form.errors))
266         mausw = mausw_form.cleaned_data["mg_auswahl"]
267         
268         
269         if alles_ok:
270             response = HttpResponseRedirect('zusammenfassung')
271             response.set_cookie("mausw1", mausw)
272             return response
273
274     # GET request / POST mit Fehlern
275     vorlagen_form = VorlagenForm(
276         templates=vorlagen_liste,
277         initial={'vorlagen' : vorlage } )
278     beitrag_form = BeitragForm(
279         initial={
280             "basisbeitrag"  : beitrag_basis,
281             "zusatzbeitrag" : beitrag_zusatz,
282     })
283     return render(request, 'kassenbrief.html', {
284         "datenquelle"  : datenquelle or "Keine Datenquelle ausgewählt",
285         'vorlagen_form': vorlagen_form, 
286         'beitrag_form' : beitrag_form, 
287         'mausw_form'   : mausw_form, 
288         'verein'       : verein,
289         'fehler_quelle': fehlertext_quelle
290     })
291
292 @login_required(login_url=LOGIN_URL)
293 def kassenbrief_zusammenfassung(request, verein):
294     vconf = config.getInstance(verein)
295     datenquelle    = vconf.getConfig("datenquelle")
296     beitrag_basis  = vconf.getConfig("beitrag_basis", 0)
297     beitrag_zusatz = vconf.getConfig("beitrag_zusatz", 0)
298     vorlage        = vconf.getConfig("vorlage")
299     mitglieder     = request.COOKIES.get('mausw1')
300     if mitglieder == "zul":
301         mitglieder = request.COOKIES.get('mausw2')
302     if request.method == 'POST':
303         post = request.POST
304         if "erstellen" in post:
305             data_path  = vconf.getConfig("data_path", "/var/ehapp")
306             build_name = time.strftime("%Y%m%d%H%M%S", time.localtime())
307
308             rc, anzahl, gesamtbetrag = routines.pdfs_erstellen(request, verein, mitglieder, vorlage, data_path, build_name)
309             if rc != 0:
310                 return HttpResponseRedirect(f'/eh-app/{verein}/kassenbrief/kein_erfolg?rc={rc}')
311             response = HttpResponseRedirect(f'/eh-app/{verein}/kassenbrief/erfolg')
312             response.set_cookie("build_name", build_name)
313             response.set_cookie("anzahl", anzahl)
314             response.set_cookie("gesamtbetrag", gesamtbetrag)
315             return response
316         else:
317             return HttpResponseRedirect(f'/eh-app/{verein}/kassenbrief')
318         
319     else:
320         tpl_name_wo_ext = os.path.splitext(vorlage)[0]
321         return render(request, 'kassenbrief_zusammenfassung.html', {
322             'verein'        : verein,
323             'datenquelle'   : datenquelle,
324             'vorlage'       : tpl_name_wo_ext,
325             'basisbeitrag'  : beitrag_basis,
326             'zusatzbeitrag' : beitrag_zusatz,
327             'miglieder'     : mitglieder        })
328
329 @login_required(login_url=LOGIN_URL)
330 def kassenbrief_erfolg(request, verein):
331     return render(request, 'kassenbrief_erfolg.html', {
332             'verein'       : verein,
333             'anzahl'       : request.COOKIES.get('anzahl'),
334             'gesamtbetrag' : request.COOKIES.get('gesamtbetrag'),
335         })
336
337 def kassenbrief_kein_erfolg(request, verein):
338     rc = request.GET.get("rc", "unknown")
339     return HttpResponse(f"<html><body><h1>Die PDF-Erzeugung schlug fehl</h1><p>Fehlercode: {rc}</p><p>Kontaktieren Sie Ihren Systembetreuer.</p></body></html>")
340
341 @login_required(login_url=LOGIN_URL)
342 def kassenbrief_download(request, verein):
343     vconf = config.getInstance(verein)
344     data_path  = vconf.getConfig("data_path", "/var/ehapp")
345     build_name = request.COOKIES.get('build_name')
346     
347     ergebnis_datei = os.path.join(data_path, "build", build_name, "ergebnis.tgz")
348
349     response = FileResponse(open(ergebnis_datei, 'rb'), as_attachment=True, filename=f"{build_name}.tgz")
350     return response
351
352 @login_required(login_url=LOGIN_URL)
353 def ehmeldung(request, verein):
354     # if this is a POST request we need to process the form data
355     if request.method == 'POST':
356         # create a form instance and populate it with data from the request:
357         form = EhmeldungForm(request.POST, request.FILES)
358         # check whether it's valid:
359         if form.is_valid():
360             # bei Änderungen Konfiguration aktualisieren
361             routines.erstelle_ehmeldung(form.cleaned_data, verein)
362             routines.erstelle_ausweis(form.cleaned_data, verein)
363             # redirect to a new URL:
364             return HttpResponseRedirect(f'/eh-app/{verein}/ehmeldung/erfolg')
365
366     # if a GET (or any other method) we'll create a blank form
367     else:
368         form = EhmeldungForm()
369
370     return render(request, 'ehmeldung.html', {'form': form, 'verein': verein})
371
372 @login_required(login_url=LOGIN_URL)
373 def ehmeldung_erfolg(request, verein):
374     return render(request, 'ehmeldung_erfolg.html', {
375             'verein'       : verein,
376         })
377
378 @login_required(login_url=LOGIN_URL)
379 def ehmeldung_download(request, verein):
380     vconf = config.getInstance(verein)
381     data_path  = vconf.requireConfig("data_path")
382     
383     ergebnis_datei = os.path.join(data_path, "build", "meldung.pdf")
384
385     response = FileResponse(open(ergebnis_datei, 'rb'), as_attachment=True, filename="meldung.pdf")
386     return response
387
388 @login_required(login_url=LOGIN_URL)
389 def ausweis_download(request, verein):
390     vconf = config.getInstance(verein)
391     data_path  = vconf.requireConfig("data_path")
392     
393     ergebnis_datei = os.path.join(data_path, "build", "ausweis.pdf")
394
395     response = FileResponse(open(ergebnis_datei, 'rb'), as_attachment=True, filename="ausweis.pdf")
396     return response
397
398 @login_required(login_url=LOGIN_URL)
399 def vertragsliste(request, verein):
400     vconf = config.getInstance(verein)
401     data_path  = vconf.requireConfig("data_path")
402     ergebnis_datei = routines.vertragsliste_erstellen(verein, data_path)
403     response = FileResponse(open(os.path.join(data_path, "build",ergebnis_datei), 'rb'), as_attachment=True, filename=ergebnis_datei)
404     return response
405
406 def index(request, verein):
407     if request.user.is_authenticated:
408         print("index login ok")
409     else:
410         print("index not logged in")
411
412     datenquelle = config.getInstance(verein).getConfig("datenquelle")
413
414     template = loader.get_template('eh_app.html')
415     response = HttpResponse(template.render(
416         {"verein"      : verein,
417          "verein_name" : verein,
418          "datenquelle" : datenquelle,
419         }, request))
420     return response    
421
422 def login(request):
423     from django.contrib import auth
424     from .forms import LoginForm
425
426     fehlertext = ""
427     # if this is a POST request we need to process the form data
428     if request.method == 'POST':
429         # create a form instance and populate it with data from the request:
430         form = LoginForm(request.POST, request.FILES)
431         # check whether it's valid:
432         if form.is_valid():
433             user = auth.authenticate(
434                 username = request.POST["name"], 
435                 password = request.POST["password"],
436             )
437             verein = request.POST["verein"]
438         if user is not None:
439             
440             # check group
441             for group in user.groups.all():
442                 if group.name == verein:
443                     auth.login(request, user)
444                     if request.user.is_authenticated:
445                         auth.login(request, user)
446                         next = request.POST.get("next", None)
447                         if next:
448                             return HttpResponseRedirect(next)
449                         else:
450                             return HttpResponseRedirect(f'/eh-app/{verein}')
451         # login fehlgeschlagen
452         fehlertext = "Login fehlgeschlagen"
453
454     # if a GET (or any other method) we'll create a blank form
455     else:
456         next   = None
457         verein = ""
458         next = request.GET.get("next", None)
459         if next:
460             path_elems = next.split("/")
461             verein = path_elems[2]
462         form = LoginForm(initial={'next': next, 'verein': verein})
463
464     return render(request, 'login.html', {'form': form, 'fehlertext': fehlertext})
465