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; }
extern "C" PyObject* OperationItemSupplier::createOrder( PyObject *self, PyObject *args, PyObject *kwdict ) { // Parse the Python arguments PyObject* pylocation = NULL; unsigned long id = 0; const char* ref = NULL; PyObject* pyitem = NULL; PyObject* pysupplier = NULL; double qty = 0; PyObject* pystart = NULL; PyObject* pyend = NULL; const char* status = NULL; const char* source = NULL; static const char *kwlist[] = { "location", "id", "reference", "item", "supplier", "quantity", "start", "end", "status", "source", NULL }; int ok = PyArg_ParseTupleAndKeywords( args, kwdict, "|OkzOOdOOzz:createOrder", const_cast<char**>(kwlist), &pylocation, &id, &ref, &pyitem, &pysupplier, &qty, &pystart, &pyend, &status, &source ); if (!ok) return NULL; Date start = pystart ? PythonData(pystart).getDate() : Date::infinitePast; Date end = pyend ? PythonData(pyend).getDate() : Date::infinitePast; // Validate all arguments if (!pylocation || !pyitem) { PyErr_SetString(PythonDataException, "item and location arguments are mandatory"); return NULL; } PythonData location_tmp(pylocation); if (!location_tmp.check(Location::metadata)) { PyErr_SetString(PythonDataException, "location argument must be of type location"); return NULL; } PythonData item_tmp(pyitem); if (!item_tmp.check(Item::metadata)) { PyErr_SetString(PythonDataException, "item argument must be of type item"); return NULL; } PythonData supplier_tmp(pysupplier); if (pysupplier && !supplier_tmp.check(Supplier::metadata)) { PyErr_SetString(PythonDataException, "supplier argument must be of type supplier"); return NULL; } Item *item = static_cast<Item*>(item_tmp.getObject()); Location *location = static_cast<Location*>(location_tmp.getObject()); Supplier *supplier = pysupplier ? static_cast<Supplier*>(supplier_tmp.getObject()) : NULL; // Find or create the destination buffer. Buffer* destbuffer = NULL; Item::bufferIterator buf_iter(item); while (Buffer* tmpbuf = buf_iter.next()) { if (tmpbuf->getLocation() == location) { if (destbuffer) { stringstream o; o << "Multiple buffers found for item '" << item << "'' and location'" << location << "'"; throw DataException(o.str()); } destbuffer = tmpbuf; } } if (!destbuffer) { // Create the destination buffer destbuffer = new BufferDefault(); stringstream o; o << item << " @ " << location; destbuffer->setName(o.str()); destbuffer->setItem(item); destbuffer->setLocation(location); } // Build the producing operation for this buffer. destbuffer->getProducingOperation(); // Look for a matching operation replenishing this buffer. Operation *oper = NULL; for (Buffer::flowlist::const_iterator flowiter = destbuffer->getFlows().begin(); flowiter != destbuffer->getFlows().end() && !oper; ++flowiter) { if (flowiter->getOperation()->getType() != *OperationItemSupplier::metadata) continue; OperationItemSupplier* opitemsupplier = static_cast<OperationItemSupplier*>(flowiter->getOperation()); if (supplier) { if (supplier->isMemberOf(opitemsupplier->getItemSupplier()->getSupplier())) oper = opitemsupplier; } else oper = opitemsupplier; } // No matching operation is found. if (!oper) { // We'll create one now, but that requires that we have a supplier defined. if (!supplier) throw DataException("Supplier is needed on this purchase order"); // Note: We know that we need to create a new one. An existing one would // have created an operation on the buffer already. ItemSupplier *itemsupplier = new ItemSupplier(); itemsupplier->setSupplier(supplier); itemsupplier->setItem(item); itemsupplier->setLocation(location); oper = new OperationItemSupplier(itemsupplier, destbuffer); new ProblemInvalidData(oper, "Purchase orders on unauthorized supplier", "operation", Date::infinitePast, Date::infiniteFuture, 1); } // Finally, create the operationplan OperationPlan *opplan = oper->createOperationPlan(qty, start, end); if (id) opplan->setRawIdentifier(id); // We can use this fast method because we call activate later if (status) opplan->setStatus(status); // Reset quantity after the status update to assure that // also non-valid quantities are getting accepted. opplan->setQuantity(qty); if (ref) opplan->setReference(ref); opplan->activate(); // Return result Py_INCREF(opplan); return opplan; }