Module Workflow Geschätzte Lektüre: 9 Minuten Workflows in LIMBAS Ein Workflow zur Kundenakquise Im folgenden Beispiel wird ein Workflow zur Akquise von Neukunden für Softwarelösungen vorgestellt. Anschließend wird gezeigt, wie dieser in LIMBAS umgesetzt werden kann. Der Workflow ist in Abbildung 1 schematisch dargestellt. (Abb. 1) (1) Um einen möglichen Neukunden anzuwerben, sendet man ihm zunächst ein Werbeprospekt zu.(2) Wenn der Kunde daraufhin Interesse an dem Produkt zeigt, dann wird ihm außerdem ein Onlinedemozugang bereitgestellt.(3) Bekräftigt der Kunde weiterhin sein Interesse, dann besteht noch die Möglichkeit, ihm eine Demo-CD zukommen zu lassen.(4) Wenn der Kunde endgültig überzeugt ist, dann sollte ein Projekttermin mit ihm vereinbart werden.(5) Falls der Kunde jedoch eine Absage erteilt, wird der Kundenakquise-Workflow abgebrochen. Der Workflow definiert die mögliche Abfolge der einzelnen Schritte in der Kundenakquise.Wurde der Workflow initiiert, dann ist der erste Schritt immer die Zusendung eines Werbeprospekts. Außerdem soll es in diesem Beispiel erst möglich sein, einen Projekttermin zu vereinbaren, wenn der Kunde einen Demozugang oder eine Demo-CD erhalten hat.Ein Abbruch der Kundenakquise ist bis vor der Fixierung des Projekttermins möglich. Des Weiteren legt der Workflow nach Durchführung jedes Schritts einen Eintrag für die Korrespondenz mit dem Kunden an.Um den Mitarbeiter nach jeder Akquiseaktion daran zu erinnern, den Kunden wieder nach sieben Tagen zu kontaktieren und sich nach seinem Interesse zu erkundigen, wird hierzu automatisch eine Wiedervorlage in Limbas angelegt.Zuletzt nimmt der Workflow Benutzereingaben über Formulare entgegen und trägt sie in die entsprechenden Datensätze ein.So wird z.B. der Projekttermin in den Kalender eingetragen oder der für die Absage vom Benutzer angegebene Absagegrund in einen automatisch erstellten Korrespondenzeintrag übernommen. Abbildung 2 zeigt das Unterformular Akquise_Absagegrund. Anlegen des Workflows Der Workflow muss zuerst im Admininterface definiert werden. Hierzu erstellen wir einen neuen Workflow mit dem Namen „Kundenakquise“. Nach Klick auf den Editier-Button können die einzelnen Schritte (Tasks) des Workflows definiert werden.Zu jedem Task wird außerdem die Tabelle angegeben, die das Formular für die entsprechende Workflow-Aktion enthalten soll.In unserem Beispiel ist dies für alle Tasks die Tabelle Kunden, da der Nutzer einen Datensatz der Kundentabelle aufrufen und hier über ein Formular die einzelnen Aktionen des Workflows durchführen soll.Das Admininterface bietet auch die Möglichkeit, Parameter an den Workflow zu übergeben. Auf diese Weise können konfigurierbare Workflows entwickelt werden. So übergeben wir z. B. für Task 1 bis 3 als Parameter ein Array mit dem Element „reminder_days“.Dieses legt fest, wie viele Tage nach der Zusendung einer Broschüre, der Bereitstellung einer Demo-CD oder eines Demozugangs der Benutzer über eine Wiedervorlage daran erinnert werden soll, den Kunden wieder zu kontaktieren.Um Wiedervorlagen, die automatisch von dem Workflow nach Durchführung einer Aktion angelegt werden sollen, separat anzuzeigen, benötigen wir eine neue Wiedervorlagenliste.Diese kann über den Menüpunkt Wiedervorlage im Admininterface angelegt werden. Hierfür wählen wir den Namen Akquise und legen als Grundtabelle ebenfalls Kunden fest. (Abb. 2) Implementierung des Workflows Ein Workflow wird in LIMBAS als Erweiterung gehandhabt. Wir haben für das im Anschluss vorgestellte Skript eine Datei mit dem Namen „ext_gtab_change.inc“ im Ordner „dependent/EXTENSIONS/workflow/“ angelegt.Diese Datei beinhaltet unsere individuellen Workflow-Funktionen und die Initiierung des Workflows, die im Folgenden dargestellt ist: #limbas workflow engine require_once("extra/workflow/lwf.lib"); #get wfl instance of dataset $wfl_inst = lmb_wfl_getRecordInst(1,$gtabid,$ID); #start Workflow if(isset($myExt_sendTask)){ #init Task lmb_wfl_init(1,$wfl_inst,$wfl_task,$gtabid,$ID,$params); } Zunächst müssen wir die Bibliothek lwf.lib einbinden, die die Workflow Engine von Limbas bereitstellt. Zusätzlich benötigen wir drei grundlegende Informationen: $wfl_id – ID des gewünschten Workflows: Generell können beliebig viele Workflows erstellt werden. Es wird aber nur immer ein einziger Workflow auf einmal abgearbeitet.Unser Beispiel enthält nur einen Workflow mit dem Namen Akquise und der ID 1. $wfl_task – ID des auszuführenden Tasks: Die Task-ID entscheidet, welcher Task als Nächstes ausgeführt werden soll. Diese kann zum Beispiel über ein Formular übergeben werden.In unserem Fall wird über ein Formular der Parameter $myExt_sendTask übergeben. $wfl_inst – ID der aktuellen Instanz: LIMBAS kann jedem Datensatz einer Tabelle eine oder mehrere Instanzen (Workflowketten) zuweisen.Ob ein Datensatz einer Instanz zugewiesen ist, kann über die Hilfsfunktion lmb_wfl_getRecordInst abgefragt werden. Ebenso wäre es möglich, die Instanz-ID über Formulare oder URLs mit zu übergeben.LIMBAS übergibt in internen Requests standardmäßig die Workflow-ID ($wfl_id) und Instanz-ID ($inst_id) falls vorhanden. In unserem Fall fragen wir explizit nach der Instanz-ID für einen bestimmten Kunden. Die Funktion lmb_wfl_init initiiert schließlich den Workflow. Dabei werden der Funktion zusätzliche Variablen als Parameter übergeben: $gtabid – ID der aktuellen Tabelle $ID – ID des entsprechenden Datensatzes $params – benutzerspezifischer Parameter Task-Funktionen Nach der Initiierung versucht LIMBAS, den entsprechenden Task auszuführen. Dazu benötigen wir für jeden Task eine entsprechende Funktion.Diese Funktion muss den Namen lmbW!_[TASK_ID] tragen, wobei TASK_ID mit der entsprechenden Task-ID zu ersetzen ist. Diese Funktionen sollen in zukünftigen LIMBAS-Versionen teilweise durch ein grafisches Frontend erstellbar sein.Ob der Workflow immer nur den nächsthöheren Task oder beliebige Tasks ausführen darf, liegt ganz in der Hand des Entwicklers. In unserem Beispiel kann jeder Task aufgerufen werden, damit der Akquisestatus frei änderbar bleibt.Fangen wir mit dem Task 0 bzw. des Starten des Workflows an (Listing 1). Unser Task prüft zunächst, ob der Parameter showElements übergeben wurde. Dies soll immer der Fall sein, wenn ein Formular dargestellt wird.Dann wird die Hilfsfunktion myExt_showElements aufgerufen, die prüft, welche Aktionen der Benutzer durchführen kann und anschließend über eine JavaScript-Funktion das Formular anpasst.In unserem Beispiel übernimmt diese das Einblenden von verfügbaren Aktionsbuttons und das Markieren von bereits erledigten Aktionen. Falls der Task 0 von dem Benutzer aufgerufen wird, um den Workflow zu initialisieren, dann wird showElements nicht übergeben.Erst wenn der Task erfolgreich beendet wurde, ruft der Workflow die nächste höhere Task-ID mit dem Parameter showElements auf. Allgemein gilt, dass ein Task nach erfolgreicher Ausführung als Funktionswert die Task-ID zurückgibt, die als aktiver Task gesetzt wird.In diesem Beispiel setzen wir als aktive Task-ID immer die ID des zuletzt ausgeführten Tasks. Um den Workflow erfolgreich zu initialisieren, wird hier also 0 zurückgegeben.Falls dagegen Fehler während der Ausführung auftreten, soll die Funktion false zurückgeben werden. Die LIMBAS Workflow Engine macht in diesem Fall alle von dem Task durchgeführten Änderungen an der Datenbank wieder rückgängig.Ein Task kann auch nur true zurückgeben, falls er keine Änderungen am Workflow durchgeführt hat, z.B. wenn er mit showElements aufgerufen wurde. Der nächste Task ist in unserem Beispiel das Zusenden einer Broschüre an den Kunden (Listing 2).LIMBAS protokolliert für alle Instanzen eines Workflows die bereits durchgeführten Tasks in einer History.Damit eine Workflow-Aktion beispielsweise nur einmal durchgeführt wird, prüft man ihr Vorhandensein in der History, die über die Funktion lmb_wfl_getHistory abgerufen werden kann.Als Nächstes legen wir eine Wiedervorlage mit der Funktion myExt_createReminder an, um den Kunden in dem festgelegten Zeitraum wieder zu kontaktieren und sich nach seinem Interesse zu erkundigen.Diese Hilfsfunktion greift im Wesentlichen auf die von Limbas bereitgestellte Erweiterungsfunktion lmb_addReminder zurück. Anschließend wird mit wflAddCorrespondence ein Eintrag in der Korrespondenztabelle erstellt.Zuletzt muss noch der Akquisestatus in dem entsprechenden Datenfeld der Kundentabelle neu gesetzt werden. Bei erfolgreicher Ausführung wird die Task-ID 1, ansonsten ein false zurückgegeben. function lmbWfl_0($wfl_inst, $active_task, $gtabid = null, $ID = null, $params = null) { if ($params['showElements']) { $hist = lmb_wfl_getHistory(1, $wfl_inst); myExt_showElements($hist); } else { // start workflow return 0; } } (Listing 1) Erstellung des Formulars als Benutzerschnittstelle für den Workflow Zu guter Letzt erstellen wir noch das entsprechende Akquiseformular für die Durchführung von Workflow-Aktionen. Hierzu rufen wir im Admininterface den Menüpunkt Formulare auf und legen das Formular Akquise für die Tabelle Kunden an.Dieses Formular enthält neben Kundendaten auch einen Bereich für die Workflow-Aktionen (Abb. 3). Um Buttons für die einzelnen Workflow-Aktionen zu erstellen, fügen wir für jede Aktion ein Texteingabefeld mit der entsprechenden Beschreibung ein.Zusätzlich wird dem onClick-Attribut der Wert myExt_sendTask(Id) zugewiesen, wobei ID durch die jeweilige Task-ID ersetzt wird. Diese JavaScriptHilfsfunktion benutzen wir, um die entsprechenden Task-ID zu übermitteln.Das spezifische Aus- oder Einblenden der Buttons in den verschiedenen Tasks wird über eine JavaScript-Funktion erledigt, die nach Laden des Formulars ausgeführt wird.Dies hat den Vorteil, auch Workflow-Elemente wie die Aktionsbuttons über den Formulareditor anpassen zu können. Dazu rufen wir die Workflow-Initialisierungsfunktion über ein PHP-Formularelement auf. Diesmal mit gesetztem showElements-Parameter. (Abb. 3) Fazit LIMBAS stellt im Moment alle Mittel bereit, um individuelle Workflows für Datenbankanwendungen in Code zu implementieren.Dieser Ansatz bietet größtmögliche Flexibilität bei der Umsetzung von Workflows, benötigt aber auch fundierte PHP-Kenntnisse, um die entsprechenden Funktionen zu implementieren.In Zukunft ist geplant, dass grundlegende Workflow-Module wie z.B. Wiedervorlagen, E-Mails oder Datenverarbeitungen über einen Workflow-Designer grafisch zusammengestellt werden können. function lmbWfl_1($wfl_inst, $active_task, $gtabid = null, $ID = null, $params = null) { global $gwfl; global $session; // Get task parameters from admin interface $t_params = $gwfl[WFL_ID]['task']['params']; // Get history of this workflow instance $hist = lmb_wfl_getHistory(WFL_ID, $wfl_inst); $days = $t_params['reminder_days']; if ($params['showElements']) { myExt_showElements($hist); } else { if (!in_array(1, $hist["task_id"])) { // Create reminder to contact customer</font> if (!myExt_createReminder(lmb_utf8_decode("Kunden kontaktieren"), $days, $gtabid, $ID, $wfl_inst)) return false; // Create entry in correspondance table if (!myExt_wflAddCorrespondence($ID, lmb_utf8_decode("Broschüre"), lmb_utf8_decode("Broschüre wurde an den Kunden gesendet."))) return false; // Set acquisition workflow status if (!update_data(array("$gtabid," . ELEMENT_ID_ACQUISITION_STATUS . ",$ID" => lmb_utf8_decode("Broschüre zugesandt")))) return false; return 1; } return true; } } (Listing 2) Dieser Wiki-Eintrag basiert auf einem unserer Artikel aus dem PHP-Magazin