Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# (c) 2018-2020
2# MPIB <https://www.mpib-berlin.mpg.de/>,
3# MPI-CBS <https://www.cbs.mpg.de/>,
4# MPIP <http://www.psych.mpg.de/>
5#
6# This file is part of Castellum.
7#
8# Castellum is free software; you can redistribute it and/or modify it
9# under the terms of the GNU Affero General Public License as published
10# by the Free Software Foundation; either version 3 of the License, or
11# (at your option) any later version.
12#
13# Castellum is distributed in the hope that it will be useful, but
14# WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16# Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public
19# License along with Castellum. If not, see
20# <http://www.gnu.org/licenses/>.
22import datetime
24from django.contrib import messages
25from django.core.exceptions import ObjectDoesNotExist
26from django.shortcuts import redirect
27from django.urls import reverse
28from django.utils.translation import gettext_lazy as _
29from django.views.generic import DetailView
30from django.views.generic import FormView
31from django.views.generic import ListView
33from castellum.castellum_auth.mixins import PermissionRequiredMixin
34from castellum.contacts.mixins import BaseContactUpdateView
35from castellum.pseudonyms.forms import PseudonymForm
36from castellum.pseudonyms.helpers import get_subject
37from castellum.recruitment.mixins import BaseAttributeSetUpdateView
38from castellum.recruitment.mixins import BaseCalendarView
39from castellum.recruitment.mixins import ParticipationRequestMixin
40from castellum.recruitment.models import Appointment
41from castellum.recruitment.models import ParticipationRequest
42from castellum.studies.mixins import StudyMixin
43from castellum.studies.models import Study
44from castellum.subjects.mixins import BaseAdditionalInfoUpdateView
45from castellum.subjects.mixins import BaseDataProtectionUpdateView
48class StudyDetailView(StudyMixin, PermissionRequiredMixin, DetailView):
49 template_name = 'execution/study_detail.html'
50 model = Study
51 permission_required = 'recruitment.view_participation_pseudonyms'
52 study_status = [Study.EXECUTION]
54 def get_object(self):
55 return self.study
57 def get_context_data(self, **kwargs):
58 context = super().get_context_data(**kwargs)
60 context['list'] = []
61 prs = self.study.participationrequest_set\
62 .filter(status=ParticipationRequest.INVITED)\
63 .select_related('subject')
64 for pr in prs: 64 ↛ 65line 64 didn't jump to line 65, because the loop on line 64 never started
65 has_access = self.request.user.has_privacy_level(pr.subject.privacy_level)
66 context['list'].append((pr, has_access))
68 return context
71class ParticipationRequestDetailView(
72 ParticipationRequestMixin, PermissionRequiredMixin, DetailView
73):
74 template_name = 'execution/participationrequest_detail.html'
75 model = ParticipationRequest
76 permission_required = 'recruitment.view_participation_pseudonyms'
77 study_status = [Study.EXECUTION]
78 participationrequest_status = [ParticipationRequest.INVITED]
80 def get_object(self):
81 return self.participationrequest
84class ResolveView(StudyMixin, PermissionRequiredMixin, FormView):
85 template_name = 'execution/study_resolve.html'
86 permission_required = 'recruitment.view_participation_pseudonyms'
87 study_status = [Study.EXECUTION]
88 form_class = PseudonymForm
90 def form_valid(self, form):
91 try:
92 subject = get_subject(self.study.domain, form.cleaned_data['pseudonym'])
93 pr = ParticipationRequest.objects.filter(
94 study=self.study,
95 subject=subject,
96 status=ParticipationRequest.INVITED,
97 ).get()
98 return redirect('execution:participationrequest-detail', self.study.pk, pr.pk)
99 except ObjectDoesNotExist:
100 messages.warning(self.request, _('No match found'))
101 return self.render_to_response(self.get_context_data(form=form))
104class ExecutionUpdateMixin(ParticipationRequestMixin):
105 study_status = [Study.EXECUTION]
106 participationrequest_status = [ParticipationRequest.INVITED]
108 def get_success_url(self):
109 return reverse(
110 'execution:participationrequest-detail',
111 args=[self.kwargs['study_pk'], self.kwargs['pk']],
112 )
114 def get_context_data(self, **kwargs):
115 context = super().get_context_data(**kwargs)
116 context['base_template'] = "execution/base.html"
117 return context
119 def get_permission_required(self):
120 permission_required = {'recruitment.view_participation_pseudonyms'}
121 permission_required.update(super().get_permission_required())
122 return permission_required
125class ContactUpdateView(ExecutionUpdateMixin, BaseContactUpdateView):
126 def get_object(self):
127 return self.participationrequest.subject.contact
130class AttributeSetUpdateView(ExecutionUpdateMixin, BaseAttributeSetUpdateView):
131 def get_object(self):
132 return self.participationrequest.subject.attributeset
135class DataProtectionUpdateView(ExecutionUpdateMixin, BaseDataProtectionUpdateView):
136 def get_object(self):
137 return self.participationrequest.subject
140class AdditionalInfoUpdateView(ExecutionUpdateMixin, BaseAdditionalInfoUpdateView):
141 def get_object(self):
142 return self.participationrequest.subject
145class CalendarView(StudyMixin, PermissionRequiredMixin, BaseCalendarView):
146 model = Study
147 permission_required = 'recruitment.view_participationrequest'
148 study_status = [Study.EXECUTION]
149 feed = 'execution:calendar-feed'
151 def get_context_data(self, **kwargs):
152 context = super().get_context_data(**kwargs)
153 context['base_template'] = "execution/base.html"
154 return context
156 def render_appointment(self, appointment):
157 return {
158 'title': appointment.session.name,
159 'start': appointment.start,
160 'end': appointment.end,
161 'url': reverse('execution:participationrequest-detail', args=[
162 self.object.pk, appointment.participant.pk
163 ]),
164 }
166 def get_appointments(self):
167 return super().get_appointments().filter(session__study=self.object)
170class ReceptionView(PermissionRequiredMixin, ListView):
171 model = Appointment
172 template_name = 'execution/reception.html'
173 permission_required = 'recruitment.search_execution'
175 def get_queryset(self):
176 return super().get_queryset().filter(
177 participant__status=ParticipationRequest.INVITED,
178 start__date=datetime.date.today(),
179 ).order_by('start')