00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #define FREPPLE_CORE
00029 #include "frepple/model.h"
00030 namespace frepple
00031 {
00032
00033 DECLARE_EXPORT const MetaCategory* FlowPlan::metadata;
00034
00035
00036 int FlowPlan::initialize()
00037 {
00038
00039 metadata = new MetaCategory("flowplan", "flowplans");
00040
00041
00042 PythonType& x = FreppleCategory<FlowPlan>::getType();
00043 x.setName("flowplan");
00044 x.setDoc("frePPLe flowplan");
00045 x.supportgetattro();
00046 const_cast<MetaCategory*>(metadata)->pythonClass = x.type_object();
00047 return x.typeReady();
00048 }
00049
00050
00051 DECLARE_EXPORT FlowPlan::FlowPlan (OperationPlan *opplan, const Flow *f)
00052 {
00053 assert(opplan && f);
00054 fl = const_cast<Flow*>(f);
00055
00056
00057 initType(metadata);
00058
00059
00060 oper = opplan;
00061 nextFlowPlan = NULL;
00062 if (opplan->firstflowplan)
00063 {
00064
00065 FlowPlan *c = opplan->firstflowplan;
00066 while (c->nextFlowPlan) c = c->nextFlowPlan;
00067 c->nextFlowPlan = this;
00068 }
00069 else
00070
00071 opplan->firstflowplan = this;
00072
00073
00074 fl->getBuffer()->flowplans.insert(
00075 this,
00076 fl->getFlowplanQuantity(this),
00077 fl->getFlowplanDate(this)
00078 );
00079
00080
00081
00082 fl->getBuffer()->setChanged();
00083 fl->getOperation()->setChanged();
00084 }
00085
00086
00087 DECLARE_EXPORT void FlowPlan::update()
00088 {
00089
00090 fl->getBuffer()->flowplans.update(
00091 this,
00092 fl->getFlowplanQuantity(this),
00093 fl->getFlowplanDate(this)
00094 );
00095
00096
00097
00098 fl->getBuffer()->setChanged();
00099 fl->getOperation()->setChanged();
00100 }
00101
00102
00103 DECLARE_EXPORT void FlowPlan::setFlow(const Flow* newfl)
00104 {
00105
00106 if (newfl == fl) return;
00107
00108
00109 if (!newfl) throw LogicException("Can't switch to NULL flow");
00110
00111
00112 if (fl)
00113 {
00114 if (fl->getOperation() != newfl->getOperation())
00115 throw LogicException("Only switching to a flow on the same operation is allowed");
00116 fl->getBuffer()->flowplans.erase(this);
00117 fl->getBuffer()->setChanged();
00118 }
00119
00120
00121 fl = newfl;
00122 fl->getBuffer()->flowplans.insert(
00123 this,
00124 fl->getFlowplanQuantity(this),
00125 fl->getFlowplanDate(this)
00126 );
00127 fl->getBuffer()->setChanged();
00128 fl->getOperation()->setChanged();
00129 }
00130
00131
00132
00133
00134 DECLARE_EXPORT void FlowPlan::writeElement(XMLOutput *o, const Keyword& tag, mode m) const
00135 {
00136 o->BeginObject(tag);
00137 o->writeElement(Tags::tag_date, getDate());
00138 o->writeElement(Tags::tag_quantity, getQuantity());
00139 o->writeElement(Tags::tag_onhand, getOnhand());
00140 o->writeElement(Tags::tag_minimum, getMin());
00141 o->writeElement(Tags::tag_maximum, getMax());
00142 if (!dynamic_cast<OperationPlan*>(o->getCurrentObject()))
00143 o->writeElement(Tags::tag_operationplan, &*getOperationPlan());
00144
00145
00146 if (o->getContentType() == XMLOutput::PLANDETAIL)
00147 {
00148
00149 PeggingIterator k(this, false);
00150 if (k) --k;
00151 for (; k; --k)
00152 {
00153 o->BeginObject(Tags::tag_pegging, Tags::tag_level, k.getLevel());
00154 o->writeElement(Tags::tag_quantity, k.getQuantityDemand());
00155 o->writeElement(Tags::tag_factor, k.getFactor());
00156 if (!k.getPegged()) o->writeElement(Tags::tag_id, "unpegged");
00157 o->writeElement(Tags::tag_buffer, Tags::tag_name, k.getBuffer()->getName());
00158 if (k.getConsumingOperationplan())
00159 o->writeElement(Tags::tag_consuming,
00160 Tags::tag_id, k.getConsumingOperationplan()->getIdentifier(),
00161 Tags::tag_operation, k.getConsumingOperationplan()->getOperation()->getName());
00162 if (k.getProducingOperationplan())
00163 o->writeElement(Tags::tag_producing,
00164 Tags::tag_id, k.getProducingOperationplan()->getIdentifier(),
00165 Tags::tag_operation, k.getProducingOperationplan()->getOperation()->getName());
00166 o->writeElement(Tags::tag_dates, DateRange(k.getProducingDate(),k.getConsumingDate()));
00167 o->EndObject(Tags::tag_pegging);
00168 }
00169
00170
00171 PeggingIterator l(this, true);
00172 if (l) ++l;
00173 for (; l; ++l)
00174 {
00175 o->BeginObject(Tags::tag_pegging, Tags::tag_level, l.getLevel());
00176 o->writeElement(Tags::tag_quantity, l.getQuantityDemand());
00177 o->writeElement(Tags::tag_factor, l.getFactor());
00178 if (!l.getPegged()) o->writeElement(Tags::tag_id, "unpegged");
00179 o->writeElement(Tags::tag_buffer, Tags::tag_name, l.getBuffer()->getName());
00180 if (l.getConsumingOperationplan())
00181 o->writeElement(Tags::tag_consuming,
00182 Tags::tag_id, l.getConsumingOperationplan()->getIdentifier(),
00183 Tags::tag_operation, l.getConsumingOperationplan()->getOperation()->getName());
00184 if (l.getProducingOperationplan())
00185 o->writeElement(Tags::tag_producing,
00186 Tags::tag_id, l.getProducingOperationplan()->getIdentifier(),
00187 Tags::tag_operation, l.getProducingOperationplan()->getOperation()->getName());
00188 o->writeElement(Tags::tag_dates, DateRange(l.getProducingDate(),l.getConsumingDate()));
00189 o->EndObject(Tags::tag_pegging);
00190 }
00191 }
00192
00193 o->EndObject(tag);
00194 }
00195
00196
00197 PyObject* FlowPlan::getattro(const Attribute& attr)
00198 {
00199 if (attr.isA(Tags::tag_operationplan))
00200 return PythonObject(getOperationPlan());
00201 if (attr.isA(Tags::tag_quantity))
00202 return PythonObject(getQuantity());
00203 if (attr.isA(Tags::tag_flow))
00204 return PythonObject(getFlow());
00205 if (attr.isA(Tags::tag_date))
00206 return PythonObject(getDate());
00207 if (attr.isA(Tags::tag_onhand))
00208 return PythonObject(getOnhand());
00209 if (attr.isA(Tags::tag_buffer))
00210 return PythonObject(getFlow()->getBuffer());
00211 return NULL;
00212 }
00213
00214
00215 int FlowPlanIterator::initialize()
00216 {
00217
00218 PythonType& x = PythonExtension<FlowPlanIterator>::getType();
00219 x.setName("flowplanIterator");
00220 x.setDoc("frePPLe iterator for flowplan");
00221 x.supportiter();
00222 return x.typeReady();
00223 }
00224
00225
00226 PyObject* FlowPlanIterator::iternext()
00227 {
00228 FlowPlan* fl;
00229 if (buffer_or_opplan)
00230 {
00231
00232 while (*bufiter != buf->getFlowPlans().end() && (*bufiter)->getQuantity()==0.0)
00233 ++(*bufiter);
00234 if (*bufiter == buf->getFlowPlans().end()) return NULL;
00235 fl = const_cast<FlowPlan*>(static_cast<const FlowPlan*>(&*((*bufiter)++)));
00236 }
00237 else
00238 {
00239
00240 while (*opplaniter != opplan->endFlowPlans() && (*opplaniter)->getQuantity()==0.0)
00241 ++(*opplaniter);
00242 if (*opplaniter == opplan->endFlowPlans()) return NULL;
00243 fl = static_cast<FlowPlan*>(&*((*opplaniter)++));
00244 }
00245 Py_INCREF(fl);
00246 return const_cast<FlowPlan*>(fl);
00247 }
00248
00249 }