How to maintain Original Estimate time from Azure to Jira

Originally asked by Ken Vetter on 10 March 2021 (original question)


I have a strange issue where I am trying to sync up task hours from an Azure Task to a Jira task and have them sync bi-directionally as the issue or task gets updated.

I can establish initial values for Original Estimates and Remaining Hours, but it seems like every other time I try to update from Azure to Jira by reducing the remaining hours in the Azure task, the Jira task updates the Original Estimate by reducing the time I subtracted in the remaining hours.

It doesn’t matter which side I initiate the task from, it still winds up changing the Original Estimate on the Jira side after 1st sync.

Example:

1st Sync

From Azure: To Jira

Original Estimate – 16 hours Original Estimate - 2d

Remaining Hours – 16 hours Remaining – 2d

1st Update Task in Azure (sync results)

From Azure: To Jira

Original Estimate – 16 hours Original Estimate – 1d 6h

Remaining Hours – 14 hours Remaining – 1d 6h

2nd Update Task in Azure

From Azure: To Jira

Original Estimate – 16 hours Original Estimate – 2d

Remaining Hours – 12 hours Remaining – 1d 4h

It seems that every other sync, the Original Estimate in Jira corrects itself. Every other time, the Original Estimate reflects the Remaining Estimate.

Need to know why this is happening and how do I fix it.

BTW, this all works fine from Jira to Azure.

Can set Original Estimate, Time Remaining, and Time Spent in Jira and all sync properly to Azure.


Comments:

Ken Vetter commented on 10 March 2021

Here are my outgoing and incoming scripts for time tracking for each side.

Outgoing Jira:

// Add the time tracking information to the datafilter
replica.timeSpent = issue.timeSpent
replica.originalEstimate = issue.originalEstimate
replica.remainingEstimate = issue.remainingEstimate

Incoming Azure:

//Time Tracking
if(replica.originalEstimate) {
workItem.“Microsoft.VSTS.Scheduling.OriginalEstimate” = (replica.originalEstimate as Double)/3600
}
if(replica.remainingEstimate) {
workItem.“Microsoft.VSTS.Scheduling.RemainingWork” = (replica.estimate as Double)/3600
}
if(replica.timeSpent) {
workItem.“Microsoft.VSTS.Scheduling.CompletedWork” = (replica.spent as Double)/3600
}

Outgoing Azure:

//Time Tracking
replica.originalEstimate = workItem.“Microsoft.VSTS.Scheduling.OriginalEstimate”
replica.RemainingWork = workItem.“Microsoft.VSTS.Scheduling.RemainingWork”
replica.CompletedWork = workItem.“Microsoft.VSTS.Scheduling.CompletedWork”

Incoming Jira:

//Time Tracking
if ((firstSync && replica.originalEstimate != null) || (!firstSync && replica.originalEstimate != previous?.originalEstimate)) {
issue.originalEstimate = (replica.originalEstimate as Double)*3600
} else {
issue.originalEstimate = (previous.originalEstimate as Double)*3600
}
if (replica.RemainingWork) {
issue.remainingEstimate = (replica.RemainingWork as Double)*3600
}
if (replica.CompletedWork) {
issue.timeSpent = (replica.CompletedWork as Double)*3600
}

In the else statement above, I am trying to maintain the value of OriginalEstimate, but is seems when I update Remaining (hours) on Azure side, that new time also gets updated to OriginalEstimate.

See my example in my question.

Ken Vetter commented on 12 March 2021

Hello Andre,

Thank for answering my question.

I have tried your scripts and getting the same result.

Jira Original Estimate is still reflecting the remaining time from Azure.

Is there a way to debug what value is being sent and received for each time entry?

I have hard coded values in to see, but would like to see what the script is interpreting in the replica values.

Thank you!

André Leroy-Beaulieu Castro commented on 19 March 2021

Hi Ken,

If your Jira is a Jira Cloud, you can go to the Entity Sync Status page of Exalate and look for the Jira issue that you are using to test this and you can click on “see remote replica” and the button to see what is being sent from the Azure side, there you will see the values stored in the custom keys. You can do the same thing in the Entity Sync Status tab on the Exalate for Azure DevOps to see the values sent from the Jira side.

Thanks,

André

Answer by André Leroy-Beaulieu Castro on 10 March 2021

Hi Ken,

I saw some flaws in your earlier scripts that I think may be the reason why you were experiencing weird behavior, here are some scripts that I think have the correct logic set up for your use case. Can you change all four of your scripts to the following, publish them, then retry your tests with a brand new work item / issue and let us know how it goes?

Thanks!

---

Outgoing Jira:

// Add the time tracking information to the datafilter

//Time Spent
replica.spent = issue.spent

//Original Estimate
replica.originalEstimate = issue.originalEstimate

//Remaining Estimate
replica.estimate = issue.estimate

Incoming Azure:

//Time Tracking
if(replica.originalEstimate) {
workItem.“Microsoft.VSTS.Scheduling.OriginalEstimate” = (replica.originalEstimate as Double)/3600
}
if(replica.remainingEstimate) {
workItem.“Microsoft.VSTS.Scheduling.RemainingWork” = (replica.estimate as Double)/3600
}
if(replica.timeSpent) {
workItem.“Microsoft.VSTS.Scheduling.CompletedWork” = (replica.spent as Double)/3600
}

Outgoing Azure:

//Time Tracking
replica.customKeys.“OriginalEstimate” = workItem.“Microsoft.VSTS.Scheduling.OriginalEstimate”
replica.customKeys.“RemainingWork” = workItem.“Microsoft.VSTS.Scheduling.RemainingWork”
replica.customKeys.“CompletedWork”= workItem.“Microsoft.VSTS.Scheduling.CompletedWork”

Incoming Jira:

//Time Tracking
if (replica.customKeys.“OriginalEstimate”) {

issue.originalEstimate = (replica.customKeys.“OriginalEstimate” as Double)*3600

}

if (replica.customKeys.“RemainingWork”) {

issue.originalEstimate = (replica.customKeys.“RemainingWork” as Double)*3600

}

if (replica.customKeys.“CompletedWork”) {

issue.originalEstimate = (replica.customKeys.“CompletedWork” as Double)*3600

}