Merge "Add User-ID Field in Booking API Serializer"
[laas.git] / src / booking / views.py
1 ##############################################################################
2 # Copyright (c) 2016 Max Breitenfeldt and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 from django.conf import settings
11 from django.contrib import messages
12 from django.contrib.auth.mixins import LoginRequiredMixin
13 from django.http import JsonResponse
14 from django.shortcuts import get_object_or_404
15 from django.urls import reverse
16 from django.utils import timezone
17 from django.views import View
18 from django.views.generic import FormView
19 from django.views.generic import TemplateView
20 from jira import JIRAError
21
22 from account.jira_util import get_jira
23 from booking.forms import BookingForm, BookingEditForm
24 from booking.models import Booking
25 from dashboard.models import Resource
26
27 def create_jira_ticket(user, booking):
28     jira = get_jira(user)
29     issue_dict = {
30         'project': 'PHAROS',
31         'summary': str(booking.resource) + ': Access Request',
32         'description': booking.purpose,
33         'issuetype': {'name': 'Task'},
34         'components': [{'name': 'POD Access Request'}],
35         'assignee': {'name': booking.resource.owner.username}
36     }
37     issue = jira.create_issue(fields=issue_dict)
38     jira.add_attachment(issue, user.userprofile.pgp_public_key)
39     jira.add_attachment(issue, user.userprofile.ssh_public_key)
40     booking.jira_issue_id = issue.id
41     booking.save()
42
43
44 class BookingFormView(FormView):
45     template_name = "booking/booking_calendar.html"
46     form_class = BookingForm
47
48     def dispatch(self, request, *args, **kwargs):
49         self.resource = get_object_or_404(Resource, id=self.kwargs['resource_id'])
50         return super(BookingFormView, self).dispatch(request, *args, **kwargs)
51
52     def get_context_data(self, **kwargs):
53         title = 'Booking: ' + self.resource.name
54         context = super(BookingFormView, self).get_context_data(**kwargs)
55         context.update({'title': title, 'resource': self.resource})
56         #raise PermissionDenied('check')
57         return context
58
59     def get_success_url(self):
60         return reverse('booking:create', kwargs=self.kwargs)
61
62     def form_valid(self, form):
63         if not self.request.user.is_authenticated:
64             messages.add_message(self.request, messages.ERROR,
65                                  'You need to be logged in to book a Pod.')
66             return super(BookingFormView, self).form_invalid(form)
67
68         user = self.request.user
69         booking = Booking(start=form.cleaned_data['start'],
70                           end=form.cleaned_data['end'],
71                           purpose=form.cleaned_data['purpose'],
72                           opsys=form.cleaned_data['opsys'],
73                           installer=form.cleaned_data['installer'],
74                           scenario=form.cleaned_data['scenario'],
75                           resource=self.resource, user=user)
76         try:
77             booking.save()
78         except ValueError as err:
79             messages.add_message(self.request, messages.ERROR, err)
80             return super(BookingFormView, self).form_invalid(form)
81         try:
82             if settings.CREATE_JIRA_TICKET:
83                 create_jira_ticket(user, booking)
84         except JIRAError:
85             messages.add_message(self.request, messages.ERROR, 'Failed to create Jira Ticket. '
86                                                                'Please check your Jira '
87                                                                'permissions.')
88             booking.delete()
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)
92
93
94 class BookingEditFormView(FormView):
95     template_name = "booking/booking_calendar.html"
96     form_class = BookingEditForm
97
98     def is_valid(self):
99         return True
100
101     def dispatch(self, request, *args, **kwargs):
102         self.resource = get_object_or_404(Resource, 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)
105
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})
110         return context
111
112     def get_form_kwargs(self):
113         kwargs = super(BookingEditFormView, self).get_form_kwargs()
114         kwargs['purpose'] = self.original_booking.purpose
115         kwargs['start'] = self.original_booking.start
116         kwargs['end'] = self.original_booking.end
117         try:
118             kwargs['installer'] = self.original_booking.installer
119         except AttributeError:
120             pass
121         try:
122             kwargs['scenario'] = self.original_booking.scenario
123         except AttributeError:
124             pass
125         return kwargs
126
127     def get_success_url(self):
128         return reverse('booking:create', args=(self.resource.id,))
129
130     def form_valid(self, form):
131
132         if not self.request.user.is_authenticated:
133             messages.add_message(self.request, messages.ERROR,
134                                  'You need to be logged in to book a Pod.')
135             return super(BookingEditFormView, self).form_invalid(form)
136
137         if not self.request.user == self.original_booking.user:
138             messages.add_message(self.request, messages.ERROR,
139                                  'You are not the owner of this booking.')
140             return super(BookingEditFormView, self).form_invalid(form)
141
142         #Do Conflict Checks
143         if self.original_booking.start != form.cleaned_data['start']:
144             if timezone.now() > form.cleaned_data['start']:
145                 messages.add_message(self.request, messages.ERROR,
146                                      'Cannot change start date after it has occurred.')
147                 return super(BookingEditFormView, self).form_invalid(form)
148         self.original_booking.start = form.cleaned_data['start']
149         self.original_booking.end = form.cleaned_data['end']
150         self.original_booking.purpose = form.cleaned_data['purpose']
151         self.original_booking.installer = form.cleaned_data['installer']
152         self.original_booking.scenario = form.cleaned_data['scenario']
153         self.original_booking.reset = form.cleaned_data['reset']
154         try:
155             self.original_booking.save()
156         except ValueError as err:
157             messages.add_message(self.request, messages.ERROR, err)
158             return super(BookingEditFormView, self).form_invalid(form)
159
160         user = self.request.user
161         return super(BookingEditFormView, self).form_valid(form)
162
163 class BookingView(TemplateView):
164     template_name = "booking/booking_detail.html"
165
166     def get_context_data(self, **kwargs):
167         booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
168         title = 'Booking Details'
169         context = super(BookingView, self).get_context_data(**kwargs)
170         context.update({'title': title, 'booking': booking})
171         return context
172
173
174 class BookingListView(TemplateView):
175     template_name = "booking/booking_list.html"
176
177     def get_context_data(self, **kwargs):
178         bookings = Booking.objects.filter(end__gte=timezone.now())
179         title = 'Search Booking'
180         context = super(BookingListView, self).get_context_data(**kwargs)
181         context.update({'title': title, 'bookings': bookings})
182         return context
183
184
185 class ResourceBookingsJSON(View):
186     def get(self, request, *args, **kwargs):
187         resource = get_object_or_404(Resource, id=self.kwargs['resource_id'])
188         bookings = resource.booking_set.get_queryset().values('id', 'start', 'end', 'purpose',
189                                                               'jira_issue_status', 'opsys__name',
190                                                               'installer__name', 'scenario__name')
191         return JsonResponse({'bookings': list(bookings)})