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

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

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 

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

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)

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 ?

Hi Thanos,,

JIRA version is 6.2 and the SR version is 3.0.16.

 

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 ?

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

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.   

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.

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

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");
    }
}

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

Thankyou very much Thanos

0 vote
Vasiliy Zverev Community Champion Jan 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.

Suggest an answer

Log in or Sign up to answer
How to earn badges on the Atlassian Community

How to earn badges on the Atlassian Community

Badges are a great way to show off community activity, whether you’re a newbie or a Champion.

Learn more
Community showcase
Posted Wednesday in Jira

Join our webinar: How 1B+ feature flag events helped us build the new Jira

Every time you release software, there's a bit of risk – that there's a bug, that something breaks, or that the feature doesn't resonate with customers. Feature flagging helps make high stakes s...

134 views 0 3
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you