1 /* This file is part of the KDE project 2 Copyright (C) 2005 - 2011 Dag Andersen <danders@get2net.dk> 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Library General Public 6 License as published by the Free Software Foundation; either 7 version 2 of the License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Library General Public License for more details. 13 14 You should have received a copy of the GNU Library General Public License 15 along with this library; see the file COPYING.LIB. If not, write to 16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Boston, MA 02110-1301, USA. 18 */ 19 20 #ifndef KPTAPPOINTMENT_H 21 #define KPTAPPOINTMENT_H 22 23 #include "plankernel_export.h" 24 25 #include "kptglobal.h" 26 27 #include "kptduration.h" 28 #include "kptdatetime.h" 29 30 #include <KoXmlReaderForward.h> 31 32 #include <QString> 33 #include <QList> 34 #include <QMultiMap> 35 #include <QSharedData> 36 37 class QDomElement; 38 39 namespace KPlato 40 { 41 42 class Effort; 43 class Appointment; 44 class Node; 45 class Resource; 46 class EffortCost; 47 class EffortCostMap; 48 class Schedule; 49 class XMLLoaderObject; 50 class DateTimeInterval; 51 class TimeInterval; 52 53 class AppointmentIntervalData : public QSharedData 54 { 55 public: AppointmentIntervalData()56 AppointmentIntervalData() : load(0) {} AppointmentIntervalData(const AppointmentIntervalData & other)57 AppointmentIntervalData(const AppointmentIntervalData &other) 58 : QSharedData(other), start(other.start), end(other.end), load(other.load) {} ~AppointmentIntervalData()59 ~AppointmentIntervalData() {} 60 61 DateTime start; 62 DateTime end; 63 double load; //percent 64 }; 65 66 class PLANKERNEL_EXPORT AppointmentInterval 67 { 68 public: 69 AppointmentInterval(); 70 AppointmentInterval(const AppointmentInterval &AppointmentInterval); 71 AppointmentInterval(const DateTime &start, const DateTime &end, double load=100); 72 AppointmentInterval(QDate date, const TimeInterval &timeInterval, double load=100); 73 ~AppointmentInterval(); 74 75 Duration effort() const; 76 Duration effort(const DateTime &start, const DateTime &end) const; 77 Duration effort(QDate time, bool upto) const; 78 79 bool loadXML(KoXmlElement &element, XMLLoaderObject &status); 80 void saveXML(QDomElement &element) const; 81 82 const DateTime &startTime() const; 83 void setStartTime(const DateTime &time); 84 const DateTime &endTime() const; 85 void setEndTime(const DateTime &time); 86 double load() const; 87 void setLoad(double load); 88 89 bool isValid() const; 90 AppointmentInterval firstInterval(const AppointmentInterval &interval, const DateTime &from) const; 91 92 bool operator==(const AppointmentInterval &interval) const; 93 bool operator<(const AppointmentInterval &interval) const; 94 95 bool intersects(const AppointmentInterval &other) const; 96 AppointmentInterval interval(const DateTime &start, const DateTime &end) const; 97 98 QString toString() const; 99 100 private: 101 QSharedDataPointer<AppointmentIntervalData> d; 102 }; 103 PLANKERNEL_EXPORT QDebug operator<<(QDebug dbg, const KPlato::AppointmentInterval& i); 104 105 106 /** 107 * This list is sorted after 1) startdatetime, 2) enddatetime. 108 * The intervals do not overlap, an interval does not start before the 109 * previous interval ends. 110 */ 111 class PLANKERNEL_EXPORT AppointmentIntervalList 112 { 113 public: 114 AppointmentIntervalList(); 115 AppointmentIntervalList(const QMultiMap<QDate, AppointmentInterval> &other); 116 117 /// Add @p interval to the list. Handle overlapping with existing intervals. 118 void add(const AppointmentInterval &interval); 119 /// Add an interval to the list. Handle overlapping with existing intervals. 120 void add(const DateTime &st, const DateTime &et, double load); 121 /// Load intervals from document 122 bool loadXML(KoXmlElement &element, XMLLoaderObject &status); 123 /// Save intervals to document 124 void saveXML(QDomElement &element) const; 125 126 AppointmentIntervalList &operator+=(const AppointmentIntervalList &lst); 127 AppointmentIntervalList &operator-=(const AppointmentIntervalList &lst); 128 AppointmentIntervalList &operator=(const AppointmentIntervalList &lst); 129 130 /// Returns the intervals in the range @p start, @p end 131 AppointmentIntervalList extractIntervals(const DateTime &start, const DateTime &end) const; 132 133 /// Return the total effort 134 Duration effort() const; 135 /// Return the effort limited to the interval @p start, @p end 136 Duration effort(const DateTime &start, const DateTime &end) const; 137 138 QMultiMap<QDate, AppointmentInterval> map(); 139 const QMultiMap<QDate, AppointmentInterval> &map() const; isEmpty()140 bool isEmpty() const { return m_map.isEmpty(); } clear()141 void clear() { m_map.clear(); } 142 143 protected: 144 void subtract(const AppointmentInterval &interval); 145 void subtract(const DateTime &st, const DateTime &et, double load); 146 147 private: 148 QMultiMap<QDate, AppointmentInterval> m_map; 149 }; 150 PLANKERNEL_EXPORT QDebug operator<<(QDebug dbg, const KPlato::AppointmentIntervalList& i); 151 152 /** 153 * A Resource can be scheduled to be used at any time, 154 * this is represented internally with Appointments 155 * There is one Appointment per resource-task pair. 156 * An appointment can be divided into several intervals, represented with 157 * a list of AppointmentInterval. 158 * This list is sorted after 1) startdatetime, 2) enddatetime. 159 * The intervals do not overlap, an interval does not start before the 160 * previous interval ends. 161 * An interval is a continuous time interval with the same load. It can span dates. 162 */ 163 class PLANKERNEL_EXPORT Appointment { 164 public: 165 explicit Appointment(); 166 Appointment(Schedule *resource, Schedule *node, const DateTime &start, const DateTime &end, double load); 167 Appointment(Schedule *resource, Schedule *node, const DateTime &start, Duration duration, double load); 168 Appointment(const Appointment &app); 169 ~Appointment(); 170 isEmpty()171 bool isEmpty() const { return m_intervals.isEmpty(); } 172 void clear(); 173 174 // get/set member values. node()175 Schedule *node() const { return m_node; } setNode(Schedule * n)176 void setNode(Schedule *n) { m_node = n; } 177 resource()178 Schedule *resource() const { return m_resource; } setResource(Schedule * r)179 void setResource(Schedule *r) { m_resource = r; } 180 181 DateTime startTime() const; 182 DateTime endTime() const; 183 double maxLoad() const; 184 repeatInterval()185 const Duration &repeatInterval() const {return m_repeatInterval;} setRepeatInterval(Duration ri)186 void setRepeatInterval(Duration ri) {m_repeatInterval=ri;} 187 repeatCount()188 int repeatCount() const { return m_repeatCount; } setRepeatCount(int rc)189 void setRepeatCount(int rc) { m_repeatCount=rc; } 190 191 bool isBusy(const DateTime &start, const DateTime &end); 192 193 /// attach appointment to resource and node 194 bool attach(); 195 /// detach appointment from resource and node 196 void detach(); 197 198 void addInterval(const AppointmentInterval &a); 199 void addInterval(const DateTime &start, const DateTime &end, double load=100); 200 void addInterval(const DateTime &start, KPlato::Duration duration, double load=100); 201 void setIntervals(const AppointmentIntervalList &lst); 202 intervals()203 const AppointmentIntervalList &intervals() const { return m_intervals; } count()204 int count() const { return m_intervals.map().count(); } intervalAt(int index)205 AppointmentInterval intervalAt(int index) const { return m_intervals.map().values().value(index); } 206 /// Return intervals between @p start and @p end 207 AppointmentIntervalList intervals(const DateTime &start, const DateTime &end) const; 208 209 bool loadXML(KoXmlElement &element, XMLLoaderObject &status, Schedule &sch); 210 void saveXML(QDomElement &element) const; 211 212 /** 213 * Returns the planned effort and cost for the interval start to end (inclusive). 214 * Only dates with any planned effort is returned. 215 * If start or end is not valid, startTime.date() respectively endTime().date() is used. 216 */ 217 EffortCostMap plannedPrDay(QDate start, QDate end, EffortCostCalculationType type = ECCT_All) const; 218 219 /// Returns the planned effort from start to end 220 Duration effort(const DateTime &start, const DateTime &end, EffortCostCalculationType type = ECCT_All) const; 221 /// Returns the planned effort from start for the duration 222 Duration effort(const DateTime &start, KPlato::Duration duration, EffortCostCalculationType type = ECCT_All) const; 223 224 /// Returns the total planned effort for @p resource on this appointment 225 Duration plannedEffort(const Resource *resource, EffortCostCalculationType type = ECCT_All) const; 226 /// Returns the total planned effort for this appointment 227 Duration plannedEffort(EffortCostCalculationType type = ECCT_All) const; 228 /// Returns the planned effort on the date 229 Duration plannedEffort(QDate date, EffortCostCalculationType type = ECCT_All) const; 230 /// Returns the planned effort for @p resource on the @p date date 231 Duration plannedEffort(const Resource *resource, QDate date, EffortCostCalculationType type = ECCT_All) const; 232 /// Returns the planned effort upto and including date 233 Duration plannedEffortTo(QDate date, EffortCostCalculationType type = ECCT_All) const; 234 /// Returns the planned effort upto and including date 235 Duration plannedEffortTo(const Resource *resource, QDate date, EffortCostCalculationType type = ECCT_All) const; 236 237 /// Returns the planned effort upto and including @p time 238 Duration plannedEffortTo(const QDateTime &time, EffortCostCalculationType type = ECCT_All) const; 239 240 /// Calculates the total planned cost for this appointment 241 EffortCost plannedCost(EffortCostCalculationType type = ECCT_All) const; 242 /// Calculates the planned cost on date 243 double plannedCost(QDate date, EffortCostCalculationType type = ECCT_All); 244 /// Calculates the planned cost upto and including date 245 double plannedCostTo(QDate date, EffortCostCalculationType type = ECCT_All); 246 247 Appointment &operator=(const Appointment &app); 248 Appointment &operator+=(const Appointment &app); 249 Appointment operator+(const Appointment &app); 250 Appointment &operator-=(const Appointment &app); 251 setCalculationMode(int mode)252 void setCalculationMode(int mode) { m_calculationMode = mode; } calculationMode()253 int calculationMode() const { return m_calculationMode; } 254 255 void merge(const Appointment &app); 256 Appointment extractIntervals(const DateTimeInterval &interval) const; 257 setAuxcilliaryInfo(const QString & info)258 void setAuxcilliaryInfo(const QString &info) { m_auxcilliaryInfo = info; } auxcilliaryInfo()259 QString auxcilliaryInfo() const { return m_auxcilliaryInfo; } 260 261 protected: 262 void copy(const Appointment &app); 263 264 private: 265 Schedule *m_node; 266 Schedule *m_resource; 267 int m_calculationMode; // Type of appointment 268 Duration m_repeatInterval; 269 int m_repeatCount; 270 QList<Duration*> m_extraRepeats; 271 QList<Duration*> m_skipRepeats; 272 273 AppointmentIntervalList m_intervals; 274 275 QString m_auxcilliaryInfo; 276 }; 277 278 279 } //KPlato namespace 280 281 #endif 282