| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- from decimal import Decimal
- from itertools import chain
-
- from oscar.core.loading import import_module
- offer_models = import_module('offer.models', ['ConditionalOffer'])
-
-
- class Applicator(object):
- u"""
- For applying offers to a basket.
- """
-
- def apply(self, request, basket):
- u"""
- Applies all relevant offers to the given basket. The user is passed
- too as sometimes the available offers are dependent on the user.
- """
- offers = self.get_offers(request, basket)
- discounts = {}
- for offer in offers:
- # For each offer, we keep trying to apply it until the
- # discount is 0
- while True:
- discount = offer.apply_benefit(basket)
- if discount > 0:
- if offer.id not in discounts:
- discounts[offer.id] = {'name': offer.name,
- 'offer': offer,
- 'voucher': offer.get_voucher(),
- 'freq': 0,
- 'discount': Decimal('0.00')}
- discounts[offer.id]['discount'] += discount
- discounts[offer.id]['freq'] += 1
- else:
- break
-
- # Store this list of discounts with the basket so it can be
- # rendered in templates
- basket.set_discounts(list(discounts.values()))
-
- def get_offers(self, request, basket):
- u"""
- Returns all offers to apply to the basket.
-
- This method should be subclassed and extended to provide more sophisticated
- behaviour. For instance, you could load extra offers based on the session or
- the user type.
- """
- site_offers = self.get_site_offers()
- basket_offers = self.get_basket_offers(basket, request.user)
- user_offers = self.get_user_offers(request.user)
- session_offers = self.get_session_offers(request)
-
- return list(chain(site_offers, basket_offers, user_offers, session_offers))
-
- def get_site_offers(self):
- u"""
- Returns site offers that are available to all users
- """
- return offer_models.ConditionalOffer.active.all()
-
- def get_basket_offers(self, basket, user):
- u"""
- Returns basket-linked offers such as those associated with a voucher code"""
- offers = []
- for voucher in basket.vouchers.all():
- if voucher.is_active() and voucher.is_available_to_user(user):
- basket_offers = voucher.offers.all()
- for offer in basket_offers:
- offer.set_voucher(voucher)
- offers = list(chain(offers, basket_offers))
- return offers
-
- def get_user_offers(self, user):
- u"""
- Returns offers linked to this particular user.
-
- Eg: student users might get 25% off
- """
- return []
-
- def get_session_offers(self, request):
- u"""
- Returns temporary offers linked to the current session.
-
- Eg: visitors coming from an affiliate site get a 10% discount
- """
- return []
-
|