pull/64/head
JamesRamm 2017-04-02 10:14:20 +01:00
rodzic 03f929b3ab
commit 91a4106714
6 zmienionych plików z 141 dodań i 117 usunięć

Wyświetl plik

@ -1,100 +1,96 @@
from django.apps import apps
from django.db import transaction
from rest_framework.decorators import api_view, permission_classes
from rest_framework import permissions, status
from rest_framework.decorators import detail_route, list_route
from rest_framework import permissions, status, viewsets
from rest_framework.response import Response
from longclaw.longclawbasket.models import BasketItem
from longclaw.longclawbasket.serializers import BasketItemSerializer
from longclaw.longclawbasket import utils
from longclaw.settings import PRODUCT_VARIANT_MODEL
from longclaw.utils import ProductVariant
ProductVariant = apps.get_model(*PRODUCT_VARIANT_MODEL.split('.'))
class BasketViewSet(viewsets.ModelViewSet):
"""
Viewset for interacting with a sessions 'basket' -
``ProductVariants`` which have been marked for checkout.BaseException
"""
serializer_class = BasketItemSerializer
permission_classes = (permissions.AllowAny, )
@api_view(["GET"])
@permission_classes([permissions.AllowAny])
def get_basket(request):
''' Get all basket items
'''
items, _ = utils.get_basket_items(request)
serializer = BasketItemSerializer(items, many=True)
return Response(data=serializer.data, status=status.HTTP_200_OK)
def get_queryset(self):
items, _ = utils.get_basket_items(self.request)
return items
@api_view(["GET"])
@permission_classes([permissions.AllowAny])
def get_item_count(request):
'''
Get quantity of a single item in the basket
'''
bid = utils.basket_id(request)
item = ProductVariant.objects.get(id=request.GET["variant_id"])
try:
count = BasketItem.objects.get(basket_id=bid, variant=item).quantity
except BasketItem.DoesNotExist:
count = 0
return Response(data={"quantity": count}, status=status.HTTP_200_OK)
def create(self, request):
"""
Add an item to the basket
"""
variant_id = request.data.get("variant_id", None)
@transaction.atomic
@api_view(["POST"])
@permission_classes([permissions.AllowAny])
def add_to_basket(request):
'''
Add an item to the basket
'''
variant = ProductVariant.objects.get(id=request.data["variant_id"])
quantity = request.data.get("quantity", 1)
if variant_id is not None:
variant = ProductVariant.objects.get(id=variant_id)
items, bid = utils.get_basket_items(request)
# Check if the variant is already in the basket
in_basket = False
for item in items:
if item.variant.id == variant.id:
item.increase_quantity(quantity)
in_basket = True
break
if not in_basket:
item = BasketItem(variant=variant, quantity=quantity, basket_id=bid)
item.save()
quantity = request.data.get("quantity", 1)
items, bid = utils.get_basket_items(request)
items, _ = utils.get_basket_items(request)
serializer = BasketItemSerializer(items, many=True)
return Response(data=serializer.data,
status=status.HTTP_201_CREATED)
# Check if the variant is already in the basket
in_basket = False
for item in items:
if item.variant.id == variant.id:
item.increase_quantity(quantity)
in_basket = True
break
if not in_basket:
item = BasketItem(variant=variant, quantity=quantity, basket_id=bid)
item.save()
@transaction.atomic
@api_view(["POST"])
@permission_classes([permissions.AllowAny])
def remove_from_basket(request):
'''
Remove an item from the basket
'''
print(request.data["variant_id"])
variant = ProductVariant.objects.get(id=request.data["variant_id"])
quantity = request.data.get("quantity", 1)
try:
item = BasketItem.objects.get(basket_id=utils.basket_id(request), variant=variant)
except BasketItem.DoesNotExist:
return Response(data={"message": "Item does not exist in cart"},
status=status.HTTP_400_BAD_REQUEST)
serializer = BasketItemSerializer(self.get_queryset(), many=True)
response = Response(data=serializer.data,
status=status.HTTP_201_CREATED)
if quantity >= item.quantity:
item.delete()
else:
item.decrease_quantity(quantity)
else:
response = Response(
{"message": "Missing 'variant_id'"},
status=status.HTTP_400_BAD_REQUEST)
items, _ = utils.get_basket_items(request)
serializer = BasketItemSerializer(items, many=True)
return Response(data=serializer.data,
status=status.HTTP_201_CREATED)
return response
@api_view(["GET"])
@permission_classes([permissions.AllowAny])
def basket_total_items(request):
'''
Get total number of items in the basket
'''
items, _ = utils.get_basket_items(request)
n_total = 0
for item in items:
n_total += item.quantity
def destroy(self, request, variant_id=None):
'''
Remove an item from the basket
'''
variant = ProductVariant.objects.get(id=variant_id)
quantity = request.data.get("quantity", 1)
try:
item = BasketItem.objects.get(
basket_id=utils.basket_id(request), variant=variant)
item.decrease_quantity(quantity)
return Response(data={"quantity": n_total}, status=status.HTTP_200_OK)
serializer = BasketItemSerializer(self.get_queryset(), many=True)
return Response(data=serializer.data,
status=status.HTTP_200_OK)
except BasketItem.DoesNotExist:
return Response(data={"message": "Item does not exist in cart"},
status=status.HTTP_400_BAD_REQUEST)
@list_route(methods=['get'])
def total_items(self, request):
'''
Get total number of items in the basket
'''
n_total = 0
for item in self.get_queryset():
n_total += item.quantity
return Response(data={"quantity": n_total}, status=status.HTTP_200_OK)
@detail_route(methods=['get'])
def item_count(self, request, variant_id=None):
'''
Get quantity of a single item in the basket
'''
bid = utils.basket_id(request)
item = ProductVariant.objects.get(id=variant_id)
try:
count = BasketItem.objects.get(basket_id=bid, variant=item).quantity
except BasketItem.DoesNotExist:
count = 0
return Response(data={"quantity": count}, status=status.HTTP_200_OK)

Wyświetl plik

@ -1,3 +1,18 @@
from django.test import TestCase
from django.test.client import RequestFactory
from longclaw.tests.utils import LongclawTestCase, BasketItemFactory
from longclaw.longclawbasket.utils import basket_id
# Create your tests here.
class BasketTest(LongclawTestCase):
def setUp(self):
request = RequestFactory().get('/')
request.session = {}
bid = basket_id(request)
BasketItemFactory(basket_id=bid)
def test_get_basket(self):
self.get_test('basket_list')
def test_basket_total_items(self):
self.get_test('basket_total_items')

Wyświetl plik

@ -3,22 +3,38 @@ from longclaw.longclawbasket import api
from longclaw.longclawbasket import views
from longclaw.settings import API_URL_PREFIX
basket_list = api.BasketViewSet.as_view({
'get': 'list',
'post': 'create'
})
basket_detail = api.BasketViewSet.as_view({
'delete': 'destroy'
})
item_count = api.BasketViewSet.as_view({
'get': 'item_count'
})
total_items = api.BasketViewSet.as_view({
'get': 'total_items'
})
urlpatterns = [
url(API_URL_PREFIX + r'add_to_basket/$',
api.add_to_basket,
name="add_to_basket"),
url(API_URL_PREFIX + r'remove_from_basket/$',
api.remove_from_basket,
name="remove_from_basket"),
url(API_URL_PREFIX + r'get_item_count/$',
api.get_item_count,
name="get_item_count"),
url(API_URL_PREFIX + r'basket_total_items/$',
api.basket_total_items,
url(API_URL_PREFIX + r'basket/$',
basket_list,
name='basket_list'),
url(API_URL_PREFIX + r'basket/count',
total_items,
name="basket_total_items"),
url(API_URL_PREFIX + r'get_basket/$',
api.get_basket,
name="get_basket"),
url(API_URL_PREFIX + r'basket/(?P<variant_id>[0-9]+)/$',
basket_detail,
name='basket_detail'),
url(API_URL_PREFIX + r'basket/(?P<variant_id>[0-9]+)/$',
item_count,
name='basket_item_count'),
url(r'basket/$',
views.BasketView.as_view(),
name="basket")

Wyświetl plik

@ -1,9 +1,6 @@
from django.apps import apps
from rest_framework import serializers
from longclaw.longclawproducts.models import Product
from longclaw.settings import PRODUCT_VARIANT_MODEL
ProductVariant = apps.get_model(*PRODUCT_VARIANT_MODEL.split('.'))
from longclaw.utils import ProductVariant
class ProductSerializer(serializers.ModelSerializer):

Wyświetl plik

@ -1,7 +1,5 @@
import factory
from django.core.urlresolvers import reverse
from django.apps import apps
from django.utils.text import slugify
from rest_framework.test import APITestCase
from rest_framework import status
@ -10,9 +8,7 @@ from wagtail_factories import PageFactory
from longclaw.longclawproducts.models import Product
from longclaw.longclawbasket.models import BasketItem
from longclaw.settings import PRODUCT_VARIANT_MODEL
ProductVariant = apps.get_model(*PRODUCT_VARIANT_MODEL.split('.'))
from longclaw.utils import ProductVariant
class ProductFactory(PageFactory):
''' Create a random Product
@ -25,8 +21,8 @@ class ProductFactory(PageFactory):
@classmethod
def _create(cls, model_class, *args, **kwargs):
kwargs['parent'] = None
return super(ProductFactory, cls)._create(model_class, *args, **kwargs)
kwargs['parent'] = None
return super(ProductFactory, cls)._create(model_class, *args, **kwargs)
class ProductVariantFactory(factory.django.DjangoModelFactory):
@ -34,7 +30,7 @@ class ProductVariantFactory(factory.django.DjangoModelFactory):
model = ProductVariant
product = factory.SubFactory(ProductFactory)
description = factory.Faker('text')
description = factory.Faker('text')
price = factory.Faker('pyfloat', positive=True, left_digits=2, right_digits=2)
ref = factory.Faker('pystr', min_chars=3, max_chars=10)
stock = factory.Faker('pyint')
@ -58,7 +54,7 @@ class LongclawTestCase(APITestCase):
urlkwargs (dict): The `kwargs` parameter to pass to the `reverse` function
'''
response = self.client.get(reverse(urlname, kwargs=urlkwargs), **kwargs)
self.assertEquals(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.status_code, status.HTTP_200_OK)
return response
def post_test(self, data, urlname, urlkwargs=None, **kwargs):
@ -78,10 +74,10 @@ class LongclawTestCase(APITestCase):
''' Submit a PATCH request and assert the response status code is 200
'''
response = self.client.patch(reverse(urlname, kwargs=urlkwargs), data, **kwargs)
self.assertEquals(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.status_code, status.HTTP_200_OK)
return response
def put_test(self, data, urlname, urlkwargs=None, **kwargs):
response = self.client.put(reverse(urlname, kwargs=urlkwargs), data, **kwargs)
self.assertEquals(response.status_code, status.HTTP_202_ACCEPTED)
return response
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
return response

Wyświetl plik

@ -0,0 +1,4 @@
from django.apps import apps
from longclaw.settings import PRODUCT_VARIANT_MODEL
ProductVariant = apps.get_model(*PRODUCT_VARIANT_MODEL.split('.'))