kplato

kptschedule.cpp
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#include "kptschedule.h"
21
22#include "kptappointment.h"
23#include "kptdatetime.h"
24#include "kptduration.h"
25#include "kptnode.h"
26
27#include <tqdom.h>
28#include <tqstring.h>
29#include <tqstringlist.h>
30
31#include <tdelocale.h>
32#include <kdebug.h>
33
34namespace KPlato
35{
36
37Schedule::Schedule()
38 : m_type(Expected),
39 m_id(0),
40 m_deleted(false),
41 m_parent(0) {
42}
43
44Schedule::Schedule(Schedule *parent)
45 : m_type(Expected),
46 m_id(0),
47 m_deleted(false),
48 m_appointments(),
49 m_parent(parent) {
50
51 if (parent) {
52 m_name = parent->name();
53 m_type = parent->type();
54 m_id = parent->id();
55 }
56 m_appointments.setAutoDelete(true);
57 //kdDebug()<<k_funcinfo<<"("<<this<<") Name: '"<<name<<"' Type="<<type<<" id="<<id<<endl;
58}
59
60Schedule::Schedule(TQString name, Type type, long id)
61 : m_name(name),
62 m_type(type),
63 m_id(id),
64 m_deleted(false),
65 m_appointments(),
66 m_parent(0) {
67
68 //kdDebug()<<k_funcinfo<<"("<<this<<") Name: '"<<name<<"' Type="<<type<<" id="<<id<<endl;
69 m_appointments.setAutoDelete(true);
70}
71
72Schedule::~Schedule() {
73}
74
75void Schedule::setParent(Schedule *parent) {
76 m_parent = parent;
77}
78
79void Schedule::setDeleted(bool on) {
80 //kdDebug()<<k_funcinfo<<"deleted="<<on<<endl;
81 m_deleted = on;
82}
83
84bool Schedule::isDeleted() const {
85 return m_parent == 0 ? m_deleted : m_parent->isDeleted();
86}
87
88void Schedule::setType(const TQString type) {
89 m_type = Expected;
90 if (type == "Expected")
91 m_type = Expected;
92 else if (type == "Optimistic")
93 m_type = Optimistic;
94 else if (type == "Pessimistic")
95 m_type = Pessimistic;
96}
97
98TQString Schedule::typeToString(bool translate) const {
99 if (translate) {
100 if (m_type == Expected)
101 return i18n("Expected");
102 if (m_type == Optimistic)
103 return i18n("Optimistic");
104 if (m_type == Pessimistic)
105 return i18n("Pessimistic");
106 return i18n("Expected");
107 } else {
108 if (m_type == Expected)
109 return "Expected";
110 if (m_type == Optimistic)
111 return "Optimistic";
112 if (m_type == Pessimistic)
113 return "Pessimistic";
114 return "Expected";
115 }
116}
117
118void Schedule::initiateCalculation() {
119 resourceError = false;
120 resourceOverbooked = false;
121 schedulingError = false;
122 inCriticalPath = false;
123 workStartTime = DateTime();
124 workEndTime = DateTime();
125}
126
127void Schedule::calcResourceOverbooked() {
128 resourceOverbooked = false;
129 TQPtrListIterator<Appointment> it = m_appointments;
130 for (; it.current(); ++it) {
131 if (it.current()->resource()->isOverbooked(startTime, endTime)) {
132 resourceOverbooked = true;
133 break;
134 }
135 }
136}
137
138TQStringList Schedule::overbookedResources() const {
139 TQStringList rl;
140 TQPtrListIterator<Appointment> it = m_appointments;
141 for (; it.current(); ++it) {
142 if (it.current()->resource()->isOverbooked(it.current()->startTime(), it.current()->endTime())) {
143 rl += it.current()->resource()->resource()->name();
144 }
145 }
146 return rl;
147}
148
149bool Schedule::loadXML(const TQDomElement &sch) {
150 m_name = sch.attribute("name");
151 setType(sch.attribute("type"));
152 m_id = sch.attribute("id").toLong();
153 return true;
154}
155
156void Schedule::saveXML(TQDomElement &element) const {
157 TQDomElement sch = element.ownerDocument().createElement("schedule");
158 element.appendChild(sch);
159 saveCommonXML(sch);
160}
161
162void Schedule::saveCommonXML(TQDomElement &element) const {
163 //kdDebug()<<k_funcinfo<<m_name<<" save schedule"<<endl;
164 element.setAttribute("name", m_name);
165 element.setAttribute("type", typeToString());
166 element.setAttribute("id", m_id);
167}
168
169void Schedule::saveAppointments(TQDomElement &element) const {
170 //kdDebug()<<k_funcinfo<<endl;
171 TQPtrListIterator<Appointment> it = m_appointments;
172 for (; it.current(); ++it) {
173 it.current()->saveXML(element);
174 }
175}
176
177bool Schedule::add(Appointment *appointment) {
178 if (m_appointments.findRef(appointment) != -1) {
179 kdError()<<k_funcinfo<<"Appointment allready exists"<<endl;
180 return false;
181 }
182 m_appointments.append(appointment);
183 //if (resource()) kdDebug()<<k_funcinfo<<"For resource '"<<resource()->name()<<"'"<<endl;
184 //if (node()) kdDebug()<<k_funcinfo<<"For node '"<<node()->name()<<"'"<<endl;
185 return true;
186}
187
189 takeAppointment(appointment);
190 delete appointment;
191}
192
194 int i = m_appointments.findRef(appointment);
195 if (i != -1) {
196 m_appointments.take(i);
197 //kdDebug()<<k_funcinfo<<"Taken: "<<appointment<<endl;
198 if (appointment->node())
199 appointment->node()->takeAppointment(appointment);
200 } else {
201 //kdDebug()<<k_funcinfo<<"Couldn't find appointment: "<<appointment<<endl;
202 }
203}
204
205Appointment *Schedule::findAppointment(Schedule *resource, Schedule *node) {
206 TQPtrListIterator<Appointment> it = m_appointments;
207 for (; it.current(); ++it) {
208 if (it.current()->node() == node && it.current()->resource() == resource)
209 return it.current();
210 }
211 return 0;
212}
213
214EffortCostMap Schedule::plannedEffortCostPrDay(const TQDate &start, const TQDate &end) const {
215 //kdDebug()<<k_funcinfo<<m_name<<endl;
216 EffortCostMap ec;
217 TQPtrListIterator<Appointment> it(m_appointments);
218 for (; it.current(); ++it) {
219 //kdDebug()<<k_funcinfo<<m_name<<endl;
220 ec += it.current()->plannedPrDay(start, end);
221 }
222 return ec;
223}
224
226 //kdDebug()<<k_funcinfo<<endl;
227 Duration eff;
228 TQPtrListIterator<Appointment> it(m_appointments);
229 for (; it.current(); ++it) {
230 eff += it.current()->plannedEffort();
231 }
232 return eff;
233}
234
235Duration Schedule::plannedEffort(const TQDate &date) const {
236 //kdDebug()<<k_funcinfo<<endl;
237 Duration eff;
238 TQPtrListIterator<Appointment> it(m_appointments);
239 for (; it.current(); ++it) {
240 eff += it.current()->plannedEffort(date);
241 }
242 return eff;
243}
244
245Duration Schedule::plannedEffortTo(const TQDate &date) const {
246 //kdDebug()<<k_funcinfo<<endl;
247 Duration eff;
248 TQPtrListIterator<Appointment> it(m_appointments);
249 for (; it.current(); ++it) {
250 eff += it.current()->plannedEffortTo(date);
251 }
252 return eff;
253}
254
256 //kdDebug()<<k_funcinfo<<endl;
257 Duration eff;
258 TQPtrListIterator<Appointment> it(m_appointments);
259 for (; it.current(); ++it) {
260 eff += it.current()->actualEffort();
261 }
262 return eff;
263}
264
265Duration Schedule::actualEffort(const TQDate &date) const {
266 //kdDebug()<<k_funcinfo<<endl;
267 Duration eff;
268 TQPtrListIterator<Appointment> it(m_appointments);
269 for (; it.current(); ++it) {
270 eff += it.current()->actualEffort(date);
271 }
272 return eff;
273}
274
275Duration Schedule::actualEffortTo(const TQDate &date) const {
276 //kdDebug()<<k_funcinfo<<endl;
277 Duration eff;
278 TQPtrListIterator<Appointment> it(m_appointments);
279 for (; it.current(); ++it) {
280 eff += it.current()->actualEffortTo(date);
281 }
282 return eff;
283}
284
285double Schedule::plannedCost() const {
286 //kdDebug()<<k_funcinfo<<endl;
287 double c = 0;
288 TQPtrListIterator<Appointment> it(m_appointments);
289 for (; it.current(); ++it) {
290 c += it.current()->plannedCost();
291 }
292 return c;
293}
294
295double Schedule::plannedCost(const TQDate &date) const {
296 //kdDebug()<<k_funcinfo<<endl;
297 double c = 0;
298 TQPtrListIterator<Appointment> it(m_appointments);
299 for (; it.current(); ++it) {
300 c += it.current()->plannedCost(date);
301 }
302 return c;
303}
304
305double Schedule::plannedCostTo(const TQDate &date) const {
306 //kdDebug()<<k_funcinfo<<endl;
307 double c = 0;
308 TQPtrListIterator<Appointment> it(m_appointments);
309 for (; it.current(); ++it) {
310 c += it.current()->plannedCostTo(date);
311 }
312 return c;
313}
314
315double Schedule::actualCost() const {
316 //kdDebug()<<k_funcinfo<<endl;
317 double c = 0;
318 TQPtrListIterator<Appointment> it(m_appointments);
319 for (; it.current(); ++it) {
320 c += it.current()->actualCost();
321 }
322 return c;
323}
324
325double Schedule::actualCost(const TQDate &date) const {
326 //kdDebug()<<k_funcinfo<<endl;
327 double c = 0;
328 TQPtrListIterator<Appointment> it(m_appointments);
329 for (; it.current(); ++it) {
330 c += it.current()->actualCost(date);
331 }
332 return c;
333}
334
335double Schedule::actualCostTo(const TQDate &date) const {
336 //kdDebug()<<k_funcinfo<<endl;
337 double c = 0;
338 TQPtrListIterator<Appointment> it(m_appointments);
339 for (; it.current(); ++it) {
340 c += it.current()->actualCostTo(date);
341 }
342 return c;
343}
344
345//-------------------------------------------------
346NodeSchedule::NodeSchedule()
347 : Schedule(),
348 m_node(0) {
349 //kdDebug()<<k_funcinfo<<"("<<this<<")"<<endl;
350 init();
351}
352
353NodeSchedule::NodeSchedule(Node *node, TQString name, Schedule::Type type, long id)
354 : Schedule(name, type, id),
355 m_node(node) {
356 //kdDebug()<<k_funcinfo<<"node name: "<<node->name()<<endl;
357 init();
358}
359
360NodeSchedule::NodeSchedule(Schedule *parent, Node *node)
361 : Schedule(parent),
362 m_node(node) {
363
364 //kdDebug()<<k_funcinfo<<"node name: "<<node->name()<<endl;
365 init();
366}
367
368NodeSchedule::~NodeSchedule() {
369 //kdDebug()<<k_funcinfo<<"("<<this<<")"<<endl;
370}
371
372void NodeSchedule::init() {
373 resourceError = false;
374 resourceOverbooked = false;
375 resourceNotAvailable = false;
376 schedulingError = false;
377 notScheduled = true;
378 inCriticalPath = false;
379}
380
381void NodeSchedule::setDeleted(bool on) {
382 //kdDebug()<<k_funcinfo<<"deleted="<<on<<endl;
383 m_deleted = on;
384 // set deleted also for possible resource schedules
385 TQPtrListIterator<Appointment> it = m_appointments;
386 for (; it.current(); ++it) {
387 if (it.current()->resource()) {
388 it.current()->resource()->setDeleted(on);
389 }
390 }
391}
392
393bool NodeSchedule::loadXML(const TQDomElement &sch) {
394 //kdDebug()<<k_funcinfo<<endl;
395 TQString s;
396 Schedule::loadXML(sch);
397 s = sch.attribute("earlieststart");
398 if (s != "")
399 earliestStart = DateTime::fromString(s);
400 s = sch.attribute("latestfinish");
401 if (s != "")
402 latestFinish = DateTime::fromString(s);
403 s = sch.attribute("start");
404 if (s != "")
405 startTime = DateTime::fromString(s);
406 s = sch.attribute("end");
407 if (s != "")
408 endTime = DateTime::fromString(s);
409 s = sch.attribute("start-work");
410 if (s != "")
411 workStartTime = DateTime::fromString(s);
412 s = sch.attribute("end-work");
413 if (s != "")
414 workEndTime = DateTime::fromString(s);
415 duration = Duration::fromString(sch.attribute("duration"));
416
417 inCriticalPath = sch.attribute("in-critical-path", "0").toInt();
418 resourceError = sch.attribute("resource-error", "0").toInt();
419 resourceOverbooked = sch.attribute("resource-overbooked", "0").toInt();
420 resourceNotAvailable = sch.attribute("resource-not-available", "0").toInt();
421 schedulingError = sch.attribute("scheduling-conflict", "0").toInt();
422 notScheduled = sch.attribute("not-scheduled", "1").toInt();
423
424 return true;
425}
426
427void NodeSchedule::saveXML(TQDomElement &element) const {
428 //kdDebug()<<k_funcinfo<<endl;
429 TQDomElement sch = element.ownerDocument().createElement("schedule");
430 element.appendChild(sch);
431 saveCommonXML(sch);
432
433 if (earliestStart.isValid())
434 sch.setAttribute("earlieststart",earliestStart.toString(TQt::ISODate));
435 if (latestFinish.isValid())
436 sch.setAttribute("latestfinish",latestFinish.toString(TQt::ISODate));
437 if (startTime.isValid())
438 sch.setAttribute("start",startTime.toString(TQt::ISODate));
439 if (endTime.isValid())
440 sch.setAttribute("end",endTime.toString(TQt::ISODate));
441 if (workStartTime.isValid())
442 sch.setAttribute("start-work", workStartTime.toString(TQt::ISODate));
443 if (workEndTime.isValid())
444 sch.setAttribute("end-work", workEndTime.toString(TQt::ISODate));
445
446 sch.setAttribute("duration",duration.toString());
447
448 sch.setAttribute("in-critical-path",inCriticalPath);
449 sch.setAttribute("resource-error",resourceError);
450 sch.setAttribute("resource-overbooked",resourceOverbooked);
451 sch.setAttribute("resource-not-available",resourceNotAvailable);
452 sch.setAttribute("scheduling-conflict",schedulingError);
453 sch.setAttribute("not-scheduled",notScheduled);
454}
455
456void NodeSchedule::addAppointment(Schedule *resource, DateTime &start, DateTime &end, double load) {
457 //kdDebug()<<k_funcinfo<<endl;
458 Appointment *a = findAppointment(resource, this);
459 if (a != 0) {
460 //kdDebug()<<k_funcinfo<<"Add interval"<<endl;
461 a->addInterval(start, end, load);
462 return;
463 }
464 a = new Appointment(resource, this, start, end, load);
465 if (!add(a)) {
466 delete a;
467 }
468 if (!resource->add(a)) {
469 delete a;
470 }
471}
472
473//-----------------------------------------------
474ResourceSchedule::ResourceSchedule()
475 : Schedule(),
476 m_resource(0) {
477 //kdDebug()<<k_funcinfo<<"("<<this<<")"<<endl;
478}
479
480ResourceSchedule::ResourceSchedule(Resource *resource, TQString name, Schedule::Type type, long id)
481 : Schedule(name, type, id),
482 m_resource(resource),
483 m_parent(0) {
484 //kdDebug()<<k_funcinfo<<"resource: "<<resource->name()<<endl;
485}
486
487ResourceSchedule::ResourceSchedule(Schedule *parent, Resource *resource)
488 : Schedule(parent),
489 m_resource(resource),
490 m_parent(parent) {
491 //kdDebug()<<k_funcinfo<<"resource: "<<resource->name()<<endl;
492}
493
494ResourceSchedule::~ResourceSchedule() {
495 //kdDebug()<<k_funcinfo<<"("<<this<<")"<<endl;
496}
497
498void ResourceSchedule::addAppointment(Schedule *node, DateTime &start, DateTime &end, double load) {
499 //kdDebug()<<k_funcinfo<<endl;
500 Appointment *a = findAppointment(this, node);
501 if (a != 0) {
502 //kdDebug()<<k_funcinfo<<"Add interval"<<endl;
503 a->addInterval(start, end, load);
504 return;
505 }
506 a = new Appointment(this, node, start, end, load);
507 if (!add(a)) {
508 delete a;
509 }
510 if (!node->add(a)) {
511 delete a;
512 }
513}
514
515bool ResourceSchedule::isOverbooked() const {
516 return false;
517}
518
519bool ResourceSchedule::isOverbooked(const DateTime &start, const DateTime &end) const {
520 if (m_resource == 0)
521 return false;
522 //kdDebug()<<k_funcinfo<<start.toString()<<" - "<<end.toString()<<endl;
523 Appointment a = appointmentIntervals();
524 TQPtrListIterator<AppointmentInterval> it = a.intervals();
525 for (; it.current(); ++it) {
526 if ((!end.isValid() || it.current()->startTime() < end) &&
527 (!start.isValid() || it.current()->endTime() > start))
528 {
529 if (it.current()->load() > m_resource->units()) {
530 //kdDebug()<<k_funcinfo<<m_name<<" overbooked"<<endl;
531 return true;
532 }
533 }
534 if (it.current()->startTime() >= end)
535 break;
536 }
537 //kdDebug()<<k_funcinfo<<m_name<<" not overbooked"<<endl;
538 return false;
539}
540
541Appointment ResourceSchedule::appointmentIntervals() const {
542 Appointment a;
543 TQPtrListIterator<Appointment> it = m_appointments;
544 for (; it.current(); ++it) {
545 a += *(it.current());
546 }
547 return a;
548}
549
550double ResourceSchedule::normalRatePrHour() const {
551 return m_resource ? m_resource->normalRate() : 0.0;
552}
553
554//--------------------------------------
555MainSchedule::MainSchedule()
556 : NodeSchedule() {
557 //kdDebug()<<k_funcinfo<<"("<<this<<")"<<endl;
558 init();
559}
560
561MainSchedule::MainSchedule(Node *node, TQString name, Schedule::Type type, long id)
562 : NodeSchedule(node, name, type, id) {
563 //kdDebug()<<k_funcinfo<<"node name: "<<node->name()<<endl;
564 init();
565}
566
567MainSchedule::~MainSchedule() {
568 //kdDebug()<<k_funcinfo<<"("<<this<<")"<<endl;
569}
570
571bool MainSchedule::loadXML(const TQDomElement &sch, Project &project) {
572 kdDebug()<<k_funcinfo<<endl;
573 TQString s;
574 Schedule::loadXML(sch);
575
576 s = sch.attribute("start");
577 if (s != "")
578 startTime = DateTime::fromString(s);
579 s = sch.attribute("end");
580 if (s != "")
581 endTime = DateTime::fromString(s);
582
583 TQDomNodeList al = sch.childNodes();
584 kdDebug()<<k_funcinfo<<"No of appointments: "<<al.count()<<endl;
585 for (unsigned int i=0; i<al.count(); ++i) {
586 if (al.item(i).isElement()) {
587 TQDomElement app = al.item(i).toElement();
588 if (app.tagName() == "appointment") {
589 // Load the appointments.
590 // Resources and tasks must allready loaded
591 Appointment *child = new Appointment();
592 if (!child->loadXML(app, project, *this)) {
593 // TODO: Complain about this
594 kdError()<<k_funcinfo<<"Failed to load appointment"<<endl;
595 delete child;
596 }
597 }
598 }
599 }
600 return true;
601}
602
603void MainSchedule::saveXML(TQDomElement &element) const {
604 saveCommonXML(element);
605
606 element.setAttribute("start",startTime.toString(TQt::ISODate));
607 element.setAttribute("end",endTime.toString(TQt::ISODate));
608}
609
610#ifndef NDEBUG
611void Schedule::printDebug(TQString indent) {
612 kdDebug()<<indent<<"Schedule["<<m_id<<"] '"<<m_name<<"' type: "<<typeToString()<<" ("<<m_type<<")"<<(isDeleted()?" Deleted":"")<<endl;
613}
614void NodeSchedule::printDebug(TQString indent) {
615 Schedule::printDebug(indent);
616 indent += "! ";
617 if (m_parent == 0)
618 kdDebug()<<indent<<"No parent schedule!"<<endl;
619 if (!notScheduled) {
620 if (node()) kdDebug()<<indent<<"Node: "<<node()->name()<<endl;
621 else kdDebug()<<indent<<"No parent node!"<<endl;
622 }
623 kdDebug()<<indent<<"Not scheduled="<<notScheduled<<endl;
624 kdDebug()<<indent<<"Start time: "<<startTime.toString()<<endl;
625 kdDebug()<<indent<<"End time: " <<endTime.toString()<<endl;
626 kdDebug()<<indent<<"Duration: "<<duration.seconds()<<TQCString(" secs")<<" ("<<duration.toString()<<")"<<endl;
627 kdDebug()<<indent<<"Earliest start: "<<earliestStart.toString()<<endl;
628 kdDebug()<<indent<<"Latest finish: " <<latestFinish.toString()<<endl;
629
630 kdDebug()<<indent<<"resourceError="<<resourceError<<endl;
631 kdDebug()<<indent<<"schedulingError="<<schedulingError<<endl;
632 kdDebug()<<indent<<"resourceNotAvailable="<<resourceNotAvailable<<endl;
633 kdDebug()<<indent<<"Resource overbooked="<<resourceOverbooked<<endl;
634 kdDebug()<<indent<<" "<<overbookedResources()<<endl;
635
636 kdDebug()<<indent<<"inCriticalPath="<<inCriticalPath<<endl;
637 kdDebug()<<indent<<endl;
638 kdDebug()<<indent<<"workStartTime="<<workStartTime.toString()<<endl;
639 kdDebug()<<indent<<"workEndTime="<<workEndTime.toString()<<endl;
640 kdDebug()<<indent<<endl;
641 kdDebug()<<indent<<"Appointments: "<<m_appointments.count()<<endl;
642 TQPtrListIterator<Appointment> it = m_appointments;
643 for (; it.current(); ++it) {
644 it.current()->printDebug(indent + " ");
645 }
646}
647void ResourceSchedule::printDebug(TQString indent) {
648 Schedule::printDebug(indent);
649 indent += "! ";
650 if (m_parent == 0)
651 kdDebug()<<indent<<"No parent schedule!"<<endl;
652 if (resource()) kdDebug()<<indent<<"Resource: "<<resource()->name()<<endl;
653 else kdDebug()<<indent<<"No parent resource!"<<endl;
654 kdDebug()<<indent<<endl;
655 kdDebug()<<indent<<"Appointments: "<<m_appointments.count()<<endl;
656}
657
658void MainSchedule::printDebug(TQString indent) {
659 Schedule::printDebug(indent);
660 indent += "! ";
661 if (node()) kdDebug()<<indent<<"Node: "<<node()->name()<<endl;
662 else kdDebug()<<indent<<"No parent node!"<<endl;
663
664 kdDebug()<<indent<<"Not scheduled="<<notScheduled<<endl;
665 kdDebug()<<indent<<"Start time: "<<startTime.toString()<<endl;
666 kdDebug()<<indent<<"End time: " <<endTime.toString()<<endl;
667 kdDebug()<<indent<<"Duration: "<<duration.seconds()<<TQCString(" secs")<<" ("<<duration.toString()<<")"<<endl;
668 kdDebug()<<indent<<"Earliest start: "<<earliestStart.toString()<<endl;
669 kdDebug()<<indent<<"Latest finish: " <<latestFinish.toString()<<endl;
670
671 kdDebug()<<indent<<endl;
672 kdDebug()<<indent<<"Appointments: "<<m_appointments.count()<<endl;
673 TQPtrListIterator<Appointment> it = m_appointments;
674 for (; it.current(); ++it) {
675 it.current()->printDebug(indent + " ");
676 }
677}
678#endif
679
680} //namespace KPlato
681
A resource (Resource) can be scheduled to be used at any time, this is represented internally with Ap...
DateTime is a TQDateTime which knows about Duration.
Definition kptdatetime.h:33
The duration class can be used to store a timespan in a convenient format.
Definition kptduration.h:34
NodeSchedule holds scheduling information for a node (task).
virtual void addAppointment(Schedule *resource, DateTime &start, DateTime &end, double load=100)
Adds appointment to both this resource schedule and node schedule.
This class represents any node in the project, a node can be a project or a subproject or any task.
Definition kptnode.h:57
Project is the main node in a project, it contains child nodes and possibly sub-projects.
Definition kptproject.h:52
virtual void addAppointment(Schedule *node, DateTime &start, DateTime &end, double load=100)
Adds appointment to both this resource schedule and node schedule.
Any resource that is used by a task.
int units() const
Return available units in percent.
The Schedule class holds data calculated during project calculation and scheduling,...
Definition kptschedule.h:55
virtual Duration plannedEffort() const
Returns the total planned effort for this task (or subtasks).
DateTime startTime
startTime is the scheduled start time.
virtual double plannedCostTo(const TQDate &date) const
Planned cost from start of activity up to and including date is the sum of all resource costs and oth...
bool resourceNotAvailable
Set if the requested resource is not available.
bool resourceOverbooked
Set if the assigned resource is overbooked.
void removeAppointment(Appointment *appointment)
removes appointment and deletes it (independent of setAutoDelete)
virtual double actualCostTo(const TQDate &date) const
Actual cost up to and including date.
virtual bool add(Appointment *appointment)
Adds appointment to this schedule only.
bool resourceError
Set if EffortType == Effort, but no resource is requested.
virtual Duration actualEffort() const
Returns the total actual effort for this task (or subtasks).
Duration duration
duration is the scheduled duration which depends on e.g.
DateTime latestFinish
latestFinish is calculated by PERT/CPM.
void takeAppointment(Appointment *appointment)
removes appointment without deleting it (independent of setAutoDelete)
virtual double actualCost() const
Actual cost is the sum total of the reported costs actually used for this node.
virtual double plannedCost() const
Planned cost is the sum total of all resources and other costs planned for this node.
bool notScheduled
Set if the node has not been scheduled.
DateTime endTime
m_endTime is the scheduled finish time.
virtual Duration actualEffortTo(const TQDate &date) const
Returns the total actual effort for this task (or subtasks) up to and including date.
DateTime earliestStart
earliestStart is calculated by PERT/CPM.
bool schedulingError
Set if the task cannot be scheduled to fullfill all the constraints.
virtual Duration plannedEffortTo(const TQDate &date) const
Returns the planned effort up to and including date.