blechreiz-website/eventplanner/models.py

180 lines
6.4 KiB
Python
Raw Permalink Normal View History

2013-06-02 21:26:10 +02:00
from django.db import models
from django.utils.translation import ugettext as _
from django.contrib.auth.models import User, Permission
from django.db.models import Q
2013-09-26 21:56:32 +02:00
2014-04-18 13:43:02 +02:00
from datetime import datetime
from location_field.models import PlainLocationField
2013-06-02 21:26:10 +02:00
class NoNextEventException(Exception):
def __str__(self):
return "No event scheduled for the future"
2013-06-02 21:26:10 +02:00
class Event(models.Model):
2013-06-02 21:26:10 +02:00
EVENT_TYPES = (
('Reh', _('Rehearsal')),
('Conc', _('Concert')),
('Party', _('Party')),
('Travel', _('Travel')),
('Option', _('Option')),
2013-06-02 21:26:10 +02:00
)
type = models.CharField(max_length=6, choices=EVENT_TYPES, default='Reh', verbose_name=_("type"))
short_desc = models.CharField(null=True, max_length=100, blank=True, verbose_name=_("Short Description"))
location = models.TextField(blank=True, verbose_name=_("location"))
map_location = PlainLocationField(blank=True, based_field=location, zoom=7, verbose_name=_("Location on map"))
desc = models.TextField(blank=True, verbose_name=_("description"))
date = models.DateField(verbose_name=_("date"))
time = models.TimeField(null=True, blank=True, verbose_name=_("time"))
meeting_time = models.TimeField(null=True, blank=True, verbose_name=_("meeting_time"))
end_date = models.DateField(null=True, blank=True, verbose_name=_("End Date"))
participants = models.ManyToManyField(User, through='EventParticipation', verbose_name=_("participants"))
def __unicode__(self):
return self.title
2013-06-02 21:26:10 +02:00
def save(self, *args, **kwargs):
# Call the "real" save() method
super(Event, self).save(*args, **kwargs)
2013-06-02 21:26:10 +02:00
# Create a "Don't Know" participation for each Musician
for u in User.objects.all():
2013-09-26 21:56:32 +02:00
if not u in self.participants.all():
EventParticipation.objects.create(event=self, user=u, status='-', comment='')
@property
def title(self):
res = self.get_type_display()
if self.short_desc:
res += " (" + self.short_desc + ") "
return res
2013-09-15 14:48:40 +02:00
@property
def displaytime(self):
if self.meeting_time is None or self.meeting_time == "":
return self.time
else:
return self.meeting_time
@property
def displaydatetime(self):
if not self.displaytime == None:
return datetime.combine(self.date, self.displaytime)
else:
return datetime.combine(self.date, datetime.min.time())
2013-06-02 21:26:10 +02:00
@staticmethod
def getNextEvent(eventType="", includePreviousFromToday=True):
"""Return the next event, of the given type. If type is the empty string the next event is returned
regardless of its type.
if includePreviousFromToday the nextEvent returned could also have been today with a startime < now """
if includePreviousFromToday:
if eventType == "":
nextEvents = Event.objects.filter(date__gte=datetime.now()).order_by('date')[:1]
else:
nextEvents = Event.objects.filter(date__gte=datetime.now(), type=eventType).order_by('date')[:1]
if len(nextEvents) == 0:
raise NoNextEventException()
return nextEvents[0]
else:
maximalNumberOfEventsOnSameDay = 4
nextEvents = []
if eventType == "":
nextEvents = Event.objects.filter(date__gte=datetime.now()).order_by('date')[
:maximalNumberOfEventsOnSameDay]
else:
nextEvents = Event.objects.filter(date__gte=datetime.now(), type=eventType).order_by('date')[
:maximalNumberOfEventsOnSameDay]
if len(nextEvents) == 0:
raise NoNextEventException()
i = 0
nextEvent = nextEvents[0]
# nextEvent is not necessarily events[0] since events[0] may have been previously today
while nextEvent.displaydatetime < datetime.now():
if len(nextEvents) <= i:
raise NoNextEventException()
else:
i += 1
nextEvent = nextEvents[i]
return nextEvent
2014-04-18 13:43:02 +02:00
class EventParticipation(models.Model):
OPTIONS = (('?', _('?')),
('Yes', _('Yes')),
('No', _('No')),
('-', _('-'))
)
2014-04-18 13:43:02 +02:00
event = models.ForeignKey(Event, verbose_name=_("event"), on_delete=models.PROTECT)
user = models.ForeignKey(User, verbose_name=_("user"), on_delete=models.PROTECT)
status = models.CharField(max_length=3, choices=OPTIONS, default='?', verbose_name=_("status"))
comment = models.CharField(max_length=64, blank=True, verbose_name=_("comment"))
2014-04-18 13:43:02 +02:00
2013-09-26 21:56:32 +02:00
def get_username(self):
return self.user.username
def save(self, *args, **kwargs):
prev = EventParticipation.objects.filter(event=self.event, user=self.user)
if len(prev) == 0:
super(EventParticipation, self).save(*args, **kwargs)
else:
prev = prev[0]
if prev.status != self.status or prev.comment != self.comment:
super(EventParticipation, self).save(*args, **kwargs)
2013-09-15 14:48:40 +02:00
@staticmethod
def hasUserSetParticipationForAllEvents(user):
if not EventParticipation.isMember(user):
return True
2013-09-26 21:56:32 +02:00
futurePart = EventParticipation.objects.filter(event__date__gte=datetime.now())
notYetEntered = futurePart.filter(user=user).filter(status='-')
if len(notYetEntered) > 0:
2013-09-15 14:48:40 +02:00
return False
else:
return True
2014-04-18 13:43:02 +02:00
@staticmethod
def isMember(user):
return user.has_perm('eventplanner.member')
@staticmethod
def isAdmin(user):
return user.has_perm('eventplanner.admin')
@staticmethod
def members():
perm = Permission.objects.get(codename='member')
f = User.objects.filter(Q(groups__permissions=perm) | Q(user_permissions=perm)).distinct()
2013-10-15 21:51:05 +02:00
return f.order_by('musician__position')
@staticmethod
def get_or_create(user, event):
try:
result = EventParticipation.objects.get(event=event, user=user)
except EventParticipation.DoesNotExist:
result = EventParticipation.objects.create(event=event, user=user, status='-', comment='')
return result
2013-06-02 21:26:10 +02:00
class Meta:
2013-09-26 21:56:32 +02:00
unique_together = ("event", "user")
permissions = (
("admin", _("Admin")),
("member", _("Member")),
)