Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

core_views.py 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. from django.http import HttpResponse, Http404, HttpResponseRedirect, HttpResponseBadRequest
  2. from django.contrib import messages
  3. from django.core.urlresolvers import reverse
  4. from oscar.core.loading import import_module
  5. basket_factory = import_module('basket.factory', ['BasketFactory'])
  6. checkout_calculators = import_module('checkout.calculators', ['OrderTotalCalculator'])
  7. order_models = import_module('order.models', ['Order', 'ShippingAddress'])
  8. checkout_utils = import_module('checkout.utils', ['ProgressChecker', 'CheckoutSessionData'])
  9. address_models = import_module('address.models', ['UserAddress'])
  10. def prev_steps_must_be_complete(view_fn):
  11. u"""
  12. Decorator fn for checking that previous steps of the checkout
  13. are complete.
  14. The completed steps (identified by URL-names) are stored in the session.
  15. If this fails, then we redirect to the next uncompleted step.
  16. """
  17. def _view_wrapper(self, request, *args, **kwargs):
  18. checker = checkout_utils.ProgressChecker()
  19. if not checker.are_previous_steps_complete(request):
  20. messages.error(request, "You must complete this step of the checkout first")
  21. url_name = checker.get_next_step(request)
  22. return HttpResponseRedirect(reverse(url_name))
  23. return view_fn(self, request, *args, **kwargs)
  24. return _view_wrapper
  25. def basket_required(view_fn):
  26. def _view_wrapper(self, request, *args, **kwargs):
  27. basket = basket_factory.BasketFactory().get_open_basket(request)
  28. if not basket:
  29. messages.error(request, "You must add some products to your basket before checking out")
  30. return HttpResponseRedirect(reverse('oscar-basket'))
  31. return view_fn(self, request, *args, **kwargs)
  32. return _view_wrapper
  33. def mark_step_as_complete(request):
  34. u"""
  35. Convenience function for marking a checkout page
  36. as complete.
  37. """
  38. checkout_utils.ProgressChecker().step_complete(request)
  39. def get_next_step(request):
  40. return checkout_utils.ProgressChecker().get_next_step(request)
  41. class CheckoutView(object):
  42. u"""
  43. Top-level superclass for all checkout view classes
  44. """
  45. def __init__(self, template_file=None):
  46. if template_file:
  47. self.template_file = template_file
  48. @basket_required
  49. @prev_steps_must_be_complete
  50. def __call__(self, request):
  51. u"""
  52. We forward request handling to the appropriate method
  53. based on the HTTP method.
  54. """
  55. # Set up the instance variables that are needed to place an order
  56. self.request = request
  57. self.co_data = checkout_utils.CheckoutSessionData(request)
  58. self.basket = basket_factory.BasketFactory().get_open_basket(self.request)
  59. # Set up template context that is available to every view
  60. method = self.co_data.shipping_method()
  61. if method:
  62. method.set_basket(self.basket)
  63. self.context = {'basket': self.basket,
  64. 'order_total': self.get_order_total(method),
  65. 'shipping_addr': self.get_shipping_address()}
  66. self.set_shipping_context(method)
  67. self.set_payment_context()
  68. if request.method == 'POST':
  69. response = self.handle_POST()
  70. elif request.method == 'GET':
  71. response = self.handle_GET()
  72. else:
  73. response = HttpResponseBadRequest()
  74. return response
  75. def set_shipping_context(self, method):
  76. if method:
  77. self.context['method'] = method
  78. self.context['shipping_total_excl_tax'] = method.basket_charge_excl_tax()
  79. self.context['shipping_total_incl_tax'] = method.basket_charge_incl_tax()
  80. def set_payment_context(self):
  81. method = self.co_data.payment_method()
  82. if method:
  83. self.context['payment_method'] = method
  84. def handle_GET(self):
  85. u"""
  86. Default behaviour is to set step as complete and redirect
  87. to the next step.
  88. """
  89. return self.get_success_response()
  90. def get_order_total(self, shipping_method):
  91. calc = checkout_calculators.OrderTotalCalculator(self.request)
  92. return calc.order_total_incl_tax(self.basket, shipping_method)
  93. def get_shipping_address(self):
  94. # Load address data into a blank address model
  95. addr_data = self.co_data.new_address_fields()
  96. if addr_data:
  97. return order_models.ShippingAddress(**addr_data)
  98. addr_id = self.co_data.user_address_id()
  99. if addr_id:
  100. try:
  101. return address_models.UserAddress._default_manager.get(pk=addr_id)
  102. except address_models.UserAddress.DoesNotExist:
  103. # This can happen if you reset all your tables and you still have
  104. # session data that refers to addresses that no longer exist
  105. pass
  106. return None
  107. def get_success_response(self):
  108. u"""
  109. Returns the appropriate redirect response if a checkout
  110. step has been successfully passed.
  111. """
  112. mark_step_as_complete(self.request)
  113. return HttpResponseRedirect(reverse(get_next_step(self.request)))
  114. def handle_POST(self):
  115. pass