from otree.api import * doc = """ Takeout_foodwaste """ def read_csv(): import csv with open (__name__ + '/catalog_1.csv', encoding='utf-8-sig') as f: rows = [row for row in csv.DictReader(f)] for row in rows: # all values in CSV are string unless you convert them row['unit_price'] = float(row['unit_price']) row['image_path'] = 'dishes/{}.jpeg'.format(row['image_jpeg']) # print(rows) return rows def read_csv_2(): import csv with open (__name__ + '/catalog_2.csv', encoding='utf-8-sig') as f: rows2 = [row for row in csv.DictReader(f)] for row2 in rows2: # all values in CSV are string unless you convert them row2['unit_price_2'] = float(row2['unit_price_2']) row2['image_path_2'] = 'dishes_2/{}.jpeg'.format(row2['image_jpeg_2']) # print(rows) return rows2 class C(BaseConstants): NAME_IN_URL = 'shop_takeout' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 PRODUCTS = read_csv() # SKU = 'stock keeping unit' = product ID PRODUCTS_DICT = {row['sku']: row for row in PRODUCTS} PRODUCTS_2 = read_csv_2() PRODUCTS_DICT_2 = {row2['sku2']: row2 for row2 in PRODUCTS_2} class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): total_price = models.FloatField(initial=0) discount = models.IntegerField(initial=0) final_price = models.FloatField(initial=0) # final price after discount restaurant = models.StringField(initial="0") class Item(ExtraModel): player = models.Link(Player) sku = models.StringField() name = models.StringField() quantity = models.IntegerField() unit_price = models.FloatField() def total_price(item: Item): return item.quantity * item.unit_price def to_dict(item: Item): return dict( sku=item.sku, name=item.name, quantity=item.quantity, total_price=total_price(item), ) def live_method(player: Player, data): if 'sku' in data: sku = data['sku'] delta = data['delta'] product = C.PRODUCTS_DICT[sku] matches = Item.filter(player=player, sku=sku) if matches: [item] = matches item.quantity += delta if item.quantity <= 0: item.delete() else: if delta > 0: Item.create( player=player, quantity=delta, sku=sku, name=product['name'], unit_price=product['unit_price'], ) items = Item.filter(player=player) item_dicts = [to_dict(item) for item in items] player.total_price = (sum([total_price(item) for item in items])) if 100 <= player.total_price < 200: # threshold amount, to be modified player.discount = 10 # first discount, to be modified elif player.total_price >=200: # threshold amount, to be modified player.discount = 30 # second discount, to be modified else: player.discount = 0 player.final_price = player.total_price - player.discount # print(player.total_price, player.discount, player.final_price) return {player.id_in_group: dict(items=item_dicts, sum=player.total_price, discount=player.discount, final_price=player.final_price)} def live_method_2(player: Player, data): if 'sku' in data: sku = data['sku'] delta = data['delta'] product = C.PRODUCTS_DICT_2[sku] matches = Item.filter(player=player, sku=sku) if matches: [item] = matches item.quantity += delta if item.quantity <= 0: item.delete() else: if delta > 0: Item.create( player=player, quantity=delta, sku=sku, name=product['name_2'], unit_price=product['unit_price_2'], ) items = Item.filter(player=player) item_dicts = [to_dict(item) for item in items] player.total_price = sum([total_price(item) for item in items]) if 100 <= player.total_price < 200: # threshold amount, to be modified player.discount = 10 # first discount, to be modified elif player.total_price >=200: # threshold amount, to be modified player.discount = 30 # second discount, to be modified else: player.discount = 0 player.final_price = player.total_price - player.discount return {player.id_in_group: dict(items=item_dicts, sum=player.total_price, discount=player.discount, final_price=player.final_price)} #PAGES class SelectRestaurant(Page): form_fields = ["restaurant"] form_model = "player" @staticmethod def vars_for_template(player: Player): # print(dict(items=Item.filter(player=player))) return dict(items=Item.filter(player=player)) class ShopPage_1(Page): @staticmethod def is_displayed(player: Player): return player.restaurant == str(1) live_method = live_method class ShopPage_2(Page): @staticmethod def is_displayed(player: Player): return player.restaurant == str(2) live_method = live_method_2 class Confirm(Page): @staticmethod def vars_for_template(player: Player): return dict(items=Item.filter(player=player)) class Results(Page): @staticmethod def vars_for_template(player: Player): return dict(items=Item.filter(player=player)) page_sequence = [ SelectRestaurant, ShopPage_1, ShopPage_2, Results ]