from otree.api import Currency as c, currency_range from otree.models import player from ._builtin import Page, WaitPage from .models import Constants, Player from .models import BasePlayer from . import models import math import random class Welcome(Page): def is_displayed(self): return self.round_number == 1 def vars_for_template(self): self.player.language = self.session.config['language'] return dict(treat=self.player.treat, language=self.player.language) def before_next_page(self): # initialize dynamic mto demand self.player.language = self.session.config['language'] self.player.demand_method() self.player.treatment_method() rand = self.player.id_in_group self.player.treat = self.player.participant.vars['treatment'][rand-1] class Anleitung(Page): def is_displayed(self): return self.round_number == 1 def vars_for_template(self): return dict(treat=self.player.treat, language=self.player.language) class Bestellung(Page): def is_displayed(self): return self.round_number <= Constants.num_rounds form_model = 'player' timeout_seconds = 180 def vars_for_template(self): self.player.language = self.session.config['language'] if self.player.language == 1: timer_text = 'Remaining time on this page:' else: timer_text = 'Verbleibende Zeit auf dieser Seite:' demand1 = self.player.participant.vars['demand'][self.round_number - 1] demand2 = self.player.participant.vars['demand'][self.round_number] demand3 = self.player.participant.vars['demand'][self.round_number + 1] demand4 = self.player.participant.vars['demand'][self.round_number + 2] demand5 = self.player.participant.vars['demand'][self.round_number + 3] display_lt = self.player.lead_time bo = self.player.open_order fgi = self.player.on_hand wip = self.player.wip c_bo = self.player.c_bo c_fgi = self.player.c_fgi c_wip = self.player.c_wip profit = self.player.payoff cum_wip = self.player.cum_wip cum_bo = self.player.cum_bo cum_fgi = self.player.cum_fgi round_umsatz = self.player.round_umsatz cum_umsatz = self.player.cum_umsatz round_payoff = self.player.round_payoff delivered = self.player.delivered_customer # ORDER COSTS ALWAYS IN SAME PERIOD if self.player.period == 0: order = 0 c_order = " 0,00" cum_order = " 0,00" else: order = self.player.in_round(self.round_number - 1).order c_order = self.player.in_round(self.round_number - 1).c_order cum_order = self.player.in_round(self.round_number - 1).cum_order return dict(p1=self.player.period + 1, d1=demand1, p2=self.player.period + 2, d2=demand2, p3=self.player.period + 3, d3=demand3, p4=self.player.period + 4, d4=demand4, p5=self.player.period + 5, d5=demand5, p6=self.player.period + 6, # d6=demand6, p7=self.player.period + 7, # d7=demand7, p8=self.player.period + 8, # d8=demand8, display_lt=int(display_lt), bo=bo, fgi=fgi, wip=wip, c_bo=c_bo, c_fgi=c_fgi, c_wip=c_wip, c_order=c_order, cum_bo=cum_bo, cum_fgi=cum_fgi, cum_wip=cum_wip, cum_order=cum_order, round_umsatz=round_umsatz, cum_umsatz=cum_umsatz, round_payoff=round_payoff, order=order, delivered=delivered, profit=profit, language=self.player.language, ) form_fields = ['order', 'estimated_lt1'] def before_next_page(self): # test over if self.round_number > Constants.test_round_length: self.player.in_round(self.round_number + 1).test_over = 1 # take treatment var to next round self.player.in_round(self.round_number + 1).treat = self.player.treat # BALANCE EQUATIONS s_cap = Constants.supplier_cap self.player.in_round(self.round_number + 1).wip = max(self.player.order + self.player.wip - s_cap, 0) self.player.in_round(self.round_number + 1).open_order = \ max(self.player.open_order + self.player.original_demand[self.round_number - 1] - self.player.on_hand - min( self.player.order + self.player.wip, s_cap), 0) self.player.in_round(self.round_number + 1).on_hand = \ max(min(self.player.on_hand + self.player.order + self.player.wip, self.player.on_hand + s_cap) - self.player.original_demand[self.round_number - 1] - self.player.open_order, 0) self.player.in_round(self.round_number + 1).delivered_customer = \ min(self.player.original_demand[self.round_number - 1] + self.player.open_order, min(self.player.order + self.player.wip + self.player.on_hand, s_cap + self.player.on_hand)) # CALC LEAD TIME - FIX AND VAR if self.player.treat == 'var' or self.player.treat == 'mto_var': lt = (self.player.in_round( self.round_number + 1).wip + 9) / s_cap # 9 is average order / 10 is capcaity of supplier lt = math.ceil(lt) int(lt) self.player.in_round(self.round_number + 1).lead_time = lt else: self.player.in_round(self.round_number + 1).lead_time = 1 # CALC COSTS self.player.in_round(self.round_number + 1).c_bo = self.player.in_round( self.round_number + 1).open_order * Constants.costs_bo # calc bo costs self.player.in_round(self.round_number + 1).c_fgi = self.player.in_round( self.round_number + 1).on_hand * Constants.costs_fgi # fgi costs self.player.in_round(self.round_number + 1).c_wip = self.player.in_round( self.round_number + 1).wip * Constants.costs_wip # wip costs self.player.c_order = self.player.order * Constants.costs_order # order costs if self.round_number > 1: self.player.cum_order = self.player.in_round( self.round_number - 1).cum_order + self.player.c_order # cum order costs else: self.player.cum_order = self.player.c_order # CUM COSTS & Payoff # if self.round_number > 0: self.player.in_round(self.round_number + 1).cum_fgi = self.player.cum_fgi + self.player.in_round( self.round_number + 1).c_fgi self.player.in_round(self.round_number + 1).cum_bo = self.player.cum_bo + self.player.in_round( self.round_number + 1).c_bo self.player.in_round(self.round_number + 1).cum_wip = self.player.cum_wip + self.player.in_round( self.round_number + 1).c_wip self.player.in_round(self.round_number + 1).round_payoff = (self.player.in_round( self.round_number + 1).delivered_customer * Constants.profit) - \ self.player.c_order - \ self.player.in_round(self.round_number + 1).c_bo - \ self.player.in_round(self.round_number + 1).c_fgi - \ self.player.in_round(self.round_number + 1).c_wip self.player.in_round(self.round_number + 1).payoff = self.player.payoff + self.player.in_round( self.round_number + 1).round_payoff self.player.in_round(self.round_number + 1).round_umsatz = self.player.in_round( self.round_number + 1).delivered_customer * Constants.profit self.player.in_round(self.round_number + 1).cum_umsatz = self.player.cum_umsatz + self.player.in_round( self.round_number + 1).delivered_customer * Constants.profit # MTO UPDATE KUNDENAUFTRÄGE if self.player.treat == "mto_fix" or self.player.treat == "mto_var": iterate_order = self.player.order for i in range(self.round_number - 1, len(self.player.participant.vars['demand'])): self.player.participant.vars['demand'][i] = self.player.participant.vars['demand'][i] - iterate_order if self.player.participant.vars['demand'][i] < 0: iterate_order = abs(self.player.participant.vars['demand'][i]) self.player.participant.vars['demand'][i] = 0 else: break # NEXT ROUND increment player period self.player.in_round(self.round_number + 1).period = self.player.period + 1 # TIME OUT if self.timeout_happened: self.player.order = 0 class TestRound(Page): def vars_for_template(self): demand1 = self.player.participant.vars['demand'][self.round_number - 1] demand2 = self.player.participant.vars['demand'][self.round_number] demand3 = self.player.participant.vars['demand'][self.round_number + 1] demand4 = self.player.participant.vars['demand'][self.round_number + 2] demand5 = self.player.participant.vars['demand'][self.round_number + 3] display_lt = self.player.lead_time bo = self.player.open_order fgi = self.player.on_hand wip = self.player.wip c_bo = self.player.c_bo c_fgi = self.player.c_fgi c_wip = self.player.c_wip profit = self.player.payoff cum_wip = self.player.cum_wip cum_bo = self.player.cum_bo cum_fgi = self.player.cum_fgi round_umsatz = self.player.round_umsatz cum_umsatz = self.player.cum_umsatz round_payoff = self.player.round_payoff delivered = self.player.delivered_customer # ORDER COSTS ALWAYS IN SAME PERIOD if self.player.period == 0: order = 0 c_order = 0 cum_order = 0 else: order = self.player.in_round(self.round_number - 1).order c_order = self.player.in_round(self.round_number - 1).c_order cum_order = self.player.in_round(self.round_number - 1).cum_order return dict(p1=self.player.period + 1, d1=demand1, p2=self.player.period + 2, d2=demand2, p3=self.player.period + 3, d3=demand3, p4=self.player.period + 4, d4=demand4, p5=self.player.period + 5, d5=demand5, p6=self.player.period + 6, # d6=demand6, p7=self.player.period + 7, # d7=demand7, p8=self.player.period + 8, # d8=demand8, display_lt=int(display_lt), bo=bo, fgi=fgi, wip=wip, c_bo=c_bo, c_fgi=c_fgi, c_wip=c_wip, c_order=c_order, cum_bo=cum_bo, cum_fgi=cum_fgi, cum_wip=cum_wip, cum_order=cum_order, round_umsatz=round_umsatz, cum_umsatz=cum_umsatz, round_payoff=round_payoff, order=order, delivered=delivered, profit=profit ) def is_displayed(self): return self.round_number <= Constants.tests # _round_length and self.round_number % Constants.tests == 1 class Beginn(Page): form_model = 'player' timeout_seconds = 30 def vars_for_template(self): if self.player.language == 1: timer_text = 'Remaining time on this page:' else: timer_text = 'Verbleibende Zeit auf dieser Seite:' def is_displayed(self): return self.round_number == Constants.test_round_length + 1 def before_next_page(self): if self.round_number % 3 == 1 and self.round_number > 1: # ------IF LAST ROUND OF TEST RESET EVERYTHING--------- self.player.test_over = 1 self.player.in_round(self.round_number).lead_time = 1 self.player.in_round(self.round_number).open_order = 0 # BO self.player.in_round(self.round_number).on_hand = 0 # Lagerbestand self.player.in_round(self.round_number).wip = 0 # Lagerbestand self.player.in_round(self.round_number).c_wip = 0 # work in process self.player.in_round(self.round_number).c_fgi = 0 # finished goods inventory self.player.in_round(self.round_number).c_bo = 0 # back order costs self.player.in_round(self.round_number - 1).c_order = 0 # bestelskosten von vor runde self.player.in_round(self.round_number).payoff = 0 # self.player.in_round(self.round_number).order = 0 self.player.in_round(self.round_number).cum_bo = 0 self.player.in_round(self.round_number).cum_wip = 0 self.player.in_round(self.round_number).cum_fgi = 0 self.player.in_round(self.round_number - 1).cum_order = 0 self.player.in_round(self.round_number).cum_umsatz = 0 self.player.in_round(self.round_number).round_payoff = 0 self.player.in_round(self.round_number).round_umsatz = 0 self.player.in_round(self.round_number).delivered_customer = 0 self.player.in_round(self.round_number).period = 0 # RESET DEMAND FOR MTO temp_demand = [ # Kundennachfrage 9, 3, 15, # TEST 9, 3, 12, 12, 3, 12, 12, 12, 12, 9, 12, 6, 12, 12, 12, 3, 12, 12, 12, 3, 9, 6, 6, 9, 3, 9, # EXP DEMAND 15, 9, 6, 15, 6, 3, 12, 12, 3, 12, 12] # weiterführender demand for i in range(0, len(temp_demand)): self.player.participant.vars['demand'][i] = temp_demand[i] class Results(Page): form_model = 'player' def is_displayed(self): return self.round_number == Constants.num_rounds def vars_for_template(self): auszahlung = self.player.in_round(self.round_number - 1).payoff / 10 taler_gewinn = self.player.in_round(self.round_number - 1).payoff auszahlung = math.ceil(auszahlung) if auszahlung < 4: auszahlung = 0 self.player.payoff = auszahlung + 4 return dict(auszahlung=self.player.payoff, taler_gewinn=taler_gewinn) form_fields = ['email', 'debriefing'] class FinalEnd(Page): form_model = 'player' def is_displayed(self): return self.round_number == Constants.num_rounds class Risk(Page): form_model = 'player' def is_displayed(self): return self.round_number == Constants.num_rounds form_fields = ['risk', 'importance_lt', 'importance_cap', 'importance_demand', 'importance_costs', 'importance_supplier', 'jobtitel', 'jobexp', 'joborder'] class Ende(Page): def is_displayed(self): return self.round_number == Constants.num_rounds def vars_for_template(self): auszahlung = self.player.in_round(self.round_number - 1).payoff / 100 taler_gewinn = self.player.in_round(self.round_number - 1).payoff auszahlung = math.ceil(auszahlung) if auszahlung < 4: auszahlung = 0 self.player.payoff = auszahlung + 4 self.player.language = self.session.config['language'] return dict(auszahlung=self.player.payoff, taler_gewinn=taler_gewinn,language=self.player.language) page_sequence = [Welcome, Anleitung, Beginn, TestRound, Ende, Risk, Results, FinalEnd, Bestellung ]