Zeiterfassung - App-Dokumentation

Ueberblick

Diese Canvas App dient zur einfachen Zeiterfassung fuer einen angemeldeten Benutzer. Die App besteht aktuell aus genau einer Startseite (ZeiterfassungNeu) und zeigt den aktuellen Status, die laufende Sitzung sowie Tages- und Monatssummen an. Benutzer koennen sich ueber Kommen einstempeln und ueber Gehen ausstempeln.

Die App arbeitet mit einer Mischung aus:

  • App-weiten Hilfsfunktionen in App.pa.yaml

  • lokalem UI-State in Variablen

  • zwischengespeicherten Collections fuer Tages- und Monatsdaten

  • direktem Schreiben und Lesen aus der Datenquelle Time Tracking Entry

Dateien

Datei

Zweck

App.pa.yaml

App-Startlogik, globale Variablen, Hilfsfunktionen, Startscreen

ZeiterfassungNeu.pa.yaml

Einziger Screen mit UI, Datenabruf, Ein- und Ausstempeln

Startverhalten

Beim Start der App werden in App.OnStart mehrere Variablen initialisiert:

  • varCurrentUserEmail: E-Mail des aktuellen Benutzers in Kleinbuchstaben

  • varSelectedDate: standardmaessig das heutige Datum

  • varIsAdminUser: Admin-Flag

  • varIsLoading: Sperrt UI waehrend laufender Datenoperationen

  • varCurrentOpenEntry: aktuell offener Zeiteintrag

  • varLunchSelected / varDinnerSelected: Status der Verpflegungsoptionen

  • varCurrentDayMinutes, varCurrentMonthMinutes, varCurrentSessionMinutes: berechnete Kennzahlen

Zusaetzlich wird geprueft, ob der aktuelle Benutzer Mitglied einer festen Office-365-Gruppe ist. Ist das der Fall, wird varIsAdminUser auf true gesetzt.

Datenquellen und Konnektoren

Time Tracking Entry

Die fachliche Hauptdatenquelle ist Time Tracking Entry. Darin werden Zeiteintraege gelesen und geschrieben. Verwendete Felder sind unter anderem:

  • mitarbeiter

  • aktivitaetsdatum

  • aktivitaetsdatumzeit

  • astart

  • Kommen

  • Gehen

  • checkout

  • zeitrecid

  • mittagessen

  • Mittagessen

  • Abendessen

  • Tagestotal

  • Monatstotal

Die App schreibt sowohl deutsch benannte als auch englisch benannte Essensfelder (mittagessen / Mittagessen). Das deutet auf ein historisch gewachsenes oder technisch bedingtes Mapping der Datenquelle hin.

Office365Groups

Der Konnektor Office365Groups wird fuer die Adminpruefung verwendet. Ueber ListGroupMembers(...) wird geprueft, ob der aktuelle Benutzer in einer fest hinterlegten Gruppe enthalten ist.

Globale Hilfsfunktionen

In App.Formulas sind mehrere wiederverwendbare Funktionen definiert:

  • FormatMinutes(totalMinutes): Wandelt Minuten in HH:mm um

  • WorkMinutes(startDt, endDt): Berechnet gearbeitete Minuten und verhindert negative Werte

  • FormatBalance(totalHours): Formatiert Stundensalden mit Vorzeichen

  • EntryDurationHours(startDt, endDt, breakMinutes): Rechnet einen Eintrag in Stunden um

  • StatusColor(statusText): Liefert eine Farbzuordnung fuer Statuswerte

Zusaetzlich sind zwei Theme-Objekte vorhanden:

  • AppTheme

  • AppTheme2

Diese kapseln zentrale Farben fuer Oberflaeche, Text, Erfolg, Warnung und Fehler.

Screen ZeiterfassungNeu

Zweck

Der Screen ist die Hauptoberflaeche fuer die taegliche Zeiterfassung. Beim Oeffnen wird automatisch btnReloadData ausgefuehrt, wodurch die aktuellen Daten geladen und die Anzeige initialisiert wird.

Sichtbare Bereiche

1. Kopfbereich

Der Header zeigt:

  • den Titel Zeiterfassung

  • das aktuell gewaehlte Datum

  • den Status Nicht eingestempelt oder Eingestempelt

Die Statusfarbe wechselt zwischen Fehler-/Warnfarbton und Erfolgsfarbe, abhaengig davon, ob ein offener Eintrag existiert.

2. Live-Zusammenfassung

Dieser Bereich zeigt:

  • die aktuelle Uhrzeit

  • die aktuelle Sitzungsdauer

Die Sitzungsdauer wird aus varCurrentSessionMinutes berechnet. Ein Timer aktualisiert diese Anzeige laufend.

3. Aktionen

Es gibt zwei Hauptaktionen:

  • btnKommen

  • btnGehen

Kommen

Beim Einstempeln passiert Folgendes:

  1. Pruefung, ob bereits ein offener Eintrag existiert

  2. Setzen des Ladezustands

  3. Erzeugen einer neuen zeitrecid per GUID()

  4. Patch() eines neuen Datensatzes in Time Tracking Entry

  5. Speichern von Benutzer, Datum, Startzeit und Verpflegungsstatus

  6. Refresh() der Datenquelle

  7. erneutes Laden der lokalen Daten ueber btnReloadData

Gehen

Beim Ausstempeln passiert Folgendes:

  1. Pruefung, ob ein offener Eintrag vorhanden ist

  2. Berechnung der aktuellen Sitzungsdauer

  3. Neuberechnung von Tages- und Monatssumme ohne Doppelzaehlung des offenen Eintrags

  4. Patch() des offenen Datensatzes mit Endzeit und Summen

  5. Refresh() der Datenquelle

  6. erneutes Laden der lokalen Daten ueber btnReloadData

4. Verpflegung

Es gibt zwei Checkboxen:

  • Mittagessen

  • Abendessen

Die Auswahl wird lokal in varLunchSelected und varDinnerSelected gehalten und beim Ein- oder Ausstempeln in die Datenquelle geschrieben.

5. Summen

Es werden zwei Kennzahlen angezeigt:

  • Tagestotal

  • Monatstotal

Beide werden aus vorbereiteten Collections berechnet und mit FormatMinutes(...) formatiert dargestellt.

6. Admin-Button

Ein Admin-Button ist vorhanden, aber die Navigation ist aktuell auskommentiert:

//Navigate(Eintragsverwaltung, ScreenTransition.Fade)

Der Button ist nur sichtbar, wenn varIsAdminUser = true.

Datenfluss

Versteckter Reload-Mechanismus

Die App verwendet einen unsichtbaren Button btnReloadData als zentrale Ladefunktion. Dessen OnSelect ist die wichtigste Stelle fuer das Lesen und Aufbereiten der Daten.

Der Ablauf:

  1. Refresh('Time Tracking Entry')

  2. Laden aller Benutzereintraege in colUserEntries

  3. Filtern des ausgewaehlten Tages nach colRawTodayEntries

  4. Anreichern zu colTodayEntries mit:

    • startTime

    • endTime

    • recordId

    • lunchValue

    • dinnerValue

  5. Filtern des aktuellen Monats nach colRawMonthEntries

  6. Anreichern zu colMonthEntries

  7. Ermitteln des offenen Eintrags in varCurrentOpenEntry

  8. Berechnen der aktuellen Kennzahlen und Ruecksetzen der Checkboxen

Live-Aktualisierung

Ein unsichtbarer Timer timRefresh laeuft mit einer Dauer von 1000 ms und aktualisiert:

  • varCurrentSessionMinutes

  • varCurrentDayMinutes

  • varCurrentMonthMinutes

Dadurch bleibt die Anzeige waehrend einer laufenden Sitzung aktuell, ohne die Datenquelle sekundenweise neu zu laden.

Verwendete Collections

Collection

Inhalt

colUserEntries

Alle Eintraege des aktuellen Benutzers

colRawTodayEntries

Rohe Tagesdaten vor Anreicherung

colTodayEntries

Tagesdaten mit berechneten Hilfsfeldern

colRawMonthEntries

Rohe Monatsdaten vor Anreicherung

colMonthEntries

Monatsdaten mit berechneten Hilfsfeldern

Verwendete Variablen

Variable

Bedeutung

varCurrentUserEmail

E-Mail des aktuellen Benutzers

varSelectedDate

aktuell betrachtetes Datum

varIsAdminUser

steuert die Sichtbarkeit von Admin-Funktionen

varIsLoading

sperrt Controls waehrend Datenoperationen

varCurrentOpenEntry

aktuell offener Zeiteintrag

varLunchSelected

Mittagessen aktiviert

varDinnerSelected

Abendessen aktiviert

varCurrentSessionMinutes

Dauer der laufenden Sitzung

varCurrentDayMinutes

Summe fuer den aktuellen Tag

varCurrentMonthMinutes

Summe fuer den aktuellen Monat

varNewDayMinutes

Hilfsvariable beim Ausstempeln

varNewMonthMinutes

Hilfsvariable beim Ausstempeln

Responsive Verhalten

Die App nutzt AutoLayout-Container. Mehrere Bereiche schalten bei schmaler Breite (App.Width < 600) von horizontalem auf vertikales Layout um. Dadurch ist die Ansicht fuer kleinere Displays vorbereitet.

Aktuelle Einschraenkungen und Auffaelligkeiten

  • Die App hat derzeit nur einen produktiv genutzten Screen.

  • Der Admin-Button ist sichtbar, aber funktional noch nicht verdrahtet.

  • In App.OnStart werden einige Variablen mehrfach gesetzt. Das ist funktional unkritisch, aber pflegeintensiver.

  • Die Datenquelle verwendet teilweise doppelte Feldkonzepte fuer Verpflegung (mittagessen und Mittagessen).

Kurzfazit

Die App ist als kompakte Single-Screen-Zeiterfassung umgesetzt. Der Kern besteht aus:

  • Einstempeln und Ausstempeln

  • Live-Anzeige der aktuellen Sitzung

  • Berechnung von Tages- und Monatssummen

  • optional sichtbarer Admin-Einstieg

Der technische Schwerpunkt liegt auf lokal vorbereiteten Collections und einem zentralen Reload-Mechanismus fuer konsistente Anzeige nach jeder Aenderung.