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");
311 if (prev || oper->first_opplan ==
this)
return;
313 if (!oper->first_opplan)
316 oper->first_opplan =
this;
317 oper->last_opplan =
this;
319 else if (*
this < *(oper->first_opplan))
322 next = oper->first_opplan;
324 oper->first_opplan =
this;
326 else if (*(oper->last_opplan) < *
this)
329 prev = oper->last_opplan;
331 oper->last_opplan =
this;
338 while (!(*x < *
this))
345 if (x) x->next =
this;
346 if (y) y->prev =
this;
356 else if (oper->first_opplan ==
this)
358 oper->first_opplan = next;
362 else if (oper->last_opplan ==
this)
364 oper->last_opplan = prev;
374 if (o->owner ==
this)
return;
389 o->nextsubopplan = firstsubopplan;
390 firstsubopplan->prevsubopplan = o;
397 o->nextsubopplan = s;
398 if (s) s->nextsubopplan = o;
399 else lastsubopplan = o;
415 if (o->owner !=
this)
422 if (o->prevsubopplan)
423 o->prevsubopplan->nextsubopplan = o->nextsubopplan;
425 firstsubopplan = o->nextsubopplan;
426 if (o->nextsubopplan)
427 o->nextsubopplan->prevsubopplan = o->prevsubopplan;
429 lastsubopplan = o->prevsubopplan;
437 return *oper < *(a.oper);
444 return quantity >= a.quantity;
451 if (firstflowplan || firstloadplan)
return;
454 for (Operation::loadlist::const_iterator g=oper->
getLoads().begin();
456 if (!g->getAlternate())
459 if (!g->getSetup().empty() && g->getResource()->getSetupMatrix())
467 if (!h->getAlternate())
new FlowPlan(
this, &*h);
474 if (!firstflowplan && !firstloadplan)
return;
477 firstflowplan = NULL;
479 firstloadplan = NULL;
496 firstsubopplan = NULL;
497 lastsubopplan = NULL;
527 if (owner == o)
return;
546 for (
OperationPlan* i = firstsubopplan; i; i = i->nextsubopplan)
549 if (i->getDates().getStart() < d)
552 d = i->getDates().getEnd();
576 for (
OperationPlan* i = lastsubopplan; i; i = i->prevsubopplan)
579 if (i->getDates().getEnd() > d)
582 d = i->getDates().getStart();
602 throw DataException(
"Operationplans can't have negative quantities");
608 return owner->
setQuantity(f,roundDown,upd,execute);
617 if (!execute)
return 0.0;
633 + (roundDown ? 0.0 : 0.99999999));
637 if (!execute)
return q;
642 if (!execute)
return f;
650 owner->quantity = quantity;
651 if (upd) owner->resizeFlowLoadPlans();
655 if (execute && firstsubopplan)
656 for (
OperationPlan *i = firstsubopplan; i; i = i->nextsubopplan)
659 i->quantity = quantity;
660 if (upd) i->resizeFlowLoadPlans();
694 for (
OperationPlan *j = firstsubopplan; j; j = j->nextsubopplan)
697 j->quantity = quantity;
698 j->resizeFlowLoadPlans();
709 throw LogicException(
"Can't copy suboperationplans. Copy the owner instead.");
715 quantity = src.quantity;
719 firstflowplan = NULL;
720 firstloadplan = NULL;
725 firstsubopplan = NULL;
726 lastsubopplan = NULL;
727 nextsubopplan = NULL;
728 prevsubopplan = NULL;
745 throw LogicException(
"No new owner passed in private copy constructor.");
751 quantity = src.quantity;
755 firstflowplan = NULL;
756 firstloadplan = NULL;
761 firstsubopplan = NULL;
762 lastsubopplan = NULL;
763 nextsubopplan = NULL;
764 prevsubopplan = NULL;
782 OperationPlan *tmp = firstsubopplan;
784 tmp = tmp->nextsubopplan;
786 tmp->getDates().getStart(),
791 for (OperationPlan* i = firstsubopplan; i; i = i->nextsubopplan)
792 if (i->flags & IS_LOCKED)
800 resizeFlowLoadPlans();
803 if (owner) owner->update();
816 opplan = opplan->next;
818 if (deleteLockedOpplans || !tmp->
getLocked())
delete tmp;
828 if (i->isStart() && !i->getLoad()->getSetup().empty() && i->getResource()->getSetupMatrix())
832 if (rule) penalty += rule->
getCost();
844 for (
OperationPlan* subopplan = firstsubopplan; subopplan; subopplan = subopplan->nextsubopplan)
845 if (!subopplan->isExcess())
return false;
852 if (i->getQuantity() <= 0)
continue;
856 double current_maximum(0.0);
857 double current_minimum(0.0);
858 Buffer::flowplanlist::const_iterator j = i->getBuffer()->getFlowPlans().rbegin();
859 if (!strict && j != i->getBuffer()->getFlowPlans().end())
861 current_maximum = i->getBuffer()->getFlowPlans().getMax(&*j);
862 current_minimum = i->getBuffer()->getFlowPlans().getMin(&*j);
864 for (; j != i->getBuffer()->getFlowPlans().end(); --j)
866 if ( (current_maximum > 0
867 && j->getOnhand() < i->getQuantity() + current_maximum -
ROUNDING_ERROR)
868 || j->getOnhand() < i->getQuantity() + current_minimum -
ROUNDING_ERROR )
870 if (j->getType() == 4 && !strict) current_maximum = j->getMax(
false);
871 if (j->getType() == 3 && !strict) current_minimum = j->getMin(
false);
872 if (&*j == &*i)
break;
960 pElement >> quantity;
981 else throw LogicException(
"Incorrect object type during read operation");
994 for (
OperationPlan *x = firstsubopplan; x; x = x->nextsubopplan)
1026 PyObject *key, *value;
1028 while (PyDict_Next(kwds, &pos, &key, &value))
1034 int result = x->
setattro(attr, field);
1035 if (result && !PyErr_Occurred())
1036 PyErr_Format(PyExc_AttributeError,
1037 "attribute '%s' on '%s' can't be updated",
1038 PyString_AsString(key), x->ob_type->tp_name);
1043 if (x && !static_cast<OperationPlan*>(x)->
activate())
1052 PythonType::evalException();
1132 Demand* y =
static_cast<Demand*
>(
static_cast<PyObject*
>(field));
1148 if (static_cast<PyObject*>(field) == Py_None)
1151 y = static_cast<Demand*>(static_cast<PyObject*>(field));
1153 y = static_cast<Buffer*>(static_cast<PyObject*>(field));
1155 y = static_cast<Resource*>(static_cast<PyObject*>(field));
1158 PyErr_SetString(
PythonDataException,
"operationplan motive must be of type demand, buffer or resource");