problems_demand.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   file : $URL: http://svn.code.sf.net/p/frepple/code/trunk/src/model/problems_demand.cpp $
00003   version : $LastChangedRevision: 1713 $  $LastChangedBy: jdetaeye $
00004   date : $LastChangedDate: 2012-07-18 11:46:01 +0200 (Wed, 18 Jul 2012) $
00005  ***************************************************************************/
00006 
00007 /***************************************************************************
00008  *                                                                         *
00009  * Copyright (C) 2007-2012 by Johan De Taeye, frePPLe bvba                 *
00010  *                                                                         *
00011  * This library is free software; you can redistribute it and/or modify it *
00012  * under the terms of the GNU Affero General Public License as published   *
00013  * by the Free Software Foundation; either version 3 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            *
00019  * GNU Affero General Public License for more details.                     *
00020  *                                                                         *
00021  * You should have received a copy of the GNU Affero General Public        *
00022  * License along with this program.                                        *
00023  * If not, see <http://www.gnu.org/licenses/>.                             *
00024  *                                                                         *
00025  ***************************************************************************/
00026 
00027 #define FREPPLE_CORE
00028 #include "frepple/model.h"
00029 
00030 namespace frepple
00031 {
00032 
00033 
00034 DECLARE_EXPORT void Demand::updateProblems()
00035 {
00036   // The relation between the demand and the related problem classes is such
00037   // that the demand object is the only active one. The problem objects are
00038   // fully controlled and managed by the associated demand object.
00039 
00040   // A flag for each problem type that may need to be created
00041   bool needsNotPlanned(false);
00042   bool needsEarly(false);
00043   bool needsLate(false);
00044   bool needsShort(false);
00045   bool needsExcess(false);
00046 
00047   // Problem detection disabled on this demand
00048   if (!getDetectProblems()) return;
00049 
00050   // Check which problems need to be created
00051   if (deli.empty())
00052   {
00053     // Check if a new ProblemDemandNotPlanned needs to be created
00054     if (getQuantity()>0.0) needsNotPlanned = true;
00055   }
00056   else
00057   {
00058     // Loop through the deliveries
00059     for (OperationPlan_list::iterator i = deli.begin(); i!=deli.end(); ++i)
00060     {
00061       // Check for ProblemLate problem
00062       long d(getDue() - (*i)->getDates().getEnd());
00063       if (d < 0L) needsLate = true;
00064       // Check for ProblemEarly problem
00065       else if (d > 0L) needsEarly = true;
00066     }
00067 
00068     // Check for ProblemShort problem
00069     double plannedqty = getPlannedQuantity();
00070     if (plannedqty + ROUNDING_ERROR < qty) needsShort = true;
00071 
00072     // Check for ProblemExcess Problem
00073     if (plannedqty - ROUNDING_ERROR > qty) needsExcess = true;
00074   }
00075 
00076   // Loop through the existing problems
00077   for (Problem::const_iterator j = Problem::begin(this, false);
00078       j!=Problem::end(); )
00079   {
00080     // Need to increment now and define a pointer to the problem, since the
00081     // problem can be deleted soon (which invalidates the iterator).
00082     Problem& curprob = *j;
00083     ++j;
00084     // The if-statement keeps the problem detection code concise and
00085     // concentrated. However, a drawback of this design is that a new Problem
00086     // subclass will also require a new Demand subclass. I think such a link
00087     // is acceptable.
00088     if (typeid(curprob) == typeid(ProblemEarly))
00089     {
00090       // if: problem needed and it exists already
00091       if (needsEarly) needsEarly = false;
00092       // else: problem not needed but it exists already
00093       else delete &curprob;
00094     }
00095     else if (typeid(curprob) == typeid(ProblemDemandNotPlanned))
00096     {
00097       if (needsNotPlanned) needsNotPlanned = false;
00098       else delete &curprob;
00099     }
00100     else if (typeid(curprob) == typeid(ProblemLate))
00101     {
00102       if (needsLate) needsLate = false;
00103       else delete &curprob;
00104     }
00105     else if (typeid(curprob) == typeid(ProblemShort))
00106     {
00107       if (needsShort) needsShort = false;
00108       else delete &curprob;
00109     }
00110     else if (typeid(curprob) == typeid(ProblemExcess))
00111     {
00112       if (needsExcess) needsExcess = false;
00113       else delete &curprob;
00114     }
00115     // Note that there may be other demand exceptions that are not caught in
00116     // this loop. These are problems defined and managed by subclasses.
00117   }
00118 
00119   // Create the problems that are required but aren't existing yet.
00120   if (needsNotPlanned) new ProblemDemandNotPlanned(this);
00121   if (needsLate) new ProblemLate(this);
00122   if (needsEarly) new ProblemEarly(this);
00123   if (needsShort) new ProblemShort(this);
00124   if (needsExcess) new ProblemExcess(this);
00125 }
00126 
00127 
00128 DECLARE_EXPORT string ProblemLate::getDescription() const
00129 {
00130   assert(getDemand() && !getDemand()->getDelivery().empty());
00131   TimePeriod t(getDemand()->getLatestDelivery()->getDates().getEnd()
00132       - getDemand()->getDue());
00133   return string("Demand '") + getDemand()->getName() + "' planned "
00134       + string(t) + " after its due date";
00135 }
00136 
00137 
00138 DECLARE_EXPORT string ProblemEarly::getDescription() const
00139 {
00140   assert(getDemand() && !getDemand()->getDelivery().empty());
00141   TimePeriod t(getDemand()->getDue()
00142       - getDemand()->getEarliestDelivery()->getDates().getEnd());
00143   return string("Demand '") + getDemand()->getName() + "' planned "
00144       + string(t) + " before its due date";
00145 }
00146 
00147 }

Documentation generated for frePPLe by  doxygen