34 DECLARE_EXPORT unsigned long OperationPlan::counterMax = 2147483647;
47 x.
setDoc(
"frePPLe operationplan");
52 x.
addMethod(
"toXML",
toXML, METH_VARARGS,
"return a XML representation");
74 Action action = MetaClass::decodeAction(in);
78 if (!*opnameElement && action==
ADD)
81 string opname = *opnameElement ? opnameElement->
getString() :
"";
96 if (opplan && !opname.
empty()
101 ch <<
"Operationplan identifier " <<
id
102 <<
" defined multiple times with different operations: '"
122 ch <<
"Can't delete operationplan with identifier " << id;
129 ch <<
"Operationplan with identifier " <<
id <<
" doesn't exist";
137 ch <<
"Operationplan with identifier " <<
id
138 <<
" already exists and can't be added again";
143 (
"Operation name missing for creating an operationplan");
149 ch <<
"Operationplan with identifier " <<
id <<
" doesn't exist";
157 if (opplan)
return opplan;
164 throw DataException(
"Operation '" + opname +
"' doesn't exist");
169 opplan = oper->
createOperationPlan(0.0,Date::infinitePast,Date::infinitePast,NULL,NULL,
id,
false);
185 if (l >= counterMin && l <= counterMax)
return NULL;
189 if (i->id == l)
return &*i;
199 if (!oper)
throw LogicException(
"Initializing an invalid operationplan");
226 static Mutex onlyOne;
232 if (id < counterMin || id > counterMax)
240 ch <<
"Operationplan id " <<
id
241 <<
" defined multiple times with different operations: '"
250 else if (useMinCounter)
256 else if (useMinCounter)
261 if (counterMin >= counterMax)
262 throw RuntimeException(
"Exhausted the range of available operationplan identifiers");
307 if (prev || oper->first_opplan ==
this)
return;
309 if (!oper->first_opplan)
312 oper->first_opplan =
this;
313 oper->last_opplan =
this;
315 else if (*
this < *(oper->first_opplan))
318 next = oper->first_opplan;
320 oper->first_opplan =
this;
322 else if (*(oper->last_opplan) < *
this)
325 prev = oper->last_opplan;
327 oper->last_opplan =
this;
334 while (!(*x < *
this))
341 if (x) x->next =
this;
342 if (y) y->prev =
this;
352 else if (oper->first_opplan ==
this)
354 oper->first_opplan = next;
358 else if (oper->last_opplan ==
this)
360 oper->last_opplan = prev;
370 if (o->owner ==
this)
return;
385 o->nextsubopplan = firstsubopplan;
386 firstsubopplan->prevsubopplan = o;
393 o->nextsubopplan = s;
394 if (s) s->nextsubopplan = o;
395 else lastsubopplan = o;
411 if (o->owner !=
this)
418 if (o->prevsubopplan)
419 o->prevsubopplan->nextsubopplan = o->nextsubopplan;
421 firstsubopplan = o->nextsubopplan;
422 if (o->nextsubopplan)
423 o->nextsubopplan->prevsubopplan = o->prevsubopplan;
425 lastsubopplan = o->prevsubopplan;
433 return *oper < *(a.oper);
440 return quantity >= a.quantity;
447 if (firstflowplan || firstloadplan)
return;
450 for (Operation::loadlist::const_iterator g=oper->
getLoads().begin();
452 if (!g->getAlternate())
455 if (!g->getSetup().empty() && g->getResource()->getSetupMatrix())
463 if (!h->getAlternate())
new FlowPlan(
this, &*h);
470 if (!firstflowplan && !firstloadplan)
return;
473 firstflowplan = NULL;
475 firstloadplan = NULL;
492 firstsubopplan = NULL;
493 lastsubopplan = NULL;
523 if (owner == o)
return;
542 for (
OperationPlan* i = firstsubopplan; i; i = i->nextsubopplan)
545 if (i->getDates().getStart() < d)
548 d = i->getDates().getEnd();
572 for (
OperationPlan* i = lastsubopplan; i; i = i->prevsubopplan)
575 if (i->getDates().getEnd() > d)
578 d = i->getDates().getStart();
598 throw DataException(
"Operationplans can't have negative quantities");
604 return owner->
setQuantity(f,roundDown,upd,execute);
613 if (!execute)
return 0.0;
620 owner->quantity = 0.0;
621 if (upd) owner->resizeFlowLoadPlans();
635 + (roundDown ? 0.0 : 0.99999999));
639 if (!execute)
return q;
644 if (!execute)
return f;
652 owner->quantity = quantity;
653 if (upd) owner->resizeFlowLoadPlans();
657 if (execute && firstsubopplan)
658 for (
OperationPlan *i = firstsubopplan; i; i = i->nextsubopplan)
661 i->quantity = quantity;
662 if (upd) i->resizeFlowLoadPlans();
696 for (
OperationPlan *j = firstsubopplan; j; j = j->nextsubopplan)
699 j->quantity = quantity;
700 j->resizeFlowLoadPlans();
711 throw LogicException(
"Can't copy suboperationplans. Copy the owner instead.");
717 quantity = src.quantity;
721 firstflowplan = NULL;
722 firstloadplan = NULL;
727 firstsubopplan = NULL;
728 lastsubopplan = NULL;
729 nextsubopplan = NULL;
730 prevsubopplan = NULL;
747 throw LogicException(
"No new owner passed in private copy constructor.");
753 quantity = src.quantity;
757 firstflowplan = NULL;
758 firstloadplan = NULL;
763 firstsubopplan = NULL;
764 lastsubopplan = NULL;
765 nextsubopplan = NULL;
766 prevsubopplan = NULL;
784 OperationPlan *tmp = firstsubopplan;
786 tmp = tmp->nextsubopplan;
788 tmp->getDates().getStart(),
793 for (OperationPlan* i = firstsubopplan; i; i = i->nextsubopplan)
794 if (i->flags & IS_LOCKED)
802 resizeFlowLoadPlans();
805 if (owner) owner->update();
818 opplan = opplan->next;
820 if (deleteLockedOpplans || !tmp->
getLocked())
delete tmp;
830 if (i->isStart() && !i->getLoad()->getSetup().empty() && i->getResource()->getSetupMatrix())
834 if (rule) penalty += rule->
getCost();
846 for (
OperationPlan* subopplan = firstsubopplan; subopplan; subopplan = subopplan->nextsubopplan)
847 if (!subopplan->isExcess())
return false;
850 bool hasFlowplans =
false;
856 if (i->getQuantity() <= 0)
continue;
859 double prod_qty = i->getQuantity();
860 for (
OperationPlan* subopplan = firstsubopplan; subopplan; subopplan = subopplan->nextsubopplan)
862 k != subopplan->endFlowPlans(); ++k)
863 if (k->getBuffer() == i->getBuffer())
864 prod_qty += k->getQuantity();
865 if (prod_qty <= 0)
continue;
869 double current_maximum(0.0);
870 double current_minimum(0.0);
871 Buffer::flowplanlist::const_iterator j = i->getBuffer()->getFlowPlans().rbegin();
872 if (!strict && j != i->getBuffer()->getFlowPlans().end())
874 current_maximum = i->getBuffer()->getFlowPlans().getMax(&*j);
875 current_minimum = i->getBuffer()->getFlowPlans().getMin(&*j);
877 for (; j != i->getBuffer()->getFlowPlans().end(); --j)
879 if ( (current_maximum > 0
883 if (j->getType() == 4 && !strict) current_maximum = j->getMax(
false);
884 if (j->getType() == 3 && !strict) current_minimum = j->getMin(
false);
885 if (&*j == &*i)
break;
979 pElement >> quantity;
1000 else throw LogicException(
"Incorrect object type during read operation");
1012 flags &= ~IS_LOCKED;
1013 for (
OperationPlan *x = firstsubopplan; x; x = x->nextsubopplan)
1049 PyObject *key, *value;
1051 while (PyDict_Next(kwds, &pos, &key, &value))
1054 #if PY_MAJOR_VERSION >= 3
1055 PyObject* key_utf8 = PyUnicode_AsUTF8String(key);
1056 Attribute attr(PyBytes_AsString(key_utf8));
1057 Py_DECREF(key_utf8);
1063 int result = x->
setattro(attr, field);
1064 if (result && !PyErr_Occurred())
1065 PyErr_Format(PyExc_AttributeError,
1066 #
if PY_MAJOR_VERSION >= 3
1067 "attribute '%S' on '%s' can't be updated",
1068 key, Py_TYPE(x)->tp_name);
1070 "attribute '%s' on '%s' can't be updated",
1071 PyString_AsString(key), Py_TYPE(x)->tp_name);
1077 if (x && !static_cast<OperationPlan*>(x)->activate())
1086 PythonType::evalException();
1166 Demand* y =
static_cast<Demand*
>(
static_cast<PyObject*
>(field));
1182 if (static_cast<PyObject*>(field) == Py_None)
1185 y = static_cast<Demand*>(static_cast<PyObject*>(field));
1187 y = static_cast<Buffer*>(static_cast<PyObject*>(field));
1189 y = static_cast<Resource*>(static_cast<PyObject*>(field));
1192 PyErr_SetString(
PythonDataException,
"operationplan motive must be of type demand, buffer or resource");