/* This file is part of the KDE project Copyright (C) 2001 Thomas Zander zander@kde.org Copyright (C) 2004 Dag Andersen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KPTTASK_H #define KPTTASK_H #include "kptnode.h" #include "kptduration.h" #include "kptresource.h" #include namespace KPlato { class DateTime; /** * A task in the scheduling software is represented by this class. A task * can be anything from 'build house' to 'drill hole' It will always mean * an activity. */ class Task : public Node { public: Task(Node *parent = 0); Task(Task &task, Node *parent = 0); ~Task(); /// Return task type. Can be Type_Task, Type_Summarytask ot Type_Milestone. virtual int type() const; /** * Returns the (previously) calculated duration. * The caller must delete returned object. */ Duration *getExpectedDuration(); /** * Instead of using the expected duration, generate a random value using * the Distribution of each Task. This can be used for Monte-Carlo * estimation of Project duration. */ Duration *getRandomDuration(); /** * Return the resource request made to group * (There should be only one) */ ResourceGroupRequest *resourceGroupRequest(ResourceGroup *group) const; void clearResourceRequests(); void addRequest(ResourceGroup *group, int numResources); void addRequest(ResourceGroupRequest *request); void takeRequest(ResourceGroupRequest *request); int units() const; int workUnits() const; void makeAppointments(); /** * Calculates if the assigned resource is overbooked * within the duration of this task */ void calcResourceOverbooked(); void setConstraint(Node::ConstraintType type); /// Load from document virtual bool load(TQDomElement &element, Project &project); /// Save to document virtual void save(TQDomElement &element) const; /// Save appointments for schedule with id virtual void saveAppointments(TQDomElement &element, long id) const; /** * Returns a list of planned effort and cost for this task * for the interval start, end inclusive */ virtual EffortCostMap plannedEffortCostPrDay(const TQDate &start, const TQDate &end) const; /// Returns the total planned effort for this task (or subtasks) virtual Duration plannedEffort(); /// Returns the total planned effort for this task (or subtasks) on date virtual Duration plannedEffort(const TQDate &date); /// Returns the planned effort up to and including date virtual Duration plannedEffortTo(const TQDate &date); /// Returns the total actual effort for this task (or subtasks) virtual Duration actualEffort(); /// Returns the total actual effort for this task (or subtasks) on date virtual Duration actualEffort(const TQDate &date); /// Returns the actual effort up to and including date virtual Duration actualEffortTo(const TQDate &date); /** * Returns the total planned cost for this task (or subtasks) */ virtual double plannedCost(); /// Planned cost on date virtual double plannedCost(const TQDate &/*date*/); /// Planned cost up to and including date virtual double plannedCostTo(const TQDate &/*date*/); /** * Returns the actaually reported cost for this task (or subtasks) */ virtual double actualCost(); /// Actual cost on date virtual double actualCost(const TQDate &/*date*/); /// Actual cost up to and including date virtual double actualCostTo(const TQDate &/*date*/); /// Effort based performance index double effortPerformanceIndex(const TQDate &date, bool *error=0); /// Cost performance index double costPerformanceIndex(const TQDate &date, bool *error=0); void initiateCalculation(Schedule &sch); /** * Sets up the lists used for calculation. * This includes adding summarytasks relations to subtasks * and lists for start- and endnodes. */ void initiateCalculationLists(TQPtrList &startnodes, TQPtrList &endnodes, TQPtrList &summarytasks); /** * Calculates ref m_durationForward from ref earliestStart and * returns the resulting end time, * which will be used as the succesors ref earliestStart. * * @param use Calculate using expected-, optimistic- or pessimistic estimate. */ DateTime calculateForward(int use); /** * Calculates ref m_durationBackward from ref latestFinish and * returns the resulting start time, * which will be used as the predecessors ref latestFinish. * * @param use Calculate using expected-, optimistic- or pessimistic estimate. */ DateTime calculateBackward(int use); /** * Schedules the task within the limits of earliestStart and latestFinish. * Calculates ref m_startTime, ref m_endTime and ref m_duration, * Assumes ref calculateForward() and ref calculateBackward() has been run. * * @param earliest The task is not scheduled to start earlier than this * @param use Calculate using expected-, optimistic- or pessimistic estimate. * @return The tasks endtime which can be used for scheduling the successor. */ DateTime scheduleForward(const DateTime &earliest, int use); /** * Schedules the task within the limits of earliestStart and latestFinish. * Calculates ref m_startTime, ref m_endTime and ref m_duration, * Assumes ref calculateForward() and ref calculateBackward() has been run. * * @param latest The task is not scheduled to end later than this * @param use Calculate using expected-, optimistic- or pessimistic estimate. * @return The tasks starttime which can be used for scheduling the predeccessor. */ DateTime scheduleBackward(const DateTime &latest, int use); /** * Summarytasks (with milestones) need special treatment because * milestones are always 'glued' to their predecessors. */ void adjustSummarytask(); /** * Return the duration calculated on bases of the requested resources */ Duration calcDuration(const DateTime &time, const Duration &effort, bool backward); // Proxy relations are relations to/from summarytasks. // These relations are distrubuted to the relevant tasks before calculation. void clearProxyRelations(); void addParentProxyRelations(TQPtrList &list); void addChildProxyRelations(TQPtrList &list); void addParentProxyRelation(Node *node, const Relation *rel); void addChildProxyRelation(Node *node, const Relation *rel); /// Check if this node has any dependent child nodes. bool isEndNode() const; /// Check if this node has any dependent parent nodes bool isStartNode() const; /** * Return the time when work can actually start on this task. * This will be the time assigned resources can start work in accordance * with their calendar, or if no resources have been assigned, * the scheduled starttime is used. */ virtual DateTime workStartTime() const; /** * Return the time when work can actually finish on this task. * This will be the time assigned resources can end work in accordance * with their calendar, or if no resources have been assigned, * the scheduled endtime is used. */ virtual DateTime workEndTime() const; /** * Return the duration that an activity's start can be delayed * without affecting the project completion date. * An activity with positive float is not on the critical path. */ Duration positiveFloat(); /** * Return the duration by which the duration of an activity or path * has to be reduced in order to fullfill a timing constraint. */ Duration negativeFloat() { return Duration(); } /** * Return the duration by which an activity can be delayed or extended * without affecting the start of any succeeding activity. */ Duration freeFloat() { return Duration(); } /** * Return the duration from Early Start to Late Start. */ Duration startFloat() { return Duration(); } /** * Return the duration the task has at its finish before a successor task starts. * This is the difference between the start time of the successor and * the finish time of this task. */ Duration finishFloat() { return Duration(); } /// A task is critical if there is no positive float virtual bool isCritical(); /// Calculate critical path virtual bool calcCriticalPath(bool fromEnd); /// Set current schedule to schedule with identity id, for me nd my children virtual void setCurrentSchedule(long id); virtual bool effortMetError() const; struct Progress { Progress() { started = finished = false; percentFinished = 0; } bool operator==(struct Progress &p) { return started == p.started && finished == p.finished && startTime == p.startTime && finishTime == p.finishTime && percentFinished == p.percentFinished && remainingEffort == p.remainingEffort && totalPerformed == p.totalPerformed; } bool operator!=(struct Progress &p) { return !(*this == p); } struct Progress &operator=(struct Progress &p) { started = p.started; finished = p.finished; startTime = p.startTime; finishTime = p.finishTime; percentFinished = p.percentFinished; remainingEffort = p.remainingEffort; totalPerformed = p.totalPerformed; return *this; } bool started, finished; DateTime startTime, finishTime; int percentFinished; Duration remainingEffort; Duration totalPerformed; }; struct Progress &progress() { return m_progress; } private: DateTime calculateSuccessors(const TQPtrList &list, int use); DateTime calculatePredeccessors(const TQPtrList &list, int use); DateTime scheduleSuccessors(const TQPtrList &list, int use); DateTime schedulePredeccessors(const TQPtrList &list, int use); DateTime workStartAfter(const DateTime &dt); DateTime workFinishBefore(const DateTime &dt); private: TQPtrList m_resource; ResourceRequestCollection *m_requests; TQPtrList m_parentProxyRelations; TQPtrList m_childProxyRelations; struct Progress m_progress; #ifndef NDEBUG public: void printDebug(bool children, TQCString indent); #endif }; } //KPlato namespace #endif