Hide keyboard shortcuts

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/>. 

21 

22import datetime 

23 

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 

32 

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 

46 

47 

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] 

53 

54 def get_object(self): 

55 return self.study 

56 

57 def get_context_data(self, **kwargs): 

58 context = super().get_context_data(**kwargs) 

59 

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)) 

67 

68 return context 

69 

70 

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] 

79 

80 def get_object(self): 

81 return self.participationrequest 

82 

83 

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 

89 

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)) 

102 

103 

104class ExecutionUpdateMixin(ParticipationRequestMixin): 

105 study_status = [Study.EXECUTION] 

106 participationrequest_status = [ParticipationRequest.INVITED] 

107 

108 def get_success_url(self): 

109 return reverse( 

110 'execution:participationrequest-detail', 

111 args=[self.kwargs['study_pk'], self.kwargs['pk']], 

112 ) 

113 

114 def get_context_data(self, **kwargs): 

115 context = super().get_context_data(**kwargs) 

116 context['base_template'] = "execution/base.html" 

117 return context 

118 

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 

123 

124 

125class ContactUpdateView(ExecutionUpdateMixin, BaseContactUpdateView): 

126 def get_object(self): 

127 return self.participationrequest.subject.contact 

128 

129 

130class AttributeSetUpdateView(ExecutionUpdateMixin, BaseAttributeSetUpdateView): 

131 def get_object(self): 

132 return self.participationrequest.subject.attributeset 

133 

134 

135class DataProtectionUpdateView(ExecutionUpdateMixin, BaseDataProtectionUpdateView): 

136 def get_object(self): 

137 return self.participationrequest.subject 

138 

139 

140class AdditionalInfoUpdateView(ExecutionUpdateMixin, BaseAdditionalInfoUpdateView): 

141 def get_object(self): 

142 return self.participationrequest.subject 

143 

144 

145class CalendarView(StudyMixin, PermissionRequiredMixin, BaseCalendarView): 

146 model = Study 

147 permission_required = 'recruitment.view_participationrequest' 

148 study_status = [Study.EXECUTION] 

149 feed = 'execution:calendar-feed' 

150 

151 def get_context_data(self, **kwargs): 

152 context = super().get_context_data(**kwargs) 

153 context['base_template'] = "execution/base.html" 

154 return context 

155 

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 } 

165 

166 def get_appointments(self): 

167 return super().get_appointments().filter(session__study=self.object) 

168 

169 

170class ReceptionView(PermissionRequiredMixin, ListView): 

171 model = Appointment 

172 template_name = 'execution/reception.html' 

173 permission_required = 'recruitment.search_execution' 

174 

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')