Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}