• Kevin Suter

KPI-Reporting in Jira

Jira ist viel mehr als nur eine Projektmanagementsoftware. Es können damit zum Beispiel auch interne Prozesse abgewickelt, Arbeitszeiten rapportiert oder – mit Jira Service Desk – ein komplettes IT Service Desk damit betrieben werden. Ein weiterer Anwendungsfall ist Business Intelligence oder die Auswertung von Key Performance Indicators (KPIs) in Jira. Durch die Arbeit in Jira entstehen viele Daten, die ausgewertet werden können. Wie das gemacht werden kann, ist im folgenden Blogbeitrag beschrieben.


Jira das Rechnen beibringen

In Jira können standardmäßig Nummer-Felder verwendet werden. Allerdings können mit diesen keine Rechenoperationen getätigt werden. Möchten Sie jedoch Berechnungen auf Basis von numerischen Feldern machen, ist eine App wie Jira Misc Custom Fields (JMCF) notwendig. Damit können Sie für ein Feld Formeln definieren, das auch die Werte anderer Felder mit einbeziehen kann:

Wollen Sie komplexere Auswertungen oder Daten via REST abfragen, z.B. alle Buchungen eines bestimmten Accounts der Rapportierungs-app Tempo Timesheets auswerten, ist die App Script Runner notwendig. Damit können sogenannte “Scripted Fields”, die Groovy Scripts wie dasjenige unten enthalten können, erstellt werden. Die Berechnungen werden wie bei der Lösung oben bei jedem Laden eines Vorgangs durchgeführt. Das folgende Beispiel berechnet die Reststunden eines Projekts anhand eines ursprünglichen Budgets und aller gebuchten verrechenbaren Stunden auf allen Vorgängen in Jira mit dem Account für das Projekt:


import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import org.apache.log4j.Logger
import org.apache.log4j.Level
import com.atlassian.jira.issue.worklog.Worklog
 
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchService = ComponentAccessor.getComponent(SearchService)
def issueManager = ComponentAccessor.getIssueManager()
def issueService = ComponentAccessor.getIssueService()
def user = ComponentAccessor.getJiraAuthenticationContext().getUser()
def workLogManager = ComponentAccessor.getWorklogManager()
 
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.tempoplugin.core.workattribute.api.WorkAttributeValueService
import com.tempoplugin.core.workattribute.api.WorkAttributeService
 
@WithPlugin("is.origo.jira.tempo-plugin")
 
@PluginModule
WorkAttributeService workAttributeService
 
@PluginModule
WorkAttributeValueService workAttributeValueService
 
String account = getCustomFieldValue("Account")
 
def log = Logger.getLogger("ch.zuara.totalRemainingHoursScriptLogger")
log.setLevel(Level.INFO)
     
def originalEstimatedHours = 0.0d
if (issue.originalEstimate != null) {
    originalEstimatedHours = issue.originalEstimate / 3600
} else {
    log.warn ("Original estimate not set. Cannot calculate value.")
    return 0.0d
}
 
if (account != null) {
         log.info("Account:" + account)
         def accountKey = account.substring(account.indexOf("(")+1,account.indexOf(")"));
         log.info("AccountKey:" + accountKey)
        
        // edit this query to suit
        def query = jqlQueryParser.parseQuery("Account = " + accountKey)
 
        def results = searchService.search(user,query, PagerFilter.getUnlimitedFilter())
        log.info("Total issues: ${results.total}")
        Double totalBillableHours = 0.0d;
        Double totalSpentHours = 0.0d;
        results.getResults().each { documentIssue ->
            log.warn(documentIssue.key)
             
            def logsForIssue = workLogManager.getByIssue(documentIssue)
 
            for(Worklog worklog : logsForIssue)
            {
                def attributeBillableSeconds = workAttributeService.getWorkAttributeByKey("BILLABLE_SECONDS").returnedValue
                def workAttributeValue = workAttributeValueService.getWorkAttributeValueByWorklogAndWorkAttribute(worklog.id, attributeBillableSeconds.id)
                def worklogBillableHours = workAttributeValue.returnedValue?.value as Double
                def worklogSpentHours = worklog.getTimeSpent() / 3600 as Double
                if (worklogBillableHours == null) { 
                    totalBillableHours += worklogSpentHours
                } else {
                    totalBillableHours += worklogBillableHours / 3600
                }
                totalSpentHours += worklogSpentHours
            }
        }
        log.info ("Total estimated hours:": originalEstimatedHours)
        log.info ("Total hours spent:": totalSpentHours)
        log.info ("Total billed hours spent:": totalBillableHours)
        return (originalEstimatedHours - totalBillableHours).round(2)
} else {
    log.warn ("Account is not set on issue. Cannot calculate value.")
    return 0.0d
}

Zahlen zusammentragen

Sind die Berechnungen auf den Jira Vorgängen erstmal gemacht, müssen diese noch gemäß den definierten Key Performance Indicators aggregiert und übersichtlich dargestellt werden. Eine sehr einfache und schnelle Möglichkeit, Zielwerte zu kontrollieren, ist die App Performance Objectives. Sie ermöglicht es durch einfach konfigurierbarer Gadgets, Werte diverser Gruppen von Issues, die via JQL definiert werden können, zu aggregieren, Zielwerte zu definieren und alle KPIs auf einem Dashboard und die Zielerreichung auf einem Jira Dashboard übersichtlich darzustellen:

Die Berechnungen werden bei jedem Laden des Dashboards live gemacht. Bei großen Datenmengen und komplexeren Auswertungen kann dies zu sehr langen Ladezeiten führen. Eine Alternative, die sowohl mehr Möglichkeiten bietet wie auch die Daten vor prozessiert, ist die App Exply des deutschen Herstellers Sandstorm. Sie präsentiert sich als ausgewachsene BI-Lösung mit zahlreichen eigenen Gadgets und einer eigenen Dashboard-Engine, die aber auch in diejenige von Jira integriert werden kann.

Fazit

Wenn Sie Ihre Daten in Jira direkt auswerten wollen, gibt es dafür wie wir in diesem Blogbeitrag gesehen haben diverse Möglichkeiten. Haben Sie einfache Anforderungen, reichen Ihnen vielleicht bereits die App Jira Misc Custom Fields (JMCF) für die Berechnungen in Kombination mit Performance Objectives und die Darstellung auf einem Dashboard.

Schnell steigt jedoch die Komplexität und Sie wollen größere Datenmengen aggregieren, Zeit-Buchungen auswerten oder mehr Berechnungs- und Darstellungsmöglichkeiten für Ihr KPI-Reporting. In diesem Fall greifen Sie am besten zur App Script Runner, die Ihnen durch die Groovy-Engine fast unbegrenzte Berechnungsmöglichkeiten sowie die Anbindung externer Schnittstellen bietet und ergänzen diese mit einer Business-Intelligence App wie Exply für die Darstellung Ihrer Inhalte.



Haben Sie Fragen oder Anregungen zum diesem Blog-Beitrag? Dürfen wir Sie unterstützen? Schreiben Sie uns auf hallo@zuara.ch oder rufen Sie uns an: 031 302 60 00.
2 Ansichten0 Kommentare

Aktuelle Beiträge

Alle ansehen