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 />
<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 />
<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 />
<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 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