1 /* This file is part of the KDE project 2 Copyright (C) 2001 Thomas Zander zander@kde.org 3 Copyright (C) 2004 - 2007 Dag Andersen <danders@get2net.dk> 4 Copyright (C) 2007 Florian Piquemal <flotueur@yahoo.fr> 5 Copyright (C) 2007 Alexis Ménard <darktears31@gmail.com> 6 7 This library is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Library General Public 9 License as published by the Free Software Foundation; either 10 version 2 of the License, or (at your option) any later version. 11 12 This library is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 Library General Public License for more details. 16 17 You should have received a copy of the GNU Library General Public License 18 along with this library; see the file COPYING.LIB. If not, write to 19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301, USA. 21 */ 22 23 #ifndef KPTTASK_H 24 #define KPTTASK_H 25 26 #include "plankernel_export.h" 27 28 #include "kptnode.h" 29 #include "kptglobal.h" 30 #include "kptdatetime.h" 31 #include "kptduration.h" 32 #include "kptresource.h" 33 34 #include <QList> 35 #include <QMap> 36 #include <utility> 37 38 /// The main namespace. 39 namespace KPlato 40 { 41 42 class Completion; 43 class XmlSaveContext; 44 45 /** 46 * The Completion class holds information about the tasks progress. 47 */ 48 class PLANKERNEL_EXPORT Completion 49 { 50 51 public: 52 class PLANKERNEL_EXPORT UsedEffort 53 { 54 public: 55 class PLANKERNEL_EXPORT ActualEffort : public std::pair<Duration, Duration> 56 { 57 public: 58 explicit ActualEffort(KPlato::Duration ne = Duration::zeroDuration, KPlato::Duration oe = Duration::zeroDuration) 59 : std::pair<Duration, Duration>(ne, oe) 60 {} ActualEffort(const ActualEffort & e)61 ActualEffort(const ActualEffort &e) 62 : std::pair<Duration, Duration>(e.first, e.second) 63 {} ~ActualEffort()64 ~ActualEffort() {} isNull()65 bool isNull() const { return (first + second) == Duration::zeroDuration; } normalEffort()66 Duration normalEffort() const { return first; } setNormalEffort(KPlato::Duration e)67 void setNormalEffort(KPlato::Duration e) { first = e; } overtimeEffort()68 Duration overtimeEffort() const { return second; } setOvertimeEffort(KPlato::Duration e)69 void setOvertimeEffort(KPlato::Duration e) { second = e; } 70 /// Returns the sum of normalEffort + overtimeEffort effort()71 Duration effort() const { return first + second; } 72 void setEffort(KPlato::Duration ne, KPlato::Duration oe = Duration::zeroDuration) { first = ne; second = oe; } 73 }; 74 UsedEffort(); 75 UsedEffort(const UsedEffort &e); 76 ~UsedEffort(); 77 bool operator==(const UsedEffort &e) const; 78 bool operator!=(const UsedEffort &e) const { return !operator==(e); } 79 void mergeEffort(const UsedEffort &value); 80 void setEffort(QDate date, const ActualEffort &value); 81 /// Returns the total effort up to @p date 82 Duration effortTo(QDate date) const; 83 /// Returns the total effort on @p date effort(QDate date)84 ActualEffort effort(QDate date) const { return m_actual.value(date); } takeEffort(QDate date)85 ActualEffort takeEffort(QDate date) { return m_actual.take(date); } 86 /// Returns the total effort for all registered dates 87 Duration effort() const; firstDate()88 QDate firstDate() const { return m_actual.firstKey(); } lastDate()89 QDate lastDate() const { return m_actual.lastKey(); } actualEffortMap()90 QMap<QDate, ActualEffort> actualEffortMap() const { return m_actual; } 91 92 /// Load from document 93 bool loadXML(KoXmlElement &element, XMLLoaderObject &status); 94 /// Save to document 95 void saveXML(QDomElement &element) const; contains(QDate date)96 bool contains(QDate date) const { return m_actual.contains(date); } 97 98 private: 99 QMap<QDate, ActualEffort> m_actual; 100 }; 101 typedef QMap<QDate, UsedEffort::ActualEffort> DateUsedEffortMap; 102 103 class PLANKERNEL_EXPORT Entry 104 { 105 public: Entry()106 Entry() 107 : percentFinished(0), 108 remainingEffort(Duration::zeroDuration), 109 totalPerformed(Duration::zeroDuration) 110 {} Entry(int percent,Duration remaining,Duration performed)111 Entry(int percent, Duration remaining, Duration performed) 112 : percentFinished(percent), 113 remainingEffort(remaining), 114 totalPerformed(performed) 115 {} Entry(const Entry & e)116 Entry(const Entry &e) { copy(e); } 117 bool operator==(const Entry &e) const { 118 return percentFinished == e.percentFinished 119 && remainingEffort == e.remainingEffort 120 && totalPerformed == e.totalPerformed 121 && note == e.note; 122 } 123 bool operator!=(const Entry &e) const { return ! operator==(e); } 124 Entry &operator=(const Entry &e) { copy(e); return *this; } 125 126 int percentFinished; 127 Duration remainingEffort; 128 Duration totalPerformed; 129 QString note; 130 protected: copy(const Entry & e)131 void copy(const Entry &e) { 132 percentFinished = e.percentFinished; 133 remainingEffort = e.remainingEffort; 134 totalPerformed = e.totalPerformed; 135 note = e.note; 136 } 137 }; 138 typedef QMap<QDate, Entry*> EntryList; 139 140 typedef QHash<const Resource*, UsedEffort*> ResourceUsedEffortMap; 141 142 explicit Completion(Node *node = 0); // review * or &, or at all? 143 Completion(const Completion ©); 144 virtual ~Completion(); 145 146 bool operator==(const Completion &p); 147 bool operator!=(Completion &p) { return !(*this == p); } 148 Completion &operator=(const Completion &p); 149 150 /// Load from document 151 bool loadXML(KoXmlElement &element, XMLLoaderObject &status); 152 /// Save to document 153 void saveXML(QDomElement &element) const; 154 startIsValid()155 bool startIsValid() const { return m_started && m_startTime.isValid(); } isStarted()156 bool isStarted() const { return m_started; } 157 void setStarted(bool on); finishIsValid()158 bool finishIsValid() const { return m_finished && m_finishTime.isValid(); } isFinished()159 bool isFinished() const { return m_finished; } 160 void setFinished(bool on); startTime()161 DateTime startTime() const { return m_startTime; } 162 void setStartTime(const DateTime &dt); finishTime()163 DateTime finishTime() const { return m_finishTime; } 164 void setFinishTime(const DateTime &dt); 165 void setPercentFinished(QDate date, int value); 166 void setRemainingEffort(QDate date, Duration value); 167 void setActualEffort(QDate date, Duration value); 168 169 /// Return a list of the resource that has done any work on this task resources()170 QList<const Resource*> resources() const { return m_usedEffort.keys(); } 171 entries()172 const EntryList &entries() const { return m_entries; } 173 void addEntry(QDate date, Entry *entry); takeEntry(QDate date)174 Entry *takeEntry(QDate date) { return m_entries.take(date); changed(); } entry(QDate date)175 Entry *entry(QDate date) const { return m_entries[ date ]; } 176 177 /// Returns the date of the latest entry 178 QDate entryDate() const; 179 /// Returns the percentFinished of the latest entry 180 int percentFinished() const; 181 /// Returns the percentFinished on @p date 182 int percentFinished(QDate date) const; 183 /// Returns the estimated remaining effort 184 Duration remainingEffort() const; 185 /// Returns the estimated remaining effort on @p date 186 Duration remainingEffort(QDate date) const; 187 /// Returns the total actual effort 188 Duration actualEffort() const; 189 /// Returns the total actual effort on @p date 190 Duration actualEffort(QDate date) const; 191 /// Returns the total actual effort upto and including @p date 192 Duration actualEffortTo(QDate date) const; 193 /// Returns the actual effort for @p resource on @p date 194 Duration actualEffort(const Resource *resource, QDate date) const; 195 /// TODO 196 QString note() const; 197 /// TODO 198 void setNote(const QString &str); 199 200 /// Returns the total actual cost 201 double actualCost() const; 202 /// Returns the actual cost for @p resource 203 double actualCost(const Resource *resource) const; 204 /// Returns the actual cost on @p date 205 double actualCost(QDate date) const; 206 /// Returns the total actual cost for @p resource on @p date 207 double actualCost(const Resource *resource, QDate date) const; 208 /// Returns the total actual effort and cost upto and including @p date 209 EffortCost actualCostTo(long int id, QDate date) const; 210 211 /** 212 * Returns a map of all actual effort and cost entered 213 */ 214 virtual EffortCostMap actualEffortCost(long id, EffortCostCalculationType type = ECCT_All) const; 215 216 void addUsedEffort(const Resource *resource, UsedEffort *value = 0); takeUsedEffort(const Resource * r)217 UsedEffort *takeUsedEffort(const Resource *r) { return m_usedEffort.take(const_cast<Resource*>(r) ); changed(); } usedEffort(const Resource * r)218 UsedEffort *usedEffort(const Resource *r) const { return m_usedEffort.value(const_cast<Resource*>(r) ); } usedEffortMap()219 const ResourceUsedEffortMap &usedEffortMap() const { return m_usedEffort; } 220 221 void setActualEffort(Resource *resource, const QDate &date, const UsedEffort::ActualEffort &value); 222 // FIXME name clash 223 UsedEffort::ActualEffort getActualEffort(Resource *resource, const QDate &date) const; 224 225 void changed(int property = -1); node()226 Node *node() const { return m_node; } setNode(Node * node)227 void setNode(Node *node) { m_node = node; } 228 229 enum Entrymode { FollowPlan, EnterCompleted, EnterEffortPerTask, EnterEffortPerResource }; setEntrymode(Entrymode mode)230 void setEntrymode(Entrymode mode) { m_entrymode = mode; } entrymode()231 Entrymode entrymode() const { return m_entrymode; } 232 void setEntrymode(const QString &mode); 233 QString entryModeToString() const; 234 QStringList entrymodeList() const; 235 236 EffortCostMap effortCostPrDay(QDate start, QDate end, long id = -1) const; 237 /// Returns the actual effort and cost pr day used by @p resource 238 EffortCostMap effortCostPrDay(const Resource *resource, QDate start, QDate end, long id = CURRENTSCHEDULE) const; 239 240 protected: 241 void copy(const Completion ©); 242 double averageCostPrHour(QDate date, long id) const; 243 std::pair<QDate, QDate> actualStartEndDates() const; 244 245 private: 246 Node *m_node; 247 bool m_started, m_finished; 248 DateTime m_startTime, m_finishTime; 249 EntryList m_entries; 250 ResourceUsedEffortMap m_usedEffort; 251 Entrymode m_entrymode; 252 253 #ifndef NDEBUG 254 public: 255 void printDebug(const QByteArray &ident) const; 256 #endif 257 }; 258 259 /** 260 * The WorkPackage class controls work flow for a task 261 */ 262 class PLANKERNEL_EXPORT WorkPackage 263 { 264 public: 265 266 /// @enum WPTransmitionStatus describes if this package was sent or received 267 enum WPTransmitionStatus { 268 TS_None, /// Not sent nor received 269 TS_Send, /// Package was sent to resource 270 TS_Receive, /// Package was received from resource 271 TS_Rejected /// Received package was rejected by project manager 272 }; 273 274 explicit WorkPackage(Task *task = 0); 275 explicit WorkPackage(const WorkPackage &wp); 276 virtual ~WorkPackage(); 277 parentTask()278 Task *parentTask() const { return m_task; } setParentTask(Task * task)279 void setParentTask(Task *task) { m_task = task; } 280 281 /// Returns the transmission status of this package transmitionStatus()282 WPTransmitionStatus transmitionStatus() const { return m_transmitionStatus; } setTransmitionStatus(WPTransmitionStatus sts)283 void setTransmitionStatus(WPTransmitionStatus sts) { m_transmitionStatus = sts; } 284 static QString transmitionStatusToString(WPTransmitionStatus sts, bool trans = false); 285 static WPTransmitionStatus transmitionStatusFromString(const QString &sts); 286 287 /// Load from document 288 virtual bool loadXML(KoXmlElement &element, XMLLoaderObject &status); 289 /// Save the full workpackage 290 virtual void saveXML(QDomElement &element) const; 291 292 /// Load from document 293 virtual bool loadLoggedXML(KoXmlElement &element, XMLLoaderObject &status); 294 /// Save the full workpackage 295 virtual void saveLoggedXML(QDomElement &element) const; 296 297 /// Set schedule manager 298 void setScheduleManager(ScheduleManager *sm); 299 /// Return schedule manager scheduleManager()300 ScheduleManager *scheduleManager() const { return m_manager; } 301 /// Return the schedule id, or NOTSCHEDULED if no schedule manager is set id()302 long id() const { return m_manager ? m_manager->scheduleId() : NOTSCHEDULED; } 303 304 Completion &completion(); 305 const Completion &completion() const; 306 307 void addLogEntry(DateTime &dt, const QString &str); 308 QMap<DateTime, QString> log() const; 309 QStringList log(); 310 311 /// Return a list of resources fetched from the appointments or requests 312 /// merged with resources added to completion 313 QList<Resource*> fetchResources(); 314 315 /// Return a list of resources fetched from the appointments or requests 316 /// merged with resources added to completion 317 QList<Resource*> fetchResources(long id); 318 319 /// Returns id of the resource that owns this package. If empty, task leader owns it. ownerId()320 QString ownerId() const { return m_ownerId; } 321 /// Set the resource that owns this package to @p owner. If empty, task leader owns it. setOwnerId(const QString & id)322 void setOwnerId(const QString &id) { m_ownerId = id; } 323 324 /// Returns the name of the resource that owns this package. ownerName()325 QString ownerName() const { return m_ownerName; } 326 /// Set the name of the resource that owns this package. setOwnerName(const QString & name)327 void setOwnerName(const QString &name) { m_ownerName = name; } 328 transmitionTime()329 DateTime transmitionTime() const { return m_transmitionTime; } setTransmitionTime(const DateTime & dt)330 void setTransmitionTime(const DateTime &dt) { m_transmitionTime = dt; } 331 332 /// Clear workpackage data 333 void clear(); 334 335 private: 336 Task *m_task; 337 ScheduleManager *m_manager; 338 Completion m_completion; 339 QString m_ownerName; 340 QString m_ownerId; 341 WPTransmitionStatus m_transmitionStatus; 342 DateTime m_transmitionTime; 343 344 QMap<DateTime, QString> m_log; 345 }; 346 347 class PLANKERNEL_EXPORT WorkPackageSettings 348 { 349 public: 350 WorkPackageSettings(); 351 bool loadXML(const KoXmlElement &element); 352 void saveXML(QDomElement &element) const; 353 bool operator==(WorkPackageSettings settings) const; 354 bool operator!=(WorkPackageSettings settings) const; 355 bool usedEffort; 356 bool progress; 357 bool documents; 358 bool remainingEffort; 359 }; 360 361 /** 362 * A task in the scheduling software is represented by this class. A task 363 * can be anything from 'build house' to 'drill hole' It will always mean 364 * an activity. 365 */ 366 class PLANKERNEL_EXPORT Task : public Node { 367 Q_OBJECT 368 public: 369 explicit Task(Node *parent = 0); 370 explicit Task(const Task &task, Node *parent = 0); 371 ~Task() override; 372 373 /// Return task type. Can be Type_Task, Type_Summarytask ot Type_Milestone. 374 int type() const override; 375 376 /** 377 * Instead of using the expected duration, generate a random value using 378 * the Distribution of each Task. This can be used for Monte-Carlo 379 * estimation of Project duration. 380 */ 381 Duration *getRandomDuration() override; 382 383 /** 384 * Return the resource request made to group 385 * (There should be only one) 386 */ 387 ResourceGroupRequest *resourceGroupRequest(const ResourceGroup *group) const override; 388 void clearResourceRequests(); 389 void addRequest(ResourceGroup *group, int numResources); 390 void addRequest(ResourceGroupRequest *request); 391 void takeRequest(ResourceGroupRequest *request); 392 void makeAppointments() override; 393 QStringList requestNameList() const override; 394 virtual QList<Resource*> requestedResources() const; 395 bool containsRequest(const QString &/*identity*/) const override; 396 ResourceRequest *resourceRequest(const QString &/*name*/) const override; 397 398 /// Return the list of resources assigned to this task 399 QStringList assignedNameList(long id = CURRENTSCHEDULE) const override; 400 401 /** 402 * Calculates if the assigned resource is overbooked 403 * within the duration of this task 404 */ 405 void calcResourceOverbooked() override; 406 407 /// Load from document 408 bool load(KoXmlElement &element, XMLLoaderObject &status) override; 409 /// Save to document 410 void save(QDomElement &element, const XmlSaveContext &context) const override; 411 /// Save appointments for schedule with id 412 void saveAppointments(QDomElement &element, long id) const override; 413 414 /// Save a workpackage document with schedule identity @p id 415 void saveWorkPackageXML(QDomElement &element, long id) const override; 416 417 /** 418 * Returns a list of planned effort and cost for this task 419 * for the interval start, end inclusive 420 */ 421 EffortCostMap plannedEffortCostPrDay(QDate start, QDate end, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All) const override; 422 /** 423 * Returns a list of planned effort and cost for the @p resource 424 * for the interval @p start, @p end inclusive, useng schedule with identity @p id 425 */ 426 EffortCostMap plannedEffortCostPrDay(const Resource *resource, QDate start, QDate end, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All) const override; 427 428 /// Returns the total planned effort for @p resource on this task (or subtasks) 429 Duration plannedEffort(const Resource *resource, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All) const override; 430 /// Returns the total planned effort for this task (or subtasks) 431 Duration plannedEffort(long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All) const override; 432 /// Returns the total planned effort for this task (or subtasks) on date 433 Duration plannedEffort(QDate date, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All) const override; 434 /// Returns the total planned effort for @p resource on this task (or subtasks) on date 435 Duration plannedEffort(const Resource *resource, QDate date, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All) const override; 436 /// Returns the planned effort up to and including date 437 Duration plannedEffortTo(QDate date, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All) const override; 438 /// Returns the planned effort for @p resource up to and including date 439 Duration plannedEffortTo(const Resource *resource, QDate date, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All) const override; 440 441 /// Returns the total actual effort for this task (or subtasks) 442 Duration actualEffort() const override; 443 /// Returns the total actual effort for this task (or subtasks) on date 444 Duration actualEffort(QDate date) const override; 445 /// Returns the actual effort up to and including date 446 Duration actualEffortTo(QDate date) const override; 447 448 /** 449 * Returns the total planned cost for this task (or subtasks) 450 */ 451 EffortCost plannedCost(long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All) const override; 452 /// Planned cost up to and including date 453 double plannedCostTo(QDate /*date*/, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All) const override; 454 455 /// Returns actual effort and cost up to and including @p date 456 EffortCost actualCostTo(long int id, QDate date) const override; 457 458 /** 459 * Returns a list of actual effort and cost for this task 460 * for the interval start, end inclusive 461 */ 462 EffortCostMap actualEffortCostPrDay(QDate start, QDate end, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All) const override; 463 /// Returns the actual effort and cost pr day used by @p resource 464 EffortCostMap actualEffortCostPrDay(const Resource *resource, QDate start, QDate end, long id = CURRENTSCHEDULE, EffortCostCalculationType = ECCT_All) const override; 465 466 /// Returns the effort planned to be used to reach the actual percent finished 467 Duration budgetedWorkPerformed(QDate date, long id = CURRENTSCHEDULE) const override; 468 469 /// Returns the cost planned to be used to reach the actual percent finished 470 double budgetedCostPerformed(QDate date, long id = CURRENTSCHEDULE) const override; 471 472 using Node::bcwsPrDay; 473 /// Return map of Budgeted Cost of Work Scheduled pr day 474 EffortCostMap bcwsPrDay(long id = CURRENTSCHEDULE, EffortCostCalculationType type = ECCT_All) override; 475 476 /// Budgeted Cost of Work Scheduled 477 double bcws(QDate date, long id = CURRENTSCHEDULE) const override; 478 479 using Node::bcwpPrDay; 480 /// Return map of Budgeted Cost of Work Performed pr day (also includes bcwsPrDay) 481 EffortCostMap bcwpPrDay(long id = CURRENTSCHEDULE, EffortCostCalculationType type = ECCT_All) override; 482 /// Budgeted Cost of Work Performed 483 double bcwp(long id = CURRENTSCHEDULE) const override; 484 /// Budgeted Cost of Work Performed (up to @p date) 485 double bcwp(QDate date, long id = CURRENTSCHEDULE) const override; 486 487 using Node::acwp; 488 /// Map of Actual Cost of Work Performed 489 EffortCostMap acwp(long id = CURRENTSCHEDULE, EffortCostCalculationType type = ECCT_All) override; 490 /// Actual Cost of Work Performed up to dat 491 EffortCost acwp(QDate date, long id = CURRENTSCHEDULE) const override; 492 493 /// Effort based performance index 494 double effortPerformanceIndex(QDate date, long id = CURRENTSCHEDULE) const override; 495 496 /// Schedule performance index 497 double schedulePerformanceIndex(QDate date, long id = CURRENTSCHEDULE) const override; 498 /// Cost performance index 499 double costPerformanceIndex(long int id, QDate date, bool *error=0) const override; 500 501 /** 502 * Return the duration that an activity's start can be delayed 503 * without affecting the project completion date. 504 * An activity with positive float is not on the critical path. 505 * @param id Schedule identity. If id is CURRENTSCHEDULE, use current schedule. 506 */ 507 Duration positiveFloat(long id = CURRENTSCHEDULE) const; 508 void setPositiveFloat(Duration fl, long id = CURRENTSCHEDULE) const; 509 /** 510 * Return the duration by which the duration of an activity or path 511 * has to be reduced in order to fulfill a timing- or dependency constraint. 512 * @param id Schedule identity. If id is CURRENTSCHEDULE, use current schedule. 513 */ 514 Duration negativeFloat(long id = CURRENTSCHEDULE) const; 515 void setNegativeFloat(Duration fl, long id = CURRENTSCHEDULE) const; 516 /** 517 * Return the duration by which an activity can be delayed or extended 518 * without affecting the start of any succeeding activity. 519 * @param id Schedule identity. If id is CURRENTSCHEDULE, use current schedule. 520 */ 521 Duration freeFloat(long id = CURRENTSCHEDULE) const; 522 void setFreeFloat(Duration fl, long id = CURRENTSCHEDULE) const; 523 /** 524 * Return the duration from Early Start to Late Start. 525 * @param id Schedule identity. If id is CURRENTSCHEDULE, use current schedule. 526 */ 527 Duration startFloat(long id = CURRENTSCHEDULE) const; 528 /** 529 * Return the duration from Early Finish to Late Finish. 530 * @param id Schedule identity. If id is CURRENTSCHEDULE, use current schedule. 531 */ 532 Duration finishFloat(long id = CURRENTSCHEDULE) const; 533 534 /** 535 * A task is critical if positive float equals 0 536 * @param id Schedule identity. If id is CURRENTSCHEDULE, use current schedule. 537 */ 538 bool isCritical(long id = CURRENTSCHEDULE) const override; 539 540 /** 541 * Set current schedule to schedule with identity id, for me and my children. 542 * @param id Schedule identity 543 */ 544 void setCurrentSchedule(long id) override; 545 546 /** 547 * The assigned resources can not fulfill the estimated effort. 548 * @param id Schedule identity. If id is CURRENTSCHEDULE, use current schedule. 549 */ 550 bool effortMetError(long id = CURRENTSCHEDULE) const override; 551 552 /// @return true if this task has been started 553 bool isStarted() const; 554 completion()555 Completion &completion() { return m_workPackage.completion(); } completion()556 const Completion &completion() const { return m_workPackage.completion(); } 557 workPackage()558 WorkPackage &workPackage() { return m_workPackage; } workPackage()559 const WorkPackage &workPackage() const { return m_workPackage; } 560 workPackageLogCount()561 int workPackageLogCount() const { return m_packageLog.count(); } workPackageLog()562 QList<WorkPackage*> workPackageLog() const { return m_packageLog; } 563 void addWorkPackage(WorkPackage *wp); 564 void removeWorkPackage(WorkPackage *wp); 565 WorkPackage *workPackageAt(int index) const; 566 567 QString wpOwnerName() const; 568 WorkPackage::WPTransmitionStatus wpTransmitionStatus() const; 569 DateTime wpTransmitionTime() const; 570 571 /** 572 * Returns the state of the task 573 * @param id The identity of the schedule used when calculating the state 574 */ 575 uint state(long id = CURRENTSCHEDULE) const override; 576 577 /// Check if this node has any dependent child nodes 578 bool isEndNode() const override; 579 /// Check if this node has any dependent parent nodes 580 bool isStartNode() const override; 581 parentProxyRelations()582 QList<Relation*> parentProxyRelations() const { return m_parentProxyRelations; } childProxyRelations()583 QList<Relation*> childProxyRelations() const { return m_childProxyRelations; } 584 585 /** 586 * Calculates and returns the duration of the node. 587 * Uses the correct expected-, optimistic- or pessimistic effort 588 * dependent on @p use. 589 * @param time Where to start calculation. 590 * @param use Calculate using expected-, optimistic- or pessimistic estimate. 591 * @param backward If true, time specifies when the task should end. 592 */ 593 Duration duration(const DateTime &time, int use, bool backward) override; 594 595 /** 596 * Return the duration calculated on bases of the estimates calendar 597 */ 598 Duration length(const DateTime &time, Duration duration, bool backward); 599 Duration length(const DateTime &time, Duration uration, Schedule *sch, bool backward); 600 601 /// Copy info from parent schedule 602 void copySchedule(); 603 /// Copy intervals from parent schedule 604 void copyAppointments(); 605 /// Copy intervals from parent schedule in the range @p start, @p end 606 /// All interval loads are scaled with @p factor 607 void copyAppointments(const DateTime &start, const DateTime &end = DateTime(), qreal factor = 1.0); 608 609 Q_SIGNALS: 610 void workPackageToBeAdded(KPlato::Node *node, int row); 611 void workPackageAdded(KPlato::Node *node); 612 void workPackageToBeRemoved(KPlato::Node *node, int row); 613 void workPackageRemoved(KPlato::Node *node); 614 615 public: 616 void initiateCalculation(MainSchedule &sch) override; 617 /** 618 * Sets up the lists used for calculation. 619 * This includes adding summarytasks relations to subtasks 620 * and lists for start- and endnodes. 621 */ 622 void initiateCalculationLists(MainSchedule &sch) override; 623 /** 624 * Calculates early start and early finish, first for all predeccessors, 625 * then for this task. 626 * @param use Calculate using expected-, optimistic- or pessimistic estimate. 627 */ 628 DateTime calculateForward(int use) override; 629 /** 630 * Calculates ref m_durationForward from ref earliestStart and 631 * returns the resulting end time (early finish), 632 * which will be used as the successors ref earliestStart. 633 * 634 * @param use Calculate using expected-, optimistic- or pessimistic estimate. 635 */ 636 DateTime calculateEarlyFinish(int use) override; 637 /** 638 * Calculates late start and late finish, first for all successors, 639 * then for this task. 640 * @param use Calculate using expected-, optimistic- or pessimistic estimate. 641 */ 642 DateTime calculateBackward(int use) override; 643 /** 644 * Calculates ref m_durationBackward from ref latestFinish and 645 * returns the resulting start time (late start), 646 * which will be used as the predecessors ref latestFinish. 647 * 648 * @param use Calculate using expected-, optimistic- or pessimistic estimate. 649 */ 650 DateTime calculateLateStart(int use) override; 651 /** 652 * Schedules the task within the limits of earliestStart and latestFinish. 653 * Calculates ref m_startTime, ref m_endTime and ref m_duration, 654 * Assumes ref calculateForward() and ref calculateBackward() has been run. 655 * 656 * @param earliest The task is not scheduled to start earlier than this 657 * @param use Calculate using expected-, optimistic- or pessimistic estimate. 658 * @return The tasks endtime which can be used for scheduling the successor. 659 */ 660 DateTime scheduleForward(const DateTime &earliest, int use) override; 661 /** 662 * Schedules the task within the limits of start time and latestFinish, 663 * Calculates end time and duration. 664 * Assumes ref calculateForward() and ref calculateBackward() has been run. 665 * 666 * @param use Calculate using expected-, optimistic- or pessimistic estimate. 667 * @return The tasks endtime which can be used for scheduling the successor. 668 */ 669 DateTime scheduleFromStartTime(int use) override; 670 /** 671 * Schedules the task within the limits of earliestStart and latestFinish. 672 * Calculates ref m_startTime, ref m_endTime and ref m_duration, 673 * Assumes ref calculateForward() and ref calculateBackward() has been run. 674 * 675 * @param latest The task is not scheduled to end later than this 676 * @param use Calculate using expected-, optimistic- or pessimistic estimate. 677 * @return The tasks starttime which can be used for scheduling the predeccessor. 678 */ 679 DateTime scheduleBackward(const DateTime &latest, int use) override; 680 /** 681 * Schedules the task within the limits of end time and latestFinish. 682 * Calculates endTime and duration. 683 * Assumes ref calculateForward() and ref calculateBackward() has been run. 684 * 685 * @param use Calculate using expected-, optimistic- or pessimistic estimate. 686 * @return The tasks starttime which can be used for scheduling the predeccessor. 687 */ 688 DateTime scheduleFromEndTime(int use) override; 689 690 /** 691 * Summarytasks (with milestones) need special treatment because 692 * milestones are always 'glued' to their predecessors. 693 */ 694 void adjustSummarytask() override; 695 696 /// Calculate the critical path 697 bool calcCriticalPath(bool fromEnd) override; 698 void calcFreeFloat() override; 699 700 // Proxy relations are relations to/from summarytasks. 701 // These relations are distributed to the child tasks before calculation. 702 void clearProxyRelations() override; 703 void addParentProxyRelations(const QList<Relation*> &) override; 704 void addChildProxyRelations(const QList<Relation*> &) override; 705 void addParentProxyRelation(Node *, const Relation *) override; 706 void addChildProxyRelation(Node *, const Relation *) override; 707 708 public: 709 DateTime earlyStartDate(); 710 void setEarlyStartDate(DateTime value); 711 712 DateTime earlyFinishDate(); 713 void setEarlyFinishDate(DateTime value); 714 715 DateTime lateStartDate(); 716 void setLateStartDate(DateTime value); 717 718 DateTime lateFinishDate(); 719 void setLateFinishDate(DateTime value); 720 721 int activitySlack(); 722 void setActivitySlack(int value); 723 724 int activityFreeMargin(); 725 void setActivityFreeMargin(int value); 726 727 protected: 728 /** 729 * Return the duration calculated on bases of the requested resources 730 */ 731 Duration calcDuration(const DateTime &time, Duration effort, bool backward); 732 733 private: 734 DateTime calculateSuccessors(const QList<Relation*> &list, int use); 735 DateTime calculatePredeccessors(const QList<Relation*> &list, int use); 736 DateTime scheduleSuccessors(const QList<Relation*> &list, int use); 737 DateTime schedulePredeccessors(const QList<Relation*> &list, int use); 738 739 /// Fixed duration: Returns @p dt 740 /// Duration with calendar: Returns first available after @p dt 741 /// Has working resource(s) allocated: Returns the earliest time a resource can start work after @p dt, and checks appointments if @p sch is not null. 742 DateTime workTimeAfter(const DateTime &dt, Schedule *sch = 0) const; 743 /// Fixed duration: Returns @p dt 744 /// Duration with calendar: Returns first available before @p dt 745 /// Has working resource(s) allocated: Returns the latest time a resource can finish work, and checks appointments if @p sch is not null. 746 DateTime workTimeBefore(const DateTime &dt, Schedule *sch = 0) const; 747 748 private: 749 QList<ResourceGroup*> m_resource; 750 751 QList<Relation*> m_parentProxyRelations; 752 QList<Relation*> m_childProxyRelations; 753 754 // This list store pointers to linked task 755 QList<Node*> m_requiredTasks; 756 757 WorkPackage m_workPackage; 758 QList<WorkPackage*> m_packageLog; 759 760 bool m_calculateForwardRun; 761 bool m_calculateBackwardRun; 762 bool m_scheduleForwardRun; 763 bool m_scheduleBackwardRun; 764 }; 765 766 } //KPlato namespace 767 768 Q_DECLARE_METATYPE(KPlato::Completion::UsedEffort::ActualEffort) 769 770 #ifndef QT_NO_DEBUG_STREAM 771 PLANKERNEL_EXPORT QDebug operator<<(QDebug dbg, const KPlato::Completion::UsedEffort::ActualEffort &ae); 772 #endif 773 774 #endif 775