21.05.2013 Aufrufe

IPA-Dokumentation 2013 ResMan Reporting

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

<strong>IPA</strong>-<strong>Dokumentation</strong> <strong>2013</strong><br />

<strong>ResMan</strong> <strong>Reporting</strong><br />

Kunde TCSB<br />

Projektname <strong>ResMan</strong> <strong>Reporting</strong><br />

Projektnummer -<br />

Autor Elisa Schnabel<br />

Ausgabedatum 21.05.<strong>2013</strong><br />

Version 1.0<br />

Eidgenössisches Departement für Wirtschaft,<br />

Bildung und Forschung WBF<br />

Staatssekretariat für Wirtschaft SECO<br />

Status In Arbeit In Prüfung Genehmigt, zur<br />

Nutzung<br />

Beteiligter Personenkreis<br />

Benutzer, Anwender Gruppenleiter TCSB<br />

Prüfung Thomas D‘Ascoli ,Fachvorgesetzter<br />

Martin Frieden, Hauptexperte<br />

Claudio Siegenthaler , 2. Experte<br />

Genehmigung Thomas D’Ascoli, Fachvorgesetzter<br />

zur Information, Kenntnis Thomas Rohrer, Berufsbildner


Dokumentinformationen<br />

Änderungskontrolle, Prüfung, Genehmigung<br />

Version Datum Name / Rolle Beschreibung<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Vorlage 2009-12-23 W. Aeby Dokumentvorlage QV2010, Version V1.0<br />

0.1<br />

0.2<br />

<strong>2013</strong>-04-29<br />

<strong>2013</strong>-04-30<br />

Elisa Schnabel<br />

Elisa Schnabel<br />

Eröffnung, Ablauf und Umfeld,<br />

Voranalyse<br />

Technisches Konzept<br />

0.3 <strong>2013</strong>-05-01 Elisa Schnabel Technisches Konzept<br />

0.4 <strong>2013</strong>-05-14 Elisa Schnabel Realisierung Systemarchitektur<br />

0.5 <strong>2013</strong>-05-16 Elisa Schnabel Realisierung GUI<br />

0.6 <strong>2013</strong>-05-16 Elisa Schnabel Realisierung, Glossar<br />

0.7 <strong>2013</strong>-05-17 Elisa Schnabel Quellen<br />

0.8 <strong>2013</strong>-05-17 Elisa Schnabel Testprotokoll<br />

0.9 <strong>2013</strong>-05-21 Elisa Schnabel Schlussbericht , Persönliches Fazit<br />

1.0 <strong>2013</strong>-05-21 Elisa Schnabel Abgabeversion<br />

Verwendete Abkürzungen<br />

Abkürzung Bedeutung<br />

BIT<br />

DB<br />

DTO<br />

EM<br />

GUI<br />

Bundesamt für Informatik und Telekommunikation<br />

Datenbank<br />

Data Transfer Object<br />

EntityManager<br />

Graphical User Interface<br />

<strong>IPA</strong> Individuelle Praktische Arbeit<br />

OdA Organisation der Arbeit<br />

QC<br />

OE<br />

Quality Center<br />

Organisationseinheit<br />

<strong>ResMan</strong> Ressourcen Manager<br />

CRUD Create Read Update Delete<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 2 von 128


Inhaltsverzeichnis<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Dokumentinformationen...................................................................................................... 2<br />

Inhaltsverzeichnis ................................................................................................................ 3<br />

Abbildungsverzeichnis ........................................................................................................ 5<br />

Tabellenverzeichnis ............................................................................................................. 6<br />

Management Summary ........................................................................................................ 7<br />

Teil 1: Ablauf und Umfeld .................................................................................................... 8<br />

1. Aufgabenstellung ................................................................................................... 9<br />

1.1 Ausgangslage ...................................................................................................... 9<br />

1.2 Auftragsformulierung ........................................................................................... 9<br />

1.3 Mittel und Methoden .......................................................................................... 10<br />

1.4 Projektorganisation ............................................................................................ 11<br />

1.5 Projektrollen ...................................................................................................... 11<br />

2. Vorkenntnisse ...................................................................................................... 12<br />

3. Vorarbeiten ........................................................................................................... 13<br />

4. Firmenstandards .................................................................................................. 14<br />

5. Datensicherung .................................................................................................... 15<br />

6. Zeitplan ................................................................................................................. 16<br />

7. Arbeitsjournal ....................................................................................................... 17<br />

7.1 Erster Tag: Montag, 29.04.<strong>2013</strong> ........................................................................ 18<br />

7.2 Zweiter Tag: Dienstag, 30.04.<strong>2013</strong> .................................................................... 19<br />

7.3 Dritter Tag: Donnerstag, 02.05.<strong>2013</strong> (Halber Tag, Morgens) ............................. 20<br />

7.4 Vierter Tag: Freitag, 03.05.<strong>2013</strong> ........................................................................ 21<br />

7.5 Fünfter Tag: Montag, 06.05.<strong>2013</strong> ....................................................................... 22<br />

7.6 Sechster Tag: Dienstag, 07.05.<strong>2013</strong> .................................................................. 23<br />

7.7 Siebter Tag: Montag, 13.05.<strong>2013</strong> ....................................................................... 24<br />

7.8 Achter Tag: Dienstag, 14.05.<strong>2013</strong> ..................................................................... 25<br />

7.9 Neunter Tag: Donnerstag, 16.05.<strong>2013</strong> (Halber Tag, Morgens) .......................... 26<br />

7.11 Zehnter Tag: Freitag, 17.05.<strong>2013</strong> ...................................................................... 27<br />

7.12 Elfter Tag: Dienstag, 21.05.<strong>2013</strong> ....................................................................... 28<br />

7.13 Arbeitszeit total .................................................................................................. 28<br />

8. Schlussbericht ..................................................................................................... 29<br />

8.1 Vergleich Ist/Soll ................................................................................................ 29<br />

8.2 Persönliches Fazit ............................................................................................. 29<br />

9. Unterschriften ...................................................................................................... 30<br />

Teil 2: Projektdokumentation ............................................................................................ 31<br />

10. Voranalyse ............................................................................................................ 32<br />

10.1 Analyse Ist Zustand / Soll-Zustand .................................................................... 32<br />

10.2 Pflichtenheft / Systemanforderungen ................................................................. 33<br />

10.3 Varianten ........................................................................................................... 34<br />

10.4 Variantenentscheid ............................................................................................ 36<br />

10.5 Informationssicherheit und Datenschutz ............................................................ 37<br />

11. Konzept ................................................................................................................. 38<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 3 von 128


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

11.1 Anwendungsfälle ............................................................................................... 38<br />

11.2 GUI Entwürfe ..................................................................................................... 46<br />

11.3 Testkonzept ....................................................................................................... 51<br />

12. Realisierung ......................................................................................................... 61<br />

12.1 Systemdesign .................................................................................................... 61<br />

12.2 GUI .................................................................................................................... 70<br />

12.3 Screenflow Diagramm ....................................................................................... 73<br />

12.4 Testprotokoll ...................................................................................................... 74<br />

12.5 JUnit Test .......................................................................................................... 75<br />

13. Einführung ............................................................................................................ 76<br />

14. Quellenverzeichnis .............................................................................................. 77<br />

14.1 Informationen..................................................................................................... 77<br />

14.3 Bilder ................................................................................................................. 77<br />

15. Glossar ................................................................................................................. 78<br />

16. Unterschriften ...................................................................................................... 79<br />

17. Anhang ................................................................................................................. 80<br />

17.1 Quellcode .......................................................................................................... 80<br />

17.2 Benutzerhandbuch .............................................................................................. 1<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 4 von 128


Abbildungsverzeichnis<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Abbildung 1: Projektorganisation........................................................................................................... 11<br />

Abbildung 2: Hermes Phasen ................................................................................................................ 14<br />

Abbildung 3:HERMES Phasenmodel für beide Projekttypen ................................................................ 31<br />

Abbildung 4:UseCase Diagramm .......................................................................................................... 38<br />

Abbildung 5: Activity Diagramm UseCase 01 ....................................................................................... 40<br />

Abbildung 6: Activity Diagramm UseCase 02-07 .................................................................................. 45<br />

Abbildung 7: GUI-Nr. 01 Schnellliste ..................................................................................................... 46<br />

Abbildung 8: GUI-Nr. 02 Suchmaske/ Erfassungsmaske für die Schnellliste ....................................... 47<br />

Abbildung 9:GUI-Nr. 03 Detailansicht ................................................................................................... 48<br />

Abbildung 10:GUI-Nr. 04 Trefferliste ..................................................................................................... 49<br />

Abbildung 11:GUI-Nr. 04 Trefferliste Resource .................................................................................... 50<br />

Abbildung 12:Komponenten Diagramm ................................................................................................ 61<br />

Abbildung 13: MVC ............................................................................................................................... 62<br />

Abbildung 14:Klassendiagramm Weblayer ........................................................................................... 63<br />

Abbildung 15:Klassendiagramm Servicelayer ....................................................................................... 64<br />

Abbildung 16:Klassendiagramm Persistenzlayer .................................................................................. 65<br />

Abbildung 17:Domain Model ................................................................................................................. 66<br />

Abbildung 18:ERD <strong>ResMan</strong> Haupttabellen ........................................................................................... 67<br />

Abbildung 19: Sequenzdiagramm Filterkriterien abspeichern .............................................................. 68<br />

Abbildung 20: Sequenzdiagramm Berechnung Auslastungsdaten ....................................................... 69<br />

Abbildung 21:Screenflow ....................................................................................................................... 73<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 5 von 128


Tabellenverzeichnis<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Tabelle 1: Projektleiter/Mitarbeiter......................................................................................................... 11<br />

Tabelle 2: Fachvorgesetzter .................................................................................................................. 11<br />

Tabelle 3: Hauptexperte ........................................................................................................................ 11<br />

Tabelle 4: Zweit-Expert ......................................................................................................................... 11<br />

Tabelle 5: Vorkenntnisse ....................................................................................................................... 12<br />

Tabelle 6: Arbeitsjournal erster Tag ...................................................................................................... 18<br />

Tabelle 7: Arbeitsjournal zweiter Tag .................................................................................................... 19<br />

Tabelle 8:Arbeitsjournal dritter Tag ....................................................................................................... 20<br />

Tabelle 9: Arbeitsjournal vierter Tag ..................................................................................................... 21<br />

Tabelle 10:Arbeitsjournal fünfter Tag .................................................................................................... 22<br />

Tabelle 11: Arbeitsjournal sechster Tag ................................................................................................ 23<br />

Tabelle 12: Arbeitsjournal siebter Tag .................................................................................................. 24<br />

Tabelle 13: Arbeitsjournal achter Tag ................................................................................................... 25<br />

Tabelle 14: Arbeitsjournal neunter Tag ................................................................................................. 26<br />

Tabelle 15: Arbeitsjournal zehnter Tag ................................................................................................. 27<br />

Tabelle 16: Arbeitsjournal elfter Tag ..................................................................................................... 28<br />

Tabelle 17: Arbeitsjournal Arbeitszeit Total ........................................................................................... 28<br />

Tabelle 18: Unterschriften ..................................................................................................................... 30<br />

Tabelle 19: Pflichtenheft Muss Anforderungen .................................................................................... 33<br />

Tabelle 20: Pflichtenheft Kann Anforderungen ..................................................................................... 33<br />

Tabelle 21:Nutzwertanalyse .................................................................................................................. 36<br />

Tabelle 22: UseCase Filterkriterien abspeichern .................................................................................. 39<br />

Tabelle 23: UseCase Auslastungsdaten abfragen ................................................................................ 41<br />

Tabelle 24: UseCase Daten sortieren ................................................................................................... 42<br />

Tabelle 25: UseCase Datenexport CSV ................................................................................................ 42<br />

Tabelle 26: UseCase Datenexport PDF ................................................................................................ 43<br />

Tabelle 27: UseCase Datenexport Excel .............................................................................................. 43<br />

Tabelle 28: UseCase Drill Down / Drill Up Navigation .......................................................................... 44<br />

Tabelle 29:Testfall 1.0 ........................................................................................................................... 52<br />

Tabelle 30:Testfall 1.1 ........................................................................................................................... 53<br />

Tabelle 31:Testfall 2.0 ........................................................................................................................... 54<br />

Tabelle 32:Testfall 3.0 ........................................................................................................................... 55<br />

Tabelle 33:Testfall 3.1 ........................................................................................................................... 56<br />

Tabelle 34:Testfall 3.2 ........................................................................................................................... 57<br />

Tabelle 35:Testfall 4.0 ........................................................................................................................... 58<br />

Tabelle 36:Testfall 5.0 ........................................................................................................................... 58<br />

Tabelle 37:Testfall 6.0 ........................................................................................................................... 59<br />

Tabelle 38:Testfall 7.0 ........................................................................................................................... 59<br />

Tabelle 39:Testfall 8.0 ........................................................................................................................... 60<br />

Tabelle 40:Testprotokoll ........................................................................................................................ 74<br />

Tabelle 41: Gloassar ............................................................................................................................. 78<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 6 von 128


Management Summary<br />

Aufgabenstellung<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Mit der Applikation Ressourcen Manager können die Gruppenleiter des Ressort TCSB die<br />

Auslastung der einzelnen Mitarbeiter planen und überwachen. Dabei ist es mit der aktuellen<br />

Version aber nur möglich, die Sicht auf jeweils einen Mitarbeiter gleichzeitig zu schaffen. Um<br />

auch die Auslastung der einzelnen Mitarbeiter miteinander vergleichen zu können, wird die<br />

Applikation um das Modul <strong>ResMan</strong> <strong>Reporting</strong> erweitert, welches es den Gruppenleitern möglich<br />

macht eine OE-weite Sicht zu schaffen oder die Auslastungsdaten nach bestimmten Kriterien<br />

zusammenzustellen. Die Kriterien, nach denen die Gruppenleiter die Daten zusammenstellen<br />

lassen, sollen ausserdem auch abgespeichert werden können. Zusätzlich soll<br />

auch ein Export der Auslastungsdaten möglich gemacht werden. (CSV, PDF, Excel)<br />

Varianten<br />

Die Applikation <strong>ResMan</strong> wurde mit der Programmiersprache Java und den Frameworks JSF,<br />

Spring und JPA umgesetzt. Deshalb gab es im Unterprojekt <strong>Reporting</strong> von der Technologie<br />

her grundsätzlich keinen Variantenentscheid. Bei der Export-Funktion gab es aber verschiedene<br />

Varianten, die zu prüfen waren. Die Varianten, der Variantenentscheid und dessen Resultate<br />

wurden in der Voranalyse abgehandelt. Alle weiteren Entscheidungen oder Überlegungen<br />

wurden während der Realisierungsphase durchgeführt und entsprechend dokumentiert.<br />

Konzept<br />

Im Rahmen des Konzepts wurden technische Vorgaben und Konzepte für die erfolgreiche<br />

Durchführung der Realisierung festgehalten. Die Konzepte betreffen zum einen die einzelnen<br />

UseCases zum anderen die Testabläufe und den Aufbau der GUIs.<br />

Realisierung<br />

Das Modul <strong>ResMan</strong> <strong>Reporting</strong> wurde in der bereits bestehenden Entwicklungsumgebung<br />

Eclipse programmiert. Das Modul wurde nach Konzept aufgebaut und implementiert. Es<br />

wurden neue Klassen erstellt und wo nötig bestehende erweitert.<br />

Testbericht<br />

Es wurden zwei unterschiedliche Testmethoden durchgeführt. Der Anwendertest deckt die<br />

Funktionalitäten der Applikation ab und der Unit-Test stellt die Zuverlässigkeit des Codes<br />

sicher. Der Unit-Test wurde für die Berechnungslogik angewendet.<br />

Mittelbedarf<br />

Für dieses Projekt wurden keine zusätzlichen Mittel benötigt. Alle verwendeten Mittel sind<br />

bereits auf meiner Workstation installiert.<br />

Fazit<br />

Alle MUSS - und gewisse KANN Funktionalitäten konnten während der <strong>IPA</strong> umgesetzt werden.<br />

Trotz ein paar technischer Probleme, an welchen ich ein wenig Zeit verloren habe,<br />

konnte ich das Projekt soweit fertigstellen.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 7 von 128


Teil 1: Ablauf und Umfeld<br />

<strong>IPA</strong> Projektname: <strong>ResMan</strong> <strong>Reporting</strong><br />

Autor: Elisa Schnabel<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 8 von 128


1. Aufgabenstellung<br />

1.1 Ausgangslage<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Im Staatssekretariat für Wirtschaft (SECO) wurde für die Abteilung „Systembetrieb und<br />

Technik“ (TCSB) ein webbasiertes Ressourcen-Management-Tool – <strong>ResMan</strong> – entwickelt.<br />

Die Applikation Ressourcen Manager dient dazu, die Auslastungsplanung der<br />

Mitarbeitenden in der Abteilung zu vereinfachen, um so die Planung anstehender Projekte<br />

effizienter durchführen zu können.<br />

Die aktuelle Version der Applikation erlaubt die Auslastungs-Planung und -Überwachung für<br />

einzelne Ressourcen und stellt diese mittels Diagrammen grafisch dar. Zwar muss bei einer<br />

Ressource die entsprechende Organisationseinheit definiert werden, es besteht momentan<br />

aber keine Möglichkeit, eine Organisationseinheit-weite Sicht zu schaffen oder Daten nach<br />

bestimmten Kriterien zusammen zu stellen.<br />

Um die Führungspersonen bei der Team Planung zu unterstützen, ist <strong>ResMan</strong> um das Modul<br />

„<strong>Reporting</strong>“ zu erweitern.<br />

1.2 Auftragsformulierung<br />

Funktionalitäten:<br />

Das neu zu schaffende Modul enthält folgende Funktionalitäten:<br />

- Abfrage von Auslastungsdaten für einzelne oder mehrere Ressourcen oder für Organisationseinheiten<br />

mit Hilfe noch zu definierender Filterkriterien.<br />

- Tabellarische Darstellung der Resultatlisten mit passenden Sortiermöglichkeiten<br />

(MUSS) und Drill-Down / Drill-Up Navigation (KANN).<br />

- Datenexport in CSV (MUSS), XLSX und PDF (beide KANN).<br />

- Abfrage von vordefinierten „Schnelllisten“ (z.B. Auslastung aller Ressourcen einer OE<br />

im aktuellen Monat).<br />

Enthaltene Arbeiten:<br />

- Dokumentiertes Design der Lösung (UML, UI-Mockups, Gedanken zu Usability)<br />

- Umsetzung auf allen Applikations-Schichten (evtl. kein zusätzliches Repository notwendig)<br />

- QS & Bugfixing<br />

- <strong>Dokumentation</strong> der Lösung (inkl. Schulungsdokumente)<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 9 von 128


1.3 Mittel und Methoden<br />

Im Rahmen dieses Projektes setze ich folgende Software und Frameworks ein:<br />

Betriebssystem: Windows 7<br />

Office: Microsoft Office 2010 Professional<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Entwicklungsumgebung: Eclipse Java EE IDE for Web Developers<br />

Programmiersprache: Java 6<br />

Browser: Mozilla Firefox 20.0.1, Google Chrome 18<br />

Internet Explorer 8<br />

Frameworks: JSF, PrimeFaces, Spring, JPA<br />

Datenbank: PostgreSQL<br />

Datenbank- Tool:<br />

Versionsmanagementsystem:<br />

Projektmethode:<br />

GUI Skizzen:<br />

pgAdmin 1.14.3<br />

TortoiseSVN 1.7.6 (Subversion 1.7.4)<br />

HERMES<br />

Balsamiq Mockups for Desktop 2.2.10<br />

UML: Visual Paradigm for UML 8.0<br />

Testing: Quality Center HP<br />

Alle Programme sind bereits vor meiner <strong>IPA</strong> auf meiner Workstation installiert.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 10 von 128


1.4 Projektorganisation<br />

Projektausschuss<br />

Fachvorgesetzter: Thomas D’Ascoli<br />

Hauptexperte: Martin Frieden<br />

Zweit-Expert: Claudio Siegenthaler<br />

Entwicklerin:<br />

Elisa Schnabel<br />

1.5 Projektrollen<br />

Auftraggeber:<br />

Beat Felber<br />

Projektleitung:<br />

Elisa Schnabel<br />

Abbildung 1: Projektorganisation<br />

1.5.1 Projektleiterin / Projektmitarbeiterin<br />

Name Elisa Schnabel<br />

elisa.schnabel@gmx.ch<br />

Tester:<br />

Mitarbeiter<br />

TCSB-MED<br />

Firma Staatssekretariat für Wirtschaft SECO<br />

Finkenhubelweg 12, 3011 Bern<br />

Tabelle 1: Projektleiter/Mitarbeiter<br />

1.5.2 Fachvorgesetzter<br />

Name Thomas D‘Ascoli<br />

thomas.dascoli@seco.admin.ch<br />

Firma Staatssekretariat für Wirtschaft SECO<br />

Finkenhubelweg 12, 3011 Bern<br />

Tabelle 2: Fachvorgesetzter<br />

1.5.3 Hauptexperte<br />

Name Martin Frieden<br />

martin.frieden@bluewin.ch<br />

Firma gibb<br />

Lorrainestrasse 5b<br />

3000 Bern 25<br />

Tabelle 3: Hauptexperte<br />

1.5.1 Zweit-Expert<br />

Name Claudio Siegenthaler<br />

cloedu@gmail.com<br />

Firma Interdiscount Division der Coop Genossenschaft<br />

Bernstrasse 90<br />

3303 Jegenstorf<br />

Tabelle 4: Zweit-Expert<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 11 von 128


2. Vorkenntnisse<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Während meiner Ausbildung habe ich verschiedene Programmiersprachen und Frameworks<br />

kennengelernt. In den letzten anderthalb Jahren habe ich aber hauptsächlich mit den<br />

Frameworks JSF, Spring, JPA und der Programmiersprache Java gearbeitet. Die nachfolgende<br />

Tabelle zeigt die während der <strong>IPA</strong> eingesetzten Frameworks, Programmiersprachen,<br />

Software und Methoden.<br />

Technologie / Software Kenntnisse Arbeiten<br />

Java Gut Mehrere Projektarbeiten in<br />

der Schule / Lehrbetrieb<br />

durchgeführt.<br />

JSF Gut Zwei Projektarbeiten im<br />

Lehrbetrieb und eine in der<br />

Schule durchgeführt.<br />

PrimeFaces Gut Zwei Projektarbeiten im<br />

Lehrbetrieb und eine in der<br />

Schule durchgeführt.<br />

Spring Grundlegend Zwei Projektarbeiten im<br />

Lehrbetrieb durchgeführt.<br />

JPA Grundlegend Zwei Projektarbeiten im<br />

Lehrbetrieb und eine in der<br />

Schule durchgeführt.<br />

HERMES Mittel Mehrere Projekte durchgeführt<br />

Schule/ Lehrbetrieb;<br />

Einführungskurs BIT für Lernende<br />

besucht.<br />

pgAdmin Grundlegend Für die Erstellung der Datenbank<br />

des <strong>ResMan</strong> Projekts<br />

benutzt.<br />

Quality Center Keine Mit dem Quality Center wurde<br />

während der Ausbildung<br />

noch nicht gearbeitet.<br />

Tabelle 5: Vorkenntnisse<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 12 von 128


3. Vorarbeiten<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Die Entwicklungsumgebung, die Konfiguration des Springframeworks und das Datenbankmodell<br />

standen bereits im Vorfeld der <strong>IPA</strong> zur Verfügung.<br />

Ansonsten wurden keine Vorarbeiten für die <strong>IPA</strong> geleistet.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 13 von 128


4. Firmenstandards<br />

HERMES<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

In den Weisungen über die Informatik im Eidg. Volkswirtschaftsdepartement (WIT-EVD) wurde<br />

festgelegt, dass als Projektmethode HERMES verwendet werden soll. So begleitet sie<br />

auch mich während meiner <strong>IPA</strong>.<br />

Abbildung 2: Hermes Phasen<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 14 von 128


5. Datensicherung<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Sämtliche <strong>IPA</strong>-relevanten Dokumente werden im Fabasoft abgelegt. Dies ist die Dokumentenablage<br />

des SECO. Des weiteren werden alle Dokumente von mir auf www.dropbox.com<br />

abgelegt. Dies ist ein Webshare für den privaten gebrauch und kann Daten bis zu einem GB<br />

speichern.<br />

Für die Programmdateien verwenden wir im SECO tortoiseSVN. Dies ist ein Versionisierungstool,<br />

welches direkt in das Kontextmenu des Explorers installiert wird. SVN arbeitet<br />

serverseitig, das heisst, dass alle Programmdateien extern auf einem Server gesichert sind.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 15 von 128


6. Zeitplan<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 16 von 128


7. Arbeitsjournal<br />

Die Festlegungen dieses Dokuments gelten im Projekt <strong>ResMan</strong> <strong>Reporting</strong>.<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Gemäss Art. 5 Absatz 2 der Wegleitung über die individuelle praktische Arbeit (<strong>IPA</strong>) an Lehrabschlussprüfungen<br />

des BBT vom 27. August 2001 gilt:<br />

„Die zu prüfende Person führt ein Arbeitsjournal. Sie dokumentiert darin täglich das Vorgehen,<br />

den Stand der Prüfungsarbeit, sämtliche fremde Hilfestellungen und besondere Vorkommnisse<br />

wie z.B. Änderungen der Aufgabenstellung, Arbeitsunterbrüche, organisatorische<br />

Probleme, Abweichungen von der Soll-Planung.“<br />

Das Arbeitsjournal zur <strong>IPA</strong> ist zwingend zu führen und den Experten und Fachvorgesetzten<br />

vorzulegen. Das Arbeitsjournal ist täglich sinngemäss und korrekt auszufüllen.<br />

Das Arbeitsjournal dient der Nachvollziehbarkeit der von den Lernenden ausgeführten Arbeiten<br />

und wird als Teil der <strong>IPA</strong> in die Bewertung mit einbezogen.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 17 von 128


7.1 Erster Tag: Montag, 29.04.<strong>2013</strong><br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Tätigkeiten: Aufwand (geplant) h Aufwand (effektiv) h<br />

Zeitplan erstellen<br />

<strong>Dokumentation</strong> eröffnen<br />

Voranalyse (Soll /Ist, Pflichtenheft,<br />

Varianten)<br />

Tabelle 6: Arbeitsjournal erster Tag<br />

1.5<br />

2<br />

4.5<br />

Total: 8 8<br />

Probleme:<br />

Keine<br />

Hilfestellungen:<br />

Keine<br />

Reflexion:<br />

Heute war der erste Tag meiner <strong>IPA</strong>. Am Morgen erstellte ich als allererstes meinen Zeitplan.<br />

Als ich damit fertig war konnte ich schon die <strong>Dokumentation</strong> eröffnen und den Teil 1:<br />

Ablauf und Umfeld am Vormittag abschliessen.<br />

Am Nachmittag konnte ich dann auch mit der Voranalyse beginnen. Ich startete mit der<br />

SOLL- IST Analyse. Anschliessend erstellte ich das Pflichtenheft (Systemanforderungen).<br />

Hierzu musste ich mir die Anforderungen aus der Aufgabenstellung herausnehmen.<br />

Ausserdem konnte ich heute auch schon mit der Variantenanalyse starten. Ich überlegte<br />

mir hierzu, wie ich die Variantenentscheide am besten nachvollziehbar darstellen könnte. Ich<br />

entschied mich schlussendlich für eine Nutzwertanalyse. Dazu informierte ich mich im Internet<br />

ein wenig.<br />

Insgesamt bin ich mit dem heutigen Tag ganz zufrieden, denn ich konnte alle Tätigkeiten, die<br />

ich mir laut Zeitplan vorgenommen hatte durchführen.<br />

Nächste Schritte:<br />

Morgen möchte ich noch den letzten Teil der Voranalyse abschliessen und mit dem Konzept<br />

starten.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 18 von 128<br />

1.5<br />

2<br />

4.5


7.2 Zweiter Tag: Dienstag, 30.04.<strong>2013</strong><br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Tätigkeiten: Aufwand (geplant) h Aufwand (effektiv) h<br />

Voranalyse abschliessen<br />

Beginnen mit technischem Konzept<br />

Tabelle 7: Arbeitsjournal zweiter Tag<br />

1.5<br />

6.5<br />

Total: 8 8.5<br />

Probleme:<br />

Keine<br />

Hilfestellungen:<br />

Keine<br />

Reflexion:<br />

Heute Morgen habe ich noch eine Stunde an der Voranalyse gearbeitet und konnte sie auch<br />

gemäss Zeitplan rechtzeitig abschliessen. Danach fing ich direkt mit dem Konzeptteil an. Ich<br />

überlegte kurz, was ich alles in den Konzeptteil reinnehmen könnte und entschied mich für<br />

das UseCase Diagramm, die UseCase Beschreibungen, ein einfaches Komponentendiagramm,<br />

welches die drei Schichten-Architektur (Presentation, Business, Persitence) beschreibt<br />

und die GUI-Skizzen sowie das Testkonzept.<br />

Zu allererst zeichnete ich das UseCase Diagramm. Hierfür nahm ich die Systemanforderungen,<br />

welche ich bereits in der Voranalyse evaluiert habe. Anschliessend beschrieb ich noch<br />

die einzelnen UseCases. Ich entschied mich, diese sehr detailliert zu beschreiben und nahm<br />

zusätzlich zu den ansonsten üblichen Feldern noch die Validierungsregeln und sonstige<br />

Regeln hinzu. Die höhere Detaillierung soll mir dann später bei der Formulierung der Testcases<br />

helfen.<br />

So gegen Ende vom heutigen Nachmittag konnte ich dann auch schon mit dem Skizzieren<br />

der GUIs beginnen. Ich verwendete dazu das Tool Balsamique-Mockup, welches die gängigen<br />

GUI-Komponenten zur Verfügung stellt. Ich überlegte, wie viele verschiedene GUI-<br />

Ansichten ich benötige und kam schlussendlich auf vier verschiedene. Da ich mir bei der<br />

Darstellung der Resultatlisten nicht ganz sicher war, nahm ich Rücksprache mit Stefan Heller,<br />

der mir dann seine ungefähren Vorstellungen schilderte. Der heutige Tag verlief wieder<br />

ohne Probleme und auch von der Zeit her liege ich noch genau im Zeitplan.<br />

Nächste Schritte:<br />

Morgen möchte ich noch die restlichen GUIS skizzieren und mit dem Testkonzept beginnen.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 19 von 128<br />

1<br />

7.5


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

7.3 Dritter Tag: Donnerstag, 02.05.<strong>2013</strong> (Halber Tag, Morgens)<br />

Tätigkeiten: Aufwand (geplant) h Aufwand (effektiv) h<br />

GUI-Skizzen erstellen und beschreiben.<br />

Testkonzept erstellen.<br />

Total: 4 5<br />

Probleme:<br />

keine<br />

Hilfestellungen:<br />

keine<br />

Reflexion:<br />

Tabelle 8:Arbeitsjournal dritter Tag<br />

2<br />

2<br />

Heute Morgen habe ich noch die restlichen GUI-Skizzen Trefferliste und Detailansicht gezeichnet.<br />

Als ich damit fertig war, fügte ich die Skizzen in die <strong>Dokumentation</strong> ein und fügte<br />

jeder Skizze noch eine Beschreibung hinzu.<br />

Anschliessend erstellte ich das Komponentendiagramm für die drei Schichtenarchitektur,<br />

welches ich auf unser Projekt anpasste – auf dem Presentationlayer wird ein MVC-Muster<br />

aus Controller (bei uns Action), Model und View (die xhtml-Seiten) verwendet und für den<br />

Business- und Persistence-Layer verwenden wir jeweils ein Interface und eine implementierende<br />

Klasse.<br />

Später fing ich mit dem Testkonzept an. Hier beschrieb ich wer, wie, was, wo getestet wird.<br />

Um auch alle Anforderungen mit den Testfällen abzudecken, entschied ich mich heute, zu<br />

jeder Anforderung im Pflichtenheft einen Testfall zu erstellen.<br />

Heute stand auch noch der erste Besuchstag der Experten an. Herr Frieden teilte mir mit,<br />

dass er statische und dynamische Diagramme in der <strong>Dokumentation</strong> erwartet. Ausserdem<br />

teilte er mir auch mit, dass ich das Arbeitsjournal etwas ausführlicher schreiben sollte. Ich<br />

werde jetzt also in den nächsten Tagen darauf achten, dass ich noch etwas mehr Zeit darin<br />

investiere.<br />

Nächste Schritte:<br />

Da ich heute mit dem Testkonzept bereits fertig geworden bin, werde ich morgen mit dem<br />

Programmieren anfangen können.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 20 von 128<br />

2<br />

3


7.4 Vierter Tag: Freitag, 03.05.<strong>2013</strong><br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Tätigkeiten: Aufwand (geplant) h Aufwand (effektiv) h<br />

GUI programmieren 8 8<br />

Total: 8 8<br />

Probleme:<br />

Probleme tauchten heute hauptsächlich bei dem Platzieren der einzelnen GUI- Elemente<br />

auf.<br />

Hilfestellungen:<br />

Keine<br />

Reflexion:<br />

Da ich gestern bereits mit dem Konzept fertig geworden bin, begann ich ein grobes Klassendiagram<br />

über die von mir neu zu erstellenden Klassen und Interfaces für alle drei Schichten<br />

zu zeichnen. Ich entschied mich für einen <strong>Reporting</strong>service und ein <strong>Reporting</strong>repository,<br />

welches die CRUD Funktionalitäten der <strong>Reporting</strong>aufgabe abbildet. Auf dem Presentationlayer<br />

entschied ich mich für die <strong>Reporting</strong> Crud-Actions und das zugehörige Model, sowie die<br />

entsprechende View (xhtml).<br />

Anschliessend konnte ich heute schon frühzeitig mit dem Programmieren der GUIs beginnen.<br />

Als allererstes fing ich mit dem GUI Eingabemaske /Suchmaske (GUI-Nr. 2) an. Da ich<br />

mir in der Voranalyse bereits überlegt habe, welche Komponenten ich für welches Filterkriterium<br />

verwenden möchte, kam ich recht zügig voran.<br />

Probleme bereiteten mir aber die Radiobuttons, die ich verwende, um eine Zeitspanne auswählen<br />

zu können. Die Labels des jeweiligen Radio Buttons wurden nicht korrekt platziert<br />

und rutschten immer unterhalb des Radiobuttons. Ich analysierte das Problem mit Hilfe des<br />

Firefox-Plugin Firebug und konnte die relevante Styleklasse identifizieren, bei der ich das<br />

margin-top verkleinern musste. Ich musste also das Primefaces-custom.css anpassen.<br />

Mit der Detailansicht (GUI-Nr. 03) wurde ich ziemlich schnell fertig, da dort ja nur Labels angezeigt<br />

werden. Auch mit der Liste, der abgespeicherten Filterkriterien GUI-Nr. 01, wurde ich<br />

relativ schnell fertig.<br />

Für das GUI Resultat Liste (GUI-Nr. 04) reichte mir die Zeit heute nicht mehr, da ich am Morgen<br />

zu viel Zeit mit dem Platzieren der einzelnen Elemente verbrachte.<br />

Im Allgemeinen bin ich mit dem heutigen Tag nicht sonderlich zufrieden. Ich habe mich nämlich<br />

ziemlich verschätzt mit der Zeit, die ich für die GUI-Programmierung aufwenden muss.<br />

Nächste Schritte:<br />

Am Montag werde ich mit der GUI- Programmierung weitermachen. Ausserdem möchte ich<br />

am Montag auch das Feature: Filterkriterien abspeichern umsetzen.<br />

Tabelle 9: Arbeitsjournal vierter Tag<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 21 von 128


7.5 Fünfter Tag: Montag, 06.05.<strong>2013</strong><br />

Tabelle 10:Arbeitsjournal fünfter Tag<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Tätigkeiten: Aufwand (geplant) h Aufwand (effektiv) h<br />

Feature „Filterkriterien abspeichern“<br />

programmieren<br />

8 9<br />

Total: 8 9<br />

Probleme:<br />

Probleme hatte ich heute vor allem mit dem Valuechangelistener der OE. Diesen brauchte<br />

ich, um das Dropdown Resource in Abhängigkeit der gewählten OE abfüllen zu können. Leider<br />

wurde der Listener nicht aufgerufen, und ich fand lange Zeit nicht heraus warum. Nach<br />

langem erfolglosem rumprobieren entschloss ich mich dann, anstelle des ValueChangeListeners<br />

von JSF ein AJAX Event zu nehmen. Dies funktionierte dann auch tadellos gleich<br />

beim ersten Versuch.<br />

Hilfestellungen:<br />

Keine<br />

Reflexion:<br />

Heute wollte ich eigentlich noch die GUI- Ansicht Resultatliste programmieren. Da ich aber<br />

dafür die kalkulierten Daten benötige, entschloss ich mich zuerst einmal das Feature Filterkriterien<br />

abspeichern umzusetzen.<br />

Dazu erstellte ich zuerst einmal auf der Datenbank die Tabelle reporting_criteria.<br />

Danach erstellte ich die dazugehörige Entität, den Persistenzlayer (Repository) und<br />

den Servicelayer.<br />

Anschliessend erstellte ich noch die <strong>Reporting</strong>PersistAction.<br />

Zuerst wollte ich die Validierung der Eingaben in diese Klasse nehmen, ich überlegte mir<br />

dann aber dass auch die Suche, also die Berechnung der Auslastungsdaten eine Validierung<br />

durchführen muss. Deswegen entschloss ich mich eine separate Klasse Validator zu erstellen,<br />

welche die Eingaben validiert und von beiden Actions aus aufgerufen werden kann.<br />

Um die Dropdowns auf der xhtml Seite abfüllen zu können erstellte ich einen Listener, der<br />

die Listen der Dropdown Komponenten abfüllt, bevor die Seite gerendert wird. Ausserdem<br />

musste ich für alle Dropdowns noch einen Konverter schreiben, der die Objekte in Strings<br />

konvertiert und umgekehrt. Des Weiteren musste ich zwei Listener programmieren, die aufgerufen<br />

werden, wenn der Wert in einem Dropdown geändert wird. Diesen Mechanismus<br />

benötigte ich beim Auswählen einer OE und beim Auswählen eines Projektes. Denn abhängig<br />

davon werden dann die Resourcen bzw. Projekttasks abgefüllt.<br />

Da bei uns Cleancode mehr gewichtet wird als javadoc, werde auch ich darauf achten sprechende<br />

namen zu verwenden, anstatt alles geanu zu kommentieren.<br />

Mit dem heutigen Tag bin ich eigentlich recht zufrieden, denn ich konnte heute das Feature<br />

Filterkriterien abspeichern vollständig umsetzen. Ich bin auch froh, dass ich für dieses Feature<br />

acht Stunden eingeplant habe, denn es kamen einige Klassen dazu wie eben z.B. die<br />

Listener und Konverter, die ich so vorher nicht eingeplant hatte.<br />

Nächste Schritte:<br />

Morgen werde ich mit dem Feature Berechnung der Auslastungsdaten anfangen.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 22 von 128


7.6 Sechster Tag: Dienstag, 07.05.<strong>2013</strong><br />

Tabelle 11: Arbeitsjournal sechster Tag<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Tätigkeiten: Aufwand (geplant) h Aufwand (effektiv) h<br />

Feature „Auslastungsdaten abfragen“<br />

programmieren<br />

8 8<br />

Total: 8 8<br />

Probleme:<br />

Das grösste Problem, mit dem ich heute konfrontiert wurde, war die Resultat Tabelle auf<br />

dem GUI-Nr. 04. Da ich für die Darstellung eine Dynamische Tabelle benötige, informierte<br />

ich mich im Internet, wie ich dies mit PrimeFaces am besten umsetzen könnte. Ich kam dann<br />

zum Ergebnis, dass ich in der DataTable dynamische Columns definieren kann.<br />

Leider wurden die dynamischen Columns in der Tabelle nicht angezeigt. Anfangs hatte ich<br />

den Verdacht, dass die Innere Liste, also die Liste von Arbeitstagen auf der Ressource nicht<br />

aufgelöst werden kann. Deswegen versuchte ich mal über einen Index auf die innere Liste<br />

zuzugreifen. Dies funktionierte auch wunderbar. Also konnte ich dies schon mal ausschliessen.<br />

Als nächstes Versuchte ich mal den Columns eine unabhängige Liste anzugeben. Dies<br />

funktionierte auch prima.<br />

Nach längerer Analyse weiterer Möglichkeiten fand ich dann raus, dass die Datatable Variable<br />

resource immer Null in der JSF Phase 6 (Render Resource) zurückgibt. Hier musste es<br />

sich um einen Fehler im Framework handeln. Da Primefaces Opensource ist und ich den<br />

Quellcode zur Verfügung hatte, versuchte ich, durch die Klassen von PrimeFaces zu debuggen,<br />

um herauszufinden, wo das Problem liegt. Aber auch dies lieferte keine klaren Ergebnisse.<br />

Später zog ich dann noch Stefan um Rat hinzu. Aber auch er fand nicht heraus, weshalb<br />

die Columns nicht angezeigt werden. Also entschlossen wir uns, die Aufgabenstellung<br />

anders zu lösen.<br />

Hilfestellungen:<br />

Stefan Heller probierte mir mit diesem Problem zu helfen. Leider fanden wir das Problem<br />

auch gemeinsam nicht heraus. Deswegen entschloss ich mich, die Tabelle nicht, wie gewohnt,<br />

deklarativ auf der XHTML Seite zu erstellen, sondern programmatisch als<br />

JSF/Primefaces-Komponente in Java.<br />

Reflexion:<br />

Heute fing ich an, das Feature „Auslastungsdaten abfragen“, umzusetzen. Als erstes erstellte<br />

ich die Action <strong>Reporting</strong>CalculateAction, in diese ich ein Teil der Berechnungslogik<br />

reinpacken werde. Anschliessend musste ich mir überlegen, wie ich die Berechnung mit Berücksichtigung<br />

der Filterkriterien umsetzen könnte.<br />

Ich entschloss mich, zuerst alle Resourcen, mit der angegebenen OE aus der Datenbank zu<br />

holen, dann über jede einzelne zu iterieren, um die Arbeitsstunden pro Tag zu berechnen.<br />

So entsteht eine Liste von Arbeitstagen, über die dann iteriert werden kann um nur die Arbeitsstunden<br />

zu berücksichtigen, die zu den angegebenen Filterkriterien passen. Als ich diese<br />

Berechnung fertig hatte, fing ich an, die Resultattabelle zu programmieren. Damit hatte<br />

ich aber Probleme, auf die ich im Abschnitt „Probleme“ bereits eingegangen bin.<br />

Insgesamt bin ich mit dem heutigen Tag nicht so zufrieden. Das Problem mit den dynamischen<br />

Columns kostete mich sehr viel Zeit. Ich hoffe, dass ich diese Zeit in den nächsten<br />

Tagen wieder aufholen kann.<br />

Nächste Schritte:<br />

Am Montag werde ich an diesem Feature weiterarbeiten.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 23 von 128


7.7 Siebter Tag: Montag, 13.05.<strong>2013</strong><br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Tätigkeiten: Aufwand (geplant) h Aufwand (effektiv) h<br />

Feature „Auslastungsdaten abfragen“<br />

programmieren.<br />

Datenexport<br />

UML activity Diagramme<br />

Total: 8 9.5<br />

Probleme:<br />

Tabelle 12: Arbeitsjournal siebter Tag<br />

2<br />

4<br />

2<br />

Heute hatte ich Probleme mit dem Sortieren der Daten in der Resultat Tabelle. Ich nutzte<br />

für die Sortierung den in der Datenbanktabelle bereits integrierten Sorter von PrimeFaces.<br />

Dieser sortierte aber die Daten nicht richtig. Denn wenn ich zum Beispiel in einer Spalte eine<br />

5, eine 23 und eine 8 hatte, sah die Sortierungsfolge nach ausgeführter Sortierung (DESC )<br />

folgendermassen aus: 23,5,8.<br />

Ich schaute mir dann nochmals meine dynamische Liste an, in welcher die Werte für die Tabelle<br />

stehen. Dabei wurde mir schnell bewusst warum die Sortierung nicht funktionierte. Da<br />

in der Liste String Werte stehen, sortierte der Sorter logischerweise nach den ASCII Zeichen.<br />

Und da in der ASCII- Tabelle die Zwei vor der Fünf kommt und die Acht nach der Fünf<br />

ist es klar, warum die Sortierung nicht wie gewünscht funktionierte. Ich musste den Sorter<br />

also dazu bringen, nicht nach Strings (ASCII) sondern numerisch zu sortieren – aber nur für<br />

die Arbeitsstunden und nicht für die Resourcebezeichnungen.<br />

Als Lösung des Problems, ersetzte ich den Typ der Liste (String) mit dem allgemeinen Typ<br />

Object und füllte die Resourcebezeichnungen als String und die Arbeitsstunden als Float ein.<br />

Danach funktionierte die Sortierung einwandfrei.<br />

Hilfestellungen:<br />

Keine<br />

Reflexion:<br />

Heute habe ich an dem Feature „Auslastungsdaten abfragen“ weitergearbeitet. Dazu programmierte<br />

ich vorallem an der Berechnungslogik. Da die Daten anhand der angegebenen<br />

Granularität (Tag, Woche, Monat) dargestellt werden sollen, musste ich mir überlegen, wie<br />

ich vorallem die Wochen und die Monatssicht umsetzen kann. Ich entschloss mich dann, die<br />

Berechnung so durchzuführen, indem ich die Granularität prüfte und anschliessend über die<br />

bereits berechneten Tage iterierte und aus den Tagen Wochen oder Monatsobjekte machte.<br />

Diese Berechnungslogik implementierte ich in dem bereits bestehenden ResourcePayloadCalculator<br />

rein.<br />

Als ich mit der Berechnung soweit fertig war, machte ich mich an die Sortierung der Daten<br />

in der Tabelle. Ich nahm hierzu den in der Datentabelle bereits integrierten Sortiermechanismus<br />

von PrimeFaces. Als ich die Sortierung allerdings testete, fiel mir auf, dass sie nicht<br />

richtig funktionierte. (Im Abschnitt Probleme genauer erklärt.) Als ich dieses Problem aber<br />

gelöst hatte, setzte ich die Exportfunktion um. Da ich den Exporter von PrimeFaces nutzte,<br />

entschied ich mich sowohl den CSV, den PDF wie auch den Excel Export umzusetzen, obwohl<br />

eigentlich nur der CSV Export eine MUSS Funktionalität wäre.<br />

Ich entschloss mich heute ausserdem, die Drill-Down Funktionalität (KANN) nicht umzusetzen,<br />

da ich sonst in Verzug mit der Zeit kommen würde. Da die <strong>Dokumentation</strong> ein wesentlichen<br />

Teil der Arbeit ausmacht, werde ich die restliche Zeit hauptsächlich noch darin<br />

investieren.<br />

Nächste Schritte:<br />

Morgen werde ich mich hauptsächlich der <strong>Dokumentation</strong> widmen.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 24 von 128<br />

7<br />

1.5<br />

1


7.8 Achter Tag: Dienstag, 14.05.<strong>2013</strong><br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Tätigkeiten: Aufwand (geplant) h Aufwand (effektiv) h<br />

UML Klassendiagramme<br />

UML Sequenzdiagramme<br />

Architektur beschreiben<br />

Testprotokoll<br />

Activity Diagramme<br />

Total: 8 8.5<br />

Probleme:<br />

Keine<br />

Hilfestellungen:<br />

Tabelle 13: Arbeitsjournal achter Tag<br />

3<br />

2<br />

2<br />

1<br />

0<br />

Stefan Heller stellte mir sein UML Buch zur Verfügung und gab mir Tipps bezüglich des Activity<br />

Diagramms.<br />

Reflexion:<br />

Heute habe ich mich ausschliesslich der Entwicklungsdokumentation gewidmet. Um die<br />

grobe Architektur zu zeigen, erstellte ich ja bereits schon ein Komponentendiagramm und ein<br />

grobes KLassendiagramm. Heute ging es noch darum, die UML Klassendiagramme der<br />

einzelnen Schichten detaillierter zu zeichnen und zu dokumentieren. Da ich viele Klassen<br />

aus der bestehenden Applikation benutze, entschied ich mich, die Klassendiagramme auf die<br />

Schichten aufzuteilen, damit sie noch einigermassen übersichtlich dargestellt werden können.<br />

Das Erstellen der Diagrammer war eigentlich kein grosser Aufwand und ging recht zügig. Da<br />

ich aber auch erreichen wollte, dass die Diagramme übersichtlich und ansprechend aussehen,<br />

habe ich ein mehrfaches der Zeit in die Anordnung der Elemente investiert. Dabei<br />

schaute ich, dass ich so wenige Überschneidungen wie möglich habe und dass die Abstände<br />

zwischen den Elementen wenn möglich gleich sind.<br />

Nachdem ich die Klassendiagramme gezeichnet hatte, erstellte ich noch zwei Sequenzdiagramme.<br />

Dafür überlegte ich mir, welche Szenarien wohl am besten geeignet dafür wären.<br />

Ich entschied mich beim ersten für das Szenario, wenn ein neues Filterkriterienset abgespeichert<br />

wird. Bei diesem Ablauf kann man nämlich schön sehen, wie die drei Schichten<br />

miteinander arbeiten. Als zweites Sequenzdiagramm entschied ich mich für den Ablauf der<br />

Berechnung. Dies machte für mich am meisten Sinn, da die Berechnung einen wesentlichen<br />

Teil meines Moduls ausmacht.<br />

Als ich mit dem Zeichenen der Diagramme fertig war, fügte ich sie in meine <strong>Dokumentation</strong><br />

ein, und verpasste jedem Diagramm noch eine Beschreibung. Am Schluss bereitete ich noch<br />

das Testprotokoll vor.<br />

Mit dem heutigen Tag bin ich sehr zufrieden, denn ich bin ziemlich vorwärts gekommen mit<br />

der <strong>Dokumentation</strong> und schön sieht sie jetzt auch noch aus.<br />

Nächste Schritte:<br />

Morgen werde ich an der <strong>Dokumentation</strong> weiterarbeiten.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 25 von 128<br />

4<br />

2<br />

1<br />

0.5<br />

1


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

7.9 Neunter Tag: Donnerstag, 16.05.<strong>2013</strong> (Halber Tag, Morgens)<br />

Tätigkeiten: Aufwand (geplant) h Aufwand (effektiv) h<br />

GUI in die <strong>Dokumentation</strong><br />

einfügen<br />

Benutzerhandbuch erstellen<br />

Total: 4 4<br />

Probleme:<br />

Keine<br />

Hilfestellungen:<br />

Keine<br />

Reflexion:<br />

Tabelle 14: Arbeitsjournal neunter Tag<br />

1<br />

3<br />

Heute habe ich wieder hauptsächlich an der <strong>Dokumentation</strong> gearbeitet. Ich korrigierte noch<br />

das Klassendiagramm vom Web Layer, da ich dort eine Klasse vergessen hatte. Anschliessend<br />

fügte ich die Bilder von den verschiedenen GUI- Ansichten und deren Beschreibung in<br />

die <strong>Dokumentation</strong> ein.<br />

Später fing ich an, das bestehende Benutzerhandbuch der Applikation <strong>ResMan</strong> mit dem<br />

Modul <strong>ResMan</strong> <strong>Reporting</strong> zu erweitern. Ich entschied mich hierzu, die gleiche Struktur zu<br />

wählen. Mit dem Benutzerhandbuch bin ich heute aber noch nicht ganz fertig geworden.<br />

Der heutige Tag verlief wieder ohne Probleme. Ich bin fast fertig mit der <strong>Dokumentation</strong> der<br />

Realisierungsphase und kann morgen das fertige Modul auf den Testserver deployen, damit<br />

dann David Giger testen kann.<br />

Nächste Schritte:<br />

Morgen werde ich das Benutzerhandbuch fertigstellen, die Tests im QC erfassen und die<br />

Applikation testen.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 26 von 128<br />

1<br />

3


7.11 Zehnter Tag: Freitag, 17.05.<strong>2013</strong><br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Tätigkeiten: Aufwand (geplant) h Aufwand (effektiv) h<br />

Benutzerhandbuch fertigstellen<br />

Testfälle im QC erfassen<br />

Unit Test erstellen<br />

Testen und Resultate festhalten<br />

Total: 8 8<br />

Probleme:<br />

Tabelle 15: Arbeitsjournal zehnter Tag<br />

1<br />

4<br />

1<br />

2<br />

Heute gab es Probleme mit dem Testserver. Und zwar wurden die deployten Änderungen<br />

nicht übernommen. Die Files waren zwar alle korrekt vorhanden, jedoch übernahm der Testserver<br />

keinerlei Änderungen. David Giger probierte auch seine Änderungen an der Applikation<br />

(unabhängig vom Modul <strong>ResMan</strong> <strong>Reporting</strong>) zu deployen, aber auch diese wurden nicht<br />

übernommen. So konnte ich sicher sein, dass es nicht an meinem Modul sondern am Server<br />

liegt.<br />

Da heute Niemand da war, der mir mit diesem Problem helfen konnte, entschied ich mich,<br />

dass die Tests lokal ausgeführt werden sollen. Da auch David Giger (meine Testperson)<br />

am <strong>ResMan</strong> entwickelt, hat auch er die aktuelle Entwicklungsumgebung und konnte somit<br />

die Tests lokal auf seiner Workstation ausführen.<br />

Hilfestellungen:<br />

Keine<br />

Reflexion:<br />

Heute habe ich als erstes das Benutzerhandbuch fertiggestellt und in den Anhang meiner<br />

<strong>Dokumentation</strong> getan. Anschliessend erfasste ich alle Testfälle im Quality Center. Hierzu<br />

nahm ich die Testfälle, welche ich bereits in der Konzeptphase detailliert beschrieben hatte.<br />

Da ich zuvor noch nie mit dem Quality Center gearbeitet hatte, fiel es mir am Anfang etwas<br />

schwer mich dort zurecht zu finden. Nach dem Erfassen des zweiten Tests, ging es dann<br />

aber ohne Probleme.<br />

Als alles soweit zum Testen bereit war, konnte dann David Giger (Lernender 3. Lehrjahr) die<br />

Tests mittels der erfassten Tests im Quality Center durchführen. Eigentlich war geplant,<br />

dass die Tests am Testserver durchgeführt werden. Da es aber mit dem Testserver Probleme<br />

gab führte David Giger sie lokal durch. Ich war bei der Durchführung der Tests dabei, um<br />

allfällige Fragen zu klären und um die Tests sofort zu protokollieren. Die Tests verliefen<br />

ohne Probleme, bis auf einen kleinen Schönheitsfehler beim Excel Export, welchen ich heute<br />

noch beheben konnte.<br />

Als die Anwendertests abgeschlossen waren, erstellte ich noch einen JUnit Test. Dieser<br />

testet die Berechnungslogik, welche ich während der <strong>IPA</strong> implementiert habe. Da ich im<br />

Rahmen meiner Ausbildung noch keine praktischen Erfahrungen mit dem Unit Testing machen<br />

konnte, musste ich mich zuerst einmal im Internet informieren, wie diese Tests erstellt<br />

werden und funktionieren. Als ich dies dann verstanden hatte, erstellte ich den Unit Test und<br />

führte ihn schlussendlich aus. Auch dieser Test verlief fehlerfrei.<br />

Der heutige Tag verlief eigentlich bis auf das Problem mit dem Testserver nach Plan. Da<br />

keine gröberen Bugs beim Testing gefunden wurden, kann ich am Dienstag meine <strong>Dokumentation</strong><br />

frühzeitig abschliessen, hochladen, drucken und binden.<br />

Nächste Schritte:<br />

Am Dienstag werde ich die <strong>Dokumentation</strong> abschliessen .<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 27 von 128<br />

1<br />

3<br />

2<br />

2


7.12 Elfter Tag: Dienstag, 21.05.<strong>2013</strong><br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Tätigkeiten: Aufwand (geplant) h Aufwand (effektiv) h<br />

Ist soll Vergleich<br />

Persönliches Fazit<br />

Management Summary<br />

SourceCode in Anhang<br />

Drucken & binden<br />

Total: 6 6<br />

Probleme:<br />

Keine<br />

Hilfestellungen:<br />

Keine<br />

Reflexion:<br />

Tabelle 16: Arbeitsjournal elfter Tag<br />

7.13 Arbeitszeit total<br />

Tabelle 17: Arbeitsjournal Arbeitszeit Total<br />

1<br />

1<br />

1<br />

2<br />

1<br />

Heute war der letzte Tag meiner <strong>IPA</strong>. Da während dem Testing keine gröberen Bugs aufgedeckt<br />

wurden, konnte ich heute auf das Bug Fixen verzichten und frühzeitig mit dem Abschluss<br />

der <strong>Dokumentation</strong> beginnen. Hierzu erstellte ich noch den Soll- Ist Vergleich und<br />

anschliessend noch mein persönliches Fazit. Zum Schluss fing ich dann noch an das Management<br />

Summary zu erstellen.<br />

Als ich mit allem fertig war, fügte ich noch den gesamten Sourcecode in meine <strong>Dokumentation</strong><br />

ein. Dies war wohl die mühseligste Arbeit von heute, denn ich hatte einige Probleme mit<br />

der Formatierung im Dokument.<br />

Ganz zum Schluss kontrollierte ich dann nochmals das gesamte Dokument. Jetzt werde ich<br />

das Dokument noch ausdrucken und binden.<br />

Der heutige Tag verlief ganz ohne Stress. Ich konnte heute noch alle notwendigen Tätigkeiten<br />

ausführen und die <strong>Dokumentation</strong> termingerecht abschliessen.<br />

Nächste Schritte:<br />

Präsentation und Websummary<br />

Totaler Zeitaufwand Person Aufwand<br />

geplant<br />

(Std)<br />

Reflexion<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 28 von 128<br />

1<br />

1<br />

1<br />

2<br />

1<br />

Aufwand<br />

effektiv<br />

(Std)<br />

Elisa Schnabel 78.5 81<br />

Da ich meine Tätigkeiten und die dazugehörigen Zeiten im Zeitplan gut geplant hatte, konnte<br />

ich meine Arbeit innerhalb von 81 Stunden erstellen. Die Abweichung von 2.5 Stunden zu den<br />

geplanten 78.5 konnte ich fast mit der Reserve verrechnen, die ich ebenfalls eingeplant hatte.


8. Schlussbericht<br />

8.1 Vergleich Ist/Soll<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Alle MUSS- Kriterien aus dem Pflichtenheft konnten in der vorgegebenen Zeit vollständig<br />

implementiert werden. Auch zwei von drei KANN- Kriterien konnten implementiert werden.<br />

Dies betrifft den PDF und den EXCEL Export. Das dritte KANN- Kriterium, nämlich die Drill-<br />

Down / Drill-Up Navigation wurde aus Zeitgründen nicht umgesetzt.<br />

Obwohl alle MUSS – und gewisse KANN- Kriterien umgesetzt wurden, gibt es bei dem Modul<br />

<strong>ResMan</strong> <strong>Reporting</strong> noch Verbesserungspotenzial. Dies betrifft vorallem die Darstellung<br />

der Auslastungsdaten in der Tabelle.<br />

8.2 Persönliches Fazit<br />

Insgesamt bin ich mit dem Resultat in der vorgegebenen Arbeitszeit zufrieden. Ich konnte<br />

das System vollständig entwickeln und bin rechtzeitig mit der <strong>Dokumentation</strong> fertig geworden.<br />

Da ich mit dem Konzept schon frühzeitig fertig wurde, konnte ich die dort gewonnene Zeit für<br />

das Programmieren nutzen. Dadurch konnte ich auch den Mehraufwand, welcher mir beim<br />

Programmieren des Features „Auslastungsdaten abfragen“ durch das Problem mit den dynamischen<br />

Collumns entstanden ist, fast ausgleichen. Obwohl mich dieses Problem viel Zeit<br />

und Nerven gekostet hat, hat es mir auch etwas sehr positives gebracht. Ich habe nämlich<br />

gelernt, wie man die JSF Komponenten auch programmatisch mit Java implementieren<br />

kann. Dies wird mir sicher auch in Zukunft bei gewissen Problemen sehr nützlich sein.<br />

Etwas sehr Wichtiges, was ich auch im Rahmen der <strong>IPA</strong> kennengelernt habe, sind die Junit<br />

Tests. Während meiner gesamten Ausbildung konnte ich mich mit dieser Thematik nämlich<br />

nie richtig auseinandersetzen. Erst im Rahmen meiner <strong>IPA</strong> konnte ich einen ersten richtigen<br />

Junit Test erstellen.<br />

Im Bereich der UML- Modellierung war vorallem das Activity Diagramm ein neuer Lerninhalt<br />

für mich. Dieses habe ich nämlich weder in der Schule noch im Lehrbetrieb jemals genutzt.<br />

Für die Formatierung von Diagrammen werde ich künftig mehr Zeit einplanen.<br />

Sehr grosse Probleme hatte ich während der gesamten <strong>IPA</strong> glücklicherweise kaum. Die einzigen<br />

Probleme tauchten während des Programmierens auf. Schade fand ich, dass die Anwendertests<br />

nicht wie geplant am Testserver durchgeführt werden konnten.<br />

Um das persönliche Fazit auf den Punkt zu bringen: Ich hatte einiges an Respekt und auch<br />

etwas Angst vor der <strong>IPA</strong>, da es sich um eine Fallnote handelt. Als ich jedoch damit begonnen<br />

habe und mich richtig in die Aufgabenstellung hineinlebte, hat es mir immer mehr Spass gemacht.<br />

Und das ist vermutlich auch ein Hauptgrund, wieso es mir gelang, die gewünschten<br />

Punkte abzudecken. Durch Freude an der Arbeit lässt es sich einfacher arbeiten. Das ist<br />

auch etwas, was ich in Zukunft bestimmt übernehmen werde. Nicht mehr Angst haben vor<br />

einer Aufgabe, sondern strukturiert mit Hilfe einer guten Planung an die Aufgabe herangehen,<br />

aber nicht übermütig werden, da ich jetzt auch wieder gesehen habe, wie aus scheinbar<br />

einfachen Aufgaben schwierige werden können.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 29 von 128


9. Unterschriften<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Die lernende Person bestätigt mit ihrer Unterschrift diese <strong>IPA</strong> aus Eigenleistung erbracht und<br />

nach den Vorgaben der Prüfungskommission Informatik Kanton Bern erstellt zu haben. Die<br />

Angaben im Arbeitsjournal entsprechen dem geleisteten Arbeitsaufwand.<br />

Datum Name / OE Unterschrift<br />

Tabelle 18: Unterschriften<br />

Lernende<br />

Fachvorgesetzter<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 30 von 128


Teil 2: Projektdokumentation<br />

<strong>IPA</strong> Projektname: <strong>ResMan</strong> <strong>Reporting</strong><br />

Autor: Schnabel Elisa<br />

Abbildung 3:HERMES Phasenmodel für beide Projekttypen<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Da ich als Projektmethode Hermes verwende, wähle ich für dieses Projekt den Projekttyp<br />

„Systementwicklung“, da ich das Teilsystem <strong>Reporting</strong> neu für eine bestehende Applikation<br />

implementiere und nicht editiere bzw. erweitere.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 31 von 128


10. Voranalyse<br />

10.1 Analyse Ist Zustand / Soll-Zustand<br />

10.1.1 Ist- Zustand<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Das <strong>ResMan</strong> Projekt soll die Auslastung der Mitarbeitenden in den Abteilungen des Ressort<br />

TCSB vereinfachen. Die durch das Tool gewonnene Übersicht der einzelnen Ressourcen<br />

soll helfen, die Planung anstehender Projekte effizienter durchführen zu können. Die Grundfunktionalitäten<br />

wurden bereits entwickelt. Es ist also mit dem jetzigen Stand der Applikation<br />

bereits möglich, die Auslastung einzelner Mitarbeiter zu überwachen und zu planen. Die aktuelle<br />

Version erlaubt aber nur die Sicht auf eine Ressource gleichzeitig.<br />

Da die wesentlichen Module der <strong>ResMan</strong>- Applikation ja schon von uns entwickelt wurden,<br />

steht mir die fertig konfigurierte Entwicklungsumgebung mit all den von uns verwendeten<br />

Frameworks wie JSF / PrimeFaces, Spring, JPA und das Framework von Stefan Heller, welches<br />

die CRUD Funktionalitäten auf dem Web- Service- und Domain-Layer zur Verfügung<br />

stellt, für die <strong>IPA</strong> zur Verfügung. Die komplette Datenbank mit den notwendigen Testdaten,<br />

welche die <strong>ResMan</strong> Applikation benötigt, steht mir ebenfalls zur Verfügung.<br />

10.1.2 Soll- Zustand<br />

Im Rahmen des Moduls <strong>ResMan</strong>-<strong>Reporting</strong> soll u.a. die Organisationseinheit-weite Sicht<br />

über die Auslastung der Mitarbeiter möglich gemacht werden.<br />

Das Modul soll mit der im <strong>ResMan</strong> bereits verwendeten Programmiersprache Java und den<br />

Frameworks JSF, PrimeFaces, Spring und JPA umgesetzt werden. Ausserdem soll die<br />

bestehende Schichtentrennung der Applikation, die mit einer drei Schichten Architektur<br />

erreicht wurde, auch im Unterprojekt <strong>ResMan</strong>- <strong>Reporting</strong> strikt eingehalten werden.<br />

Mit Hilfe einer Suchmaske soll es den Führungspersonen möglich gemacht werden, die<br />

Auslastungsdaten einzelner Mitarbeiter oder auch aus einer ganzen Organisationseinheit<br />

abfragen zu können oder Daten nach bestimmten Kriterien zusammenzustellen.<br />

Dazu sollen auf der Suchmaske bestimmte Filterkriterien eingegeben werden können, auf<br />

Grund derer dann die Auslastungsdaten zusammengestellt werden. Die Kriterien sind die<br />

Organisationseinheit, die Resource, die Zeitspanne (von Datum / bis Datum), das Projekt,<br />

die Projektaufgabe, Aufgabe, die Granularität (Wie sollen die Ergebnisse präsentiert werden,<br />

z.B. Tag, Woche, Monat. In dem Sinne kein eigentliches Filterkriterium) und der<br />

Auslastungswert in Stunden (von / bis).<br />

Die OE und die Resource sollen mit Hilfe eines Dropdowns ausgewählt werden können. Die<br />

Zeitspanne soll mit Hilfe eines „Datepickers“ oder mit Hilfe von Radiobuttons gewählt werden<br />

können. Das Projekt und die Projektaufgabe sollen mit Hilfe eines Dropdowns und die<br />

Aufgabe mittels Autocompleter ausgewählt werden können. Der Auslastungswert soll mittels<br />

Eingabefeldern gesetzt werden können.<br />

Die somit entstandene Liste der Auslastungsdaten soll anschliessend in einer Tabelle<br />

dargestellt werden. Die Tabelle soll unter anderem eine Sortierung der abgefragten Daten<br />

gewährleisten können. Ausserdem soll mittels Drill-Down Funktion die Möglichkeit gegeben<br />

werden, die Daten detaillierter anschauen zu können.<br />

Mit Hilfe von “Export Buttons“ unterhalb der Tabelle soll ausserdem die Möglichkeit gegeben<br />

werden, die Daten in der Tabelle in ein CSV File, XLSX und PDF zu exportieren.<br />

Die eingegebenen Filterkriterien, nach denen die Daten zusammengestellt werden, sollen<br />

auf Wunsch auch abgespeichert werden können (Schnellliste), so dass sie wieder abrufbar<br />

sind. Das bringt den Vorteil, dass häufig verwendete Filterkriterien nicht immer wieder neu<br />

eingegeben werden müssen.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 32 von 128


10.2 Pflichtenheft / Systemanforderungen<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

In den nachfolgenden Tabellen sind die einzelnen Systemanforderungen (MUSS und KANN)<br />

des Moduls <strong>ResMan</strong>-<strong>Reporting</strong> aufgelistet.<br />

10.2.1 Muss- Kriterien<br />

Kriterium Bezeichnung Beschreibung<br />

1.0 Abfrage der Auslastungsdaten<br />

einzelner Mitarbeiter<br />

oder aus einer ganzen OE.<br />

Eine Führungsperson muss mit Hilfe einer<br />

Suchmaske Filterkriterien eingeben können. Anhand<br />

derer müssen dann die Auslastungsdaten<br />

zusammengestellt werden und in Form einer<br />

Tabelle angezeigt werden.<br />

2.0 Auslastungsdaten sortieren. Eine Führungsperson muss die Auslastungsdaten<br />

in der Tabelle sortieren können.<br />

3.0 Auslastungsdaten in CSV<br />

Datei exportieren.<br />

Eine Führungsperson muss auf Wunsch die Daten<br />

aus der Tabelle in eine CSV- Datei exportieren<br />

können.<br />

4.0 Filterkriterien abspeichern Eine Führungsperson muss die eingegebenen<br />

Filterkriterien abspeichern können, so dass sie<br />

jederzeit wieder abrufbar sind.<br />

Tabelle 19: Pflichtenheft Muss Anforderungen<br />

10.2.2 Kann- Kriterien<br />

Kriterium Bezeichnung Beschreibung<br />

5.0 Auslastungsdaten in PDF<br />

Datei exportieren.<br />

6.0 Auslastungsdaten in Excel<br />

Datei exportieren.<br />

7.0 Drill-Down / Drill-Up<br />

Navigation<br />

Tabelle 20: Pflichtenheft Kann Anforderungen<br />

Eine Führungsperson kann auf Wunsch die Daten<br />

aus der Tabelle in ein PDF exportieren.<br />

Eine Führungsperson kann auf Wunsch die Daten<br />

aus der Tabelle in ein Excel exportieren.<br />

Eine Führungsperson kann mittels Drill-Down/<br />

Drill-Up Navigation die detaillierte Ansicht der<br />

Daten anschauen.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 33 von 128


10.3 Varianten<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Da die <strong>ResMan</strong> Applikation bereits mit der Programmiersprache Java und den Frameworks<br />

JSF / PrimeFaces, Spring und JPA entwickelt wurde, sind diese auch für das Modul <strong>ResMan</strong><br />

<strong>Reporting</strong> einzusetzen. Daher gibt es von der Technologie her grundsätzlich keinen Variantenentscheid.<br />

Jedoch gibt es beim Datenexport verschiedene Varianten, die zu prüfen sind.<br />

10.3.1 Export in CSV Datei<br />

10.3.1.1 Variante 1- Exporter von PrimeFaces nutzen<br />

PrimeFaces bietet eine Komponente DataExporter an, die es ermöglicht, die Daten aus der<br />

Datentabelle in eine CSV Datei zu exportieren.<br />

Mit dieser Variante ist der Entwicklungs-und Lernaufwand sehr gering. Ausserdem ist diese<br />

Komponente in einem von uns verwendeten Framework bereits vorhanden.<br />

10.3.1.2 Variante 2- Java Bibliothek CSV nutzen<br />

Es gibt eine Java CSV Open-Source-Java-Bibliothek welche Klassen zum Lesen und<br />

Schreiben von CSV und einfache Textdateien anbietet. Die Bibliothek unterstützt alle Arten<br />

von CSV.<br />

Der Entwicklungs- und Lernaufwand und somit auch der Aufwand für die Wartung, sind bei<br />

dieser Variante deutlich höher als bei der Variante 1. Ein Minuspunkt ist bei dieser Variante<br />

auch, dass ich zusätzliche Libraries einbinden müsste.<br />

10.3.2 Export in PDF Datei<br />

10.3.2.1 Variante 1- Exporter von PrimeFaces nutzen<br />

PrimeFaces bietet eine Komponente DataExporter an, die es ermöglicht, die Daten aus der<br />

Datentabelle in eine PDF Datei zu exportieren.<br />

Mit dieser Variante ist der Entwicklungs-und Lernaufwand sehr gering. Ausserdem ist diese<br />

Komponente in einem von uns verwendeten Framework bereits vorhanden.<br />

10.3.2.2 Variante 2- Java und iText Bibliothek nutzen<br />

iText ist eine frei verfügbare Programmierschnittstelle zur dynamischen Erzeugung und Bearbeitung<br />

von PDF-Dateien mittels der Programmiersprache Java.<br />

Auch bei dieser Variante ist der Entwicklungs- und Lernaufwand dementsprechend auch der<br />

Aufwand für die Wartung deutlich grösser als bei der Variante 1. Ein weiterer Nachteil dieser<br />

Variante ist auch, dass sie nicht in einem von uns verwendeten Framework vorhanden ist.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 34 von 128


10.3.3 Export in Excel Datei<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

10.3.3.1 Variante 1- Exporter von PrimeFaces nutzen<br />

PrimeFaces bietet eine Komponente DataExporter an, die es ermöglicht, die Daten aus der<br />

Datentabelle in eine Excel Datei zu exportieren.<br />

Mit dieser Variante ist der Entwicklungs-und Lernaufwand wie auch beim PDF und CSV Export<br />

sehr gering. Ausserdem ist diese Komponente in einem von uns verwendeten Framework<br />

bereits vorhanden.<br />

10.3.3.2 Variante 2- Java Bibliothek nutzen<br />

POI ist Open-Source-Software, die Java-APIs zum Lesen und Schreiben von Dateien im Dateiformat<br />

von Microsoft Office wie z. B. Word und Excel bereitstellt.<br />

Diese Variante wäre deutlich aufwändiger als die Variante 1, da ich mir dazu erst das nötige<br />

Wissen aneignen müsste und später dann auch die Person, welche die Applikation wartet.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 35 von 128


10.4 Variantenentscheid<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Für die Variantenentscheide wurde eine Nutzwertanalyse erstellt. Die nachfolgende Tabelle zeigt diese. Das V steht für die jeweilige Variante und das<br />

W steht für den errechneten Wert. Jedes erstellte Kriterium erhält eine Gewichtung. Den Varianten werden pro Kriterium Punkte vergeben<br />

(min 0, max 3). Die erreichten Punkte werden mit der Gewichtung multipliziert. So erhält man den Endwert. Die Variante mit den meisten<br />

Punkten setzt sich durch.<br />

Kriterium Gewichtung<br />

(1-5)<br />

Tabelle 21:Nutzwertanalyse<br />

Wie man der Nutzwertanalyse entnehmen kann, ist die Entscheidung klar: Ich entscheide mich bei dem CSV, PDF sowie bei dem Excel Export für die<br />

Variante 1. Für die Export Funktion werde ich also den PrimeFaces Exporter einsetzen<br />

.<br />

CSV PDF Excel<br />

V 1 W1 V2 W2 V1 W1 V2 W1 V1 W1 V2 W2<br />

Abdeckung Anforderungen 5 3 15 3 15 3 15 3 15 3 15 3 15<br />

Kosten 5 3 15 3 15 3 15 3 15 3 15 3 15<br />

Entwicklungsaufwand 3 3 9 1 3 3 9 1 3 3 9 1 3<br />

Bereits in einem von uns eingesetzten<br />

Framework vorhanden<br />

(Wartbarkeit)<br />

Lernaufwand (Wissensbeschaffung,<br />

Wartbarkeit)<br />

4 3 12 0 0 3 12 0 0 3 12 0 0<br />

2 3 6 1 2 3 6 2 4 3 6 1 2<br />

Total: 57 35 57 37 57 35<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 36 von 128


10.5 Informationssicherheit und Datenschutz<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Die Daten, mit denen in der <strong>ResMan</strong> Applikation gearbeitet wird, sind besonders schützenswert.<br />

Es handelt sich hierbei um persönliche Daten wie Namen und Passwörter. Durch das<br />

JPA Framework und durch das Validieren der Eingaben werden die Daten vor SQL- Injektion<br />

geschützt. Ausserdem sind die Daten nur für Personen mit bestimmten Berechtigungen ersichtlich.<br />

Dafür sorgt die Benutzeridentifikation der <strong>ResMan</strong> Anwendung.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 37 von 128


11. Konzept<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Das Konzept beschreibt die Anwendungsfälle, die zusätzlich als Anwendungsfalldiagramm<br />

dargestellt werden. Die GUI- Skizzen zeigen einen ersten Entwurf des Layouts. Das Testkonzept<br />

beschreibt, wie wo was getestet wird. Das Klassendiagramm und Komponentendiagramm<br />

werden in die Realisierungsphase verschoben, da dort die fertige Architektur gezeigt<br />

wird.<br />

11.1 Anwendungsfälle<br />

In diesem Kapitel befinden sich das Anwendungsfalldiagramm, dessen Beschreibungen und<br />

die einzelnen Aktivitätsdiagramme.<br />

11.1.2 Anwendungsfall-Diagramm<br />

Das nachfolgende Anwendungsfall Diagramm zeigt alle Anwendungsfälle des Moduls Resman<br />

<strong>Reporting</strong>. Insgesamt gibt es sieben verschiedene Anwendungsfälle. Es gibt jeweils nur<br />

einen Aktor und dies sind die Gruppenleiter des Ressort TCSB.<br />

Abbildung 4:UseCase Diagramm<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 38 von 128


11.1.3 Beschreibung der Anwendungsfälle<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Nachfolgend werden alle Anwendungsfälle, die bereits im Anwendungsfalldiagramm aufgezeigt<br />

wurden, detailliert beschrieben.<br />

11.1.3.1 Anwendungsfall Filterkriterien abspeichern<br />

Nr.: 01<br />

Name: Filterkriterien abspeichern<br />

Aktoren: System (S), Gruppenleiter (A)<br />

Kurzbeschreibung: Die eingegebenen Filterkriterien werden in der Datenbank abgespeichert.<br />

Auslösendes Ereignis: A: ruft die Seite reporting.xhtml auf. (GUI-Nr. 02)<br />

Eingehende Daten: OE, Resource, Datum von, Datum bis, Projekt, Projektaufgabe,<br />

Aufgabe, Auslastungswert von bis, Granularität.<br />

Ausgehende Daten: GUI-Nr. 03<br />

Ergebnis: Die Kriterien befinden sich in der Datenbank.<br />

Vorbedingungen: Die Tabelle reporting_criteria besteht bereits<br />

Normalablauf (NA): 1. A: ruft die Seite „reporting.xhtml“ auf.(GUI-Nr 01)<br />

2. S: initialisiert die Daten<br />

3. S: baut den Komponentenbaum auf<br />

4. A: gibt die erforderlichen Filterkriterien ein.<br />

5. A: drückt auf die Schaltfläche [Speichern].<br />

6. S: validiert die Eingaben.<br />

7. S: legt die Filterkriterien in der Datenbank ab.<br />

Alternativablauf (AA): Validierungsfehler<br />

NA 1-6<br />

7. S: gibt die Validierungsfehler als Meldung aus.<br />

Validierungsregeln: 1. Die Organisationseinheit ist ein Pflichtfeld.<br />

2. Datum von, Datum bis sind Pflichtfelder.<br />

3. Angabe einer Granularität ist Pflicht.<br />

4. Das Datum von muss kleiner gleich dem Datum bis sein.<br />

5. Der Auslastungswert von muss kleiner gleich dem Auslastungswert<br />

bis sein.<br />

Weitere Regeln: 1. Resource Dropdown wird erst aktiviert, wenn eine Organisationseinheit<br />

ausgewählt wurde.<br />

2. Projektaufgabe Dropdown wird erst aktiviert, wenn ein<br />

Projekt ausgewählt wurde.<br />

3. Wenn die Radiobuttons angewählt werden(z.B. aktuelle<br />

Woche), werden automatisch die Datumsfelder mit dem<br />

entsprechenden Datum abgefüllt.<br />

Tabelle 22: UseCase Filterkriterien abspeichern<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 39 von 128


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

11.1.3.1.1 Aktivitätsdiagramm UseCase 01<br />

Das nachfolgende Aktivitätsdiagramm zeigt den Ablauf des Anwendungsfalls 01 (Filterkriterien<br />

abspeichern).<br />

Abbildung 5: Activity Diagramm UseCase 01<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 40 von 128


11.1.3.2 Anwendungsfall Auslastungsdaten abfragen<br />

Tabelle 23: UseCase Auslastungsdaten abfragen<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Nr.: 02<br />

Name: Auslastungsdaten abfragen<br />

Aktoren: System (S), Gruppenleiter (A)<br />

Kurzbeschreibung: Die Auslastungsdaten der Mitarbeiter werden auf Grund der Filterkriterien<br />

zusammengestellt.<br />

Auslösendes Ereignis: A: ruft die Seite reporting.xhtml auf. (GUI-Nr. 02)<br />

Eingehende Daten: OE, Resource, Datum von, Datum bis, Projekt, Projektaufgabe,<br />

Aufgabe, Auslastungswert, Granularität.<br />

Ausgehende Daten: Auslastungsdaten der Mitarbeiter (GUI-Nr. 04)<br />

Ergebnis: Die Mitarbeiter werden in der Resultat Tabelle angezeigt<br />

Vorbedingungen: Es existieren bereits Daten in der DB.<br />

Normalablauf (NA): 1. A: ruft die Seite „reporting.xhtml“ auf.<br />

2. S: initialisiert die Daten<br />

3. S: baut den Komponentenbaum auf<br />

4. A: gibt die erforderlichen Filterkriterien ein.<br />

5. A: betätigt die Schaltfläche [Suchen]<br />

6. S: validiert die Eingaben<br />

7. S: liest alle Mitarbeiter mit der entsprechenden OU aus der DB.<br />

8. S: berechnet die Arbeitstage mit den dazugehörigen Arbeits<br />

Stunden aufgrund der Zeitspanne und der Filterkriterien.<br />

9. Je nach Granularität werden die Arbeitsstunden auf den Tagen<br />

pro Woche oder pro Monat zusammengerechnet.<br />

10. S: gibt die berechneten Daten in der Resultat Tabelle aus.<br />

Alternativablauf (AA): Validierungsfehler<br />

NA 1-6<br />

7. S: gibt die Validierungsfehler als Meldung aus.<br />

Validierungsregeln: 1. Die Organisationseinheit ist ein Pflichtfeld<br />

2. Datum von, Datum bis sind Pflichtfelder<br />

3. Das Datum von muss kleiner gleich dem Datum bis sein<br />

4. Angabe einer Granularität ist Pflicht.<br />

5. Der Auslastungswert von muss kleiner gleich dem Auslastungswert<br />

bis sein.<br />

Weitere Regeln: 1. Resource Dropdown wird erst aktiviert, wenn eine Organisationseinheit<br />

ausgewählt wurde.<br />

2. Projektaufgabe Dropdown wird erst aktiviert, wenn ein<br />

Projekt ausgewählt wurde.<br />

3. Wenn die Radiobuttons angewählt werden(z.B. aktuelle Woche),<br />

werden automatisch die Datumsfelder mit dem entsprechenden<br />

Datum abgefüllt.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 41 von 128


11.1.3.3 Anwendungsfall Daten sortieren<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Nr.: 03<br />

Name: Daten sortieren<br />

Aktoren: System (S), Gruppenleiter (A)<br />

Kurzbeschreibung: Die berechneten Daten in der Resultat Tabelle werden sortiert.<br />

Auslösendes Ereignis: A: betätigt das „Sortieren“ Icon in der zu sortierenden Spalte.<br />

Eingehende Daten: Keine<br />

Ergebnis: Die Daten in der Resultat Tabelle liegen nach dem entsprechenden<br />

Wert sortiert vor.<br />

Vorbedingungen: UseCase 02 Auslastungsdaten abfragen.<br />

(Es wurden Mitarbeiter gefunden)<br />

Normalablauf (NA): 1. A: drückt auf das „Sortieren“ Icon in der zu sortierenden<br />

Spalte.<br />

2. S: sortiert die Daten in der gewünschten Spalte.<br />

Alternativablauf (AA): -<br />

Validierungsregeln: -<br />

Weitere Regeln Bei der Sortierung der Daten müssen die alphanummerischen sowie<br />

die nummerischen Werte berücksichtigt werden.<br />

Tabelle 24: UseCase Daten sortieren<br />

11.1.3.4 Anwendungsfall Datenexport CSV<br />

Nr.: 04<br />

Name: Datenexport CSV<br />

Aktoren: System (S), Gruppenleiter (A)<br />

Kurzbeschreibung: Die Daten in der Resultat Tabelle werden in eine CSV Datei exportiert.<br />

Auslösendes Ereignis: A: betätigt das „CSV Export“ Icon.<br />

Eingehende Daten: Auslastungsdaten in der Resultat Tabelle<br />

Ausgehende Daten: CSV Datei<br />

Ergebnis: Die Daten befinden sich in einer CSV Datei.<br />

Vorbedingungen: UseCase 02 Auslastungsdaten abfragen<br />

(Es wurden Mitarbeiter gefunden).<br />

Normalablauf (NA): 1. A: drückt auf das „CSV Export“ Icon unterhalb der Resultat<br />

Tabelle.<br />

2. S: exportiert die Daten in eine CSV Datei.<br />

3. S: lädt die Datei herunter und speichert sie im Download<br />

Ordner ab.<br />

Alternativablauf (AA): -<br />

Validierungsregeln: -<br />

Tabelle 25: UseCase Datenexport CSV<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 42 von 128


11.1.3.5 Anwendungsfall Datenexport PDF<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Nr.: 05<br />

Name: Datenexport PDF<br />

Aktoren: System (S), Gruppenleiter (A)<br />

Kurzbeschreibung: Die Daten in der Resultat Tabelle werden in eine PDF Datei exportiert.<br />

Auslösendes Ereignis: A: betätigt das „PDF Export“ Icon.<br />

Eingehende Daten: Auslastungsdaten in der Resultat Tabelle<br />

Ausgehende Daten: PDF Datei<br />

Ergebnis: Die Daten befinden sich in einer PDF Datei.<br />

Vorbedingungen: UseCase 02 Auslastungsdaten abfragen<br />

(Es wurden Mitarbeiter gefunden).<br />

Normalablauf (NA): 1. A: drückt auf das „PDF Export“ Icon unterhalb der Resultat<br />

Tabelle.<br />

2. S: exportiert die Daten in eine PDF Datei.<br />

3. S: lädt die Datei herunter und speichert sie im Download<br />

Ordner ab.<br />

Alternativablauf (AA): -<br />

Validierungsregeln: -<br />

Tabelle 26: UseCase Datenexport PDF<br />

11.1.3.6 Anwendungsfall Datenexport Excel<br />

Nr.: 06<br />

Name: Datenexport Excel<br />

Aktoren: System (S), Gruppenleiter (A)<br />

Kurzbeschreibung: Die Daten in der Resultat Tabelle werden in eine Excel Datei exportiert.<br />

Auslösendes Ereignis: A: betätigt das „Excel Export“ Icon.<br />

Eingehende Daten: Auslastungsdaten in der Resultat Tabelle<br />

Ausgehende Daten: Excel Datei<br />

Ergebnis: Die Daten befinden sich in einer Excel Tabelle.<br />

Vorbedingungen: UseCase 02 Auslastungsdaten abfragen<br />

(Es wurden Mitarbeiter gefunden).<br />

Ablauf: 1. A: drückt auf das „Excel Export“ Icon unterhalb der Resultat<br />

Tabelle.<br />

2. S: exportiert die Daten in eine Excel Datei.<br />

3. S: lädt die Datei herunter, speichert sie im Download<br />

Ordner ab.<br />

Alternativablauf (NA): -<br />

Validierungsregeln: -<br />

Weitere Reglen Excel unterstütz nur 255 Spalten. Deshalb wird die Excel Exportfunktion<br />

deaktiviert, falls die Resultattabelle mehr als 255 Spalten enthält.<br />

Tabelle 27: UseCase Datenexport Excel<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 43 von 128


11.1.3.7 Anwendungsfall Drill Down / Drill Up Navigation<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Nr.: 07<br />

Name: Drill Down / Drill Up Navigation<br />

Aktoren: System (S), Gruppenleiter (A)<br />

Kurzbeschreibung: Wenn der Aktor auf eine Spalte in der Tabelle klickt, wie z.B. in den<br />

Monat Juli, soll die Tabelle aktualisert werden und nur noch den Monat<br />

Juli detailliert anzeigen.<br />

Auslösendes Ereignis: Klick auf den Header der gewünschten Spalte in der Tabelle.<br />

Eingehende Daten: -<br />

Ergebnis: Es erscheint die detaillierte Ansicht auf die Daten in der Tabelle.<br />

Vorbedingungen: UseCase 02 Auslastungsdaten abfragen<br />

(Es wurden Mitarbeiter gefunden).<br />

Ablauf: 1. A: klickt auf den Header der gewünschten Spalte in der Tabelle.<br />

2. S: Zeigt die detaillierte Sicht auf die Daten in der Tabelle.<br />

Alternativablauf (NA): -<br />

Validierungsregeln: -<br />

Tabelle 28: UseCase Drill Down / Drill Up Navigation<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 44 von 128


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

11.1.3.7.1 Aktivitätsdiagramm UseCases 02- 07<br />

Das nachfolgende Aktivitätsdiagramm beschreibt die Abläufe der Anwendungsfälle 2-7. Die<br />

Anwendungsfälle wurden aufgrund der Nachvollziehbarkeit in dem gleichen Aktivitätsdiagramm<br />

zusammengefasst.<br />

Abbildung 6: Activity Diagramm UseCase 02-07<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 45 von 128


11.2 GUI Entwürfe<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Im Modul <strong>ResMan</strong> <strong>Reporting</strong> gibt es insgesamt vier verschiedene grafische Benutzeroberflächen.<br />

1. die Suchmaske / Erfassungsmaske,<br />

2. die Detailansicht der abgespeicherten Suchparameter,<br />

3. die Tabelle mit den gespeicherten Suchparametern (Schnellliste) und<br />

4. die Tabelle mit den Auslastungsdaten.<br />

11.2.1 Schnellliste Filterkriterien GUI-Nr. 01<br />

Die nachfolgende GUI- Skizze zeigt die Schnellliste des Moduls <strong>ResMan</strong> <strong>Reporting</strong>. In der<br />

Tabelle sind alle definierten Filterkriteriensets ersichtlich, welche vom aktiven User abgespeichert<br />

wurden. Mit einem Klick auf das Bearbeiten- Icon in der letzten Spalte erscheint die<br />

Suchmaske GUI-Nr. 02, in welcher dann die Kriterien bereits abgefüllt wurden. Es besteht<br />

ausserdem auch die Möglichkeit, die Kriterien zu löschen.<br />

Abbildung 7: GUI-Nr. 01 Schnellliste<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 46 von 128


11.2.2 Suchmaske / Erfassungsmaske GUI- Nr. 02<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Die nachfolgende GUI- Skizze zeigt die Suchmaske bzw. Erfassungsmaske des Moduls<br />

<strong>ResMan</strong> <strong>Reporting</strong>. Auf dieser Maske können die Gruppenleiter ihre gewünschten Filterkriterien<br />

eingeben, eine Suche starten und / oder die Kriterien abspeichern.<br />

Abbildung 8: GUI-Nr. 02 Suchmaske/ Erfassungsmaske für die Schnellliste<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 47 von 128


11.2.3 Detailansicht Filterkriterien GUI-Nr. 03<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Die nachfolgende GUI-Skizze zeigt die detaillierte Sicht auf die Filterkriterien. Diese Seite<br />

erscheint nachdem die Kriterien abgespeichert wurden. Betätigt man die Schaltfläche [Zurück<br />

zur Suche], gelangt man wieder auf das Suchformular (GUI-Nr. 02).<br />

Abbildung 9:GUI-Nr. 03 Detailansicht<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 48 von 128


11.2.4 Trefferliste (Falls keine explizite Resource gewählt wurde) GUI-Nr. 04<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Die nachfolgende GUI-Skizze zeigt die Trefferliste des Moduls <strong>ResMan</strong> <strong>Reporting</strong> an. Die<br />

Tabelle ist dynamisch und zeigt je nach gewählter Zeitspanne und Granularität ein andere<br />

Anzahl Spalten an. Wenn keine explizite Ressource gewählt wird, wird die Gesamtauslastung<br />

der OE mitangezeigt. Das nachfolgende Beispiel zeigt die Auslastung einer OE für ein<br />

ganzes Jahr. Die Granularität ist hierbei der Monat. Jede Spalte in der Tabelle ist sortierbar.<br />

Unterhalb der Tabelle befinden sich ausserdem die Export Buttons, mittels welcher die Daten<br />

der Tabelle in das jeweilige Format exportiert werden können.<br />

Abbildung 10:GUI-Nr. 04 Trefferliste<br />

Anmerkung: Aufwandshalber wurden nur die ersten drei Spalten der Tabelle mit Werten<br />

ausgefüllt.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 49 von 128


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

11.2.6 Trefferliste (Im Falle, dass eine explizite Resource gewählt wurde) GUI-Nr. 04<br />

Die nachfolgende GUI-Skizze zeigt ebenfalls die Trefferliste des Moduls <strong>ResMan</strong> <strong>Reporting</strong><br />

an. Der Unterschied zur bereits weiter oben gesehenen Trefferliste ist hierbei, dass eine explizite<br />

Resource gewählt wurde. In diesem Falle wird nämlich nicht die ganze OE gezeigt<br />

sondern nur die gewählte Resource. Die gewählte Granularität in diesem Beispiel ist der<br />

Tag.<br />

Abbildung 11:GUI-Nr. 04 Trefferliste Resource<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 50 von 128


11.3 Testkonzept<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Sogenannte Whitebox-Tests werden während der Entwicklung bereits vom Entwickler<br />

durchgeführt. Nach jeder grösseren Änderung oder Neuerung wird das gesamte Modul getestet,<br />

um das korrekte Zusammenspiel der einzelnen Komponenten sicherzustellen. In diesem<br />

Testkonzept wird beschrieben, wie die Applikation nach der Implementierung getestet<br />

werden soll.<br />

11.3.1 Testziele<br />

Ziel des Testverfahrens ist es, eventuelle, vom Entwickler noch nicht entdeckte Fehler der<br />

Applikation aufzudecken. Es soll sichergestellt werden, dass die erstellte Applikation den<br />

Anforderungen entspricht.<br />

11.3.2 Testverfahren<br />

Die Applikation wird von einem Mitarbeiter getestet. Die Tests werden anhand der definierten<br />

Testfälle im QC durchgeführt. Ich werde bei der Durchführung der Tests dabei sein, um sie<br />

zu protokollieren und bei Bedarf die Testfälle zu erläutern und Unklarheiten zu klären bzw.<br />

die Testfälle zu verfeinern.<br />

Gefundene Bugs werden nach den Tests vom Entwickler behoben und anschliessend erneut<br />

getestet. Dieses Verfahren dauert solange an, bis keine Fehler mehr gefunden wurden.<br />

Neben den Anwendertests wird zusätzlich ein JUnit- Test erstellt, der die Berechnungslogik<br />

des Moduls testet.<br />

11.3.3 Auswertung<br />

Die Auswertung der Anwendertests wird in einem ausgefüllten Testprotokoll festgehalten.<br />

Dabei ist zu unterscheiden zwischen bestanden und nicht bestanden. Die Applikation hat<br />

den Test bestanden, sobald alle der zu testenden Funktionen ohne Probleme durchgeführt<br />

werden konnten. Ansonsten gilt der Test als nicht bestanden.<br />

11.3.4 Testumgebung<br />

Die Tests werden an unserem Testserver durchgeführt (http://resman-test.tcsb.admin.ch),<br />

auf den ich das fertige Modul deployen werde. Durch die Tests führt das Quality Center.<br />

11.3.4.1 Test-Benutzeraccount<br />

Für die Durchführung der Tests wird der Testaccount benutzt. Die Login Daten hierfür sind<br />

die folgenden:<br />

Benutzername: seco-tes<br />

Passwort : 12345678<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 51 von 128


11.3.5 Testspezifikation<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Nachfolgend sind die einzelnen Testfälle des Moduls <strong>ResMan</strong> <strong>Reporting</strong> aufgelistet. Die hier<br />

aufgeführten Tests wurden zusätzlich im Quality Center erfasst.<br />

Filterkriterienset abspeichern<br />

Nummer T 1.0<br />

QC Nummer 27<br />

Beschreibung Ein Benutzer speichert ein neues Filterkriterienset ab.<br />

Vorbedingungen Keine<br />

Ablauf Beschreibung Erwartung<br />

Tabelle 29:Testfall 1.0<br />

Bei Toplevelnavigation auf<br />

Schaltfläche [<strong>Reporting</strong>] klicken.<br />

Auf das „neue Suche“ Icon<br />

rechts oberhalb der Tabelle klicken.<br />

Die Felder:<br />

-OE<br />

-Ressource<br />

-Datum- von / bis<br />

-Granularität<br />

-Projekt<br />

-Projektaufgabe<br />

-Aufgabe<br />

-Auslastung von –bis<br />

können ausgefüllt werden.<br />

Auf Schaltfläche [Speichern]<br />

klicken.<br />

Es erscheint die Maske Schnellliste.<br />

In der Tabelle befinden sich alle vom<br />

aktiven User erfassten Filterkriteriensets.<br />

Es erscheint die Suchmaske / Erfassungsmaske.<br />

Es erscheint die Maske Detailansicht.<br />

Sie zeigt alle soeben abgespeicherten<br />

Filterkriterien an.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 52 von 128


Filterkriterienset abspeichern mit Validierungsfehlern<br />

Nummer T 1.1<br />

QC Nummer 27<br />

Tabelle 30:Testfall 1.1<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Beschreibung Ein Benutzer versucht ein neues Filterkriterienset abzuspeichern und löst<br />

dabei Validierungsfehler aus.<br />

Vorbedingungen Keine<br />

Ablauf Beschreibung Erwartung<br />

Bei Toplevelnavigation auf<br />

Schaltfläche [<strong>Reporting</strong>] klicken.<br />

Auf das „neue Suche“ Icon<br />

rechts oberhalb der Tabelle klicken.<br />

Die Felder:<br />

-OE<br />

-Ressource<br />

-Datum- von / bis<br />

-Granularität<br />

-Projekt<br />

-Projektaufgabe<br />

-Aufgabe<br />

-Auslastung von –bis<br />

Erscheinen.<br />

Auf Schaltfläche [Speichern]<br />

klicken, ohne ein Feld auszufüllen.<br />

Es erscheint die Maske Schnellliste. In der<br />

Tabelle befinden sich alle vom aktiven User<br />

erfassten Filterkriteriensets.<br />

Es erscheint die Suchmaske / Erfassungsmaske.<br />

Es werden die folgenden Validierungsmeldungen<br />

ausgegeben:<br />

-Bitte erfassen Sie eine OE<br />

-Bitte erfassen Sie ein Datum von<br />

-Bitte erfassen Sie ein Datum bis<br />

-Bitte geben Sie eine Granularität an.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 53 von 128


Filterkriterienset bearbeiten<br />

Nummer T 2.0<br />

QC Nummer 27<br />

Tabelle 31:Testfall 2.0<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Beschreibung Ein Benutzer bearbeitet ein bestehendes Filterkriterienset in der Schnellliste.<br />

Vorbedingungen Es sind Filterkriteriensets in der Schnellliste vorhanden.<br />

Ablauf Beschreibung Erwartung<br />

Bei Toplevelnavigation auf<br />

Schaltfläche [<strong>Reporting</strong>] klicken.<br />

Auf das Icon „bearbeiten / suchen“<br />

in der letzten Spalte des<br />

gewünschten Eintrages klicken.<br />

Die Felder:<br />

-OE<br />

-Ressource<br />

-Datum- von / bis<br />

-Granularität<br />

-Projekt<br />

-Projektaufgabe<br />

-Aufgabe<br />

-Auslastung von –bis<br />

Können mutiert werden.<br />

Auf Schaltfläche [Speichern]<br />

klicken.<br />

Es erscheint die Maske Schnellliste. In der<br />

Tabelle befinden sich alle vom aktiven User<br />

erfassten Filterkriteriensets<br />

Es erscheint die Suchmaske / Erfassungsmaske.<br />

Es erscheint die Maske Detailansicht. Sie<br />

zeigt alle gewählten Filterkriterien an.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 54 von 128


Report zusammenstellen ohne Eintrag aus Schnellliste<br />

Nummer T 3.0<br />

QC Nummer 27<br />

Tabelle 32:Testfall 3.0<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Beschreibung Ein Benutzer stellt einen Report (Auslastungsdaten) ohne Eintrag aus der<br />

Schnellliste zusammen.<br />

Vorbedingungen Keine<br />

Ablauf Beschreibung Erwartung<br />

Bei Toplevelnavigation auf<br />

Schaltfläche [<strong>Reporting</strong>] klicken.<br />

Auf das „neue Suche“ Icon<br />

rechts oberhalb der Tabelle klicken.<br />

Die Felder:<br />

-OE<br />

-Ressource<br />

-Datum- von / bis<br />

-Granularität<br />

-Projekt<br />

-Projektaufgabe<br />

-Aufgabe<br />

-Auslastung von –bis<br />

Können ausgefüllt werden.<br />

Auf Schaltfläche [Suchen] klicken.<br />

Es erscheint die Maske Schnellliste. In der<br />

Tabelle befinden sich alle vom aktiven User<br />

erfassten Filterkriteriensets.<br />

Es erscheint die Suchmaske / Erfassungsmaske.<br />

Es erscheint die Maske Trefferliste. In der<br />

Tabelle stehen die Auslastungsdaten, die<br />

anhand der eingegebenen Filterkriterien<br />

zusammengestellt / berechnet wurden.<br />

Falls keine explizite Resource gewählt<br />

wurde, befindet sich in der ersten Zeile der<br />

Tabelle die Gesamtauslastung aller Mitarbeiter.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 55 von 128


Report zusammenstellen mit Eintrag aus Schnellliste<br />

Nummer T 3.1<br />

QC Nummer 27<br />

Tabelle 33:Testfall 3.1<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Beschreibung Ein Benutzer stellt einen Report (Auslastungsdaten) zusammen mittels eines<br />

Filterkriteriensets aus der Schnellliste.<br />

Vorbedingungen Es sind Filterkriteriensets in der Schnellliste vorhanden.<br />

Ablauf Beschreibung Erwartung<br />

Bei Toplevelnavigation auf<br />

Schaltfläche [<strong>Reporting</strong>] klicken.<br />

Auf das Icon „bearbeiten / suchen“<br />

in der letzten Spalte des<br />

gewünschten Eintrages klicken.<br />

Auf Schaltfläche [Suchen] klicken.<br />

Es erscheint die Maske Schnellliste. In der<br />

Tabelle befinden sich alle vom aktiven User<br />

erfassten Filterkriteriensets.<br />

Es erscheint die Suchmaske / Erfassungsmaske.<br />

Es erscheint die Maske Trefferliste. In der<br />

Tabelle stehen die Auslastungsdaten, die<br />

anhand der eingegebenen Filterkriterien<br />

zusammengestellt / berechnet wurden.<br />

Falls keine explizite Resource gewählt<br />

wurde, befindet sich in der ersten Zeile der<br />

Tabelle die Gesamtauslastung aller Mitarbeiter.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 56 von 128


Report zusammenstellen mit Validierungsfehlern<br />

Nummer T 3.2<br />

QC Nummer 27<br />

Tabelle 34:Testfall 3.2<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Beschreibung Ein Benutzer versucht einen Report zusammen zu stellen und löst dabei Validierungsfehler<br />

aus.<br />

Vorbedingungen Keine<br />

Ablauf Beschreibung Erwartung<br />

Bei Toplevelnavigation auf<br />

Schaltfläche [<strong>Reporting</strong>] klicken.<br />

Auf das Icon „neue Suche“<br />

rechts oberhalb der Schnellliste<br />

klicken.<br />

Die Felder:<br />

-OE<br />

-Ressource<br />

-Datum- von / bis<br />

-Granularität<br />

-Projekt<br />

-Projektaufgabe<br />

-Aufgabe<br />

-Auslastung von –bis<br />

erscheinen.<br />

Auf Schaltfläche [Suchen] klicken,<br />

ohne ein Feld auszufüllen.<br />

Es erscheint die Maske Schnellliste. In der<br />

Tabelle befinden sich alle vom aktiven User<br />

erfassten Filterkriteriensets.<br />

Es erscheint die Suchmaske / Erfassungsmaske.<br />

Es werden die folgenden Validierungsmeldungen<br />

ausgegeben:<br />

-Bitte erfassen Sie eine OE<br />

-Bitte erfassen Sie ein Datum von<br />

-Bitte erfassen Sie ein Datum bis<br />

-Bitte geben Sie eine Granularität an.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 57 von 128


Auslastungsdaten sortieren<br />

Nummer T 4.0<br />

QC Nummer 27<br />

Beschreibung Ein Benutzer sortiert die Auslastungsdaten in der Trefferliste.<br />

Vorbedingungen Erfolgreicher Ausgang von Testfall Nr. 3.0 oder 3.1<br />

Ablauf Beschreibung Erwartung<br />

Tabelle 35:Testfall 4.0<br />

Tabelle 36:Testfall 5.0<br />

Bei Toplevelnavigation auf Schaltfläche<br />

[<strong>Reporting</strong>] klicken.<br />

Auf das Icon „bearbeiten / suchen“<br />

in der letzten Spalte des<br />

gewünschten Eintrages klicken.<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Es erscheint die Maske Schnellliste. In der<br />

Tabelle befinden sich alle vom aktiven User<br />

erfassten Filterkriteriensets.<br />

Es erscheint die Suchmaske / Erfassungsmaske.<br />

Auf Schaltfläche [Suchen] klicken. Es erscheint die Maske Trefferliste. In der<br />

Tabelle stehen die Auslastungsdaten, die<br />

anhand der eingegebenen Filterkriterien<br />

zusammengestellt / berechnet wurden.<br />

Auf das Icon „sortieren“ (Pfeil) in<br />

der zu sortierenden Spalte klicken.<br />

Auslastungsdaten in CSV exportieren<br />

Nummer T 5.0<br />

QC Nummer 27<br />

Die Daten in der Tabelle liegen nach der<br />

gewünschten Spalte sortiert vor.<br />

Beschreibung Ein Benutzer exportiert die Daten in der Trefferliste in ein CSV File.<br />

Vorbedingungen Erfolgreicher Ausgang von Testfall Nr. 3.0 oder 3.1<br />

Ablauf Beschreibung Erwartung<br />

Bei Toplevelnavigation auf<br />

Schaltfläche [<strong>Reporting</strong>] klicken.<br />

Auf das Icon „bearbeiten / suchen“<br />

in der letzten Spalte des<br />

gewünschten Eintrages klicken.<br />

Auf Schaltfläche [Suchen] klicken.<br />

Auf das Icon „CSV Export“ klicken.<br />

Es erscheint die Maske Schnellliste. In der<br />

Tabelle befinden sich alle vom aktiven User<br />

erfassten Filterkriteriensets.<br />

Es erscheint die Suchmaske / Erfassungsmaske.<br />

Es erscheint die Maske Trefferliste. In der<br />

Tabelle stehen die Auslastungsdaten, die<br />

anhand der eingegebenen Filterkriterien<br />

zusammengestellt / berechnet wurden.<br />

Es wurde eine CSV Datei erstellt, die alle<br />

Daten aus der Tabelle beinhaltet. Die Datei<br />

befindet sich im Download Ordner.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 58 von 128


Auslastungsdaten in PDF exportieren<br />

Nummer<br />

QC Nummer<br />

Beschreibung<br />

Vorbedingungen<br />

Tabelle 37:Testfall 6.0<br />

Tabelle 38:Testfall 7.0<br />

T 6.0<br />

27<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Ein Benutzer exportiert die Daten in der Trefferliste in eine PDF Datei.<br />

Erfolgreicher Ausgang von Testfall Nr. 3.0 oder 3.1<br />

Ablauf Beschreibung Erwartung<br />

Bei Toplevelnavigation auf<br />

Schaltfläche [<strong>Reporting</strong>] klicken.<br />

Auf das Icon „bearbeiten / suchen“<br />

in der letzten Spalte des<br />

gewünschten Eintrages klicken.<br />

Auf Schaltfläche [Suchen] klicken.<br />

Auf das Icon „PDF Export“ klicken.<br />

Auslastungsdaten in Excel exportieren<br />

Nummer T 7.0<br />

QC Nummer 27<br />

Es erscheint die Maske Schnellliste. In der<br />

Tabelle befinden sich alle vom aktiven User<br />

erfassten Filterkriteriensets.<br />

Es erscheint die Suchmaske / Erfassungsmaske.<br />

Es erscheint die Maske Trefferliste. In der<br />

Tabelle stehen die Auslastungsdaten, die<br />

anhand der eingegebenen Filterkriterien<br />

zusammengestellt / berechnet wurden.<br />

Es wurde eine PDF Datei erstellt, die alle<br />

Daten aus der Tabelle beinhaltet. Die Datei<br />

befindet sich im Download Ordner.<br />

Beschreibung Ein Benutzer exportiert die Daten in der Trefferliste in ein Excel File.<br />

Vorbedingungen Erfolgreicher Ausgang von Testfall Nr. 3.0 oder 3.1<br />

Ablauf Beschreibung Erwartung<br />

Bei Toplevelnavigation auf<br />

Schaltfläche [<strong>Reporting</strong>] klicken.<br />

Auf das Icon „bearbeiten / suchen“<br />

in der letzten Spalte des<br />

gewünschten Eintrages klicken.<br />

Auf Schaltfläche [Suchen] klicken.<br />

Auf das Icon „Excel Export“ klicken.<br />

Es erscheint die Maske Schnellliste. In der<br />

Tabelle befinden sich alle vom aktiven User<br />

erfassten Filterkriteriensets.<br />

Es erscheint die Suchmaske / Erfassungsmaske.<br />

Es erscheint die Maske Trefferliste. In der<br />

Tabelle stehen die Auslastungsdaten, die<br />

anhand der eingegebenen Filterkriterien<br />

zusammengestellt / berechnet wurden.<br />

Es wurde eine Excel Datei erstellt, die alle<br />

Daten aus der Tabelle beinhaltet. Die Datei<br />

befindet sich im Download Ordner.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 59 von 128


Filterkriterienset löschen<br />

Nummer T 8.0<br />

QC Nummer 27<br />

Beschreibung Ein Benutzer löscht ein Filterkriterienset aus der Schnellliste.<br />

Tabelle 39:Testfall 8.0<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Vorbedingungen Es ist mindestens ein Filterkriterienset in der Schnellliste vorhanden.<br />

Ablauf Beschreibung Erwartung<br />

Bei Toplevelnavigation auf<br />

Schaltfläche [<strong>Reporting</strong>] klicken.<br />

Auf das Icon „löschen“ in der<br />

letzten Spalte des zu löschenden<br />

Eintrages klicken.<br />

Es erscheint die Maske Schnellliste. In der<br />

Tabelle befinden sich alle vom aktiven User<br />

erfassten Filterkriteriensets.<br />

Es erscheint ein Dialogfenster: „Wollen Sie<br />

dieses Objekt wirklich löschen?“.<br />

Auf Schaltfläche [Ja] klicken. Der Eintrag wurde aus der Tabelle entfernt.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 60 von 128


12. Realisierung<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

In der Phase Realisierung wurden die in der Voranalyse evaluierten Systemanforderungen<br />

umgesetzt.<br />

12.1 Systemdesign<br />

In diesem Kapitel wird die Architektur des Moduls <strong>ResMan</strong> <strong>Reporting</strong> anhand von Klassen-,<br />

Sequenz- und Komponentendiagrammen erläutert. Übersichtshalber wurde das Klassendiagramm<br />

in die drei Schichten Web, Service und Persistenz aufgeteilt. Es wurde jedoch in das<br />

Web und das Service Klassendiagramm jeweils zusätzlich die Interface Klasse der darunterliegenden<br />

Schicht eingefügt, um die Abhängigkeiten zwischen den drei Schichten zu visualisieren.<br />

12.1.1 Komponenten Diagramm Architektur<br />

Das Modul <strong>ResMan</strong> <strong>Reporting</strong> wurde in einer „Drei-Schichten-Architektur“ modelliert. Die<br />

Schichten der Benutzeroberfläche, der Logik und der Datenhaltung wurden durch Interfaces<br />

voneinander entkoppelt. Da sich die Entitäten in der Persistenzschicht befinden, und die<br />

Webschicht nicht auf die Persistenzschicht zugreifen darf, werden sogenannte DTOs eingesetzt,<br />

welche die Daten zwischen der Web- und Serviceschicht transportieren. Da per Definition<br />

die Web nur Abhängigkeiten auf die Serviceschicht haben darf und nicht umgekehrt,<br />

werden die DTOs in der Serviceschicht zur Verfügung gestellt.<br />

Die Referenzen zwischen den einzelnen Klassen wird durch die Dependency Injection (DI)<br />

gehandhabt, welche vom Spring Framework zur Verfügung gestellt wird.<br />

Die Webschicht stellt die Benutzeroberfläche dar, sie stellt Formulare für die Dateneingabe<br />

bereit, präsentiert Daten und ist für die Dialogführung zuständig. In der Serviceschicht werden<br />

die DTOs auf die Entitäten gemappt, welche dann an die Persistenzschicht weitergereicht<br />

werden. Die Persistenzschicht ist für die Datenspeicherung zuständig.<br />

Das nachfolgende Diagramm zeigt den Aufbau der Architektur des Moduls <strong>ResMan</strong> <strong>Reporting</strong><br />

anhand von Komponenten.<br />

Abbildung 12:Komponenten Diagramm<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 61 von 128


12.1.2 Web Layer<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Der Web Layer wurde nach dem Model View Controller (MVC) Pattern aufgebaut. Der View<br />

entspricht einer XHTML Seite, der Controller der Action und das Model der Modelklasse.<br />

Die nachfolgende Grafik veranschaulicht das MVC Prinzip mit dessen Zugriffsrechten am<br />

Beispiel des Moduls <strong>ResMan</strong> <strong>Reporting</strong>. Die Action darf auf das Model zugreifen. Umgekehrt<br />

ist dies aber nicht möglich. Die XHTML Seite greift jeweils auf das Model und auf die Action<br />

zu.<br />

Abbildung 13: MVC<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 62 von 128


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

12.1.2.1 Klassendiagramm Web Layer<br />

Das nachfolgende Klassendiagramm zeigt die Klassen des Web Layers des Moduls <strong>ResMan</strong> <strong>Reporting</strong>. In diesem Diagramm sieht man die Modelklassen,<br />

die Action Klassen und die XHTML Seite. Alle Action Klassen erhalten eine Referenz auf das Model. Die drei Action Klassen BaseDelete, Base-<br />

Persist und BaseEdit erhalten zusätzlich eine Referenz auf den <strong>Reporting</strong>Service. Die Actionklassen und die Modellklasse haben unterschiedliche Scopes.<br />

Der RequestScope wird für die Actionklassen und der längerlebige SessionScope für die Modellklasse verwendet.<br />

Anmerkung: Die Klassen die im Rahmen des Moduls <strong>ResMan</strong> <strong>Reporting</strong> erstellt wurden, sind gelb hinterlegt. Die restlichen Klassen, die nicht im Rahmen dieses Moduls<br />

erstellt wurden, sind grau hinterlegt. Übersichtshalber wurden die getter / setter Methoden weggelassen.<br />

Abbildung 14:Klassendiagramm Weblayer<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 63 von 128


12.1.3 Klassendiagramm Service Layer<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Das nachfolgende Klassendiagramm zeigt die Klassen des Service Layers des Moduls<br />

<strong>ResMan</strong> <strong>Reporting</strong>. Die Service Klasse wird von der Klasse BasePersistenceService abgeleitet.<br />

Zusätzlich implementiert die ServiceKlasse noch ein Interface, durch welches der Servicelayer<br />

vom Weblayer entkoppelt wird. Die Klasse Base Persistence Service erhält eine<br />

Referenz auf das Repository.<br />

Anmerkung: Die grau hinterlegten Klassen kennzeichnen die Klassen, die bereits in der bestehenden<br />

Applikation in Verwendung sind. Die gelb hinterlegten Klassen und Interfaces wurden im Rahmen des<br />

Moduls <strong>ResMan</strong> <strong>Reporting</strong> erstellt. Übersichtshalber wurden die getter / setter Methoden in den Klassen<br />

<strong>Reporting</strong>Criteria und <strong>Reporting</strong>CriteriaDto weggelassen.<br />

Abbildung 15:Klassendiagramm Servicelayer<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 64 von 128


12.1.4 Klassendiagramm Persistence Layer<br />

Abbildung 16:Klassendiagramm Persistenzlayer<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Das nachfolgende Klassendiagramm zeigt die Klassen des Persistenz Layers des Moduls<br />

<strong>ResMan</strong> <strong>Reporting</strong>. Die Klasse Jpa<strong>Reporting</strong>Repository enthält keine eigenen Methoden.<br />

Die Klasse erbt alle Methoden vom JPAExtendedBaseRepository, in welcher auch die ganze<br />

Speicher „Logik“ abgehandelt wird.<br />

Anmerkung: Die gelb hinterlegten Klassen wurden im Rahmen des Moduls Resman <strong>Reporting</strong> erstellt.<br />

Die grau hinterlegten Klassen kennzeichnen wiederrum die in der Applikation bereits verwendeten<br />

Klassen.Übersichtshalber wurden die getter / setter Methoden in den Klassen weggelassen.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 65 von 128


12.1.5 Domain Model<br />

Abbildung 17:Domain Model<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Das nachfolgende Klassendiagramm zeigt alle Entitäten welche im Modul <strong>ResMan</strong> <strong>Reporting</strong> verwendet werden. Die Entitäten befinden sich alle im<br />

Persistenz Layer. Alle Klassen werden von der Superklasse BaseResmanEntity abgeleitet. Da der Persistenzlayer mit JPA umgesetzt wurde, beinhalten<br />

die einzelnen Klassen noch entsprechende Annotationen wie z.B. @Entity, die vom EntityManager benötigt werden, um die Klassen als Entitäten zu<br />

identifizieren.<br />

Anmerkung: Die grau hinterlegten Klassen kennzeichnen die Klassen die bereits in der bestehenden Applikation in Verwendung sind. Die gelb hinterlegte Klasse wurde<br />

im Rahmen des Moduls <strong>ResMan</strong> <strong>Reporting</strong> erstellt. In den Entitäten befinden sich ausschliesslich die entsprechenden Attribute und deren getter / setter Methoden,<br />

die aber übersichtshalber im Diagramm weggelassen wurden.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 66 von 128


12.1.6 Entity Relationship Diagramm<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Das nachfolgende Entity Relationship Diagramm (ERD) zeigt die Datenbanktabellen, welche<br />

im Modul <strong>ResMan</strong> <strong>Reporting</strong> benutzt werden. Die orange hinterlegten Tabellen kennzeichnen<br />

diejenigen Tabellen, die schon bereits von der Applikation verwendet werden. Die gelb<br />

hinterlegte Tabelle wurde im Rahmen des Moduls <strong>ResMan</strong> <strong>Reporting</strong> erstellt. In dieser Tabelle<br />

werden die Filterkriterien abgelegt. Die Tabellen welche die Stammdaten der Applikation<br />

beinhalten wurden übersichtshalber weggelassen.<br />

Abbildung 18:ERD <strong>ResMan</strong> Haupttabellen<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 67 von 128


12.1.7 Sequenzdiagramm Benutzer erfassen<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Das nachfolgende Sequenzdiagramm beschreibt den Ablauf im System, wenn ein neues Filterkriterienset abgespeichert bzw. bearbeitet wird. Dieses<br />

Szenario durchläuft alle drei Schichten der Applikation. Die <strong>Reporting</strong>PersistAction wird durch die reporting.xhtml Seite aufgerufen, wenn die Schaltfläche<br />

[Speichern] betätigt wird. Die Klasse <strong>Reporting</strong>Validator validiert die Eingaben vom Benutzer und gibt ein Boolean valid zurück. Wenn es keine Validierungsfehler<br />

gibt, wird der Service aufgerufen, in welchem das DTO auf die entsprechende Entität gemappt wird und an das Repository weitergereicht<br />

wird. Dort wird dann die Entität vom EM persistiert. Die persistierte Entität wird anschliessend wieder an den Servicelayer zurückgegeben, auf das<br />

DTO gemappt und an den Weblayer zurückgereicht.<br />

Abbildung 19: Sequenzdiagramm Filterkriterien abspeichern<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 68 von 128


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

12.1.8 Sequenzdiagramm Report zusammenstellen / berechnen<br />

Das nachfolgende Sequenzdiagramm beschreibt den Ablauf im System, wenn die Auslastungsdaten berechnet bzw. zusammengestellt werden. Die<br />

<strong>Reporting</strong>CalculateAction wird von der reporting.xhtml aufgerufen, wenn die Schaltfläche [Suchen] betätigt wird. Die Klasse <strong>Reporting</strong>Validator validiert<br />

die Eingaben vom Benutzer und gibt ein Boolean valid zurück. Wenn es keine Validierungsfehler gibt, wird die Berechnung anhand der Filterkriterien<br />

durchgeführt. Die Berechnung findet auf dem ResourcePayloadCalculator und in der <strong>Reporting</strong>CalculateAction statt. Nachdem die eigentliche Berechnung<br />

durchgeführt wurde, werden die Daten für das Model aufbereitet und auf die Modelklasse gesetzt.<br />

Abbildung 20: SequenzdiagrammBerechnungAuslastungsdaten<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 69 von 128


12.2 GUI<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Nachfolgend werden die GUIs aufgezeigt, die im Rahmen des Moduls <strong>ResMan</strong> <strong>Reporting</strong><br />

entwickelt wurden. Die GUIs wurden anhand der GUI- Skizzen, welche bereits in der Konzeptphase<br />

erstellt wurden, aufgebaut.<br />

12.2.1 GUI-Nr. 01 Schnellliste<br />

Das nachfolgende GUI zeigt die Schnellliste des Moduls <strong>ResMan</strong> <strong>Reporting</strong>. In dieser Tabelle<br />

befinden sich alle Filterkriteriensets, die vom aktiven Benutzer abgespeichert wurden. Betätigt<br />

man das Icon „bearbeiten /suchen“ in der letzten Spalte der Tabelle, so erscheint die<br />

Suchmaske / Erfassungsmaske. Auf dieser Maske ist es ausserdem auch möglich, ein Filterkriterienset<br />

zu löschen.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 70 von 128


12.2.2 GUI-Nr.02 Suchmaske/ Erfassungsmaske<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Das nachfolgende GUI zeigt die Erfassungsmaske/Suchmaske der Filterkriteriensets. Wie<br />

der Name schon sagt, wird dieses GUI für das Abspeichern eines Filterkriteriensets und für<br />

die Suche verwendet. Die Eingabefelder, welche mit einem Stern gekennzeichnet sind, sind<br />

Pflichtfelder.<br />

12.2.3 GUI- Nr.03 Detailansicht<br />

Das nachfolgende GUI zeigt die Detailansicht auf ein Filterkriterienset. Dieses GUI wird nur<br />

dann angezeigt, wenn das Filterkriterienset erfolgreich abgespeichert wurde.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 71 von 128


12.2.4 GUI-Nr. 04 Trefferliste (Wenn keine Ressource gewählt)<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Dieses GUI zeigt die Trefferliste in Form einer dynamischen Tabelle. In der ersten Spalte<br />

befindet sich die Ressource und in den nachfolgenden Spalten befinden sich die Auslastungswerte.<br />

Die Anzahl Spalten und die Beschriftung sind abhängig von der gewählten Granularität.<br />

In der ersten Zeile befindet sich ausserdem die totale Auslastung der gewählten<br />

OE. Wird eine spezifische Ressource gewählt, wird diese weggelassen.<br />

12.2.5 GUI-Nr.04 Trefferliste(Wenn eine Ressource gewählt)<br />

Dieses GUI zeigt ebenfalls die Trefferliste. Dieses GUI ist bis auf eine Ausnahme Identisch<br />

mit der bereits weiter oben gesehenen Trefferliste. Der einzige Unterschied ist, dass die Gesamtauslastung<br />

hier weggelassen wird, da in diesem Beispiel eine spezifische Ressource<br />

gewählt wurde.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 72 von 128


12.3 Screenflow Diagramm<br />

Das nachfolgende Screenflow Diagramm zeigt die Navigationsmöglichkeiten innerhalb des Moduls <strong>ResMan</strong> <strong>Reporting</strong>.<br />

Abbildung 21:Screenflow<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 73 von 128


12.4 Testprotokoll<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Testfall Nr. Testbeschreibung Erwartung Ergebnis OK? Visum<br />

1.0 Ein Benutzer speichert ein neues Filterkriterienset<br />

ab.<br />

1.1 Ein Benutzer versucht ein neues Filterkriterienset<br />

abzuspeichern und löst dabei Validierungsfehler<br />

aus.<br />

2.0 Ein Benutzer bearbeitet ein bestehendes Filterkrite-<br />

rienset in der Schnellliste.<br />

3.0 Ein Benutzer stellt einen Report (Auslastungsdaten)<br />

ohne Eintrag aus Schnellliste zusammen.<br />

3.1 Ein Benutzer stellt einen Report (Auslastungsdaten)<br />

zusammen mittels eines Filterkriteriensets aus<br />

der Schnellliste.<br />

3.2 Ein Benutzer versucht einen Report zusammen zu<br />

stellen und löst dabei Validierungsfehler aus.<br />

4.0 Ein Benutzer sortiert die Auslastungsdaten in der<br />

Trefferliste.<br />

5.0 Ein Benutzer exportiert die Daten in der Trefferliste<br />

in ein CSV File.<br />

6.0 Ein Benutzer exportiert die Daten in der Trefferliste<br />

in ein PDF File.<br />

7.0 Ein Benutzer exportiert die Daten in der Trefferliste<br />

in ein Excel File.<br />

8.0 Ein Benutzer löscht ein Filterkriterienset aus der<br />

Schnellliste.<br />

Tabelle 40:Testprotokoll<br />

Das Filterkriterienset befindet sich in der Datenbanktabelle<br />

reporting_criteria.<br />

Die entsprechenden Validierungsmeldungen werden<br />

ausgegeben.<br />

Die mutierten Felder liegen bearbeitet in der Tabelle<br />

reporting_criteria vor.<br />

Auf der Maske Trefferliste erscheint eine Tabelle,<br />

in der die berechneten Auslastungsdaten stehen.<br />

Auf der Maske Trefferliste erscheint eine Tabelle,<br />

in der die berechneten Auslastungsdaten stehen.<br />

Die entsprechenden Validierungsmeldungen werden<br />

ausgegeben.<br />

Die Daten liegen nach der gewünschten Spalte<br />

sortiert vor.<br />

Die Daten aus der Trefferliste wurden in ein CSV<br />

File exportiert, welches sich im Download Ordner<br />

befindet.<br />

Die Daten aus der Trefferliste wurden in ein PDF<br />

File exportiert, welches sich im Download Ordner<br />

befindet.<br />

Die Daten aus der Trefferliste wurden in ein Excel<br />

File exportiert, welches sich im Download Ordner<br />

befindet<br />

Das Filterkriterienset wurde aus der Datenbank<br />

und somit aus der Schnellliste entfernt.<br />

Wie erwartet.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 74 von 128<br />

OK<br />

gid<br />

Wie erwartet. OK gid<br />

Wie erwartet. OK gid<br />

Wie erwartet.<br />

OK<br />

gid<br />

Wie erwartet. OK gid<br />

Wie erwartet.<br />

OK<br />

gid<br />

Wie erwartet. OK gid<br />

Wie erwartet. OK<br />

gid<br />

Wie erwartet. OK gid<br />

Wie erwartet OK gid<br />

Wie erwartet. OK gid


12.4.1 Testprotokoll aus Quality Center<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Nachfolgend noch das Testprotokoll, welches im Quality Center nach der Durchführung der<br />

Anwender Tests generiert wurde.<br />

12.5 JUnit Test<br />

Neben den Anwendertests wurden zusätzlich acht JUnit Testmethoden erstellt, welche die<br />

verschiedenen Berechnungen des Moduls <strong>ResMan</strong> <strong>Reporting</strong> auf Korrektheit testen. Dabei<br />

werden auch Dinge getestet, die bei einem normalen Anwendertest nicht so beachtet würden.<br />

- Die erste Testmethode testet die Anzahl WorkDays, welche für die übergebene Zeitspanne<br />

erstellt werden.<br />

- Die zweite testet die Anzahl WorkWeeks, die anhand der übergebenen WorkDay Liste<br />

erstellt werden.<br />

- Die dritte Testmethode testet die Anzahl WorkWeeks, die erstellt werden, wenn die<br />

Zeitspanne über ein Jahr hinaus geht.<br />

- Die vierte Testmethode testet die Anzahl WorkMonthes, welche anhand der übergebenen<br />

WorkDay Liste erstellt werden.<br />

- Die fünfte Testmethode testet die Anzahl WorkMonthes, welche erstellt werden, wenn<br />

die Zeitspanne über ein Jahr hinaus geht.<br />

- Die Testmethoden sechs, sieben und acht testen die Arbeitsstunden, welche für das<br />

übergebene Projekt bzw. Projekttask und Task berechneten werden.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 75 von 128


13. Einführung<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Im Zusammenhang mit der <strong>IPA</strong> wird für die Phase Einführung ausschliesslich das erweiterte<br />

Benutzerhandbuch ausgeliefert und am 31. Mai <strong>2013</strong> eine Präsentation mit anschliessender<br />

Demo durchgeführt.<br />

Der Go-Live Termin und der Abnahmetermin durch den Kunden, wurden bisher noch nicht<br />

festgelegt.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 76 von 128


14. Quellenverzeichnis<br />

14.1 Informationen<br />

Datenexport<br />

http://www.primefaces.org/showcase/ui/exporter.jsf<br />

http://www.opencsv.sourceforge.net<br />

http://itextpdf.com/<br />

http://poi.apache.org/<br />

PrimeFaces Dynamische Tabelle<br />

14.3 Bilder<br />

http://www.primefaces.org/showcase/ui/datatableDynamicColumns.jsf<br />

http://balusc.blogspot.ch/2006/06/using-datatables.html#PopulateDynamicDatatable<br />

Bild Quelle<br />

Abbildung 1: Projektorganisation Selbst erstellt<br />

Abbildung 2: Hermes Phasen<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

http://old.code.zhdk.ch/projects/madek/attachment/wiki/Ablaufs<br />

konzept/image1.jpeg<br />

Abbildung 3:HERMES Phasenmodel http://www.pmaktuell.org/PMAktuell-200902/034-Wissen-<br />

Mourgue1-GPM<br />

Abbildung 4:UseCase Diagramm Selbst erstellt<br />

Abbildung 5: GUI-Nr. 01 Schnellliste Selbst erstellt<br />

Abbildung 6: GUI-Nr. 02 Suchmaske Selbst erstellt<br />

Abbildung 7:GUI-Nr. 03 Detailansicht Selbst erstellt<br />

Abbildung 8:GUI-Nr. 04 Trefferliste Selbst erstellt<br />

Abbildung 9:GUI-Nr. 04 Trefferliste 2 Selbst erstellt<br />

Abbildung 10:ERD Selbst erstellt<br />

Abbildung 11:Komponenten Diagramm Selbst erstellt<br />

Abbildung 12:Klassendiagramm Web Selbst erstellt<br />

Abbildung 13:Klassendiagramm Service Selbst erstellt<br />

Abbildung 14:Klassendiagramm Persistenz<br />

Selbst erstellt<br />

Abbildung 15:Domain Model Selbst erstellt<br />

Abbildung 16: Sequenzdiagramm Filterkriterien<br />

abspeichern<br />

Abbildung 17: Sequenzdiagramm Berechnung<br />

Auslastungsdaten<br />

Selbst erstellt<br />

Selbst erstellt<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 77 von 128


15. Glossar<br />

Begriff Bedeutung<br />

Tabelle 41: Gloassar<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

DI Dependency Injection oder kurz DI ist ein Entwurfsmuster und dient<br />

in einem objektorientierten System dazu, die Abhängigkeiten zwischen<br />

Komponenten oder Objekten zu minimieren.<br />

DTO Ein Data Transfer Object ist ein Entwurfsmuster aus der Softwareentwicklung,<br />

welches gebraucht wird um Daten zwischen Sybsystemen<br />

einer Applikation zu transportieren.<br />

JSF Java Server Faces, oder kurz JSF ist ein Komponentenbasiertes<br />

Präsentationsframework für Java Webanwendungen. Mit Hilfe von<br />

JSF kann der Entwickler auf einfache Art und Weise Komponenten<br />

für Benutzerschnittstellen in Webseiten einbinden und die Navigation<br />

definieren.<br />

JPA Die Java Persistence API oder kurz JPA bietet den Java Entwicklern<br />

die Möglichkeit eines objektorientierten /relationalen Mappings.<br />

Mit Hilfe dieses Mappings ist es möglich relationale Daten in Java-<br />

Anwendungen zu verwalten.<br />

Die Java Persistence API besteht aus drei Bereichen:<br />

- Die Java Persistence API<br />

- Die Abfragesprache<br />

- Object / Relationales Mapping-Metadaten<br />

MVC Model View Controller (MVC) ist ein Muster zur Strukturierung von<br />

Software-Entwicklung in die drei Einheiten Datenmodell, Präsentation<br />

und Programmsteuerung. Ziel des Musters ist ein flexibler Programmentwurf,<br />

der eine spätere Änderung oder Erweiterung erleichtert<br />

und eine Wiederverwendbarkeit der einzelnen Komponenten<br />

ermöglicht.<br />

PrimeFaces PrimeFaces ist eine JSF-Komponentenbibliothek.<br />

Spring Das Spring Framework (kurz Spring) ist ein quelloffenes Framework<br />

für die Java-Plattform. Ziel des Frameworks ist es, die Entwicklung<br />

mit Java/Java EE zu vereinfachen. Spring bietet mit einem breiten<br />

Spektrum an Funktionalität eine ganzheitliche Lösung zur Entwicklung<br />

von Anwendungen und deren Geschäftslogiken. Primäre Features<br />

für Spring sind die Dependency Injection und das Aspekt orientierte<br />

Programmieren.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 78 von 128


16. Unterschriften<br />

Datum Name / OE Unterschrift<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 79 von 128


17. Anhang<br />

17.1 Quellcode<br />

17.1.1 Klassen Web Layer<br />

<strong>Reporting</strong>Model.java<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

* The class <strong>Reporting</strong>Model contains the data, which are used from the<br />

* reporting.xhtml site.<br />

*<br />

* @author seco-sbi, SECO<br />

* @since 1.0.0<br />

*<br />

*/<br />

@Model(scope = Scope.SESSION)<br />

public class <strong>Reporting</strong>Model extends BaseWebEntityModel implements Serializable<br />

{<br />

private static final long serialVersionUID = 1L;<br />

private static final double EMPTY_WORK_HOUR = 0.0;<br />

private List reportingCriterias;<br />

private List resources;<br />

private List projects;<br />

private List projectTasks;<br />

private List tasks;<br />

private boolean ouSelected = false;<br />

private boolean projectSelected = false;<br />

private List headers;<br />

private List dynamicList;<br />

private HtmlPanelGroup tablePanel;<br />

/**<br />

* Constructor<br />

*/<br />

public <strong>Reporting</strong>Model() {<br />

setMode(MODE_DETAIL_EDIT);<br />

}<br />

@Override<br />

public <strong>Reporting</strong>CriteriaDto createNewEntity() {<br />

return new <strong>Reporting</strong>CriteriaDto();<br />

}<br />

public List getResources() {<br />

if (resources == null) {<br />

return new ArrayList();<br />

}<br />

return resources;<br />

}<br />

public void setResources(List resources) {<br />

this.resources = resources;<br />

}<br />

public boolean isOuSelected() {<br />

return ouSelected;<br />

}<br />

public void setOuSelected(boolean ouSelected) {<br />

this.ouSelected = ouSelected;<br />

}<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 80 von 128<br />

public List getProjects() {


public boolean isOuSelected() {<br />

return ouSelected;<br />

}<br />

public void setOuSelected(boolean ouSelected) {<br />

this.ouSelected = ouSelected;<br />

}<br />

public List getProjects() {<br />

return projects;<br />

}<br />

public void setProjects(List projects) {<br />

this.projects = projects;<br />

}<br />

public List get<strong>Reporting</strong>Criterias() {<br />

return reportingCriterias;<br />

}<br />

public void set<strong>Reporting</strong>Criterias(ListreportingC){<br />

this.reportingCriterias = reportingC;<br />

}<br />

public List getProjectTasks() {<br />

if (projectTasks == null) {<br />

return new ArrayList();<br />

} else {<br />

return projectTasks;<br />

}<br />

}<br />

public void setProjectTasks(List projectTasks) {<br />

this.projectTasks = projectTasks;<br />

}<br />

public boolean isProjectSelected() {<br />

return projectSelected;<br />

}<br />

public void setProjectSelected(boolean projectSelected) {<br />

this.projectSelected = projectSelected;<br />

}<br />

public List getTasks() {<br />

if (tasks == null) {<br />

return new ArrayList();<br />

} else {<br />

return tasks;<br />

}<br />

}<br />

public void setTasks(List tasks) {<br />

this.tasks = tasks;<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

public boolean isValueInWorkHourRange(float totalWorkHours) {<br />

if ((double) totalWorkHours >= currentEntity.getWorkHoursFrom() && (double)<br />

totalWorkHours


}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

public boolean isValueInWorkHourRange(float totalWorkHours) {<br />

if ((double) totalWorkHours>=currentEntity.getWorkHoursFrom()&&(double)<br />

totalWorkHours


<strong>Reporting</strong>PersistAction.java<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

* Action for persisting <strong>Reporting</strong>Criteria entities<br />

*<br />

* @author seco-sbi, SECO<br />

* @since 1.0.0<br />

*<br />

*/<br />

@Controller<br />

public class <strong>Reporting</strong>PersistAction extends BasePersistAction<br />

{<br />

private final UserService userService;<br />

private final <strong>Reporting</strong>Validator validator;<br />

private static final int FIRST=0;<br />

/**<br />

* Constructor<br />

*<br />

* @param model<br />

* @param service<br />

* @param validator<br />

*@param userService<br />

*/<br />

@Inject<br />

public <strong>Reporting</strong>PersistAction(<strong>Reporting</strong>Model model, <strong>Reporting</strong>Service service,<br />

UserService userService, <strong>Reporting</strong>Validator validator) {<br />

super(model, service);<br />

this.userService = userService;<br />

this.validator = validator;<br />

}<br />

@Override<br />

protected boolean validateCurrentEntity() {<br />

return validator.validateCurrentEntity();<br />

}<br />

@Override<br />

protected void onPrePersist() {<br />

model.getCurrentEntity().setUser(getActiveUser());<br />

}<br />

@Override<br />

protected String getTargetUrl() {<br />

return Page.REPORTING.getRedirectUrl();<br />

}<br />

private UserDto getActiveUser() {<br />

String activeUserName = SecurityContextHolder.getContext().getAuthentication().getName();<br />

QueryCriteria criteria = new QueryCriteria();<br />

criteria.where("username", activeUserName);<br />

List authUser = userService.find(criteria);<br />

if (authUser == null) {<br />

return null;<br />

}<br />

return authUser.get(FIRST);<br />

}<br />

}<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 83 von 128


<strong>Reporting</strong>EditAction.java<br />

/**<br />

* Action to show or edit an existing <strong>Reporting</strong>CriteriaDto<br />

*<br />

* @author seco-sbi, SECO<br />

* @since 1.0.0<br />

*/<br />

@Controller<br />

public class <strong>Reporting</strong>EditAction extends BaseEditAction {<br />

}<br />

private final <strong>Reporting</strong>Model model;<br />

private final ProjectTaskService projectTaskService;<br />

private final ResourceService resourceService;<br />

/**<br />

* Constructor<br />

* @param model, projectTaskService, resourceService<br />

*/<br />

@Inject<br />

public <strong>Reporting</strong>EditAction(<strong>Reporting</strong>Model model, ProjectTaskService<br />

projectTaskService, ResourceService resourceService) {<br />

super(model);<br />

this.model = model;<br />

this.projectTaskService = projectTaskService;<br />

this.resourceService = resourceService;<br />

}<br />

@Override<br />

protected void executeInternal(<strong>Reporting</strong>CriteriaDto entity) {<br />

model.setCurrentEntity(entity);<br />

model.setOuSelected(true);<br />

fillResources();<br />

if (model.getCurrentEntity().getProject() != null) {<br />

model.setProjectSelected(true);<br />

fillProjectTasks();<br />

}<br />

model.setMode(<strong>Reporting</strong>Model.MODE_SEARCH);<br />

}<br />

public void fillResources() {<br />

model.getResources().clear();<br />

List resources = new ArrayList();<br />

QueryCriteria criteria = new QueryCriteria();<br />

criteria.where("ou", model.getCurrentEntity().getOu());<br />

resources = resourceService.find(criteria);<br />

model.setResources(resources);<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

public void fillProjectTasks() {<br />

model.getProjectTasks().clear();<br />

List projectTasks = new ArrayList();<br />

QueryCriteria criteria = new QueryCriteria();<br />

criteria.where("project", model.getCurrentEntity().getProject());<br />

projectTasks = projectTaskService.find(criteria);<br />

model.setProjectTasks(projectTasks);<br />

}<br />

@Override<br />

protected String getTargetUrl() {<br />

return Page.REPORTING.getRedirectUrl();<br />

}<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 84 von 128


<strong>Reporting</strong>DeleteAction.java<br />

/**<br />

* Action to delete a <strong>Reporting</strong>Criteria entity<br />

*<br />

* @author seco-sbi, seco<br />

* @since 1.0.0<br />

*<br />

*/<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

@Controller<br />

public class <strong>Reporting</strong>DeleteAction extends BaseDeleteAction {<br />

}<br />

private final <strong>Reporting</strong>Model model;<br />

/**<br />

* Constructor<br />

*<br />

* @param model<br />

* @param service<br />

*/<br />

@Inject<br />

public <strong>Reporting</strong>DeleteAction(<strong>Reporting</strong>Model model, <strong>Reporting</strong>Service service) {<br />

super(model, service);<br />

this.model = model;<br />

}<br />

@Override<br />

protected void updateModel(<strong>Reporting</strong>CriteriaDto entity) {<br />

model.get<strong>Reporting</strong>Criterias().remove(entity);<br />

model.setMode(WebEntityModel.MODE_DETAIL_CREATE);<br />

}<br />

@Override<br />

protected String getTargetUrl() {<br />

return Page.REPORTING.getRedirectUrl();<br />

}<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 85 von 128


<strong>Reporting</strong>ClearAction.java<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

* Action to reset the datas in the inputfields of the view.This Action is used to create<br />

new Search.<br />

*<br />

* @author seco-sbi, seco<br />

* @since 1.0.0<br />

*<br />

*/ @Controller<br />

public class <strong>Reporting</strong>ClearAction {<br />

}<br />

private final <strong>Reporting</strong>Model model;<br />

/**<br />

* Constructor<br />

*<br />

* @param model<br />

*<br />

*/<br />

@Inject<br />

public <strong>Reporting</strong>ClearAction(<strong>Reporting</strong>Model model) {<br />

this.model = model;<br />

}<br />

public void execute() {<br />

model.setMode(<strong>Reporting</strong>Model.MODE_SEARCH);<br />

model.setCurrentEntity(new <strong>Reporting</strong>CriteriaDto());<br />

model.setOuSelected(false);<br />

model.setProjectSelected(false);<br />

}<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 86 von 128


<strong>Reporting</strong>CalculateAction.java<br />

/**<br />

* Action to calculate WorkHours for Resources based on the given Filter<br />

* Criterias<br />

*<br />

* @author seco-sbi, SECO<br />

* @since 1.0.0<br />

*<br />

*/<br />

@Controller<br />

public class <strong>Reporting</strong>CalculateAction {<br />

private final ResourceService resourceService;<br />

private final <strong>Reporting</strong>Model reportingModel;<br />

private final ResourcePayloadCalculator calculator;<br />

private final ResourceModel resourceModel;<br />

private final <strong>Reporting</strong>Validator validator;<br />

private static final int WEEK = 2;<br />

private static final int MONTH = 3;<br />

private static final int FIRST_ELEMENT = 0;<br />

private static final float INITIAL_VALUE = 0;<br />

/**<br />

* Constructor<br />

*<br />

* @param model, resourceModel<br />

* @param service, resourceService<br />

* @param calculator, validator<br />

*/<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

@Inject<br />

public <strong>Reporting</strong>CalculateAction(<strong>Reporting</strong>Model model, <strong>Reporting</strong>Service service,<br />

ResourceService resourceService, ResourcePayloadCalculator calculator, ResourceModel<br />

resourceModel, <strong>Reporting</strong>Validator validator) {<br />

}<br />

this.resourceService = resourceService;<br />

this.reportingModel = model;<br />

this.calculator = calculator;<br />

this.resourceModel = resourceModel;<br />

this.validator = validator;<br />

/**<br />

* main method of this Action, which is called from the reporting.xhtml<br />

* site. This method is the only one which can be accessed from an other<br />

* class.(public)<br />

*<br />

* @return the url of the reporting.xhtml page<br />

*/<br />

public String execute() {<br />

if (!validateCurrentEntity()) {<br />

return null;<br />

}<br />

QueryCriteria criteria = createCriteria(reportingModel);<br />

calculateWorkDaysForResource(criteria);<br />

reportingModel.setMode(<strong>Reporting</strong>Model.MODE_DETAIL_RESULT);<br />

return Page.REPORTING.getRedirectUrl();<br />

}<br />

private QueryCriteria createCriteria(<strong>Reporting</strong>Model model) {<br />

QueryCriteria criteria = new QueryCriteria();<br />

criteria.where("ou", reportingModel.getCurrentEntity().getOu());<br />

if (reportingModel.getCurrentEntity().getResource() != null) {<br />

criteria.where("id", reportingMod-<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 87 von 128<br />

el.getCurrentEntity().getResource().getId());<br />

return criteria;


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

private QueryCriteria createCriteria(<strong>Reporting</strong>Model model) {<br />

QueryCriteria criteria = new QueryCriteria();<br />

criteria.where("ou", reportingModel.getCurrentEntity().getOu());<br />

if (reportingModel.getCurrentEntity().getResource() != null) {<br />

criteria.where("id", reportingModel.getCurrentEntity().getResource().getId());<br />

return criteria;<br />

}<br />

return criteria;<br />

}<br />

/**<br />

* calculates the WorkDays or WorkWeeks or WorkMonths for each resource based on the<br />

* given DateRange and FilterCriterias<br />

*<br />

* @param criteria<br />

*/<br />

private void calculateWorkDaysForResource(QueryCriteria criteria) {<br />

<strong>Reporting</strong>CriteriaDto currentEntity = reportingModel.getCurrentEntity();<br />

List resources = new ArrayList();<br />

List resourceReports = new ArrayList();<br />

resources = resourceService.find(criteria);<br />

if (!resources.isEmpty()) {<br />

for (ResourceDto rDto : resources) {<br />

ResourceReport report = new ResourceReport();<br />

resourceModel.setCurrentEntity(rDto);<br />

calculator.calculateDaysInRange(resourceModel,<br />

currentEntity.getStartDate(), currentEntity.getEndDate());<br />

List workDays = new ArrayList();<br />

switch (currentEntity.getMode()) {<br />

case RESOURCE:<br />

workDays = resourceModel.getWorkDays();<br />

case PROJECT:<br />

workDays = calculator.calculateDaysForSpecificProject<br />

(currentEntity.getProject(), resourceModel);<br />

break;<br />

case PROJECT_TASK:<br />

workDays = calculator.calculateDaysForSpecificProjectTask<br />

(currentEntity.getProjectTask(),resourceModel);<br />

break;<br />

case TASK:<br />

workDays = calculator.calculateDaysForSpecificTask<br />

(currentEntity.getTask(), resourceModel);<br />

}<br />

report.setResource(rDto);<br />

}<br />

switch (reportingModel.getCurrentEntity().getGranularity()) {<br />

case WEEK:<br />

report.setWeeks(calculator.calculateHoursForWorkWeeks(workDays));<br />

break;<br />

case MONTH:<br />

report.setMonths(calculator.calculateHoursForWorkMonths(workDays));<br />

break;<br />

default:<br />

report.setDays(workDays);<br />

}<br />

resourceReports.add(report);<br />

if (resourceReports.size() > 1) {<br />

switch (reportingModel.getCurrentEntity().getGranularity()) {<br />

case WEEK:<br />

resourceReports = calculateTotalWorkHoursFor-<br />

Weeks(resourceReports);<br />

break;<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 88 von 128<br />

case MONTH:<br />

resourceReports = calculateTotalWorkHoursFor-


}<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

if (resourceReports.size() > 1) {<br />

switch (reportingModel.getCurrentEntity().getGranularity()) {<br />

case WEEK:<br />

resourceReports = calculateTotalWorkHoursForWeeks(resourceReports);<br />

break;<br />

case MONTH:<br />

resourceReports = calculateTotalWorkHoursForMonths(resourceReports);<br />

break;<br />

default:<br />

resourceReports = calculateTotalWorkHoursForDays(resourceReports);<br />

}<br />

}<br />

}<br />

populateDynamicDataTable(resourceReports);<br />

private boolean isResourceAddable(float totalWorkHours) {<br />

boolean isAddable = false;<br />

if (!reportingModel.isWorkHourRangeEmpty()) {<br />

if (reportingModel.isValueInWorkHourRange(totalWorkHours)) {<br />

isAddable = true;<br />

} else {<br />

isAddable = false;<br />

}<br />

} else {<br />

isAddable = true;<br />

}<br />

return isAddable;<br />

}<br />

private boolean isNotNullWorkhours(float totalWorkHours) {<br />

if (totalWorkHours == 0.0) {<br />

return false;<br />

} else {<br />

return true;<br />

}<br />

}<br />

private float calculateTotalWorkHours(List days) {<br />

float totalWorkHours = INITIAL_VALUE;<br />

for (WorkDay day : days) {<br />

totalWorkHours += day.getWorkHours();<br />

}<br />

return totalWorkHours;<br />

}<br />

private boolean validateCurrentEntity() {<br />

return validator.validateCurrentEntity<br />

}<br />

* @param reports<br />

* @return<br />

*/<br />

private List loadDynamicList(List reports) {<br />

List dynamicList = new ArrayList();<br />

for (ResourceReport report : reports) {<br />

List reportList = new ArrayList();<br />

if (report.getResource() != null) {<br />

reportList.add(report.getResource().getFirstName() + " " + report.getResource().getLastName());<br />

} else {<br />

reportList.add(report.getOu().getName());<br />

Elisa Schnabel }<br />

21.05.<strong>2013</strong> Seite 89 von 128<br />

reportList = report.createListOfWorkhours(reportList);


**<br />

* method to create the Dynamic Result Table<br />

* @param reports<br />

*/<br />

private void populateDynamicDataTable(List reports) {<br />

List dynamicList = loadDynamicList(reports);<br />

List headers = loadHeaders(reports);<br />

HtmlPanelGroup group = reportingModel.getTablePanel();<br />

group.getChildren().clear();<br />

DataTable table = new DataTable();<br />

table.setValueExpression("value",<br />

createValueExpression("#{reportingModel.dynamicList}", List.class));<br />

table.setVar("dynamicItem");<br />

table.setId("resultTbl");<br />

table.setPaginator(true);<br />

table.setRows(10);<br />

table.setStyleClass("dataTable");<br />

table.setPaginatorPosition("bottom");<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

// Iterate over columns.<br />

for (int i = 0; i < dynamicList.get(FIRST_ELEMENT).size(); i++) {<br />

// new Column<br />

Column column = new Column();<br />

column.setValueExpression("sortBy", createValueExpression("#{dynamicItem["<br />

+ i + "]}", Object.class));<br />

table.getChildren().add(column);<br />

// set Header<br />

HtmlOutputText headerText = new HtmlOutputText();<br />

headerText.setValue(headers.get(i));<br />

column.setHeader(headerText);<br />

// setContent<br />

HtmlOutputText output = new HtmlOutputText();<br />

output.setValueExpression("value", createValueExpression("#{dynamicItem[" +<br />

i + "]}", Object.class));<br />

column.getChildren().add(output);<br />

}<br />

reportingModel.setColumnHeaders(headers);<br />

reportingModel.setDynamicList(dynamicList);<br />

group.getChildren().add(table);<br />

}<br />

/**<br />

* method to load the values for the columns of the dynamic DataTable<br />

* @param reports<br />

* @return<br />

*/<br />

private List loadDynamicList(List reports) {<br />

List dynamicList = new ArrayList();<br />

for (ResourceReport report : reports) {<br />

List reportList = new ArrayList();<br />

if (report.getResource() != null) {<br />

reportList.add(report.getResource().getFirstName() + " " +<br />

report.getResource().getLastName());<br />

} else {<br />

reportList.add(report.getOu().getName());<br />

}<br />

reportList = report.createListOfWorkhours(reportList);<br />

dynamicList.add(reportList);<br />

}<br />

return dynamicList; }<br />

Elisa Schnabel<br />

/**<br />

21.05.<strong>2013</strong> Seite 90 von 128<br />

* method to load the headers for the columns of the dynamic Datatable


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

* method to load the headers for the columns of the dynamic Datatable<br />

*<br />

* @param reports<br />

* @return headers<br />

*/<br />

private List loadHeaders(List reports) {<br />

List headers = new ArrayList();<br />

DateFormat formatter = new SimpleDateFormat("dd.MMM.yy");<br />

String cW = "KW";<br />

headers.add("Resource / OE");<br />

if (reports.get(FIRST_ELEMENT).getDays() != null) {<br />

for (WorkDay day : reports.get(FIRST_ELEMENT).getDays()) {<br />

headers.add(formatter.format(day.getDate()));<br />

}<br />

} else if (reports.get(FIRST_ELEMENT).getWeeks() != null) {<br />

for (WorkWeek week : reports.get(FIRST_ELEMENT).getWeeks()) {<br />

headers.add(cW + " " + String.valueOf(week.getCalendarWeek()));<br />

}<br />

} else {<br />

List monthHeaders = getMonthHeaders();<br />

for (WorkMonth month : reports.get(FIRST_ELEMENT).getMonths()) {<br />

headers.add(monthHeaders.get(month.getMonthNumber() - 1));<br />

}<br />

}<br />

return headers;<br />

}<br />

private ValueExpression createValueExpression(String valueExpression, Class valueType) {<br />

FacesContext facesContext = FacesContext.getCurrentInstance();<br />

return facesContext.getApplication().getExpressionFactory()<br />

.createValueExpression(facesContext.getELContext(), valueExpression, valueType);<br />

}<br />

/**<br />

* method to calculate the total of each column.This method is called when<br />

* the Granularity is day<br />

* @param reports<br />

* @return<br />

*/<br />

private List calculateTotalWorkHoursForDays(List reports) {<br />

float currentWorkHours = INITIAL_VALUE;<br />

ResourceReport totalResource = new ResourceReport();<br />

List days = new ArrayList();<br />

}<br />

for (WorkDay day : reports.get(FIRST_ELEMENT).getDays()) {<br />

WorkDay workDay = new WorkDay();<br />

workDay.setDate(day.getDate());<br />

days.add(workDay);<br />

totalResource.setDays(days);<br />

}<br />

int i = 0;<br />

for (WorkDay day : totalResource.getDays()) {<br />

for (ResourceReport report : reports) {<br />

currentWorkHours += report.getDays().get(i).getWorkHours();<br />

}<br />

day.setWorkHours(currentWorkHours);<br />

currentWorkHours = INITIAL_VALUE;<br />

i++;<br />

}<br />

totalResource.setOu(reports.get(FIRST_ELEMENT).getResource().getOu());<br />

reports.add(totalResource);<br />

return reports;<br />

/** Elisa Schnabel 21.05.<strong>2013</strong> Seite 91 von 128<br />

* method to calculate the total of each column. This method is called when


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

* method to calculate the total of each column. This method is called when<br />

* the Granularity is week<br />

* @param reports<br />

* @return<br />

*/<br />

private List calculateTotalWorkHoursForWeeks(List reports) {<br />

float currentWorkHours = INITIAL_VALUE;<br />

ResourceReport totalResource = new ResourceReport();<br />

List workWeeks = new ArrayList();<br />

for (WorkWeek week : reports.get(FIRST_ELEMENT).getWeeks()) {<br />

WorkWeek workWeek = new WorkWeek();<br />

workWeek.setCalendarWeek(week.getCalendarWeek());<br />

workWeeks.add(workWeek);<br />

totalResource.setWeeks(workWeeks);<br />

}<br />

int i = 0;<br />

for (WorkWeek week : totalResource.getWeeks()) {<br />

for (ResourceReport report : reports) {<br />

currentWorkHours += report.getWeeks().get(i).getWorkHours();<br />

}<br />

week.setWorkHours(currentWorkHours);<br />

currentWorkHours = INITIAL_VALUE;<br />

i++;<br />

}<br />

totalResource.setOu(reports.get(FIRST_ELEMENT).getResource().getOu());<br />

reports.add(0, totalResource);<br />

return reports;<br />

}<br />

/**<br />

* method to calculate the total of each column. This method is called when<br />

* the Granularity is month<br />

* @param reports<br />

* @return<br />

*/<br />

private List calculateTotalWorkHoursForMonths(List reports) {<br />

float currentWorkHours = INITIAL_VALUE;<br />

ResourceReport totalResource = new ResourceReport();<br />

List workMonths = new ArrayList();<br />

}<br />

}<br />

for (WorkMonth month : reports.get(FIRST_ELEMENT).getMonths()) {<br />

WorkMonth workMonth = new WorkMonth();<br />

workMonth.setMonthNumber(month.getMonthNumber());<br />

workMonths.add(workMonth);<br />

totalResource.setMonths(workMonths);<br />

}<br />

int i = 0;<br />

for (WorkMonth month : totalResource.getMonths()) {<br />

for (ResourceReport report : reports) {<br />

currentWorkHours += report.getMonths().get(i).getWorkHours();<br />

}<br />

month.setWorkHours(currentWorkHours);<br />

currentWorkHours = INITIAL_VALUE;<br />

i++;<br />

}<br />

totalResource.setOu(reports.get(FIRST_ELEMENT).getResource().getOu());<br />

reports.add(0, totalResource);<br />

return reports;<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 92 von 128


<strong>Reporting</strong>Validator.java<br />

/**<br />

* validates the <strong>Reporting</strong>CriteriaDto fields<br />

*<br />

* @author seco-sbi, SECO<br />

* @since 1.0.0<br />

*<br />

*/<br />

@Controller<br />

public class <strong>Reporting</strong>Validator {<br />

private final <strong>Reporting</strong>Model model;<br />

/**<br />

* Constructor<br />

*<br />

* @param model<br />

*/<br />

@Inject<br />

public <strong>Reporting</strong>Validator(<strong>Reporting</strong>Model model) {<br />

this.model = model;<br />

}<br />

public boolean validateCurrentEntity() {<br />

boolean valid = true;<br />

<strong>Reporting</strong>CriteriaDto currentEntity = model.getCurrentEntity();<br />

valid &= validateCurrentEntityNotNull(currentEntity);<br />

valid &= validateStartTime(currentEntity);<br />

valid &= validateEndTime(currentEntity);<br />

valid &= validateOu(currentEntity);<br />

valid &= validateGranularity(currentEntity);<br />

valid &= validateWorkHours(currentEntity);<br />

return valid;<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

* @param currentEntity<br />

* @return true if the currentEntity is not null<br />

*/<br />

private boolean validateCurrentEntityNotNull(<strong>Reporting</strong>CriteriaDto currentEntity) {<br />

if (currentEntity == null) {<br />

MessageHelper.putErrorMsg("system.error.msg.general");<br />

return false;<br />

}<br />

return true;<br />

}<br />

/**<br />

*<br />

* @param currentEntity<br />

* @return true if the startDate is not null<br />

*/<br />

private boolean validateStartTime(<strong>Reporting</strong>CriteriaDto currentEntity) {<br />

if (currentEntity.getStartDate() == null) {<br />

MessageHelper.putErrorMsg("reporting.validation.msg.missingStartTime");<br />

return false;<br />

}<br />

return true;<br />

}<br />

/**<br />

*<br />

* @param currentEntity<br />

* @return true if the endDate is not null and not before the startDate<br />

Elisa */ Schnabel 21.05.<strong>2013</strong> Seite 93 von 128<br />

private boolean validateEndTime(<strong>Reporting</strong>CriteriaDto currentEntity) {


}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

*<br />

* @param currentEntity<br />

* @return true if the endDate is not null and not before the startDate<br />

*/<br />

private boolean validateEndTime(<strong>Reporting</strong>CriteriaDto currentEntity) {<br />

if (currentEntity.getEndDate() == null) {<br />

MessageHelper.putErrorMsg("reporting.validation.msg.missingEndTime");<br />

return false;<br />

}<br />

if (currentEntity.getStartDate() != null) {<br />

int result = currentEntity.getStartDate().compareTo(currentEntity.getEndDate());<br />

if (result workHoursFrom<br />

*/<br />

private boolean validateWorkHours(<strong>Reporting</strong>CriteriaDto currentEntity) {<br />

if (currentEntity.getWorkHoursFrom() == 0.0 && currentEntity.getWorkHoursTo() != 0.0) {<br />

MessageHelper.putErrorMsg("reporting.validation.msg.workHoursFrom");<br />

return false;<br />

}<br />

if (currentEntity.getWorkHoursTo() < currentEntity.getWorkHoursFrom()) {<br />

MessageHelper.putErrorMsg("reporting.validation.msg.workHoursTo");<br />

return false;<br />

}<br />

return true;<br />

}<br />

/**<br />

*<br />

* @param currentEntity<br />

* @return true if the granularity is not null<br />

*/<br />

private boolean validateGranularity(<strong>Reporting</strong>CriteriaDto currentEntity) {<br />

if (currentEntity.getGranularity() == 0) {<br />

MessageHelper.putErrorMsg("reporting.validation.msg.granularity");<br />

return false;<br />

}<br />

return true;<br />

}<br />

private void calculateWorkDaysForResource(QueryCriteria criteria) {<br />

Elisa Schnabel <strong>Reporting</strong>CriteriaDto currentEntity 21.05.<strong>2013</strong> = reportingModel.getCurrentEntity(); Seite 94 von 128<br />

List resources = new ArrayList();<br />

List resourceReports = new ArrayList();


<strong>Reporting</strong>PreRenderViewListener.java<br />

/**<br />

* Listener to be called before the reporting.xhtml view is rendered.Fills the<br />

* DataTabele with the <strong>Reporting</strong>Criteria Sets from the active user and fills the<br />

* dropdowns ou an project.<br />

*<br />

* @author seco-sbi<br />

* @since 1.0.0<br />

*/<br />

@Controller<br />

public class <strong>Reporting</strong>PreRenderViewListener {<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

private final CommonCodesModel codesModel;<br />

private final OrganizationalUnitService ouService;<br />

private final <strong>Reporting</strong>Model reportingModel;<br />

private final ProjectService projectService;<br />

private final <strong>Reporting</strong>Service reportingService;<br />

private final UserService userService;<br />

/**<br />

* Constructor<br />

*<br />

* @param codesModel, reportingModel<br />

* @param ouService, projectService, reportingService<br />

*/<br />

@Inject<br />

public <strong>Reporting</strong>PreRenderViewListener(CommonCodesModel codesModel,<br />

OrganizationalUnitService ouService,<strong>Reporting</strong>Model reportingModel, ProjectService<br />

projectService, <strong>Reporting</strong>Service reportingService, UserService userService) {<br />

this.codesModel = codesModel;<br />

this.ouService = ouService;<br />

this.reportingModel = reportingModel;<br />

this.projectService = projectService;<br />

this.reportingService = reportingService;<br />

this.userService = userService;<br />

}<br />

public void execute() {<br />

if (!FacesContext.getCurrentInstance().isPostback()) {<br />

loadOrganizationalUnits();<br />

loadProjects();<br />

load<strong>Reporting</strong>Criterias();<br />

}<br />

}<br />

private void loadOrganizationalUnits() {<br />

if (codesModel.getOus().isEmpty()) {<br />

Map map = new HashMap();<br />

for (OrganizationalUnitDto ou : ouService.getAll()) {<br />

map.put(ou.getId(), ou);<br />

}<br />

codesModel.setOus(map);<br />

}<br />

}<br />

private void loadProjects() {<br />

List projects = new ArrayList();<br />

for (ProjectDto project : projectService.getAll()) {<br />

projects.add(project);<br />

}<br />

reportingModel.setProjects(projects);<br />

}<br />

private void load<strong>Reporting</strong>Criterias() {<br />

Elisa Schnabel List criterias 21.05.<strong>2013</strong> = new ArrayList();<br />

Seite 95 von 128<br />

QueryCriteria criteria = new QueryCriteria();


}<br />

private void loadProjects() {<br />

List projects = new ArrayList();<br />

for (ProjectDto project : projectService.getAll()) {<br />

projects.add(project);<br />

}<br />

reportingModel.setProjects(projects);<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

private void load<strong>Reporting</strong>Criterias() {<br />

List criterias = new ArrayList();<br />

QueryCriteria criteria = new QueryCriteria();<br />

criteria.where("user", getActiveUser());<br />

criterias = reportingService.find(criteria);<br />

reportingModel.set<strong>Reporting</strong>Criterias(criterias);<br />

}<br />

/**<br />

* @return the active user.<br />

*/<br />

private UserDto getActiveUser() {<br />

String name = SecurityContextHolder.getContext().getAuthentication().getName();<br />

QueryCriteria userCriteria = new QueryCriteria();<br />

userCriteria.where("username", name);<br />

List user = userService.find(userCriteria);<br />

return user.get(FIRST);<br />

}<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 96 von 128


<strong>Reporting</strong>ValueChangeListenerOu.java<br />

/**<br />

* Listener to be called when a new ou is selected. Fills the resource dropdown<br />

* depending on the selected ou.<br />

*<br />

* @author seco-sbi<br />

* @since 1.0.0<br />

*<br />

*/<br />

@Controller<br />

public class <strong>Reporting</strong>ValueChangelistenerOu {<br />

}<br />

private final <strong>Reporting</strong>Model reportingModel;<br />

private final ResourceService resourceService;<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

@Inject<br />

public <strong>Reporting</strong>ValueChangelistenerOu(<strong>Reporting</strong>Model reportingModel, ResourceService<br />

resourceService) {<br />

this.reportingModel = reportingModel;<br />

this.resourceService = resourceService;<br />

}<br />

public void execute() {<br />

OrganizationalUnitDto selectedOu = reportingModel.getCurrentEntity().getOu();<br />

if (selectedOu != null) {<br />

reportingModel.setOuSelected(true);<br />

reportingModel.getResources().clear();<br />

reportingModel.setResources(loadResources(selectedOu));<br />

} else {<br />

reportingModel.setOuSelected(false);<br />

}<br />

}<br />

private List loadResources(OrganizationalUnitDto selectedOu) {<br />

List resources = new ArrayList();<br />

QueryCriteria criteria = new QueryCriteria();<br />

criteria.where("ou", selectedOu);<br />

resources = resourceService.find(criteria);<br />

return resources;<br />

}<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 97 von 128


<strong>Reporting</strong>ValueChangeListenerProject.java<br />

/**<br />

* Listener to be called when a new project is selected. Fills the ProjectTask<br />

* dropdown depending on the selected project.<br />

*<br />

* @author seco-sbi<br />

* @since 1.0.0<br />

*<br />

*/<br />

@Controller<br />

public class <strong>Reporting</strong>ValueChangelistenerProject {<br />

}<br />

private final <strong>Reporting</strong>Model repModel;<br />

private final ProjectTaskService taskService;<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

@Inject<br />

public <strong>Reporting</strong>ValueChangelistenerProject(<strong>Reporting</strong>Model repModel, ProjectTaskService<br />

taskService) {<br />

this.repModel = repModel;<br />

this.taskService = taskService;<br />

}<br />

public void execute(){<br />

ProjectDto selected = repModel.getCurrentEntity().getProject();<br />

if (selected != null) {<br />

repModel.setProjectSelected(true);<br />

if (!repModel.getProjectTasks().isEmpty()) {<br />

repModel.getProjectTasks().clear();<br />

}<br />

repModel.setProjectTasks(loadProjectTasks(selected));<br />

} else {<br />

repModel.setProjectSelected(false);<br />

}<br />

}<br />

private List loadProjectTasks(ProjectDto selected) {<br />

List projectTasks = new ArrayList();<br />

QueryCriteria criteria = new QueryCriteria();<br />

criteria.where("project", selected);<br />

projectTasks = taskService.find(criteria);<br />

return projectTasks;<br />

}<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 98 von 128


<strong>Reporting</strong>ValueChangeListenerDate.java<br />

/**<br />

* Listener to be called when a radio button Date is selected. Fills the fields<br />

* startDate, endDate depending on the selected radio button.<br />

*<br />

* @author seco-sbi<br />

* @since 1.0.0<br />

*<br />

*/@Controller<br />

public class <strong>Reporting</strong>ValueChangelistenerDate {<br />

}<br />

private final <strong>Reporting</strong>Model reportingModel;<br />

public static final int CURRENT_DAY = 1;<br />

public static final int CURRENT_WEEK = 2;<br />

public static final int CURRENT_MONTH = 3;<br />

public static final int CURRENT_YEAR = 4;<br />

public static final int NO_SELECTION = 0;<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

@Inject<br />

public <strong>Reporting</strong>ValueChangelistenerDate(<strong>Reporting</strong>Model repModel) {<br />

this.reportingModel = repModel;<br />

}<br />

public void execute(AjaxBehaviorEvent e) {<br />

<strong>Reporting</strong>CriteriaDto currentEntity = reportingModel.getCurrentEntity();<br />

int value = currentEntity.getRadioDate();<br />

DateRange dateRange=null;<br />

switch (value) {<br />

case CURRENT_DAY:<br />

dateRange = DateHelper.getCurrentDayRange();<br />

break;<br />

case CURRENT_WEEK:<br />

dateRange = DateHelper.getCurrentWeek();<br />

break;<br />

case CURRENT_MONTH:<br />

dateRange = DateHelper.getCurrentMonth();<br />

break;<br />

case CURRENT_YEAR:<br />

dateRange = DateHelper.getCurrentYear();<br />

break;<br />

default: {<br />

throw new IllegalArgumentException(String.format("Undefined range: %d", value));<br />

}<br />

}<br />

currentEntity.setStartDate(dateRange.getStartDate());<br />

currentEntity.setEndDate(dateRange.getEndDate());<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 99 von 128


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

ResourcePayloadCalculator.java<br />

(Die nachfolgende Klasse wurde nicht im Rahmen des Moduls <strong>ResMan</strong> <strong>Reporting</strong> erstellt,<br />

aber um ein paar Methoden erweitert. Entsprechende Codeabschnitte wurden gekennzeichnet.)<br />

/**<br />

* Utility class for resource calculation matters.<br />

*<br />

* @author seco-gid, SECO<br />

* @since 1.0.0<br />

*<br />

*/<br />

@Controller<br />

public class ResourcePayloadCalculator {<br />

private final HolidayService holidayService;<br />

@Inject<br />

public ResourcePayloadCalculator(HolidayService holidayService) {<br />

this.holidayService = holidayService;<br />

}<br />

/**<br />

*<br />

* @param model<br />

* @param start<br />

* @param end<br />

*/<br />

public void calculateDaysInRange(ResourceModel model) {<br />

calculateDaysInRange(model, model.getRange().getStartDate(), model.getRange().getEndDate());<br />

}<br />

/**<br />

*<br />

* @param model<br />

* @param start<br />

* @param end<br />

*/<br />

public void calculateDaysInRange(ResourceModel model, Date start, Date end) {<br />

List workDays = model.getWorkDays();<br />

workDays.clear();<br />

Date currentDate = start;<br />

Calendar cal = Calendar.getInstance();<br />

cal.setTime(currentDate);<br />

if (end == null) {<br />

end = start;<br />

}<br />

while (!currentDate.after(end)) {<br />

if ((cal.get(Calendar.DAY_OF_WEEK) != 1 && cal.get(Calendar.DAY_OF_WEEK) != 7) || model.isDisplayWeekends())<br />

{<br />

workDays.add(calculateDay(model, currentDate));<br />

}<br />

cal.setTime(currentDate);<br />

cal.add(Calendar.DAY_OF_YEAR, 1);<br />

currentDate = cal.getTime();<br />

}<br />

}<br />

/**<br />

*<br />

* @param model<br />

* @param date<br />

* @return WorkDay<br />

*/<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 100 von 128<br />

public WorkDay calculateDay(ResourceModel model, Date date) {<br />

ResourceDto currentEntity = model.getCurrentEntity();


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

*<br />

* @param model<br />

* @param date<br />

* @return WorkDay<br />

*/<br />

public WorkDay calculateDay(ResourceModel model, Date date) {<br />

ResourceDto currentEntity = model.getCurrentEntity();<br />

List payloads = new ArrayList();<br />

List absences = new ArrayList();<br />

float totalWorkHours = 0;<br />

WorkDay day = new WorkDay();<br />

day.setCapacity(calculateMaxDailyCapacity(model.getCurrentEntity()));<br />

checkForPartTimeAbsences(date, currentEntity, totalWorkHours, day);<br />

day.setDate(date);<br />

totalWorkHours = checkForTasks(date, currentEntity, payloads, totalWorkHours);<br />

totalWorkHours = checkForProjectTasks(date, currentEntity, payloads, totalWorkHours);<br />

day.setWorkHours(totalWorkHours);<br />

checkForAbsences(date, currentEntity, absences, day);<br />

checkForWeekendOrHoliday(date, day);<br />

day.setPayloads(payloads);<br />

day.setAbsences(absences);<br />

return day;<br />

}<br />

/**<br />

*<br />

* @param date<br />

* @param currentEntity<br />

* @param payloads<br />

* @param totalWorkHours<br />

* @return<br />

*/<br />

private float checkForTasks(Date date, ResourceDto currentEntity, List payloads,<br />

float totalWorkHours) {<br />

if (CollectionUtils.isNotEmpty(currentEntity.getTasks())) {<br />

for (TaskDto task : currentEntity.getTasks()) {<br />

if (DateHelper.isDateInRange(date, task.getStartDate(), task.getEndDate())) {<br />

if (!DateHelper.isWeekend(date) || task.isWeekendRelevant()) {<br />

ExceptionalDateRangeDto exception = null;<br />

if (CollectionUtils.isNotEmpty(task.getExceptions())) {<br />

exception = DateHelper.getExceptionOn(task.getExceptions(), date);<br />

}<br />

if (exception == null) {<br />

totalWorkHours += task.getWorkHours();<br />

}<br />

else {<br />

totalWorkHours += exception.getWorkHours();<br />

}<br />

payloads.add(task);<br />

}<br />

}<br />

}<br />

}<br />

return totalWorkHours;<br />

}<br />

/**<br />

*<br />

* @param date<br />

* @param currentEntity<br />

* @param payloads<br />

* @param totalWorkHours<br />

* @return<br />

*/<br />

private float checkForProjectTasks(Date date, ResourceDto currentEntity, List<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 101 von 128<br />

payloads,<br />

float totalWorkHours) {


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

*<br />

* @param date<br />

* @param currentEntity<br />

* @param payloads<br />

* @param totalWorkHours<br />

* @return<br />

*/<br />

private float checkForProjectTasks(Date date, ResourceDto currentEntity, List<br />

payloads,<br />

float totalWorkHours) {<br />

if (CollectionUtils.isNotEmpty(currentEntity.getProjectTasks())) {<br />

for (ProjectTaskDto projectTask : currentEntity.getProjectTasks()) {<br />

if (DateHelper.isDateInRange(date, projectTask.getStartDate(),<br />

projectTask.getEndDate())) {<br />

if (!DateHelper.isWeekend(date) || projectTask.isWeekendRelevant()) {<br />

ExceptionalDateRangeDto exception = null;<br />

if (CollectionUtils.isNotEmpty(projectTask.getExceptions())) {<br />

exception = DateHelper.getExceptionOn(projectTask.getExceptions(), date);<br />

}<br />

if (exception != null) {<br />

totalWorkHours += exception.getWorkHours();<br />

}<br />

else {<br />

totalWorkHours += projectTask.getWorkHours();<br />

}<br />

payloads.add(projectTask);<br />

}<br />

}<br />

}<br />

}<br />

return totalWorkHours;<br />

}<br />

/**<br />

*<br />

*@param date<br />

*@param currentEntity<br />

*@param day<br />

*/<br />

private void checkForAbsences(Date date, ResourceDto currentEntity, List absences,<br />

WorkDay day) {<br />

if (CollectionUtils.isNotEmpty(currentEntity.getAbsences())) {<br />

for (AbsenceDto absence : currentEntity.getAbsences()) {<br />

if (DateHelper.isDateInRange(date, absence.getStartDate(), absence.getEndDate())) {<br />

day.setCapacity(day.getCapacity() - absence.getWorkHours());<br />

absences.add(absence);<br />

}<br />

}<br />

}<br />

if (day.getCapacity() < 0F) {<br />

day.setCapacity(0F);<br />

}<br />

}<br />

/**<br />

*<br />

*@param date<br />

*@param currentEntity<br />

*@param totalWorkHours<br />

*@param day<br />

*/<br />

private void checkForPartTimeAbsences(Date date, ResourceDto currentEntity, float totalWork-<br />

Hours, WorkDay day) {<br />

if (currentEntity.getPartTimeAbsence() Elisa Schnabel == null) 21.05.<strong>2013</strong> {<br />

Seite 102 von 128<br />

return;<br />

}


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

private void checkForWeekendOrHoliday(Date date, WorkDay day) {<br />

if (DateHelper.isWeekend(date)) {<br />

day.setCapacity(0F);<br />

}<br />

else {<br />

HolidayDto holidayDay = holidayService.findHoliday(date);<br />

if (holidayDay != null) {<br />

day.setCapacity((day.getCapacity() * (100 - holidayDay.getPercentage())) / 100);<br />

}<br />

}<br />

}<br />

/**<br />

*<br />

* @param resource<br />

* @param workDays<br />

* @return a list containing workdays that exceeds the capacity<br />

*/<br />

public List calculateOverloadedWorkDays(ResourceDto resource, List workDays) {<br />

List list = new ArrayList();<br />

if (resource != null<br />

&& resource.getLevelOfEmployment() != null) {<br />

for (WorkDay workDay : workDays) {<br />

if (workDay.getWorkHours() > resource.getLevelOfEmployment()) {<br />

list.add(workDay);<br />

}<br />

}<br />

}<br />

return list;<br />

}<br />

/**<br />

*<br />

* @param resource<br />

* @return the maxDailyCapacity<br />

*/<br />

public float calculateMaxDailyCapacity(ResourceDto resource) {<br />

int hoursPerWeek = resource.getWorkingPattern().getHoursPerWeek();<br />

int numberOfWorkDays = 5;<br />

}<br />

if (resource.getPartTimeAbsence().isMonday()) {<br />

numberOfWorkDays--;<br />

}<br />

if (resource.getPartTimeAbsence().isTuesday()) {<br />

numberOfWorkDays--;<br />

}<br />

if (resource.getPartTimeAbsence().isWednesday()) {<br />

numberOfWorkDays--;<br />

}<br />

if (resource.getPartTimeAbsence().isThursday()) {<br />

numberOfWorkDays--;<br />

}<br />

if (resource.getPartTimeAbsence().isFriday()) {<br />

numberOfWorkDays--;<br />

}<br />

if (numberOfWorkDays == 0) {<br />

return 0;<br />

}<br />

return (hoursPerWeek * (float) resource.getLevelOfEmployment()) / (numberOfWorkDays * 100F);<br />

public List calculateHoursForWorkWeeks(List workDays) {<br />

List weeks = new ArrayList();<br />

float workHours = 0;<br />

int currentWeek = 0, nextWeek = 0;<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 103 von 128<br />

for (WorkDay day : workDays) {<br />

nextWeek = DateHelper.getWeekOfYear(day.getDate());


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

--------------Codeabschnitt Elisa Schnabel --------------<br />

/**<br />

* calculates the total workhours for workweeks based on the given list of workdays<br />

* @param workDays<br />

* @return the list of calculated workweeks<br />

*/<br />

public List calculateHoursForWorkWeeks(List workDays) {<br />

List weeks = new ArrayList();<br />

float workHours = 0;<br />

int currentWeek = 0, nextWeek = 0;<br />

for (WorkDay day : workDays) {<br />

nextWeek = DateHelper.getWeekOfYear(day.getDate());<br />

if (currentWeek < nextWeek && currentWeek != 0 || day.isLast(workDays) ||<br />

nextWeek < currentWeek) {<br />

WorkWeek week = new WorkWeek();<br />

week.setCalendarWeek(currentWeek);<br />

weeks.add(week);<br />

if (day.isLast(workDays)) {<br />

workHours += day.getWorkHours();<br />

}<br />

week.setWorkHours(workHours);<br />

workHours = 0;<br />

}<br />

currentWeek = DateHelper.getWeekOfYear(day.getDate());<br />

workHours += day.getWorkHours();<br />

}<br />

return weeks; }<br />

/**<br />

* calculates the total of workhours for workmonths based on the given list of workdays<br />

* @param workDays<br />

* @return the list of calculated workmonths<br />

*/<br />

public List calculateHoursForWorkMonths(List workDays) {<br />

List months = new ArrayList();<br />

float workHours = 0;<br />

int currentMonth = 0, nextMonth = 0;<br />

for (WorkDay day : workDays) {<br />

nextMonth = DateHelper.getMonthOfYear(day.getDate());<br />

if (currentMonth < nextMonth && currentMonth != 0 || day.isLast(workDays) ||<br />

nextMonth < currentMonth){<br />

WorkMonth month = new WorkMonth();<br />

month.setMonthNumber(currentMonth);<br />

if (day.isLast(workDays)) {<br />

workHours += day.getWorkHours();<br />

}<br />

month.setWorkHours(workHours);<br />

workHours = 0;<br />

months.add(month);<br />

}<br />

currentMonth = DateHelper.getMonthOfYear(day.getDate());<br />

workHours += day.getWorkHours();<br />

}<br />

return months; }<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 104 von 128


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

* calculates the workHours for each workday based on the given project<br />

* @param project<br />

* @param model<br />

* @return the list of calculated workdays for the given project<br />

*/<br />

public List calculateDaysForSpecificProject(ProjectDto project, ResourceModel model){<br />

List workDays = new ArrayList();<br />

float totalWorkHours=0;<br />

boolean containsProjectTask =false;<br />

for (WorkDay day : model.getWorkDays()) {<br />

for(PayLoadDto payload : day.getPayloads()){<br />

if(payload instanceof ProjectTaskDto &&<br />

((ProjectTaskDto)payload).getProject().equals(project)){<br />

containsProjectTask=true;<br />

totalWorkHours += payload.getWorkHours();<br />

}else{<br />

continue;<br />

}<br />

}<br />

if(containsProjectTask == true){<br />

day.setWorkHours(totalWorkHours);<br />

totalWorkHours=0;<br />

containsProjectTask=false;<br />

}else{<br />

day.setWorkHours(0);<br />

}<br />

workDays.add(day);<br />

}<br />

return workDays;<br />

}<br />

/**<br />

* calculates the workHours for each workday based on the given projecttask<br />

* @param projectTask<br />

* @param model<br />

* @return the list of calculated workdays for the given projecttaks<br />

*/<br />

public List calculateDaysForSpecificProjectTask(ProjectTaskDto projectTask, Resource<br />

Model model){<br />

List workDays = new ArrayList();<br />

boolean containsProjectTask =false;<br />

float totalWorkHours=0;<br />

for (WorkDay day : model.getWorkDays()) {<br />

for(PayLoadDto payload : day.getPayloads()){<br />

if(payload instanceof ProjectTaskDto &&<br />

((ProjectTaskDto)payload).equals(projectTask)){<br />

totalWorkHours += payload.getWorkHours();<br />

containsProjectTask=true;<br />

}else{<br />

continue;<br />

}<br />

}<br />

if(containsProjectTask == true){<br />

day.setWorkHours(totalWorkHours);<br />

totalWorkHours=0;<br />

containsProjectTask=false;<br />

}else{<br />

day.setWorkHours(0);<br />

}<br />

workDays.add(day);<br />

}<br />

return workDays; }<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 105 von 128


**<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

* calculates the workHours for each workday based on the given task<br />

* @param task<br />

* @param model<br />

* @return the list of calculated workdays for the given task<br />

*/<br />

public List calculateDaysForSpecificTask(TaskDto task, ResourceModel model) {<br />

List workDays = new ArrayList();<br />

boolean containsTask = false;<br />

float totalWorkHours = 0;<br />

for (WorkDay day : model.getWorkDays()) {<br />

for (PayLoadDto payload : day.getPayloads()) {<br />

if (payload instanceof TaskDto && ((TaskDto) payload).equals(task)) {<br />

totalWorkHours += payload.getWorkHours();<br />

containsTask = true;<br />

} else {<br />

continue;<br />

}<br />

}<br />

if (containsTask == true) {<br />

day.setWorkHours(totalWorkHours);<br />

totalWorkHours = 0;<br />

containsTask = false;<br />

} else {<br />

day.setWorkHours(0);<br />

}<br />

workDays.add(day);<br />

}<br />

return workDays;<br />

}<br />

}<br />

--------------Codeabschnitt Elisa Schnabel --------------<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 106 von 128


TaskAutocomplete.java<br />

/**<br />

* Backing bean for Primefaces Autocompleter Task<br />

*<br />

* @author seco-sbi,<br />

* @since 1.0.0<br />

*<br />

*/<br />

@Controller<br />

public class TaskAutocomplete {<br />

}<br />

private final TaskService service;<br />

/**<br />

* Constructor<br />

*<br />

* @param service<br />

*/<br />

@Inject<br />

public TaskAutocomplete(TaskService service) {<br />

this.service = service;<br />

}<br />

/**<br />

*<br />

* @param query<br />

* @return a list of matching (title) task<br />

*/<br />

public List complete(String query) {<br />

query = query.trim();<br />

List hits = null;<br />

hits = service.findByTitle(query);<br />

if (hits != null) {<br />

return hits;<br />

}else{<br />

return null;<br />

}<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 107 von 128


<strong>Reporting</strong>.xhtml<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

&nbsp;<br />

<br />

Elisa Schnabel <br />

21.05.<strong>2013</strong> Seite 108 von 128


/><br />

/><br />

/><br />

/><br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

<br />

&nbsp;<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 110 von 128<br />


<strong>IPA</strong>-<strong>Dokumentation</strong><br />


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

-<br />

<br />

Elisa Schnabel 112 von 128<br />

<br />


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

&nbsp;<br />

&nbsp;<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 113 von 128


17.1.2 Klassen Service Layer<br />

<strong>Reporting</strong>Service.java<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

* service Interface for <strong>Reporting</strong><br />

*<br />

* @author seco-sbi, SECO<br />

* @since 1.0.0<br />

*<br />

*/<br />

public interface <strong>Reporting</strong>Service extends PersistenceService {<br />

}<br />

Default<strong>Reporting</strong>Service.java<br />

/**<br />

* Service for <strong>Reporting</strong><br />

* @author seco-sbi, SECO<br />

* @since 1.0.0<br />

*/<br />

@Service<br />

public class Default<strong>Reporting</strong>Service extends BasePersistenceService implements<br />

<strong>Reporting</strong>Service {<br />

/**<br />

* Constructor<br />

*<br />

* @param repository<br />

* @param mapper<br />

*/<br />

@Inject<br />

public Default<strong>Reporting</strong>Service(<strong>Reporting</strong>Repository repository, Mapper mapper) {<br />

super(mapper, repository, <strong>Reporting</strong>CriteriaDto.class, <strong>Reporting</strong>Criteria.class);<br />

}<br />

@Override<br />

public <strong>Reporting</strong>CriteriaDto save(<strong>Reporting</strong>CriteriaDto dto) {<br />

return saveInternal(dto);<br />

}<br />

@Override<br />

public <strong>Reporting</strong>CriteriaDto getById(Integer id) {<br />

return getByIdInternal(id);<br />

}<br />

@Override<br />

public List find(QueryCriteria criteria) {<br />

List dtos = new ArrayList();<br />

if (criteria == null) {<br />

return dtos;<br />

}<br />

Object userDto = criteria.getCriterionValue("user");<br />

if(userDto !=null){<br />

criteria.replaceCriterionValue("user", mapper.mapObject(userDto, User.class));<br />

}<br />

List criterias = repository.find(criteria);<br />

if (criterias != null && !criterias.isEmpty()) {<br />

dtos = mapper.mapCollection(criterias, <strong>Reporting</strong>CriteriaDto.class);<br />

}<br />

return dtos; }<br />

@Override<br />

public void remove(<strong>Reporting</strong>CriteriaDto dto) {<br />

removeInternal(dto);<br />

}<br />

}<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 114 von 128


<strong>Reporting</strong>CriteriaDto.java<br />

/**<br />

* Data transfer Object for <strong>Reporting</strong>Criteria<br />

* @author seco-sbi, SECO<br />

* @since 1.0.0<br />

*<br />

*/<br />

public class <strong>Reporting</strong>CriteriaDto extends BaseResmanDto {<br />

private Integer id;<br />

private Date startDate;<br />

private Date endDate;<br />

private OrganizationalUnitDto ou;<br />

private ResourceDto resource;<br />

private ProjectDto project;<br />

private UserDto user;<br />

private ProjectTaskDto projectTask;<br />

private TaskDto task;<br />

private double workHoursFrom;<br />

private double workHoursTo;<br />

private int granularity;<br />

private float totalWorkHours;<br />

public enum Mode {<br />

RESOURCE, PROJECT_TASK, PROJECT, TASK<br />

}<br />

@Override<br />

public Integer getId() {<br />

return id;<br />

}<br />

@Override<br />

public void setId(Integer id) {<br />

this.id = id;<br />

}<br />

public Date getStartDate() {<br />

return startDate;<br />

}<br />

public void setStartDate(Date startDate) {<br />

this.startDate = startDate;<br />

}<br />

public Date getEndDate() {<br />

return endDate;<br />

}<br />

public void setEndDate(Date endDate) {<br />

this.endDate = endDate;<br />

}<br />

public OrganizationalUnitDto getOu() {<br />

return ou;<br />

}<br />

public void setOu(OrganizationalUnitDto ou) {<br />

this.ou = ou;<br />

}<br />

public ResourceDto getResource() {<br />

return resource;<br />

}<br />

public void setResource(ResourceDto resource) {<br />

this.resource = resource;<br />

}<br />

public ProjectDto getProject() {<br />

return project;<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

public Elisa Schnabel void setProject(ProjectDto project) 21.05.<strong>2013</strong> {<br />

Seite 115 von 128<br />

this.project = project;


}<br />

public ProjectDto getProject() {<br />

return project;<br />

}<br />

public void setProject(ProjectDto project) {<br />

this.project = project;<br />

}<br />

public UserDto getUser() {<br />

return user;<br />

}<br />

public void setUser(UserDto user) {<br />

this.user = user;<br />

}<br />

public TaskDto getTask() {<br />

return task;<br />

}<br />

public void setTask(TaskDto task) {<br />

this.task = task;<br />

}<br />

public double getWorkHoursFrom() {<br />

return workHoursFrom;<br />

}<br />

public void setWorkHoursFrom(double workHoursFrom) {<br />

this.workHoursFrom = workHoursFrom;<br />

}<br />

public double getWorkHoursTo() {<br />

return workHoursTo;<br />

}<br />

public void setWorkHoursTo(double workHoursTo) {<br />

this.workHoursTo = workHoursTo;<br />

}<br />

public int getGranularity() {<br />

return granularity;<br />

}<br />

public void setGranularity(int granularity) {<br />

this.granularity = granularity;<br />

}<br />

public ProjectTaskDto getProjectTask() {<br />

return projectTask;<br />

}<br />

public void setProjectTask(ProjectTaskDto projectTask) {<br />

this.projectTask = projectTask;<br />

}<br />

public float getTotalWorkHours() {<br />

return totalWorkHours;<br />

}<br />

public void setTotalWorkHours(float totalWorkHours) {<br />

this.totalWorkHours = totalWorkHours;<br />

}<br />

public Mode getMode() {<br />

Mode mode = Mode.RESOURCE;<br />

if (project == null && projectTask == null && task ==null ) {<br />

mode = Mode.RESOURCE;<br />

}else if(project != null && projectTask != null){<br />

mode=Mode.PROJECT_TASK;<br />

}else if(project!= null && projectTask == null){<br />

mode=Mode.PROJECT;<br />

}<br />

return mode;<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 116 von 128


WorkDay.java (Nicht selbsterstellte Klasse, nur für das Verständnis)<br />

public class WorkDay {<br />

private Date date;<br />

private float capacity;<br />

private float workHours;<br />

private List absences = new ArrayList();<br />

private List payloads = new ArrayList();<br />

private boolean absenceContained = false;<br />

private boolean fullAbsence = false;<br />

private boolean partTimeAbsence = false;<br />

private boolean overloaded = false;<br />

private int week;<br />

public Date getDate() {<br />

return date;<br />

}<br />

public void setDate(Date date) {<br />

this.date = date;<br />

}<br />

public float getWorkHours() {<br />

return workHours;<br />

}<br />

public void setWorkHours(float workHours) {<br />

this.workHours = workHours;<br />

}<br />

public float getCapacity() {<br />

return capacity;<br />

}<br />

public void setCapacity(float capacity) {<br />

this.capacity = capacity;<br />

}<br />

public List getPayloads() {<br />

return payloads;<br />

}<br />

public void setPayloads(List payloads) {<br />

this.payloads = payloads;<br />

}<br />

public List getTasks() {<br />

List list = new ArrayList();<br />

for (PayLoadDto item : getPayloads()) {<br />

if (item instanceof TaskDto) {<br />

list.add((TaskDto) item);<br />

}<br />

}<br />

return list;<br />

}<br />

public List getProjectTasks() {<br />

List list = new ArrayList();<br />

for (PayLoadDto item : getPayloads()) {<br />

if (item instanceof ProjectTaskDto) {<br />

list.add((ProjectTaskDto) item);<br />

}<br />

}<br />

return list;<br />

}<br />

public boolean isAbsenceContained() {<br />

return absenceContained;<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

* @param absenceContained<br />

* the absenceContained to set<br />

*/ Elisa Schnabel 21.05.<strong>2013</strong> Seite 117 von 128<br />

public void setAbsenceContained(boolean absenceContained) {


}<br />

public void setAbsenceContained(boolean absenceContained) {<br />

this.absenceContained = absenceContained;<br />

}<br />

public List getAbsences() {<br />

return absences;<br />

}<br />

public void setAbsences(List absences) {<br />

this.absences = absences;<br />

}<br />

public boolean isFullAbsence() {<br />

return fullAbsence;<br />

}<br />

public void setFullAbsence(boolean fullAbsence) {<br />

this.fullAbsence = fullAbsence;<br />

}<br />

public boolean isPartTimeAbsence() {<br />

return partTimeAbsence;<br />

}<br />

public void setPartTimeAbsence(boolean partTimeAbsence) {<br />

this.partTimeAbsence = partTimeAbsence;<br />

}<br />

public boolean isOverloaded() {<br />

return overloaded;<br />

}<br />

public void setOverloaded(boolean value) {<br />

this.overloaded = value;<br />

}<br />

public int getWeek() {<br />

return week;<br />

}<br />

public void setWeek(int week) {<br />

this.week = week;<br />

public boolean isLast(List workDays) {<br />

final int LAST_INDEX_OF_LIST = (workDays.size() - 1);<br />

return workDays.lastIndexOf(this) == LAST_INDEX_OF_LIST;<br />

} }<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 118 von 128


WorkWeek.java<br />

public class WorkWeek {<br />

private DateRange daterange;<br />

private int calendarWeek;<br />

private float workHours;<br />

public WorkWeek.java int getCalendarWeek() {<br />

return calendarWeek;<br />

}<br />

public void setCalendarWeek(int calendarWeek) {<br />

this.calendarWeek = calendarWeek;<br />

}<br />

public float getWorkHours() {<br />

return workHours;<br />

}<br />

public void setWorkHours(float workHours) {<br />

this.workHours = workHours;<br />

WorkMonth.java<br />

}<br />

public DateRange getDaterange() {<br />

public class WorkMonth {<br />

return daterange;<br />

}<br />

private DateRange range;<br />

private<br />

public void<br />

int monthNumber;<br />

setDaterange(DateRange daterange) {<br />

this.daterange = daterange;<br />

private float workHours;<br />

}<br />

}<br />

public DateRange getRange() {<br />

return range;<br />

}<br />

public void setRange(DateRange range) {<br />

this.range = range;<br />

}<br />

public int getMonthNumber() {<br />

return monthNumber;<br />

}<br />

}<br />

public void setMonthNumber(int monthNumber) {<br />

this.monthNumber = monthNumber;<br />

}<br />

public float getWorkHours() {<br />

return workHours;<br />

}<br />

public void setWorkHours(float workHours) {<br />

this.workHours = workHours;<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 119 von 128


ResourceReport.java<br />

/**<br />

* This class contains a resource and its calculated WorkDays, WorkWeeks and<br />

* WorkMonths. This class is used by the <strong>Reporting</strong>CalculateAction.<br />

*<br />

* @author seco-sbi<br />

* @since 1.0.0<br />

* WorkWeek.java<br />

*/<br />

public class ResourceReport {<br />

}<br />

private OrganizationalUnitDto ou;<br />

private ResourceDto resource;<br />

private List days;<br />

private List weeks;<br />

private List months;<br />

public ResourceDto getResource() {<br />

return resource;<br />

}<br />

public void setResource(ResourceDto resource) {<br />

this.resource = resource;<br />

}<br />

public List getDays() {<br />

return days;<br />

}<br />

public void setDays(List days) {<br />

this.days = days;<br />

}<br />

public List getWeeks() {<br />

return weeks;<br />

}<br />

public void setWeeks(List weeks) {<br />

this.weeks = weeks;<br />

}<br />

public List getMonths() {<br />

return months;<br />

}<br />

public void setMonths(List months) {<br />

this.months = months;<br />

}<br />

public OrganizationalUnitDto getOu() {<br />

return ou;<br />

}<br />

public void setOu(OrganizationalUnitDto ou) {<br />

this.ou = ou;<br />

}<br />

public List createListOfWorkhours(List reportList) {<br />

if (this.getDays() != null) {<br />

for (WorkDay day : this.getDays()) {<br />

reportList.add(Float.valueOf(day.getWorkHours()));<br />

}<br />

} else if (this.getWeeks() != null) {<br />

for (WorkWeek week : this.getWeeks()) {<br />

reportList.add(Float.valueOf(week.getWorkHours()));<br />

}<br />

} else {<br />

for (WorkMonth month : this.getMonths()) {<br />

reportList.add(Float.valueOf(month.getWorkHours()));<br />

}<br />

}<br />

return reportList;+<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 120 von 128


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

/**<br />

* repository interface for the <strong>Reporting</strong>Criteria- Entity<br />

*<br />

* @author seco-sbi, SECO<br />

* @since 1.0.0<br />

*<br />

*/<br />

public interface <strong>Reporting</strong>Repository extends ExtendedBaseRepository {<br />

}<br />

17.1.3 Klassen Persistez Layer<br />

<strong>Reporting</strong>Repository.java<br />

Jpa<strong>Reporting</strong>Repository.java<br />

/**<br />

* repository for <strong>Reporting</strong>Criteria<br />

*<br />

* @author seco-sbi, SECO<br />

* @since 1.0.0<br />

*<br />

*/<br />

@Repository<br />

public class Jpa<strong>Reporting</strong>Repository extends JpaExtendedBaseRepository<br />

implements <strong>Reporting</strong>Repository {<br />

}<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 121 von 128


<strong>Reporting</strong>Criteria.java<br />

/**<br />

* <strong>Reporting</strong> Entity for Table rm_reporting_criteria<br />

*<br />

* @author seco-sbi, SECO<br />

* @since 1.0.0<br />

*<br />

*/<br />

@Entity<br />

@Table(name = "rm_reporting_criteria")<br />

public class <strong>Reporting</strong>Criteria extends BaseResmanEntity {<br />

@Id<br />

@SequenceGenerator(name = "RM_REPORTINGCRITERIA_ID_GENERATOR", sequenceName =<br />

"rm_reporting_criteria_id_seq", allocationSize = 1)<br />

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator =<br />

"RM_REPORTINGCRITERIA_ID_GENERATOR")<br />

@Column(name = "id", unique = true, nullable = false)<br />

private Integer id;<br />

@Temporal(TemporalType.DATE)<br />

@Column(name = "start_date", nullable = false)<br />

private Date startDate;<br />

@Temporal(TemporalType.DATE)<br />

@Column(name = "end_date", nullable = false)<br />

private Date endDate;<br />

@ManyToOne<br />

@JoinColumn(name = "ou_id")<br />

private OrganizationalUnit ou;<br />

@ManyToOne<br />

@JoinColumn(name = "resource_id")<br />

private Resource resource;<br />

@ManyToOne<br />

@JoinColumn(name = "project_id")<br />

private Project project;<br />

@ManyToOne<br />

@JoinColumn(name = "user_id")<br />

private User user;<br />

@ManyToOne<br />

@JoinColumn(name = "projectTask_id")<br />

private ProjectTask projectTask;<br />

@ManyToOne<br />

@JoinColumn(name = "task_id")<br />

private Task task;<br />

@Column(name = "work_hours_from", nullable = true)<br />

private double workHoursFrom;<br />

@Column(name = "work_hours_to", nullable = true)<br />

private double workHoursTo;<br />

@Column(name = "granularity", nullable = true)<br />

private int granularity;<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

@Column(name = "radio_date", nullable = true)<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 122 von 128<br />

private int radioDate;


@Override<br />

public Integer getId() {<br />

return id;<br />

}<br />

@Override<br />

public void setId(Integer id) {<br />

this.id = id;<br />

}<br />

public Date getStartDate() {<br />

return startDate;<br />

}<br />

public void setStartDate(Date startDate) {<br />

this.startDate = startDate;<br />

}<br />

public Date getEndDate() {<br />

return endDate;<br />

}<br />

public void setEndDate(Date endDate) {<br />

this.endDate = endDate;<br />

}<br />

public OrganizationalUnit getOu() {<br />

return ou;<br />

}<br />

public void setOu(OrganizationalUnit ou) {<br />

this.ou = ou;<br />

}<br />

public Resource getResource() {<br />

return resource;<br />

}<br />

public void setResource(Resource resource) {<br />

this.resource = resource;<br />

}<br />

public Project getProject() {<br />

return project;<br />

}<br />

public void setProject(Project project) {<br />

this.project = project;<br />

}<br />

public User getUser() {<br />

return user;<br />

}<br />

public void setUser(User user) {<br />

this.user = user;<br />

}<br />

public Task getTask() {<br />

return task;<br />

}<br />

public void setTask(Task task) {<br />

this.task = task;<br />

}<br />

public double getWorkHoursFrom() {<br />

return workHoursFrom;<br />

}<br />

public void setWorkHoursFrom(double workHoursFrom) {<br />

this.workHoursFrom = workHoursFrom;<br />

}<br />

public double getWorkHoursTo() {<br />

return workHoursTo;<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

public void setWorkHoursTo(double workHoursTo) {<br />

this.workHoursTo Elisa Schnabel = workHoursTo;<br />

21.05.<strong>2013</strong> Seite 123 von 128<br />

}


public double getWorkHoursTo() {<br />

return workHoursTo;<br />

}<br />

public void setWorkHoursTo(double workHoursTo) {<br />

this.workHoursTo = workHoursTo;<br />

}<br />

public int getGranularity() {<br />

return granularity;<br />

}<br />

public void setGranularity(int granularity) {<br />

this.granularity = granularity;<br />

}<br />

public ProjectTask getProjectTask() {<br />

return projectTask;<br />

}<br />

public void setProjectTask(ProjectTask projectTask) {<br />

this.projectTask = projectTask;<br />

}<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 124 von 128


ResourcePayloadCalculatorTest.java<br />

public class ResourcePayloadCalculatorTest {<br />

private HolidayService holidayService = new MockedHolidayService();<br />

private ResourcePayloadCalculator calculator = new ResourcePayloadCalculator(holidayService);<br />

private ResourceModel model;<br />

private Date startDate;<br />

private Date endDate;<br />

@Before<br />

public void setup() {<br />

initDates(DateHelper.getCurrentWeek());<br />

model = initResourceModel(startDate, endDate, calculator);<br />

}<br />

@Test<br />

public void calculateDaysInRange() {<br />

calculator.calculateDaysInRange(model, startDate, endDate);<br />

Assert.assertEquals(5, model.getWorkDays().size());<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

@Test<br />

public void calculateHoursForWorkWeeks(){<br />

calculator.calculateDaysInRange(model, startDate, endDate);<br />

List weeks = calculator.calculateHoursForWorkWeeks(model.getWorkDays());<br />

Assert.assertEquals(1, weeks.size());<br />

}<br />

@Test<br />

public void calculateHoursForWorkWeeksWithYearOverflow(){<br />

initDates("01.12.<strong>2013</strong>", "31.01.2014");<br />

calculator.calculateDaysInRange(model, startDate, endDate);<br />

List weeks = calculator.calculateHoursForWorkWeeks(model.getWorkDays());<br />

Assert.assertEquals(9, weeks.size());<br />

}<br />

@Test<br />

public void calculateHoursForWorkMonths(){<br />

calculator.calculateDaysInRange(model, startDate, endDate);<br />

List months = calculator.calculateHoursForWorkMonths(model.getWorkDays());<br />

Assert.assertEquals(1, months.size());<br />

}<br />

@Test<br />

public void calculateHoursForWorkMonthsWithYearOverflow(){<br />

initDates("01.12.<strong>2013</strong>", "31.01.2014");<br />

calculator.calculateDaysInRange(model, startDate, endDate);<br />

List months = calculator.calculateHoursForWorkMonths(model.getWorkDays());<br />

Assert.assertEquals(2, months.size());<br />

}<br />

@Test<br />

public void calculateDaysForSpecificProjectTask(){<br />

calculator.calculateDaysInRange(model, startDate, endDate);<br />

List days=<br />

calculator.calculateDaysForSpecificProjectTask(initProjectTask(startDate, endDate), model);<br />

Assert.assertEquals(5, days.size());<br />

for(WorkDay day :days){<br />

Assert.assertEquals(8F, day.getWorkHours());<br />

}<br />

}<br />

@Test<br />

public void calculateDaysForSpecificTask(){<br />

calculator.calculateDaysInRange(model, startDate, endDate);<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 125 von 128<br />

List days= calculator.calculateDaysForSpecificTask(initTask(startDate, endDate),<br />

model);


<strong>IPA</strong>-<strong>Dokumentation</strong><br />

@Test<br />

public void calculateDaysForSpecificTask(){<br />

calculator.calculateDaysInRange(model, startDate, endDate);<br />

List days= calculator.calculateDaysForSpecificTask(initTask(startDate, endDate), model);<br />

Assert.assertEquals(5, days.size());<br />

for(WorkDay day :days){<br />

Assert.assertEquals(8F, day.getWorkHours());<br />

}<br />

}<br />

@Test<br />

public void calculateDaysForSpecificProject(){<br />

calculator.calculateDaysInRange(model, startDate, endDate); List days= calculator.calculateDaysForSpecificProject(initProject(startDate,<br />

endDate), model);<br />

Assert.assertEquals(5, days.size());<br />

for(WorkDay day :days){<br />

Assert.assertEquals(8F, day.getWorkHours());<br />

}<br />

}<br />

private ResourceModel initResourceModel(Date startDate, Date endDate,<br />

ResourcePayloadCalculator calculator){<br />

ResourceModel model = new ResourceModel(calculator);<br />

ResourceDto resource = initResource();<br />

TaskDto task = initTask(startDate, endDate);<br />

ProjectTaskDto projectTask = initProjectTask(startDate, endDate);<br />

List tasks = new ArrayList();<br />

List ptasks = new ArrayList();<br />

ptasks.add(projectTask);<br />

tasks.add(task);<br />

resource.setTasks(tasks);<br />

resource.setProjectTasks(ptasks);<br />

model.setCurrentEntity(resource);<br />

return model;<br />

}<br />

private TaskDto initTask(Date startDate, Date endDate){<br />

TaskDto task = new TaskDto();<br />

task.setStartDate(startDate);<br />

task.setEndDate(endDate);<br />

task.setWorkHours(8F);<br />

task.setTitle("test");<br />

task.setId(1);<br />

return task;<br />

}<br />

private ProjectTaskDto initProjectTask(Date startDate, Date endDate){<br />

ProjectTaskDto task = new ProjectTaskDto();<br />

ProjectDto project = initProject(startDate, endDate);<br />

task.setStartDate(startDate);<br />

task.setEndDate(endDate);<br />

task.setWorkHours(8F);<br />

task.setTitle("test");<br />

task.setId(1);<br />

task.setProject(project);<br />

return task;<br />

}<br />

private ProjectDto initProject(Date startDate, Date endDate){<br />

ProjectDto project= new ProjectDto();<br />

project.setStartDate(startDate);<br />

project.setEndDate(endDate);<br />

project.setName("Test");<br />

project.setId(1);<br />

return project;<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 126 von 128<br />

}


}<br />

private ProjectDto initProject(Date startDate, Date endDate){<br />

ProjectDto project= new ProjectDto();<br />

project.setStartDate(startDate);<br />

project.setEndDate(endDate);<br />

project.setName("Test");<br />

project.setId(1);<br />

return project;<br />

}<br />

private ResourceDto initResource(){<br />

WorkingPatternDto wp = new WorkingPatternDto();<br />

wp.setHoursPerWeek(42);<br />

ResourceDto resource = new ResourceDto();<br />

resource.setWorkingPattern(wp);<br />

resource.setLevelOfEmployment(100);<br />

return resource;<br />

}<br />

private void initDates(DateRange range){<br />

startDate = DateHelper.generalizeDate(range.getStartDate());<br />

endDate = DateHelper.generalizeDate(range.getEndDate());<br />

}<br />

private void initDates(String start, String end){<br />

SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");<br />

try {<br />

startDate = DateHelper.generalizeDate(formatter.parse(start));<br />

endDate = DateHelper.generalizeDate(formatter.parse(end));<br />

} catch (ParseException e) {<br />

e.printStackTrace();<br />

}<br />

}<br />

private static class MockedHolidayService implements HolidayService {<br />

}<br />

@Override<br />

public HolidayDto save(HolidayDto dto) {<br />

return null;<br />

@Override<br />

public List find(QueryCriteria criteria) {<br />

return new ArrayList();<br />

}<br />

@Override<br />

public void remove(HolidayDto dto) {<br />

}<br />

@Override<br />

public List getAll() {<br />

return null;<br />

}<br />

@Override<br />

public HolidayDto findHoliday(Date date) {<br />

return null;<br />

}<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 127 von 128


17.2 Benutzerhandbuch<br />

<strong>IPA</strong>-<strong>Dokumentation</strong><br />

Das nachfolgende Benutzerhandbuch wurde während der <strong>IPA</strong> um das Modul <strong>ResMan</strong> <strong>Reporting</strong><br />

erweitert.<br />

Elisa Schnabel 21.05.<strong>2013</strong> Seite 1

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!