Add "review and pay" as a step in order payment. (#356)
This commit is contained in:
parent
1f2652d134
commit
9adc2a878f
|
@ -89,6 +89,11 @@
|
||||||
{% if not order.paid %}
|
{% if not order.paid %}
|
||||||
{% bootstrap_button "Cancel order" button_type="submit" button_class="btn-danger" name="cancel_order" %}
|
{% bootstrap_button "Cancel order" button_type="submit" button_class="btn-danger" name="cancel_order" %}
|
||||||
{% endif %}
|
{% 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>
|
</div>
|
||||||
{% if order.paid %}
|
{% if order.paid %}
|
||||||
|
@ -98,47 +103,4 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</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 & 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 %}
|
{% endblock %}
|
||||||
|
|
126
src/profiles/templates/shop/order_review.html
Normal file
126
src/profiles/templates/shop/order_review.html
Normal 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 & 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 %}
|
||||||
|
|
|
@ -313,15 +313,19 @@ class TestOrderDetailView(TestCase):
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
self.assertIn("quantity", response.context["order_product_formset"].errors[0])
|
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):
|
def test_terms_have_to_be_accepted(self):
|
||||||
self.client.force_login(self.user)
|
self.client.force_login(self.user)
|
||||||
|
|
||||||
opr = OrderProductRelationFactory(order=self.order)
|
data = {"payment_method": "bank_transfer"}
|
||||||
|
|
||||||
data = self.base_form_data
|
|
||||||
data["form-0-id"] = opr.pk
|
|
||||||
data["form-0-quantity"] = 11
|
|
||||||
data["payment_method"] = "bank_transfer"
|
|
||||||
|
|
||||||
response = self.client.post(self.path, data=data)
|
response = self.client.post(self.path, data=data)
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
|
@ -329,13 +333,7 @@ class TestOrderDetailView(TestCase):
|
||||||
def test_accepted_terms_and_chosen_payment_method(self):
|
def test_accepted_terms_and_chosen_payment_method(self):
|
||||||
self.client.force_login(self.user)
|
self.client.force_login(self.user)
|
||||||
|
|
||||||
opr = OrderProductRelationFactory(order=self.order)
|
data = {"payment_method": "bank_transfer", "accept_terms": True}
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
response = self.client.post(self.path, data=data)
|
response = self.client.post(self.path, data=data)
|
||||||
self.assertEquals(response.status_code, 302)
|
self.assertEquals(response.status_code, 302)
|
||||||
|
|
|
@ -12,6 +12,11 @@ urlpatterns = [
|
||||||
include(
|
include(
|
||||||
[
|
[
|
||||||
path("", OrderDetailView.as_view(), name="order_detail"),
|
path("", OrderDetailView.as_view(), name="order_detail"),
|
||||||
|
path(
|
||||||
|
"review/",
|
||||||
|
OrderReviewAndPayView.as_view(),
|
||||||
|
name="order_review_and_pay",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"invoice/", DownloadInvoiceView.as_view(), name="download_invoice"
|
"invoice/", DownloadInvoiceView.as_view(), name="download_invoice"
|
||||||
),
|
),
|
||||||
|
|
|
@ -345,43 +345,55 @@ class OrderDetailView(
|
||||||
order.invoice_address = request.POST.get("invoice_address") or ""
|
order.invoice_address = request.POST.get("invoice_address") or ""
|
||||||
order.save()
|
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)
|
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(
|
class DownloadInvoiceView(
|
||||||
LoginRequiredMixin,
|
LoginRequiredMixin,
|
||||||
EnsureUserOwnsOrderMixin,
|
EnsureUserOwnsOrderMixin,
|
||||||
|
|
Loading…
Reference in a new issue