i'm able to roll up the worklog from subticket to its parent and for linked epic for present ticket if we provide worklog its replicating for stories and linked epic .but for previously created and logged work its not working.please give me suggestions on this .i'm using bulk update using below script.if any one knows please provide me a solution.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.issue.search.SearchQuery
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.issue.MutableIssue
def issueManager = ComponentAccessor.getIssueManager()
def issueLinkManager = ComponentAccessor.getIssueLinkManager()
def worklogManager = ComponentAccessor.getWorklogManager()
def searchService = ComponentAccessor.getComponent(SearchService)
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def issueService = ComponentAccessor.getIssueService()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
// JQL to fetch all Epics across projects
def jqlQuery = 'issuetype = Epic'
// Parse JQL
def parseResult = searchService.parseQuery(user, jqlQuery)
if (!parseResult.isValid()) {
log.error("Invalid JQL Query: $jqlQuery")
return "Invalid JQL Query"
}
// Execute search
def searchResults = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter())
searchResults.results.each { epicIssue ->
def totalWorklogSeconds = 0
// Get the mutable version of the Epic
MutableIssue epic = issueManager.getIssueObject(epicIssue.id)
// Get linked Stories and Tasks via "Epic-Story Link"
def linkedIssues = issueLinkManager.getOutwardLinks(epic.id)
.findAll { it.issueLinkType.name == "Epic-Story Link" }
.collect { it.destinationObject }
linkedIssues.each { linkedIssue ->
// Sum worklogs for the Story or Task
totalWorklogSeconds += worklogManager.getByIssue(linkedIssue)?.sum { it.timeSpent } ?: 0
// Include worklogs from subtasks
linkedIssue.getSubTaskObjects().each { subtask ->
totalWorklogSeconds += worklogManager.getByIssue(subtask)?.sum { it.timeSpent } ?: 0
}
}
// Convert to Jira format (milliseconds)
def totalWorklogMilliseconds = totalWorklogSeconds * 1000
// Get the custom field "Total Time Logged"
def totalTimeLoggedField = customFieldManager.getCustomFieldObjects(epic).find { it.name == "Total Time Logged" }
if (totalTimeLoggedField) {
// Use IssueService to update the issue properly
def issueInputParameters = issueService.newIssueInputParameters()
issueInputParameters.addCustomFieldValue(totalTimeLoggedField.idAsLong, totalWorklogMilliseconds.toString())
def validationResult = issueService.validateUpdate(user, epic.id, issueInputParameters)
if (validationResult.isValid()) {
issueService.update(user, validationResult)
log.info("Updated Epic ${epic.key} - Total Worklog: ${totalWorklogMilliseconds / 3600000} hours")
} else {
log.warn("Failed to update Epic ${epic.key}: ${validationResult.errorCollection}")
}
} else {
log.warn("Custom field 'Total Time Logged' not found for Epic ${epic.key}")
}
}
return "Bulk update complete!"