# Tutorial: Your First Project

We have mentioned already that TaskJuggler uses plain text files that describe the project to schedule it. As you will see now, the syntax of the file is easy to understand and very intuitive. This chapter will walk you step by step through your first project. You create the project plan for a made-up accounting software project. Refer to for a full listing of the example. This project demonstrates some of the basic features of TaskJuggler for more advanced features please refer to .

## Starting the project

To start a TaskJuggler project file you need to use the project property.

    project acso "Accounting Software" "1.0" 2002-01-16 2002-04-26 {
      now 2002-03-04
      timeformat "%Y-%m-%d"
      currency "EUR"
      scenario plan "Plan" {
        scenario delayed "Delayed"
      }
    }

It tells TaskJuggler the default project ID, a short name for your 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. So, make it big enough, that all your tasks fit within. But don't make it too big, since this will result in longer scheduling times and higher memory consumption.

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 now to set the current day for the scheduler to another value than to the moment your invoke 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. The currency attribute specifies the unit of currency values.

Since each culture has it's own way of specifying dates, the format is configurable. Use the timeformat attribute to specify the default format. This is the format used for reports. It's not the format that you use in TaskJuggler project files. This format is fixed and must be Year-Month-Day-Hours:Minutes:Seconds-Timezone. All values after day are optional.

In this tutorial we would like to compare two scenarios of the project. The first scenario is the one that we have planned. The second scenario is how it really happended. The two scenarios have the same task structure, but the start and end dates of the task may vary. In reality we assume that the project got delayed, so we call the second scenario "Delayed". The scenario property is used to specify the scenarios. The delayed scenario is nested into the plan scenario. This tells TaskJuggler to use all values from the plan scenario also for the delayed scenario unless the delay scenario has it's own values. We'll see further down, how to specify values for a scenario.

## Global Attributes

Besides finding suitable start and end dates of our project, we also like to do a simple profit and loss analysis. So we have to specify the default daily costs of an employee. This can be changed for certain 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.

    rate 310.0

The rate attribute can be used to specify the daily costs of resources.

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.

    macro allocate_developers [
      allocate dev1
      allocate dev2 { limits { dailymax 4h } }
      allocate dev3
    ]

To use the macro you simply have to write `${allocate_developers}` and TaskJuggler will replace the term `${allocate_developers}` with the pattern. We will use the macro further down in the example and then explain the meaning of the pattern.

## Declaring Resources

A TaskJuggler feature that you will probably make heavy use of is flags . Once declared you can attach them to many properties. When you generate reports of the TaskJuggler results, you can use the flags to filter out information and limit the report to exactly those details that you want to have included.

    flags team

    resource dev "Developers" {
      resource dev1 "Paul Smith" { rate 330.0 }
      resource dev2 "Sebastien Bono"
      resource dev3 "Klaus Mueller" { vacation 2002-02-01 - 2002-02-05 }

      flags team
    }
    resource misc "The Others" {
      resource test "Peter Murphy" { limits { dailymax 6.4h } rate 240.0 }
      resource doc "Dim Sung" { rate 280.0 }

      flags team
    }

This snippet of the example shows the resource 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 you can see, resource properties can be nested. `dev` is a virtual resource, a team, that consists of three other resources.

`dev1`, alias Paul Smith costs more than the normal employee. So the declaration of `dev1` overwrites the inherited default rate with a new value of 330.0. The default value has been inherited from the enclosing scope, resource `dev`. Which in turn has inherited it from the global scope.

The declaration of the resource Klaus Müller uses another optional attribute. With vacation you can specify a certain time interval where the resource is not available.

Here you need 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. `2002-02-01` specifies midnight February 1st, 2002. Again following the TaskJuggler concept of needing as little information as needed 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 you specify a time interval, the end date is not included in the interval. But the second before the date that you have specified is. So Klaus Müllers vacation ends 23:59:59 on February 4th, 2002.

Peter Murphy only works 6.4 hours a day. So we use the limits attribute to limit his daily working hours. We could also define exact working hours using the shift property, but we ignore this for now.

Note that we have attached the flag `team` after the declaration of the sub-resources to the team resources. This way, they flags don't get handed down to the sub-resources. If we would have declared the flags before the sub-resources, then they would have the flags attached as well.

## Declaring Accounts

The use of our resources will create costs. For a profit and loss analysis, we need to balance the costs against the customer payments. In order to not get lost with all the various 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.

    account dev "Development" cost
    account doc "Dokumentation" cost
    account rev "Payments" revenue

The account property has 3 fixed attributes, an ID, a name and a type. The type can either be `cost` or `revenue` . For the analysis TaskJuggler subtracts the total amount of all cost accounts from the total amount from all revenue accounts.

Accounts can also be nested. Nested accounts may not have a type specified. They inherit the type of the top-level account.

## Specifying the Tasks

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:

    task AcSo "Accounting Software" {
      task spec "Specification"
      task software "Software Development"
      task test "Software testing"
      task deliveries "Milestones"
    }

Similar to resources, tasks are declared by using the task 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 constrast to all other TaskJuggler properties, task IDs inherit the ID of the enclosing task as a prefix to the ID. The full ID of the `spec` task is `AcSo.spec`.

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.

      task spec "Specification" {
        effort 20d
        ${allocate_developers}
        depends !deliveries.start
      }

The effort to complete the task is specified with 20 man days. Alternatively we could have used the length attribute or the duration attribute. `length` specifies the duration of the task in working days while `duration` specifies the duration in calendar days. Contrary to effort these two don't have to have a specification of the involved resources. Since `effort` 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. Tasks with `length` or `duration` criteria and allocated resources, will last exactly as long as requested. Resources will be allocated only if available.

Here we use the above mentioned macro `allocate_developers`. The expression

        ${allocate_developers}

is simply expanded to

      allocate dev1
      allocate dev2 { limits { dailymax 4h } }
      allocate dev3

If you need to allocate the same bunch of people to several task, the macro saves you some writing. You could have written the allocate 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.

One more interesting thing to note is the fact that we like the resource `dev2` only to work 50% of the day on this task, so we use the optional attribute limits to specify this.

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 `spec` task depends on a sub tasks of the `deliveries` tasks. We haven't specified it yet, but it has the local ID `start`.

To specify the dependency between the two task we use the depends 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 `AcSo.spec`.

Relative IDs always start with one or more exclamation marks. Each exclamation mark moves the scope to the next enclosing task. So `!deliveries.start` is expanded to `AcSo.deliveries.start` since `AcSo` is the enclosing task of `deliveries`. Relative task IDs are a little bit confusing at first, but have a real advantage over absolute IDs. Sooner or later you want to move tasks around in your project and then it's a lot less likely that you have to fix dependency specifications of relative IDs.

The software development task is still too complex to specify it directly. So we split it into sub tasks again.

      task software "Software Development" {
        priority 1000
        task database "Database coupling"
        task gui "Graphical User Interface"
        task backend "Back-End Functions"
      }

We use the priority attribute to mark the importance of the tasks. 500 is the default priority of top-level tasks. 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). `priority` is an attribute that is handed down to sub tasks if specified before the sub tasks declaration. So all sub tasks of `software` have a priority of 1000 as well unless they have their own priority definition.

        task database "Database coupling" {
          effort 20d
          depends !!spec
          allocate dev1, dev2
        }

The work on the database coupling should not start before the specification has been finished. So we use again the depends 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 `software` task. The second one is to get into the `AcSo` scope that contains the `spec` tasks. This time we allocate resources directly without using a macro.

        task gui "Graphical User Interface" {
          effort 35d
          delayed:effort 40d
          depends !database, !backend
          allocate dev2, dev3
        }

TaskJuggler can schedule your project for two different scenarios. We have called the first scenario "plan" scenario and the second "delayed" scenario. Many of the reports allow you to put the values of both scenarios side by side to each other, so you can compare the two scenarios. All scenario specific values that are not explicitly stated for the delayed scenario are taken from the plan scenario. So the user only has to specify the values that differ in the delayed scenario. 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 may vary. In the example we have planned the work on the graphical user interface to be 35 man days. It turned out that we actually needed 40 man days. By prefixing the start effort attribute with `delayed:` the effort value for the delayed scenario can be specified.

        task backend "Back-End Functions" {
          effort 30d
          complete 95
          depends !database, !!spec
          allocate dev1
          allocate dev2
        }

By default TaskJuggler assumes that all tasks are on schedule. Sometimes you want to generate reports, that show how much of a task has actually been completed. TaskJuggler uses the current date for this unless you have specified another date using the now attribute. If a task is ahead of schedule or late that can be specified using the complete attribute. This 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.

      task test "Software testing" {

        task alpha "Alpha Test" {
          effort 1w
          depends !!software
          allocate test, dev2
        }

        task beta "Beta Test" {
          effort 4w
          depends !alpha
          allocate test, dev1
        }
      }

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 dailyworkinghours attribute.

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 `dev` and all documentation work to the account `doc`. To achieve this, we use the attribute `account` to credit all tasks to the `dev` account.

    task AcSo "Accounting Software" {

      account dev

      task software "Software Development" {

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. The only exception is the writing of the manual. We need to change the account for this task again as it is also a sub task of `AcSo`.

      task manual "Manual" {
        effort 10w
        depends !deliveries.start
        allocate doc, dev3
        account doc
      }

## Specifying Milestones

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 you just want to capture a certain moment in your project plan. These moments are usually called milestones since they have some level of importance for the progress of the project.

TaskJuggler has support for milestones as well. They are handled as special types of tasks. By using the optional attribute milestone 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.

      task deliveries "Milestones" {

        account rev

        task start "Project start" {
          milestone
          start 2002-01-16
          delayed:start 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
        }
      }
    }

We have put all important milestones of the project as sub tasks of the `deliveries` 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 start 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 `delayed:` prefix again to specify the start date for the delayed scenario.

Every milestone is linked to a customer payment. By using the startcredit attribute we can credit the specified amount to the account associated with this task. Since we have assigned the `rev` account to the enclosing task, all milestones will use this account as well.

Did you notice the line in the task `done` that starts with a hash? This line is commented out. If TaskJuggler finds a hash it ignores the rest of the line. This way you can include comments in your project. The maxend 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.

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.

## Generating Reports of the scheduled Project

TaskJuggler offers a number of report types. Probably the most popular ones are interactive reports and HTML reports.

### Generating Interactive Reports

Interactive reports are only available in the TaskJuggler GUI. The command line version will just ignore interactive report definitions. To view a task report in the GUI, you have to add the following lines to your project.

    taskreport "Project Overview" {
      columns start, end, effort, duration, completed, status, note, cost, revenue
      scenario delayed
    }

The syntax is very similar to other report types. The only noticable differences are:

- A column with the task name is always included.

- A Gantt chart will always be displayed.

- Interactive reports only support one scenario. By default this is the first scenario, but the user can select another scenario to be displayed. To view the delayed scenario we use the keyword scenario.

The interactive resource reports have a very similar syntax:

    resourcereport "Resource Usage" {
      columns effort, freeload, utilization, rate
      scenario delayed
      hideresource 0
    }

### Generating HTML Reports

You can advice TaskJuggler to generate one or more HTML pages that contain lists of your tasks, resources or accounts.

Before we start with the reports, we present you 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 raw HTML tags. If you are not familiar with HTML this will look very strange to you. Don't worry, this is just a cool feature we would like to demonstrate. You can use TaskJuggler to it's full extend without having to learn HTML code.

The HTML code is injected into the reports using the rawhead attribute. This will put the HTML code close to the top of the HTML page right after the body started. As you can see 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.

    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>'
    ]

### Generating HTML Task Reports

As the first report, we would like to have a general overview of all tasks with their computed start and end dates. To visualize the dates a bit more, we also include a Gantt chart like bar graph. The property htmltaskreport defines exactly this, a list of all tasks in a table. The columns are flexible and can be specified with the column 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.

    htmltaskreport "Tasks-Overview.html" {
      ${navbar}
      columns hierarchindex, name, duration, effort { title "Work"},
              start, end, weekly
      timeformat "%a %Y-%m-%d"
      barlabels empty
      headline "Accounting Software Project"
      caption "This table presents a management-level overview of the
        project. The values are days or man-days."
    }

Since we don't like the default column title for the effort column we change it to "Work". Dates should be displayed as `Sun 2003-09-29`, so we use the attribute timeformat. For the overview page we don't like to have load values in the calendar. We just want to have the Gantt chart like bars that visualize the duration of the tasks. Since the load values are reported by default, we use the attribute barlabels to surpress them. With the headline attribute we can specify a headline for the report. To have a little more info included as well, we use the caption attribute. Both of these attributes are followed by the string to be included into the report.

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.

    htmltaskreport "Tasks-Details.html" {
      ${navbar}
      columns no, name, start, end, scenario, daily
      start 2002-03-01
      end 2002-04-01
      scenarios plan, delayed
      headline "Accounting Software Project - March 2002"
      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 delayed schedule differs significantly
        from the original plan."
      hideresource 0
    }

In order to limit the report to a reasonable size, we limit the daily calendar to the interval 2002-03-01 - 2002-04-01 with the `start` and `end` attributes. 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 hideresource 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.

To add even more information to this report, we also turn on the reporting of values of the delayed scenario by using the scenarios attribute. This causes TaskJuggler to split the lines of the report into one for each scenario where appropriate and report the values underneath each other.

### Generating HTML Resource Reports

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 loadunit to report the load in hours instead of days.

    htmlresourcereport "Staff-Overview.html" {
      ${navbar}
      columns no, name, scenario, weekly, effort
      scenarios plan, delayed
      loadunit hours
      headline "Weekly working hours for the Accounting Software Project"
    }

Now a similar report but with much more details. We want to include the tasks again, this time each resource should be followed by the tasks the resource is assigned to. In htmltaskreports resources are hidden by default while in htmlresourcereports tasks are hidden by default. To include tasks the attribute hidetask needs to be used. It is followed by a logical expression just like hideresource.

    htmlresourcereport "Staff-Details.html" {
      ${navbar}
      columns name, daily, effort
      start 2002-03-01
      end 2002-04-01
      hidetask 0
      hideresource team
      sortresources nameup
      loadunit hours
      headline "Daily working hours for the Accounting Software Project -
      March 2002"
    }

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 `team` to those pseudo resources. We now use this flag as logical expression for hideresource. 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 sortresources is taking care of this.

### Generating HTML Account Reports

To conclude the HTML reports a report that shows how poorly the project is calculated is generated. The company won't get rich with this project. Due to the slip, it actually needs a loan from the bank to pay the salaries.

    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
    	scenarios plan, delayed
    }

The htmlaccountreport property produces similar reports as the above ones, but it lists accounts instead of tasks or resources. The `total` column shows the value of the account at the end of the reported time interval. The accumulate 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.

### Generating XML Reports

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. Since the Konqueror plug-in already uses the new, version 2 XML format, you have to comment out the version attribute.

    xmlreport "AccountingSoftware.tjx" {
    	#version 2
    }