It's all about the answers!

Ask a question

Adding approvals to work item in precondition (server side)

Morten Madsen (3052844) | asked Aug 15 '13, 7:18 a.m.
edited Aug 15 '13, 7:19 a.m.
Hi, I'm trying to create a plugin which will automatically add an approval to a work item, if the plugin detects a certain status change.

Right now the code is experimental, and should add an approval to ALL status changes, but I can't get it to work. The entire operation runs fine, but no approvals are saved in the work item:

Object obj = operation.getOperationData();
SaveParameter data = (SaveParameter) obj;
// getting standard utilities
IWorkItemServer ws = getService(IWorkItemServer.class);			
IAuditableCommon wiCommon = ws.getAuditableCommon();
IRepositoryItemService rs = getService(IRepositoryItemService.class);
IAuditableServer as = getService(IAuditableServer.class);
// getting work item info
IWorkItem wi_old = (IWorkItem) data.getOldState();
IWorkflowInfo wfInfo_old = ws.getWorkflow(wi_old.getWorkItemType(), wi_old.getProjectArea(), monitor);
String workItemState_old = wfInfo_old.getStateName(wi_old.getState2());
IWorkItem wi = (IWorkItem) data.getNewState();
IWorkflowInfo wfInfo = ws.getWorkflow(wi.getWorkItemType(), wi.getProjectArea(), monitor);
String workItemState = wfInfo.getStateName(wi.getState2());
// if no state change occurred -> exit this advisor
if (workItemState.equals(workItemState_old))
wi_old = (IWorkItem) wi_old.getWorkingCopy();

IApprovals approvals= wi_old.getApprovals();
IApprovalDescriptor descriptor= approvals.createDescriptor(WorkItemApprovals.REVIEW_TYPE.getIdentifier(), "My approval");
IApproval approval= approvals.createApproval(descriptor, wi_old.getOwner());

ws.saveWorkItem2(wi_old, ws.resolveWorkItemReferences(wi_old, monitor), null);
IAdvisorInfo info = collector.createProblemInfo("WorkItem ("+wi.getId()+") - new state ["+workItemState+"]", "bla bla bla", this.getClass().getName());
Any ideas why this won't work?

Thanks a lot

Accepted answer

permanent link
sam detweiler (12.5k6189201) | answered Aug 15 '13, 7:39 a.m.
you are saving the OLD workitem contents, which then get overlayed by the NEW workitem contents.
ws.saveWorkItem2(wi_old, ws.resolveWorkItemReferences(wi_old, monitor), null);

also, watch out, your 'save' SHOULD cause your plugin to get called again.  you should use saveWorkitem3 with the ability to pass a parameter
Morten Madsen selected this answer as the correct answer

Morten Madsen commented Aug 15 '13, 7:51 a.m. | edited Aug 15 '13, 7:51 a.m.

Thanks for your answer. You are right in both cases. Yes, I save the old workitem because I will not allow the status change. But I add approvals to this old state and execute another save operation which will in turn invoke my advisor again.

This invocation however will not do anything because oldStatus == newStatus. This save operation will then return to the first invocation of the advisor which will deny the state transition. Shouldn't this work?

If this will not work, how can I: 1. preserve the old state (deny any changes to status), 2. add a new approval?

sam detweiler commented Aug 15 '13, 8:02 a.m.

good question.

you are in an advisor (which should not change the workitem)
you change the workitem (save2)
then reject the original change.

I do not know what happens to the original workitem contents on the rejection.

Morten Madsen commented Aug 15 '13, 8:30 a.m.

Thanks for trying anyway :).

What I CAN do though is add the approval to the new state and then let the action go through. But can I change the state to the old one? I can see that IWorkItem.setState2() is deprecated. I now have to add the workflow action to saveWorkItem2(). But this actually means, that you cannot change the workflow action during a save operation?

Tim Mok commented Aug 15 '13, 9:07 a.m.

It doesn't sound like saving a work item during a work item precondition is a good idea. The precondition runs before the work item save and you save the work item again in the precondition. This would cause the precondition to run again, which causes another work item save.

The precondition is there to enforce a process. I think it would be better to check if the conditions are met and let the user retry the work item save after addressing the conditions.

Morten Madsen commented Aug 15 '13, 10:00 a.m.

I agree. I've changed my process now.

What I really want is to make the user confirm that he really wants to do this status change (which will trigger automatic build and code generation + deployment on mainframe).

In case of a very large number of re-generations (for example if one change a common include file) then I want to be sure, that the user understands the consequence.

I've decided to implement it as an error message blocking the status change saying "please add comment stating "FORCE_GENERATE"". This will happen very rarely so I think it's a good tradeoff. The server will then add a comment "Forcing generation of XX targets" when the automatic build begins.

Your answer

Register or to post your answer.