vkk.workhours.allprojects.forms

A collection of Forms for this module.

  1"""
  2A collection of `Form`s for this module.
  3"""
  4
  5from django import forms
  6from django.db.models import Sum
  7from django.utils import timezone
  8from vkk.users.models import User
  9from vkk.workhours.models import ProjectAssignment, Period, WorkHours, WorkHoursCorrection, PeriodClosure
 10from django.utils.translation import gettext_lazy as _
 11
 12
 13class YearSelectForm(forms.Form):
 14    """
 15    A `Form` subclass for selecting a year.
 16    """
 17
 18    def __init__(self, *args, **kwargs):
 19        """
 20        Constructs and returns an instance of this class.
 21        """
 22        super().__init__(*args, **kwargs)
 23        choices = {(entry['start'].year, entry['start'].year)
 24                   for entry in Period.objects.all().values('start')}
 25        choices = list(choices)
 26        choices.sort()
 27        self.fields['year'] = forms.ChoiceField(
 28            label=_('Year'),
 29            choices=choices
 30        )
 31
 32
 33class AssigneeForm(forms.Form):
 34    """
 35    A `Form` subclass providing functionality for administrating work hours of a contributor.
 36    """
 37    custom_template = 'vkk/workhours/allprojects/assignee_form.html'
 38
 39    class Media:
 40        """
 41        A inner class for meta information.
 42        """
 43        css = {'all': ('styles/assignee_form.css',)}
 44        js = ('scripts/assignee.js',)
 45
 46    def __init__(self, *args, assignee=None, manager=None, year=None, **kwargs):
 47        """
 48        Constructs and returns an instance of this class.
 49        """
 50        super().__init__(*args, **kwargs)
 51        self._assignee = assignee
 52        self._year = year
 53        self._periods = Period.objects.filter(
 54            start__year=year,
 55        ).order_by('start')
 56        self._assignments = ProjectAssignment.objects.filter(
 57            contributor=assignee,
 58            project__projectmanager__manager=manager,
 59            project__projectmanager__end__gte=timezone.now().date()
 60        ).order_by('project__invoice_number')
 61
 62        for assignment in self._assignments:
 63            for period in self._periods:
 64                workhours = WorkHours.objects.filter(
 65                    project_assignment=assignment,
 66                    period=period,
 67                )
 68                workhours_correction = WorkHoursCorrection.objects.filter(
 69                    project_assignment=assignment,
 70                    period=period,
 71                )
 72
 73                disabled = timezone.now() > period.dead_line_final
 74                if not disabled:
 75                    closure = PeriodClosure.objects.filter(
 76                        project_assignment=assignment,
 77                        period=period
 78                    )
 79                    if closure.exists():
 80                        disabled = closure[0].is_closed_manager
 81
 82                field = forms.DecimalField(
 83                    required=False,
 84                    min_value=0,
 85                    max_digits=5,
 86                    decimal_places=2,
 87                    disabled=disabled
 88                )
 89
 90                initial = workhours.aggregate(Sum('hours'))['hours__sum'] or 0
 91                if workhours_correction.exists():
 92                    initial += workhours_correction[0].ammount
 93                if initial != 0:
 94                    field.initial = initial
 95
 96                self.fields[str(assignment.id) + '_' + str(period.id)] = field
 97
 98    def _get_field_structure(self):
 99        return [
100            (
101                assignment,
102                [
103                    self[str(assignment.pk) + '_' + str(period.id)] for period in self._periods
104                ]
105            ) for assignment in self._assignments
106        ]
107
108    def as_html(self):
109        context = super().get_context()
110        context.update({
111            'assignee': self._assignee,
112            'year': self._year,
113            'periods': self._periods,
114            'fields_more': self._get_field_structure()
115        })
116        return self.render(
117            template_name=self.custom_template,
118            context=context
119        )
120
121    def save(self):
122        if self.is_valid() and self.has_changed():
123            for assignment in self._assignments:
124                for period in self._periods:
125                    field_name = str(assignment.pk) + '_' + str(period.id)
126                    if field_name in self.changed_data:
127                        workhours = WorkHours.objects.filter(
128                            project_assignment=assignment,
129                            period=period,
130                        )
131                        value = (self.cleaned_data[field_name] or 0) - (
132                            workhours.aggregate(Sum('hours'))['hours__sum'] or 0)
133                        if value == 0:
134                            WorkHoursCorrection.objects.filter(
135                                project_assignment=assignment,
136                                period=period,
137                            ).delete()
138                        else:
139                            WorkHoursCorrection.objects.update_or_create(
140                                project_assignment=assignment,
141                                period=period,
142                                defaults={'ammount': value}
143                            )
144
145
146class AssgineeClosureForm(forms.Form):
147    assignee = forms.ModelChoiceField(queryset=User.objects.all())
148    period = forms.ModelChoiceField(queryset=Period.objects.all())
149    manager = forms.ModelChoiceField(queryset=User.objects.all())
150
151    def save(self):
152        if self.is_valid():
153            assignee = self.cleaned_data['assignee']
154            period = self.cleaned_data['period']
155            manager = self.cleaned_data['manager']
156            project_assignments = ProjectAssignment.objects.filter(
157                contributor=assignee,
158                project__projectmanager__manager=manager
159            )
160
161            objs = [PeriodClosure(
162                period=period,
163                project_assignment=project_assignment,
164                is_closed_contributor=True,
165                is_closed_manager=True,
166            ) for project_assignment in project_assignments]
167
168            PeriodClosure.objects.bulk_create(
169                objs=objs,
170                ignore_conflicts=False,
171                update_conflicts=True,
172                update_fields=['is_closed_contributor', 'is_closed_manager'],
173                unique_fields=['period', 'project_assignment']
174            )
class YearSelectForm(django.forms.forms.Form):
14class YearSelectForm(forms.Form):
15    """
16    A `Form` subclass for selecting a year.
17    """
18
19    def __init__(self, *args, **kwargs):
20        """
21        Constructs and returns an instance of this class.
22        """
23        super().__init__(*args, **kwargs)
24        choices = {(entry['start'].year, entry['start'].year)
25                   for entry in Period.objects.all().values('start')}
26        choices = list(choices)
27        choices.sort()
28        self.fields['year'] = forms.ChoiceField(
29            label=_('Year'),
30            choices=choices
31        )

A Form subclass for selecting a year.

YearSelectForm(*args, **kwargs)
19    def __init__(self, *args, **kwargs):
20        """
21        Constructs and returns an instance of this class.
22        """
23        super().__init__(*args, **kwargs)
24        choices = {(entry['start'].year, entry['start'].year)
25                   for entry in Period.objects.all().values('start')}
26        choices = list(choices)
27        choices.sort()
28        self.fields['year'] = forms.ChoiceField(
29            label=_('Year'),
30            choices=choices
31        )

Constructs and returns an instance of this class.

media

Return all media required to render the widgets on this form.

declared_fields = {}
base_fields = {}
Inherited Members
django.forms.forms.BaseForm
default_renderer
field_order
prefix
use_required_attribute
template_name_div
template_name_p
template_name_table
template_name_ul
template_name_label
is_bound
data
files
auto_id
initial
error_class
label_suffix
empty_permitted
fields
renderer
order_fields
errors
is_valid
add_prefix
add_initial_prefix
template_name
get_context
non_field_errors
add_error
has_error
full_clean
clean
has_changed
changed_data
is_multipart
hidden_fields
visible_fields
get_initial_for_field
django.forms.utils.RenderableFormMixin
as_p
as_table
as_ul
as_div
django.forms.utils.RenderableMixin
render
class AssigneeForm(django.forms.forms.Form):
 34class AssigneeForm(forms.Form):
 35    """
 36    A `Form` subclass providing functionality for administrating work hours of a contributor.
 37    """
 38    custom_template = 'vkk/workhours/allprojects/assignee_form.html'
 39
 40    class Media:
 41        """
 42        A inner class for meta information.
 43        """
 44        css = {'all': ('styles/assignee_form.css',)}
 45        js = ('scripts/assignee.js',)
 46
 47    def __init__(self, *args, assignee=None, manager=None, year=None, **kwargs):
 48        """
 49        Constructs and returns an instance of this class.
 50        """
 51        super().__init__(*args, **kwargs)
 52        self._assignee = assignee
 53        self._year = year
 54        self._periods = Period.objects.filter(
 55            start__year=year,
 56        ).order_by('start')
 57        self._assignments = ProjectAssignment.objects.filter(
 58            contributor=assignee,
 59            project__projectmanager__manager=manager,
 60            project__projectmanager__end__gte=timezone.now().date()
 61        ).order_by('project__invoice_number')
 62
 63        for assignment in self._assignments:
 64            for period in self._periods:
 65                workhours = WorkHours.objects.filter(
 66                    project_assignment=assignment,
 67                    period=period,
 68                )
 69                workhours_correction = WorkHoursCorrection.objects.filter(
 70                    project_assignment=assignment,
 71                    period=period,
 72                )
 73
 74                disabled = timezone.now() > period.dead_line_final
 75                if not disabled:
 76                    closure = PeriodClosure.objects.filter(
 77                        project_assignment=assignment,
 78                        period=period
 79                    )
 80                    if closure.exists():
 81                        disabled = closure[0].is_closed_manager
 82
 83                field = forms.DecimalField(
 84                    required=False,
 85                    min_value=0,
 86                    max_digits=5,
 87                    decimal_places=2,
 88                    disabled=disabled
 89                )
 90
 91                initial = workhours.aggregate(Sum('hours'))['hours__sum'] or 0
 92                if workhours_correction.exists():
 93                    initial += workhours_correction[0].ammount
 94                if initial != 0:
 95                    field.initial = initial
 96
 97                self.fields[str(assignment.id) + '_' + str(period.id)] = field
 98
 99    def _get_field_structure(self):
100        return [
101            (
102                assignment,
103                [
104                    self[str(assignment.pk) + '_' + str(period.id)] for period in self._periods
105                ]
106            ) for assignment in self._assignments
107        ]
108
109    def as_html(self):
110        context = super().get_context()
111        context.update({
112            'assignee': self._assignee,
113            'year': self._year,
114            'periods': self._periods,
115            'fields_more': self._get_field_structure()
116        })
117        return self.render(
118            template_name=self.custom_template,
119            context=context
120        )
121
122    def save(self):
123        if self.is_valid() and self.has_changed():
124            for assignment in self._assignments:
125                for period in self._periods:
126                    field_name = str(assignment.pk) + '_' + str(period.id)
127                    if field_name in self.changed_data:
128                        workhours = WorkHours.objects.filter(
129                            project_assignment=assignment,
130                            period=period,
131                        )
132                        value = (self.cleaned_data[field_name] or 0) - (
133                            workhours.aggregate(Sum('hours'))['hours__sum'] or 0)
134                        if value == 0:
135                            WorkHoursCorrection.objects.filter(
136                                project_assignment=assignment,
137                                period=period,
138                            ).delete()
139                        else:
140                            WorkHoursCorrection.objects.update_or_create(
141                                project_assignment=assignment,
142                                period=period,
143                                defaults={'ammount': value}
144                            )

A Form subclass providing functionality for administrating work hours of a contributor.

AssigneeForm(*args, assignee=None, manager=None, year=None, **kwargs)
47    def __init__(self, *args, assignee=None, manager=None, year=None, **kwargs):
48        """
49        Constructs and returns an instance of this class.
50        """
51        super().__init__(*args, **kwargs)
52        self._assignee = assignee
53        self._year = year
54        self._periods = Period.objects.filter(
55            start__year=year,
56        ).order_by('start')
57        self._assignments = ProjectAssignment.objects.filter(
58            contributor=assignee,
59            project__projectmanager__manager=manager,
60            project__projectmanager__end__gte=timezone.now().date()
61        ).order_by('project__invoice_number')
62
63        for assignment in self._assignments:
64            for period in self._periods:
65                workhours = WorkHours.objects.filter(
66                    project_assignment=assignment,
67                    period=period,
68                )
69                workhours_correction = WorkHoursCorrection.objects.filter(
70                    project_assignment=assignment,
71                    period=period,
72                )
73
74                disabled = timezone.now() > period.dead_line_final
75                if not disabled:
76                    closure = PeriodClosure.objects.filter(
77                        project_assignment=assignment,
78                        period=period
79                    )
80                    if closure.exists():
81                        disabled = closure[0].is_closed_manager
82
83                field = forms.DecimalField(
84                    required=False,
85                    min_value=0,
86                    max_digits=5,
87                    decimal_places=2,
88                    disabled=disabled
89                )
90
91                initial = workhours.aggregate(Sum('hours'))['hours__sum'] or 0
92                if workhours_correction.exists():
93                    initial += workhours_correction[0].ammount
94                if initial != 0:
95                    field.initial = initial
96
97                self.fields[str(assignment.id) + '_' + str(period.id)] = field

Constructs and returns an instance of this class.

custom_template = 'vkk/workhours/allprojects/assignee_form.html'
def as_html(self):
109    def as_html(self):
110        context = super().get_context()
111        context.update({
112            'assignee': self._assignee,
113            'year': self._year,
114            'periods': self._periods,
115            'fields_more': self._get_field_structure()
116        })
117        return self.render(
118            template_name=self.custom_template,
119            context=context
120        )
def save(self):
122    def save(self):
123        if self.is_valid() and self.has_changed():
124            for assignment in self._assignments:
125                for period in self._periods:
126                    field_name = str(assignment.pk) + '_' + str(period.id)
127                    if field_name in self.changed_data:
128                        workhours = WorkHours.objects.filter(
129                            project_assignment=assignment,
130                            period=period,
131                        )
132                        value = (self.cleaned_data[field_name] or 0) - (
133                            workhours.aggregate(Sum('hours'))['hours__sum'] or 0)
134                        if value == 0:
135                            WorkHoursCorrection.objects.filter(
136                                project_assignment=assignment,
137                                period=period,
138                            ).delete()
139                        else:
140                            WorkHoursCorrection.objects.update_or_create(
141                                project_assignment=assignment,
142                                period=period,
143                                defaults={'ammount': value}
144                            )
media

Return all media required to render the widgets on this form.

declared_fields = {}
base_fields = {}
Inherited Members
django.forms.forms.BaseForm
default_renderer
field_order
prefix
use_required_attribute
template_name_div
template_name_p
template_name_table
template_name_ul
template_name_label
is_bound
data
files
auto_id
initial
error_class
label_suffix
empty_permitted
fields
renderer
order_fields
errors
is_valid
add_prefix
add_initial_prefix
template_name
get_context
non_field_errors
add_error
has_error
full_clean
clean
has_changed
changed_data
is_multipart
hidden_fields
visible_fields
get_initial_for_field
django.forms.utils.RenderableFormMixin
as_p
as_table
as_ul
as_div
django.forms.utils.RenderableMixin
render
class AssigneeForm.Media:
40    class Media:
41        """
42        A inner class for meta information.
43        """
44        css = {'all': ('styles/assignee_form.css',)}
45        js = ('scripts/assignee.js',)

A inner class for meta information.

css = {'all': ('styles/assignee_form.css',)}
js = ('scripts/assignee.js',)
class AssgineeClosureForm(django.forms.forms.Form):
147class AssgineeClosureForm(forms.Form):
148    assignee = forms.ModelChoiceField(queryset=User.objects.all())
149    period = forms.ModelChoiceField(queryset=Period.objects.all())
150    manager = forms.ModelChoiceField(queryset=User.objects.all())
151
152    def save(self):
153        if self.is_valid():
154            assignee = self.cleaned_data['assignee']
155            period = self.cleaned_data['period']
156            manager = self.cleaned_data['manager']
157            project_assignments = ProjectAssignment.objects.filter(
158                contributor=assignee,
159                project__projectmanager__manager=manager
160            )
161
162            objs = [PeriodClosure(
163                period=period,
164                project_assignment=project_assignment,
165                is_closed_contributor=True,
166                is_closed_manager=True,
167            ) for project_assignment in project_assignments]
168
169            PeriodClosure.objects.bulk_create(
170                objs=objs,
171                ignore_conflicts=False,
172                update_conflicts=True,
173                update_fields=['is_closed_contributor', 'is_closed_manager'],
174                unique_fields=['period', 'project_assignment']
175            )

A collection of Fields, plus their associated data.

assignee
period
manager
def save(self):
152    def save(self):
153        if self.is_valid():
154            assignee = self.cleaned_data['assignee']
155            period = self.cleaned_data['period']
156            manager = self.cleaned_data['manager']
157            project_assignments = ProjectAssignment.objects.filter(
158                contributor=assignee,
159                project__projectmanager__manager=manager
160            )
161
162            objs = [PeriodClosure(
163                period=period,
164                project_assignment=project_assignment,
165                is_closed_contributor=True,
166                is_closed_manager=True,
167            ) for project_assignment in project_assignments]
168
169            PeriodClosure.objects.bulk_create(
170                objs=objs,
171                ignore_conflicts=False,
172                update_conflicts=True,
173                update_fields=['is_closed_contributor', 'is_closed_manager'],
174                unique_fields=['period', 'project_assignment']
175            )
media

Return all media required to render the widgets on this form.

declared_fields = {'assignee': <django.forms.models.ModelChoiceField object>, 'period': <django.forms.models.ModelChoiceField object>, 'manager': <django.forms.models.ModelChoiceField object>}
base_fields = {'assignee': <django.forms.models.ModelChoiceField object>, 'period': <django.forms.models.ModelChoiceField object>, 'manager': <django.forms.models.ModelChoiceField object>}
Inherited Members
django.forms.forms.BaseForm
BaseForm
default_renderer
field_order
prefix
use_required_attribute
template_name_div
template_name_p
template_name_table
template_name_ul
template_name_label
is_bound
data
files
auto_id
initial
error_class
label_suffix
empty_permitted
fields
renderer
order_fields
errors
is_valid
add_prefix
add_initial_prefix
template_name
get_context
non_field_errors
add_error
has_error
full_clean
clean
has_changed
changed_data
is_multipart
hidden_fields
visible_fields
get_initial_for_field
django.forms.utils.RenderableFormMixin
as_p
as_table
as_ul
as_div
django.forms.utils.RenderableMixin
render