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