def create_requirements(self): """ Recursively create all jobs needed to complete the current one. SUPPLY jobs are trivial, they stop the recursion. """ if self.activity == Job.SUPPLY: return # stop recursion materials = self.blueprint.get_bill_of_materials(activity=self.activity, runs=self.runs, me_level=self.blueprint.me) for mat in materials: self.children_jobs.add(Job.create(item_id=mat.requiredTypeID, quantity=mat.quantity, order=self.order, row=self.row)) parent_bp_id = self.blueprint.parentBlueprintTypeID if parent_bp_id is not None and self.blueprint.invented: # only create invention jobs if we don't own a BPO/BPC attempts = InventionPolicy.attempts(self.blueprint) # Since invented blueprints have fixed number of runs, we need to # prorate the number of invention jobs that will be actually charged # to the client. effective_runs = self.runs / float(self.blueprint.runs) * attempts # create a temp OwnedBlueprint that will be used to run the invention bpc = OwnedBlueprint.objects.create(typeID=parent_bp_id, copy=True) # add an INVENTION job self.children_jobs.create(item_id=parent_bp_id, blueprint=bpc, runs=effective_runs, order=self.order, row=self.row, activity=Job.INVENTION) if self.activity == Job.INVENTION: # add a SUPPLY job for T1 BPCs self.children_jobs.create(item_id=self.blueprint.typeID, runs=round(self.runs), order=self.order, row=self.row, activity=Job.SUPPLY) decriptorTypeID = InventionPolicy.decryptor(self.parent_job.blueprint) if decriptorTypeID is not None: # add a SUPPLY job for a decryptor if needed self.children_jobs.create(item_id=decriptorTypeID, runs=round(self.runs), order=self.order, row=self.row, activity=Job.SUPPLY) for job in self.children_jobs.all(): # recursive call job.create_requirements()
def create(item_id, quantity, order, row): """ Create a job (MANUFACTURING by default). If the item cannot be manufactured or if the corp does not own the blueprint needed for the item, a SUPPLY job is created. The number of runs is calculated from the needed quantity """ item = Type.objects.select_related(depth=2).get(pk=item_id) try: if item.blueprint is None: # item cannot be manufactured bp = None activity = Job.SUPPLY duration = 0 runs = quantity else: bpid = item.blueprintTypeID activity = Job.MANUFACTURING bp = OwnedBlueprint.objects.filter(typeID=bpid, copy=False).order_by('-me')[0] runs = quantity / item.portionSize if quantity % item.portionSize: runs += 1 duration = bp.manufacturing_time(runs) except IndexError: if item.metaGroupID == 2 and item.blueprint.parent_blueprint is not None: # we're trying to manufacture a T2 item without owning its BPO # we must create an OwnedBlueprint for this job only (that will # be consumed with it) # The invention policies are to be specified in InventionPolicies activity = Job.MANUFACTURING bp = InventionPolicy.blueprint(item.blueprint) runs = quantity / item.portionSize if quantity % item.portionSize: runs += 1 duration = bp.manufacturing_time(runs) bp.save() else: bp = None activity = Job.SUPPLY duration = 0 runs = quantity return Job.objects.create(order=order, row=row, item_id=item_id, blueprint=bp, runs=runs, activity=activity, duration=duration)