home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2004 March / VPR0403.ISO / talks / 071 / paper.dkb < prev    next >
Encoding:
Extensible Markup Language  |  2003-09-18  |  34.8 KB  |  935 lines

  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <article id="paper-71">
  3.   <articleinfo>
  4.     <title>The TaskJuggler Project Management Software</title>
  5.     <author>
  6.       <firstname>Chris</firstname>
  7.       <surname>Schlaeger</surname>
  8.     </author>
  9.     <copyright>
  10.       <year>2003</year>
  11.       <holder>Chris Schlaeger</holder>
  12.     </copyright>
  13.   </articleinfo>
  14.  
  15. <section><title>Introduction</title>
  16.  
  17. <para>TaskJuggler is a project planing tool for Linux and UNIX
  18. system-based operating systems. All tasks with their dependencies and
  19. other properties are edited by using a text editor. The file is then
  20. sent through TaskJuggler which in turn produces all sorts of reports in
  21. HTML or XML format. The HTML files can be viewed and printed with any
  22. web browser. The XML files are used by the Gantt- and PERT chart
  23. generators and the KDE Konqueror plug-in.</para>
  24.  
  25. <para>Since TaskJuggler is not constrained by the performance requirements
  26. of real-time editing it can offer a much broader set of features not
  27. found in any of the WYSIWYG (What You See Is What You Get) project
  28. planing tools. The the project description language is easy to learn
  29. and supports the user very effectively during the planing and tracking
  30. process.</para> 
  31.  
  32. <para>TaskJuggler does not only honor the task interdependencies but
  33. also takes resource constrains and job prioritization into account.
  34. The multi-scenario support makes TaskJuggler a versatile tool for both
  35. what-if-analysis and plan/actual comparisons.  Using TaskJuggler's
  36. powerful filtering and reporting algorithms the user can create a
  37. variety of task lists, resource usage tables, status reports, project
  38. calendars and project accounting statements.</para>
  39.  
  40. </section>
  41. <section><title>Features and Highlights</title>
  42.  
  43. <itemizedlist mark='opencircle'>
  44.  
  45. <listitem><para>Automatic scheduling of interdependent tasks with resource
  46. conflict solver.</para></listitem>
  47.  
  48. <listitem><para>Powerful project description syntax with macro
  49. support.</para></listitem>
  50.  
  51. <listitem><para>Flexible working hours and vacation
  52. handling.</para></listitem>
  53.  
  54. <listitem><para>Support for shifts.</para></listitem>
  55.  
  56. <listitem><para>Multiple time zone support.</para></listitem>
  57.  
  58. <listitem><para>Flexible resource grouping.</para></listitem>
  59.  
  60. <listitem><para>Project accounting support.</para></listitem>
  61.  
  62. <listitem><para>Task may have initial and finishing costs.</para></listitem>
  63.  
  64. <listitem><para>Resource may have running costs.</para></listitem>
  65.  
  66. <listitem><para>Support for profit and loss analysis.</para></listitem>
  67.  
  68. <listitem><para>HTML and XML report generation.</para></listitem>
  69.  
  70. <listitem><para>Gantt and PERT chart generators.</para></listitem>
  71.  
  72. <listitem><para>Support for plan and actual scenario
  73. comparisons.</para></listitem>
  74.  
  75. <listitem><para>Project tracking support.</para></listitem>
  76.  
  77. <listitem><para>Groupware support by using a revision control system
  78. such as CVS or RCS on the project description files.</para></listitem>
  79.  
  80. <listitem><para>Support for central resource allocation
  81. database.</para></listitem>
  82.  
  83. <listitem><para>Support for cascaded and nested projects.</para></listitem>
  84.  
  85. <listitem><para>Import and export of sub-projects.</para></listitem>
  86.  
  87. <listitem><para>Unicode and localization support.</para></listitem>
  88.  
  89. </itemizedlist>
  90.  
  91. </section>
  92. <section><title>Basics</title>
  93.  
  94. <para>TaskJuggler uses one or more text files to describe a project.
  95. The main project should be placed in a file with the
  96. <emphasis>.tjp</emphasis> extension. This main project may
  97. contain several sub-projects. Such sub-projects should be placed in
  98. files with the <emphasis>.tjsp</emphasis> extension. These
  99. sub-projects are included in the main project during compile
  100. time.</para>
  101.  
  102. <para>TaskJuggler works like a compiler. The user provides the source
  103. files and TaskJuggler computes the contents and creates the output
  104. files.</para>
  105.  
  106. <para>Let's say <filename>AcSo.tjp</filename> is a valid TaskJuggler
  107. project file. It contains the tasks of the project and their
  108. dependencies. To schedule the project and create report files the user
  109. calls TaskJuggler to process it.</para>
  110.  
  111. <programlisting>
  112. % taskjuggler AcSo.tjp
  113. </programlisting>
  114.  
  115. <para>TaskJuggler will try to schedule all tasks with the specified
  116. conditions and generate the reports that were requested with the
  117. <emphasis>htmltaskreport</emphasis>,
  118. <emphasis>htmlresourcereport</emphasis> or other report attributes in
  119. the input file.</para>
  120.  
  121. </section> 
  122. <section><title>The TaskJuggler Syntax</title>
  123.  
  124. <para>To introduce the TaskJuggler syntax we create the project plan
  125. for a software development project. This example illustrates the
  126. basic features of TaskJuggler. The full source code of the example and
  127. the resulting reports can be found on the <ulink
  128. url="http://www.taskjuggler.org">TaskJuggler Web Site</ulink> at
  129. <ulink
  130. url="http://www.taskjuggler.org/example.php">http://www.taskjuggler.org/example.php</ulink>.</para>
  131.  
  132. <para>A project is always started with the
  133. <emphasis>project</emphasis> property.</para>
  134.  
  135. <programlisting>
  136. project acso "Accounting Software" "1.0" 2002-01-16 2002-04-26 {
  137.   now 2002-03-04
  138. }
  139. </programlisting>
  140.  
  141. <para>It tells TaskJuggler the default project ID, a short name for
  142. the project, a version number and a start and end date. The start and
  143. end dates don't need to be exact, but must enclose all tasks. It
  144. specifies the time interval the TaskJuggler scheduler will use to fit
  145. the tasks in.</para>
  146.  
  147. <para>All TaskJuggler properties have a certain number of fixed
  148. attributes and a set of optional attributes. Optional attributes are
  149. always enclosed in curly braces. In this example we use the optional
  150. attributes <emphasis>now</emphasis> to set the current
  151. day for the scheduler to another value than to the moment the user
  152. invokes TaskJuggler. We pick a day during the above specified project
  153. period.  So we always get the same results of a TaskJuggler run, no
  154. matter when we process our first project.</para>
  155.  
  156. </section>
  157. <section><title>Global Attributes</title>
  158.  
  159. <para>Besides finding suitable start and end dates for the tasks of
  160. the project, TaskJuggler can also do a simple profit and loss
  161. analysis. The user has to specify the default daily costs of an
  162. employee. This can be changed for specific employees later but it
  163. illustrates an important concept of TaskJuggler - inheritance of
  164. attributes. In order to reduce the size of the TaskJuggler project
  165. file to a still readable minimum, properties inherit many optional
  166. attributes from their enclosing scope. We'll see further down, what
  167. this actually means. Here we are at top-level scope, so this is the
  168. default for all following properties.</para>
  169.  
  170. <programlisting>
  171. rate 310.0
  172. currency "EUR"
  173. </programlisting>
  174.  
  175. <para>The <emphasis>rate</emphasis> attribute can be used to specify
  176. the daily costs of resources. The <emphasis>currency</emphasis>
  177. attribute specifies the currency to be used.</para>
  178.  
  179. </section>
  180. <section><title>Macros</title>
  181.  
  182. <para>Macros are another TaskJuggler feature to keep project files
  183. small. Macros are text patterns that can be defined once and inserted
  184. many times further down the project. A macro always has a name and the
  185. text pattern is enclosed by square brackets. </para>
  186.  
  187. <programlisting>
  188. macro allocate_developers [
  189.   allocate dev1
  190.   allocate dev2 { load 0.5 }
  191.   allocate dev3
  192. ]
  193. </programlisting>
  194.  
  195. <para>To use the macro the user simply has to write <emphasis>
  196. ${allocate_developers} </emphasis> and TaskJuggler will replace
  197. the <emphasis>${allocate_developers}</emphasis> with the
  198. pattern. We will use the macro further down in the example and then
  199. explain the meaning of the pattern.</para>
  200.  
  201. <para>Macros can also have parameters. Inside the macro they are
  202. referenced by their number.</para>
  203.  
  204. <programlisting>
  205. macro foo [
  206.   The first parameter is ${1}.
  207.   And the second is ${2}.
  208. ]
  209. </programlisting>
  210.  
  211. <para>Now the call</para>
  212.  
  213. <programlisting>
  214. ${foo "bar1" "bar2"}
  215. </programlisting>
  216.  
  217. <para>would be expanded to</para>
  218.  
  219. <programlisting>
  220.   The first parameter is bar1.
  221.   And the second is bar2.
  222. </programlisting>
  223.  
  224. </section>
  225. <section><title>Using flags</title>
  226.  
  227. <para>A TaskJuggler feature that the user will probably make heavy use of
  228. is <emphasis>flags</emphasis>. Once declared the user can attach
  229. them to many properties. When generating reports of the TaskJuggler
  230. results, the user can use the flags to filter out information and limit the
  231. report to exactly those details that should be included.</para>
  232.  
  233. <programlisting>
  234. flags team
  235. </programlisting>
  236.  
  237. <para>Flags must be declared at global scope before they can be
  238. attached to other properties.</para>
  239.  
  240. </section>
  241. <section><title>Declaring Resources</title>
  242.  
  243. <programlisting>
  244. resource dev "Developers" {
  245.   resource dev1 "Paul Smith" { rate 330.0 }
  246.   resource dev2 "S饕astien Bono"
  247.   resource dev3 "Klaus Mller" { vacation 2002-02-01 - 2002-02-05 }
  248.  
  249.   flags team
  250. }
  251. resource misc "The Others" {
  252.   resource test "Peter Murphy" { maxeffort 0.8 rate 240.0 }
  253.   resource doc "Dim Sung" { rate 280.0 }
  254.  
  255.   flags team
  256. }
  257. </programlisting>
  258.  
  259. <para>This snippet of the example shows the <emphasis>
  260. resource </emphasis> property. Resources always have an ID and a Name. IDs
  261. may only consist of ASCII characters, numbers and the underline
  262. character. All global TaskJuggler properties have IDs. They need to be
  263. unique within their property class. The ID is needed so that we can
  264. reference the property again later without having the need to write
  265. the potentially much longer name. Names are strings and as such
  266. enclosed in double quotes.  Strings may contain any character, even
  267. non-ASCII characters. As seen above, resource properties can be
  268. nested. <emphasis>dev</emphasis> is a virtual resource,
  269. a team, that consists of three other resources.</para>
  270.  
  271. <para><emphasis>dev1</emphasis>, alias Paul Smith earns
  272. more than the normal employee. So the declaration of <emphasis>
  273. dev1</emphasis> overwrites the inherited default rate with a
  274. new value of 330.0. The default value has been inherited from the
  275. enclosing scope, resource <emphasis>dev</emphasis>.
  276. Which in turn has inherited it from the global scope. </para>
  277.  
  278. <para>The declaration of the resource Klaus Mueller uses another
  279. optional attribute. With <emphasis>vacation</emphasis> the user can
  280. specify a certain time interval where the resource is not
  281. available.</para>
  282.  
  283. </section>
  284. <section><title>Time and Date Specifications</title>
  285.  
  286. <para>It is important to understand how TaskJuggler handles time
  287. intervals. Internally TaskJuggler uses the number of seconds after
  288. January 1st, 1970 to store any date. So all dates are actually stored
  289. with an accuracy of 1 second. <emphasis>2002-02-01</emphasis>
  290. specifies midnight February 1st, 2002. Again following the TaskJuggler
  291. concept of needing as little info as necessary and extending the rest
  292. with sensible defaults, TaskJuggler adds the time 0:00:00 if nothing
  293. else has been specified. So the vacation ends on midnight February
  294. 5th, 2002. Well, almost. Every time the user specifies a time
  295. interval, the end date is not included in the interval. But the second
  296. before the date that has been specified is still part of the interval.
  297. So Klaus Mueller's vacation ends 23:59:59 on February 4th,
  298. 2002.</para>
  299.  
  300. <para>Peter Murphy only works 6.5 hours a day (actually 6.4 hours). So
  301. we use the <emphasis>maxeffort</emphasis> attribute to limit his daily
  302. working hours. We could also define exact working hours using the
  303. <emphasis>shift</emphasis> property, but we ignore this for now.
  304. <emphasis>shift</emphasis> enables the user to specify the exact
  305. working hours for each day of the week.</para>
  306.  
  307. <para>Note that we have attached the flag <emphasis>team</emphasis>
  308. after the declaration of the sub-resources to the team resources. This
  309. way, they flags don't get inherited by the sub-resources. If we would
  310. have declared the flags before the sub-resources, then they would have
  311. the flags attached as well.</para>
  312.  
  313. </section>
  314. <section><title>Declaring Accounts</title>
  315.  
  316. <para>The use of our resources will create costs. For a profit and
  317. loss analysis, we need to balance the costs against the customer
  318. payments. So that we don't get lost with all the amounts, we declare 3
  319. accounts to credit the amounts to. We create one account for the
  320. development costs, one for the documentation costs and one for the
  321. customer payments.</para>
  322.  
  323. <programlisting>
  324. account dev "Development" cost
  325. account doc "Dokumentation" cost
  326. account rev "Payments" revenue
  327. </programlisting>
  328.  
  329. <para>The <emphasis>account</emphasis> property has 3
  330. fixed attributes, an ID, a name and a type. The type can either be
  331. <emphasis>cost</emphasis> or <emphasis>revenue</emphasis>. For the
  332. analysis TaskJuggler subtracts the total amount of all cost accounts
  333. from the total amount of all revenue accounts.</para>
  334.  
  335. </section>
  336. <section><title>Specifying Tasks</title>
  337.  
  338. <para>Let's focus on the real work now. The project should solve a
  339. problem - the creation of an accounting software. Since the job is
  340. quite complicated we break it down into several sub tasks. We need to
  341. do a specification, develop the software, test the software and write
  342. a manual. In TaskJuggler syntax this would look like that:</para>
  343.  
  344. <programlisting>
  345. task AcSo "Accounting Software" {
  346.   task spec "Specification" 
  347.   task software "Software Development"
  348.   task test "Software testing"
  349.   task deliveries "Milestones"
  350. }
  351. </programlisting>
  352.  
  353. <para>Just like resources, tasks are declared by using the 
  354. <emphasis>task</emphasis> keyword followed by an ID and a name
  355. string. All TaskJuggler properties have their own namespaces. This
  356. means, that it is quite OK to have a resource and a task with the same
  357. ID. Tasks may have optional attributes which can be tasks again, so
  358. tasks can be nested. In contrast to all other TaskJuggler properties,
  359. task IDs inherit the ID of their enclosing task as a prefix to the ID.
  360. The full ID of the <emphasis>spec</emphasis> task is
  361. <emphasis>AcSo.spec</emphasis>.TaskJuggler uses dots to concatenate the
  362. IDs of hierarchical tasks to absolute IDs.</para>
  363.  
  364. <para>To track important milestones of the project, we also added a
  365. task called Milestones. This task, like most of the other task will
  366. get some sub tasks later on. We consider the specification task simple
  367. enough that we don't have to break it into further sub tasks. So let's
  368. add some more details to it.</para>
  369.  
  370. </section>
  371. <section><title>Task Durations</title>
  372.  
  373. <programlisting>
  374.   task spec "Specification" {
  375.     effort 20d
  376.     ${allocate_developers}
  377.     depends !deliveries.start
  378.   }
  379. </programlisting>
  380.  
  381. <para>The effort to complete the task is specified with 20 man days.
  382. Alternatively we could have used the <emphasis>length</emphasis>
  383. attribute or the <emphasis>duration</emphasis> attribute.
  384. <emphasis>length</emphasis> specifies the duration of the task in
  385. working days while <emphasis>duration</emphasis> specifies the
  386. duration in calendar days. Contrary to <emphasis>effort</emphasis>
  387. these two don't require to have a specification of the involved
  388. resources. If resources are specified they are allocated when
  389. available but they do not affect the total duration of the
  390. task.</para>
  391.  
  392. </section>
  393. <section><title>Allocating Resources</title>
  394.  
  395. <para>Since <emphasis>effort</emphasis> specifies the duration in man
  396. days, we need to say who should be allocated to the task. The task
  397. won't finish before the resources could be allocated long enough to
  398. reach the specified effort.</para>
  399.  
  400. <para>Here we use the above mentioned macro
  401. <emphasis>allocate_developers</emphasis>. The
  402. expression</para>
  403.  
  404. <programlisting>
  405.     ${allocate_developers}
  406. </programlisting>
  407.  
  408. <para>is simply expanded to</para>
  409.  
  410. <programlisting>
  411.   allocate dev1
  412.   allocate dev2 { load 0.5 }
  413.   allocate dev3
  414. </programlisting>
  415.  
  416. <para>If it is necessary to allocate the same bunch of people to
  417. several task, the macro saves some writing. One could have written the
  418. <emphasis>allocate</emphasis> attributes directly instead of using the
  419. macro. Since the allocation of multiple resources to a task is a very
  420. common place for macro usage, we found it a good idea to use it in
  421. this example as well.</para>
  422.  
  423. <para>One more interesting thing to note is the fact that we like
  424. the resource <emphasis>dev2</emphasis> only to work 50% of
  425. the day on this task, so we use the optional attribute 
  426. <emphasis>load</emphasis> to specify this.</para>
  427.  
  428. <para>For TaskJuggler to schedule a task it needs to know either the
  429. start and end criteria of a task, or one of them and a duration
  430. specification. The start and end criteria can either be fixed dates or
  431. relative dates. Relative dates are specification of the type "task B
  432. starts after task A has finished". Or in other words, task B depends
  433. on task A. In this example the <emphasis>spec</emphasis> task depends
  434. on a sub tasks of the <emphasis>deliveries</emphasis> tasks. We
  435. haven't specified it yet, but it has the local ID
  436. <emphasis>start</emphasis>.</para>
  437.  
  438. </section>
  439. <section><title>Task Dependencies</title>
  440.  
  441. <para>To specify the dependency between the two task we use the 
  442. <emphasis>depends</emphasis> attribute. The attribute must be
  443. followed by one or more task IDs. If more than one ID is specified,
  444. each ID has to be separated with a comma from the previous one. Task
  445. IDs can be either absolute IDs or relative IDs. An absolute ID of a
  446. task is the ID of this task prepended by the IDs of all enclosing
  447. tasks. The task IDs are separated by a dot from each other. The
  448. absolute ID of the specification task would be
  449. <emphasis>AcSo.spec</emphasis>.</para>
  450.  
  451. <para>Relative IDs always start with one or more exclamation marks.
  452. Each exclamation mark moves the scope to the next enclosing task. So
  453. <emphasis>!deliveries.start</emphasis> is expanded to
  454. <emphasis>AcSo.deliveries.start</emphasis> since
  455. <emphasis>AcSo</emphasis> is the enclosing task of
  456. <emphasis>deliveries</emphasis>. Relative task IDs are a little bit
  457. confusing at first, but have a real advantage over absolute IDs.
  458. Sooner or later the user wants to move tasks around in the project
  459. and then it's a lot less likely that one has to fix dependency
  460. specifications of relative IDs.</para>
  461.  
  462. <para>The software development task is still too complex to specify it
  463. directly. So we split it into sub tasks again.</para>
  464.  
  465. </section>
  466. <section><title>Task Priorities</title>
  467.  
  468. <programlisting>
  469.   task software "Software Development" {
  470.     priority 1000
  471.     task database "Database coupling"
  472.     task gui "Graphical User Interface"
  473.     task backend "Back-End Functions"
  474.   }
  475. </programlisting>
  476.  
  477. <para>We use the <emphasis>priority</emphasis>
  478. attribute to mark the importance of the tasks. By default all tasks
  479. have a priority of 500 unless the parent tasks specifies it
  480. differently. Setting the priority to 1000 marks the task as most
  481. important task, since the possible range is 1 (not important at all)
  482. to 1000 (ultimately important).  <emphasis>priority</emphasis> is an
  483. attribute that is inherited to sub tasks if specified before the sub
  484. tasks declaration.  So all sub tasks of <emphasis>software</emphasis>
  485. have a priority of 1000 as well.</para>
  486.  
  487. <programlisting>
  488.     task database "Database coupling" {
  489.       effort 20d
  490.       depends !!spec
  491.       allocate dev1
  492.       allocate dev2
  493.     }
  494. </programlisting>
  495.  
  496. <para>The work on the database coupling should not start before the
  497. specification has been finished. So we use again the 
  498. <emphasis>depends</emphasis> attribute to let TaskJuggler
  499. know about this. This time we use two exclamation marks for the
  500. relative ID. The first one puts us in the scope of the enclosing
  501. <emphasis>software</emphasis> task. The second one is to
  502. get into the <emphasis>AcSo</emphasis> scope that contains
  503. the <emphasis>spec</emphasis> tasks. This time we allocate
  504. resources directly without using a macro.</para>
  505.  
  506. </section>
  507. <section><title>Comparing multiple Project Scenarios</title>
  508.  
  509. <programlisting>
  510.     task gui "Graphical User Interface" {
  511.       effort 35d
  512.       actualeffort 40d
  513.       depends !database, !backend
  514.       allocate dev2
  515.       allocate dev3
  516.     }
  517. </programlisting>
  518.  
  519. <para>TaskJuggler can schedule the project for two different
  520. scenarios. The first scenario is called the plan scenario. The other
  521. is referred to as the actual scenario. Many of the reports allow 
  522. to put the values of both scenarios side by side to each other, so one 
  523. can compare the two scenarios. The two scenarios must have the same
  524. task structure and the same dependencies. But the start and end dates
  525. of tasks as well as the duration and the resulting resource allocation
  526. may vary. In the example we have planed the work on the graphical user
  527. interface to be 35 man days. It turned out that we actually needed 40
  528. man days. The <emphasis>actualeffort</emphasis> attribute can be used
  529. to specify this.</para>
  530.  
  531. </section>
  532. <section><title>Tracking the Project Status</title>
  533.  
  534. <programlisting>
  535.     task backend "Back-End Functions" {
  536.       effort 30d
  537.       complete 95
  538.       depends !database, !!spec
  539.       allocate dev1
  540.       allocate dev2
  541.     }
  542. </programlisting>
  543.  
  544. <para>By default TaskJuggler assumes that all tasks are on schedule.
  545. Sometimes the user wants to generate reports, that show how much of a
  546. task has actually been completed. TaskJuggler uses the current date
  547. for this unless another date has been specified by using the
  548. <emphasis>now</emphasis> attribute. If a task is ahead of schedule or
  549. late this can be specified using the <emphasis>complete</emphasis>
  550. attribute. It specifies how many percent of the task have been
  551. completed up to the current date.  In our case the back-end
  552. implementation is slightly ahead of schedule as we will see from the
  553. report.</para>
  554.  
  555. </section>
  556. <section><title>Specifying Efforts</title>
  557.  
  558. <programlisting>
  559.   task test "Software testing" {
  560.  
  561.     task alpha "Alpha Test" {
  562.       effort 1w
  563.       depends !!software
  564.       allocate test
  565.       allocate dev2
  566.     }
  567.  
  568.     task beta "Beta Test" {
  569.       effort 4w
  570.       depends !alpha
  571.       allocate test
  572.       allocate dev1
  573.     }
  574.   }
  575. </programlisting>
  576.  
  577. <para>The software testing task has been split up into an alpha and a
  578. beta test task. The interesting thing here is, that efforts can not
  579. only be specified as man days, but also man weeks, man hours, etc. Per
  580. default TaskJuggler assumes a man week is 40 man hours or 5 man days.
  581. These values can be changed using the 
  582. <emphasis>dailyworkinghours</emphasis>
  583. attribute.</para>
  584.  
  585. </section>
  586. <section><title>Crediting costs to Accounts</title>
  587.  
  588. <para>Let's go back to the outermost task again. At the beginning of
  589. the example we stated that we want to credit all development work to
  590. one account with ID <emphasis>dev</emphasis> and all documentation
  591. work to the account <emphasis>doc</emphasis>. To achieve this, we use
  592. the attribute account to credit all tasks to the
  593. <emphasis>dev</emphasis> account.</para>
  594.  
  595. <programlisting>
  596. task AcSo "Accounting Software" {
  597.  
  598.   account dev
  599.  
  600.   task software "Software Development" {
  601. </programlisting>
  602.  
  603. <para>Since we specify the attribute for the top-level task before we
  604. declare any sub tasks, this attribute will be inherited by all sub
  605. tasks and their sub tasks and so on. Since the only exception is the
  606. writing of the manual, we need to change the account for this task
  607. again since it is also a sub task of
  608. <emphasis>AcSo</emphasis>.</para>
  609.  
  610. <programlisting>
  611.   task manual "Manual" {
  612.     effort 10w
  613.     depends !deliveries.start
  614.     allocate doc
  615.     allocate dev3
  616.     account doc
  617.   }
  618. </programlisting>
  619.  
  620. </section>
  621. <section><title>Specifying Milestones</title>
  622.  
  623. <para>All task that have been discussed so far, had a certain duration. We
  624. did not always specify the duration explicitly, but we expect them to
  625. last for a certain period of time. Sometimes the user just wants to capture
  626. a certain moment in the project plan. These moments are usually
  627. called milestones since they have some level of importance for the
  628. progress of the project.</para>
  629.  
  630. <para>TaskJuggler has support for milestones as well. They are handled
  631. as special types of tasks. By using the optional attribute
  632. <emphasis>milestone</emphasis> for a task, this task
  633. is declared a milestone. Milestones have no duration, so it's illegal
  634. to specify any duration criteria, or a non identical start and end
  635. date.</para>
  636.  
  637. <programlisting>
  638.   task deliveries "Milestones" {
  639.  
  640.     account rev
  641.  
  642.     task start "Project start" {
  643.       milestone
  644.       start 2002-01-16
  645.       actualstart 2002-01-20
  646.       startcredit 33000.0
  647.     }
  648.  
  649.     task prev "Technology Preview" {
  650.       milestone
  651.       depends !!software.backend
  652.       startcredit 13000.0
  653.     }
  654.  
  655.     task beta "Beta version" {
  656.       milestone
  657.       depends !!test.alpha
  658.       startcredit 13000.0
  659.     }
  660.  
  661.     task done "Ship Product to customer" {
  662.       milestone
  663.       # maxend 2002-04-17
  664.       depends !!test.beta, !!manual
  665.       startcredit 14000.0
  666.     }
  667.   }
  668. }
  669. </programlisting>
  670.  
  671. <para>We have put all important milestones of the project as sub tasks
  672. of the <emphasis>deliveries</emphasis> task. This way they
  673. show up nicely grouped in the reports. All milestone have either a
  674. dependency or a fixed start date. For the first milestone we have used
  675. the attribute <emphasis>start</emphasis> to set a fixed
  676. start date. All other tasks have direct or indirect dependencies on
  677. this task. Moving back the start date will slip the whole project.
  678. This has actually happened, so we use the 
  679. <emphasis>actualstart</emphasis> attribute to specify the
  680. real start of the project 4 days later.</para>
  681.  
  682. <para>Every milestone is linked to a customer payment. By using the
  683. <emphasis>startcredit</emphasis> attribute we can
  684. credit the specified amount to the account associated with this task.
  685. Since we have assigned the <emphasis>rev</emphasis>
  686. account to the enclosing task, all milestones will use this account as
  687. well.</para>
  688.  
  689. <para>The line within the definition of the task 
  690. <emphasis>done</emphasis> that starts with a hash is a comment.
  691. If TaskJuggler finds a hash it ignores the rest
  692. of the line. This way the user can include comments in the project.
  693. The <emphasis>maxend</emphasis> attribute specifies that the
  694. task should end no later than the specified date. This information is
  695. not used for scheduling but only for checking the schedule afterwards.
  696. Since the task will end later than the specified date, commenting out
  697. the line would trigger a warning.</para>
  698.  
  699. <para>Now the project has been completely specified. Stopping here would
  700. result in a valid TaskJuggler file that could be processed and
  701. scheduled. But no reports would be generated to visualize the
  702. results.</para>
  703.  
  704. </section>
  705. <section><title>Generating Reports of the scheduled Project</title>
  706.  
  707. <para>TaskJuggler offers a number of report types. Probably the most
  708. popular ones are the HTML reports. The user can advice TaskJuggler to
  709. generate one or more HTML pages that contain lists of tasks,
  710. resources or accounts.</para>
  711.  
  712. <para>Before we start with the reports, we present another macro.
  713. We like to add a navigation bar to each HTML page that holds a number
  714. of buttons. Each button changes the page to another report. This way
  715. we can create a navigation bar that holds links to all reports. Since
  716. we have created a macro, we can add the navigation bar to all reports
  717. without much hassle. The navigation bar is constructed with HTML tags.
  718. If the user is not familiar with HTML this will look very strange but
  719. it is a cool feature we would like to demonstrate.  Certainly the user
  720. can use TaskJuggler to it's full extend without having to learn HTML
  721. code.</para>
  722.  
  723. <para>The HTML code is injected into the reports using the 
  724. <emphasis>rawhead</emphasis> attribute. This will
  725. put the HTML code close to the top of the HTML page right after the
  726. body started. As can be seen here, string parameters of attributes can
  727. be enclosed in single quotes as well. This is handy, if the string
  728. itself needs to contain double quotes.</para>
  729.  
  730. <programlisting>
  731. macro navbar [
  732. rawhead
  733.   '<p><center>
  734.   <table border="2" cellpadding="10">
  735.   <tr>
  736.     <td class="default" style="font-size:120%" rowspan="2">
  737.     <a href="Tasks-Overview.html">Tasks Overview</td>
  738.     <td class="default" style="font-size:120%" rowspan="2">
  739.     <a href="Tasks-Details.html">Tasks Details</td>
  740.     <td class="default" style="font-size:120%" rowspan="2">
  741.     <a href="Staff-Overview.html">Staff Overview</td>
  742.     <td class="default" style="font-size:120%" rowspan="2">
  743.     <a href="Staff-Details.html">Staff Details</td>
  744.     <td class="default" style="font-size:120%" rowspan="2">
  745.     <a href="Accounting.html">Accounting</td>
  746.     <td class="default" style="font-size:120%" rowspan="2">
  747.     <a href="acso.eps">GANTT Chart (Postscript)</td>
  748.   </tr>
  749.   </table>
  750.   </center></p><br>'
  751. ]
  752. </programlisting>
  753.  
  754. </section>
  755. <section><title>Generating HTML Task Reports</title>
  756.  
  757. <para>As the first report, we would like to have a general overview of all
  758. tasks with their computed start and end dates. For better
  759. readability we include a calendar like column that lists the effort
  760. for each week. The report shell consists mainly of a listing of the
  761. tasks in a table form. The property 
  762. <emphasis>htmltaskreport</emphasis> generates exactly this,
  763. a list of all tasks in a table. The columns are flexible and
  764. can be specified with the 
  765. <emphasis>column</emphasis> attribute. For this
  766. report we like to see the number, the name, the start and end
  767. date, a weekly calendar and the total effort in the table.</para>
  768.  
  769. <programlisting>
  770. htmltaskreport "Tasks-Overview.html" {
  771.   ${navbar}
  772.   columns no, name, start, end, weekly, effort
  773.   headline "Accounting Software Project"
  774.   caption "This table shows the load for each task on a weekly basis.
  775.   All values are man-days."
  776. }
  777. </programlisting>
  778.  
  779. <para>With the <emphasis>headline</emphasis>
  780. attribute we can specify a headline for the report. To have a little
  781. more info included as well, we use the 
  782. <emphasis>caption</emphasis> attribute. Both of
  783. these attributes are followed by the string to be included into the
  784. report.</para>
  785.  
  786. <para>
  787. Now we like to generate a report that contains a lot more details
  788. about the task. The weekly calendar is replaced by a daily calendar.
  789. The weekly calendar had a column for each week. The daily calendar
  790. features a column for each day. The column includes the load for the
  791. task for the week or day and a colored background in case the task is
  792. active that day or week.</para>
  793.  
  794. <programlisting>
  795. htmltaskreport "Tasks-Details.html" {
  796.   ${navbar}
  797.   columns no, name, start, end, daily
  798.   headline "Accounting Software Project"
  799.   caption "This table shows the load of each day for all the tasks.
  800.   Additionally the resources used for each task are listed. Since the
  801.   project start was delayed, the actual schedule differs significantly
  802.   from the original plan."
  803.   hideresource 0
  804.   showactual
  805. }
  806. </programlisting>
  807.  
  808. <para>We also like to list all assigned resources right after each
  809. task. Normally resources are hidden in task reports but they can be
  810. enabled by using the 
  811. <emphasis>hideresource</emphasis> attribute.
  812. The attribute is followed by a logical expression that specifies what
  813. resources to hide. The expression is evaluated for each resource and
  814. if the result is true (not 0) than the resource is hidden. Since we
  815. want to show all resources we put a 0 in, so it's false for all
  816. resources.</para>
  817.  
  818. <para>To add even more information to this report, we also turn on the
  819. reporting of values of the actual scenario by using the 
  820. <emphasis>showactual</emphasis> attribute. This
  821. causes TaskJuggler to split the lines of the report into two where
  822. appropriate and report the actual value underneath the plan
  823. value.</para>
  824.  
  825. </section>
  826. <section><title>Generating HTML Resource Reports</title>
  827.  
  828. <para> The previous report listed the resources per task. Now we want
  829. to generate a report the lists all resources. It's again a report with
  830. a weekly calendar. This time we use the attribute 
  831. <emphasis>loadunit</emphasis> to report the load
  832. in hours instead of days.</para>
  833.  
  834. <programlisting>
  835. htmlresourcereport "Staff-Overview.html" {
  836.   ${navbar}
  837.   columns no, name, weekly, effort
  838.   showactual
  839.   loadunit hours
  840.   headline "Weekly working hours for the Accounting Software Project"
  841. }
  842. </programlisting>
  843.  
  844. <para> Now a similar report but with much more details. We want to
  845. include that tasks again, this time each resource should be followed
  846. by the tasks the resource is assigned to. In 
  847. <emphasis>htmltaskreports</emphasis> resources are hidden
  848. by default while in 
  849. <emphasis>htmlresourcereports</emphasis> tasks are
  850. hidden by default. To include tasks the attribute 
  851. <emphasis>hidetask</emphasis> needs to be used. It
  852. is followed by a logical expression just like 
  853. <emphasis>hideresource</emphasis>.</para>
  854.  
  855. <programlisting>
  856. htmlresourcereport "Staff-Details.html" {
  857.   ${navbar}
  858.   columns name, daily, effort
  859.   showactual
  860.   hidetask 0
  861.   hideresource team
  862.   sortresources nameup
  863.   loadunit hours
  864.   headline "Daily working hours for the Accounting Software Project"
  865. }
  866. </programlisting>
  867.  
  868. <para>When specifying the resources we have grouped the resources into
  869. two teams by creating two pseudo resources that had the real employees
  870. as sub resources. We have attached the flag
  871. <emphasis>team</emphasis> to those pseudo resources. We
  872. now use this flag as logical expression for 
  873. <emphasis>hideresource</emphasis>. So all
  874. resources that have this flag will be hidden in the report. For better
  875. readability we sort the resource list by name in ascending order. The
  876. attribute 
  877. <emphasis>sortresources</emphasis> is taking
  878. care of this.</para>
  879.  
  880. </section>
  881. <section><title>Generating HTML Account Reports</title>
  882.  
  883. <para> To conclude the HTML reports a report that shows how badly the
  884. project is calculated is generated. The company won't get rich with this
  885. project. Due to the slip, it actually needs some money from the bank
  886. to pay the salaries. </para>
  887.  
  888. <programlisting>
  889. htmlaccountreport "Accounting.html" {
  890.     ${navbar} columns no, name, total, monthly 
  891.     headline "P&L for the Accounting Software Project" 
  892.     caption "The table shows the profit and loss analysis as well as the
  893.              cashflow situation of the Accounting Software Project." 
  894.     accumulate
  895.     showactual
  896. }
  897. </programlisting>
  898.  
  899. <para>The <emphasis>htmlaccountreport</emphasis>
  900. property produces similar reports as the above ones, but it lists
  901. accounts instead of tasks or resources. The
  902. <emphasis>total</emphasis> column shows the value of the
  903. account at the end of the reported time interval. The 
  904. <emphasis>accumulate</emphasis> attribute
  905. puts the calendar in accumulation mode. The monthly columns list the
  906. value of the account at the end of the month. Normally the amount that
  907. has been added or subtracted from the account would be listed.</para>
  908.  
  909. </section>
  910. <section><title>Generating XML Reports</title>
  911.  
  912. <para> Finally we generate an XML report that contains all info about
  913. the scheduled project. This report will be used by tjx2gantt to create
  914. a nice GANTT chart of our project. The file can also be read by tools
  915. like tjGUI or the KDE Konqueror plug-in. </para>
  916.  
  917. <programlisting>
  918. xmlreport "AccountingSoftware.tjx"
  919. </programlisting>
  920.  
  921. </section>
  922. <section><title>Conclusion</title>
  923.  
  924. <para>TaskJuggler is a substantially different approach to project
  925. planing and tracking tools. The powerful textual project description
  926. language allows the user to efficiently capture the properties of the
  927. project. Since the scheduler it is not hampered by the performance
  928. requirements of GUI based tools it offers many important features not
  929. found in GUI tools. For future versions we plan an optimizer that can
  930. find best results even with complex tasks and skill-based resource
  931. selections.</para>
  932.  
  933. </section>
  934. </article>
  935.