Kalenderfilter
Wertauflöser - Kurzfassung
Zweck: Führt ausgehend von einem als Eingabewert bereitgestellten Datum oder Datumsbereich eine Werktag-Prüfung gegen einen bestimmten Kalender aus. Bei nicht-bestandener Prüfung wird ein Ausweichtermin zurückgegeben, sonst der Eingabewert.
Der Kalenderfilter-Wertauflöser führt ausgehend von einem als Eingabewert bereitgestellten Datum oder Datumsbereich eine Werktag-Prüfung (Details s. u.) gegen einen wahlweise Statisch oder zur Laufzeit per Wertauflöser spezifizierten Kalender aus. Die Prüfung gilt als bestanden, wenn der Kalender das Datum bzw. die Von- und Bis-Daten eines Datumsbereichs als Werktag einstuft. Dann wird der Eingabewert zurückgegeben. Anderenfalls wird ein Ausweichtermin für das Datum oder den Datumsbereich gesucht und zurückgegeben.
Die Option Rückwärts springen entscheidet über die Suchrichtung (früher/später) für den Ausweichtermin, falls der Eingabewert die Werktag-Prüfung gegen den angegebenen Kalender nicht besteht.
Besonderer Anwendungsfall: Im Kontext einer Für jeden Eintrag wiederholen (Schleife)-Ereignisaktion (s. letztes Beispiel unten) kann der Kalenderfilter-Wertauflöser genutzt werden, um ausgehend von einem Starttermin einen Termin zu ermitteln, der eine bestimmte Anzahl Werktage vom Starttermin "entfernt" ist.
Als Eingabewert wird einer der folgenden Datentypen erwartet:
Long ( java.lang.Long)
"Datum" (java.lang.Date)
"Zeitstempel" (java.sql.Timestamp)
"Datum mit Zeit" (DateTime)
"Datumsbereich mit Zeit" (DateRange)
Interpretation von Datumswerten ohne deklarierte Zeitzone
Ein Long-Wert als Eingabewert wird als Millisekunden seit 01.01.1970 00:00:00.000 (UTC) interpretiert. Allerdings gilt dabei - wie für alle als Datum interpretierten Eingabewert-Typen ohne Zeitzone (Long, Timestamp, Date) - nicht die Zeitzone UTC als Standard. Vielmehr wird die im Kontext anwendbare Standard-Zeitzone nach folgender Logik berücksichtigt:
Sofern für den Benutzer der Session (in der tatsächlich angemeldeten Sitzung) eine "Default Zeitzone" (defaultTimeZone) definiert ist, wird diese verwendet.
Andernfalls wird auf das Konto der Firma der Session (in der tatsächlich angemeldeten Sitzung) und die dort ggf. definierte "Default Zeitzone" (defaultTimeZone) zurückgegriffen.
Nur wenn keines der beiden Konten eine "Default Zeitzone" für die tatsächlich angemeldete Sitzung definiert, gibt die Auswahl für die Zeitzone im Betriebssystem des Servers oder Clients den Ausschlag:
Im Server-Kontext (z. B. für Ereignisbehandlungen) wird die Zeitzone aus dem Ausführungskontext des Lobster Data Platform / Orchestration-Servers übernommen.
Im Client-Kontext (z. B. in einem Client Workflow) wird die Auswahl für die Zeitzone im Client-Betriebssystem übernommen.
Der Typ des Rückgabewerts entspricht immer dem Typ des Eingabewerts.
►HINWEIS◄ Für die als "Datumswerte ohne deklarierte Zeitzone" zusammengefassten Datentypen bedeutet das, dass die im Kontext anwendbare Standard-Zeitzone zwar von der Prüf- und Berechnungslogik berücksichtigt wird, aber in den Daten des Rückgabewerts nicht explizit erscheint. Die für die Interpretation genutzte Zeitzone kann entscheidend dafür sein, welchem Kalendertag ein bestimmter Eingabewert zugeordnet wird, der formal nur "UTC-Millisekunden" definiert. Der abhängig vom Abgleich zwischen dem zugeordneten Kalendertag und einem Kalender ermittelte Rückgabewert wird dann aber wieder nur in "UTC-Millisekunden" definiert.
Zur Ermittlung der Rückgabewerts greift folgende Fallunterscheidung:
Geeigneter Typ als Eingabewert? |
Kalender definiert? |
"Werktag-Prüfung" (s. u.) |
Option |
Rückgabewert |
|
irrelevant |
irrelevant |
irrelevant |
Eingabewert |
|
|
|||
|
|
|||
|
|
Ausweichtermin: geringstmögliche Verschiebung des Eingabewerts (Datumswert/-bereich) nach später, |
||
|
Ausweichtermin: geringstmögliche Verschiebung des Eingabewerts (Datumswert/-bereich) nach früher, |
|||
►HINWEISE◄ Regeln für das "Vorwärts springen" oder "Rückwärts springen"
|
Für die "Werktag-Prüfung" des Eingabewerts gegen den definierten Kalender gelten folgende Regeln:
Typ des Eingabewerts |
Prüflogik |
Long |
Ein Datumswert (im Unterschied zu einem "Datumsbereich", s. u.) gilt als Werktag, wenn der unter Berücksichtigung der anwendbaren Zeitzone ermittelte Kalendertag laut dem definierten Kalender als Werktag gilt. Dabei werden ggf. Festlegungen auf unterschiedlichen Ebenen des Kalendermodells berücksichtigt:
Ein Kalendertag gilt als Werktag, wenn eine der folgenden Bedingungen erfüllt ist:
Verweise auf ungeeignet parametrierte Kalender in einem Kalenderfilter-Wertauflöser können Endlosschleifen verursachen, die einen Neustart des Servers erfordern. |
"Datumsbereich mit Zeit" |
Ein "Datumsbereich" gilt als Werktag, wenn die unter Berücksichtigung der Zeitzone ermittelten Kalendertage für die "Von"- und die "Bis"-Komponente bei der Bewertung gegen den definierten Kalender nach der oben beschriebenen Prüflogik als Werktage gelten. ►WICHTIG◄ Ob der Kalender zwischen dem "Von"- und "Bis"-Kalendertag Werktage ausweist oder nicht, spielt für die Prüfung keine Rolle! Wird die Prüfung für einen Datumsbereich nicht bestanden, dann wird der Datumsbereich insgesamt "parallel" verschoben, also ein Ausweichtermin unter Beibehaltung der originalen Zeitspanne zwischen "Von"- und "Bis"-Komponente ermittelt. ►WARNUNG◄ Möglicherweise beinhaltet ein Kalender in der gewünschten Suchrichtung kein Paar von Werktagen (für "Von" und "Bis") im "passenden" Abstand. Definiert ein Kalender z. B. nur drei benachbarte Wochentage (etwa: Montag, Dienstag und Mittwoch) als Werktage, dann ist es unmöglich, einen geeigneten Termin für einen Datumsbereich mit einer Zeitspanne von 3 - 4 Tagen zu finden. Das folgende Schema verdeutlicht die Problematik im Beispiel: |
Konfiguration
Der Kalenderfilter-Wertauflöser erwartet als Eingabewert einen Datumswert oder Datumsbereich, der per Verkettung oder als Bezugsobjekt bereitgestellt werden kann.
Die Option Statisch (per Standard abgewählt) bezieht sich auf die Konfiguration für den Pflichtparameter Kalender. Wir die Option ausgewählt (s. Bild) erscheint ein Auswahlfeld, das eine statische Einfachauswahl für einen Kalender unterstützt. Im Dropdown erscheinen alle Kalender für die im Kontext der Konfiguration Lesezugriff besteht. Zur Laufzeit besteht immer Zugriff auf den ausgewählten Kalender. Ein bereits ausgewählter Kalender, für den in der aktuellen Konfigurationssitzung kein Lesezugriff besteht erscheint mit der Beschriftung "Hidden calendar". Wie im Bild gezeigt, unterstützt eine Suchfunktion die Auswahl des Kalenders anhand der im Label enthaltenen Eigenschaften (im Beispiel: Name "24-1 (MON)"). |
|
Wird die Option Statisch abgewählt, dann kann und muss für den Parameter Kalender ein Wertauflöser konfiguriert werden. Als Rückgabewert für den Wertauflöser wird entweder ein Kalender-Objekt (Calendar) erwartet (s. Bild rechts unten) oder ein Long-Wert (s. Bild rechts), der die ID (id) eines Kalender-Objekt angibt. Im Bild rechts oben referenziert der statisch definierte Long-Wert 451 den Kalender "24-1 (MON)" aus dem Beispiel darüber. Im Bild rechts unten wird ein Variable-Wertauflöser eingesetzt, um eine Variable zu lesen, die zur Laufzeit ein Objekt vom Typ "Kalender" (Calendar) liefern muss. Diese Variable könnte z. B. mit einer Suche (Ereignisaktion) befüllt werden. ►HINWEISE◄
|
|
|
|
Die Option Rückwärts springen ist per Standard abgewählt. Dann wird im Kalender (bzw. entlang einer theoretischen "Zeitachse") "vorwärts gesprungen", falls der Eingabewert die "Werktag-Prüfung" (s. o.) nicht besteht. Wird die Option Rückwärts springen ausgewählt, dann wird bei Bedarf nach Ersatzterminen gesucht, die früher liegen als Eingabewert.
|
|
Beispiele
Einfache Terminberechnung unter Berücksichtigung von Werktagen
Im Kontext einer Ereignisbehandlung wird die voraussichtlichen Ankunftszeit ("ETA") einer Sendung als "Datum mit Zeit" berechnet. Da die eintreffende Ware nur bei Eingang an einem Werktag als sofort (bzw. an demselben Kalendertag) verfügbar gilt, soll das berechnete "ETA"-Datum noch mit einem bestehenden Kalender abgeglichen werden, um ein weiteres Datum ("AVAIL") für die effektive Verfügbarkeit der Ware beim Empfänger zur ermitteln. Der Benutzer soll durch eine Hinweis anzeigen (Popup)-Ereignisaktion über die Kalendertage für "ETA" und "AVAIL" informiert werden. Laufzeitbeispiel:
Konfiguration: Für die Konfiguration rechts gilt das bereits berechnete "ETA"-Datum (als "Datum mit Zeit") als Bezugsobjekt innerhalb einer Ausführen mit-Ereignisaktion (nicht im Bild).
►ANMERKUNG◄ Das Verfügbarkeitsdatum wird hier nur als Kalendertag ohne Uhrzeitkomponenten angezeigt und auch sonst nicht verarbeitet oder gespeichert. Insofern spielt es keine Rolle, dass eine im berechneten "ETA"-Datum enthaltene Uhrzeit ggf. an das "AVAIL"-Datum übergeht. Das folgende Beispiel beschäftigt sich mit diesem Problem. |
|
Terminberechnung mit bedingter Anpassung der Uhrzeit (nur beim "Vorwärts springen" zum folgenden Werktag)
Das vorige Beispiel soll nun so erweitert werden, dass einerseits die im "ETA"-Datum berechnete Uhrzeit minutengenau in der Meldung erscheint. Andererseits soll beim "Vorwärts springen" - also wenn das "ETA"-Datum auf einen Kalendertag fällt, der kein Werktag ist - die Uhrzeit für den Verfügbarkeitstermin ("AVAIL") statisch auf die Uhrzeit 07:30 Uhr (am folgenden Werktag) gesetzt werden. Trifft die "ETA" direkt einen Werktag soll die Ware weiterhin als "sofort" verfügbar gelten. Laufzeitbeispiel:
Konfiguration:
|
|
Terminermittlung gegen einen zur Laufzeit "dynamisch" ausgewählten Kalender
Im Kontext einer Ereignisbehandlung soll für eine konkrete Bestellung ermittelt werden, bis zu welchem Termin im laufenden Monat über den für die Bestellung bereits ausgewählten Spediteur noch Teilladungen beauftragt werden können. Je Spediteur sei deshalb für die Terminkoordination ein Kalender mit dem einheitlichen Namen "LTL" angelegt, der wiederkehrende und diskret festgelegte Terminoptionen für die Abwicklung von Teilladungen als "Werktage" abbildet. Konfiguration: Die Ereignisbehandlung muss im Kontext der betreffenden Bestellung zunächst den zum ausgewählten Spediteur passenden Kalender ermitteln. Dies ermöglicht eine Suche (Ereignisaktion), die innerhalb einer Ausführen als-Ereignisaktion ausgeführt wird, damit der Lesezugriff für die im Besitz der diversen Spediteure angelegten Kalender gewährleistet ist. Die Suche (Ereignisaktion) soll hier nicht ausführlich beschrieben werden. Sie soll als Tupel-Suche den ersten (und konventionsgemäß: einzigen) Kalender im Besitz eines bestimmten Spediteurs finden, dessen Name "LTL" lautet. Als Projektion wird für den Kalenderfilter nur das Feld id benötigt. Das Ergebnis der Tupel-Suche wird in die Variable LTL@FWD geschrieben.
►ANMERKUNG◄ Der Fall, dass der LTL_ultimate-Termin zum Zeitpunkt der Anfrage bereits in der Vergangenheit liegt, wird hier nicht gesondert behandelt. |
|
Laufzeitbeispiel: Ein Spediteur bietet Transporte für Teilladungen laut seinem "LTL"-Kalender grundsätzlich nur Donnerstags an. Eine Abfrage für den LTL_ultimate-Termin im August 2022 ergibt den rechts dargestellten Wert, der auf den Kalendertag "Donnerstag, 25 August 2022" verweist. ►ANMERKUNG◄ Der Millisekunden-Wert im Feld dateValue in der Darstellung rechts zeigt, dass sich die Uhrzeit (23:59:59.999) aus dem Eingangswert ("Ende des Monats") auch im Rückgabewert des Kalenderfilters spiegelt. |
Ausschnitt aus dem
<entry> <key xsi:type= "xsd:string" >LTL_ultimate</key> <value dateValue= "1661464799999" timeZone= "Europe/Berlin" xsi:type= "core:DateTime" /> </entry> |
Terminversatz um eine vorgegebene Anzahl von Werktagen
Ausgehend von einem - hier als "Datum mit Zeit"-Wert in der Variablen start - vorgegebenen Datum soll im Abgleich mit einem bestimmten Kalender ein Zieldatum (end) ermittelt werden, das eine bestimmte Anzahl von Werktagen (offset) nach dem start liegt. Konfiguration: Innerhalb einer Ereignisaktion iteriert die rechts abgebildete Für jeden Eintrag wiederholen (Schleife) über die Variable offset, die die Anzahl der Werktage ab start als Ganzzahl definiert:
Am Ende sollten zwischen start und end genau so viele Werktage (nach dem ausgewählten Kalender) Differenz liegen, wie in der Variable offset angegeben wurde. ►ANMERKUNG◄ Die hier gezeigte Konfiguration setzt voraus, dass der Wert der Variablen offset>0 ist und die Variable end zu Beginn noch keinen Wert ($null) enthält. |
|