Using scriptrunner listener to copy contents of a parent field to subtask work field

Neil I August 18, 2017

Can anyone help me with Scriptrunner. I need to be able to create a scriptrunner listener that will copy a parents status (e.g. backlog, in progress etc..) to a subtask work field called "Parent Status". I also need to be able to copy a parent work field "RCA Date" to subtask custom field "Parent RCA Date". I need a listener so these subtask fields are updated whenever the parent field is updated. Thanks in advance.

1 answer

1 accepted

3 votes
Answer accepted
Jenna Davis
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 23, 2017

Hello,

You should be able to do something similar to this for the parent status field:

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

if(!event.issue.isSubTask()){
return
}

def customFieldManager = ComponentAccessor.customFieldManager

def parent = event.issue.getParentObject()
def status = parent.status.name

def parentStatus = customFieldManager.getCustomFieldObjectByName("Parent Status")
def changeHolder = new DefaultIssueChangeHolder()

parentStatus.updateValue(null, event.issue, new ModifiedValue(parentStatus.getValue(event.issue), status), changeHolder)

For the RCA Date field, it should be similar code. You'll just need to change what fields you're getting and updating. 

Note: I didn't test the code out directly, but I think it should work for you. 

If you have any trouble getting this to work or need help coding the script for your RCA field, let me know! I'll be glad to help you out further. :)

Jenna

Neil I August 24, 2017

Thank you Jenna. This is great.

However, this code only works when the sub-task is edited, taking the status from the parent issue and updating the sub-task 'parent status' field.

What I really need is for the sub-task 'parent status' field to be updated when the parent issue is edited or transitioned rather than when the sub-task is edited or transitioned.

Again, thanks in advance. Really appreciated.

Neil

Jenna Davis
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 25, 2017

You are completely correct, I overlooked that. I think you should be able to do this with similar code by using something like 

event.issue.getSubTaskObjects()

in order to access your subtasks, then loop through the collection of subtasks you get back and update them (similar to above). If you need help writing out code for this, let me know. 

Neil I September 6, 2017

Thanks Jenna. I'm not a developer so unsure how to structure your suggestion. If you do have time to write the code that would be awesome.

Neil

Jenna Davis
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.
September 6, 2017

Here is a listener that should catch 'Issue Created' and 'Issue Updated' events. I also set my listener to catch 'Generic Events' and created post functions to fire generic events on transitions to ensure they are caught. You could also make this a custom event with some additions to the code. There are other community questions that cover how to catch custom events like this if want to do that and need help writing it. :)

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

if(!event.issue.isSubTask() && !event.issue.getSubTaskObjects()){
return
}

def customFieldManager = ComponentAccessor.customFieldManager

if(event.issue.isSubTask()) {

def parent = event.issue.getParentObject()
def status = parent.status.name

def parentStatus = customFieldManager.getCustomFieldObjectByName("Parent Status")
def changeHolder = new DefaultIssueChangeHolder()

parentStatus.updateValue(null, event.issue, new ModifiedValue(parentStatus.getValue(event.issue), status), changeHolder)
}

if(event.issue.getSubTaskObjects()){
def subtasks = event.issue.getSubTaskObjects()
def status = event.issue.status.name
subtasks.each {
def parentStatus = customFieldManager.getCustomFieldObjectByName("Parent Status")
def changeHolder = new DefaultIssueChangeHolder()

parentStatus.updateValue(null, it, new ModifiedValue(parentStatus.getValue(it), status), changeHolder)
}

}

 

Please let me know if you have any more questions!

 

Like Kiran Pamuru likes this
Jenna Davis
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.
September 8, 2017

Did this code work for you?

Neil I September 8, 2017

This worked perfectly. Thank you so much for your help. You're a ⭐️

Hitendra Joshi September 4, 2018

Hi Jenna, 

I am trying to create a listener to change status of Parent issue to inprogress if child issue <Any issue> type, status change to inprogress. 

Could you help me how i can achieve ?

Thank much, 

Jenna Davis
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.
September 4, 2018
Hitendra Joshi September 4, 2018

Hi Jenna,

I am trying to achieve this using listener not post function, is there a way to perform this using listner? change Parent -status-> InProgress If Child issue -are-> Inprogress. 

Jenna Davis
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.
September 4, 2018

I believe it should be similar code - essentially you'd just want to listen for when an issue transitions to 'In Progress', then check if that issue has a parent and transition it if so. The easiest way to get the listener working should be with the Fire a Generic Event event that can be processed by a listener post function. You can add an event that gets fired when your child moves to in progress, which is then caught by your listener, then transition the parent in the listener script.  

If you need help writing up the script could you open a new question? That way we're not crowding this question out and people that might need help on this in the future can find the response easier. :)

Jenna

Judah October 24, 2018

@Jenna Davis

I am trying to adapt the code you've provided above to copy down a custom field value from parent to child on the listener event 'issue created'. 

My field type is a selected list - single choice. 

I have been able to write a listener that will copy the value when the parent is updated but I cannot get the value to copy down when a new issue is created...

Any insight? 

Tomislav Sablic February 10, 2020

This one works for me for custom field called "Contract"

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import org.springframework.LdapDataEntry

def issue = event.issue as Issue

// Check if issue is Sub-task
if(!issue.isSubTask()){
return
}

def customFieldManager = ComponentAccessor.getCustomFieldManager()

// Get parent issue
def parent = issue.getParentObject()
if(parent == null){
return
}

// Get Contract value from parent issue
def parentContractField = customFieldManager.getCustomFieldObjects(parent).find{it.name == "Contract"}
def parentContractFieldValue = parent.getCustomFieldValue(parentContractField)
log.error "Parent contract: " + parentContractFieldValue

// Check if parent field has value
if(parentContractFieldValue == null){
return
}

// Get Contract value from child issue
def childContractField = customFieldManager.getCustomFieldObjects(issue).find{it.name == "Contract"}
def childContractFieldValue = issue.getCustomFieldValue(childContractField)
log.error "Child contract: " + childContractFieldValue

// Check if the values are the same
if(childContractFieldValue == parentContractFieldValue){
return
}

// Change child value to inherit the parent's value
try{
def changeHolder = new DefaultIssueChangeHolder()
childContractField.updateValue(null, issue, new ModifiedValue(childContractFieldValue,parentContractFieldValue),changeHolder)
log.error "OK!"
} catch (Exception e){
log.error "Exception: ${e}"
}



Rodolfo So February 19, 2021

Is this using scriptrunner listener? I tried it did not reflect the change in subtasks level

Karl Samson February 21, 2024

This is the sort of code I'm looking for to also update a custom field in any linked issues. How would I include 'Linked' issues in the above code please?

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events