problems_demand.cpp
Go to the documentation of this file.00001 /*************************************************************************** 00002 file : $URL: https://frepple.svn.sourceforge.net/svnroot/frepple/trunk/src/model/problems_demand.cpp $ 00003 version : $LastChangedRevision: 713 $ $LastChangedBy: jdetaeye $ 00004 date : $LastChangedDate: 2008-03-28 15:26:21 +0100 (Fri, 28 Mar 2008) $ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA * 00024 * * 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 TimePeriod t((*(getDemand()->getDelivery().begin()))->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 TimePeriod t(getDemand()->getDue() 00141 - (*(getDemand()->getDelivery().begin()))->getDates().getEnd()); 00142 return string("Demand '") + getDemand()->getName() + "' planned " 00143 + string(t) + " before its due date"; 00144 } 00145 00146 }
Documentation generated by
