1 ##############################################################################
2 # Copyright (c) 2016 Max Breitenfeldt and others.
3 # Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ##############################################################################
11 from django.contrib import messages
12 from django.shortcuts import get_object_or_404
13 from django.http import JsonResponse
14 from django.urls import reverse
15 from django.utils import timezone
16 from django.views import View
17 from django.views.generic import FormView
18 from django.views.generic import TemplateView
19 from django.shortcuts import redirect, render
22 from booking.forms import BookingForm, BookingEditForm
23 from resource_inventory.models import ResourceBundle
24 from resource_inventory.resource_manager import ResourceManager
25 from booking.models import Booking, Installer, Opsys
26 from booking.stats import StatisticsManager
29 def drop_filter(context):
31 for os in Opsys.objects.all():
32 installer_filter[os.id] = []
33 for installer in os.sup_installers.all():
34 installer_filter[os.id].append(installer.id)
37 for installer in Installer.objects.all():
38 scenario_filter[installer.id] = []
39 for scenario in installer.sup_scenarios.all():
40 scenario_filter[installer.id].append(scenario.id)
42 context.update({'installer_filter': json.dumps(installer_filter), 'scenario_filter': json.dumps(scenario_filter)})
45 class BookingFormView(FormView):
46 template_name = "booking/booking_calendar.html"
47 form_class = BookingForm
49 def dispatch(self, request, *args, **kwargs):
50 self.resource = get_object_or_404(ResourceBundle, id=self.kwargs['resource_id'])
51 return super(BookingFormView, self).dispatch(request, *args, **kwargs)
53 def get_context_data(self, **kwargs):
54 title = 'Booking: ' + str(self.resource.id)
55 context = super(BookingFormView, self).get_context_data(**kwargs)
56 context.update({'title': title, 'resource': self.resource})
62 def get_success_url(self):
63 return reverse('booking:create', kwargs=self.kwargs)
65 def form_valid(self, form):
66 if not self.request.user.is_authenticated:
67 messages.add_message(self.request, messages.ERROR,
68 'You need to be logged in to book a Pod.')
69 return super(BookingFormView, self).form_invalid(form)
71 if form.cleaned_data['end'] - form.cleaned_data['start'] > timezone.timedelta(days=21):
72 messages.add_message(self.request, messages.ERROR,
73 'Bookings can be no more than 3 weeks long.')
74 return super(BookingFormView, self).form_invalid(form)
76 user = self.request.user
77 booking = Booking(start=form.cleaned_data['start'],
78 end=form.cleaned_data['end'],
79 purpose=form.cleaned_data['purpose'],
80 installer=form.cleaned_data['installer'],
81 scenario=form.cleaned_data['scenario'],
82 resource=self.resource,
87 except ValueError as err:
88 messages.add_message(self.request, messages.ERROR, err)
89 return super(BookingFormView, self).form_invalid(form)
90 messages.add_message(self.request, messages.SUCCESS, 'Booking saved')
91 return super(BookingFormView, self).form_valid(form)
94 class BookingEditFormView(FormView):
95 template_name = "booking/booking_calendar.html"
96 form_class = BookingEditForm
101 def dispatch(self, request, *args, **kwargs):
102 self.resource = get_object_or_404(ResourceBundle, id=self.kwargs['resource_id'])
103 self.original_booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
104 return super(BookingEditFormView, self).dispatch(request, *args, **kwargs)
106 def get_context_data(self, **kwargs):
107 title = 'Editing Booking on: ' + self.resource.name
108 context = super(BookingEditFormView, self).get_context_data(**kwargs)
109 context.update({'title': title, 'resource': self.resource, 'booking': self.original_booking})
115 def get_form_kwargs(self):
116 kwargs = super(BookingEditFormView, self).get_form_kwargs()
117 kwargs['purpose'] = self.original_booking.purpose
118 kwargs['start'] = self.original_booking.start
119 kwargs['end'] = self.original_booking.end
122 def get_success_url(self):
123 return reverse('booking:create', args=(self.resource.id,))
125 def form_valid(self, form):
127 if not self.request.user.is_authenticated:
128 messages.add_message(self.request, messages.ERROR,
129 'You need to be logged in to book a Pod.')
130 return super(BookingEditFormView, self).form_invalid(form)
132 if not self.request.user == self.original_booking.user:
133 messages.add_message(self.request, messages.ERROR,
134 'You are not the owner of this booking.')
135 return super(BookingEditFormView, self).form_invalid(form)
138 if self.original_booking.end != form.cleaned_data['end']:
139 if form.cleaned_data['end'] - self.original_booking.end > timezone.timedelta(days=7):
140 messages.add_message(self.request, messages.ERROR,
141 'Extensions can not be longer than one week.')
142 return super(BookingEditFormView, self).form_invalid(form)
143 elif self.original_booking.ext_count <= 0:
144 messages.add_message(self.request, messages.ERROR,
145 'Cannot change end date after maximum number of extensions reached.')
146 return super(BookingEditFormView, self).form_invalid(form)
149 self.original_booking.ext_count -= 1
151 if self.original_booking.start != form.cleaned_data['start']:
152 if timezone.now() > form.cleaned_data['start']:
153 messages.add_message(self.request, messages.ERROR,
154 'Cannot change start date after it has occurred.')
155 return super(BookingEditFormView, self).form_invalid(form)
156 self.original_booking.start = form.cleaned_data['start']
157 self.original_booking.end = form.cleaned_data['end']
158 self.original_booking.purpose = form.cleaned_data['purpose']
159 self.original_booking.installer = form.cleaned_data['installer']
160 self.original_booking.scenario = form.cleaned_data['scenario']
161 self.original_booking.reset = form.cleaned_data['reset']
163 self.original_booking.save()
164 except ValueError as err:
165 messages.add_message(self.request, messages.ERROR, err)
166 return super(BookingEditFormView, self).form_invalid(form)
168 return super(BookingEditFormView, self).form_valid(form)
171 class BookingView(TemplateView):
172 template_name = "booking/booking_detail.html"
174 def get_context_data(self, **kwargs):
175 booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
176 title = 'Booking Details'
177 context = super(BookingView, self).get_context_data(**kwargs)
178 context.update({'title': title, 'booking': booking})
182 class BookingDeleteView(TemplateView):
183 template_name = "booking/booking_delete.html"
185 def get_context_data(self, **kwargs):
186 booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
187 title = 'Delete Booking'
188 context = super(BookingDeleteView, self).get_context_data(**kwargs)
189 context.update({'title': title, 'booking': booking})
193 def bookingDelete(request, booking_id):
194 booking = get_object_or_404(Booking, id=booking_id)
196 messages.add_message(request, messages.SUCCESS, 'Booking deleted')
197 return redirect('../../../../')
200 class BookingListView(TemplateView):
201 template_name = "booking/booking_list.html"
203 def get_context_data(self, **kwargs):
204 bookings = Booking.objects.filter(end__gte=timezone.now())
205 title = 'Search Booking'
206 context = super(BookingListView, self).get_context_data(**kwargs)
207 context.update({'title': title, 'bookings': bookings})
211 class ResourceBookingsJSON(View):
212 def get(self, request, *args, **kwargs):
213 resource = get_object_or_404(ResourceBundle, id=self.kwargs['resource_id'])
214 bookings = resource.booking_set.get_queryset().values(
220 'config_bundle__name'
222 return JsonResponse({'bookings': list(bookings)})
225 def booking_detail_view(request, booking_id):
227 if request.user.is_authenticated:
230 return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
232 booking = get_object_or_404(Booking, id=booking_id)
233 return render(request, "booking/booking_detail.html", {
234 'title': 'Booking Details',
236 'pdf': ResourceManager().makePDF(booking.resource),
240 def booking_stats_view(request):
243 "booking/stats.html",
245 "data": StatisticsManager.getContinuousBookingTimeSeries(),
246 "title": "Booking Statistics"
251 def booking_stats_json(request):
253 span = int(request.GET.get("days", 14))
256 return JsonResponse(StatisticsManager.getContinuousBookingTimeSeries(span), safe=False)