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 "kplatokernel_export.h" |
24 | |
25 | #include "kptglobal.h" |
26 | |
27 | #include "kptduration.h" |
28 | #include "kptdatetime.h" |
29 | |
30 | #include <KoXmlReader.h> |
31 | |
32 | #include <QString> |
33 | #include <QList> |
34 | #include <QSharedData> |
35 | |
36 | #include <kdebug.h> |
37 | |
38 | class QDomElement; |
39 | |
40 | namespace KPlato |
41 | { |
42 | |
43 | class Effort; |
44 | class Appointment; |
45 | class Node; |
46 | class Resource; |
47 | class ResourceRequest; |
48 | class EffortCost; |
49 | class EffortCostMap; |
50 | class Schedule; |
51 | class XMLLoaderObject; |
52 | class DateTimeInterval; |
53 | |
54 | class AppointmentIntervalData : public QSharedData |
55 | { |
56 | public: |
57 | AppointmentIntervalData() : load( 0 ) {} |
58 | AppointmentIntervalData( const AppointmentIntervalData &other ) |
59 | : QSharedData( other ), start( other.start ), end( other.end ), load( other.load ) {} |
60 | ~AppointmentIntervalData() {} |
61 | |
62 | DateTime start; |
63 | DateTime end; |
64 | double load; //percent |
65 | }; |
66 | |
67 | class KPLATOKERNEL_EXPORT AppointmentInterval |
68 | { |
69 | public: |
70 | AppointmentInterval(); |
71 | AppointmentInterval(const AppointmentInterval &AppointmentInterval); |
72 | AppointmentInterval(const DateTime &start, const DateTime &end, double load=100); |
73 | ~AppointmentInterval(); |
74 | |
75 | Duration effort() const; |
76 | Duration effort(const DateTime &start, const DateTime end) const; |
77 | Duration effort(const 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 | KPLATOKERNEL_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 KPLATOKERNEL_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 existsing intervals. |
118 | void add( const AppointmentInterval &interval ); |
119 | /// Add an interval to the list. Handle overlapping with existsing 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 ( 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; |
140 | bool isEmpty() const { return m_map.isEmpty(); } |
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 | KPLATOKERNEL_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 countinous time interval with the same load. It can span dates. |
162 | */ |
163 | class KPLATOKERNEL_EXPORT Appointment { |
164 | public: |
165 | explicit Appointment(); |
166 | Appointment(Schedule *resource, Schedule *node, DateTime start, DateTime end, double load); |
167 | Appointment(Schedule *resource, Schedule *node, DateTime start, Duration duration, double load); |
168 | Appointment( const Appointment &app ); |
169 | ~Appointment(); |
170 | |
171 | bool isEmpty() const { return m_intervals.isEmpty(); } |
172 | void clear(); |
173 | |
174 | // get/set member values. |
175 | Schedule *node() const { return m_node; } |
176 | void setNode(Schedule *n) { m_node = n; } |
177 | |
178 | Schedule *resource() const { return m_resource; } |
179 | void setResource(Schedule *r) { m_resource = r; } |
180 | |
181 | DateTime startTime() const; |
182 | DateTime endTime() const; |
183 | double maxLoad() const; |
184 | |
185 | const Duration &repeatInterval() const {return m_repeatInterval;} |
186 | void setRepeatInterval(Duration ri) {m_repeatInterval=ri;} |
187 | |
188 | int repeatCount() const { return m_repeatCount; } |
189 | void setRepeatCount(int rc) { m_repeatCount=rc; } |
190 | |
191 | void deleteAppointmentFromRepeatList(DateTime time); |
192 | void addAppointmentToRepeatList(DateTime time); |
193 | |
194 | bool isBusy(const DateTime &start, const DateTime &end); |
195 | |
196 | /// attach appointment to resource and node |
197 | bool attach(); |
198 | /// detach appointment from resource and node |
199 | void detach(); |
200 | |
201 | void addInterval(const AppointmentInterval &a); |
202 | void addInterval(const DateTime &start, const DateTime &end, double load=100); |
203 | void addInterval(const DateTime &start, const Duration &duration, double load=100); |
204 | void setIntervals(const AppointmentIntervalList &lst); |
205 | |
206 | const AppointmentIntervalList &intervals() const { return m_intervals; } |
207 | int count() const { return m_intervals.map().count(); } |
208 | AppointmentInterval intervalAt( int index ) const { return m_intervals.map().values().value( index ); } |
209 | /// Return intervals between @p start and @p end |
210 | AppointmentIntervalList intervals( const DateTime &start, const DateTime &end ) const; |
211 | |
212 | bool loadXML(KoXmlElement &element, XMLLoaderObject &status, Schedule &sch); |
213 | void saveXML(QDomElement &element) const; |
214 | |
215 | /** |
216 | * Returns the planned effort and cost for the interval start to end (inclusive). |
217 | * Only dates with any planned effort is returned. |
218 | * If start or end is not valid, startTime.date() respectivly endTime().date() is used. |
219 | */ |
220 | EffortCostMap plannedPrDay(const QDate& start, const QDate& end, EffortCostCalculationType type = ECCT_All) const; |
221 | |
222 | /// Returns the planned effort from start to end |
223 | Duration effort(const DateTime &start, const DateTime &end, EffortCostCalculationType type = ECCT_All) const; |
224 | /// Returns the planned effort from start for the duration |
225 | Duration effort(const DateTime &start, const Duration &duration, EffortCostCalculationType type = ECCT_All) const; |
226 | |
227 | /// Returns the total planned effort for @p resource on this appointment |
228 | Duration plannedEffort( const Resource *resource, EffortCostCalculationType type = ECCT_All ) const; |
229 | /// Returns the total planned effort for this appointment |
230 | Duration plannedEffort(EffortCostCalculationType type = ECCT_All) const; |
231 | /// Returns the planned effort on the date |
232 | Duration plannedEffort(const QDate &date, EffortCostCalculationType type = ECCT_All) const; |
233 | /// Returns the planned effort for @p resource on the @p date date |
234 | Duration plannedEffort( const Resource *resource, const QDate &date, EffortCostCalculationType type = ECCT_All ) const; |
235 | /// Returns the planned effort upto and including date |
236 | Duration plannedEffortTo(const QDate &date, EffortCostCalculationType type = ECCT_All) const; |
237 | /// Returns the planned effort upto and including date |
238 | Duration plannedEffortTo( const Resource *resource, const QDate &date, 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(const QDate &date, EffortCostCalculationType type = ECCT_All); |
244 | /// Calculates the planned cost upto and including date |
245 | double plannedCostTo(const 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 | |
252 | void setCalculationMode( int mode ) { m_calculationMode = mode; } |
253 | int calculationMode() const { return m_calculationMode; } |
254 | |
255 | void merge(const Appointment &app); |
256 | Appointment ( const DateTimeInterval &interval ) const; |
257 | |
258 | void setAuxcilliaryInfo( const QString &info ) { m_auxcilliaryInfo = info; } |
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*> ; |
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 | |