200dc830ff448c88e275261ed9370f460b09f9d3
[pharos.git] / tools / pharos-dashboard / 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.contrib.auth.models import User
12 from django.db import models
13 from jira import JIRA
14 from jira import JIRAError
15
16 from dashboard.models import Resource
17 from django.conf import settings
18
19
20 class Booking(models.Model):
21     id = models.AutoField(primary_key=True)
22     user = models.ForeignKey(User, models.CASCADE)  # delete if user is deleted
23     resource = models.ForeignKey(Resource, models.PROTECT)
24     start = models.DateTimeField()
25     end = models.DateTimeField()
26     jira_issue_id = models.IntegerField(null=True)
27     jira_issue_status = models.CharField(max_length=50)
28
29     purpose = models.CharField(max_length=300, blank=False)
30
31     class Meta:
32         db_table = 'booking'
33
34     def get_jira_issue(self):
35         try:
36             jira = JIRA(server=settings.JIRA_URL,
37                         basic_auth=(settings.JIRA_USER_NAME, settings.JIRA_USER_PASSWORD))
38             issue = jira.issue(self.jira_issue_id)
39             return issue
40         except JIRAError:
41             return None
42
43     def authorization_test(self):
44         """
45         Return True if self.user is authorized to make this booking.
46         """
47         user = self.user
48         # Check if User is troubleshooter / admin
49         if user.has_perm('booking.add_booking'):
50             return True
51         # Check if User owns this resource
52         if user == self.resource.owner:
53             return True
54         return False
55
56     def save(self, *args, **kwargs):
57         """
58         Save the booking if self.user is authorized and there is no overlapping booking.
59         Raise PermissionError if the user is not authorized
60         Raise ValueError if there is an overlapping booking
61         """
62         if not self.authorization_test():
63             raise PermissionError('Insufficient permissions to save this booking.')
64         if self.start >= self.end:
65             raise ValueError('Start date is after end date')
66         # conflicts end after booking starts, and start before booking ends
67         conflicting_dates = Booking.objects.filter(resource=self.resource).exclude(id=self.id)
68         conflicting_dates = conflicting_dates.filter(end__gt=self.start)
69         conflicting_dates = conflicting_dates.filter(start__lt=self.end)
70         if conflicting_dates.count() > 0:
71             raise ValueError('This booking overlaps with another booking')
72         return super(Booking, self).save(*args, **kwargs)
73
74     def __str__(self):
75         return str(self.resource) + ' from ' + str(self.start) + ' until ' + str(self.end)