Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,364,119
Community Members
 
Community Events
168
Community Groups

How to NOT clone the created date from a custom listener script?

I have a custom listener script on ScriptRunner (for Jira Server version 8.13.8) that basically listens for issuetype "A" and whenever its checkbox custom field gets selected, it then clones issue "A" and creates a new issuetype "B" with a few other custom fields pre-filled.

Script works fine, except now issue "B" also clones the created date from issue "A". So it looks like "B" was created months ago when really it was created today, and we query based on created dates.

Cloning on the issue's view screen (More > Clone) doesn't reflect this problem, it's only when the listener script triggers, using the event Issue Created and Issue Updated. On my script, it also has the ImportUtils set reindex in place.

What do I need to add to my current script so that created date (and possible update date) doesn't get copied over?

1 answer

1 accepted

0 votes
Answer accepted

Hi @Diana Gorv 

Can you share your script ?

 

How do you create the new issue what function are you using ?

 

Regards

Hi @Florian Bonniec the script is very long due to numerous custom fields desired, so I cut it down as simplest as I can. I apologize in advance if some variables are missing.

I run this under ScriptRunner's Custom Listeners with trigger events "Issue Updated" and "Issue Created". 

 

// this portion syncs the fields from parent issue to child issue that follows clone link and only updates the field when the parent issue changes

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.project.ProjectManager
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.util.ImportUtils

//defining key variables overall
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def issueManager = ComponentAccessor.getIssueManager()
def optionsManager = ComponentAccessor.getComponent(OptionsManager)
def changeHistoryManager = ComponentAccessor.getChangeHistoryManager()
def issue = event.issue
def indexService = ComponentAccessor.getComponent(IssueIndexingService.class)
def changeHolder = new DefaultIssueChangeHolder()
def currentUserObj = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

//start at parent issue A
if(issue.issueType.name == "A"){
//loop through bug links
List<IssueLink> allOutIssueLink = ComponentAccessor.getIssueLinkManager().getInwardLinks(issue.getId())
for(Iterator<IssueLink> outIterator = allOutIssueLink.iterator(); outIterator.hasNext();){
IssueLink issuelink = (IssueLink) outIterator.next()

//define all desired fields on A. simplfying to just look at 1 custom field for this question
def issueACustomFieldChanged = false
def issueACustomFieldName = "Custom Field Name"

//check to see if update to fields was made
def changeHistory = changeHistoryManager.getChangeHistories(issue)
//grab the latest history entry to see what fields changed
def history = changeHistory.getAt(changeHistory.size() -1)
for (def changeItem : history.getChangeItemBeans()) {
if(changeItem.getField().equals(issueACustomFieldName)) {
cfChanged = true
}
}
//only update field if the link is a clone
if (issueLink.getIssueLinkType().getName() == "Cloners" {

MutableIssue linkedIssue = issueLink.getSourceObject() as MutableIssue

//only update child issue B
if(linkedIssue.issueType.name == "B") {

//update B if changed happened. Issue A and B have the similar fields, but this script only cares about these ones. this one is a radio button
if(issueACustomFieldChanged) {
def issueBCustomField = customFieldManager.getCustomFieldObjectsByName(issueACustomFieldName).getAt(0)
def issueBCustomFieldConfig = issueBCustomField.getRelevantConfig(linkedIssue)
def issueBValue = issue.getCustomFieldValue(issueBCustomField)
def issueBOption = optionsManager.getOptions(issueBCustomFieldConfig).getOptionForValue(issueBValue.toString(), null)
issueBCustomField.updateValue(null, linkedIssue, new ModifiedValue(linkedIssue.getCustomFieldValue(issueBCustomField), issueBOption), changeHolder)
}
//update the issue so we get an entry in the history
issueManager.updateIssue(currentUserObj, linkedIssue, EventDispatchOption.ISSUE_UPDATED, false)

//need to tell jira to reindex so that change is searchable
boolean wasIndexing = ImportUtils.isIndexIssues()
ImportUtils.setIndexIssues(true)
indexService.reIndex(linkedIssue)
ImportUtils.setIndexIssues(wasIndexing)
}
}
}
}

//second portion "when checkbox is selected in parent issue A, checks to make sure there isn't a duplicate issue B, otherwise creates new issue B"

//only look for when checkbox custom field is updated in parent issue A
if(issue.issueType.name == "A"){

//define key objects for later
def projectManager = ComponentAccessor.getProjectManager()
def linkManager = ComponentAccessor.getIssueLinkManager()
def issueFactory = ComponentAccessor.getIssueFactory()

//get issue type B
def bType = ComponentAccessor.issueTypeSchemeManager.getIssueTypeForProject(issue.projectObject).find{it.name=="B"}

//get all checkbox values in issue type A
def checkboxA = customFieldManager.getCustomFieldObjectsByName("Checkbox A")
def checkboxAValue = checkboxA.getAt(0).getValue(issue)

//get all currently linked issue B for comparison
List<IssueLink> allIssueLinks = ComponentAccessor.getIssueLinkManager().getInwardLinks(issue.getId())
//loop through links and pull out all checkbox we have links for
def existingCheckbox = new ArrayList<>();
for (Iterator<IssueLink> outIterator = allIssueLinks.iterator(); outIterator.hasNext();) {
IssueLink issueLink = (IssueLink) outIterator.next();

//only interested in cloned issues that are issue B
if (issueLink.getIssueLinkType().getName() == "Cloners"){
MutableIssue linkedIssue = issueLink.getSourceObject() as MutableIssue;
if(linkedIssue.issueType.name == "B") {

//get checkbox in issue B and add it to the list
def checkboxB = customFieldManager.getCustomFieldObjectsByName("Checkbox B")
def checkboxBValue = checkboxB.getAt(0).getValue(linkedIssue)
existingCheckbox.add(checkboxBValue)
}
}
}
//loop through all checkboxA and compare to existing issue B
for (def checkboxBValue : checkboxAValue) {
def found = false
for(def existingCheckboxA : existingCheckboxB) {
if (checkboxAValue.toString().equals(existingCheckboxA.toString()) {
found = true;
break;
}
}
if(!found) {
//create a new issue type B and clones A
def toClone = issueFactory.cloneIssueWithAllFields(issue)
toClone.setIssueTypeObject(bType)
}
//checkboxB
def checkboxB = customFieldManager.getCustomFieldObjectsByName("Checkbox B").getAt(0)
def fieldConfig = checkboxB.getRelevantConfig(issue)
def option = optionsManager.getOptions(fieldConfig).getOptionForValue(checkboxBValue.toString(), null)
toClone.setCustomFieldValue(checkboxB, option)

//set up links
linkManager.createIssueLink(newIssue.id, issue.id, Long.parseLong("Cloners link Id number here"), Long.valueOf(1), currentUserObj)
}
}
}

So you get the colne by doing 

def toClone = issueFactory.cloneIssueWithAllFields(issue)

You can then set the created date by doing

toClone. setCreated(new Date().toTimestamp())

Then you have to store the new issue, this part is not in the script

issueManager.createIssueObject(currentUserObj, toClone)

@Florian Bonniec 

Works like a charm! Thank you so much!

Suggest an answer

Log in or Sign up to answer