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 %} {% if current_camp.shop_open %}
<li><a href="{% url 'shop:index' %}">Shop</a></li> <li><a href="{% url 'shop:index' %}">Shop</a></li>
{% endif %} {% 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 %} {% if user.is_authenticated %}
<li><a href="{% url 'profiles:detail' %}">Profile</a></li> <li><a href="{% url 'profiles:detail' %}">Profile</a></li>
<li><a href="{% url 'account_logout' %}">Logout</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 # no fields here, just three submit buttons
pass 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.contrib.postgres.fields import DateTimeRangeField, JSONField
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone from django.utils import timezone
from bornhack.utils import CreatedUpdatedModel, UUIDModel from bornhack.utils import CreatedUpdatedModel, UUIDModel
from .managers import ProductQuerySet from .managers import ProductQuerySet

View file

@ -1,13 +1,41 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block content %} {% block content %}
<h2>Shop</h2> <h2>Shop</h2>
<p class="lead"> <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> </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"> <table class="table table-bordered table-hover">
<thead> <thead>
<tr> <tr>
@ -17,7 +45,6 @@ Here you can see the different products and prices.
<th>Buy</th> <th>Buy</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for product in product_list %} {% for product in product_list %}
<tr {% if not product.is_available %}style="color: lightgrey"{%endif%}> <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>
<td> <td>
{% if product.is_available %} {% if product.is_available %}
<a href=""> {% bootstrap_button "Add to order" href="{% reverse 'shop:product_detail' pk=product.id %}" button_class="btn-primary" %}
Add to order
</a>
{% else %} {% else %}
N/A N/A
{% endif %} {% endif %}
@ -41,5 +66,4 @@ Here you can see the different products and prices.
</tbody> </tbody>
{% endfor %} {% endfor %}
</table> </table>
{% endblock %} {% endblock %}

View file

@ -13,6 +13,7 @@ urlpatterns = [
#name='epay_callback' #name='epay_callback'
#), #),
url(r'$', ShopIndexView.as_view(), name='index'), 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]+)/$', OrderDetailView.as_view(), name='order_detail'),
url(r'orders/(?P<pk>[0-9]+)/checkout/$', CheckoutView.as_view(), name='checkout'), 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.http import HttpResponse
from django.contrib import messages from django.contrib import messages
from .models import Order, Product, EpayCallback, EpayPayment from .models import Order, Product, EpayCallback, EpayPayment, OrderProductRelation
from .forms import CheckoutForm from .forms import CheckoutForm, AddToOrderForm
class ShopIndexView(ListView): class ShopIndexView(ListView):
model = Product model = Product
template_name = "shop_index.html" 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 model = Product
template_name = 'product_detail.html' template_name = 'product_detail.html'
form_class = 'AddToOrderForm'
context_object_name = 'product' 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): class OrderDetailView(LoginRequiredMixin, DetailView):
model = Product model = Product
@ -36,6 +64,7 @@ class CheckoutView(LoginRequiredMixin, FormView):
""" """
model = Order model = Order
template_name = 'checkout.html' template_name = 'checkout.html'
form_class='CheckoutForm'
context_object_name = 'order' context_object_name = 'order'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
@ -43,17 +72,17 @@ class CheckoutView(LoginRequiredMixin, FormView):
raise Http404("Order not found") raise Http404("Order not found")
if self.get_object().paid: 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') return HttpResponseRedirect('shop:order_detail')
if not self.get_object().products: 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 HttpResponseRedirect('shop:order_detail')
return self.render_to_response(self.get_context_data()) return self.render_to_response(self.get_context_data())
def form_valid(self, form): 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 form.instance.finalized=True
### set payment_method based on submit button used ### set payment_method based on submit button used
@ -86,13 +115,33 @@ class CheckoutView(LoginRequiredMixin, FormView):
class CoinifyRedirectView(TemplateView): class CoinifyRedirectView(TemplateView):
template_name = 'coinify_redirect.html' 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): def get_context_data(self, **kwargs):
order = Order.objects.get(pk=kwargs.get('order_id')) order = Order.objects.get(pk=kwargs.get('order_id'))
context = super(CoinifyView, self).get_context_data(**kwargs) context = super(CoinifyView, self).get_context_data(**kwargs)
context['order'] = order context['order'] = order
### Initiate coinify API and create invoice
coinifyapi = CoinifyAPI(settings.COINIFY_API_KEY, settings.COINIFY_API_SECRET) coinifyapi = CoinifyAPI(settings.COINIFY_API_KEY, settings.COINIFY_API_SECRET)
response = coinifyapi.invoice_create( response = coinifyapi.invoice_create(
amount, amount,
currency, currency,