""" This file implements the member-facing registration workflow. See ../../README.md """ from django.http import HttpResponseRedirect from django.shortcuts import render from django.urls import reverse from django.contrib.auth.mixins import LoginRequiredMixin from django.utils.safestring import mark_safe from django.utils import timezone from django.contrib import messages from django import forms from squarepay.models import MembershipPayment from squarepay.dispense import get_item_price from .models import Member, Membership, get_membership_choices, make_pending_membership, MEMBERSHIP_TYPES from .forms import MyModelForm from .views import MyUpdateView """ 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 """ 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.
" 'Policies can be found here.')) 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': { '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.') if (self['email_address'].value().lower().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(); 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() ms = make_pending_membership(m) ms.membership_type = self.cleaned_data['membership_type'] 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 """ simple FormView which displays registration form and handles template rendering & form submission """ class RegisterView(MyUpdateView): template_name = 'register.html' form_class = RegisterForm model = Member def get_context_data(self, **kwargs): """ update view context with current renewal year """ context = super().get_context_data(**kwargs) context['year'] = timezone.now().year return context def form_valid(self, form): """ called when valid form data has been POSTed invalid form data simply redisplays the form with validation errors """ # 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 if self.request.user.is_staff: return HttpResponseRedirect(reverse("admin:membership-approve",args=[ms.pk])) else: return thanks_view(self.request, m, ms) def thanks_view(request, member, ms): """ display a thankyou page after registration is completed """ context = { 'member': member, 'ms': ms, 'login_url': reverse('memberdb:login_member', kwargs={'id' : member.id, 'member_token': member.login_token}), } return render(request, 'thanks.html', context) class RenewView(LoginRequiredMixin, RegisterView): template_name = 'renew.html' form_class = RenewForm model = Member def get_object(self): """ try to get a pending renewal for this year (to edit & resubmit) otherwise create a new one """ u = self.request.user m = self.request.member if m is None: # this member is not in the DB yet - make a new Member object and prefill some data m = Member(username=u.username) m.first_name = u.first_name m.last_name = u.last_name m.email_address = u.email m.login_token = None # renewing members won't need this, make sure it is null for security return m def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) last_renewal = self.object.get_last_renewal() # renew.html says whether a record exists in the DB or not context['is_new'] = self.request.member is None # let the template check if user has already renewed this year so it displays a warning if last_renewal is not None: context['last_renewal'] = last_renewal.date_submitted.year context['memberships'] = [last_renewal] return context def form_valid(self, form): m, ms = form.save() messages.success(self.request, 'Your membership renewal has been submitted.') # always redirect to member home on renewal - you can't renew for someone else, and it # is confusing if you get redirected to the admin site return HttpResponseRedirect(reverse("memberdb:home"))