1 /* This file is part of the KDE project
2    Copyright (C) 2008 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 // clazy:excludeall=qstring-arg
21 #include "AccountsTester.h"
22 
23 #include "kptaccount.h"
24 #include "kptduration.h"
25 #include "kptnode.h"
26 #include "kpttask.h"
27 
28 #include "debug.cpp"
29 #include <QTest>
30 
31 namespace KPlato
32 {
33 
init()34 void AccountsTester::init()
35 {
36     project = new Project();
37     project->setId(project->uniqueCalendarId());
38     project->registerNodeId(project);
39 
40     today = QDate::currentDate();
41     tomorrow = today.addDays(1);
42     yesterday = today.addDays(-1);
43     nextweek = today.addDays(7);
44     t1 = QTime(9, 0, 0);
45     t2 = QTime(17, 0, 0);
46     length = t1.msecsTo(t2);
47 
48     t = project->createTask();
49     t->setName("T1");
50     project->addTask(t, project);
51     t->estimate()->setUnit(Duration::Unit_d);
52     t->estimate()->setExpectedEstimate(1.0);
53 
54     sm = project->createScheduleManager("Test Plan");
55     project->addScheduleManager(sm);
56 
57     // standard worktime defines 8 hour day as default
58     Calendar *c = new Calendar();
59     c->setDefault(true);
60     for (int i=1; i <= 7; ++i) {
61         CalendarDay *d = c->weekday(i);
62         d->setState(CalendarDay::Working);
63         d->addInterval(t1, length);
64     }
65     project->addCalendar(c);
66 
67     ResourceGroup *g = new ResourceGroup();
68     project->addResourceGroup(g);
69     r = new Resource();
70     r->setAvailableFrom(QDateTime(yesterday, QTime(), Qt::LocalTime));
71     r->setCalendar(c);
72     r->setNormalRate(100.0);
73     project->addResource(g, r);
74 
75     ResourceGroupRequest *gr = new ResourceGroupRequest(g);
76     t->addRequest(gr);
77     ResourceRequest *rr = new ResourceRequest(r, 100);
78     gr->addResourceRequest(rr);
79     t->estimate()->setType(Estimate::Type_Effort);
80 
81     //qDebug()<<"Calculate forward, Task: ASAP -----------------------------------";
82     project->setConstraintStartTime(DateTime(today, QTime()));
83     project->setConstraintEndTime(DateTime(tomorrow, QTime()));
84     sm->createSchedules();
85     project->calculate(*sm);
86 
87     QCOMPARE(t->earlyStart(), t->requests().workTimeAfter(project->startTime()));
88     QVERIFY(t->lateStart() >=  t->earlyStart());
89     QVERIFY(t->earlyFinish() <= t->endTime());
90     QVERIFY(t->lateFinish() >= t->endTime());
91 
92     QCOMPARE(t->startTime(), DateTime(today, t1));
93     QCOMPARE(t->endTime(), t->startTime() + Duration(0, 8, 0));
94 //###    QVERIFY(t->schedulingError() == false);
95 
96     sm->setBaselined(true);
97 
98 
99 }
cleanup()100 void AccountsTester::cleanup()
101 {
102     delete project;
103     project = 0;
104     t = 0;
105     r = 0;
106     sm = 0;
107     topaccount = 0;
108 }
109 
defaultAccount()110 void AccountsTester::defaultAccount() {
111     Account *a = new Account("Default Account");
112     project->accounts().insert(a);
113     project->accounts().setDefaultAccount(a);
114 
115     EffortCostMap ec = project->accounts().plannedCost(*a, t->startTime().date(), t->endTime().date());
116     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
117     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
118     QCOMPARE(ec.totalCost(), 800.0);
119 
120     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
121     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
122     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
123     QCOMPARE(ec.totalCost(), 0.0);
124 
125     t->completion().setEntrymode(Completion::FollowPlan);
126     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
127     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
128     QCOMPARE(ec.totalCost(), 800.0);
129 
130     t->completion().setEntrymode(Completion::EnterCompleted);
131     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
132     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
133     QCOMPARE(ec.totalCost(), 0.0);
134 
135     t->completion().setEntrymode(Completion::EnterCompleted);
136     t->completion().setStarted(true);
137     t->completion().setStartTime(DateTime(tomorrow, QTime()));
138     t->completion().setPercentFinished(tomorrow, 50);
139     ec = project->accounts().actualCost(*a, t->startTime().date(), tomorrow);
140     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
141     QCOMPARE(ec.totalCost(), 0.0);
142 
143     t->completion().setEntrymode(Completion::EnterEffortPerTask);
144     t->completion().setActualEffort(tomorrow, Duration(0, 4, 0));
145     ec = project->accounts().actualCost(*a, t->startTime().date(), tomorrow);
146     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
147     QCOMPARE(ec.totalCost(), 400.0);
148 
149     t->completion().setEntrymode(Completion::EnterEffortPerResource);
150     Completion::UsedEffort *ue = new Completion::UsedEffort();
151     Completion::UsedEffort::ActualEffort e(Duration(0, 6, 0)) ;
152     ue->setEffort(tomorrow, e);
153     t->completion().addUsedEffort(r, ue);
154     ec = project->accounts().actualCost(*a, t->startTime().date(), tomorrow);
155     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 6.0);
156     QCOMPARE(ec.totalCost(), 600.0);
157 
158 }
159 
costPlaces()160 void AccountsTester::costPlaces() {
161     EffortCostMap ec;
162     Account *top = new Account("Top account");
163     project->accounts().insert(top);
164 
165     Account *a = new Account("Running account");
166     project->accounts().insert(a, top);
167     a->addRunning(*t);
168     ec = a->plannedCost(sm->scheduleId());
169     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
170     QCOMPARE(ec.totalCost(), 800.0);
171 
172     a = new Account("Startup account");
173     project->accounts().insert(a, top);
174     a->addStartup(*t);
175     t->setStartupCost(200.0);
176     ec = a->plannedCost(sm->scheduleId());
177     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
178     QCOMPARE(ec.totalCost(), 200.0);
179 
180     a = new Account("Shutdown cost");
181     project->accounts().insert(a, top);
182     a->addShutdown(*t);
183     t->setShutdownCost(300.0);
184     ec = a->plannedCost(sm->scheduleId());
185     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
186     QCOMPARE(ec.totalCost(), 300.0);
187 
188     ec = top->plannedCost(sm->scheduleId());
189 
190 //    Debug::print(top, sm->scheduleId(), "All planned cost in child accounts--------");
191     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
192     QCOMPARE(ec.totalCost(), 1300.0);
193 
194     a = new Account("All cost in one account");
195     project->accounts().insert(a);
196     a->addRunning(*t);
197     a->addStartup(*t);
198     a->addShutdown(*t);
199     ec = a->plannedCost(sm->scheduleId());
200 //    Debug::print(a, sm->scheduleId(), "All planned cost in one account-----------");
201     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
202     QCOMPARE(ec.totalCost(), 1300.0);
203 
204 }
205 
startupDefault()206 void AccountsTester::startupDefault() {
207     Account *a = new Account("Default Account");
208     project->accounts().insert(a);
209     project->accounts().setDefaultAccount(a);
210 
211     EffortCostMap ec = project->accounts().plannedCost(*a, t->startTime().date(), t->endTime().date());
212     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
213     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
214     QCOMPARE(ec.totalCost(), 800.0);
215 
216     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
217     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
218     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
219     QCOMPARE(ec.totalCost(), 0.0);
220 
221     t->setStartupCost(25.0);
222 
223     ec = project->accounts().plannedCost(*a, t->startTime().date(), t->endTime().date());
224     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
225     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
226     QCOMPARE(ec.totalCost(), 825.0);
227 
228     qDebug()<< t->completion().entryModeToString();
229     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
230     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
231     QVERIFY(! t->completion().isStarted());
232     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
233     QCOMPARE(ec.totalCost(), 0.0);
234 
235     t->completion().setEntrymode(Completion::EnterCompleted);
236     t->completion().setStarted(true);
237     t->completion().setStartTime(DateTime(tomorrow, QTime()));
238     t->completion().setPercentFinished(tomorrow, 50);
239     QVERIFY(t->completion().isStarted());
240     qDebug()<<t->completion().startTime()<<":"<<t->startTime().date()<<tomorrow;
241     ec = project->accounts().actualCost(*a, t->startTime().date(), tomorrow);
242     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
243     QCOMPARE(ec.totalCost(), 25.0);
244 
245     ec = project->accounts().actualCost(*a, QDate(), QDate());
246     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
247     QCOMPARE(ec.totalCost(), 25.0);
248 
249     t->completion().setEntrymode(Completion::EnterEffortPerTask);
250     t->completion().setActualEffort(tomorrow, Duration(0, 4, 0));
251     ec = project->accounts().actualCost(*a, t->startTime().date(), tomorrow);
252     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
253     QCOMPARE(ec.totalCost(), 425.0);
254 
255     ec = project->accounts().actualCost(*a, QDate(), QDate());
256     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
257     QCOMPARE(ec.totalCost(), 425.0);
258 }
259 
startupAccount()260 void AccountsTester::startupAccount() {
261     Account *a = new Account("Account");
262     project->accounts().insert(a);
263     a->addStartup(*t);
264 
265     // planned wo startup cost
266     EffortCostMap ec = project->accounts().plannedCost(*a, t->startTime().date(), t->endTime().date());
267     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
268     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
269     QCOMPARE(ec.totalCost(), 0.0);
270 
271     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
272     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
273     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
274     QCOMPARE(ec.totalCost(), 0.0);
275 
276     // planned with startup cost, no running cost
277     t->setStartupCost(25.0);
278     ec = project->accounts().plannedCost(*a, t->startTime().date(), t->endTime().date());
279     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
280     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
281     QCOMPARE(ec.totalCost(), 25.0);
282 
283     // actual, task not started
284     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
285     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
286     QVERIFY(! t->completion().isStarted());
287     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
288     QCOMPARE(ec.totalCost(), 0.0);
289 
290     // start task (tomorrow), no actual effort
291     t->completion().setEntrymode(Completion::EnterCompleted);
292     t->completion().setStarted(true);
293     t->completion().setStartTime(DateTime(tomorrow, QTime()));
294     QVERIFY(t->completion().isStarted());
295 
296     ec = project->accounts().actualCost(*a, tomorrow, tomorrow);
297     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
298     QCOMPARE(ec.totalCost(), 25.0);
299 
300     ec = project->accounts().actualCost(*a, QDate(), QDate());
301     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
302     QCOMPARE(ec.totalCost(), 25.0);
303 
304     // add actual effort, but no running cost
305     t->completion().setEntrymode(Completion::EnterEffortPerTask);
306     t->completion().setActualEffort(tomorrow, Duration(0, 4, 0));
307     ec = project->accounts().actualCost(*a, t->startTime().date(), tomorrow);
308     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
309     QCOMPARE(ec.totalCost(), 25.0);
310 
311     ec = project->accounts().actualCost(*a, QDate(), QDate());
312     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
313     QCOMPARE(ec.totalCost(), 25.0);
314 
315     // add running account
316     a->addRunning(*t);
317     // planned wo startup cost
318     t->completion().setStarted(false);
319     t->setStartupCost(0.0);
320 
321     ec = project->accounts().plannedCost(*a, t->startTime().date(), t->endTime().date());
322     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
323     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
324     QCOMPARE(ec.totalCost(), 800.0);
325 
326     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
327     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
328     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
329     QCOMPARE(ec.totalCost(), 0.0);
330 
331     // planned with startup cost
332     t->setStartupCost(25.0);
333     ec = project->accounts().plannedCost(*a, t->startTime().date(), t->endTime().date());
334     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
335     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
336     QCOMPARE(ec.totalCost(), 825.0);
337 
338     // actual, task not started
339     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
340     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
341     QVERIFY(! t->completion().isStarted());
342     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
343     QCOMPARE(ec.totalCost(), 0.0);
344 
345     // start task (tomorrow), 4h actual effort from before
346     t->completion().setEntrymode(Completion::EnterCompleted);
347     t->completion().setStarted(true);
348     t->completion().setStartTime(DateTime(tomorrow, QTime()));
349     QVERIFY(t->completion().isStarted());
350 
351     Debug::print(t, "Started tomorrow, 4h actual effort");
352     Debug::print(t->completion(), t->name());
353 
354     ec = project->accounts().actualCost(*a, tomorrow, tomorrow);
355     Debug::print(ec);
356     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
357     QCOMPARE(ec.totalCost(), 425.0);
358 
359     ec = project->accounts().actualCost(*a, QDate(), QDate());
360     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
361     QCOMPARE(ec.totalCost(), 425.0);
362 }
363 
364 
shutdownAccount()365 void AccountsTester::shutdownAccount() {
366     Account *a = new Account("Account");
367     project->accounts().insert(a);
368     a->addShutdown(*t);
369     t->completion().setStarted(true);
370     t->completion().setStartTime(t->startTime());
371 
372     // planned wo shutdown cost
373     EffortCostMap ec = project->accounts().plannedCost(*a, t->startTime().date(), t->endTime().date());
374     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
375     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
376     QCOMPARE(ec.totalCost(), 0.0);
377 
378     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
379     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
380     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
381     QCOMPARE(ec.totalCost(), 0.0);
382 
383     // planned with shutdown cost, no running account
384     t->setShutdownCost(25.0);
385     ec = project->accounts().plannedCost(*a, t->startTime().date(), t->endTime().date());
386     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
387     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
388     QCOMPARE(ec.totalCost(), 25.0);
389 
390     // actual, task not finished
391     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
392     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
393     QVERIFY(! t->completion().isFinished());
394     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
395     QCOMPARE(ec.totalCost(), 0.0);
396 
397     // finish task (tomorrow), no actual effort
398     t->completion().setEntrymode(Completion::EnterCompleted);
399     t->completion().setFinished(true);
400     t->completion().setFinishTime(DateTime(tomorrow, QTime()));
401     QVERIFY(t->completion().isFinished());
402 
403     ec = project->accounts().actualCost(*a, tomorrow, tomorrow);
404     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
405     QCOMPARE(ec.totalCost(), 25.0);
406 
407     ec = project->accounts().actualCost(*a, QDate(), QDate());
408     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
409     QCOMPARE(ec.totalCost(), 25.0);
410 
411     // add actual effort, no running account
412     t->completion().setEntrymode(Completion::EnterEffortPerTask);
413     t->completion().setActualEffort(tomorrow, Duration(0, 4, 0));
414     ec = project->accounts().actualCost(*a, t->startTime().date(), tomorrow);
415     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
416     QCOMPARE(ec.totalCost(), 25.0);
417 
418     ec = project->accounts().actualCost(*a, QDate(), QDate());
419     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
420     QCOMPARE(ec.totalCost(), 25.0);
421 
422     // add running account
423     a->addRunning(*t);
424     t->completion().setFinished(false);
425     t->setShutdownCost(0.0);
426     // planned wo finish cost
427     ec = project->accounts().plannedCost(*a, t->startTime().date(), t->endTime().date());
428     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
429     QCOMPARE(ec.totalCost(), 800.0);
430 
431     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
432     Debug::print(t, "planned wo finish cost, with running", true);
433     Debug::print(t->completion(), t->name());
434     Debug::print(ec);
435     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
436     QCOMPARE(ec.totalCost(), 0.0);
437 
438     // planned with startup cost
439     t->setShutdownCost(25.0);
440     ec = project->accounts().plannedCost(*a, t->startTime().date(), t->endTime().date());
441     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
442     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
443     QCOMPARE(ec.totalCost(), 825.0);
444 
445     // actual, task not finished
446     ec = project->accounts().actualCost(*a, t->startTime().date(), t->endTime().date());
447     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
448     QVERIFY(! t->completion().isFinished());
449     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
450     QCOMPARE(ec.totalCost(), 0.0);
451 
452     // finish task (tomorrow), 4h actual effort from before
453     t->completion().setEntrymode(Completion::EnterCompleted);
454     t->completion().setFinished(true);
455     t->completion().setFinishTime(DateTime(tomorrow, QTime()));
456     QVERIFY(t->completion().isFinished());
457 
458     ec = project->accounts().actualCost(*a, tomorrow, tomorrow);
459     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
460     QCOMPARE(ec.totalCost(), 425.0);
461 
462     ec = project->accounts().actualCost(*a, QDate(), QDate());
463     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
464     QCOMPARE(ec.totalCost(), 425.0);
465 }
466 
subaccounts()467 void AccountsTester::subaccounts()
468 {
469     Account *a1 = new Account("Account");
470     project->accounts().insert(a1);
471 
472     Account *a2 = new Account("Sub-Account");
473     project->accounts().insert(a2, a1);
474 
475     project->accounts().setDefaultAccount(a2);
476 
477     EffortCostMap ec = project->accounts().plannedCost(*a2);
478     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
479     QCOMPARE(ec.totalCost(), 800.0);
480 
481     ec = project->accounts().plannedCost(*a1);
482     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
483     QCOMPARE(ec.totalCost(), 800.0);
484 
485     ec = project->accounts().actualCost(*a2);
486     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
487     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
488     QCOMPARE(ec.totalCost(), 0.0);
489 
490     ec = project->accounts().actualCost(*a1);
491     qDebug()<<t->startTime()<<t->endTime()<<ec.totalEffort().toDouble(Duration::Unit_h);
492     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
493     QCOMPARE(ec.totalCost(), 0.0);
494 
495     t->completion().setEntrymode(Completion::FollowPlan);
496     ec = project->accounts().actualCost(*a2);
497     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
498     QCOMPARE(ec.totalCost(), 800.0);
499 
500     ec = project->accounts().actualCost(*a1);
501     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
502     QCOMPARE(ec.totalCost(), 800.0);
503 
504     t->completion().setEntrymode(Completion::EnterCompleted);
505     ec = project->accounts().actualCost(*a2);
506     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
507     QCOMPARE(ec.totalCost(), 0.0);
508 
509     ec = project->accounts().actualCost(*a1);
510     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
511     QCOMPARE(ec.totalCost(), 0.0);
512 
513     t->completion().setEntrymode(Completion::EnterEffortPerTask);
514     t->completion().setStarted(true);
515     t->completion().setStartTime(DateTime(tomorrow, QTime()));
516     t->completion().setPercentFinished(tomorrow, 50);
517     t->completion().setActualEffort(tomorrow, Duration(0, 4, 0));
518     ec = project->accounts().actualCost(*a2);
519     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
520     QCOMPARE(ec.totalCost(), 400.0);
521 
522     ec = project->accounts().actualCost(*a1);
523     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
524     QCOMPARE(ec.totalCost(), 400.0);
525 
526     t->setStartupCost(25.0);
527     a1->addStartup(*t);
528 
529     ec = project->accounts().actualCost(*a2);
530     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
531     QCOMPARE(ec.totalCost(), 400.0);
532 
533     ec = project->accounts().actualCost(*a1);
534     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
535     QCOMPARE(ec.totalCost(), 425.0);
536 
537     project->accounts().setDefaultAccount(a1);
538 
539     ec = project->accounts().plannedCost(*a2);
540     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
541     QCOMPARE(ec.totalCost(), 0.0);
542 
543     ec = project->accounts().plannedCost(*a1);
544     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
545     QCOMPARE(ec.totalCost(), 825.0);
546 
547     ec = project->accounts().actualCost(*a2);
548     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
549     QCOMPARE(ec.totalCost(), 0.0);
550 
551     ec = project->accounts().actualCost(*a1);
552     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
553     QCOMPARE(ec.totalCost(), 425.0);
554 
555     t->setShutdownCost(1.0);
556     a2->addShutdown(*t);
557 
558     ec = project->accounts().plannedCost(*a2);
559     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
560     QCOMPARE(ec.totalCost(), 1.0);
561 
562     ec = project->accounts().plannedCost(*a1);
563     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 8.0);
564     QCOMPARE(ec.totalCost(), 826.0);
565 
566     t->completion().setFinished(true);
567     t->completion().setFinishTime(DateTime(tomorrow, QTime()));
568 
569     ec = project->accounts().actualCost(*a2);
570     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 0.0);
571     QCOMPARE(ec.totalCost(), 1.0);
572 
573     ec = project->accounts().actualCost(*a1);
574     QCOMPARE(ec.totalEffort().toDouble(Duration::Unit_h), 4.0);
575     QCOMPARE(ec.totalCost(), 426.0);
576 }
577 
deleteAccount()578 void AccountsTester::deleteAccount()
579 {
580     QVERIFY(project->accounts().allAccounts().isEmpty());
581 
582     qInfo()<<"Add/delete one account";
583     Account *a1 = new Account("Account");
584     project->accounts().insert(a1);
585 
586     QCOMPARE(project->accounts().allAccounts().count(), 1);
587     QCOMPARE(project->accounts().allAccounts().first(), a1);
588 
589     delete a1;
590     QVERIFY(project->accounts().allAccounts().isEmpty());
591 
592     qInfo()<<"Add/delete one account with one sub-account";
593     a1 = new Account("Account 1");
594     project->accounts().insert(a1);
595     Account *a2 = new Account("Account 1.1");
596     project->accounts().insert(a2, a1);
597     QCOMPARE(project->accounts().allAccounts().count(), 2);
598 
599     qInfo()<<"Delete top account";
600     delete a1;
601     QVERIFY(project->accounts().allAccounts().isEmpty());
602 
603     qInfo()<<"Add/delete one account with one sub-account";
604     a1 = new Account("Account 1");
605     project->accounts().insert(a1);
606     a2 = new Account("Account 1.1");
607     project->accounts().insert(a2, a1);
608     project->accounts().setDefaultAccount(a2);
609     QCOMPARE(project->accounts().allAccounts().count(), 2);
610 
611     qInfo()<<"Delete sub account";
612     delete a2;
613     QVERIFY(project->accounts().defaultAccount() == 0);
614     QCOMPARE(project->accounts().allAccounts().count(), 1);
615 
616     qInfo()<<"Delete top account";
617     delete a1;
618     QVERIFY(project->accounts().allAccounts().isEmpty());
619 }
620 
621 } //namespace KPlato
622 
623 QTEST_GUILESS_MAIN(KPlato::AccountsTester)
624