Files
PyRIGS/RIGS/models.py
Tom Price 737d79ef48 Enabled event create button
Added MIC field to the event form

Added the ability to specify the fields you want to query in an api request

Changes to the user profile to enable queries via the API
2014-12-02 01:24:38 +00:00

260 lines
8.7 KiB
Python

import hashlib
import datetime
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.conf import settings
import reversion
# Create your models here.
class Profile(AbstractUser):
initials = models.CharField(max_length=5, unique=True, null=True, blank=True)
phone = models.CharField(max_length=13, null=True, blank=True)
@property
def profile_picture(self):
url = ""
if settings.USE_GRAVATAR or settings.USE_GRAVATAR is None:
url = "https://www.gravatar.com/avatar/" + hashlib.md5(self.email).hexdigest() + "?d=identicon&s=500"
return url
@property
def name(self):
return self.get_full_name() + ' "' + self.initials + '"'
class RevisionMixin(object):
@property
def last_edited_at(self):
version = reversion.get_for_object(self)[0]
return version.revision.date_created
@property
def last_edited_by(self):
version = reversion.get_for_object(self)[0]
return version.revision.user
@reversion.register
class Person(models.Model, RevisionMixin):
name = models.CharField(max_length=50)
phone = models.CharField(max_length=15, blank=True, null=True)
email = models.EmailField(blank=True, null=True)
address = models.TextField(blank=True, null=True)
notes = models.TextField(blank=True, null=True)
def __str__(self):
string = self.name
if len(self.notes) > 0:
string += "*"
return string
@reversion.register
class Organisation(models.Model, RevisionMixin):
name = models.CharField(max_length=50)
phone = models.CharField(max_length=15, blank=True, null=True)
email = models.EmailField(blank=True, null=True)
address = models.TextField(blank=True, null=True)
notes = models.TextField(blank=True, null=True)
union_account = models.BooleanField(default=False)
def __str__(self):
string = self.name
if len(self.notes) > 0:
string += "*"
return string
class VatManager(models.Manager):
def current_rate(self):
return self.find_rate(datetime.datetime.now())
def find_rate(self, date):
# return self.filter(startAt__lte=date).latest()
try:
return self.filter(start_at__lte=date).latest()
except VatRate.DoesNotExist:
r = VatRate
r.rate = 0
return r
@reversion.register
class VatRate(models.Model, RevisionMixin):
start_at = models.DateTimeField()
rate = models.DecimalField(max_digits=6, decimal_places=6)
comment = models.CharField(max_length=255)
objects = VatManager()
@property
def as_percent(self):
return self.rate * 100
class Meta:
ordering = ['-start_at']
get_latest_by = 'start_at'
def __str__(self):
return self.comment + " " + str(self.start_at) + " @ " + str(self.as_percent) + "%"
@reversion.register
class Venue(models.Model, RevisionMixin):
name = models.CharField(max_length=255)
phone = models.CharField(max_length=15, blank=True, null=True)
email = models.EmailField(blank=True, null=True)
three_phase_available = models.BooleanField(default=False)
notes = models.TextField(blank=True, null=True)
address = models.TextField(blank=True, null=True)
def __str__(self):
string = self.name
if self.notes and len(self.notes) > 0:
string += "*"
return string
class EventManager(models.Manager):
def current_events(self):
# startAfter = self.filter(startDate__gte=datetime.date.today(), endDate__isnull=True)
# endAfter = self.filter(endDate__gte=datetime.date.today())
# activeDryHire = filter(dryHire=True, checkedInBy__isnull=False, canceled=False)
# canceledDryHire = filter(dry_hire=True, canceled=True)
# events = chain(startAfter, endAfter, activeDryHire, canceledDryHire)
# return sorted(events, key=operator.attrgetter('start_date'))
events = self.filter(
models.Q(start_date__gte=datetime.date.today(), end_date__isnull=True) | # Starts after with no end
models.Q(end_date__gte=datetime.date.today()) | # Ends after
models.Q(dry_hire=True, checked_in_by__isnull=False, status__lt=Event.CANCELLED) | # Active dry hire LT
models.Q(dry_hire=True, checked_in_by__isnull=False, status__gt=Event.CANCELLED) | # Active dry hire GT
models.Q(dry_hire=True, status=Event.CANCELLED, start_date__gte=datetime.date.today())
# Canceled but not started
).order_by('meet_at', 'start_date')
return events
def rig_count(self):
events = self.filter(
models.Q(start_date__gte=datetime.date.today(), end_date__isnull=True,
is_rig=True) | # Starts after with no end
models.Q(end_date__gte=datetime.date.today(), is_rig=True) | # Ends after
models.Q(dry_hire=True, checked_in_by__isnull=False, status__lt=Event.CANCELLED,
is_rig=True) | # Active dry hire LT
models.Q(dry_hire=True, checked_in_by__isnull=False, status__gt=Event.CANCELLED, is_rig=True)
# Active dry hire GT
).order_by('meet_at', 'start_date')
return len(events)
@reversion.register(follow=['items'])
class Event(models.Model, RevisionMixin):
# Done to make it much nicer on the database
PROVISIONAL = 0
CONFIRMED = 1
BOOKED = 2
CANCELLED = 3
EVENT_STATUS_CHOICES = (
(PROVISIONAL, 'Provisional'),
(CONFIRMED, 'Confirmed'),
(BOOKED, 'Booked'),
(CANCELLED, 'Cancelled'),
)
name = models.CharField(max_length=255)
person = models.ForeignKey('Person', null=True, blank=True)
organisation = models.ForeignKey('Organisation', blank=True, null=True)
venue = models.ForeignKey('Venue')
description = models.TextField(blank=True, null=True)
notes = models.TextField(blank=True, null=True)
status = models.IntegerField(choices=EVENT_STATUS_CHOICES, default=PROVISIONAL)
dry_hire = models.BooleanField(default=False)
is_rig = models.BooleanField(default=True)
based_on = models.ForeignKey('Event', related_name='future_events', blank=True, null=True)
# Timing
start_date = models.DateField()
start_time = models.TimeField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True)
end_time = models.TimeField(blank=True, null=True)
access_at = models.DateTimeField(blank=True, null=True)
meet_at = models.DateTimeField(blank=True, null=True)
meet_info = models.CharField(max_length=255, blank=True, null=True)
# Crew management
checked_in_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='event_checked_in', blank=True, null=True)
mic = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='event_mic', blank=True, null=True)
# Monies
payment_method = models.CharField(max_length=255, blank=True, null=True)
payment_received = models.CharField(max_length=255, blank=True, null=True)
purchase_order = models.CharField(max_length=255, blank=True, null=True)
collector = models.CharField(max_length=255, blank=True, null=True)
# Calculated values
@property
def sum_total(self):
total = 0
for item in self.items.all():
total += item.total_cost
return total
@property
def vat_rate(self):
return VatRate.objects.find_rate(self.start_date)
@property
def vat(self):
return self.sum_total * self.vat_rate.rate
@property
def total(self):
return self.sum_total + self.vat
@property
def cancelled(self):
return (self.status == self.CANCELLED)
@property
def confirmed(self):
return (self.status == self.BOOKED or self.status == self.CONFIRMED)
objects = EventManager()
def __str__(self):
return str(self.pk) + ": " + self.name
class EventItem(models.Model):
event = models.ForeignKey('Event', related_name='items')
name = models.CharField(max_length=255)
description = models.TextField(blank=True, null=True)
quantity = models.IntegerField()
cost = models.DecimalField(max_digits=10, decimal_places=2)
order = models.IntegerField()
@property
def total_cost(self):
return self.cost * self.quantity
class Meta:
ordering = ['order']
def __str__(self):
return str(self.event.pk) + "." + str(self.order) + ": " + self.event.name + " | " + self.name
class EventCrew(models.Model):
event = models.ForeignKey('Event', related_name='crew')
user = models.ForeignKey(settings.AUTH_USER_MODEL)
rig = models.BooleanField(default=False)
run = models.BooleanField(default=False)
derig = models.BooleanField(default=False)
notes = models.TextField(blank=True, null=True)