Commit 7f699435 authored by frekk's avatar frekk
Browse files

use dispense to display prices for memberships

parent c36c3835
......@@ -8,25 +8,10 @@ from django.urls import reverse
from django.utils import timezone
from django import forms
from memberdb.models import Member, Membership, MEMBERSHIP_TYPES_
from memberdb.models import Member, Membership, get_membership_type
from memberdb.forms import MyModelForm
from memberdb.views import MyUpdateView
def get_membership_type(member):
best = None
is_fresh = member.memberships.all().count() == 0
for t in MEMBERSHIP_TYPES_:
if (t['must_be_fresh'] == is_fresh and t['is_student'] == member.is_student and t['is_guild'] == member.is_guild):
best = t
break
elif (t['is_student'] == member.is_student and t['is_guild'] == member.is_guild):
best = t
break
if (best is None):
return MEMBERSHIP_TYPES_[1]['dispense']
else:
return best['dispense']
def make_pending_membership(member):
# check if this member already has a pending membership
ms = Membership.objects.filter(member=member, approved__exact=False).first()
......
......@@ -2,61 +2,96 @@ from django.db import models
from django.db.models import F
from django.core.validators import RegexValidator
from squarepay.dispense import get_item_price
"""
dictionary of membership types & descriptions, should be updated if these are changed in dispense.
"""
MEMBERSHIP_TYPES_ = [
{
MEMBERSHIP_TYPES = {
'oday': {
'dispense':'pseudo:11',
'desc':'O\' Day Special',
'desc':'O\' Day Special - first time members only',
'is_guild':True,
'is_student':True,
'must_be_fresh':True,
},
{
'student_and_guild': {
'dispense':'pseudo:10',
'desc':'Student and UWA Guild member',
'is_guild':True,
'is_student':True,
'must_be_fresh':False,
},
{
'student_only': {
'dispense':'pseudo:9',
'desc':'Student and not UWA Guild member',
'is_guild':False,
'is_student':True,
'must_be_fresh':False,
},
{
'guild_only': {
'dispense':'pseudo:8',
'desc':'Non-Student and UWA Guild member',
'is_guild':True,
'is_student':False,
'must_be_fresh':False,
},
{
'non_student': {
'dispense':'pseudo:7',
'desc':'Non-Student and not UWA Guild member',
'is_guild':False,
'is_student':False,
'must_be_fresh':False,
},
{
'lifer': {
'dispense':'',
'desc':'Life member',
'is_guild':False,
'is_student':False,
'must_be_fresh':False,
}
]
}
def get_membership_choices(is_renew=None, get_prices=True):
"""
turn MEMBERSHIP_TYPES into a list of choices used by Django
also dynamically fetch the prices from dispense (if possible)
"""
choices = []
for key, val in MEMBERSHIP_TYPES.items():
if (val['must_be_fresh'] and is_renew == True):
# if you have an account already, you don't qualify for the fresher special
continue
if (val['dispense'] == '' and is_renew == False):
# free memberships can only apply to life members, and they will have an existing membership somewhere
# so this option is only displayed on the renewal form
continue
else:
price = get_item_price(val['dispense'])
if (get_prices and price is not None):
desc = "%s ($%1.2f)" % (val['desc'], price / 100.0)
choices += [(key, desc)]
else:
# don't display the price
choices += [(key, val['desc'])]
def get_membership_types():
l = []
for t in MEMBERSHIP_TYPES_:
l += [(t['dispense'], t['desc'])]
return l
return choices
MEMBERSHIP_TYPES = get_membership_types()
def get_membership_type(member):
best = 'non_student'
is_fresh = member.memberships.all().count() == 0
for i, t in MEMBERSHIP_TYPES.items():
if (t['must_be_fresh'] == is_fresh and t['is_student'] == member.is_student and t['is_guild'] == member.is_guild):
best = i
break
elif (t['is_student'] == member.is_student and t['is_guild'] == member.is_guild):
best = i
break
return best
def make_token():
return get_random_string(128)
PAYMENT_METHODS = [
('dispense', 'Existing dispense credit'),
......@@ -84,7 +119,6 @@ class IncAssocMember (models.Model):
class Meta:
verbose_name = "Incorporations Act member data"
verbose_name_plural = verbose_name
default_permissions = ['view']
"""
Member table: only latest information, one record per member
......@@ -95,10 +129,11 @@ class Member (IncAssocMember):
display_name = models.CharField ('Display name', max_length=200)
username = models.SlugField ('Username', max_length=32, null=False, blank=False, unique=True, validators=[RegexValidator(regex='^[a-z0-9._-]+$')])
phone_number = models.CharField ('Phone number', max_length=20, blank=False, validators=[RegexValidator(regex='^\+?[0-9() -]+$')])
is_student = models.BooleanField ('Student at UWA', default=True, blank=True)
is_student = models.BooleanField ('Student', default=True, blank=True, help_text="Tick this box if you are a current student at a secondary or tertiary institution in WA")
is_guild = models.BooleanField ('UWA Guild member', default=True, blank=True)
id_number = models.CharField ('Student number or Drivers License', max_length=50 , blank=False)
id_number = models.CharField ('Student email or Drivers License', max_length=255, blank=False, help_text="Student emails should end with '.edu.au' and drivers licences should be in the format '[WA]DL 1234567'")
member_updated = models.DateTimeField ('Internal UCC info last updated', auto_now=True)
login_token = models.CharField ('Temporary access key', max_length=128, null=True, editable=False, default=make_token)
def __str__ (self):
if (self.display_name != "%s %s" % (self.first_name, self.last_name)):
......@@ -115,7 +150,7 @@ Membership table: store information related to individual (successful/accepted)
"""
class Membership (models.Model):
member = models.ForeignKey (Member, on_delete=models.CASCADE, related_name='memberships')
membership_type = models.CharField ('Membership type', max_length=10, blank=True, null=False, choices=MEMBERSHIP_TYPES)
membership_type = models.CharField ('Membership type', max_length=20, blank=True, null=False, choices=get_membership_choices(get_prices=False))
payment_method = models.CharField ('Payment method', max_length=10, blank=True, null=True, choices=PAYMENT_METHODS, default=None)
approved = models.BooleanField ('Membership approved', default=False)
approver = models.ForeignKey (Member, on_delete=models.SET_NULL, null=True, blank=True, related_name='approved_memberships')
......@@ -126,6 +161,9 @@ class Membership (models.Model):
def __str__ (self):
return "Member [%s] (%s) renewed membership on %s" % (self.member.username, self.member.display_name, self.date_submitted.strftime("%Y-%m-%d"))
def get_dispense_item(self):
return MEMBERSHIP_TYPES[self.membership_type]['dispense']
class Meta:
verbose_name = "Membership renewal record"
ordering = ['approved', '-date_submitted']
\ No newline at end of file
ordering = ['approved', '-date_submitted']
......@@ -10,7 +10,10 @@ from django.utils.safestring import mark_safe
from django.contrib import messages
from django import forms
from .models import Member, Membership
from squarepay.models import MembershipPayment
from squarepay.dispense import get_item_price
from .models import Member, Membership, get_membership_choices, MEMBERSHIP_TYPES
from .forms import MyModelForm
from .views import MyUpdateView
from .approve import make_pending_membership
......@@ -26,7 +29,7 @@ class RegisterForm(MyModelForm):
"You agree to abide by the UCC Constitution, rulings of the UCC Committee, UCC and "
"UWA’s Network Usage Guidelines and that you will be subscribed to the UCC Mailing List. <br>"
'Policies can be found <a href="https://www.ucc.asn.au/infobase/policies.ucc">here</a>.'))
#membership_type = forms.ChoiceField(label='Select your membership type', required=True, choices=MEMBERSHIP_TYPES)
membership_type = forms.ChoiceField(label='Select your membership type', required=True, choices=get_membership_choices(is_renew=False))
class Meta:
model = Member
......@@ -56,13 +59,17 @@ class RegisterForm(MyModelForm):
# now create a corresponding Membership (marked as pending / not accepted, mostly default values)
ms = make_pending_membership(m)
# make a card payment thing as well
if (commit):
ms.save();
return m, ms
class RenewForm(RegisterForm):
confirm_email = None
membership_type = forms.ChoiceField(label='Select your membership type', required=True, choices=get_membership_choices(is_renew=True))
class Meta(RegisterForm.Meta):
fields = ['first_name', 'last_name', 'phone_number', 'is_student', 'is_guild', 'id_number', 'email_address']
......@@ -91,7 +98,7 @@ class RegisterView(MyUpdateView):
# save the member data and get the Member instance
m, ms = form.save()
#messages.success(self.request, 'Your registration has been submitted.')
return HttpResponseRedirect(reverse("memberdb:thanks"))
return
class RenewView(LoginRequiredMixin, MyUpdateView):
template_name = 'renew.html'
......@@ -121,3 +128,19 @@ class RenewView(LoginRequiredMixin, MyUpdateView):
m, ms = form.save()
messages.success(self.request, 'Your membership renewal has been submitted.')
return HttpResponseRedirect(reverse("memberdb:home"))
def create_member_payment(membership, commit=True):
""" creates a MembershipPayment object for the given membership """
# get the amount from dispense
price = get_item_price(membership.membership_type)
if (price is None or price == 0):
return None
desc = MEMBERSHIP_TYPES[membership.membership_type]['desc']
payment = MembershipPayment(description=desc, amount=price, membership=membership)
if (commit):
payment.save()
return payment
def thanks_page(request, membership):
pass
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment