I am building a listener that is meant to populate three fields on an issue's parent - total children, completed children, and percent complete. The script runs just fine if an issue's parent changes or is removed. The problem happens when an issue is archived. What it seems to be doing is calculating a search count before the issue is archived or restored.
For instance, if an Epic has 2 stories and I archive one of them, the script will output 2 total children. If I then restore the story, it'll output 1 total child.
I've tried just adding a Thread.sleep(3000) to give it some time incase it's a synchronization problem, but that didn't work.
Any idea why the issue search counts aren't calculating based off the current status of the issue?
Here's the relevant code:
import com.atlassian.jira.issue.fields.config.manager.IssueTypeSchemeManager
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
def issue = event.issue
def portfolioIssues = ["Portfolio", "ART", "SAFe Epic", "Epic"]
def project = issue.getProjectObject()
def issueName = issue.getIssueType().name
def changeHolder = new DefaultIssueChangeHolder()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def issueManager = ComponentAccessor.getIssueManager()
def issueTypeSchemeManager = ComponentAccessor.getComponent(IssueTypeSchemeManager)
List changeItemsList = event.getChangeLog()?.getRelated("ChildChangeItem")
def eventID = event.eventTypeId
log.warn("Event ID: ${event.eventTypeId}")
log.warn(changeItemsList)
def fieldChanged = changeItemsList?.find{ it.field }
log.warn("Field Changed: ${fieldChanged}")
else if (fieldChanged?.get('field') == "Feature Link" || [18, 19].find{ it == eventID }.asBoolean()) {
def issueTypes = issueTypeSchemeManager.getNonSubTaskIssueTypesForProject(project).getAt("name")
issueTypes = issueTypes - portfolioIssues
issueTypes = issueTypes.collect { "\"${it}\"" }.flatten().join(",")
//def newParentId = fieldChanged?.getAt("newstring")
def newParentId = (fieldChanged?.get('field') == "Feature Link") == true ? fieldChanged?.getAt("newstring") : issue.getEpic().getKey()
log.warn("New Parent: ${newParentId}")
if (newParentId) {
def newParent = Issues.getByKey(newParentId)
//Thread.sleep(3000)
calcFunction (customFieldManager, newParent, issue, issueTypes, changeHolder)
}
def oldParentId = fieldChanged?.getAt("oldstring")
log.warn("Old Parent: ${oldParentId}")
if (oldParentId) {
def oldParent = Issues.getByKey(oldParentId)
calcFunction (customFieldManager, oldParent, issue, issueTypes, changeHolder)
}
}
def calcFunction (customFieldManager, parent, issue, issueTypes, changeHolder) {
def totalChildren = customFieldManager.getCustomFieldObjects(parent).find {it.name == "Total Children"}
def doneChildren = customFieldManager.getCustomFieldObjects(parent).find {it.name == "Total Completed Children"}
def percentDone = customFieldManager.getCustomFieldObjects(parent).find {it.name == "Children Completion Percentage"}
double totalIssueCount = Issues.search("issue in childIssuesOf('${parent.key}') and issuetype in (${issueTypes})").size()
double doneIssueCount = Issues.search("issue in childIssuesOf('${parent.key}') and issuetype in (${issueTypes}) and resolution is not empty").size()
double percentComplete = (((doneIssueCount / totalIssueCount)*100).round(0))
log.warn("Total Children: ${totalIssueCount}")
log.warn("Done Children: ${doneIssueCount}")
log.warn("Done Children Percent: ${percentComplete}")
totalChildren.updateValue(null, parent, new ModifiedValue(parent.getCustomFieldValue(totalChildren), totalIssueCount),changeHolder)
doneChildren.updateValue(null, parent, new ModifiedValue(parent.getCustomFieldValue(doneChildren), doneIssueCount),changeHolder)
if(percentComplete) {
percentDone.updateValue(null, parent, new ModifiedValue(parent.getCustomFieldValue(percentDone), percentComplete),changeHolder)
}
}