BI Generatoren

Generatoren für die Berechnung der Business Intelligence Kennzahlen

Betriebsart

Cloud Abo

|

ON-PREMISES

Module

Leistung & CRM

Budget & Teilprojekt

Fremdkosten

Ressourcenplanung

Business Intelligence

Erstellt: 22.04.2020
Aktualisiert: 02.05.2025 | BI Generatoren Code ab Vertec 6.8 beschrieben.

Für die Bereitstellung der Daten für das Business Intelligence Modul setzen wir einen Datenspeicher gemäss dem Datawarehouse Konzept ein, z.T. auch "OLAP Cube" genannt. Je nach Selektion der Dimensionen wird dann sinngemäss ein Schnitt aus einem Würfel geschnitten.

Im Wesentlichen besteht das Datawarehouse aus einer grossen Datentabelle (Cube) mit vorberechneten Datenwerten. Dadurch wird ein effizienter, Businesslogik unabhängiger Zugriff auf die BI Daten und somit eine performante Anzeige auch mit grossen Datenmengen ermöglicht.

Die Berechnung erfolgt zeitlich unabhängig und mit voller Businesslogik Unterstützung via regelmässiger geplanter Aufgaben. So kann die Berechnung bei Bedarf in einzelnen Paketen (z.B. einzelne Monate) in eigenen Prozessen geschehen oder sogar parallelisiert werden.

Die Berechnungslogik wird in "Generatoren" genannten Python Scripts definiert. Diese sind auf den Kennzahlen hinterlegt. Um den Code eines Generators einzusehen, klicken Sie auf den Button mit den drei Punkten beim Feld Generator auf der Kennzahl:

Der Generator muss für die Kennzahlen, auf denen er hinterlegt ist, eine Berechnung enthalten. Der interne Name der Kennzahl muss also mit den vom Generator zurückgelieferten Werten übereinstimmen.

Standard BI Generatoren

Vertec liefert standardmässig folgende Generatoren mit:

Generator-Name Verwendete Daten

Berechnete Kennzahlen

ServicesGenerator.ServicesGenerator Leistungssummen (globaler groupLeistungen Operator) gruppiert nach Projekt, Phase, Bearbeiter und Tätigkeit.
  • Honorar extern
  • Honorar intern
  • Aufwand extern
  • Aufwand intern
  • Kosten
  • Honorar extern verrechnet
  • Honorar extern offen
  • Honorar extern abgeschrieben
  • Deckungsbeitrag (DB)
ProjectGenerator.ProjectGenerator

Leistungssummen (globaler groupLeistungen Operator) gruppiert nach Projekt und Rechnung. Verwendet nur die produktiven Projekte.

  • Bestand Vorschüsse
  • Angefangene Arbeiten
UsersGenerator.UsersGenerator

Projektbearbeiter, die vor dem Enddatum eingetreten und noch nicht ausgetreten sind bzw. deren Austrittsdatum nach dem Startdatum liegt.

  • Vollzeitstellen (FTE)
  • Headcount
  • Produktivität
  • Sollzeit
  • Arbeitszeit
  • Überzeitsaldo
  • Feriensaldo
  • Feriensaldo abgegrenzt
InvoicesGenerator.InvoicesGenerator Rechnungen, welche verrechnet sind und deren Valutadatum innerhalb des berechneten Datumsbereichs liegt.
  • Umsatz Leistungen
  • Umsatz Spesen
  • Umsatz Auslagen
PhasesGenerator.PhasesGenerator (vor Vertec 8.6)

Projektphasen der obersten Ebene, welche ein Erteiltdatum haben und deren Erteiltdatum vor dem Enddatum liegt, und die nicht oder erst nach dem Startdatum abgeschlossen wurden:

  • Auftragsbestand Honorar
  • Auftragseingang Honorar
  • Aufwand Ist
  • Aufwand Budget Rest
  • Aufwand Budget Total
PhasesMonthGenerator.PhasesMonthGenerator

Projektphasen der obersten Ebene, welche ein Erteiltdatum haben und deren Erteiltdatum vor dem Enddatum liegt, und die nicht oder erst nach dem Startdatum abgeschlossen wurden:

  • Auftragseingang Honorar
  • Aufwand Budget Total
  • Budget per Ende Monat
PhasesRangeGenerator.PhasesRangeGenerator

Projektphasen der obersten Ebene, welche ein Erteiltdatum haben und deren Erteiltdatum vor dem Enddatum liegt, und die nicht oder erst nach dem Startdatum abgeschlossen wurden:

  • Externes Honorar pro Phase
  • Interne Stunden pro Phase

Daten berechnen

Die Daten werden regelmässig über eine (oder mehrere) geplante Aufgabe in der Nacht berechnet. Die geplanten Aufgaben finden Sie im Ordner Einstellungen > Customizing > Geplante Aufgaben.

Bei diesem Vorgang werden alle bei den aktiven Kennzahlen hinterlegten Generatoren angestossen und die Werte für den Zeitraum von Januar des vorletzten Jahres bis zum Ende des nächsten Jahres berechnet.

Auf der Aufgabe ist im Status sichtbar, ob die Berechnung erfolgreich war oder fehlgeschlagen ist. Im Ausgabefenster wird die Rückmeldung der Berechnung angezeigt.

Eine Vertec App muss dafür nicht laufen, nur ein laufender Vertec Cloud Server ist Voraussetzung. Für die Berechnung wird auf der geplanten Aufgabe ein Benutzer hinterlegt, welcher für die Berechnung verwendet wird. Dieser Benutzer muss über Administratoren-Rechte verfügen, damit die Berechnungen durchgeführt werden können.

Zeitpunkt der Ausführung

Unter Nächste Ausführung wird angezeigt, wann die geplante Aufgabe das nächste Mal ausgeführt wird:

Im Cloud Abo kann die Zeit auf der Oberfläche nicht verändert werden. Die Berechnung erfolgt immer über Nacht, in einem Zeitfenster zwischen 23 Uhr und 5 Uhr.

Bei On-Premises kann das Zeitfenster mit den Parametern Special Task Scheduler Range Start und Special Task Scheduler Range End im Vertec.ini-File gesetzt werden. 

Berechnung manuell anstossen

Eine BI-Berechnung kann auch manuell angestossen werden. Hier gibt es zwei Varianten:

  • Geplante Aufgabe jetzt ausführen: Dafür wird im Kontextmenü der geplanten Aufgabe der Menüpunkt Jetzt ausführen geklickt:

    Dadurch wird die Berechnung aller Generatoren auf allen aktiven Kennzahlen angestossen.

    Achtung: Die Berechnung wird direkt in der laufenden Vertec App gestartet und nicht wie bei der zeitgesteuerten Ausführung in einem separaten Task Runner Prozess. Das sollte nicht im laufenden Betrieb gemacht werden, da die Berechnung sehr lange dauern und Vertec dadurch blockiert sein kann.

  • Anstossen der Berechnung eines Generators: Auf den einzelnen Kennzahlen kann die Berechnung manuell angestossen werden, indem im Kontextmenü Kennzahlen neu berechnen gewählt wird:

    Dabei wird der auf der Kennzahl hinterlege Generator angestossen und die entsprechenden Kennzahlen neu berechnet. Es kann jeweils das Datumsintervall noch gesetzt werden:

    Am Ende kommt eine Meldung, welche Kennzahlen berechnet wurden.

    Einmal berechnete Werte für einen Zeitraum und die betroffenen Kennzahlen bleiben im System vorhanden.

    Bei einer Neuberechnung der Daten werden bereits vorhandene Werte nur für diesen Zeitraum und die betroffenen Kennzahlen gelöscht und dann die neuen Werte eingefügt. Alle anderen Werte bleiben bestehen.

Python Methoden zur Berechnung der BI Daten

Es gibt zwei Python Methoden für die Berechnung der BI Daten.

vtcapp.standardprocessbi()

Löst die Berechnung aller Generatoren auf allen aktiven Kennzahlen aus.

Benötigt Administrator-Rechte.

Entspricht der Durchführung der standardmässig mitgelieferten geplanten Aufgabe, siehe oben.

vtcapp.processbi(von: String, bis: String, generator: String)

Löst die Berechnung des als Parameter mitgelieferten Generators aus.

Benötigt Administrator-Rechte.

Von- und Bis-Datum werden als String im Format "Jahr-Monat" angegeben.

Der Generator muss gleich angegeben werden wie bei den Kennzahlen, also "<Modulname>.<Generatorname>".

vtcapp.processbi("2018-01", "2020-02", "OffersGenerator.OffersGenerator")

Entspricht der Berechnung der BI Daten auf einer Kennzahl, siehe oben.

Generatoren erweitern / erstellen

Generatoren können auch erweitert bzw. neue Generatoren geschrieben werden. Dafür erzeugen Sie im Ordner Einstellungen > Berichte & Scripts > Scripts einen neuen Scripteintrag und verfassen den Generator-Code als Python Script.

Die Bezeichnung des Scripteintrags ist der Modulname. Zusammen mit dem Klassennamen des Generators bildet er die Generator-ID. Diese können Sie bei den BI Kennzahlen, die durch den Generator berechnet werden, als Generator angeben:

Modulnamen müssen eindeutig sein. Sie überschreiben also nicht einen bestehenden Generator, indem Sie ein Modul gleichen Namens verfassen, sondern indem Sie einen neuen Generator erstellen und auf den entsprechenden Kennzahlen hinterlegen.

BI Generatoren Code ab Vertec 6.8

Ab Vertec Version 6.8 gibt es ein eingebautes Modul namens vtcbi mit folgenden Klassen:

  • BiGenerator: Neue Basisklasse für Generatoren
  • Measure: Klasse, die eine Kennzahl beschreibt
  • Dimension: Klasse, die eine Dimension beschreibt

Das Modul vtcbi wird auch als Stub File ausgeliefert. 

Das Modul bzw. die Klassen müssen im BI Generator Script importiert werden:

from vtcbi import BiGenerator, Measure, Dimension

BIGenerator

initialize(self, startdate, enddate)
Optional. Wird einmal vor der Berechnung mit dem gesamten Zeitraum aufgerufen. Um Daten für den gesamten Zeitraum vorzuberechnen, empfehlen wir, die Methode generate_range() zu verwenden.
generate_month(self, startdate, enddate)

Wird von der Businesslogik für jeden berechneten Monat einmal aufgerufen. startdate und enddate sind jeweils der erste und letzte Tag des Monats.

Muss seinerseits self.store_values() aufrufen.

Es darf nur entweder generate_month() oder generate_range() verwendet werden. Wird beides deklariert, erscheint eine Fehlermeldung beim Ausführen.

generate_range(self, startdate, enddate)

Die Methode wird einmal für den gesamten zu berechnenden Zeitraum aufgerufen. Kann genutzt werden, um Daten vorzuberechnen.

Muss seinerseits self.store_values() aufrufen und der Parameter date muss übergeben werden. Die Werte werden dann automatisch zum richtigen Zeitpunkt eingeordnet.

Es darf nur entweder generate_month() oder generate_range() verwendet werden. Wird beides deklariert, erscheint eine Fehlermeldung beim Ausführen.

store_values([currency, date])

Mit store_values() werden die angegebenen Measures und Dimensionen berechnet und gespeichert.

  • currency: Optionaler Parameter für die Währung. Falls in Vertec mit mehreren Währungen gearbeitet wird, muss bei der Berechnung von Betrag- und Stundensatzwerten die Währung als Objekt übergeben werden (z.B. mit projekt.waehrung). Die Beträge werden dann in Leitwährung umgerechnet.
  • date: Optionaler Parameter für das Datum. Ist dieser gesetzt, wird date pro Zeile als Datum zurückgegeben, sonst startdate. Wird store_values() von der Methode generate_range() aufgerufen, muss immer ein date angegeben werden.
finalize(self)
Optional. Wird einmalig nach der Berechnung aufgerufen. Kann genutzt werden, um geladene Daten wieder freizugeben (zum Beispiel Leistungssummen).

Measure

Die BI Kennzahlen (Measures) werden innerhalb eines Generators wie folgt definiert:

Measure(InternalName: string, Description: string, Unit: integer, [IsCutOffDateValue: boolean=False])
InternalName
Hier wird der interne Name der Kennzahl angegeben.
Description
Hier wird die Bezeichnung der Kennzahl angegeben. Die Bezeichnung wird als NV (Native) des Bezeichnungsfelds verwendet (MLString), wenn die Kennzahl direkt aus dem Generator importiert wird.
Unit

Damit wird die Einheit der Kennzahl angegeben.

  • 0 = Betrag (BiUnit.Amount)
  • 1 = Aufwand (BiUnit.Hours)
  • 2 = Prozent (BiUnit.Percentage)
  • 3 = Menge (BiUnit.Quantity)
  • 4 = Ansatz (BiUnit.Rate)

Für die einfachere Nutzbarkeit gibt es die Hilfsklasse vtcbi.BiUnit, die entsprechende Konstanten enthält. Dafür muss sie importiert werden:

from vtcbi import BiUnit
IsCutOffDateValue

Optional. Gibt an, ob es sich bei der Kennzahl um einen Stichtagwert handelt.

–    True: Stichtagwert

Standardmässig ist dieser Wert False. Er muss also nur bei Stichtagwerten angegeben werden.

Dimension

Die Dimensionen werden wie die Kennzahlen innerhalb eines Generators definiert:

Dimension(order: integer, type: string[, role: string]
Order

Reihenfolge der Dimension auf der Kennzahl. Muss der Reihenfolge auf der Kennzahl entsprechen:

Type
Hier wird der Klassenname der Dimension angegeben.
Role
Optional. Hier kann der Rollenname der Dimension angegeben. Der hier übergebene Wert wird als NV (Native) des Rollenfelds verwendet (MLString).

Beispiel

Als Beispiel wird ein Generator erzeugt, der produktive und unproduktive Leistungen getrennt anzeigen soll.

Mit generate_range() wird dabei der gesamte Zeitraum kalkuliert. Das store_values() sorgt selbst für die richtige Summierung und Einsortierung.

from vtcbi import BiGenerator, Measure, Dimension, BiUnit

class ProductiveGenerator(BiGenerator):

    prodServices = Measure("ProdServices", "Productive Services", BiUnit.Hours)
    unprodServices = Measure("UnprodServices", "Unproductive Services", 1)
    project = Dimension(1, "Projekt")
    projectmanager = Dimension(2, "Projektbearbeiter", "as project manager")
    user = Dimension(3, "Projektbearbeiter")
    
    def generate_range(self, startdate, enddate):
        # calc leistsums for the whole period, grouped by month, project and user
        leistsums = vtcapp.evalocl("TimSession.allInstances->first->groupLeistungen('{}', '{}', 'MONTH, PROJEKT, BEARBEITER')".format
            (vtcapp.datetostrgerman(startdate), vtcapp.datetostrgerman(enddate)))
            
        for leistsum in leistsums:    
            self.project = leistsum.evalocl("projekt")
            self.projectmanager = leistsum.evalocl("projekt->oclAsType(Projekt).projektleiter")
            self.user = leistsum.evalocl("bearbeiter")
            self.prodServices = leistsum.evalocl("(minutenintOffen + minutenIntVerrechnet)-(minutenintOffenUnprod + minutenIntVerrechnetUnprod)")
            self.unprodServices = leistsum.evalocl("minutenintOffenUnprod + minutenIntVerrechnetUnprod")
            self.store_values(None, leistsum.evalocl("datum"))

BI Generatoren Code vor Vertec 6.8

Die Deklaration des Generators ist wie folgt:

class <Generatorname>(object):

Auf das Generator-Objekt kann im Script jederzeit über self zugegriffen werden. Innerhalb des Generators stehen folgende Methoden zur Verfügung:

Methode Beschreibung
get_dimensions(self) Mit dieser Methode wird angegeben, für welche Dimensionen der Generator Werte berechnet:
def get_dimensions(self):
    return ['Projekt', 'Projektbearbeiter']

In den Kennzahlen müssen genauso viele Dimensionen angegeben werden, wie hier geliefert werden, und zwar in der angegebenen Reihenfolge.

Möchte man also zum Beispiel Werte sowohl für Bearbeiter als Projektleiter als auch für Bearbeiter als Hauptbearbeiter anzeigen, muss die Dimension Projektbearbeiter zweimal angegeben werden:

def get_dimensions(self):
    return ['Projekt', 'Projektbearbeiter', 'Projektbearbeiter']
get_measures(self) Mit dieser Methode wird angegeben, welche Kennzahlen damit berechnet werden. Die Rückgabewerte müssen den internen Namen auf den Kennzahlen entsprechen.
def get_measures(self):
    return ['OffersQuantity']

Auf allen Kennzahlen, die hier zurückgeliefert werden, kann der Generator dann hinterlegt werden.

initialize(self, startdate, enddate)

Als erstes wird diese Methode durchlaufen. Die Variablen startdate und enddate enthalten das Datumsintervall der gesamten berechneten Periode.

Hier kann man die Listen der verwendeten Objekte performanceoptimiert preloaden. So hat man alle relevanten Daten der gesamten Periode. In der Methode generate() werden die Daten dann pro Monat berechnet.

generate(self, startdate, enddate)

Die generate() Methode wird so viel Mal durchlaufen, wie es Monate in der berechneten Periode hat.

Die Variablen startdate und enddate enthalten immer den ersten und den letzten Tag des Monats, also bei Januar bis Juni bspw. 1.1.23 und 30.6.23.

Die im initialize() vorgeladenen Daten können hier nun pro Monat gefiltert und berechnet werden.

Rückgabewert

Als Rückgabewert wird ein Tuple aus Dimensionen und ein Tuple aus Measures (Kennzahlen) zurückgeliefert, in genau der oben deklarierten Reihenfolge.

Der Rückgabewert wird nicht wie sonst in Python mit return() zurückgegeben, sondern mit yield():

yield((project, project.projektleiter), (OffersQuantity,))

Die Verwendung von yield() hat zur Folge, dass es nicht nur einen Rückgabewert gibt (und alle Daten mühsam in einem Array zusammengefasst und dann zurückgegeben werden müssen), sondern jede Zeile zurückgegeben werden kann, bis der gesamte Code abgelaufen ist. So können zum Beispiel innerhalb einer Projekt-Schleife die berechneten Daten pro Projekt etc. laufend einfach "abgeliefert" werden (siehe Beispielcode weiter unten).

Währungen

Falls man in Vertec mit mehr als einer Währung arbeitet, muss man dies bei der Berechnung beachten. Dafür kann pro Rückgabezeile optional eine Währung mitgegeben werden (Beispiel aus dem mitgelieferten InvoiceGenerator):

yield ((project), turnover_tuple, project.waehrung)

Vertec kümmert sich dann selbst um die korrekte Umrechnung in die Leitwährung. Angezeigt werden die Werte immer in Leitwährung.

finalize(self) Am Schluss wird noch die finalize-Methode durchlaufen. Darin können zum Beispiel nicht mehr benötigte Objekte aus dem Memory wieder entfernt werden.

Netherlands

United Kingdom