123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- 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()
|