implemented cancel subscription, will likely need some more work and testing
This commit is contained in:
parent
5257fcd7c3
commit
eac0e88596
|
@ -35,6 +35,7 @@ urlpatterns = [
|
||||||
url(r'^latest/$', LatestEntriesFeed()),
|
url(r'^latest/$', LatestEntriesFeed()),
|
||||||
|
|
||||||
url(r'membership/join/$', subscription.MembershipJoinView.as_view(), name='join_hackspace'),
|
url(r'membership/join/$', subscription.MembershipJoinView.as_view(), name='join_hackspace'),
|
||||||
|
url(r'membership/cancel/$', subscription.MembershipCancelView.as_view(), name='cancel_membership'),
|
||||||
url(r'membership/(?P<provider>[\w\-]+)/success$', subscription.MembershipJoinSuccessView.as_view(), name='join_hackspace_success'),
|
url(r'membership/(?P<provider>[\w\-]+)/success$', subscription.MembershipJoinSuccessView.as_view(), name='join_hackspace_success'),
|
||||||
url(r'membership/(?P<provider>\w{0,50})/failure$', subscription.MembershipJoinFailureView.as_view(), name='join_hackspace_failure'),
|
url(r'membership/(?P<provider>\w{0,50})/failure$', subscription.MembershipJoinFailureView.as_view(), name='join_hackspace_failure'),
|
||||||
url(r'^admin/password_reset/$', auth_views.password_reset, name='admin_password_reset'),
|
url(r'^admin/password_reset/$', auth_views.password_reset, name='admin_password_reset'),
|
||||||
|
|
|
@ -9,4 +9,12 @@
|
||||||
margin: auto;
|
margin: auto;
|
||||||
text-shadow: 1px 1px #FFF;
|
text-shadow: 1px 1px #FFF;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
.middle {
|
||||||
|
font-size: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
margin: 50px;
|
||||||
|
}
|
||||||
|
.date {
|
||||||
|
padding:14px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,9 +101,14 @@ class gocardless_provider:
|
||||||
def get_token(self):
|
def get_token(self):
|
||||||
return 'N/A'
|
return 'N/A'
|
||||||
|
|
||||||
def cancel_subscribe(self, reference):
|
def cancel_subscription(self, reference):
|
||||||
subscription = gocardless.client.subscription(reference)
|
try:
|
||||||
response = subscription.cancel()
|
subscription = gocardless.client.subscription(reference)
|
||||||
|
response = subscription.cancel()
|
||||||
|
except gocardless.exceptions.ClientError:
|
||||||
|
return {
|
||||||
|
'success': False
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
'amount': subscription.amount,
|
'amount': subscription.amount,
|
||||||
'start_date': subscription.created_at,
|
'start_date': subscription.created_at,
|
||||||
|
|
|
@ -9,11 +9,42 @@ from django.contrib import messages
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
|
||||||
from mhackspace.users.models import User
|
from mhackspace.users.models import User, Membership
|
||||||
|
from mhackspace.users.models import MEMBERSHIP_CANCELLED
|
||||||
from mhackspace.users.forms import MembershipJoinForm
|
from mhackspace.users.forms import MembershipJoinForm
|
||||||
from mhackspace.subscriptions.payments import select_provider
|
from mhackspace.subscriptions.payments import select_provider
|
||||||
|
|
||||||
|
|
||||||
|
class MembershipCancelView(LoginRequiredMixin, RedirectView):
|
||||||
|
permanent = False
|
||||||
|
pattern_name = 'users:detail'
|
||||||
|
|
||||||
|
def get_redirect_url(self, *args, **kwargs):
|
||||||
|
payment_provider = 'gocardless'
|
||||||
|
provider = select_provider(payment_provider)
|
||||||
|
|
||||||
|
member = Membership.objects.filter(user=self.request.user).first()
|
||||||
|
|
||||||
|
result = provider.cancel_subscription(
|
||||||
|
reference=member.reference
|
||||||
|
)
|
||||||
|
if result.get('success') is True:
|
||||||
|
# set membership to cancelled on success
|
||||||
|
member.status = MEMBERSHIP_CANCELLED
|
||||||
|
member.save()
|
||||||
|
|
||||||
|
# remove user from group on success
|
||||||
|
group = Group.objects.get(name='members')
|
||||||
|
self.request.user.groups.remove(group)
|
||||||
|
messages.add_message(
|
||||||
|
self.request,
|
||||||
|
messages.SUCCESS,
|
||||||
|
'Your membership has now been cancelled')
|
||||||
|
|
||||||
|
kwargs['username'] = self.request.user.get_username()
|
||||||
|
return super(MembershipCancelView, self).get_redirect_url(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class MembershipJoinView(LoginRequiredMixin, UpdateView):
|
class MembershipJoinView(LoginRequiredMixin, UpdateView):
|
||||||
model = User
|
model = User
|
||||||
fields = []
|
fields = []
|
||||||
|
|
|
@ -26,24 +26,25 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
{% if membership.get_status %}
|
{% if membership.get_status %}
|
||||||
<div id="membercard" class="registered">
|
<div id="membercard" class="registered">
|
||||||
<div class="date">Joined {{membership.date}}</div>
|
<div class="date">Joined {{membership.date}}</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="middle">
|
<div class="middle">
|
||||||
<p>MHS{{ user.id|stringformat:"05d" }}</p><p>{{user.name}}{{user.last_name}}</p>
|
<p>MHS{{ user.id|stringformat:"05d" }}</p><p>{{user.name}}{{user.last_name}}</p>
|
||||||
<a href="/profile/membership/cancel">Cancel Membership</a>
|
</div>
|
||||||
|
<a href="{% url 'cancel_membership' %}">Cancel Membership</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% else %}
|
||||||
|
<div>
|
||||||
|
<h2>Sign up below</h2>
|
||||||
|
<form method="POST" action="{% url 'join_hackspace' %}" class="contact_us_form">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ membership_form|crispy }}
|
||||||
|
<button class="btn btn-primary" type="submit" name="action">{% trans "Send" %}</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div>
|
|
||||||
<h2>Sign up below</h2>
|
|
||||||
<form method="POST" action="{% url 'join_hackspace' %}" class="contact_us_form">
|
|
||||||
{% csrf_token %}
|
|
||||||
{{ membership_form|crispy }}
|
|
||||||
<button class="btn btn-primary" type="submit" name="action">{% trans "Send" %}</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
from django.contrib.admin import ModelAdmin
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.auth.admin import UserAdmin as AuthUserAdmin
|
from django.contrib.auth.admin import UserAdmin as AuthUserAdmin
|
||||||
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
|
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
|
||||||
from .models import User
|
from .models import User, Membership, MEMBERSHIP_STATUS_CHOICES
|
||||||
|
|
||||||
|
|
||||||
class MyUserChangeForm(UserChangeForm):
|
class MyUserChangeForm(UserChangeForm):
|
||||||
class Meta(UserChangeForm.Meta):
|
class Meta(UserChangeForm.Meta):
|
||||||
model = User
|
model = User
|
||||||
|
|
||||||
|
|
||||||
class MyUserCreationForm(UserCreationForm):
|
class MyUserCreationForm(UserCreationForm):
|
||||||
|
|
||||||
error_message = UserCreationForm.error_messages.update({
|
error_message = UserCreationForm.error_messages.update({
|
||||||
'duplicate_username': 'This username has already been taken.'
|
'duplicate_username': 'This username has already been taken.'
|
||||||
})
|
})
|
||||||
|
@ -40,3 +39,8 @@ class MyUserAdmin(AuthUserAdmin):
|
||||||
) + AuthUserAdmin.fieldsets
|
) + AuthUserAdmin.fieldsets
|
||||||
list_display = ('username', 'name', 'is_superuser')
|
list_display = ('username', 'name', 'is_superuser')
|
||||||
search_fields = ['name']
|
search_fields = ['name']
|
||||||
|
|
||||||
|
@admin.register(Membership)
|
||||||
|
class MembershipAdmin(ModelAdmin):
|
||||||
|
list_display = ('user', 'payment', 'date', 'status')
|
||||||
|
list_filter = ('status',)
|
||||||
|
|
|
@ -29,10 +29,18 @@ class User(AbstractUser):
|
||||||
|
|
||||||
|
|
||||||
class Blurb(models.Model):
|
class Blurb(models.Model):
|
||||||
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='+')
|
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='+')
|
||||||
skills = models.CharField(max_length=255)
|
skills = models.CharField(max_length=255)
|
||||||
description = models.TextField()
|
description = models.TextField()
|
||||||
|
|
||||||
|
MEMBERSHIP_CANCELLED = 0
|
||||||
|
|
||||||
|
MEMBERSHIP_STATUS_CHOICES = (
|
||||||
|
(0, 'Guest user'),
|
||||||
|
(1, 'Active membership'),
|
||||||
|
(3, 'Membership Expired'),
|
||||||
|
(4, 'Membership Cancelled')
|
||||||
|
)
|
||||||
|
|
||||||
MEMBERSHIP_STRING = {
|
MEMBERSHIP_STRING = {
|
||||||
0: 'Guest user',
|
0: 'Guest user',
|
||||||
|
@ -55,7 +63,7 @@ class Membership(models.Model):
|
||||||
payment = models.DecimalField(max_digits=6, decimal_places=2, default=0.0)
|
payment = models.DecimalField(max_digits=6, decimal_places=2, default=0.0)
|
||||||
date = models.DateTimeField()
|
date = models.DateTimeField()
|
||||||
reference = models.CharField(max_length=255)
|
reference = models.CharField(max_length=255)
|
||||||
status = models.PositiveSmallIntegerField(default=0)
|
status = models.PositiveSmallIntegerField(default=0, choices=MEMBERSHIP_STATUS_CHOICES)
|
||||||
email = models.CharField(max_length=255)
|
email = models.CharField(max_length=255)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
Loading…
Reference in New Issue