Timekeepings
Diese Seite ist unvollständig und noch in Bearbeitung.
Ein Timekeeping ist ein Ereignis innerhalb des Arbeitszeiterfassungssystems.
Inhaltsverzeichnis
Entwicklernotizen
Ein Timekeeping ist ein Ereignis innerhalb des Arbeitszeiterfassungssystems. Im konkreten Fall kann der Mitarbeiter zum Beispiel "Arbeit Beginn" und "Arbeit Ende" stempeln (über unsere Station, die MAE o.ä.). Es ist hervorzuheben, dass diese Ereignisse nur einen Zeitpunkt repräsentieren, also keine Aussage über die Dauer bieten.
Wenn im Client ein Timekeeping nicht vorhanden ist, heißt das unter Umständen nur, dass es noch nicht vom Server geladen wurde. Aufgrund der Menge an Zeiterfassungsdaten werden immer nur zeitliche Abschnitte angefragt. Zum Beispiel werden beim erstmaligen Anlegen eines Coworkers nur seine Timekeepings der letzten sieben Tage erfragt.
Aufbau
Die Timekeepings werden wie alle Ressourcen über WebAccessoren vom REST-Service abgehohlt und in den üblichen internen Listen abgespeichert. In diesem speziellen Fall jedoch existieren diese nicht im ResourcePool, sondern jeweils einer in einem Coworker.
WebAccessor<Timekeeping>* timekeepingAcc() { return m_timekeepingAcc; } // coworker.h
event
Ein Timekeeping ist neben seinem Zeitpunkt vor allem auch durch seinen Typ charakterisiert (z.B. "Arbeit", "Pause" etc.) und seinen Zustand (z.B. "Start" oder "Stop"). Diese beiden Sachen sind zusammen im "event"-Attribut des Timekeepings als String gespeichert (z.B. "work_start" oder "break_stop"). Zur besseren Verarbeitung dieser hat das Timekeeping intern zwei Structs definiert: "EventState" und "EventType" und über die getter-Funktionen eventType() und eventState() lässt sich für jedes Timekeeping der entsprechende Wert abfragen.
timestamps
Alle Timestamps aus dem XML sind in UTC-Zeit und müssen auch so wieder an den webservice übergeben werden. Dazu gehören
- created_at - Zeitpunkt der Erstellung in der Datenbank
- updated_at - Zeitpunkt der letzten Aktualisierung in der Datenbank
- user_timestamp - Zeitpunkt an dem der Benutzer/Mitarbeiter das Ereignis abgeschickt/gestempelt hat
- telematik_timestamp - Zeitpunkt an dem das entsprechende Telematik-System das Ereignis rausgeschickt hat
Der im OSCpc üblicherweise zu nutzende Timestamp ist der user_timestamp.
Da die Zeitstempel sehr oft und überall abgefragt werden existiert im Objekt eine Art Caching und es wird dringend geraten die userTimestamp(...) Funktion zu benutzen. Sie gibt eine QDateTime Referenz zurück. Ihr erster Parameter legt fest ob man die Zeit in lokaler oder UTC-Zeit(default) möchte. Ihr zweiter Parameter, ob eine den eingestellten Aufrundungsregeln(siehe unten) entsprechend veränderter Zeitstempel geliefert werden soll oder nicht(default).
Zum Setzen des user_timestamps existiert die setUserTimestampUTC(...) Funktion die einen korrekt formatierten Zeitstempel als QString erfordert. Z.B. durch
QString isoFrom = from.toUTC().toString(Qt::ISODate); // QDateTime from;
Sonstiges
- coworker_uuid - Der Mitarbeiter zu dem das Ereignis gehört
- garmin_uuid - Optional - Der Garmin von dem das Ereignis gesendet wurde.
- system_uuid - Optional - Das Fahrzeug von dem das Ereignis gesendet wurde.
- world_x, world_y, map_text - Wenn vorhanden Koordinaten und die dafür gefundene Adresse an dem das Ereignis gestempelt wurde.
Bevor auf die Benutzung der Timekeepings eingegangen wird, muss eine davon abgeleitete Struktur erläutert werden.
Erweiterte Timekeepings - CombinedTimekeeping
Um die Arbeit mit den Timekeepings zu erleichtern wurde eine Wrapper-Struktur geschaffen, die Klasse CombinedTimekeeping
Sie stellt, soweit möglich, einen vollständigen Ereigniszeitraum von Anfang bis Ende dar. Hat also auch Informationen über die Dauer des Ereignisses. Es ist dabei wichtig anzumerken, dass die Vollständigkeit nicht zwingend ist. So kann z.B. ein Start- oder Endzeitpunkt des Ereignisses durchaus fehlen.
Die CombinedTimekeepings werden im Hintergrund beim Anlegen und Ändern von Timekeepings mitverwaltet und synchronisiert. Wer an diesen internen Strukturen etwas verändert sollte genau wissen was er tut, da sonst sehr schnell fehlerhafte Einträge entstehen und Programmabstürze die Folge sind.
Benutztung der Ctks
Der Zugriff auf die CombinedTimekeepings erfolgt ebenfalls über den jeweiligen Coworker. Dabei gibt es verschiedene Hashes und Mappings um möglichst schnell die gewünschten Daten zu erhalten
- QList<CombinedTimekeeping*> m_listCombinedTimekeepings
- Eine einfache Liste aller geladenen Ctks.
- Benutzt im CombinedWorktimeBySystemModel.
- QMap<QDate, QList<CombinedTimekeeping*>*> m_combinedTimekeepingsByDayList
- Dies ist eine spezielle Map um eine Liste aller CombinedTimekeepings eines bestimmten Tages zu bekommen. Dabei ist zu beachten das Ereignisse die über mehrere Tage gehen (z.B. Urlaub oder Arbeit über Mitternacht hinaus) auch für jeden dieser Tage einmal in der Map gespeichert sind. Der Programmierer muss daher entsprechend beachten z.B. etwaige Ereignissdauern nicht doppelt zu verrechnen.
- Benutzt im TimekeepingModelMonthly, CombinedWorktimesModel, TimekeepingReportDaily
- QMap<QDate, QHash<Timekeeping::EventType, QList<CombinedTimekeeping*>*>*> m_combinedTimekeepingsByDayHash
- Dies ist eine spezielle Map um eine Liste aller CombinedTimekeepings eines bestimmten Tages und eines bestimmten Typs zu bekommen. Ansonsten gilt das gleiche wie bei der zuvor genannten Struktur.
- Benutzt im HolidayIllModel, HolidayIllReport, PlanningByCoworkerModel
Benutztung der Timekeepings
Timekeepings werden wie alle Resourcetypen nur als Smartpointer erstellt (genauer: QExplicitlySharedDataPointer) um die Speicherverwaltung zu vereinfachen. Über den entsprechenden Coworker kann über den dort angelegten Timekeeping-WebAccessor auf dessen Liste an geladenen Timekeepings zugegriffen werden.
Folgende Ereignistypen sind in der Datenbank definiert und können vom Timekeeping angenommen werden
- work_start, work_stop (Arbeit)
- private_start, private_stop (Privat)
- driver_start, driver_stop (Fahrer)
- break_start, break_stop (Pause)
- customer_start, customer_stop (Kunde)
- waiting_start, waiting_stop (Wartend)
- holiday_start, holiday_stop (Urlaub)
- ill_start, ill_stop (Krankheit)
- alert (Alarm)
- function_1, function_2, function_3 (Funktion 1-3)
- garmin_id_1, garmin_id_2, garmin_id_3, garmin_id_4, garmin_id_5, garmin_id_6, garmin_id_7, garmin_id_8, garmin_driver_id
Beispiel des XML eines Timekeepings
<timekeeping generated-at="2013-07-02T17:30:37Z"> <world-x type="float">9.290938</world-x> <world-y type="float">49.077442</world-y> <remarks nil="true"/> <created-at type="datetime">2013-07-02T17:24:36Z</created-at> <system-uuid type="string">90DB8C71-297D-4F34-A3AB-B3840DCC42B3</system-uuid> <user-timestamp type="datetime">2013-07-02T17:24:36Z</user-timestamp> <uuid type="string">44D3611E-E33C-11E2-9064-12314303963F</uuid> <updated-at type="datetime">2013-07-02T17:24:36Z</updated-at> <garmin-uuid type="string">D89BE2ED-82F8-43E1-BB3E-3FFE32ED9A0C</garmin-uuid> <telematik-timestamp type="datetime">2013-07-02T17:24:28Z</telematik-timestamp> <event type="string">garmin_id_3</event> <coworker-uuid type="string">5906DB16-6D11-4ECF-AA09-CC35EC88C406</coworker-uuid> <description nil="true"/> <map-text type="string"> Staat: DE Land: Baden-Württemberg Landkreis: Heilbronn Postleitzahl: 74232 Stadt: Abstatt Strasse: Etrastraße 2 </map-text> </timekeeping>