Fixed cc brand bug, Added button to print/save pdf to booking order detail view.Added booking order list.Added booking order list views. Added customised user navbar. Added “my bookings” link to navbar. Added membership active date range. Fixed function to calculate if a membership is active or not. Added membership order detail view. Added order membership view. Create order membership detail html.Added validation to not allow booking on already booked dates.
This commit is contained in:
parent
63dd0f3ea0
commit
d917c8a606
12 changed files with 397 additions and 33 deletions
|
@ -1,5 +1,7 @@
|
|||
from django.contrib import admin
|
||||
from .models import Supporter, DGGallery, DGPicture
|
||||
from .models import Supporter, DGGallery, DGPicture, Booking, BookingPrice,\
|
||||
MembershipOrder, Membership, MembershipType, BookingOrder
|
||||
|
||||
from utils.models import ContactMessage
|
||||
#
|
||||
class DGPictureInline(admin.StackedInline):
|
||||
|
@ -10,4 +12,9 @@ class DGGalleryAdmin(admin.ModelAdmin):
|
|||
|
||||
admin.site.register(DGGallery, DGGalleryAdmin)
|
||||
admin.site.register(ContactMessage)
|
||||
admin.site.register(Supporter)
|
||||
admin.site.register(Booking)
|
||||
admin.site.register(BookingPrice)
|
||||
admin.site.register(MembershipOrder)
|
||||
admin.site.register(Membership)
|
||||
admin.site.register(MembershipType)
|
||||
admin.site.register(BookingOrder)
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
from django import forms
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
from utils.models import BillingAddress
|
||||
from utils.forms import LoginFormMixin, SignupFormMixin, BillingAddressForm
|
||||
|
||||
from .models import MembershipType
|
||||
from .models import Booking
|
||||
|
||||
|
||||
class LoginForm(LoginFormMixin):
|
||||
|
@ -55,9 +58,10 @@ class BookingBillingForm(BillingAddressForm):
|
|||
|
||||
|
||||
class BookingDateForm(forms.Form):
|
||||
start_date = forms.DateField(required=False)
|
||||
end_date = forms.DateField(required=False)
|
||||
date_range = forms.CharField(required=False)
|
||||
start_date = forms.DateField(required=False, widget=forms.HiddenInput())
|
||||
end_date = forms.DateField(required=False, widget=forms.HiddenInput())
|
||||
date_range = forms.CharField(required=False,
|
||||
widget=forms.TextInput(attrs={'id': 'booking-date-range'}))
|
||||
|
||||
def clean_date_range(self):
|
||||
date_range = self.cleaned_data.get('date_range')
|
||||
|
@ -70,10 +74,19 @@ class BookingDateForm(forms.Form):
|
|||
|
||||
if start_date > end_date:
|
||||
raise forms.ValidationError("Your end date must be greather than your start date.")
|
||||
|
||||
q1 = Q(start_date__lte=start_date, end_date__gte=start_date)
|
||||
q2 = Q(start_date__gt=start_date, start_date__lte=end_date)
|
||||
if Booking.objects.filter(q1 | q2).exists():
|
||||
raise forms.ValidationError("You already have a booking in these dates.")
|
||||
|
||||
return start_date, end_date
|
||||
|
||||
def clean(self):
|
||||
start_date, end_date = self.cleaned_data.get('date_range')
|
||||
self.cleaned_data['start_date'] = start_date
|
||||
self.cleaned_data['end_date'] = end_date
|
||||
# import pdb
|
||||
# pdb.set_trace()
|
||||
if self.cleaned_data.get('date_range'):
|
||||
start_date, end_date = self.cleaned_data.get('date_range')
|
||||
self.cleaned_data['start_date'] = start_date
|
||||
self.cleaned_data['end_date'] = end_date
|
||||
return self.cleaned_data
|
||||
|
|
27
digitalglarus/migrations/0015_auto_20160908_0149.py
Normal file
27
digitalglarus/migrations/0015_auto_20160908_0149.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.4 on 2016-09-08 01:49
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('digitalglarus', '0014_booking_final_price'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='bookingorder',
|
||||
name='amount',
|
||||
field=models.FloatField(default=35),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='membershiporder',
|
||||
name='amount',
|
||||
field=models.FloatField(default=35.0),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
32
digitalglarus/migrations/0016_auto_20160909_0110.py
Normal file
32
digitalglarus/migrations/0016_auto_20160909_0110.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.4 on 2016-09-09 01:10
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('digitalglarus', '0015_auto_20160908_0149'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='bookingprice',
|
||||
old_name='special_price_offer',
|
||||
new_name='special_month_price',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='bookingorder',
|
||||
name='original_price',
|
||||
field=models.FloatField(default=20),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='bookingorder',
|
||||
name='special_month_price',
|
||||
field=models.FloatField(default=290),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -4,7 +4,7 @@ from membership.models import StripeCustomer
|
|||
from utils.models import BillingAddress
|
||||
|
||||
|
||||
class MembershipRequired(object):
|
||||
class MembershipRequiredMixin(object):
|
||||
membership_redirect_url = None
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
|
@ -12,11 +12,23 @@ class MembershipRequired(object):
|
|||
if not Membership.is_digitalglarus_member(request.user):
|
||||
return HttpResponseRedirect(self.membership_redirect_url)
|
||||
|
||||
return super(MembershipRequired, self).dispatch(request, *args, **kwargs)
|
||||
return super(MembershipRequiredMixin, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
|
||||
class IsNotMemberMixin(object):
|
||||
already_member_redirect_url = None
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
from .models import Membership
|
||||
if Membership.is_digitalglarus_member(request.user):
|
||||
return HttpResponseRedirect(self.already_member_redirect_url)
|
||||
|
||||
return super(MembershipRequiredMixin, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
|
||||
class Ordereable(models.Model):
|
||||
customer = models.ForeignKey(StripeCustomer)
|
||||
amount = models.FloatField()
|
||||
billing_address = models.ForeignKey(BillingAddress)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
approved = models.BooleanField(default=False)
|
||||
|
|
|
@ -64,7 +64,8 @@ class Membership(models.Model):
|
|||
@classmethod
|
||||
def is_digitalglarus_member(cls, user):
|
||||
past_month = (datetime.today() - relativedelta(months=1)).month
|
||||
has_booking_current_month = Q(membershiporder__created_at__month=datetime.today().month)
|
||||
has_booking_current_month = Q(membershiporder__customer__user=user,
|
||||
membershiporder__created_at__month=datetime.today().month)
|
||||
has_booking_past_month = Q(membershiporder__customer__user=user,
|
||||
membershiporder__created_at__month=past_month)
|
||||
return cls.objects.filter(has_booking_past_month | has_booking_current_month).exists()
|
||||
|
@ -78,6 +79,25 @@ class Membership(models.Model):
|
|||
class MembershipOrder(Ordereable, models.Model):
|
||||
membership = models.ForeignKey(Membership)
|
||||
|
||||
@classmethod
|
||||
def current_membership(cls, user):
|
||||
last_payment = cls.objects.\
|
||||
filter(customer__user=user).last()
|
||||
start_date = last_payment.created_at
|
||||
_, days_in_month = calendar.monthrange(start_date.year,
|
||||
start_date.month)
|
||||
start_date.replace(day=1)
|
||||
end_date = start_date + timedelta(days=days_in_month)
|
||||
return start_date, end_date
|
||||
|
||||
def get_membership_range_date(self):
|
||||
start_date = self.created_at
|
||||
_, days_in_month = calendar.monthrange(start_date.year,
|
||||
start_date.month)
|
||||
start_date.replace(day=1)
|
||||
end_date = start_date + timedelta(days=days_in_month)
|
||||
return start_date, end_date
|
||||
|
||||
@classmethod
|
||||
def create(cls, data):
|
||||
stripe_charge = data.pop('stripe_charge', None)
|
||||
|
@ -85,12 +105,13 @@ class MembershipOrder(Ordereable, models.Model):
|
|||
instance.stripe_charge_id = stripe_charge.id
|
||||
instance.last4 = stripe_charge.source.last4
|
||||
instance.cc_brand = stripe_charge.source.brand
|
||||
instance.save()
|
||||
return instance
|
||||
|
||||
|
||||
class BookingPrice(models.Model):
|
||||
price_per_day = models.FloatField()
|
||||
special_price_offer = models.FloatField()
|
||||
special_month_price = models.FloatField()
|
||||
|
||||
|
||||
class Booking(models.Model):
|
||||
|
@ -124,7 +145,7 @@ class Booking(models.Model):
|
|||
@classmethod
|
||||
def booking_price(cls, user, start_date, end_date):
|
||||
|
||||
MAX_MONTH_PRICE = 290
|
||||
MAX_MONTH_PRICE = BookingPrice.objects.last().special_month_price
|
||||
MAX_MONTH_DAYS_PROMOTION = 31
|
||||
MIN_MONTH_DAYS_PROMOTION = 19
|
||||
|
||||
|
@ -146,6 +167,8 @@ class Booking(models.Model):
|
|||
|
||||
class BookingOrder(Ordereable, models.Model):
|
||||
booking = models.OneToOneField(Booking)
|
||||
original_price = models.FloatField()
|
||||
special_month_price = models.FloatField()
|
||||
|
||||
def booking_days(self):
|
||||
return (self.booking.end_date - self.booking.start_date).days + 1
|
||||
|
|
|
@ -14,12 +14,17 @@
|
|||
<h2 class="signup-lead">Start coworking at Digital Glarus! <br> Membership costs only
|
||||
<strong>35CHF</strong> per month.<br> 2 free working days included!</h2>
|
||||
<hr class="primary">
|
||||
|
||||
{% bootstrap_form_errors form layout='inline' %}
|
||||
<div class="signup-form form-group row">
|
||||
<input type="hidden" name="next" value="{{ request.GET.next }}">
|
||||
<form action="" method="post" class="form" novalidate>
|
||||
{% csrf_token %}
|
||||
<input class="form-control" placeholder="Select your dates" type="text" id="booking-date-range" name="date_range">
|
||||
{% bootstrap_form_errors form layout='inline' %}
|
||||
{% for field in form %}
|
||||
{% bootstrap_field field show_label=False %}
|
||||
{% endfor %}
|
||||
|
||||
<!-- <input class="form-control" placeholder="Select your dates" type="text" id="booking-date-range" name="date_range"> -->
|
||||
<button type="submit" class="btn btn-primary btn-blue">Book</button>
|
||||
</form>
|
||||
<br>
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
{% extends "new_base_glarus.html" %}
|
||||
{% load staticfiles bootstrap3 i18n %}
|
||||
{% block content %}
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
.invoice-title{
|
||||
text-align: center !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
</script>
|
||||
|
||||
<section id="price">
|
||||
<div class="signup-container">
|
||||
<div class="col-xs-12 col-sm-6 col-lg-8 text-center wow fadeInDown">
|
||||
<div class="payment-box">
|
||||
<h2 class="section-heading payment-head">Your Membership Order Detail</h2>
|
||||
<hr class="greyline-long">
|
||||
<h2 class="billing-head">Invoice<btn class="btn btn-primary btn-grey btn-edit print" data-print="price">Get PDF</btn></h2>
|
||||
|
||||
<h2 class="order-head">Order Number</h2>
|
||||
<h2 class="member-name">#{{order.id}}</h2>
|
||||
|
||||
<h2 class="order-head">Billed to :</h2>
|
||||
<h2 class="history-name">{{user.name}}<br>
|
||||
{{order.billing_address.street_address}},{{order.billing_address.postal_code}}<br>
|
||||
{{order.billing_address.city}}, {{order.billing_address.country}}.
|
||||
</h2>
|
||||
|
||||
<h2 class="order-head">Payment Method</h2>
|
||||
<h2 class="history-name">
|
||||
{{order.cc_brand}} ending **** {{order.last4}}<br>
|
||||
{{user.email}}
|
||||
</h2>
|
||||
|
||||
<hr class="greyline-long">
|
||||
<h2 class="order-head">Order Summary</h2>
|
||||
<h2 class="history-name">
|
||||
Dates: {{membership_start_date|date}} - {{membership_end_date|date}}<br>
|
||||
</h2>
|
||||
<h2 class="col-xs-6 payment-total text-left">Membership month {{order.created_at|date:"F"}}</h2>
|
||||
<h2 class="order-sum">{{order.amount|floatformat}}CHF</h2>
|
||||
<hr class="greyline-long">
|
||||
<h2 class="col-xs-6 payment-total text-left"> Total</h2>
|
||||
<h2 class="order-result">{{order.amount|floatformat}}CHF</h2>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-sm-4 col-lg-4 wow fadeInDown">
|
||||
<div class="order-summary">
|
||||
<div class="header text-center">
|
||||
<h2 class="order-name">Order Summary</h2>
|
||||
</div>
|
||||
<div class="order-box">
|
||||
<h2 class="col-xs-6 order-item" style="padding-bottom:10px"> Dates: {{membership_start_date|date}} - {{membership_end_date|date}}<br><br></h2>
|
||||
|
||||
<h2 class="col-xs-6 payment-total">Membership month {{order.created_at|date:"F"}}</h2>
|
||||
<h2 class="order-sum">{{order.amount|floatformat}}CHF</h2>
|
||||
<hr class="greyline">
|
||||
<h2 class="col-xs-6 payment-total">Total</h2>
|
||||
<h2 class="order-result">{{order.amount|floatformat}}CHF</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- stripe key data -->
|
||||
{% if stripe_key %}
|
||||
<script type="text/javascript">
|
||||
(function () {window.stripeKey = "{{stripe_key}}";})();
|
||||
</script>
|
||||
|
||||
{%endif%}
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,68 @@
|
|||
{% extends "new_base_glarus.html" %}
|
||||
{% load staticfiles bootstrap3 i18n %}
|
||||
{% block content %}
|
||||
|
||||
|
||||
<!-- Header -->
|
||||
<!-- Services Section -->
|
||||
<section id="price">
|
||||
<div class="signup-container">
|
||||
<div class="col-xs-12 col-sm-6 col-lg-8 text-center wow fadeInDown">
|
||||
<div class="payment-box">
|
||||
<h2 class="section-heading payment-head">Your Order History</h2>
|
||||
<hr class="greyline-long">
|
||||
<h2 class="order-head">Member Name</h2>
|
||||
<h2 class="member-name">{{request.user.name}}</h2>
|
||||
<hr class="greyline-long">
|
||||
<h2 class="order-head">Active Membership</h2>
|
||||
<h2 class="member-name">{{membership_start_date|date}}-{{membership_end_date|date}}</h2>
|
||||
<hr class="greyline-long">
|
||||
<h2 class="order-head">Booking history</h2>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Valid Month</th>
|
||||
<th>Date</th>
|
||||
<th>Invoice</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for order in orders%}
|
||||
<tr>
|
||||
<th scope="row">{{order.id}}</th>
|
||||
<td>{{order.created_at|date:"F"}}</td>
|
||||
<td>{{order.created_at|date}}</td>
|
||||
<td><a class="btn btn-xs btn-primary btn-darkgrey" href="{% url 'digitalglarus:membership_orders_detail' order.id %}">View</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2 class="order-head">Billing Adress<btn class="btn btn-primary btn-grey btn-edit">Edit</btn></h2>
|
||||
<h2 class="history-name">Nico Schottelius<br>
|
||||
In der Au 7 8762 Schwanden<br>
|
||||
Switzerland
|
||||
</h2>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-xs-12 col-sm-4 col-lg-4 wow fadeInDown">
|
||||
<div class="order-summary">
|
||||
<h2 class="thankyou">Thank You!</h2>
|
||||
<div class="order-box">
|
||||
<span class="glyphicon glyphicon-heart icon-up"></span>
|
||||
<h2 class="signup-lead text-center">Digital Glarus lives with your love!<br>
|
||||
Our coworking space is here because of your love and support.</h2>
|
||||
|
||||
<hr class="greyline">
|
||||
|
||||
<p class="order-bottom-text text-center">This box is here just to thank you</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -25,6 +25,8 @@
|
|||
<link href="{% static 'digitalglarus/css/ungleich.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'digitalglarus/css/history.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'digitalglarus/css/price.css' %}" rel="stylesheet">
|
||||
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.css" />
|
||||
|
||||
<!-- <link href="css/bootstrap.min.css" rel="stylesheet"> -->
|
||||
<link href="{% static 'digitalglarus/css/lib/animate.min.css' %}" rel="stylesheet">
|
||||
<!-- <link href="{% static 'css/membership.css' %}" rel="stylesheet"> -->
|
||||
|
@ -53,7 +55,32 @@
|
|||
|
||||
</script>
|
||||
<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon">
|
||||
<style id="igtranslator-color" type="text/css"></style></head>
|
||||
<style id="igtranslator-color" type="text/css"></style>
|
||||
<style type="text/css">
|
||||
|
||||
|
||||
.navbar-default .nav .dropdown.open .dropdown-toggle {
|
||||
background: none !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
|
||||
.navbar-default .nav .dropdown li a{
|
||||
color:#0f1221;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.navbar-default .nav li a .glyphicon-user{
|
||||
|
||||
font-size: 15px;
|
||||
display: inline-block;
|
||||
margin: 0px;
|
||||
color:white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
<body id="page-top" class="index">
|
||||
|
||||
|
@ -89,13 +116,39 @@
|
|||
<li>
|
||||
<a class="page-scroll" href="#contact">Contact</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="page-scroll" href="{% url 'digitalglarus:login' %}">Log In</a>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
<li class="dropdown home-dropdown">
|
||||
<a class="dropdown-toggle" role="button" data-toggle="dropdown" href="#">
|
||||
<i class="glyphicon glyphicon-user"></i>{{request.user.name}} <span class="caret"></span>
|
||||
</a>
|
||||
<ul id="g-account-menu" class="dropdown-menu" role="menu">
|
||||
<li>
|
||||
<a href="{% url 'digitalglarus:booking_orders_list' %}">
|
||||
<i class="fa fa-home" aria-hidden="true"></i> {% trans "Bookings"%}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'digitalglarus:membership_orders_list' %}"><i class="fa fa-heart-o" aria-hidden="true"></i> {% trans "Membership"%}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'digitalglarus:logout' %}">
|
||||
<i class="fa fa-lock" aria-hidden="true"></i>
|
||||
{% trans "Logout"%}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<a class="page-scroll" href="{% url 'digitalglarus:login' %}">Login</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<!-- <li>
|
||||
<a class="page-scroll" href="{% url 'digitalglarus:signup' %}">Sign Up</a>
|
||||
</li>
|
||||
</ul>
|
||||
--> </ul>
|
||||
</div>
|
||||
<!-- /.navbar-collapse -->
|
||||
</div>
|
||||
|
@ -174,8 +227,6 @@
|
|||
-->
|
||||
<!-- Include Date Range Picker -->
|
||||
<script type="text/javascript" src="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.css" />
|
||||
|
||||
|
||||
<!-- Booking JavaScript -->
|
||||
<script src="{% static 'digitalglarus/js/booking.js' %}"></script>
|
||||
|
|
|
@ -5,7 +5,7 @@ from . import views
|
|||
from .views import ContactView, IndexView, AboutView, HistoryView, LoginView, SignupView,\
|
||||
PasswordResetView, PasswordResetConfirmView, MembershipPaymentView, MembershipActivatedView,\
|
||||
MembershipPricingView, BookingSelectDatesView, BookingPaymentView, OrdersBookingDetailView,\
|
||||
BookingOrdersListView
|
||||
BookingOrdersListView, MembershipOrdersListView, OrdersMembershipDetailView
|
||||
# from membership.views import LoginRegistrationView
|
||||
|
||||
urlpatterns = [
|
||||
|
@ -30,6 +30,10 @@ urlpatterns = [
|
|||
name='membership_activated'),
|
||||
url(_(r'membership/pricing/?$'), MembershipPricingView.as_view(),
|
||||
name='membership_pricing'),
|
||||
url(_(r'membership/orders/(?P<pk>\d+)/?$'), OrdersMembershipDetailView.as_view(),
|
||||
name='membership_orders_detail'),
|
||||
url(_(r'membership/orders/?$'), MembershipOrdersListView.as_view(),
|
||||
name='membership_orders_list'),
|
||||
url(_(r'supporters/?$'), views.supporters, name='supporters'),
|
||||
url(r'calendar_api/(?P<month>\d+)/(?P<year>\d+)?$', views.CalendarApi.as_view(),name='calendar_api_1'),
|
||||
url(r'calendar_api/', views.CalendarApi.as_view(),name='calendar_api'),
|
||||
|
|
|
@ -34,7 +34,7 @@ from .forms import LoginForm, SignupForm, MembershipBillingForm, BookingDateForm
|
|||
from .models import MembershipType, Membership, MembershipOrder, Booking, BookingPrice,\
|
||||
BookingOrder
|
||||
|
||||
from .mixins import MembershipRequired
|
||||
from .mixins import MembershipRequiredMixin, IsNotMemberMixin
|
||||
|
||||
|
||||
class IndexView(TemplateView):
|
||||
|
@ -44,7 +44,7 @@ class IndexView(TemplateView):
|
|||
class LoginView(LoginViewMixin):
|
||||
template_name = "digitalglarus/login.html"
|
||||
form_class = LoginForm
|
||||
success_url = reverse_lazy('digitalglarus:landing')
|
||||
success_url = reverse_lazy('digitalglarus:membership_pricing')
|
||||
|
||||
|
||||
class SignupView(SignupViewMixin):
|
||||
|
@ -77,7 +77,7 @@ class HistoryView(TemplateView):
|
|||
return context
|
||||
|
||||
|
||||
class BookingSelectDatesView(LoginRequiredMixin, MembershipRequired, FormView):
|
||||
class BookingSelectDatesView(LoginRequiredMixin, MembershipRequiredMixin, FormView):
|
||||
template_name = "digitalglarus/booking.html"
|
||||
form_class = BookingDateForm
|
||||
membership_redirect_url = reverse_lazy('digitalglarus:membership_pricing')
|
||||
|
@ -102,7 +102,7 @@ class BookingSelectDatesView(LoginRequiredMixin, MembershipRequired, FormView):
|
|||
return super(BookingSelectDatesView, self).form_valid(form)
|
||||
|
||||
|
||||
class BookingPaymentView(LoginRequiredMixin, MembershipRequired, FormView):
|
||||
class BookingPaymentView(LoginRequiredMixin, MembershipRequiredMixin, FormView):
|
||||
template_name = "digitalglarus/booking_payment.html"
|
||||
form_class = BookingBillingForm
|
||||
membership_redirect_url = reverse_lazy('digitalglarus:membership_pricing')
|
||||
|
@ -199,7 +199,10 @@ class BookingPaymentView(LoginRequiredMixin, MembershipRequired, FormView):
|
|||
'booking': booking,
|
||||
'customer': customer,
|
||||
'billing_address': billing_address,
|
||||
'stripe_charge': charge
|
||||
'stripe_charge': charge,
|
||||
'amount': final_price,
|
||||
'original_price': normal_price,
|
||||
'special_month_price': BookingPrice.objects.last().special_month_price
|
||||
}
|
||||
order = BookingOrder.create(order_data)
|
||||
|
||||
|
@ -208,8 +211,6 @@ class BookingPaymentView(LoginRequiredMixin, MembershipRequired, FormView):
|
|||
# 'membership_dates': membership.type.first_month_formated_range
|
||||
# })
|
||||
return HttpResponseRedirect(self.get_success_url(order.id))
|
||||
return super(BookingPaymentView, self).form_valid(form)
|
||||
# return HttpResponseRedirect(reverse('digitalglarus:membership_activated'))
|
||||
|
||||
|
||||
class MembershipPricingView(TemplateView):
|
||||
|
@ -224,10 +225,11 @@ class MembershipPricingView(TemplateView):
|
|||
return context
|
||||
|
||||
|
||||
class MembershipPaymentView(LoginRequiredMixin, FormView):
|
||||
class MembershipPaymentView(LoginRequiredMixin, IsNotMemberMixin, FormView):
|
||||
template_name = "digitalglarus/membership_payment.html"
|
||||
login_url = reverse_lazy('digitalglarus:signup')
|
||||
form_class = MembershipBillingForm
|
||||
already_member_redirect_url = reverse_lazy('digitalglarus:membership_orders_list')
|
||||
|
||||
def get_form_kwargs(self):
|
||||
self.membership_type = MembershipType.objects.get(name='standard')
|
||||
|
@ -291,7 +293,8 @@ class MembershipPaymentView(LoginRequiredMixin, FormView):
|
|||
'membership': membership,
|
||||
'customer': customer,
|
||||
'billing_address': billing_address,
|
||||
'stripe_charge': charge
|
||||
'stripe_charge': charge,
|
||||
'amount': membership_type.first_month_price
|
||||
}
|
||||
MembershipOrder.create(order_data)
|
||||
|
||||
|
@ -319,6 +322,45 @@ class MembershipActivatedView(TemplateView):
|
|||
return context
|
||||
|
||||
|
||||
class MembershipOrdersListView(LoginRequiredMixin, ListView):
|
||||
template_name = "digitalglarus/membership_orders_list.html"
|
||||
context_object_name = "orders"
|
||||
login_url = reverse_lazy('digitalglarus:login')
|
||||
model = MembershipOrder
|
||||
paginate_by = 10
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(MembershipOrdersListView, self).get_context_data(**kwargs)
|
||||
start_date, end_date = MembershipOrder.current_membership(self.request.user)
|
||||
context.update({
|
||||
'membership_start_date': start_date,
|
||||
'membership_end_date': end_date,
|
||||
})
|
||||
return context
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = super(MembershipOrdersListView, self).get_queryset()
|
||||
queryset = queryset.filter(customer__user=self.request.user)
|
||||
return queryset
|
||||
|
||||
|
||||
class OrdersMembershipDetailView(LoginRequiredMixin, DetailView):
|
||||
template_name = "digitalglarus/membership_orders_detail.html"
|
||||
context_object_name = "order"
|
||||
login_url = reverse_lazy('digitalglarus:login')
|
||||
# permission_required = ['view_hostingorder']
|
||||
model = MembershipOrder
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(OrdersMembershipDetailView, self).get_context_data(**kwargs)
|
||||
start_date, end_date = self.object.get_membership_range_date()
|
||||
context.update({
|
||||
'membership_start_date': start_date,
|
||||
'membership_end_date': end_date,
|
||||
})
|
||||
return context
|
||||
|
||||
|
||||
class OrdersBookingDetailView(LoginRequiredMixin, DetailView):
|
||||
template_name = "digitalglarus/booking_orders_detail.html"
|
||||
context_object_name = "order"
|
||||
|
|
Loading…
Reference in a new issue