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.

utils.py 3.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. from decimal import Decimal
  2. from itertools import chain
  3. from oscar.core.loading import import_module
  4. offer_models = import_module('offer.models', ['ConditionalOffer'])
  5. class Applicator(object):
  6. u"""
  7. For applying offers to a basket.
  8. """
  9. def apply(self, request, basket):
  10. u"""
  11. Applies all relevant offers to the given basket. The user is passed
  12. too as sometimes the available offers are dependent on the user.
  13. """
  14. offers = self.get_offers(request, basket)
  15. discounts = {}
  16. for offer in offers:
  17. # For each offer, we keep trying to apply it until the
  18. # discount is 0
  19. while True:
  20. discount = offer.apply_benefit(basket)
  21. if discount > 0:
  22. if offer.id not in discounts:
  23. discounts[offer.id] = {'name': offer.name,
  24. 'offer': offer,
  25. 'voucher': offer.get_voucher(),
  26. 'freq': 0,
  27. 'discount': Decimal('0.00')}
  28. discounts[offer.id]['discount'] += discount
  29. discounts[offer.id]['freq'] += 1
  30. else:
  31. break
  32. # Store this list of discounts with the basket so it can be
  33. # rendered in templates
  34. basket.set_discounts(list(discounts.values()))
  35. def get_offers(self, request, basket):
  36. u"""
  37. Returns all offers to apply to the basket.
  38. This method should be subclassed and extended to provide more sophisticated
  39. behaviour. For instance, you could load extra offers based on the session or
  40. the user type.
  41. """
  42. site_offers = self.get_site_offers()
  43. basket_offers = self.get_basket_offers(basket, request.user)
  44. user_offers = self.get_user_offers(request.user)
  45. session_offers = self.get_session_offers(request)
  46. return list(chain(site_offers, basket_offers, user_offers, session_offers))
  47. def get_site_offers(self):
  48. u"""
  49. Returns site offers that are available to all users
  50. """
  51. return offer_models.ConditionalOffer.active.all()
  52. def get_basket_offers(self, basket, user):
  53. u"""
  54. Returns basket-linked offers such as those associated with a voucher code"""
  55. offers = []
  56. for voucher in basket.vouchers.all():
  57. if voucher.is_active() and voucher.is_available_to_user(user):
  58. basket_offers = voucher.offers.all()
  59. for offer in basket_offers:
  60. offer.set_voucher(voucher)
  61. offers = list(chain(offers, basket_offers))
  62. return offers
  63. def get_user_offers(self, user):
  64. u"""
  65. Returns offers linked to this particular user.
  66. Eg: student users might get 25% off
  67. """
  68. return []
  69. def get_session_offers(self, request):
  70. u"""
  71. Returns temporary offers linked to the current session.
  72. Eg: visitors coming from an affiliate site get a 10% discount
  73. """
  74. return []