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
38class QDomElement;
39
40namespace KPlato
41{
42
43class Effort;
44class Appointment;
45class Node;
46class Resource;
47class ResourceRequest;
48class EffortCost;
49class EffortCostMap;
50class Schedule;
51class XMLLoaderObject;
52class DateTimeInterval;
53
54class AppointmentIntervalData : public QSharedData
55{
56public:
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
67class KPLATOKERNEL_EXPORT AppointmentInterval
68{
69public:
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
100private:
101 QSharedDataPointer<AppointmentIntervalData> d;
102};
103KPLATOKERNEL_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 */
111class KPLATOKERNEL_EXPORT AppointmentIntervalList
112{
113public:
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 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;
140 bool isEmpty() const { return m_map.isEmpty(); }
141 void clear() { m_map.clear(); }
142
143protected:
144 void subtract( const AppointmentInterval &interval );
145 void subtract( const DateTime &st, const DateTime &et, double load );
146
147private:
148 QMultiMap<QDate, AppointmentInterval> m_map;
149};
150KPLATOKERNEL_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 */
163class KPLATOKERNEL_EXPORT Appointment {
164public:
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 extractIntervals( const DateTimeInterval &interval ) const;
257
258 void setAuxcilliaryInfo( const QString &info ) { m_auxcilliaryInfo = info; }
259 QString auxcilliaryInfo() const { return m_auxcilliaryInfo; }
260
261protected:
262 void copy(const Appointment &app);
263
264private:
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