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