Thursday, December 13, 2007

Documentum Workflow: Reporting History by Document

Issue:
Tracking workflow status by document from Webtop’s Properties/History tab.

Requirements:
Allow a user to select a document in Webtop and click on Properties/History to view the document’s workflow history.

Solution History:
Webtop: Out-of-box workflow functionality which requires running the dm_WFReporting job and auditing events.

Report: Properties/History
Location: Select Workflow task and go to Properties/History
You’ll get a list of the work activities, there date/time stamps and who performed it.

Report: Workflow Reporting
Location: Tools/Workflow/Workflow Reporting
Attributes: Workflow Name, Status, Active, Task Name, Performer, Supervisor
Edit Report:
User – select a user
Document – select a document by drilling down folders
Template – select a workflow template
Show overdue, all, running, or completed workflows

Report: Historical Report (Process or User)
Location: Tools/Workflow/Historical Report/Process or User
Form options:

  • Display statistics for business process running
  • From: To:
  • Include only process where these conditions are met
  • Process Template name contains: type in text
  • Or User contains: type in text
  • Workflow Supervisor is: select user
  • Duration: select operater and type in days, hours, minutes
  • Cost: select operator and type in number
  • Location is: select folder

WorkQueue Monitor
Location: Select Workflow task and go to Properties/History
Functionality: You’ll get a list of the work activities, there date/time stamps and who performed it.

Solution:
Create a custom Package_History table
Purpose: This is necessary because the link between the workflow instance and the package id (the content id) is lost after the workflow is complete. This provides the track record of workflow’s packages during the workflow activity and after the workflow is complete.

Create a custom Workflow_History table
Purpose: To keep track of workflow queue items. We decided to store all workflow related queue events in a custom table to assure that the historical information for the workflow activities would not be deleted by the queue management job.

Query the workflow history based on the following steps

  1. Look up the workflow instance ID from the custom package history table based on the Object ID.
  2. Select attributes from the custom workflow history table
  3. Union these results with a selection from the dmi_queue_item table

Present the User with the following information about the document’s workflow history
Date: Timestamp of action
Work Queue: Name of the work queue or activity
Performer: Name of the user who performance the task
Action: The event status of the activity

Changes to Webtop
Component changes
· Make a copy of the history_component.xml to the custom folder and extend for the original configuration file, and point the behavior to the new class
· Set “String_3” to true: true so it will show up on the jsp page.


Create a custom component behavior class
The main customization is with the query string method:

protected String getQuery(String strVisibleAttrs, ArgumentList args)
{
if(m_strSelectedVersionObjectId == null)
m_strSelectedVersionObjectId = m_strObjectId;
String strWhere = m_strQueryConditionFormat;
strWhere = StringUtil.replace(strWhere, "{r_object_id}", "'" +
m_strSelectedVersionObjectId + "'");
StringBuffer buf = new StringBuffer(128);
buf.append("SELECT ");
buf.append(strVisibleAttrs);
buf.append("'1' as dummy");
buf.append(" FROM dm_dbo.wf_history_s WHERE ");
buf.append(strWhere);
buf.append(" OR workflow_id in (select r_workflow_id ");
buf.append(" from dm_dbo.package_history ");
buf.append(" where r_component_id = '"+m_strObjectId+"' ) ");
buf.append(" UNION ");
buf.append(" SELECT sent_by as user_name, task_name as event_name,
task_state as string_3, date_sent as time_stamp, '1' as dummy ");
buf.append(" FROM dmi_queue_item");
buf.append(" WHERE router_id in ");
buf.append(" (select r_workflow_id ");
buf.append(" from dm_dbo.package_history ");
buf.append(" where r_component_id = '"+m_strObjectId+"' ) ");
buf.append(" ORDER BY 4 ASC");

System.out.println("Query: "+buf.toString());
return buf.toString();
}

Component Presentation Changes
The history.jsp file is copied and moved the custom folder in /custom/webcomponet/library/history

Friday, December 7, 2007

Documentum Workflow: Queue Management

Overview
In Workflows, each work item or task has to be managed, maintained and tracked. As workflows are executed and performed, there are certain aspects of managing these tasks that are not straight forward and are definitely not offered out-of-the-box with Webtop.

Management:

Issue:
Work queue tasks could be acquired then left unattended unless a scheduled job runs to determine whether the user who acquired the task is still using the system or has left for the day.

Solution History:

First Attempt:
The first fix was to customize the logout functionality of Webtop to set the work item (task) to the “putback” auto-activity. The “putback” auto-activity then gets the work item’s sequence number and subtracts 1 from it and sets the work item back to the previous activity.

First Attempt Issues:
This does not take into account user’s who X out of their browser without logging out. It also doesn’t scale.

Follow Up Attempt:
We decided to create a scheduled job which would execute a java method that “unacquired” the work items, like the “unassign” functionality in the Work Queue Monitor page on Webtop. This required some reverse engineering of the existing unassign class to figure which services and api’s were used and the objects and jars required. This also required looking at DA’s User Session functionality and bringing that in as well. Here are the components of this solution:

Documentum Objects
dm_job
dm_method

Java classes

Class: public class TimeoutPutBackMethod implements IDmMethod

Methods:

execute(Map params, OutputStream output)

- This is the main dm_method execution method which excepts parameters sent from the job and an output stream which ends up as a report written to the “Temp/Jobs// log files.

getAllActiveSessions(session, output)

- This method uses DfSessionCommand object to get all of the active sessions on the repository.
- This also queries the a_held_by (Username who acquired it) values of the work items to figure out which work items should be unassigned.

unAssignWorkflowTasks(IDfSession session, String UserName, String sDCTMDocbase, OutputStream output)

- Calls the getWQName method to lookup the work queue name based on the activity name.
- Calls UnassignQueuedTask.unassignTasks

getWQName(IDfSession session, String ActivityName)
- queries the dm_activity table looking for the performer (work queue name) based on the activity name.

Class: public class UnassignQueuedTask

Method:
unassignTasks(IDfSession m_session, String m_taskId, String m_queueName, String m_docbase, OutputStream output)

- This method constructs a work queue manager service and work queue object to unassign the work item.

Non-standard APIs used
import java.io.OutputStream;
Used for outputting strings to a job report file.
import com.documentum.services.workqueue.IWorkQueue;
This is used to construct a workqueue and unassign it
import com.documentum.services.workqueue.IWorkQueueMgmt;
This is used to construct a workqueue manager service
import com.documentum.mthdservlet.IDmMethod;
Used to implement this method and to be able to execute it as a dm_method object
import com.documentum.admin.commands.DfSessionCommand;
This is used to get all of the active sessions in the repository