more work on shop

This commit is contained in:
Thomas Steen Rasmussen 2016-05-13 08:36:56 +02:00
parent 62fe63bd03
commit b942d674ef
6 changed files with 93 additions and 17 deletions

View File

@ -40,7 +40,7 @@
{% if current_camp.shop_open %}
<li><a href="{% url 'shop:index' %}">Shop</a></li>
{% endif %}
<li><a href="{% url 'good-to-know' %}">Good to know</a></li>
<li><a href="{% url 'good-to-know' %}">Info</a></li>
{% if user.is_authenticated %}
<li><a href="{% url 'profiles:detail' %}">Profile</a></li>
<li><a href="{% url 'account_logout' %}">Logout</a></li>

View File

@ -6,3 +6,7 @@ class CheckoutForm(forms.Form):
# no fields here, just three submit buttons
pass
class AddToOrderForm(forms.Form):
# no fields, just a submit button
pass

View File

@ -2,9 +2,7 @@ from django.db import models
from django.contrib.postgres.fields import DateTimeRangeField, JSONField
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from bornhack.utils import CreatedUpdatedModel, UUIDModel
from .managers import ProductQuerySet

View File

@ -1,13 +1,41 @@
{% extends 'base.html' %}
{% block content %}
<h2>Shop</h2>
<p class="lead">
Here you can see the different products and prices.
Here you can see your orders and available products in the shop.
</p>
<h3>Orders</h3>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Order ID</th>
<th>Open?</th>
<th>Paid?</th>
<th>Delivered?</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for order in orders %}
<tr {% if order.finalized and order.paid %}style="color: lightgreen"{%endif%}>
<td>{{ order.id }}</td>
<td>{{ order.finalized }}</td>
<td>{{ order.paid }}</td>
<td>?</td>
<td>
{% if order.finalized and not order.paid %}
{% bootstrap_button "Pay order" href="{% reverse 'shop:order_detail' pk=order.id %}" button_class="btn-primary" %}
{% bootstrap_button "Cancel order" href="{% reverse 'shop:order_cancel' pk=order.id %}" button_class="btn-primary" %}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<h3>Products</h3>
<table class="table table-bordered table-hover">
<thead>
<tr>
@ -17,7 +45,6 @@ Here you can see the different products and prices.
<th>Buy</th>
</tr>
</thead>
<tbody>
{% for product in product_list %}
<tr {% if not product.is_available %}style="color: lightgrey"{%endif%}>
@ -30,9 +57,7 @@ Here you can see the different products and prices.
</td>
<td>
{% if product.is_available %}
<a href="">
Add to order
</a>
{% bootstrap_button "Add to order" href="{% reverse 'shop:product_detail' pk=product.id %}" button_class="btn-primary" %}
{% else %}
N/A
{% endif %}
@ -41,5 +66,4 @@ Here you can see the different products and prices.
</tbody>
{% endfor %}
</table>
{% endblock %}

View File

@ -13,6 +13,7 @@ urlpatterns = [
#name='epay_callback'
#),
url(r'$', ShopIndexView.as_view(), name='index'),
url(r'products/(?P<pk>[0-9]+)/$', ProductDetailView.as_view(), name='product_detail'),
url(r'orders/(?P<pk>[0-9]+)/$', OrderDetailView.as_view(), name='order_detail'),
url(r'orders/(?P<pk>[0-9]+)/checkout/$', CheckoutView.as_view(), name='checkout'),
]

View File

@ -8,20 +8,48 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse
from django.contrib import messages
from .models import Order, Product, EpayCallback, EpayPayment
from .forms import CheckoutForm
from .models import Order, Product, EpayCallback, EpayPayment, OrderProductRelation
from .forms import CheckoutForm, AddToOrderForm
class ShopIndexView(ListView):
model = Product
template_name = "shop_index.html"
def get_context_data(self, **kwargs):
context = super(EpayView, self).get_context_data(**kwargs)
context['orders'] = Order.objects.filter(user=self.request.user)
return context
class ProductDetailView(LoginRequiredMixin, DetailView):
class ProductDetailView(LoginRequiredMixin, FormView):
model = Product
template_name = 'product_detail.html'
form_class = 'AddToOrderForm'
context_object_name = 'product'
def get(self, request, *args, **kwargs):
self.product == Product.objects.get(id=kwargs.get('product_id'))
def form_valid(self, form):
### do we have an open order?
try:
order = Order.objects.get(user=self.request.user, finalized=False)
except Order.DoesNotExist:
### no open order - open a new one
order = Order.objects.create(user=request.user)
### get product from kwargs
product = Product.objects.get(id=
if self.product in order.products.all():
### this product is already added to this order, increase count by one
OrderProductRelation.objects.filter(product=self.product, order=order).update(quantity=F('quantity') + 1)
else:
order.products.add(self.product)
### done
return super(ProductDetailView, self).form_valid(form)
class OrderDetailView(LoginRequiredMixin, DetailView):
model = Product
@ -36,6 +64,7 @@ class CheckoutView(LoginRequiredMixin, FormView):
"""
model = Order
template_name = 'checkout.html'
form_class='CheckoutForm'
context_object_name = 'order'
def get(self, request, *args, **kwargs):
@ -43,17 +72,17 @@ class CheckoutView(LoginRequiredMixin, FormView):
raise Http404("Order not found")
if self.get_object().paid:
messages.error('This order is already paid for!')
messages.error(request, 'This order is already paid for!')
return HttpResponseRedirect('shop:order_detail')
if not self.get_object().products:
messages.error('This order contains no products!')
messages.error(request, 'This order contains no products!')
return HttpResponseRedirect('shop:order_detail')
return self.render_to_response(self.get_context_data())
def form_valid(self, form):
### mark order as finalizedredirect user to payment
### mark order as finalized and redirect user to payment
form.instance.finalized=True
### set payment_method based on submit button used
@ -86,13 +115,33 @@ class CheckoutView(LoginRequiredMixin, FormView):
class CoinifyRedirectView(TemplateView):
template_name = 'coinify_redirect.html'
def get(self, request, *args, **kwargs):
### validate a few things
self.order = Order.objects.get(pk=kwargs.get('order_id'))
if self.order.user != request.user:
raise Http404("Order not found")
if not self.order.finalized:
messages.error(request, 'This order is still open!')
return HttpResponseRedirect('shop:order_detail')
if self.order.paid:
messages.error(request, 'This order is already paid for!')
return HttpResponseRedirect('shop:order_detail')
if not self.get_object().products:
messages.error(request, 'This order contains no products!')
return HttpResponseRedirect('shop:order_detail')
return self.render_to_response(self.get_context_data())
def get_context_data(self, **kwargs):
order = Order.objects.get(pk=kwargs.get('order_id'))
context = super(CoinifyView, self).get_context_data(**kwargs)
context['order'] = order
### Initiate coinify API and create invoice
coinifyapi = CoinifyAPI(settings.COINIFY_API_KEY, settings.COINIFY_API_SECRET)
response = coinifyapi.invoice_create(
amount,
currency,