예제 #1
0
 def test_add_item_to_cart(self):
     item_1, price_1, quantity_1 = Item("Item_1"), 2.0, 20
     quantity_to_add_to_cart = 15
     Catalogue().add_item(item_1, price_1, quantity_1)
     cart = Cart()
     cart.add_item(item_1, quantity_to_add_to_cart)
     assert item_1 in cart.show_items()
     assert quantity_to_add_to_cart == cart.show_items()[item_1]
     assert Catalogue().show_items(
     )[item_1][1] == quantity_1 - quantity_to_add_to_cart
예제 #2
0
class Cart:

    def __init__(self):
        self._items = {}
        self._catalogue = Catalogue()
        self._sub_total = 0.0
        self._discount = 0.0

    def add_item(self, item: Item, quantity: int):
        if quantity <= 0 or quantity > self._catalogue.show_items()[item][1]:
            raise ValueError("Not a valid quantity")
        self._catalogue.remove_item(item, quantity)
        if item in self._items:
            self._items[item] += quantity
        else:
            self._items[item] = quantity

    def remove_item(self, item: Item, quantity: int):
        if item not in self._items or self._items[item] < quantity:
            raise ValueError("Incorrect Quantity")
        self._items[item] -= quantity
        self._catalogue.add_existing_item(item, quantity)

    def show_items(self):
        return copy.copy(self._items)

    def calculate_discount(self):
        discount = Utility.round_up(self._calc_disc(Offers().show_offers(), self.show_items()), 2)
        return discount

    def _calc_disc(self, offer_list, remaining_items):
        if len(offer_list) == 0 or len(remaining_items) == 0:
            return 0.0
        discount_summary = []

        for offer in offer_list:
            discount, ri = offer.get_discount_and_remaining_items(remaining_items)
            offer_list_copy = copy.copy(offer_list)
            if discount == 0.0:
                offer_list_copy.remove(offer)
            else:
                discount_summary.append(discount + self._calc_disc(offer_list_copy, ri))
        if not discount_summary:
            return 0.0

        return max(discount_summary)

    def calculate_sub_total(self):
        sub_total = 0.0
        for item in self._items:
            sub_total += Catalogue().show_items()[item][0] * self._items[item]
        return Utility.round_up(sub_total, 2)

    def calculate_totals(self):
        return Utility.round_up(self.calculate_sub_total() - self.calculate_discount(), 2)
예제 #3
0
 def test_discount_calculation(self):
     item1 = Item("item1")
     item2 = Item("item2")
     Catalogue().add_item(item1, 100.0, 10)
     Catalogue().add_item(item2, 100.0, 10)
     Offers().clear_offers()
     an_offer = BuynGetmOffer(offer_name="b1", n=2, m=1, item=item1)
     Offers().add_offer(an_offer)
     items = {item1: 4, item2: 4}
     expected_discount = 100.0
     actual_discount, _ = an_offer.get_discount_and_remaining_items(items)
     assert expected_discount == actual_discount
예제 #4
0
    def test_remove_item_from_cart(self):
        item_1, price_1, quantity_1 = Item("Item_2"), 2.0, 20
        quantity_to_add_to_cart = 15
        Catalogue().add_item(item_1, price_1, quantity_1)
        cart = Cart()
        cart.add_item(item_1, quantity_to_add_to_cart)

        quantity_to_remove_from_cart = 5
        cart.remove_item(item_1, quantity_to_remove_from_cart)
        assert cart.show_items(
        )[item_1] == quantity_to_add_to_cart - quantity_to_remove_from_cart
        assert Catalogue().show_items()[item_1][
            1] == quantity_1 - quantity_to_add_to_cart + quantity_to_remove_from_cart
예제 #5
0
    def test_calculate_percent_discount(self):
        item_1, price_1, quantity_1 = Item("an_item"), 100.0, 20
        quantity_to_add_to_cart = 2
        Catalogue().clear_catalogue()
        Catalogue().add_item(item_1, price_1, quantity_1)
        Offers().clear_offers()
        an_offer = PercentOffer("p1", 10, item_1)
        Offers().add_offer(an_offer)
        expected_discount = 20.0

        cart = Cart()
        cart.add_item(item_1, quantity_to_add_to_cart)
        actual_discount = cart.calculate_discount()
        assert actual_discount == expected_discount
    def test_discount_calculation_applied_to_more_items_in_set(self):
        item1 = Item("item1")
        item2 = Item("item2")
        item3 = Item("item3")
        Catalogue().add_item(item1, 100.0, 10)
        Catalogue().add_item(item2, 100.0, 10)
        Catalogue().add_item(item3, 1000.0, 10)
        Offers().clear_offers()

        x = {item2, item3}
        an_offer = BuynOfXOffer(offer_name="b1", n=3, x=x)
        Offers().add_offer(an_offer)
        items = {item1: 4, item2: 4, item3: 2}
        expected_discount = 100.0
        actual_discount, _ = an_offer.get_discount_and_remaining_items(items)
        assert expected_discount == actual_discount
예제 #7
0
    def test_calculate_sub_total(self):
        item_1, price_1, quantity_1 = Item("an_item_1"), 100.0, 20
        item_2, price_2, quantity_2 = Item("an_item_2"), 200.0, 20
        quantity_to_add_to_cart_1 = 2
        quantity_to_add_to_cart_2 = 2
        Catalogue().clear_catalogue()
        Catalogue().add_item(item_1, price_1, quantity_1)
        Catalogue().add_item(item_2, price_2, quantity_2)

        expected_sub_total = 600.0

        cart = Cart()
        cart.add_item(item_1, quantity_to_add_to_cart_1)
        cart.add_item(item_2, quantity_to_add_to_cart_2)

        actual_sub_total = cart.calculate_sub_total()
        assert actual_sub_total == expected_sub_total
예제 #8
0
 def test_discount_calculation(self):
     item1 = Item("item1")
     item2 = Item("item2")
     Catalogue().add_item(item1, 100.0, 10)
     Offers().clear_offers()
     an_offer = PercentOffer(offer_name="p1", percent=10, item=item1)
     Offers().add_offer(an_offer)
     items = {item1: 1, item2: 1}
     expected_discount = 10.0
     actual_discount, _ = an_offer.get_discount_and_remaining_items(items)
     assert expected_discount == actual_discount
예제 #9
0
    def test_calculate_totals_for_BuynGetm(self):
        item_1, price_1, quantity_1 = Item("an_item_1"), 100.0, 20
        item_2, price_2, quantity_2 = Item("an_item_2"), 100.0, 20
        quantity_to_add_to_cart_1 = 4
        quantity_to_add_to_cart_2 = 4
        Catalogue().clear_catalogue()
        Catalogue().add_item(item_1, price_1, quantity_1)
        Catalogue().add_item(item_2, price_2, quantity_2)
        Offers().clear_offers()
        an_offer = BuynGetmOffer("b1", 3, 1, item_1)
        Offers().add_offer(an_offer)

        expected_totals = 700.0

        cart = Cart()
        cart.add_item(item_1, quantity_to_add_to_cart_1)
        cart.add_item(item_2, quantity_to_add_to_cart_2)

        actual_total = cart.calculate_totals()
        assert actual_total == expected_totals
    def __init__(self, offer_name, n, x):
        if (Offers().show_offers()) == 0  and offer_name in [offer.offer_name for offer in Offers().show_offers()]:
            raise ValueError("Offer with the same name already exists")

        if n < len(x):
            raise ValueError("Offer can never be applied, as not enough items to apply on")

        self.offer_name = offer_name
        self._price = lambda item: Catalogue().get_price(item)

        self._n = n
        self._X = sorted(x, key=self._price, reverse=True)
예제 #11
0
    def test_calculate_percent_discount_on_two_items(self):
        item_1, price_1, quantity_1 = Item("an_item_1"), 100.0, 20
        item_2, price_2, quantity_2 = Item("an_item_2"), 100.0, 20
        quantity_to_add_to_cart_1 = 2
        quantity_to_add_to_cart_2 = 2
        Catalogue().clear_catalogue()
        Catalogue().add_item(item_1, price_1, quantity_1)
        Catalogue().add_item(item_2, price_2, quantity_2)
        Offers().clear_offers()
        an_offer = PercentOffer("p1", 10, item_1)
        another_offer = PercentOffer("p2", 20, item_2)
        Offers().add_offer(an_offer)
        Offers().add_offer(another_offer)

        expected_discount = 60.0

        cart = Cart()
        cart.add_item(item_1, quantity_to_add_to_cart_1)
        cart.add_item(item_2, quantity_to_add_to_cart_2)
        actual_discount = cart.calculate_discount()
        assert actual_discount == expected_discount
예제 #12
0
class TestCatalogue(unittest.TestCase):
    catalogue = Catalogue()

    def test_add_an_item_to_catalogue(self):
        first_item, price, quantity = Item("FirstItem"), 2.0, 10
        self.catalogue.add_item(first_item, price, quantity)
        assert first_item in self.catalogue.show_items()
        assert price == self.catalogue.show_items()[first_item][0]
        assert quantity == self.catalogue.show_items()[first_item][1]

    def test_there_is_only_one_catalogue(self):
        an_item, price, quantity = Item("Item1"), 2.0, 10
        catalogue1 = Catalogue()
        catalogue1.add_item(an_item, price, quantity)
        catalogue2 = Catalogue()
        assert an_item in catalogue2.show_items()

    def add_two_items_in_catalogue(self):
        first_item, price1, quantity1 = Item("I1"), 2.0, 10
        second_item, price2, quantity2 = Item("I2"), 3.0, 20
        self.catalogue.add_item(first_item, price1, quantity1)
        self.catalogue.add_item(second_item, price2, quantity2)
        assert first_item in self.catalogue.show_items()
        assert second_item in self.catalogue.show_items()

    def remove_some_quantity_of_an_item_from_catalogue(self):
        item, price, quantity = Item("Item"), 2.0, 10
        self.catalogue.add_item(item, price, quantity)
        if item in self.catalogue.show_items():
            self.catalogue.remove_item(item, 4)
        assert self.catalogue.show_items()[item][1] == 6

    def remove_all_quantity_of_an_item_from_catalogue(self):
        an_item, price, quantity = Item("AnItem"), 2.0, 10
        self.catalogue.add_item(an_item, price, quantity)
        if an_item in self.catalogue.show_items():
            self.catalogue.remove_item(an_item, 10)
        assert self.catalogue.show_items()[an_item][1] == 0

    def add_more_quantity_without_adding_price(self):
        item, price, quantity = Item("Item"), 2.0, 10
        self.catalogue.add_item(item, price, quantity)
        additional_quantity = 10
        self.catalogue.add_existing_item(
            item, additional_quantity=additional_quantity)
        assert self.catalogue.show_items()[item][1] == 20
 def get_discount_and_remaining_items(self, items):
     """
     gets the discount by applying this offer once on the items
     ---
     Params:
         items: all items along with their quantity e.g. {item1: quantity1, item2: quantity2} where item1, item2 are of type Item, and quantity1, quantity2 are of type int
     ---
     Returns:
         discount on single application of this offer, and remaining items on which discount is not applied
     """
     discount = 0.00
     if self._item in items and items[self._item] >= self._n + self._m:
         item_price = Catalogue().get_price(self._item)
         discount = item_price
         items[self._item] -= (self._n + self._m)
         if items[self._item] == 0:
             del items[self._item]
     return discount, items
예제 #14
0
 def calculate_sub_total(self):
     sub_total = 0.0
     for item in self._items:
         sub_total += Catalogue().show_items()[item][0] * self._items[item]
     return Utility.round_up(sub_total, 2)
예제 #15
0
 def __init__(self):
     self._items = {}
     self._catalogue = Catalogue()
     self._sub_total = 0.0
     self._discount = 0.0
예제 #16
0
 def test_there_is_only_one_catalogue(self):
     an_item, price, quantity = Item("Item1"), 2.0, 10
     catalogue1 = Catalogue()
     catalogue1.add_item(an_item, price, quantity)
     catalogue2 = Catalogue()
     assert an_item in catalogue2.show_items()
예제 #17
0
    def setup(self):
        Catalogue().clear_catalogue()
        Offers().clear_offers()
        self.baked_bean = Item("BakedBean")
        self.sardines = Item("Sardines")
        self.biscuits = Item("Biscuits")
        self.shampoo_small = Item("Shampoo(Small)")
        self.shampoo_medium = Item("Shampoo (Medium)")
        self.shampoo_large = Item("Shampoo (Large)")

        catalogue = Catalogue()
        catalogue.add_item(self.baked_bean, 0.99, 100)
        catalogue.add_item(self.sardines, 1.89, 100)
        catalogue.add_item(self.biscuits, 1.20, 100)
        catalogue.add_item(self.shampoo_small, 2.00, 100)
        catalogue.add_item(self.shampoo_medium, 2.50, 100)
        catalogue.add_item(self.shampoo_large, 3.50, 100)

        baked_bean_offer = BuynGetmOffer("bakedBean2For1", 2, 1,
                                         self.baked_bean)
        sardines_offer = PercentOffer("Sardines25", 25, self.sardines)
        shampoo_offer = BuynOfXOffer(
            "ShampooSet3", 3,
            {self.shampoo_small, self.shampoo_medium, self.shampoo_large})
        Offers().add_offer(baked_bean_offer)
        Offers().add_offer(sardines_offer)
        Offers().add_offer(shampoo_offer)