DECLARE_EXPORT void Resource::inspect(const string msg) const { logger << "Inspecting resource " << getName() << ": "; if (!msg.empty()) logger << msg; logger << endl; for (loadplanlist::const_iterator oo = getLoadPlans().begin(); oo != getLoadPlans().end(); ++oo) { logger << " " << oo->getDate() << " qty:" << oo->getQuantity() << ", oh:" << oo->getOnhand(); switch (oo->getEventType()) { case 1: logger << ", oper:" << static_cast<const LoadPlan*>(&*oo)->getOperationPlan()->getOperation() << endl; break; case 2: logger << ", event set-onhand" << endl; break; case 3: logger << ", event update-minimum" << endl; break; case 4: logger << ", event update-maximum" << endl; break; } } }
DECLARE_EXPORT void Resource::inspect(const string msg) const { logger << "Inspecting resource " << getName() << ": "; if (!msg.empty()) logger << msg; logger << endl; for (loadplanlist::const_iterator oo = getLoadPlans().begin(); oo != getLoadPlans().end(); ++oo) { logger << " " << oo->getDate() << " qty:" << oo->getQuantity() << ", oh:" << oo->getOnhand(); if (oo->getEventType() == 1) logger << ", oper:" << static_cast<const LoadPlan*>(&*oo)->getOperationPlan()->getOperation(); logger << endl; } }
DECLARE_EXPORT void Resource::updateSetups(const LoadPlan* ldplan) { // No updating required this resource if (!getSetupMatrix() || (ldplan && ldplan->getOperationPlan()->getOperation() != OperationSetup::setupoperation)) return; // Update later setup opplans OperationPlan *opplan = ldplan ? ldplan->getOperationPlan() : NULL; loadplanlist::const_iterator i = ldplan ? getLoadPlans().begin(ldplan) : getLoadPlans().begin(); string prevsetup = ldplan ? ldplan->getSetup() : getSetup(); for (; i != getLoadPlans().end(); ++i) { const LoadPlan* l = dynamic_cast<const LoadPlan*>(&*i); if (l && !l->getLoad()->getSetup().empty() && l->getOperationPlan()->getOperation() == OperationSetup::setupoperation && l->getOperationPlan() != opplan && !l->isStart()) { // Next conversion operation OperationPlanState x = l->getOperationPlan()->getOperation()->setOperationPlanParameters( l->getOperationPlan(), l->getOperationPlan()->getQuantity(), Date::infinitePast, l->getOperationPlan()->getDates().getEnd(), true, false); if (x.start != l->getOperationPlan()->getDates().getStart()) // We need to change a setup plan l->getOperationPlan()->restore(x); else if (ldplan && x.start == l->getOperationPlan()->getDates().getStart()) // We found a setup plan that doesn't need updating. Later setup plans // won't require updating either return; } } }
bool OperationPlan::updateFeasible() { if (!getOperation()->getDetectProblems()) { // No problems to be flagged on this operation setFeasible(true); return true; } // The implementation of this method isn't really cleanly object oriented. It uses // logic which only the different resource and buffer implementation classes should be // aware. if (firstsubopplan) { // Check feasibility of child operationplans for (OperationPlan *i = firstsubopplan; i; i = i->nextsubopplan) { if (!i->updateFeasible()) { setFeasible(false); return false; } } } else { // Before current and before fence problems are only detected on child operationplans if (getConfirmed()) { if (dates.getEnd() < Plan::instance().getCurrent()) { // Before current violation setFeasible(false); return false; } } else { if (dates.getStart() < Plan::instance().getCurrent()) { // Before current violation setFeasible(false); return false; } else if (dates.getStart() < Plan::instance().getCurrent() + oper->getFence() && getProposed()) { // Before fence violation setFeasible(false); return false; } } } if (nextsubopplan && getEnd() > nextsubopplan->getStart() + Duration(1L) && !nextsubopplan->getConfirmed() && owner && !owner->getOperation()->hasType<OperationSplit>() ) { // Precedence violation // Note: 1 second grace period for precedence problems to avoid rounding issues setFeasible(false); return false; } // Verify the capacity constraints for (auto ldplan = getLoadPlans(); ldplan != endLoadPlans(); ++ldplan) { if (ldplan->getResource()->hasType<ResourceDefault>() && ldplan->getQuantity() > 0) { auto curMax = ldplan->getMax(); for ( auto cur = ldplan->getResource()->getLoadPlans().begin(&*ldplan); cur != ldplan->getResource()->getLoadPlans().end(); ++cur ) { if (cur->getOperationPlan() == this && cur->getQuantity() < 0) break; if (cur->getEventType() == 4) curMax = cur->getMax(false); if ( cur->getEventType() != 5 && cur->isLastOnDate() && cur->getOnhand() > curMax + ROUNDING_ERROR ) { // Overload on default resource setFeasible(false); return false; } } } else if (ldplan->getResource()->hasType<ResourceBuckets>()) { for ( auto cur = ldplan->getResource()->getLoadPlans().begin(&*ldplan); cur != ldplan->getResource()->getLoadPlans().end() && cur->getEventType() != 2; ++cur ) { if (cur->getOnhand() < -ROUNDING_ERROR) { // Overloaded capacity on bucketized resource setFeasible(false); return false; } } } } // Verify the material constraints for (auto flplan = beginFlowPlans(); flplan != endFlowPlans(); ++flplan) { if ( !flplan->getFlow()->isConsumer() || flplan->getBuffer()->hasType<BufferInfinite>() ) continue; auto flplaniter = flplan->getBuffer()->getFlowPlans(); for (auto cur = flplaniter.begin(&*flplan); cur != flplaniter.end(); ++cur) { if (cur->getOnhand() < -ROUNDING_ERROR && cur->isLastOnDate()) { // Material shortage setFeasible(false); return false; } } } // After all checks, it turns out to be feasible setFeasible(true); return true; }