You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kplato/kpttask.h

307 lines
11 KiB

/* This file is part of the KDE project
Copyright (C) 2001 Thomas Zander zander@kde.org
Copyright (C) 2004 Dag Andersen <danders@get2net.dk>
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 <qptrlist.h>
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(QDomElement &element, Project &project);
/// Save to document
virtual void save(QDomElement &element) const;
/// Save appointments for schedule with id
virtual void saveAppointments(QDomElement &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 QDate &start, const QDate &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 QDate &date);
/// Returns the planned effort up to and including date
virtual Duration plannedEffortTo(const QDate &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 QDate &date);
/// Returns the actual effort up to and including date
virtual Duration actualEffortTo(const QDate &date);
/**
* Returns the total planned cost for this task (or subtasks)
*/
virtual double plannedCost();
/// Planned cost on date
virtual double plannedCost(const QDate &/*date*/);
/// Planned cost up to and including date
virtual double plannedCostTo(const QDate &/*date*/);
/**
* Returns the actaually reported cost for this task (or subtasks)
*/
virtual double actualCost();
/// Actual cost on date
virtual double actualCost(const QDate &/*date*/);
/// Actual cost up to and including date
virtual double actualCostTo(const QDate &/*date*/);
/// Effort based performance index
double effortPerformanceIndex(const QDate &date, bool *error=0);
/// Cost performance index
double costPerformanceIndex(const QDate &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(QPtrList<Node> &startnodes, QPtrList<Node> &endnodes, QPtrList<Node> &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(QPtrList<Relation> &list);
void addChildProxyRelations(QPtrList<Relation> &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 QPtrList<Relation> &list, int use);
DateTime calculatePredeccessors(const QPtrList<Relation> &list, int use);
DateTime scheduleSuccessors(const QPtrList<Relation> &list, int use);
DateTime schedulePredeccessors(const QPtrList<Relation> &list, int use);
DateTime workStartAfter(const DateTime &dt);
DateTime workFinishBefore(const DateTime &dt);
private:
QPtrList<ResourceGroup> m_resource;
ResourceRequestCollection *m_requests;
QPtrList<Relation> m_parentProxyRelations;
QPtrList<Relation> m_childProxyRelations;
struct Progress m_progress;
#ifndef NDEBUG
public:
void printDebug(bool children, QCString indent);
#endif
};
} //KPlato namespace
#endif