Example #1
0
    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()
Example #2
0
    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
Example #3
0
 def setUp(self):
     self.applications = results.OfferApplications()
     self.offer = models.ConditionalOffer()
Example #4
0
 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)