Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. from django.http import HttpResponseRedirect
  2. from django.shortcuts import get_object_or_404, render
  3. from django.core.urlresolvers import reverse
  4. from django.contrib import messages
  5. from django.core.exceptions import ObjectDoesNotExist
  6. from oscar.view.generic import ModelView
  7. from oscar.core.loading import import_module
  8. import_module('basket.models', ['Basket', 'Line', 'InvalidBasketLineError'], locals())
  9. import_module('basket.forms', ['FormFactory'], locals())
  10. import_module('basket.factory', ['BasketFactory'], locals())
  11. import_module('basket.signals', ['basket_addition'], locals())
  12. import_module('product.models', ['Item'], locals())
  13. import_module('offer.models', ['Voucher'], locals())
  14. class BasketView(ModelView):
  15. u"""Class-based view for the basket model."""
  16. template_file = 'oscar/basket/summary.html'
  17. def __init__(self):
  18. self.response = HttpResponseRedirect(reverse('oscar-basket'))
  19. self.factory = BasketFactory()
  20. def get_model(self):
  21. u"""Return a basket model"""
  22. return self.factory.get_or_create_open_basket(self.request, self.response)
  23. def handle_GET(self, basket):
  24. u"""Handle GET requests against the basket"""
  25. saved_basket = self.factory.get_saved_basket(self.request, self.response)
  26. self.response = render(self.request, self.template_file, locals())
  27. def handle_POST(self, basket):
  28. u"""Handle POST requests against the basket"""
  29. try:
  30. super(BasketView, self).handle_POST(basket)
  31. except InvalidBasketLineError, e:
  32. # We handle InvalidBasketLineError gracefully as it will be domain logic
  33. # which causes this to be thrown (eg. a product out of stock)
  34. messages.error(self.request, str(e))
  35. def do_flush(self, basket):
  36. u"""Flush basket content"""
  37. basket.flush()
  38. messages.info(self.request, "Your basket has been emptied")
  39. def do_add(self, basket):
  40. u"""Add an item to the basket"""
  41. item = get_object_or_404(Item.objects, pk=self.request.POST['product_id'])
  42. # Send signal so analytics can track this event. Note that be emitting
  43. # the signal here, we do not track quantity changes to a product - only
  44. # the initial "add".
  45. basket_addition.send(sender=self, product=item, user=self.request.user)
  46. factory = FormFactory()
  47. form = factory.create(item, self.request.POST)
  48. if not form.is_valid():
  49. self.response = HttpResponseRedirect(item.get_absolute_url())
  50. messages.error(self.request, "Unable to add your item to the basket - submission not valid")
  51. else:
  52. # Extract product options from POST
  53. options = []
  54. for option in item.options:
  55. if option.code in form.cleaned_data:
  56. options.append({'option': option, 'value': form.cleaned_data[option.code]})
  57. basket.add_product(item, form.cleaned_data['quantity'], options)
  58. messages.info(self.request, "'%s' (quantity %d) has been added to your basket" %
  59. (item.get_title(), form.cleaned_data['quantity']))
  60. def do_add_voucher(self, basket):
  61. code = self.request.POST['voucher_code']
  62. # First check if the voucher is already in the basket
  63. try:
  64. voucher = basket.vouchers.get(code=code)
  65. messages.error(self.request, "You have already added the '%s' voucher to your basket" % voucher.code)
  66. return
  67. except ObjectDoesNotExist:
  68. pass
  69. try:
  70. voucher = Voucher._default_manager.get(code=code)
  71. if not voucher.is_active():
  72. messages.error(self.request, "The '%s' voucher has expired" % voucher.code)
  73. return
  74. is_available, message = voucher.is_available_to_user(self.request.user)
  75. if not is_available:
  76. messages.error(self.request, message)
  77. return
  78. basket.vouchers.add(voucher)
  79. basket.save()
  80. messages.info(self.request, "Voucher '%s' added to basket" % voucher.code)
  81. except ObjectDoesNotExist:
  82. messages.error(self.request, "No voucher found with code '%s'" % code)
  83. def do_remove_voucher(self, basket):
  84. code = self.request.POST['voucher_code']
  85. try:
  86. voucher = basket.vouchers.get(code=code)
  87. basket.vouchers.remove(voucher)
  88. basket.save()
  89. messages.info(self.request, "Voucher '%s' removed from basket" % voucher.code)
  90. except ObjectDoesNotExist:
  91. messages.error(self.request, "No voucher found with code '%s'" % code)
  92. class LineView(ModelView):
  93. def __init__(self):
  94. self.response = HttpResponseRedirect(reverse('oscar-basket'))
  95. self.factory = BasketFactory()
  96. def get_model(self):
  97. u"""Get basket lines"""
  98. basket = self.factory.get_open_basket(self.request)
  99. return basket.lines.get(line_reference=self.kwargs['line_reference'])
  100. def handle_POST(self, line):
  101. u"""Handle POST requests against the basket line"""
  102. try:
  103. super(LineView, self).handle_POST(line)
  104. except Basket.DoesNotExist:
  105. messages.error(self.request, "You don't have a basket to adjust the lines of")
  106. except Line.DoesNotExist:
  107. messages.error(self.request, "Unable to find a line with reference %s in your basket" % self.kwargs['line_reference'])
  108. except InvalidBasketLineError, e:
  109. messages.error(self.request, str(e))
  110. def _get_quantity(self):
  111. u"""Get item quantity"""
  112. if 'quantity' in self.request.POST:
  113. return int(self.request.POST['quantity'])
  114. return 0
  115. def do_increment_quantity(self, line):
  116. u"""Increment item quantity"""
  117. q = self._get_quantity()
  118. line.quantity += q
  119. line.save()
  120. msg = "The quantity of '%s' has been increased by %d" % (line.product, q)
  121. messages.info(self.request, msg)
  122. def do_decrement_quantity(self, line):
  123. u"""Decrement item quantity"""
  124. q = self._get_quantity()
  125. line.quantity -= q
  126. line.save()
  127. msg = "The quantity of '%s' has been decreased by %d" % (line.product, q)
  128. messages.info(self.request, msg)
  129. def do_set_quantity(self, line):
  130. u"""Set an item quantity"""
  131. q = self._get_quantity()
  132. line.quantity = q
  133. line.save()
  134. msg = "The quantity of '%s' has been set to %d" % (line.product, q)
  135. messages.info(self.request, msg)
  136. def do_delete(self, line):
  137. u"""Delete a basket item"""
  138. line.delete()
  139. msg = "'%s' has been removed from your basket" % line.product
  140. messages.info(self.request, msg)
  141. def do_save_for_later(self, line):
  142. u"""Save basket for later use"""
  143. saved_basket = self.factory.get_or_create_saved_basket(self.request, self.response)
  144. saved_basket.merge_line(line)
  145. msg = "'%s' has been saved for later" % line.product
  146. messages.info(self.request, msg)
  147. class SavedLineView(ModelView):
  148. def __init__(self):
  149. self.response = HttpResponseRedirect(reverse('oscar-basket'))
  150. self.factory = BasketFactory()
  151. def get_model(self):
  152. basket = self.factory.get_saved_basket(self.request, self.response)
  153. return basket.lines.get(line_reference=self.kwargs['line_reference'])
  154. def handle_POST(self, line):
  155. u"""Handle POST requests against a saved line"""
  156. try:
  157. super(SavedLineView, self).handle_POST(line)
  158. except InvalidBasketLineError, e:
  159. messages.error(self.request, str(e))
  160. def do_move_to_basket(self, line):
  161. u"""Merge line items in to current basket"""
  162. real_basket = self.factory.get_or_create_open_basket(self.request, self.response)
  163. real_basket.merge_line(line)
  164. msg = "'%s' has been moved back to your basket" % line.product
  165. messages.info(self.request, msg)
  166. def do_delete(self, line):
  167. u"""Delete line item"""
  168. line.delete()
  169. msg = "'%s' has been removed" % line.product
  170. messages.warn(self.request, msg)
  171. def _get_quantity(self):
  172. u"""Get line item quantity"""
  173. if 'quantity' in self.request.POST:
  174. return int(self.request.POST['quantity'])
  175. return 0