diff --git a/TimeScheduler/Readme.txt b/TimeScheduler/Readme.txt new file mode 100644 index 0000000..78b4812 --- /dev/null +++ b/TimeScheduler/Readme.txt @@ -0,0 +1,47 @@ +Beispielprojekt für die Anwendung von WPF. + +Anforderung: + + Mit der Applikation soll die Arbeitszeit automatisiert erfast und permanent gespeichert werden. + Dafür wird pro Zeiteinheit ein Element angelegt, das folgenden Eigenschaften besitzt: + - Beschreibung des Elementes + - Von-Zeitpunkt (1/4h genau) + - Bis-Zeitpunkt (1/4h genau) + - Kostenstelle + - Typ (Normal, Pause, Urlaub, Krank) + Die Darstellung des Elementes soll vom Typ abhängig sein, z.B. Hintergrundfarbe ist normal blau und bei Pause gelb. + Es sollen nicht immer alle Elemente dargestellt werden, sondern nur die das selektieren Tages. + + Die aktuelle Arbeitszeit, soll graphisch markiert sein, und deren Endezeit soll automatisch angepasst werden. + Beim Sperren/Ruhezustand soll autmoatisch die aktuelle Arbeitszeit abgeschlossen werden und eine neue gestartet + werden, aber nur wenn die aktuelle Arbeitszeit > 15min ist. + + Über ein Menü (z.B. Kontextmenü) erstellt man eine neue aktuelle oder löscht eine vorhandene. Zur Einfachheit + darf man die aktuelle Arbeitszeit nicht löschen. + Desweitern soll man die selektierte Arbeitszeit mit der nächsten Arbeitszeit verschmelzen können, wobei nur die + Endezeit auf das selektierte Objekt übernommen wird. + Um einen Überblick über die Daten zu bekommen, soll es eine Diagnoseoberfläche geben, in der man + + Beim Start wird die zuletzt gespeicherten Daten geladen und die letzte Arbeitszeit des aktuellen Tages wird als + aktuelle Arbeitszeit hergenommen. Bei Änderungen an den Arbeitszeiten, sollen diese direkt permanent gespeichert + werden, spätestens beim beenden der Anwendung. + Das speichern sollte sehr robust werden, damit die Datei nicht zerstört werden, wenn während des speichern die + Anwendung abstürzt. + + Zur Implementierung soll WPF mit dem MVVM-Pattern benutzt werden + +Erweiterte Funktionaltiät: + - Bei Sperrungen/Ruhezustände über 8h soll das Element nicht als Arbeitzeit gelten sondern entfernt werden + - Es erscheint eine Nachfrage nach einer Entsperrung/Aufwachen (aus Ruhezustand) wie die Zeit seit der + letzten Sperrung/Ruhezustand eingetragen werden soll + - Kostenstellen-Editor einbauen + - Die Kostenstellen in Task aufteilen + + +Beschreibung der Struktur: + - Oberflächen sind direkt in der Root + - ViewModel: die ViewModels für die Oberflächen + - Resource: Resourcen die benötigt werden + - Model: Klassen, die die Datenbestände beinhalten + - Domain: Schnittstellen und Implementierungen für die Datenbeschaffung + - Common: Allgmeine Klassen die in jeder WPF-Anwendung benötigt werden diff --git a/TimeScheduler/TimeScheduler.sln b/TimeScheduler/TimeScheduler.sln index 13265ff..8dfb62e 100644 --- a/TimeScheduler/TimeScheduler.sln +++ b/TimeScheduler/TimeScheduler.sln @@ -7,6 +7,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TimeScheduler", "TimeSchedu EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TimeScheduler.Test", "TimeScheduler.Test\TimeScheduler.Test.csproj", "{8B47037C-584E-41FB-B8B8-14FAD26D7BCA}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{57AA67D7-E7F9-4D31-BAD8-242100BE21C8}" + ProjectSection(SolutionItems) = preProject + Readme.txt = Readme.txt + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/TimeScheduler/TimeScheduler/Diagnose.xaml b/TimeScheduler/TimeScheduler/Diagnose.xaml new file mode 100644 index 0000000..ed71295 --- /dev/null +++ b/TimeScheduler/TimeScheduler/Diagnose.xaml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TimeScheduler/TimeScheduler/Diagnose.xaml.cs b/TimeScheduler/TimeScheduler/Diagnose.xaml.cs new file mode 100644 index 0000000..9d35139 --- /dev/null +++ b/TimeScheduler/TimeScheduler/Diagnose.xaml.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace TimeScheduler +{ + /// + /// Interaktionslogik für Diagnose.xaml + /// + public partial class Diagnose : Window + { + public Diagnose() + { + InitializeComponent(); + } + } +} diff --git a/TimeScheduler/TimeScheduler/Domain/IDomain.cs b/TimeScheduler/TimeScheduler/Domain/IDomain.cs index f986d89..37bc9ec 100644 --- a/TimeScheduler/TimeScheduler/Domain/IDomain.cs +++ b/TimeScheduler/TimeScheduler/Domain/IDomain.cs @@ -7,6 +7,9 @@ namespace TimeScheduler.Domain /// Schnittstelle zum Provider der die Daten ermitteln public interface IDomain { + /// Ermittelt die Monate, für denen Daten vorliegen + /// Liste der Monate, in der Daten vorliegen + IEnumerable GetMonths(); /// Ermittelt die Werte für den angegebenen Tag /// Der Tag für den Werte gesucht werden sollen /// Die Daten, für den angefragten Tag diff --git a/TimeScheduler/TimeScheduler/Domain/Impl/FileDomain.cs b/TimeScheduler/TimeScheduler/Domain/Impl/FileDomain.cs index 9a7740e..34d8470 100644 --- a/TimeScheduler/TimeScheduler/Domain/Impl/FileDomain.cs +++ b/TimeScheduler/TimeScheduler/Domain/Impl/FileDomain.cs @@ -81,6 +81,12 @@ namespace TimeScheduler.Domain.Impl #endregion #region IDomain + IEnumerable IDomain.GetMonths() + { + return allItems_ + .GroupBy(x => x.From.Year * 100 + x.From.Month) + .Select(x => new DateTime(x.Key / 100, x.Key % 100, 1)); + } IEnumerable IDomain.GetItems(DateTime date) { return allItems_ diff --git a/TimeScheduler/TimeScheduler/Domain/Impl/TimeItem.cs b/TimeScheduler/TimeScheduler/Domain/Impl/TimeItem.cs index 17f7385..21a7048 100644 --- a/TimeScheduler/TimeScheduler/Domain/Impl/TimeItem.cs +++ b/TimeScheduler/TimeScheduler/Domain/Impl/TimeItem.cs @@ -64,6 +64,10 @@ namespace TimeScheduler.Domain.Impl } #endregion + #region Weitere Eigenschaften + public TimeSpan Duration { get { return till_ - from_; } } + #endregion + #region ITimeItem (Eigenschaften nicht implizit implementieren, sonst funktioniert das Binden nicht) private int key_; /// @@ -81,8 +85,11 @@ namespace TimeScheduler.Domain.Impl set { if (SetField(ref from_, value.Subtract(TimeSpan.FromMinutes(value.Minute % 15)))) + { if (From > Till) Till = From; + OnPropertyChanged("Duration"); + } } } @@ -94,8 +101,11 @@ namespace TimeScheduler.Domain.Impl set { if (SetField(ref till_, value.Subtract(TimeSpan.FromMinutes(value.Minute % 15)))) + { if (Till < From) From = Till; + OnPropertyChanged("Duration"); + } } } diff --git a/TimeScheduler/TimeScheduler/MainWindow.xaml b/TimeScheduler/TimeScheduler/MainWindow.xaml index b9e89f2..4685c69 100644 --- a/TimeScheduler/TimeScheduler/MainWindow.xaml +++ b/TimeScheduler/TimeScheduler/MainWindow.xaml @@ -15,6 +15,13 @@ + + + + + + + @@ -26,13 +33,24 @@ - + + + + + + +