register.py 5.99 KB
Newer Older
1
2
3
4
"""
This file implements the member-facing registration workflow. See ../../README.md
"""

5
from django.http import HttpResponseRedirect
6
7
from django.shortcuts import render
from django.urls import reverse
frekk's avatar
frekk committed
8
from django.contrib.auth.mixins import LoginRequiredMixin
9
from django.utils.safestring import mark_safe
frekk's avatar
frekk committed
10
from django.contrib import messages
11
12
from django import forms

13
14
15
16
from squarepay.models import MembershipPayment
from squarepay.dispense import get_item_price

from .models import Member, Membership, get_membership_choices, MEMBERSHIP_TYPES
frekk's avatar
frekk committed
17
18
from .forms import MyModelForm
from .views import MyUpdateView
frekk's avatar
frekk committed
19
from .approve import make_pending_membership
20
21
22
23
24
25

"""
First step: enter an email address and some details (to fill at least a Member model) to create a pending membership.
see https://docs.djangoproject.com/en/2.1/ref/models/fields/#error-messages
and https://docs.djangoproject.com/en/2.1/ref/forms/fields/#error-messages
"""
Zack Wong's avatar
Zack Wong committed
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class RegisterRenewForm(MyModelForm):
	confirm_email   = forms.EmailField(label='Confirm your email address', required=False)
	agree_tnc       = forms.BooleanField(label='I agree to the terms & conditions', required=True, help_text=mark_safe(
		"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>"
		'<b>Policies can be found <a href="https://www.ucc.asn.au/infobase/policies.ucc">here</a>.</b>'))
	membership_type = forms.ChoiceField(label='Select your membership type', required=True, choices=get_membership_choices(is_renew=False))

	class Meta:
		model = Member
		fields = ['first_name', 'last_name', 'phone_number', 'is_student', 'is_guild', 'id_number', 'id_desc', 'email_address']
		error_messages = {
			'username': {
				'unique': 'This username is already taken, please pick another one.',
				'invalid': 'Please pick a username with only lowercase letters and numbers'
			}
		}

	def clean(self):
		try:
			if (self['email_address'].value() != self['confirm_email'].value()):
				self.add_error('email_address', 'Email addresses must match.')
Zack Wong's avatar
Zack Wong committed
48
			if (self['email_address'].value().lower().split('@')[1] in ["ucc.asn.au", "ucc.gu.uwa.edu.au"]):
Zack Wong's avatar
Zack Wong committed
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
					self.add_error('email_address', 'Contact address cannot be an UCC address.')
		except:
			pass
		super().clean();

	def save(self, commit=True):
		# get the Member model instance (ie. a record in the Members table) based on submitted form data
		m = super().save(commit=False)
		if (m.display_name == ""):
			m.display_name = "%s %s" % (m.first_name, m.last_name);
		# must save otherwise membership creation will fail
		m.save()

		# now create a corresponding Membership (marked as pending / not accepted, mostly default values)
		ms = make_pending_membership(m)

		if (commit):
			ms.save();
		return m, ms

class RegisterForm(RegisterRenewForm):
	username = forms.CharField(
		label='Preferred Username (optional)',
		required=False,
		help_text="This will be the username you use to access club systems. You may leave this blank to choose a username later"
	)

	class Meta():
		model = Member
		fields = ['first_name', 'last_name', 'username', 'phone_number', 'is_student', 'is_guild', 'id_number', 'id_desc', 'email_address']


	def clean(self):
		try:
			if (self['email_address'].value() != self['confirm_email'].value()):
				self.add_error('email_address', 'Email addresses must match.')
			if (self['email_address'].value().split('@')[1] in ["ucc.asn.au", "ucc.gu.uwa.edu.au"]):
					self.add_error('email_address', 'Contact address cannot be an UCC address.')
		except:
			pass
		super().clean();


class RenewForm(RegisterRenewForm):
	confirm_email = None
	membership_type = forms.ChoiceField(label='Select your membership type', required=True, choices=get_membership_choices(is_renew=True))

	class Meta:
		model = Member
		fields = ['first_name', 'last_name', 'phone_number', 'is_student', 'is_guild', 'id_number', 'id_desc', 'email_address']
		exclude = ['username']

	def save(self, commit=True):
		m, ms = super().save(commit=False)
		m.username = self.request.user.username
		m.has_account = m.get_uid() != None
		if (commit):
			m.save()
			ms.save()
		return m, ms
frekk's avatar
frekk committed
109

110
"""
frekk's avatar
frekk committed
111
simple FormView which displays registration form and handles template rendering & form submission
112
"""
frekk's avatar
frekk committed
113
class RegisterView(MyUpdateView):
Zack Wong's avatar
Zack Wong committed
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
	template_name = 'register.html'
	form_class = RegisterForm
	model = Member
	can_create = False

	"""
	called when valid form data has been POSTed
	invalid form data simply redisplays the form with validation errors
	"""
	def form_valid(self, form):
		# save the member data and get the Member instance
		m, ms = form.save()
		messages.success(self.request, 'Your registration has been submitted.')

		# don't set the member session info - user can click on the link
		#self.request.session['member_id'] = m.id
		return thanks_view(self.request, m, ms)
131
132

def thanks_view(request, member, ms):
Zack Wong's avatar
Zack Wong committed
133
134
135
136
	""" display a thankyou page after registration is completed """
	context = {
		'member': member,
		'ms': ms,
Zack Wong's avatar
Zack Wong committed
137
		'login_url': reverse('memberdb:login_member', kwargs={'id' : member.id, 'member_token': member.login_token}),
Zack Wong's avatar
Zack Wong committed
138
139
	}
	return render(request, 'thanks.html', context)
140

frekk's avatar
frekk committed
141
class RenewView(LoginRequiredMixin, MyUpdateView):
Zack Wong's avatar
Zack Wong committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
	template_name = 'renew.html'
	form_class = RenewForm
	model = Member

	def get_object(self):
		u = self.request.user

		obj = Member.objects.filter(username__exact=u.username).first()
		if (obj is None):
			# make a new Member object and prefill some data
			obj = Member(username=u.username)
			obj.first_name = u.first_name
			obj.last_name = u.last_name
			obj.email_address = u.email
			obj.login_token = None # renewing members won't need this
		return obj

	def get_context_data(self, **kwargs):
		context = super().get_context_data(**kwargs)
		context.update({
			'is_new': Member.objects.filter(username__exact=self.request.user.username).count() == 0,
		})
		return context

	def form_valid(self, form):
		m, ms = form.save()
		messages.success(self.request, 'Your membership renewal has been submitted.')
		return HttpResponseRedirect(reverse("memberdb:home"))