diff --git a/gms/memberdb/admin.py b/gms/memberdb/admin.py index 4d17d3c7a612f02889f1c60bec13569bc21f5c8f..2bdcf7997d5edbb5815819ff92b827abfb5fff91 100644 --- a/gms/memberdb/admin.py +++ b/gms/memberdb/admin.py @@ -1,11 +1,22 @@ from django.contrib import admin -from memberdb.models import Member +from memberdb.models import Member, IncAssocMember, Membership from memberdb.actions import download_as_csv +admin.site.site_header = "Gumby Management System" +admin.site.site_title = "UCC Gumby Management System" +admin.site.index_title = "Membership Database" + +""" +Customise the administrative interface for modifying Member records +""" class MemberAdmin(admin.ModelAdmin): - list_display = ('real_name', 'username', 'guild_member') - list_filter = ['guild_member', 'membership_type'] - search_fields = ('real_name', 'username', ) + list_display = ['first_name', 'last_name', 'display_name', 'username'] + list_filter = ['is_guild', 'is_student'] + search_fields = list_display actions = [download_as_csv] admin.site.register(Member, MemberAdmin) + +# Register the other models with default admin site pages +admin.site.register(IncAssocMember) +admin.site.register(Membership) diff --git a/gms/memberdb/models.py b/gms/memberdb/models.py index f061fe90200151bb6620d8e21a1657621a0f1960..a27db23a3ac00717ccf807bf6c8978c021e272e1 100644 --- a/gms/memberdb/models.py +++ b/gms/memberdb/models.py @@ -1,45 +1,63 @@ from django.db import models import datetime -MEMBERSHIP_TYPES = ( - (1, 'O\' Day Special'), - (2, 'Student'), - (3, 'Non Student'), -# (1, 'O\' Day Special'), -# (2, 'First time UWA student'), -# (3, 'Rejoining UWA student'), -# (4, 'Not a student'), -# (5, 'Member of an associate club'), -# (6, 'Student at another univeristy'), -# (7, 'Life member'), -) +MEMBERSHIP_TYPES = [ + ('pseudo:11', 'O\' Day Special'), + ('pseudo:10', 'Student and UWA Guild member'), + ('pseudo:9', 'Student and not UWA Guild member'), + ('pseudo:8', 'Non-Student and UWA Guild member'), + ('pseudo:7', 'Non-Student and not UWA Guild member'), + ('', 'Life member'), +] -#GENDERS = ( -# (1, 'Male'), -# (2, 'Female'), -# (3, 'Other'), -# (4, 'Undefined'), -#) +PAYMENT_METHODS = [ + ('dispense', 'Existing dispense credit'), + ('cash', 'Cash (in person)'), + ('card', 'Tap-n-Go via Square (in person)'), + ('online', 'Online payment via Square'), + ('eft', 'Bank transfer') +] -class Member (models.Model): - #membership_year = models.IntegerField ('Membership Year', default=datetime.date.today().year,) - real_name = models.CharField ('Real Name', max_length=200,) - username = models.CharField ('Username', max_length=16, blank=True) - email_address = models.CharField ('Email Address', max_length=200, - blank=True) - membership_type = models.IntegerField ('Membership Type', choices=MEMBERSHIP_TYPES,) - guild_member = models.BooleanField ('Guild Member', - default=False, blank=True) - student_no = models.CharField ('Student Number or ID Number', max_length=20, - blank=True) - phone_number = models.CharField ('Phone Number', max_length=14, - blank=True) - date_of_birth = models.DateField ('Date of Birth', null=True, blank=True) - signed_up = models.DateField ('Signed up', default=datetime.date.today()) - - def __unicode__ (self): - if len (self.username) > 0: - return "%s <%s>" % (self.real_name, self.username) - else: - return self.real_name +""" +Member record for data we are legally required to keep under Incorporations Act (and make available to members upon request) +Note: these data should only be changed administratively or with suitable validation since it must be up to date & accurate. +""" +class IncAssocMember (models.Model): + first_name = models.CharField ('First name', max_length=200) + last_name = models.CharField ('Surname', max_length=200) + email_address = models.EmailField ('Email address', blank=True) + updated = models.DateField ('Last updated', auto_now=True) + created = models.DateField ('When created', auto_now_add=True) + def __unicode__ (self): + return "%s %s <%s>" % (self.first_name, self.last_name, self.email_address) + +""" +Member table: only latest information, one record per member +Some of this data may be required by the UWA Student Guild. Other stuff is just good to know, and we don't _need_ to keep historical data for every current/past member. +Note: Privacy laws are a thing, unless people allow it then we cannot provide this info to members. +""" +class Member (IncAssocMember): + display_name = models.CharField ('Display name', max_length=200) + username = models.CharField ('Username', max_length=32, blank=False, unique=True) + phone_number = models.CharField ('Phone number', max_length=14, blank=True) + date_of_birth = models.DateField ('Date of birth', blank=True) + last_renew = models.DateField ('Last renewal', blank=False) + is_student = models.BooleanField ('Student at UWA', default=True) + is_guild = models.BooleanField ('UWA Guild member', default=True) + id_number = models.CharField ('Student number or Drivers License', max_length=50 , blank=False) + member_updated = models.DateField ('Last updated', auto_now=True) + def __unicode__ (self): + return "[%s] %s (%s %s)" % (self.username, self.display_name, self.first_name, self.last_name) + +""" +Membership table: store information related to individual (successful/accepted) signups/renewals +""" +class Membership (models.Model): + member = models.ForeignKey (Member, on_delete=models.CASCADE) + membership_type = models.CharField ('Membership type', max_length=10, blank=False, null=True) + payment_method = models.CharField ('Payment method', max_length=10, choices=PAYMENT_METHODS) + accepted = models.BooleanField ('Membership approved', default=False) + date_submitted = models.DateTimeField ('Date signed up', auto_now_add=True) + date_paid = models.DateTimeField ('Date of payment', blank=True, null=True) + date_accepted = models.DateTimeField ('Date accepted', blank=True, null=True) diff --git a/gms/memberdb/templates/base.html b/gms/memberdb/templates/base.html new file mode 100644 index 0000000000000000000000000000000000000000..fbac209027d8b4eba68e9bfef476cf442c45566c --- /dev/null +++ b/gms/memberdb/templates/base.html @@ -0,0 +1,45 @@ +{% load static %} +<!DOCTYPE html> +<html> +<head> +<title>{% block title %}{% endblock %}</title> +<link rel="stylesheet" type="text/css" href="{% static "main.css" %}"> +{% block extrahead %}{% endblock %} +{% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE">{% endblock %} +</head> + +<body> + +<!-- Container --> +<div id="container"> + + <!-- Header --> + <div id="header"> + {% block header %}{% endblock %} + </div> + <!-- END Header --> + + <!-- Content --> + <div id="content"> + {% block content_title %}{% if title %}<h1>{{ title }}</h1>{% endif %}{% endblock %} + {% block content %} + {% block object-tools %}{% endblock %} + {{ content }} + {% endblock %} + {% block sidebar %}{% endblock %} + <br class="clear"> + </div> + <!-- END Content --> + + <!-- Footer --> + {% block footer %} + <div id="footer"> + + </div> + {% endblock %} + <!-- END Footer --> +</div> +<!-- END Container --> + +</body> +</html> diff --git a/gms/memberdb/templates/index.html b/gms/memberdb/templates/index.html new file mode 100644 index 0000000000000000000000000000000000000000..7c8fd022de958b7e1a1e6a01886eb0412c7359bd --- /dev/null +++ b/gms/memberdb/templates/index.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} + +{% block title %}Gumbies registered in the system{% endblock %} + +{% block content %} +{% if member_list %} + <ul> + {% for m in member_list %} + <li><a href="{% url 'memberdb:info' m.username %}">{{ m.display_name }}</a></li> + {% endfor %} + </ul> +{% else %} + <p>No members are registered :(</p> +{% endif %} +{% endblock %} \ No newline at end of file diff --git a/gms/memberdb/templates/renew.html b/gms/memberdb/templates/renew.html new file mode 100644 index 0000000000000000000000000000000000000000..030c9671243f4abc5f5f86f014c72864290e6be0 --- /dev/null +++ b/gms/memberdb/templates/renew.html @@ -0,0 +1,12 @@ +<h1>Renew membership for {{ m.username }}</h1> + +{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %} + +<form action="{% url 'memberdb:renew' m.username %}" method="post"> +{% csrf_token %} +{% for choice in question.choice_set.all %} + <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}"> + <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br> +{% endfor %} +<input type="submit" value="Vote"> +</form> \ No newline at end of file diff --git a/gms/memberdb/urls.py b/gms/memberdb/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..ffbe8de997cd6f92c2e1c99c2ca9a9797760c33a --- /dev/null +++ b/gms/memberdb/urls.py @@ -0,0 +1,12 @@ +from django.urls import path + +from . import views + +app_name = 'memberdb' +urlpatterns = [ + path('', views.index, name='index'), + path('<str:username>/', views.info, name='info'), + path('register/', views.register, name='register'), + path('renew/', views.renew, name='renew'), + path('renew/<str:username>/', views.renew, name='renew'), +] \ No newline at end of file diff --git a/gms/memberdb/views.py b/gms/memberdb/views.py index 91ea44a218fbd2f408430959283f0419c921093e..7b78cdac91ce3edfd6c772a79ed982e1379a1144 100644 --- a/gms/memberdb/views.py +++ b/gms/memberdb/views.py @@ -1,3 +1,19 @@ +from django.http import HttpResponse from django.shortcuts import render +from .models import Member, IncAssocMember -# Create your views here. +def index(request): + member_list = Member.objects.all() + context = { + 'member_list': member_list, + } + return render(request, 'index.html', context) + +def renew(request, username): + return HttpResponse("Renew your membership now, " + username); + +def register(request): + return HttpResponse("Hi there, plz enter your details to register."); + +def info(request, username): + return HttpResponse("Information for user " + username); \ No newline at end of file