Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Copy custom field (select list) from parent to child with listener on 'issue created'.

Judah
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.
October 24, 2018

I am trying to copy a custom field from parent to child (sub-task) using a listener on 'issue created' event. This code is piece-meal from many places...I am getting an error on this line

MutableIssue parentIssue = issue.getParentObject()
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.UpdateIssueRequest
import com.atlassian.jira.issue.fields.CustomField

MutableIssue parentIssue = issue.getParentObject()

CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()

CustomField copyFrom = customFieldManager.getCustomFieldObject("Source of Request - JudahTest")
CustomField cf2Update = customFieldManager.getCustomFieldObject("Source of Request - JudahTest")

def valcf2Update = parentIssue.getCustomFieldValue(cf2Update)

if (valcf2Update == null){
parentIssue.setCustomFieldValue(cf2Update, event.issue.getCustomFieldValue(copyFrom))
}

ComponentAccessor.getIssueManager().updateIssue(
ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
, parentIssue
, UpdateIssueRequest.builder().eventDispatchOption(EventDispatchOption.ISSUE_UPDATED).sendMail(false).build() )

 

Any help would be greatly appreciated. 

1 answer

1 accepted

1 vote
Answer accepted
Joshua Yamdogo @ Adaptavist
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.
October 24, 2018

Hi,

I made a few modifications to your script and it seems to work fine.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

Issue issue = event.issue

if (issue.issueType.name == "Sub-task") {

def changeHolder = new DefaultIssueChangeHolder()

def parentIssue = issue.getParentObject()

def customFieldManager = ComponentAccessor.getCustomFieldManager()

def field = customFieldManager.getCustomFieldObjects(event.issue).find { it.name == "Source of Request - JudahTest" }

def subTaskValue = issue.getCustomFieldValue(field)
def parentValue = parentIssue.getCustomFieldValue(field)

if (parentValue == null && subTaskValue) {
field.updateValue(null, parentIssue, new ModifiedValue(parentIssue.getCustomFieldValue(field), subTaskValue), changeHolder)
} else {
field.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(field), parentValue), changeHolder)
}
}

I added a listener that listens for a "Create Issue" event. The listener checks to see if the newly created issue is a sub-task. If it is, it will get the parent value's for the custom field and update the sub-task to match the value.

You can find an example of updating custom field values in listeners on our new website: https://library.adaptavist.com/entity/update-the-value-of-a-custom-field-using-a-listener

Regards,

Josh

Judah
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.
October 25, 2018 edited

Thank you Joshua Yamdogo @ Adaptavistthis works perfectly!

A few clarification questions if you have time... 

1. Can you briefly explain what the DefaultIssueChangeHolder() class does?  I saw that you passed it as a parameter in the updateValue() method and I'm not sure what a ChangeHolder 'does'.

2. Is updateValue() a better method to use than setCustomFieldValue()? - this is what I attempted to use. 

3. How does "it" work in this context, what can I use "it" to reference? Is that a groovy object? I saw that you called "it.name"?

Again, thank you for your efforts and time, this is a beautifully executed solution. 

Judah
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.
October 25, 2018 edited

Also, the documentation on the new website you've provided looks great!

https://library.adaptavist.com/

Thanks again!

Joshua Yamdogo @ Adaptavist
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.
October 25, 2018

Sure!

1. I think this is best explained by the Atlassian docs here. Essentially, the IssueChangeHolder defines a simple object that can contain the changes that have occurred to an issue.

2. updateValue() is necessary for listeners because it actually updates the issue in the data store. setCustomFieldValue() will set the value for the issue, but it won't persist the change to the database. So after the listener is finished executing, changes made with setCustomFieldValue() will be erased. setCustomFieldValue() is generally fine to use in things like Post-Functions, which have built-in functionalities to persist changes.

3. 'it' is just the default loop parameter in Groovy. You could write it like this as well: 

def field = customFieldManager.getCustomFieldObjects(event.issue).find { field -> field.name == "Source of Request - JudahTest" }

Good example here: https://www.tutorialspoint.com/groovy/groovy_find.htm

Thomas Hardin
Contributor
May 10, 2019

Joshua Yamdogo @ Adaptavist   - By chance do you have an example for an updated issue? I am using Portfolio for Jira and my goal is to update a mutli-select field in the parent issue when the single select field is updated on a child. I'm using JMWE for the post function to set the field value in the parent issue, which works perfectly, but if the issue updated, I have nothing to work with.

Thanks,

Joshua Yamdogo @ Adaptavist
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.
May 10, 2019

@Thomas Hardin 

I don't have an exact example for that use-case but it would be similar to the one above. You could set up a Script Listener that fires on the Issue Updated Event. The code might look something like this:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

def change = event?.getChangeLog()?.getRelated("ChildChangeItem")?.find {
it.field == "Single Select Field" // your select field name here
}

if (change) {
log.debug("Value changed from ${change.oldstring} to ${change.newstring}")

// your actions if the field has changed

def customFieldManager = ComponentAccessor.customFieldManager
def optionsManager = ComponentAccessor.optionsManager

def issue = event.issue as MutableIssue

def customFieldToChange = customFieldManager.getCustomFieldObject("multi_select_list_name") // your multiselect field name here
def fieldConfig = customFieldToChange.getRelevantConfig(issue.getParentObject())

def allOptions = optionsManager.getOptions(fieldConfig)
def newOptionsToSet = allOptions.findAll { it.value in [].add(change.newstring) } // new values for multiselect field

def changeHolder = new DefaultIssueChangeHolder()
customFieldToChange.updateValue(null, issue.getParentObject(), new ModifiedValue(issue.getCustomFieldValue(customFieldToChange), newOptionsToSet), changeHolder)
}

The script checks the change log of the event and sees if the single select field has changed. If it has, get the MultiSelect field from the parent and all of its field options. Then, get the value from the SingleSelect field and match it to an option that the MultiSelect field has. Finally, update the value of the MultiSelect field on the parent.

I've not tested this and it makes assumptions about the values you want to set for the MultiSelect field, but might be enough to get you started. I'd recommend posting a new question on community if you don't figure it out.

Regards,

Josh

Suggest an answer

Log in or Sign up to answer
TAGS
atlassian, atlassian government cloud, fedramp, webinar, register for webinar, atlassian cloud webinar, fedramp moderate offering, work faster with cloud

Unlocking the future with Atlassian Government Cloud ☁️

Atlassian Government Cloud has achieved FedRAMP Authorization at the Moderate level! Join our webinar to learn how you can accelerate mission success and move work forward faster in cloud, all while ensuring your critical data is secure.

Register Now
AUG Leaders

Atlassian Community Events