script within postfunction does not execute

Alexander Becker August 19, 2015

Hi,

I started developing scripts in JIRA server 6.2.4, using the groovy scriptrunner plugin.

I want to populate a custom field (multi-line text - id: customfield_11170) with data from other custom fields on the "create issue"-screen, so that the populated field shows up on the "view issue"-screen.

When adding the following script code to a "invisible" scripted field placed on "create issue"-screen, all happens as supposed :

_______________________________________________

import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.util.IssueChangeHolder
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue


// getting related issue
MutableIssue myIssue = issue


CustomFieldManager customFieldManager = componentManager.getCustomFieldManager()


// retrieving values from custom fields
    // summary
String summary = myIssue.summary
    //date
CustomField dateField = customFieldManager.getCustomFieldObject("customfield_10874")
String date = myIssue.getUpdated()
    // assignee
CustomField assigneeField = customFieldManager.getCustomFieldObject("assignee")
String currentAssignee = myIssue.getAssignee().getName()
    // correspondence category
CustomField categoryField = customFieldManager.getCustomFieldObject("customfield_10780")
String category = myIssue.getCustomFieldValue(categoryField)
    // correspondence field "from"
CustomField vonField = customFieldManager.getCustomFieldObject("customfield_10871")
String von = myIssue.getCustomFieldValue(vonField)
    // correspondence field "to"
CustomField zuField = customFieldManager.getCustomFieldObject("customfield_10872")
String zu = myIssue.getCustomFieldValue(zuField)


// predefined table header -> gets to be a "table"
String header = "||Datum||Name||Kategorie||von||zu||Zusammenfassung||\n"


// concatenating new table row data -> gets to be a "table row" to add to table
String newValue = header + "|" + date + "|" + currentAssignee + "|" + category + "|" + von + "|" + zu + "|" + summary + "|\n"


// updating value in custom field "short description" (customfield_11170)
if(summary != null){
    
    CustomField dstSummaryField = customFieldManager.getCustomFieldObject("customfield_11170")
    IssueChangeHolder ich = new DefaultIssueChangeHolder()
    ModifiedValue mv = new ModifiedValue("",newValue)
    dstSummaryField.updateValue(null,myIssue,mv,ich)    
    
}


return newValue // not necessary, could be null, the cripted field does not have to be populated itself

 

________________________________________________________

so, THAT works. The table is generated and populated.

 

My Problem:

Adding a "similar script" to ANOTHER scriptedfield ONLY placed on the another screen "modify issue" (transition screen, so each scripted field is on ONE transition screen) results in executing the first script to, but the first one is placed on the "create issue screen", and I don't know why it executes on the second transition, too!

I thought, placing ONE scripted field to ONE screen only results in executing the related script ONLy on this transition and not everytime...?!??

So I decided to separate both script functionalities to place them each "as a postfunction" to the transitions WHERE they should execute. -> script1 for create-issue-transition and script2 for modify-issue-transition.

But placing script1 (above) as a postfunction doesn't seem to do anything, the result is "no String in customfield_11170, so -> no table generated.

 

What do I understand wrong on using the scripted fields or using postfunctions?

Anyone out ther, who can help.

 

Thanks alot.

Regard,

Alexander

 

9 answers

1 vote
Guilherme Nogueira
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 20, 2015

Well, I didn't tested it but check out:

 

 

import com.atlassian.jira.issue.Issue

import com.atlassian.jira.issue.MutableIssue

import com.atlassian.jira.issue.IssueManager

import com.atlassian.jira.ComponentManager

import com.atlassian.jira.issue.CustomFieldManager

import com.atlassian.jira.issue.fields.CustomField

import com.atlassian.jira.issue.util.IssueChangeHolder

import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

import com.atlassian.jira.issue.ModifiedValue

 

 

// getting related issue

MutableIssue myIssue = issue

 

 

CustomFieldManager customFieldManager = componentManager.getCustomFieldManager()

 

 

// retrieving values from custom fields

    // summary

String summary = myIssue.summary

    //date

CustomField dateField = customFieldManager.getCustomFieldObject("customfield_10874")

String date = myIssue.getUpdated()

    // assignee

CustomField assigneeField = customFieldManager.getCustomFieldObject("assignee")

String currentAssignee = myIssue.getAssignee().getName()

    // correspondence category

CustomField categoryField = customFieldManager.getCustomFieldObject("customfield_10780")

String category = myIssue.getCustomFieldValue(categoryField)

    // correspondence field "from"

CustomField vonField = customFieldManager.getCustomFieldObject("customfield_10871")

String von = myIssue.getCustomFieldValue(vonField)

    // correspondence field "to"

CustomField zuField = customFieldManager.getCustomFieldObject("customfield_10872")

String zu = myIssue.getCustomFieldValue(zuField)

 

 

// predefined table header -> gets to be a "table"

String header = "||Datum||Name||Kategorie||von||zu||Zusammenfassung||\n"

 

 

// concatenating new table row data -> gets to be a "table row" to add to table

String newValue = header + "|" + date + "|" + currentAssignee + "|" + category + "|" + von + "|" + zu + "|" + summary + "|\n"

 

 

 

// updating value in custom field "short description" (customfield_11170)

if(summary != null){

     

    CustomField dstSummaryField = customFieldManager.getCustomFieldObject("customfield_11170")

    IssueChangeHolder ich = new DefaultIssueChangeHolder()

    ModifiedValue mv = new ModifiedValue("",newValue)

    dstSummaryField.updateValue(null, myIssue, new ModifiedValue(myIssue.getCustomFieldValue(dstSummaryField), newValue), ich)  

     

}

 

A few comments about your code:

This line:

CustomField assigneeField = customFieldManager.getCustomFieldObject("assignee")

Will return null, "assignee" is not a custom field. To get assignee use myissue.getAssignee() or something.

 

Those two lines:

ModifiedValue mv = new ModifiedValue("",newValue)

    dstSummaryField.updateValue(null,myIssue,mv,ich)

Using modified value you must to inform through function the object custom field, so the correct thing will be:

 

 ModifiedValue mv = new ModifiedValue(YOURCUSTOMFIELDHERE,newValue)

 

i made a few changes and it should work, you don't need return anymore. Although due this return your first solution worked.

 

I hope it helps.

 

BR.

Guilherme Nogueira.

 

 

0 votes
JamieA
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 22, 2015

You don't want a script field, you want a post-function. There's no such thing as an invisible script field - script fields are not present on screens where you can edit, eg create issue.

0 votes
Guilherme Nogueira
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 21, 2015

Actually ComponentManager is deprecated. Atlassian recommend to use only component ComponentAccessor.

0 votes
Guilherme Nogueira
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 21, 2015

Great. But talking about ComponentManager you can replace by using component acessor. Like this: OptionsManager optionsManager = ComponentAccessor.getComponent(OptionsManager.class); ComponentAccessor.getCustomFieldManager().getCustomFieldObject("customfield_12305"); Success!!

0 votes
Alexander Becker August 21, 2015

So here my solution:

  • I created a new event under Administration->System->Events
  • I added this newly created event to the transition "create issue" in the first place in the postfunction list
  • I called a self implemented groovy-Scriptlistener class (code below) on Administration-> Add-Ons->Scriptrunner->Scriptlisteners
  • this script was externally edited (IntelliJ Idea 14)
  • I had to get a workaround to get two objects (ComponentManager and the "current issue". Now knowing I can retrieve the currently processed issue from the event fired smile
//package "grayed out"


import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.util.IssueChangeHolder;
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder;
import com.atlassian.jira.issue.ModifiedValue;
import com.atlassian.jira.event.issue.AbstractIssueEventListener;
import com.atlassian.jira.event.issue.IssueEvent;
import org.apache.log4j.Logger;

/**  class OnCreateListener listens to events supposed to happen on the create transition screen
 *   while crating a new issue (Trouble ticket) within the JIRA Hotline Projekt
**/
public class OnCreateListener extends AbstractIssueEventListener {

    // logging instance: path: "C:\Atlassian\Application Data\JIRA\log\    atlassian-jira.log ")
    Logger log = Logger.getLogger(OnCreateListener.class);

    /**
     * Constructor with setting logging mode
     */
    public OnCreateListener(){
        super();
        log.setLevel(org.apache.log4j.Level.DEBUG);
    }

    /** method overrides workflowEvent() method from super class
     *  AbstractIssueEventListener
     */
    @Override
    public void workflowEvent(IssueEvent event) {
        log.debug("Event fired on create transition");

        // retrieving the current issue processed
        MutableIssue myIssue = (MutableIssue) event.getIssue();
        executeScript(myIssue);

        log.debug("Event processed on create transition, table with first summary entry created.");
    }

    /** method executes script with functionality of
     * creating a table header
     * filling first row of table with initial data related to process "create issue"
     *
     * @param myIssue: the current issue processed on this workflow transition
     */
    public void executeScript(MutableIssue myIssue){

        CustomFieldManager customFieldManager =  ComponentAccessor.getCustomFieldManager();

        // retrieving values from custom fields
            // summary
        String summary = myIssue.getSummary();
            //date
        CustomField dateField = customFieldManager.getCustomFieldObject("customfield_10874");
        String date = String.valueOf(myIssue.getUpdated());
            // assignee
        CustomField assigneeField = customFieldManager.getCustomFieldObject("assignee");
        String currentAssignee = myIssue.getAssignee().getName();
            // correspondence category
        CustomField categoryField = customFieldManager.getCustomFieldObject("customfield_10780");
        String category = String.valueOf(myIssue.getCustomFieldValue(categoryField));
            // correspondence field "from"
        CustomField vonField = customFieldManager.getCustomFieldObject("customfield_10871");
        String von = String.valueOf(myIssue.getCustomFieldValue(vonField));
            // correspondence field "to"
        CustomField zuField = customFieldManager.getCustomFieldObject("customfield_10872");
        String zu = String.valueOf(myIssue.getCustomFieldValue(zuField));

    // predefined table header
        String header = "||Datum||Name||Kategorie||von||zu||Zusammenfassung||\n";

    // concatenating new table row data
        String newValue = header + "|" + date + "|" + currentAssignee + "|" + category + "|" + from + "|" + to + "|" + summary + "|\n";

    // updating value in custom field "short description table" (customfield_11170)
        if(summary != null){

            CustomField dstSummaryField = customFieldManager.getCustomFieldObject("customfield_11170");
            IssueChangeHolder ich = new DefaultIssueChangeHolder();
            ModifiedValue mv = new ModifiedValue(String.valueOf(dstSummaryField),newValue);
            dstSummaryField.updateValue(null,myIssue,mv,ich);

        }
    }
}

 

 

Guilherme Nogueira
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 21, 2015

great!

0 votes
Alexander Becker August 21, 2015

Yes I did, thx for that but the two suggestions weren't the problem. I didn't use the 'wrong retrieved' custom field for the assignee (the line under the mentioned one is doing your suggestion. The second tip was right so far, I hve to replace the original "old value§ not an emty String. On Create issue process it would be the same, but code would be nicer that way. The problem (now solved) was the following: The class ComponentManager could not be resolved because the standard maven dependency for the package (artifact-id) jira-api excludes the jira.core package for some reason, so I had to figure out how to get to this Object. I will post the new code (and short description of doing) within a new post right now. Thanks for the suggestions,

0 votes
Guilherme Nogueira
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 20, 2015

Did u check my answer?

0 votes
Alexander Becker August 19, 2015

hope wrapping the code is resulting in what you have meant, I can't see a difference within the Mozilla browser..

0 votes
Peter Bengov
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 19, 2015

Hi Alexander, please edit you message and wrap the code syntax with the {code} ... {code}. It will be more readable and understandable. Thanks

Suggest an answer

Log in or Sign up to answer