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 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. from django.views.generic import ListView, FormView, DeleteView, DetailView
  2. from django.db.models.loading import get_model
  3. from django.core.urlresolvers import reverse
  4. from django.contrib import messages
  5. from django.http import HttpResponseRedirect
  6. from django.shortcuts import get_object_or_404
  7. from oscar.core.loading import get_classes
  8. ConditionalOffer = get_model('offer', 'ConditionalOffer')
  9. Condition= get_model('offer', 'Condition')
  10. OrderDiscount = get_model('order', 'OrderDiscount')
  11. Benefit = get_model('offer', 'Benefit')
  12. MetaDataForm, ConditionForm, BenefitForm, PreviewForm = get_classes('dashboard.offers.forms', [
  13. 'MetaDataForm', 'ConditionForm', 'BenefitForm', 'PreviewForm'])
  14. class OfferListView(ListView):
  15. model = ConditionalOffer
  16. context_object_name = 'offers'
  17. template_name = 'dashboard/offers/offer_list.html'
  18. class OfferWizardStepView(FormView):
  19. wizard_name = 'offer_wizard'
  20. form_class = None
  21. step_name = None
  22. update = False
  23. url_name = None
  24. # Keep a reference to previous view class to allow checks to be made on whether
  25. # prior steps have been completed
  26. previous_view = None
  27. def get(self, request, *args, **kwargs):
  28. if self.update:
  29. self.offer = get_object_or_404(ConditionalOffer, id=kwargs['pk'])
  30. if not self.is_previous_step_complete(request):
  31. messages.warning(request, "%s step not complete" % self.previous_view.step_name.title())
  32. return HttpResponseRedirect(self.get_back_url())
  33. return super(OfferWizardStepView, self).get(request, *args, **kwargs)
  34. def post(self, request, *args, **kwargs):
  35. if self.update:
  36. self.offer = get_object_or_404(ConditionalOffer, id=kwargs['pk'])
  37. if not self.is_previous_step_complete(request):
  38. messages.warning(request, "%s step not complete" %
  39. self.previous_view.step_name.title())
  40. return HttpResponseRedirect(self.get_back_url())
  41. return super(OfferWizardStepView, self).post(request, *args, **kwargs)
  42. def is_previous_step_complete(self, request):
  43. if not self.previous_view:
  44. return True
  45. return self.previous_view.is_valid(self, request)
  46. def _key(self, step_name=None, is_object=False):
  47. key = step_name if step_name else self.step_name
  48. if self.update:
  49. key += str(self.offer.id)
  50. if is_object:
  51. key += '_obj'
  52. return key
  53. def _store_form_kwargs(self, form):
  54. session_data = self.request.session.setdefault(self.wizard_name, {})
  55. form_kwargs = {'data': form.cleaned_data.copy()}
  56. session_data[self._key()] = form_kwargs
  57. self.request.session.save()
  58. def _fetch_form_kwargs(self, step_name=None):
  59. if not step_name:
  60. step_name = self.step_name
  61. session_data = self.request.session.setdefault(self.wizard_name, {})
  62. return session_data.get(self._key(step_name), {})
  63. def _store_object(self, form):
  64. session_data = self.request.session.setdefault(self.wizard_name, {})
  65. session_data[self._key(is_object=True)] = form.save(commit=False)
  66. self.request.session.save()
  67. def _fetch_object(self, step_name):
  68. session_data = self.request.session.setdefault(self.wizard_name, {})
  69. return session_data.get(self._key(step_name, is_object=True), None)
  70. def _flush_session(self):
  71. self.request.session[self.wizard_name] = {}
  72. self.request.session.save()
  73. def get_form_kwargs(self, *args, **kwargs):
  74. form_kwargs = {}
  75. if self.update:
  76. form_kwargs['instance'] = self.get_instance()
  77. session_kwargs = self._fetch_form_kwargs()
  78. form_kwargs.update(session_kwargs)
  79. parent_kwargs = super(OfferWizardStepView, self).get_form_kwargs(*args, **kwargs)
  80. form_kwargs.update(parent_kwargs)
  81. return form_kwargs
  82. def get_context_data(self, **kwargs):
  83. ctx = super(OfferWizardStepView, self).get_context_data(**kwargs)
  84. if self.update:
  85. ctx['pk'] = self.kwargs.get('pk', None)
  86. ctx['back_url'] = self.get_back_url()
  87. ctx['title'] = self.get_title()
  88. return ctx
  89. def get_back_url(self):
  90. if not self.previous_view:
  91. return None
  92. if self.update:
  93. return reverse(self.previous_view.url_name,
  94. kwargs={'pk': self.kwargs['pk']})
  95. return reverse(self.previous_view.url_name)
  96. def get_title(self):
  97. if self.update:
  98. return "Edit %s for offer #%d" % (self.step_name, self.offer.id)
  99. return 'Create new offer: %s' % self.step_name
  100. def form_valid(self, form):
  101. self._store_form_kwargs(form)
  102. self._store_object(form)
  103. return super(OfferWizardStepView, self).form_valid(form)
  104. def get_success_url(self):
  105. if self.update:
  106. return reverse(self.success_url_name,
  107. kwargs={'pk': self.kwargs['pk']})
  108. return reverse(self.success_url_name)
  109. @classmethod
  110. def is_valid(cls, current_view, request):
  111. if current_view.update:
  112. return True
  113. return current_view._fetch_object(cls.step_name) is not None
  114. class OfferMetaDataView(OfferWizardStepView):
  115. step_name = 'metadata'
  116. form_class = MetaDataForm
  117. template_name = 'dashboard/offers/metadata_form.html'
  118. url_name = 'dashboard:offer-metadata'
  119. success_url_name = 'dashboard:offer-condition'
  120. def get_instance(self):
  121. return self.offer
  122. class OfferConditionView(OfferWizardStepView):
  123. step_name = 'condition'
  124. form_class = ConditionForm
  125. template_name = 'dashboard/offers/condition_form.html'
  126. url_name = 'dashboard:offer-condition'
  127. success_url_name = 'dashboard:offer-benefit'
  128. previous_view = OfferMetaDataView
  129. def get_instance(self):
  130. return self.offer.condition
  131. class OfferBenefitView(OfferWizardStepView):
  132. step_name = 'benefit'
  133. form_class = BenefitForm
  134. template_name = 'dashboard/offers/benefit_form.html'
  135. url_name = 'dashboard:offer-benefit'
  136. success_url_name = 'dashboard:offer-preview'
  137. previous_view = OfferConditionView
  138. def get_instance(self):
  139. return self.offer.benefit
  140. class OfferPreviewView(OfferWizardStepView):
  141. step_name = 'preview'
  142. form_class = PreviewForm
  143. template_name = 'dashboard/offers/preview.html'
  144. previous_view = OfferBenefitView
  145. url_name = 'dashboard:offer-preview'
  146. def get_context_data(self, **kwargs):
  147. ctx = super(OfferPreviewView, self).get_context_data(**kwargs)
  148. ctx['offer'] = self._fetch_object('metadata') or self.offer
  149. ctx['condition'] = self._fetch_object('condition') or self.offer.condition
  150. ctx['benefit'] = self._fetch_object('benefit') or self.offer.benefit
  151. return ctx
  152. def get_form_kwargs(self, *args, **kwargs):
  153. return super(OfferWizardStepView, self).get_form_kwargs(*args, **kwargs)
  154. def form_valid(self, form):
  155. condition = self._fetch_object('condition') or self.offer.condition
  156. condition.save()
  157. benefit = self._fetch_object('benefit') or self.offer.benefit
  158. benefit.save()
  159. offer = self._fetch_object('metadata') or self.offer
  160. offer.condition = condition
  161. offer.benefit = benefit
  162. offer.save()
  163. self._flush_session()
  164. if self.update:
  165. msg = "Offer #%d updated" % offer.id
  166. else:
  167. msg = "Offer created!"
  168. messages.success(self.request, msg)
  169. return HttpResponseRedirect(self.get_success_url())
  170. def get_title(self):
  171. if self.update:
  172. return "Preview offer #%d" % self.offer.id
  173. return 'Preview offer'
  174. def get_success_url(self):
  175. return reverse('dashboard:offer-list')
  176. class OfferDeleteView(DeleteView):
  177. model = ConditionalOffer
  178. template_name = 'dashboard/offers/offer_delete.html'
  179. context_object_name = 'offer'
  180. def get_success_url(self):
  181. messages.success(self.request, "Offer deleted!")
  182. return reverse('dashboard:offer-list')
  183. class OfferDetailView(DetailView):
  184. model = ConditionalOffer
  185. template_name = 'dashboard/offers/offer_detail.html'
  186. context_object_name = 'offer'
  187. def get_context_data(self, **kwargs):
  188. ctx = super(OfferDetailView, self).get_context_data(**kwargs)
  189. ctx['order_discounts'] = OrderDiscount.objects.filter(offer_id=self.object.id).order_by('-id')
  190. return ctx