aboutsummaryrefslogtreecommitdiffstats
path: root/src/booking
diff options
context:
space:
mode:
authorSawyer Bergeron <sbergeron@iol.unh.edu>2018-01-05 16:07:13 -0500
committerSawyer Bergeron <sbergeron@iol.unh.edu>2018-01-09 15:03:34 -0500
commita1df798486c60c911dfb2e6c2c487f7bcb7f6d01 (patch)
tree60bec95b5de53c332ab1101240095940e5a4554b /src/booking
parentc81da17a046f1ad81f05de8a242b14ec02cf7c9a (diff)
Implement Booking Modification Interface
Jira: PHAROS-330 Users can change start date if it has not already occurred, and can change end date, purpose, and both installer and scenario. Standard checks apply similar to when initially creating a booking. Change-Id: Ibae7fe91a58bd6e0741db065265c05c3823bdc27 Signed-off-by: Sawyer Bergeron <sbergeron@iol.unh.edu>
Diffstat (limited to 'src/booking')
-rw-r--r--src/booking/forms.py44
-rw-r--r--src/booking/migrations/0002_booking_changeid.py (renamed from src/booking/migrations/0002_auto_20171213_1506.py)10
-rw-r--r--src/booking/migrations/0003_auto_20180108_2024.py25
-rw-r--r--src/booking/models.py8
-rw-r--r--src/booking/urls.py1
-rw-r--r--src/booking/views.py74
6 files changed, 157 insertions, 5 deletions
diff --git a/src/booking/forms.py b/src/booking/forms.py
index 1f09c05..b4acd8f 100644
--- a/src/booking/forms.py
+++ b/src/booking/forms.py
@@ -11,10 +11,21 @@
import django.forms as forms
from booking.models import Installer, Scenario, Opsys
-
+from datetime import datetime
class BookingForm(forms.Form):
- fields = ['start', 'end', 'purpose', 'opsys', 'installer', 'scenario']
+ fields = ['start', 'end', 'purpose', 'opsys', 'reset', 'installer', 'scenario']
+
+ start = forms.DateTimeField()
+ end = forms.DateTimeField()
+ reset = forms.ChoiceField(choices = ((True, 'Yes'),(False, 'No')), label="Reset System", initial='False', required=False)
+ purpose = forms.CharField(max_length=300)
+ opsys = forms.ModelChoiceField(queryset=Opsys.objects.all(), required=False)
+ installer = forms.ModelChoiceField(queryset=Installer.objects.all(), required=False)
+ scenario = forms.ModelChoiceField(queryset=Scenario.objects.all(), required=False)
+
+class BookingEditForm(forms.Form):
+ fields = ['start', 'end', 'purpose', 'opsys', 'reset', 'installer', 'scenario']
start = forms.DateTimeField()
end = forms.DateTimeField()
@@ -22,3 +33,32 @@ class BookingForm(forms.Form):
opsys = forms.ModelChoiceField(queryset=Opsys.objects.all(), required=False)
installer = forms.ModelChoiceField(queryset=Installer.objects.all(), required=False)
scenario = forms.ModelChoiceField(queryset=Scenario.objects.all(), required=False)
+ reset = forms.ChoiceField(choices = ((True, 'Yes'),(False, 'No')), label="Reset System", initial='False', required=True)
+
+
+ def __init__(self, *args, **kwargs ):
+ cloned_kwargs = {}
+ cloned_kwargs['purpose'] = kwargs.pop('purpose')
+ cloned_kwargs['start'] = kwargs.pop('start')
+ cloned_kwargs['end'] = kwargs.pop('end')
+ if 'installer' in kwargs:
+ cloned_kwargs['installer'] = kwargs.pop('installer')
+ if 'scenario' in kwargs:
+ cloned_kwargs['scenario'] = kwargs.pop('scenario')
+ super(BookingEditForm, self).__init__( *args, **kwargs)
+
+ self.fields['purpose'].initial = cloned_kwargs['purpose']
+ self.fields['start'].initial = cloned_kwargs['start'].strftime('%m/%d/%Y %H:%M')
+ self.fields['end'].initial = cloned_kwargs['end'].strftime('%m/%d/%Y %H:%M')
+ try:
+ self.fields['installer'].initial = cloned_kwargs['installer'].id
+ except KeyError:
+ pass
+ except AttributeError:
+ pass
+ try:
+ self.fields['scenario'].initial = cloned_kwargs['scenario'].id
+ except KeyError:
+ pass
+ except AttributeError:
+ pass
diff --git a/src/booking/migrations/0002_auto_20171213_1506.py b/src/booking/migrations/0002_booking_changeid.py
index 3e0a5fa..33af8fd 100644
--- a/src/booking/migrations/0002_auto_20171213_1506.py
+++ b/src/booking/migrations/0002_booking_changeid.py
@@ -25,4 +25,14 @@ class Migration(migrations.Migration):
name='opsys',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='booking.Opsys'),
),
+ migrations.AddField(
+ model_name='booking',
+ name='changeid',
+ field=models.TextField(default='no change ID'),
+ ),
+ migrations.AlterField(
+ model_name='booking',
+ name='changeid',
+ field=models.TextField(blank=True, default='no change ID', null=True),
+ ),
]
diff --git a/src/booking/migrations/0003_auto_20180108_2024.py b/src/booking/migrations/0003_auto_20180108_2024.py
new file mode 100644
index 0000000..93cecc2
--- /dev/null
+++ b/src/booking/migrations/0003_auto_20180108_2024.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2018-01-08 20:24
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('booking', '0002_booking_changeid'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='booking',
+ name='reset',
+ field=models.BooleanField(default=False),
+ ),
+ migrations.AlterField(
+ model_name='booking',
+ name='changeid',
+ field=models.TextField(blank=True, default='initial', null=True),
+ ),
+ ] \ No newline at end of file
diff --git a/src/booking/models.py b/src/booking/models.py
index 0bf5961..9156484 100644
--- a/src/booking/models.py
+++ b/src/booking/models.py
@@ -13,6 +13,8 @@ from django.contrib.auth.models import User
from django.db import models
from jira import JIRA
from jira import JIRAError
+from django.utils.crypto import get_random_string
+import hashlib
from dashboard.models import Resource
@@ -40,10 +42,12 @@ class Opsys(models.Model):
class Booking(models.Model):
id = models.AutoField(primary_key=True)
+ changeid = models.TextField(default='initial', blank=True, null=True)
user = models.ForeignKey(User, models.CASCADE) # delete if user is deleted
resource = models.ForeignKey(Resource, models.PROTECT)
start = models.DateTimeField()
end = models.DateTimeField()
+ reset = models.BooleanField(default=False)
jira_issue_id = models.IntegerField(null=True)
jira_issue_status = models.CharField(max_length=50)
@@ -78,6 +82,10 @@ class Booking(models.Model):
conflicting_dates = conflicting_dates.filter(start__lt=self.end)
if conflicting_dates.count() > 0:
raise ValueError('This booking overlaps with another booking')
+ if not self.changeid:
+ self.changeid = self.id
+ else:
+ self.changeid = hashlib.md5(self.changeid.encode() + get_random_string(length=32).encode()).hexdigest()
return super(Booking, self).save(*args, **kwargs)
def __str__(self):
diff --git a/src/booking/urls.py b/src/booking/urls.py
index 9e01316..403e32f 100644
--- a/src/booking/urls.py
+++ b/src/booking/urls.py
@@ -29,6 +29,7 @@ from booking.views import *
urlpatterns = [
url(r'^(?P<resource_id>[0-9]+)/$', BookingFormView.as_view(), name='create'),
+ url(r'^(?P<resource_id>[0-9]+)/edit/(?P<booking_id>[0-9]+)/$', BookingEditFormView.as_view(), name='edit'),
url(r'^(?P<resource_id>[0-9]+)/bookings_json/$', ResourceBookingsJSON.as_view(),
name='bookings_json'),
diff --git a/src/booking/views.py b/src/booking/views.py
index da2fe11..ab3a04e 100644
--- a/src/booking/views.py
+++ b/src/booking/views.py
@@ -7,7 +7,6 @@
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
@@ -21,11 +20,10 @@ from django.views.generic import TemplateView
from jira import JIRAError
from account.jira_util import get_jira
-from booking.forms import BookingForm
+from booking.forms import BookingForm, BookingEditForm
from booking.models import Booking
from dashboard.models import Resource
-
def create_jira_ticket(user, booking):
jira = get_jira(user)
issue_dict = {
@@ -55,6 +53,7 @@ class BookingFormView(FormView):
title = 'Booking: ' + self.resource.name
context = super(BookingFormView, self).get_context_data(**kwargs)
context.update({'title': title, 'resource': self.resource})
+ #raise PermissionDenied('check')
return context
def get_success_url(self):
@@ -92,6 +91,75 @@ class BookingFormView(FormView):
return super(BookingFormView, self).form_valid(form)
+class BookingEditFormView(FormView):
+ template_name = "booking/booking_calendar.html"
+ form_class = BookingEditForm
+
+ def is_valid(self):
+ return True
+
+ def dispatch(self, request, *args, **kwargs):
+ self.resource = get_object_or_404(Resource, id=self.kwargs['resource_id'])
+ self.original_booking = get_object_or_404(Booking, id=self.kwargs['booking_id'])
+ return super(BookingEditFormView, self).dispatch(request, *args, **kwargs)
+
+ def get_context_data(self, **kwargs):
+ title = 'Editing Booking on: ' + self.resource.name
+ context = super(BookingEditFormView, self).get_context_data(**kwargs)
+ context.update({'title': title, 'resource': self.resource})
+ return context
+
+ def get_form_kwargs(self):
+ kwargs = super(BookingEditFormView, self).get_form_kwargs()
+ kwargs['purpose'] = self.original_booking.purpose
+ kwargs['start'] = self.original_booking.start
+ kwargs['end'] = self.original_booking.end
+ try:
+ kwargs['installer'] = self.original_booking.installer
+ except AttributeError:
+ pass
+ try:
+ kwargs['scenario'] = self.original_booking.scenario
+ except AttributeError:
+ pass
+ return kwargs
+
+ def get_success_url(self):
+ return reverse('booking:create', args=(self.resource.id,))
+
+ def form_valid(self, form):
+
+ if not self.request.user.is_authenticated:
+ messages.add_message(self.request, messages.ERROR,
+ 'You need to be logged in to book a Pod.')
+ return super(BookingEditFormView, self).form_invalid(form)
+
+ if not self.request.user == self.original_booking.user:
+ messages.add_message(self.request, messages.ERROR,
+ 'You are not the owner of this booking.')
+ return super(BookingEditFormView, self).form_invalid(form)
+
+ #Do Conflict Checks
+ if self.original_booking.start != form.cleaned_data['start']:
+ if timezone.now() > form.cleaned_data['start']:
+ messages.add_message(self.request, messages.ERROR,
+ 'Cannot change start date after it has occurred.')
+ return super(BookingEditFormView, self).form_invalid(form)
+ self.original_booking.start = form.cleaned_data['start']
+ self.original_booking.end = form.cleaned_data['end']
+ self.original_booking.purpose = form.cleaned_data['purpose']
+ self.original_booking.installer = form.cleaned_data['installer']
+ self.original_booking.scenario = form.cleaned_data['scenario']
+ self.original_booking.reset = form.cleaned_data['reset']
+ try:
+ self.original_booking.save()
+ except ValueError as err:
+ messages.add_message(self.request, messages.ERROR, err)
+ return super(BookingEditFormView, self).form_invalid(form)
+
+ user = self.request.user
+ return super(BookingEditFormView, self).form_valid(form)
+
class BookingView(TemplateView):
template_name = "booking/booking_detail.html"