Handbuch

ProjectForge® 2011

Version: 3.6.1
Datum: 2011-05-27
Projekt: ProjectForge® 2011
URL: www.projectforge.org
Autor: Kai Reinhard
mailtok.reinhard@me.com

downloadVersion zum Ausdrucken: Handbuch.pdf

Inhaltsverzeichnis

1Einleitung
1.1 Übersicht über alle Menüpunkte
2Allgemeine Konzepte
2.1 Vollindizierte Freitextsuche
2.1.1 Automatische Wildcards
2.1.2 Suche in Aufgaben
2.2 Quickselect
2.3 Filter für Änderungszeitraum von Objekten
2.4 Autovervollständigung
2.5 Favoriten/Bookmarks
2.5.1 Favoriten/Bookmarks in den Listenansichten
2.5.2 Favoriten/Bookmarks in den Editieransichten
2.6 Angemeldet bleiben
2.7 Apple touch icon
2.8 Tooltipps
3Adressbuch
3.1 Rückwärtssuche von Telefonnummern
3.2 Persönliche Favoriten
3.2.1 Exportieren von vCards in externe Adressbücher
3.2.1.1 Hinweis für Apple Adressbuch-Nutzer
3.2.2 Exportieren der persönlichen Telefonliste
3.2.3 Persönliche Telefonliste für ein Snom-Telefon
3.3 Exportieren der Telefonliste
3.4 Animierter Nummern-Zoom für Telefonwahl
3.5 Direktwahl über die Telefonanlage
3.5.1 Konfiguration
3.6 Mailings
4Kalenderfunktionalität
4.1 Normalmodus, Zeitberichtsfunktion
4.2 Auswählmodus
4.3 Quick-Time-Browse-Funktion
4.4 Ferientagfunktion
4.5 Zeitzonensupport
5Aufgaben in ProjectForge®
5.1 Verbrauch
5.1.1 Für laufende Aufgaben
5.1.2 Für abgeschlossene Aufgaben
5.1.3 Unterdrücken der Statusanzeige des Verbrauchbalkens
5.2 Zeitberichtsbuchungen
6Auftragsbuch
6.1 E-Mail-Benachrichtigung
7Scripting von ProjectForge®
7.1 Beispiele
7.1.1 Beispiel: Hibernate-Criterion-API
7.1.2 Beispiel: Verwenden der ProjectForge®-Filter
7.2 Verwenden von Datumsangaben
7.3 Zugfriffsmöglichkeiten und Zugriffsschutz (DAOs)
7.4 Erzeugen von Exceltabellen
7.4.1 Beispiel: Excelexport einfacher Listen
7.4.2 Beispiel: Excelexport von gejointen Objekten
7.4.3 Eigene Joinobjekte
7.4.4 Formate
7.4.5 Modifizieren von existierenden Exceldateien
7.4.6 Zellenformate
7.4.7 Excel und Zeitdauern
7.5 Erzeugen von Diagrammen
7.6 Nested und indexed Properties
7.7 Import von Excellisten
8Buchhaltung mit ProjectForge®
8.1 Rechnungsbuch
8.1.1 Kostenträgerzuordnung
8.1.2 Klonfunktion von Ausgangsrechnungen (Debitoren)
8.2 Datev-Import
8.2.1 Grundsätzliches zum ProjectForge®-Excel-Import
8.2.1.1 Schritt 1: Auswahl der zu importierenden Excel-Datei
8.2.1.2 Schritt 2: Daten werden eingelesen
8.2.1.3 Schritt 3: Verproben
8.2.1.4 Schritt 4: Prüfen, selektieren und Übernahme
8.2.1.5 Schritt 5: Import abgeschlossen
8.2.2 Import der Lohnbuchkonten (Kontenplan)
8.2.2.1 Format
8.2.3 Import der Buchungssätze (01-12)
8.2.3.1 Format
8.3 Weitere Imports
8.3.1 Mitarbeitergehälter
8.4 Zeitberichte
8.4.1 Zeitberichtsschutz
8.4.2 Kostenträger
8.4.3 Zeitbericht buchen
8.4.4 Monatsberichte
8.4.5 JIRA-Support
8.5 Kostenträgerrechnung
8.5.1 Arbeitszeitanteil
8.6 Reporting via Report-Objectives (in progress)
8.7 JasperReports, Beta
8.7.1 Step by Step Report definieren
8.7.2 Report testen
8.7.3 Reports mit GroovyScript
8.7.3.1 Rückgabewerte des GroovyScripts
8.7.3.2 Direktes Erzeugen von Excellisten
9Datenschutz
9.1 Passwörter
9.2 Historisierung
9.3 Protokollierungen
9.4 Direktwahl - Rufnummern

Abbildungsverzeichnis

1Vollständiges Funktionsmenü (ohne Dokumentationsmenü).
2Die vollindizierte Freitextsuche
3Erweiterte Suche für Filterung in der Änderungshistorie
4Favoriten/Bookmarks in Listenansichten
5Favoriten/Bookmarks in Listenansichten
6Erstellen des persönlichen Adress- bzw. Telefonbuchs.
7Auswahl der Telefonliste für das Snom-Telefon
8Import der Telefonliste in das Snom-Telefon
9Animierter Nummernzoom zur vereinfachten Telefonwahl
10Direktwahl aus dem Addressbuch heraus
11Direktwahl aus dem Addressbuch heraus
12Wochen- und monatsweises Blättern
13Aufgabenhierarchie in ProjectForge®
14Auftragsbuch mit E-Mail-Benachrichtigung
15Beispiel eines Diagrammexports
16Excelimportbeispiel
17Datev-Import, Schritt 1: Auswahl der Importdatei
18Datev-Import, Schritt 2: Einlesen der Datei
19Datev-Import, Schritt 3: Verproben
20Datev-Import, Schritt 4: Prüfen, Selektion und Übernahme
21Datev-Import, Schritt 5: Abschluss
22Excelformat für Datev-Import des Kontenplans
23Excelformat für Datev-Import der Buchungssätze
24Zeitberichtsschutz für Aufgaben (inkl. Unteraufgaben)
25Zuordnung von Kost2-Kostenträgern zu Aufgaben
26Zeitberichte anlegen / ändern mit Kost2-Kostenträgern
27iReport: Registrieren des ProjectForge®-Reporting-Jars
28iReport: Edit Query

1 Einleitung

Dieses Dokument enthält einige Tipps und Best-Practice-Ansätze rund um ProjectForge®.

1.1 Übersicht über alle Menüpunkte

Abb. 1 zeigt das vollständige Menü (ohne Dokumentationsmenü).
Abbildung 1: Vollständiges Funktionsmenü (ohne Dokumentationsmenü).

2 Allgemeine Konzepte

2.1 Vollindizierte Freitextsuche

Zu allen Listenansichten existiert ein Suchfeld in welches (Teil)worte eingegeben werden können. Welche Felder indiziert werden kann über den Tooltipp des Suchfelds stets aktuell eingesehen werden (s. Abb. 2 ).
Abbildung 2: Über das Suchfeld kann eine vollindizierte Freitextsuche gestartet werden. Dabei können auch Teilwörter eingegeben werden, sowie logische Ausdrücke gebildet werden.
Die detaillierte Beschreibung der Möglichkeiten findet sich direkt auf der Lucene-Seite

lucene.apache.org/java/2_4_0/queryparsersyntax.html .

Diese Seite ist auch durch Klick auf das Fragezeichensymbol direkt erreichbar.
Die folgende Tabelle zeigt einige häufig genutzte Möglichkeiten der Suchfunktion.
Ausdruck Funktion
abc Es werden alle Objekte gesucht in deren Feldern abc als Wortbeginn vorkommt.
*abc* Es werden alle Objekte gesucht in deren Feldern abc als Wortbestandteil vorkommt.
meier~ Phonetische Suche: Es werden sowohl mayer als auch meier gefunden!
abc def Es werden alle Objekte gesucht in deren Feldern "abc" als Wortbeginn und/oder "def" als Wortbeginn vorkommt.
abc* def Es werden alle Objekte gesucht in deren Feldern Worte mit "abc" beginnend und "def" vorkommen kann.
+abc -def Es werden alle Objekte gesucht in deren Feldern "abc" als Wort vorkommt und "def" nicht vorkommt.
name:abc def Es werden alle Objekte gesucht in deren Feld "name" abc als Wort auftaucht und/oder in beliebigen Feldern "def" vorkommen kann.

2.1.1 Automatische Wildcards

Hinweis

Werden nur alphanumerische Worte (zusätzlich sind die Zeichen @._* überall und +- nicht an erster Stelle erlaubt) eingegeben, so fügt ProjectForge® automatisch Wildcards für die Teilwortsuche ein. Für alle anderen Ausdrücke wird die Suchanfrage unverändert an Lucene weitergereicht. Logische Lucene-Schlüsselworte (AND, OR und NOT) werden nicht modifiziert.

Ausdruck Automatische Ersetzung für Lucene
hallo hallo*
hallo ProjectForge hallo* ProjectForge*
k.reinhard@projectforge k.reinhard@projectforge*
hallo AND 2008-11-21 NOT hurz OR test hallo* AND 2008-11-21 NOT hurz* OR test*
(Ausdrücke, die Sonderzeichen wie -+ enthalten, werden nicht um ein '*' expandiert.)
hallo AND name:hurzel hallo AND name:hurzel
(keinerlei Ersetzung vorgenommen, da ':' vorkommt.)
+hallo und hurzel +hallo und hurzel
(keinerlei Ersetzung vorgenommen, da mit '+' beginnend.)
Zur Überprüfung wird unterhalb des Suchfelds der verwendete Suchstring angezeigt, sofern diese abweichend von der Benutzereingabe ist (also modifiziert wurde).

2.1.2 Suche in Aufgaben

Die Volltextsuche berücksichtigt bei Aufgaben auch die Namen der übergeordneten Aufgaben. Bei der Suche in den Zeitberichten werden so bei Eingabe von 'DHL' auch alle Zeitberichte gefunden, die Unteraufgaben von DHL zugeordnet worden.

2.2 Quickselect

Wenn eine Aufgabe, ein Benutzer etc. ausgewählt werden soll und im Suchfeld ein Kriterium angegeben wird, so dass nur ein Treffer gefunden wird, so wird dieser automatisch ausgewählt und zur aufrufenden Seite zurück verzweigt.

2.3 Filter für Änderungszeitraum von Objekten

Auf den Listenseiten (Wicketversion) können über "Erweiterte Suche" Objekte auch anhand des Datums der Änderungen gesucht werden. So ist es beispielsweise möglich, alle Objekte zu suchen, die ein Benutzer in den letzten 10 Minuten geändert hat, oder alle Objekte, die in einem bestimmten Zeitraum geändert worden.
Die sonstigen Filterkriterien werden ebenfalls berücksichtigt. Abb. 3 zeigt die erweiterte Suche anhand einer Zeitberichtsliste.
Abbildung 3: Über den erweiterten Filter können Objekte anhand von Änderungszeitpunkten gesucht werden. Die erweiterte Suche erscheint, wenn auf "Erweiterte Suche" rechts neben dem Freitextsuchefeld geklickt wird.

2.4 Autovervollständigung

Für einige Texteingabefelder (z. B. Adresssuche oder Eingabe eines Orts bei der Erfassung eines Zeitberichts) wird eine Autovervollständigung angeboten. Wenn beispielsweise mindestens 2 Zeichen eingegeben worden sind, werden Vorschläge vom Server zur Vervollständigung als Liste angeboten. In der Liste kann auch über die Pfeiltasten oder Bild-hoch/runter-Tasten navigiert werden.
Ein Doppelklick führt i. d. R. zur direkten und sofortigen Anzeige von Favoriten, ohne das im Hintergrund nochmals eine Serverabfrage gestartet wird. Bei einigen Suchfeldern (z. B. Adresssuche) werden die zuletzt benutzten Suchanfrage als Favoriten bei dieser Doppelklickfunktion vorgeschlagen.

2.5 Favoriten/Bookmarks

ProjectForge® zeigt auf vielen Seiten ein Bookmark-Icon an. Ein Klick auf dieses Icon zeigt Links auf die aktuelle Seite an, so dass diese direkt über ein Bookmark aus dem Browser angesprungen werden kann. Dazu kann einer der angegebenen Links einfach kopiert und in den Browser übertragen werden.
ProjectForge® gibt i. d. R. einen Link an, der die Seite direkt ohne weitere Vorbelegungen (ohne Parameter) aufruft und einen Link, der die wichtigsten Parameter enthält, damit die direkt aufgerufene Seite schon die gewünschten Vorbelegungen enthält.
Hinweis: Diese Funktion ist auf allen Seiten automatisch integriert, die bereits in die neue ProjectForge®-Technologie (Wicket) überführt wurden.

2.5.1 Favoriten/Bookmarks in den Listenansichten

Wie Abb. 4 zeigt, bietet ProjectForge® in Listenansichten zwei Direktlinks an:
  1. Direktlink für den Aufruf mit den vom Benutzer zuletzt verwendeten Filtereinstellungen.
  2. Direktlink mit Parametern für den Aufruf der Listenansicht inklusive aller Filtereinstellungen.
Abbildung 4: Die Abbildung zeigt die Favoriten/Bookmark-Funktionalität innerhalb der Listenansichten. In dem Beispiel enthält der erste Link den direkten Aufruf dieser Seite ohne Parameterübergabe. ProjectForge® würde dann den zuletzt vom User verwendeten Filter verwenden. Der zweite Link enthält auch alle Filterangaben, so dass bei Aufruf dieses Links die Seite mit den identischen Filtereinstellungen aufgerufen wird.

2.5.2 Favoriten/Bookmarks in den Editieransichten

Wie Abb. 5 zeigt, biete ProjectForge® in den Editieransichten zwei Direktlinks an:
  1. Direktlink zur Anzeige des entsprechenden Objekts.
  2. Direktlink mit Parametern für den Aufruf der Editieransicht zur Eingabe neuer Objekte mit einigen bereits ausgefüllten Felder (gemäß Parametern).
Der zweite Link kann somit genutzt werden, um Schablonen für die Anlage von neuen Zeitberichten außerhalb von ProjectForge® zu führen (z. B. in JIRA oder innerhalb der E-Mail-Kommunikation).
Abbildung 5: Die Abbildung zeigt die Favoriten/Bookmark-Funktionalität innerhalb der Editieransichten. In dem Beispiel enthält der erste Link den direkten Aufruf zur Anzeige des aktuellen Zeitberichts. Der zweite Link enthält den Aufruf der Funktion "Zeitbericht anlegen" mit bereits vorbelegten Feldern (aus den Parametern) heraus.

2.6 Angemeldet bleiben

Bei der Anmeldung kann der Anwender die Auswahl "angemeldet bleiben" wählen.

2.7 Apple touch icon

ProjectForge enthält auf allen Seiten ein so genanntes Apple touch icon, d. h. die Webseite kann z. B. auf einem iPhone zum Home-Screen mit entsprechendem Icon hinzugefügt werden.

2.8 Tooltipps

Wird ein Text kursiv angezeigt, so verbirgt sich in der Regel ein Tooltip dahinter, d. h. eine Tooltipp-Box mit zusätzlichen Informationen erscheint, wenn der Mauszeiger über diesem Feld platziert wird.

3 Adressbuch

3.1 Rückwärtssuche von Telefonnummern

ProjectForge® indiziert zusätzlich zu jeder Telefonnummer auch die Nummer ohne Sonder- und Leerzeichen. Über das Suchfeld kann also eine Telefonnummer oder ein Bestandteil hieraus eingegeben werden, und die zugehörige Adresse wird gefunden, sofern ein korrespondierender Eintrag vorhanden ist.

Hinweis

Bei der Rückwärtssuche am besten die führende "0" weglassen, da diese bei allen Adressen eigentlich durch eine "+49" ersetzt sein sollte. Diese Funktion ist sinnvoll für entgangene Anrufe.

3.2 Persönliche Favoriten

In der Adressenliste können Adressen für die persönliche Telefonliste oder in ein externes Adressbuch übernommen werden. Empfehlenswert ist auch die Synchronisation mit dem Mobile.
Entweder können Adressen über die Blätterfunktion oder über Suchbegriffe (z. B. alle Adressen eines Kunden oder von Micromata) zur Auswahl selektiert werden.
Favorisierte Adressen (entweder als ganze Adressen oder mind. eine Telefonnummer) werden rot dargestellt.
Über die Funktion "die 50 neueste" oder Sortierung aller Adressen nach dem letzten Änderungsdatum kann die Adressenliste regelmäßig auf neue zu favorisierende Adressen überprüft werden.

3.2.1 Exportieren von vCards in externe Adressbücher

Durch Anwahl der Checkbox hinter dem Namen einer Adresse kann die komplette Adresse als Favorit markiert werden (s. Abb. 6 ). Über den Button "Export vCards" können dann alle so markierten Adressen heruntergeladen werden.

Hinweis

Bitte im externen Adressbuch UTF-8 als Zeichensatz einstellen!
Abbildung 6: Die Abbildung zeigt die Möglichkeit, ganze Adressen oder einzelne Telefonnummern in das persönliche Adressbuch oder die persönliche Telefonliste zu übernehmen.

3.2.1.1 Hinweis für Apple Adressbuch-Nutzer

Mehrfache Exports sorgen dafür, dass sich die Notizen auf magische Art vervielfachen. Als Lösungsmöglichkeit wird empfohlen, folgendes AppleScript vor einem Export laufen zu lassen:
1
2
3
4
5
6
7
8
9
tell application "Address Book"
repeat with thisPerson in every person
if (exists (note of thisPerson)) and ((note of thisPerson) contains "CLASS: WORK") then
log "Name: " & (name of thisPerson)
delete note of thisPerson
end if
end repeat
save
end tell
  1. Das Script kann im AppleScript-Editor direkt ausgeführt werden. (Ergebnis "missing value" ist normal.)
  2. Anschließend den Export durchführen.

3.2.2 Exportieren der persönlichen Telefonliste

Telefonnummern von Adressen können einzeln durch Anwahl der Checkboxen hinter den betreffenden Telefonnummern zur persönlichen Telefonliste hinzugefügt werden (s. Abb. 6 ). Diese Telefonliste kann dann beispielsweise auf das Mobiltelefon oder auf ein Systemtelefon übertragen werden.
Über den Button "Telefonliste" können alle markierten Telefonnummern im Iso-8859-Format als CSV-Datei heruntergeladen werden. Dabei erweitert ProjectForge® die Namen automatisch um die Suffixe "mobil" oder "privat", wenn es sich nicht um die geschäftliche Telefonnummer handelt.

3.2.3 Persönliche Telefonliste für ein Snom-Telefon

Die exportierte Telefonliste kann z. B. direkt in ein Snom-Telefon übernommern werden. Dazu muss die Webseite des gewünschten Telefons aufgerufen werden. Die folgenden Abbildungen 7 und 8 zeigen exemplarisch den Import einer Telefonliste.

Hinweis

Telefonlisten können im Snom-Telefon immer wieder überladen werden, die Snom-Software führt die Listen zusammen, so dass Einträge nicht doppelt vorkommen. Wenn alle Adressen aus ProjectForge® übernommen werden, können bestehende Einträge durch Anwahl der Checkbox "Vorher ganzes Adressbuch löschen" gelöscht werden.
Abbildung 7: Über "Datei auswählen" kann die von ProjectForge® exportierte Telefonliste importiert werden. Das Format der Telefonliste ist so gewählt, dass die Standardeinstellungen der Snom-Webseite übernommern werden können.
Abbildung 8: Ein evtl. vorhandenes Adressbuch kann durch Anwahl der entsprechenden Checkbox gelöscht werden. Andernfalls führt die Snom-Software die Einträge zusammen, so dass Dupletten nach Möglichkeit verhindert werden. Nachträglich können über die Snom-Webseite auch die Einträge nachbearbeitet werden (z. B. Löschen möglicher Duplette).
Wichtig ist, dass für die erste Spalte "Name" und für die zweite Spalte "Nummer" aus den Comboboxen gewählt wird.

3.3 Exportieren der Telefonliste

Die aktuell gefilterte Liste kann als Tabelle z. B. für die Weiterverarbeitung in OpenOffice verwendet werden. Dabei werden alle Felder der Adressen mit exportiert. Es werden aus Datenschutzgründen nur die persönlichen Favoriten exportiert. Die Mitarbeiter aus der Gruppe PF_Finance (Finanzbuchhaltung) erhalten die komplette Liste. Für Marketingaktionen o. ä. bitte Rücksprache mit der Finanzbuchhaltung nehmen.

Hinweis

Als erste Adresse wird im Export die so genannte Mailingadresse ausgegeben. Diese ist die postalische Adresse, sofern gegeben, ansonsten die geschäftliche Adresse.

3.4 Animierter Nummern-Zoom für Telefonwahl

Abb. 9 zeigt eine Mouse-over-Funktion, wenn der Cursor über einer Telefonnummer aus der Adressliste positioniert wird. Dann wird die Telefonnummer vergrößert, was die manuelle Wahl sehr vereinfacht.
Abbildung 9: Animierter Nummernzoom zur vereinfachten Telefonwahl

3.5 Direktwahl über die Telefonanlage

Wenn ein Benutzer in seinem Nutzeraccount eine oder mehrere Telefonanlagen-Ids hinterlegt hat, so kann aus ProjectForge® heraus bei Unterstützung durch die Telefonanlage ein direkter Anruf gestartet werden.
10 zeigt die Möglichkeit, aus dem Adressbuch heraus direkt einen Anruf zu initiieren.
Abbildung 10: Über das Adressbuch kann durch Anklicken einer Telefonnummer direkt in die Direktwahl gesprungen werden. Anschließend die Return-Taste drücken und der Anruf wird ausgelöst.
11 zeigt die Möglichkeit, Direktwahlen über Eingabe von Namen bzw. Namensbestandteilen zu initiieren. Das Nummernfeld hat automatisch den Fokus und nach Eingabe von mindestens 2 Zeichen erscheint eine Autovervollständigungsliste, aus der die gewünschte Adresse ausgewählt werden kann. Es wird automatisch die Geschäftsnummer bzw. die Mobilfunknummer ausgewählt. Durch Drücken der Return-Taste kann das Telefongespräch gestartet werden. Alternativ können die anderen Nummern der Adresse durch Anklicken direkt angewählt werden.
Selbstverständlich können auch Rufnummern direkt eingegeben werden.

Hinweis

Die Direktwahlseite ist für die Benutzung ohne Maus entworfen, d. h. sie lässt sich schnell über Tasten steuern. Die Returntaste löst auch hier (wie in der gesamten ProjectForge®-Applikation) die Standardaktion aus (hier wählen).
Abbildung 11: Über das Adressbuch kann durch Anklicken einer Telefonnummer direkt in die Direktwahl gesprungen werden. Anschließend die Return-Taste drücken und der Anruf wird ausgelöst.

3.5.1 Konfiguration

Das eigene Telefon bzw. die Liste der eigenen Telefone wird unter Mein Zugang festgelegt.

3.6 Mailings

Über ProjectForge® können Adresslisten (Excel-Export) für Mailings exportiert werden. Folgendes Vorgehen empfliehlt sich:
  1. Exportieren der Excelliste
  2. Bearbeiten der Excelliste (markieren/entfernen) von Einträgen
  3. Besteht bereits eine bearbeitete Excelliste aus früheren Mailings, so sollten die neuen Adressen angehängt werden (export der neuesten Adressen).
  4. Über ein Skript können alle Adressen automatisch aktualisiert werden.
Über folgendes Skript können in vorhandenen Excellisten die Adressen nachträglich automatisch aktualisiert werden. Dabei werden die alten Adresswerte in die letzte Spalte geschrieben.

Beispiel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import java.text.*
import org.apache.commons.lang.*
import org.hibernate.criterion.*
import org.projectforge.address.*
import org.projectforge.core.*
import org.projectforge.export.*

xls = reportScriptingStorage.getFile("Kunden_Mailing_Inwest_.xls"// Wurde mit diesem Namen hochgeladen.
ExportWorkbook workbook = new ExportWorkbook(xls);// Verwende vorhandene Exceldatei

ExportSheet sheet = workbook.getSheet("Mailing_neu"); // Hole Sheet mit dem angegebenen Namen
rows = sheet.rows; // Hole alle Zeilen
result = "";

QueryFilter filter = new QueryFilter()
filter.add(Expression.eq("deleted"false))
list = addressDao.getList(filter)

DecimalFormat format = new DecimalFormat("#");

for (int i = 2; i < sheet.rows.size; i++) {
  row = sheet.getRow(i);
  row.addCell(14) // In Spalte 14 kommen die alten Adresswerte rein.
  name = row.getCell(1).getStringCellValue().trim(); // Spalte 1
  vorname = row.getCell(2).getStringCellValue().trim(); // Spalte 2
  firma = row.getCell(4).getStringCellValue().trim(); // Spalte 4
  strasse = row.getCell(10).getStringCellValue().trim(); // Spalte 10
  if (row.getCell(11).numericCellType == true) {
    plz = format.format(row.getCell(11).getNumericCellValue());
  } else {
    plz = row.getCell(11).getStringCellValue().trim();
  }
  ort = row.getCell(12).getStringCellValue().trim(); // Spalte 12
  country = row.getCell(13).getStringCellValue(); // Spalte 13
  oldAddress = firma + "; " + strasse + "; " + plz + " " + ort + "; " + country;
  ll = list.findAll{ entry -> (entry.name.equals(name) && entry.firstName.equals(vorname)) }
  if (ll.size > 1)
    result += "*** " + name + ", " + vorname + " doppelt.\n";
  else if (ll.size < 1)
    result += "*** " + name + ", " + vorname + " nicht gefunden.\n";
  else {
    adr = ll.get(0);
    changed = false;
    if (StringUtils.equals(StringUtils.defaultString(adr.organization).trim(), firma) == false) {
      changed = true;
      row.getCell(4).setValue(StringUtils.defaultString(adr.organization));
      result += name + ", Firma: " + firma + " -> " + adr.organization + "\n";
    }
    if (StringUtils.equals(StringUtils.defaultString(adr.mailingAddressText).trim(), strasse) == false) {
      changed = true;
      row.getCell(10).setValue(StringUtils.defaultString(adr.mailingAddressText));
      result += name + ", Straße: " + strasse + " -> " + adr.mailingAddressText + "\n";
    }
    if (StringUtils.equals(StringUtils.defaultString(adr.mailingZipCode).trim(), plz) == false) {
      changed = true;
      row.getCell(11).setValue(StringUtils.defaultString(adr.mailingZipCode));
      result += name + ", PLZ: " + plz + " -> " + adr.mailingZipCode + "\n";
    }
    if (StringUtils.equals(StringUtils.defaultString(adr.mailingCity).trim(), ort) == false) {
      changed = true;
      row.getCell(12).setValue(StringUtils.defaultString(adr.mailingCity));
      result += name + ", Ort: " + ort + " -> " + adr.mailingCity + "\n";
    }
    if (StringUtils.equals(StringUtils.defaultString(adr.mailingCountry).trim(), country) == false) {
      if (adr.mailingCountry == null || ("Deutschland".equals(adr.mailingCountry.trim()) == false && "D".equals(adr.mailingCountry.trim()) == false)) {
        changed = true;
      }
      row.getCell(13).setValue(StringUtils.defaultString(adr.mailingCountry));
      result += name + ", Country: " + country + " -> " + adr.mailingCountry + "\n";
    }
    if (changed == true) {
      result += name + ", " + vorname + " geändert: " + oldAddress + " \n";
      row.getCell(14).setValue(oldAddress);
    }
  }
}
return result;
return workbook;

4 Kalenderfunktionalität

Der Kalendar hat eine zentrale Bedeutung in ProjectForge®. Er dient der Organisation von Zeitberichten und der eleganten Auswahl von Tagen oder Zeiträumen.

4.1 Normalmodus, Zeitberichtsfunktion

Im normalen Modus werden im Kalender die Zeitberichte des aktuell angemeldeten Benutzers angezeigt. Durch Anklicken eines Tages kann ein neuer Zeitbericht zu diesem Tag angelegt werden. Wird die Stoppzeit eines vorhandenen Zeitberichts angeklickt (sofern kein Folgezeitbericht vorhanden), so wird diese Uhrzeit als Startzeit für einen neuen Zeitbericht vorausgewählt. Eine anwählbare Startzeit eines Zeitberichts wird analog als Stopp-Zeit für einen neuen Zeitbericht angenommen.
Wird eine Pause (Lücke in den Berichten eines Tages) ausgewählt, so wird ein Zeitbericht vorgeblendet, der die Lücke hinsichtlich Start- und Stoppzeit vollständig ausfüllt.

Hinweis

Merke: Die leeren Zeitberichte (Pausen) werden für jeden Tag berechnet und werden lediglich angezeigt. Diese Zeitberichte werden nicht in der Datenbank gesichert.

4.2 Auswählmodus

Im Auswählmodus kann der Anwender einen Tag auswählen. Wenn die aufrufende Methode einen Zeitraum unterstützt (z. B. die Zeitraumsuche bei Zeitberichten), so kann auch eine ganze Woche oder ein ganzer Monat durch anklicken selektiert werden. Der aufrufenden Seite wird dann der Zeitraum als Start-/Stoppzeit übergeben.

4.3 Quick-Time-Browse-Funktion

Über eine schnelle Blätterfunktion kann der Anwender auch ohne Aufruf des Kalenders wochen- oder monatsweise blättern (s. z. B. die Filterfunktion in der Zeitberichtsliste aus Abb. 12 ).
Abbildung 12: Wochen- und monatsweises Blättern

4.4 Ferientagfunktion

In ProjectForge® sind alle deutschen Feiertage mit ihren Berechnungsregeln hinterlegt. Die Feiertage werden visualisiert.

4.5 Zeitzonensupport

ProjectForge® arbeitet intern durchgängig mit UTC. Die Zeitzone des Benutzers (z. B. "Europe/Berlin") wird nur in der Anzeige und der Eingabe durch den Anwender berücksichtigt. Zur Illustration und Kontrolle wird an einigen Zeit und Datumsfeldern die interne UTC-Zeit mit weißer Schrift auf grauem Hintergrund unauffällig angezeigt.

5 Aufgaben in ProjectForge®

Aufgaben werden in ProjectForge® hierarchisch organisiert. Die Aufgaben können Themenbereiche, Kunden, Abteilungen, Projekte o. ä. sein. Zugriffsrechte von z. B. Zeitberichten werden Aufgabenspezifisch definiert. Unteraufgaben erben einige Angaben der Elternaufgaben, sofern sie nicht in der betroffenen Aufgabe selber festgelegt wurden. 13 zeigt die Baumansicht in Projektforge zu Aufgaben. Über die Icons können Aufgaben (vollständig oder einzeln) auf- und zugeklappt werden.
Abbildung 13: Aufgabenhierarchie in ProjectForge®

Die folgende Tabelle beschreibt die Felder von Aufgaben und deren jeweilige Funktion.
Feld Kurzbeschreibung
Übergeordnete Aufgabe Die Aufgabe ist Unteraufgabe der übergeordneten Aufgabe. Hierüber wird ein Aufgabenbaum definiert, wobei die oberste Aufgabe (Knoten) in ProjectForge® der so genannte Wurzelknoten (Root) ist. Außer dieser Aufgabe, haben alle Aufgaben übergeordnete Aufgaben. Angezeigt werden im Aufgabenbaum auf oberster Ebene alle Aufgaben, die den Wurzelknoten als übergeordnete Aufgabe haben.
Name Der Aufgabenname sollte kurz die Aufgabe kennzeichnen. Aufgabennamen müssen nicht eindeutig sein.
Referenz Dieses Feld kann vielseitig verwendet werden, z. B. für Bestellnummern, Auftragsnummern o. ä.. Die Referenz vererbt sich automatisch auf alle Unteraufgaben, sofern sie dort nicht selber definiert sind. Im Export der Zeitberichte wird auch die Referenz zu jedem Zeitbericht (abgeleitet aus der Aufgabe und ggf. der übergeordneten Aufgaben).
Status Nicht begonnen, begonnen oder geschlossen. In der Baumansicht kann über den Filter eingestellt werden, welche Aufgaben eingeblendet werden sollen.
Priorität
Kurzbeschreibung Wird auch in der Baumansicht angezeigt.
Beschreibung Freitextfeld.
Fortschritt Frei-/Infofeld ohne weiterer Funktion.
Maximalstunden Wenn ausgefüllt, so wird der Verbrauch sowohl in der Aufgabenhierarchie als auch beim Buchen eines Zeitberichts angezeigt, s. 5.1 .
Verantwortliche(r) ProjectForge®-User zur Info.
Wiedervorlage Frei-/Infofeld ohne weiterer Funktion.
Frist Frei-/Infofeld ohne weiterer Funktion.
Projekt Wenn ein Projekt zugeordnet wurde, so müssen alle Zeitberichte zu dieser Aufgabe mit einem dem Projekt verknüpften Kostenträger gebucht weren. Das Projekt vererbt sich.
Kost2 Wenn eine Kost2 zugeordnet wurde, so müssen alle Zeitberichte zu dieser Aufgabe mit diesem Kostenträger gebucht weren. Der Kostenträger vererbt sich.
Zeitberichtsschutz Ist dieses Feld gesetzt, so können Zeitberichte zu dieser Aufgabe und jeder Unteraufgabe nur nach diesem Datum gebucht werden. Zeitberichte mit Zeitangaben bis einschließlich zu dem hier angegeben Datum werden abgewiesen. Nur die Mitarbeiter der Buchhaltung können sich über diesen Zeitberichtsschutz für andere Mitarbeiter hinwegsetzen. Eigene Zeitberichte unterliegen auch dem Schutz.

5.1 Verbrauch

Die Verbräuche werden in der Aufgabenhierarchie und beim Buchen von Zeitberichten angezeigt. Als Tooltip werden die bereits verbrauchten Gesamtstunden inklusive aller Unteraufgaben angezeigt. Wird eine Unteraufgabe ohne Maximalstundenwert mit einem Zeitbericht bebucht, so wird die nächste Elternaufgabe mit Maximalstundenwert visualisiert.

5.1.1 Für laufende Aufgaben

Anzeige Bedeutung Tooltip
Keine Budgetangabe. Gesamtverbrauch Tage.
Budgetverbrauch 0-80% Gesamtverbrauch Tage und Prozentwert. als grün angezeigt.
Budgetverbrauch 80%-90% Gesamtverbrauch Tage und Prozentwert.
Budgetverbrauch 90%-100% Gesamtverbrauch Tage und Prozentwert.
Budgetverbrauch über 100% Gesamtverbrauch Tage und Prozentwert.

5.1.2 Für abgeschlossene Aufgaben

Anzeige Bedeutung Tooltip
Keine Budgetangabe. Gesamtverbrauch Tage.
Budgetverbrauch 0-100% Gesamtverbrauch Tage und Prozentwert.
Budgetverbrauch 100%-110% Gesamtverbrauch Tage und Prozentwert.
Budgetverbrauch über 110% Gesamtverbrauch Tage und Prozentwert.

5.1.3 Unterdrücken der Statusanzeige des Verbrauchbalkens

Falls in einer Oberaufgabe einmal eine Statusanzeige des Verbrauchbalkens unterdrückt werden soll, so kann für die Aufgabe einfach eine Maximaldauer von 0 eingegeben werden. Anschließend werden nur noch die Gesamtstunden ohne Status und Maximalstundenwert angezeigt.

5.2 Zeitberichtsbuchungen

Zeitberichte der Mitarbeiter müssen immer auf Aufgaben gebucht werden. Um die Qualität der Zeitberichtsbuchungen kontrollieren und in der Qualität verbessern zu können, kann das Buchen reglementiert werden.
Folgende Regeln finden in ProjectForge® Anwendung. Trifft einer dieser Regeln zu, so kann auf die entsprechende Aufgabe kein Zeitbericht gebucht bzw. geändert werden.
  1. Der Mitarbeiter muss gemäß der Zugriffsverwaltung auf die Aufgabe oder eine Oberaufgabe die Rechte zum Eintragen von eigenen Zeitberichten besitzen.
  2. Wird ein Zeitbericht nicht in buchhalterisch relevanten Daten wie Beginn- und Endezeit, Kost2, Aufgabe und Benutzer geändert, so ist dies jederzeit möglich. So können Anwender Tippfehler oder ähnliches in den Berichten korrigieren.
  3. Ist die Aufgabe oder eine Oberaufgabe geschlossen oder gelöscht?
  4. Hat die Aufgabe oder eine Oberaufgabe den Status "komplett geschlossen"?
  5. Ist die Aufgabe keine Blattaufgabe (d. h. sie besitzt wiederum Unteraufgaben) und ist der Status auf "nur Aufgabenblätter" gesetzt?
  6. Hat eine Unteraufgabe eine zugewiesene Auftragsposition?
Die letzte Regel ist darin begründet, dass zu einem Auftrag nicht mehr genau der tatsächliche Aufwand bestimmt werden kann, da Zeitberichte von Überaufgaben nicht genau den Aufträgen zugeordnet werden können.

6 Auftragsbuch

Angebote und Aufträge können in ProjectForge® gemanaged werden. Aufträge können Projektmanagern zugeordnet werden, die dann Zugriff auf diese Aufträge/Angebote haben. Die Buchhaltung hat Zugriff auf alle Einträge.

6.1 E-Mail-Benachrichtigung

Änderungen im Auftragsbuch werden dem zugehörigen Projektmanager, sofern er nicht selbst die Änderung vornimmt, per E-Mail mitgeteilt. Abb. 14 zeigt die Möglichkeit, für einzelne Änderungen die Benachrichtigung auch abzuschalten. Dies ist nur möglich, wenn der Projektleiter nicht der aktuell angemeldete Benutzer ist.
Abbildung 14: Auftragsbuch mit E-Mail-Benachrichtigung

7 Scripting von ProjectForge®

An einigen Stellen bietet ProjectForge® eine Scripting-Funktionalität über Groovy. Folgende Beispiele mögen die Möglichkeiten demonstrieren:

7.1 Beispiele

7.1.1 Beispiel: Hibernate-Criterion-API

Beispiel

1
2
3
4
5
6
7
8
import org.hibernate.criterion.*
import org.projectforge.core.*

QueryFilter filter = new QueryFilter()         // Definiere eine Query
filter.addOrder(Order.asc("username"))         // Setze das Sortierkriterium
List userList = userDao.getList(filter)        // Hole die Benutzeriste

return "Es wurden " + userList.size + " User gefunden."
Es kann demnach die vollständige Hibernate-Criterion-API verwendet werden. Da der Rückgabewert eine Zeichenkette ist, wird diese einfach ausgegeben.

7.1.2 Beispiel: Verwenden der ProjectForge®-Filter

Beispiel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import org.projectforge.core.*
import org.projectforge.timesheet.*
import org.projectforge.common.*

DateHolder date = new DateHolder() // Using the user's current time zone

TimesheetFilter tf = new TimesheetFilter()
date.setDate(2009, Calendar.JANUARY, 01, 00, 00, 00)
tf.setStartTime(date.date)
date.setDate(2009, Calendar.JANUARY, 31, 23, 59, 59)
tf.setStopTime(date.date)
tf.setUserId(17)
List timesheetList = timesheetDao.getList(tf)

return "Es wurden " + timesheetList.size + " Zeitberichte gefunden."

7.2 Verwenden von Datumsangaben

ProjectForge® arbeitet immer mit der korrekten Zeitzone des angemeldeten Benutzers. Intern werden sämtliche Zeitangaben als UTC gespeichert! Deshalb funktionieren Abfragen in ProjectForge® auch nur korrekt, wenn die Zeitzone beim Erzeugen von Date-Objekten korrekt gesetzt ist. Dies erledigt automatisch die Klasse DateHolder.

Beispiel

1
2
3
4
5
6
7
8
9
10
11
import org.projectforge.common.*

DateHolder date = new DateHolder() // user's current time zone / locale

date.setDate(2009, Calendar.JANUARY, 01) // CET: 01.01.2009 00:00
String result = "UTC: " + date.date // UTC: Wed Dec 31 23:00:00 UTC 2008

date.setDate(2009, Calendar.APRIL, 01, 17, 03) // CEST: 01.04.2009 17:03
result += ", UTC: " + date.date // UTC: Wed Apr 01 15:03:00 UTC 2009

return result

7.3 Zugfriffsmöglichkeiten und Zugriffsschutz (DAOs)

Innerhalb des Groovy-Skripts werden einige Funktionen, wie z. B. Datenbankzugriffsmöglichkeiten über DAOs (DataAccessObjects) bereitgestellt. Dabei stellen die DAOs sicher, dass ein Anwender nur diejenigen Datenbankobjekte sieht, die er gemäß Nutzerrechten auch sehen darf. Objekte ohne Zugriffserlaubnis werden vor der Rückgabe an das Groovy entfernt.

7.4 Erzeugen von Exceltabellen

Gibt das Groovy-Skript ein ExportWorkbook zurück, so wird für diese Workbook direkt eine Exceldatei erzeugt und zum direkten Download weitergeleitet.

7.4.1 Beispiel: Excelexport einfacher Listen

Beispiel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import org.hibernate.criterion.*
import org.projectforge.core.*
import org.projectforge.export.*

QueryFilter filter = new QueryFilter()         // Definiere eine Query
filter.addOrder(Order.asc("username"))         // Setze das Sortierkriterium
List userList = userDao.getList(filter)        // Hole die Benutzeriste

ExportWorkbook workbook = new ExportWorkbook();// Erzeuge ein neues Workbook
ExportSheet sheet = workbook.addSheet("Users"// Erzeuge ein Tabellenblatt
sheet.contentProvider.colWidths = [10, 20]     // setze die Spaltenbreiten auf Zeichenlänge 10 bzw. 20.
sheet.propertyNames = ["username""lastname"// Definiere die Properties, die dann die
sheet.addRow().setCapitalizedValues(sheet.propertyNames)  // Füge die Kopfzeile hinzu
sheet.addRows(userList)                        // einzelnen Zeilen füllen

return workbook

7.4.2 Beispiel: Excelexport von gejointen Objekten

Beispiel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import org.projectforge.core.*
import org.projectforge.export.*
import org.projectforge.timesheet.*
import java.text.SimpleDateFormat

TimesheetFilter tf = new TimesheetFilter()
SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm")
tf.setStartTime(df.parse("01.01.2009 00:00"))
tf.setStopTime(df.parse("31.01.2009 23:59"))
tf.setUserId(17)
List timesheetList = timesheetDao.getList(tf)

ExportWorkbook workbook = new ExportWorkbook();
ExportSheet sheet = workbook.addSheet("Timesheets")
sheet.contentProvider.colWidths = [10, 20, 15, 10]
sheet.contentProvider.putFormat(java.sql.Timestamp.class,"DD.MM.YYYY hh:mm"// Definiere Format für alle Timestamps
sheet.contentProvider.putFormat("stopTime","hh:mm")             // Definiere Format für Property 'stopTime'
sheet.addRow().setValues("Username""Beschreibung""StartDate""StopDate""fakturiert")
sheet.propertyNames = ["user.username""description""startTime""stopTime""kost2.kost2Art.fakturiert"]
sheet.addRows(timesheetList)

return workbook

7.4.3 Eigene Joinobjekte

Das Zusammenführen von Datensätzen kann direkt über Groovy abgebildet werden (als elegante Alternative zur Hibernate-Query-Language), wie folgendes Beispiel demonstriert.

Beispiel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import org.fibu.*
import org.fibu.kost.*
import org.projectforge.export.*
import org.projectforge.core.*

class JoinedObject {
  BuchungssatzDO satz
  EmployeeDO employee
}

// Laden der Liste mit den Buchungsätzen
BuchungssatzFilter filter = new BuchungssatzFilter();
filter.setFrom(2008, 0) // Januar
filter.setTo(2008, 11)  // Dezember

def buchungssaetze = buchungssatzDao.getList(filter)
buchungssaetze = buchungssaetze.findAll{ satz -> (5000..5999).contains(satz.konto.nummer) }

// Laden der Liste mit den Usern
def employees = employeeDao.getList().findAll{it.kost1 != null}

def result = new ArrayList()
buchungssaetze.each{bs ->
  el = new JoinedObject()
  el.satz = bs
  el.employee = employees.find{employee -> employee.kost1Id == bs.kost1.id}
  result.add(el)
}

// Generieren eines ExcelWorkbooks
ExportWorkbook workbook = new ExportWorkbook();
ExportSheet sheet = workbook.addSheet("Ergebnis")
sheet.contentProvider.colWidths = [10, 10, 8, 8, 10, 10, 20, 20]
sheet.addRow().setValues("Datum""Betrag""Konto""Gegen-konto""Kost1""Kost2""Name")
sheet.contentProvider.putFormat("satz.datum""DD.MM.YYYY")
sheet.contentProvider.putFormat("satz.betrag""#,##0.00$;[Red]-#,##0.00$"// English format
sheet.contentProvider.putFormat("satz.konto.nummer""0")
sheet.contentProvider.putFormat("satz.gegenKonto.nummer""0")
sheet.propertyNames = ["satz.datum""satz.betrag""satz.konto.nummer""satz.gegenKonto.nummer",
  "satz.kost1.formattedNumber""satz.kost2.formattedNumber""employee.user.fullname"]
sheet.addRows(result)

return workbook

7.4.4 Formate

Beispiel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import org.projectforge.calendar.*
import org.projectforge.common.*
import org.projectforge.core.*
import org.projectforge.export.*

ExportWorkbook workbook = new ExportWorkbook();// Erzeuge ein neues Workbook
ExportSheet sheet = workbook.addSheet("Test"// Erzeuge ein Tabellenblatt
sheet.contentProvider.colWidths = [20, 20, 20]
sheet.addRow().setValues("Typ""Precision""Value")
sheet.addRow().setValues("DayHolder""Day"new DayHolder())
sheet.addRow().setValues("DateHolder""Day"new DateHolder().setPrecision(DatePrecision.DAY))
sheet.addRow().setValues("DateHolder""Minutes"new DateHolder().setPrecision(DatePrecision.MINUTE))
sheet.addRow().setValues("DateHolder""Seconds"new DateHolder().setPrecision(DatePrecision.SECOND))
sheet.addRow().setValues("DateHolder""Millis"new DateHolder().setPrecision(DatePrecision.MILLISECOND))

return workbook

Hinweis

ProjectForge® verwendet standardmäßig auch die Genauigkeit der DateHolder-Objekte. Wenn beim DateHolder Sekunden als Genauigkeit eingestellt sind, so werden auch die Sekunden ausgegeben. Bei DayHoldern oder einer Genauigkeit von Tagen, so wird nur das Datum ausgegeben. Alle unterstützten Genauigkeiten sind: DAY, HOUR_OF_DAY, MINUTE_15, MINUTE, SECOND, MILLISECOND.

7.4.5 Modifizieren von existierenden Exceldateien

Es können Exceltabellen hochgeladen werden, die per Script modifiziert werden können.

Beispiel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import org.hibernate.criterion.*
import org.projectforge.core.*
import org.projectforge.export.*

QueryFilter filter = new QueryFilter()         // Definiere eine Query
filter.addOrder(Order.asc("username"))         // Setze das Sortierkriterium
List userList = userDao.getList(filter)        // Hole die Benutzeriste

xls = reportScriptingStorage.getFile("MeinReport.xls"// Wurde mit diesem Namen hochgeladen.
ExportWorkbook workbook = new ExportWorkbook(xls);// Verwende vorhandene Exceldatei
ExportSheet sheet = workbook.addSheet("Users"// Erzeuge ein Tabellenblatt
sheet.contentProvider.colWidths = [10, 20]     // setze die Spaltenbreiten auf Zeichenlänge 10 bzw. 20.
sheet.propertyNames = ["username""lastname"// Definiere die Properties, die dann die
sheet.addRow().setCapitalizedValues(sheet.propertyNames)  // Füge die Kopfzeile hinzu
sheet.addRows(userList)                        // einzelnen Zeilen füllen

return workbook

7.4.6 Zellenformate

Es muss die englische Notation verwendet werden.

Beispiel

DD.MM.YYYY hh:mm Zeitstempel mit Minuten
DD.MM.YYYY hh:mm:ss Zeitstempel mit Sekunden
0 Normale Zahlendarstellung ohne Tausendertrennzeichen.
#,##0.00$ Währungsdarstellung (Dollar)
#,##0.00$;[Red]-#,##0.00$ Währung in Dollar mit roter Darstellung von negativen Zahlen.

7.4.7 Excel und Zeitdauern

Excel verwendet für die interne Darstellung von Zeitdauern den Bruchteil von 24h. Um z. B. Millisekunden im Excel in Form von Stunden und Minuten in einer Zelle anzuzeigen, muss eine kleine Umrechnung vorgenommern werden:
1
2
3
BigDecimal duration = new BigDecimal(durationInMillis / 1000); // Seconds
duration = duration.divide(new BigDecimal(60 * 60 * 24), 8, RoundingMode.HALF_UP); // Fraction of day (24 hours)
double excelDuration = duration.doubleValue();
Als Zellenformat kann dann beispielsweise "[h]:mm" verwendet werden.

7.5 Erzeugen von Diagrammen

Diagramme können über JFreeChart (www.jfree.org) erzeugt werden.
Abbildung 15: Beispiel eines Diagrammexports

Beispiel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import org.jfree.chart.*
import org.jfree.chart.plot.*
import org.jfree.data.general.*
import org.jfree.util.*
import org.projectforge.export.*

DefaultPieDataset dataset = new DefaultPieDataset()
dataset.setValue("Linux", 15)
dataset.setValue("Mac", 8)
dataset.setValue("Windows", 70)
dataset.setValue("Others", 7)
JFreeChart chart = ChartFactory.createPieChart3D("Users on www.heise.de", dataset, truetruefalse)
PiePlot3D plot = (PiePlot3D) chart.getPlot()

ExportJFreeChart export = new ExportJFreeChart(chart, 800, 600)
return export

7.6 Nested und indexed Properties

Es können Bean-Properties auch über die übliche Punkt-Notation benutzt werden:
1
2
sheet.propertyNames = ["user.username""description""startTime""stopTime",
         "kost2.kost2Art.fakturiert"]
dass auch so genannte nested properties gefunden werden. Im Beipiel ist kost2Art ein Property von kost2 und fakturiert wiederum ein Property von kost2Art.
Ebenso werden so genannte indexed Properties unterstützt: users[3].name oder result.userList[0].

7.7 Import von Excellisten

Abb. 16 zeigt die Beispielimportdatei.
Abbildung 16: Excelimportbeispiel

Beispiel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.text.*;
import org.projectforge.export.*
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.UK);

xls = reportScriptingStorage.getFile("import-example.xls"// Wurde mit diesem Namen hochgeladen.
ExportWorkbook workbook = new ExportWorkbook(xls);// Verwende vorhandene Exceldatei
ExportSheet sheet = workbook.getSheet("Sheet-1"); // Hole Sheet mit dem angegebenen Namen
rows = sheet.rows; // Hole alle Zeilen
result = "";
total = 0.0;

for (int i = 1; i < sheet.rows.size; i++) {
  row = sheet.getRow(i);
  no = row.getCell(0).getNumericCellValue();
  name = row.getCell(1).getStringCellValue();
  amount = row.getCell(2).getNumericCellValue();
  total += amount;
  result += (int)no + ". The amount of " + name + " is: " + nf.format(amount) + "\n";
}
result += "The total amount is: " + nf.format(total);
return result;
The output is:
 1. The amount of Susan is: £50.23
2. The amount of Hugo is: £17.00
3. The amount of Lisa is: £15.00
4. The amount of Mona is: £10.00
The total amount is: £92.23

8 Buchhaltung mit ProjectForge®

8.1 Rechnungsbuch

ProjectForge® unterstützt sowohl Eingangs- (Kreditoren) als auch Ausgangsrechnungen (Debitoren):

8.1.1 Kostenträgerzuordnung

Es empfiehlt sich, diese Funktionen direkt auszuprobieren, da sie relativ selbsterklärend und intuitiv abgebildet sind.
Rechnungspositionen können auf Kostenträger (Kost1 und Kost2) verteilt werden. Über eine Autovervollständigung kann eine Verteilung sehr schnell übernommen werden. So kann der Anwender Kostenträgernummern oder auch Beschreibungstexte eines Kostenträgers eingeben (wie Kundenname, Art etc.).
Es können beliebig viele Zuordnungen hinzugefügt werden. Bei Anlage einer neuen Zeile setzt ProjectForge® automatisch den verbleibenden Betrag ein, dieser kann geändert oder auch als Prozentzahl eingegeben werden.
Aus Gründen der Nachvollziehbarkeit können nur noch nicht gespeicherte Positionen gelöscht werden (jeweils von der letzten beginnend). Soll eine Zeile nachträglich entfernt werden, so kann ein Betrag von 0 € eingesetzt werden.

8.1.2 Klonfunktion von Ausgangsrechnungen (Debitoren)

Um die Erstellung von wiederkehrenden Debitorenrechnungen zu vereinfachen, können diese geklont werden:

8.2 Datev-Import

Über diese Funktion werden die Konten (Kontenplan) und die Buchungssätze eingelesen. Diese Daten werden vom Steuerbüro in Form eines Excel-Exports geliefert.

8.2.1 Grundsätzliches zum ProjectForge®-Excel-Import

Im folgenden wird anhand des Kontenplans der Import und die notwendigen Prüfschritte erläutert.

8.2.1.1 Schritt 1: Auswahl der zu importierenden Excel-Datei

Abb. 17 zeigt den ersten Schritt: Es wird die zu importierende Excel-Datei über den Browserknopf "Datei auswählen" im lokalen Dateisystem selektiert. Anschließend wird die gewünschte Importfunktion (z. B. "Import Kontenplan") gewählt.
Abbildung 17: Datev-Import, Schritt 1: Auswahl der Importdatei

8.2.1.2 Schritt 2: Daten werden eingelesen

Abb. 18 zeigt den zweiten Schritt: Die Daten wurden erfolgreich eingelesen und die importierten Tabellenblätter (Sheets) untereinander angezeigt (standardmäßig sind alle Blätter zugeklappt). Im Fehlerfalle wird der Fehler mit Tabellenblatt, Zeilennummer und Spaltennummer angezeigt (z. B. wenn ein nicht passendes Zahlenformat in einer Zelle erkannt wurde.) Fehlerhafte Datensätze können bereits eingesehen werden (durch Aufklappen des Importbereichs).
Abbildung 18: Datev-Import, Schritt 2: Einlesen der Datei

8.2.1.3 Schritt 3: Verproben

Abb. 19 zeigt den zweiten Schritt: Die Daten wurden erfolgreich eingelesen und die importierten Tabellenblätter (Sheets) untereinander angezeigt (standardmäßig sind alle Blätter zugeklappt). Nun sollte die Funktion "Verproben" für das gewünschte Tabellenblatt / die gewünschten Tabellenblätter gewählt werden.
Beim Verproben gleicht ProjectForge® die importierten Datensätze mit evtl. bereits vorhandenen Datensätzen ab. Nach dem Verproben werden auch neue und modifizierte Datensätze angezeigt.
Abbildung 19: Datev-Import, Schritt 3: Verproben

8.2.1.4 Schritt 4: Prüfen, selektieren und Übernahme

Abb. 20 zeigt den vierten Schritt: Nach der Verprobung können nun die zu speichernden Datensätze einer Sichtprüfung unterzogen werden. Bei modifizierten Einträgen wird über einen Tooltipp der ursprüngliche Wert angezeigt.
Nach der Prüfung können die Datensätze selektiert werden, die in ProjectForge® übernommen werden sollen. Mit der Funktion "Select all" können auch alle angezeigten Datensätze markiert werden. Anschließend kann über "Commit" eine Übernahme bestätigt und angestoßen werden.
Abbildung 20: Datev-Import, Schritt 4: Prüfen, Selektion und Übernahme

8.2.1.5 Schritt 5: Import abgeschlossen

Abb. 21 zeigt den fünften Schritt: Nach dem Import wird angezeigt, wieviel Datensätze übernommen wurden. Ein abschließendes "Verproben" sollte aufgerufen werden. Wenn alle Änderungen erfolgreich übernommen wurden und alle Datensätze selektiert worden waren, so müsste abschließend für das Tabellenblatt "nichts zu tun" angezeigt werden. Wurde nur ein Teilsatz der Daten selektiert, so werden die übrigen noch zur Auswahl angeboten.
Abbildung 21: Datev-Import, Schritt 5: Abschluss

8.2.2 Import der Lohnbuchkonten (Kontenplan)

Für den Import der Lohnbuchkonten wird im zu importierenden Exceldokument ein Tabellenreiter mit dem Namen "Kontenplan" erwartet. Dieses Tabellenblatt wird für den Import verwendet. Alle anderen Tabellenblätter werden ignoriert.

8.2.2.1 Format

Folgendes Format wird erwartet (Abb. 22 ).
Abbildung 22: Excelformat für Datev-Import des Kontenplans
In Zeile 3 wird die Kopfspalte mit den Namen "Konto" und "Bezeichnung" erwartet. Vorhandene Konten werden nicht gelöscht, sondern bei Vorhandensein modifiziert.

8.2.3 Import der Buchungssätze (01-12)

Für den Import der Buchungssätze werden im zu importierenden Exceldokument die Tabellenblätter mit dem Namen "01", "02", ..., "12" berücksichtigt. Diese Blätter stehen für die zu importierenden Buchungsmonate.

8.2.3.1 Format

Folgendes Format wird erwartet (Abb. 23 ).
Abbildung 23: Excelformat für Datev-Import der Buchungssätze
In Zeile 3 wird die Kopfspalte mit den Namen "Konto" und "Bezeichnung" erwartet. Vorhandene Konten werden nicht gelöscht, sondern bei Vorhandensein modifiziert.

8.3 Weitere Imports

8.3.1 Mitarbeitergehälter

Das Excelformat wird wie folgt angenommen:
  1. Ein Monatsheet hat die Namenskonvention yyyy-mm, also z. B. "2009-05".
  2. Die Spalten lauten:
    1. Kostenstelle Mitarbeiter: z. B. "3.050.00.00"
    2. Mitarbeiter im Format Nachname, Vorname
    3. Bruttogehalt und Sozialversicherung AG als Decimalzahl, z. B. "1.846,77"
    4. Tantieme, Ziel, Ü-Std. etc. als Dezimalzahl
    5. Sonderzahlung als Dezimalzahl
    6. Kfz als Dezimalzahl
    7. Gesamt wird ignoriert
    8. Bemerkung als Textfeld
Folendes Skript erzeugt dann die notwendigen Datenbank-SQL-Statements:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import org.projectforge.core.*
import org.projectforge.export.*
import java.text.*

year = 2009; month = 4;

if (month < 10) monthString = "0" + month
else monthString = "" + month
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMANY);
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);

xls = reportScriptingStorage.getFile("2009-Gehaltslisten.xls"// Wurde mit diesem Namen hochgeladen.
ExportWorkbook workbook = new ExportWorkbook(xls);// Verwende vorhandene Exceldatei
ExportSheet sheet = workbook.getSheet(year + "-" + monthString); // Hole Sheet mit dem angegebenen Namen
rows = sheet.rows; // Hole alle Zeilen
String result = "";

for (int i = 4; i < sheet.rows.size; i++) {
  row = sheet.getRow(i);
  kost1String = row.getCell(0).getStringCellValue();
  employeeName = row.getCell(1).getStringCellValue();
  bruttoMitAgAnteil = row.getCell(2).getNumericCellValue();
  tantieme_zv = row.getCell(3).getNumericCellValue();
  sonderzahlung = row.getCell(4).getNumericCellValue();
  kfz = row.getCell(5).getNumericCellValue();
  bemerkung = row.getCell(7).getStringCellValue();
  gesamt = new BigDecimal(bruttoMitAgAnteil + tantieme_zv + sonderzahlung + kfz).setScale(2, java.math.RoundingMode.HALF_UP);
  if (employeeName != null)
    employee = employeeDao.getByName(employeeName);
  if (kost1String == null)
    break;
  kost1 = kost1Dao.getKost1(kost1String);
  if (kost1 == null) {
    result += "\n-- **********" + kost1String;
  } else if (kost1.getDescription().equals(employeeName) == false) {
    result += "\n-- **********" + kost1.getDescription() + " != " + employeeName;
  } else if (employee == null) {
    result += "\n-- ********** Employee '" + employeeName + "' not found.";
  } else {
    text = "Excel-Import Kai";
    if (tantieme_zv > 0) text += "; Tantieme/Zielvereinbarung/Ueberstunden o. ae.: " + nf.format(tantieme_zv);
    if (sonderzahlung > 0) text += "; Sonderzahlung: " + nf.format(sonderzahlung);
    if (kfz > 0) text += "; KFZ: " + nf.format(kfz);
    if (bemerkung != null && bemerkung.trim().size() > 0) text += "; " + bemerkung;
    result += "\ninsert into t_fibu_employee_salary (pk,created,last_update,deleted,brutto_mit_ag_anteil,month,type,year,comment,employee_id) values (nextval('hibernate_sequence'),now(), now(),false," + gesamt + ", " + (month - 1)+ ", 'GEHALT', " + year + ",'" + text + "'," + employee.id + ");";
  }
}
return result;

8.4 Zeitberichte

8.4.1 Zeitberichtsschutz

Zeitberichte können mit einem Zeitberichtsschutz versehen werden. Dieser dient dazu, dass Mitarbeiter zur einer Aufgabe (inkl. aller Unteraufgaben) keine Zeitberichte mehr bis zum angegebenen Stichtag eintragen oder in der Zeit ändern dürfen.
Dies ist sinnvoll, weil beispielsweise die Zeitberichte bereits abgerechnet oder von der Buchhaltung übernommen wurden. Abb. 24 zeigt exemplarisch eine Aufgabe, für die ein Zeitberichtsschutz bis 31.12.2008 festgelegt wurde.
Zeitberichte vor dem Stichtag können nur noch von der Buchhaltung in den Zeitangaben manipuliert werden.

Hinweis

Mitarbeiter, die nachträglich solche Aufgaben bebuchen möchten, müssten die Zeitberichte unter einer anderen Aufgabe verbuchen und sammeln, und der Buchhaltung das "Umziehen" der Zeitberichte mitteilen. Die Buchhaltung kann dann diese Zeitberichte in den geschützten Bereich verschieben und dies in Nachtragsrechnungen bei Kunden o. ä. berücksichtigen.
Abbildung 24: Zeitberichtsschutz für Aufgaben (inkl. Unteraufgaben)

8.4.2 Kostenträger

Sind zu einer Aufgabe Kost2-Kostenträger assoziiert (direkt oder über Vererbung), so muss ein Mitarbeiter beim Buchen eines Zeitberichts automatisch einen passenden Kostenträger auswählen.
Abb. 25 zeigt eine Aufgabe, der das Projekt "4.080.00 - ProjectForge®" und der Kost2-Kostenträger "4.000.99.01" zugeordnet wurden.
Abbildung 25: Zuordnung von Kost2-Kostenträgern zu Aufgaben

Hinweis

Wenn Kostenträger fehlen, können diese einem Projekt neu zugeordnet werden (dabei sollte der Status auf "ACTIVE" gesetzt werden.
Wenn Kostenträger nicht mehr erscheinen sollen, so kann dieser entweder aus dem Feld "Kost2" der betroffenen Aufgabe entfernt oder als Projektkostenträger auf "INACTIVE" oder "ENDED" gesetzt werden.

8.4.3 Zeitbericht buchen

Zeitberichte mit Kost2-Trägern erwarten zwingend die Auswahl eines Kostenträgers, wie in Abb. 26 gezeigt.
Abbildung 26: Zeitberichte anlegen / ändern mit Kost2-Kostenträgern

8.4.4 Monatsberichte

Für die Buchhaltung werden die Zeitberichte der Mitarbeiter monatlich mit Zuordnung zu den Kostenträgern aus Kost2 benötigt. Diese können über den Menüpunkt "Monatsbericht" direkt erzeugt werden. Werden zu Zeitberichten keine Kostenträgerangaben gefunden, so wird die Aufgabe anstelle des Kostenträgers ausgegeben.

8.4.5 JIRA-Support

JIRA-Issues werden unterstützt, sofern konfiguriert. Taucht in Zeitberichtsbeschreibungen ein JIRA-Issue auf, so wird dieser als Link angezeigt.

8.5 Kostenträgerrechnung

8.5.1 Arbeitszeitanteil

Zu Kostenträgern (Kost2) kann ein Anteil definiert werden, zu dem eine gebuchte Zeit als Arbeitszeit angerechnet wird (z. B. 0,5 für Reisezeiten, wenn diese nur halb als Arbeitszeit angerechnet werden sollen).
Ebenso können zu Kostenarten (Kost2-Art) Arbeitszeitanteile definiert werden, dann wird automatisch für alle Kostenträger (Kost2), die diese Kostenart tragen, die gebuchte Zeit entsprechend anteilig als Arbeitszeit angerechnet.
Ist eine Arbeitszeitanteil sowohl für Kost2 als auch für die Kost2-Art definiert, so wird die Angabe für Kost2 herangezogen und die Angabe der Kost2-Art für diesen Kost2-Träger ignoriert.

8.6 Reporting via Report-Objectives (in progress)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<ReportObjective title="Customer ACME" id="ACME" suppressOther="true" suppressDuplicates="true">
  <kost1-include>3.*</kost1-include>
  <kost1-exclude>*.01</kost1-exclude>
  <kost1-exclude>*.12</kost1-exclude>
  <kost2-include>5.*</kost2-include>
  <kost2-exclude>*.02</kost2-exclude>
  <kost2-exclude>*.11</kost2-exclude>
  <ReportObjective title="Project ACME-WEB-Portal" id="ACME-WEB-Portal">
    <kost2-include>5.020.01.*</kost2-include>
  </ReportObjective>
  <ReportObjective title="Project ACME-Java-Migration" id="ACME-Java-Migration">
    <kost2-include>5.020.02.*</kost2-include>
  </ReportObjective>
</ReportObjective>
  1. Ist eine Includeliste leer, so matchen alle Datensätze bezüglich dieser Includeliste (Wildcard).
  2. Ist eine Includeliste nicht leer, so muss mindestens ein Eintrag matchen, damit der Datensatz mit dieser Liste matcht.
  3. Bei mehreren Includelisten muss ein Datensatz mit jeder Includeliste matchen.
  4. Matcht ein beliebiger Eintrag aus einer Excludeliste, wird der Datensatz unabhängig von allen anderen Include- und Excludelisten ausgeschlossen.
Es wird die Methode String.matches(regExp) für die Auswertung der regulären Ausdrücke verwendet. Die Dokumentation der regulären Ausdrücke ist in der Klasse java.util.regex.Pattern zu finden. Zur einfacheren Eingabe modifiziert ProjectForge® automatisch die Ausdrücke. Alle Punkte werden maskiert und die Wildcards durch ".*" ersetzt. Die Ersetzung kann unterdrückt werden, indem ein einfaches Hochkomma vorangestellt wird, also beispielsweise "'^5\.510.*" bleibt (fast) unverändert: es wird lediglich das führende Hochkomma entfernt.
Beispiele: (Dies ist sinnvoll, da normalerweise '.' für ein beliebiges Zeichen und * für beliebiges Mehrfachauftreten des vorangegangenen Zeichens steht. Beispielsweise würde "3.1*" auf "3x1111" aber nicht auf "3.120.08.02" matchen, was eher verwirrend wäre.)

Hinweis

Ein Child-ReportObjective kann die Buchungssätze des Eltern-ReportObjectives immer nur subselektieren, d. h. die Buchungssätze bilden immer eine Untermenge!
Auf die Buchungssätze der Report-Objectives kann direkt zugegriffen werden.

Beispiel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import org.fibu.*
import org.fibu.kost.*
import org.projectforge.export.*
import org.projectforge.core.*

class JoinedObject {
  BuchungssatzDO satz
  EmployeeDO employee
}

// Laden der Liste mit den Buchungsätzen
def buchungssaetze = reportStorage.getCurrentReport().getBuchungssaetze() // Kann über Report-Objectives gewählt werden.
buchungssaetze = buchungssaetze.findAll{ satz -> (5000..5999).contains(satz.konto.nummer) }

// Laden der Liste mit den Usern
def employees = employeeDao.getList().findAll{it.kost1 != null}

def result = new ArrayList()
buchungssaetze.each{bs ->
  el = new JoinedObject()
  el.satz = bs
  el.employee = employees.find{employee -> employee.kost1Id == bs.kost1.id}
  result.add(el)
}

// Generieren eines ExcelWorkbooks
ExportWorkbook workbook = new ExportWorkbook();
ExportSheet sheet = workbook.addSheet("Ergebnis")
sheet.contentProvider.colWidths = [10, 10, 8, 8, 10, 10, 20, 20]
sheet.addRow().setValues("Datum""Betrag""Konto""Gegen-konto""Kost1""Kost2""Name")
sheet.contentProvider.putFormat("satz.datum""DD.MM.YYYY")
sheet.contentProvider.putFormat("satz.betrag""#,##0.00$;[Red]-#,##0.00$"// English format
sheet.contentProvider.putFormat("satz.konto.nummer""0")
sheet.contentProvider.putFormat("satz.gegenKonto.nummer""0")
sheet.propertyNames = ["satz.datum""satz.betrag""satz.konto.nummer""satz.gegenKonto.nummer",
  "satz.kost1.formattedNumber""satz.kost2.formattedNumber""employee.user.fullname"]
sheet.addRows(result)

return workbook

8.7 JasperReports, Beta

8.7.1 Step by Step Report definieren

  1. iReport starten
  2. ProjectForgeReportingInterfaces-3.6.1.jar herunterladen (nur notwendig bei Änderungen und erstmalig)
  3. Unter Einstellungen -> Classpath Jar registrieren (nur bei Änderungen des Jars notwendig und erstmalig), s. Abb. 27
  4. Gewünschte Query als JavaBean DataSource mit org.projectforge.reporting.Buchungssatz erstellen, s. Abb. 27 . Die Dokumentation der Entitäten ist als Java-Api-Doc hier zu finden.
Abbildung 27: Das Jar sollte erstmalig und bei jeder Änderung registriert werden.
Abbildung 28: Die Abfrage kann anhand des Beans org.projectforge.reporting.Buchungssatz erstellt werden.

8.7.2 Report testen

  1. Zunächst ReportObjectives hochladen
  2. ReportObjectives laden (über Zeitraum)
  3. JasperReportDesign (jrxml) hochladen

8.7.3 Reports mit GroovyScript

Wird kein GroovyScript angegeben, so werden die Buchungsätze des aktuell gewählten ReportObjectives an JasperReport inkl. Bwa-Werte übergeben. Die vorhandenen Variablen sind in der Webapplikation angegeben. Dies sind z. B.:
Variable Typ Kurzbeschreibung
reportStorage ReportStorage Der geladene ReportStorage mit allen Buchungssätzen zugeordnet zu den ReportObjectives in dem gewählten Zeitraum.
Package: org.fibu.kost.reporting
app String Kennung der Applikation: ProjectForge V. <verstion>
appVersion String Version der Applikation
appRelease String Release-Datum der aktuellen Applikationsversion als Text.
reportList ReportGeneratorList Liste der Reports, die mit JasperReport erzeugt werden sollen. Diese Liste wird vom GroovyScript befüllt.
Package: org.fibu.kost.reporting
scriptResult.
output
String Wenn ein Ausdruck oder ein Ergebnis noch zusätzlich ausgegeben weden soll. Diese Funktion ist obsulet, wenn gleichzeitig ein Report heruntergeladen wird.
*Dao ScriptingDao Über die ScriptingDaos, wie beispielsweise timesheetDao oder userDao kann auf die ProjectForge®-Entitäten direkt zugegriffen werden. Es findet eine volle Zugriffskontrolle durch ProjectForge® statt.

Beispiel

1
2
3
4
5
6
7
8
9
10
11
12
13
list = reportStorage.getCurrentReport().getBuchungssaetze(); // Kann über Report-Objectives gewählt werden.

result = list.findAll{ satz -> satz.kost2.kost2Art.fakturiert == false }

report = reportList.addReport()
report.addParameter("test""hurzel")
report.setBeanCollection(result)
report.addBwa(result)

//scriptResult.output=app + " " + list.size() + " " + result.size()
//return "Umsatzerloese: " + report.getParameter("umsatzErloese")

return reportList

8.7.3.1 Rückgabewerte des GroovyScripts

Das GroovyScript muss die reportList als Ergebnis zurückliefern, damit für die enthaltenen Report JasperReports aufgerufen wird.
Zu Testzwecken kann das GroovyScript andere Rückgabewerte zurückgeben, diese werden dann nach dem Ausführen des Scripts ausgegeben. JasperReport wird dann nicht aufgerufen.

8.7.3.2 Direktes Erzeugen von Excellisten

Gibt das GroovyScript ein Objekt vom Type ExportWorkbook zurück, so wird aus diesem Workbook direkt Excel erzeugt und heruntergeladen. Wie es funktioniert, wird unter 7.4 beschrieben.

9 Datenschutz

9.1 Passwörter

Passwörter werden SHA-verschlüsselt in der Datenbank abgelegt. Sie liegen nur temporär für die Verarbeitung im Hauptspeicher im Klartext vor. Direkt nach der Verarbeitung (z. B. Login) werden die Passwortvariablen geöscht. Passwörter werden nicht protokolliert.

9.2 Historisierung

Sämtliche Änderungen (Anlegen, Ändern, Löschen) an Datensätzen werden mit Zeitstempel und Benutzer persistiert. Die Historientabelle wird bei der Anzeige des Editierendialogs angezeigt. Es gibt einzelne Spezialfelder von Datenobjekten, die nicht historisiert werden, d. h. zu diesen Felder existiert keine Änderungshistorie.

9.3 Protokollierungen

Zugriffsverletzungen und Basisaktivitäten der Anwender werden aus Gründen eine möglichen Fehleranalyse und eines möglicherweise notwendigen Datenrecovery protokolliert. Sie werden nicht zu statistischen Zwecken bezüglich Benutzeraktivitäten Einzelner verwendet.

9.4 Direktwahl - Rufnummern

Jede Direktwahl wird protokolliert. Folgende Felder sind enthalten:
  1. Benutzer
  2. Quellrufnummer
  3. Zielrufnummer (wobei die letzten 3 Endziffern ausgeixt sind: 012345xxx).