Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

order.py 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. from django.db import models
  2. from django.core.validators import MaxValueValidator, MinValueValidator
  3. import random
  4. from .names import OrderNames
  5. from .attributeset import AttributeSet
  6. from .engineeringmodel import EngineeringModel
  7. from .worker import Worker
  8. from .offer import Offer
  9. from .event import (
  10. SpecialOrder,
  11. SOChangeRequirement,
  12. SORegularIncrementUpdates,
  13. SOPrototyp,
  14. )
  15. # in attributeset einbauen?
  16. attributelist = [
  17. "experience",
  18. "reliability",
  19. "python",
  20. "javascript",
  21. "cpp",
  22. "management",
  23. ]
  24. # order zum abarbeiten
  25. class Order(models.Model):
  26. name = models.CharField(default="random order", max_length=20)
  27. profit = models.IntegerField(default=1000)
  28. status = models.IntegerField(
  29. default=0, validators=[MinValueValidator(0), MaxValueValidator(1)]
  30. )
  31. maxRounds = models.IntegerField(
  32. default=5, validators=[MinValueValidator(5), MaxValueValidator(100)]
  33. )
  34. requiredWorkload = models.ForeignKey(
  35. AttributeSet, default=1, on_delete=models.CASCADE
  36. )
  37. engineeringModel = models.ForeignKey(
  38. EngineeringModel, default=1, on_delete=models.DO_NOTHING, blank=True
  39. )
  40. assignedWorkers = models.ManyToManyField(Worker, blank=True)
  41. offers = models.ManyToManyField(
  42. Offer,
  43. blank=True,
  44. related_name="order_offers",
  45. )
  46. specialorder = models.ForeignKey(
  47. SpecialOrder, default=1, on_delete=models.CASCADE, blank=True
  48. )
  49. recalculated = models.BooleanField(default=False)
  50. def __str__(self):
  51. return self.name
  52. def getRandomSpecialorder(name):
  53. randnum = random.randint(1, 3)
  54. if randnum == 1:
  55. specialorder = SOPrototyp.createRandom(name)
  56. elif randnum == 2:
  57. specialorder = SOChangeRequirement.createRandom(name)
  58. else:
  59. specialorder = SORegularIncrementUpdates.createRandom(name)
  60. return specialorder
  61. @classmethod
  62. def createRandom(cls):
  63. name = random.choice(OrderNames.objects.all()).name
  64. profit = random.randint(40000, 100000)
  65. maxRounds = round(random.uniform(0.7, 1.3) * (profit / 10000))
  66. requiredWorkload = AttributeSet.createRandom(maxRounds * 13)
  67. engineeringModel = EngineeringModel.objects.all().get(name="ModelChaotic")
  68. specialorder = cls.getRandomSpecialorder(name)
  69. order = cls(
  70. name=name,
  71. profit=profit,
  72. maxRounds=maxRounds,
  73. requiredWorkload=requiredWorkload,
  74. engineeringModel=engineeringModel,
  75. specialorder=specialorder,
  76. )
  77. order.save()
  78. return order
  79. def setStatus(self, status):
  80. self.status = status
  81. self.save()
  82. def assignWorker(self, worker):
  83. worker.setStatus(2)
  84. self.assignedWorkers.add(worker)
  85. def unassignWorker(self, worker):
  86. worker.setStatus(1)
  87. self.assignedWorkers.remove(worker)
  88. def setEngineeringmodel(self, model):
  89. self.engineeringModel = model
  90. self.save()
  91. def decreaseRounds(self):
  92. self.maxRounds -= 1
  93. self.save()
  94. def recalculate(self, company):
  95. if not self.recalculated:
  96. self.engineeringModel.recalculate(order=self, company=company)
  97. print("recalculated")
  98. def calculateWorkload(self, workersatisfaction):
  99. self.decreaseRounds()
  100. finished = False
  101. for worker in self.assignedWorkers.all():
  102. if worker.skilledModels == self.engineeringModel:
  103. if self.engineeringModel.name == "ModelScrum":
  104. amplifyer = self.engineeringModel.bonus(worker=worker, order=self)
  105. else:
  106. amplifyer = worker.amplifyer
  107. else:
  108. self.engineeringModel.penalty(worker=worker, order=self)
  109. if self.engineeringModel.name == "ModelScrum":
  110. amplifyer = 0.6
  111. else:
  112. amplifyer = 1
  113. # arbeit an order wenn nicht blockeirt
  114. if worker.status != 3:
  115. for attribute in attributelist:
  116. newval = getattr(self.requiredWorkload, attribute) - (
  117. getattr(worker.attributes, attribute)
  118. * amplifyer
  119. * (workersatisfaction * 0.01)
  120. )
  121. setattr(
  122. self.requiredWorkload,
  123. attribute,
  124. max(0, newval), # 0 setzen wenn negativwert
  125. )
  126. self.requiredWorkload.save()
  127. # prüfe ob alles abgearbeitet
  128. finished = True
  129. for attribute in attributelist:
  130. if getattr(self.requiredWorkload, attribute) > 0:
  131. finished = False
  132. break
  133. return finished
  134. def changeWorkload(self, number):
  135. for attribute in attributelist:
  136. setattr(
  137. self.requiredWorkload,
  138. attribute,
  139. getattr(self.requiredWorkload, attribute) * number,
  140. )
  141. self.requiredWorkload.save()
  142. def addWorkload(self, number):
  143. for attribute in attributelist:
  144. setattr(
  145. self.requiredWorkload,
  146. attribute,
  147. getattr(self.requiredWorkload, attribute) + number,
  148. )
  149. self.requiredWorkload.save()
  150. def finishOrder(self, company):
  151. company.addProfit(self.profit)
  152. company.calculateCustomerSatisfaction(30)
  153. company.save()
  154. self.cancelOrder()
  155. def addOffer(self, offer):
  156. self.offers.add(offer)
  157. def removeOffer(self, offer):
  158. self.offers.remove(offer)
  159. def checkOffer(self, amount):
  160. if amount > (self.profit * 1.2) or amount < (self.profit * 0.8):
  161. return False
  162. else:
  163. return True
  164. def calculateBestOffer(self):
  165. if self.offers.exists():
  166. # Wenn offers vorhanden
  167. bestoffer = (0, 0)
  168. for offer in self.offers.all():
  169. x = float(offer.company.customersatisfaction) / float(offer.amount)
  170. if x >= bestoffer[0]:
  171. bestoffer = (x, offer)
  172. self.setProfit(offer.amount)
  173. return bestoffer[1]
  174. else:
  175. # wenn keine offers
  176. return
  177. def cancelOrder(self):
  178. for worker in self.assignedWorkers.all():
  179. self.unassignWorker(worker)
  180. self.save()
  181. def setProfit(self, amount):
  182. self.profit = amount
  183. self.save()