Link AUP from dashboard
[pharos-tools.git] / dashboard / src / booking / models.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
11 from django.conf import settings
12 from django.contrib.auth.models import User
13 from django.db import models
14 from jira import JIRA
15 from jira import JIRAError
16 from django.utils.crypto import get_random_string
17 import hashlib
18
19 from dashboard.models import Resource
20
21
22 class Installer(models.Model):
23     id = models.AutoField(primary_key=True)
24     name = models.CharField(max_length=30)
25
26     def __str__(self):
27         return self.name
28
29 class Scenario(models.Model):
30     id = models.AutoField(primary_key=True)
31     name = models.CharField(max_length=300)
32
33     def __str__(self):
34         return self.name
35
36 class Opsys(models.Model):
37     id = models.AutoField(primary_key=True)
38     name = models.CharField(max_length=100)
39
40     def __str__(self):
41         return self.name
42
43 class Booking(models.Model):
44     id = models.AutoField(primary_key=True)
45     changeid = models.TextField(default='initial', blank=True, null=True)
46     user = models.ForeignKey(User, models.CASCADE)  # delete if user is deleted
47     resource = models.ForeignKey(Resource, models.PROTECT)
48     start = models.DateTimeField()
49     end = models.DateTimeField()
50     reset = models.BooleanField(default=False)
51     jira_issue_id = models.IntegerField(null=True)
52     jira_issue_status = models.CharField(max_length=50)
53
54     opsys = models.ForeignKey(Opsys, models.DO_NOTHING, null=True)
55     installer = models.ForeignKey(Installer, models.DO_NOTHING, null=True)
56     scenario = models.ForeignKey(Scenario, models.DO_NOTHING, null=True)
57     purpose = models.CharField(max_length=300, blank=False)
58
59     class Meta:
60         db_table = 'booking'
61
62     def get_jira_issue(self):
63         try:
64             jira = JIRA(server=settings.JIRA_URL,
65                         basic_auth=(settings.JIRA_USER_NAME, settings.JIRA_USER_PASSWORD))
66             issue = jira.issue(self.jira_issue_id)
67             return issue
68         except JIRAError:
69             return None
70
71     def save(self, *args, **kwargs):
72         """
73         Save the booking if self.user is authorized and there is no overlapping booking.
74         Raise PermissionError if the user is not authorized
75         Raise ValueError if there is an overlapping booking
76         """
77         if self.start >= self.end:
78             raise ValueError('Start date is after end date')
79         # conflicts end after booking starts, and start before booking ends
80         conflicting_dates = Booking.objects.filter(resource=self.resource).exclude(id=self.id)
81         conflicting_dates = conflicting_dates.filter(end__gt=self.start)
82         conflicting_dates = conflicting_dates.filter(start__lt=self.end)
83         if conflicting_dates.count() > 0:
84             raise ValueError('This booking overlaps with another booking')
85         if not self.changeid:
86             self.changeid = self.id
87         else:
88             self.changeid = hashlib.md5(self.changeid.encode() + get_random_string(length=32).encode()).hexdigest()
89         return super(Booking, self).save(*args, **kwargs)
90
91     def __str__(self):
92         return str(self.resource) + ' from ' + str(self.start) + ' until ' + str(self.end)