Groovy Scripted fields: working days / Hours when calculating dates

Hi, I'm using a scripted field to calculate a latest start date based on due date and original estimation.

The problem I'm encountering is that the result date ignores Jiras settings for working days, hours per day etc. So when my task is due on monday 1pm and i have estimated 2 days for it, i want the latest start date to be set to thursday 1pm instead of sunday night, as 2 days are 16 hours.

Is there a function or simple script for that?

3 answers

1 vote

Use com.atlassian.jira.util.JiraDurationUtils.

Hey Jamie,

i'm trying to do exactly this thing but i haven't figured out how to do it.

I convert the absolute time of original estimate to working days but after that i do not know how to exlude the weekends.

I took a look in the API but i didn't find something that is doing that,

Thanx in advance.

Cheers,

Kostas

Finally i have found a solution by converting the original estimate in number of weeks. That way i can exclude the weekends.

Kostas, would you mind sharing your code?

THX

Daniela

Hey Daniella,

the following code if for a custom listener that catches the event of due date field editing and calculates the latest starting date according to the original estimate.

I have not used JiraDurationUtils cos i convert original estimate to working days in a different way.

I'm sure that the quality of code could be better but it works for my cases, also some imports are not necessary.

Hope it helps.

Cheers,

Kostas

import com.atlassian.jira.event.issue.AbstractIssueEventListener;
import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.event.type.EventDispatchOption;
import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.comments.CommentManager;
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.jira.issue.comments.CommentManager;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.security.JiraAuthenticationContext;
import com.atlassian.jira.user.ApplicationUser;
import com.atlassian.jira.util.JiraDurationUtils;
import com.atlassian.jira.util.I18nHelper;
import com.atlassian.crowd.embedded.api.User;
import java.sql.Connection;
import java.sql.Timestamp
import java.util.Locale;
import groovy.sql.Sql;
import org.apache.log4j.Category
import org.ofbiz.core.entity.ConnectionFactory;
import org.ofbiz.core.entity.DelegatorInterface;
import com.atlassian.jira.web.bean.I18nBean.AccessorFactory;
import com.atlassian.jira.util.I18nHelper;
import com.atlassian.jira.web.bean.I18nBean;







class UpdateDatesListener extends AbstractIssueEventListener {
    Category log = Category.getInstance(UpdateDatesListener.class)
    
 
    @Override
    void workflowEvent(IssueEvent event) {
	

	ComponentManager componentManager = ComponentManager.getInstance();
	
	MutableIssue issue = componentManager.getIssueManager().getIssueObject(event.getIssue().getLong("id"));


	
	if (issue.getDueDate()){

	//Condition, listener to be executed if duedate values changes. I should add here a condition when the original estimate changes

	if (event?.changeLog?.getRelated('ChildChangeItem')?.any{ it.field=='duedate' }) {
	//log.setLevel(org.apache.log4j.Level.DEBUG)
       log.warn "Event: ${event.getEventTypeId()} fired for ${event.issue} and caught by UpdateDatesListener"
	
	
	
	CustomFieldManager customFieldManager = ComponentManager.getInstance().getCustomFieldManager();
	
		
	IssueManager issueManager = componentManager.getIssueManager()

	User user = ComponentAccessor.getJiraAuthenticationContext().getUser().getDirectoryUser();
	

	
	
	//Create Custom Field Objects Using theis ids
	CustomField customField_planned_start = customFieldManager.getCustomFieldObject( 13602 );
	CustomField customField_planned_end = customFieldManager.getCustomFieldObject( 13603 );
	
	JiraDurationUtils jiraDurationUtils = ComponentAccessor.getComponent(JiraDurationUtils.class);
	
	
	
	//Get issue original estimate

	def original_est = issue.getOriginalEstimate() ?: 0


		
	//Get Due Date
	log.warn ("Due Date: " + issue.getDueDate());
	

	//Get the Original Estimate Original Value in Sec
	log.warn ("Original Work Estimate in secs: " + original_est);

	

	//Get the original estimate date in working days. If value is 3.4d, working days are rounded to 4d. 28800 are the seconds for 5d/8h working schedule.
	def working_days = Math.ceil((original_est/28800))

	log.warn ("Working Days: " + working_days.toInteger());


	//Calculate the range in weeks of original estimate
	def weeks = Math.ceil((working_days/5));
	
	//Print range
	log.warn ("Working Weeks: " + weeks);
	
	
	//Calculate extra days from weekends
	def extra_days;


	
	
	if (( issue.getDueDate().getDay() - working_days.toInteger() + (weeks.toInteger() - 1)*5 ) >= 0) {
	

	log.warn ("Residual: " + (issue.getDueDate().getDay() - working_days.toInteger() + (weeks.toInteger() - 1)*5))

	
	extra_days = (weeks - 1)*2;
	
	log.warn ("Extra Days: " + extra_days)
	
	} else {


	log.warn ("Residual: " + (issue.getDueDate().getDay() - working_days.toInteger() + (weeks.toInteger() - 1)*5))

	extra_days = weeks*2;

	

	log.warn ("Extra Days: " + extra_days)

	}


	//Set the new date time value in Planned Start customfield. The calcuation type is [issue.getDueDate() + 1 - (working_days.toInteger() + extra_days.toInteger())]
	
	issue.setCustomFieldValue(customField_planned_start, issue.getDueDate() + 1 - (working_days.toInteger() + extra_days.toInteger()));

	issueManager.updateIssue(user, issue, EventDispatchOption.ISSUE_UPDATED, false)

	}
	}
	}
	
}

0 vote

eg:

def jiraDurationUtils = ComponentAccessor.getComponent(JiraDurationUtils.class)

assert "3 days" == jiraDurationUtils.getFormattedDuration(TimeUnit.HOURS.toSeconds(24))

You can get code to work out a duration ignoring weekends from stackoverflow.

This should be possible with jiraDurationUtils but I am not seeing it right now.

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
Published Tuesday in Marketplace Apps

If you’re an Atlassian app developer, you’ll want to know about Atlas Camp!

This September 6-7, hundreds of Atlassian App developers will flock to Barcelona Spain to build skills, discover product roadmaps, meet face-to-face with the Atlassian team, and learn how to extend t...

119 views 0 4
Read article

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