diff --git a/RIGS/models/events.py b/RIGS/models/events.py index 151dd606..0ba41fb7 100644 --- a/RIGS/models/events.py +++ b/RIGS/models/events.py @@ -290,7 +290,6 @@ class Event(BaseEvent): """ Inc VAT """ - @property def total(self): return Decimal(self.sum_total + self.vat).quantize(Decimal('.01')) @@ -337,9 +336,8 @@ class Event(BaseEvent): return "danger" elif self.confirmed and self.authorised: if self.dry_hire or self.riskassessment: - return "success" - else: - return "warning" + return "success" + return "warning" else: return "warning" @@ -360,7 +358,7 @@ class Event(BaseEvent): elif self.start_time is not None and self.start_date == self.access_at.date() and self.access_at.time() > self.start_time: errdict['access_at'] = ['Regardless of what some clients might think, access time cannot be after the event has started.'] - if errdict != {}: # If there was an error when validation + if errdict: # If there was an error when validation raise ValidationError(errdict) def save(self, *args, **kwargs): @@ -435,9 +433,16 @@ class Subhire(BaseEvent): events = models.ManyToManyField(Event) quote = models.URLField(default='', validators=[validate_url]) - objects = SubhireManager() + @property + def is_rig(self): + return False + + @property + def dry_hire(self): + return False + @property def display_id(self): return f"S{self.pk:05d}" diff --git a/RIGS/views/ical.py b/RIGS/views/ical.py index 087cd594..2ec5045f 100644 --- a/RIGS/views/ical.py +++ b/RIGS/views/ical.py @@ -1,12 +1,14 @@ import datetime -import pytz +from django.utils import timezone from django.conf import settings from django.db.models import Q from django_ical.views import ICalFeed from RIGS import models +from itertools import chain + class CalendarICS(ICalFeed): """ @@ -31,6 +33,7 @@ class CalendarICS(ICalFeed): params['dry-hire'] = request.GET.get('dry-hire', 'true') == 'true' params['non-rig'] = request.GET.get('non-rig', 'true') == 'true' params['rig'] = request.GET.get('rig', 'true') == 'true' + params['subhire'] = request.GET.get('subhire', 'true') == 'true' params['cancelled'] = request.GET.get('cancelled', 'false') == 'true' params['provisional'] = request.GET.get('provisional', 'true') == 'true' @@ -40,42 +43,46 @@ class CalendarICS(ICalFeed): def description(self, params): desc = "Calendar generated by RIGS system. This includes event types: " + ('Rig, ' if params['rig'] else '') + ( - 'Non-rig, ' if params['non-rig'] else '') + ('Dry Hire ' if params['dry-hire'] else '') + '\n' - desc = desc + "Includes events with status: " + ('Cancelled, ' if params['cancelled'] else '') + ( + 'Non-rig, ' if params['non-rig'] else '') + ('Dry Hire, ' if params['dry-hire'] else '') + ('Subhires' if params['subhire'] else '') + '\n' + desc += "Includes events with status: " + ('Cancelled, ' if params['cancelled'] else '') + ( 'Provisional, ' if params['provisional'] else '') + ('Confirmed/Booked, ' if params['confirmed'] else '') return desc def items(self, params): # include events from up to 1 year ago - start = datetime.datetime.now() - datetime.timedelta(days=365) + start = timezone.now() - datetime.timedelta(days=365) filter = Q(start_date__gte=start) - typeFilters = Q(pk=None) # Need something that is false for every entry + type_filters = Q(pk=None) # Need something that is false for every entry if params['dry-hire']: - typeFilters = typeFilters | Q(dry_hire=True, is_rig=True) + type_filters = type_filters | Q(dry_hire=True, is_rig=True) if params['non-rig']: - typeFilters = typeFilters | Q(is_rig=False) + type_filters = type_filters | Q(is_rig=False) if params['rig']: - typeFilters = typeFilters | Q(is_rig=True, dry_hire=False) + type_filters = type_filters | Q(is_rig=True, dry_hire=False) - statusFilters = Q(pk=None) # Need something that is false for every entry + status_filters = Q(pk=None) # Need something that is false for every entry if params['cancelled']: - statusFilters = statusFilters | Q(status=models.Event.CANCELLED) + status_filters = status_filters | Q(status=models.Event.CANCELLED) if params['provisional']: - statusFilters = statusFilters | Q(status=models.Event.PROVISIONAL) + status_filters = status_filters | Q(status=models.Event.PROVISIONAL) if params['confirmed']: - statusFilters = statusFilters | Q(status=models.Event.CONFIRMED) | Q(status=models.Event.BOOKED) + status_filters = status_filters | Q(status=models.Event.CONFIRMED) | Q(status=models.Event.BOOKED) - filter = filter & typeFilters & statusFilters + filter = filter & type_filters & status_filters - return models.Event.objects.filter(filter).order_by('-start_date').select_related('person', 'organisation', + events = models.Event.objects.filter(filter).order_by('-start_date').select_related('person', 'organisation', 'venue', 'mic') + subhires = models.Subhire.objects.filter(status_filters).order_by('-start_date').select_related('person', 'organisation') + + return list(chain(events, subhires)) + def item_title(self, item): title = '' @@ -106,30 +113,32 @@ class CalendarICS(ICalFeed): return item.latest_time def item_location(self, item): - return item.venue + if hasattr(item, 'venue'): + return item.venue + return "" def item_description(self, item): # Create a nice information-rich description # note: only making use of information available to "non-keyholders" - tz = pytz.timezone(self.timezone) - desc = f'Rig ID = {item.display_id}\n' desc += f'Event = {item.name}\n' - desc += 'Venue = ' + (item.venue.name if item.venue else '---') + '\n' + if hasattr(item, 'venue'): + desc += 'Venue = ' + (item.venue.name if item.venue else '---') + '\n' if item.is_rig and item.person: desc += 'Client = ' + item.person.name + ( (' for ' + item.organisation.name) if item.organisation else '') + '\n' desc += f'Status = {item.get_status_display()}\n' - desc += 'MIC = ' + (item.mic.name if item.mic else '---') + '\n' + if hasattr(item, 'mic'): + desc += 'MIC = ' + (item.mic.name if item.mic else '---') + '\n' desc += '\n' - if item.meet_at: + if hasattr(item, 'meet_at') and item.meet_at: desc += 'Crew Meet = ' + ( - item.meet_at.astimezone(tz).strftime('%Y-%m-%d %H:%M') if item.meet_at else '---') + '\n' - if item.access_at: + timezone.make_aware(item.meet_at).strftime('%Y-%m-%d %H:%M') if item.meet_at else '---') + '\n' + if hasattr(item, 'access_at') and item.access_at: desc += 'Access At = ' + ( - item.access_at.astimezone(tz).strftime('%Y-%m-%d %H:%M') if item.access_at else '---') + '\n' + timezone.make_aware(item.access_at).strftime('%Y-%m-%d %H:%M') if item.access_at else '---') + '\n' if item.start_date: desc += 'Event Start = ' + item.start_date.strftime('%Y-%m-%d') + ( (' ' + item.start_time.strftime('%H:%M')) if item.has_start_time else '') + '\n' @@ -140,8 +149,6 @@ class CalendarICS(ICalFeed): desc += '\n' if item.description: desc += f'Event Description:\n{item.description}\n\n' - # if item.notes: // Need to add proper keyholder checks before this gets put back - # desc += 'Notes:\n'+item.notes+'\n\n' desc += f'URL = https://rigs.nottinghamtec.co.uk{item.get_absolute_url()}' diff --git a/users/templates/profile_detail.html b/users/templates/profile_detail.html index a3c6ec11..98577d85 100644 --- a/users/templates/profile_detail.html +++ b/users/templates/profile_detail.html @@ -118,6 +118,11 @@ Dry-Hires + +
+