Esempio n. 1
0
Location::~Location()
{
  // Remove all references from buffers to this location
  for (Buffer::iterator buf = Buffer::begin();
      buf != Buffer::end(); ++buf)
    if (buf->getLocation() == this)
      buf->setLocation(nullptr);

  // Remove all references from resources to this location
  for (Resource::iterator res = Resource::begin();
      res != Resource::end(); ++res)
    if (res->getLocation() == this)
      res->setLocation(nullptr);

  // Remove all references from operations to this location
  for (Operation::iterator oper = Operation::begin();
      oper != Operation::end(); ++oper)
    if (oper->getLocation() == this)
      oper->setLocation(nullptr);

  // Remove all references from demands to this location
  for (Demand::iterator dmd = Demand::begin();
      dmd != Demand::end(); ++dmd)
    if (dmd->getLocation() == this)
      dmd->setLocation(nullptr);

  // Remove all item suppliers referencing this location
  for (Supplier::iterator sup = Supplier::begin();
    sup != Supplier::end(); ++sup)
  {
    for (Supplier::itemlist::const_iterator it = sup->getItems().begin();
      it != sup->getItems().end(); )
    {
      if (it->getLocation() == this)
      {
        const ItemSupplier *itemsup = &*it;
        ++it;   // Advance iterator before the delete
        delete itemsup;
      }
      else
        ++it;
    }
  }

  // The ItemDistribution objects are automatically deleted by the
  // destructor of the Association list class.
}
Esempio n. 2
0
DECLARE_EXPORT Location::~Location()
{
  // Remove all references from buffers to this location
  for (Buffer::iterator buf = Buffer::begin();
      buf != Buffer::end(); ++buf)
    if (buf->getLocation() == this) buf->setLocation(NULL);

  // Remove all references from resources to this location
  for (Resource::iterator res = Resource::begin();
      res != Resource::end(); ++res)
    if (res->getLocation() == this) res->setLocation(NULL);

  // Remove all references from operations to this location
  for (Operation::iterator oper = Operation::begin();
      oper != Operation::end(); ++oper)
    if (oper->getLocation() == this) oper->setLocation(NULL);
}
Esempio n. 3
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;
  for (Buffer::iterator bufiter = Buffer::begin(); bufiter != Buffer::end(); ++bufiter)
  {
    if (bufiter->getLocation() == location && bufiter->getItem() == item)
    {
      if (destbuffer)
      {
        stringstream o;
        o << "Multiple buffers found for item '" << item << "'' and location'" << location << "'";
        throw DataException(o.str());
      }
      destbuffer = &*bufiter;
    }
  }
  if (!destbuffer)
  {
    // Create the destination buffer
    destbuffer = new BufferDefault();
    stringstream o;
    o << item << " @ " << location;
    destbuffer->setName(o.str());
    destbuffer->setItem(item);
    destbuffer->setLocation(location);
  }

  // Look for a matching matching supplying operation on this buffer.
  // Here we also trigger the creation of its producing operation, which
  // contains the logic to build possible transfer operations.
  Operation *oper = NULL;
  Operation* prodOper = destbuffer->getProducingOperation();
  if (prodOper && prodOper->getType() == *OperationItemSupplier::metadata)
  {
    if (supplier)
    {
      if (supplier->isMemberOf(static_cast<OperationItemSupplier*>(prodOper)->getItemSupplier()->getSupplier()))
        oper = prodOper;
    }
    else
      oper = prodOper;
  }
  else if (prodOper && prodOper->getType() == *OperationAlternate::metadata)
  {
    SubOperation::iterator soperiter = prodOper->getSubOperationIterator();
    while (SubOperation *soper = soperiter.next())
    {
      if (soper->getType() == *OperationItemSupplier::metadata)
      {
        if (supplier)
        {
          if (supplier->isMemberOf(static_cast<OperationItemSupplier*>(prodOper)->getItemSupplier()->getSupplier()))
          {
            oper = soper->getOperation();
            break;
          }
        }
        else
        {
          oper = prodOper;
          break;
        }
      }
    }
  }

  // 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 (status)
    opplan->setStatus(status);
  if (ref)
    opplan->setReference(ref);

  // Return result
  Py_INCREF(opplan);
  return opplan;
}
Esempio n. 4
0
extern "C" PyObject* OperationItemDistribution::createOrder(
  PyObject *self, PyObject *args, PyObject *kwdict
  )
{
  // Parse the Python arguments
  PyObject* pydest = NULL;
  unsigned long id = 0;
  const char* ref = NULL;
  PyObject* pyitem = NULL;
  PyObject* pyorigin = NULL;
  double qty = 0;
  PyObject* pystart = NULL;
  PyObject* pyend = NULL;
  int consume = 1;
  const char* status = NULL;
  const char* source = NULL;
  static const char *kwlist[] = {
    "destination", "id", "reference", "item", "origin", "quantity", "start",
    "end", "consume_material", "status", "source", NULL
    };
  int ok = PyArg_ParseTupleAndKeywords(
    args, kwdict, "|OkzOOdOOpzz:createOrder", const_cast<char**>(kwlist),
    &pydest, &id, &ref, &pyitem, &pyorigin, &qty, &pystart, &pyend,
    &consume, &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 (!pydest || !pyitem)
  {
    PyErr_SetString(PythonDataException, "item and destination arguments are mandatory");
    return NULL;
  }
  PythonData dest_tmp(pydest);
  if (!dest_tmp.check(Location::metadata))
  {
    PyErr_SetString(PythonDataException, "destination 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 origin_tmp(pyorigin);
  if (pyorigin && !origin_tmp.check(Location::metadata))
  {
    PyErr_SetString(PythonDataException, "origin argument must be of type location");
    return NULL;
  }
  Item *item = static_cast<Item*>(item_tmp.getObject());
  Location *dest = static_cast<Location*>(dest_tmp.getObject());
  Location *origin = pyorigin ? static_cast<Location*>(origin_tmp.getObject()) : NULL;

  // Find or create the destination buffer.
  Buffer* destbuffer = NULL;
  for (Buffer::iterator bufiter = Buffer::begin(); bufiter != Buffer::end(); ++bufiter)
  {
    if (bufiter->getLocation() == dest && bufiter->getItem() == item)
    {
      if (destbuffer)
      {
        stringstream o;
        o << "Multiple buffers found for item '" << item << "'' and location'" << dest << "'";
        throw DataException(o.str());
      }
      destbuffer = &*bufiter;
    }
  }
  if (!destbuffer)
  {
    // Create the destination buffer
    destbuffer = new BufferDefault();
    stringstream o;
    o << item << " @ " << dest;
    destbuffer->setName(o.str());
    destbuffer->setItem(item);
    destbuffer->setLocation(dest);
  }

  // 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() != *OperationItemDistribution::metadata
      || flowiter->getQuantity() <= 0)
        continue;
    OperationItemDistribution* opitemdist = static_cast<OperationItemDistribution*>(flowiter->getOperation());
    if (origin)
    {
      // Origin must match as well
      for (Operation::flowlist::const_iterator fl = opitemdist->getFlows().begin();
          fl != opitemdist->getFlows().end(); ++ fl)
      {
        if (fl->getQuantity() < 0 && fl->getBuffer()->getLocation()->isMemberOf(origin))
          oper = opitemdist;
      }
    }
    else
      oper = opitemdist;
  }

  // No matching operation is found.
  if (!oper)
  {
    // We'll create one now, but that requires that we have an origin defined.
    if (!origin)
      throw DataException("Origin location is needed on this distribution order");
    Buffer* originbuffer = NULL;
    for (Buffer::iterator bufiter = Buffer::begin(); bufiter != Buffer::end(); ++bufiter)
    {
      if (bufiter->getLocation() == origin && bufiter->getItem() == item)
      {
        if (originbuffer)
        {
          stringstream o;
          o << "Multiple buffers found for item '" << item << "'' and location'" << dest << "'";
          throw DataException(o.str());
        }
        originbuffer = &*bufiter;
      }
    }
    if (!originbuffer)
    {
      // Create the origin buffer
      originbuffer = new BufferDefault();
      stringstream o;
      o << item << " @ " << origin;
      originbuffer->setName(o.str());
      originbuffer->setItem(item);
      originbuffer->setLocation(origin);
    }
    // Note: We know that we need to create a new one. An existing one would
    // have created an operation on the buffer already.
    ItemDistribution *itemdist = new ItemDistribution();
    itemdist->setOrigin(origin);
    itemdist->setItem(item);
    itemdist->setDestination(dest);
    oper = new OperationItemDistribution(itemdist, originbuffer, destbuffer);
    new ProblemInvalidData(oper, "Distribution orders on unauthorized lanes", "operation",
      Date::infinitePast, Date::infiniteFuture, 1);
  }

  // Finally, create the operationplan
  OperationPlan *opplan = oper->createOperationPlan(qty, start, end, NULL, NULL, 0, false);
  if (id)
    opplan->setIdentifier(id);
  if (status)
    opplan->setStatus(status);
  if (ref)
    opplan->setReference(ref);
  if (!consume)
    opplan->setConsumeMaterial(false);
  opplan->activate();

  // Return result
  Py_INCREF(opplan);
  return opplan;
}