flowplan.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002   file : $URL: https://frepple.svn.sourceforge.net/svnroot/frepple/tags/0.8.0/src/model/flowplan.cpp $
00003   version : $LastChangedRevision: 1108 $  $LastChangedBy: jdetaeye $
00004   date : $LastChangedDate: 2009-12-06 18:54:18 +0100 (Sun, 06 Dec 2009) $
00005  ***************************************************************************/
00006 
00007 /***************************************************************************
00008  *                                                                         *
00009  * Copyright (C) 2007 by Johan De Taeye                                    *
00010  *                                                                         *
00011  * This library is free software; you can redistribute it and/or modify it *
00012  * under the terms of the GNU Lesser General Public License as published   *
00013  * by the Free Software Foundation; either version 2.1 of the License, or  *
00014  * (at your option) any later version.                                     *
00015  *                                                                         *
00016  * This library is distributed in the hope that it will be useful,         *
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
00019  * General Public License for more details.                                *
00020  *                                                                         *
00021  * You should have received a copy of the GNU Lesser General Public        *
00022  * License along with this library; if not, write to the Free Software     *
00023  * Foundation Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,*
00024  * USA                                                                     *
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   // Initialize the metadata
00039   metadata = new MetaCategory("flowplan", "flowplans");
00040 
00041   // Initialize the Python type
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   // Initialize the Python type
00057   initType(metadata);
00058 
00059   // Link the flowplan to the operationplan
00060   oper = opplan;
00061   nextFlowPlan = NULL;
00062   if (opplan->firstflowplan)
00063   {
00064     // Append to the end
00065     FlowPlan *c = opplan->firstflowplan;
00066     while (c->nextFlowPlan) c = c->nextFlowPlan;
00067     c->nextFlowPlan = this;
00068   }
00069   else
00070     // First in the list
00071     opplan->firstflowplan = this;
00072 
00073   // Compute the flowplan quantity
00074   fl->getBuffer()->flowplans.insert(
00075     this,
00076     fl->getFlowplanQuantity(this),
00077     fl->getFlowplanDate(this)
00078     );
00079 
00080   // Mark the operation and buffer as having changed. This will trigger the
00081   // recomputation of their problems
00082   fl->getBuffer()->setChanged();
00083   fl->getOperation()->setChanged();
00084 }
00085 
00086 
00087 DECLARE_EXPORT void FlowPlan::update()
00088 {
00089   // Update the timeline data structure
00090   fl->getBuffer()->flowplans.update(
00091     this,
00092     fl->getFlowplanQuantity(this),
00093     fl->getFlowplanDate(this)
00094     );
00095 
00096   // Mark the operation and buffer as having changed. This will trigger the
00097   // recomputation of their problems
00098   fl->getBuffer()->setChanged();
00099   fl->getOperation()->setChanged();
00100 }
00101 
00102 
00103 DECLARE_EXPORT void FlowPlan::setFlow(const Flow* newfl)
00104 {
00105   // No change
00106   if (newfl == fl) return;
00107 
00108   // Verify the data
00109   if (!newfl) throw LogicException("Can't switch to NULL flow");
00110 
00111   // Remove from the old buffer, if there is one
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   // Insert in the new buffer
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 // Remember that this method only superficially looks like a normal
00133 // writeElement() method.
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   // Write pegging info
00146   if (o->getContentType() == XMLOutput::PLANDETAIL)
00147   {
00148     // Write the upstream pegging
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     // Write the downstream pegging
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   // Initialize the type
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     // Skip uninteresting entries
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     // Skip uninteresting entries
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 } // end namespace

Generated on 16 Apr 2010 for frePPLe by  doxygen 1.6.1