You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

views.py 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. from django.contrib import messages
  2. from django.core.urlresolvers import reverse
  3. from django.db.models import get_model
  4. from django.http import HttpResponseRedirect, Http404
  5. from django.views.generic import ListView, FormView
  6. from django.forms.models import modelformset_factory
  7. from extra_views import ModelFormsetView
  8. from oscar.apps.basket.forms import BasketLineForm, AddToBasketForm, \
  9. BasketVoucherForm, SavedLineForm
  10. class BasketView(ModelFormsetView):
  11. model = get_model('basket', 'Line')
  12. basket_model = get_model('basket', 'Basket')
  13. form_class = BasketLineForm
  14. extra = 0
  15. can_delete = True
  16. template_name='basket/basket.html'
  17. def get_queryset(self):
  18. return self.request.basket.lines.all()
  19. def get_context_data(self, **kwargs):
  20. context = super(BasketView, self).get_context_data(**kwargs)
  21. context['voucher_form'] = BasketVoucherForm()
  22. if self.request.user.is_authenticated():
  23. try:
  24. saved_basket = self.basket_model.saved.get(owner=self.request.user)
  25. saved_queryset = saved_basket.lines.all().select_related('product', 'product__stockrecord')
  26. SavedFormset = modelformset_factory(self.model, form=SavedLineForm, extra=0, can_delete=True)
  27. formset = SavedFormset(queryset=saved_queryset)
  28. context['saved_formset'] = formset
  29. except self.basket_model.DoesNotExist:
  30. pass
  31. return context
  32. def formset_valid(self, formset):
  33. needs_auth = False
  34. for form in formset:
  35. if form.cleaned_data['save_for_later']:
  36. instance = form.instance
  37. if self.request.user.is_authenticated():
  38. saved_basket, _ = get_model('basket','basket').saved.get_or_create(owner=self.request.user)
  39. saved_basket.merge_line(instance)
  40. messages.info(self.request, "'%s' has been saved for later" % instance.product)
  41. else:
  42. needs_auth = True
  43. if needs_auth:
  44. messages.error(self.request, "You can't save an item for later if you're not logged in!")
  45. return HttpResponseRedirect(self.request.META.get('HTTP_REFERER', reverse('basket:summary')))
  46. def formset_invalid(self, formset):
  47. messages.info(self.request, "There was a problem updating your basket, please check that all quantities are numbers")
  48. return HttpResponseRedirect(self.request.META.get('HTTP_REFERER', reverse('basket:summary')))
  49. class BasketAddView(FormView):
  50. u"""
  51. Handles the add-to-basket operation, shouldn't be accessed via GET because there's nothing sensible to render.
  52. """
  53. form_class = AddToBasketForm
  54. product_model = get_model('product', 'item')
  55. def get(self, request, *args, **kwargs):
  56. return HttpResponseRedirect(reverse('basket:summary'))
  57. def get_form_kwargs(self):
  58. kwargs = super(BasketAddView, self).get_form_kwargs()
  59. try:
  60. product = self.product_model.objects.get(pk=self.request.POST['product_id'])
  61. except self.product_model.DoesNotExist:
  62. raise Http404()
  63. kwargs['instance'] = product
  64. return kwargs
  65. def form_valid(self, form):
  66. options = []
  67. for option in form.instance.options:
  68. if option.code in form.cleaned_data:
  69. options.append({'option': option, 'value': form.cleaned_data[option.code]})
  70. self.request.basket.add_product(form.instance, form.cleaned_data['quantity'], options)
  71. messages.info(self.request, "'%s' (quantity %d) has been added to your basket" %
  72. (form.instance.get_title(), form.cleaned_data['quantity']))
  73. return HttpResponseRedirect(self.request.META.get('HTTP_REFERER',reverse('basket:summary')))
  74. def form_invalid(self, form):
  75. return HttpResponseRedirect(self.request.META.get('HTTP_REFERER',reverse('basket:summary')))
  76. class VoucherView(ListView):
  77. model = get_model('offer', 'voucher')
  78. can_delete = True
  79. extra = 0
  80. def get_queryset(self):
  81. self.request.basket.vouchers.all()
  82. class VoucherAddView(FormView):
  83. form_class = BasketVoucherForm
  84. voucher_model = get_model('offer', 'voucher')
  85. def get(self, request, *args, **kwargs):
  86. return HttpResponseRedirect(reverse('basket:summary'))
  87. def _check_voucher(self, code):
  88. try:
  89. voucher = self.request.basket.vouchers.get(code=code)
  90. messages.error(self.request, "You have already added the '%s' voucher to your basket" % voucher.code)
  91. return
  92. except self.voucher_model.DoesNotExist:
  93. pass
  94. try:
  95. voucher = self.voucher_model._default_manager.get(code=code)
  96. if not voucher.is_active():
  97. messages.error(self.request, "The '%s' voucher has expired" % voucher.code)
  98. return
  99. is_available, message = voucher.is_available_to_user(self.request.user)
  100. if not is_available:
  101. messages.error(self.request, message)
  102. return
  103. self.request.basket.vouchers.add(voucher)
  104. self.request.basket.save()
  105. messages.info(self.request, "Voucher '%s' added to basket" % voucher.code)
  106. except self.voucher_model.DoesNotExist:
  107. messages.error(self.request, "No voucher found with code '%s'" % code)
  108. def form_valid(self, form):
  109. code = form.cleaned_data['code']
  110. self._check_voucher(code)
  111. return HttpResponseRedirect(self.request.META.get('HTTP_REFERER', reverse('basket:summary')))
  112. def form_invalid(self, form):
  113. return HttpResponseRedirect(reverse('basket:summary'))
  114. class SavedView(ModelFormsetView):
  115. model = get_model('basket', 'line')
  116. basket_model = get_model('basket', 'basket')
  117. form_class = SavedLineForm
  118. extra = 0
  119. can_delete = True
  120. def get(self, request, *args, **kwargs):
  121. return HttpResponseRedirect(reverse('basket:summary'))
  122. def get_queryset(self):
  123. try:
  124. saved_basket = self.basket_model.saved.get(owner=self.request.user)
  125. return saved_basket.lines.all().select_related('product', 'product__stockrecord')
  126. except self.basket_model.DoesNotExist:
  127. return []
  128. def formset_valid(self, formset):
  129. for form in formset:
  130. if form.cleaned_data['move_to_basket']:
  131. msg = "'%s' has been moved back to your basket" % form.instance.product
  132. messages.info(self.request, msg)
  133. real_basket = self.request.basket
  134. real_basket.merge_line(form.instance)
  135. return HttpResponseRedirect(self.request.META.get('HTTP_REFERER', reverse('basket:summary')))
  136. def formset_invalid(self, formset):
  137. return HttpResponseRedirect(self.request.META.get('HTTP_REFERER', reverse('basket:summary')))
  138. # def do_remove_voucher(self, basket):
  139. # code = self.request.POST['voucher_code']
  140. # try:
  141. # voucher = basket.vouchers.get(code=code)
  142. # basket.vouchers.remove(voucher)
  143. # basket.save()
  144. # messages.info(self.request, "Voucher '%s' removed from basket" % voucher.code)
  145. # except ObjectDoesNotExist:
  146. # messages.error(self.request, "No voucher found with code '%s'" % code)
  147. #
  148. # def do_bulk_load(self, basket):
  149. # num_additions = 0
  150. # num_not_found = 0
  151. # for sku in re.findall(r"[\d -]{5,}", self.request.POST['source_text']):
  152. # try:
  153. # item = Item.objects.get(upc=sku)
  154. # basket.add_product(item)
  155. # num_additions += 1
  156. # except Item.DoesNotExist:
  157. # num_not_found += 1
  158. # messages.info(self.request, "Added %d items to your basket (%d missing)" % (num_additions, num_not_found))
  159. #