1/* This file is part of the KDE project
2 Copyright (C) 2005 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;
7 version 2 of the License.
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 KPTEFFORTCOST_H
21#define KPTEFFORTCOST_H
22
23#include <QDateTime>
24#include <QMap>
25
26#include "kptduration.h"
27
28#include <kdebug.h>
29
30#include <QDebug>
31#include <QMetaType>
32
33namespace KPlato
34{
35
36class KPLATOKERNEL_EXPORT EffortCost
37{
38public:
39 EffortCost()
40 : m_effort(Duration::zeroDuration),
41 m_cost(0),
42 m_bcwpEffort(0.0),
43 m_bcwpCost(0.0)
44 {}
45 EffortCost(const Duration &effort, const double cost)
46 : m_effort(effort),
47 m_cost(cost),
48 m_bcwpEffort(0.0),
49 m_bcwpCost(0.0)
50 {
51 //kDebug();
52 }
53 ~EffortCost() {
54 //kDebug();
55 }
56 double hours() const { return m_effort.toDouble( Duration::Unit_h ); }
57 Duration effort() const { return m_effort; }
58 void setEffort( const Duration &effort ) { m_effort = effort; }
59 double cost() const { return m_cost; }
60 void setCost(double cost) { m_cost = cost; }
61 void setBcwpEffort( double value ) { m_bcwpEffort = value; }
62 double bcwpEffort() const { return m_bcwpEffort; }
63 void setBcwpCost( double value ) { m_bcwpCost = value; }
64 double bcwpCost() const { return m_bcwpCost; }
65 void add(const Duration &effort, double cost, double bcwpEffort = 0.0, double bcwpCost = 0.0 );
66 EffortCost &operator+=(const EffortCost &ec) {
67 add(ec.m_effort, ec.m_cost, ec.m_bcwpEffort, ec.m_bcwpCost);
68 return *this;
69 }
70
71#ifndef QT_NO_DEBUG_STREAM
72 QDebug debug( QDebug dbg) const;
73#endif
74
75private:
76 Duration m_effort;
77 double m_cost;
78 double m_bcwpEffort;
79 double m_bcwpCost;
80};
81
82typedef QMap<QDate, EffortCost> EffortCostDayMap;
83class KPLATOKERNEL_EXPORT EffortCostMap
84{
85public:
86 EffortCostMap()
87 : m_days() {
88 //kDebug();
89 }
90 EffortCostMap( const EffortCostMap &map );
91
92 ~EffortCostMap() {
93 //kDebug();
94 m_days.clear();
95 }
96
97 void clear() { m_days.clear(); }
98
99 EffortCost effortCost(const QDate &date) const {
100 EffortCost ec;
101 if (!date.isValid()) {
102 //kError()<<"Date not valid";
103 return ec;
104 }
105 EffortCostDayMap::const_iterator it = m_days.find(date);
106 if (it != m_days.end())
107 ec = it.value();
108 return ec;
109 }
110 void insert(const QDate &date, const EffortCost &ec );
111
112 void insert(const QDate &date, const Duration &effort, const double cost) {
113 if (!date.isValid()) {
114 //kError()<<"Date not valid";
115 return;
116 }
117 m_days.insert(date, EffortCost(effort, cost));
118 }
119 /**
120 * If data for this date already exists add the new values to the old,
121 * else the new values are inserted.
122 */
123 EffortCost &add(const QDate &date, const Duration &effort, const double cost) {
124 return add(date, EffortCost(effort, cost));
125 }
126 /**
127 * If data for this date already exists add the new values to the old,
128 * else the new value is inserted.
129 */
130 EffortCost &add(const QDate &date, const EffortCost &ec) {
131 if (!date.isValid()) {
132 //kError()<<"Date not valid";
133 return zero();
134 }
135 //kDebug()<<date.toString();
136 return m_days[date] += ec;
137 }
138
139 bool isEmpty() const {
140 return m_days.isEmpty();
141 }
142
143 const EffortCostDayMap &days() const { return m_days; }
144
145 EffortCostMap &operator=(const EffortCostMap &ec);
146 EffortCostMap &operator+=(const EffortCostMap &ec);
147 EffortCost &effortCostOnDate(const QDate &date) {
148 return m_days[date];
149 }
150 /// Return total cost for the next num days starting at date
151 double cost(const QDate &date, int num=7) {
152 double r=0.0;
153 for (int i=0; i < num; ++i) {
154 r += costOnDate(date.addDays(i));
155 }
156 return r;
157 }
158 double costOnDate(const QDate &date) const {
159 if (!date.isValid()) {
160 //kError()<<"Date not valid";
161 return 0.0;
162 }
163 if (m_days.contains(date)) {
164 return m_days[date].cost();
165 }
166 return 0.0;
167 }
168 Duration effortOnDate(const QDate &date) const {
169 if (!date.isValid()) {
170 kError()<<"Date not valid";
171 return Duration::zeroDuration;
172 }
173 if (m_days.contains(date)) {
174 return m_days[date].effort();
175 }
176 return Duration::zeroDuration;
177 }
178 double hoursOnDate(const QDate &date) const {
179 if (!date.isValid()) {
180 kError()<<"Date not valid";
181 return 0.0;
182 }
183 if (m_days.contains(date)) {
184 return m_days[date].hours();
185 }
186 return 0.0;
187 }
188 void addBcwpCost( const QDate &date, double cost );
189
190 double bcwpCostOnDate(const QDate &date) const {
191 if (!date.isValid()) {
192 //kError()<<"Date not valid";
193 return 0.0;
194 }
195 if (m_days.contains(date)) {
196 return m_days[date].bcwpCost();
197 }
198 return 0.0;
199 }
200 double bcwpEffortOnDate(const QDate &date) const {
201 if (!date.isValid()) {
202 //kError()<<"Date not valid";
203 return 0.0;
204 }
205 if (m_days.contains(date)) {
206 return m_days[date].bcwpEffort();
207 }
208 return 0.0;
209 }
210 double totalCost() const {
211 double cost = 0.0;
212 EffortCostDayMap::const_iterator it;
213 for(it = m_days.constBegin(); it != m_days.constEnd(); ++it) {
214 cost += it.value().cost();
215 }
216 return cost;
217 }
218 Duration totalEffort() const {
219 Duration eff;
220 EffortCostDayMap::const_iterator it;
221 for(it = m_days.constBegin(); it != m_days.constEnd(); ++it) {
222 eff += it.value().effort();
223 }
224 return eff;
225 }
226
227 double costTo( const QDate &date ) const {
228 double cost = 0.0;
229 EffortCostDayMap::const_iterator it;
230 for(it = m_days.constBegin(); it != m_days.constEnd(); ++it) {
231 if ( it.key() > date ) {
232 break;
233 }
234 cost += it.value().cost();
235 }
236 return cost;
237 }
238 Duration effortTo( const QDate &date ) const {
239 Duration eff;
240 EffortCostDayMap::const_iterator it;
241 for(it = m_days.constBegin(); it != m_days.constEnd(); ++it) {
242 if ( it.key() > date ) {
243 break;
244 }
245 eff += it.value().effort();
246 }
247 return eff;
248 }
249 double hoursTo( const QDate &date ) const {
250 double eff = 0.0;
251 EffortCostDayMap::const_iterator it;
252 for(it = m_days.constBegin(); it != m_days.constEnd(); ++it) {
253 if ( it.key() > date ) {
254 break;
255 }
256 eff += it.value().hours();
257 }
258 return eff;
259 }
260 /// Return the BCWP cost to @p date. (BSWP is cumulative)
261 double bcwpCost( const QDate &date ) const;
262 /// Return the BCWP effort to @p date. (BSWP is cumulative)
263 double bcwpEffort( const QDate &date ) const;
264 /// Return the BCWP total cost. Since BCWP is cumulative this is the last entry.
265 double bcwpTotalCost() const {
266 double cost = 0.0;
267 if ( ! m_days.isEmpty() ) {
268 cost = m_days.values().last().bcwpCost();
269 }
270 return cost;
271 }
272 /// Return the BCWP total cost. Since BCWP is cumulative this is the last entry.
273 double bcwpTotalEffort() const {
274 double eff = 0.0;
275 if ( ! m_days.isEmpty() ) {
276 eff = m_days.values().last().bcwpEffort();
277 }
278 return eff;
279 }
280
281 QDate startDate() const { return m_days.isEmpty() ? QDate() : m_days.keys().first(); }
282 QDate endDate() const { return m_days.isEmpty() ? QDate() : m_days.keys().last(); }
283
284#ifndef QT_NO_DEBUG_STREAM
285 QDebug debug( QDebug dbg) const;
286#endif
287
288private:
289 EffortCost &zero() { return m_zero; }
290
291private:
292 EffortCost m_zero;
293 EffortCostDayMap m_days;
294};
295
296
297} //namespace KPlato
298
299Q_DECLARE_METATYPE( KPlato::EffortCost )
300Q_DECLARE_METATYPE( KPlato::EffortCostMap )
301
302#ifndef QT_NO_DEBUG_STREAM
303KPLATOKERNEL_EXPORT QDebug operator<<( QDebug dbg, const KPlato::EffortCost &ec );
304KPLATOKERNEL_EXPORT QDebug operator<<( QDebug dbg, const KPlato::EffortCost *ec );
305KPLATOKERNEL_EXPORT QDebug operator<<( QDebug dbg, const KPlato::EffortCostMap &i );
306#endif
307
308#endif
309