Just a heads up: On March 24, 2025, starting at 4:30pm CDT / 19:30 UTC, the site will be undergoing scheduled maintenance for a few hours. During this time, the site might be unavailable for a short while. Thanks for your patience.

×
Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

[Script Runner] Could we choose which fields get copied from parent in a listener

Cristina_Abunei
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.
January 5, 2018

Hello,

We a custom field called 'Number of stories'. It is a select list, with the values 1,2,3,4 and 5. It is set on epics.

We created a listener that whenever a somebody choose a value for this field, the same number of stories are created as issues in epic for that epic.

The code is below:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent
import com.onresolve.scriptrunner.canned.jira.utils.ConditionUtils
import com.onresolve.scriptrunner.canned.jira.utils.CopyIssueWithAttachments
import com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CreateSubTask
import com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CloneIssue
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.issuetype.IssueType
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.workflow.JiraWorkflow
import com.atlassian.jira.config.StatusManager
import com.atlassian.jira.config.DefaultStatusManager
import com.atlassian.jira.issue.status.Status
import com.atlassian.jira.issue.customfields.option.Option

def changeItems = event.getChangeLog().getRelated("ChildChangeItem")?.find {it.field == "Number of Stories"}
if(changeItems)
{
def issueTypes = ComponentAccessor.getConstantsManager().getAllIssueTypeObjects();
def issueManager = ComponentAccessor.getIssueManager();
MutableIssue issue = (MutableIssue)event.issue
ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def numberOfStoriesField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName('Number of Stories')
def numberOfStories = issue.getCustomFieldValue(numberOfStoriesField).toString().toInteger()
def linkManager = ComponentAccessor.getIssueLinkManager()
def index = 1
IssueType type = null
for (issueType in issueTypes)
if(issueType.getName() == "Story")
{
type = issueType
break;
}

for (index =1; index <= numberOfStories; index++)
{
MutableIssue newIssue = (MutableIssue)createIssue(issue, user, type)
newIssue.summary = "[Story" +index.toString()+"]" + newIssue.summary
issueManager.updateIssue(user, newIssue, EventDispatchOption.DO_NOT_DISPATCH, false)
def sprint = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName('Sprint')
newIssue.setCustomFieldValue(sprint, null)
issueManager.updateIssue(user, newIssue, EventDispatchOption.DO_NOT_DISPATCH, false)
if(issue.getIssueType().getName() == 'Epic')
{
def epicLink = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName('Epic Link')
newIssue.setCustomFieldValue(epicLink, issue)
issueManager.updateIssue(user, newIssue, EventDispatchOption.DO_NOT_DISPATCH, false)
}
else
{
linkManager.createIssueLink(issue.getId(), newIssue.getId(),(Long)10003,(Long)1,user)
}
newIssue.description = issue.description
issueManager.updateIssue(user, newIssue, EventDispatchOption.DO_NOT_DISPATCH, false)
}

if(issue.getIssueType().getName() == 'Problem Report' && issue.getStatus().getName() == 'Working')
{
def optionsManager = ComponentAccessor.getOptionsManager()
def phaseField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName('CA Phase')
def stateField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName('CA State')
Option phaseOption = optionsManager.getOptions(phaseField.getRelevantConfig(issue)).getOptionForValue("Realize",null);
Option stateOption = optionsManager.getOptions(stateField.getRelevantConfig(issue)).getOptionForValue("I50_Design_Defined",null);
def aux = ComponentAccessor.getIssueManager().getIssueByCurrentKey(issue.getKey())
aux.setCustomFieldValue(phaseField,phaseOption)
issueManager.updateIssue(user, aux, EventDispatchOption.DO_NOT_DISPATCH, false)
aux.setCustomFieldValue(stateField,stateOption)
issueManager.updateIssue(user, aux, EventDispatchOption.DO_NOT_DISPATCH, false)
}

issue.setCustomFieldValue(numberOfStoriesField, null)
issueManager.updateIssue(user, issue, EventDispatchOption.DO_NOT_DISPATCH, false)
return;

}
def createIssue(Issue issue,ApplicationUser user, IssueType type)
{
def issueManager = ComponentAccessor.getIssueManager()
def params = [
issue : issue,
(CloneIssue.FIELD_TARGET_PROJECT) : issue.getProjectObject().getKey(),
(ConditionUtils.FIELD_ADDITIONAL_SCRIPT): '''
checkLink = {link->false}
checkAttachment = {a -> a.filename.endsWith(".txt")}
'''
]


def aux = new CopyIssueWithAttachments().doScript(params)
StatusManager statusManager = ComponentAccessor.getComponentOfType(StatusManager.class)
String status = ""
if(issue.getProjectObject().getKey() != 'HW')
status = "10600"
else
status = "10800"
Status statusObject = statusManager.getStatus(status)
MutableIssue newIssue = ComponentAccessor.getIssueManager().getIssueObject(aux.newIssue.toString())
newIssue.setIssueTypeObject(type)
issueManager.updateIssue(user, newIssue, EventDispatchOption.ISSUE_UPDATED, false)
JiraWorkflow workflow = ComponentAccessor.getWorkflowManager().getWorkflow(issue.getProjectObject().getId(), type.getId())
ComponentAccessor.getWorkflowManager().migrateIssueToWorkflow(newIssue, workflow,statusObject )
issueManager.updateIssue(user, newIssue, EventDispatchOption.ISSUE_UPDATED, false)
return newIssue
}

What we would like to ask is if this can be changed somehow so that we can choose which fields are copied to the story from the epic.
More exactly, the assignee gets copied, and also some fields referring to the Definition of Done for the Epic, which are not at all relevant for the story.
We currently delete these values from the story by purging them at creation via a post function, but that removes the values whenever somebody manually creates an issue (or via CSV).

Thank you.

 

1 answer

0 votes
Alexey Matveev
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.
January 5, 2018

Hello,

It depends on how flexible you want it to be. For example, you could add a select list with options which would mean a copy template. I mean suppose you have a select list called Template. Then you provide options there like Template1, Template2, Template2. Then in your listener you analyze the Template field together with the Number of stories field. If Template1 is chosen then you copy, for example, only assignee, if Template2 then you copy Assignee and the summary field and so on.

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events