From f3ebc526793594ce14fba355f7383c4f30cbf1ab Mon Sep 17 00:00:00 2001 From: Levi Date: Mon, 28 Nov 2016 10:32:37 -0500 Subject: [PATCH 1/3] Finished #2715 #2716 #2717 --- digitalglarus/forms.py | 17 ++- .../migrations/0023_bookingorder_status.py | 20 +++ digitalglarus/models.py | 18 +++ .../digitalglarus/booking_orders_detail.html | 53 ++++++- .../emails/booking_cancellation.html | 137 ++++++++++++++++++ .../emails/booking_cancellation.txt | 137 ++++++++++++++++++ digitalglarus/urls.py | 2 + digitalglarus/views.py | 57 +++++++- 8 files changed, 435 insertions(+), 6 deletions(-) create mode 100644 digitalglarus/migrations/0023_bookingorder_status.py create mode 100644 digitalglarus/templates/digitalglarus/emails/booking_cancellation.html create mode 100644 digitalglarus/templates/digitalglarus/emails/booking_cancellation.txt diff --git a/digitalglarus/forms.py b/digitalglarus/forms.py index f5bb53aa..b6fb9ea7 100644 --- a/digitalglarus/forms.py +++ b/digitalglarus/forms.py @@ -8,7 +8,7 @@ from utils.models import BillingAddress from utils.forms import LoginFormMixin, SignupFormMixin, BillingAddressForm from .models import MembershipType, MembershipOrder -from .models import Booking +from .models import Booking, BookingOrder class LoginForm(LoginFormMixin): @@ -74,6 +74,21 @@ class BookingBillingForm(BillingAddressForm): } +class CancelBookingForm(forms.ModelForm): + status = forms.CharField(widget=forms.HiddenInput(), required=False) + + class Meta: + model = BookingOrder + fields = ['status'] + + def clean(self): + booking = self.instance.booking + days_to_start = (booking.start_date - datetime.today().date()).days + if days_to_start < 7: + raise forms.ValidationError("You can't cancel your booking") + return self.cleaned_data + + class BookingDateForm(forms.Form): start_date = forms.DateField(required=False, widget=forms.TextInput(attrs={'id': 'booking-date-1', diff --git a/digitalglarus/migrations/0023_bookingorder_status.py b/digitalglarus/migrations/0023_bookingorder_status.py new file mode 100644 index 00000000..80f6cd83 --- /dev/null +++ b/digitalglarus/migrations/0023_bookingorder_status.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-11-25 03:04 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('digitalglarus', '0022_auto_20161023_0218'), + ] + + operations = [ + migrations.AddField( + model_name='bookingorder', + name='status', + field=models.PositiveIntegerField(choices=[(1, 'Approved'), (2, 'Cancelled')], default=1), + ), + ] diff --git a/digitalglarus/models.py b/digitalglarus/models.py index ae91db47..82f6b35b 100644 --- a/digitalglarus/models.py +++ b/digitalglarus/models.py @@ -238,9 +238,18 @@ class Booking(models.Model): class BookingOrder(Ordereable, models.Model): + + APPROVED, CANCELLED = range(1, 3) + + STATUS_CHOICES = ( + (APPROVED, 'Approved'), + (CANCELLED, 'Cancelled') + ) + booking = models.OneToOneField(Booking) original_price = models.FloatField() special_month_price = models.FloatField() + status = models.PositiveIntegerField(choices=STATUS_CHOICES, default=1) @classmethod def user_has_not_bookings(cls, user): @@ -255,6 +264,15 @@ class BookingOrder(Ordereable, models.Model): def booking_days(self): return (self.booking.end_date - self.booking.start_date).days + 1 + def cancellation_available(self): + days_to_start = (booking.start_date - datetime.today()).days + return False if days_to_start < 7 else True + + + def cancel(self): + self.status = self.CANCELLED + self.save() + class Supporter(models.Model): name = models.CharField(max_length=200) diff --git a/digitalglarus/templates/digitalglarus/booking_orders_detail.html b/digitalglarus/templates/digitalglarus/booking_orders_detail.html index 9dd8a25c..2cfe2f76 100644 --- a/digitalglarus/templates/digitalglarus/booking_orders_detail.html +++ b/digitalglarus/templates/digitalglarus/booking_orders_detail.html @@ -20,10 +20,22 @@

Your Booking Detail


+ {% bootstrap_form_errors form type='non_fields'%} + {% if messages %} + + {% endif %} +

InvoiceGet PDF

Order Number

#{{order.id}}

+ +

Status

+

{{order.get_status_display}}

Billed to :

{{user.name}}
@@ -55,11 +67,50 @@

View my bookings
Go to my page -

+

+ {% if not order.get_status_display == 'Cancelled' %} +
+ {% csrf_token %} +

+ + + +

+ + + + +
+ {% endif %} + + + + + +

+ + +
diff --git a/digitalglarus/templates/digitalglarus/emails/booking_cancellation.html b/digitalglarus/templates/digitalglarus/emails/booking_cancellation.html new file mode 100644 index 00000000..f2294335 --- /dev/null +++ b/digitalglarus/templates/digitalglarus/emails/booking_cancellation.html @@ -0,0 +1,137 @@ +{% load static from staticfiles %} + + + + + + +Oxygen Invoice + + + + + + + + + + + + + +
+
+ + +
+ +
+ + + +
+ logo + +
+
+ +
+
+
+
+ + + + + + + + + + +
+ Your booking is cancelled. +
+ Your booking order from following dates has been cancelled.
{{booking.start_date|date}} to {{booking.end_date|date}}
+ You can book new dates by visiting our homepage,
or simply clicking the button below. +
+ +
+
+
+
+ + +
+ Your Digital Glarus Team
+
+
+
+ + + diff --git a/digitalglarus/templates/digitalglarus/emails/booking_cancellation.txt b/digitalglarus/templates/digitalglarus/emails/booking_cancellation.txt new file mode 100644 index 00000000..f2294335 --- /dev/null +++ b/digitalglarus/templates/digitalglarus/emails/booking_cancellation.txt @@ -0,0 +1,137 @@ +{% load static from staticfiles %} + + + + + + +Oxygen Invoice + + + + + + + + + + + + + +
+
+ + +
+ +
+ + + +
+ logo + +
+
+ +
+
+
+
+ + + + + + + + + + +
+ Your booking is cancelled. +
+ Your booking order from following dates has been cancelled.
{{booking.start_date|date}} to {{booking.end_date|date}}
+ You can book new dates by visiting our homepage,
or simply clicking the button below. +
+ +
+
+
+
+ + +
+ Your Digital Glarus Team
+
+
+
+ + + diff --git a/digitalglarus/urls.py b/digitalglarus/urls.py index 09678b96..004d60ec 100644 --- a/digitalglarus/urls.py +++ b/digitalglarus/urls.py @@ -28,6 +28,8 @@ urlpatterns = [ url(_(r'booking/payment/?$'), BookingPaymentView.as_view(), name='booking_payment'), url(_(r'booking/orders/(?P\d+)/?$'), OrdersBookingDetailView.as_view(), name='booking_orders_detail'), + # url(_(r'booking/orders/(?P\d+)/cancel/?$'), BookingCancelView.as_view(), + # name='booking_orders_cancel'), url(_(r'booking/orders/?$'), BookingOrdersListView.as_view(), name='booking_orders_list'), url(_(r'membership/payment/?$'), MembershipPaymentView.as_view(), name='membership_payment'), diff --git a/digitalglarus/views.py b/digitalglarus/views.py index 39b7ae32..13cf9908 100644 --- a/digitalglarus/views.py +++ b/digitalglarus/views.py @@ -13,7 +13,7 @@ from django.utils.translation import get_language from djangocms_blog.models import Post from django.contrib import messages from django.http import JsonResponse -from django.views.generic import View, DetailView, ListView +from django.views.generic import View, DetailView, ListView, DeleteView from .models import Supporter @@ -34,7 +34,7 @@ from utils.models import UserBillingAddress from .forms import LoginForm, SignupForm, MembershipBillingForm, BookingDateForm,\ - BookingBillingForm + BookingBillingForm, CancelBookingForm from .models import MembershipType, Membership, MembershipOrder, Booking, BookingPrice,\ BookingOrder @@ -568,14 +568,63 @@ class OrdersMembershipDetailView(LoginRequiredMixin, DetailView): return context -class OrdersBookingDetailView(LoginRequiredMixin, DetailView): +# class BookingCancelView(FormView): +# success_message = "Your booking has been cancelled" +# model = BookingOrder +# form_class = CancelBookingForm + +# def get_success_url(self): +# pk = self.kwargs.get(self.pk_url_kwarg) +# return reverse_lazy('digitalglarus:booking_orders_list', kwargs={'pk': pk}) + +# def form_valid(self, form): +# booking_order = self.get_object() +# # booking_order.cancel() +# request = self.request + +# return HttpResponseRedirect(self.get_success_url()) + + +class OrdersBookingDetailView(LoginRequiredMixin, UpdateView): template_name = "digitalglarus/booking_orders_detail.html" context_object_name = "order" login_url = reverse_lazy('digitalglarus:login') + form_class = CancelBookingForm + success_message = "You booking has been cancelled" # permission_required = ['view_hostingorder'] model = BookingOrder - def get_context_data(self, *args, **kwargs): + def get_success_url(self): + pk = self.kwargs.get(self.pk_url_kwarg) + return reverse_lazy('digitalglarus:booking_orders_detail', kwargs={'pk': pk}) + + def form_valid(self, form): + + booking_order = self.get_object() + booking_order.cancel() + request = self.request + + context = { + 'order': booking_order, + 'booking': booking_order.booking, + 'base_url': "{0}://{1}".format(request.scheme, request.get_host()) + + } + email_data = { + 'subject': 'Your membership has been charged', + 'to': request.user.email, + 'context': context, + 'template_name': 'booking_cancellation', + 'template_path': 'digitalglarus/emails/' + } + email = BaseEmail(**email_data) + email.send() + + messages.add_message(self.request, messages.SUCCESS, self.success_message) + + return HttpResponseRedirect(self.get_success_url()) + + def get_context_data(self, **kwargs): context = super(OrdersBookingDetailView, self).get_context_data(**kwargs) From b588dcf7416f10fc42303b19b8424b18f350aa4b Mon Sep 17 00:00:00 2001 From: Levi Date: Tue, 29 Nov 2016 01:20:42 -0500 Subject: [PATCH 2/3] Fixed #2693 --- .../templates/digitalglarus/membership_payment.html | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/digitalglarus/templates/digitalglarus/membership_payment.html b/digitalglarus/templates/digitalglarus/membership_payment.html index 38fd706a..6c412cc3 100644 --- a/digitalglarus/templates/digitalglarus/membership_payment.html +++ b/digitalglarus/templates/digitalglarus/membership_payment.html @@ -71,7 +71,7 @@
-
+

@@ -84,13 +84,22 @@
-
+
+
+
+ {% else %} +
+

You don't have any order yet

+
+ + {% endif %}
diff --git a/digitalglarus/views.py b/digitalglarus/views.py index 54765b73..cc500922 100644 --- a/digitalglarus/views.py +++ b/digitalglarus/views.py @@ -37,7 +37,7 @@ from .forms import LoginForm, SignupForm, MembershipBillingForm, BookingDateForm BookingBillingForm, CancelBookingForm from .models import MembershipType, Membership, MembershipOrder, Booking, BookingPrice,\ - BookingOrder + BookingOrder, BookingCancellation from .mixins import MembershipRequiredMixin, IsNotMemberMixin @@ -519,6 +519,14 @@ class UserBillingAddressView(LoginRequiredMixin, UpdateView): return next_url + def get_context_data(self, **kwargs): + context = super(UserBillingAddressView, self).get_context_data(**kwargs) + current_billing_address = self.request.user.billing_addresses.first() + context.update({ + 'current_billing_address': current_billing_address + }) + return current_billing_address + def form_valid(self, form): """ If the form is valid, save the associated model. @@ -546,8 +554,8 @@ class UserBillingAddressView(LoginRequiredMixin, UpdateView): def get_object(self): current_billing_address = self.request.user.billing_addresses.filter(current=True).last() - if not current_billing_address: - raise AttributeError("Billing Address does not exists") + # if not current_billing_address: + # raise AttributeError("Billing Address does not exists") return current_billing_address @@ -639,6 +647,27 @@ class OrdersBookingDetailView(LoginRequiredMixin, UpdateView): booking_order.cancel() request = self.request + BookingCancellation.create(booking_order) + + context = { + 'order': booking_order, + 'booking': booking_order.booking, + 'base_url': "{0}://{1}".format(request.scheme, request.get_host()), + 'user': request.user + + } + + email_data = { + 'subject': 'A cancellation has been requested', + 'to': 'info@ungleich.ch', + 'context': context, + 'template_name': 'booking_cancellation_notification', + 'template_path': 'digitalglarus/emails/' + } + + email = BaseEmail(**email_data) + email.send() + context = { 'order': booking_order, 'booking': booking_order.booking, @@ -646,7 +675,7 @@ class OrdersBookingDetailView(LoginRequiredMixin, UpdateView): } email_data = { - 'subject': 'Your membership has been charged', + 'subject': 'Your booking has been cancelled', 'to': request.user.email, 'context': context, 'template_name': 'booking_cancellation',