diff --git a/app/ShyBadger/src/services/BasketService.py b/app/ShyBadger/src/services/BasketService.py index 4eae938..566f1bf 100644 --- a/app/ShyBadger/src/services/BasketService.py +++ b/app/ShyBadger/src/services/BasketService.py @@ -16,7 +16,7 @@ class BasketService: def total(self, sessionID: str) -> int: items = self.baskets[sessionID] - prices = self.dealsService.getPrices() + prices = self.dealsService.get_items_with_final_prices(items) return sum(prices) def scan(self, session_id: str, itemId) -> None: diff --git a/app/ShyBadger/src/services/DealsService.py b/app/ShyBadger/src/services/DealsService.py index d1e10a1..7ffa568 100644 --- a/app/ShyBadger/src/services/DealsService.py +++ b/app/ShyBadger/src/services/DealsService.py @@ -4,34 +4,51 @@ import math class DealsService: - deals = [] + # deals and promotions are global and therefor class vars instead of instance vars + deals = dict() + promotions = defaultdict(list) + def __init__(self) -> None: - pass - - def get_prices(self) -> list: - return [0] + self.promotions["A0001"].append("two_for_one") + self.deals["two_for_one"] = DealsService.two_for_one_deal - def _round_up(self, val: float): - return math.ceil(val*100)/100 - def two_for_one_deal(self, items) -> list: - new_items = [] + def get_items_with_final_prices(self, items) -> list: groups = defaultdict(list) for obj in items: groups[obj.id].append(obj) for group in groups.values(): - for deal in self.deals: - # the deals do not stack, the first deal in the list of deals is taken, - # ideally for the customer all deals would be calculated and the maximum value selected - # not implemented for time reasons - if deal(group): + # the deals do not stack, the first deal in the list of deals is taken, + # ideally for the customer all deals would be calculated and the maximum value selected + # not implemented for time reasons + + for promotion in self.promotions.get(group[0].id): + # iterate over all promotions for this item + # lookup the higher order function that is associated with this deal name + # apply the function to the item group + # if the deal was applied to the group of items break and move on to the next item group + # this avoids discout stacking + if self.deals[promotion](group): break return [item for group in groups.values() for item in group] - def two_for_one_deal(self, group): + @staticmethod + def two_for_one_deal(group): '''' applies deal onto item group in place ''' + # ideally would be an object implementing a "Deal"-interface, + # which has 2 functions, deal_is_applicable() and apply_deal() + def _round_up(self, val: float): + return math.ceil(val*100)/100 + + # could be compressed + # not done since this would be the 2 different functions in the above mentioned interface + deal_is_applicable = False + if len(group) >= 2: + deal_is_applicable = True + for i in range(len(group)//2): - group[i].price = self._round_up(group[i].price / 2) \ No newline at end of file + group[i].price = _round_up(group[i].price / 2) + return deal_is_applicable \ No newline at end of file diff --git a/app/ShyBadger/src/services/ProductService.py b/app/ShyBadger/src/services/ProductService.py index bfc4574..5f79515 100644 --- a/app/ShyBadger/src/services/ProductService.py +++ b/app/ShyBadger/src/services/ProductService.py @@ -1,13 +1,16 @@ -from collections import defaultdict - from src.models import Item class ProductService: - prices = None + # prices are global, sheduled function to refresh prices periodically + # could save ressources under high load + prices = dict() def __init__(self) -> None: - self.prices = defaultdict() + # placeholder data + self.prices["A0001"] = 12.99 + self.prices["A0002"] = 3.99 + def get_item_from_id(self, item_id: str) -> Item: return Item(id=item_id, price=self.prices.get(item_id))