Cloud Migration Resources
Planning a Cloud migration? These resources can help you get started:
→ Time to SLA Cloud features – Review Cloud features and understand key differences between DC and Cloud.
→ Migration support from Appfire – Learn how we can help you migrate smoothly.
I want to create a shared SLA goal
Context: A Development Team Manager wants to be notified before a shared SLA threshold is exceeded across multiple work items.
User problem: As a Development Team Manager, I want to create a shared SLA goal for work items that match specific criteria, so the total allowed time is distributed dynamically across those items.
Solution: Using Time to SLA’s Dynamic Duration feature to automatically adjust the SLA goal for each newly created work item.
How it works (example)
In this example:
Only work items that:
Belong to the Goal project
Were created this month
Share a total SLA quota of 1 hour
If existing issues have already consumed 5 minutes of working time, the next created issue will automatically receive an SLA goal of 55 minutes.
Each new issue recalculates the remaining SLA time, ensuring the 1-hour quota is never exceeded.
Configuration steps
Dynamic Duration feature will be used for this use case.
Add the dynamic Duration custom field as described here.
Create an SLA (for example,
First Response) with:Goal type: Dynamic duration
Goal value: Driven by the Dynamic Duration custom field
This SLA represents the shared 1-hour quota.
Add a scripted post function to the Create transition in your workflow and use the following script. Place this post function in the second position.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
def changeHolder = new DefaultIssueChangeHolder()
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchService = ComponentAccessor.getComponent(SearchService)
def issueManager = ComponentAccessor.getIssueManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def searchProvider = ComponentAccessor.getComponent(SearchProvider)
// Edit this query to suit you use case. To only include finished SLAs add slaFunction=isFinished() to the query
def query = jqlQueryParser.parseQuery("project = Goal and created >= startOfMonth()")
def results = searchService.search(user, query, PagerFilter.getUnlimitedFilter())
def totalWorkingDurationAsSeconds = 0L
results.getResults().each { documentIssue ->
MutableIssue foundIssue = issueManager.getIssueObject(documentIssue.id)
// Replace 10303 with the id of the SLA Overview custom field in your instance
def overviewField = customFieldManager.getCustomFieldObject("customfield_10303")
def overviewFieldValue = foundIssue.getCustomFieldValue(overviewField)
if (overviewFieldValue && overviewFieldValue.size() > 0) {
overviewFieldValue.each {
String slaName = it.sla.description
if (slaName.equals("SLA-Resolution")) {
long workingDurationAsSeconds = it.workingDurationAsSeconds
totalWorkingDurationAsSeconds += workingDurationAsSeconds
} else {
log.warn("This SLA is not eligible")
}
}
}
}
MutableIssue issue = issue
// Replace 3600 (60*60 seconds) with the SLA duration you want
long dynamicSLAGoal = 3600L - totalWorkingDurationAsSeconds
// Replace 10301 with the id of TTS-Dynamic Duration field id
def dynamicDurationField = customFieldManager.getCustomFieldObject(10301)
String remainingSlaDuration = Long.toString(Math.round(dynamicSLAGoal / 60)) + "m"
if (remainingSlaDuration.equals("0m") || remainingSlaDuration.contains("-")) {
dynamicDurationField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(dynamicDurationField), "0m"), changeHolder)
} else {
dynamicDurationField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(dynamicDurationField), remainingSlaDuration), changeHolder)
}Immediately after the scripted post function, add:
Stores updates to an issue (no change history is created)
Your post functions should look like this:
Publish the workflow to apply the changes.
Result
All matching work items share a single SLA quota
Each new issue automatically receives the remaining available SLA time
Managers can track progress and receive notifications before the SLA is exceeded
