Design Pattern: Gesperrter Datensatz (Blocked Entity)

23. Januar 2014 18:19

Dies ist die deutsche Übersetzung des Artikels Blocked Entity des NAV Design Patterns Projekts.

von Abhishek Ghosh, Microsoft Development Center Copenhagen

Meet the Pattern

Das Muster Gesperrter Datensatz (auch: Gesperrte Entität, engl. Blocked Entity) wird angewendet, wenn Transaktionen für einen Datensatz (meistens ein Stammdaten-Datensatz) vorübergehend oder für immer abgebrochen werden müssen.
Bild

Know the Pattern

Bei diesem Muster erhält der Datensatz einen Status, welcher die Erlaubnis für eine eine bestimmte Transaktion speichert. Der Status wird von der Geschäftslogik ausgewertet, welche die Transaktionen kontrolliert. Die Änderung des Status kann vorübergehend oder dauerhaft sein.

Ein Beispiel für einen vorübergehenden Abbruch könnte z.B. sein: Eine Handelskette hat viele Beschwerden über einen seiner Artikel erhalten und will nun alle Transaktionen im Einkauf und Verkauf für diesen Artikel stoppen, so lange bis der Zulieferer das Problem gelöst hat. Möglicherweise werden für Zwischenzeit Ersatzartikel geliefert.
Weiteres Beispiel: Inventurzählungen, für welche ein Lagerabschnitt gesperrt wird, während im übrigen Lager das Tagesgeschäft fortgeführt wird. Bei diesem Szenario ist es notwendig, einen auszuzählenden Lagerplatz für alle Transaktionen, z.B. Kommissionierungen und Einlagerungen, für die Dauer der Zählung zu sperren.

Im Gegensatz dazu können endgültige Sperren notwendig sein, wenn ein Artikel dauerhaft aus dem Sortiment gezogen wird bzw. werden soll und der Betrieb den weiteren Einkauf oder Verkauf dieses Artikels unterbinden möchte. Da der Betrieb die Transaktionshistorie für diesen Artikel wahren möchte, möchte er den Artikel nicht löschen.

Die Implementierung dieser Art von Anforderungen erfolgt in Microsoft Dynamics NAV einfach, indem der betroffenen Tabelle (und der dazu gehörigen Page) ein Gesperrt-Feld hinzugefügt wird. Dessen Feldwert wird in der Geschäftslogik an den für diese Transaktion relevanten Stellen ausgewertet. In den meisten, einfachen Fällen benötigt man für das Gesperrt-Feld nur zwei Werte (ja oder nein), welche kennzeichnen ob für diesen Datensatz die Transaktion ausgeführt werden darf, oder nicht.

Manchmal aber können zusätzliche (konditionale) Sperrebenen erforderlich sein. Zum Beispiel möchte ein Unternehmen Verkäufe an Kunden mit überfälligen Zahlungen so lange unterbinden, bis die Zahlungen geleistet worden sind. Oder, der Kunde hat eine Rechnung reklamiert, und das Unternehmen möchte eine weitere Faktura so lange unterbinden, bis das Problem mit dem Kunden geklärt worden ist. Gleichzeitig sollen ausstehende Lieferungen an den Kunden fortgesetzt werden, um die Geschäftsbeziehung nicht zu gefährden. In diesen Fällen können, je nach Anforderung, weitere Status für das Gesperrt-Feld nowendig sein.

Use the Pattern

Wie bereits im vorherigen Abschnitt erwähnt wurde, wird dieses Muster je nach Anforderung auf zwei Arten implementiert: Entweder als Boolean-Feld (zwei Ausprägungen für einfache Anforderungen) oder als Optionsfeld für komplexere Anforderungen. Nachfolgend werden diese beiden Arten näher erläutert.

  • Implementierung als Boolean-Feld
    Fügt der Tabelle ein neues Boolean-Feld namens Gesperrt (engl. Blocked) hinzu.

    Fügt an geeigneter Stelle eine Prüfung des Feldes ein. Am einfachsten geht dies mit dem Befehl TESTFIELD:
    Code:
    <rec variable>.TESTFIELD(Blocked,FALSE);

    Alternativ kann auch eine selbst formulierte Fehlermeldung ausgegeben werden. Dies solltet ihr aber nur dann tun, wenn euch die vom TESTFIELD generierte Fehlermeldung nicht reicht.

  • Implementierung als Option-Feld
    Fügt der Tabelle ein neues Option-Feld names Gesperrt (eng. Blocked) hinzu. Die Optionswerte werden die unterschiedlichen Sperrstatus abbilden, welche vom Unternehmen gefordert werden.

Fügt dieses Feld der Card Page (oder der List Page, falls es für diese Tabelle keine Card Page gibt) hinzu. Wie auch bei der Implementierung als Boolean-Feld fügt man das Feld normalerweise in die rechte Spalte des Inforegisteres Allgemein (engl. General) ein.

Erstellt in der Tabelle eine neue Funktion, an welche der Transaktionskontext übergeben wird, und welche unter Auswertung des Gesperrt-Feldes entscheidet, ob die Transaktion erlaubt ist oder nicht. Wahlweise können bereits innerhalb dieser Funktion Fehlermeldungen implementiert werden.

Hinweis: Optionsfelder setzen voraus, dass zu einem Zeitpunkt genau ein Optionswert gültig sein kann. Oder anders gesagt: die Optionswerte sollten sich gegenseitig ausschließen.

  • Hier ein Beispiel, wie man es besser nicht machen sollte: Wenn wir einen Artikel für den Verkauf und/oder Einkauf sperren wollen, bieten sich zunächst folgende 4 Optionen an: Nicht sperren | Verkauf sperren | Einkauf sperren | Verkauf und Einkauf sperren. Möchte man aber nun nachträglich weitere Transaktionen hinzufügen, wird die Anzahl an notwendigen Optionswerten unüberschaubar. Sinnvoller ist es, zwei Boolean-Felder zu schaffen: Verkauf gesperrt: ja|nein und Einkauf gesperrt: ja|nein.

  • Ein gutes Anwendungsbeispiel wäre es, das Verhalten an der gewählten Option auszurichten, z.B. je Sperrgrund eine andere Fehlermeldung auszugeben. Hiefür wären z.B. folgende Optionswerte für einen Artikel denkbar: Nicht gesperrt | Wegen Defekt gesperrt | Wegen ausstehender Genehmigung gesperrt usw.

Beispiel

Implementierung als Boolean-Feld
Als Beispiel der Boolean-Implementierung schauen wir uns die Artikelkarte an.
Artikelkarte.png
In Codeunit 22 - Item Jnl-Post Line, wurde mit folgenden Codezeilen eine Prüfung auf Basis des Gesperrt-Feldes realisiert:

Code:
IF NOT CalledFromAdjustment THEN
  Item
.TESTFIELD(Blocked,FALSE);


Implementierung als Option-Feld
Als Beispiel der Option-Feld-Implementierung schauen wir uns die Debitorenkarte an.
Debitorenkarte.png
Die Funktionen CheckBlockedCustOnDocs und CheckBlockedCustOnJnls in der Tabelle Customer werten das Gesperrt-Feld abhängig von der übergebenen Belegart aus. Diese Funktionen wiederum werden an verschiedenen Stellen, z.B. bei Buchungsroutinen, aufgerufen, wo eine Statusprüfung des Gesperrt-Feldes notwendig ist. Diese Vorgehensweise ist gerade bei noch komplexeren Implementierungen sinnvoll, da dies es die Wiederverwendung vereinfacht und dafür sorgt, dass die Prüfung immer nach dem gleichen Schema verläuft.

Verwendung im NAV-Standard

Der NAV-Standard wendet das Muster Gesperrter Datensatz bereits in folgenden Tabellen an:

  • Item (Artikel)
  • G/L Account (Sachkonto)
  • Customer (Debitor)
  • Vendor (Kreditor)
  • Bin (Lagerplatz)
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.