Check All Done

checkAllDone.groovy
/*
**  This groovy code shows how you can construct a scripted condition to show (or not show) a transition.
**  Always try it first on a test instance before applying it into production
**
**  This method is using the table grid editor rest api to retrieve necessary data
*/

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.properties.APKeys
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.fields.config.FieldConfigScheme
import com.atlassian.jira.util.json.JSONArray
import com.atlassian.jira.util.json.JSONObject
import org.apache.commons.io.IOUtils
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.utils.URIBuilder
import org.apache.http.impl.client.DefaultHttpClient
import com.opensymphony.workflow.InvalidInputException



/*
** Set following values to your own environment
** CUSTOM_FIELD_NAME = Name of the grid custom field you want to traverse
** COLUMN_INDEX = Index of the column which needs to be tested, the first column has index 0
** EXPECTED_VALUE = Value that the column should display
*/

String CUSTOM_FIELD_NAME = "Grid Default"
int COLUMN_INDEX = 2; 				
String EXPECTED_VALUE = "Done"

/*
** Let's make sure that we have a custom field
*/

def customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName(CUSTOM_FIELD_NAME);
if (customField == null) {
	log.error("Customfield ${CUSTOM_FIELD_NAME} is unknown")
    invalidInputException = new InvalidInputException("Customfield ${CUSTOM_FIELD_NAME} is unknown");
	return;
}

def customFieldId = customField.getId();

/*
** Setup of some global variables which are necessary to run 
*/

final String ROWS = "rows";
final String ENCODING = "UTF-8";
final String BASE_URL = ComponentAccessor.getApplicationProperties().getString(APKeys.JIRA_BASEURL);
final String REST_PATH = "/rest/idalko-igrid/1.0/datagrid/data";
def httpclient = new DefaultHttpClient();




def confSchemeId = getConfSchemeId(customField);
if (confSchemeId == null) {
	return;
}

def issueId = String.valueOf(issue.getId());

// the tempId is the id of the HQL table associated with this grid
def tempId = getTempId(issue, customField);
if (tempId == null) {
	return
}

if (!customFieldId.isEmpty() && !confSchemeId.isEmpty() && !tempId.isEmpty()) {
    log.debug("Accessing grid data on JIRA '${BASE_URL}' for issue '${issue.key}'");
    
    def uri = new URIBuilder()
            .setPath(BASE_URL + REST_PATH)
            .setParameter("_mode", "edit")
            .setParameter("_issueId", issueId)
            .setParameter("_fieldId", customFieldId)
            .setParameter("_confSchemeId", confSchemeId)
            .setParameter("_dataId", tempId)
            .build();

	/*
	** retrieving the complete grid 
	*/
	
    def httpGet = new HttpGet(uri);
    def response = httpclient.execute(httpGet);
    def contentInputStream = response.getEntity().getContent();
    def responseContent = IOUtils.toString(contentInputStream, ENCODING);
    JSONObject jsonObject = new JSONObject(responseContent);
    JSONArray rows = jsonObject.getJSONArray(ROWS);
	
	log.debug("Retrieving rows from grid resulting in " + rows)

	/*
	** Traversing all the row, checking if the column is set to 'Done'
	*/
	
    for (int i = 0; i < rows.length(); i++) {

        def jSONObject = rows.getJSONObject(i);
        def cells = jSONObject.getJSONArray("cell");
        def cellValue = cells.get(COLUMN_INDEX);

        if (!EXPECTED_VALUE.equals(cellValue)) {
            invalidInputException = new InvalidInputException("Not all values have been set to '${EXPECTED_VALUE}'");
			return;
        }
    }
}


/*
** Some helper methods allowing to retrieve appropriate information
*/


private String getConfSchemeId(CustomField field) {
    final List<FieldConfigScheme> configurationSchemes = field.getConfigurationSchemes();

    if (configurationSchemes.isEmpty()) {
		log.error("No config scheme found for field ${field.getName()}");
		invalidInputException = new InvalidInputException("No configscheme found");
		return null;
    }

    return String.valueOf(configurationSchemes.iterator().next().getId());
}

private String getTempId(Issue issue, CustomField customField) {
    def commandsString = issue.getCustomFieldValue(customField);
	
    if (commandsString == null) {
		log.error("The grid commands string is empty ...");
		invalidInputException = new InvalidInputException("The grid commands string is empty");
		return null;
	}
	
	def tempIdExtractor = (commandsString =~ /tempId","(\w+)"/)
	if (! tempIdExtractor.hasGroup()) {  
		log.error("tempId not located in commandstring '${commandsString}'... probably a bug");
		invalidInputException = new InvalidInputException("tempId not located in commandstring ... probably a bug");
		return null; 
	}
	
	log.debug("tempId = " + tempIdExtractor[0][1])
	return tempIdExtractor[0][1]	
}