|
|
|
@ -6,6 +6,7 @@ from django.contrib.auth.decorators import user_passes_test
|
|
|
|
|
from django.contrib.auth.models import Group
|
|
|
|
|
from django.core.exceptions import MultipleObjectsReturned
|
|
|
|
|
from decorators import *
|
|
|
|
|
from collections import Iterable
|
|
|
|
|
from decimal import Decimal, InvalidOperation
|
|
|
|
|
from helper import *
|
|
|
|
|
import datetime
|
|
|
|
@ -20,7 +21,7 @@ class BuyableItemHandler(BaseHandler):
|
|
|
|
|
|
|
|
|
|
BUY_ITEM, BUY_DEPOSIT, BUY_ITEM_AND_DEPOSIT = range(3)
|
|
|
|
|
|
|
|
|
|
def read(self, request, itemId=None):
|
|
|
|
|
def read(self, request, itemId=None, bulkBuy=False):
|
|
|
|
|
"""Get one or multiple items.
|
|
|
|
|
|
|
|
|
|
- type: Only get items belonging to this type
|
|
|
|
@ -29,6 +30,12 @@ class BuyableItemHandler(BaseHandler):
|
|
|
|
|
Note that neither type nor barcode is used if an item id
|
|
|
|
|
is specified.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
if bulkBuy:
|
|
|
|
|
ret = rc.NOT_IMPLEMENTED
|
|
|
|
|
ret.write("\nBulk buying does not support GET\n")
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
barcode = request.GET.get('barcode', None)
|
|
|
|
|
if itemId == None:
|
|
|
|
|
obj = Buyable.objects.all()
|
|
|
|
@ -54,15 +61,24 @@ class BuyableItemHandler(BaseHandler):
|
|
|
|
|
return error
|
|
|
|
|
|
|
|
|
|
@manglePluginPerms
|
|
|
|
|
def create(self, request, itemId=None):
|
|
|
|
|
def create(self, request, itemId=None, bulkBuy=False):
|
|
|
|
|
"""Buy one or multiple :class:`Buyable <buyable.models.Buyable>` items.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
if not request.content_type:
|
|
|
|
|
request.data = request.POST
|
|
|
|
|
|
|
|
|
|
if bulkBuy:
|
|
|
|
|
return self.bulkBuy(request)
|
|
|
|
|
else:
|
|
|
|
|
return self.buyItem(request, itemId)
|
|
|
|
|
|
|
|
|
|
def buyItem(self, request, itemId):
|
|
|
|
|
"""Buy a :class:`Buyable <buyable.models.Buyable>` item.
|
|
|
|
|
|
|
|
|
|
- deposit: Set to 0 for no deposit, 1 for item+deposit and 2 for deposit only (default 0)
|
|
|
|
|
- amount: amount of items to buy (default 1)
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
if not request.content_type:
|
|
|
|
|
request.data = request.POST
|
|
|
|
|
if not itemId:
|
|
|
|
|
return rc.BAD_REQUEST
|
|
|
|
|
item = None
|
|
|
|
@ -92,7 +108,77 @@ class BuyableItemHandler(BaseHandler):
|
|
|
|
|
p.save()
|
|
|
|
|
order.updatePrice(commit=True)
|
|
|
|
|
order.save()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return rc.CREATED
|
|
|
|
|
|
|
|
|
|
def bulkBuy(self, request):
|
|
|
|
|
"""Buy a :class:`Buyable <buyable.models.Buyable>` item.
|
|
|
|
|
|
|
|
|
|
To buy multiple items, the body of the POST-request has to
|
|
|
|
|
be either JSON or YAML.
|
|
|
|
|
- items: List of items to buy.
|
|
|
|
|
- deposits: List of items to buy deposit for.
|
|
|
|
|
"""
|
|
|
|
|
if not request.content_type:
|
|
|
|
|
ret = rc.BAD_REQUEST
|
|
|
|
|
ret.write("\nThe content-type of the request must not be empty/urlencoded\n")
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
if not request.data.has_key("items") and not request.data.has_key("deposits"):
|
|
|
|
|
ret = rc.BAD_REQUEST
|
|
|
|
|
ret.write("\nYou need to specify either items or deposits (or both).\n")
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
itemList = []
|
|
|
|
|
try:
|
|
|
|
|
if request.data.has_key('items'):
|
|
|
|
|
if not isinstance(request.data['items'], Iterable):
|
|
|
|
|
raise TypeError()
|
|
|
|
|
itemList += request.data['items']
|
|
|
|
|
if request.data.has_key('deposits'):
|
|
|
|
|
if request.data.has_key('items'):
|
|
|
|
|
if not isinstance(request.data['deposits'], Iterable):
|
|
|
|
|
raise TypeError()
|
|
|
|
|
itemList += request.data['deposits']
|
|
|
|
|
except TypeError:
|
|
|
|
|
ret = rc.BAD_REQUEST
|
|
|
|
|
ret.write("\nThe items/deposists parameter have to be a list.\n")
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
ids = {}
|
|
|
|
|
for item in itemList:
|
|
|
|
|
if not ids.has_key(item):
|
|
|
|
|
try:
|
|
|
|
|
ids[item] = Buyable.objects.get(id=item)
|
|
|
|
|
except Buyable.DoesNotExist:
|
|
|
|
|
ret = rc.NOT_FOUND
|
|
|
|
|
ret.write("\nThe item with the id '%s' could not be found\n" % (item,))
|
|
|
|
|
return ret
|
|
|
|
|
except ValueError:
|
|
|
|
|
ret = rc.NOT_FOUND
|
|
|
|
|
ret.write("\nItem ids should be numeric (and preferably integers)\n")
|
|
|
|
|
return ret
|
|
|
|
|
if item in request.data['deposits'] and not ids[item].hasDeposit():
|
|
|
|
|
ret = rc.BAD_REQUEST
|
|
|
|
|
ret.write("\nItem '%s' cant be bought with deposit\n" % (item,))
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
order = Order()
|
|
|
|
|
order.create(request.user)
|
|
|
|
|
order.save()
|
|
|
|
|
purchases = []
|
|
|
|
|
if request.data.has_key('items'):
|
|
|
|
|
for item in request.data['items']:
|
|
|
|
|
p = Purchase.create(order, ids[item], isDeposit=False)
|
|
|
|
|
p.save()
|
|
|
|
|
if request.data.has_key('deposits'):
|
|
|
|
|
for item in request.data['deposits']:
|
|
|
|
|
p = Purchase.create(order, ids[item], isDeposit=True)
|
|
|
|
|
p.save()
|
|
|
|
|
|
|
|
|
|
order.updatePrice(commit=True)
|
|
|
|
|
order.save()
|
|
|
|
|
|
|
|
|
|
return rc.CREATED
|
|
|
|
|
|
|
|
|
|
class BuyableTypeHandler(BaseHandler):
|
|
|
|
|