I'm trying to write script to notify approvers via slack ot issue transition.
I choose script listener (not post-finction) due to large number of possible transitions.
So how to do following:
I've done that before on cloud version via REST API, there is no problem with that, but in server version I've got original issue (not after transition) so there is no approval yet in moment of transition. I've try to access approval custom field, but there is no approvers info in it. I've try to search examples how to work with approvals in scriptrunner, but no dice. I've try following code to test jira java api, but it's not working...
@WithPlugin ("com.atlassian.servicedesk")
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.servicedesk.api.approval
def issue = ComponentAccessor.getIssueManager().getIssueObject("DVPT-1")
ApprovalQuery query = approvalService.newQueryBuilder().issue(issue).build()
it shows error about "ApprovalQuery" class. What I need to import to have it?
How to work with approvals?
Hi All,
How to get the user who approved the ticket and then set him as assignee to that ticket. second part is easy but im struggling with first one.
A bit simpler via customField:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.servicedesk.api.approval.ApprovalService
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
@WithPlugin("com.atlassian.servicedesk")
def issue = ComponentAccessor.getIssueManager().getIssueObject("DVPS-7010") // For console testing
def robotUser = ComponentAccessor.getUserManager().getUserByKey("robot-manager")
def approvalService = ComponentAccessor.getOSGiComponentInstanceOfType(ApprovalService)
def approval = issue.getCustomFieldValue(ComponentAccessor.getCustomFieldManager().getCustomFieldObjectsByName('Approvals').first()).getApprovals()
if (approval && !approval.first().getDecision().isPresent()) {
def approvalsNeeded = approvalService.getApprovers(robotUser, approval.first()).findAll{!it.getApproverDecision().isPresent()}.collect{it.getApproverUser().name}
log.info("Approvals needed: $approvalsNeeded")
//
// Remind to approve
//
} else {
log.warn("No pending approvals found for issue [$issue.key]")
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Nicely done! The code was very helpful!
We had a case where we needed to implement approving issues via e-mail. We used a script for that. At first, we implemented only issue transitions based on the content of the mail. That wasn't good because the approvals did not get recorded and approvers didn't see their approved issues.
This code was a good basis to get what we needed and to trigger transitions and to get approvals to register.
Example snippet, if anyone should need it:
...
if(unansweredApproval!=null && approvalService.canAnswerApproval(approver,unansweredApproval)){
if(com.getBody().contains("Approve")){
approvalService.answerApproval(approver,unansweredApproval,ApprovalDecisionType.APPROVED);
} else if(com.getBody().contains("Decline")){
approvalService.answerApproval(approver,unansweredApproval,ApprovalDecisionType.REJECTED);
}
}
...
The only thing that didn't work for us was
approval.first().getDecision().isPresent()
It returned the firs approval. Which is ok if you only have one level of approval. But it, in the end, was simple to find the one approval that doesn't have a decision.
Anyways, thanks for the post. I wanted you and other participants to know that somebody found it useful. :)
Cheers,
Marina
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Marina, thanks for your snippet.
But what is
com.getBody()
in your code?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Udjin,
the snippet is inside the loop
for(Comment com : commentManager.getComments(issue)) {
...
}
Cheers,
Marina
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Oh, understood. You took value from comment, and approve/disapprove depending on value. Thank you!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
That's what I came up with:
import org.apache.log4j.Logger
import org.apache.log4j.Level
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.servicedesk.api.approval.ApprovalService
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
@WithPlugin("com.atlassian.servicedesk")
logs = Logger.getLogger("com.acme.customListener")
logs.setLevel(Level.DEBUG)
def issue = ComponentAccessor.getIssueManager().getIssueObject("DVPS-7011") // console testing
def robotUser = ComponentAccessor.getUserManager().getUserByKey("robot-manager")
def approvalService = ComponentAccessor.getOSGiComponentInstanceOfType(ApprovalService)
def approvalQuery = approvalService.newQueryBuilder().issue(issue.id).build()
def approvalOpt = approvalService.getApprovals(robotUser, approvalQuery).findFirst()
if (approvalOpt.isPresent() && !approvalOpt.get().getDecision().isPresent()) {
def approvalsNeeded = approvalService.getApprovers(robotUser, approvalOpt.get()).findAll{!it.getApproverDecision().isPresent()}.collect{it.getApproverUser().name}
logs.info("Approvals needed: $approvalsNeeded")
//
// Remind to approve
//
} else {
logs.info("No pending approvals found for issue [$issue.key]")
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Kirill,
The Approvals and the Approvers are actually custom fields, therefore you can retrieve their values in the usual way
import com.atlassian.jira.component.ComponentAccessor
def issue = ComponentAccessor.getIssueManager().getIssueObject("SD-2")
def approversCF = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find {it.name == "Approvers"}
def approvers = issue.getCustomFieldValue(approversCF)
log.debug approvers //a list of ApplicationUsers
def approvalsCF = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find {it.name == "Approvals"}
def approvals = issue.getCustomFieldValue(approvalsCF)
log.debug approvals // a list of Approval see https://docs.atlassian.com/jira-servicedesk/3.9.0-m0124/com/atlassian/servicedesk/api/approval/Approval.html
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Jira Server 7.11?
Actually, you are waaay wrong /-)
You script returns:
2018-07-17 16:38:48,068 INFO [runner.ScriptRunnerImpl]:
2018-07-17 16:38:48,072 INFO [runner.ScriptRunnerImpl]: com.atlassian.servicedesk.plugins.approvals.internal.customfield.ApprovalsCFValue@475f642
I found the way to get those values, but another bug (no values on transition) prevents me from implement listener script:
import com.atlassian.jira.component.ComponentAccessor
def issue = ComponentAccessor.getIssueManager().getIssueObject('DVPT-1')
def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
log.info("User: $currentUser.name")
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.atlassian.servicedesk.api.approval.ApprovalService
@WithPlugin("com.atlassian.servicedesk")
def approvalService = ComponentAccessor.getOSGiComponentInstanceOfType(ApprovalService)
def approvalQuery = approvalService.newQueryBuilder().issue(issue.id).build()
def approvalEither = approvalService.getApprovals(currentUser, approvalQuery)
def approvals = approvalEither.isRight() ? approvalEither.right : []
def pendingApproval = approvals.find{!it.getDecisionDetails().getOrNull()?.getDecision()}
def approversList = []
if (pendingApproval) {
def approversEither = approvalService.getApprovers(currentUser, pendingApproval)
def approvers = approversEither.isRight() ? approversEither.right : []
approversList = approvers.findAll{!it.getApproverDecision().getOrNull()}.collect{it.getApproverUser().name}
log.info("Pending approval of: $approversList")
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Kirill,
The ApprovalCFValue is a collection of approvals
public ApprovalsCFValue(Collection<Approval> approvals) {
this.approvals = approvals;
}
Do not try to overcomplicate things, those are custom fields treat them as custom fields.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@kilinich do you have any working code? Share it please, I can't make my script (that based on this topic) works.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Nope, Adaptavista confirm that problem but there is no solution yet, so I add notification in post-function instead of listener
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.