00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef KPTNODE_H
00022 #define KPTNODE_H
00023
00024 #include "kptrelation.h"
00025 #include "kptduration.h"
00026 #include "kptdatetime.h"
00027 #include "kptschedule.h"
00028
00029 #include <qintdict.h>
00030 #include <qrect.h>
00031 #include <qptrlist.h>
00032 #include <qstring.h>
00033 #include <qcanvas.h>
00034
00035 #include <vector>
00036
00037 class QDomElement;
00038
00039 namespace KPlato
00040 {
00041
00042 class Account;
00043 class Project;
00044 class Appointment;
00045 class ResourceGroup;
00046 class Resource;
00047 class ResourceGroupRequest;
00048 class Effort;
00049 class WBSDefinition;
00050 class EffortCostMap;
00051
00057 class Node {
00058
00059 public:
00060 enum ConstraintType { ASAP, ALAP, MustStartOn, MustFinishOn, StartNotEarlier, FinishNotLater, FixedInterval };
00061
00062 Node(Node *parent = 0);
00063 Node(Node &node, Node *parent = 0);
00064
00065
00066
00067 virtual ~Node() = 0;
00068
00069 bool setId(QString id);
00070 QString id() const { return m_id; }
00071
00072 enum NodeTypes {
00073 Type_Node = 0,
00074 Type_Project = 1,
00075 Type_Subproject = 2,
00076 Type_Task = 3,
00077 Type_Milestone = 4,
00078 Type_Periodic = 5,
00079 Type_Summarytask = 6
00080 };
00081
00082 virtual int type() const = 0;
00083
00088 virtual Node *projectNode();
00089
00090
00091 virtual bool load(QDomElement &) { return true; }
00092 virtual bool load(QDomElement &, Project &) { return true; }
00093 virtual void save(QDomElement &element) const = 0;
00095 virtual void saveRelations(QDomElement &element) const;
00096
00097
00098
00099
00100
00101 Node *getParent() const { return m_parent; }
00102 void setParent( Node* newParent ) { m_parent = newParent;}
00103 const QPtrList<Node> &childNodeIterator() const { return m_nodes; }
00104 int numChildren() const { return m_nodes.count(); }
00105 virtual void addChildNode(Node *node, Node *after=0);
00106 virtual void addChildNode_NoId(Node *node, Node *after=0);
00107 virtual void insertChildNode(unsigned int index, Node *node);
00108 virtual void insertChildNode_NoId(unsigned int index, Node *node);
00109 void delChildNode(Node *node, bool remove=true);
00110 void delChildNode_NoId(Node *node, bool remove=true);
00111 void delChildNode(int number, bool remove=true);
00112 void delChildNode_NoId(int number, bool remove=true);
00113 Node* getChildNode(int number) { return m_nodes.at(number); }
00114 const Node* getChildNode(int number) const;
00115 int findChildNode( Node* node );
00116
00117
00118
00119
00120
00121
00122
00123 int numDependChildNodes() const { return m_dependChildNodes.count(); }
00125 virtual void addDependChildNode( Node *node, Relation::Type p=Relation::FinishStart);
00127 virtual void addDependChildNode( Node *node, Relation::Type p, Duration lag);
00129 virtual bool addDependChildNode( Relation *relation);
00131 virtual void insertDependChildNode( unsigned int index, Node *node, Relation::Type p=Relation::FinishStart);
00132 void delDependChildNode( Node *node, bool remove=false);
00133 void delDependChildNode( Relation *rel, bool remove=false);
00134 void delDependChildNode( int number, bool remove=false);
00135 Relation *getDependChildNode( int number) {
00136 return m_dependChildNodes.at(number);
00137 }
00138 QPtrList<Relation> &dependChildNodes() { return m_dependChildNodes; }
00139
00144 void takeDependChildNode(Relation *rel);
00145
00146 int numDependParentNodes() const { return m_dependParentNodes.count(); }
00148 virtual void addDependParentNode(Node *node, Relation::Type p=Relation::FinishStart);
00150 virtual void addDependParentNode( Node *node, Relation::Type p, Duration lag);
00152 virtual bool addDependParentNode( Relation *relation);
00154 virtual void insertDependParentNode( unsigned int index, Node *node, Relation::Type p=Relation::FinishStart);
00155 void delDependParentNode( Node *node, bool remove=false);
00156 void delDependParentNode( Relation *rel, bool remove=false);
00157 void delDependParentNode( int number, bool remove=false);
00158 Relation *getDependParentNode( int number) {
00159 return m_dependParentNodes.at(number);
00160 }
00161 QPtrList<Relation> &dependParentNodes() { return m_dependParentNodes; }
00162
00167 void takeDependParentNode(Relation *rel);
00168
00169 bool isParentOf(Node *node);
00170 bool isDependChildOf(Node *node);
00171
00172 Relation *findParentRelation(Node *node);
00173 Relation *findChildRelation(Node *node);
00174 Relation *findRelation(Node *node);
00175
00176 void setStartTime(DateTime startTime);
00178 virtual DateTime startTime() const
00179 { return m_currentSchedule ? m_currentSchedule->startTime : DateTime(); }
00180 const QDate &startDate() const { return m_dateOnlyStartDate; }
00181 void setEndTime(DateTime endTime);
00183 virtual DateTime endTime() const
00184 { return m_currentSchedule ? m_currentSchedule->endTime : DateTime(); }
00185 const QDate &endDate() const { return m_dateOnlyEndDate; }
00186
00187 void setEffort(Effort* e) { m_effort = e; }
00188 Effort* effort() const { return m_effort; }
00189
00193 virtual Duration *getExpectedDuration() = 0;
00194
00200 virtual Duration *getRandomDuration() = 0;
00201
00206 Duration *getDelay();
00207
00213 DateTime getEarliestStart() const
00214 { return m_currentSchedule ? m_currentSchedule->earliestStart : DateTime(); }
00219 void setEarliestStart(const DateTime &dt)
00220 { if (m_currentSchedule) m_currentSchedule->earliestStart = dt; }
00225 DateTime getLatestFinish() const
00226 { return m_currentSchedule ? m_currentSchedule->latestFinish : DateTime(); }
00232 void setLatestFinish(const DateTime &dt)
00233 { if (m_currentSchedule) m_currentSchedule->latestFinish = dt; }
00234
00235 QString &name() { return m_name; }
00236 QString &leader() { return m_leader; }
00237 QString &description() { return m_description; }
00238 const QString &name() const { return m_name; }
00239 const QString &leader() const { return m_leader; }
00240 const QString &description() const { return m_description; }
00241 void setName(const QString &n) { m_name = n; }
00242 void setLeader(const QString &l) { m_leader = l; }
00243 void setDescription(const QString &d) { m_description = d; }
00244
00245 virtual void setConstraint(Node::ConstraintType type) { m_constraint = type; }
00246 void setConstraint(QString &type);
00247 int constraint() const { return m_constraint; }
00248 QString constraintToString() const;
00249
00250 virtual void setConstraintStartTime(QDateTime time) { m_constraintStartTime = time; }
00251 virtual void setConstraintEndTime(QDateTime time) { m_constraintEndTime = time; }
00252
00253 virtual DateTime constraintStartTime() const { return m_constraintStartTime; }
00254 virtual DateTime constraintEndTime() const { return m_constraintEndTime; }
00255 virtual DateTime startNotEarlier() const { return m_constraintStartTime; }
00256 virtual DateTime finishNotLater() const { return m_constraintEndTime; }
00257 virtual DateTime mustStartOn() const { return m_constraintStartTime; }
00258 virtual DateTime mustFinishOn() const { return m_constraintEndTime; }
00259
00260 virtual ResourceGroupRequest *resourceRequest(ResourceGroup *) const { return 0; }
00261 virtual void makeAppointments();
00262
00264 bool resourceError() const
00265 { return m_currentSchedule ? m_currentSchedule->resourceError : false; }
00267 virtual bool resourceOverbooked() const
00268 { return m_currentSchedule ? m_currentSchedule->resourceOverbooked : false; }
00271 virtual void calcResourceOverbooked();
00273 bool resourceNotAvailable() const
00274 { return m_currentSchedule ? m_currentSchedule->resourceNotAvailable : false; }
00276 virtual bool schedulingError() const
00277 { return m_currentSchedule ? m_currentSchedule->schedulingError : false; }
00279 bool notScheduled() const
00280 { return m_currentSchedule == 0 || m_currentSchedule->isDeleted() || m_currentSchedule->notScheduled; }
00281
00282 virtual EffortCostMap plannedEffortCostPrDay(const QDate &start, const QDate &end) const=0;
00283
00285 virtual Duration plannedEffort() { return Duration::zeroDuration; }
00287 virtual Duration plannedEffort(const QDate &) { return Duration::zeroDuration; }
00289 virtual Duration plannedEffortTo(const QDate &) { return Duration::zeroDuration; }
00290
00292 virtual Duration actualEffort() { return Duration::zeroDuration; }
00294 virtual Duration actualEffort(const QDate &) { return Duration::zeroDuration; }
00296 virtual Duration actualEffortTo(const QDate &) { return Duration::zeroDuration; }
00297
00302 virtual double plannedCost() { return 0; }
00303
00305 virtual double plannedCost(const QDate &) { return 0; }
00310 virtual double plannedCostTo(const QDate &) { return 0; }
00315 virtual double actualCost() { return 0; }
00317 virtual double actualCost(const QDate &) { return 0; }
00319 virtual double actualCostTo(const QDate &) { return 0; }
00320
00322 double effortPerformanceIndex(const QDate &, bool *) { return 0.0; }
00324 double costPerformanceIndex(const QDate &, bool *) { return 0.0; }
00325
00326 virtual void initiateCalculationLists(QPtrList<Node> &startnodes, QPtrList<Node> &endnodes, QPtrList<Node> &summarytasks) = 0;
00327 virtual DateTime calculateForward(int ) = 0;
00328 virtual DateTime calculateBackward(int ) = 0;
00329 virtual DateTime scheduleForward(const DateTime &, int ) = 0;
00330 virtual DateTime scheduleBackward(const DateTime &, int ) = 0;
00331 virtual void adjustSummarytask() = 0;
00332
00333 virtual void initiateCalculation(Schedule &sch);
00334 virtual void resetVisited();
00335 void propagateEarliestStart(DateTime &time);
00336 void propagateLatestFinish(DateTime &time);
00337 void moveEarliestStart(DateTime &time);
00338 void moveLatestFinish(DateTime &time);
00339
00340 virtual Duration summarytaskDurationForward(const DateTime &)
00341 { return Duration::zeroDuration; }
00342
00343 virtual DateTime summarytaskEarliestStart()
00344 { return DateTime(); }
00345
00346 virtual Duration summarytaskDurationBackward(const DateTime &)
00347 { return Duration::zeroDuration; }
00348
00349 virtual DateTime summarytaskLatestFinish()
00350 { return DateTime(); }
00351
00352 const Duration &duration()
00353 { return m_currentSchedule ? m_currentSchedule->duration : Duration::zeroDuration; }
00362 Duration duration(const DateTime &time, int use, bool backward);
00363
00364 virtual Duration calcDuration(const DateTime &, const Duration &, bool ) { return Duration::zeroDuration;}
00365
00366 Node *siblingBefore();
00367 Node *childBefore(Node *node);
00368 Node *siblingAfter();
00369 Node *childAfter(Node *node);
00370 bool moveChildUp(Node *node);
00371 bool moveChildDown(Node *node);
00372
00374 bool legalToLink(Node *node);
00376 virtual bool legalToLink(Node *, Node *) { return false; }
00378 virtual bool isEndNode() const;
00380 virtual bool isStartNode() const;
00381 virtual void clearProxyRelations() {}
00382 virtual void addParentProxyRelations(QPtrList<Relation> &) {}
00383 virtual void addChildProxyRelations(QPtrList<Relation> &) {}
00384 virtual void addParentProxyRelation(Node *, const Relation *) {}
00385 virtual void addChildProxyRelation(Node *, const Relation *) {}
00386
00388 virtual void saveAppointments(QDomElement &element, long id) const;
00390 QPtrList<Appointment> appointments();
00392
00394 virtual bool addAppointment(Appointment *appointment);
00396 virtual bool addAppointment(Appointment *appointment, Schedule &main);
00398 virtual void addAppointment(ResourceSchedule *resource, DateTime &start, DateTime &end, double load=100);
00399
00401 virtual Node *findNode() const { return findNode(m_id); }
00403 virtual Node *findNode(const QString &id) const
00404 { return (m_parent ? m_parent->findNode(id) : 0); }
00406 virtual bool removeId() { return removeId(m_id); }
00408 virtual bool removeId(const QString &id)
00409 { return (m_parent ? m_parent->removeId(id) : false); }
00411 virtual void insertId(const QString &id) { insertId(id, this); }
00413 virtual void insertId(const QString &id, const Node *node)
00414 { if (m_parent) m_parent->insertId(id, node); }
00415
00421 virtual DateTime workStartTime() const
00422 { return m_currentSchedule ? m_currentSchedule->workStartTime : DateTime(); }
00423 void setWorkStartTime(const DateTime &dt)
00424 { if (m_currentSchedule) m_currentSchedule->workStartTime = dt; }
00425
00431 virtual DateTime workEndTime() const
00432 { return m_currentSchedule ? m_currentSchedule->workEndTime : DateTime(); }
00433 void setWorkEndTime(const DateTime &dt)
00434 { if (m_currentSchedule) m_currentSchedule->workEndTime = dt; }
00435
00436 virtual bool isCritical() const { return false; }
00437 virtual bool inCriticalPath() const
00438 { return m_currentSchedule ? m_currentSchedule->inCriticalPath : false; }
00439 virtual bool calcCriticalPath(bool fromEnd);
00440
00442 virtual int level();
00444 virtual void generateWBS(int count, WBSDefinition &def, QString wbs=QString());
00445 QString wbs() const { return m_wbs; }
00446
00447 double startupCost() const { return m_startupCost; }
00448 void setStartupCost(double cost) { m_startupCost = cost; }
00449
00450 Account *startupAccount() const { return m_startupAccount; }
00451 void setStartupAccount(Account *acc) { m_startupAccount = acc; }
00452
00453 double shutdownCost() const { return m_shutdownCost; }
00454 void setShutdownCost(double cost) { m_shutdownCost = cost; }
00455
00456 Account *shutdownAccount() const { return m_shutdownAccount; }
00457 void setShutdownAccount(Account *acc) { m_shutdownAccount = acc; }
00458
00459 Account *runningAccount() const { return m_runningAccount; }
00460 void setRunningAccount(Account *acc) { m_runningAccount = acc; }
00461
00462 Schedule *currentSchedule() const { return m_currentSchedule; }
00464 virtual void setCurrentSchedule(long id);
00465
00466 void setCurrentSchedulePtr(Schedule *schedule) { m_currentSchedule = schedule; }
00467
00468 QIntDict<Schedule> &schedules() { return m_schedules; }
00470 Schedule *findSchedule(const QString name, const Schedule::Type type) const;
00472 Schedule *findSchedule(const Schedule::Type type) const;
00474 Schedule *findSchedule(long id) const { return m_schedules[id]; }
00476 void takeSchedule(const Schedule *schedule);
00478 void addSchedule(Schedule *schedule);
00480 Schedule *createSchedule(QString name, Schedule::Type type, long id);
00482 Schedule *createSchedule(Schedule *parent);
00483
00485 void setScheduleDeleted(long id, bool onoff);
00487 virtual void setParentSchedule(Schedule *sch);
00488
00489 DateTime startTime()
00490 { return m_currentSchedule ? m_currentSchedule->startTime : DateTime(); }
00491 DateTime endTime()
00492 { return m_currentSchedule ? m_currentSchedule->endTime : DateTime(); }
00493
00494 protected:
00495 QPtrList<Node> m_nodes;
00496 QPtrList<Relation> m_dependChildNodes;
00497 QPtrList<Relation> m_dependParentNodes;
00498 Node *m_parent;
00499
00500 QString m_id;
00501 QString m_name;
00502 QString m_leader;
00503 QString m_description;
00504
00505 Effort* m_effort;
00506
00507
00508 ConstraintType m_constraint;
00509
00514 DateTime m_constraintStartTime;
00519 DateTime m_constraintEndTime;
00520
00521 bool m_visitedForward;
00522 bool m_visitedBackward;
00523 Duration m_durationForward;
00524 Duration m_durationBackward;
00525
00526 QDate m_dateOnlyStartDate;
00527 QDate m_dateOnlyEndDate;
00528 Duration m_dateOnlyDuration;
00529
00530 QIntDict<Schedule> m_schedules;
00531 Schedule *m_currentSchedule;
00532
00533 QString m_wbs;
00534
00535 double m_startupCost;
00536 Account *m_startupAccount;
00537 double m_shutdownCost;
00538 Account *m_shutdownAccount;
00539 Account *m_runningAccount;
00540
00541 private:
00542 void init();
00543
00544 #ifndef NDEBUG
00545 public:
00546 virtual void printDebug(bool children, QCString indent);
00547 #endif
00548
00549 };
00550
00552
00558 class Effort {
00559 public:
00560 Effort ( Duration e = Duration::zeroDuration, Duration p = Duration::zeroDuration,
00561 Duration o = Duration::zeroDuration );
00562
00563 Effort ( double e, double p = 0, double o = 0);
00564
00565 Effort (const Effort &effort);
00566 ~Effort();
00567
00568 enum Type { Type_Effort = 0,
00569 Type_FixedDuration = 1
00570 };
00571 Type type() const { return m_type; }
00572 void setType(Type type) { m_type = type; }
00573 void setType(QString type);
00574 QString typeToString() const;
00575
00576 enum Use { Use_Expected=0, Use_Optimistic=1, Use_Pessimistic=2 };
00577 const Duration& effort(int use) {
00578 if (use == Effort::Use_Expected)
00579 return m_expectedEffort;
00580 else if (use == Effort::Use_Optimistic)
00581 return m_optimisticEffort;
00582 else if (use == Effort::Use_Pessimistic)
00583 return m_pessimisticEffort;
00584
00585 return m_expectedEffort;
00586 }
00587 const Duration& optimistic() const {return m_optimisticEffort;}
00588 const Duration& pessimistic() const {return m_pessimisticEffort;}
00589 const Duration& expected() const {return m_expectedEffort;}
00590
00591 void set( Duration e, Duration p = Duration::zeroDuration, Duration o = Duration::zeroDuration );
00592 void set( int e, int p = -1, int o = -1 );
00593 void set(unsigned days, unsigned hours, unsigned minutes);
00594 void expectedEffort(unsigned *days, unsigned *hours, unsigned *minutes);
00595
00596 bool load(QDomElement &element);
00597 void save(QDomElement &element) const;
00598
00603 void setOptimisticRatio(int percent);
00608 int optimisticRatio() const;
00613 void setPessimisticRatio(int percent);
00618 int pessimisticRatio() const;
00619
00623 static const Effort zeroEffort;
00624
00625 private:
00626 Duration m_optimisticEffort;
00627 Duration m_pessimisticEffort;
00628 Duration m_expectedEffort;
00629
00630 Type m_type;
00631
00632 #ifndef NDEBUG
00633 public:
00634 void printDebug(QCString indent);
00635 #endif
00636
00637 };
00638
00639 }
00640
00641 #endif