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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. import warnings
  2. from oscar.core.loading import get_class
  3. Repository = get_class('shipping.repository', 'Repository')
  4. class CheckoutSessionData(object):
  5. """
  6. Class responsible for marshalling all the checkout session data
  7. """
  8. SESSION_KEY = 'checkout_data'
  9. def __init__(self, request):
  10. self.request = request
  11. if self.SESSION_KEY not in self.request.session:
  12. self.request.session[self.SESSION_KEY] = {}
  13. def _check_namespace(self, namespace):
  14. if namespace not in self.request.session[self.SESSION_KEY]:
  15. self.request.session[self.SESSION_KEY][namespace] = {}
  16. def _get(self, namespace, key, default=None):
  17. """
  18. Return session value or None
  19. """
  20. self._check_namespace(namespace)
  21. if key in self.request.session[self.SESSION_KEY][namespace]:
  22. return self.request.session[self.SESSION_KEY][namespace][key]
  23. return default
  24. def _set(self, namespace, key, value):
  25. """
  26. Set session value
  27. """
  28. self._check_namespace(namespace)
  29. self.request.session[self.SESSION_KEY][namespace][key] = value
  30. self.request.session.modified = True
  31. def _unset(self, namespace, key):
  32. """
  33. Unset session value
  34. """
  35. self._check_namespace(namespace)
  36. if key in self.request.session[self.SESSION_KEY][namespace]:
  37. del self.request.session[self.SESSION_KEY][namespace][key]
  38. self.request.session.modified = True
  39. def _flush_namespace(self, namespace):
  40. self.request.session[self.SESSION_KEY][namespace] = {}
  41. self.request.session.modified = True
  42. def flush(self):
  43. """
  44. Delete session key
  45. """
  46. self.request.session[self.SESSION_KEY] = {}
  47. # Guest checkout
  48. def set_guest_email(self, email):
  49. self._set('guest', 'email', email)
  50. def get_guest_email(self):
  51. return self._get('guest', 'email')
  52. # Shipping address
  53. # ================
  54. # Options:
  55. # 1. No shipping required (eg digital products)
  56. # 2. Ship to new address (entered in a form)
  57. # 3. Ship to an addressbook address (address chosen from list)
  58. def reset_shipping_data(self):
  59. self._flush_namespace('shipping')
  60. def ship_to_user_address(self, address):
  61. """
  62. Set existing shipping address id to session and unset address fields
  63. from session
  64. """
  65. self.reset_shipping_data()
  66. self._set('shipping', 'user_address_id', address.id)
  67. def ship_to_new_address(self, address_fields):
  68. """
  69. Set new shipping address details to session and unset shipping address
  70. id
  71. """
  72. self._unset('shipping', 'new_address_fields')
  73. phone_number = address_fields.get('phone_number')
  74. if phone_number:
  75. address_fields = address_fields.copy()
  76. address_fields['phone_number'] = unicode(
  77. address_fields['phone_number'])
  78. self._set('shipping', 'new_address_fields', address_fields)
  79. def new_shipping_address_fields(self):
  80. """
  81. Get shipping address fields from session
  82. """
  83. return self._get('shipping', 'new_address_fields')
  84. def shipping_user_address_id(self):
  85. """
  86. Get user address id from session
  87. """
  88. return self._get('shipping', 'user_address_id')
  89. user_address_id = shipping_user_address_id
  90. def is_shipping_address_set(self):
  91. """
  92. Test whether a shipping address has been stored in the session.
  93. This can be from a new address or re-using an existing address.
  94. """
  95. new_fields = self.new_shipping_address_fields()
  96. has_new_address = new_fields is not None
  97. has_old_address = self.user_address_id() > 0
  98. return has_new_address or has_old_address
  99. # Shipping method
  100. # ===============
  101. def use_free_shipping(self):
  102. """
  103. Set "free shipping" code to session
  104. """
  105. self._set('shipping', 'method_code', '__free__')
  106. def use_shipping_method(self, code):
  107. """
  108. Set shipping method code to session
  109. """
  110. self._set('shipping', 'method_code', code)
  111. def shipping_method_code(self, basket):
  112. """
  113. Returns the shipping method code
  114. """
  115. return self._get('shipping', 'method_code')
  116. def shipping_method(self, basket):
  117. """
  118. Returns the shipping method model based on the
  119. data stored in the session.
  120. """
  121. warnings.warn((
  122. "shipping_method is deprecated as the functionality has "
  123. "been moved to the get_shipping_method from the checkout "
  124. "session mixin"), DeprecationWarning)
  125. code = self.shipping_method_code(basket)
  126. if not code:
  127. return None
  128. return Repository().find_by_code(code, basket)
  129. def is_shipping_method_set(self, basket):
  130. """
  131. Test if a valid shipping method is stored in the session
  132. """
  133. return self.shipping_method_code(basket) is not None
  134. # Billing address fields
  135. # ======================
  136. #
  137. # There are 3 common options:
  138. # 1. Billing address is entered manually through a form
  139. # 2. Billing address is selected from address book
  140. # 3. Billing address is the same as the shipping address
  141. def bill_to_new_address(self, address_fields):
  142. """
  143. Store address fields for a billing address.
  144. """
  145. self._flush_namespace('billing')
  146. self._set('billing', 'new_address_fields', address_fields)
  147. def bill_to_user_address(self, address):
  148. """
  149. Set an address from a user's address book as the billing address
  150. :address: The address object
  151. """
  152. self._flush_namespace('billing')
  153. self._set('billing', 'user_address_id', address.id)
  154. def bill_to_shipping_address(self):
  155. """
  156. Record fact that the billing address is to be the same as
  157. the shipping address.
  158. """
  159. self._flush_namespace('billing')
  160. self._set('billing', 'billing_address_same_as_shipping', True)
  161. # Legacy method name
  162. billing_address_same_as_shipping = bill_to_shipping_address
  163. def is_billing_address_same_as_shipping(self):
  164. return self._get('billing', 'billing_address_same_as_shipping', False)
  165. def billing_user_address_id(self):
  166. """
  167. Return the ID of the user address being used for billing
  168. """
  169. return self._get('billing', 'user_address_id')
  170. def new_billing_address_fields(self):
  171. """
  172. Return fields for a billing address
  173. """
  174. return self._get('billing', 'new_address_fields')
  175. # Payment methods
  176. # ===============
  177. def pay_by(self, method):
  178. self._set('payment', 'method', method)
  179. def payment_method(self):
  180. return self._get('payment', 'method')
  181. # Submission methods
  182. def set_order_number(self, order_number):
  183. self._set('submission', 'order_number', order_number)
  184. def get_order_number(self):
  185. return self._get('submission', 'order_number')
  186. def set_submitted_basket(self, basket):
  187. self._set('submission', 'basket_id', basket.id)
  188. def get_submitted_basket_id(self):
  189. return self._get('submission', 'basket_id')