Merge "Provide Interface for Booking Deletion"
[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 from django.shortcuts import redirect
22
23 from account.jira_util import get_jira
24 from booking.forms import BookingForm, BookingEditForm
25 from booking.models import Booking
26 from dashboard.models import Resource
27
28 def create_jira_ticket(user, booking):
29     jira = get_jira(user)
30     issue_dict = {
31         'project': 'PHAROS',
32         'summary': str(booking.resource) + ': Access Request',
33         'description': booking.purpose,
34         'issuetype': {'name': 'Task'},
35         'components': [{'name': 'POD Access Request'}],
36         'assignee': {'name': booking.resource.owner.username}
37     }
38     issue = jira.create_issue(fields=issue_dict)
39     jira.add_attachment(issue, user.userprofile.pgp_public_key)
40     jira.add_attachment(issue, user.userprofile.ssh_public_key)
41     booking.jira_issue_id = issue.id
42     booking.save()
43
44
45 class BookingFormView(FormView):
46     template_name = "booking/booking_calendar.html"
47     form_class = BookingForm
48
49     def dispatch(self, request, *args, **kwargs):
50         self.resource = get_object_or_404(Resource, id=self.kwargs['resource_id'])
51         return super(BookingFormView, self).dispatch(request, *args, **kwargs)
52
53     def get_context_data(self, **kwargs):
54         title = 'Booking: ' + self.resource.name
55         context = super(BookingFormView, self).get_context_data(**kwargs)
56         context.update({'title': title, 'resource': self.resource})
57         #raise PermissionDenied('check')
58         return context
59
60     def get_success_url(self):
61         return reverse('booking:create', kwargs=self.kwargs)
62
63     def form_valid(self, form):
64         if not self.request.user.is_authenticated:
65             messages.add_message(self.request, messages.ERROR,
66                                  'You need to be logged in to book a Pod.')
67             return super(BookingFormView, self).form_invalid(form)
68
69         user = self.request.user
70         booking = Booking(start=form.cleaned_data['start'],
71                           end=form.cleaned_data['end'],
72                           purpose=form.cleaned_data['purpose'],
73                           opsys=form.cleaned_data['opsys'],
74                           installer=form.cleaned_data['installer'],
75                           scenario=form.cleaned_data['scenario'],
76                           resource=self.resource, user=user)
77         try:
78             booking.save()
79         except ValueError as err:
80             messages.add_message(self.request, messages.ERROR, err)
81             return super(BookingFormView, self).form_invalid(form)
82         try:
83             if settings.CREATE_JIRA_TICKET:
84                 create_jira_ticket(user, booking)
85         except JIRAError:
86             messages.add_message(self.request, messages.ERROR, 'Failed to create Jira Ticket. '
87                                                                'Please check your Jira '
88                                                                'permissions.')
89             booking.delete()
90             return super(BookingFormView, self).form_invalid(form)
91         messages.add_message(self.request, messages.SUCCESS, 'Booking saved')
92         return super(BookingFormView, self).form_valid(form)
93
94
95 class BookingEditFormView(FormView):
96     template_name = "booking/booking_calendar.html"
97     form_class = BookingEditForm
98
99     def is_valid(self):
100         return True
101
102     def dispatch(self, request, *args, **kwargs):
103         self.resource = get_object_or_404(Resource, id=self.kwargs['resource_id'])
104         self.original_booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
105         return super(BookingEditFormView, self).dispatch(request, *args, **kwargs)
106
107     def get_context_data(self, **kwargs):
108         title = 'Editing Booking on: ' + self.resource.name
109         context = super(BookingEditFormView, self).get_context_data(**kwargs)
110         context.update({'title': title, 'resource': self.resource})
111         return context
112
113     def get_form_kwargs(self):
114         kwargs = super(BookingEditFormView, self).get_form_kwargs()
115         kwargs['purpose'] = self.original_booking.purpose
116         kwargs['start'] = self.original_booking.start
117         kwargs['end'] = self.original_booking.end
118         try:
119             kwargs['installer'] = self.original_booking.installer
120         except AttributeError:
121             pass
122         try:
123             kwargs['scenario'] = self.original_booking.scenario
124         except AttributeError:
125             pass
126         return kwargs
127
128     def get_success_url(self):
129         return reverse('booking:create', args=(self.resource.id,))
130
131     def form_valid(self, form):
132
133         if not self.request.user.is_authenticated:
134             messages.add_message(self.request, messages.ERROR,
135                                  'You need to be logged in to book a Pod.')
136             return super(BookingEditFormView, self).form_invalid(form)
137
138         if not self.request.user == self.original_booking.user:
139             messages.add_message(self.request, messages.ERROR,
140                                  'You are not the owner of this booking.')
141             return super(BookingEditFormView, self).form_invalid(form)
142
143         #Do Conflict Checks
144         if self.original_booking.start != form.cleaned_data['start']:
145             if timezone.now() > form.cleaned_data['start']:
146                 messages.add_message(self.request, messages.ERROR,
147                                      'Cannot change start date after it has occurred.')
148                 return super(BookingEditFormView, self).form_invalid(form)
149         self.original_booking.start = form.cleaned_data['start']
150         self.original_booking.end = form.cleaned_data['end']
151         self.original_booking.purpose = form.cleaned_data['purpose']
152         self.original_booking.installer = form.cleaned_data['installer']
153         self.original_booking.scenario = form.cleaned_data['scenario']
154         self.original_booking.reset = form.cleaned_data['reset']
155         try:
156             self.original_booking.save()
157         except ValueError as err:
158             messages.add_message(self.request, messages.ERROR, err)
159             return super(BookingEditFormView, self).form_invalid(form)
160
161         user = self.request.user
162         return super(BookingEditFormView, self).form_valid(form)
163
164 class BookingView(TemplateView):
165     template_name = "booking/booking_detail.html"
166
167
168     def get_context_data(self, **kwargs):
169         booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
170         title = 'Booking Details'
171         context = super(BookingView, self).get_context_data(**kwargs)
172         context.update({'title': title, 'booking': booking})
173         return context
174
175 class BookingDeleteView(TemplateView):
176     template_name = "booking/booking_delete.html"
177
178     def get_context_data(self, **kwargs):
179         booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
180         title = 'Delete Booking'
181         context = super(BookingDeleteView, self).get_context_data(**kwargs)
182         context.update({'title': title, 'booking': booking})
183         return context
184
185 def bookingDelete(request, booking_id):
186     booking = get_object_or_404(Booking, id=booking_id)
187     booking.delete()
188     messages.add_message(request, messages.SUCCESS, 'Booking deleted')
189     return redirect('../../../../')
190
191 class BookingListView(TemplateView):
192     template_name = "booking/booking_list.html"
193
194     def get_context_data(self, **kwargs):
195         bookings = Booking.objects.filter(end__gte=timezone.now())
196         title = 'Search Booking'
197         context = super(BookingListView, self).get_context_data(**kwargs)
198         context.update({'title': title, 'bookings': bookings})
199         return context
200
201
202 class ResourceBookingsJSON(View):
203     def get(self, request, *args, **kwargs):
204         resource = get_object_or_404(Resource, id=self.kwargs['resource_id'])
205         bookings = resource.booking_set.get_queryset().values('id', 'start', 'end', 'purpose',
206                                                               'jira_issue_status', 'opsys__name',
207                                                               'installer__name', 'scenario__name')
208         return JsonResponse({'bookings': list(bookings)})