From 9adc2a878fe439c7c49f1e10cbedc6a44bdf5617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Tue, 9 Jul 2019 00:29:18 +0200 Subject: [PATCH] Add "review and pay" as a step in order payment. (#356) --- src/profiles/templates/shop/order_detail.html | 48 +------ src/profiles/templates/shop/order_review.html | 126 ++++++++++++++++++ src/shop/tests.py | 24 ++-- src/shop/urls.py | 5 + src/shop/views.py | 80 ++++++----- 5 files changed, 193 insertions(+), 90 deletions(-) create mode 100644 src/profiles/templates/shop/order_review.html diff --git a/src/profiles/templates/shop/order_detail.html b/src/profiles/templates/shop/order_detail.html index ce505954..50cd05eb 100644 --- a/src/profiles/templates/shop/order_detail.html +++ b/src/profiles/templates/shop/order_detail.html @@ -89,6 +89,11 @@ {% if not order.paid %} {% bootstrap_button "Cancel order" button_type="submit" button_class="btn-danger" name="cancel_order" %} {% endif %} + {% if not order.paid %} + + Review and pay + + {% endif %} {% if order.paid %} @@ -98,47 +103,4 @@ {% endif %} - -{% if not order.paid %} -
-
-

Terms and Payment Options

-
-
-
- {% csrf_token %} -
- -
- -
-
- {% bootstrap_button " Blockchain" button_type="submit" button_class="btn-primary" name="payment_method" value="blockchain" %} -
-
- {% bootstrap_button " Bank transfer" button_type="submit" button_class="btn-primary" name="payment_method" value="bank_transfer" %} -
-
- {% bootstrap_button " Cash" button_type="submit" button_class="btn-primary" name="payment_method" value="cash" %} -
-
- {% bootstrap_button " Credit card*" button_type="submit" button_class="btn-primary" name="payment_method" value="credit_card" %} -
-
-
-
* Please consider the alternatives before choosing credit card. Credit cards are expensive and difficult for us to handle. Thank you!
-
- -
-{% endif %} - {% endblock %} diff --git a/src/profiles/templates/shop/order_review.html b/src/profiles/templates/shop/order_review.html new file mode 100644 index 00000000..17577151 --- /dev/null +++ b/src/profiles/templates/shop/order_review.html @@ -0,0 +1,126 @@ +{% extends 'profile_base.html' %} +{% load bootstrap3 %} +{% load shop_tags %} + +{% block profile_content %} + +
+ Not ready to pay for your order yet? + Go back and edit it +
+ +
+ +
+
+

Details for Order #{{ order.id }}

+
+
+ +

+ Please review your order to make sure the quantities are right. +

+ + + + + + {% for orp in order.orderproductrelation_set.all %} + + + +
+ Name + + Quantity + + Price + + Total + +
+ {{ orp.product.name }} + + {{ orp.quantity }} + + {{ orp.product.price|currency }} + + {{ orp.total|currency }} + + {% endfor %} + +
+ + Included VAT (25%) + + {{ order.vat|currency }} + +
+ + Total + + {{ order.total|currency }}
+ +
+ + {% if order.comment %} +

Comment:

+
{{ order.comment|linebreaks }}
+ {% endif %} + + {% if order.invoice_address %} +

Invoice Address:

+
{{ order.invoice_address|linebreaks }}
+ {% endif %} + +
+
+ +
+
+

Terms and Payment Options

+
+
+
+ {% csrf_token %} +
+ +
+ +

+ Choose a payment option: +

+ +
+
+ {% bootstrap_button " Blockchain" button_type="submit" button_class="btn-primary" name="payment_method" value="blockchain" %} +
+
+ {% bootstrap_button " Bank transfer" button_type="submit" button_class="btn-primary" name="payment_method" value="bank_transfer" %} +
+
+ {% bootstrap_button " Cash" button_type="submit" button_class="btn-primary" name="payment_method" value="cash" %} +
+
+ {% bootstrap_button " Credit card*" button_type="submit" button_class="btn-primary" name="payment_method" value="credit_card" %} +
+
+
+
* Please consider the alternatives before choosing credit card. Credit cards are expensive and difficult for us to handle. Thank you!
+
+ +
+ +{% endblock %} + diff --git a/src/shop/tests.py b/src/shop/tests.py index 0fc39228..c45a9dae 100644 --- a/src/shop/tests.py +++ b/src/shop/tests.py @@ -313,15 +313,19 @@ class TestOrderDetailView(TestCase): self.assertEquals(response.status_code, 200) self.assertIn("quantity", response.context["order_product_formset"].errors[0]) + +class TestOrderReviewAndPay(TestCase): + def setUp(self): + self.user = UserFactory() + self.order = OrderFactory(user=self.user) + # Add order + OrderProductRelationFactory(order=self.order) + self.path = reverse("shop:order_review_and_pay", kwargs={"pk": self.order.pk}) + def test_terms_have_to_be_accepted(self): self.client.force_login(self.user) - opr = OrderProductRelationFactory(order=self.order) - - data = self.base_form_data - data["form-0-id"] = opr.pk - data["form-0-quantity"] = 11 - data["payment_method"] = "bank_transfer" + data = {"payment_method": "bank_transfer"} response = self.client.post(self.path, data=data) self.assertEquals(response.status_code, 200) @@ -329,13 +333,7 @@ class TestOrderDetailView(TestCase): def test_accepted_terms_and_chosen_payment_method(self): self.client.force_login(self.user) - opr = OrderProductRelationFactory(order=self.order) - - data = self.base_form_data - data["form-0-id"] = opr.pk - data["form-0-quantity"] = 11 - data["payment_method"] = "bank_transfer" - data["accept_terms"] = True + data = {"payment_method": "bank_transfer", "accept_terms": True} response = self.client.post(self.path, data=data) self.assertEquals(response.status_code, 302) diff --git a/src/shop/urls.py b/src/shop/urls.py index 4078b47f..ed46e312 100644 --- a/src/shop/urls.py +++ b/src/shop/urls.py @@ -12,6 +12,11 @@ urlpatterns = [ include( [ path("", OrderDetailView.as_view(), name="order_detail"), + path( + "review/", + OrderReviewAndPayView.as_view(), + name="order_review_and_pay", + ), path( "invoice/", DownloadInvoiceView.as_view(), name="download_invoice" ), diff --git a/src/shop/views.py b/src/shop/views.py index 42d7c721..d6813045 100644 --- a/src/shop/views.py +++ b/src/shop/views.py @@ -345,43 +345,55 @@ class OrderDetailView( order.invoice_address = request.POST.get("invoice_address") or "" order.save() - # Then at last see if the user is paying for the order. - payment_method = request.POST.get("payment_method") - if payment_method in order.PAYMENT_METHODS: - if not request.POST.get("accept_terms"): - messages.error( - request, - "You need to accept the general terms and conditions before you can continue!", - ) - return self.render_to_response( - self.get_context_data(order_product_formset=formset) - ) - - # Set payment method and mark the order as closed - order.payment_method = payment_method - order.open = None - order.customer_comment = request.POST.get("customer_comment") or "" - order.invoice_address = request.POST.get("invoice_address") or "" - order.save() - - reverses = { - Order.CREDIT_CARD: reverse_lazy( - "shop:epay_form", kwargs={"pk": order.id} - ), - Order.BLOCKCHAIN: reverse_lazy( - "shop:coinify_pay", kwargs={"pk": order.id} - ), - Order.BANK_TRANSFER: reverse_lazy( - "shop:bank_transfer", kwargs={"pk": order.id} - ), - Order.CASH: reverse_lazy("shop:cash", kwargs={"pk": order.id}), - } - - return HttpResponseRedirect(reverses[payment_method]) - return super(OrderDetailView, self).get(request, *args, **kwargs) +class OrderReviewAndPayView( + LoginRequiredMixin, + EnsureUserOwnsOrderMixin, + EnsureOrderHasProductsMixin, + EnsureOrderIsNotCancelledMixin, + DetailView, +): + template_name = "shop/order_review.html" + context_object_name = "order" + + def post(self, request, *args, **kwargs): + self.object = self.get_object() + order = self.object + + payment_method = request.POST.get("payment_method") + if payment_method in order.PAYMENT_METHODS: + if not request.POST.get("accept_terms"): + messages.error( + request, + "You need to accept the general terms and conditions before you can continue!", + ) + return self.render_to_response(self.get_context_data()) + + # Set payment method and mark the order as closed + order.payment_method = payment_method + order.open = None + order.customer_comment = request.POST.get("customer_comment") or "" + order.invoice_address = request.POST.get("invoice_address") or "" + order.save() + + reverses = { + Order.CREDIT_CARD: reverse_lazy( + "shop:epay_form", kwargs={"pk": order.id} + ), + Order.BLOCKCHAIN: reverse_lazy( + "shop:coinify_pay", kwargs={"pk": order.id} + ), + Order.BANK_TRANSFER: reverse_lazy( + "shop:bank_transfer", kwargs={"pk": order.id} + ), + Order.CASH: reverse_lazy("shop:cash", kwargs={"pk": order.id}), + } + + return HttpResponseRedirect(reverses[payment_method]) + + class DownloadInvoiceView( LoginRequiredMixin, EnsureUserOwnsOrderMixin,