The following detailed list shows which parser functions are valid for a migration and which are not, with possible workarounds on some parser functions which are not available for JWT Cloud.
Parser function JWT (Server / DC) 3.x | Parser function cloud | Map | Notes |
---|---|---|---|
siblingIssuesUnderEpic() | siblingIssuesUnderEpic() | ||
userDisplayName() | Workaroundissue.reporter.displayName //and issue.watchers.map(u=>u.displayName) Only possible to access it using an user field, but it is not possible to access to an user with an username, only with the account ID. | ||
filterByPredicate() | WorkaroundText list let list = ["abc", "def", "ghij", "klmn"]; list.filter(t=> t.length>3) Number list let list = [3,2,5,1,6,0]; list.filter(t=> t>3) Issue list let current = issue; let list = issue.links.map(l=>l.linkedIssue); list.filter(i=>i.priority>=issue.priority) It won't be possible to use the seed itself, but as long as you have the current issue and the list of issues in variables, it's possible to replicate the functionality. | ||
getRemoteLinks() | |||
count() | count() | ||
mathOnNumberList() | WorkaroundJust like for mathOnIssueList() but using a number list. | ||
componentLeader() | Not possible to replicate because the only available component's properties are ID and name. | ||
defaultUserForRole() | It's only possible to access to the ID, name and description of the Project Roles. | ||
lastDayOfTheMonth() | Workaround%{stringToDate(toString(year({issue.created}, RUN_AS_LOCAL)) + "/" + toString(month({issue.created}, RUN_AS_LOCAL)) + "/" + toString(getMatchingValue(month({issue.created}, RUN_AS_LOCAL), [1,2,3,4,5,6,7,8,9,10,11,12], [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31])), RUN_AS_LOCAL)} | ||
round() | round(number) | ||
timeLogged() | Workaround%{sum(toNumberList(jiraExpression("issue.links.map(l=>l.linkedIssue) .map(e=>e.timeSpent)")))} It's only possible to do it using our General parser. | ||
filterByResolution() | Workaroundlet list = issue.links.map(l=>l.linkedIssue); list.filter(i=>i.resolution!=null && ["Done", "Resolved"].includes(i.resolution.name)) | ||
filterByIssueType() | Workaroundlet issues = issue.links.map(l=>l.linkedIssue); issues.filter(i=>i.issueType.name=="Bug") | ||
linkedIssues() | linkedIssues() | The Cloud's version doesn't include Epic-Tasks links. | |
project() | Workaroundnew Project(10000) | ||
isAClone() | WorkaroundThere is no direct way of implementing the same behaviour, but we can filter an issue list comparing some of its fields with the Current issue, so we can check if the current issue has the same fields as any other on that issue list, which would mean that it is a clone. For example: let current = issue; let list = issue.links.map(l=>l.linkedIssue); list.some(i=>i.priority==issue.priority && i.summary==issue.summary) | ||
mathOnIssueList() | Workaroundlet list = issue.links.map(l=>l.linkedIssue); list.map(i=>i.customfield_10016 * issue.customfield_10017) It can be done as long as the mathematical calculations are not complex. | ||
lastAssigneeInRole() | Not possible to access the historic values of the Assignee field. | ||
withinCalendar() | Not possible because JWT's Calendars are not implemented in the Cloud version. | ||
year() | year() | ||
userEmail() | Not possible to access to a user's email. | ||
wikiToHTML() | Not possible to convert the rich text wiki content into HTML. | ||
weekOfTheYear() | Not possible to access to that kind of information. | ||
usersWithEmail() | Not possible to access to a user's email. | ||
usersWhoTransitioned() | Not possible to get the user who transition an issue. | ||
usersInRole() | Not possible to get all the users that belongs to a project role. | ||
usersInGroup() | Not possible to get all the users that belongs to a group. | ||
userProperty() | Workaorundissue.reporter.properties.get("key") This should work, but it is not working for me. | ||
userFullName() | Workaorundissue.reporter.displayName //and issue.watchers.map(u=>u.displayName) Only possible to access it using an user field, but it is not possible to access to an user with an username, only with the account ID. | ||
unreleasedVersionsBySequence() | Not possible to access to the versions that belongs to a project, only to the versions that belongs to an issue. | ||
unreleasedVersions() | Not possible to access to the versions that belongs to a project, only to the versions that belongs to an issue. | ||
union() | union() | ||
unescapeHTML() | It's not really necessary a workaround, because, for example, if the HTML escapes are in the description and in the summary, then we can just do the following: issue.summary //or issue.description.plainText //Because it's rich text | ||
trim() | trim() | ||
transitivelyLinkedIssues() | Workaround%{union(linkedIssues("is blocked by", linkedIssues("is blocked by")), linkedIssues("is blocked by"))} Using our General parser we can access the current issue's linked issues and theirs linked issues. | ||
transitionLinkedIssues() | Not possible because that kind of information is not available. | ||
toUpperCase() | toUpperCase() | ||
toStringList() | toStringList() | ||
toString() | toString() | ||
toRadians() | Not possible because that kind of information is not available. | ||
toNumberList() | toNumberList() | ||
toNumber() | toNumber() | ||
toLowerCase() | toLowerCase() | ||
toInteger() | Not possible to cast string into number in other representation different than the decimal. | ||
toDegree() | Not possible to make complex/trigonometric calculations using Jira Expressions. | ||
timeZone() | WorkaroundSince to convert string to date time values the string needs to be written in the ISO 8601 format, the time zones will always be just like it is explained here. With this in mind, a workaround can be build if needed using our parser function getMatchingValue(). | ||
timesOfTransition() | Not possible because that kind of information is not available. | ||
timePart() | timePart() | ||
timeInValue() | Not possible because that kind of information is not available. | ||
timeInStatus() | Not possible because that kind of information is not available. | ||
timeDifference() | Not possible because JWT's Calendars are not implemented in the Cloud version. | ||
textOnStringList() | Just like with textOnIssueList() but on a text list. | ||
textOnNumberList() | Just like with textOnIssueList() but on a text list. | ||
textOnNumberList() | Just like with textOnIssueList() but on a number list. | ||
textOnIssueList() | Workaroundlet list = issue.links.map(l=>l.linkedIssue); list.map(i=>issue.summary + " - " + i.priority.name) | ||
tanh() | Not possible to make trigonometric calculations using Jira Expressions. | ||
tan() | Not possible to make trigonometric calculations using Jira Expressions. | ||
sum() | sum() | ||
subtractDatesSkippingWeekends() | Workaroundlet now = new Date(); now = now.minusHours(12); now = now.minusMinutes(15); now.getDay()==0? now.minusDays(1):(now.getDay()==6? now.minusDays(2): now)//Skip weekends | ||
subtasks() | subtasks() | ||
substring() | substring() | ||
sublist() | sublist() | ||
stringToDate() | stringToDate() | ||
status() | Not possible to find statuses by their ID. | ||
startDates() | Not possible to access that property. | ||
sqrt() | Not possible to make complex calculations using Jira Expressions. | ||
sort() | sort() | ||
sinh() | Not possible to make trigonometric calculations in Jira Expressions. | ||
sin() | Not possible to make trigonometric calculations in Jira Expressions. | ||
similarity() | |||
siblingSubtasks() | Workaroundlet parent = issue.parent; parent.subtasks.filter(s=>s.key!=issue.key) | ||
shortFormatDuration() | There's not really a workaround for this, because Jira Expressions don't let you calculate the difference between dates, nor working with Duration values. Also, with our parser we can calculate the difference, but we cannot format it. | ||
shortFormatWorkDuration() | There's no workaround for the same reason as shortFormatDuration(). | ||
siblingIssues() | Not possible to navigate through the Advanced Roadmaps hierarchy. Only the Parent link is accessible, but then it's not possible to acces their children, or I have not found the way, | ||
setStringList() | WorkaroundIt would be the same as setBoolean(), but in the variable we would get a string list. | ||
setString() | WorkaroundIt would be the same as setBoolean(), but in the variable we would get a string. | ||
setNumberList() | WorkaroundIt would be the same as setBoolean(), but in the variable we would get a number list . | ||
setNumber() | WorkaroundIt would be the same as setBoolean(), but in the variable we would get a number. | ||
setIssueList() | WorkaroundIt would be the same as setBoolean(), but in the variable we would get an issue list. | ||
setBoolean() | WorkaroundSince Jira Expressions allows to have variables, there is a simple workaround for this: let myBoolean = issue.priority.name>"Medium"; myBoolean ? "It is correct": "It's not" | ||
second() | second() | ||
rolesUserPlays() | Workaroundissue.reporter.getProjectRoles(new Project("SGC")) | ||
resolution() | Not possible to find a resolution by its ID. | ||
replaceFirst() | replaceFirst() | ||
replaceAll() | replaceAll() | ||
remainder() | Workaround%{3 - 4*round(3/4)} | ||
releasedVersionsBySequence() | Not possible to access to the project's versions, only to the ones that are assigned to the current issue. | ||
releasedVersions() | Not possible to access to the project's versions, only to the ones that are assigned to the current issue. | ||
releaseDates() | Workaroundissue.fixVersions.map(v=>v.releaseDate) There's no workaround for the project keys' variant. | ||
filterByValue() | filterByValue() | ||
random() | random() | ||
projectType() | Workaroundnew Project("SGC").projectTypeKey | ||
projectPropertyExists() | Not possible to access the projects' description. | ||
projectProperty() | Not possible to access the projects' description. | ||
projectName() | Workaroundnew Project("SGC").name | ||
projectLeader() | Not possible to access that kind of information using Jira Expressions. | ||
projectLead() | Not possible to access that kind of information using Jira Expressions. | ||
projectKeys() | Not possible to find projects by their project category or without any parameter. | ||
projectKey() | Not possible to find projects by their name, only by their ID and their key. | ||
projectCategory() | Not possible to access this property. | ||
priority() | Not possible because we cannot find IssuePriorities by their IDs. | ||
previousValue() | Not possible to access to historic values. | ||
pow() | The only possible way of replicating this behaviour would be just to manually make the calculation, so if it's pow(5,2) you can do: 5*5. But I don't think this is a workaround, because it should be changed every time the second parameter changes ,so it's not that automatic. | ||
parent() | Workaroundissue.customfield_10018 Where 10018 is the Parent link's custom field ID in the corresponding instance. | ||
option() | Not possible to access to that kind of information about fields. | ||
numberOfSelectedItems() | Not possible to access to that kind of information about selectable fields. | ||
numberOfRemoteIssueLinks() | Not possible to differentiate between remote and non-remote issue links. | ||
numberOfAvailableItems() | Not possible to access to that kind of information about selectable fields. | ||
nthElement() | nthElement() | ||
nextUserInGroup() | Not possible to access to information about Groups. | ||
nextTime() | Not possible because we have not implemented yet Calendars on the Cloud version. | ||
nextDayOfTheWeek() | Workaroundlet daysInWeek = [1,2,3,4,5,6,7].map(n => issue.created.plusDays(n).toCalendarDateUTC() ); let days = daysInWeek.map(d=>d.getDay()); let index = days.indexOf(4); //4 is Thursday daysInWeek[index] | ||
monthToString() | Workaround%{getMatchingValue(month({issue.created}, RUN_AS_LOCAL), [1,2,3,4,5,6,7,8,9,10,11,12], ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"])} | ||
month() | month() | ||
modulus() | modulus(numbers) | ||
minute() | minute() | ||
min(list) | min(numbers) | ||
min() | min() | ||
max(list) | max(numbers) | ||
max() | max() | ||
mathOnStringList() | WorkaroundJust like for mathOnIssueList() but using a string list. | ||
matches() | matches() | ||
log() | Not possible to make complex calculations with Jira Expressions. | ||
log10() | Not possible to make complex calculations with Jira Expressions. | ||
length() | length() | ||
leastBusyUserInRole() | Not possible to access an specific Project Role or to find users. | ||
latestReleasedVersion() | Not possible to find project's versions, just the current issue's version. | ||
lastFieldChangeTime() | Not possible to access the historic values of any field. | ||
last() | last() | ||
issueType() | IssueType doesn't have a constructor, so it's not possible to find issue types. | ||
issuesUnderEpic() | issuesUnderEpic() | ||
issuesUnder() | Not possible to access the Advanced roadmaps' Parent link nor the Advanced roadmaps' children, so it's not possible to replicate any of the AR functions behaviour yet. | ||
issuesFromJQL() | issuesFromJQL() | ||
issueSecurityLevel() | Not possible to access all of the Security Levels in the instance, so it's not possible to find them, just the one that the issue has. | ||
issuesAbove() | Not possible to access the Advanced roadmaps' Parent link nor the Advanced roadmaps' children, so it's not possible to replicate any of the AR functions behaviour yet. | ||
issueKeysToIssueList() | issueKeysToIssueList() | ||
issueKeyFromID() | Workaroundlet issue = new Issue(10004); issue.key | ||
issueIDFromKey() | Workaroundlet issue = new Issue("SGC-5"); issue.id | ||
isJwtTriggeredTransition() | Property not existent in the Transition's json. | ||
isInGroup() | Workaroundlet users = issue.watchers; users.map(u=>u.getProjectRoles(issue.project).length!=0) This code should work correctly, but unfortunately it seems like the getProjectRoles() function does not work correctly and it does not return anything. | ||
isBulkTriggeredTransition() | Property not existent in the Transition's json. | ||
isActive() | Even though there is an active property in the json returned of an user, is not possible to access it, so is not possible to replicate its behaviour. | ||
invertList() | Workaroundlet list = [11,7,3,2,5]; let pos = list.map(e=>list.length-list.indexOf(e)-1); pos.flatMap(p=> list[p]) The list pos is a inverted list of the indexes of the original list. | ||
intersect() | intersect() | ||
indexOf() | Workaroundlet list = [11,7,3,2,5]; list.indexOf(2) | ||
htmlToTxt() | WorkaroundThe function replace can be use to replace every HTML tag into an empty string. issue.description.plainText.replace("<([^>]+)>", "") | ||
hour() | hour() | ||
hasChanged() | Not possible to access historic values in Jira Expressions. | ||
groupsUserBelongsTo() | It's possible to access to a user's groups, but it's not possible to do it by only using the username, because to access to a user the acccount ID should be used. Also, using a field code it can be done. Workaroundissue.reporter.groups or let userSearch = new User("5e60bebccf54800ce3a0221c"); userSearch.groups | ||
getUserKey() | It's not possible, because there's no way to access to the user key without using API. | ||
getStringList() | WorkaroundIt would be the same as the one for getBoolean(), but in the variable we would store an issue list. | ||
getString() | WorkaroundIt would be the same as the one for getBoolean(), but in the variable we would store an issue list. | ||
getNumberList() | WorkaroundIt would be the same as the one for getBoolean(), but in the variable we would store an issue list. | ||
getNumber() | WorkaroundIt would be the same as the one for getBoolean(), but in the variable we would store an issue list. | ||
getMatchingValue() | getMatchingValue() | ||
getIssuesFromProjects() | WorkaroundNot possible with Jira Expression, but it's possible with our parser function issuesFromJQL(). %{issuesFromJQL("project in ('SGC, CRM')")} | ||
getIssueList() | WorkaroundIt would be the same as the one above, but in the variable we would store an issue list. | ||
getBoolean() | WorkaroundSince Jira Expressions allows to have variables, there is a simple workaround for this: let myBoolean = issue.priority.name>"Medium"; myBoolean ? "It is correct": "It's not" | ||
getAscii() | Not possible. | ||
fullNameToUser() | Not possible, because there is no way to access the users, just the users that are related to the issue/s itself. | ||
formatWorkDuration() | There's no workaround because of the same reason as the previous function. | ||
formatDuration() | There's not really a workaround for this, because Jira Expressions don't let you calculate the difference between dates, nor working with Duration values. Also, with our parser we can calculate the difference, but we can't format it. | ||
floor() | floor() | ||
first() | first() | ||
findReplaceFirstIgnoreCase() | findReplaceFirstIgnoreCase() | ||
findReplaceFirst() | findReplaceFirst() | ||
findReplaceAllIgnoreCase() | findReplaceAllIgnoreCase() | ||
findReplaceAll() | findReplaceAll() | ||
findPatternIgnoreCase() | findPatternIgnoreCase() | ||
findPattern() | findPattern() | ||
findModify() | Workaroundlet desc = issue.description.plainText; desc.replace("\badmin\b", "tester") | ||
filterByStatusCategory() | Workaroundlet list = issue.links.map(l=>l.linkedIssue); list.filter(i=>["To Do"].includes(i.status.category.name)) | ||
filterByStatus() | Workaroundlet list = issue.links.map(l=>l.linkedIssue); list.filter(i=>["Backlog", "Selected for Development"].includes(i.status.name)) | ||
filterByProjectCategory() | Workaroundlet list = issue.links.map(l=>l.linkedIssue); list.filter(i=>i.project.projectTypeKey=="software") To filter by a list of Project Categories the includes() function should be used, just like in the filterByProject() example. | ||
filterByProject() | Workaroundlet list = issue.links.map(l=>l.linkedIssue); list.filter(i=> ["SGC", "CT"].includes(i.project.key)) Where SGC and CT are project keys. | ||
filterByFieldValue() | Workaroundlet issues = issue.links.map(l=>l.linkedIssue); issues.filter(i=>i.summary=="Testing cases") Or if it is a numeric field: let issues = issue.links.map(l=>l.linkedIssue); issues.filter(i=>i.customfield_10033>10) | ||
filterByCardinality() | filterByCardinality() | ||
filledInTransitionScreen() | There is no way to know when a field has changed using Jira Expressions. It's also not possible to access the fields available in a Transition's screen. | ||
fieldValue() | Workaroundlet issues = issue.links; issues.map(i=>i.linkedIssue.summary) This expression will allow us to access the summary of all the current issue's linked issues. This linked issues can be filtered, but I don't think it's possible to access issues which are not linked to the current issue. | ||
fieldHistory() | There is no way to access the field's history. | ||
fieldChangeTimes() | There is no way to know when a field has changed using Jira Expressions. | ||
except() | except() | ||
escapeHTML() | Jira Expression doesn't have the power to escape HTML characters. | ||
epic() | epic() | ||
earliestUnreleasedVersion() | Not possible to access the project's versions, so it's not possible to replicate it yet. | ||
earliestUnreleasedUnarchivedVersion() | Not possible to access the project's versions, so it's not possible to replicate it yet. | ||
distinct() | distinct() | ||
displayNameToUser() | It's only possible to find users via ID. | ||
daysInTheMonth() | Workaround%{getMatchingValue(month({issue.created}, RUN_AS_LOCAL), [1,2,3,4,5,6,7,8,9,10,11,12], [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31])} Not with Jira Expression, but we can achieve it with our Parser Expressions. | ||
dayOfTheYear() | Not possible to replicate the behavior. | ||
dayOfTheWeekToString() | Workaround%{getMatchingValue(dayOfTheWeek({issue.created}, RUN_AS_LOCAL), [1,2,3,4,5,6,7],["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"])} Not with Jira Expression, but we can achieve it with our Parser Expressions. | ||
dayOfTheWeek() | dayOfTheWeek() | ||
dayOfTheMonth() | dayOfTheMonth() | ||
dateToString() | dateToString() | ||
dateTimeToString() | dateTimeToString() | ||
dateTime() | Workaroundnew Date("2020-05-03T15:53:00") The date must be inputted as, a string with the ISO 8601 format. | ||
datePart() | datePart() | ||
cosh() | Not possible to execute any trigonometric operation using Jira Expressions. | ||
cos() | Not possible to execute any trigonometric operation using Jira Expressions. | ||
componentLeads() | WorkaroundOur field code %{issue.components.leads} | ||
ceil() | ceil(number) | Not possible with the available numeric operators. | |
abs() | abs(number) | ||
cbrt() | Not possible with the available numeric operators. | ||
capitalizeWordsFully() | Workaround let words = issue.summary.split(" "); words.map(w=>w.split("").map(c=>w.indexOf(c)==0? c.toUpperCase(): c.toLowerCase())).join().replace("\[", "").replace(" ","").replace(",","").replace("\]"," ") This expression works the same as the previous one, but making sure that the chars that are not the first in each word are in lower case. | ||
capitalizeWords() | Workaround let words = issue.summary.split(" "); words.map(w=>w.split("").map(c=>w.indexOf(c)==0? c.toUpperCase(): c)).join().replace("\[", "").replace(" ","").replace(",","").replace("\]"," ") This expression converts the phrase into a list of char lists of each word, and then it converts to upper case every first char of each word. Then it converts it again into a string replacing the brackets and commas. | ||
avg() | avg() | ||
availableItems() | Not possible to access the possible options of a select-able field with Jira expressions. | ||
attachmentUrls() | Workaround issue?.attachments?.map(a => "https://jwt-cloud-integration.atlassian.net/secure/attachment/" + a.id + "/" + a.filename) It's not possible to get the attachment's content, which is the attachment's URL, even if it appears in the json. So the only way to replicate the behavior would be by "manually" writing the URL. | ||
asin() | |||
atan() | |||
archivedVersions() | Not possible to access the project's versions, so it's not possible to replicate it yet. | ||
append() | append() | ||
allIssuesUnder() | Not possible to access the Advanced roadmaps' Parent link nor the Advanced roadmaps' children, so it's not possible to replicate any of the AR functions behavior yet. | ||
allComments() | Workaround issue.comments.map(c=>c.body.plainText) | ||
allCommenters() | Workaround | ||
allCommentDates() | Workaround issue.comments.map(c=>c.created) | ||
allCommentCreators() | Workaround issue.comments.map(c=>c.author.displayName) | ||
allAvailableItems() | Not possible with Jira expressions. | ||
addDays() | addDays() | ||
acos() | Not possible with Jira expression. |
If you still have questions, feel free to refer to our support team.