Initial Commit
@@ -0,0 +1,2 @@
|
||||
from django.contrib import admin
|
||||
from .backend import *
|
||||
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class MygameConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'mygame'
|
||||
@@ -0,0 +1,163 @@
|
||||
from django.db import models
|
||||
from polymorphic.models import PolymorphicModel
|
||||
|
||||
# from .company import Company
|
||||
from .worker import Worker
|
||||
from .offer import Offer
|
||||
from .order import Order
|
||||
|
||||
|
||||
# Action und erbende Klassen
|
||||
class Action(PolymorphicModel):
|
||||
name = models.CharField(default="random Action", max_length=20)
|
||||
actionmaker = models.ForeignKey("Company", default=1, on_delete=models.CASCADE)
|
||||
|
||||
def execute(self):
|
||||
pass
|
||||
|
||||
def cancel(self):
|
||||
pass
|
||||
|
||||
def addActionToCompany(self):
|
||||
self.actionmaker.addAction(self)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class ActionEmploy(Action):
|
||||
worker = models.ForeignKey(Worker, default=1, on_delete=models.CASCADE)
|
||||
|
||||
@classmethod
|
||||
def create(cls, worker, actionmaker):
|
||||
# klassenobject erstellen
|
||||
name = "Hiring " + worker.name
|
||||
action = cls(name=name, worker=worker, actionmaker=actionmaker)
|
||||
action.save()
|
||||
# worker von market entferenen und action zu company hinzufügen
|
||||
actionmaker.removeFromWorkermarket(worker)
|
||||
action.addActionToCompany()
|
||||
return action
|
||||
|
||||
def execute(self):
|
||||
self.worker.setStatus(1)
|
||||
self.worker.save()
|
||||
self.actionmaker.workers.add(self.worker)
|
||||
# Arbeiter zu Company hinzufügen
|
||||
|
||||
def cancel(self):
|
||||
self.actionmaker.addToWorkermarket(self.worker)
|
||||
|
||||
|
||||
class ActionUnemploy(Action):
|
||||
worker = models.ForeignKey(Worker, null=True, blank=True, on_delete=models.CASCADE)
|
||||
|
||||
@classmethod
|
||||
def create(cls, worker, actionmaker):
|
||||
# klassenobject erstellen
|
||||
name = "Firing " + worker.name
|
||||
action = cls(name=name, worker=worker, actionmaker=actionmaker)
|
||||
action.save()
|
||||
# workerstatus anpassen und action zu company hinzufügen
|
||||
actionmaker.workers.remove(worker)
|
||||
action.addActionToCompany()
|
||||
return action
|
||||
|
||||
def execute(self):
|
||||
pass # self.worker.delete() hier das delete noch machbar machen
|
||||
|
||||
def cancel(self):
|
||||
self.actionmaker.workers.add(self.worker)
|
||||
|
||||
|
||||
class ActionOffer(Action):
|
||||
order = models.ForeignKey(Order, default=1, on_delete=models.CASCADE)
|
||||
amount = models.IntegerField(default=0)
|
||||
|
||||
@classmethod
|
||||
def create(cls, order, amount, actionmaker):
|
||||
# klassenobject erstellen
|
||||
name = "Offer for " + order.name
|
||||
action = cls(
|
||||
name=name,
|
||||
order=order,
|
||||
amount=amount,
|
||||
actionmaker=actionmaker,
|
||||
)
|
||||
action.save()
|
||||
# order von market entfernen und action zu company hinzufügen
|
||||
action.addActionToCompany()
|
||||
return action
|
||||
|
||||
def execute(self):
|
||||
self.order.setStatus(1)
|
||||
self.order.save()
|
||||
offer = Offer.objects.create(
|
||||
company=self.actionmaker, amount=self.amount, order=self.order
|
||||
)
|
||||
self.order.offers.add(offer)
|
||||
# Angebot einer Order auf OrderMarket vorlegen
|
||||
|
||||
def cancel(self):
|
||||
# bleibt leer actually
|
||||
pass
|
||||
|
||||
|
||||
class ActionCancelOrder(Action):
|
||||
order = models.ForeignKey(Order, default=1, on_delete=models.CASCADE)
|
||||
|
||||
@classmethod
|
||||
def create(cls, order, actionmaker):
|
||||
# klassenobject erstellen
|
||||
name = "Cancel " + order.name
|
||||
action = cls(
|
||||
name=name,
|
||||
order=order,
|
||||
actionmaker=actionmaker,
|
||||
)
|
||||
action.save()
|
||||
# action zu company hinzufügen
|
||||
action.addActionToCompany()
|
||||
return action
|
||||
|
||||
def execute(self):
|
||||
self.actionmaker.calculateCustomerSatisfaction(-30)
|
||||
self.order.cancelOrder()
|
||||
self.order.delete()
|
||||
|
||||
def cancel(self):
|
||||
# bleibt leer actually
|
||||
pass
|
||||
|
||||
|
||||
class ActionTrain(Action):
|
||||
worker = models.ForeignKey(Worker, null=True, blank=True, on_delete=models.CASCADE)
|
||||
trainskill = models.CharField(default="empty", max_length=50)
|
||||
cost = models.IntegerField(default=1000)
|
||||
|
||||
@classmethod
|
||||
def create(cls, worker, trainskill, actionmaker):
|
||||
# klassenobject erstellen
|
||||
name = "Train Worker " + worker.name
|
||||
action = cls(
|
||||
name=name,
|
||||
worker=worker,
|
||||
trainskill=trainskill,
|
||||
actionmaker=actionmaker,
|
||||
)
|
||||
# worker locken status 3
|
||||
worker.setStatus(3)
|
||||
action.save()
|
||||
# action zu company hinzufügen
|
||||
action.addActionToCompany()
|
||||
return action
|
||||
|
||||
def execute(self):
|
||||
# Arbeiter in bestimmtem Skill verbesser und für eine runde locken
|
||||
self.worker.improveAttribute(attribute=self.trainskill, amount=10)
|
||||
self.worker.setLockedRounds(1)
|
||||
# trainingskosten zahlen
|
||||
self.actionmaker.addProfit(-self.cost)
|
||||
|
||||
def cancel(self):
|
||||
self.worker.setStatus(1)
|
||||
@@ -0,0 +1,46 @@
|
||||
from django.db import models
|
||||
import random
|
||||
|
||||
|
||||
# attributeset für worker skills und order workload
|
||||
class AttributeSet(models.Model):
|
||||
experience = models.IntegerField(default=10)
|
||||
reliability = models.IntegerField(default=10)
|
||||
python = models.IntegerField(default=10)
|
||||
javascript = models.IntegerField(default=10)
|
||||
cpp = models.IntegerField(default=10)
|
||||
management = models.IntegerField(default=10)
|
||||
|
||||
def __str__(self):
|
||||
return "AttributeSet"
|
||||
|
||||
@classmethod
|
||||
def createRandom(cls, median):
|
||||
attributelist = []
|
||||
for j in range(6):
|
||||
randnumber = round(random.uniform(0.5, 1.5) * (median))
|
||||
# if randnumber > 100:
|
||||
# randnumber = 100
|
||||
attributelist.append(randnumber)
|
||||
attributeset = cls(
|
||||
experience=attributelist[0],
|
||||
reliability=attributelist[1],
|
||||
python=attributelist[2],
|
||||
javascript=attributelist[3],
|
||||
cpp=attributelist[4],
|
||||
management=attributelist[5],
|
||||
)
|
||||
attributeset.save()
|
||||
return attributeset
|
||||
|
||||
def increase(self, amount, attribute):
|
||||
if attribute in [
|
||||
"experience",
|
||||
"reliability",
|
||||
"python",
|
||||
"javascript",
|
||||
"cpp",
|
||||
"management",
|
||||
]:
|
||||
setattr(self, attribute, (getattr(self, attribute) + amount))
|
||||
self.save()
|
||||
@@ -0,0 +1,201 @@
|
||||
from django.db import models
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
import random
|
||||
from mygame.backend.event import SpecialOrder
|
||||
from .worker import Worker
|
||||
from .order import Order
|
||||
from .event import Event
|
||||
from .action import *
|
||||
|
||||
# ACTION NOCH IMPORTIEREN?
|
||||
|
||||
|
||||
# company die jeder spieler steuert
|
||||
class Company(models.Model):
|
||||
name = models.CharField(default="A company", max_length=20)
|
||||
user = models.CharField(default="default User", max_length=20)
|
||||
customersatisfaction = models.IntegerField(
|
||||
default=100, validators=[MinValueValidator(0), MaxValueValidator(100)]
|
||||
)
|
||||
workersatisfaction = models.IntegerField(
|
||||
default=100, validators=[MinValueValidator(0), MaxValueValidator(100)]
|
||||
)
|
||||
money = models.IntegerField(default=100000)
|
||||
workermarket = models.ManyToManyField(Worker, related_name="workermarket")
|
||||
actions = models.ManyToManyField("Action", blank=True)
|
||||
workers = models.ManyToManyField(Worker, blank=True, related_name="workers")
|
||||
orders = models.ManyToManyField(Order, blank=True)
|
||||
events = models.ManyToManyField(Event, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def addProfit(self, profit):
|
||||
self.money += profit
|
||||
self.save()
|
||||
|
||||
def clearEvents(self):
|
||||
for event in self.events.all():
|
||||
# wenn specialorder ignoriert wurde -> penalty und removen (nicht löschen)
|
||||
if isinstance(event, SpecialOrder):
|
||||
for order in self.orders.all():
|
||||
if order.specialorder == event:
|
||||
event.handle(order=order, company=self, handle=False)
|
||||
self.events.remove(event)
|
||||
else:
|
||||
event.delete()
|
||||
|
||||
def addEvent(self, event):
|
||||
self.events.add(event)
|
||||
self.save()
|
||||
|
||||
def getEvent(self, eventnumber, direction):
|
||||
# wenn keine events gib leeres event
|
||||
if not self.events.exists():
|
||||
event = Event.createEmpty()
|
||||
return (event, eventnumber)
|
||||
# bei klick auf eventbutton immer erstes event zeigen
|
||||
if eventnumber == 0 and direction == "default":
|
||||
event = self.events.order_by("id")[eventnumber]
|
||||
elif direction == "previous":
|
||||
# wenn bei erstem element zurück dann letztes element zeigen
|
||||
if eventnumber <= 0:
|
||||
eventnumber = self.events.count() - 1
|
||||
event = self.events.order_by("id")[eventnumber]
|
||||
else:
|
||||
eventnumber -= 1
|
||||
event = self.events.order_by("id")[eventnumber]
|
||||
elif direction == "next":
|
||||
# wenn bei letztem element weiter dann erstes anzeigen
|
||||
if eventnumber >= (self.events.count() - 1):
|
||||
eventnumber = 0
|
||||
event = self.events.order_by("id")[eventnumber]
|
||||
else:
|
||||
eventnumber += 1
|
||||
event = self.events.order_by("id")[eventnumber]
|
||||
return (event, eventnumber)
|
||||
|
||||
def addAction(self, action):
|
||||
for existingaction in self.actions.all():
|
||||
if action.name == existingaction.name:
|
||||
self.cancelAction(existingaction.id)
|
||||
self.actions.add(action)
|
||||
|
||||
def deleteAction(self, action):
|
||||
self.actions.delete(action)
|
||||
|
||||
def calculateCustomerSatisfaction(self, number):
|
||||
calc = self.customersatisfaction
|
||||
calc += number
|
||||
if calc < 0:
|
||||
calc = 0
|
||||
if calc > 100:
|
||||
calc = 100
|
||||
self.customersatisfaction = calc
|
||||
self.save()
|
||||
|
||||
def calculateWorkerSatisfaction(self, number):
|
||||
if (self.workersatisfaction + number) > 100:
|
||||
self.workersatisfaction = 100
|
||||
elif (self.workersatisfaction + number) < 0:
|
||||
self.workersatisfaction = 0
|
||||
else:
|
||||
self.workersatisfaction += number
|
||||
self.save()
|
||||
|
||||
def calculateAllWorkersHappyness(self, addhappyness):
|
||||
for worker in self.workers.all():
|
||||
worker.calculateHappyness(addhappyness)
|
||||
|
||||
def paySalary(self):
|
||||
salarysum = 0
|
||||
for worker in self.workers.all():
|
||||
if self.money < salarysum:
|
||||
worker.calculateHappyness(-50)
|
||||
else:
|
||||
salarysum += worker.salary
|
||||
self.money -= salarysum
|
||||
self.save()
|
||||
|
||||
def checkWorkerQuit(self):
|
||||
threshhold = 55
|
||||
for worker in self.workers.all():
|
||||
if worker.happyness <= threshhold:
|
||||
diff = threshhold - worker.happyness
|
||||
randnum = random.randint(1, 100)
|
||||
if 2 * diff > randnum:
|
||||
event = Event.createWorkerQuit(
|
||||
threshhold=threshhold,
|
||||
workername=worker.name,
|
||||
workerhappyness=worker.happyness,
|
||||
)
|
||||
self.addEvent(event)
|
||||
worker.quitJob()
|
||||
|
||||
def calculateOrderWorkload(self):
|
||||
for order in self.orders.all():
|
||||
finished = order.calculateWorkload(self.workersatisfaction)
|
||||
if finished:
|
||||
order.finishOrder(self)
|
||||
event = Event.createOrderFinished(
|
||||
ordername=order.name, profit=str(order.profit)
|
||||
)
|
||||
self.events.add(event)
|
||||
order.delete()
|
||||
elif order.maxRounds == 0:
|
||||
order.cancelOrder()
|
||||
self.calculateCustomerSatisfaction(-30)
|
||||
event = Event.createOrderFailed(ordername=order.name)
|
||||
self.events.add(event)
|
||||
order.delete()
|
||||
|
||||
def addOrder(self, order):
|
||||
self.orders.add(order)
|
||||
|
||||
def deleteOrder(self, order):
|
||||
self.orders.remove(order)
|
||||
|
||||
def addToWorkermarket(self, worker):
|
||||
self.workermarket.add(worker)
|
||||
|
||||
def removeFromWorkermarket(self, worker):
|
||||
self.workermarket.remove(worker)
|
||||
|
||||
def generateWorkermarket(self):
|
||||
self.clearWorkermarket()
|
||||
for x in range(5):
|
||||
worker = Worker.createRandom()
|
||||
self.addToWorkermarket(worker)
|
||||
|
||||
def clearWorkermarket(self):
|
||||
for worker in self.workermarket.all():
|
||||
if worker.status == 0:
|
||||
worker.delete()
|
||||
self.workermarket.clear()
|
||||
|
||||
# actions:
|
||||
def cancelAction(self, id):
|
||||
action = Action.objects.get(id=id)
|
||||
action.cancel()
|
||||
if action:
|
||||
action.delete()
|
||||
|
||||
def actionEmploy(self, worker):
|
||||
act = ActionEmploy.create(worker=worker, actionmaker=self)
|
||||
return act
|
||||
|
||||
def actionUnemploy(self, worker):
|
||||
act = ActionUnemploy.create(worker=worker, actionmaker=self)
|
||||
return act
|
||||
|
||||
def actionOffer(self, order, amount):
|
||||
act = ActionOffer.create(order=order, amount=amount, actionmaker=self)
|
||||
return act
|
||||
|
||||
def actionCancelOrder(self, order):
|
||||
act = ActionCancelOrder.create(order=order, actionmaker=self)
|
||||
return act
|
||||
|
||||
def actionTrain(self, worker, trainskill):
|
||||
act = ActionTrain.create(worker=worker, trainskill=trainskill, actionmaker=self)
|
||||
return act
|
||||
@@ -0,0 +1,147 @@
|
||||
from django.db import models
|
||||
from polymorphic.models import PolymorphicModel
|
||||
import random
|
||||
|
||||
|
||||
# EngineeringModel und erbende Klassen
|
||||
class EngineeringModel(PolymorphicModel):
|
||||
name = models.CharField(default="random EngineeringModel", max_length=30)
|
||||
description = models.CharField(default="random description", max_length=200)
|
||||
pros = models.CharField(default="random pro", max_length=100)
|
||||
cons = models.CharField(default="random con", max_length=100)
|
||||
|
||||
# wird bei zuweisen des models ausgelöst
|
||||
def recalculate(self, order, company):
|
||||
pass
|
||||
|
||||
# wird bei workload berechnung ausgelöst, wenn workermodel nicht ordermodel
|
||||
def penalty(self, worker, order):
|
||||
worker.calculateHappyness(-5)
|
||||
|
||||
def bonus(self, worker, order):
|
||||
pass
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def getPros(self):
|
||||
return self.pros.split(",")
|
||||
|
||||
def getCons(self):
|
||||
return self.cons.split(",")
|
||||
|
||||
|
||||
class ModelV(EngineeringModel):
|
||||
def recalculate(self, order, company):
|
||||
# positives
|
||||
# +10 workerSatisfaction +10 happyness
|
||||
company.calculateAllWorkersHappyness(addhappyness=10)
|
||||
company.calculateWorkerSatisfaction(number=10)
|
||||
# +10 customerSatisfaction
|
||||
company.calculateCustomerSatisfaction(10)
|
||||
# negatives
|
||||
# 1: extra work for SOPrototyp und SOChangeRequirement
|
||||
# +10% workload
|
||||
order.changeWorkload(1.1)
|
||||
|
||||
order.recalculated = True
|
||||
order.save()
|
||||
company.save()
|
||||
|
||||
|
||||
class ModelSpiral(EngineeringModel):
|
||||
def recalculate(self, order, company):
|
||||
# positives
|
||||
# 1: BONUS AUF SOPrototyp UND SOChangeRequirement
|
||||
# +10 customerSatisfaciton
|
||||
company.calculateCustomerSatisfaction(10)
|
||||
|
||||
# negatives
|
||||
# 1: -10 happyness and workersatisfaction
|
||||
company.calculateAllWorkersHappyness(addhappyness=-10)
|
||||
company.calculateWorkerSatisfaction(number=-10)
|
||||
# +10% workload
|
||||
order.changeWorkload(1.1)
|
||||
|
||||
order.recalculated = True
|
||||
order.save()
|
||||
company.save()
|
||||
|
||||
|
||||
class ModelWaterfall(EngineeringModel):
|
||||
def recalculate(self, order, company):
|
||||
# positives
|
||||
# +10 workerSatisfaction +10 happyness
|
||||
company.calculateAllWorkersHappyness(addhappyness=10)
|
||||
company.calculateWorkerSatisfaction(number=10)
|
||||
# -10% workload
|
||||
order.changeWorkload(0.9)
|
||||
|
||||
# negatives
|
||||
# 1: extra work for SOPrototyp und SOChangeRequirement
|
||||
# -10 customerSatisfaction
|
||||
company.calculateCustomerSatisfaction(-10)
|
||||
|
||||
order.recalculated = True
|
||||
order.save()
|
||||
company.save()
|
||||
|
||||
|
||||
class ModelScrum(EngineeringModel):
|
||||
def recalculate(self, order, company):
|
||||
# positives
|
||||
# 1: BONUS bei SOPrototyp und SOChangeRequirement
|
||||
# 2: +20% if skilledModel of worker is scrum
|
||||
# IN BONUS HIER UNTEN
|
||||
# # negatives
|
||||
# 1: random workload shift zwischen 1% und +20%
|
||||
randnum = round(random.uniform(1.01, 1.2), 2)
|
||||
order.changeWorkload(randnum)
|
||||
# -40% auf skills wenn skilled model nicht scrum
|
||||
# IN ORDER.CALCULATEWORKLOAD
|
||||
order.recalculated = True
|
||||
order.save()
|
||||
company.save()
|
||||
|
||||
def bonus(self, worker, order):
|
||||
ampnew = worker.amplifyer + 0.2
|
||||
return ampnew
|
||||
|
||||
|
||||
class ModelChaotic(EngineeringModel):
|
||||
def recalculate(self, order, company):
|
||||
# positives
|
||||
# NIX
|
||||
|
||||
# negatives:
|
||||
# +10% workload
|
||||
order.changeWorkload(1.1)
|
||||
# -20 workerSatisfaction -10 happyness
|
||||
|
||||
company.calculateAllWorkersHappyness(addhappyness=-10)
|
||||
company.calculateWorkerSatisfaction(number=-20)
|
||||
# extra work bei prototyp und changerequirement
|
||||
|
||||
order.recalculated = True
|
||||
order.save()
|
||||
company.save()
|
||||
|
||||
|
||||
class ModelHeyJoe(EngineeringModel):
|
||||
def recalculate(self, order, company):
|
||||
# positives
|
||||
# 1: BONUS AUF SOPrototyp UND SOChangeRequirement
|
||||
# +30 customerSatisfaciton
|
||||
company.calculateCustomerSatisfaction(30)
|
||||
|
||||
# negatives
|
||||
# 1: -10 happyness and workersatisfaction
|
||||
|
||||
company.calculateAllWorkersHappyness(addhappyness=-15)
|
||||
company.calculateWorkerSatisfaction(number=-15)
|
||||
# +10% workload
|
||||
order.changeWorkload(1.2)
|
||||
|
||||
order.recalculated = True
|
||||
order.save()
|
||||
company.save()
|
||||
@@ -0,0 +1,310 @@
|
||||
from django.db import models
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
from polymorphic.models import PolymorphicModel
|
||||
from .engineeringmodel import EngineeringModel
|
||||
import random
|
||||
|
||||
|
||||
# Event und erbende Klassen (specialOrder)
|
||||
class Event(PolymorphicModel):
|
||||
name = models.CharField(default="random Event", max_length=40)
|
||||
description = models.CharField(default="Event description here", max_length=200)
|
||||
|
||||
@classmethod
|
||||
def createEmpty(cls):
|
||||
emptyEvent = cls(
|
||||
name="Your E-Mails are empty",
|
||||
description="You do not have E-Mails this round.",
|
||||
)
|
||||
emptyEvent.save()
|
||||
return emptyEvent
|
||||
|
||||
@classmethod
|
||||
def createOrderFailed(cls, ordername):
|
||||
name = ordername + " canceled."
|
||||
description = (
|
||||
"Your order "
|
||||
+ ordername
|
||||
+ " ran out of rounds! The order was canceled and your customerSatisfaction decreased."
|
||||
)
|
||||
event = cls(
|
||||
name=name,
|
||||
description=description,
|
||||
)
|
||||
event.save()
|
||||
return event
|
||||
|
||||
@classmethod
|
||||
def createOrderFinished(cls, ordername, profit):
|
||||
name = ordername + " finished."
|
||||
description = (
|
||||
"Your order "
|
||||
+ ordername
|
||||
+ " was completed! The profit of "
|
||||
+ profit
|
||||
+ " was added to your companys money."
|
||||
)
|
||||
event = cls(
|
||||
name=name,
|
||||
description=description,
|
||||
)
|
||||
event.save()
|
||||
return event
|
||||
|
||||
@classmethod
|
||||
def createWorkerQuit(cls, threshhold, workername, workerhappyness):
|
||||
name = workername + " quit his job."
|
||||
description = (
|
||||
"Your worker "
|
||||
+ workername
|
||||
+ " quit his job due to his happyness falling to "
|
||||
+ str(workerhappyness)
|
||||
+ "! Falling below "
|
||||
+ str(threshhold)
|
||||
+ " will result in increasing chance for your worker to quit!"
|
||||
)
|
||||
event = cls(
|
||||
name=name,
|
||||
description=description,
|
||||
)
|
||||
event.save()
|
||||
return event
|
||||
|
||||
@classmethod
|
||||
def createSpecialOrderPenalty(cls, order):
|
||||
name = "You ignored the Special Order for " + order.name
|
||||
description = (
|
||||
"You ignored the Special Order for the order "
|
||||
+ order.name
|
||||
+ ". Penalties have been applied! [-20 Customer Satisfaction; -20% Profit]"
|
||||
)
|
||||
event = cls(
|
||||
name=name,
|
||||
description=description,
|
||||
)
|
||||
event.save()
|
||||
return event
|
||||
|
||||
@classmethod
|
||||
def createSpecialOrderBonus(cls, order):
|
||||
name = "You handled the Special Order for " + order.name
|
||||
description = (
|
||||
"You handled the Special Order for the order "
|
||||
+ order.name
|
||||
+ " in a flexible model. You received a bonus on your order!"
|
||||
+ " [+10 Customer Satisfaction; +10 Worker Satisfaction; +20% Profit ; +10 happyness all Workers]"
|
||||
)
|
||||
event = cls(
|
||||
name=name,
|
||||
description=description,
|
||||
)
|
||||
event.save()
|
||||
return event
|
||||
|
||||
@classmethod
|
||||
def createSpecialOrderWrongModel(cls, order):
|
||||
name = "You handled the Special Order for " + order.name
|
||||
description = (
|
||||
"You handled the Special Order for the order "
|
||||
+ order.name
|
||||
+ ", but you are working with an unflexible model! You let your workers work overtime to complete the customers wish."
|
||||
+ " [+30 Workload on all Skills; -20 happyness all Workers; -10 Worker Satsifaction]"
|
||||
)
|
||||
event = cls(
|
||||
name=name,
|
||||
description=description,
|
||||
)
|
||||
event.save()
|
||||
return event
|
||||
|
||||
|
||||
class EventOfferAccepted(Event):
|
||||
order = models.ForeignKey("Order", default=1, on_delete=models.CASCADE)
|
||||
modelset = models.BooleanField(default=False)
|
||||
|
||||
def setModel(self, model):
|
||||
self.order.setEngineeringmodel(model)
|
||||
self.modelset = True
|
||||
self.save()
|
||||
|
||||
|
||||
class SpecialOrder(Event):
|
||||
occuranceProbability = models.IntegerField(
|
||||
default=100, validators=[MinValueValidator(0), MaxValueValidator(100)]
|
||||
)
|
||||
|
||||
validModels = models.ManyToManyField(EngineeringModel, blank=True)
|
||||
occured = models.BooleanField(default=False)
|
||||
hint = models.CharField(default="no hint", max_length=100)
|
||||
|
||||
def getValidModels(self):
|
||||
vmodels = []
|
||||
for model in self.validModels.all():
|
||||
vmodels.append(model.name)
|
||||
return vmodels
|
||||
|
||||
def setDefaultValidModels(self):
|
||||
self.validModels.add(EngineeringModel.objects.get(name="ModelScrum"))
|
||||
self.validModels.add(EngineeringModel.objects.get(name="ModelSpiral"))
|
||||
self.validModels.add(EngineeringModel.objects.get(name="ModelHeyJoe"))
|
||||
|
||||
def createHint(occuranceProbability):
|
||||
if occuranceProbability <= 10:
|
||||
hintlist = [
|
||||
"The project is discussed completely from the beginning, and clear agreements are made regarding the requirements and scope of the project.",
|
||||
"The customer is known to wish little interaction with its project partners and just wants to get the job done.",
|
||||
"A tight budget and strict time management allows little changes within the project.",
|
||||
"The company has emphasized the importance of precise planning and scope definition, indicating their intention to avoid unnecessary changes.",
|
||||
"The client's primary focus is on efficiency and timely completion, suggesting they are unlikely to introduce substantial changes mid-project.",
|
||||
"With a fixed project scope and well-defined milestones, the company seems committed to maintaining project stability.",
|
||||
"Previous collaborations with the company reveal a preference for minimal modifications during the project execution phase.",
|
||||
]
|
||||
else:
|
||||
hintlist = [
|
||||
"Previous project collaborations with the firm have involved multiple change requests and additional features added throughout the development process.",
|
||||
"The client has expressed a strong desire for flexibility and creativity in the project execution.",
|
||||
"Given the dynamic nature of the industry they work in, it is likely that the company will request modifications to adapt to emerging trends.",
|
||||
"The client has not yet finalized their longterm strategy, which means changes and updates to the project might be needed.",
|
||||
"The company regularely takes user feedback, which might demand project alteration and updating.",
|
||||
"The client has expressed an interest in prototyping certain features to explore different possibilities, which may result in the addition of new requirements.",
|
||||
"The customer wishes for an agile project execution to have the option to get involved in the projects development.",
|
||||
]
|
||||
hint = random.choice(hintlist)
|
||||
return hint
|
||||
|
||||
def calculateOccurance(self):
|
||||
randnum = random.randint(1, 100)
|
||||
if (self.occuranceProbability >= randnum) and not self.occured:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def createOccuranceProbability():
|
||||
# 50% chance dass es relativ wahrscheinlich/unwahrscheinlich ist das SO auftritt
|
||||
randnum = random.randint(1, 2)
|
||||
if randnum == 1:
|
||||
# niedrige OP
|
||||
occuranceProbability = random.randint(1, 5)
|
||||
else:
|
||||
# hohe OP
|
||||
occuranceProbability = random.randint(30, 40)
|
||||
return occuranceProbability
|
||||
|
||||
def occure(self, company):
|
||||
if self.calculateOccurance():
|
||||
company.events.add(self)
|
||||
self.occured = True
|
||||
self.save()
|
||||
|
||||
def handle(self, order, company, handle):
|
||||
if order.engineeringModel.name in self.getValidModels():
|
||||
self.bonus(order, company)
|
||||
event = Event.createSpecialOrderBonus(order)
|
||||
elif handle == True:
|
||||
self.invest(order, company)
|
||||
event = Event.createSpecialOrderWrongModel(order)
|
||||
else:
|
||||
self.penalty(order, company)
|
||||
event = Event.createSpecialOrderPenalty(order)
|
||||
|
||||
company.events.remove(self)
|
||||
company.events.add(event)
|
||||
return event
|
||||
|
||||
def bonus(self, order, company):
|
||||
company.calculateCustomerSatisfaction(20)
|
||||
company.calculateWorkerSatisfaction(10)
|
||||
|
||||
order.profit *= 1.2
|
||||
for worker in company.workers.all():
|
||||
worker.calculateHappyness(10)
|
||||
|
||||
order.save()
|
||||
company.save()
|
||||
|
||||
def penalty(self, order, company):
|
||||
company.calculateCustomerSatisfaction(-20)
|
||||
order.profit *= 0.8
|
||||
|
||||
order.save()
|
||||
company.save()
|
||||
|
||||
def invest(self, order, company):
|
||||
order.addWorkload(30)
|
||||
for worker in company.workers.all():
|
||||
worker.calculateHappyness(-20)
|
||||
company.calculateWorkerSatisfaction(-10)
|
||||
order.save()
|
||||
company.save()
|
||||
|
||||
|
||||
class SOPrototyp(SpecialOrder):
|
||||
@classmethod
|
||||
def createRandom(cls, ordername):
|
||||
name = "Specialorder prototyp request from " + ordername
|
||||
description = (
|
||||
"Your customer for the order "
|
||||
+ ordername
|
||||
+ " wants you to produce a prototyp for them to review."
|
||||
)
|
||||
# hier random low <5% per round oder high < 40% per round
|
||||
occuranceProbability = cls.createOccuranceProbability()
|
||||
hint = cls.createHint(occuranceProbability=occuranceProbability)
|
||||
specialorder = cls(
|
||||
name=name,
|
||||
description=description,
|
||||
occuranceProbability=occuranceProbability,
|
||||
hint=hint,
|
||||
)
|
||||
specialorder.save()
|
||||
specialorder.setDefaultValidModels()
|
||||
specialorder.save()
|
||||
return specialorder
|
||||
|
||||
|
||||
class SORegularIncrementUpdates(SpecialOrder):
|
||||
@classmethod
|
||||
def createRandom(cls, ordername):
|
||||
name = "Specialorder regular incremental updates request from " + ordername
|
||||
description = (
|
||||
"Your customer for the order "
|
||||
+ ordername
|
||||
+ " wants to get regular updates on the increments of the project!"
|
||||
)
|
||||
# hier random low <5% per round oder high < 40% per round
|
||||
occuranceProbability = cls.createOccuranceProbability()
|
||||
hint = cls.createHint(occuranceProbability=occuranceProbability)
|
||||
specialorder = cls(
|
||||
name=name,
|
||||
description=description,
|
||||
occuranceProbability=occuranceProbability,
|
||||
hint=hint,
|
||||
)
|
||||
specialorder.save()
|
||||
specialorder.setDefaultValidModels()
|
||||
specialorder.save()
|
||||
return specialorder
|
||||
|
||||
|
||||
class SOChangeRequirement(SpecialOrder):
|
||||
@classmethod
|
||||
def createRandom(cls, ordername):
|
||||
name = "Specialorder change requirement request from " + ordername
|
||||
description = (
|
||||
"Your customer for the order "
|
||||
+ ordername
|
||||
+ " wants to change some requirements on your order. "
|
||||
)
|
||||
# hier random low <5% per round oder high < 40% per round
|
||||
occuranceProbability = cls.createOccuranceProbability()
|
||||
hint = cls.createHint(occuranceProbability=occuranceProbability)
|
||||
specialorder = cls(
|
||||
name=name,
|
||||
description=description,
|
||||
occuranceProbability=occuranceProbability,
|
||||
hint=hint,
|
||||
)
|
||||
specialorder.save()
|
||||
specialorder.setDefaultValidModels()
|
||||
specialorder.save()
|
||||
return specialorder
|
||||
@@ -0,0 +1,300 @@
|
||||
from django.db import models
|
||||
from .names import WorkerNames, OrderNames
|
||||
from .timer import Timer
|
||||
from .timer import Timer
|
||||
from .company import Company
|
||||
from .order import Order
|
||||
|
||||
# from .action import Action
|
||||
from .offer import Offer
|
||||
from ..initialdatabase import InitialDatabase
|
||||
from .engineeringmodel import (
|
||||
ModelChaotic,
|
||||
ModelScrum,
|
||||
ModelSpiral,
|
||||
ModelV,
|
||||
ModelWaterfall,
|
||||
ModelHeyJoe,
|
||||
)
|
||||
|
||||
|
||||
# Spielklasse kontrollier das gamegeschehen
|
||||
class Game(models.Model):
|
||||
name = models.CharField(default="Game", max_length=20)
|
||||
gamemaster = models.CharField(max_length=20)
|
||||
running = models.BooleanField(default=False)
|
||||
participants = models.ManyToManyField(Company)
|
||||
maxRounds = models.IntegerField(default=10)
|
||||
currentRound = models.IntegerField(default=1)
|
||||
ordermarket = models.ManyToManyField(Order)
|
||||
actionpool = models.ManyToManyField("Action")
|
||||
timer = models.ForeignKey(Timer, default=1, on_delete=models.CASCADE)
|
||||
acceptedOffers = models.ManyToManyField(Offer, blank=True)
|
||||
ordermarketsize = models.IntegerField(default=5)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
# Standard Datenbankeinträge generieren die hart codiert sind (in initialdatabase.py)
|
||||
def initializeDatabase(self):
|
||||
data = InitialDatabase()
|
||||
self.createWorkernames(data)
|
||||
self.createOrdernames(data)
|
||||
self.createEngineeringmodels(data)
|
||||
|
||||
def createWorkernames(self, data):
|
||||
for name in data.workernames:
|
||||
WorkerNames.objects.get_or_create(name=name)
|
||||
|
||||
def createOrdernames(self, data):
|
||||
for name in data.ordernames:
|
||||
OrderNames.objects.get_or_create(name=name)
|
||||
|
||||
def createEngineeringmodels(self, data):
|
||||
ModelV.objects.get_or_create(
|
||||
name=data.engineeringmodelnames[0],
|
||||
description=data.engineeringmodeldescription[0],
|
||||
pros=data.engineeringmodelprocon[0][0],
|
||||
cons=data.engineeringmodelprocon[0][1],
|
||||
)
|
||||
ModelSpiral.objects.get_or_create(
|
||||
name=data.engineeringmodelnames[1],
|
||||
description=data.engineeringmodeldescription[1],
|
||||
pros=data.engineeringmodelprocon[1][0],
|
||||
cons=data.engineeringmodelprocon[1][1],
|
||||
)
|
||||
ModelWaterfall.objects.get_or_create(
|
||||
name=data.engineeringmodelnames[2],
|
||||
description=data.engineeringmodeldescription[2],
|
||||
pros=data.engineeringmodelprocon[2][0],
|
||||
cons=data.engineeringmodelprocon[2][1],
|
||||
)
|
||||
ModelScrum.objects.get_or_create(
|
||||
name=data.engineeringmodelnames[3],
|
||||
description=data.engineeringmodeldescription[3],
|
||||
pros=data.engineeringmodelprocon[3][0],
|
||||
cons=data.engineeringmodelprocon[3][1],
|
||||
)
|
||||
ModelChaotic.objects.get_or_create(
|
||||
name=data.engineeringmodelnames[4],
|
||||
description=data.engineeringmodeldescription[4],
|
||||
pros=data.engineeringmodelprocon[4][0],
|
||||
cons=data.engineeringmodelprocon[4][1],
|
||||
)
|
||||
ModelHeyJoe.objects.get_or_create(
|
||||
name=data.engineeringmodelnames[5],
|
||||
description=data.engineeringmodeldescription[5],
|
||||
pros=data.engineeringmodelprocon[5][0],
|
||||
cons=data.engineeringmodelprocon[5][1],
|
||||
)
|
||||
|
||||
# -----------------------------------------------------------------------------------
|
||||
|
||||
# Bearbeitung des Gameablaufs mit diesen Funktionen kontrollieren:
|
||||
def startGame(self):
|
||||
# klarmachen dass workernames ordernames engineeringmodels und spezialorders
|
||||
# alle definiert sind -> sonst datenbankeinträge generieren
|
||||
self.setDefault()
|
||||
self.initializeDatabase()
|
||||
# spiel auf running stellen
|
||||
self.running = True
|
||||
self.save()
|
||||
# runde starten
|
||||
self.startRound()
|
||||
# timer starten
|
||||
self.runTimer()
|
||||
|
||||
def setDefault(self):
|
||||
self.currentRound = 1
|
||||
self.save()
|
||||
for company in self.participants.all():
|
||||
for worker in company.workers.all():
|
||||
worker.delete()
|
||||
for order in company.orders.all():
|
||||
order.delete()
|
||||
company.money = 300000
|
||||
company.customersatisfaction = 100
|
||||
company.workersatisfaction = 100
|
||||
company.save()
|
||||
|
||||
def endGame(self):
|
||||
# game running False stellen
|
||||
self.running = False
|
||||
self.save()
|
||||
|
||||
def startRound(self):
|
||||
# ordermarket generieren
|
||||
self.generateOrdermarket()
|
||||
# companys ihren workermarket generieren lassen
|
||||
self.generateWorkermarket()
|
||||
|
||||
def processGameround(self):
|
||||
# events von LETZTER RUNDE clearen()
|
||||
self.clearEvents()
|
||||
# arbeiter bezahlen
|
||||
self.paySalary()
|
||||
# schauen ob worker quittet (zufällig mit steigender wahrscheinlichkeit je niedriger)
|
||||
self.checkWorkerQuit()
|
||||
# companyOrder verbleibende Workload neu berechnen
|
||||
self.calculateOrderWorkload()
|
||||
# alle Aktionen ausführen und clearen
|
||||
self.executeActions()
|
||||
# Krankheit zufällig generieren
|
||||
self.calculateSick()
|
||||
# unlock locked workers wenn countdown auf 0; dann zähle countdown runter
|
||||
self.countdownLockedWorkers()
|
||||
# recalculate der models auf orders anwenden
|
||||
self.modelsRecalculateOrders()
|
||||
# SpecialOrders passieren lassen()
|
||||
self.specialordersOccure()
|
||||
# beste offer für jede order auf ordermarket rausfinden
|
||||
self.calculateBestOffers()
|
||||
# offers an beste berechnete company verteilen
|
||||
self.distributeBestOffers()
|
||||
# passive regeln anpassen
|
||||
self.passiveGamerules()
|
||||
# checken ob es letzte runde ist
|
||||
gameend = self.checkLastRound()
|
||||
# runde hochzählen
|
||||
self.increaseRound()
|
||||
# nächste Runde starten
|
||||
self.startRound()
|
||||
# gameende signalisieren
|
||||
return gameend
|
||||
|
||||
# -----------------------------------------------------------------------------------
|
||||
def passiveGamerules(self):
|
||||
for company in self.participants.all():
|
||||
company.calculateWorkerSatisfaction(2)
|
||||
company.calculateCustomerSatisfaction(2)
|
||||
for worker in company.workers.all():
|
||||
worker.calculateHappyness(1)
|
||||
|
||||
# Spielexecution Funktionen die Funktionen zur Spielkontorlle implementieren
|
||||
# adde 5 elemente zu ordermarket
|
||||
def generateOrdermarket(self):
|
||||
self.clearOrdermarket()
|
||||
for x in range(self.ordermarketsize):
|
||||
order = Order.createRandom()
|
||||
self.addOrder(order)
|
||||
|
||||
def generateWorkermarket(self):
|
||||
for company in self.participants.all():
|
||||
company.generateWorkermarket()
|
||||
|
||||
def clearParticipants(self, username):
|
||||
for player in self.participants.all():
|
||||
# alle comapnys ausser gamemaster company kicken
|
||||
if not (player.user == username):
|
||||
self.participants.remove(player)
|
||||
|
||||
def clearEvents(self):
|
||||
for company in self.participants.all():
|
||||
company.clearEvents()
|
||||
|
||||
def callbackTimerCompleted(self):
|
||||
gameend = self.processGameround()
|
||||
if gameend:
|
||||
self.timer.stop()
|
||||
|
||||
def runTimer(self):
|
||||
self.timer.start(callback=self.callbackTimerCompleted)
|
||||
|
||||
def getRemainingTimer(self):
|
||||
return self.timer.remainingtimer
|
||||
|
||||
def checkWorkerQuit(self):
|
||||
for company in self.participants.all():
|
||||
company.checkWorkerQuit()
|
||||
|
||||
def countdownLockedWorkers(self):
|
||||
for company in self.participants.all():
|
||||
for worker in company.workers.all():
|
||||
# unlocken wenn locked und countdown = 0 und setze sick false
|
||||
if worker.lockedRounds <= 0 and worker.status == 3:
|
||||
worker.setStatus(1)
|
||||
worker.setSick(False)
|
||||
# countdown lockedRounds wenn größer 0
|
||||
elif worker.lockedRounds > 0:
|
||||
rounds = worker.lockedRounds - 1
|
||||
worker.setLockedRounds(rounds)
|
||||
|
||||
def calculateSick(self):
|
||||
for company in self.participants.all():
|
||||
for worker in company.workers.all():
|
||||
worker.calculateSick()
|
||||
|
||||
def executeActions(self):
|
||||
for company in self.participants.all():
|
||||
for action in company.actions.all():
|
||||
action.execute()
|
||||
for action in company.actions.all():
|
||||
action.delete()
|
||||
|
||||
def calculateOrderWorkload(self):
|
||||
for company in self.participants.all():
|
||||
company.calculateOrderWorkload()
|
||||
|
||||
def calculateBestOffers(self):
|
||||
for order in self.ordermarket.all():
|
||||
bestoffer = order.calculateBestOffer()
|
||||
self.acceptedOffers.add(bestoffer)
|
||||
|
||||
def modelsRecalculateOrders(self):
|
||||
for company in self.participants.all():
|
||||
for order in company.orders.all():
|
||||
order.recalculate(company)
|
||||
|
||||
def distributeBestOffers(self):
|
||||
for acceptedoffer in self.acceptedOffers.all():
|
||||
acceptedoffer.order.setStatus(1)
|
||||
self.ordermarket.remove(acceptedoffer.order)
|
||||
acceptedoffer.company.addOrder(acceptedoffer.order)
|
||||
acceptedoffer.offerAcceptedEvent()
|
||||
# offers deleten da nicht mehr gebraucht
|
||||
acceptedoffer.delete()
|
||||
|
||||
def specialordersOccure(self):
|
||||
for company in self.participants.all():
|
||||
for order in company.orders.all():
|
||||
order.specialorder.occure(company=company)
|
||||
|
||||
def increaseRound(self):
|
||||
self.currentRound += 1
|
||||
self.save()
|
||||
|
||||
def checkLastRound(self):
|
||||
if self.maxRounds <= self.currentRound:
|
||||
self.endGame() # beende spiel
|
||||
return True
|
||||
return False
|
||||
|
||||
def addOrder(self, order):
|
||||
self.ordermarket.add(order)
|
||||
|
||||
def removeOrder(self, order):
|
||||
self.ordermarket.remove(order)
|
||||
|
||||
def clearOrdermarket(self):
|
||||
for order in self.ordermarket.all():
|
||||
if order.status == 0:
|
||||
order.delete()
|
||||
self.ordermarket.clear()
|
||||
|
||||
def paySalary(self):
|
||||
for company in self.participants.all():
|
||||
company.paySalary()
|
||||
|
||||
def createLeaderboard(self):
|
||||
tuples = []
|
||||
for company in self.participants.all():
|
||||
tuples.append((company.money, company))
|
||||
tuples = sorted(tuples, key=lambda x: x[0], reverse=True)
|
||||
# companys aus den tuples ziehen
|
||||
leaderboard = []
|
||||
i = 1
|
||||
for element in tuples:
|
||||
leaderboard.append((i, element[1]))
|
||||
i = i + 1
|
||||
|
||||
return leaderboard
|
||||
@@ -0,0 +1,11 @@
|
||||
from django.db import models
|
||||
|
||||
|
||||
# Klassen für hartcodierte Datenbank:
|
||||
# Namen Datenbank
|
||||
class WorkerNames(models.Model):
|
||||
name = models.CharField(default="no name", max_length=20)
|
||||
|
||||
|
||||
class OrderNames(models.Model):
|
||||
name = models.CharField(default="no name", max_length=20)
|
||||
@@ -0,0 +1,25 @@
|
||||
from django.db import models
|
||||
from .event import EventOfferAccepted
|
||||
|
||||
|
||||
# offer für orders
|
||||
class Offer(models.Model):
|
||||
company = models.ForeignKey("Company", default=1, on_delete=models.CASCADE)
|
||||
amount = models.IntegerField(default=0)
|
||||
order = models.ForeignKey("Order", default=1, on_delete=models.CASCADE)
|
||||
|
||||
def offerAcceptedEvent(self):
|
||||
name = "Offer for " + self.order.name
|
||||
description = (
|
||||
"Your offer for the order "
|
||||
+ self.order.name
|
||||
+ " has been accepted!"
|
||||
+ " You have "
|
||||
+ str(self.order.maxRounds)
|
||||
+ " rounds time to finish the order and claim your profit of "
|
||||
+ str(self.order.profit)
|
||||
)
|
||||
offeracceptedevent = EventOfferAccepted.objects.create(
|
||||
name=name, description=description, order=self.order
|
||||
)
|
||||
self.company.addEvent(offeracceptedevent)
|
||||
@@ -0,0 +1,211 @@
|
||||
from django.db import models
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
import random
|
||||
from .names import OrderNames
|
||||
from .attributeset import AttributeSet
|
||||
from .engineeringmodel import EngineeringModel
|
||||
from .worker import Worker
|
||||
from .offer import Offer
|
||||
from .event import (
|
||||
SpecialOrder,
|
||||
SOChangeRequirement,
|
||||
SORegularIncrementUpdates,
|
||||
SOPrototyp,
|
||||
)
|
||||
|
||||
# in attributeset einbauen?
|
||||
attributelist = [
|
||||
"experience",
|
||||
"reliability",
|
||||
"python",
|
||||
"javascript",
|
||||
"cpp",
|
||||
"management",
|
||||
]
|
||||
|
||||
|
||||
# order zum abarbeiten
|
||||
class Order(models.Model):
|
||||
name = models.CharField(default="random order", max_length=20)
|
||||
profit = models.IntegerField(default=1000)
|
||||
status = models.IntegerField(
|
||||
default=0, validators=[MinValueValidator(0), MaxValueValidator(1)]
|
||||
)
|
||||
maxRounds = models.IntegerField(
|
||||
default=5, validators=[MinValueValidator(5), MaxValueValidator(100)]
|
||||
)
|
||||
requiredWorkload = models.ForeignKey(
|
||||
AttributeSet, default=1, on_delete=models.CASCADE
|
||||
)
|
||||
engineeringModel = models.ForeignKey(
|
||||
EngineeringModel, default=1, on_delete=models.DO_NOTHING, blank=True
|
||||
)
|
||||
assignedWorkers = models.ManyToManyField(Worker, blank=True)
|
||||
offers = models.ManyToManyField(
|
||||
Offer,
|
||||
blank=True,
|
||||
related_name="order_offers",
|
||||
)
|
||||
specialorder = models.ForeignKey(
|
||||
SpecialOrder, default=1, on_delete=models.CASCADE, blank=True
|
||||
)
|
||||
recalculated = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def getRandomSpecialorder(name):
|
||||
randnum = random.randint(1, 3)
|
||||
if randnum == 1:
|
||||
specialorder = SOPrototyp.createRandom(name)
|
||||
elif randnum == 2:
|
||||
specialorder = SOChangeRequirement.createRandom(name)
|
||||
else:
|
||||
specialorder = SORegularIncrementUpdates.createRandom(name)
|
||||
return specialorder
|
||||
|
||||
@classmethod
|
||||
def createRandom(cls):
|
||||
name = random.choice(OrderNames.objects.all()).name
|
||||
profit = random.randint(40000, 100000)
|
||||
maxRounds = round(random.uniform(0.7, 1.3) * (profit / 10000))
|
||||
requiredWorkload = AttributeSet.createRandom(maxRounds * 13)
|
||||
engineeringModel = EngineeringModel.objects.all().get(name="ModelChaotic")
|
||||
specialorder = cls.getRandomSpecialorder(name)
|
||||
order = cls(
|
||||
name=name,
|
||||
profit=profit,
|
||||
maxRounds=maxRounds,
|
||||
requiredWorkload=requiredWorkload,
|
||||
engineeringModel=engineeringModel,
|
||||
specialorder=specialorder,
|
||||
)
|
||||
order.save()
|
||||
return order
|
||||
|
||||
def setStatus(self, status):
|
||||
self.status = status
|
||||
self.save()
|
||||
|
||||
def assignWorker(self, worker):
|
||||
worker.setStatus(2)
|
||||
self.assignedWorkers.add(worker)
|
||||
|
||||
def unassignWorker(self, worker):
|
||||
worker.setStatus(1)
|
||||
self.assignedWorkers.remove(worker)
|
||||
|
||||
def setEngineeringmodel(self, model):
|
||||
self.engineeringModel = model
|
||||
self.save()
|
||||
|
||||
def decreaseRounds(self):
|
||||
self.maxRounds -= 1
|
||||
self.save()
|
||||
|
||||
def recalculate(self, company):
|
||||
if not self.recalculated:
|
||||
self.engineeringModel.recalculate(order=self, company=company)
|
||||
print("recalculated")
|
||||
|
||||
def calculateWorkload(self, workersatisfaction):
|
||||
self.decreaseRounds()
|
||||
finished = False
|
||||
for worker in self.assignedWorkers.all():
|
||||
if worker.skilledModels == self.engineeringModel:
|
||||
if self.engineeringModel.name == "ModelScrum":
|
||||
amplifyer = self.engineeringModel.bonus(worker=worker, order=self)
|
||||
else:
|
||||
amplifyer = worker.amplifyer
|
||||
else:
|
||||
self.engineeringModel.penalty(worker=worker, order=self)
|
||||
if self.engineeringModel.name == "ModelScrum":
|
||||
amplifyer = 0.6
|
||||
else:
|
||||
amplifyer = 1
|
||||
|
||||
# arbeit an order wenn nicht blockeirt
|
||||
if worker.status != 3:
|
||||
for attribute in attributelist:
|
||||
newval = getattr(self.requiredWorkload, attribute) - (
|
||||
getattr(worker.attributes, attribute)
|
||||
* amplifyer
|
||||
* (workersatisfaction * 0.01)
|
||||
)
|
||||
setattr(
|
||||
self.requiredWorkload,
|
||||
attribute,
|
||||
max(0, newval), # 0 setzen wenn negativwert
|
||||
)
|
||||
|
||||
self.requiredWorkload.save()
|
||||
|
||||
# prüfe ob alles abgearbeitet
|
||||
finished = True
|
||||
for attribute in attributelist:
|
||||
if getattr(self.requiredWorkload, attribute) > 0:
|
||||
finished = False
|
||||
break
|
||||
|
||||
return finished
|
||||
|
||||
def changeWorkload(self, number):
|
||||
for attribute in attributelist:
|
||||
setattr(
|
||||
self.requiredWorkload,
|
||||
attribute,
|
||||
getattr(self.requiredWorkload, attribute) * number,
|
||||
)
|
||||
|
||||
self.requiredWorkload.save()
|
||||
|
||||
def addWorkload(self, number):
|
||||
for attribute in attributelist:
|
||||
setattr(
|
||||
self.requiredWorkload,
|
||||
attribute,
|
||||
getattr(self.requiredWorkload, attribute) + number,
|
||||
)
|
||||
|
||||
self.requiredWorkload.save()
|
||||
|
||||
def finishOrder(self, company):
|
||||
company.addProfit(self.profit)
|
||||
company.calculateCustomerSatisfaction(30)
|
||||
company.save()
|
||||
self.cancelOrder()
|
||||
|
||||
def addOffer(self, offer):
|
||||
self.offers.add(offer)
|
||||
|
||||
def removeOffer(self, offer):
|
||||
self.offers.remove(offer)
|
||||
|
||||
def checkOffer(self, amount):
|
||||
if amount > (self.profit * 1.2) or amount < (self.profit * 0.8):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def calculateBestOffer(self):
|
||||
if self.offers.exists():
|
||||
# Wenn offers vorhanden
|
||||
bestoffer = (0, 0)
|
||||
for offer in self.offers.all():
|
||||
x = float(offer.company.customersatisfaction) / float(offer.amount)
|
||||
if x >= bestoffer[0]:
|
||||
bestoffer = (x, offer)
|
||||
self.setProfit(offer.amount)
|
||||
return bestoffer[1]
|
||||
else:
|
||||
# wenn keine offers
|
||||
return
|
||||
|
||||
def cancelOrder(self):
|
||||
for worker in self.assignedWorkers.all():
|
||||
self.unassignWorker(worker)
|
||||
self.save()
|
||||
|
||||
def setProfit(self, amount):
|
||||
self.profit = amount
|
||||
self.save()
|
||||
@@ -0,0 +1,45 @@
|
||||
from django.db import models
|
||||
import threading
|
||||
import time
|
||||
|
||||
|
||||
# Timer mit Thread damit er seperat vom gamegeschehen läuft
|
||||
class TimerThread(threading.Thread):
|
||||
def __init__(self, timermodel, callback):
|
||||
super(TimerThread, self).__init__()
|
||||
self.timermodel = timermodel
|
||||
self.callback = callback
|
||||
|
||||
def run(self):
|
||||
self.timermodel.running = True
|
||||
while self.timermodel.remainingtimer >= 0 and self.timermodel.running:
|
||||
time.sleep(1)
|
||||
self.timermodel.remainingtimer -= 1
|
||||
self.timermodel.save()
|
||||
|
||||
if self.timermodel.remainingtimer <= 1:
|
||||
# self.stop()
|
||||
self.callback()
|
||||
self.reset()
|
||||
|
||||
def reset(self):
|
||||
self.timermodel.remainingtimer = self.timermodel.timer
|
||||
self.timermodel.save()
|
||||
|
||||
def stop(self):
|
||||
self.timermodel.running = False
|
||||
self.reset()
|
||||
# self.join()
|
||||
|
||||
|
||||
class Timer(models.Model):
|
||||
timer = models.IntegerField(default=60)
|
||||
remainingtimer = models.IntegerField(default=60)
|
||||
running = models.BooleanField(default=False)
|
||||
|
||||
def start(self, callback):
|
||||
self.thread = TimerThread(self, callback)
|
||||
self.thread.start()
|
||||
|
||||
def stop(self):
|
||||
self.thread.stop()
|
||||
@@ -0,0 +1,99 @@
|
||||
from django.db import models
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
import random
|
||||
from .engineeringmodel import EngineeringModel, ModelChaotic
|
||||
from .attributeset import AttributeSet
|
||||
from .names import WorkerNames
|
||||
|
||||
|
||||
# worker klasse
|
||||
class Worker(models.Model):
|
||||
name = models.CharField(default="random worker", max_length=20)
|
||||
attributes = models.ForeignKey(AttributeSet, default=1, on_delete=models.CASCADE)
|
||||
skilledModels = models.ForeignKey(
|
||||
EngineeringModel, on_delete=models.CASCADE, blank=True
|
||||
)
|
||||
amplifyer = models.FloatField(
|
||||
default=1, validators=[MinValueValidator(1.0), MaxValueValidator(2.0)]
|
||||
)
|
||||
salary = models.IntegerField(default=1000)
|
||||
status = models.IntegerField(
|
||||
default=0, validators=[MinValueValidator(0), MaxValueValidator(3)]
|
||||
)
|
||||
# status 0 = in workermarket; 1=in company; 2=wokring on order; 3=locked
|
||||
lockedRounds = models.IntegerField(default=0, validators=[MinValueValidator(0)])
|
||||
happyness = models.IntegerField(
|
||||
default=100, validators=[MinValueValidator(0), MaxValueValidator(100)]
|
||||
)
|
||||
sick = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@classmethod
|
||||
def createRandom(cls):
|
||||
name = random.choice(WorkerNames.objects.all()).name
|
||||
attributes = AttributeSet.createRandom(20)
|
||||
allmodels = EngineeringModel.objects.all()
|
||||
allmodelsnochaotic = [
|
||||
model for model in allmodels if not isinstance(model, ModelChaotic)
|
||||
]
|
||||
skilledModels = random.choice(allmodelsnochaotic)
|
||||
if random.random() < 0.8:
|
||||
value = round(random.uniform(1, 1.3), 1)
|
||||
else:
|
||||
value = round(random.uniform(1.3, 1.6), 1)
|
||||
amplifyer = value
|
||||
salary = round(amplifyer * 2500 * random.uniform(0.7, 1.3))
|
||||
worker = cls(
|
||||
name=name,
|
||||
attributes=attributes,
|
||||
skilledModels=skilledModels,
|
||||
amplifyer=amplifyer,
|
||||
salary=salary,
|
||||
status=0,
|
||||
)
|
||||
worker.save()
|
||||
return worker
|
||||
|
||||
def improveAttribute(self, attribute, amount):
|
||||
self.attributes.increase(attribute=attribute, amount=amount)
|
||||
|
||||
def calculateHappyness(self, number):
|
||||
if (self.happyness + number) > 100:
|
||||
self.happyness = 100
|
||||
elif (self.happyness + number) < 0:
|
||||
self.happyness = 0
|
||||
else:
|
||||
self.happyness += number
|
||||
self.save()
|
||||
|
||||
def quitJob(self):
|
||||
self.delete()
|
||||
|
||||
def calculateSick(self):
|
||||
if self.sick == False:
|
||||
randnumber = random.randint(1, 100)
|
||||
if randnumber <= 3:
|
||||
self.setStatus(3)
|
||||
self.setSick(True)
|
||||
rounds = random.randint(1, 2)
|
||||
self.setLockedRounds(rounds)
|
||||
elif self.sick == True and self.lockedRounds < 0:
|
||||
self.setSick(False)
|
||||
self.setStatus(1)
|
||||
|
||||
def setStatus(self, status):
|
||||
self.status = status
|
||||
self.save()
|
||||
|
||||
def getStatus(self):
|
||||
return self.status
|
||||
|
||||
def setLockedRounds(self, amount):
|
||||
self.lockedRounds = amount
|
||||
self.save()
|
||||
|
||||
def setSick(self, sickness):
|
||||
self.sick = sickness
|
||||
self.save()
|
||||
@@ -0,0 +1,53 @@
|
||||
import asyncio
|
||||
from channels.generic.websocket import AsyncWebsocketConsumer
|
||||
from .backend.game import Game
|
||||
from channels.db import database_sync_to_async
|
||||
|
||||
|
||||
class TimerConsumer(AsyncWebsocketConsumer):
|
||||
async def connect(self):
|
||||
await self.accept()
|
||||
self.gameid = self.scope["url_route"]["kwargs"]["gameid"]
|
||||
self.game = await self.getGame()
|
||||
timer = await self.getRemainingTimer()
|
||||
await self.send(text_data=str(timer))
|
||||
self.timerTask = asyncio.ensure_future(self.timer(timer))
|
||||
|
||||
async def timer(self, timer):
|
||||
await asyncio.sleep(1)
|
||||
try:
|
||||
while timer >= 0:
|
||||
if self.game.running:
|
||||
await self.send(text_data=str(timer))
|
||||
timer -= 1
|
||||
await asyncio.sleep(1)
|
||||
else:
|
||||
await self.send(text_data="game not started")
|
||||
self.game = await self.getGame()
|
||||
await asyncio.sleep(1)
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
finally:
|
||||
self.game = await self.getGame()
|
||||
if self.game.currentRound > self.game.maxRounds:
|
||||
await self.send(text_data="endGame")
|
||||
else:
|
||||
await self.send(text_data="nextRound")
|
||||
|
||||
@database_sync_to_async
|
||||
def getRemainingTimer(self):
|
||||
return self.game.timer.remainingtimer
|
||||
|
||||
@database_sync_to_async
|
||||
def getGame(self):
|
||||
return Game.objects.get(id=self.gameid)
|
||||
|
||||
@database_sync_to_async
|
||||
def processGameround(self, game):
|
||||
gameend = game.processGameround()
|
||||
|
||||
async def receive(self, event):
|
||||
pass
|
||||
|
||||
async def disconnect(self, event):
|
||||
self.timerTask.cancel()
|
||||
@@ -0,0 +1,22 @@
|
||||
from django import forms
|
||||
from django.core.validators import *
|
||||
|
||||
|
||||
class LoginForm(forms.Form):
|
||||
username = forms.CharField(
|
||||
label="Username", min_length=4, max_length=30, widget=forms.TextInput
|
||||
)
|
||||
password = forms.CharField(
|
||||
label="Password", min_length=4, max_length=30, widget=forms.PasswordInput
|
||||
)
|
||||
game_id = forms.CharField(label="Game ID", widget=forms.NumberInput)
|
||||
create_join_game = forms.ChoiceField(
|
||||
label="Create/Join Game",
|
||||
choices=(("1", "Join"), ("2", "Create")),
|
||||
)
|
||||
|
||||
|
||||
class GamesettingsForm(forms.Form):
|
||||
rounds = forms.CharField(label="set number of rounds:", required=False, widget=forms.NumberInput)
|
||||
timer = forms.CharField(label="set roundtimer:", required=False, widget=forms.NumberInput)
|
||||
ordermarketsize = forms.CharField(label="set ordermarket size:", required=False, widget=forms.NumberInput)
|
||||
@@ -0,0 +1,313 @@
|
||||
class InitialDatabase:
|
||||
# Names generiert von chatgpt https://chat.openai.com/
|
||||
# Workernames
|
||||
workernames = [
|
||||
"Emma",
|
||||
"Mia",
|
||||
"Hannah",
|
||||
"Emilia",
|
||||
"Lina",
|
||||
"Ulma",
|
||||
"Lena",
|
||||
"Anna",
|
||||
"Marie",
|
||||
"Lea",
|
||||
"Noah",
|
||||
"Leon",
|
||||
"Ben",
|
||||
"Paul",
|
||||
"Finn",
|
||||
"Elias",
|
||||
"Felix",
|
||||
"Maximilian",
|
||||
"Luis",
|
||||
"Luca",
|
||||
"Laura",
|
||||
"Eva",
|
||||
"Maja",
|
||||
"Clara",
|
||||
"Amelie",
|
||||
"Isabella",
|
||||
"Lara",
|
||||
"Emily",
|
||||
"Sarah",
|
||||
"Charlotte",
|
||||
"Alexander",
|
||||
"Maximilian",
|
||||
"Paul",
|
||||
"Benjamin",
|
||||
"Finn",
|
||||
"Elias",
|
||||
"Luis",
|
||||
"Henry",
|
||||
"Luca",
|
||||
"Jakob",
|
||||
"David",
|
||||
"Niklas",
|
||||
"Leon",
|
||||
"Julian",
|
||||
"Jonas",
|
||||
"Tom",
|
||||
"Tim",
|
||||
"Simon",
|
||||
"Moritz",
|
||||
"Jan",
|
||||
"Sofia",
|
||||
"Luisa",
|
||||
"Johanna",
|
||||
"Mila",
|
||||
"Liam",
|
||||
"Oskar",
|
||||
"Theo",
|
||||
"Anton",
|
||||
"Friedrich",
|
||||
"Emil",
|
||||
"Ida",
|
||||
"Matilda",
|
||||
"Greta",
|
||||
"Frida",
|
||||
"Mila",
|
||||
"Lotta",
|
||||
"Mina",
|
||||
"Ella",
|
||||
"Julia",
|
||||
"Paula",
|
||||
"Leonard",
|
||||
"Karl",
|
||||
"Erik",
|
||||
"Johannes",
|
||||
"Finn",
|
||||
"Niklas",
|
||||
"Max",
|
||||
"Jonas",
|
||||
"Jakob",
|
||||
"Philipp",
|
||||
"Hannah",
|
||||
"Emilia",
|
||||
"Clara",
|
||||
"Lara",
|
||||
"Isabella",
|
||||
"Mia",
|
||||
"Laura",
|
||||
"Sophia",
|
||||
"Lea",
|
||||
"Marie",
|
||||
]
|
||||
# Ordernames
|
||||
ordernames = [
|
||||
"Online Shopping Platform",
|
||||
"Fitness Tracking Mobile App",
|
||||
"Social Media API",
|
||||
"Customer Relationship Management System",
|
||||
"Customer Support Chatbot",
|
||||
"E-commerce Recommendation Engine",
|
||||
"Web Scraping Tool",
|
||||
"Payment Gateway Integration",
|
||||
"Content Management System (CMS)",
|
||||
"Real-time Analytics Dashboard",
|
||||
"Task Management Application with Kanban Board",
|
||||
"Retail Store Inventory Management System",
|
||||
"Ticketing System for Customer Support",
|
||||
"Sentiment Analysis Machine Learning Model",
|
||||
"Blockchain-based Voting System",
|
||||
"Location-based Restaurant Finder App",
|
||||
"Calendar Scheduling Application",
|
||||
"Document Management System",
|
||||
"Virtual Reality (VR) Game",
|
||||
"Multiplayer Online Game",
|
||||
"Weather Forecasting Application",
|
||||
"Stock Trading Platform",
|
||||
"News Aggregator Website",
|
||||
"Ride-sharing App with GPS Tracking",
|
||||
"Movie Recommendation System",
|
||||
"E-learning Platform",
|
||||
"Music Streaming Service",
|
||||
"Social Networking Platform",
|
||||
"Video Conferencing Application",
|
||||
"Movie Theater Ticket Reservation System",
|
||||
"Automated Testing Framework for Web Applications",
|
||||
"Business Card Scanning Mobile App",
|
||||
"Secure Password Manager Application",
|
||||
"Customer Review Sentiment Analysis Tool",
|
||||
"Task Automation Script",
|
||||
"Customer Feedback Management System",
|
||||
"Recipe Recommendation App",
|
||||
"Flight Booking System",
|
||||
"Fraud Detection System for Financial Transactions",
|
||||
"Online Auction Platform",
|
||||
"Language Translation Tool",
|
||||
"IT Support Ticketing System",
|
||||
"Personal Finance Tracking Mobile App",
|
||||
"Social Media Analytics Dashboard",
|
||||
"Document Collaboration Platform",
|
||||
"Task Tracking Application",
|
||||
"Social Media Sentiment Analysis Tool",
|
||||
"Book Recommendation System",
|
||||
"E-commerce Platform with Inventory Management",
|
||||
"Movie Review Sentiment Analysis Tool",
|
||||
"Ride-hailing App",
|
||||
"Content-based Music Playlist Recommendation System",
|
||||
"Appointment Booking System for Healthcare Clinic",
|
||||
"Secure Chat Application with End-to-End Encryption",
|
||||
"Online Food Delivery Platform",
|
||||
"Customer Feedback Sentiment Analysis Tool",
|
||||
"Project Task Management System",
|
||||
"News Recommendation Engine",
|
||||
"Language Learning Mobile App",
|
||||
"Travel Planning Application",
|
||||
"AI-powered Virtual Assistant",
|
||||
"Smart Home Automation System",
|
||||
"Real Estate Listing Website",
|
||||
"Restaurant Table Reservation System",
|
||||
"Inventory Tracking Mobile App",
|
||||
"Music Production Software",
|
||||
"Event Management Platform",
|
||||
"Online Course Marketplace",
|
||||
"Expense Tracking Application",
|
||||
"Job Recruitment Platform",
|
||||
"Pet Adoption Website",
|
||||
"Home Workout Mobile App",
|
||||
"Stock Portfolio Management System",
|
||||
"Social Media Influencer Analytics Tool",
|
||||
"Food Recipe Sharing Platform",
|
||||
"AI-based Image Recognition Software",
|
||||
"Tourist Guide Mobile App",
|
||||
"Cryptocurrency Exchange Platform",
|
||||
"Language Proficiency Testing Software",
|
||||
"Virtual Interior Design Application",
|
||||
"Fitness Meal Planning App",
|
||||
"Cloud Storage Service",
|
||||
"Car Rental Booking System",
|
||||
"Data Visualization Dashboard",
|
||||
"Online Art Marketplace",
|
||||
"Restaurant Review Aggregator",
|
||||
"AI Chatbot for Legal Advice",
|
||||
"Music Concert Ticket Booking App",
|
||||
"Online Language Tutoring Platform",
|
||||
"Virtual Job Interview Platform",
|
||||
"Property Rental Management Software",
|
||||
"Restaurant Menu Ordering App",
|
||||
"AI-based Medical Diagnosis Tool",
|
||||
"Online Wedding Planning Platform",
|
||||
"Collaborative Code Editor",
|
||||
"Online Therapy Platform",
|
||||
"Home Energy Monitoring System",
|
||||
"Sports League Management Software",
|
||||
"AI-powered Resume Builder",
|
||||
"Food Delivery Recommendation App",
|
||||
"Online Marketplace for Handmade Crafts",
|
||||
"Automated Email Marketing Platform",
|
||||
]
|
||||
# Engineeringmodel
|
||||
engineeringmodelnames = [
|
||||
"ModelV",
|
||||
"ModelSpiral",
|
||||
"ModelWaterfall",
|
||||
"ModelScrum",
|
||||
"ModelChaotic",
|
||||
"ModelHeyJoe",
|
||||
]
|
||||
vmodeldesc = """The V-model uses a sequential approach with multiple phases, such as
|
||||
specification, system modeling, component modeling, implementation, component testing, integration testing and validation. The
|
||||
first four phases are constructive phases (creating code), while the last three phases concentrate on project quality and testing.
|
||||
The name originates from the fact that the phases are often represented as a V, with the development phases (descending left side of the V)
|
||||
facing the quality assurance (ascending right side of the V). Since each developmnet phase has a corresponding testing phase, assuring good project
|
||||
quality is a basis of the V-model. Planning the project in closed phases also makes
|
||||
the project easier to plan than than it would be with more flexible apporaches. The downside of the model is, that
|
||||
preplanning phases will make change of requirements difficult and building the project from bottom up will make
|
||||
prototyping hard to achieve."""
|
||||
spiraldesc = """
|
||||
The model spiral is an agile software engineering model that organizes the development
|
||||
of a software product in multiple iterations. Each iteration implements a portion of the project
|
||||
and creates a product prototype with more functionality than
|
||||
the previous iteration, growing the product bigger with each step. Succesively improving
|
||||
the project with each iteration makes finding errors early on in the project easy and naturaly
|
||||
brings prototyped versions, which will make updating and communicating with customers easy. The downside
|
||||
is, that this can lead to work redundancy, recoding functionalities and retesting, which makes
|
||||
predicting the conclusion and costs of the project hard."""
|
||||
waterfalldesc = """The model waterfall is a software engineering model that organizes
|
||||
the workload in five phases: analysis, design, implementation, integration and production.
|
||||
The phases will be worked through sequentially and going back phases is not intended. Using this
|
||||
software engineering method is most succesful for short and well defined products, since it is
|
||||
very unflexible and therefore it is hard to respond to customer requests. Due to its straight
|
||||
forward nature with closed production phases it is easy for workers to work with and the production completion is
|
||||
relatively predictable."""
|
||||
scrumdesc = """Scrum is an agile software engineering model for incrementally and iteratively
|
||||
developing software. Key elements within Scrum are short timewindows, designated to specific functionalities (Sprints),
|
||||
planning tasks beforehand in a so called product backlog and daily meetings to keep every involved workers updated on
|
||||
current problems and changes. This makes Scrum a highly flexible model with the ability to update customers frequently
|
||||
and reach good project quality. The downside is, that workers have to get familiar with the working principles and
|
||||
predicting the conclusion of a project can be hard due to the high flexibility."""
|
||||
chaotidesc = """The chaotic model is equal to not choosing a model (default). It is not a model used in
|
||||
softwareengineering, but signals that your workers will work uncoordinated. Working like this will make your workers more
|
||||
insecure in their work and company."""
|
||||
heyjoedesc = """The HeyJoe Model is an organizational method in which the manager organizes the team through
|
||||
daily instructions. Users and customers communicate directly with the manager to access team members. Team members are
|
||||
deployed flexibly to where they are most urgently needed, and their tasks, such as analysis and design, vary
|
||||
depending on the daily instructions. The Model brings a lot of flexibility while working with customers, but workers
|
||||
involved are working in a highly volatile work environment. Switching the tasks daily makes it hard to get a good workflow,
|
||||
which increases the work needed to finish the whole project"""
|
||||
engineeringmodeldescription = [
|
||||
vmodeldesc,
|
||||
spiraldesc,
|
||||
waterfalldesc,
|
||||
scrumdesc,
|
||||
chaotidesc,
|
||||
heyjoedesc,
|
||||
]
|
||||
vmodelprocon = [
|
||||
# pros
|
||||
"""-the preplanned phases give workers a good roadmap for their work [+10 Worker Satisfaction; +10 happynes all workers],
|
||||
-multiple validation phases ensure a high quality project [+10 Customer Satisfaction]""",
|
||||
# cons
|
||||
"""-low flexibility due to preplanned phases [extra work for SPECIAL ORDERS],
|
||||
-the emphasise on testing and validating each development step can cause extra workload [+10% workload]""",
|
||||
]
|
||||
spiralprocon = [
|
||||
# pros
|
||||
"""-high flexibility and regular prototyping within production [bonus on SPECIAL ORDERS],
|
||||
-easy customer involvement and feedback through the production process [+10 Customer Satisfaction]""",
|
||||
# cons
|
||||
"""-multiple iterations can lead to work redundancy and recoding functionalities [+10% workload],
|
||||
-workers will be unhappy with the redundant work [-10 Worker Satisfaction; -10 happynes all workers]""",
|
||||
]
|
||||
waterfallprocon = [
|
||||
# pros
|
||||
"""-workers appreciate the easy usage and predictability [+10 Worker Satisfaction; +10 happynes all workers],
|
||||
-straight forward planning and clear responsibilities [-10% workload]""",
|
||||
# cons
|
||||
"""-low flexibility due to preplanned phases [extra work for SPECIAL ORDERS],
|
||||
-low customer involvement and late feedback [-10 Customer Satisfaction]""",
|
||||
]
|
||||
scrumprocon = [
|
||||
# pros
|
||||
"""-high flexibility and iterative work in closed production iterations (sprints) [bonus on SPECIAL ORDERS],
|
||||
-workers familiar with Scrum work efficiently with it [+20% on skills if skilled model is Scrum]""",
|
||||
# cons
|
||||
"""-the high flexibility makes predicting project conclusion hard [random workload shift between 1% and +20%],
|
||||
-workers not familiar with scrum are overthrown by the new structure [-40% on skills if skilled model is NOT ModelScrum]""",
|
||||
]
|
||||
chaoticprocon = [
|
||||
# pros
|
||||
"""this model doesnt bring positives""",
|
||||
# cons
|
||||
"""-workers dont like volatility in their workplace [-20 Worker Satisfaction],
|
||||
-missing structure leads to inefficient work [+10% workload],
|
||||
-workers are not prepared for flexibility [extra work for SPECIAL ORDERS]""",
|
||||
]
|
||||
heyjoeprocon = [
|
||||
# pros
|
||||
"""-due to tasks varying every day, flexibility in project inkrementation is easy [bonus on SPECIAL ORDERS],
|
||||
-customers like the easy way for them to influence the project by contacting the manager [+30 Customer Satisfaction]""",
|
||||
# cons
|
||||
"""-workers dislike the high volatility in their daily work [-15 Worker Satisfaction; -15 happynes all workers],
|
||||
-Switching tasks daily leads to more workload due to workers having to adjust to new tasks [+20% workload]""",
|
||||
]
|
||||
engineeringmodelprocon = [
|
||||
vmodelprocon,
|
||||
spiralprocon,
|
||||
waterfallprocon,
|
||||
scrumprocon,
|
||||
chaoticprocon,
|
||||
heyjoeprocon,
|
||||
]
|
||||
@@ -0,0 +1,372 @@
|
||||
# Generated by Django 4.1.7 on 2023-08-03 10:31
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Action',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(default='random Action', max_length=20)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='AttributeSet',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('experience', models.IntegerField(default=10)),
|
||||
('reliability', models.IntegerField(default=10)),
|
||||
('python', models.IntegerField(default=10)),
|
||||
('javascript', models.IntegerField(default=10)),
|
||||
('cpp', models.IntegerField(default=10)),
|
||||
('management', models.IntegerField(default=10)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Company',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(default='A company', max_length=20)),
|
||||
('user', models.CharField(default='default User', max_length=20)),
|
||||
('customersatisfaction', models.IntegerField(default=100, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
|
||||
('workersatisfaction', models.IntegerField(default=100, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
|
||||
('money', models.IntegerField(default=100000)),
|
||||
('actions', models.ManyToManyField(blank=True, to='mygame.action')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EngineeringModel',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(default='random EngineeringModel', max_length=30)),
|
||||
('description', models.CharField(default='random description', max_length=200)),
|
||||
('pros', models.CharField(default='random pro', max_length=100)),
|
||||
('cons', models.CharField(default='random con', max_length=100)),
|
||||
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Event',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(default='random Event', max_length=40)),
|
||||
('description', models.CharField(default='Event description here', max_length=200)),
|
||||
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Offer',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('amount', models.IntegerField(default=0)),
|
||||
('company', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mygame.company')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='OrderNames',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(default='no name', max_length=20)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Timer',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('timer', models.IntegerField(default=60)),
|
||||
('remainingtimer', models.IntegerField(default=60)),
|
||||
('running', models.BooleanField(default=False)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='WorkerNames',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(default='no name', max_length=20)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ModelChaotic',
|
||||
fields=[
|
||||
('engineeringmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.engineeringmodel')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.engineeringmodel',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ModelScrum',
|
||||
fields=[
|
||||
('engineeringmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.engineeringmodel')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.engineeringmodel',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ModelSpiral',
|
||||
fields=[
|
||||
('engineeringmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.engineeringmodel')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.engineeringmodel',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ModelV',
|
||||
fields=[
|
||||
('engineeringmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.engineeringmodel')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.engineeringmodel',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ModelWaterfall',
|
||||
fields=[
|
||||
('engineeringmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.engineeringmodel')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.engineeringmodel',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SpecialOrder',
|
||||
fields=[
|
||||
('event_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.event')),
|
||||
('occuranceProbability', models.IntegerField(default=100, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
|
||||
('occured', models.BooleanField(default=False)),
|
||||
('hint', models.CharField(default='no hint', max_length=100)),
|
||||
('validModels', models.ManyToManyField(blank=True, to='mygame.engineeringmodel')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.event',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Worker',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(default='random worker', max_length=20)),
|
||||
('amplifyer', models.FloatField(default=1, validators=[django.core.validators.MinValueValidator(1.0), django.core.validators.MaxValueValidator(2.0)])),
|
||||
('salary', models.IntegerField(default=1000)),
|
||||
('status', models.IntegerField(default=0, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(3)])),
|
||||
('lockedRounds', models.IntegerField(default=0, validators=[django.core.validators.MinValueValidator(0)])),
|
||||
('happyness', models.IntegerField(default=100, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])),
|
||||
('sick', models.BooleanField(default=False)),
|
||||
('attributes', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mygame.attributeset')),
|
||||
('skilledModels', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to='mygame.engineeringmodel')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Order',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(default='random order', max_length=20)),
|
||||
('profit', models.IntegerField(default=1000)),
|
||||
('status', models.IntegerField(default=0, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)])),
|
||||
('maxRounds', models.IntegerField(default=5, validators=[django.core.validators.MinValueValidator(5), django.core.validators.MaxValueValidator(100)])),
|
||||
('recalculated', models.BooleanField(default=False)),
|
||||
('assignedWorkers', models.ManyToManyField(blank=True, to='mygame.worker')),
|
||||
('engineeringModel', models.ForeignKey(blank=True, default=1, on_delete=django.db.models.deletion.DO_NOTHING, to='mygame.engineeringmodel')),
|
||||
('offers', models.ManyToManyField(blank=True, related_name='order_offers', to='mygame.offer')),
|
||||
('requiredWorkload', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mygame.attributeset')),
|
||||
('specialorder', models.ForeignKey(blank=True, default=1, on_delete=django.db.models.deletion.CASCADE, to='mygame.specialorder')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='offer',
|
||||
name='order',
|
||||
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mygame.order'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Game',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(default='Game', max_length=20)),
|
||||
('gamemaster', models.CharField(max_length=20)),
|
||||
('maxRounds', models.IntegerField(default=10)),
|
||||
('currentRound', models.IntegerField(default=1)),
|
||||
('ordermarketsize', models.IntegerField(default=5)),
|
||||
('acceptedOffers', models.ManyToManyField(blank=True, to='mygame.offer')),
|
||||
('actionpool', models.ManyToManyField(to='mygame.action')),
|
||||
('ordermarket', models.ManyToManyField(to='mygame.order')),
|
||||
('participants', models.ManyToManyField(to='mygame.company')),
|
||||
('timer', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mygame.timer')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='company',
|
||||
name='events',
|
||||
field=models.ManyToManyField(blank=True, to='mygame.event'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='company',
|
||||
name='orders',
|
||||
field=models.ManyToManyField(blank=True, to='mygame.order'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='company',
|
||||
name='workermarket',
|
||||
field=models.ManyToManyField(related_name='workermarket', to='mygame.worker'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='company',
|
||||
name='workers',
|
||||
field=models.ManyToManyField(blank=True, related_name='workers', to='mygame.worker'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='action',
|
||||
name='actionmaker',
|
||||
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mygame.company'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='action',
|
||||
name='polymorphic_ctype',
|
||||
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SOChangeRequirement',
|
||||
fields=[
|
||||
('specialorder_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.specialorder')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.specialorder',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SOPrototyp',
|
||||
fields=[
|
||||
('specialorder_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.specialorder')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.specialorder',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SORegularIncrementUpdates',
|
||||
fields=[
|
||||
('specialorder_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.specialorder')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.specialorder',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventOfferAccepted',
|
||||
fields=[
|
||||
('event_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.event')),
|
||||
('modelset', models.BooleanField(default=False)),
|
||||
('order', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mygame.order')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.event',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ActionUnemploy',
|
||||
fields=[
|
||||
('action_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.action')),
|
||||
('worker', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mygame.worker')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.action',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ActionTrain',
|
||||
fields=[
|
||||
('action_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.action')),
|
||||
('trainskill', models.CharField(default='empty', max_length=50)),
|
||||
('cost', models.IntegerField(default=1000)),
|
||||
('worker', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mygame.worker')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.action',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ActionOffer',
|
||||
fields=[
|
||||
('action_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.action')),
|
||||
('amount', models.IntegerField(default=0)),
|
||||
('order', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mygame.order')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.action',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ActionEmploy',
|
||||
fields=[
|
||||
('action_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.action')),
|
||||
('worker', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mygame.worker')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.action',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ActionCancelOrder',
|
||||
fields=[
|
||||
('action_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.action')),
|
||||
('order', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='mygame.order')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.action',),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.7 on 2023-09-11 07:08
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mygame', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='game',
|
||||
name='running',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
# Generated by Django 4.1.7 on 2023-10-20 14:14
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mygame', '0002_game_running'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ModelHeyJoe',
|
||||
fields=[
|
||||
('engineeringmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='mygame.engineeringmodel')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
'base_manager_name': 'objects',
|
||||
},
|
||||
bases=('mygame.engineeringmodel',),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
from .backend import game
|
||||
@@ -0,0 +1,6 @@
|
||||
from django.urls import re_path
|
||||
from . import consumers
|
||||
|
||||
websocket_urlpatterns = [
|
||||
re_path(r"^mygame/company/(?P<gameid>\d+)/$", consumers.TimerConsumer.as_asgi())
|
||||
]
|
||||
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,423 @@
|
||||
{% extends "mygame/company.html" %} {% block content %}
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 m-3 shadow rounded text-danger"
|
||||
>
|
||||
Action: {{viewedaction.name}}
|
||||
</h1>
|
||||
{%if viewedaction.order%}
|
||||
<!-- Order offer -->
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Workload
|
||||
</h2>
|
||||
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Required Skill</th>
|
||||
<th scope="col">Workload</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">experience</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-experience"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.order.requiredWorkload.experience}}%"
|
||||
>
|
||||
{{viewedaction.order.requiredWorkload.experience}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">reliability</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-reliability"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.order.requiredWorkload.reliability}}%"
|
||||
>
|
||||
{{viewedaction.order.requiredWorkload.reliability}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">python</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-python"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.order.requiredWorkload.python}}%"
|
||||
>
|
||||
{{viewedaction.order.requiredWorkload.python}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">javascript</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-javascript"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.order.requiredWorkload.javascript}}%"
|
||||
>
|
||||
{{viewedaction.order.requiredWorkload.javascript}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">cpp</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-cpp"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.order.requiredWorkload.cpp}}%"
|
||||
>
|
||||
{{viewedaction.order.requiredWorkload.cpp}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">management</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-management"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.order.requiredWorkload.management}}%"
|
||||
>
|
||||
{{viewedaction.order.requiredWorkload.management}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Attributes
|
||||
</h2>
|
||||
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Attribute</th>
|
||||
<th scope="col">Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%if viewedaction.amount%}
|
||||
<tr>
|
||||
<th scope="row" class="fs-5 text-danger">Offered Amount</th>
|
||||
<td class="fs-5 text-danger">{{viewedaction.amount}}</td>
|
||||
</tr>
|
||||
{%endif%}
|
||||
<tr>
|
||||
{%if viewedaction.amount%}
|
||||
<th scope="row">Maximum Rounds</th>
|
||||
{%else%}
|
||||
<th scope="row">Rounds left</th>
|
||||
{%endif%}
|
||||
<td>{{viewedaction.order.maxRounds}}</td>
|
||||
</tr>
|
||||
{%if viewedaction.order.status == 1%}
|
||||
|
||||
<tr>
|
||||
<th scope="row">Engineeringmodel</th>
|
||||
<td>{{viewedaction.order.engineeringModel}}</td>
|
||||
</tr>
|
||||
{% endif%}
|
||||
<tr>
|
||||
<th scope="row">Customer Description</th>
|
||||
<td>{{viewedaction.order.specialorder.hint}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{%endif%} {%if viewedaction.trainskill%}
|
||||
<!-- Training -->
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Training
|
||||
</h2>
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Worker</th>
|
||||
<td>{{viewedaction.worker.name}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Training Skill</th>
|
||||
<td>{{viewedaction.trainskill}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Cost</th>
|
||||
<td>{{viewedaction.cost}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{%endif%}{%if viewedaction.worker%}
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Skills
|
||||
</h2>
|
||||
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Skill</th>
|
||||
<th scope="col">Strength</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">experience</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-experience"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.worker.attributes.experience}}%"
|
||||
>
|
||||
{{viewedaction.worker.attributes.experience}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">reliability</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-reliability"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.worker.attributes.reliability}}%"
|
||||
>
|
||||
{{viewedaction.worker.attributes.reliability}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">python</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-python"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.worker.attributes.python}}%"
|
||||
>
|
||||
{{viewedaction.worker.attributes.python}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">javascript</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-javascript"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.worker.attributes.javascript}}%"
|
||||
>
|
||||
{{viewedaction.worker.attributes.javascript}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">cpp</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-cpp"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.worker.attributes.cpp}}%"
|
||||
>
|
||||
{{viewedaction.worker.attributes.cpp}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">management</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-management"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.worker.attributes.management}}%"
|
||||
>
|
||||
{{viewedaction.worker.attributes.management}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{%if not viewedaction.trainskill%}
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Attributes
|
||||
</h2>
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Attribute</th>
|
||||
<th scope="col">Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Skilled Model</th>
|
||||
<td>{{viewedaction.worker.skilledModels}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Amplifyer</th>
|
||||
<td>{{viewedaction.worker.amplifyer}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Salary</th>
|
||||
<td>{{viewedaction.worker.salary}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Happyness</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-management"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedaction.worker.happyness}}%"
|
||||
>
|
||||
{{viewedaction.worker.happyness}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{%endif%} {%endif%}
|
||||
|
||||
<form
|
||||
action="{% url 'companyAction' gameid=game.id username=user.username actionid=viewedaction.id %}"
|
||||
method="post"
|
||||
>
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-danger m-2"
|
||||
type="submit"
|
||||
value="cancel"
|
||||
id="cancel"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,249 @@
|
||||
{% extends "mygame/company.html" %} {% block content %}
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 m-3 shadow rounded"
|
||||
>
|
||||
Assign Workers: {{assignorder.name}}
|
||||
</h1>
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Workload
|
||||
</h2>
|
||||
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Required Skill</th>
|
||||
<th scope="col">Workload</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">experience</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-experience"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{assignorder.requiredWorkload.experience}}%"
|
||||
>
|
||||
{{assignorder.requiredWorkload.experience}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">reliability</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-reliability"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{assignorder.requiredWorkload.reliability}}%"
|
||||
>
|
||||
{{assignorder.requiredWorkload.reliability}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">python</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-python"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{assignorder.requiredWorkload.python}}%"
|
||||
>
|
||||
{{assignorder.requiredWorkload.python}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">javascript</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-javascript"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{assignorder.requiredWorkload.javascript}}%"
|
||||
>
|
||||
{{assignorder.requiredWorkload.javascript}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">cpp</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-cpp"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{assignorder.requiredWorkload.cpp}}%"
|
||||
>
|
||||
{{assignorder.requiredWorkload.cpp}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">management</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-management"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{assignorder.requiredWorkload.management}}%"
|
||||
>
|
||||
{{assignorder.requiredWorkload.management}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Attributes
|
||||
</h2>
|
||||
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Relevant Attribute</th>
|
||||
<th scope="col">Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Remaining Rounds</th>
|
||||
<td>{{assignorder.maxRounds}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Model</th>
|
||||
<td>{{assignorder.engineeringModel}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Assign
|
||||
</h2>
|
||||
<form
|
||||
class="m-2"
|
||||
action="{% url 'companyOrder' gameid=game.id username=user.username orderid=assignorder.id %}"
|
||||
method="post"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Unassigned Workers</th>
|
||||
<th scope="col">Assigned Workers</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
{% for worker in company.workers.all %} {%if worker.sick == True%}
|
||||
<div class="m-2">
|
||||
<label for="assign {{worker.id}}">
|
||||
{{worker.name}}({{worker.skilledModels}})</label
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="assign {{worker.id}}"
|
||||
name="assign {{worker.id}}"
|
||||
value="{{worker.id}}"
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
{% elif worker.status == 1 %}
|
||||
<div class="m-2">
|
||||
<label for="assign {{worker.id}}">
|
||||
{{worker.name}} ({{worker.skilledModels}})</label
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="assign {{worker.id}}"
|
||||
name="assign {{worker.id}}"
|
||||
value="{{worker.id}}"
|
||||
/>
|
||||
</div>
|
||||
{% endif %} {% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{% for worker in assignorder.assignedWorkers.all %}
|
||||
<div class="m-2">
|
||||
<label for="{{worker.id}}">
|
||||
{{worker.name}} ({{worker.skilledModels}})</label
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="unassign {{worker.id}}"
|
||||
name="unassign {{worker.id}}"
|
||||
value="{{worker.id}}"
|
||||
/>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-success m-2"
|
||||
type="submit"
|
||||
name="action"
|
||||
id="save assignment"
|
||||
value="save assignment"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,559 @@
|
||||
{%load static%}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
height: 75%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.col-coloring {
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
.bottom-row {
|
||||
background-color: #333;
|
||||
color: white;
|
||||
height: 20%;
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: #333;
|
||||
color: white;
|
||||
justify-content: space-evenly;
|
||||
height: 5%;
|
||||
width: 100%;
|
||||
}
|
||||
.viewlinker {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.hovering {
|
||||
}
|
||||
.hovering:hover {
|
||||
background-color: grey;
|
||||
}
|
||||
</style>
|
||||
<title>Company</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var currentURL = window.location.href;
|
||||
var urlSplit = currentURL.split("/");
|
||||
var indexCompany = urlSplit.indexOf("company");
|
||||
var gameid = urlSplit[indexCompany + 1];
|
||||
var url =
|
||||
"ws://" + window.location.host + "/mygame/company/" + gameid + "/";
|
||||
var socket = new WebSocket(url);
|
||||
|
||||
socket.onmessage = function (event) {
|
||||
if (event.data === "nextRound") {
|
||||
document.getElementById("nextRoundForm").submit();
|
||||
} else if (event.data === "endGame") {
|
||||
document.getElementById("endGameForm").submit();
|
||||
} else {
|
||||
var timerDiv = document.getElementById("timer");
|
||||
timerDiv.innerHTML = event.data;
|
||||
}
|
||||
};
|
||||
|
||||
socket.onopen = function () {
|
||||
console.log("Socket opened");
|
||||
};
|
||||
|
||||
socket.onclose = function () {
|
||||
console.log("Socket closed");
|
||||
};
|
||||
|
||||
socket.onerror = function (error) {
|
||||
console.log("Socket error:");
|
||||
};
|
||||
</script>
|
||||
<div
|
||||
class="header row align-items-center text-center justify-content-evenly g-0"
|
||||
>
|
||||
<div class="col-md">{{company.name}}</div>
|
||||
<div class="col-md">
|
||||
<form
|
||||
action="{% url 'companyEvent' gameid=game.id username=user.username eventnumber=0%}"
|
||||
method="get"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<input
|
||||
class="btn btn-primary"
|
||||
type="submit"
|
||||
value="E-Mails"
|
||||
id="viewgamerules"
|
||||
name="action"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-md">Money: {{company.money}}</div>
|
||||
<div class="col-md">
|
||||
Customer Satisfaction: {{company.customersatisfaction}}
|
||||
</div>
|
||||
<div class="col-md">
|
||||
Worker Satisfaction: {{company.workersatisfaction}}
|
||||
</div>
|
||||
<div class="col-md">Round: {{game.currentRound}}/{{game.maxRounds}}</div>
|
||||
{% if game.running == True%}
|
||||
<div class="timer col-md" id="timer">Timer:</div>
|
||||
{% else %}
|
||||
<div class="col-md">Game didn't start yet</div>
|
||||
{%endif%}
|
||||
</div>
|
||||
<form
|
||||
id="nextRoundForm"
|
||||
action="{% url 'companyEvent' gameid=game.id username=user.username eventnumber=0%}"
|
||||
method="get"
|
||||
style="display: none"
|
||||
>
|
||||
{% csrf_token %}
|
||||
</form>
|
||||
<form
|
||||
id="endGameForm"
|
||||
action="{% url 'standings' gameid=game.id username=user.username%}"
|
||||
method="get"
|
||||
style="display: none"
|
||||
>
|
||||
{% csrf_token %}
|
||||
</form>
|
||||
|
||||
<!-- Zeile für den oberen Inhalt -->
|
||||
<div class="container-fluid g-0">
|
||||
<div class="col-md-4 col-coloring overflow-y-auto">
|
||||
<div class="row justify-content-evenly g-0">
|
||||
<div class="col-md-6 p-3">
|
||||
<!-- Inhalt links Zeile 1 -->
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 shadow rounded"
|
||||
>
|
||||
Workers
|
||||
</h1>
|
||||
{%for worker in company.workers.all%}
|
||||
<a
|
||||
class="viewlinker"
|
||||
href="{% url 'companyWorker' gameid=game.id username=user.username workerid=worker.id %}"
|
||||
>
|
||||
<div
|
||||
class="card border-primary mb-3 shadow-lg"
|
||||
style="max-width: 540px"
|
||||
>
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4 align-self-center">
|
||||
<img
|
||||
src="{% static 'mygame/images/worker01.png' %}"
|
||||
class="img-thumbnail"
|
||||
alt="worker"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title justify-content-evenly">
|
||||
{{worker.name}} {%if worker.sick == True%}
|
||||
<p class="text-danger">[sick]</p>
|
||||
{%elif worker.status == 2%}
|
||||
<p class="text-success">[working]</p>
|
||||
{%elif worker.status == 3%}
|
||||
<p class="text-warning">[training]</p>
|
||||
{%endif%}
|
||||
</h5>
|
||||
<div
|
||||
class="progress mb-2"
|
||||
role="progressbar"
|
||||
aria-label="worker-happyness"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
{%if worker.happyness > 55 %}
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark bg-success"
|
||||
style="width: {{worker.happyness}}%"
|
||||
>
|
||||
happyness
|
||||
</div>
|
||||
{% else%}
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark bg-danger"
|
||||
style="width: {{worker.happyness}}%"
|
||||
>
|
||||
happyness
|
||||
</div>
|
||||
{%endif%}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-experience"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{worker.attributes.experience}}%"
|
||||
>
|
||||
experience
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-reliability"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{worker.attributes.reliability}}%"
|
||||
>
|
||||
reliability
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-python"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{worker.attributes.python}}%"
|
||||
>
|
||||
python
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-javascript"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{worker.attributes.javascript}}%"
|
||||
>
|
||||
javascript
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-cpp"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{worker.attributes.cpp}}%"
|
||||
>
|
||||
cpp
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-management"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{worker.attributes.management}}%"
|
||||
>
|
||||
management
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{%endfor%}
|
||||
</div>
|
||||
<div class="col-md-6 p-3">
|
||||
<!-- Inhalt links Zeile 2 -->
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 shadow rounded"
|
||||
>
|
||||
Orders
|
||||
</h1>
|
||||
{%for order in company.orders.all%}
|
||||
<a
|
||||
class="viewlinker"
|
||||
href="{% url 'companyOrder' gameid=game.id username=user.username orderid=order.id %}"
|
||||
>
|
||||
<!-- Quelle Bild https://pixabay.com/de/vectors/ausr%C3%BCstung-symbol-service-aufbau-1674891/-->
|
||||
|
||||
<div
|
||||
class="card border-primary mb-3 shadow-lg"
|
||||
style="
|
||||
max-width: 540px;
|
||||
background-image: url('{%static 'mygame/images/order.png'%}');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
"
|
||||
>
|
||||
<div class="row g-0">
|
||||
<div class="col-md-12">
|
||||
<div class="card-body">
|
||||
<h5
|
||||
class="card-title border-bottom font-weight-bold fs-4"
|
||||
>
|
||||
{{order.name}}
|
||||
</h5>
|
||||
<div class="card-text fs-5">
|
||||
<p>Model: {{order.engineeringModel}}</p>
|
||||
<p>Profit: {{order.profit}}</p>
|
||||
<p>Rounds left: {{order.maxRounds}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{%endfor%}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 overflow-y-auto g-0">
|
||||
<!-- Inhalt mittlerer Block -->
|
||||
<div>{% block content %}{% endblock %}</div>
|
||||
</div>
|
||||
<div class="col-md-4 col-coloring overflow-y-auto">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-6 p-3">
|
||||
<!-- Inhalt rechts Zeile 1 -->
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 shadow rounded fs-2"
|
||||
>
|
||||
Workermarket
|
||||
</h1>
|
||||
{%for worker in company.workermarket.all%}
|
||||
<a
|
||||
class="viewlinker"
|
||||
href="{% url 'companyWorker' gameid=game.id username=user.username workerid=worker.id %}"
|
||||
>
|
||||
<div
|
||||
class="card border-primary mb-3 shadow-lg"
|
||||
style="max-width: 540px"
|
||||
>
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4 align-self-center">
|
||||
<img
|
||||
src="{% static 'mygame/images/worker01.png' %}"
|
||||
class="img-thumbnail"
|
||||
alt="worker"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{worker.name}}</h5>
|
||||
<div class="row"><p>{{worker.skilledModels}}</p></div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-experience"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{worker.attributes.experience}}%"
|
||||
>
|
||||
experience
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-reliability"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{worker.attributes.reliability}}%"
|
||||
>
|
||||
reliability
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-python"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{worker.attributes.python}}%"
|
||||
>
|
||||
python
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-javascript"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{worker.attributes.javascript}}%"
|
||||
>
|
||||
javascript
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-cpp"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{worker.attributes.cpp}}%"
|
||||
>
|
||||
cpp
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-management"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{worker.attributes.management}}%"
|
||||
>
|
||||
management
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{%endfor%}
|
||||
</div>
|
||||
<div class="col-md-6 p-3">
|
||||
<!-- Inhalt rechts Zeile 2 -->
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 shadow rounded fs-2"
|
||||
>
|
||||
Ordermarket
|
||||
</h1>
|
||||
{%for order in game.ordermarket.all%}
|
||||
<a
|
||||
class="viewlinker"
|
||||
href="{% url 'companyOrder' gameid=game.id username=user.username orderid=order.id %}"
|
||||
>
|
||||
<!-- Quelle Bild https://pixabay.com/de/vectors/ausr%C3%BCstung-symbol-service-aufbau-1674891/-->
|
||||
<div
|
||||
class="card border-primary mb-3 shadow-lg"
|
||||
style="
|
||||
max-width: 540px;
|
||||
background-image: url('{%static 'mygame/images/order.png'%}');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
"
|
||||
>
|
||||
<div class="row g-0">
|
||||
<div class="col-md-12">
|
||||
<div class="card-body">
|
||||
<h5
|
||||
class="card-title border-bottom font-weight-bold fs-4"
|
||||
>
|
||||
{{order.name}}
|
||||
</h5>
|
||||
<div class="card-text fs-5">
|
||||
<p>estimated profit: {{order.profit}}</p>
|
||||
<p>max. rounds: {{order.maxRounds}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{%endfor%}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Zeile für den unteren Inhalt -->
|
||||
<div class="bottom-row text-center">
|
||||
<h1>Actions</h1>
|
||||
<div class="row g-0">
|
||||
{%for action in company.actions.all%}
|
||||
<div class="col-md-3">
|
||||
<a
|
||||
class="viewlinker"
|
||||
href="{% url 'companyAction' gameid=game.id username=user.username actionid=action.id%}"
|
||||
>
|
||||
<div class="text-light border border-white p-1 m-1 rounded">
|
||||
{{action.name}}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{%endfor%}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap einbinden -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,102 @@
|
||||
{% extends "mygame/company.html" %} {% block content %} {% load filters %}
|
||||
<div>
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 m-3 shadow rounded"
|
||||
>
|
||||
E-Mails
|
||||
</h1>
|
||||
|
||||
<form
|
||||
class="row g-0 justify-content-evenly m-2"
|
||||
action="{% url 'companyEvent' gameid=game.id username=user.username eventnumber=eventnumber%}"
|
||||
method="post"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<div class="col-md-6">
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-primary btn-block m-2"
|
||||
type="submit"
|
||||
value="previous"
|
||||
id="previous"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-primary btn-block m-2"
|
||||
type="submit"
|
||||
value="next"
|
||||
id="next"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div
|
||||
class="row g-0 justify-content-center border border-secondary-subtle rounded m-3"
|
||||
>
|
||||
<div class="col-md-10">
|
||||
<h2
|
||||
class="border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
{{companyevent.name}}
|
||||
</h2>
|
||||
</div>
|
||||
<div class="col-md-9 m-4">{{companyevent.description}}</div>
|
||||
|
||||
{%if companyevent.modelset == False%}
|
||||
<form
|
||||
class="col-md-8"
|
||||
action="{% url 'companyEventSetModel' gameid=game.id username=user.username eventid=companyevent.id modelnumber=0%}"
|
||||
method="post"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-warning btn-block m-2"
|
||||
type="submit"
|
||||
value="choose model"
|
||||
id="choose model"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
{%endif%} {% if companyevent|isInstanceOf:"SpecialOrder" %}
|
||||
<form
|
||||
class="row g-0 justify-content-evenly m-2"
|
||||
action="{% url 'companySpecialOrder' gameid=game.id username=user.username specialorderid=companyevent.id%}"
|
||||
method="post"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-4">
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-success btn-block m-2"
|
||||
type="submit"
|
||||
value="handle"
|
||||
id="handle"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-danger btn-block m-2"
|
||||
type="submit"
|
||||
value="ignore"
|
||||
id="ignore"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{%endif%}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,103 @@
|
||||
{% extends "mygame/company.html" %} {% block content %}
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 m-3 shadow rounded"
|
||||
>
|
||||
Model: {{engineeringmodel.name}}
|
||||
</h1>
|
||||
<form
|
||||
class="row g-0 justify-content-evenly m-2"
|
||||
action="{% url 'companyEventSetModel' gameid=game.id username=user.username eventid=eventid modelnumber=modelnumber%}"
|
||||
method="post"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<div class="col-md-6">
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-primary btn-block m-2"
|
||||
type="submit"
|
||||
value="previous"
|
||||
id="previous"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-primary btn-block m-2"
|
||||
type="submit"
|
||||
value="next"
|
||||
id="next"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Description
|
||||
</h2>
|
||||
<div class="row g-0 justify-content-center m-2 mt-4 mb-4">
|
||||
<div class="d-grid gap-2">
|
||||
<button
|
||||
class="btn btn-info"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseDescription"
|
||||
aria-expanded="false"
|
||||
aria-controls="collapseDescription"
|
||||
>
|
||||
View Description
|
||||
</button>
|
||||
</div>
|
||||
<div class="collapse col-md-9 m-2" id="collapseDescription">
|
||||
<div class="card card-body">{{engineeringmodel.description}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr class="justify-content-center">
|
||||
<th scope="col" class="text-success text-center fs-2">Positives</th>
|
||||
<th scope="col" class="text-danger text-center fs-2">Negatives</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
{%for pro in engineeringmodel.getPros%}
|
||||
<div class="border border-success-subtle rounded p-2 m-2">
|
||||
{{pro}}
|
||||
</div>
|
||||
{%endfor%}
|
||||
</td>
|
||||
<td>
|
||||
{%for con in engineeringmodel.getCons%}
|
||||
<div class="border border-danger-subtle rounded p-2 m-2">{{con}}</div>
|
||||
{%endfor%}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<form
|
||||
class="row g-0 justify-content-evenly m-2"
|
||||
action="{% url 'companyEventSetModel' gameid=game.id username=user.username eventid=eventid modelnumber=modelnumber%}"
|
||||
method="post"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-warning"
|
||||
type="submit"
|
||||
value="set model"
|
||||
id="set model"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,170 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lobby</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css"
|
||||
/>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
/* Stil für den Kopfbereich */
|
||||
.header {
|
||||
background-color: #333;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Stil für die Buttons im Kopfbereich */
|
||||
.header button {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
background-color: lightgray;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Kopfzeile mit Buttons -->
|
||||
<div class="header">
|
||||
<div class="row g-0 align-items-center">
|
||||
<div class="col-md-6">
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 shadow rounded"
|
||||
>
|
||||
Gamelobby for {{game.name}}
|
||||
</h1>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{%if game.gamemaster == user.username%}
|
||||
|
||||
<form
|
||||
class="m-2"
|
||||
action="{% url 'startGame' gameid=game.id username=user.username%}"
|
||||
method="post"
|
||||
>
|
||||
{% csrf_token %}
|
||||
|
||||
<input
|
||||
class="btn btn-success col-md-12"
|
||||
type="submit"
|
||||
value="start game"
|
||||
id="startGame"
|
||||
name="action"
|
||||
/>
|
||||
</form>
|
||||
{%else%}
|
||||
<form
|
||||
class="m-2"
|
||||
action="{% url 'gamerules' gameid=game.id%}"
|
||||
method="get"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<input
|
||||
class="btn btn-primary col-md-12"
|
||||
type="submit"
|
||||
value="view gamerules"
|
||||
id="viewgamerules"
|
||||
name="action"
|
||||
/>
|
||||
</form>
|
||||
{%endif%}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid overflow-y-auto">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1
|
||||
class="col-md-6 bg-secondary-subtle text-center font-weight-bold border-bottom border-2 border-primary p-3 mt-3 shadow rounded"
|
||||
>
|
||||
Game ID: {{game.id}}
|
||||
</h1>
|
||||
<h1
|
||||
class="col-md-6 bg-secondary-subtle text-center font-weight-bold border-bottom border-2 border-primary p-3 mt-3 shadow rounded"
|
||||
>
|
||||
Gamemaster: {{game.gamemaster}}
|
||||
</h1>
|
||||
<ul class="list-group mb-3">
|
||||
<li class="list-group-item bg-secondary-subtle">
|
||||
<h1
|
||||
class="text-center bg-secondary-subtle font-weight-bold border-bottom border-2 border-primary p-3 mt-3 shadow rounded"
|
||||
>
|
||||
Joined Players:
|
||||
</h1>
|
||||
</li>
|
||||
{%for player in game.participants.all%}
|
||||
|
||||
<li class="list-group-item bg-secondary-subtle fs-4">
|
||||
{{player.name}}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<h1
|
||||
class="text-center bg-secondary-subtle font-weight-bold border-bottom border-2 border-primary p-3 mt-3 shadow rounded"
|
||||
>
|
||||
Gamesettings:
|
||||
</h1>
|
||||
{%if game.gamemaster == user.username%}
|
||||
<form
|
||||
action="{% url 'lobby' gameid=game.id username=user.username%}"
|
||||
method="post"
|
||||
>
|
||||
{% csrf_token %}
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item bg-secondary-subtle">
|
||||
Number of rounds: {{ gamesettingsform.rounds }}
|
||||
</li>
|
||||
<li class="list-group-item bg-secondary-subtle">
|
||||
Roundtimer: {{ gamesettingsform.timer }}
|
||||
</li>
|
||||
<li class="list-group-item bg-secondary-subtle">
|
||||
Ordermarket size: {{ gamesettingsform.ordermarketsize }}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="d-grid gap-2 mt-2">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
type="submit"
|
||||
value="changesettings"
|
||||
id="changesettings"
|
||||
name="action"
|
||||
>
|
||||
save settings
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{%else%}
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item bg-secondary-subtle">
|
||||
Number of rounds: {{gamesettingsform.rounds.initial}}
|
||||
</li>
|
||||
<li class="list-group-item bg-secondary-subtle">
|
||||
Roundtimer: {{gamesettingsform.timer.initial}}
|
||||
</li>
|
||||
<li class="list-group-item bg-secondary-subtle">
|
||||
Ordermarket size: {{gamesettingsform.ordermarketsize.initial}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{%endif%}
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Login</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css"
|
||||
/>
|
||||
<style>
|
||||
body {
|
||||
background-color: grey;
|
||||
}
|
||||
.container {
|
||||
padding: 20px;
|
||||
background-color: lightblue;
|
||||
border: 2px solid black;
|
||||
text-align: center;
|
||||
}
|
||||
.errormessage {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="body">
|
||||
<div class="container">
|
||||
{%if error_message%}
|
||||
<div class="errormessage">{{error_message}}</div>
|
||||
{% endif %}
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 m-3 shadow rounded"
|
||||
>
|
||||
Login
|
||||
</h1>
|
||||
<form
|
||||
class="row g-0 justify-content-center"
|
||||
action="{% url 'loginView' %}"
|
||||
method="post"
|
||||
>
|
||||
{% csrf_token %} {%for field in form%}
|
||||
<div class="col-md-12 fs-3">{{field.label}}</div>
|
||||
<div class="col-md-12 m-2">{{field}}</div>
|
||||
{%endfor%}
|
||||
<div class="col-md-6 m-2">
|
||||
<button type="submit" class="col-md-12 btn btn-primary">
|
||||
Start!
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,247 @@
|
||||
{% extends "mygame/company.html" %} {% block content %}
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 m-3 shadow rounded"
|
||||
>
|
||||
Order: {{viewedorder.name}}
|
||||
</h1>
|
||||
{%if errormessage%}
|
||||
<div class="m-2 pb-0 text-center text-light bg-danger rounded">
|
||||
{{errormessage}}
|
||||
</div>
|
||||
{%endif%}
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Workload
|
||||
</h2>
|
||||
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Required Skill</th>
|
||||
<th scope="col">Workload</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">experience</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-experience"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedorder.requiredWorkload.experience}}%"
|
||||
>
|
||||
{{viewedorder.requiredWorkload.experience}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">reliability</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-reliability"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedorder.requiredWorkload.reliability}}%"
|
||||
>
|
||||
{{viewedorder.requiredWorkload.reliability}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">python</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-python"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedorder.requiredWorkload.python}}%"
|
||||
>
|
||||
{{viewedorder.requiredWorkload.python}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">javascript</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-javascript"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedorder.requiredWorkload.javascript}}%"
|
||||
>
|
||||
{{viewedorder.requiredWorkload.javascript}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">cpp</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-cpp"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedorder.requiredWorkload.cpp}}%"
|
||||
>
|
||||
{{viewedorder.requiredWorkload.cpp}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">management</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-management"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedorder.requiredWorkload.management}}%"
|
||||
>
|
||||
{{viewedorder.requiredWorkload.management}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Attributes
|
||||
</h2>
|
||||
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Attribute</th>
|
||||
<th scope="col">Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
{%if viewedorder.status == 0%}
|
||||
<th scope="row">Estimated Profit</th>
|
||||
{%else%}
|
||||
<th scope="row">Profit</th>
|
||||
{% endif%}
|
||||
<td>{{viewedorder.profit}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
{%if viewedorder.status == 0%}
|
||||
<th scope="row">Maximum Rounds</th>
|
||||
{%else%}
|
||||
<th scope="row">Rounds left</th>
|
||||
{% endif%}
|
||||
<td>{{viewedorder.maxRounds}}</td>
|
||||
</tr>
|
||||
{%if viewedorder.status == 1%}
|
||||
|
||||
<tr>
|
||||
<th scope="row">Engineeringmodel</th>
|
||||
<td>{{viewedorder.engineeringModel}}</td>
|
||||
</tr>
|
||||
{% endif%}
|
||||
<tr>
|
||||
<th scope="row">Customer Description</th>
|
||||
<td>{{viewedorder.specialorder.hint}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<form
|
||||
class="row g-0 justify-content-evenly m-2"
|
||||
action="{% url 'companyOrder' gameid=game.id username=user.username orderid=viewedorder.id %}"
|
||||
method="post"
|
||||
>
|
||||
{% csrf_token %} {%if viewedorder.status == 0 %}
|
||||
<div class="row g-0 justify-content-evenly">
|
||||
<div class="col-md-6 p-2">
|
||||
<input
|
||||
class="form-control"
|
||||
type="number"
|
||||
placeholder="Insert your Offer"
|
||||
id="offerfield"
|
||||
name="offerfield"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6 p-2">
|
||||
<input
|
||||
class="btn btn-primary w-100"
|
||||
type="submit"
|
||||
value="offer"
|
||||
id="offer"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{%elif viewedorder.status == 1 %}
|
||||
<div class="col-md-6">
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-danger btn-block m-2"
|
||||
type="submit"
|
||||
value="cancel"
|
||||
id="cancel"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-success btn-block m-2"
|
||||
type="submit"
|
||||
value="assign resources"
|
||||
id="assign resources"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{%endif%}
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Standings</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css"
|
||||
/>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #e6f2ff;
|
||||
}
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 m-3 shadow rounded"
|
||||
>
|
||||
Leaderboard for {{game.name}}
|
||||
</h1>
|
||||
<table class="table table-striped p-3 m-3 shadow rounded">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Place</th>
|
||||
<th scope="col">Company</th>
|
||||
<th scope="col">Money</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%for item in leaderboard%}
|
||||
<div>
|
||||
<tr>
|
||||
<td>{{item.0}}</td>
|
||||
<td>{{item.1.name}}</td>
|
||||
<td>{{item.1.money}}$</td>
|
||||
</tr>
|
||||
</div>
|
||||
{%endfor%}
|
||||
</tbody>
|
||||
</table>
|
||||
<div>Please complete the following Survey:</div>
|
||||
<a href="https://www.survio.com/survey/d/V6G8P1V8W7N1Z6E3Y">Survey</a>
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,248 @@
|
||||
{% extends "mygame/company.html" %} {% block content %}
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 m-3 shadow rounded"
|
||||
>
|
||||
Training: {{trainworker.name}}
|
||||
</h1>
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Description
|
||||
</h2>
|
||||
<div class="row g-0 justify-content-center m-2">
|
||||
<div class="col-md-12 m-2 p-2 border border-secondary-subtle rounded">
|
||||
<p>Choose a skill that you want to train (add 10 points).</p>
|
||||
<p class="text-danger">
|
||||
The worker will be blocked from working on orders for one round!
|
||||
</p>
|
||||
</div>
|
||||
<form
|
||||
action="{% url 'companyTraining' gameid=game.id username=user.username workerid=trainworker.id %}"
|
||||
method="post"
|
||||
>
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Skill</th>
|
||||
<th scope="col">Strength</th>
|
||||
<th scope="col">Selection</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">experience</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress align-self-center"
|
||||
role="progressbar"
|
||||
aria-label="worker-experience"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{trainworker.attributes.experience}}%"
|
||||
>
|
||||
{{trainworker.attributes.experience}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="trainskill"
|
||||
id="experienceRadio"
|
||||
value="experience"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<label class="btn btn-outline-primary" for="experienceRadio"
|
||||
>train</label
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">reliability</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress align-self-center"
|
||||
role="progressbar"
|
||||
aria-label="worker-reliability"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{trainworker.attributes.reliability}}%"
|
||||
>
|
||||
{{trainworker.attributes.reliability}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="trainskill"
|
||||
id="reliabilityRadio"
|
||||
value="reliability"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<label class="btn btn-outline-primary" for="reliabilityRadio"
|
||||
>train</label
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">python</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress align-self-center"
|
||||
role="progressbar"
|
||||
aria-label="worker-python"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{trainworker.attributes.python}}%"
|
||||
>
|
||||
{{trainworker.attributes.python}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="trainskill"
|
||||
id="pythonRadio"
|
||||
value="python"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<label class="btn btn-outline-primary" for="pythonRadio"
|
||||
>train</label
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">javascript</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress align-self-center"
|
||||
role="progressbar"
|
||||
aria-label="worker-javascript"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{trainworker.attributes.javascript}}%"
|
||||
>
|
||||
{{trainworker.attributes.javascript}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="trainskill"
|
||||
id="javascriptRadio"
|
||||
value="javascript"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<label class="btn btn-outline-primary" for="javascriptRadio"
|
||||
>train</label
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">cpp</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress align-self-center"
|
||||
role="progressbar"
|
||||
aria-label="worker-cpp"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{trainworker.attributes.cpp}}%"
|
||||
>
|
||||
{{trainworker.attributes.cpp}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="trainskill"
|
||||
id="cppRadio"
|
||||
value="cpp"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<label class="btn btn-outline-primary" for="cppRadio"
|
||||
>train</label
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">management</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress align-self-center"
|
||||
role="progressbar"
|
||||
aria-label="worker-management"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{trainworker.attributes.management}}%"
|
||||
>
|
||||
{{trainworker.attributes.management}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="trainskill"
|
||||
id="managementRadio"
|
||||
value="management"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<label class="btn btn-outline-primary" for="managementRadio"
|
||||
>train</label
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<input
|
||||
class="btn btn-success"
|
||||
type="submit"
|
||||
value="start training"
|
||||
id="start training"
|
||||
name="action"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,243 @@
|
||||
{% extends "mygame/company.html" %} {% block content %}
|
||||
<h1
|
||||
class="text-center font-weight-bold border-bottom border-2 border-primary p-3 m-3 shadow rounded"
|
||||
>
|
||||
Worker: {{viewedworker.name}}
|
||||
</h1>
|
||||
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Skills
|
||||
</h2>
|
||||
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Skill</th>
|
||||
<th scope="col">Strength</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">experience</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-experience"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedworker.attributes.experience}}%"
|
||||
>
|
||||
{{viewedworker.attributes.experience}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">reliability</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-reliability"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedworker.attributes.reliability}}%"
|
||||
>
|
||||
{{viewedworker.attributes.reliability}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">python</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-python"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedworker.attributes.python}}%"
|
||||
>
|
||||
{{viewedworker.attributes.python}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">javascript</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-javascript"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedworker.attributes.javascript}}%"
|
||||
>
|
||||
{{viewedworker.attributes.javascript}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">cpp</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-cpp"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedworker.attributes.cpp}}%"
|
||||
>
|
||||
{{viewedworker.attributes.cpp}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">management</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-management"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedworker.attributes.management}}%"
|
||||
>
|
||||
{{viewedworker.attributes.management}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<h2
|
||||
class="col-md-4 border-bottom border-1 border-primary p-2 m-2 mt-4 shadow rounded text-center"
|
||||
>
|
||||
Attributes
|
||||
</h2>
|
||||
<div class="m-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Attribute</th>
|
||||
<th scope="col">Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">Skilled Model</th>
|
||||
<td>{{viewedworker.skilledModels}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Amplifyer</th>
|
||||
<td>{{viewedworker.amplifyer}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Salary</th>
|
||||
<td>{{viewedworker.salary}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Happyness</th>
|
||||
<td>
|
||||
<div
|
||||
class="progress"
|
||||
role="progressbar"
|
||||
aria-label="worker-management"
|
||||
aria-valuenow="0"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
>
|
||||
<div
|
||||
class="progress-bar overflow-visible text-dark"
|
||||
style="width: {{viewedworker.happyness}}%"
|
||||
>
|
||||
{{viewedworker.happyness}}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<form
|
||||
action="{% url 'companyWorker' gameid=game.id username=user.username workerid=viewedworker.id %}"
|
||||
method="post"
|
||||
>
|
||||
<div class="d-grid gap-2">
|
||||
{% csrf_token %} {%if viewedworker.status == 0 %}
|
||||
<input
|
||||
class="btn btn-primary m-2"
|
||||
type="submit"
|
||||
value="hire"
|
||||
id="hire"
|
||||
name="action"
|
||||
/>
|
||||
{%elif viewedworker.status == 2 or viewedworker.status == 3 %}
|
||||
<input
|
||||
class="btn btn-danger m-2"
|
||||
type="submit"
|
||||
value="fire"
|
||||
id="fire"
|
||||
name="action"
|
||||
disabled="True"
|
||||
/>
|
||||
<input
|
||||
class="btn btn-primary m-2 mt-0"
|
||||
type="submit"
|
||||
value="train"
|
||||
id="train"
|
||||
name="action"
|
||||
disabled="True"
|
||||
/>
|
||||
{%else%}
|
||||
<input
|
||||
class="btn btn-danger m-2"
|
||||
type="submit"
|
||||
value="fire"
|
||||
id="fire"
|
||||
name="action"
|
||||
/>
|
||||
<input
|
||||
class="btn btn-primary m-2 mt-0"
|
||||
type="submit"
|
||||
value="train"
|
||||
id="train"
|
||||
name="action"
|
||||
/>
|
||||
{%endif%}
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,11 @@
|
||||
from django import template
|
||||
from mygame.backend.event import SpecialOrder
|
||||
|
||||
register = template.Library()
|
||||
|
||||
#so kann man isinstance im frontend nutzen
|
||||
# (KLASSEN DIE MAN FILTERN WILL IMPORTIEREN)
|
||||
@register.filter
|
||||
def isInstanceOf(value, classname):
|
||||
classobject = eval(classname)
|
||||
return isinstance(value, classobject)
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
@@ -0,0 +1,51 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.loginView, name="loginView"),
|
||||
path("lobby/<int:gameid>/<str:username>", views.lobby, name="lobby"),
|
||||
path("gamerules/<int:gameid>/", views.gamerules, name="gamerules"),
|
||||
path(
|
||||
"company/<int:gameid>/<str:username>/startGame/",
|
||||
views.startGame,
|
||||
name="startGame",
|
||||
),
|
||||
path(
|
||||
"company/<int:gameid>/<str:username>/worker/<int:workerid>/",
|
||||
views.companyWorker,
|
||||
name="companyWorker",
|
||||
),
|
||||
path(
|
||||
"company/<int:gameid>/<str:username>/order/<int:orderid>/",
|
||||
views.companyOrder,
|
||||
name="companyOrder",
|
||||
),
|
||||
path(
|
||||
"company/<int:gameid>/<str:username>/training/<int:workerid>/",
|
||||
views.companyTraining,
|
||||
name="companyTraining",
|
||||
),
|
||||
path(
|
||||
"company/<int:gameid>/<str:username>/action/<int:actionid>/",
|
||||
views.companyAction,
|
||||
name="companyAction",
|
||||
),
|
||||
path(
|
||||
"company/<int:gameid>/<str:username>/events/<int:eventnumber>/",
|
||||
views.companyEvent,
|
||||
name="companyEvent",
|
||||
),
|
||||
path(
|
||||
"company/<int:gameid>/<str:username>/setModel/<int:eventid>/<int:modelnumber>",
|
||||
views.companyEventSetModel,
|
||||
name="companyEventSetModel",
|
||||
),
|
||||
path(
|
||||
"company/<int:gameid>/<str:username>/specialorder/<int:specialorderid>/",
|
||||
views.companySpecialOrder,
|
||||
name="companySpecialOrder",
|
||||
),
|
||||
path("company/<int:gameid>/<str:username>/", views.company, name="company"),
|
||||
path("standings/<int:gameid>/<str:username>/", views.standings, name="standings"),
|
||||
]
|
||||
@@ -0,0 +1,479 @@
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.urls import reverse
|
||||
from mygame.forms import *
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import authenticate, login
|
||||
from django.shortcuts import redirect
|
||||
import time
|
||||
|
||||
from mygame.backend.engineeringmodel import EngineeringModel
|
||||
from .backend.game import Game
|
||||
from .backend.timer import Timer
|
||||
from .backend.company import Company
|
||||
from .backend.worker import Worker
|
||||
from .backend.order import Order
|
||||
from .backend.action import Action
|
||||
from .backend.game import Game
|
||||
from .backend.engineeringmodel import EngineeringModel
|
||||
from .backend.event import Event, SpecialOrder
|
||||
|
||||
|
||||
def loginView(request):
|
||||
if request.method == "POST":
|
||||
try:
|
||||
form = LoginForm(request.POST)
|
||||
if form.is_valid():
|
||||
username = form.cleaned_data["username"]
|
||||
gameid = form.cleaned_data["game_id"]
|
||||
password = form.cleaned_data["password"]
|
||||
choice = form.cleaned_data["create_join_game"]
|
||||
|
||||
# Create oder Join angewählt?
|
||||
if choice == "1":
|
||||
lobby = Game.objects.get(id=int(gameid))
|
||||
|
||||
else:
|
||||
timer = Timer.objects.create()
|
||||
lobby, created = Game.objects.get_or_create(
|
||||
name=username + "'s Game", gamemaster=username
|
||||
)
|
||||
lobby.timer = timer
|
||||
lobby.save()
|
||||
gameid = lobby.id
|
||||
|
||||
# Checken ob username existiert:
|
||||
# Wenn Ja und passwort stimmt -> einloggen
|
||||
# Wenn Ja und passwort flasch -> Fehler
|
||||
# Wenn nein -> username mit passwort erstellen
|
||||
if User.objects.filter(username=username).exists():
|
||||
user = authenticate(username=username, password=password)
|
||||
if user is not None:
|
||||
login(request, user)
|
||||
|
||||
else:
|
||||
raise NameError("Username already exists!")
|
||||
|
||||
else:
|
||||
user = User.objects.create_user(
|
||||
username=username, password=password
|
||||
)
|
||||
login(request, user)
|
||||
|
||||
company, created = Company.objects.get_or_create(
|
||||
name=username, user=username
|
||||
)
|
||||
lobby.participants.add(company)
|
||||
lobby.save()
|
||||
|
||||
except:
|
||||
error_message = "FEHLER AUFGETRETEN"
|
||||
else:
|
||||
return HttpResponseRedirect(
|
||||
reverse(
|
||||
"lobby",
|
||||
args=(
|
||||
gameid,
|
||||
username,
|
||||
),
|
||||
)
|
||||
)
|
||||
return render(
|
||||
request,
|
||||
"mygame/login.html",
|
||||
{
|
||||
"error_message": error_message,
|
||||
"form": form,
|
||||
},
|
||||
)
|
||||
else:
|
||||
form = LoginForm()
|
||||
return render(request, "mygame/login.html", {"form": form})
|
||||
|
||||
|
||||
def lobby(request, gameid, username):
|
||||
game = get_object_or_404(Game, id=gameid)
|
||||
|
||||
if request.method == "POST":
|
||||
if request.POST.get("action", False) == "clearlobby":
|
||||
game.clearParticipants(username)
|
||||
if request.POST.get("action", False) == "changesettings":
|
||||
gamesettingsform = GamesettingsForm(
|
||||
request.POST,
|
||||
initial={
|
||||
"timer": game.timer.timer,
|
||||
"rounds": game.maxRounds,
|
||||
"ordermarketsize": game.ordermarketsize,
|
||||
},
|
||||
)
|
||||
try:
|
||||
if gamesettingsform.is_valid():
|
||||
game.maxRounds = gamesettingsform.cleaned_data["rounds"]
|
||||
game.ordermarketsize = gamesettingsform.cleaned_data[
|
||||
"ordermarketsize"
|
||||
]
|
||||
game.timer.timer = gamesettingsform.cleaned_data["timer"]
|
||||
game.timer.remainingtimer = gamesettingsform.cleaned_data["timer"]
|
||||
game.save()
|
||||
game.timer.save()
|
||||
except (KeyError, game.DoesNotExist):
|
||||
return render(
|
||||
request,
|
||||
"mygame/lobby.html",
|
||||
{
|
||||
"lobby": game,
|
||||
"gamesettingsform": gamesettingsform,
|
||||
"error_message": "EIN FEHLER IST AUFGETRETEN.",
|
||||
},
|
||||
)
|
||||
# hier errormessages je nach fehler ausgeben
|
||||
else:
|
||||
return HttpResponseRedirect(
|
||||
reverse(
|
||||
"lobby",
|
||||
args=(
|
||||
gameid,
|
||||
username,
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
gamesettingsform = GamesettingsForm(
|
||||
initial={
|
||||
"timer": game.timer.timer,
|
||||
"rounds": game.maxRounds,
|
||||
"ordermarketsize": game.ordermarketsize,
|
||||
}
|
||||
)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"mygame/lobby.html",
|
||||
{"game": game, "gamesettingsform": gamesettingsform},
|
||||
)
|
||||
|
||||
|
||||
def gamerules(request, gameid):
|
||||
game = get_object_or_404(Game, id=gameid)
|
||||
return render(
|
||||
request,
|
||||
"mygame/gamerules.html",
|
||||
{
|
||||
"game": game,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def startGame(request, gameid, username):
|
||||
game = get_object_or_404(Game, id=gameid)
|
||||
game.startGame()
|
||||
return redirect("company", gameid=gameid, username=username)
|
||||
|
||||
|
||||
def company(request, gameid, username):
|
||||
game = get_object_or_404(Game, id=gameid)
|
||||
company = get_object_or_404(Company, user=username)
|
||||
if request.method == "POST":
|
||||
if request.POST["action"] == "next round":
|
||||
gameend = game.processGameround()
|
||||
if gameend:
|
||||
return redirect("standings", gameid=gameid, username=username)
|
||||
else:
|
||||
eventtuple = company.getEvent(0, "default")
|
||||
companyevent = eventtuple[0]
|
||||
eventnumber = eventtuple[1]
|
||||
return render(
|
||||
request,
|
||||
"mygame/email.html",
|
||||
{
|
||||
"game": game,
|
||||
"company": company,
|
||||
"companyevent": companyevent,
|
||||
"eventnumber": eventnumber,
|
||||
},
|
||||
)
|
||||
return render(request, "mygame/company.html", {"game": game, "company": company})
|
||||
|
||||
|
||||
def companyWorker(request, gameid, username, workerid):
|
||||
game = get_object_or_404(Game, id=gameid)
|
||||
company = get_object_or_404(Company, user=username)
|
||||
try:
|
||||
viewedworker = Worker.objects.get(id=workerid)
|
||||
except:
|
||||
return render(
|
||||
request,
|
||||
"mygame/company.html",
|
||||
{"game": game, "company": company},
|
||||
)
|
||||
if request.method == "POST":
|
||||
if request.POST["action"] == "hire":
|
||||
viewedaction = company.actionEmploy(viewedworker)
|
||||
return render(
|
||||
request,
|
||||
"mygame/action.html",
|
||||
{"game": game, "company": company, "viewedaction": viewedaction},
|
||||
)
|
||||
elif request.POST["action"] == "fire":
|
||||
viewedaction = company.actionUnemploy(viewedworker)
|
||||
return render(
|
||||
request,
|
||||
"mygame/action.html",
|
||||
{"game": game, "company": company, "viewedaction": viewedaction},
|
||||
)
|
||||
elif request.POST["action"] == "train":
|
||||
return companyTraining(request, gameid, username, workerid)
|
||||
return render(
|
||||
request,
|
||||
"mygame/worker.html",
|
||||
{"game": game, "company": company, "viewedworker": viewedworker},
|
||||
)
|
||||
|
||||
|
||||
def companyOrder(request, gameid, username, orderid):
|
||||
game = get_object_or_404(Game, id=gameid)
|
||||
company = get_object_or_404(Company, user=username)
|
||||
try:
|
||||
viewedorder = get_object_or_404(Order, id=orderid)
|
||||
except:
|
||||
return render(
|
||||
request,
|
||||
"mygame/company.html",
|
||||
{"game": game, "company": company},
|
||||
)
|
||||
|
||||
if request.method == "POST":
|
||||
if request.POST["action"] == "offer":
|
||||
try:
|
||||
amount = int(request.POST["offerfield"])
|
||||
acceptoffer = viewedorder.checkOffer(amount)
|
||||
if acceptoffer == False:
|
||||
errormessage = "you can only offer 20 percent higher or lower than the estimated profit"
|
||||
return render(
|
||||
request,
|
||||
"mygame/order.html",
|
||||
{
|
||||
"game": game,
|
||||
"company": company,
|
||||
"viewedorder": viewedorder,
|
||||
"errormessage": errormessage,
|
||||
},
|
||||
)
|
||||
except:
|
||||
errormessage = "please enter numbers only"
|
||||
return render(
|
||||
request,
|
||||
"mygame/order.html",
|
||||
{
|
||||
"game": game,
|
||||
"company": company,
|
||||
"viewedorder": viewedorder,
|
||||
"errormessage": errormessage,
|
||||
},
|
||||
)
|
||||
else:
|
||||
viewedaction = company.actionOffer(order=viewedorder, amount=amount)
|
||||
return render(
|
||||
request,
|
||||
"mygame/action.html",
|
||||
{"game": game, "company": company, "viewedaction": viewedaction},
|
||||
)
|
||||
if request.POST["action"] == "assign resources":
|
||||
return render(
|
||||
request,
|
||||
"mygame/assign.html",
|
||||
{"game": game, "company": company, "assignorder": viewedorder},
|
||||
)
|
||||
if request.POST["action"] == "cancel":
|
||||
viewedaction = company.actionCancelOrder(viewedorder)
|
||||
return render(
|
||||
request,
|
||||
"mygame/action.html",
|
||||
{"game": game, "company": company, "viewedaction": viewedaction},
|
||||
)
|
||||
if request.POST["action"] == "save assignment":
|
||||
for worker in company.workers.all():
|
||||
workerid = request.POST.get("assign " + str(worker.id), 0)
|
||||
if workerid != 0:
|
||||
viewedorder.assignWorker(worker)
|
||||
viewedorder.save()
|
||||
workerid = request.POST.get("unassign " + str(worker.id), 0)
|
||||
if workerid != 0:
|
||||
viewedorder.unassignWorker(worker)
|
||||
viewedorder.save()
|
||||
|
||||
return render(
|
||||
request,
|
||||
"mygame/assign.html",
|
||||
{"game": game, "company": company, "assignorder": viewedorder},
|
||||
)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"mygame/order.html",
|
||||
{"game": game, "company": company, "viewedorder": viewedorder},
|
||||
)
|
||||
|
||||
|
||||
def companyTraining(request, gameid, username, workerid):
|
||||
game = get_object_or_404(Game, id=gameid)
|
||||
company = get_object_or_404(Company, user=username)
|
||||
try:
|
||||
trainworker = get_object_or_404(Worker, id=workerid)
|
||||
except:
|
||||
return render(
|
||||
request,
|
||||
"mygame/company.html",
|
||||
{"game": game, "company": company},
|
||||
)
|
||||
|
||||
if request.method == "POST":
|
||||
trainskill = request.POST.get("trainskill", False)
|
||||
if trainskill:
|
||||
viewedaction = company.actionTrain(
|
||||
worker=trainworker, trainskill=trainskill
|
||||
)
|
||||
return render(
|
||||
request,
|
||||
"mygame/action.html",
|
||||
{"game": game, "company": company, "viewedaction": viewedaction},
|
||||
)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"mygame/training.html",
|
||||
{"game": game, "company": company, "trainworker": trainworker},
|
||||
)
|
||||
|
||||
|
||||
def companyAction(request, gameid, username, actionid):
|
||||
game = get_object_or_404(Game, id=gameid)
|
||||
company = get_object_or_404(Company, user=username)
|
||||
# hier schauen welche action es ist dann aus entsprechender table holen
|
||||
try:
|
||||
viewedaction = get_object_or_404(Action, id=actionid)
|
||||
except:
|
||||
return render(
|
||||
request,
|
||||
"mygame/company.html",
|
||||
{"game": game, "company": company},
|
||||
)
|
||||
|
||||
if request.method == "POST":
|
||||
if request.POST["action"] == "cancel":
|
||||
company.cancelAction(id=actionid)
|
||||
return render(
|
||||
request,
|
||||
"mygame/company.html",
|
||||
{"game": game, "company": company},
|
||||
)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"mygame/action.html",
|
||||
{"game": game, "company": company, "viewedaction": viewedaction},
|
||||
)
|
||||
|
||||
|
||||
def companyEvent(request, gameid, username, eventnumber):
|
||||
game = get_object_or_404(Game, id=gameid)
|
||||
company = get_object_or_404(Company, user=username)
|
||||
|
||||
if request.method == "POST":
|
||||
if request.POST.get("action", False) == "previous":
|
||||
eventresult = company.getEvent(eventnumber, "previous")
|
||||
if request.POST.get("action", False) == "next":
|
||||
eventresult = company.getEvent(eventnumber, "next")
|
||||
else:
|
||||
eventresult = company.getEvent(eventnumber, "default")
|
||||
|
||||
companyevent = eventresult[0]
|
||||
eventnumber = eventresult[1]
|
||||
|
||||
return render(
|
||||
request,
|
||||
"mygame/email.html",
|
||||
{
|
||||
"game": game,
|
||||
"company": company,
|
||||
"companyevent": companyevent,
|
||||
"eventnumber": eventnumber,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def companyEventSetModel(request, gameid, username, eventid, modelnumber):
|
||||
game = get_object_or_404(Game, id=gameid)
|
||||
company = get_object_or_404(Company, user=username)
|
||||
engineeringmodels = EngineeringModel.objects.all()
|
||||
|
||||
if request.method == "POST":
|
||||
if request.POST.get("action", False) == "previous":
|
||||
modelnumber -= 1
|
||||
if modelnumber < 0:
|
||||
modelnumber = engineeringmodels.count() - 1
|
||||
engineeringmodel = engineeringmodels[modelnumber]
|
||||
if request.POST.get("action", False) == "next":
|
||||
modelnumber += 1
|
||||
if modelnumber > (engineeringmodels.count() - 1):
|
||||
modelnumber = 0
|
||||
if request.POST.get("action", False) == "set model":
|
||||
eventofferaccepted = Event.objects.get(id=eventid)
|
||||
setmodel = engineeringmodels.order_by("id")[modelnumber]
|
||||
eventofferaccepted.setModel(setmodel)
|
||||
return render(
|
||||
request,
|
||||
"mygame/email.html",
|
||||
{
|
||||
"game": game,
|
||||
"company": company,
|
||||
"companyevent": eventofferaccepted,
|
||||
"eventnumber": 0,
|
||||
},
|
||||
)
|
||||
|
||||
engineeringmodel = engineeringmodels.order_by("id")[modelnumber]
|
||||
|
||||
return render(
|
||||
request,
|
||||
"mygame/engineeringmodel.html",
|
||||
{
|
||||
"game": game,
|
||||
"company": company,
|
||||
"engineeringmodel": engineeringmodel,
|
||||
"modelnumber": modelnumber,
|
||||
"eventid": eventid,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def companySpecialOrder(request, gameid, username, specialorderid):
|
||||
game = get_object_or_404(Game, id=gameid)
|
||||
company = get_object_or_404(Company, user=username)
|
||||
if request.method == "POST":
|
||||
specialorder = SpecialOrder.objects.get(id=specialorderid)
|
||||
for order in company.orders.all():
|
||||
if order.specialorder.id == specialorderid:
|
||||
order = order
|
||||
if request.POST.get("action", False) == "handle":
|
||||
event = specialorder.handle(order=order, company=company, handle=True)
|
||||
|
||||
if request.POST.get("action", False) == "ignore":
|
||||
event = specialorder.handle(order=order, company=company, handle=False)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"mygame/email.html",
|
||||
{"game": game, "company": company, "companyevent": event, "eventnumber": 0},
|
||||
)
|
||||
|
||||
|
||||
def standings(request, gameid, username):
|
||||
game = get_object_or_404(Game, id=gameid)
|
||||
company = get_object_or_404(Company, user=username)
|
||||
leaderboard = game.createLeaderboard()
|
||||
return render(
|
||||
request,
|
||||
"mygame/standings.html",
|
||||
{"game": game, "company": company, "leaderboard": leaderboard},
|
||||
)
|
||||