Jazz Forum Welcome to the Jazz Community Forum Connect and collaborate with IBM Engineering experts and users

Restrict parent-child links between work items?

 Hi team.

Example: My use model says that the hierarchy should be:
Epic -> Story -> Task -> Defect

But in some cases where the user forgets to link the work items or are linking wrong.
Example: Epic -> Defect

They already have created templates, but are very useful just when I start a new dev project.

What I need:
Restrict only the links defined in my use model to be created.

Defects can only be children of Task.
Tasks can only be children of Story.
Story can only be children of Epic.

Tks
JG

0 votes

Comments

Ralph and Nate, tks a lot.


I understood that there is no built-in option.
I will study and adapt Nate solution.

Ralph, by chance, I am also reading your blog today to another problem: Deliver on the wrong workitem. Tks again.
:-)
Restrict Delivery of Changesets Associated to Wrong Work Item Types Advisor


Accepted answer

Permanent link

I implemented something very similar to this in our environment. We had a certain usage model for how we expected work items to be linked to one another in a plan. If users didn't conform to this usage model, our earned value reports wouldn't display correctly. To try and teach people the correct usage model, we implemented a precondition that throws warnings (not errors) if a user violates the expected link relationships. Here's my code:

package com.smxg.opex.clm;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;

import com.ibm.team.links.common.IReference;
import com.ibm.team.process.common.IProcessConfigurationElement;
import com.ibm.team.process.common.advice.AdvisableOperation;
import com.ibm.team.process.common.advice.IAdvisorInfo;
import com.ibm.team.process.common.advice.IAdvisorInfoCollector;
import com.ibm.team.process.common.advice.runtime.IOperationAdvisor;
import com.ibm.team.repository.common.IAuditable;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.ibm.team.repository.service.AbstractService;
import com.ibm.team.workitem.common.IAuditableCommon;
import com.ibm.team.workitem.common.ISaveParameter;
import com.ibm.team.workitem.common.internal.workflow.WorkflowManager;
import com.ibm.team.workitem.common.model.IWorkItem;
import com.ibm.team.workitem.common.model.IWorkItemHandle;
import com.ibm.team.workitem.common.model.WorkItemEndPoints;
import com.ibm.team.workitem.common.workflow.IWorkflowInfo;
import com.ibm.team.workitem.service.IWorkItemServer;

public class EnforceEarnedValueUsageModel extends AbstractService implements IOperationAdvisor
{
 boolean Debug = false;
 @Override
 public void run(AdvisableOperation operation, IProcessConfigurationElement advisorConfiguration, IAdvisorInfoCollector collector, IProgressMonitor monitor) throws TeamRepositoryException
 {
  if(advisorConfiguration.getAttribute("description") != null) Debug = advisorConfiguration.getAttribute("description").contains("DEBUG");
  if(Debug) System.out.println("EnforceEarnedValueUsageModel advisor has been triggered.");
  
  Object data = operation.getOperationData(); 
  if (!(data instanceof ISaveParameter)) return;
  
  ISaveParameter saveParameter = (ISaveParameter) data;  
  IAuditable auditable = saveParameter.getNewState();
  if(!(auditable instanceof IWorkItem)) return;

  IAuditableCommon iac = saveParameter.getSaveOperationParameter().getAuditableCommon();
  IWorkItem workItem = (IWorkItem) auditable;
  
  //If there is no parent work item, we don't need to worry about any further validating. We can just exit.
  List<IReference> ParentReferenceList;
  if(saveParameter.getNewReferences().hasReferences(WorkItemEndPoints.PARENT_WORK_ITEM)) {
   ParentReferenceList = (ArrayList<IReference>) saveParameter.getNewReferences().getReferences(WorkItemEndPoints.PARENT_WORK_ITEM);
  } else {
   if(Debug) System.out.println("There is no parent work item. No rules will be verified.");
   return;
  }  
  
  //We're only interested in validating a few types of work items: Task, Task with Approval, Sub Task, Plan Item, Change Request
  String WI_TypeID = workItem.getWorkItemType();
  if(Debug) System.out.println("The work item type is: " + WI_TypeID);
  if(!WI_TypeID.equals("omr.309.mat.workitem.workItemType.plan_item") && !WI_TypeID.equals("omr.309.mat.workItemType.sub_task") && !WI_TypeID.equals("task") && !WI_TypeID.equals("omr.309.mat.workItemType.task_with_approval") && !WI_TypeID.equals("omr.309.mat.workItemType.change_request")) {
   if(Debug) System.out.println("No rules are verified for this work item type.");
   return;
  }
  
  //Let's figure out what this work item's parent is.
  IReference ParentRef = ParentReferenceList.get(0);
  IWorkItem ParentWI = iac.resolveAuditable((IWorkItemHandle)ParentRef.resolve(),IWorkItem.FULL_PROFILE, null);
  String ParentTypeID = ParentWI.getWorkItemType();
  
  //Verify that plan items (Change Request, and Plan Item) are not children of execution items
  if(WI_TypeID.equals("omr.309.mat.workitem.workItemType.plan_item") || WI_TypeID.equals("omr.309.mat.workItemType.change_request")) {
   if(!ParentTypeID.equals("omr.309.mat.workitem.workItemType.plan_item") && !ParentTypeID.equals("omr.309.mat.workItemType.change_request")) {
    IAdvisorInfo createProblemInfo = collector.createProblemInfo("Plan Items Must Be Children of Other Plan Items", "The work item you are trying to save is a type of \"plan item\", but the parent of this work item is an \"execution item\". Plan items should only be children of other plan items to ensure complexity roll-up functions correctly.", "error");
    collector.addInfo(createProblemInfo);
    return;
   }
  }
  //Check that the user isn't trying to save a Task as a child of another Task.
  if(WI_TypeID.equals("task") || WI_TypeID.equals("omr.309.mat.workItemType.task_with_approval")) {
   if(ParentTypeID.equals("task") || ParentTypeID.equals("omr.309.mat.workItemType.task_with_approval")) {
    IAdvisorInfo createProblemInfo = collector.createProblemInfo("Tasks Must Not Be Children of Other Tasks", "The earned value usage model, which must be adhered to for the CLM Earned Value report to work correctly, stipulates that Tasks cannot be children of other Tasks. Change the parent work item to a Plan Item and try again.", "error");
    collector.addInfo(createProblemInfo);
    return;
   }
  }
  //Check whether the user is trying to save a Sub Task below another Sub Task.
  if(WI_TypeID.equals("omr.309.mat.workItemType.sub_task") && ParentTypeID.equals("omr.309.mat.workItemType.sub_task")) {
   IAdvisorInfo createProblemInfo = collector.createProblemInfo("Sub Tasks Must Not be Children of Other Sub Tasks", "The earned value usage model, which must be adhered to for the CLM Earned Value report to work correctly, stipulates that Sub Tasks cannot be children of other Sub Tasks. Change the parent work item to a Task and try again.", "error");
   collector.addInfo(createProblemInfo);
   return;
  }
  if(WI_TypeID.equals("omr.309.mat.workItemType.sub_task") && (ParentTypeID.equals("omr.309.mat.workitem.workItemType.plan_item") || ParentTypeID.equals("omr.309.mat.workItemType.change_request"))) {
   IAdvisorInfo createProblemInfo = collector.createProblemInfo("Sub Tasks Must Not be Children of Planning Items", "The earned value usage model, which must be adhered to for the CLM Earned Value report to work correctly, stipulates that Sub Tasks cannot be direct children of Planning work item types. Use a Task work item type instead.", "error");
   collector.addInfo(createProblemInfo);
   return;
  }
 }
}

Ralph Schoon selected this answer as the correct answer

1 vote

Comments

Thanks for sharing Nate. I am tempted to use this and make it a little bit more configurable to be able to publish it. For now I linked back from my blogs interesting links page.


One other answer

Permanent link
You will have to create operational behavior (advisors) that check on work item save, if the rules are kept. There are potential issues with such a construct as well. E.g. you can change the type of a work item. This change can make links that where perfectly fine before illegal.

Start here to find out about extending RTC: https://rsjazz.wordpress.com/2015/09/30/learning-to-fly-getting-started-with-the-rtc-java-apis/

0 votes

Your answer

Register or log in to post your answer.

Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.

Search context
Follow this question

By Email: 

Once you sign in you will be able to subscribe for any updates here.

By RSS:

Answers
Answers and Comments
Question details
× 12,020

Question asked: Mar 14 '16, 9:28 a.m.

Question was seen: 3,075 times

Last updated: Mar 14 '16, 4:06 p.m.

Confirmation Cancel Confirm