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. }
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); }
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; }
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; }