def __init__(self, basket, catalogue, offers):
     self.basket = basket
     self.basket_catalogue = copy.copy(self.basket)
     self.catalogue = catalogue
     self.offers = offers
     self.pricer = {"sub-total": 0.00, "discount": 0.00, "total": 0.00}
     self.offer_calc = OfferCalculator()
    def test_bogof_perm_four(self):
        calc = OfferCalculator()
        basket_item = {"quantity": 1, "price": 0.99}
        offer = {"discount_type": "bogof", "details": {"buy": 2, "free": 1}}
        results = calc.bogof(offer, basket_item)

        self.assertEqual(0.00, results)
    def test_percentage_with_sardines(self):
        calc = OfferCalculator()

        basket_item = {
            "name": "Sardines",
            "quantity": 2,
            "price": 1.89,
            "total": 3.78
        }

        offer = {
            "name": "25% off total",
            "discount_type": "percentage",
            "details": {
                "amount": 25
            },
            "products": ["Sardines"],
        }

        results = calc.percentage(offer, basket_item)

        self.assertEqual(0.95, results)
    def test_offer_calc_return_value(self):
        calc = OfferCalculator()
        basket_item = {
            "name": "Baked Beans",
            "quantity": 4,
            "price": 0.99,
            "total": 3.96,
        }

        offers = [{
            "name": "buy two get one free",
            "discount_type": "bogof",
            "details": {
                "buy": 2,
                "free": 1
            },
            "products": ["Baked Beans"],
        }]

        results = calc.handle(offers, basket_item)
        expected = {"discount": 0.99}
        self.assertEqual(expected, results)
    def test_bogof_with_beans(self):
        calc = OfferCalculator()

        basket_item = {
            "name": "Baked Beans",
            "quantity": 6,
            "price": 0.99,
            "total": 3.96,
        }

        offer = {
            "name": "buy two get one free",
            "discount_type": "bogof",
            "details": {
                "buy": 2,
                "free": 1
            },
            "products": ["Baked Beans"],
        }

        results = calc.bogof(offer, basket_item)

        self.assertEqual(1.98, results)
class BasketPricer:
    def __init__(self, basket, catalogue, offers):
        self.basket = basket
        self.basket_catalogue = copy.copy(self.basket)
        self.catalogue = catalogue
        self.offers = offers
        self.pricer = {"sub-total": 0.00, "discount": 0.00, "total": 0.00}
        self.offer_calc = OfferCalculator()

    def handle(self) -> dict:
        self.basket_catalogue_calc()
        self.basket_offers_calc()
        self.calculate_totals()
        return self.pricer

    def basket_catalogue_calc(self):
        for item in self.basket_catalogue:
            catalogue_listing = list(
                filter(lambda x: x["name"] == item["name"], self.catalogue))
            if catalogue_listing:
                item["price"] = catalogue_listing[0]["price"]
                item["total"] = item["price"] * item["quantity"]

    def basket_offers_calc(self):
        for item in self.basket_catalogue:
            on_offer = list(
                filter(lambda x: item["name"] in x["products"], self.offers))
            if on_offer:
                item.update(self.offer_calc.handle(on_offer, item))

    def calculate_totals(self):
        for item in self.basket_catalogue:
            self.pricer["sub-total"] = Helpers.formatted(
                self.pricer["sub-total"] + item["total"])
            if "discount" in item:
                self.pricer["discount"] += item["discount"]
                if item['discount'] > item['total']:
                    item['discount'] = item['total']
                self.pricer["total"] += item["total"] - item["discount"]
            else:
                self.pricer["total"] += item["total"]