The formula fields library provides you with an overview of all available templates and additional use cases (example expressions) that should give you an easy start on how to use Advanced Formula Fields.
Make sure to come by once in a while since the number of use cases will grow over time.
Templates
Advanced Formula Fields provides a varied set of preconfigured Templates you can use with minimal configuration. These are shown if you Create and configure formula fields or when you Manage existing formula fields / Field overview.
They are group into logical categories depending on the use case or the data that you likely want to display. These categories are:
📚 Additional use cases using custom formulas
In addition to the built-in templates we have collected a large collection of uses cases to be used in Custom number formula and Custom text formulafields.
🔢 Custom number formulas
|
Use case |
Parsing mode |
Expression |
|---|---|---|
|
General |
%{floor(avg(toNumberList(jiraExpression("issue.subtasks.map(i=>(Number(new Date())- Number(i.created)))"))))} |
|
|
General |
%{%{issue.status} = "Open" ? 0 : ( %{issue.status} = "Planning" ? 15 : ( %{issue.status} = "In Progress" ? 60 : ( %{issue.status} = "In Review" ? 70 : ( %{issue.status} = "Implementing" ? 85 : 100 ))))} |
|
|
General |
%{count(findPattern(%{issue.cfnnnnn}, %{issue.cfmmmmm}))} |
|
|
General |
%{{issue.dueDate} != null ? floor(max({issue.dueDate} - datePart({system.currentDateTime}, RUN_AS_LOCAL), 0) / DAY) : null |
|
|
Difference between the current day and the earliest sub-task due date |
General |
%{max(fieldValue({issue.dueDate},subtasks())) != null ? ceil(( min(filterByValue(fieldValue({issue.dueDate},subtasks()),!=, null )) - {system.currentDateTime}) / DAY) : null} |
|
General |
%{{issue.resolutionDate} != null ? (({issue.resolutionDate} - {issue.created})) : null} |
|
|
General |
%{max([{issue.cfAAAAA}, {issue.cfBBBBB}, {issue.cfCCCCC}, {issue.cfDDDDD}, {issue.cfEEEEE}])} |
|
|
General |
%{count(findPattern(%{issue.cfnnnn}, "."))} |
|
|
General |
%{count(filterByStatus(subtasks(), "Done, Completed"))} |
|
|
General |
%{count(filterByIssueType(filterByStatus(subtasks(), "Done, Completed"), "Sub-task, Sub-story"))} |
|
|
Jira expression |
issue.changelogs .filter(changelog => changelog.items .some(item => item.fieldId == 'customfield_nnnnn')) .length |
|
|
General |
%{%{issue.fixVersions} != null ? count(issuesFromJQL( "fixVersion in ('" + jiraExpression( "issue?.fixVersions?.map( v => v?.name).join(\"','\") ") + "') ")) : null} |
|
|
Jira expression |
issue.subtasks.length && issue.subtasks.map( s => (s.customfield_nnnnn || 0) * (s.customfield_ppppp || 0)) .reduce((a, b) => a + b) |
|
|
General |
%{sum([%{issue.cfnnnnn} = "Option 1" ? 1 : 0, %{issue.cfppppp} = "Option 2" ? 1 : 0 ])} |
|
|
General |
%{{issue.cfnnnnn} = null ? null : {issue.cfnnnnn} - sum( append(fieldValue({issue.cfppppp}, subtasks()), [0]))} |
|
|
General |
%{sum(fieldValue({issue.cfnnnn}, subtasks()))} |
|
|
General |
%{sum(fieldValue({issue.cfnnnnn},issuesFromJQL("project = DEMO and 'fieldName' is not empty")))} |
|
|
General |
%{sum(append(fieldValue({issue.timeSpent},linkedIssues("is blocked by")), [0]))/60} |
|
|
General |
%{%{issue.issueType} = "Epic" ? (sum(append(fieldValue( {issue.timeSpent}, issuesUnderEpic()), [{issue.timeSpent}] )) / 60) : null} |
|
|
General |
%{%{issue.fixVersions} != null ? sum(append(fieldValue({issue.timeSpent}, issuesFromJQL("fixVersion = '"+%{issue.fixVersions.id}+"'")),[0]))/60) : null} |
|
|
General |
%{{issue.dueDate} != null ? max({issue.dueDate} - {system.currentDateTime}, 0) / DAY : null} |
|
|
General |
%{{system.currentDateTime} - {issue.created}} |
|
|
General |
%{sum(append(fieldValue({issue.originalEstimate},linkedIssues( "is blocked by")),[0]))/60} |
|
|
General |
%{sum(append(fieldValue({issue.remainingEstimate},linkedIssues( "is blocked by")),[0]))/60} |
🔡 Custom text formulas
|
Use case |
Parsing mode |
Expression |
|---|---|---|
|
Jira expression |
let minDate = issue?.links.map(link => link.linkedIssue.customfield_nnnnn).filter( d => d != null); minDate.length > 0 ? new Date(minDate.reduce((a, b) => a < b ? a : b )).toString() : "" |
|
|
Jira expression |
let minDate = issue?.links.map(link => link.linkedIssue.customfield_nnnnn).filter( d => d != null); minDate.length > 0 ? new CalendarDate(minDate.reduce((a, b) => a < b ? a : b )).toString() : "" |
|
|
General |
%{matches(%{issue.cfnnnnn},"6|7|8|9") ? "Valid":"Invalid"} |
|
|
Jira expression |
issue.changelogs.filter(changelog => changelog.items.some(item => item.fieldId == 'duedate' && item.from != null)).map( changelog => {duedateentry: changelog.items.filter(item => item.fieldId == 'duedate' )}).map(e => new CalendarDate( e.duedateentry[0].from).toString()).join(", ") |
|
|
General |
%{filterByProject(linkedIssues(), %{issue.project.key})} |
|
|
Jira expression |
issue.subtasks.filter(s => s?.originalEstimate == null && s?.customfield_nnnnn == null).map(i => i.key).join(", ") |
|
|
Jira expression |
issue.changelogs.filter(changelog => changelog.items.some(item => item.fieldId == 'status')).map(changelog => changelog.created).concat(issue.created)[0].toString() |
|
|
General |
%{{issue.dueDate} = null or %{issue.resolution} != null? "⚪" : (addDays({system.currentDateTime}, 14, RUN_AS_LOCAL) < {issue.dueDate} ? "🟢" : (addDays({system.currentDateTime}, 7, RUN_AS_LOCAL) < {issue.dueDate} ? "🟡" : ({system.currentDateTime} < {issue.dueDate} ? "🟠" : "🔴")))} |
|
|
General |
%{%{issue.status.category} = "To Do" ? "🔴⚪️⚪️" : ( %{issue.status.category} = "In Progress" ? "⚪️🟡⚪️" : ( %{issue.status.category} = "Done" ? "⚪️⚪️🟢" : "⚪️⚪️⚪️" ))} |
|
|
General |
%{count(findPattern(%{issue.cfnnnnn}, "\b(?:https?://|www\.)\S*(?=.*utm_source=)(?=.*utm_medium=)(?=.*utm_campaign=)\S\b")) = count(findPattern(%{issue.cfnnnnn}, "\b(?:https?://|www\.)\S+\b")) ? "🟢" : "🔴"} |
|
|
General |
let subtasks = issue.subtasks|| []; if (subtasks.length == 0){ 'No sub-tasks' } else{ let doneSubtasks = subtasks.filter(s => s.status.name == "Done"); let value = (doneSubtasks.length / subtasks.length) * 100; let percent = value - value % 1 + (value % 1 >= 0.5 ? 1 : 0); let totalBlocks = 10; let filled = (percent / 100) * totalBlocks; let full = filled - filled % 1 + (filled % 1 >= 0.5 ? 1 : 0); let bar = '🟩'.repeat(full) + '⬜️'.repeat(totalBlocks - full); `${bar} ${percent}%` } |
|
|
General |
%{%{issue.status} = "Open" ? "🟩🟩🟩🟩🟩" : ( %{issue.status} = "Planning" ? "🟩🟩⬜️⬜️⬜️" : ( %{issue.status} = "In Progress" ? "🟩🟩🟩⬜️⬜️" : ( %{issue.status} = "In Review" ? "🟩🟩🟩🟩⬜️" : ( %{issue.status} = "Done" ? "🟩🟩🟩🟩🟩" : "⬜️⬜️⬜️⬜️⬜️" ))))} |