Friday, September 12, 2008

Reporting and exporting from xProcess 2.9

A project I've been working with recently has been needing to get reports and data out of xProcess to integrate with other management reports. This hasn't proved as easy as I would have hoped with the product's standard reports, custom reports through BIRT, exporting and other options failing to give us what we needed. I decided to do some more experimenting with "UI Actions", which use OGNL to navigate over the data. Turns out this is a pretty good option with writing the required scripts being quite straightforward. The hardest thing turned out to be actually getting the export file which was a bit more of a hassle. I'm told all this will be great in v3 but for now here's my solution.

First you need to create a new Action in your process, and set it applicable to "Task" (or whatever type of object you want to report on) and "UI Action to "true". The only other crucial bit in this stage is writing the OGNL Expression. My script is below so you can always paste that in, see what it does and then change it!

We wanted to extract a set of key attributes of tasks (like dates and size) and display them in a spreadsheet.The script produces a set of comma-separated values (csv format). Unfortunately v2.9 doesn't give you an easy way to save this in a file. Instead the script outputs the values to the console (so you have to start xProcess with a console window). Once the output has been produced you then have to cut and paste the data into a csv file -- yes that's the "clonky" bit. Still it doesn't take a moment and you then have the data in a spreadsheet where you can mess with it to your heart's content. Brill!

All I want now is v3 so I can get this sort of report through a nice clean user interface. Here's the script...
"-- Output to console action - summarises task information --",

#categoryName ='Importance',
#category = #this.getProcess().getCategoryTypeByName(#categoryName),

#output='\n\nTabular output for: ' + getName() +'\n'+
'Name,'+
'Parent Task,'+
'Start,'+
'End,'+
'Target End,'+
#categoryName + (#category==null ? ' (WARNING - no such category)' : '') +','+
'Size (points),'+
'Estimate (person-hours),'+
'Actual/Planned (person-hours),'+
'Actual to date (person-hours),'+
'Closed?,'+
'Assigned to' +
'\n',

"-- First define the different functions for Leaf and Parent tasks --",

#leafOutput = :[
#output = #output +
name +','+
parent.name +','+
start +','+
end50 +','+
(targetEnd==null ? '' : targetEnd) +','+
(#cat=getCategoryInType(#category), #cat ==null ? '' : #cat.label) +','+
size + ','+
estimateOfEffort/60.0 +','+
bookedTime/60.0 +','+
bookedTimeToDateIncludingConfirmedTimeToday/60.0 +','+
closed,
getCurrentManualAssignments().{#output = #output + ',' + person.label},
#output = #output + '\n'
],

#parentOutput = :[
#output = #output +
'REST OF ' + name +','+
(parent==null ? '' : parent.name) +','+
start +','+
end50 +','+
(targetEnd==null ? '' : targetEnd) +','+
(#cat=getCategoryInType(#deliveryCategory), #cat ==null ? '' : #cat.label) +','+
(topDown ? (#result = size - sizeRolledUpFromChildren, #result>0 ? #result : 0) : '') + ','+
(topDown ? (#effort = estimateOfEffort - estimateOfEffortRolledUpFromChildren, #effort>0 ? #effort/60.0 : 0) : '') + ','+
bookedTime/60.0 +','+
bookedTimeToDateIncludingConfirmedTimeToday/60.0 +','+
closed,
getCurrentManualAssignments().{#output = #output + ',' + person.label},
#output = #output + '\n'
],

"-- Then process all the tasks, including the one selected --",

#tasks = getAllTasks(),
#tasks.add(#this),
#tasks.{
#this.isDesignatedAsParent() ? #parentOutput(#this): #leafOutput(#this)
},
#$sysout.println(#output),

"-- Inform the user where the output is",

#$dialog.informUser('Output to console: ' + getName(), 'The result of this action has been sent to the console.\nCut and paste the output into a Spreadsheet and use Data->Text to Columns... to create the table.\n\n'+
'Note: If you do not have a visible console, close xProcess and restart it from a command line window, or run xProcess with a console by adding "- console" to the target command. (E.g. on a Windows machine the Target field of the shortcut should look something like:\n\n"C:\\Program Files\\Ivis\\xProcess 2\\xProcess\\xprocess.exe" -console')
Note: one of the columns this scripts outputs is a category value ("Importance"). You could use the same pattern to display other relevant categories - "Target Delivery" for example if this was a category defined in your data.

No comments:

Breakout sessions that ensure everyone in the meeting meets everyone else

Lockdown finds us doing more and more in online meetings, whether it's business, training, parties or families. It also finds us spendin...