Skip to main content
Skip table of contents

zAgileConnect API – Transition Jira Issues from Salesforce – Usage & Examples

Please note that zAgileConnect license is required for a user to invoke this API. The methods will throw a zsfjira.ZC.ZCApiLicenceException when executed by a user without a zAgileConnect license

Summary Steps

1. Retrieve the available Transitions for an Issue

CODE
zsfjira.ZCBeans.AvailableTransitionsResult availableTransitionsResult = zsfjira.ZC.Issues.getAvailableTransitions('SEL-1');

2. Create a Transition Issue Bean

CODE
zsfjira.ZCBeans.TransitionIssueBean transitionIssueBean = availableTransitionsResult.buildIssueTransitionFromName('In Progress');

3. Execute the Transition

CODE
zsfjira.ZCBeans.TransitionIssueResult transitionIssueResult = zsfjira.ZC.Issues.transitionIssue('SEL-1', transitionIssueBean);

1. Retrieve Available Transitions for an Issue

You can get the Available Transitions Names as follows:

CODE
zsfjira.ZCBeans.AvailableTransitionsResult availableTransitionsResult = zsfjira.ZC.Issues.getAvailableTransitions('SEL-1');
List<String> transtionsNames = availableTransitionsResult.getAvailableTransitionsNames();

In some scenarios you may want to retrieve all the available transitions metadata returned by Jira API. It can be done using the method getTransitionsData(), it will return the metadata as a Map<String, Object>

CODE
ZCBeans.AvailableTransitionsResult availableTransitionsResult = ZC.Issues.getAvailableTransitions('SEL-1019');
Map<String, Object> transtionsData = availableTransitionsResult.getTransitionsData();

The retrieved metadata looks like:

CODE
{    
       "transitions": [ 
              { 
                     "fields": {}, 
                     "to": {
                                    //...
                            },
                     "name": "Stop Progress",
                     "id": "301"      
               }, 
               {
                     "fields": 
                      { 
                          "assignee": {
                                        "operations": ["set"],
                                        "autoCompleteUrl": "....",
                                        "name": "Assignee",
                                        "schema": {
                                           "system": "assignee",
                                           "type": "user"
                                         },
                                        "required": false
                                        }
                       },
                       "to": {
                                     //..
                       },
                       "name": "Resolve Issue",
                       "id": "5"
               }    ],
        "expand": "transitions"
}

2. Create a Transition Issue Bean

There are two different ways of creating the Transition Issue Bean:

  • From the AvailableTransitionsResult, where you first retrieve the available transitions for the Issue and then create the Transition Bean for a particular Transition Name.
CODE
zsfjira.ZCBeans.AvailableTransitionsResult availableTransitionsResult = zsfjira.ZC.Issues.getAvailableTransitions('SEL-1');
zsfjira.ZCBeans.TransitionIssueBean transitionIssueBean = availableTransitionsResult.buildIssueTransitionFromName('In Progress');
  • From scratch specifying the Transition ID.

You can execute transition without calling first the getAvailableTransitions() method that retrieves Jira metadata, if you know the ID of the transition you want to try to execute. Please note the transitions that can be executed for an Issue depends on the Jira workflow, so it is possible that a transition can only be executed if the Issue has a specific status (for example an Issue can not execute the transitions “Close” if the issue is already closed).

You can create a IssueTransitionBean directly with the transition ID. Please note when setting transition screen field values (as described below) without retrieving the metadata for available Transitions you will need to set field values by its field ID (using setFieldById() method).

CODE
Integer transitionId = 41;//"Done" transition Id
zsfjira.ZCBeans.TransitionIssueBean transitionIssueBean = new zsfjira.ZCBeans.TransitionIssueBean(transitionId);
transitionIssueBean.setFieldById('resolution', new Map<String, String>{'name' => 'Fixed'});
transitionIssueBean.setFieldById('summary', 'The new summary');
zsfjira.ZCBeans.TransitionIssueResult transitionIssueResult = zsfjira.ZC.Issues.transitionIssue('OP-3165', transitionIssueBean);

2.1 Transition Screen Fields

Some Issue transitions may have a screen of fields configured in Jira, some of them may be required for the transition to be executed. You can set values for the Issue fields in the transition screen before executing the transition.

Getting Transition Screen Fields Names
CODE
zsfjira.ZCBeans.AvailableTransitionsResult availableTransitionsResult = zsfjira.ZC.Issues.getAvailableTransitions('OP-3165'); 
zsfjira.ZCBeans.TransitionIssueBean transitionIssueBean = availableTransitionsResult.buildIssueTransitionFromName('Done');
List<String> fieldsNames = transitionIssueBean.getFieldsNames();
Getting Required Transition Screen Fields Names
CODE
zsfjira.ZCBeans.AvailableTransitionsResult availableTransitionsResult = zsfjira.ZC.Issues.getAvailableTransitions('OP-3165'); 
zsfjira.ZCBeans.TransitionIssueBean transitionIssueBean = availableTransitionsResult.buildIssueTransitionFromName('Done');
List<String> requiredFeldsNames = transitionIssueBean .getRequiredFieldsNames();
Populating Transition Issue Screen Fields

You can populate transition Issue screen fields by using the ‘Issue Template’, just like the issue template used for creating or updating issues.

CODE
zsfjira.ZCBeans.IssueTemplate issueTemplate = new zsfjira.ZCBeans.IssueTemplate('OP-3165');
issueTemplate.setFixVersions(new zsfjira.ZCBeans.NameOrIdIssueFieldValue[]{new zsfjira.ZCBeans.NameIssueFieldValue('1.0.4')}); 
issueTemplate.setSummary('new summary for issue transitioned');
issueTemplate.setReporter(new zsfjira.ZCBeans.NameIssueFieldValue('zagile'));

zsfjira.ZCBeans.AvailableTransitionsResult availableTransitionsResult = zsfjira.ZC.Issues.getAvailableTransitions('OP-3165');
zsfjira.ZCBeans.TransitionIssueBean transitionIssueBean = availableTransitionsResult.buildIssueTransitionFromName('Done');
transitionIssueBean.populateFieldsWith(issueTemplate);
transitionIssueBean.setFieldByName('Resolution', new Map<String, String>{'name' => 'Fixed'});//you can also add more fields not supported in the issue template using the setFielByName or setFieldById
transitionIssueBean.setComment('A sample transition comment');
zsfjira.ZCBeans.TransitionIssueResult transitionIssueResult = zsfjira.ZC.Issues.transitionIssue('OP-3165', transitionIssueBean);

3. Execute the Transition

To execute the transition you will need to pass the Issuekey and the Transition Issue Bean described above

CODE
zsfjira.ZCBeans.TransitionIssueResult transitionIssueResult = zsfjira.ZC.Issues.transitionIssue('SEL-1', transitionIssueBean);

The execution will return a transition issue result that can be used for error handling.

3.1 Validate Transition Issue data before executing transition

You can validate and sanitize your Issue transition bean before trying to execute the transition. This will detect problems in the bean and try to correct them if possible. For example it will remove all transition screen fields that are not listed in the metadata and will return warning messages if there is a required field that is not set in the bean.

CODE
Integer transitionId = 41;// To Done
zsfjira.ZCBeans.TransitionIssueBean transitionIssueBean = new zsfjira.ZCBeans.TransitionIssueBean(transitionId);
try{
   String warningMessage = transitionIssueBean.validateAndSanitize();
}
catch (Exception e){
   System.debug(System.LoggingLevel.ERROR, e.getMessage()); 
}
CODE
zsfjira.ZCBeans.AvailableTransitionsResult availableTransitionsResult = zsfjira.ZC.Issues.getAvailableTransitions('OP-3165'); 
zsfjira.ZCBeans.TransitionIssueBean transitionIssueBean = availableTransitionsResult.buildIssueTransitionFromName('Start Progress');
transitionIssueBean.setFieldById('resolution', null);
try{
   String warningMessage = transitionIssueBean.validateAndSanitize();
}
catch (Exception e){
   System.debug(System.LoggingLevel.ERROR, e.getMessage()); 
}

The validateAndSanitize() will raise an Exception when a field has an empty value or there is not the metadata.

3.2 Error handling

The method hasError() returns ‘true’ if issue transition fails. The method getErrorMessage() returns the error message.

CODE
Integer transitionId = 41;// To Done
zsfjira.ZCBeans.TransitionIssueBean transitionIssueBean = new zsfjira.ZCBeans.TransitionIssueBean(transitionId);
transitionIssueBean.setFieldById('resolution', new Map<String, String>{'name' => 'Fixed'});
zsfjira.ZCBeans.TransitionIssueResult transitionIssueResult = zsfjira.ZC.Issues.transitionIssue('OP-3165', transitionIssueBean);
if(transitionIssueResult.hasError()){ 
    System.debug(System.LoggingLevel.ERROR, transitionIssueResult.getErrorMessage()); 
}

It may be also possible to run into some errors when trying to retrieve the available transitions, you can handle them as follows

CODE
zsfjira.ZCBeans.AvailableTransitionsResult availableTransitionsResult = zsfjira.ZC.Issues.getAvailableTransitions('SEL-1019');
if(availableTransitionsResult.hasError()){
    System.debug(System.LoggingLevel.ERROR, availableTransitionsResult.getErrorMessage());
}

3.3 License Handling

All operations included in this API require the user to have a valid zAgileConnect license. Try..Catch blocks below show how to catch license exceptions.

CODE
try{
    zsfjira.ZCBeans.AvailableTransitionsResult availableTransitionsResult = zsfjira.ZC.Issues.getAvailableTransitions('SEL-1019');
    zsfjira.ZCBeans.TransitionIssueBean transitionIssueBean = availableTransitionsResult.buildIssueTransitionFromName('Start Progress');
    zsfjira.ZCBeans.TransitionIssueResult transitionIssueResult = zsfjira.ZC.Issues.transitionIssue('SEL-1019', transitionIssueBean);
}catch(Exception exe){
    System.debug(System.LoggingLevel.ERROR, transitionIssueResult.getMessage()); 
    // Will indicate: User [Username] does need a zAgileConnect Licence to perform this operation.
}

Close a Jira Issue on Case Closed Example

CODE
trigger OnCaseClosedJiraIssuesTrigger on Case (after update) {
    List<Case> cases = new List<Case>();

    for(Case oldCase: Trigger.old){
        Case newCase = Trigger.newMap.get(oldCase.Id);
        if(oldCase.Status != newCase.Status && newCase.Status == 'Closed'){
            cases.add(oldCase);
        }
    }

    for(Case scase: cases){
        for ( zsfjira__ZIssue_SF__c issueSf :[SELECT zsfjira__ZIssue__r.zsfjira__IssueKey__c FROM zsfjira__ZIssue_SF__c WHERE zsfjira__Case__c = :scase.Id] ){
            CaseClosedJiraIssuesHandler.closeIssue(issueSf.zsfjira__ZIssue__r.zsfjira__IssueKey__c);
        }
    }
}


public class CaseClosedJiraIssuesHandler {
    
    @future (callout = true)
    public static void closeIssue(String issueKey){
        zsfjira.ZCBeans.AvailableTransitionsResult availableTransitions = zsfjira.ZC.Issues.getAvailableTransitions(issueKey);

        if(availableTransitions.getAvailableTransitionsNames().contains('Close Issue')){
            zsfjira.ZCBeans.TransitionIssueBean transitionIssueBean = availableTransitions.buildIssueTransitionFromName('Close Issue');
            transitionIssueBean.setFieldByName('Resolution', new Map<String, String>{'name' => 'Done'});
            transitionIssueBean.setComment('Closed by case closed');
            zsfjira.ZCBeans.TransitionIssueResult transitionIssueResult = zsfjira.ZC.Issues.transitionIssue(issueKey, transitionIssueBean);
        }
    }
}
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.