vkk.workhours.contributor.views
This submodule contains all of the class based views of this module.
1""" 2This submodule contains all of the class based views of this module. 3""" 4 5from django.views.generic import RedirectView, FormView, ListView, TemplateView 6from django.utils import timezone 7from django.db.models import Sum, Q 8from django.http import Http404 9from django.urls import reverse 10from django.shortcuts import get_object_or_404, redirect 11from django.forms import Form, modelform_factory 12from vkk.generic.views import CustomSuccessView 13from vkk.generic.mixins import OnSuccessMixin 14from vkk.workhours.models import Period, WorkHours, PeriodClosure, ProjectAssignment, WorkHoursCorrection 15from vkk.workhours.forms import PeriodSelectForm 16from .forms import WorkhourCalendarForm 17from .mixins import ContributorRequiredMixin, ContributorPeriodSelectorMixin 18 19 20class PeriodRedirect(ContributorRequiredMixin, RedirectView): 21 """ 22 Redirects a contributor to a period. 23 """ 24 25 def get_redirect_url(self, *args, **kwargs): 26 """ 27 Returns an URL to redirect to. 28 """ 29 # Catches Period Selection from GET 30 if 'period' in self.request.GET: 31 now = timezone.now() 32 query_set = Period.objects.filter( 33 Q(dead_line__gte=now) | 34 Q(workhours__project_assignment__pk=self.kwargs['assignment_pk']) | 35 Q(periodclosure__project_assignment__pk=self.kwargs['assignment_pk']) 36 ).distinct() 37 form = PeriodSelectForm(query_set, data=self.request.GET) 38 if form.is_valid(): 39 period = form.cleaned_data.get("period") 40 else: 41 raise Http404() 42 # Catches Period no given 43 elif 'period_pk' not in kwargs: 44 period = Period.objects.latest(create=True) 45 # Looks up Period 46 else: 47 period = get_object_or_404(Period, pk=kwargs['period_pk']) 48 49 return reverse( 50 'vkk:workhours:contributor:calendar', 51 args=[kwargs['assignment_pk'], period.pk] 52 ) 53 54 55class WorkhoursView(ContributorRequiredMixin, ContributorPeriodSelectorMixin, FormView): 56 """ 57 Displays a calendar for entering work hours. 58 """ 59 form_class = WorkhourCalendarForm 60 template_name = 'vkk/workhours/contributor/workhours.html' 61 62 def get_context_data(self, **kwargs): 63 """ 64 Returns a dictionary of context data used in the template layer. 65 """ 66 context = super().get_context_data(**kwargs) 67 context["project"] = ProjectAssignment.objects.select_related('project').get( 68 pk=self.kwargs['assignment_pk'] 69 ).project 70 return context 71 72 def dispatch(self, request, *args, **kwargs): 73 """ 74 Dispatches an incoming request according to its method. 75 """ 76 period = Period.objects.filter( 77 pk=self.kwargs['period_pk'], 78 dead_line__lt=timezone.now() 79 ) 80 if period.exists(): 81 return redirect('vkk:workhours:contributor:summary', **self.kwargs) 82 83 closure = PeriodClosure.objects.filter( 84 project_assignment__pk=self.kwargs['assignment_pk'], 85 period__pk=self.kwargs['period_pk'] 86 ) 87 if closure.exists() and (closure[0].is_closed_contributor or closure[0].is_closed_manager): 88 return redirect('vkk:workhours:contributor:summary', **self.kwargs) 89 return super().dispatch(request, *args, **kwargs) 90 91 def get_form_kwargs(self): 92 """ 93 Returns the key word arguments used for constructing 94 the associated `WorkhourCalendarForm` instance. 95 """ 96 kwargs = super().get_form_kwargs() 97 kwargs.update({ 98 'period_pk': self.kwargs['period_pk'], 99 'assignment_pk': self.kwargs['assignment_pk'], 100 }) 101 return kwargs 102 103 def get_success_url(self): 104 """ 105 Returns an URL to redirect to after a successfully action. 106 """ 107 return reverse( 108 'vkk:workhours:contributor:summary', 109 args=[ 110 self.kwargs['assignment_pk'], 111 self.kwargs['period_pk'] 112 ] 113 ) 114 115 def form_valid(self, form): 116 """ 117 A method, which is called, if the associated 118 `WorkhourCalendarForm` instance is valid. 119 """ 120 form.save() 121 return super().form_valid(form) 122 123 124class SummaryView(ContributorRequiredMixin, ContributorPeriodSelectorMixin, ListView): 125 """ 126 A class based view providing a summary of `WorkHours` for a given period. 127 """ 128 model = WorkHours 129 template_name = 'vkk/workhours/contributor/summary.html' 130 131 def get_queryset(self): 132 """ 133 Returns a query set of `WorkHours`, associated with the given 134 primary keys of an `ProjectAssignment` and `Period`. 135 """ 136 query_set = super().get_queryset() 137 query_set = query_set.filter( 138 project_assignment__pk=self.kwargs['assignment_pk'], 139 period__pk=self.kwargs['period_pk'] 140 ) 141 return query_set.order_by('day') 142 143 def get_context_data(self, **kwargs): 144 """ 145 Returns a dictionary of context data used in the template layer. 146 """ 147 context = super().get_context_data(**kwargs) 148 query_set = context["object_list"] 149 150 correction = WorkHoursCorrection.objects.filter( 151 project_assignment__pk=self.kwargs['assignment_pk'], 152 period__pk=self.kwargs['period_pk'] 153 ) 154 context["correction"] = correction 155 156 context.update(query_set.aggregate(Sum('hours'))) 157 if context["hours__sum"] is None: 158 context["hours__sum"] = 0 159 if correction.exists(): 160 context["hours__sum"] += correction[0].ammount 161 162 context["fields"] = ['day', 'hours'] 163 164 closure = PeriodClosure.objects.filter( 165 project_assignment__pk=self.kwargs['assignment_pk'], 166 period__pk=self.kwargs['period_pk'] 167 ) 168 if closure.exists() and (closure[0].is_closed_contributor or closure[0].is_closed_manager): 169 context['closure'] = True 170 else: 171 context['closure'] = False 172 173 context['project'] = ProjectAssignment.objects.select_related('project').get( 174 pk=self.kwargs['assignment_pk'] 175 ).project 176 177 return context 178 179 180class ClosureView(ContributorRequiredMixin, OnSuccessMixin, FormView): 181 """ 182 A class based view offering functionality to lock a given `Period` for a 183 `ProjectAssignment`. 184 """ 185 template_name = 'vkk/workhours/contributor/closure.html' 186 form_class = Form 187 on_success = 'closure_success' 188 189 def post(self, request, *args, **kwargs): 190 """ 191 Method which is called in case a POST request is dispatched. 192 """ 193 form = self.get_form() 194 model_form = modelform_factory( 195 model=PeriodClosure, 196 fields='__all__', 197 )( 198 data={ 199 'period': self.kwargs['period_pk'], 200 'project_assignment': self.kwargs['assignment_pk'], 201 'is_closed_contributor': True, 202 }, 203 ) 204 if form.is_valid and model_form.is_valid: 205 model_form.save() 206 return self.form_valid(form) 207 else: 208 return self.handle_no_permission() 209 210 211class ClosureSuccessView(ContributorRequiredMixin, CustomSuccessView): 212 """ 213 A class based view meant to offer a confirmation to a successful locking 214 of a `Period`. 215 """ 216 template_name = 'vkk/workhours/contributor/closure_success.html' 217 model = PeriodClosure 218 on_success = 'summary'
21class PeriodRedirect(ContributorRequiredMixin, RedirectView): 22 """ 23 Redirects a contributor to a period. 24 """ 25 26 def get_redirect_url(self, *args, **kwargs): 27 """ 28 Returns an URL to redirect to. 29 """ 30 # Catches Period Selection from GET 31 if 'period' in self.request.GET: 32 now = timezone.now() 33 query_set = Period.objects.filter( 34 Q(dead_line__gte=now) | 35 Q(workhours__project_assignment__pk=self.kwargs['assignment_pk']) | 36 Q(periodclosure__project_assignment__pk=self.kwargs['assignment_pk']) 37 ).distinct() 38 form = PeriodSelectForm(query_set, data=self.request.GET) 39 if form.is_valid(): 40 period = form.cleaned_data.get("period") 41 else: 42 raise Http404() 43 # Catches Period no given 44 elif 'period_pk' not in kwargs: 45 period = Period.objects.latest(create=True) 46 # Looks up Period 47 else: 48 period = get_object_or_404(Period, pk=kwargs['period_pk']) 49 50 return reverse( 51 'vkk:workhours:contributor:calendar', 52 args=[kwargs['assignment_pk'], period.pk] 53 )
Redirects a contributor to a period.
26 def get_redirect_url(self, *args, **kwargs): 27 """ 28 Returns an URL to redirect to. 29 """ 30 # Catches Period Selection from GET 31 if 'period' in self.request.GET: 32 now = timezone.now() 33 query_set = Period.objects.filter( 34 Q(dead_line__gte=now) | 35 Q(workhours__project_assignment__pk=self.kwargs['assignment_pk']) | 36 Q(periodclosure__project_assignment__pk=self.kwargs['assignment_pk']) 37 ).distinct() 38 form = PeriodSelectForm(query_set, data=self.request.GET) 39 if form.is_valid(): 40 period = form.cleaned_data.get("period") 41 else: 42 raise Http404() 43 # Catches Period no given 44 elif 'period_pk' not in kwargs: 45 period = Period.objects.latest(create=True) 46 # Looks up Period 47 else: 48 period = get_object_or_404(Period, pk=kwargs['period_pk']) 49 50 return reverse( 51 'vkk:workhours:contributor:calendar', 52 args=[kwargs['assignment_pk'], period.pk] 53 )
Returns an URL to redirect to.
Inherited Members
- django.views.generic.base.View
- View
- http_method_names
- view_is_async
- as_view
- setup
- http_method_not_allowed
- django.contrib.auth.mixins.AccessMixin
- login_url
- permission_denied_message
- raise_exception
- redirect_field_name
- get_login_url
- get_permission_denied_message
- get_redirect_field_name
- handle_no_permission
- django.views.generic.base.RedirectView
- permanent
- url
- pattern_name
- query_string
- get
- head
- post
- options
- delete
- put
- patch
56class WorkhoursView(ContributorRequiredMixin, ContributorPeriodSelectorMixin, FormView): 57 """ 58 Displays a calendar for entering work hours. 59 """ 60 form_class = WorkhourCalendarForm 61 template_name = 'vkk/workhours/contributor/workhours.html' 62 63 def get_context_data(self, **kwargs): 64 """ 65 Returns a dictionary of context data used in the template layer. 66 """ 67 context = super().get_context_data(**kwargs) 68 context["project"] = ProjectAssignment.objects.select_related('project').get( 69 pk=self.kwargs['assignment_pk'] 70 ).project 71 return context 72 73 def dispatch(self, request, *args, **kwargs): 74 """ 75 Dispatches an incoming request according to its method. 76 """ 77 period = Period.objects.filter( 78 pk=self.kwargs['period_pk'], 79 dead_line__lt=timezone.now() 80 ) 81 if period.exists(): 82 return redirect('vkk:workhours:contributor:summary', **self.kwargs) 83 84 closure = PeriodClosure.objects.filter( 85 project_assignment__pk=self.kwargs['assignment_pk'], 86 period__pk=self.kwargs['period_pk'] 87 ) 88 if closure.exists() and (closure[0].is_closed_contributor or closure[0].is_closed_manager): 89 return redirect('vkk:workhours:contributor:summary', **self.kwargs) 90 return super().dispatch(request, *args, **kwargs) 91 92 def get_form_kwargs(self): 93 """ 94 Returns the key word arguments used for constructing 95 the associated `WorkhourCalendarForm` instance. 96 """ 97 kwargs = super().get_form_kwargs() 98 kwargs.update({ 99 'period_pk': self.kwargs['period_pk'], 100 'assignment_pk': self.kwargs['assignment_pk'], 101 }) 102 return kwargs 103 104 def get_success_url(self): 105 """ 106 Returns an URL to redirect to after a successfully action. 107 """ 108 return reverse( 109 'vkk:workhours:contributor:summary', 110 args=[ 111 self.kwargs['assignment_pk'], 112 self.kwargs['period_pk'] 113 ] 114 ) 115 116 def form_valid(self, form): 117 """ 118 A method, which is called, if the associated 119 `WorkhourCalendarForm` instance is valid. 120 """ 121 form.save() 122 return super().form_valid(form)
Displays a calendar for entering work hours.
63 def get_context_data(self, **kwargs): 64 """ 65 Returns a dictionary of context data used in the template layer. 66 """ 67 context = super().get_context_data(**kwargs) 68 context["project"] = ProjectAssignment.objects.select_related('project').get( 69 pk=self.kwargs['assignment_pk'] 70 ).project 71 return context
Returns a dictionary of context data used in the template layer.
73 def dispatch(self, request, *args, **kwargs): 74 """ 75 Dispatches an incoming request according to its method. 76 """ 77 period = Period.objects.filter( 78 pk=self.kwargs['period_pk'], 79 dead_line__lt=timezone.now() 80 ) 81 if period.exists(): 82 return redirect('vkk:workhours:contributor:summary', **self.kwargs) 83 84 closure = PeriodClosure.objects.filter( 85 project_assignment__pk=self.kwargs['assignment_pk'], 86 period__pk=self.kwargs['period_pk'] 87 ) 88 if closure.exists() and (closure[0].is_closed_contributor or closure[0].is_closed_manager): 89 return redirect('vkk:workhours:contributor:summary', **self.kwargs) 90 return super().dispatch(request, *args, **kwargs)
Dispatches an incoming request according to its method.
92 def get_form_kwargs(self): 93 """ 94 Returns the key word arguments used for constructing 95 the associated `WorkhourCalendarForm` instance. 96 """ 97 kwargs = super().get_form_kwargs() 98 kwargs.update({ 99 'period_pk': self.kwargs['period_pk'], 100 'assignment_pk': self.kwargs['assignment_pk'], 101 }) 102 return kwargs
Returns the key word arguments used for constructing
the associated WorkhourCalendarForm
instance.
104 def get_success_url(self): 105 """ 106 Returns an URL to redirect to after a successfully action. 107 """ 108 return reverse( 109 'vkk:workhours:contributor:summary', 110 args=[ 111 self.kwargs['assignment_pk'], 112 self.kwargs['period_pk'] 113 ] 114 )
Returns an URL to redirect to after a successfully action.
116 def form_valid(self, form): 117 """ 118 A method, which is called, if the associated 119 `WorkhourCalendarForm` instance is valid. 120 """ 121 form.save() 122 return super().form_valid(form)
A method, which is called, if the associated
WorkhourCalendarForm
instance is valid.
Inherited Members
- django.views.generic.base.View
- View
- http_method_names
- view_is_async
- as_view
- setup
- http_method_not_allowed
- options
- django.contrib.auth.mixins.AccessMixin
- login_url
- permission_denied_message
- raise_exception
- redirect_field_name
- get_login_url
- get_permission_denied_message
- get_redirect_field_name
- handle_no_permission
- django.views.generic.base.TemplateResponseMixin
- template_engine
- response_class
- content_type
- render_to_response
- get_template_names
- django.views.generic.edit.FormMixin
- initial
- success_url
- prefix
- get_initial
- get_prefix
- get_form_class
- get_form
- form_invalid
- django.views.generic.base.ContextMixin
- extra_context
- django.views.generic.edit.ProcessFormView
- get
- post
- put
125class SummaryView(ContributorRequiredMixin, ContributorPeriodSelectorMixin, ListView): 126 """ 127 A class based view providing a summary of `WorkHours` for a given period. 128 """ 129 model = WorkHours 130 template_name = 'vkk/workhours/contributor/summary.html' 131 132 def get_queryset(self): 133 """ 134 Returns a query set of `WorkHours`, associated with the given 135 primary keys of an `ProjectAssignment` and `Period`. 136 """ 137 query_set = super().get_queryset() 138 query_set = query_set.filter( 139 project_assignment__pk=self.kwargs['assignment_pk'], 140 period__pk=self.kwargs['period_pk'] 141 ) 142 return query_set.order_by('day') 143 144 def get_context_data(self, **kwargs): 145 """ 146 Returns a dictionary of context data used in the template layer. 147 """ 148 context = super().get_context_data(**kwargs) 149 query_set = context["object_list"] 150 151 correction = WorkHoursCorrection.objects.filter( 152 project_assignment__pk=self.kwargs['assignment_pk'], 153 period__pk=self.kwargs['period_pk'] 154 ) 155 context["correction"] = correction 156 157 context.update(query_set.aggregate(Sum('hours'))) 158 if context["hours__sum"] is None: 159 context["hours__sum"] = 0 160 if correction.exists(): 161 context["hours__sum"] += correction[0].ammount 162 163 context["fields"] = ['day', 'hours'] 164 165 closure = PeriodClosure.objects.filter( 166 project_assignment__pk=self.kwargs['assignment_pk'], 167 period__pk=self.kwargs['period_pk'] 168 ) 169 if closure.exists() and (closure[0].is_closed_contributor or closure[0].is_closed_manager): 170 context['closure'] = True 171 else: 172 context['closure'] = False 173 174 context['project'] = ProjectAssignment.objects.select_related('project').get( 175 pk=self.kwargs['assignment_pk'] 176 ).project 177 178 return context
A class based view providing a summary of WorkHours
for a given period.
132 def get_queryset(self): 133 """ 134 Returns a query set of `WorkHours`, associated with the given 135 primary keys of an `ProjectAssignment` and `Period`. 136 """ 137 query_set = super().get_queryset() 138 query_set = query_set.filter( 139 project_assignment__pk=self.kwargs['assignment_pk'], 140 period__pk=self.kwargs['period_pk'] 141 ) 142 return query_set.order_by('day')
Returns a query set of WorkHours
, associated with the given
primary keys of an ProjectAssignment
and Period
.
144 def get_context_data(self, **kwargs): 145 """ 146 Returns a dictionary of context data used in the template layer. 147 """ 148 context = super().get_context_data(**kwargs) 149 query_set = context["object_list"] 150 151 correction = WorkHoursCorrection.objects.filter( 152 project_assignment__pk=self.kwargs['assignment_pk'], 153 period__pk=self.kwargs['period_pk'] 154 ) 155 context["correction"] = correction 156 157 context.update(query_set.aggregate(Sum('hours'))) 158 if context["hours__sum"] is None: 159 context["hours__sum"] = 0 160 if correction.exists(): 161 context["hours__sum"] += correction[0].ammount 162 163 context["fields"] = ['day', 'hours'] 164 165 closure = PeriodClosure.objects.filter( 166 project_assignment__pk=self.kwargs['assignment_pk'], 167 period__pk=self.kwargs['period_pk'] 168 ) 169 if closure.exists() and (closure[0].is_closed_contributor or closure[0].is_closed_manager): 170 context['closure'] = True 171 else: 172 context['closure'] = False 173 174 context['project'] = ProjectAssignment.objects.select_related('project').get( 175 pk=self.kwargs['assignment_pk'] 176 ).project 177 178 return context
Returns a dictionary of context data used in the template layer.
Inherited Members
- django.views.generic.base.View
- View
- http_method_names
- view_is_async
- as_view
- setup
- http_method_not_allowed
- options
- django.contrib.auth.mixins.AccessMixin
- login_url
- permission_denied_message
- raise_exception
- redirect_field_name
- get_login_url
- get_permission_denied_message
- get_redirect_field_name
- handle_no_permission
- django.views.generic.list.MultipleObjectTemplateResponseMixin
- template_name_suffix
- get_template_names
- django.views.generic.base.TemplateResponseMixin
- template_engine
- response_class
- content_type
- render_to_response
- django.views.generic.list.BaseListView
- get
- django.views.generic.list.MultipleObjectMixin
- allow_empty
- queryset
- paginate_by
- paginate_orphans
- context_object_name
- paginator_class
- page_kwarg
- ordering
- get_ordering
- paginate_queryset
- get_paginate_by
- get_paginator
- get_paginate_orphans
- get_allow_empty
- get_context_object_name
- django.views.generic.base.ContextMixin
- extra_context
181class ClosureView(ContributorRequiredMixin, OnSuccessMixin, FormView): 182 """ 183 A class based view offering functionality to lock a given `Period` for a 184 `ProjectAssignment`. 185 """ 186 template_name = 'vkk/workhours/contributor/closure.html' 187 form_class = Form 188 on_success = 'closure_success' 189 190 def post(self, request, *args, **kwargs): 191 """ 192 Method which is called in case a POST request is dispatched. 193 """ 194 form = self.get_form() 195 model_form = modelform_factory( 196 model=PeriodClosure, 197 fields='__all__', 198 )( 199 data={ 200 'period': self.kwargs['period_pk'], 201 'project_assignment': self.kwargs['assignment_pk'], 202 'is_closed_contributor': True, 203 }, 204 ) 205 if form.is_valid and model_form.is_valid: 206 model_form.save() 207 return self.form_valid(form) 208 else: 209 return self.handle_no_permission()
A class based view offering functionality to lock a given Period
for a
ProjectAssignment
.
190 def post(self, request, *args, **kwargs): 191 """ 192 Method which is called in case a POST request is dispatched. 193 """ 194 form = self.get_form() 195 model_form = modelform_factory( 196 model=PeriodClosure, 197 fields='__all__', 198 )( 199 data={ 200 'period': self.kwargs['period_pk'], 201 'project_assignment': self.kwargs['assignment_pk'], 202 'is_closed_contributor': True, 203 }, 204 ) 205 if form.is_valid and model_form.is_valid: 206 model_form.save() 207 return self.form_valid(form) 208 else: 209 return self.handle_no_permission()
Method which is called in case a POST request is dispatched.
Inherited Members
- django.views.generic.base.View
- View
- http_method_names
- view_is_async
- as_view
- setup
- http_method_not_allowed
- options
- django.contrib.auth.mixins.AccessMixin
- login_url
- permission_denied_message
- raise_exception
- redirect_field_name
- get_login_url
- get_permission_denied_message
- get_redirect_field_name
- handle_no_permission
- django.views.generic.base.TemplateResponseMixin
- template_engine
- response_class
- content_type
- render_to_response
- get_template_names
- django.views.generic.edit.FormMixin
- initial
- success_url
- prefix
- get_initial
- get_prefix
- get_form_class
- get_form
- get_form_kwargs
- form_valid
- form_invalid
- get_context_data
- django.views.generic.base.ContextMixin
- extra_context
- django.views.generic.edit.ProcessFormView
- get
- put
212class ClosureSuccessView(ContributorRequiredMixin, CustomSuccessView): 213 """ 214 A class based view meant to offer a confirmation to a successful locking 215 of a `Period`. 216 """ 217 template_name = 'vkk/workhours/contributor/closure_success.html' 218 model = PeriodClosure 219 on_success = 'summary'
A class based view meant to offer a confirmation to a successful locking
of a Period
.
Inherited Members
- django.views.generic.base.View
- View
- http_method_names
- view_is_async
- as_view
- setup
- http_method_not_allowed
- options
- django.contrib.auth.mixins.AccessMixin
- login_url
- permission_denied_message
- raise_exception
- redirect_field_name
- get_login_url
- get_permission_denied_message
- get_redirect_field_name
- handle_no_permission
- django.views.generic.base.TemplateView
- get
- django.views.generic.base.TemplateResponseMixin
- template_engine
- response_class
- content_type
- render_to_response
- get_template_names
- django.views.generic.base.ContextMixin
- extra_context
- get_context_data