summaryrefslogtreecommitdiffstats
path: root/tools/pharos-dashboard/booking/models.py
blob: 4be8ccabae0f45e3a7dd1fc037b3a1f3fc2d4ccd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from django.contrib.auth.models import User
from django.db import models
from jira import JIRA

from dashboard.models import Resource
from pharos_dashboard import settings


class Booking(models.Model):
    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(User, models.CASCADE)  # delete if user is deleted
    resource = models.ForeignKey(Resource, models.PROTECT)
    start = models.DateTimeField()
    end = models.DateTimeField()
    jira_issue_id = models.IntegerField(null=True)

    purpose = models.CharField(max_length=300, blank=False)

    class Meta:
        db_table = 'booking'

    def get_jira_issue(self):
        jira = JIRA(server=settings.JIRA_URL, basic_auth=(settings.JIRA_USER_NAME, settings.JIRA_USER_PASSWORD))
        issue = jira.issue(self.jira_issue_id)
        return issue

    def authorization_test(self):
        """
        Return True if self.user is authorized to make this booking.
        """
        user = self.user
        # Check if User is troubleshooter / admin
        if user.has_perm('booking.add_booking'):
            return True
        # Check if User owns this resource
        if user == self.resource.owner:
            return True
        return False

    def save(self, *args, **kwargs):
        """
        Save the booking if self.user is authorized and there is no overlapping booking.
        Raise PermissionError if the user is not authorized
        Raise ValueError if there is an overlapping booking
        """
        if not self.authorization_test():
            raise PermissionError('Insufficient permissions to save this booking.')
        if self.start >= self.end:
            raise ValueError('Start date is after end date')
        # conflicts end after booking starts, and start before booking ends
        conflicting_dates = Booking.objects.filter(resource=self.resource).exclude(id=self.id)
        conflicting_dates = conflicting_dates.filter(end__gt=self.start)
        conflicting_dates = conflicting_dates.filter(start__lt=self.end)
        if conflicting_dates.count() > 0:
            raise ValueError('This booking overlaps with another booking')
        return super(Booking, self).save(*args, **kwargs)

    def __str__(self):
        return str(self.resource) + ' from ' + str(self.start) + ' until ' + str(self.end)