vkk.workhours.manager.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.utils.translation import gettext_lazy as _
  6from django.core.exceptions import ValidationError
  7from django.urls import reverse
  8from django.forms import Form
  9from django.shortcuts import get_object_or_404
 10from django.views.generic import FormView, RedirectView
 11from vkk.generic.views import CustomDetailView, CustomUpdateView, CustomSuccessView, CustomCreateView, CustomFilterView
 12from vkk.workhours.models import Project, ProjectManager, ProjectAssignment, Period, PeriodClosure
 13from vkk.workhours.mixins import PeriodSelectorMixin
 14from vkk.generic.mixins import OnSuccessMixin
 15from vkk.workhours.forms import WorkhourSheetForm, PeriodSelectForm
 16from vkk.users.models import User, send_registration_mail
 17from .mixins import ManagerRequiredMixin
 18from .forms import ProjectRegisterContributorForm
 19
 20
 21class ManagerProjectOverView(ManagerRequiredMixin, CustomDetailView):
 22    """
 23    A class based view, which provides an overview of a project to a project manager.
 24    """
 25    model = Project
 26    slug_field = 'invoice_number'
 27    slug_url_kwarg = 'invoice_number'
 28    template_name = 'vkk/workhours/manager/details.html'
 29    fields = ['name', 'invoice_number',
 30              'department', 'contractor', 'start', 'end']
 31
 32    def get_context_data(self, **kwargs):
 33        """
 34        Returns a dictionary of data meant for the template layer.
 35        """
 36        context = super().get_context_data(**kwargs)
 37        context["managers"] = ProjectManager.objects.filter(
 38            project__invoice_number=self.kwargs['invoice_number'],
 39            manager__is_active=True,
 40        ).prefetch_related('manager').order_by('manager__last_name', 'manager__first_name')
 41        context["contributors"] = ProjectAssignment.objects.filter(
 42            project__invoice_number=self.kwargs['invoice_number'],
 43            contributor__is_active=True,
 44        ).prefetch_related('contributor').order_by('contributor__last_name', 'contributor__first_name')
 45        return context
 46
 47
 48class ManagerDetailView(ManagerRequiredMixin, CustomDetailView):
 49    """
 50    A class based view extending the `CustomDetailView` class with checks for user permissions.
 51    """
 52    pass
 53
 54
 55class ManagerUpdateView(ManagerRequiredMixin, CustomUpdateView):
 56    """
 57    A class based view extending the `CustomUpdateView` class with checks for user permissions.
 58    """
 59    pass
 60
 61
 62class ManagerSuccessView(ManagerRequiredMixin, CustomSuccessView):
 63    """
 64    A class based view extending the `CustomSuccessView` class with checks for user permissions.
 65    """
 66    pass
 67
 68
 69class ManagerRegisterContributorView(ManagerRequiredMixin, CustomCreateView):
 70    """
 71    A class based view providing functionality for registering new users.
 72    """
 73    model = User
 74    form_class = ProjectRegisterContributorForm
 75    on_success = 'register_contributor_success'
 76
 77    def form_valid(self, form):
 78        """
 79        After the associated form has been validated, a new `User` is created and
 80         assigned to the project. Returns a `HTTPResponse` object.
 81        """
 82        user = form.save()
 83        send_registration_mail(user)
 84        project = Project.objects.get(
 85            invoice_number=self.kwargs['invoice_number'])
 86        ProjectAssignment.objects.create(
 87            contributor=user,
 88            project=project,
 89            salary_level=form.cleaned_data['salary_level']
 90        )
 91        return super().form_valid(form)
 92
 93
 94class ManagerContributorCreateView(ManagerRequiredMixin, CustomCreateView):
 95    """
 96    A class based view providing functionality for assigning users to the project.
 97    """
 98    model = ProjectAssignment
 99    fields = ['salary_level']
100    on_success = 'add_contributor_success'
101    drop_key = 'pk'
102
103    def form_valid(self, form):
104        """
105        After the associated form has been validated, the given user is
106         assigned to the project. Returns a `HTTPResponse` object.
107        """
108        form.instance.contributor = User.objects.get(pk=self.kwargs['pk'])
109        form.instance.project = Project.objects.get(
110            invoice_number=self.kwargs['invoice_number'])
111        try:
112            form.instance.full_clean()
113        except ValidationError as err:
114            form.add_error(None, err)
115            return self.form_invalid(form)
116        return super().form_valid(form)
117
118
119class ManagerContributorFilterView(ManagerRequiredMixin, CustomFilterView):
120    """
121    Extends the `CustomFilterView` to offer a view for listing and filtering potential new contributors to the given project.
122    """
123    model = User
124    fields = ['last_name', 'first_name', 'email']
125    action_options = {'add_contributor': _('Add')}
126
127    def get_queryset(self):
128        """
129        Returns the query set of all `Users` excluding those, who are already contributors to the given project.
130        """
131        return super().get_queryset().exclude(
132            projectassignment__project__invoice_number=self.kwargs['invoice_number']
133        )
134
135
136class ManagerWorkhourSheetSelectionView(ManagerRequiredMixin, PeriodSelectorMixin, RedirectView):
137    """
138    A class based view providing functionality for selecting a and redirecting to specific work hours sheet.
139    """
140
141    def get_redirect_url(self, *args, **kwargs):
142        """
143        Returns an URL to redirect to based of whether a valid `Period` is provided.
144        """
145        # Catches Period Selection from GET
146        if 'period' in self.request.GET:
147            query_set = Period.objects.all()
148            form = PeriodSelectForm(query_set, data=self.request.GET)
149            if form.is_valid():
150                period = form.cleaned_data.get("period")
151            else:
152                raise Http404()
153        # Catches Period no given
154        elif 'period_pk' not in kwargs:
155            period = Period.objects.latest(create=True)
156        # Looks up Period
157        else:
158            period = get_object_or_404(Period, pk=kwargs['period_pk'])
159
160        return reverse(
161            'vkk:workhours:manager:workhours_sheet',
162            args=[kwargs['invoice_number'], period.pk]
163        )
164
165
166class ManagerWorkhourSheetView(ManagerRequiredMixin, PeriodSelectorMixin, FormView):
167    """
168    A class based view providing functionality for displaying and managing a work hours sheet at a form.
169    """
170    form_class = WorkhourSheetForm
171    template_name = 'vkk/workhours/workhours_sheet.html'
172    period_select_namespace = 'vkk:workhours:manager:workhours_sheet_selection'
173
174    def setup(self, request, *args, **kwargs):
175        """
176        Extends the `setup()` method of the parent class.
177        """
178        super().setup(request, *args, **kwargs)
179        self.assignments = ProjectAssignment.objects.filter(
180            project__invoice_number=self.kwargs['invoice_number']
181        )
182
183    def get_context_data(self, **kwargs):
184        """
185        Returns a dictionary with context data for the template layer.
186        """
187        context = super().get_context_data(**kwargs)
188        manager_closed_count = self.assignments.filter(
189            periodclosure__period=self.kwargs['period_pk'],
190            periodclosure__is_closed_manager=True
191        ).count()
192        assignment_count = self.assignments.count()
193        if manager_closed_count == assignment_count:
194            context['closed'] = True
195            context['saveable'] = False
196        else:
197            context['closed'] = False
198            context['saveable'] = True
199
200        context['project'] = get_object_or_404(
201            Project, invoice_number=self.kwargs['invoice_number'])
202        return context
203
204    def get_form_kwargs(self):
205        """
206        Returns a dictionary with keyword arguments for instantiating the form class.
207        """
208        kwargs = super().get_form_kwargs()
209        assignments = self.assignments.order_by(
210            'contributor__last_name', 'contributor__first_name')
211        kwargs.update({
212            'period_pk': self.kwargs['period_pk'],
213            'assignments': assignments,
214            'invoice_number': self.kwargs['invoice_number']
215        })
216        return kwargs
217
218    def get_success_url(self):
219        """
220        Returns a URL to redirect to after accepting and processing the form.
221        """
222        return reverse(
223            'vkk:workhours:manager:workhours_sheet_success',
224            args=[
225                self.kwargs['invoice_number'],
226                self.kwargs['period_pk']
227            ]
228        )
229
230    def form_valid(self, form):
231        """
232        Calls the `save()` method on the associated form and returns a redirect response.
233        """
234        form.save()
235        return super().form_valid(form)
236
237
238class ManagerPeriodClosureView(ManagerRequiredMixin, OnSuccessMixin, FormView):
239    """
240    A class based view providing functionality to lock work hour entries of all
241     `ProjectAssignment`s associated with the given project for a given `Period`.
242    """
243    template_name = 'vkk/workhours/contributor/closure.html'
244    form_class = Form
245    on_success = 'period_closure_success'
246
247    def post(self, request, *args, **kwargs):
248        """
249        Extends the `post()` method with functionality associated with the form handling.
250        """
251        form = self.get_form()
252        if form.is_valid():
253            self.close_period()
254            return self.form_valid(form)
255        else:
256            return self.form_invalid(form)
257
258    def close_period(self):
259        """
260        Manages `PeriodClosure` instances accordingly.
261        """
262        assignments = ProjectAssignment.objects.filter(
263            project__invoice_number=self.kwargs['invoice_number'],
264        )
265        period = get_object_or_404(Period, pk=self.kwargs['period_pk'])
266        closing = [
267            PeriodClosure(
268                period=period,
269                project_assignment=assignment,
270                is_closed_contributor=True,
271                is_closed_manager=True
272            ) for assignment in assignments
273        ]
274        PeriodClosure.objects.bulk_create(
275            closing,
276            update_conflicts=True,
277            update_fields=['is_closed_contributor', 'is_closed_manager'],
278            unique_fields=['project_assignment', 'period']
279        )
280
281
282class ManagerPeriodClosureSuccessView(ManagerRequiredMixin, CustomSuccessView):
283    """
284    Extends the `CustomSuccessView` class to provide functionality for
285     displaying a successful lock of a work hours sheet.
286    """
287    template_name = 'vkk/workhours/contributor/closure_success.html'
288    model = PeriodClosure
289    on_success = 'workhours_sheet'
22class ManagerProjectOverView(ManagerRequiredMixin, CustomDetailView):
23    """
24    A class based view, which provides an overview of a project to a project manager.
25    """
26    model = Project
27    slug_field = 'invoice_number'
28    slug_url_kwarg = 'invoice_number'
29    template_name = 'vkk/workhours/manager/details.html'
30    fields = ['name', 'invoice_number',
31              'department', 'contractor', 'start', 'end']
32
33    def get_context_data(self, **kwargs):
34        """
35        Returns a dictionary of data meant for the template layer.
36        """
37        context = super().get_context_data(**kwargs)
38        context["managers"] = ProjectManager.objects.filter(
39            project__invoice_number=self.kwargs['invoice_number'],
40            manager__is_active=True,
41        ).prefetch_related('manager').order_by('manager__last_name', 'manager__first_name')
42        context["contributors"] = ProjectAssignment.objects.filter(
43            project__invoice_number=self.kwargs['invoice_number'],
44            contributor__is_active=True,
45        ).prefetch_related('contributor').order_by('contributor__last_name', 'contributor__first_name')
46        return context

A class based view, which provides an overview of a project to a project manager.

model = <class 'vkk.workhours.models.Project'>
slug_field = 'invoice_number'
slug_url_kwarg = 'invoice_number'
template_name = 'vkk/workhours/manager/details.html'
fields = ['name', 'invoice_number', 'department', 'contractor', 'start', 'end']
def get_context_data(self, **kwargs):
33    def get_context_data(self, **kwargs):
34        """
35        Returns a dictionary of data meant for the template layer.
36        """
37        context = super().get_context_data(**kwargs)
38        context["managers"] = ProjectManager.objects.filter(
39            project__invoice_number=self.kwargs['invoice_number'],
40            manager__is_active=True,
41        ).prefetch_related('manager').order_by('manager__last_name', 'manager__first_name')
42        context["contributors"] = ProjectAssignment.objects.filter(
43            project__invoice_number=self.kwargs['invoice_number'],
44            contributor__is_active=True,
45        ).prefetch_related('contributor').order_by('contributor__last_name', 'contributor__first_name')
46        return context

Returns a dictionary of data meant for 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
vkk.workhours.manager.mixins.ManagerRequiredMixin
check_field
dispatch
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
vkk.generic.views.CustomDetailView
action_options
django.views.generic.detail.SingleObjectTemplateResponseMixin
template_name_field
template_name_suffix
get_template_names
django.views.generic.base.TemplateResponseMixin
template_engine
response_class
content_type
render_to_response
django.views.generic.detail.BaseDetailView
get
django.views.generic.detail.SingleObjectMixin
queryset
context_object_name
pk_url_kwarg
query_pk_and_slug
get_object
get_queryset
get_slug_field
get_context_object_name
django.views.generic.base.ContextMixin
extra_context
49class ManagerDetailView(ManagerRequiredMixin, CustomDetailView):
50    """
51    A class based view extending the `CustomDetailView` class with checks for user permissions.
52    """
53    pass

A class based view extending the CustomDetailView class with checks for user permissions.

Inherited Members
django.views.generic.base.View
View
http_method_names
view_is_async
as_view
setup
http_method_not_allowed
options
vkk.workhours.manager.mixins.ManagerRequiredMixin
check_field
dispatch
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
vkk.generic.views.CustomDetailView
fields
action_options
template_name
django.views.generic.detail.SingleObjectTemplateResponseMixin
template_name_field
template_name_suffix
get_template_names
django.views.generic.base.TemplateResponseMixin
template_engine
response_class
content_type
render_to_response
django.views.generic.detail.BaseDetailView
get
django.views.generic.detail.SingleObjectMixin
model
queryset
slug_field
context_object_name
slug_url_kwarg
pk_url_kwarg
query_pk_and_slug
get_object
get_queryset
get_slug_field
get_context_object_name
get_context_data
django.views.generic.base.ContextMixin
extra_context
56class ManagerUpdateView(ManagerRequiredMixin, CustomUpdateView):
57    """
58    A class based view extending the `CustomUpdateView` class with checks for user permissions.
59    """
60    pass

A class based view extending the CustomUpdateView class with checks for user permissions.

Inherited Members
django.views.generic.base.View
View
http_method_names
view_is_async
as_view
setup
http_method_not_allowed
options
vkk.workhours.manager.mixins.ManagerRequiredMixin
check_field
dispatch
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
vkk.generic.views.CustomUpdateView
on_success
template_name
drop_key
vkk.generic.mixins.OnSuccessMixin
kwarg_override
get_success_url
django.views.generic.edit.UpdateView
template_name_suffix
django.views.generic.detail.SingleObjectTemplateResponseMixin
template_name_field
get_template_names
django.views.generic.base.TemplateResponseMixin
template_engine
response_class
content_type
render_to_response
django.views.generic.edit.BaseUpdateView
get
post
django.views.generic.edit.ModelFormMixin
fields
get_form_class
get_form_kwargs
form_valid
django.views.generic.edit.FormMixin
initial
form_class
success_url
prefix
get_initial
get_prefix
get_form
form_invalid
get_context_data
django.views.generic.detail.SingleObjectMixin
model
queryset
slug_field
context_object_name
slug_url_kwarg
pk_url_kwarg
query_pk_and_slug
get_object
get_queryset
get_slug_field
get_context_object_name
django.views.generic.base.ContextMixin
extra_context
django.views.generic.edit.ProcessFormView
put
63class ManagerSuccessView(ManagerRequiredMixin, CustomSuccessView):
64    """
65    A class based view extending the `CustomSuccessView` class with checks for user permissions.
66    """
67    pass

A class based view extending the CustomSuccessView class with checks for user permissions.

Inherited Members
django.views.generic.base.View
View
http_method_names
view_is_async
as_view
setup
http_method_not_allowed
options
vkk.workhours.manager.mixins.ManagerRequiredMixin
check_field
dispatch
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
vkk.generic.views.CustomSuccessView
model
on_success
vkk.generic.mixins.OnSuccessMixin
drop_key
kwarg_override
get_success_url
django.views.generic.base.TemplateView
get
django.views.generic.base.TemplateResponseMixin
template_name
template_engine
response_class
content_type
render_to_response
get_template_names
django.views.generic.base.ContextMixin
extra_context
get_context_data
70class ManagerRegisterContributorView(ManagerRequiredMixin, CustomCreateView):
71    """
72    A class based view providing functionality for registering new users.
73    """
74    model = User
75    form_class = ProjectRegisterContributorForm
76    on_success = 'register_contributor_success'
77
78    def form_valid(self, form):
79        """
80        After the associated form has been validated, a new `User` is created and
81         assigned to the project. Returns a `HTTPResponse` object.
82        """
83        user = form.save()
84        send_registration_mail(user)
85        project = Project.objects.get(
86            invoice_number=self.kwargs['invoice_number'])
87        ProjectAssignment.objects.create(
88            contributor=user,
89            project=project,
90            salary_level=form.cleaned_data['salary_level']
91        )
92        return super().form_valid(form)

A class based view providing functionality for registering new users.

model = <class 'vkk.users.models.User'>
on_success = 'register_contributor_success'
def form_valid(self, form):
78    def form_valid(self, form):
79        """
80        After the associated form has been validated, a new `User` is created and
81         assigned to the project. Returns a `HTTPResponse` object.
82        """
83        user = form.save()
84        send_registration_mail(user)
85        project = Project.objects.get(
86            invoice_number=self.kwargs['invoice_number'])
87        ProjectAssignment.objects.create(
88            contributor=user,
89            project=project,
90            salary_level=form.cleaned_data['salary_level']
91        )
92        return super().form_valid(form)

After the associated form has been validated, a new User is created and assigned to the project. Returns a HTTPResponse object.

Inherited Members
django.views.generic.base.View
View
http_method_names
view_is_async
as_view
setup
http_method_not_allowed
options
vkk.workhours.manager.mixins.ManagerRequiredMixin
check_field
dispatch
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
vkk.generic.views.CustomCreateView
template_name
vkk.generic.mixins.OnSuccessMixin
drop_key
kwarg_override
get_success_url
django.views.generic.edit.CreateView
template_name_suffix
django.views.generic.detail.SingleObjectTemplateResponseMixin
template_name_field
get_template_names
django.views.generic.base.TemplateResponseMixin
template_engine
response_class
content_type
render_to_response
django.views.generic.edit.BaseCreateView
get
post
django.views.generic.edit.ModelFormMixin
fields
get_form_class
get_form_kwargs
django.views.generic.edit.FormMixin
initial
success_url
prefix
get_initial
get_prefix
get_form
form_invalid
get_context_data
django.views.generic.detail.SingleObjectMixin
queryset
slug_field
context_object_name
slug_url_kwarg
pk_url_kwarg
query_pk_and_slug
get_object
get_queryset
get_slug_field
get_context_object_name
django.views.generic.base.ContextMixin
extra_context
django.views.generic.edit.ProcessFormView
put
 95class ManagerContributorCreateView(ManagerRequiredMixin, CustomCreateView):
 96    """
 97    A class based view providing functionality for assigning users to the project.
 98    """
 99    model = ProjectAssignment
100    fields = ['salary_level']
101    on_success = 'add_contributor_success'
102    drop_key = 'pk'
103
104    def form_valid(self, form):
105        """
106        After the associated form has been validated, the given user is
107         assigned to the project. Returns a `HTTPResponse` object.
108        """
109        form.instance.contributor = User.objects.get(pk=self.kwargs['pk'])
110        form.instance.project = Project.objects.get(
111            invoice_number=self.kwargs['invoice_number'])
112        try:
113            form.instance.full_clean()
114        except ValidationError as err:
115            form.add_error(None, err)
116            return self.form_invalid(form)
117        return super().form_valid(form)

A class based view providing functionality for assigning users to the project.

fields = ['salary_level']
on_success = 'add_contributor_success'
drop_key = 'pk'
def form_valid(self, form):
104    def form_valid(self, form):
105        """
106        After the associated form has been validated, the given user is
107         assigned to the project. Returns a `HTTPResponse` object.
108        """
109        form.instance.contributor = User.objects.get(pk=self.kwargs['pk'])
110        form.instance.project = Project.objects.get(
111            invoice_number=self.kwargs['invoice_number'])
112        try:
113            form.instance.full_clean()
114        except ValidationError as err:
115            form.add_error(None, err)
116            return self.form_invalid(form)
117        return super().form_valid(form)

After the associated form has been validated, the given user is assigned to the project. Returns a HTTPResponse object.

Inherited Members
django.views.generic.base.View
View
http_method_names
view_is_async
as_view
setup
http_method_not_allowed
options
vkk.workhours.manager.mixins.ManagerRequiredMixin
check_field
dispatch
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
vkk.generic.views.CustomCreateView
template_name
vkk.generic.mixins.OnSuccessMixin
kwarg_override
get_success_url
django.views.generic.edit.CreateView
template_name_suffix
django.views.generic.detail.SingleObjectTemplateResponseMixin
template_name_field
get_template_names
django.views.generic.base.TemplateResponseMixin
template_engine
response_class
content_type
render_to_response
django.views.generic.edit.BaseCreateView
get
post
django.views.generic.edit.ModelFormMixin
get_form_class
get_form_kwargs
django.views.generic.edit.FormMixin
initial
form_class
success_url
prefix
get_initial
get_prefix
get_form
form_invalid
get_context_data
django.views.generic.detail.SingleObjectMixin
queryset
slug_field
context_object_name
slug_url_kwarg
pk_url_kwarg
query_pk_and_slug
get_object
get_queryset
get_slug_field
get_context_object_name
django.views.generic.base.ContextMixin
extra_context
django.views.generic.edit.ProcessFormView
put
120class ManagerContributorFilterView(ManagerRequiredMixin, CustomFilterView):
121    """
122    Extends the `CustomFilterView` to offer a view for listing and filtering potential new contributors to the given project.
123    """
124    model = User
125    fields = ['last_name', 'first_name', 'email']
126    action_options = {'add_contributor': _('Add')}
127
128    def get_queryset(self):
129        """
130        Returns the query set of all `Users` excluding those, who are already contributors to the given project.
131        """
132        return super().get_queryset().exclude(
133            projectassignment__project__invoice_number=self.kwargs['invoice_number']
134        )

Extends the CustomFilterView to offer a view for listing and filtering potential new contributors to the given project.

model = <class 'vkk.users.models.User'>
fields = ['last_name', 'first_name', 'email']
action_options = {'add_contributor': 'Hinzufügen'}
def get_queryset(self):
128    def get_queryset(self):
129        """
130        Returns the query set of all `Users` excluding those, who are already contributors to the given project.
131        """
132        return super().get_queryset().exclude(
133            projectassignment__project__invoice_number=self.kwargs['invoice_number']
134        )

Returns the query set of all Users excluding those, who are already contributors to the given project.

Inherited Members
django.views.generic.base.View
View
http_method_names
view_is_async
as_view
setup
http_method_not_allowed
options
vkk.workhours.manager.mixins.ManagerRequiredMixin
check_field
dispatch
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
vkk.generic.views.CustomFilterView
template_name
filter_fields
get_filter_fields
get_filter
get
get_context_data
vkk.generic.views.CustomListView
keys
paginate_by
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.MultipleObjectMixin
allow_empty
queryset
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
class ManagerWorkhourSheetSelectionView(vkk.workhours.manager.mixins.ManagerRequiredMixin, vkk.workhours.mixins.PeriodSelectorMixin, django.views.generic.base.RedirectView):
137class ManagerWorkhourSheetSelectionView(ManagerRequiredMixin, PeriodSelectorMixin, RedirectView):
138    """
139    A class based view providing functionality for selecting a and redirecting to specific work hours sheet.
140    """
141
142    def get_redirect_url(self, *args, **kwargs):
143        """
144        Returns an URL to redirect to based of whether a valid `Period` is provided.
145        """
146        # Catches Period Selection from GET
147        if 'period' in self.request.GET:
148            query_set = Period.objects.all()
149            form = PeriodSelectForm(query_set, data=self.request.GET)
150            if form.is_valid():
151                period = form.cleaned_data.get("period")
152            else:
153                raise Http404()
154        # Catches Period no given
155        elif 'period_pk' not in kwargs:
156            period = Period.objects.latest(create=True)
157        # Looks up Period
158        else:
159            period = get_object_or_404(Period, pk=kwargs['period_pk'])
160
161        return reverse(
162            'vkk:workhours:manager:workhours_sheet',
163            args=[kwargs['invoice_number'], period.pk]
164        )

A class based view providing functionality for selecting a and redirecting to specific work hours sheet.

def get_redirect_url(self, *args, **kwargs):
142    def get_redirect_url(self, *args, **kwargs):
143        """
144        Returns an URL to redirect to based of whether a valid `Period` is provided.
145        """
146        # Catches Period Selection from GET
147        if 'period' in self.request.GET:
148            query_set = Period.objects.all()
149            form = PeriodSelectForm(query_set, data=self.request.GET)
150            if form.is_valid():
151                period = form.cleaned_data.get("period")
152            else:
153                raise Http404()
154        # Catches Period no given
155        elif 'period_pk' not in kwargs:
156            period = Period.objects.latest(create=True)
157        # Looks up Period
158        else:
159            period = get_object_or_404(Period, pk=kwargs['period_pk'])
160
161        return reverse(
162            'vkk:workhours:manager:workhours_sheet',
163            args=[kwargs['invoice_number'], period.pk]
164        )

Returns an URL to redirect to based of whether a valid Period is provided.

Inherited Members
django.views.generic.base.View
View
http_method_names
view_is_async
as_view
setup
http_method_not_allowed
vkk.workhours.manager.mixins.ManagerRequiredMixin
check_field
dispatch
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
vkk.workhours.mixins.PeriodSelectorMixin
period_select_namespace
get_context_data
get_select_url
django.views.generic.base.RedirectView
permanent
url
pattern_name
query_string
get
head
post
options
delete
put
patch
class ManagerWorkhourSheetView(vkk.workhours.manager.mixins.ManagerRequiredMixin, vkk.workhours.mixins.PeriodSelectorMixin, django.views.generic.edit.FormView):
167class ManagerWorkhourSheetView(ManagerRequiredMixin, PeriodSelectorMixin, FormView):
168    """
169    A class based view providing functionality for displaying and managing a work hours sheet at a form.
170    """
171    form_class = WorkhourSheetForm
172    template_name = 'vkk/workhours/workhours_sheet.html'
173    period_select_namespace = 'vkk:workhours:manager:workhours_sheet_selection'
174
175    def setup(self, request, *args, **kwargs):
176        """
177        Extends the `setup()` method of the parent class.
178        """
179        super().setup(request, *args, **kwargs)
180        self.assignments = ProjectAssignment.objects.filter(
181            project__invoice_number=self.kwargs['invoice_number']
182        )
183
184    def get_context_data(self, **kwargs):
185        """
186        Returns a dictionary with context data for the template layer.
187        """
188        context = super().get_context_data(**kwargs)
189        manager_closed_count = self.assignments.filter(
190            periodclosure__period=self.kwargs['period_pk'],
191            periodclosure__is_closed_manager=True
192        ).count()
193        assignment_count = self.assignments.count()
194        if manager_closed_count == assignment_count:
195            context['closed'] = True
196            context['saveable'] = False
197        else:
198            context['closed'] = False
199            context['saveable'] = True
200
201        context['project'] = get_object_or_404(
202            Project, invoice_number=self.kwargs['invoice_number'])
203        return context
204
205    def get_form_kwargs(self):
206        """
207        Returns a dictionary with keyword arguments for instantiating the form class.
208        """
209        kwargs = super().get_form_kwargs()
210        assignments = self.assignments.order_by(
211            'contributor__last_name', 'contributor__first_name')
212        kwargs.update({
213            'period_pk': self.kwargs['period_pk'],
214            'assignments': assignments,
215            'invoice_number': self.kwargs['invoice_number']
216        })
217        return kwargs
218
219    def get_success_url(self):
220        """
221        Returns a URL to redirect to after accepting and processing the form.
222        """
223        return reverse(
224            'vkk:workhours:manager:workhours_sheet_success',
225            args=[
226                self.kwargs['invoice_number'],
227                self.kwargs['period_pk']
228            ]
229        )
230
231    def form_valid(self, form):
232        """
233        Calls the `save()` method on the associated form and returns a redirect response.
234        """
235        form.save()
236        return super().form_valid(form)

A class based view providing functionality for displaying and managing a work hours sheet at a form.

form_class = <class 'vkk.workhours.forms.WorkhourSheetForm'>
template_name = 'vkk/workhours/workhours_sheet.html'
period_select_namespace = 'vkk:workhours:manager:workhours_sheet_selection'
def setup(self, request, *args, **kwargs):
175    def setup(self, request, *args, **kwargs):
176        """
177        Extends the `setup()` method of the parent class.
178        """
179        super().setup(request, *args, **kwargs)
180        self.assignments = ProjectAssignment.objects.filter(
181            project__invoice_number=self.kwargs['invoice_number']
182        )

Extends the setup() method of the parent class.

def get_context_data(self, **kwargs):
184    def get_context_data(self, **kwargs):
185        """
186        Returns a dictionary with context data for the template layer.
187        """
188        context = super().get_context_data(**kwargs)
189        manager_closed_count = self.assignments.filter(
190            periodclosure__period=self.kwargs['period_pk'],
191            periodclosure__is_closed_manager=True
192        ).count()
193        assignment_count = self.assignments.count()
194        if manager_closed_count == assignment_count:
195            context['closed'] = True
196            context['saveable'] = False
197        else:
198            context['closed'] = False
199            context['saveable'] = True
200
201        context['project'] = get_object_or_404(
202            Project, invoice_number=self.kwargs['invoice_number'])
203        return context

Returns a dictionary with context data for the template layer.

def get_form_kwargs(self):
205    def get_form_kwargs(self):
206        """
207        Returns a dictionary with keyword arguments for instantiating the form class.
208        """
209        kwargs = super().get_form_kwargs()
210        assignments = self.assignments.order_by(
211            'contributor__last_name', 'contributor__first_name')
212        kwargs.update({
213            'period_pk': self.kwargs['period_pk'],
214            'assignments': assignments,
215            'invoice_number': self.kwargs['invoice_number']
216        })
217        return kwargs

Returns a dictionary with keyword arguments for instantiating the form class.

def get_success_url(self):
219    def get_success_url(self):
220        """
221        Returns a URL to redirect to after accepting and processing the form.
222        """
223        return reverse(
224            'vkk:workhours:manager:workhours_sheet_success',
225            args=[
226                self.kwargs['invoice_number'],
227                self.kwargs['period_pk']
228            ]
229        )

Returns a URL to redirect to after accepting and processing the form.

def form_valid(self, form):
231    def form_valid(self, form):
232        """
233        Calls the `save()` method on the associated form and returns a redirect response.
234        """
235        form.save()
236        return super().form_valid(form)

Calls the save() method on the associated form and returns a redirect response.

Inherited Members
django.views.generic.base.View
View
http_method_names
view_is_async
as_view
http_method_not_allowed
options
vkk.workhours.manager.mixins.ManagerRequiredMixin
check_field
dispatch
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
vkk.workhours.mixins.PeriodSelectorMixin
get_select_url
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
class ManagerPeriodClosureView(vkk.workhours.manager.mixins.ManagerRequiredMixin, vkk.generic.mixins.OnSuccessMixin, django.views.generic.edit.FormView):
239class ManagerPeriodClosureView(ManagerRequiredMixin, OnSuccessMixin, FormView):
240    """
241    A class based view providing functionality to lock work hour entries of all
242     `ProjectAssignment`s associated with the given project for a given `Period`.
243    """
244    template_name = 'vkk/workhours/contributor/closure.html'
245    form_class = Form
246    on_success = 'period_closure_success'
247
248    def post(self, request, *args, **kwargs):
249        """
250        Extends the `post()` method with functionality associated with the form handling.
251        """
252        form = self.get_form()
253        if form.is_valid():
254            self.close_period()
255            return self.form_valid(form)
256        else:
257            return self.form_invalid(form)
258
259    def close_period(self):
260        """
261        Manages `PeriodClosure` instances accordingly.
262        """
263        assignments = ProjectAssignment.objects.filter(
264            project__invoice_number=self.kwargs['invoice_number'],
265        )
266        period = get_object_or_404(Period, pk=self.kwargs['period_pk'])
267        closing = [
268            PeriodClosure(
269                period=period,
270                project_assignment=assignment,
271                is_closed_contributor=True,
272                is_closed_manager=True
273            ) for assignment in assignments
274        ]
275        PeriodClosure.objects.bulk_create(
276            closing,
277            update_conflicts=True,
278            update_fields=['is_closed_contributor', 'is_closed_manager'],
279            unique_fields=['project_assignment', 'period']
280        )

A class based view providing functionality to lock work hour entries of all ProjectAssignments associated with the given project for a given Period.

template_name = 'vkk/workhours/contributor/closure.html'
form_class = <class 'django.forms.forms.Form'>
on_success = 'period_closure_success'
def post(self, request, *args, **kwargs):
248    def post(self, request, *args, **kwargs):
249        """
250        Extends the `post()` method with functionality associated with the form handling.
251        """
252        form = self.get_form()
253        if form.is_valid():
254            self.close_period()
255            return self.form_valid(form)
256        else:
257            return self.form_invalid(form)

Extends the post() method with functionality associated with the form handling.

def close_period(self):
259    def close_period(self):
260        """
261        Manages `PeriodClosure` instances accordingly.
262        """
263        assignments = ProjectAssignment.objects.filter(
264            project__invoice_number=self.kwargs['invoice_number'],
265        )
266        period = get_object_or_404(Period, pk=self.kwargs['period_pk'])
267        closing = [
268            PeriodClosure(
269                period=period,
270                project_assignment=assignment,
271                is_closed_contributor=True,
272                is_closed_manager=True
273            ) for assignment in assignments
274        ]
275        PeriodClosure.objects.bulk_create(
276            closing,
277            update_conflicts=True,
278            update_fields=['is_closed_contributor', 'is_closed_manager'],
279            unique_fields=['project_assignment', 'period']
280        )

Manages PeriodClosure instances accordingly.

Inherited Members
django.views.generic.base.View
View
http_method_names
view_is_async
as_view
setup
http_method_not_allowed
options
vkk.workhours.manager.mixins.ManagerRequiredMixin
check_field
dispatch
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
vkk.generic.mixins.OnSuccessMixin
drop_key
kwarg_override
get_success_url
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
class ManagerPeriodClosureSuccessView(vkk.workhours.manager.mixins.ManagerRequiredMixin, vkk.generic.views.CustomSuccessView):
283class ManagerPeriodClosureSuccessView(ManagerRequiredMixin, CustomSuccessView):
284    """
285    Extends the `CustomSuccessView` class to provide functionality for
286     displaying a successful lock of a work hours sheet.
287    """
288    template_name = 'vkk/workhours/contributor/closure_success.html'
289    model = PeriodClosure
290    on_success = 'workhours_sheet'

Extends the CustomSuccessView class to provide functionality for displaying a successful lock of a work hours sheet.

template_name = 'vkk/workhours/contributor/closure_success.html'
on_success = 'workhours_sheet'
Inherited Members
django.views.generic.base.View
View
http_method_names
view_is_async
as_view
setup
http_method_not_allowed
options
vkk.workhours.manager.mixins.ManagerRequiredMixin
check_field
dispatch
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
vkk.generic.mixins.OnSuccessMixin
drop_key
kwarg_override
get_success_url
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