int main (int argc, char *argv[]) { try { // 0: Initialize FreppleInitialize(); // 1: Read the model FreppleReadXMLFile("problems.xml",true,false); reportProblems("reading input"); // 2: Plan the model FreppleReadXMLData( "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" \ "<plan xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" \ "<?python\n" \ "frepple.solver_mrp(name=\"MRP\", constraints=0).solve()\n" \ "?>\n" \ "</plan>", true, false ); reportProblems("planning"); // Define variables for each of the 2 operation_plans Operation *buildoper = Operation::find("make end item"); OperationPlan *build = &*OperationPlan::iterator(buildoper); Operation *deliveroper = Operation::find("delivery end item"); OperationPlan *deliver = &*OperationPlan::iterator(deliveroper); if (!deliver || !build) throw DataException("Can't find operationplans"); // 3: Increase quantity of the delivery & report float oldqty = deliver->getQuantity(); deliver->setQuantity(100); reportProblems("increasing delivery quantity"); // 4: Reduce the quantity of the delivey & report deliver->setQuantity(1); reportProblems("decreasing delivery quantity"); // 5: Move the delivery early & report Date oldstart = deliver->getDates().getStart(); deliver->setStart(oldstart - Duration(86400)); reportProblems("moving delivery early"); // 6: Move the delivery late & report deliver->setStart(oldstart + Duration(86400)); reportProblems("moving delivery late"); // 7: Restoring original delivery plan & report deliver->setQuantity(oldqty); deliver->setStart(oldstart); reportProblems("restoring original delivery plan"); // 8: Deleting delivery delete deliver; reportProblems("deleting delivery plan"); // 9: Move the make operation before current & report oldstart = build->getDates().getStart(); build->setStart(Plan::instance().getCurrent() - Duration(1)); reportProblems("moving build early"); // 10: Restoring the original build plan & report build->setStart(oldstart); reportProblems("restoring original build plan"); } catch (...) { logger << "Error: Caught an exception in main routine:" << endl; try { throw; } catch (const exception& e) {logger << " " << e.what() << endl;} catch (...) {logger << " Unknown type" << endl;} return EXIT_FAILURE; } return EXIT_SUCCESS; }
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(); }