def __init__(self, *args, **kwargs): super(AbstractBasket, self).__init__(*args, **kwargs) # We keep a cached copy of the basket lines as we refer to them often # within the same request cycle. Also, applying offers will append # discount data to the basket lines which isn't persisted to the DB and # so we want to avoid reloading them as this would drop the discount # information. self._lines = None self.offer_applications = results.OfferApplications()
def apply_offers(self, basket, offers): applications = results.OfferApplications() for offer in offers: num_applications = 0 # Keep applying the offer until either # (a) We reach the max number of applications for the offer. # (b) The benefit can't be applied successfully. while num_applications < offer.get_max_applications(basket.owner): result = offer.apply_benefit(basket) num_applications += 1 if not result.is_successful: break applications.add(offer, result) if result.is_final: break # Store this list of discounts with the basket so it can be # rendered in templates basket.offer_applications = applications
def setUp(self): self.applications = results.OfferApplications() self.offer = models.ConditionalOffer()
def reset_offer_applications(self): """ Remove any discounts so they get recalculated """ self.offer_applications = results.OfferApplications() self._lines = None
def apply_offers(self, basket, offers): """ Apply offers to the basket in priority order Group the given flat list of offers into groups based on their offer group. Then, apply the offers in order of (1) offer group priority and (2) offer priority. Within each group, an item in a line is limited to being consumed by a single offer, but this limitation is reset for each group. This makes it possible to apply multiple offers to a single line item. """ pre_offers_apply.send(sender=self.__class__, basket=basket, offers=offers) applications = results.OfferApplications() for group_priority, offers_in_group in group_offers(offers): # Get the OfferGroup object from the list of offers offers_in_group = list(offers_in_group) group = offers_in_group[0].offer_group if len( offers_in_group) > 0 else None # Signal the lines that we're about to start applying an offer group pre_offer_group_apply.send(sender=self.__class__, basket=basket, group=group, offers=offers_in_group) for line in basket.all_lines(): line.begin_offer_group_application() # Apply each offer in the group for offer in offers_in_group: num_applications = 0 # Keep applying the offer until either # (a) We reach the max number of applications for the offer. # (b) The benefit can't be applied successfully. max_applications = offer.get_max_applications(basket.owner) while num_applications < max_applications: result = offer.apply_benefit(basket) num_applications += 1 if not result.is_successful: break applications.add(offer, result) if result.is_final: break # Signal the lines that we've finished applying an offer group for line in basket.all_lines(): line.end_offer_group_application() post_offer_group_apply.send(sender=self.__class__, basket=basket, group=group, offers=offers_in_group) # Signal the lines that we've finished applying all offer groups for line in basket.all_lines(): line.finalize_offer_group_applications() # Store this list of discounts with the basket so it can be rendered in templates basket.offer_applications = applications post_offers_apply.send(sender=self.__class__, basket=basket, offers=offers)