• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

d120 / pyfeedback / 10204065558

01 Aug 2024 03:16PM UTC coverage: 89.224% (-0.8%) from 89.993%
10204065558

push

github

web-flow
Merge pull request #304 from d120/removing_old_features

Removing old features

10 of 10 new or added lines in 2 files covered. (100.0%)

16 existing lines in 2 files now uncovered.

2542 of 2849 relevant lines covered (89.22%)

0.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.57
/src/feedback/views/veranstalter.py
1
# coding=utf-8
2

3
from django import forms
1✔
4
from django.conf import settings
1✔
5
from django.views.decorators.http import require_safe
1✔
6
from django.contrib import auth
1✔
7
from django.http import HttpResponseRedirect, Http404
1✔
8
from django.urls import reverse
1✔
9
from django.shortcuts import render
1✔
10
from django.shortcuts import render_to_response
1✔
11
from django.core.mail import send_mail
1✔
12
from django.template.loader import render_to_string
1✔
13

14
from formtools.wizard.views import SessionWizardView
1✔
15
from feedback.models import Veranstaltung, Tutor, past_semester_orders, Log
1✔
16
from feedback.forms import VeranstaltungEvaluationForm, VeranstaltungBasisdatenForm, \
1✔
17
    VeranstaltungFreieFragen, VeranstaltungVeroeffentlichung, VeranstaltungDigitaleEvaluationForm
18

19

20
@require_safe
1✔
21
def login(request):
1✔
22
    if 'vid' in request.GET and 'token' in request.GET:
1✔
23
        vid = int(request.GET['vid'])
1✔
24
        token = str(request.GET['token'])
1✔
25

26
        user = auth.authenticate(vid=vid, token=token)
1✔
27
        if user:
1✔
28
            auth.login(request, user)
1✔
29
            v = Veranstaltung.objects.get(id=vid)
1✔
30
            request.session['vid'] = v.id
1✔
31
            request.session['veranstaltung'] = str(v)
1✔
32

33
            return HttpResponseRedirect(reverse('veranstalter-index'))
1✔
34

35
    return render(request, 'veranstalter/login_failed.html')
1✔
36

37

38
def veranstalter_dashboard(request):
1✔
39
    """Definiert den Dashboard für die Veranstalter-View."""
40
    if request.user.username != settings.USERNAME_VERANSTALTER:
1✔
41
        return render(request, 'veranstalter/not_authenticated.html')
1✔
42

43
    data = {}
1✔
44
    veranst = Veranstaltung.objects.get(id=request.session['vid'])
1✔
45

46
    data["veranstaltung"] = veranst
1✔
47
    data["logs"] = Log.objects.filter(veranstaltung=veranst).order_by('timestamp')
1✔
48
    data["allow_order"] = veranst.allow_order()
1✔
49

50
    if veranst.status >= Veranstaltung.STATUS_BESTELLUNG_LIEGT_VOR:
1✔
51
        bestellung = [("Evaluieren", veranst.get_evaluieren_display)]
×
52
        if veranst.evaluieren:
×
53
            bestellung.append(("Typ", veranst.get_typ_display))
×
54
            bestellung.append(("Anazhl", veranst.anzahl))
×
55
            bestellung.append(("Sprache", veranst.get_sprache_display))
×
56
            bestellung.append(("Verantwortlich", veranst.verantwortlich.__str__() + '\n'
×
57
                               + veranst.verantwortlich.anschrift + '\n'
58
                               + veranst.verantwortlich.email))
59

60
            ergebnis_empfanger_str = ""
×
61
            for empfaenger in veranst.ergebnis_empfaenger.all():
×
62
                ergebnis_empfanger_str += empfaenger.__str__() + "\n"
×
63
            bestellung.append(("Ergebnis Empfänger", ergebnis_empfanger_str))
×
64

65
            if veranst.auswertungstermin:
×
66
                bestellung.append(("Auswertungstermin", veranst.auswertungstermin))
×
67

68
            bestellung.append(("Primärdozent", veranst.primaerdozent))
×
69
            bestellung.append(("Freie Frage 1", veranst.freiefrage1))
×
70
            bestellung.append(("Freie Frage 2", veranst.freiefrage2))
×
71
            bestellung.append(("Veröffentlichen", veranst.get_veroeffentlichen_display))
×
72

73
        data["bestellung"] = bestellung
×
74

75
    return render(request, 'veranstalter/dashboard.html', data)
1✔
76

77

78
# ---------------------------------------- START WIZARD ---------------------------------------- #
79

80
# Alle Templates, die vom Wizard gebraucht werden.
81
VERANSTALTER_VIEW_TEMPLATES = {
1✔
82
    "evaluation": "formtools/wizard/evaluation.html",
83
    "basisdaten": "formtools/wizard/basisdaten.html",
84
    "digitale_eval": "formtools/wizard/digitale_evaluation.html",
85
    "freie_fragen": "formtools/wizard/freiefragen.html",
86
    "veroeffentlichen": "formtools/wizard/veroeffentlichen.html",
87
    "zusammenfassung": "formtools/wizard/zusammenfassung.html"
88
}
89

90
# Alle Schritte, die vom Wizard gebraucht werden.
91
VERANSTALTER_WIZARD_STEPS = {
1✔
92
    "evaluation": "Evaluation",
93
    "basisdaten": "Basisdaten",
94
    "digitale_eval": "Digitale Evaluation",
95
    "freie_fragen": "Freie Fragen",
96
    "veroeffentlichen": "Veroeffentlichen",
97
    "zusammenfassung": "Zusammenfassung"
98
}
99

100

101
def perform_evalution(wizard):
1✔
102
    """
103
    Wenn wir keine Vollerhebung haben, und der Veranstalter nicht evauliert, dann
104
    springt der Wizard direkt zur Zusammenfassung.
105
    """
106
    if not wizard.cached_obj.get("cleaned_data_evaluation", {}):
1✔
107
        wizard.cached_obj["cleaned_data_evaluation"] = wizard.get_cleaned_data_for_step('evaluation') or {}
1✔
108
    cleaned_data = wizard.cached_obj["cleaned_data_evaluation"]
1✔
109

110
    v = wizard.get_instance()
1✔
111

112
    if v.semester.vollerhebung:
1✔
113
        return True
1✔
114

115
    return cleaned_data.get('evaluieren', True)
1✔
116

117
def show_digital_eval_form(wizard):
1✔
118
    show_summary_form = perform_evalution(wizard)
1✔
119
    if show_summary_form:
1✔
120
        cleaned_data = wizard.get_cleaned_basisdaten()
1✔
121
        digitale_eval = cleaned_data.get('digitale_eval', '')
1✔
122
        return digitale_eval
1✔
123
    return show_summary_form
1✔
124

125

126
def swap(collection, i, j):
1✔
127
    """Einfache Swap-Funktion, die für die Darstellung von Daten in der Zusammenfassung gebraucht wird."""
128
    # swap elements of summary data and ignore IndexError of no evaluation
129
    try:
1✔
130
        collection[i], collection[j] = collection[j], collection[i]
1✔
131
    except IndexError:
1✔
132
        pass
1✔
133

134

135
class VeranstalterWizard(SessionWizardView):
1✔
136
    """Definiert den Wizard für den Bestellprozess."""
137
    form_list = [
1✔
138
        ('evaluation', VeranstaltungEvaluationForm),
139
        ('basisdaten', VeranstaltungBasisdatenForm),
140
        ('digitale_eval', VeranstaltungDigitaleEvaluationForm),
141
        ('freie_fragen', VeranstaltungFreieFragen),
142
        ('veroeffentlichen', VeranstaltungVeroeffentlichung),
143
        ('zusammenfassung', forms.Form)
144
    ]
145

146
    condition_dict = {
1✔
147
        'basisdaten': perform_evalution,
148
        'digitale_eval': show_digital_eval_form,
149
        'freie_fragen': perform_evalution,
150
        'veroeffentlichen': perform_evalution,
151
    }
152

153
    cached_obj = {}
1✔
154

155
    def dispatch(self, request, *args, **kwargs):
1✔
156
        self.cached_obj = {}
1✔
157
        return super(VeranstalterWizard, self).dispatch(request, *args, **kwargs)
1✔
158

159
    def get_instance(self):
1✔
160
        if self.cached_obj.get("veranstaltung_obj", None) is None:
1✔
161
            if 'vid' not in self.request.session:
1✔
162
                raise Http404('Ihre Session ist abgelaufen. Bitte loggen Sie sich erneut über den Link ein.')
1✔
163
            self.cached_obj["veranstaltung_obj"] = Veranstaltung.objects.\
1✔
164
                select_related().filter(id=self.request.session['vid'])[0]
165
        return self.cached_obj["veranstaltung_obj"]
1✔
166

167
    def get_all_veranstalter(self):
1✔
168
        if self.cached_obj.get("all_veranstalter", None) is None:
1✔
169
            self.cached_obj["all_veranstalter"] = self.get_instance().veranstalter.all()
1✔
170
        return self.cached_obj["all_veranstalter"]
1✔
171

172
    def get_cleaned_basisdaten(self):
1✔
173
        if not self.cached_obj.get("cleaned_data_basisdaten", {}):
1✔
174
            self.cached_obj["cleaned_data_basisdaten"] = self.get_cleaned_data_for_step('basisdaten') or {}
1✔
175
        return self.cached_obj["cleaned_data_basisdaten"]
1✔
176

177
    def get(self, request, *args, **kwargs):
1✔
178
        if self.request.user.username != settings.USERNAME_VERANSTALTER:
1✔
179
            return render(self.request, 'veranstalter/not_authenticated.html')
×
180
        veranstaltung = self.get_instance()
1✔
181
        if veranstaltung.allow_order():
1✔
182
            return super(VeranstalterWizard, self).get(request, *args, **kwargs)
1✔
183
        else:
184
            return HttpResponseRedirect(reverse('veranstalter-index'))
1✔
185

186
    def get_context_data(self, form, **kwargs):
1✔
187
        context = super(VeranstalterWizard, self).get_context_data(form=form, **kwargs)
1✔
188
        context.update({'veranstaltung': self.get_instance()})
1✔
189

190
        progressbar = []
1✔
191
        step_active = True
1✔
192
        for step_key in self.form_list:
1✔
193
            progressbar.append({
1✔
194
                'step_value': VERANSTALTER_WIZARD_STEPS[step_key],
195
                'step_active': step_active,
196
                'step_key': step_key if step_key in self.steps.all else None
197
            })
198
            if step_active:
1✔
199
                if step_key == self.steps.current:
1✔
200
                    step_active = False
1✔
201
        context.update({'progressbar': progressbar})
1✔
202

203
        if self.steps.current == "basisdaten":
1✔
204
            past_sem_data = past_semester_orders(self.get_instance())
1✔
205
            context.update({'past_semester_data': past_sem_data})
1✔
206

207
        if self.steps.current == "zusammenfassung":
1✔
208
            all_form_data = []
1✔
209
            for step_form in self.form_list:
1✔
210
                form_obj = self.get_form(
1✔
211
                    step=step_form,
212
                    data=self.storage.get_step_data(step_form),
213
                    files=self.storage.get_step_files(step_form),
214
                )
215

216
                if form_obj.is_valid():
1✔
217
                    for field_key, field_obj in list(form_obj.fields.items()):
1✔
218
                        cleaned_d = form_obj.cleaned_data[field_key]
1✔
219
                        field_value = ""
1✔
220

221
                        if isinstance(field_obj, forms.fields.TypedChoiceField):
1✔
222
                            for key, choice in field_obj.choices:
1✔
223
                                if key == cleaned_d:
1✔
224
                                    field_value = choice
1✔
225
                                    break
1✔
226
                        else:
227
                            field_value = form_obj.cleaned_data[field_key]
1✔
228

229
                        field_label = field_obj.label
1✔
230

231
                        if field_label is None:
1✔
232
                            field_label = field_key
1✔
233

234
                        all_form_data.append({
1✔
235
                            'label': field_label,
236
                            'value': field_value
237
                        })
238

239
            swap(all_form_data, 5, 6)
1✔
240
            swap(all_form_data, 6, 7)
1✔
241
            context.update({'all_form_data':  all_form_data})
1✔
242
        return context
1✔
243

244
    def get_form_instance(self, step):
1✔
245
        return self.get_instance()
1✔
246

247
    def get_form_kwargs(self, step=None):
1✔
248
        kwargs = super(VeranstalterWizard, self).get_form_kwargs(step)
1✔
249

250
        if step == "basisdaten":
1✔
251
            kwargs.update({'all_veranstalter': self.get_all_veranstalter()})
1✔
252
            
253
        return kwargs
1✔
254

255
    def get_template_names(self):
1✔
256
        return [VERANSTALTER_VIEW_TEMPLATES[self.steps.current]]
1✔
257

258
    def done(self, form_list, **kwargs):
1✔
259
        cleaned_data = self.get_cleaned_basisdaten()
1✔
260
        ergebnis_empfaenger = cleaned_data.get('ergebnis_empfaenger', None)
1✔
261

262
        instance = self.get_instance()
1✔
263

264
        save_to_db(self.request, instance, form_list)
1✔
265
        context = self.get_context_data('zusammenfassung')
1✔
266
        send_mail_to_verantwortliche(ergebnis_empfaenger, context, instance)
1✔
267

268
        return render_to_response('formtools/wizard/bestellung_done.html', )
1✔
269

270

271
def send_mail_to_verantwortliche(ergebnis_empfaenger, context, veranstaltung):
1✔
272
    """
273
    Sendet eine Email an die Ergebnis-Empfaenger mit der Zusammenfassung der Bestellung.
274
    :param ergebnis_empfaenger: Empfänger der Ergebnisse
275
    :param context: E-Mail Inhalt
276
    :param veranstaltung: Veranstaltung
277
    """
278
    context.update({'veranstaltung': veranstaltung})
1✔
279

280
    msg_html = render_to_string('formtools/wizard/email_zusammenfassung.html', context)
1✔
281

282
    if ergebnis_empfaenger is not None:
1✔
283
        for e in ergebnis_empfaenger:
1✔
284
            send_mail(
1✔
285
                'Evaluation der Lehrveranstaltungen - Zusammenfassung der Daten für {}'.format(veranstaltung.name),
286
                'Nachfolgend finder Sie Informationen zu Ihrer Bestellung',
287
                settings.DEFAULT_FROM_EMAIL,
288
                [e.email],
289
                html_message=msg_html,
290
                fail_silently=False,
291
            )
292

293

294
def save_to_db(request, instance, form_list):
1✔
295
    """
296
    Speichert alle eingegebenen Daten des Wizards auf das Modell
297
    und setzt den Status einer Veranstaltung auf den nächsten validen Zustand.
298
    :param request: aktueller Request
299
    :param instance: die aktuelle Instanz
300
    :param form_list: Liste aller Forms
301
    """
302
    for form in form_list:
1✔
303
        for key, val in form.cleaned_data.items():
1✔
304
            if isinstance(form.instance, Veranstaltung):
1✔
305
                if key == 'ergebnis_empfaenger':
1✔
306
                    getattr(instance, key).set(val)
1✔
307
                else:
308
                    setattr(instance, key, val)
1✔
309
            else:
UNCOV
310
                setattr(form.instance, key, val)
×
311

312
        if hasattr(form, 'instance') and not isinstance(form.instance, Veranstaltung):
1✔
UNCOV
313
            form.instance.save()
×
314

315
    instance.set_next_state()
1✔
316
    instance.save()
1✔
317
    instance.log(request.user, is_frontend=True)
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc