Is it possible to configure RTC to automatically create an approval based on an enumeration literal using the value of another attribute as the title?
Hello,
I am using CLM Suite 6.0.6.
I have a customer request to configure RTC to create an approval when a primary attribute on a work item is set to a particular literal. Not only this, but also to configure the behavior so that the name of each approval created by RTC is the value of a secondary attribute on the work item. I haven't seen this use case discussed anywhere and since I am not proficient in extending, I was curious as to if this is even possible to configure as a precondition or participant. If it is possible, what level of difficulty would the extension be compared to the solution provided here:
Any information is greatly appreciated.
Accepted answer
Yes, that can be done. You need a server extension (participant/follow up action). It can likely be done using unsupported JavaScript in the Web UI as well. Davyd is talking about that.
In addition to the post you cite, https://rsjazz.wordpress.com/ contains posts how to get started with server extension development (workshop) and several examples how to access work item attribute values.
2 other answers
Too long to post as a comment...
If you have access to the server then Ralph's approach is by far the best, as it translates well to all clients, but it's tough when you're on a SaaS instance.
The following JavaScript snippet creates a new approval via the undocumented WorkItemProxy - use at your own risk and peril!!! If you don't know what you're doing then Bad Things(tm) can happen!
The two Utils functions are used to check whether the approval already exists, and to retrieve a list of internal user ids that need to be added to the approval - in my Utils function this is done based on their assigned role in the team associated with the Filed Against category.
/*******************************************************************************
* CLM workitem customisation scripts
* (c) Copyright Davyd Norris 2019. All Rights Reserved.
*
******************************************************************************/
dojo.require("com.ibm.team.workitem.api.common.WorkItemAttributes");
dojo.require("og.Utilities");
(function() {
var WorkItemAttributes = com.ibm.team.workitem.api.common.WorkItemAttributes;
var Utils = og.Utilities;
var createApproval = function(workItem, title, filedAgainst, role, type) {
if (Utils.hasApprovalBeenCreated(title)) {
return;
}
var dueDate = new Date();
var newApproval = {
cumulativeState : "com.ibm.team.workitem.approvalState.pending",
approvalType : 'com.ibm.team.workitem.approvalType.' + type,
dueDate : dueDate.setDate(dueDate.getDate() + 2),
name : title,
approvals : [],
_isNew : true
};
Utils.getCategoryList('projects')
.then(function(projects) {
var teamArea = projects.find(function(item) {
return item.id === filedAgainst;
}).teamArea;
return Utils.getTeamMembersWithRole(teamArea, role);
})
.then(function(members) {
for (var i = 0; i < members.length; i++) {
newApproval.approvals.push({
approver : {
itemId : members[i]
},
state : 'com.ibm.team.workitem.approvalState.pending',
_isNew : true
});
}
var newId = workItem.getProxy().getValue( {path :[ 'approvals' ],defaultValue:[]} ).length;
workItem.getProxy().setValue({
ignoreChange: false,
notifyEvenIfUnchanged:false,
path: ['approvals', newId],
value: newApproval
});
workItem.getProxy().storeWorkItem({
self : this,
operationMsg : "Saving",
applyDelta : true,
onSuccess : function(param) {
console.log("Approval Saved");
}
});
});
};
})();
* CLM workitem customisation scripts
* (c) Copyright Davyd Norris 2019. All Rights Reserved.
*
******************************************************************************/
dojo.require("com.ibm.team.workitem.api.common.WorkItemAttributes");
dojo.require("og.Utilities");
(function() {
var WorkItemAttributes = com.ibm.team.workitem.api.common.WorkItemAttributes;
var Utils = og.Utilities;
var createApproval = function(workItem, title, filedAgainst, role, type) {
if (Utils.hasApprovalBeenCreated(title)) {
return;
}
var dueDate = new Date();
var newApproval = {
cumulativeState : "com.ibm.team.workitem.approvalState.pending",
approvalType : 'com.ibm.team.workitem.approvalType.' + type,
dueDate : dueDate.setDate(dueDate.getDate() + 2),
name : title,
approvals : [],
_isNew : true
};
Utils.getCategoryList('projects')
.then(function(projects) {
var teamArea = projects.find(function(item) {
return item.id === filedAgainst;
}).teamArea;
return Utils.getTeamMembersWithRole(teamArea, role);
})
.then(function(members) {
for (var i = 0; i < members.length; i++) {
newApproval.approvals.push({
approver : {
itemId : members[i]
},
state : 'com.ibm.team.workitem.approvalState.pending',
_isNew : true
});
}
var newId = workItem.getProxy().getValue( {path :[ 'approvals' ],defaultValue:[]} ).length;
workItem.getProxy().setValue({
ignoreChange: false,
notifyEvenIfUnchanged:false,
path: ['approvals', newId],
value: newApproval
});
workItem.getProxy().storeWorkItem({
self : this,
operationMsg : "Saving",
applyDelta : true,
onSuccess : function(param) {
console.log("Approval Saved");
}
});
});
};
})();
This is how you would use the function somewhere in your attribute customisation script (this one creates a Review type of approval):
var projId = workItem.getValue(WorkItemAttributes.FILED_AGAINST);
createApproval(workItem, 'Project Director Assessment', projId, 'Project Director', 'review');
createApproval(workItem, 'Project Director Assessment', projId, 'Project Director', 'review');