vkk.workhours.contributor.forms

  1import datetime
  2from django import forms
  3from vkk.workhours.models import WorkHours, Period, ProjectAssignment
  4from vkk.workhours.forms import date_iterator
  5
  6# Forms
  7
  8
  9class WorkhourCalendarForm(forms.Form):
 10    class Media:
 11        css = {'all': ('styles/calendar.css',)}
 12
 13    template_name_calendar = 'vkk/workhours/contributor/calendar.html'
 14
 15    def __init__(self, *args, period_pk=None, assignment_pk=None, **kwargs):
 16        super().__init__(*args, **kwargs)
 17        self._project_assignment = ProjectAssignment.objects.get(
 18            pk=assignment_pk
 19        )
 20
 21        # create fields
 22        self._period = Period.objects.get(pk=period_pk)
 23        today = datetime.date.today()
 24        field_class = WorkHours.hours.field.formfield
 25
 26        for date in date_iterator(self._period.start, self._period.end):
 27            is_disabled = date > today or self._project_assignment.project.start > date \
 28                or self._project_assignment.project.end < date
 29            field = field_class(
 30                min_value=0,
 31                max_value=24,
 32                required=False,
 33                label=date.day,
 34                label_suffix='',
 35                disabled=is_disabled
 36            )
 37            self.fields[date.isoformat()] = field
 38
 39        # provide initial data
 40        workhours = WorkHours.objects.filter(
 41            period__pk=period_pk,
 42            project_assignment__pk=assignment_pk
 43        )
 44        for entry in workhours:
 45            field = self.fields.get(entry.day.isoformat())
 46            if field is not None:
 47                field.initial = entry.hours
 48
 49    def _get_date_calendar_structure(self):
 50        dates = date_iterator(self._period.start, self._period.end)
 51
 52        # subdevision into months
 53        months = []
 54        month_number = -1
 55        for date in dates:
 56            if date.month != month_number:
 57                months += [[]]
 58                month_number = date.month
 59            months[-1] += [date]
 60
 61        # subdevision into weeks
 62        weeks = []
 63        for month in months:
 64            weeks += [[]]
 65            week_day = 7
 66            for date in month:
 67                if date.weekday() < week_day:
 68                    weeks[-1] += [[]]
 69                weeks[-1][-1] += [date]
 70                week_day = date.weekday()
 71
 72        return weeks
 73
 74    def _get_field_calendar_structure(self):
 75        calendar = self._get_date_calendar_structure()
 76        return [[(
 77            [(day, self[day.isoformat()]) for day in week]
 78        ) for week in month] for month in calendar]
 79
 80    def as_calendar(self):
 81        context = super().get_context()
 82        context.update({'fields_more': self._get_field_calendar_structure()})
 83        return self.render(
 84            template_name=self.template_name_calendar,
 85            context=context
 86        )
 87
 88    def save(self):
 89        if self.is_valid() and self.has_changed():
 90            add = []
 91            delete = []
 92            for field_name in self.changed_data:
 93                initial = self.fields[field_name].initial
 94                value = self.cleaned_data.get(field_name)
 95                if value is None or value == 0.0:
 96                    delete.append(
 97                        datetime.date.fromisoformat(field_name)
 98                    )
 99                elif initial is None:
100                    add.append(WorkHours(
101                        project_assignment=self._project_assignment,
102                        period=self._period,
103                        day=datetime.date.fromisoformat(field_name),
104                        hours=value
105                    ))
106                else:
107                    WorkHours.objects.filter(
108                        project_assignment=self._project_assignment,
109                        period=self._period,
110                        day=datetime.date.fromisoformat(field_name),
111                    ).update(hours=value)
112            WorkHours.objects.filter(
113                project_assignment=self._project_assignment,
114                period=self._period,
115                day__in=delete
116            ).delete()
117            WorkHours.objects.bulk_create(add)
class WorkhourCalendarForm(django.forms.forms.Form):
 10class WorkhourCalendarForm(forms.Form):
 11    class Media:
 12        css = {'all': ('styles/calendar.css',)}
 13
 14    template_name_calendar = 'vkk/workhours/contributor/calendar.html'
 15
 16    def __init__(self, *args, period_pk=None, assignment_pk=None, **kwargs):
 17        super().__init__(*args, **kwargs)
 18        self._project_assignment = ProjectAssignment.objects.get(
 19            pk=assignment_pk
 20        )
 21
 22        # create fields
 23        self._period = Period.objects.get(pk=period_pk)
 24        today = datetime.date.today()
 25        field_class = WorkHours.hours.field.formfield
 26
 27        for date in date_iterator(self._period.start, self._period.end):
 28            is_disabled = date > today or self._project_assignment.project.start > date \
 29                or self._project_assignment.project.end < date
 30            field = field_class(
 31                min_value=0,
 32                max_value=24,
 33                required=False,
 34                label=date.day,
 35                label_suffix='',
 36                disabled=is_disabled
 37            )
 38            self.fields[date.isoformat()] = field
 39
 40        # provide initial data
 41        workhours = WorkHours.objects.filter(
 42            period__pk=period_pk,
 43            project_assignment__pk=assignment_pk
 44        )
 45        for entry in workhours:
 46            field = self.fields.get(entry.day.isoformat())
 47            if field is not None:
 48                field.initial = entry.hours
 49
 50    def _get_date_calendar_structure(self):
 51        dates = date_iterator(self._period.start, self._period.end)
 52
 53        # subdevision into months
 54        months = []
 55        month_number = -1
 56        for date in dates:
 57            if date.month != month_number:
 58                months += [[]]
 59                month_number = date.month
 60            months[-1] += [date]
 61
 62        # subdevision into weeks
 63        weeks = []
 64        for month in months:
 65            weeks += [[]]
 66            week_day = 7
 67            for date in month:
 68                if date.weekday() < week_day:
 69                    weeks[-1] += [[]]
 70                weeks[-1][-1] += [date]
 71                week_day = date.weekday()
 72
 73        return weeks
 74
 75    def _get_field_calendar_structure(self):
 76        calendar = self._get_date_calendar_structure()
 77        return [[(
 78            [(day, self[day.isoformat()]) for day in week]
 79        ) for week in month] for month in calendar]
 80
 81    def as_calendar(self):
 82        context = super().get_context()
 83        context.update({'fields_more': self._get_field_calendar_structure()})
 84        return self.render(
 85            template_name=self.template_name_calendar,
 86            context=context
 87        )
 88
 89    def save(self):
 90        if self.is_valid() and self.has_changed():
 91            add = []
 92            delete = []
 93            for field_name in self.changed_data:
 94                initial = self.fields[field_name].initial
 95                value = self.cleaned_data.get(field_name)
 96                if value is None or value == 0.0:
 97                    delete.append(
 98                        datetime.date.fromisoformat(field_name)
 99                    )
100                elif initial is None:
101                    add.append(WorkHours(
102                        project_assignment=self._project_assignment,
103                        period=self._period,
104                        day=datetime.date.fromisoformat(field_name),
105                        hours=value
106                    ))
107                else:
108                    WorkHours.objects.filter(
109                        project_assignment=self._project_assignment,
110                        period=self._period,
111                        day=datetime.date.fromisoformat(field_name),
112                    ).update(hours=value)
113            WorkHours.objects.filter(
114                project_assignment=self._project_assignment,
115                period=self._period,
116                day__in=delete
117            ).delete()
118            WorkHours.objects.bulk_create(add)

A collection of Fields, plus their associated data.

WorkhourCalendarForm(*args, period_pk=None, assignment_pk=None, **kwargs)
16    def __init__(self, *args, period_pk=None, assignment_pk=None, **kwargs):
17        super().__init__(*args, **kwargs)
18        self._project_assignment = ProjectAssignment.objects.get(
19            pk=assignment_pk
20        )
21
22        # create fields
23        self._period = Period.objects.get(pk=period_pk)
24        today = datetime.date.today()
25        field_class = WorkHours.hours.field.formfield
26
27        for date in date_iterator(self._period.start, self._period.end):
28            is_disabled = date > today or self._project_assignment.project.start > date \
29                or self._project_assignment.project.end < date
30            field = field_class(
31                min_value=0,
32                max_value=24,
33                required=False,
34                label=date.day,
35                label_suffix='',
36                disabled=is_disabled
37            )
38            self.fields[date.isoformat()] = field
39
40        # provide initial data
41        workhours = WorkHours.objects.filter(
42            period__pk=period_pk,
43            project_assignment__pk=assignment_pk
44        )
45        for entry in workhours:
46            field = self.fields.get(entry.day.isoformat())
47            if field is not None:
48                field.initial = entry.hours
def as_calendar(self):
81    def as_calendar(self):
82        context = super().get_context()
83        context.update({'fields_more': self._get_field_calendar_structure()})
84        return self.render(
85            template_name=self.template_name_calendar,
86            context=context
87        )
def save(self):
 89    def save(self):
 90        if self.is_valid() and self.has_changed():
 91            add = []
 92            delete = []
 93            for field_name in self.changed_data:
 94                initial = self.fields[field_name].initial
 95                value = self.cleaned_data.get(field_name)
 96                if value is None or value == 0.0:
 97                    delete.append(
 98                        datetime.date.fromisoformat(field_name)
 99                    )
100                elif initial is None:
101                    add.append(WorkHours(
102                        project_assignment=self._project_assignment,
103                        period=self._period,
104                        day=datetime.date.fromisoformat(field_name),
105                        hours=value
106                    ))
107                else:
108                    WorkHours.objects.filter(
109                        project_assignment=self._project_assignment,
110                        period=self._period,
111                        day=datetime.date.fromisoformat(field_name),
112                    ).update(hours=value)
113            WorkHours.objects.filter(
114                project_assignment=self._project_assignment,
115                period=self._period,
116                day__in=delete
117            ).delete()
118            WorkHours.objects.bulk_create(add)
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 WorkhourCalendarForm.Media:
11    class Media:
12        css = {'all': ('styles/calendar.css',)}