You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
334 lines
14 KiB
334 lines
14 KiB
from datetime import date, datetime |
|
from django.db import models |
|
from django.contrib.auth.models import User |
|
from django.contrib.contenttypes.fields import GenericForeignKey |
|
from django.contrib.contenttypes.models import ContentType |
|
from django.utils.timezone import now, pytz |
|
from simple_history.models import HistoricalRecords |
|
from simple_history import register |
|
|
|
TIMEZONE_CALGARY = pytz.timezone('America/Edmonton') |
|
|
|
register(User) |
|
|
|
IGNORE = '+' |
|
|
|
def today_alberta_tz(): |
|
return datetime.now(TIMEZONE_CALGARY).date() |
|
|
|
class Member(models.Model): |
|
user = models.OneToOneField(User, related_name='member', blank=True, null=True, on_delete=models.SET_NULL) |
|
signup_helper = models.ForeignKey(User, related_name='signed_up', blank=True, null=True, on_delete=models.SET_NULL) |
|
old_email = models.CharField(max_length=254, blank=True, null=True) |
|
photo_large = models.CharField(max_length=64, blank=True, null=True) |
|
photo_medium = models.CharField(max_length=64, blank=True, null=True) |
|
photo_small = models.CharField(max_length=64, blank=True, null=True) |
|
member_forms = models.CharField(max_length=64, blank=True, null=True) |
|
|
|
set_details = models.BooleanField(default=False) |
|
first_name = models.CharField(max_length=32) |
|
last_name = models.CharField(max_length=32) |
|
preferred_name = models.CharField(max_length=32) |
|
phone = models.CharField(default='', max_length=32, null=True) |
|
emergency_contact_name = models.CharField(default='', max_length=64, blank=True) |
|
emergency_contact_phone = models.CharField(default='', max_length=32, blank=True) |
|
birthdate = models.DateField(blank=True, null=True) |
|
is_minor = models.BooleanField(default=False) |
|
guardian_name = models.CharField(max_length=32, blank=True, null=True) |
|
public_bio = models.CharField(max_length=512, blank=True) |
|
private_notes = models.CharField(max_length=512, blank=True) |
|
|
|
is_director = models.BooleanField(default=False) |
|
is_staff = models.BooleanField(default=False) |
|
is_instructor = models.BooleanField(default=False) |
|
status = models.CharField(max_length=32, blank=True, null=True) |
|
expire_date = models.DateField(default=today_alberta_tz, null=True) |
|
current_start_date = models.DateField(default=today_alberta_tz, null=True) |
|
application_date = models.DateField(default=today_alberta_tz, null=True) |
|
vetted_date = models.DateField(blank=True, null=True) |
|
orientation_date = models.DateField(blank=True, null=True, default=None) |
|
lathe_cert_date = models.DateField(blank=True, null=True, default=None) |
|
mill_cert_date = models.DateField(blank=True, null=True, default=None) |
|
wood_cert_date = models.DateField(blank=True, null=True, default=None) |
|
wood2_cert_date = models.DateField(blank=True, null=True, default=None) |
|
tormach_cnc_cert_date = models.DateField(blank=True, null=True, default=None) |
|
precix_cnc_cert_date = models.DateField(blank=True, null=True, default=None) |
|
rabbit_cert_date = models.DateField(blank=True, null=True, default=None) |
|
trotec_cert_date = models.DateField(blank=True, null=True, default=None) |
|
paused_date = models.DateField(blank=True, null=True) |
|
monthly_fees = models.IntegerField(default=55, blank=True, null=True) |
|
is_allowed_entry = models.BooleanField(default=True) |
|
discourse_username = models.CharField(default='', max_length=40, blank=True, null=True) |
|
mediawiki_username = models.CharField(default='', max_length=40, blank=True, null=True) |
|
allow_last_scanned = models.BooleanField(default=True) |
|
|
|
history = HistoricalRecords(excluded_fields=['member_forms']) |
|
|
|
list_display = ['user', 'preferred_name', 'last_name', 'status'] |
|
search_fields = ['user__username', 'preferred_name', 'last_name', 'status'] |
|
def __str__(self): |
|
return getattr(self.user, 'username', 'None') |
|
|
|
class Transaction(models.Model): |
|
user = models.ForeignKey(User, related_name='transactions', blank=True, null=True, on_delete=models.SET_NULL) |
|
recorder = models.ForeignKey(User, related_name=IGNORE, blank=True, null=True, on_delete=models.SET_NULL) |
|
|
|
member_id = models.IntegerField(blank=True, null=True) |
|
date = models.DateField(default=today_alberta_tz) |
|
amount = models.DecimalField(max_digits=7, decimal_places=2) |
|
reference_number = models.CharField(max_length=64, blank=True, null=True) |
|
memo = models.TextField(blank=True, null=True) |
|
number_of_membership_months = models.IntegerField(blank=True, null=True) |
|
payment_method = models.TextField(blank=True, null=True) |
|
category = models.TextField(blank=True, null=True) |
|
account_type = models.TextField(blank=True, null=True) |
|
info_source = models.TextField(blank=True, null=True) |
|
paypal_txn_id = models.CharField(max_length=17, blank=True, null=True, unique=True) |
|
paypal_txn_type = models.CharField(max_length=64, blank=True, null=True) |
|
paypal_payer_id = models.CharField(max_length=13, blank=True, null=True) |
|
protocoin = models.DecimalField(max_digits=7, decimal_places=2, default=0) |
|
|
|
report_type = models.TextField(blank=True, null=True) |
|
report_memo = models.TextField(blank=True, null=True) |
|
|
|
history = HistoricalRecords() |
|
|
|
list_display = ['date', 'user', 'amount', 'protocoin', 'account_type', 'category'] |
|
search_fields = ['date', 'user__username', 'account_type', 'category'] |
|
def __str__(self): |
|
return '%s tx %s' % (user.username, date) |
|
|
|
class PayPalHint(models.Model): |
|
user = models.ForeignKey(User, related_name='paypal_hints', blank=True, null=True, on_delete=models.SET_NULL) |
|
|
|
account = models.CharField(unique=True, max_length=13) |
|
member_id = models.IntegerField(null=True) |
|
|
|
history = HistoricalRecords() |
|
|
|
list_display = ['account', 'user'] |
|
search_fields = ['account', 'user__username'] |
|
def __str__(self): |
|
return self.account |
|
|
|
class IPN(models.Model): |
|
datetime = models.DateTimeField(auto_now_add=True) |
|
data = models.TextField() |
|
status = models.CharField(max_length=32) |
|
|
|
history = HistoricalRecords() |
|
|
|
list_display = ['datetime', 'status'] |
|
search_fields = ['datetime', 'status'] |
|
def __str__(self): |
|
return self.datetime |
|
|
|
class Card(models.Model): |
|
user = models.ForeignKey(User, related_name='cards', blank=True, null=True, on_delete=models.SET_NULL) |
|
|
|
member_id = models.IntegerField(blank=True, null=True) |
|
card_number = models.CharField(unique=True, max_length=16, blank=True, null=True) |
|
notes = models.TextField(blank=True, null=True) |
|
last_seen_at = models.DateField(blank=True, null=True) |
|
last_seen = models.DateTimeField(blank=True, null=True) |
|
active_status = models.CharField(max_length=32, blank=True, null=True) |
|
|
|
history = HistoricalRecords(excluded_fields=['last_seen_at', 'last_seen']) |
|
|
|
list_display = ['card_number', 'user', 'last_seen'] |
|
search_fields = ['card_number', 'user__username', 'last_seen'] |
|
def __str__(self): |
|
return self.card_number |
|
|
|
class Course(models.Model): |
|
name = models.TextField(blank=True, null=True) |
|
description = models.TextField(blank=True, null=True) |
|
is_old = models.BooleanField(default=False) |
|
tags = models.CharField(max_length=128, blank=True) |
|
|
|
history = HistoricalRecords() |
|
|
|
list_display = ['name', 'id'] |
|
search_fields = ['name', 'id'] |
|
def __str__(self): |
|
return self.name |
|
|
|
class Session(models.Model): |
|
instructor = models.ForeignKey(User, related_name='teaching', blank=True, null=True, on_delete=models.SET_NULL) |
|
course = models.ForeignKey(Course, related_name='sessions', blank=True, null=True, on_delete=models.SET_NULL) |
|
|
|
is_cancelled = models.BooleanField(default=False) |
|
old_instructor = models.TextField(blank=True, null=True) |
|
datetime = models.DateTimeField(blank=True, null=True) |
|
cost = models.DecimalField(max_digits=5, decimal_places=2) |
|
max_students = models.IntegerField(blank=True, null=True) |
|
|
|
history = HistoricalRecords() |
|
|
|
list_display = ['datetime', 'course', 'instructor'] |
|
search_fields = ['datetime', 'course__name', 'instructor__username'] |
|
def __str__(self): |
|
return '%s @ %s' % (self.course.name, self.datetime.astimezone(TIMEZONE_CALGARY).strftime('%Y-%m-%d %-I:%M %p')) |
|
|
|
class Training(models.Model): |
|
user = models.ForeignKey(User, related_name='training', blank=True, null=True, on_delete=models.SET_NULL) |
|
session = models.ForeignKey(Session, related_name='students', blank=True, null=True, on_delete=models.SET_NULL) |
|
|
|
member_id = models.IntegerField(blank=True, null=True) |
|
attendance_status = models.TextField(blank=True, null=True) |
|
sign_up_date = models.DateField(default=today_alberta_tz, blank=True, null=True) |
|
paid_date = models.DateField(blank=True, null=True) |
|
|
|
history = HistoricalRecords() |
|
|
|
list_display = ['session', 'user'] |
|
search_fields = ['session__course__name', 'user__username'] |
|
def __str__(self): |
|
return '%s taking %s @ %s' % (self.user, self.session.course.name, self.session.datetime) |
|
|
|
class Interest(models.Model): |
|
user = models.ForeignKey(User, related_name='interests', null=True, on_delete=models.SET_NULL) |
|
course = models.ForeignKey(Course, related_name='interests', null=True, on_delete=models.SET_NULL) |
|
|
|
satisfied_by = models.ForeignKey(Session, related_name='satisfies', null=True, on_delete=models.SET_NULL) |
|
|
|
list_display = ['user', 'course', 'satisfied_by'] |
|
search_fields = ['user__username', 'course__name'] |
|
def __str__(self): |
|
return '%s interested in %s' % (self.user, self.course) |
|
|
|
|
|
class MetaInfo(models.Model): |
|
backup_id = models.TextField() |
|
|
|
class StatsMemberCount(models.Model): |
|
date = models.DateField(default=today_alberta_tz) |
|
member_count = models.IntegerField() |
|
green_count = models.IntegerField() |
|
six_month_plus_count = models.IntegerField() |
|
vetted_count = models.IntegerField() |
|
subscriber_count = models.IntegerField() |
|
|
|
list_display = ['date', 'member_count', 'green_count', 'six_month_plus_count', 'vetted_count', 'subscriber_count'] |
|
search_fields = ['date', 'member_count', 'green_count', 'six_month_plus_count', 'vetted_count', 'subscriber_count'] |
|
|
|
class StatsSignupCount(models.Model): |
|
month = models.DateField() |
|
signup_count = models.IntegerField() |
|
retain_count = models.IntegerField(default=0) |
|
vetted_count = models.IntegerField(default=0) |
|
|
|
list_display = ['month', 'signup_count', 'retain_count', 'vetted_count'] |
|
search_fields = ['month', 'signup_count', 'retain_count', 'vetted_count'] |
|
|
|
class StatsSpaceActivity(models.Model): |
|
date = models.DateField(default=today_alberta_tz) |
|
card_scans = models.IntegerField() |
|
|
|
list_display = ['date', 'card_scans'] |
|
search_fields = ['date', 'card_scans'] |
|
|
|
class Usage(models.Model): |
|
user = models.ForeignKey(User, related_name='usages', blank=True, null=True, on_delete=models.SET_NULL) |
|
|
|
username = models.CharField(max_length=64, blank=True) # incase of LDAP-Spaceport mismatch |
|
|
|
device = models.CharField(max_length=64) |
|
started_at = models.DateTimeField(auto_now_add=True) |
|
finished_at = models.DateTimeField(null=True) |
|
deleted_at = models.DateTimeField(null=True, blank=True) |
|
|
|
num_seconds = models.IntegerField() |
|
num_reports = models.IntegerField() |
|
memo = models.TextField(blank=True) |
|
should_bill = models.BooleanField(default=True) |
|
|
|
history = HistoricalRecords(excluded_fields=['num_reports']) |
|
|
|
list_display = ['started_at', 'finished_at', 'user', 'num_seconds', 'should_bill'] |
|
search_fields = ['started_at', 'finished_at', 'user__username'] |
|
def __str__(self): |
|
return str(self.started_at) |
|
|
|
class PinballScore(models.Model): |
|
user = models.ForeignKey(User, related_name='scores', blank=True, null=True, on_delete=models.SET_NULL) |
|
|
|
started_at = models.DateTimeField(auto_now_add=True) |
|
finished_at = models.DateTimeField(null=True) |
|
|
|
game_id = models.IntegerField() |
|
player = models.IntegerField() |
|
score = models.IntegerField() |
|
|
|
# no history |
|
|
|
list_display = ['started_at', 'game_id', 'player', 'score', 'user'] |
|
search_fields = ['started_at', 'game_id', 'player', 'score', 'user__username'] |
|
def __str__(self): |
|
return str(self.started_at) |
|
|
|
class Hosting(models.Model): |
|
user = models.ForeignKey(User, related_name='hosting', blank=True, null=True, on_delete=models.SET_NULL) |
|
|
|
started_at = models.DateTimeField(auto_now_add=True) |
|
finished_at = models.DateTimeField() |
|
hours = models.DecimalField(max_digits=5, decimal_places=2) |
|
|
|
# no history |
|
|
|
list_display = ['started_at', 'hours', 'finished_at', 'user'] |
|
search_fields = ['started_at', 'hours', 'finished_at', 'user__username'] |
|
def __str__(self): |
|
return str(self.started_at) |
|
|
|
class StorageSpace(models.Model): |
|
user = models.ForeignKey(User, related_name='storage', blank=True, null=True, on_delete=models.SET_NULL) |
|
|
|
shelf_id = models.TextField(unique=True) |
|
location = models.TextField(choices=[ |
|
('member_shelves', 'Member Shelves'), |
|
('lockers', 'Lockers'), |
|
('large_project_storage', 'Large Project Storage'), |
|
]) |
|
memo = models.TextField(blank=True) |
|
|
|
history = HistoricalRecords() |
|
|
|
list_display = ['shelf_id', 'location', 'user', 'id'] |
|
search_fields = ['shelf_id', 'location', 'user__username', 'id'] |
|
def __str__(self): |
|
return self.shelf_id |
|
|
|
|
|
class HistoryIndex(models.Model): |
|
content_type = models.ForeignKey(ContentType, null=True, on_delete=models.SET_NULL) |
|
object_id = models.PositiveIntegerField() |
|
history = GenericForeignKey('content_type', 'object_id') |
|
|
|
owner_id = models.PositiveIntegerField() |
|
owner_name = models.TextField() |
|
object_name = models.TextField() |
|
history_user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL) |
|
history_date = models.DateTimeField() |
|
history_type = models.TextField() |
|
revert_url = models.TextField() |
|
|
|
is_system = models.BooleanField() |
|
is_admin = models.BooleanField() |
|
|
|
list_display = ['history_date', 'history_user', 'history_type', 'owner_name', 'object_name'] |
|
search_fields = ['history_date', 'history_user__username', 'history_type', 'owner_name', 'object_name'] |
|
def __str__(self): |
|
return '%s changed %s\'s %s' % (self.history_user, self.owner_name, self.object_name) |
|
|
|
class HistoryChange(models.Model): |
|
index = models.ForeignKey(HistoryIndex, related_name='changes', null=True, on_delete=models.SET_NULL) |
|
|
|
field = models.TextField() |
|
old = models.TextField() |
|
new = models.TextField() |
|
|
|
list_display = ['field', 'old', 'new', 'index'] |
|
search_fields = ['field', 'old', 'new', 'index__history_user__username'] |
|
def __str__(self): |
|
return self.field
|
|
|