problems_demand.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/problems_demand.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 
00031 namespace frepple
00032 {
00033 
00034 
00035 DECLARE_EXPORT void Demand::updateProblems()
00036 {
00037   // The relation between the demand and the related problem classes is such
00038   // that the demand object is the only active one. The problem objects are
00039   // fully controlled and managed by the associated demand object.
00040 
00041   // A flag for each problem type that may need to be created
00042   bool needsNotPlanned(false);
00043   bool needsEarly(false);
00044   bool needsLate(false);
00045   bool needsShort(false);
00046   bool needsExcess(false);
00047 
00048   // Check which problems need to be created
00049   if (!getHidden())
00050   {
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 
00077   // Loop through the existing problems
00078   for (Problem::const_iterator j = Problem::begin(this, false);
00079       j!=Problem::end(); )
00080   {
00081     // Need to increment now and define a pointer to the problem, since the
00082     // problem can be deleted soon (which invalidates the iterator).
00083     Problem& curprob = *j;
00084     ++j;
00085     // The if-statement keeps the problem detection code concise and
00086     // concentrated. However, a drawback of this design is that a new Problem
00087     // subclass will also require a new Demand subclass. I think such a link
00088     // is acceptable.
00089     if (typeid(curprob) == typeid(ProblemEarly))
00090     {
00091       // if: problem needed and it exists already
00092       if (needsEarly) needsEarly = false;
00093       // else: problem not needed but it exists already
00094       else delete &curprob;
00095     }
00096     else if (typeid(curprob) == typeid(ProblemDemandNotPlanned))
00097     {
00098       if (needsNotPlanned) needsNotPlanned = false;
00099       else delete &curprob;
00100     }
00101     else if (typeid(curprob) == typeid(ProblemLate))
00102     {
00103       if (needsLate) needsLate = false;
00104       else delete &curprob;
00105     }
00106     else if (typeid(curprob) == typeid(ProblemShort))
00107     {
00108       if (needsShort) needsShort = false;
00109       else delete &curprob;
00110     }
00111     else if (typeid(curprob) == typeid(ProblemExcess))
00112     {
00113       if (needsExcess) needsExcess = false;
00114       else delete &curprob;
00115     }
00116     // Note that there may be other demand exceptions that are not caught in
00117     // this loop. These are problems defined and managed by subclasses.
00118   }
00119 
00120   // Create the problems that are required but aren't existing yet.
00121   if (needsNotPlanned) new ProblemDemandNotPlanned(this);
00122   if (needsLate) new ProblemLate(this);
00123   if (needsEarly) new ProblemEarly(this);
00124   if (needsShort) new ProblemShort(this);
00125   if (needsExcess) new ProblemExcess(this);
00126 }
00127 
00128 
00129 DECLARE_EXPORT string ProblemLate::getDescription() const
00130 {
00131   assert(getDemand() && !getDemand()->getDelivery().empty());
00132   TimePeriod t(getDemand()->getLatestDelivery()->getDates().getEnd()
00133                - getDemand()->getDue());
00134   return string("Demand '") + getDemand()->getName() + "' planned "
00135          + string(t) + " after its due date";
00136 }
00137 
00138 
00139 DECLARE_EXPORT string ProblemEarly::getDescription() const
00140 {
00141   assert(getDemand() && !getDemand()->getDelivery().empty());
00142   TimePeriod t(getDemand()->getDue()
00143                - getDemand()->getEarliestDelivery()->getDates().getEnd());
00144   return string("Demand '") + getDemand()->getName() + "' planned "
00145          + string(t) + " before its due date";
00146 }
00147 
00148 }