vkk.workhours.allprojects.forms

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

A collection of Fields, plus their associated data.

YearSelectForm(*args, **kwargs)
11    def __init__(self, *args, **kwargs):
12        super().__init__(*args, **kwargs)
13        choices = {(entry['start'].year, entry['start'].year)
14                   for entry in Period.objects.all().values('start')}
15        choices = list(choices)
16        choices.sort()
17        self.fields['year'] = forms.ChoiceField(
18            label=_('Year'),
19            choices=choices
20        )
media

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

Inherited Members
django.forms.forms.BaseForm
order_fields
errors
is_valid
add_prefix
add_initial_prefix
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):
 23class AssigneeForm(forms.Form):
 24    custom_template = 'vkk/workhours/allprojects/assignee_form.html'
 25
 26    class Media:
 27        css = {'all': ('styles/assignee_form.css',)}
 28        js = ('scripts/assignee.js',)
 29
 30    def __init__(self, *args, assignee=None, manager=None, year=None, **kwargs):
 31        super().__init__(*args, **kwargs)
 32        self._assignee = assignee
 33        self._year = year
 34        self._periods = Period.objects.filter(
 35            start__year=year,
 36        ).order_by('start')
 37        self._assignments = ProjectAssignment.objects.filter(
 38            contributor=assignee,
 39            project__projectmanager__manager=manager,
 40            project__projectmanager__end__gte=timezone.now().date()
 41        ).order_by('project__invoice_number')
 42
 43        for assignment in self._assignments:
 44            for period in self._periods:
 45                workhours = WorkHours.objects.filter(
 46                    project_assignment=assignment,
 47                    period=period,
 48                )
 49                workhours_correction = WorkHoursCorrection.objects.filter(
 50                    project_assignment=assignment,
 51                    period=period,
 52                )
 53
 54                disabled = timezone.now() > period.dead_line_final
 55                if not disabled:
 56                    closure = PeriodClosure.objects.filter(
 57                        project_assignment=assignment,
 58                        period=period
 59                    )
 60                    if closure.exists():
 61                        disabled = closure[0].is_closed_manager
 62
 63                field = forms.DecimalField(
 64                    required=False,
 65                    min_value=0,
 66                    max_digits=5,
 67                    decimal_places=2,
 68                    disabled=disabled
 69                )
 70
 71                initial = workhours.aggregate(Sum('hours'))['hours__sum'] or 0
 72                if workhours_correction.exists():
 73                    initial += workhours_correction[0].ammount
 74                if initial != 0:
 75                    field.initial = initial
 76
 77                self.fields[str(assignment.id) + '_' + str(period.id)] = field
 78
 79    def _get_field_structure(self):
 80        return [
 81            (
 82                assignment,
 83                [
 84                    self[str(assignment.pk) + '_' + str(period.id)] for period in self._periods
 85                ]
 86            ) for assignment in self._assignments
 87        ]
 88
 89    def as_html(self):
 90        context = super().get_context()
 91        context.update({
 92            'assignee': self._assignee,
 93            'year': self._year,
 94            'periods': self._periods,
 95            'fields_more': self._get_field_structure()
 96        })
 97        return self.render(
 98            template_name=self.custom_template,
 99            context=context
100        )
101
102    def save(self):
103        if self.is_valid() and self.has_changed():
104            for assignment in self._assignments:
105                for period in self._periods:
106                    field_name = str(assignment.pk) + '_' + str(period.id)
107                    if field_name in self.changed_data:
108                        workhours = WorkHours.objects.filter(
109                            project_assignment=assignment,
110                            period=period,
111                        )
112                        value = (self.cleaned_data[field_name] or 0) - (
113                            workhours.aggregate(Sum('hours'))['hours__sum'] or 0)
114                        if value == 0:
115                            WorkHoursCorrection.objects.filter(
116                                project_assignment=assignment,
117                                period=period,
118                            ).delete()
119                        else:
120                            WorkHoursCorrection.objects.update_or_create(
121                                project_assignment=assignment,
122                                period=period,
123                                defaults={'ammount': value}
124                            )

A collection of Fields, plus their associated data.

AssigneeForm(*args, assignee=None, manager=None, year=None, **kwargs)
30    def __init__(self, *args, assignee=None, manager=None, year=None, **kwargs):
31        super().__init__(*args, **kwargs)
32        self._assignee = assignee
33        self._year = year
34        self._periods = Period.objects.filter(
35            start__year=year,
36        ).order_by('start')
37        self._assignments = ProjectAssignment.objects.filter(
38            contributor=assignee,
39            project__projectmanager__manager=manager,
40            project__projectmanager__end__gte=timezone.now().date()
41        ).order_by('project__invoice_number')
42
43        for assignment in self._assignments:
44            for period in self._periods:
45                workhours = WorkHours.objects.filter(
46                    project_assignment=assignment,
47                    period=period,
48                )
49                workhours_correction = WorkHoursCorrection.objects.filter(
50                    project_assignment=assignment,
51                    period=period,
52                )
53
54                disabled = timezone.now() > period.dead_line_final
55                if not disabled:
56                    closure = PeriodClosure.objects.filter(
57                        project_assignment=assignment,
58                        period=period
59                    )
60                    if closure.exists():
61                        disabled = closure[0].is_closed_manager
62
63                field = forms.DecimalField(
64                    required=False,
65                    min_value=0,
66                    max_digits=5,
67                    decimal_places=2,
68                    disabled=disabled
69                )
70
71                initial = workhours.aggregate(Sum('hours'))['hours__sum'] or 0
72                if workhours_correction.exists():
73                    initial += workhours_correction[0].ammount
74                if initial != 0:
75                    field.initial = initial
76
77                self.fields[str(assignment.id) + '_' + str(period.id)] = field
def as_html(self):
 89    def as_html(self):
 90        context = super().get_context()
 91        context.update({
 92            'assignee': self._assignee,
 93            'year': self._year,
 94            'periods': self._periods,
 95            'fields_more': self._get_field_structure()
 96        })
 97        return self.render(
 98            template_name=self.custom_template,
 99            context=context
100        )
def save(self):
102    def save(self):
103        if self.is_valid() and self.has_changed():
104            for assignment in self._assignments:
105                for period in self._periods:
106                    field_name = str(assignment.pk) + '_' + str(period.id)
107                    if field_name in self.changed_data:
108                        workhours = WorkHours.objects.filter(
109                            project_assignment=assignment,
110                            period=period,
111                        )
112                        value = (self.cleaned_data[field_name] or 0) - (
113                            workhours.aggregate(Sum('hours'))['hours__sum'] or 0)
114                        if value == 0:
115                            WorkHoursCorrection.objects.filter(
116                                project_assignment=assignment,
117                                period=period,
118                            ).delete()
119                        else:
120                            WorkHoursCorrection.objects.update_or_create(
121                                project_assignment=assignment,
122                                period=period,
123                                defaults={'ammount': value}
124                            )
media

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

Inherited Members
django.forms.forms.BaseForm
order_fields
errors
is_valid
add_prefix
add_initial_prefix
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:
26    class Media:
27        css = {'all': ('styles/assignee_form.css',)}
28        js = ('scripts/assignee.js',)
class AssgineeClosureForm(django.forms.forms.Form):
127class AssgineeClosureForm(forms.Form):
128    assignee = forms.ModelChoiceField(queryset=User.objects.all())
129    period = forms.ModelChoiceField(queryset=Period.objects.all())
130    manager = forms.ModelChoiceField(queryset=User.objects.all())
131
132    def save(self):
133        if self.is_valid():
134            assignee = self.cleaned_data['assignee']
135            period = self.cleaned_data['period']
136            manager = self.cleaned_data['manager']
137            project_assignments = ProjectAssignment.objects.filter(
138                contributor=assignee,
139                project__projectmanager__manager=manager
140            )
141
142            objs = [PeriodClosure(
143                period=period,
144                project_assignment=project_assignment,
145                is_closed_contributor=True,
146                is_closed_manager=True,
147            ) for project_assignment in project_assignments]
148
149            PeriodClosure.objects.bulk_create(
150                objs=objs,
151                ignore_conflicts=False,
152                update_conflicts=True,
153                update_fields=['is_closed_contributor', 'is_closed_manager'],
154                unique_fields=['period', 'project_assignment']
155            )

A collection of Fields, plus their associated data.

def save(self):
132    def save(self):
133        if self.is_valid():
134            assignee = self.cleaned_data['assignee']
135            period = self.cleaned_data['period']
136            manager = self.cleaned_data['manager']
137            project_assignments = ProjectAssignment.objects.filter(
138                contributor=assignee,
139                project__projectmanager__manager=manager
140            )
141
142            objs = [PeriodClosure(
143                period=period,
144                project_assignment=project_assignment,
145                is_closed_contributor=True,
146                is_closed_manager=True,
147            ) for project_assignment in project_assignments]
148
149            PeriodClosure.objects.bulk_create(
150                objs=objs,
151                ignore_conflicts=False,
152                update_conflicts=True,
153                update_fields=['is_closed_contributor', 'is_closed_manager'],
154                unique_fields=['period', 'project_assignment']
155            )
media

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

Inherited Members
django.forms.forms.BaseForm
BaseForm
order_fields
errors
is_valid
add_prefix
add_initial_prefix
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