How to Copy the Work Log in Field via Script-runner Listener Class?

Vineet Kumar January 14, 2016

Hi All,

I would like to copy the value of 'Logged' field to a custom field every time the issue gets updated, I was able to collect this groovy class which i have placed as a 'Custom listener' thru Script-runner plugin, but it is failing to copy the value. Can someone please correct me?

 

import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
public class LoggedFieldDuplicate
{


@EventListener
public void listenForIssueEvent(IssueEvent issueEvent)
{
if (issueEvent.getEventTypeId().equals(EventType.ISSUE_WORKLOG_DELETED_ID) || issueEvent.getEventTypeId().equals(EventType.ISSUE_WORKLOG_UPDATED_ID) || issueEvent.getEventTypeId().equals(EventType.ISSUE_WORKLOGGED_ID))
{
Issue issue = issueEvent.getIssue();
log.debug "Logged Time: ${issue.getTimeSpent()} "
def tgtField = customFieldManager.getCustomFieldObjects(issue).find {it.name == "Actual Fix time coding"}
def changeHolder = new DefaultIssueChangeHolder();
tgtField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(tgtField), issue.getTimeSpent()),changeHolder);
}
}
}

2 answers

1 accepted

1 vote
Answer accepted
Thanos Batagiannis _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 14, 2016

Hi Vineet,

In your customer Listener you should be able to select from the dropdown the events you need to trigger the listener (in your case should be work started on issue, work stopped, worklog deleted) and fro the inline add 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

def customFieldManager = ComponentAccessor.getCustomFieldManager()
Issue issue = event.issue;
log.debug "Logged Time: ${issue.getTimeSpent()} "
def tgtField = customFieldManager.getCustomFieldObjects(issue).find {it.name == "Actual Fix time coding"}
def changeHolder = new DefaultIssueChangeHolder();
tgtField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(tgtField), issue.getTimeSpent() as Double),changeHolder);

Note that the .getTimeSpent() returns a long so you should make sure that the custom field type you are trying to update is type of number, or get a string representation of the long and save it to a text field custom field. Please let me know if this works for you 

Thanos Batagiannis _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 14, 2016

The getTimeSpent() will return to you the time in milliseconds, so probably you would like to convert into hours.

Vineet Kumar January 14, 2016

Hi Thanos, Thanks for your valuable response i have tried the same but the value is still failing to replicate. Below is the exception i have received. Can you please help.

2016-01-15 02:18:59,335 http-bio-8086-exec-15 WARN vkumar 138x540x1 ob2q24 0:0:0:0:0:0:0:1 /secure/CreateWorklog.jspa [jira.workflow.listeners.CustomListener] Listener class must implement workflowEvent(IssueEvent event).
2016-01-15 02:18:59,341 http-bio-8086-exec-15 ERROR vkumar 138x540x1 ob2q24 0:0:0:0:0:0:0:1 /secure/CreateWorklog.jspa [atlassian.event.internal.AsynchronousAbleEventDispatcher] There was an exception thrown trying to dispatch event 'com.atlassian.jira.event.issue.IssueEvent@41d1131c[issue=GROOVY-1,comment=<null>,worklog=com.atlassian.jira.issue.worklog.WorklogImpl@1ab86c58,changelog=[GenericEntity:ChangeGroup][id,10101][author,vkumar][created,2016-01-15 02:18:59.288][issue,10000],eventTypeId=10,sendMail=true,params={level=null, eventsource=action, rolelevel=null, baseurl=http://localhost:8086},subtasksUpdated=false]' from the invoker 'SingleParameterMethodListenerInvoker{method=public void com.onresolve.scriptrunner.runner.ScriptListener.workflowEvent(com.atlassian.jira.event.issue.IssueEvent), listener=com.onresolve.scriptrunner.runner.ScriptListener@52912851}'.
java.lang.RuntimeException: No signature of method: LoggedField.workflowEvent() is applicable for argument types: (com.atlassian.jira.event.issue.IssueEvent) values: [com.atlassian.jira.event.issue.IssueEvent@41d1131c[issue=GROOVY-1,comment=<null>,worklog=com.atlassian.jira.issue.worklog.WorklogImpl@1ab86c58,changelog=[GenericEntity:ChangeGroup][id,10101][author,vkumar][created,2016-01-15 02:18:59.288][issue,10000],eventTypeId=10,sendMail=true,params={level=null, eventsource=action, rolelevel=null, baseurl=http://localhost:8086},subtasksUpdated=false]]
	at com.atlassian.event.internal.SingleParameterMethodListenerInvoker.invoke(SingleParameterMethodListenerInvoker.java:54)
	at com.atlassian.event.internal.AsynchronousAbleEventDispatcher$2.run(AsynchronousAbleEventDispatcher.java:66)
	at com.atlassian.event.internal.AsynchronousAbleEventDispatcher$1.execute(AsynchronousAbleEventDispatcher.java:32)
	at com.atlassian.event.internal.AsynchronousAbleEventDispatcher.dispatch(AsynchronousAbleEventDispatcher.java:60)
	at com.atlassian.event.internal.EventPublisherImpl.invokeListeners(EventPublisherImpl.java:160)
	at com.atlassian.event.internal.EventPublisherImpl.publish(EventPublisherImpl.java:79)
Thanos Batagiannis _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 14, 2016

Hi Vineet,

Can I ask you what JIRA and SR versions you use ? And if you tried it as a a script listener > custom listener ?

Vineet Kumar January 14, 2016

Hi Thanos,,

JIRA version is 6.2 and the SR version is 3.0.16.

 

Thanos Batagiannis _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 15, 2016

Vinnet, 

The script I posted to you is custom listener script which executed with the events you associate. I had the chance to test the script above using a SR v3.1.* (the last non paid) associating all the work log events and it works. Could you please try it as a custom listener ?

Vineet Kumar January 17, 2016

Hi Thanos, I really appreciate your effort, actually it was custom listener from the beginning, i have selected the events you have mentioned, but when i am logging the additional time my number (type) field is still not updating. I am using this version for trial and there is a plan to purchase a latest version of script-runner in this quarter on my request. field.jpglistner.jpg

Thanos Batagiannis _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 17, 2016

Hi Vinnet,

Just try to add the above code as a groovy script int he 'name of groovy class' field. For example add your LoggedField.groovy script into a path declared as your script roots (you can find your script roots by navigating into the script console). And then in the name of groovy class just add LoggedField.groovy. Please let me know if this works.   

Vineet Kumar January 18, 2016

Hi Thanos, I was doing in the same way, I have created a Number field with the name "Actual Fix time coding" and placed it on the view and edit screen, now when i am creating/updating the work log the field "Logged" is updating but the field "Actual Fix time coding" is still empty with the same exception.

Vineet Kumar January 18, 2016

And also the exception says that "Listener class must implement workflowEvent(IssueEvent event)", please advise.

Vineet Kumar January 20, 2016

Hi Thanos, Thanks for the help, with the help of below script i was able to pass the value.

But currently i have created the field of number type but i would like to have a Text field instead, Any idea how can i typecast, run some attempts but unsuccessful.

package acme.LoggedFieldEvent
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
import org.apache.log4j.Category
import com.atlassian.jira.event.issue.*
class LoggedFieldEvent extends AbstractIssueEventListener {
    Category log = Category.getInstance(LoggedFieldEvent.class);
	
    @Override
	
    void workflowEvent(IssueEvent event) {
	log.setLevel(org.apache.log4j.Level.DEBUG);
    def customFieldManager = ComponentAccessor.getCustomFieldManager()
	Issue issue = event.issue;
	log.debug "Logged Time===================================>>>>>>>>>>>: ${issue.getTimeSpent()} "
	def tgtField = customFieldManager.getCustomFieldObjects(issue).find {it.name == "Actual Fix time coding"}
	def changeHolder = new DefaultIssueChangeHolder();
	tgtField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(tgtField), (issue.getTimeSpent()/(60*60)) as double),changeHolder);
	log.debug ("SGD Event: ${event.getEventTypeId()} fired for ${event.issue} and caught by ExampleListener");
    }
}
Thanos Batagiannis _Adaptavist_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 20, 2016

I suppose the (issue.getTimeSpent()/(60*60)).toString() will do the trick

Vineet Kumar January 20, 2016

Thankyou very much Thanos

0 votes
Vasiliy Zverev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 14, 2016

To store changes of issue into database you need to use 

ComponentAccessor.getIssueManager().updateIssue(ComponentAccessor.jiraAuthenticationContext.getUser().directoryUser, issue, EventDispatchOption.ISSUE_UPDATED, false)

So, you change number of fields and then store it into database one time.

Vineet Kumar January 20, 2016

Thanks Vasiliy

Suggest an answer

Log in or Sign up to answer