DECLARE_EXPORT Load::~Load() { // Set a flag to make sure the level computation is triggered again HasLevel::triggerLazyRecomputation(); // Delete existing loadplans if (getOperation() && getResource()) { // Loop over operationplans for(OperationPlan::iterator i(getOperation()); i != OperationPlan::end(); ++i) // Loop over loadplans for(OperationPlan::LoadPlanIterator j = i->beginLoadPlans(); j != i->endLoadPlans(); ) if (j->getLoad() == this) j.deleteLoadPlan(); else ++j; } // Delete the load from the operation and resource if (getOperation()) getOperation()->loaddata.erase(this); if (getResource()) getResource()->loads.erase(this); }
DECLARE_EXPORT Load::~Load() { // Set a flag to make sure the level computation is triggered again HasLevel::triggerLazyRecomputation(); // Delete existing loadplans if (getOperation() && getResource()) { // Loop over operationplans for(OperationPlan::iterator i(getOperation()); i != OperationPlan::end(); ++i) // Loop over loadplans for(OperationPlan::LoadPlanIterator j = i->beginLoadPlans(); j != i->endLoadPlans(); ) if (j->getLoad() == this) j.deleteLoadPlan(); else ++j; } // Delete the load from the operation and resource if (getOperation()) getOperation()->loaddata.erase(this); if (getResource()) getResource()->loads.erase(this); // Clean up alternate loads if (hasAlts) { // The load has alternates. // Make a new load the leading one. Or if there is only one alternate // present it is not marked as an alternate any more. unsigned short cnt = 0; int minprio = INT_MAX; Load* newLeader = NULL; for (Operation::loadlist::iterator i = getOperation()->loaddata.begin(); i != getOperation()->loaddata.end(); ++i) if (i->altLoad == this) { cnt++; if (i->priority < minprio) { newLeader = &*i; minprio = i->priority; } } if (cnt < 1) throw LogicException("Alternate loads update failure"); else if (cnt == 1) // No longer an alternate any more newLeader->altLoad = NULL; else { // Mark a new leader load newLeader->hasAlts = true; newLeader->altLoad = NULL; for (Operation::loadlist::iterator i = getOperation()->loaddata.begin(); i != getOperation()->loaddata.end(); ++i) if (i->altLoad == this) i->altLoad = newLeader; } } if (altLoad) { // The load is an alternate of another one. // If it was the only alternate, then the hasAlts flag on the parent // load needs to be set back to false bool only_one = true; for (Operation::loadlist::iterator i = getOperation()->loaddata.begin(); i != getOperation()->loaddata.end(); ++i) if (i->altLoad == altLoad) { only_one = false; break; } if (only_one) altLoad->hasAlts = false; } }
DECLARE_EXPORT void LoadPlan::setResource(Resource* newres, bool check) { // Nothing to do if (res == newres) return; // Validate the argument if (!newres) throw DataException("Can't switch to NULL resource"); if (check) { // New resource must be a subresource of the load's resource. bool ok = false; for (const Resource* i = newres; i && !ok; i = i->getOwner()) if (i == getLoad()->getResource()) ok = true; if (!ok) throw DataException("Resource isn't matching the resource specified on the load"); // New resource must have the required skill if (getLoad()->getSkill()) { ok = false; for(Resource::skilllist::const_iterator s = newres->getSkills().begin(); s != newres->getSkills().end() && !ok; s++) if (s->getSkill() == getLoad()->getSkill()) ok = true; if (!ok) throw DataException("Resource misses the skill specified on the load"); } } // Mark entities as changed if (oper) oper->getOperation()->setChanged(); if (res && res!=newres) res->setChanged(); newres->setChanged(); // Update also the setup operationplans if (oper && oper->getOperation() != OperationSetup::setupoperation) { bool oldHasSetup = ld && !ld->getSetup().empty() // TODO not fully correct. If the load is changed, it is still possible that the old load had a setup, while ld doesn't have one any more... && res && res->getSetupMatrix(); bool newHasSetup = ld && !ld->getSetup().empty() && newres->getSetupMatrix(); OperationPlan *setupOpplan = NULL; if (oldHasSetup) { for (OperationPlan::iterator i(oper); i != oper->end(); ++i) if (i->getOperation() == OperationSetup::setupoperation) { setupOpplan = &*i; break; } if (!setupOpplan) oldHasSetup = false; } if (oldHasSetup) { if (newHasSetup) { // Case 1: Both the old and new load require a setup LoadPlan *setupLdplan = NULL; for (OperationPlan::LoadPlanIterator j = setupOpplan->beginLoadPlans(); j != setupOpplan->endLoadPlans(); ++j) if (j->getLoad() == ld) { setupLdplan = &*j; break; } if (!setupLdplan) throw LogicException("Can't find loadplan on setup operationplan"); // Update the loadplan setupOpplan->setEnd(setupOpplan->getDates().getEnd()); } else { // Case 2: Delete the old setup which is not required any more oper->eraseSubOperationPlan(setupOpplan); } } else { if (newHasSetup) { // Case 3: Create a new setup operationplan OperationSetup::setupoperation->createOperationPlan( 1, Date::infinitePast, oper->getDates().getEnd(), NULL, oper); } //else: // Case 4: No setup for the old or new load } } // Find the loadplan before the setup LoadPlan *prevldplan = NULL; if (getOperationPlan()->getOperation() == OperationSetup::setupoperation) { for (TimeLine<LoadPlan>::const_iterator i = getResource()->getLoadPlans().begin(isStart() ? getOtherLoadPlan() : this); i != getResource()->getLoadPlans().end(); --i) { const LoadPlan *l = dynamic_cast<const LoadPlan*>(&*i); if (l && l->getOperationPlan() != getOperationPlan() && l->getOperationPlan() != getOperationPlan()->getOwner() && !l->isStart()) { prevldplan = const_cast<LoadPlan*>(l); break; } } if (!prevldplan) { for (TimeLine<LoadPlan>::const_iterator i = getResource()->getLoadPlans().begin(isStart() ? getOtherLoadPlan() : this); i != getResource()->getLoadPlans().end(); ++i) { const LoadPlan *l = dynamic_cast<const LoadPlan*>(&*i); if (l && l->getOperationPlan() != getOperationPlan() && l->getOperationPlan() != getOperationPlan()->getOwner() && !l->isStart()) { prevldplan = const_cast<LoadPlan*>(l); break; } } } } // Change this loadplan and its brother for (LoadPlan *ldplan = getOtherLoadPlan(); true; ) { // Remove from the old resource, if there is one if (res) { res->loadplans.erase(ldplan); res->setChanged(); } // Insert in the new resource. // This code assumes the date and quantity of the loadplan don't change // when a new resource is assigned. ldplan->res = newres; newres->loadplans.insert( ldplan, ld->getLoadplanQuantity(ldplan), ld->getLoadplanDate(ldplan) ); // Repeat for the brother loadplan or exit if (ldplan != this) ldplan = this; else break; } // Update the setups on the old resource if (prevldplan) prevldplan->res->updateSetups(prevldplan); // Change the resource newres->setChanged(); }