Add "review and pay" as a step in order payment. (#356)

This commit is contained in:
Víðir Valberg Guðmundsson 2019-07-09 00:29:18 +02:00 committed by Thomas Steen Rasmussen
parent 1f2652d134
commit 9adc2a878f
5 changed files with 193 additions and 90 deletions

View File

@ -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 %}
<a href="{% url "shop:order_review_and_pay" pk=order.pk %}" class="btn btn-success btn-lg pull-right">
Review and pay
</a>
{% endif %}
</div>
{% if order.paid %}
@ -98,47 +103,4 @@
{% endif %}
</div>
{% if not order.paid %}
<div class="panel panel-default">
<div class="panel-heading">
<h4>Terms and Payment Options</h4><i class="icon-btc"></i>
</div>
<div class="panel-body">
<form method="POST" class="form-inline">
{% csrf_token %}
<div class="checkbox" style="margin-top: -10px;">
<label>
<input type="checkbox" name="accept_terms" />
I accept the <a href="{% url 'general-terms' %}">general terms &amp; conditions</a>.
Finally I accept to adhere to our <a href="{% url 'conduct' %}">Code of Conduct</a>
during events as well as in BornHack online channels.
</label>
</div>
<div class="btn-group btn-group-justified">
<div class="btn-group">
{% bootstrap_button "<i class='glyphicon glyphicon-bitcoin'></i> Blockchain" button_type="submit" button_class="btn-primary" name="payment_method" value="blockchain" %}
</div>
<div class="btn-group">
{% bootstrap_button "<i class='glyphicon glyphicon-piggy-bank'></i> Bank transfer" button_type="submit" button_class="btn-primary" name="payment_method" value="bank_transfer" %}
</div>
<div class="btn-group">
{% bootstrap_button "<i class='glyphicon glyphicon-menu-hamburger'></i> Cash" button_type="submit" button_class="btn-primary" name="payment_method" value="cash" %}
</div>
<div class="btn-group">
{% bootstrap_button "<i class='glyphicon glyphicon-credit-card'></i> Credit card*" button_type="submit" button_class="btn-primary" name="payment_method" value="credit_card" %}
</div>
</div>
</form>
<div class="alert alert-info" style="margin-top: 5px; margin-bottom: -10px;">* Please consider the alternatives before choosing credit card. Credit cards are expensive and difficult for us to handle. Thank you!</div>
</div>
<div class="panel-footer">
<i>Bank transfers take up to a week to get registered, but the other
payment methods should be more or less instant. Please
<a href="{% url 'contact' %}">contact us</a> if your have questions.</i>
</div>
</div>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,126 @@
{% extends 'profile_base.html' %}
{% load bootstrap3 %}
{% load shop_tags %}
{% block profile_content %}
<div>
Not ready to pay for your order yet?
<a href="{% url "shop:order_detail" pk=order.pk %}">Go back and edit it</a>
</div>
<hr />
<div class="panel panel-default">
<div class="panel-heading">
<h4>Details for Order #{{ order.id }}</h4>
</div>
<div class="panel-body">
<p>
Please review your order to make sure the quantities are right.
</p>
<table class="table table-bordered">
<thead>
<tr>
<th>
Name
<th>
Quantity
<th>
Price
<th>
Total
<tbody>
{% for orp in order.orderproductrelation_set.all %}
<tr>
<td>
{{ orp.product.name }}
<td>
{{ orp.quantity }}
<td>
{{ orp.product.price|currency }}
<td>
{{ orp.total|currency }}
{% endfor %}
<tr>
<td colspan="2">
<td>
<strong>Included VAT (25%)</strong>
<td>
{{ order.vat|currency }}
<tr>
<td colspan="2">
<td>
<strong>Total</strong>
<td>
{{ order.total|currency }}<br />
</table>
{% if order.comment %}
<h4>Comment:</h4>
<div class="alert alert-info">{{ order.comment|linebreaks }}</div>
{% endif %}
{% if order.invoice_address %}
<h4>Invoice Address:</h4>
<div class="alert alert-info">{{ order.invoice_address|linebreaks }}</div>
{% endif %}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4>Terms and Payment Options</h4><i class="icon-btc"></i>
</div>
<div class="panel-body">
<form method="POST" class="form-inline">
{% csrf_token %}
<div class="checkbox" style="margin-top: -10px;">
<label>
<p>
<input type="checkbox" name="accept_terms" />
I accept the <a href="{% url 'general-terms' %}">general terms &amp; conditions</a>.
Finally I accept to adhere to our <a href="{% url 'conduct' %}">Code of Conduct</a>
during events as well as in BornHack online channels.
</p>
</label>
</div>
<p>
<strong>Choose a payment option:</strong>
</p>
<div class="btn-group btn-group-justified">
<div class="btn-group">
{% bootstrap_button "<i class='glyphicon glyphicon-bitcoin'></i> Blockchain" button_type="submit" button_class="btn-primary" name="payment_method" value="blockchain" %}
</div>
<div class="btn-group">
{% bootstrap_button "<i class='glyphicon glyphicon-piggy-bank'></i> Bank transfer" button_type="submit" button_class="btn-primary" name="payment_method" value="bank_transfer" %}
</div>
<div class="btn-group">
{% bootstrap_button "<i class='glyphicon glyphicon-menu-hamburger'></i> Cash" button_type="submit" button_class="btn-primary" name="payment_method" value="cash" %}
</div>
<div class="btn-group">
{% bootstrap_button "<i class='glyphicon glyphicon-credit-card'></i> Credit card*" button_type="submit" button_class="btn-primary" name="payment_method" value="credit_card" %}
</div>
</div>
</form>
<div class="alert alert-info" style="margin-top: 5px; margin-bottom: -10px;">* Please consider the alternatives before choosing credit card. Credit cards are expensive and difficult for us to handle. Thank you!</div>
</div>
<div class="panel-footer">
<i>Bank transfers take up to a week to get registered, but the other
payment methods should be more or less instant. Please
<a href="{% url 'contact' %}">contact us</a> if your have questions.</i>
</div>
</div>
{% endblock %}

View File

@ -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)

View File

@ -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"
),

View File

@ -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,