Files
PyRIGS/RIGS/models.py
Tom Price b52da8c2c0 Changes to importer:
Added delete method to all importers
Added nonrig importing
Venue import optimisation

Reran importer for empty DB
Reset password appropriately

Added view permission to all models where needed.
Migrated DB to reflect.

Fixed all print buttons on event detail.
2014-12-08 02:42:18 +00:00

281 lines
9.2 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
class Meta:
permissions = (
('view_person', 'Can view Persons'),
)
@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 Meta:
permissions = (
('view_organisation', 'Can view Organisations'),
)
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 Meta:
permissions = (
('view_venue', 'Can view Venues'),
)
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', blank=True, null=True)
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 Meta:
permissions = (
('view_event', 'Can view Events'),
)
class EventItem(models.Model):
event = models.ForeignKey('Event', related_name='items', blank=True)
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)