From ba2e231078ca5883354bbbe523d5788ba6f55a56 Mon Sep 17 00:00:00 2001 From: Levi Date: Fri, 28 Oct 2016 11:25:09 -0500 Subject: [PATCH 1/2] As an user I want to receive an email after finishing a booking process. Change Ungleich logo in email to DG logo. Error in membership booking email order dates. Fixed #2670 Design order email when a booking is free.Fixed template issues. Helping natacha to fix bug deploying project. Fixing copies.Fixed #2682. Fixed #2685 fixing copies . Helping natacha fixing bugs. Fixed #2677 Address line change. Started reactivate membership feature --- .../static/digitalglarus/js/payment.js | 14 +- .../static/digitalglarus/js/utils.js | 1 - .../digitalglarus/booking_payment.html | 4 +- .../emails/booking_order_email.html | 136 ++++++++++++++++++ .../emails/booking_order_email.txt | 136 ++++++++++++++++++ .../emails/membership_charge.html | 8 +- .../emails/membership_charge.txt | 8 +- .../emails/membership_monthly_charge.html | 2 +- .../emails/membership_monthly_charge.txt | 2 +- .../digitalglarus/membership_deactivated.html | 2 +- .../digitalglarus/membership_payment.html | 4 +- .../digitalglarus/membership_pricing.html | 11 -- digitalglarus/urls.py | 3 +- digitalglarus/views.py | 16 +++ utils/forms.py | 2 +- 15 files changed, 319 insertions(+), 30 deletions(-) create mode 100644 digitalglarus/templates/digitalglarus/emails/booking_order_email.html create mode 100644 digitalglarus/templates/digitalglarus/emails/booking_order_email.txt diff --git a/digitalglarus/static/digitalglarus/js/payment.js b/digitalglarus/static/digitalglarus/js/payment.js index d9c6e0f7..3179f721 100644 --- a/digitalglarus/static/digitalglarus/js/payment.js +++ b/digitalglarus/static/digitalglarus/js/payment.js @@ -24,6 +24,10 @@ $( document ).ready(function() { } }); + //Acept term and conditions button + + + var submit_form_btn = $('#payment_button'); submit_form_btn.on('click', submit_payment); @@ -41,6 +45,12 @@ $( document ).ready(function() { console.log("submiting"); e.preventDefault(); + if (!$('.agree-terms').is(':checked')){ + alert("You must accept terms and conditions."); + return; + } + + /* Visual feedback */ $form.find('[type=submit]').html('Validating '); @@ -119,7 +129,7 @@ $( document ).ready(function() { } else { return false; } - } + }; $form.find('[type=submit]').prop('disabled', true); var readyInterval = setInterval(function() { @@ -129,5 +139,7 @@ $( document ).ready(function() { } }, 250); + + }); diff --git a/digitalglarus/static/digitalglarus/js/utils.js b/digitalglarus/static/digitalglarus/js/utils.js index e824dafc..65584778 100644 --- a/digitalglarus/static/digitalglarus/js/utils.js +++ b/digitalglarus/static/digitalglarus/js/utils.js @@ -19,5 +19,4 @@ $( document ).ready(function() { }); - }); \ No newline at end of file diff --git a/digitalglarus/templates/digitalglarus/booking_payment.html b/digitalglarus/templates/digitalglarus/booking_payment.html index 1b465282..2f57361e 100644 --- a/digitalglarus/templates/digitalglarus/booking_payment.html +++ b/digitalglarus/templates/digitalglarus/booking_payment.html @@ -162,14 +162,14 @@
- +
diff --git a/digitalglarus/templates/digitalglarus/emails/booking_order_email.html b/digitalglarus/templates/digitalglarus/emails/booking_order_email.html new file mode 100644 index 00000000..d45bcc72 --- /dev/null +++ b/digitalglarus/templates/digitalglarus/emails/booking_order_email.html @@ -0,0 +1,136 @@ +{% load static from staticfiles %} + + + + + + +Oxygen Invoice + + + + + + + + + + + + + +
+
+ + +
+ +
+ + + +
+ logo + +
+
+ +
+
+
+
+ + + + + + + + + + +
+ Thank you for your booking. +
+ Your booking order from {{booking.start_date|date}} to {{booking.end_date|date}} has been placed.
You can view your invoice clicking on the button below. +
+ +
+
+
+
+ + +
+ Digitalglarus
+
+
+
+ + + diff --git a/digitalglarus/templates/digitalglarus/emails/booking_order_email.txt b/digitalglarus/templates/digitalglarus/emails/booking_order_email.txt new file mode 100644 index 00000000..5a414ae4 --- /dev/null +++ b/digitalglarus/templates/digitalglarus/emails/booking_order_email.txt @@ -0,0 +1,136 @@ +{% load static from staticfiles %} + + + + + + +Oxygen Invoice + + + + + + + + + + + + + +
+
+ + +
+ +
+ + + +
+ logo + +
+
+ +
+
+
+
+ + + + + + + + + + +
+ Thank you for your booking. +
+ Your booking order from {{booking.start_date|date}} to {{booking.end_date|date}} has been placed.
You can view your invoice clicking on the button below. +
+ +
+
+
+
+ + +
+ Digitalglarus
+
+
+
+ + + diff --git a/digitalglarus/templates/digitalglarus/emails/membership_charge.html b/digitalglarus/templates/digitalglarus/emails/membership_charge.html index d2d3971f..a6af3443 100644 --- a/digitalglarus/templates/digitalglarus/emails/membership_charge.html +++ b/digitalglarus/templates/digitalglarus/emails/membership_charge.html @@ -65,7 +65,7 @@
-
+ diff --git a/digitalglarus/templates/digitalglarus/membership_payment.html b/digitalglarus/templates/digitalglarus/membership_payment.html index 0aa1c7ee..6f5dd384 100644 --- a/digitalglarus/templates/digitalglarus/membership_payment.html +++ b/digitalglarus/templates/digitalglarus/membership_payment.html @@ -93,13 +93,13 @@
- +
diff --git a/digitalglarus/urls.py b/digitalglarus/urls.py index 6ed5271a..4b00fbf3 100644 --- a/digitalglarus/urls.py +++ b/digitalglarus/urls.py @@ -20,7 +20,8 @@ urlpatterns = [ url(r'reset-password-confirm/(?P[0-9A-Za-z]+)-(?P.+)/$', PasswordResetConfirmView.as_view(), name='reset_password_confirm'), url(_(r'history/?$'), HistoryView.as_view(), name='history'), - url(_(r'users/billing_address/?$'), UserBillingAddressView.as_view(), name='user_billing_address'), + url(_(r'users/billing_address/?$'), UserBillingAddressView.as_view(), + name='user_billing_address'), url(_(r'booking/?$'), BookingSelectDatesView.as_view(), name='booking'), url(_(r'booking/payment/?$'), BookingPaymentView.as_view(), name='booking_payment'), url(_(r'booking/orders/(?P\d+)/?$'), OrdersBookingDetailView.as_view(), diff --git a/digitalglarus/views.py b/digitalglarus/views.py index 73af4ca2..3a0d0780 100644 --- a/digitalglarus/views.py +++ b/digitalglarus/views.py @@ -255,6 +255,22 @@ class BookingPaymentView(LoginRequiredMixin, MembershipRequiredMixin, FormView): } order = BookingOrder.create(order_data) + context = { + 'booking': booking, + 'order': order, + 'base_url': "{0}://{1}".format(self.request.scheme, self.request.get_host()) + } + + email_data = { + 'subject': 'Your booking order has been placed', + 'to': self.request.user.email, + 'context': context, + 'template_name': 'booking_order_email', + 'template_path': 'digitalglarus/emails/' + } + email = BaseEmail(**email_data) + email.send() + return HttpResponseRedirect(self.get_success_url(order.id)) diff --git a/utils/forms.py b/utils/forms.py index 80b6186b..e8580f9d 100644 --- a/utils/forms.py +++ b/utils/forms.py @@ -116,7 +116,7 @@ class UserBillingAddressForm(forms.ModelForm): model = UserBillingAddress fields = ['street_address', 'city', 'postal_code', 'country', 'user'] labels = { - 'street_address': _('Street Address'), + 'street_address': _('Street Building'), 'city': _('City'), 'postal_code': _('Postal Code'), 'Country': _('Country'), From 56776e8894ff576466427b5e5ced0931b921beeb Mon Sep 17 00:00:00 2001 From: Levi Date: Mon, 31 Oct 2016 23:01:43 -0500 Subject: [PATCH 2/2] =?UTF-8?q?Edited=20membership=5Forder=5Flist.html=20t?= =?UTF-8?q?o=20allow=20=E2=80=9Cbecome=20a=20member=E2=80=9D=20option.Edit?= =?UTF-8?q?ed=20membership=5Forder=5Flist.html=20for=20new=20deactivate=20?= =?UTF-8?q?membership=20flow.Fixed=20get=5Fcurrent=5Fmembership=20function?= =?UTF-8?q?=20.Fixed=20Reactivated=20membership=20view.Fixed=20Mixin=20to?= =?UTF-8?q?=20know=20if=20an=20user=20is=20an=20active=20member=20or=20not?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- digitalglarus/mixins.py | 30 +++++++++++++++++ digitalglarus/models.py | 32 ++++++++++++++++--- .../digitalglarus/membership_orders_list.html | 30 +++++++++++++---- digitalglarus/urls.py | 5 ++- digitalglarus/views.py | 22 +++++++++++-- 5 files changed, 105 insertions(+), 14 deletions(-) diff --git a/digitalglarus/mixins.py b/digitalglarus/mixins.py index 5392ad37..7c214e14 100644 --- a/digitalglarus/mixins.py +++ b/digitalglarus/mixins.py @@ -1,5 +1,11 @@ +from django.core.urlresolvers import reverse_lazy +from django.contrib.auth.mixins import LoginRequiredMixin +from django.views.generic import UpdateView from django.db import models from django.http import HttpResponseRedirect +from django.contrib import messages + + from membership.models import StripeCustomer from utils.models import BillingAddress @@ -50,3 +56,27 @@ class Ordereable(models.Model): instance.cc_brand = stripe_charge.source.brand instance.save() return instance + + +class ChangeMembershipStatusMixin(LoginRequiredMixin, UpdateView): + success_message = None + success_url = reverse_lazy('digitalglarus:membership_orders_list') + login_url = reverse_lazy('digitalglarus:login') + fields = '__all__' + + def get_object(self): + from .models import MembershipOrder + membership_order = MembershipOrder.objects.\ + filter(customer__user=self.request.user).last() + if not membership_order: + raise AttributeError("Membership does not exists") + membership = membership_order.membership + return membership + + def post(self, *args, **kwargs): + membership = self.get_object() + membership.activate() + + messages.add_message(self.request, messages.SUCCESS, self.success_message) + + return HttpResponseRedirect(self.success_url) diff --git a/digitalglarus/models.py b/digitalglarus/models.py index 876df6d7..a3b9dd9c 100644 --- a/digitalglarus/models.py +++ b/digitalglarus/models.py @@ -65,6 +65,19 @@ class Membership(models.Model): start_date = models.DateField() end_date = models.DateField() + @classmethod + def get_current_membership(cls, user): + + has_order_current_month = Q(membershiporder__customer__user=user, + membershiporder__created_at__month=datetime.today().month) + # import pdb;pdb.set_trace() + return cls.objects.\ + filter(has_order_current_month).last() + + # def get_current_active_membership(cls, user): + # membership = cls.get_current_membership(user) + # return membership if membership and membership.active else None + @classmethod def get_by_user(cls, user): return cls.objects.\ @@ -75,15 +88,22 @@ class Membership(models.Model): instance = cls.objects.create(**data) return instance + @classmethod + def activate_or_crete(cls, data, user): + membership = cls.get_by_user(user) + obj, created = cls.objects.update_or_create(id=membership.id, defaults=data) + return obj + @classmethod def is_digitalglarus_active_member(cls, user): - past_month = (datetime.today() - relativedelta(months=1)).month + # past_month = (datetime.today() - relativedelta(months=1)).month has_order_current_month = Q(membershiporder__customer__user=user, membershiporder__created_at__month=datetime.today().month) - has_order_past_month = Q(membershiporder__customer__user=user, - membershiporder__created_at__month=past_month) + # has_order_past_month = Q(membershiporder__customer__user=user, + # membershiporder__created_at__month=past_month) active_membership = Q(active=True) - return cls.objects.filter(has_order_past_month | has_order_current_month).\ + # return cls.objects.filter(has_order_past_month | has_order_current_month).\ + return cls.objects.filter(has_order_current_month).\ filter(active_membership).exists() def update_dates(self, start_date, end_date): @@ -95,6 +115,10 @@ class Membership(models.Model): self.active = False self.save() + def activate(self): + self.active = True + self.save() + class MembershipOrder(Ordereable, models.Model): membership = models.ForeignKey(Membership) diff --git a/digitalglarus/templates/digitalglarus/membership_orders_list.html b/digitalglarus/templates/digitalglarus/membership_orders_list.html index 57284121..b7ed582c 100644 --- a/digitalglarus/templates/digitalglarus/membership_orders_list.html +++ b/digitalglarus/templates/digitalglarus/membership_orders_list.html @@ -59,22 +59,40 @@ {% endif %}

Your Next Membership

- {% if next_membership_start_date and next_membership_end_date%} + {% if next_membership_start_date and next_membership_end_date and current_membership.active %}

Dates: {{next_membership_start_date|date}} - {{next_membership_end_date|date}}

+ {% elif current_membership.active == False %} +

+ Your membership is deactivated +

{% else %}

- You are not a member yet + You are not a member.

{% endif %} -
- - Deactivate -
+ {% if not current_membership == None %} + {% if current_membership.active %} + + {% elif not current_membership.active %} +
+ {% csrf_token %} +
+ +
+
+ {% endif %} + {% else %} + + {% endif %}
diff --git a/digitalglarus/urls.py b/digitalglarus/urls.py index 4b00fbf3..488ba1d3 100644 --- a/digitalglarus/urls.py +++ b/digitalglarus/urls.py @@ -6,7 +6,8 @@ from .views import ContactView, IndexView, AboutView, HistoryView, LoginView, Si PasswordResetView, PasswordResetConfirmView, MembershipPaymentView, MembershipActivatedView,\ MembershipPricingView, BookingSelectDatesView, BookingPaymentView, OrdersBookingDetailView,\ BookingOrdersListView, MembershipOrdersListView, OrdersMembershipDetailView, \ - MembershipDeactivateView, MembershipDeactivateSuccessView, UserBillingAddressView + MembershipDeactivateView, MembershipDeactivateSuccessView, UserBillingAddressView, \ + MembershipReactivateView # from membership.views import LoginRegistrationView urlpatterns = [ @@ -33,6 +34,8 @@ urlpatterns = [ name='membership_activated'), url(_(r'membership/deactivate/?$'), MembershipDeactivateView.as_view(), name='membership_deactivate'), + url(_(r'membership/reactivate/?$'), MembershipReactivateView.as_view(), + name='membership_reactivate'), url(_(r'membership/deactivate/success/?$'), MembershipDeactivateSuccessView.as_view(), name='membership_deactivate_success'), url(_(r'membership/pricing/?$'), MembershipPricingView.as_view(), diff --git a/digitalglarus/views.py b/digitalglarus/views.py index 3a0d0780..fabf7c93 100644 --- a/digitalglarus/views.py +++ b/digitalglarus/views.py @@ -17,6 +17,7 @@ from django.views.generic import View, DetailView, ListView from .models import Supporter +from .mixins import ChangeMembershipStatusMixin from utils.forms import ContactUsForm from utils.mailer import BaseEmail @@ -357,13 +358,14 @@ class MembershipPaymentView(LoginRequiredMixin, IsNotMemberMixin, FormView): # Get membership dates membership_start_date, membership_end_date = membership_type.first_month_range - # Create membership plan + # Create or update membership plan membership_data = { 'type': membership_type, + 'active': True, 'start_date': membership_start_date, 'end_date': membership_end_date } - membership = Membership.create(membership_data) + membership = Membership.activate_or_crete(membership_data, self.request.user) # Create membership order order_data = { @@ -446,6 +448,16 @@ class MembershipDeactivateView(LoginRequiredMixin, UpdateView): return HttpResponseRedirect(self.success_url) +class MembershipReactivateView(ChangeMembershipStatusMixin): + success_message = "Your membership has been reactivate :)" + template_name = "digitalglarus/membership_orders_list.html" + + def post(self, request, *args, **kwargs): + membership = self.get_object() + membership.activate() + return super(MembershipReactivateView, self).post(request, *args, **kwargs) + + class UserBillingAddressView(LoginRequiredMixin, UpdateView): model = UserBillingAddress form_class = UserBillingAddressForm @@ -504,12 +516,16 @@ class MembershipOrdersListView(LoginRequiredMixin, ListView): def get_context_data(self, **kwargs): context = super(MembershipOrdersListView, self).get_context_data(**kwargs) - start_date, end_date = MembershipOrder.current_membership_dates(self.request.user) + current_membership = Membership.get_current_membership(self.request.user) + start_date, end_date = (current_membership.start_date, current_membership.end_date)\ + if current_membership else [None, None] + next_start_date, next_end_date = MembershipOrder.next_membership_dates(self.request.user) current_billing_address = self.request.user.billing_addresses.filter(current=True).last() context.update({ 'membership_start_date': start_date, 'membership_end_date': end_date, + 'current_membership': current_membership, 'next_membership_start_date': next_start_date, 'next_membership_end_date': next_end_date, 'billing_address': current_billing_address