home *** CD-ROM | disk | FTP | other *** search
- <?xml version="1.0" encoding="ISO-8859-1"?>
- <article id="paper-71">
- <articleinfo>
- <title>The TaskJuggler Project Management Software</title>
- <author>
- <firstname>Chris</firstname>
- <surname>Schlaeger</surname>
- </author>
- <copyright>
- <year>2003</year>
- <holder>Chris Schlaeger</holder>
- </copyright>
- </articleinfo>
-
- <section><title>Introduction</title>
-
- <para>TaskJuggler is a project planing tool for Linux and UNIX
- system-based operating systems. All tasks with their dependencies and
- other properties are edited by using a text editor. The file is then
- sent through TaskJuggler which in turn produces all sorts of reports in
- HTML or XML format. The HTML files can be viewed and printed with any
- web browser. The XML files are used by the Gantt- and PERT chart
- generators and the KDE Konqueror plug-in.</para>
-
- <para>Since TaskJuggler is not constrained by the performance requirements
- of real-time editing it can offer a much broader set of features not
- found in any of the WYSIWYG (What You See Is What You Get) project
- planing tools. The the project description language is easy to learn
- and supports the user very effectively during the planing and tracking
- process.</para>
-
- <para>TaskJuggler does not only honor the task interdependencies but
- also takes resource constrains and job prioritization into account.
- The multi-scenario support makes TaskJuggler a versatile tool for both
- what-if-analysis and plan/actual comparisons. Using TaskJuggler's
- powerful filtering and reporting algorithms the user can create a
- variety of task lists, resource usage tables, status reports, project
- calendars and project accounting statements.</para>
-
- </section>
- <section><title>Features and Highlights</title>
-
- <itemizedlist mark='opencircle'>
-
- <listitem><para>Automatic scheduling of interdependent tasks with resource
- conflict solver.</para></listitem>
-
- <listitem><para>Powerful project description syntax with macro
- support.</para></listitem>
-
- <listitem><para>Flexible working hours and vacation
- handling.</para></listitem>
-
- <listitem><para>Support for shifts.</para></listitem>
-
- <listitem><para>Multiple time zone support.</para></listitem>
-
- <listitem><para>Flexible resource grouping.</para></listitem>
-
- <listitem><para>Project accounting support.</para></listitem>
-
- <listitem><para>Task may have initial and finishing costs.</para></listitem>
-
- <listitem><para>Resource may have running costs.</para></listitem>
-
- <listitem><para>Support for profit and loss analysis.</para></listitem>
-
- <listitem><para>HTML and XML report generation.</para></listitem>
-
- <listitem><para>Gantt and PERT chart generators.</para></listitem>
-
- <listitem><para>Support for plan and actual scenario
- comparisons.</para></listitem>
-
- <listitem><para>Project tracking support.</para></listitem>
-
- <listitem><para>Groupware support by using a revision control system
- such as CVS or RCS on the project description files.</para></listitem>
-
- <listitem><para>Support for central resource allocation
- database.</para></listitem>
-
- <listitem><para>Support for cascaded and nested projects.</para></listitem>
-
- <listitem><para>Import and export of sub-projects.</para></listitem>
-
- <listitem><para>Unicode and localization support.</para></listitem>
-
- </itemizedlist>
-
- </section>
- <section><title>Basics</title>
-
- <para>TaskJuggler uses one or more text files to describe a project.
- The main project should be placed in a file with the
- <emphasis>.tjp</emphasis> extension. This main project may
- contain several sub-projects. Such sub-projects should be placed in
- files with the <emphasis>.tjsp</emphasis> extension. These
- sub-projects are included in the main project during compile
- time.</para>
-
- <para>TaskJuggler works like a compiler. The user provides the source
- files and TaskJuggler computes the contents and creates the output
- files.</para>
-
- <para>Let's say <filename>AcSo.tjp</filename> is a valid TaskJuggler
- project file. It contains the tasks of the project and their
- dependencies. To schedule the project and create report files the user
- calls TaskJuggler to process it.</para>
-
- <programlisting>
- % taskjuggler AcSo.tjp
- </programlisting>
-
- <para>TaskJuggler will try to schedule all tasks with the specified
- conditions and generate the reports that were requested with the
- <emphasis>htmltaskreport</emphasis>,
- <emphasis>htmlresourcereport</emphasis> or other report attributes in
- the input file.</para>
-
- </section>
- <section><title>The TaskJuggler Syntax</title>
-
- <para>To introduce the TaskJuggler syntax we create the project plan
- for a software development project. This example illustrates the
- basic features of TaskJuggler. The full source code of the example and
- the resulting reports can be found on the <ulink
- url="http://www.taskjuggler.org">TaskJuggler Web Site</ulink> at
- <ulink
- url="http://www.taskjuggler.org/example.php">http://www.taskjuggler.org/example.php</ulink>.</para>
-
- <para>A project is always started with the
- <emphasis>project</emphasis> property.</para>
-
- <programlisting>
- project acso "Accounting Software" "1.0" 2002-01-16 2002-04-26 {
- now 2002-03-04
- }
- </programlisting>
-
- <para>It tells TaskJuggler the default project ID, a short name for
- the project, a version number and a start and end date. The start and
- end dates don't need to be exact, but must enclose all tasks. It
- specifies the time interval the TaskJuggler scheduler will use to fit
- the tasks in.</para>
-
- <para>All TaskJuggler properties have a certain number of fixed
- attributes and a set of optional attributes. Optional attributes are
- always enclosed in curly braces. In this example we use the optional
- attributes <emphasis>now</emphasis> to set the current
- day for the scheduler to another value than to the moment the user
- invokes TaskJuggler. We pick a day during the above specified project
- period. So we always get the same results of a TaskJuggler run, no
- matter when we process our first project.</para>
-
- </section>
- <section><title>Global Attributes</title>
-
- <para>Besides finding suitable start and end dates for the tasks of
- the project, TaskJuggler can also do a simple profit and loss
- analysis. The user has to specify the default daily costs of an
- employee. This can be changed for specific employees later but it
- illustrates an important concept of TaskJuggler - inheritance of
- attributes. In order to reduce the size of the TaskJuggler project
- file to a still readable minimum, properties inherit many optional
- attributes from their enclosing scope. We'll see further down, what
- this actually means. Here we are at top-level scope, so this is the
- default for all following properties.</para>
-
- <programlisting>
- rate 310.0
- currency "EUR"
- </programlisting>
-
- <para>The <emphasis>rate</emphasis> attribute can be used to specify
- the daily costs of resources. The <emphasis>currency</emphasis>
- attribute specifies the currency to be used.</para>
-
- </section>
- <section><title>Macros</title>
-
- <para>Macros are another TaskJuggler feature to keep project files
- small. Macros are text patterns that can be defined once and inserted
- many times further down the project. A macro always has a name and the
- text pattern is enclosed by square brackets. </para>
-
- <programlisting>
- macro allocate_developers [
- allocate dev1
- allocate dev2 { load 0.5 }
- allocate dev3
- ]
- </programlisting>
-
- <para>To use the macro the user simply has to write <emphasis>
- ${allocate_developers} </emphasis> and TaskJuggler will replace
- the <emphasis>${allocate_developers}</emphasis> with the
- pattern. We will use the macro further down in the example and then
- explain the meaning of the pattern.</para>
-
- <para>Macros can also have parameters. Inside the macro they are
- referenced by their number.</para>
-
- <programlisting>
- macro foo [
- The first parameter is ${1}.
- And the second is ${2}.
- ]
- </programlisting>
-
- <para>Now the call</para>
-
- <programlisting>
- ${foo "bar1" "bar2"}
- </programlisting>
-
- <para>would be expanded to</para>
-
- <programlisting>
- The first parameter is bar1.
- And the second is bar2.
- </programlisting>
-
- </section>
- <section><title>Using flags</title>
-
- <para>A TaskJuggler feature that the user will probably make heavy use of
- is <emphasis>flags</emphasis>. Once declared the user can attach
- them to many properties. When generating reports of the TaskJuggler
- results, the user can use the flags to filter out information and limit the
- report to exactly those details that should be included.</para>
-
- <programlisting>
- flags team
- </programlisting>
-
- <para>Flags must be declared at global scope before they can be
- attached to other properties.</para>
-
- </section>
- <section><title>Declaring Resources</title>
-
- <programlisting>
- resource dev "Developers" {
- resource dev1 "Paul Smith" { rate 330.0 }
- resource dev2 "S饕astien Bono"
- resource dev3 "Klaus Mller" { vacation 2002-02-01 - 2002-02-05 }
-
- flags team
- }
- resource misc "The Others" {
- resource test "Peter Murphy" { maxeffort 0.8 rate 240.0 }
- resource doc "Dim Sung" { rate 280.0 }
-
- flags team
- }
- </programlisting>
-
- <para>This snippet of the example shows the <emphasis>
- resource </emphasis> property. Resources always have an ID and a Name. IDs
- may only consist of ASCII characters, numbers and the underline
- character. All global TaskJuggler properties have IDs. They need to be
- unique within their property class. The ID is needed so that we can
- reference the property again later without having the need to write
- the potentially much longer name. Names are strings and as such
- enclosed in double quotes. Strings may contain any character, even
- non-ASCII characters. As seen above, resource properties can be
- nested. <emphasis>dev</emphasis> is a virtual resource,
- a team, that consists of three other resources.</para>
-
- <para><emphasis>dev1</emphasis>, alias Paul Smith earns
- more than the normal employee. So the declaration of <emphasis>
- dev1</emphasis> overwrites the inherited default rate with a
- new value of 330.0. The default value has been inherited from the
- enclosing scope, resource <emphasis>dev</emphasis>.
- Which in turn has inherited it from the global scope. </para>
-
- <para>The declaration of the resource Klaus Mueller uses another
- optional attribute. With <emphasis>vacation</emphasis> the user can
- specify a certain time interval where the resource is not
- available.</para>
-
- </section>
- <section><title>Time and Date Specifications</title>
-
- <para>It is important to understand how TaskJuggler handles time
- intervals. Internally TaskJuggler uses the number of seconds after
- January 1st, 1970 to store any date. So all dates are actually stored
- with an accuracy of 1 second. <emphasis>2002-02-01</emphasis>
- specifies midnight February 1st, 2002. Again following the TaskJuggler
- concept of needing as little info as necessary and extending the rest
- with sensible defaults, TaskJuggler adds the time 0:00:00 if nothing
- else has been specified. So the vacation ends on midnight February
- 5th, 2002. Well, almost. Every time the user specifies a time
- interval, the end date is not included in the interval. But the second
- before the date that has been specified is still part of the interval.
- So Klaus Mueller's vacation ends 23:59:59 on February 4th,
- 2002.</para>
-
- <para>Peter Murphy only works 6.5 hours a day (actually 6.4 hours). So
- we use the <emphasis>maxeffort</emphasis> attribute to limit his daily
- working hours. We could also define exact working hours using the
- <emphasis>shift</emphasis> property, but we ignore this for now.
- <emphasis>shift</emphasis> enables the user to specify the exact
- working hours for each day of the week.</para>
-
- <para>Note that we have attached the flag <emphasis>team</emphasis>
- after the declaration of the sub-resources to the team resources. This
- way, they flags don't get inherited by the sub-resources. If we would
- have declared the flags before the sub-resources, then they would have
- the flags attached as well.</para>
-
- </section>
- <section><title>Declaring Accounts</title>
-
- <para>The use of our resources will create costs. For a profit and
- loss analysis, we need to balance the costs against the customer
- payments. So that we don't get lost with all the amounts, we declare 3
- accounts to credit the amounts to. We create one account for the
- development costs, one for the documentation costs and one for the
- customer payments.</para>
-
- <programlisting>
- account dev "Development" cost
- account doc "Dokumentation" cost
- account rev "Payments" revenue
- </programlisting>
-
- <para>The <emphasis>account</emphasis> property has 3
- fixed attributes, an ID, a name and a type. The type can either be
- <emphasis>cost</emphasis> or <emphasis>revenue</emphasis>. For the
- analysis TaskJuggler subtracts the total amount of all cost accounts
- from the total amount of all revenue accounts.</para>
-
- </section>
- <section><title>Specifying Tasks</title>
-
- <para>Let's focus on the real work now. The project should solve a
- problem - the creation of an accounting software. Since the job is
- quite complicated we break it down into several sub tasks. We need to
- do a specification, develop the software, test the software and write
- a manual. In TaskJuggler syntax this would look like that:</para>
-
- <programlisting>
- task AcSo "Accounting Software" {
- task spec "Specification"
- task software "Software Development"
- task test "Software testing"
- task deliveries "Milestones"
- }
- </programlisting>
-
- <para>Just like resources, tasks are declared by using the
- <emphasis>task</emphasis> keyword followed by an ID and a name
- string. All TaskJuggler properties have their own namespaces. This
- means, that it is quite OK to have a resource and a task with the same
- ID. Tasks may have optional attributes which can be tasks again, so
- tasks can be nested. In contrast to all other TaskJuggler properties,
- task IDs inherit the ID of their enclosing task as a prefix to the ID.
- The full ID of the <emphasis>spec</emphasis> task is
- <emphasis>AcSo.spec</emphasis>.TaskJuggler uses dots to concatenate the
- IDs of hierarchical tasks to absolute IDs.</para>
-
- <para>To track important milestones of the project, we also added a
- task called Milestones. This task, like most of the other task will
- get some sub tasks later on. We consider the specification task simple
- enough that we don't have to break it into further sub tasks. So let's
- add some more details to it.</para>
-
- </section>
- <section><title>Task Durations</title>
-
- <programlisting>
- task spec "Specification" {
- effort 20d
- ${allocate_developers}
- depends !deliveries.start
- }
- </programlisting>
-
- <para>The effort to complete the task is specified with 20 man days.
- Alternatively we could have used the <emphasis>length</emphasis>
- attribute or the <emphasis>duration</emphasis> attribute.
- <emphasis>length</emphasis> specifies the duration of the task in
- working days while <emphasis>duration</emphasis> specifies the
- duration in calendar days. Contrary to <emphasis>effort</emphasis>
- these two don't require to have a specification of the involved
- resources. If resources are specified they are allocated when
- available but they do not affect the total duration of the
- task.</para>
-
- </section>
- <section><title>Allocating Resources</title>
-
- <para>Since <emphasis>effort</emphasis> specifies the duration in man
- days, we need to say who should be allocated to the task. The task
- won't finish before the resources could be allocated long enough to
- reach the specified effort.</para>
-
- <para>Here we use the above mentioned macro
- <emphasis>allocate_developers</emphasis>. The
- expression</para>
-
- <programlisting>
- ${allocate_developers}
- </programlisting>
-
- <para>is simply expanded to</para>
-
- <programlisting>
- allocate dev1
- allocate dev2 { load 0.5 }
- allocate dev3
- </programlisting>
-
- <para>If it is necessary to allocate the same bunch of people to
- several task, the macro saves some writing. One could have written the
- <emphasis>allocate</emphasis> attributes directly instead of using the
- macro. Since the allocation of multiple resources to a task is a very
- common place for macro usage, we found it a good idea to use it in
- this example as well.</para>
-
- <para>One more interesting thing to note is the fact that we like
- the resource <emphasis>dev2</emphasis> only to work 50% of
- the day on this task, so we use the optional attribute
- <emphasis>load</emphasis> to specify this.</para>
-
- <para>For TaskJuggler to schedule a task it needs to know either the
- start and end criteria of a task, or one of them and a duration
- specification. The start and end criteria can either be fixed dates or
- relative dates. Relative dates are specification of the type "task B
- starts after task A has finished". Or in other words, task B depends
- on task A. In this example the <emphasis>spec</emphasis> task depends
- on a sub tasks of the <emphasis>deliveries</emphasis> tasks. We
- haven't specified it yet, but it has the local ID
- <emphasis>start</emphasis>.</para>
-
- </section>
- <section><title>Task Dependencies</title>
-
- <para>To specify the dependency between the two task we use the
- <emphasis>depends</emphasis> attribute. The attribute must be
- followed by one or more task IDs. If more than one ID is specified,
- each ID has to be separated with a comma from the previous one. Task
- IDs can be either absolute IDs or relative IDs. An absolute ID of a
- task is the ID of this task prepended by the IDs of all enclosing
- tasks. The task IDs are separated by a dot from each other. The
- absolute ID of the specification task would be
- <emphasis>AcSo.spec</emphasis>.</para>
-
- <para>Relative IDs always start with one or more exclamation marks.
- Each exclamation mark moves the scope to the next enclosing task. So
- <emphasis>!deliveries.start</emphasis> is expanded to
- <emphasis>AcSo.deliveries.start</emphasis> since
- <emphasis>AcSo</emphasis> is the enclosing task of
- <emphasis>deliveries</emphasis>. Relative task IDs are a little bit
- confusing at first, but have a real advantage over absolute IDs.
- Sooner or later the user wants to move tasks around in the project
- and then it's a lot less likely that one has to fix dependency
- specifications of relative IDs.</para>
-
- <para>The software development task is still too complex to specify it
- directly. So we split it into sub tasks again.</para>
-
- </section>
- <section><title>Task Priorities</title>
-
- <programlisting>
- task software "Software Development" {
- priority 1000
- task database "Database coupling"
- task gui "Graphical User Interface"
- task backend "Back-End Functions"
- }
- </programlisting>
-
- <para>We use the <emphasis>priority</emphasis>
- attribute to mark the importance of the tasks. By default all tasks
- have a priority of 500 unless the parent tasks specifies it
- differently. Setting the priority to 1000 marks the task as most
- important task, since the possible range is 1 (not important at all)
- to 1000 (ultimately important). <emphasis>priority</emphasis> is an
- attribute that is inherited to sub tasks if specified before the sub
- tasks declaration. So all sub tasks of <emphasis>software</emphasis>
- have a priority of 1000 as well.</para>
-
- <programlisting>
- task database "Database coupling" {
- effort 20d
- depends !!spec
- allocate dev1
- allocate dev2
- }
- </programlisting>
-
- <para>The work on the database coupling should not start before the
- specification has been finished. So we use again the
- <emphasis>depends</emphasis> attribute to let TaskJuggler
- know about this. This time we use two exclamation marks for the
- relative ID. The first one puts us in the scope of the enclosing
- <emphasis>software</emphasis> task. The second one is to
- get into the <emphasis>AcSo</emphasis> scope that contains
- the <emphasis>spec</emphasis> tasks. This time we allocate
- resources directly without using a macro.</para>
-
- </section>
- <section><title>Comparing multiple Project Scenarios</title>
-
- <programlisting>
- task gui "Graphical User Interface" {
- effort 35d
- actualeffort 40d
- depends !database, !backend
- allocate dev2
- allocate dev3
- }
- </programlisting>
-
- <para>TaskJuggler can schedule the project for two different
- scenarios. The first scenario is called the plan scenario. The other
- is referred to as the actual scenario. Many of the reports allow
- to put the values of both scenarios side by side to each other, so one
- can compare the two scenarios. The two scenarios must have the same
- task structure and the same dependencies. But the start and end dates
- of tasks as well as the duration and the resulting resource allocation
- may vary. In the example we have planed the work on the graphical user
- interface to be 35 man days. It turned out that we actually needed 40
- man days. The <emphasis>actualeffort</emphasis> attribute can be used
- to specify this.</para>
-
- </section>
- <section><title>Tracking the Project Status</title>
-
- <programlisting>
- task backend "Back-End Functions" {
- effort 30d
- complete 95
- depends !database, !!spec
- allocate dev1
- allocate dev2
- }
- </programlisting>
-
- <para>By default TaskJuggler assumes that all tasks are on schedule.
- Sometimes the user wants to generate reports, that show how much of a
- task has actually been completed. TaskJuggler uses the current date
- for this unless another date has been specified by using the
- <emphasis>now</emphasis> attribute. If a task is ahead of schedule or
- late this can be specified using the <emphasis>complete</emphasis>
- attribute. It specifies how many percent of the task have been
- completed up to the current date. In our case the back-end
- implementation is slightly ahead of schedule as we will see from the
- report.</para>
-
- </section>
- <section><title>Specifying Efforts</title>
-
- <programlisting>
- task test "Software testing" {
-
- task alpha "Alpha Test" {
- effort 1w
- depends !!software
- allocate test
- allocate dev2
- }
-
- task beta "Beta Test" {
- effort 4w
- depends !alpha
- allocate test
- allocate dev1
- }
- }
- </programlisting>
-
- <para>The software testing task has been split up into an alpha and a
- beta test task. The interesting thing here is, that efforts can not
- only be specified as man days, but also man weeks, man hours, etc. Per
- default TaskJuggler assumes a man week is 40 man hours or 5 man days.
- These values can be changed using the
- <emphasis>dailyworkinghours</emphasis>
- attribute.</para>
-
- </section>
- <section><title>Crediting costs to Accounts</title>
-
- <para>Let's go back to the outermost task again. At the beginning of
- the example we stated that we want to credit all development work to
- one account with ID <emphasis>dev</emphasis> and all documentation
- work to the account <emphasis>doc</emphasis>. To achieve this, we use
- the attribute account to credit all tasks to the
- <emphasis>dev</emphasis> account.</para>
-
- <programlisting>
- task AcSo "Accounting Software" {
-
- account dev
-
- task software "Software Development" {
- </programlisting>
-
- <para>Since we specify the attribute for the top-level task before we
- declare any sub tasks, this attribute will be inherited by all sub
- tasks and their sub tasks and so on. Since the only exception is the
- writing of the manual, we need to change the account for this task
- again since it is also a sub task of
- <emphasis>AcSo</emphasis>.</para>
-
- <programlisting>
- task manual "Manual" {
- effort 10w
- depends !deliveries.start
- allocate doc
- allocate dev3
- account doc
- }
- </programlisting>
-
- </section>
- <section><title>Specifying Milestones</title>
-
- <para>All task that have been discussed so far, had a certain duration. We
- did not always specify the duration explicitly, but we expect them to
- last for a certain period of time. Sometimes the user just wants to capture
- a certain moment in the project plan. These moments are usually
- called milestones since they have some level of importance for the
- progress of the project.</para>
-
- <para>TaskJuggler has support for milestones as well. They are handled
- as special types of tasks. By using the optional attribute
- <emphasis>milestone</emphasis> for a task, this task
- is declared a milestone. Milestones have no duration, so it's illegal
- to specify any duration criteria, or a non identical start and end
- date.</para>
-
- <programlisting>
- task deliveries "Milestones" {
-
- account rev
-
- task start "Project start" {
- milestone
- start 2002-01-16
- actualstart 2002-01-20
- startcredit 33000.0
- }
-
- task prev "Technology Preview" {
- milestone
- depends !!software.backend
- startcredit 13000.0
- }
-
- task beta "Beta version" {
- milestone
- depends !!test.alpha
- startcredit 13000.0
- }
-
- task done "Ship Product to customer" {
- milestone
- # maxend 2002-04-17
- depends !!test.beta, !!manual
- startcredit 14000.0
- }
- }
- }
- </programlisting>
-
- <para>We have put all important milestones of the project as sub tasks
- of the <emphasis>deliveries</emphasis> task. This way they
- show up nicely grouped in the reports. All milestone have either a
- dependency or a fixed start date. For the first milestone we have used
- the attribute <emphasis>start</emphasis> to set a fixed
- start date. All other tasks have direct or indirect dependencies on
- this task. Moving back the start date will slip the whole project.
- This has actually happened, so we use the
- <emphasis>actualstart</emphasis> attribute to specify the
- real start of the project 4 days later.</para>
-
- <para>Every milestone is linked to a customer payment. By using the
- <emphasis>startcredit</emphasis> attribute we can
- credit the specified amount to the account associated with this task.
- Since we have assigned the <emphasis>rev</emphasis>
- account to the enclosing task, all milestones will use this account as
- well.</para>
-
- <para>The line within the definition of the task
- <emphasis>done</emphasis> that starts with a hash is a comment.
- If TaskJuggler finds a hash it ignores the rest
- of the line. This way the user can include comments in the project.
- The <emphasis>maxend</emphasis> attribute specifies that the
- task should end no later than the specified date. This information is
- not used for scheduling but only for checking the schedule afterwards.
- Since the task will end later than the specified date, commenting out
- the line would trigger a warning.</para>
-
- <para>Now the project has been completely specified. Stopping here would
- result in a valid TaskJuggler file that could be processed and
- scheduled. But no reports would be generated to visualize the
- results.</para>
-
- </section>
- <section><title>Generating Reports of the scheduled Project</title>
-
- <para>TaskJuggler offers a number of report types. Probably the most
- popular ones are the HTML reports. The user can advice TaskJuggler to
- generate one or more HTML pages that contain lists of tasks,
- resources or accounts.</para>
-
- <para>Before we start with the reports, we present another macro.
- We like to add a navigation bar to each HTML page that holds a number
- of buttons. Each button changes the page to another report. This way
- we can create a navigation bar that holds links to all reports. Since
- we have created a macro, we can add the navigation bar to all reports
- without much hassle. The navigation bar is constructed with HTML tags.
- If the user is not familiar with HTML this will look very strange but
- it is a cool feature we would like to demonstrate. Certainly the user
- can use TaskJuggler to it's full extend without having to learn HTML
- code.</para>
-
- <para>The HTML code is injected into the reports using the
- <emphasis>rawhead</emphasis> attribute. This will
- put the HTML code close to the top of the HTML page right after the
- body started. As can be seen here, string parameters of attributes can
- be enclosed in single quotes as well. This is handy, if the string
- itself needs to contain double quotes.</para>
-
- <programlisting>
- macro navbar [
- rawhead
- '<p><center>
- <table border="2" cellpadding="10">
- <tr>
- <td class="default" style="font-size:120%" rowspan="2">
- <a href="Tasks-Overview.html">Tasks Overview</td>
- <td class="default" style="font-size:120%" rowspan="2">
- <a href="Tasks-Details.html">Tasks Details</td>
- <td class="default" style="font-size:120%" rowspan="2">
- <a href="Staff-Overview.html">Staff Overview</td>
- <td class="default" style="font-size:120%" rowspan="2">
- <a href="Staff-Details.html">Staff Details</td>
- <td class="default" style="font-size:120%" rowspan="2">
- <a href="Accounting.html">Accounting</td>
- <td class="default" style="font-size:120%" rowspan="2">
- <a href="acso.eps">GANTT Chart (Postscript)</td>
- </tr>
- </table>
- </center></p><br>'
- ]
- </programlisting>
-
- </section>
- <section><title>Generating HTML Task Reports</title>
-
- <para>As the first report, we would like to have a general overview of all
- tasks with their computed start and end dates. For better
- readability we include a calendar like column that lists the effort
- for each week. The report shell consists mainly of a listing of the
- tasks in a table form. The property
- <emphasis>htmltaskreport</emphasis> generates exactly this,
- a list of all tasks in a table. The columns are flexible and
- can be specified with the
- <emphasis>column</emphasis> attribute. For this
- report we like to see the number, the name, the start and end
- date, a weekly calendar and the total effort in the table.</para>
-
- <programlisting>
- htmltaskreport "Tasks-Overview.html" {
- ${navbar}
- columns no, name, start, end, weekly, effort
- headline "Accounting Software Project"
- caption "This table shows the load for each task on a weekly basis.
- All values are man-days."
- }
- </programlisting>
-
- <para>With the <emphasis>headline</emphasis>
- attribute we can specify a headline for the report. To have a little
- more info included as well, we use the
- <emphasis>caption</emphasis> attribute. Both of
- these attributes are followed by the string to be included into the
- report.</para>
-
- <para>
- Now we like to generate a report that contains a lot more details
- about the task. The weekly calendar is replaced by a daily calendar.
- The weekly calendar had a column for each week. The daily calendar
- features a column for each day. The column includes the load for the
- task for the week or day and a colored background in case the task is
- active that day or week.</para>
-
- <programlisting>
- htmltaskreport "Tasks-Details.html" {
- ${navbar}
- columns no, name, start, end, daily
- headline "Accounting Software Project"
- caption "This table shows the load of each day for all the tasks.
- Additionally the resources used for each task are listed. Since the
- project start was delayed, the actual schedule differs significantly
- from the original plan."
- hideresource 0
- showactual
- }
- </programlisting>
-
- <para>We also like to list all assigned resources right after each
- task. Normally resources are hidden in task reports but they can be
- enabled by using the
- <emphasis>hideresource</emphasis> attribute.
- The attribute is followed by a logical expression that specifies what
- resources to hide. The expression is evaluated for each resource and
- if the result is true (not 0) than the resource is hidden. Since we
- want to show all resources we put a 0 in, so it's false for all
- resources.</para>
-
- <para>To add even more information to this report, we also turn on the
- reporting of values of the actual scenario by using the
- <emphasis>showactual</emphasis> attribute. This
- causes TaskJuggler to split the lines of the report into two where
- appropriate and report the actual value underneath the plan
- value.</para>
-
- </section>
- <section><title>Generating HTML Resource Reports</title>
-
- <para> The previous report listed the resources per task. Now we want
- to generate a report the lists all resources. It's again a report with
- a weekly calendar. This time we use the attribute
- <emphasis>loadunit</emphasis> to report the load
- in hours instead of days.</para>
-
- <programlisting>
- htmlresourcereport "Staff-Overview.html" {
- ${navbar}
- columns no, name, weekly, effort
- showactual
- loadunit hours
- headline "Weekly working hours for the Accounting Software Project"
- }
- </programlisting>
-
- <para> Now a similar report but with much more details. We want to
- include that tasks again, this time each resource should be followed
- by the tasks the resource is assigned to. In
- <emphasis>htmltaskreports</emphasis> resources are hidden
- by default while in
- <emphasis>htmlresourcereports</emphasis> tasks are
- hidden by default. To include tasks the attribute
- <emphasis>hidetask</emphasis> needs to be used. It
- is followed by a logical expression just like
- <emphasis>hideresource</emphasis>.</para>
-
- <programlisting>
- htmlresourcereport "Staff-Details.html" {
- ${navbar}
- columns name, daily, effort
- showactual
- hidetask 0
- hideresource team
- sortresources nameup
- loadunit hours
- headline "Daily working hours for the Accounting Software Project"
- }
- </programlisting>
-
- <para>When specifying the resources we have grouped the resources into
- two teams by creating two pseudo resources that had the real employees
- as sub resources. We have attached the flag
- <emphasis>team</emphasis> to those pseudo resources. We
- now use this flag as logical expression for
- <emphasis>hideresource</emphasis>. So all
- resources that have this flag will be hidden in the report. For better
- readability we sort the resource list by name in ascending order. The
- attribute
- <emphasis>sortresources</emphasis> is taking
- care of this.</para>
-
- </section>
- <section><title>Generating HTML Account Reports</title>
-
- <para> To conclude the HTML reports a report that shows how badly the
- project is calculated is generated. The company won't get rich with this
- project. Due to the slip, it actually needs some money from the bank
- to pay the salaries. </para>
-
- <programlisting>
- htmlaccountreport "Accounting.html" {
- ${navbar} columns no, name, total, monthly
- headline "P&L for the Accounting Software Project"
- caption "The table shows the profit and loss analysis as well as the
- cashflow situation of the Accounting Software Project."
- accumulate
- showactual
- }
- </programlisting>
-
- <para>The <emphasis>htmlaccountreport</emphasis>
- property produces similar reports as the above ones, but it lists
- accounts instead of tasks or resources. The
- <emphasis>total</emphasis> column shows the value of the
- account at the end of the reported time interval. The
- <emphasis>accumulate</emphasis> attribute
- puts the calendar in accumulation mode. The monthly columns list the
- value of the account at the end of the month. Normally the amount that
- has been added or subtracted from the account would be listed.</para>
-
- </section>
- <section><title>Generating XML Reports</title>
-
- <para> Finally we generate an XML report that contains all info about
- the scheduled project. This report will be used by tjx2gantt to create
- a nice GANTT chart of our project. The file can also be read by tools
- like tjGUI or the KDE Konqueror plug-in. </para>
-
- <programlisting>
- xmlreport "AccountingSoftware.tjx"
- </programlisting>
-
- </section>
- <section><title>Conclusion</title>
-
- <para>TaskJuggler is a substantially different approach to project
- planing and tracking tools. The powerful textual project description
- language allows the user to efficiently capture the properties of the
- project. Since the scheduler it is not hampered by the performance
- requirements of GUI based tools it offers many important features not
- found in GUI tools. For future versions we plan an optimizer that can
- find best results even with complex tasks and skill-based resource
- selections.</para>
-
- </section>
- </article>
-