diff --git a/src/teams/templates/shifts/shift_list.html b/src/teams/templates/shifts/shift_list.html index 374d987c..3e1ce28b 100644 --- a/src/teams/templates/shifts/shift_list.html +++ b/src/teams/templates/shifts/shift_list.html @@ -15,7 +15,11 @@ {% if request.user in team.responsible_members.all %} - Create shift + Create a single shift + + + Create multiple shifts {% endif %} diff --git a/src/teams/urls.py b/src/teams/urls.py index e48a6b27..658d64a7 100644 --- a/src/teams/urls.py +++ b/src/teams/urls.py @@ -21,6 +21,7 @@ from teams.views.tasks import ( from teams.views.shifts import ( ShiftListView, ShiftCreateView, + ShiftCreateMultipleView, ShiftUpdateView, ) @@ -131,6 +132,11 @@ urlpatterns = [ ShiftCreateView.as_view(), name="shift_create" ), + path( + 'create_multiple/', + ShiftCreateMultipleView.as_view(), + name="shift_create_multiple" + ), path( '/', ShiftUpdateView.as_view(), diff --git a/src/teams/views/shifts.py b/src/teams/views/shifts.py index 334b911a..54edd600 100644 --- a/src/teams/views/shifts.py +++ b/src/teams/views/shifts.py @@ -1,5 +1,5 @@ from django.contrib.auth.mixins import LoginRequiredMixin -from django.views.generic import CreateView, UpdateView, ListView +from django.views.generic import CreateView, UpdateView, ListView, FormView from django import forms from django.contrib.postgres.forms.ranges import RangeWidget from django.utils import timezone @@ -121,6 +121,7 @@ class ShiftForm(forms.ModelForm): return super().save(commit=commit) + class ShiftCreateView(LoginRequiredMixin, CampViewMixin, CreateView): model = TeamShift template_name = "shifts/shift_form.html" @@ -165,3 +166,96 @@ class ShiftUpdateView(LoginRequiredMixin, CampViewMixin, UpdateView): context = super().get_context_data(**kwargs) context['team'] = self.object.team return context + + +class MultipleShiftForm(forms.Form): + + date = forms.DateField( + help_text="Format is YYYY-MM-DD" + ) + + number_of_shifts = forms.IntegerField( + help_text="How many shifts in a day?" + ) + + start_time = forms.TimeField( + help_text="When the first shift should start? Defaults to 00:00.", + required=False, + initial="00:00" + ) + + end_time = forms.TimeField( + help_text="When the last shift should end? Defaults to 00:00 (next day).", + required=False, + initial="00:00" + ) + + people_required = forms.IntegerField() + + +class ShiftCreateMultipleView(LoginRequiredMixin, CampViewMixin, FormView): + template_name = "shifts/shift_form.html" + form_class = MultipleShiftForm + + def form_valid(self, form): + team = Team.objects.get( + camp=self.camp, + slug=self.kwargs['team_slug'] + ) + date = form.cleaned_data['date'] + number_of_shifts = form.cleaned_data['number_of_shifts'] + start_time = form.cleaned_data['start_time'] + end_time = form.cleaned_data['end_time'] + people_required = form.cleaned_data['people_required'] + + current_timezone = timezone.get_current_timezone() + + # create start datetime + start_datetime = ( + timezone.datetime.combine(date, start_time) + .astimezone(current_timezone) + ) + # create end datetime + if end_time == "00:00": + # if end time is midnight, we want midnight for next day + date = date + timezone.timedelta(days=1) + + end_datetime = ( + timezone.datetime.combine(date, end_time) + .astimezone(current_timezone) + ) + # figure out minutes between start and end datetime + total_minutes = (end_datetime - start_datetime).total_seconds() / 60 + # divide by number of shifts -> duration for each shift + shift_duration = total_minutes / number_of_shifts + + shifts = [] + for index in range(number_of_shifts + 1): + shift_range = DateTimeTZRange( + start_datetime, + start_datetime + timezone.timedelta(minutes=shift_duration), + ) + shifts.append(TeamShift( + team=team, + people_required=people_required, + shift_range=shift_range + )) + start_datetime += timezone.timedelta(minutes=shift_duration) + + TeamShift.objects.bulk_create(shifts) + + return super().form_valid(form) + + def get_success_url(self): + return reverse( + 'teams:shift_list', + kwargs=self.kwargs + ) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['team'] = Team.objects.get( + camp=self.camp, + slug=self.kwargs['team_slug'] + ) + return context