Subtasks should inherit field values from the parent task on create

Hello.

I am trying to configure JIRA so that subtasks inherit field values from their parent, when they are created. The workflow postfunction offered by ScriptRunner does not work when creating the issue, as the link between parent and child is not yet created.

I installed the "Copy to Subtask" plugin but it doesn't work. No fields are inherited from the parent issue.

I am using JIRA 6.4.3 and ScriptRunner 3.0.14.

I would be interested in implementing some sort of listener for this, but I haven't had much luck with them. Does anybody know if there is a problem with creating inline Groovy classes? I've run mutiple examples from the documentation but none work.

 

Thank you,

Cristina

 

 

4 answers

1 accepted

This widget could not be displayed.

Hey,

So the solution was ridiculously simple. Because i usually view my workflows in text mode, i hadn't noticed the "Create" transition before the first status. I added a "Copy values" postfunction on that transition and it all works like a charm.

Thanks for the answers, I'm sure they'll be useful to me in other ways.

Hi Cristina, 

When i'm in Transition: Create Issue > Post Functions > Add post function is see a list of available functions but no 'Copy values' function. Did you do anything to make this function available? 

but this will only work for sub tasks,,,not for linked issues to a parent task ?

 

Hi Cristina, 

I have followed your suggestions - and it is working well for all fields except for Labels - where I get and error (please see below)

Is it working for you for lables as well ?

Thanks!

Naama

2017-06-16 13:45:34,766 http-bio-8443-exec-24025 ERROR naama 825x6280973x1 2ig2dz 10.1.5.250,10.1.8.105 /secure/QuickCreateIssue.jspa [c.a.j.bc.issue.DefaultIssueService] Error creating issue:
com.atlassian.jira.exception.CreateException: Unable to copy value from field 'Labels' to 'Labels'.
at com.atlassian.jira.issue.managers.DefaultIssueManager.createIssue(DefaultIssueManager.java:588)
at com.atlassian.jira.issue.managers.DefaultIssueManager.createIssue(DefaultIssueManager.java:494)
at com.atlassian.jira.bc.issue.DefaultIssueService.create(DefaultIssueService.java:230)
at com.atlassian.jira.bc.issue.DefaultIssueService.create(DefaultIssueService.java:199)
at sun.reflect.GeneratedMethodAccessor2676.invoke(Unknown Source)

This widget could not be displayed.
Vasiliy Zverev Community Champion Feb 03, 2016

I wrote this postfunction to copy values from a parent task to a subtask:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.UpdateIssueRequest
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.user.ApplicationUser

IssueManager issueManager = ComponentAccessor.getIssueManager();
Issue parentIssue = issueManager.getIssueObject(issue.getParentId());

ComponentAccessor.getCommentManager().create(issue, ComponentAccessor.getJiraAuthenticationContext().getUser(), "test", false);

issue.subTaskObjects.any

CstFldCoper cstFldCoper = new CstFldCoper();

cstFldCoper.copyCustomFieldFromParentToSubTask(parentIssue, issue, 10008L);  //Ответственный
cstFldCoper.copyCustomFieldFromParentToSubTask(parentIssue, issue, 10005L); //РФГ
cstFldCoper.copyCustomFieldFromParentToSubTask(parentIssue, issue, 10716L); //координатор разработчиков

public class CstFldCoper{
    private CustomField cstFld;
    private CustomFieldManager cstFldMng = ComponentAccessor.getCustomFieldManager();
    UpdateIssueRequest updIssReq;
    ApplicationUser curUser = ComponentAccessor.getJiraAuthenticationContext().getUser();
    IssueManager issueManager1 = ComponentAccessor.getIssueManager();

    public CstFldCoper(){
        //Задаём параметры для обновления запроса
        UpdateIssueRequest.UpdateIssueRequestBuilder issueRequestBuilder = new UpdateIssueRequest.UpdateIssueRequestBuilder();
        issueRequestBuilder.eventDispatchOption(EventDispatchOption.ISSUE_UPDATED);
        issueRequestBuilder.sendMail(false);
        updIssReq = new UpdateIssueRequest(issueRequestBuilder);
    }

    public void copyCustomFieldFromParentToSubTask(Issue _parent, MutableIssue _subTask, long _cstFldId){
        cstFld = cstFldMng.getCustomFieldObject(_cstFldId);
        _subTask.setCustomFieldValue(cstFld, _parent.getCustomFieldValue(cstFld));
        issueManager1.updateIssue(curUser, _subTask, updIssReq);
    }
}
This widget could not be displayed.

I've done this using a listener, a sample is included below.  It's not an inline script, I had to put the file in /home/jira/jira_data/com/myorg/listeners.  I've sanitized it somewhat (removed workflow and organization names), but it should do the trick.  It syncs two fields, "Fix Version/s" and a custom field called "Verified Version/s".  It's based on this example:

http://stackoverflow.com/questions/18428756/update-jira-subtask-fix-version-when-parent-issue-fix-version-updated

But is updated to account for being out of date, plus it handles the empty list case.  It's designed to listen for all projects and events, and use the name of the workflow to determine if the sync should take place, that way nobody can forget to include it in the listener when new projects are created.  Finally, it does the sync for edge cases like adding a sub-task to an existing parent.

Hmm, actually, this is more than what you asked for in that it will keep them in sync after creation.  Oh well, hopefully it helps.

package com.myorg.listeners;
import org.apache.log4j.Category;
import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.event.issue.AbstractIssueEventListener;
import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.project.version.Version;
import com.atlassian.jira.config.SubTaskManager;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.event.type.EventDispatchOption;
import com.atlassian.jira.workflow.WorkflowManager;
import com.atlassian.jira.workflow.JiraWorkflow;
import java.util.ArrayList;
import java.util.Collection;
class SyncParentFixVerifiedVersionsToSubTask extends AbstractIssueEventListener 
{
    Category log = Category.getInstance(SyncParentFixVerifiedVersionsToSubTask.class);
    SubTaskManager subTaskManager = ComponentManager.getInstance().getSubTaskManager();
    WorkflowManager workflowManager = ComponentManager.getInstance().getWorkflowManager();
    IssueManager issueManager = ComponentManager.getInstance().getIssueManager();
    CustomFieldManager customFieldManager = ComponentManager.getInstance().getCustomFieldManager();
    Boolean changed = false;
    Long workflowId;
    @Override
    void workflowEvent(IssueEvent event) {
        try {
            if (subTaskManager.isSubTasksEnabled()) {
                Issue eventIssue = event.getIssue();
                JiraWorkflow workflow = workflowManager.getWorkflow(eventIssue);
                if (workflow.getName() == "Put Workflow Name Here") {
                    CustomField vvcf = customFieldManager.getCustomFieldObjectByName("Verified Version/s");
                    if ( !eventIssue.getIssueTypeObject().isSubTask() ) {
                        // Change is on a potential parent, sync to sub-tasks if there are any
                        Collection<Issue> subTasks = eventIssue.getSubTaskObjects();
                        List changeItems = event.getChangeLog().getRelated("ChildChangeItem");
                        // Sync FixVersion/s
                        if( changeItems.any {it.get('field')=='Fix Version'} ) {
                            changed = true;
                            // Collection<Version> fixVersions = new ArrayList<Version>();
                            // fixVersions = eventIssue.getFixVersions();
                            Collection<Version> fixVersions = eventIssue.getFixVersions();
                            if (!subTasks.isEmpty()) {
                                subTasks.each {
                                    it.setFixVersions(fixVersions);
                                }                     
                            }
                        }
                        // Sync Verified Version/s
                        if( changeItems.any {it.get('field')=='Verified Version/s'} ) {
                            changed = true;
                            Collection<Version> verifiedVersions = new ArrayList<Version>();
                            verifiedVersions = eventIssue.getCustomFieldValue(vvcf);
                            if (!subTasks.isEmpty()) {
                                subTasks.each {
                                    it.setCustomFieldValue(vvcf,verifiedVersions);
                                }
                            }
                        }
                        if (changed) {
                            subTasks.each {
                                issueManager.updateIssue(event.getUser(), it, EventDispatchOption.ISSUE_UPDATED, false);
                            }
                        }
                    } else {
                        // Change is on a sub-task, sync from the parent if they are out of sync
                        Issue parentIssue = eventIssue.getParentObject();
                        // Sync "Fix Version/s"
                        Collection<Version> parentFixVersions = parentIssue.getFixVersions();
                        if (parentFixVersions == null) parentFixVersions = new ArrayList<Version>();
                        Collection<Version> fixVersions = eventIssue.getFixVersions();
                        if (fixVersions == null) fixVersions = new ArrayList<Version>();
                        if(!(parentFixVersions.containsAll(fixVersions) && fixVersions.containsAll(parentFixVersions))) {
                            eventIssue.setFixVersions(parentFixVersions);
                            changed = true;
                        }
                        // Sync "Verified Version/s"
                        Collection<Version> parentVerifiedVersions = parentIssue.getCustomFieldValue(vvcf);
                        if (parentVerifiedVersions == null) parentVerifiedVersions = new ArrayList<Version>();
                        Collection<Version> verifiedVersions = eventIssue.getCustomFieldValue(vvcf);
                        if (verifiedVersions == null) verifiedVersions = new ArrayList<Version>();
                        if(!(parentVerifiedVersions.containsAll(verifiedVersions) && verifiedVersions.containsAll(parentVerifiedVersions))) {
                            eventIssue.setCustomFieldValue(vvcf,parentVerifiedVersions);
                            changed = true;
                        }
                        if (changed) {
                            issueManager.updateIssue(event.getUser(), eventIssue, EventDispatchOption.ISSUE_UPDATED, false);
                        }
                    }
                }
            }
        }
        catch (ex) {
            log.debug "Event: ${event.getEventTypeId()} fired for ${event.issue} and caught by SyncParentFixVerifiedVersionsToSubTask"
            log.debug (ex.getMessage())
        }
    }
}
This widget could not be displayed.
Andreas Knecht Community Champion Nov 21, 2016

There's now a very easy to configure way to copy field values from parents to sub-tasks (and vice versa) using Automation for JIRA!

You can easily modify related issues (such as parents, stories, sub-tasks, epics, linked issues and even JQL) using our related issues action and condition:

(this example transitions sub-tasks, but you could just as easily change this to edit field values on the sub-tasks etc)

For more details see https://blog.codebarrel.io/synchronize-parent-and-sub-task-issues-with-automation-for-jira-bdcca6c9d453

Hi 

Can you tell me how to copy fields from a parent to a sub task?

At the moment, I cant seem to get anything from the parent issue to the sub-task usign automation. In the additional fields box I have:

 

{
"fields": {
"First Name": "{{issue.parent.fields.First Name}}",
"Last Name": "{{issue.parent.fields.Last Name}}"
}
}

 

However it is not working. If I just add text instead of {{issue.parent.fields.First Name}}. The text appears. 

Andreas Knecht Community Champion Sep 15, 2017

Hi Luke,

What you posted should work, but it depends a bit on your rule config.  Can you post a screenshot of your entire rule configuration at https://codebarrel.io/support please?

Cheers,
  Andreas

Suggest an answer

Log in or Sign up to answer
Atlassian Summit 2018

Meet the community IRL

Atlassian Summit is an excellent opportunity for in-person support, training, and networking.

Learn more
Community showcase
Posted Wednesday in New to Jira

Are you planning to trial, or are currently trialling Jira Software? - We want to talk to you!

Hello! I'm Rayen, a product manager at Atlassian. My team and I are working hard to improve the trial experience for Jira Software Cloud. We are interested in   talking to 20 people planning t...

232 views 3 0
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you