1 2 3 13 Previous Next

SAP Business Process Management

184 Posts

I am in learning phase of BPM. I successfully created a process which involved 3 WDJ screens and 2level BPM process.

Although i faced below WebService Exception frequently

Exception on execution of web service  with operation Operation' in interface WSDL

 

 

Mainly I found two reasons for the exception:

 

 

1. Authentication has failed for webService

2. All the parameters are not set

 

Solution:

 

1. Set UserId Password to the web service to code

 

Refer link below:

 

http://wiki.scn.sap.com/wiki/display/WDJava/Exception+on+Execution+of+Web+Service

 

Or

 

Set Authentication Property to your WDJ application:

 

 

Select Application -> go to Property ->

 

Select Application Properties

 

Capture1.PNG

 

 

Click Add

 

 

Click on browse select Authentication.

 

Capture2.PNG

 

 

 

And Run the application. It will ask for credentials.

 

 

 

2.  If any of the parameter value is not set it might throw exception. If you dont have values for all set empty string.

Hi

 

My name is Jan Nyfeler.

 

Today I'd like to write about SAP NW BPMs new OData-Services for Completing Tasks and - new - starting Processes. Another concern I'd like to discuss is reusability and componentization within sapui5.

 

I've read the excellent tutorials about the odata task service and the task data odata service from Andre Backofen (Custom UIs with the BPM OData Service and BPM OData: Implementing a Basic Custom Task Execution UI) as well as the blog series about sapui5 and nwds / nwdi by Christian Loos (Developing SAP UI5 applications in SAP NetWeaver Developer Studio - Part 1/2)

 

You can find the official SAP Help here OData Service for Accessing BPM Task Data - Modeling Processes with Process Composer - SAP Library and here BPM OData Service for Starting BPM Processes - Modeling Processes with Process Composer - SAP Library.

 

You can create your project / DC setup according to the blog post by Christian Loos. I came across a couple of issues I had to solve differently or in addition to Christians explenations:

 

DCs

In addition to the web module, you need an Java EE / Enterprise Application Archive (ear). Within this ear-DCs META-INF directory you'll need a file named application.xml. In my case it has the following content:

 

<?xml version="1.0" encoding="ASCII"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" version="5">
  <display-name>pr~sapui5~demo~ear~novobc.ch</display-name>
  <module>
    <web>
      <web-uri>novobc.ch~pr~sapui5~demo.war</web-uri>
      <context-root>pr~sapui5~demo~novobc.ch</context-root>
    </web>
  </module>
</application>

 

In the web module there is a web.xml file. I don't need the extra content as described by Christian. My web.xml looks like

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>pr~sapui5~demo~novobc.ch</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

Afterwards you're ready to go.

 

In my example I'd like to create a very simple approval-process. Therefor we'll need three DCs. You can name them as your companies naming convention ask you to. In my case the three DCs are:

  • Web Module (pr/sapui5/demo)
  • Enterprise Archive (pr/sapui5/demo/ear)
  • Process Composer (pr/pm/demo)

 

Process

My process looks like this:

Process.PNG

However I'm going to cover only the process start application as well as the user interface for the activity "Antrag stellen". The idea is the following: an employee can start a process and check it in this activity. After completing the task, the process is forwarded to the employees supervisor for approval.

 

The web service used for starting a process looks like this:

 

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.example.org/Start_Bewilligung_Async/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Start_Bewilligung_Async" targetNamespace="http://www.example.org/Start_Bewilligung_Async/">
  <wsdl:types>
    <xsd:schema targetNamespace="http://www.example.org/Start_Bewilligung_Async/" xmlns:Q1="http://www.example.org/Antrag">
            <xsd:import schemaLocation="Antrag.xsd" namespace="http://www.example.org/Antrag"></xsd:import>
            <xsd:element name="StartBewilligung">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="Antrag" type="Q1:Antrag"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="StartBewilligungRequest">
    <wsdl:part element="tns:StartBewilligung" name="parameters"/>
  </wsdl:message>
  <wsdl:portType name="Start_Bewilligung_Async">
    <wsdl:operation name="StartBewilligung">
      <wsdl:input message="tns:StartBewilligungRequest"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="Start_Bewilligung_AsyncSOAP" type="tns:Start_Bewilligung_Async">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="StartBewilligung">
      <soap:operation soapAction="http://www.example.org/Start_Bewilligung_Async/StartBewilligung"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="Start_Bewilligung_Async">
    <wsdl:port binding="tns:Start_Bewilligung_AsyncSOAP" name="Start_Bewilligung_AsyncSOAP">
      <soap:address location="http://www.example.org/"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

The correspondig Antrag-Datatype looks like this:

 

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/Antrag" xmlns:tns="http://www.example.org/Antrag$" elementFormDefault="qualified">
    <complexType name="Antrag">
    <sequence>
    <element name="Mitarbeiter" type="string"></element>
    <element name="Vorgesetzter" type="string"></element>
    <element name="Titel" type="string"></element>
    <element name="Beschreibung" type="string"></element>
    <element name="Status" type="string"></element>
    </sequence>
    </complexType>
</schema>

 

 

SAPUI5

Icons

Check out the sap-icon://-Protocol. It's a great and easy way to include icons into your views....

Views

SAPUI5 offers different ways of creating views (JavaScript, JSON, HTML, XML). I usually choose to create XML view as it is the (for me personally) most self-explanatory way and it's very easy to bind data to input elements.

In addition, I've found this tool (Fast SAPUI5 Develop tool) by Lucky Li for creating views - as there is no WYSIWYG-Editor for SAPUI5 (See wish list down below) so far this might help others.

Form-Fragments

I'm a lazy guy and don't like to do stuff twice ;-)

Web Dynpro has a great componentization approach - you create a component and reuse it as many time as you want to. By Context-Mapping and public methods you can interact with the reused components in every way you need to.

I discovered the fragment-approach in SAPUI5: this enables you to create a UI-Fragment and reuse this fragment in different views. Not exactly the same comfort as in Web Dynpro, but it's a good beginning.

 

My fragment for the approval process looks like this (Antrag.fragment.xml):

<core:FragmentDefinition
  xmlns="sap.m"
  xmlns:l="sap.ui.layout"
  xmlns:f="sap.ui.layout.form"
  xmlns:core="sap.ui.core">
  <Panel id="FragmentPanel">
  <l:Grid
    defaultSpan="L12 M12 S12"
    width="auto">
    <l:content>
    <f:SimpleForm id="Formular"
        minWidth="1024"
        maxContainerCols="2"
        editable="true"
        layout="ResponsiveGridLayout"
        title="Antrag"
        labelSpanL="4"
        labelSpanM="4"
        emptySpanL="0"
        emptySpanM="0"
        columnsL="2"
        columnsM="2"
        class="editableForm">
        <f:content>
          <core:Title text="Antragsdaten" />
          <Label text="Titel" />
          <Input id="Titel" value="{Antrag/Titel}" />
          <!--<Label text="Datum" />
    <DateTimeInput type="Date">
      <layoutData>
              <l:GridData span="L4 M4 S4" />
          </layoutData>
          </DateTimeInput> -->
        <!-- <Label text="Kosten" />
          <Input id="Kosten" value="{Antrag/Kosten}" type="Number">
          <layoutData>
              <l:GridData span="L4 M4 S4" />
          </layoutData>
          </Input> -->
          <Label text="Status" />
          <Select id="Status" selectedKey="{Antrag/Status}" width="100%">
            <items>
              <core:Item text="" key="" />
              <core:Item text="Entwurf" key="Entwurf" />
              <core:Item text="Beantragt" key="Beantragt" />
              <core:Item text="Bewilligt" key="Bewilligt" />
              <core:Item text="Korrektur" key="Korrektur" />
              <core:Item text="Abgelehnt" key="Abgelehnt" />
            </items>
          </Select>
          <Label text="Beschreibung" />
          <TextArea id="Beschreibung" value="{Antrag/Beschreibung}" rows="8" />
          <core:Title text="Beteiligte" />
          <Label text="Mitarbeiter" />
          <Input id="Mitarbeiter" value="{Antrag/Mitarbeiter}" />
          <Label text="Vorgesetzter" />
          <Input id="Vorgesetzter" value="{Antrag/Vorgesetzter}" />
        </f:content>
      </f:SimpleForm>
    </l:content>
  </l:Grid>
  </Panel>
</core:FragmentDefinition>

The view for my Start application looks like this:

<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:c="sap.ui.commons"
  controllerName="demo.StartAntrag" xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form" xmlns:html="http://www.w3.org/1999/xhtml">
  <Panel id="Panel">
  </Panel>
      <Bar>
        <contentRight>
          <Button id="Abschliessen" text="Bewilligungsprozess starten" press="handleAbschliessenPress" />
        </contentRight>
      </Bar>
</core:View>

And the view for the Task looks like this:

<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:c="sap.ui.commons"
  controllerName="demo.AntragM" xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form" xmlns:html="http://www.w3.org/1999/xhtml">
  <Panel id="Panel">
  </Panel>
      <Bar>
        <contentRight>
          <Button id="Abschliessen" text="Abschliessen" press="handleAbschliessenPress" />
        </contentRight>
      </Bar>
</core:View>

 

For both views the fragment is inserted at onInit() in the corresponding controller.

Start Process

There are new odata-services for working with sap nw bpm processes.

The SAP help says, that first a X-CSRF-Token need to be fetched (GET-Request) and afterwards a POST request should be submitted in order to start a process. Using SAPUI5 OData-Model the code would look similar to this:

var startProcessSvcURL = "/bpmodata/startprocess.svc/novobc.ch/pr~pm~demo/Bewilligung";
            var startData = {};
            startData.ProcessStartEvent = {};
            startData.ProcessStartEvent.Antrag = {};//Form binding;
oModel.create("/StartData", startData, null, function(
                                               oData, oResponse) {
                                         // message
                                         }, function(oEvent) {
                                               sap.m.MessageBox.show("Beim Start des Prozesses ist ein Fehler aufgetreten.",
                                                           sap.m.MessageBox.Icon.ERROR,
                                                           "Fehler beim Prozessstart");
                                         });

However we were not getting this to work as the initial GET-request in order to fetch the Token is sent to an invalid url.

It tries to get from ../bpmodata/startprocess.svc/novobc.ch/pr~pm~demo/Bewilligung which is the root url used to initialize the OData-Model. As the Post (oModel.create()) is submitted to /bpmodata/startprocess.svc/novobc.ch/pr~pm~demo/Bewilligung/StartData it should also try to fetch the token from this url. However, we were not able to get it working correctly, but Andre Backofen was a great support and offered to investigate our issue further.

 

To get the demo process working, we're avoiding SAPUI5 OData-Model in this particular case and are going JQuery: First, we're fetching the Token by GET.

Afterwards we reuse the fetched token and set it to the post request's header.

 

$.ajax({
    type: 'GET',
    url: 'http://s083.novo-bc.ch:50000/bpmodata/startprocess.svc/novobc.ch/pr~pm~demo/Bewilligung/StartData',
    beforeSend: function(requestGET){requestGET.setRequestHeader('X-CSRF-Token', 'Fetch');},
    success: function(data, textStatus, requestGET){
    $.ajax({
   type: 'POST',
   url: 'http://s083.novo-bc.ch:50000/bpmodata/startprocess.svc/novobc.ch/pr~pm~demo/Bewilligung/StartData',
   beforeSend: function(requestPOST){
  requestPOST.setRequestHeader('X-CSRF-Token', requestGET.getResponseHeader('X-CSRF-Token'));
  requestPOST.setRequestHeader('Content-Type', 'application/json');
    },
   data: startData,
   success: function () {sap.m.MessageBox.show("Der Prozess wurde erfolgreich gestartet. Sie können das Fenster schliessen.",
  sap.m.MessageBox.Icon.SUCCESS,
  "Prozess erfolgreich gestartet");}
  });
    }
   });

 

Here is the complete code of the working controller - I'm aware that it won't win a beauty contest (especially how I created the payload), but it's working and starts the demo process:

jQuery.sap.require("demo.Util");
jQuery.sap.require("sap.m.MessageBox");
sap.ui
  .controller(
  "demo.StartAntrag",
  {
  getFormFragment : function() {
  return sap.ui.xmlfragment("demo.Antrag", this);
  },
  /**
  * Called when a controller is instantiated and its View
  * controls (if available) are already created. Can be used
  * to modify the View before it is displayed, to bind event
  * handlers and do other one-time initialization.
  *
  * @memberOf demo.Antrag
  */
  onInit : function() {
  this.oForm = this.getFormFragment();
  var oPanel = this.getView().byId("Panel");
  oPanel.removeContent(0);
  oPanel.insertContent(this.oForm);
  var oMitarbeiter = sap.ui.getCore().byId("Mitarbeiter");
  oMitarbeiter.setValue("Nyfeler Jan");
  oMitarbeiter.setEnabled(false);
  var oVorgesetzter = sap.ui.getCore().byId("Vorgesetzter");
  oVorgesetzter.setValue("Nyfeler Jan");
  oVorgesetzter.setEnabled(false);
  var oStatus = sap.ui.getCore().byId("Status");
  oStatus.setSelectedKey("Entwurf");
  oStatus.setEnabled(false);
  },
  /**
  * Similar to onAfterRendering, but this hook is invoked
  * before the controller's View is re-rendered (NOT before
  * the first rendering! onInit() is used for that one!).
  *
  * @memberOf demo.Antrag
  */
  // onBeforeRendering: function() {
  //
  // },
  /**
  * Called when the View has been rendered (so its HTML is
  * part of the document). Post-rendering manipulations of
  * the HTML could be done here. This hook is the same one
  * that SAPUI5 controls get after being rendered.
  *
  * @memberOf demo.Antrag
  */
  // onAfterRendering: function() {
  //
  // },
  /**
  * Called when the Controller is destroyed. Use this one to
  * free resources and finalize activities.
  *
  * @memberOf demo.Antrag
  */
  // onExit: function() {
  //
  // }
  handleAbschliessenPress : function() {
  var that = this;
  var startProcessSvcURL = "/bpmodata/startprocess.svc/novobc.ch/pr~pm~demo/Bewilligung";
  var oModel = new sap.ui.model.odata.ODataModel(startProcessSvcURL, true);
  var startData = '{"vendor":"novobc.ch","dcName":"pr~pm~demo","processTechnicalName":"Bewilligung","ProcessStartEvent":{"::StartBewilligung":{"Antrag":{"Mitarbeiter":"MitarbeiterValue","Vorgesetzter":"VorgesetzterValue","Titel":"TitelValue","Beschreibung":"BeschreibungValue","Status":"StatusValue"}}}}';
  var Mitarbeiter = sap.ui.getCore().byId("Mitarbeiter").getValue();
  var Vorgesetzter = sap.ui.getCore().byId("Vorgesetzter").getValue();
  var Titel = sap.ui.getCore().byId("Titel").getValue();
  var Beschreibung = sap.ui.getCore().byId("Beschreibung").getValue();
  var Status = sap.ui.getCore().byId("Status").getSelectedKey();
  startData = startData.replace("MitarbeiterValue", Mitarbeiter);
  startData = startData.replace("VorgesetzterValue", Vorgesetzter);
  startData = startData.replace("TitelValue", Titel);
  startData = startData.replace("BeschreibungValue", Beschreibung);
  startData = startData.replace("StatusValue", Status);
  $.ajax({
    type: 'GET',
    url: 'http://s083.novo-bc.ch:50000/bpmodata/startprocess.svc/novobc.ch/pr~pm~demo/Bewilligung/StartData',
    beforeSend: function(requestGET){requestGET.setRequestHeader('X-CSRF-Token', 'Fetch');},
    success: function(data, textStatus, requestGET){
    $.ajax({
  type: 'POST',
  url: 'http://s083.novo-bc.ch:50000/bpmodata/startprocess.svc/novobc.ch/pr~pm~demo/Bewilligung/StartData',
  beforeSend: function(requestPOST){
    requestPOST.setRequestHeader('X-CSRF-Token', requestGET.getResponseHeader('X-CSRF-Token'));
    requestPOST.setRequestHeader('Content-Type', 'application/json');
    },
  data: startData,
  success: function () {sap.m.MessageBox.show("Der Prozess wurde erfolgreich gestartet. Sie können das Fenster schliessen.",
  sap.m.MessageBox.Icon.SUCCESS,
  "Prozess erfolgreich gestartet");}
  });
    }
  });
  }
  });

Working with Tasks

Working with bpm tasks within SAPUI5 is very easy and I mostly referr to Andre Backofens Blog Posts.

 

This is the code of the task controller:

jQuery.sap.require("demo.Util");
jQuery.sap.require("sap.m.MessageBox");
sap.ui.controller("demo.AntragM", {
  getFormFragment: function () {
    return sap.ui.xmlfragment("demo.Antrag", this);
  },
/**
* Called when a controller is instantiated and its View controls (if available) are already created.
* Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization.
* @memberOf demo.AntragM
*/
  onInit: function() {
    oForm = this.getFormFragment();
    var oPanel = this.getView().byId("Panel");
    oPanel.removeContent(0);
    oPanel.insertContent(oForm);
  this.taskId = getValueOfURLParameter("taskId");
  //alert(this.taskId);
  var taskDataSvcURL = "/bpmodata/taskdata.svc/" + this.taskId;
  var taskDataODataModel = new sap.ui.model.odata.ODataModel(taskDataSvcURL, true);
  taskDataODataModel.setDefaultBindingMode(sap.ui.model.BindingMode.TwoWay);
  sap.ui.getCore().setModel(taskDataODataModel);
  oForm.setModel(taskDataODataModel);
  sap.ui.getCore().byId("FragmentPanel").bindElement("/InputData('" + this.taskId + "')", {expand:"Antrag"});
  claimTask(this.taskId);
  var oMitarbeiter = sap.ui.getCore().byId("Mitarbeiter");
  oMitarbeiter.setEnabled(false);
  var oVorgesetzter = sap.ui.getCore().byId("Vorgesetzter");
  oVorgesetzter.setEnabled(false);
  var oStatus = sap.ui.getCore().byId("Status");
  oStatus.setEnabled(false);
  },
/**
* Similar to onAfterRendering, but this hook is invoked before the controller's View is re-rendered
* (NOT before the first rendering! onInit() is used for that one!).
* @memberOf demo.AntragM
*/
// onBeforeRendering: function() {
//
// },
/**
* Called when the View has been rendered (so its HTML is part of the document). Post-rendering manipulations of the HTML could be done here.
* This hook is the same one that SAPUI5 controls get after being rendered.
* @memberOf demo.AntragM
*/
// onAfterRendering: function() {
//
// },
/**
* Called when the Controller is destroyed. Use this one to free resources and finalize activities.
* @memberOf demo.AntragM
*/
// onExit: function() {
//
// }
  handleAbschliessenPress: function() {
  var outputData = {};
  var antrag = this.getView().getModel().getProperty("/InputData('" + this.taskId + "')/Antrag");
  outputData.Antrag = antrag;
  sap.ui.getCore().getModel().create("/OutputData", outputData, null, function(oEvent) {
  //Aufgabenfenster schliessen
  sap.m.MessageBox.show("Die Aufgabe wurde erfolgreich abgeschlossen. Sie können das Fenster schliessen.",
  sap.m.MessageBox.Icon.SUCCESS,
  "Aufgabe erfolgreich abgeschlossen");
  });
  }
});




 

Wish List

SAPUI5 is a great UI technology and (in my opinion) future-proof as it is based on modern and common web technologies. However, defining and layouting views is not comfortable, error-prone and no fun. A WYSIWYG-Editor for views similar to the web dynpro concept would be a huge additional value - I'm aware about the AppBuilder, but it is - in my opinion - only for rapid prototyping and is limited in functionallity and (as far as I know) it won't be developed further as well.

 

A disadvantage of developing client side javascript code is that there are no build-errors. It is very likely that you'll deploy non-valid code to the server. As App-Builder and River-RDE provide acceptable javascript code validation something in this quality would be desirable within NWDS as well.

 

There is already a plurality of non-consolidated development tools available for working with SAPUI5 (App Builder, NWDS, River RDE, some HANA-related Cloud tools). This is confusing. As SAP provides an eclipse-based IDE (NWDS) an consolidated IDE would be consequent - I'd like to develop processes and User Interfaces within the same tool.

 

Also, I noticed that the well known task header from web dynpro / VC tasks where you have some metadata-information as well as the process chart link is missing when using custom technologies as task uis.

 

I'd like a SAP provided SAPUI5 replacement for this

 

Other

I'd like to thank Andre Backofen (Andre Backofen) for his uncomplicated support. Also, check out my collegue (Patrick Wenger)'s Blog Posts about this issue and other SAPUI5 related stuff:

 

 

I hope you enjoyed my first Blog Post. Comment if you have any questions or remarks

 

Jan

Those of you who read the excellent Blog series of Andre Backofen (Custom UIs with the BPM OData Service) but were wondering how to start a new process instance with the BPM OData API, will hopefully find here at least a momentary solution:

 

The API documentation "BPM OData Service for Starting BPM Processes" (BPM OData Service for Starting BPM Processes - Modeling Processes with Process Composer - SAP Library) just mentions, which URL is to use for this purpose. Unfortunately it lacks an example of the payload for the http post command. With the help of Andre Backofen and a lot of try and error we found the following payload to be working:

 

{

       "vendor": "novobc.ch",

       "dcName": "pr~pm~demo",

       "processTechnicalName": "Bewilligung",

       "ProcessStartEvent": {

                 "::StartBewilligung": {

                           "Antrag": {

                           "Mitarbeiter": "MA",

                           "Vorgesetzter": "VG"

                 }

            }

       }

}

 

Please note the double colon in front of the Process StartEvent name ("::StartBewilligung"). Make also sure that your object hierarchy is correct. You can find all the necessary data with the help of the OData Service calls that are mentioned in the API docs.

 

To actually start a new process instance you must send this data to the BPM system. For the time being we are not aware of any other method than using a direct jQuery ajax call. There will most probably be some better support of the UI5 Library, but for now we did the following:

 

var startData = '{"vendor":"novobc.ch","dcName":"pr~pm~demo","processTechnicalName":"Bewilligung","ProcessStartEvent":{"::StartBewilligung":{"Antrag":{"Mitarbeiter":"MA","Vorgesetzter":"VG"}}}}';
$.ajax({
  type: 'GET',
  url: 'http://yourhost:yourport/bpmodata/startprocess.svc/novobc.ch/pr~pm~demo/Bewilligung/StartData',
  beforeSend: function(requestGET){requestGET.setRequestHeader('X-CSRF-Token', 'Fetch');},
  success: function(data, textStatus, requestGET){
   $.ajax({
  type: "POST",
  url: "http://yourhost:yourport/bpmodata/startprocess.svc/novobc.ch/pr~pm~demo/Bewilligung/StartData",
  beforeSend: function(requestPOST){
  requestPOST.setRequestHeader('X-CSRF-Token', requestGET.getResponseHeader('X-CSRF-Token'));
  requestPOST.setRequestHeader('Content-Type', 'application/json');
  },
  data: startData,
  success: function () {sap.m.MessageBox.show("Prozess erfolgreich gestartet",
  sap.m.MessageBox.Icon.SUCCESS,
  "Der Prozess wurde erfolgreich gestartet!");}
    });
  },
  error: function (requestGET, textStatus, errorThrown) {
  alert("Fehler: " + requestGET.getResponseHeader('X-CSRF-Token'));
  }
   });


This code will not win any beauty contest, that's for sure. However, maybe it helps someone to get this thing running. I certainly hope so. For a much more elaborate discussion of this topic see also the blog of my colleague at Working with SAP NW BPM and SAPUI5: Using SAP NW BPMs OData-Services

 

Patrick

I work as SAP BW consultant and have not really much experience in business process modelling. But with my clients I often have the discussion, the BW system is not so important, It's an reporting system only. The real important system is ERP, because there are the processes. If the processes don't work properly or return the wrong results, it's the bigger error.

 

I then argue, that a report is the outcome of many processes. Take month close for example. You put all the financial data of your different companies together, consolidate it. You define a business process how the consolidation of your companies should be done and which business rules have to be taken into account. And at the end you get your formatted financial statement in the colours and look and feel of your company. Every one is happy.

 

The second fact, if the report returns the wrong figures because of a wrong business process implemenation no one is happy. Sometimes the report at the end reveals that are some open issues in the business process, which have not been foreseen.

 

I think most of the business processes create documents in the normal process flow. Some of the created documents are used for a corporate reporting.

From my point of view there is a strong dependency between ERP and BW system even from process modelling view and that you should think of integrating reporting in business process modelling.

 

My questions are:

 

What are your experiences with integration of reporting into bussiness process modelling?

How is your argumentation pro or con to integrate reporting in business processes modelling?

 

I'm tensed to read your comments and arguments.

The Merck Group uses Process Observer in the context of Master Data Harmonization. While the core process of creating and changing master data is implemented using SAP Master Data Governance (SAP MDG-M, find the Success Story here), Process Observer is used for reporting and to make the process visible. A story about this was released at the SAP Forum in Austria 2013, DSAG Technologietage 2013 and at SAP TechEd in 2012. The presentation from the SAP Forum is online and can be reviewed here (the document is available in German only).

 

The basis for the integration of Process Observer into SAP MDG is the SAP Master Data Governance rapid-deployment solution. In the SAP Demo Store, a demo is available showcasing this integration: EIM MDG-M Create Material with Process Observer (Logon to the SAP Demo Store required).

Hi community,

 

In this new blog, I want to focus on the definition and the use of tasks in Process Observer and on how specific tools can make your life easier.

 

Task Definition


Let me start with the meta-model:

metamodel2.png

Tasks are representatives of activities performed by users on business objects in the back-end application. The information about the execution of BO activities is published via events by the back-end application. In the process definition, tasks are assigned to process activities (= Activity Binding). While process activities are defined only in the context of a process definition, tasks are independent, reusable entities.

 

Before tasks can be used they are defined as a combination of a Business Object Type and a Task Type in the process façade (transaction POC_FACADE ‘Maintain Objects in Façade Layer’).

task definition.png

You can define header level tasks and item level tasks. Please select the checkbox accordingly. By adding customer-defined Business Object Types and Task Types (with key Z…) you can also create new custom tasks.

 

In the case of direct [non-BOR] events being raised by the back-end application (see blog Process Observer (POB) Direct Event API for Logging Processes from SAP and Non-SAP Systems ) no further mapping is required between a direct event and a task. It is assumed that the direct event contains information about the predecessor BO that is then used for the binding of the process instance.

 

If you are using BOR events in your application, you need to provide additional mapping between the BOR event and a task defined in the process façade as defined above. In order to do this, you can :

 

1) Maintain the mapping in the Customizing transaction ‘Maintain BOR Instrumentation’

bor_task_mapping.png

or 2) Implement the BAdI ‘Mapping of BOR Events to Tasks’.

img_bor_task_mapping.png

For BOR events you may also need to consider adding information about the predecessor BO to the event (only the object itself is considered a predecessor and does not need to be added). You have the following options for defining the predecessor. The options are executed in the given order.


1) Implement BAdI ‘Previous BO Determination’

pre_bo_determination.png

2) Customizing: Map Previous Objects from Business Object Repository Payload

map_from_payload.png

3) (Do nothing but) use the built-in functionality of the Document Relationship Browser (DRB) function module (find additional information about the DRB  here )

 

While options 1) and 2) are recommended for productive environments, you may use option 3) for rapid prototyping, but you must be aware of potential performance issues that using the DRB module during runtime can cause.

After the tasks are received by Process Observer, you can further manipulate them before process definition mapping is performed. The following BAdIs are available:

  • Enrichment of Task Event Data (only for BOR events)
  • Enhance/Split Tasks (all events)

enrich task.png

Note: Up to now BOR Events and direct Events have been processed in separate jobs, one after the other, which may have some side-effects (see blog article Process Observer (POB) - working with BOR events made easy). When working with direct events for Process Observer and finding duplicate events in the log, please check that the same event is not also provided as a BOR event by the system as the default. If necessary, deactivate the BOR event by removing the mapping from BOR to task in transaction POC_BOR. You may also check the transaction_ID linked to the events (see blog article … direct event…), as the system normally filters out the duplicate events by comparing the transaction_IDs.

Now, with note 2030279, we have a report for unified processing of BOR events and direct events available. Events of all types are now processed together, and in the order in which the events  occur. In order to use unified event processing, you need so top the currently scheduled event processing report with SM37, the reschedule the event processing (transaction POC_JOB_SCHEDULER), and select the ‘Unified BOR-/non_BOR Event Processing’ checkbox.

scheduler.png

If you want to execute the new report manually, execute report POCR_PROCESS_EVENTQUEUE_UNI in transaction SE38.

 

Task Binding


In order to enable Process Observer to create process logs, tasks are assigned to process activities in Customizing transaction POC_MODEL (‘Create and Maintain Process Definition’). You may assign multiple tasks to the same process activity. The activity is logged when one of the assigned tasks is observed by POB.

You can modify the way tasks are assigned to a process activity:

1) In a BAdI or a BRFplus rule, you can further evaluate a detected task-activity assignment at runtime and discard the assignment (compare with the meta-model given above).

binding_rule.png


Using this concept, you may use the same task (for example ‘Create Object’) to bind the BO activity to different process definitions (variants of a process). Depending on an attribute, such as the object type, you may bind it to the one or the other process definitions when you check this in the relevant starting steps of the processes.


Use BAdI ‘Rule-Based Binding of Task to a Process Activity’ as an alternative to creating a BRFplus rule.

binding_badi.png

Note: Another approach to solve this use case is to use different tasks in the instrumentation of the application. In some cases this may be more efficient as it may avoid overhead processing, or the generation of orphaned tasks (see below).

 

2) You may also flag tasks assigned to activities as additional tasks. This means that the tasks are only considered as additional information. Logging of the activity only takes place if at least one non-additional (or main) task occurs. Additional tasks are logged and assigned in this context, but if only the additional task occurs, no activity is logged.


Also in finding the predecessor instance, additional tasks behave differently: they are not included in finding predecessors. (Note: If you really rely on this behavior, please apply note 1994183).
additional_task.png
You may use this feature in order to store additional information in the context of the activity, where the BO-ID in the additional task does not need to be specific for the process, but you can still use it in the extended search of the process monitor.


As an example you may have a change ID that represents the change of a material. You use the change object and ID in the main task. In an additional task, you could add the task executed with the material ID (not specific to the tracked process). In the monitor search you can find all change processes for a
given material ID.

 

Orphaned Tasks

 

Tasks not bound to logged process instances at runtime are called orphaned tasks.Together with bound tasks they are stored in table POC_D_BA_LOG. Orphaned tasks may occur due to:

  • Activation of logging on BO type level (all tasks in the context of a certain BO type are logged)
  • Extended logging of a process (not only tasks assigned to the active process definition are logged, but also all other tasks related to BO types referenced in the process definition. You normally use this setting only in testing environments.)
  • Discarding of process binding in the binding BAdI or BRFplus rule (see above)
  • Errors in the process definition or application instrumentation (for example, the predecessor BO is missing and so the binding of the task to a process instance does not take place.

 

So orphaned tasks may be of interest to you for detecting errors of process definition and instrumentation, especially at design time.

 

Task Monitor and Additional Tools


There are different transactions that you can use to review the logged tasks without entering via the process monitor. This is especially helpful in the implementation and testing time of your process definition and instrumentation to check whether events or tasks have successfully reached Process Observer, and whether they are bound to a process.

  • POC_TASK_ORPHAN: Lists orphaned task
  • POC_TASK: Lists all tasks with their assignments to processes and activities

task_monitor.png

While there is no general Process Observer setting to prevent the logging of orphaned tasks, we have provided a sample BAdI implementation that filters out orphaned tasks before writing the process logs to the DBs. To use this feature, please implement note 2018078.


The corrections from the notes mentioned in this document are also available with these SPs:

  • SP 13 for SAP Business Suite Foundation 7.31
  • SP 08 for SAP Business Suite Foundation 7.46


This blog explains the various NWBPM patterns that can be used for business solutions.

 

In next blog I will explain how to configure each steps clearly.

 

Simple NWBPM with Operation mapping:

This pattern is to understand the basics of mapping and also how to import and use operation mapping developed in ESR in NWBPM.

 

SimpleBPM.jpg

 

Collect pattern based on time:

 

This pattern is used to collect messages for a particular period of time(say 60 seconds).And send the collected message to 2 different system using message split.

 

SimpleBPM.jpg

 

Collect based on count:

 

This pattern is used to collect the messages based on count. The same pattern can be extended to collect messages based on correlation and strict condition by giving condition at the start and intermediate message events respectively. These patterns are called as aggregator and strict conditional start patterns

 

SimpleBPM.jpg

 

 

SAP PI with NWBPM and BRM:

This pattern integrates PI with NWBPM and BRM.The complete PO package.And also collects the messages for a particualr period of time and sends it to a target.

 

SimpleBPM.jpg

NWBPM pattern to merge 2 system:

This pattern merges messages coming from 2 system based on a correlation condition(n:1).And sends the message to a single target system.

SimpleBPM.jpg

Split pattern based on Indexing:

This pattern splits the incoming message with multiple records to individual ones using indexing and count.And also each message is processed with a time delay of 5 seconds.

SimpleBPM.jpg

 

References:

 

http://scn.sap.com/community/bpm/blog/2013/09/27/sequential-split-of-messages-and-looping-in-nwbpm-process-using-indexing-of-record

 

http://scn.sap.com/community/bpm/blog/2013/03/27/conditional-start-typical-examples-27

http://scn.sap.com/community/process-orchestration/blog/2012/10/11/enterprise-patterns-in-process-orchestration-aggregator

Business Process Management projects can easily become entangled in complexity, scope creep and lack of corporate buy in. Those are just a few of the many challenges BPM projects see. Technical tips can always be useful (like this one), but here are some higher level business management tips aggregated from BPM implementation professionals, which can make the difference between successful projects, and those that never get off the ground.

Paying Attentinion to the User

One of the key mistakes in a BPM project is to ignore the users of the system until the solution is at an advanced stage. Interviewing users early on in a project about how they currently perform a process helps you discover redundancies, difficulties, and time wasters. If your BPM solution can address these issues, it will be a stronger, more useful solution. Also, the more users are involved in the design of the solution, the more they will feel part of the solution and be motivated to accept it. Finally, test a prototype of the process (or part of it) with users before the project is complete. This will save you time later on when the project is in the testing stage. In short, strive to design your BPM solution with the help of those who will be using it. Some BPM providers, such as SAP, have placed a user focus on their BPM products with this tip in mind.

Reporting and ROI

In designing a BPM solution, it’s important to plan for and implement reports. It’s fine to automate a process, but if you can’t prove ROI with hard data, then the solution may not receive the recognition or usage it deserves. Reports give clear proof of results. They also enable you to isolate process bottlenecks. A report on the average time it takes to complete each task, or on the number of processes that are waiting for completion by each participant, can expose such bottlenecks and help minimise them. In this way, reports help you prove solution success and improve on it. Some BPM solutions include powerful reporting capabilities on process performance. An example would be BPM Software by PNMsoft (see some examples here).

Living in a Process Bubble

Bubbles.jpg

Can processes live in a bubble? Can they function well without information from the outside world? The answer in most cases is no. In order to build a solution which improves your business, provides better service and speeds up problem solving, processes must be in tune with the environment in which they live. You can achieve this in several ways:

  • Provide processes with information from external systems.
  • Ensure that processes listen for and react to external events such as request overflow, passed deadlines, or out-of-bound statistics.
  • Define decision points with business rules, where processes evaluate external data before selecting the next step.
  • Enable increased human interaction with processes, and joint human/process decision making.
  • Give end-users and developers the opportunity to provide feedback and suggest process improvements.

To sum up, a process that lives in a bubble will stay in the bubble. Burst that bubble and a whole new world awaits.

Continuous Improvement

BPM projects are not ‘one offs’, rather, they are opportunities for continual improvement and optimisation. In part, this is thanks to the cyclical BPM model which includes five iterative stages:  Model, Implement, Execute, Monitor, Optimize.

This means that once the current cycle of a project is complete, a new cycle begins, where you use the knowledge and data gathered from the first cycle to create a better solution the second time around.  In particular, the Monitoring stage is an opportunity to gather KPI and performance data which lead the way towards Optimization. Also, it’s important to be attuned to factors such as new requirements, updated technology and end-user feedback. Thus, through awareness of process performance and its surroundings, you will achieve better results during each iteration of the BPM cycle.

Gartner has some excellent additional BPM tips and advice.

BPM OData: Implementing an advanced custom task execution UI

This blog post, as part 3 of BPM OData blog series, refers to the recently introduced OData Service in SAP NetWeaver BPM available with SAP NetWeaver 7.3 EHP 1 SP 09 and higher. The features described in this blog post are available with SAP NetWeaver 7.3 EHP 1 SP 10 and higher.

 

Advanced UIs for the Customer Creation Process

After implementing a basic UI in the previous blog post, this blog post shows how to implement a more powerful UI using complex data types, collections and faults.

 

In this blog post, we use again the running example implementing the creation of a customer record in a credit institution. The data used in this example is up to now organized in a flat structure containing only primitive data types such as String or int. In more realistic scenarios you will most likely have a complex data structure containing custom data types and collections of entities. If we take a look at the example, the customer data would probably have an own complex type for the customer’s address. Moreover, a customer can have multiple phone numbers and electronic business cards (vCard), which should also be covered by the customer data. To display and edit this data in a suitable way, we will enhance the sample application accordingly as shown in Figure 1 (Tab 1).

 

Making the running example more realistic also includes scenarios, where you not only want to confirm a customer record, but where you might also want to reject a customer record. This could be the case, for example, if the customer record already exists in the backend. Rejecting a customer record requires the possibility to complete a task with a fault. This is supported in the newest version of the BPM OData Service and thus allows us to enhance the example accordingly as shown in Figure 1 (Tab 2).

ProcessWithUIs.png

Figure 1: Enhanced task execution UI of the task Verify Customer Data

 

The enhancements are divided into two steps. At first we will introduce the complex data structure and afterwards enhance the example with a fault. For both steps we will incrementally enhance the underlying scenario by adjusting the BPM Task and the used data types. With these enhancements we will have a deeper look at the technical basics when using the new features of the BPM OData Service. This helps you to better understand what’s happening behind the scenes when developing your SAPUI5 application. Finally we will enhance the existing SAPUI5 application to also make use of the new enhancements. Parts of the source code of the sample SAPUI5 application are attached to this blog post. Here is an overview about the mentioned steps covered by the following sections:

 

Complex data types and collections / Faults

  • Enhancing the running example
  • Technical Basics
  • Enhancing the SAPUI5 User Interface

 

Complex data types and collections

This section describes how to use complex data types and collections utilizing the BPM OData Service. Therefore we will enhance the underlying scenario, have a look at the technical basics and afterwards enhance the SAPUI5 application accordingly.

 

Enhancing the running example

The data structure previously used in the running example represented a customer record in a flat manner by using only primitive data types. This makes totally sense for simple data structures but becomes unhandy when the data structure grows and becomes more complex. Taking a look at the customer’s address shows this. For now the customer has a number of properties related to the address and these properties are grouped by having a prefix such as address-street. Separating the address into an own custom data type not only increases the readability but also the reusability. The new data type contains all the properties related to the address such as street. Instead of having a property called address-street, the customer has now a property called address using the newly defined custom data type.

 

Having improved the existing data structure we can now add some further information to a customer record. A customer has typically a number of phone numbers and vCards. Both types are defined within the customer as an unbounded property using minOccurs=0 and maxOccurs=unbounded, which basically means that we define a collection. A phone-number itself is a simple String while a vCard is defined using a new complex type.

 

Below is the enhanced XSD that is used to define the data structure:

<complexType name="Customer">
  <sequence>
    <element name="firstName" type="string"></element>
    <element name="lastName" type="string"></element>
    <element name="address" type="tns:Address"></element>
    <element name="currency" type="string" default="EUR"></element>
    <element name="phone-numbers" type="string" minOccurs="0" maxOccurs="unbounded"></element>
    <element name="vcards" type="tns:Vcard" minOccurs="0" maxOccurs="unbounded"></element>
  </sequence>
</complexType>
<complexType name="Address">
  <sequence>
    <element name="street" type="string"></element>
    <element name="city" type="string"></element>
    <element name="zip" type="integer"></element>
    <element name="country" type="string"></element>
  </sequence>
</complexType>
<complexType name="Vcard">
  <sequence>
    <element name="attr1" type="string"></element>
    <element name="attr2" type="string"></element>
    <element name="attr3" type="string"></element>
  </sequence>
</complexType>





 

Technical Basics

Using the enhanced data structure with the BPM OData Service works more or less the same as already described in the first blog post. The OData Service provides functionalities to access the input and output data of a task instance. Accessing for example the input data returns an entity called InputData which contains the data as specified in the BPM Process. In case of the running example we get an entity called Customer containing the data set of a customer with the first name John and the last name Doe. With the newest enhancements the entity contains also three referenced entities namely address, phone-numbers and vcards. In order to see more details of these entities, you need to expand them using the $expand operation as shown in the table below.

 

Expanding the entities shows that the entity address matches to the newly defined complex XSD type Address. The entity contains the defined properties with some sample data, e.g. street is set to Main St. Same is true for the entities phone-numbers and vcards. This is true for the entities phone-numbers and vcards as well, but in this case a collection is returned as defined in the XSD. For example, phone-numbers is a collection of three entities each containing a single phone number represented as a String.

 

The table below shows the URL used to access the input data of a BPM task along with the service response:

HTTP Method

GET

URL

… /bpmodata/taskdata.svc/e898ab9c36f611e3a6bf0000006379d2/InputData('e898ab9c36f611e3a6bf0000006379d2')?$format=json&$expand=Customer/address, Customer/phone-numbers, Customer/vcards

Response Body

(simplified)

{
  "d": {
    "Customer": {
      "firstName": "John",
      "lastName": "Doe",
      "currency": "EUR",
      "address": {
        "street": "Main str.",
        "city": "Walldorf",
        "zip": "69190",
        "country": "Germany"
      },
      "phone-numbers": {
        "results": [
          {"phone-numbers": "05567 39461"},
          {"phone-numbers": "05567 88753"},
          {"phone-numbers": "0155 1197510"}
        ]
      },
      "vcards": {
        "results": [
          {
            "attr1": "John Doe",
            "attr2": "john.doe(at)provider.com",
            "attr3": "john.doe"
          },
          {
            "attr1": "J. D.",
            "attr2": "jd(at)provider.com",
            "attr3": "jd"
          }
        ]
      }
    }
  }
}





 

Having a look at the Metadata Document for this task instance shows the structure of the input data including the referenced entities address, phone-numbers and vcards. As shown by the returned EDM, a complex type will be translated into an own entity type. The XSD element using such a complex type will be translated to a so-called Navigation Property which refers to the according instance of the EDM entity type. The navigation property address for example refers to the entity representing the customer's address whose entity type is Address. Navigation properties are expandable, thus you need to expand them using the $expand operation in order to access the according data.

 

Similar to complex types, a collection will be translated into an own entity type and a navigation property. Each navigation property is bound to a so-called Association defining the relationship between the entity types, e.g. Customer to Address. Moreover, this association defines a multiplicity for each referenced entity type. In case of a collection, this multiplicity is set to '*', which represents a one-to-many association and thus corresponds to a collection.

 

The table below shows the URL used to get the metadata and the corresponding response:

HTTP Method

GET

URL

…/bpmodata/taskdata.svc/e898ab9c36f611e3a6bf0000006379d2/$metadata

Response Body

(simplified)

<EntityType Name="Customer">
  <Property Name="firstName" Type="Edm.String" Nullable="true" />
  <Property Name="lastName" Type="Edm.String" Nullable="true" />
  <Property Name="currency" Type="Edm.String" Nullable="true" DefaultValue="EUR" />
  <NavigationProperty Name="address"
      Relationship="BPMTaskData.Customer_Address"
      FromRole="Customer" ToRole="Address" />
  <NavigationProperty Name="phone-numbers"
      Relationship="BPMTaskData.Customer_phone-numbers"
      FromRole="Customer" ToRole="phone-numbers" />
  <NavigationProperty Name="vcards" Relationship="BPMTaskData.Customer_Vcard"
      FromRole="Customer" ToRole="Vcard" />
</EntityType>
<EntityType Name="Address">
  <Property Name="street" Type="Edm.String" Nullable="true" />
  <Property Name="city" Type="Edm.String" Nullable="true" />
  <Property Name="zip" Type="Edm.Decimal" Nullable="true" />
  <Property Name="country" Type="Edm.String" Nullable="true" />
</EntityType>
<EntityType Name="phone-numbers">
  <Property Name="phone-numbers" Type="Edm.String" Nullable="true" />
</EntityType>
<EntityType Name="Vcard">
  <Property Name="attr1" Type="Edm.String" Nullable="true" />
  <Property Name="attr2" Type="Edm.String" Nullable="true" />
  <Property Name="attr3" Type="Edm.String" Nullable="true" />
</EntityType>
<Association Name="Customer_Address">
  <End Type="BPMTaskData.Customer" Multiplicity="1" Role="Customer" />
  <End Type="BPMTaskData.Address" Multiplicity="1" Role="Address" />
</Association>
<Association Name="Customer_phone-numbers">
  <End Type="BPMTaskData.Customer" Multiplicity="1" Role="Customer" />
  <End Type="BPMTaskData.phone-numbers" Multiplicity="*" Role="phone-numbers" />
</Association>
<Association Name="Customer_Vcard">
  <End Type="BPMTaskData.Customer" Multiplicity="1" Role="Customer" />
  <End Type="BPMTaskData.Vcard" Multiplicity="*" Role="Vcard" />
</Association>





 

Completing a task that contains complex properties and collections works basically the same as already described in the first blog post. You simply send an HTTP POST request to the URL which is also used to retrieve the output data. Only the data, which is sent to the service using the request body, differs slightly. The data needs to reflect the structure as defined in the metadata of the OData Service, i.e. as defined in the XSD. Therefore it also needs to contain the new entities representing the address, phone-numbers and vcards. The referenced entities are simply represented as a new JSON object, e.g. an address is a new JSON object embedded in the customer object as shown in the table below.

 

How does this look like in the example? Let’s imagine the used zip code is incorrect and we would like to correct it. With some experience we could write down the required data structure on our own, but in our case there is even an easier way. Since the input and output data of this task has the same structure, we can simply fetch the input data, modify it and sent it back as output data. Doing this, we can simply correct the given zip code. But be aware, that the input data entity is wrapped into a container required by OData while the output data entity is directly used without requiring this container. This means we need to remove this container when using the input data as basis for the output data.

 

The table below shows the URL used to complete a BPM task along with the service response:

HTTP Method

POST

URL

… /bpmodata/taskdata.svc/e898ab9c36f611e3a6bf0000006379d2/OutputData

Request Headers

Authorization

Basic dXNlcm5hbWU6cGFzc3dvcmQ=

X-CSRF-Token

781057a9-b96a-468c-b393-981f98292335

Accept

application/json

Content-Type

application/json

Request Body

{
  "Customer": {
    "firstName": "John",
    "lastName": "Doe",
    "currency": "EUR",
    "address": {
      "street": "Main str.",
      "city": "Walldorf",
      "zip": "12345",
      "country": "Germany"
    },
    "phone-numbers": {
      "results": [
        {"phone-numbers": "05567 39461"},
        {"phone-numbers": "05567 88753"},
        {"phone-numbers": "0155 1197510"}
      ]
    },
    "vcards": {
      "results": [
        {
          "attr1": "John Doe",
          "attr2": "john.doe(at)provider.com",
          "attr3": "john.doe"
        },
        {
          "attr1": "J. D.",
          "attr2": "jd(at)provider.com",
          "attr3": "jd"
        }
      ]
    }
  }
}





Response Body

(simplified)

{
  "d": {
    "Customer": {
      "firstName": "John",
      "lastName": "Doe",
      "currency": "EUR",
      "address": {
        "street": "Main str.",
        "city": "Walldorf",
        "zip": "12345",
        "country": "Germany"
      },
      "phone-numbers": {
        "results": [
          {"phone-numbers": "05567 39461"},
          {"phone-numbers": "05567 88753"},
          {"phone-numbers": "0155 1197510"}
        ]
      },
      "vcards": {
        "results": [
          {
            "attr1": "John Doe",
            "attr2": "john.doe(at)provider.com",
            "attr3": "john.doe"
          },
          {
            "attr1": "J. D.",
            "attr2": "jd(at)provider.com",
            "attr3": "jd"
          }
        ]
      }
    }
  }
}





 

However you construct the entity required to complete the task, it is crucial to use the correct format for your data. The OData Standard and thus the BPM OData Service is very strict when it comes to the format of the data. Frequently issues are missing brackets, too many brackets, wrong property names, etc. For example, a collection is always assigned to a property called results. Using some other name such as result (without the ending s) would lead to a failing HTTP POST request when sending this data.

 

Enhancing the SAPUI5 User Interface

Having the technical details in mind, we can now start to enhance the UI. The sample application was already able to display the address of a customer, but we need to adjust it with regard to our latest changes. Furthermore, it needs to be enhanced in order to show the newly introduced phone numbers and vCards.

 

Adjust Element Binding

The sample application is built of Panels containing TextFields. The TextFields are bound to specific properties of the OData Model. With help of an element binding, we set the binding context of the root panel. As a result, the binding of all contained TextFields can be defined relatively to the binding context, in our case the InputData.

 

While defining the element binding, we also specify which referenced entities should be expanded. This included so far only the referenced entity Customer. This needs to be enhanced to also include the newly introduced referenced entities address, phone-numbers and vcards.

 

The snippet below shows the element binding of the Panel in verifyCustomerData.controller.js:


panel.bindElement("/InputData('"+taskId+"')", {expand:"Customer/address, Customer/phone-numbers,
  Customer/vcards"});

 

Adjust Property Binding for Address

Expanding the referenced entities makes the according data available on the client-side so that the UI controls can access it. The property bindings of the existing UI controls in the sample application are using the shortened notation, where the binding path is specified within curly brackets as value for the field value. The path of the properties related to the customer's address changed slightly. Using the newly introduced hierarchy we have an additional path segment while the property names changed.

 

The snippet below shows the adjusted property binding of a TextField in verifyCustomerData.view.js:

oMatrix.createRow(
  new sap.ui.commons.Label({text : "Street", design : sap.ui.commons.LabelDesign.Bold }),
  new sap.ui.commons.TextField({value : "{Customer/address/street}"}) // property binding
);





 

Enhance the SAPUI5 User Interface to display phone-numbers and vcards

With these small adjustments the customer’s address is displayed correctly again. In order to display the phone numbers and vCards as well, we need to implement some new UI controls. Displaying a collection works nice using a table or a row repeater. In the example we are using a table to visualize the vcards collection. Each row of the table contains a number of TextFields to display the attributes of a specific vcard as shown in figure 2.

UI_vcards.png

Figure 2: UI Control to display the collection vcards

 

The property binding of the TextFields is again defined using the shortened notation in curly brackets. Each row of a table is bound to a particular item of the underlying collection. This means the binding path is relative to a collection item, e.g. a vcard of the vcards collection. Therefore we can directly access the attributes of a vcard.

 

The snippet below shows how the table is created in verifyCustomerData.view.js:

var vcardsTable = new sap.ui.table.Table({
  visibleRowCount : 3,
  width : "35%",
  design : sap.ui.commons.LabelDesign.Bold,
  selectionMode : sap.ui.table.SelectionMode.None
});
var attr1Column = new sap.ui.table.Column({
  label : new sap.ui.commons.Label({text : "attr1"}),
  template : new sap.ui.commons.TextField({value : "{attr1}"}) // property binding
});





 

 

After creating the table it needs to be bound to the desired collection. This is done using the method bindRows. With the given parameter we define the binding path to the collection. This is again relative to the binding context of the table’s parent. Since the table is embedded within the root panel, the binding path is defined relative to the input data, e.g. Customer/vcards.

 

The snippet below shows how the collection is bound to the table in verifyCustomerData.view.js:

vcardsTable.bindRows("Customer/vcards");

 

This concludes the adjustments needed on the UI side in order to make use of the enhancements done in the scenario. The UI is now able to display complex data structures as well. Attentive readers are probably concerned about the completion of a task in SAPUI5 using such a data structure. This works the same way as already described in the previous blog post. No need to adjust anything in the SAPUI5 application, it works already out of the box for complex structures.

 

Faults

This section describes how to use BPM Faults utilizing the BPM OData Service. Therefore we will enhance the underlying scenario, have a look at the technical basics and afterwards enhance the SAPUI5 application accordingly.

 

Enhancing the running example

With help of the Custom UI Details dialog (see figure 3) the input and output type of a task can be configured as well as possible faults (Error Type). A new fault is added to the task by clicking on the button Add, assigning a name and defining the data type of the fault. In case of the running example, we add a new Fault called RejectCustomer having the custom data type Fault.

DialogCustomUI.pngFigure 3: Dialog to enter the custom UI details

 

The data type of the fault is used to provide some data when completing a task with this fault (same as for output data). In case of our example, we would like to provide the possibility for the task owner to name the reason why he failed the task and thus rejected the customer record. In order to support this, we define a custom data type Fault in the XSD which contains a property called faultMessage of type String.

 

Below is the enhanced XSD that is used to define the data type of the fault RejectCustomer:

<complexType name="Fault">
  <sequence>
    <element name="faultMessage" type="string"></element>
  </sequence>
</complexType>





 

Technical Basics

The BPM OData Service supports two ways to access the faults of a BPM Task. If you do not know the available faults of a task, you can explore them using the the entity FaultData. If you already know what you are searching for, you can directly access the fault using the name of the fault.

 

Using the entity FaultData allows you to explore all the available faults of a specific task. The response will list the names of all assigned faults.A fault itself contains an empty data object, since this data is only set when completing the task with the fault. If you expand the fault RejectCustomer you can explore the according data object which corresponds to the previously defined Fault.

 

The table below shows the URL used to access the entity FaultData of a BPM task along with the service response:

HTTP Method

GET

URL

… /bpmodata/taskdata.svc/e898ab9c36f611e3a6bf0000006379d2/FaultData('e898ab9c36f611e3a6bf0000006379d2')?$format=json&$expand=RejectCustomer/Fault

Response Body

(simplified)

{
  "d": {
    "RejectCustomer": {
      "Fault": {
        "faultMessage": null
      }
    }
  }
}





 

Once you know the name of your desired fault, you can directly access it using this name. The response contains again the according data object. The table below shows the URL used to access a specific fault of a BPM task along with the service response:

HTTP Method

GET

URL

/bpmodata/taskdata.svc/e898ab9c36f611e3a6bf0000006379d2/RejectCustomer('e898ab9c36f611e3a6bf0000006379d2')?$format=json&$expand=Fault

Response Body

(simplified)

{
  "d": {
    "Fault": {
      "faultMessage": null
    }
  }
}





 

Completing a task with a fault works basically the same way as completing a task regularly. You just send an HTTP POST request to the URL that is used to directly access a fault by name. The request body contains the data as defined by the type of the fault, in our example a Fault object containing a faultMessage. The response body contains the actual BPM fault that was created on the server in order to fail the task.

 

The table below shows the URL used to complete a BPM task with a fault along with the service response:

HTTP Method

POST

URL

… /bpmodata/taskdata.svc/e898ab9c36f611e3a6bf0000006379d2/RejectCustomer

Request Headers

Authorization

Basic dXNlcm5hbWU6cGFzc3dvcmQ=

X-CSRF-Token

781057a9-b96a-468c-b393-981f98292335

Accept

application/json

Content-Type

application/json

Request Body

{
  "Fault": {
    "faultMessage": "Customer already exists."
  }
}





Response Body

(simplified)

{
  "d": {
    "Fault": {
      "faultMessage": "Customer already exists."
    }
  }
}





 

Enhancing the SAPUI5 User Interface

Based on the technical details learned in the previous section, we can now implement the UI accordingly. Rejecting a customer was not yet considered in the sample application. Therefore we need to add some UI controls including the according bindings. Furthermore, we need to implement the functionality to finally perform the HTTP POST request in order to fail the task.

 

On the UI side we introduce a new Tab containing a root panel as shown in figure 4. This panel contains a TextArea bound to the faultMessage and a Button which triggers the post request to fail the task.

UI_fault.pngFigure 4: UI Control to complete the task Verify Customer Data with the fault Reject Customer

 

The implementation of the UI works pretty much the same as already done for the input data. On the root panel we define again an element binding as you already know from the input data. But this time the panel is bound to a specific fault, in our case RejectCustomer.

 

The snippet below shows the element binding of the Panel in verifyCustomerData.controller.js:

faultPanel.bindElement("/RejectCustomer('" + taskId + "')", {expand : "Fault" });

 

Having done this, we can create the TextArea and bind it relatively to the fault. This means we can directly use the data type Fault as starting point for the binding path. In our case the TextArea is bound to the faultMessage.

 

The snippet below shows how the controls are created in verifyCustomerData.view.js:

oMatrixLayout.createRow(
  new sap.ui.commons.Label({text : "Reason", design : sap.ui.commons.LabelDesign.Bold }),
  new sap.ui.commons.TextArea({value : "{Fault/faultMessage}", rows : 2, cols : 60})
);





 

After implementing the UI and defining the bindings, the sample application is able to gather the needed fault data from the end user and, thanks to the experimental Two-Way Binding, pushes this data directly back to the ODataModel. In order to finally complete the task, we just fetch this data from the ODataModel, create the required fault data and send a post request based on the RejectCustomer fault. This works again basically the same as completing a task in a regular way.

 

The snippet below shows how to complete a task with a fault in verifyCustomerData.controller.js:

var faultData = {};
var fault = odataModel.getProperty("/RejectCustomer('" + taskId + "')/Fault");
faultData.Fault = fault;
odataModel.create("/RejectCustomer", faultData);





 

Conclusion

This part has shown the implementation of a more advanced custom task execution UI for a BPM task. This included the usage of complex data types and collections as well as completing a task with a fault. The technical details of these functionalities have been described and the sample SAPUI5 application has been enhanced accordingly.

We recently ran into this issue while doing process modelling with our NWDS version 7.3 SP07.

 

Error details:

 

We had developed few WD Java UI components with dependency to KM API's ( dependency with DC - tc/km/frwk). While assigning these UI's to our newly developed process, we were unable to do a search for UI components using the NWDS wizard.

 

Error.png

Error Log:

 

BC-BMT-BPM-CMP#Exception while searching components.

[EXCEPTION]

  1. com.sap.sdi.SearchDiscoveryException: SEARCH_BROWSE: While searching for WD Components : Error while finding WD component {SC=KMC-CM, DC=tc/kmc/kmc.people.shared/wd_picker, COMPONENT_PACKAGE=com/sap/netweaver/kmc/people/wdpicker, REPOS=LocalDevelopment^LocalDevelopment, COMPONENT=PeoplePicker, DC_VENDOR=sap.com, SC_VENDOR=sap.com}

at com.sap.sdi.wd.search.WDSearchProvider.search(WDSearchProvider.java:173)

at com.sap.sdi.services.SearchBrowseService.search(SearchBrowseService.java:127)

at com.sap.sdi.services.SearchBrowseService.search(SearchBrowseService.java:113)

at com.sap.glx.ide.task.util.SearchUtil.search(SearchUtil.java:194)

at com.sap.glx.ide.task.util.SearchUtil.searchComponents(SearchUtil.java:129)

at com.sap.glx.ide.uui.wizard.UuiWizardPage1$8$1SearchComponentsRunnable.run(UuiWizardPage1.java:410)

at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)

Caused by: com.sap.sdi.SearchDiscoveryException: Error while finding WD component {SC=KMC-CM, DC=tc/kmc/kmc.people.shared/wd_picker, COMPONENT_PACKAGE=com/sap/netweaver/kmc/people/wdpicker, REPOS=LocalDevelopment^LocalDevelopment, COMPONENT=PeoplePicker, DC_VENDOR=sap.com, SC_VENDOR=sap.com}

at com.sap.sdi.wd.search.WDSearchProvider.createComponentIVResultNodes(WDSearchProvider.java:371)

at com.sap.sdi.wd.search.WDSearchProvider.search(WDSearchProvider.java:171)

... 6 more

 

[Error: com.sap.glx.ide.flow.util.logger.IDEAbstractDynamicParticipant$TRACEENTRIES Thread[ModalContext,6,main]]



We reached out to SAP support team with this issue and found that the issue is related to 2 Jars files in DC's - tc/km/kmc/people.shared/wd_picker and tc/km/km/wdui/dispatcher. Both the Jar's have a path which is more thatn 255 character and hence it works only in Windows Server.

 

Now since our landscape doesn't have a NWDI to manage this requirement, we found a workaround.

 

Workaround:

 

Delete all DC's under KMC-CM SCA except for tc/km/frwk using remove client option in Development Infrastructure perspective. Shutdown the NWDS and the delete the DC's from your workspace.

 

This way the UI wizard in process composer will search without any issues

Ready to set your BPM process into production?

Based on experience from customer projects, here are some important things to consider for a "healthy" Go-Live:

 

272750_l_srgb_s_gl (2).jpg

1) Handle errors in the process model

A typical case for a process error is when an external web service is called via automated activity, and the external system is not available.

By default, the process will be suspended with an error. Starting with 7.31 SP10, you can define a boundary event to automatically handle such errors.

Other reasons for suspended processes could be mapping errors. Check your mappings and make sure that all fields which are marked as mandatory will actually be filled.

 

2) Set all log levels to "Error"

Logging too much information can have a serious impact on performance. In production, the global log level should be "Error". In case a specific issue needs to be investigated, only the log levels of the relevant locations should be increased. After the investigation is finished, set the log level back to "Error".

For more information on how to change log levels, see Log Configuration with SAP NetWeaver Administrator - Monitoring - SAP Library

 

3) Define Administrator roles

SAP BPM has a fine-grained authorization concept: Authorizations and Roles - Business Process Management Security Guide - SAP Library

In general, there are two types of administrator users: technical and "business".

Technical administrators have full access to NWA, can modify system configuration and manage all processes/tasks. They would have the role "SAP_BPM_SuperAdmin" assigned.

Business administrators have access to NWA but can only manage processes and tasks for which they have been authorized. This happens by defining a respective role or group as "Process Administrator" and "Task Administrator" in the Process Composer.

 

4) Run performance tests

This becomes more important the more volume and users you expect. Use tools such as JMeter to simulate load on the system.

Identify bottlenecks and check the system configuration. Performance tests should be performed on a hardware similar to the production system.

Also see the official BPM sizing guide.

 

5) Set up archiving

Without archiving, the system database will continue to grow and queries will take longer over time.

The best option is to set up an archiving job to regularly clean out old processes.

For more on archiving, see Process Data Archiving - Monitoring and Managing BPM Systems, Processes, and Tasks - SAP Library

 

Obviously, the points I mentioned do not cover all pre-requisites for a successful go-live. There are many more aspects such as NWDI transport, optimal system configuration, user management etc.

For customers having a support contract with SAP, consider to schedule a full health check service for SAP BPM.
Please contact your support contract representative for more details.

Hello Everyone,

 

This blog, as the title suggests, sheds some light on integrating a UI developed in SAP UI5 as a BPM task. Not necessarily UI5, it can be a UI developed in any other technology which is not predefined in BPM at design-time like, WD Java, WD ABAP, Visual Composer or Adobe Offline Forms.

Other UI technologies like JSP, HTML etc. can also be integrated in this fashion.

 

Applies to:

 

NetWeaver 7.3 EHP1 (7.31) onwards.

 

How to:

 

1. Double-click on the Human Activity in your BPM Process to open its Properties :

 

     Task1.jpg

2. In the 'Task' property of the Human Activity, click on the 'Task' link as shown to open the Task Properties :

 

task2.jpg

 

3. In the User Interface Property of the Task, click on 'Choose':

 

task3.png

 

4. Now select on 'Custom Technologies' and clcik on 'OK':

 

task3.png

 

5. In the next dialog box that opens up, enter the relative URL* of the UI, define the input and output types (mandatory) and define the Fault Types for exception Handling (not mandatory) and click on 'Finish' :

 

task3.png

*Relative URL: If the UI Application is deployed on the same AS Server, eliminating the server details from the URL of the UI will give you the Relative URL.

                        For example: URL of UI : http://<hostname>:<port>/POC_SecondView/index.html, then Relative URL : /POC_SecondView/index.html

 

Now, the Relative URL of the UI should be seen in the UI property of the task now, which was blank earlier:

 

task3.png

 

The input and putput parameters we defined earlier should be available in the Input and Output mapping of the Human Activity:

 

Input Mapping:

 

task3.png

 

Output Mapping:

 

task3.png

 

That's it! You're Done!

 

Note:

 

As SAP UI5 and other custom technologies do not have a context of their own, we will have to use the BPM "oData Service" to bind the UI data to the BPM Process Context Data.

 

For more details on the BPM oData service, please refer this article by Vitaly Yarmolik.

 

For exclusive blog series  on  'Custom UIs with the BPM oData Service', please refer this excellent blog by Andre Backofen.

 

Hope this blog helps in some way.  Please let me know  in case I have mentioned anything wrong.

 

Regards,

Sid.

2014-New-SAP-BPM-Book.jpgCo-authored by Pia Klausnitzer

 

Back in the autumn of 2013, I was thrilled to hear that my dear colleagues Birgit Heilig and Martin Moeller were asked to write a book about SAP NetWeaver BPM and took the adventure without hesitation.

 

It sounded like a very tight deadline back then, but as you can imagine, they both dedicated to it long evenings and many weekends.

 

The result published in February 2014, is a new book called “Business Process Management mit SAP NetWeaver BPM” in German (for now). Approximately 500 pages of practical approach and examples of all features and benefits of SAP NetWeaver BPM. Truly impressive!

 

Strangely enough both authors say the biggest challenge was the request to write it in German...

 

Yes, we all hope for an English version sometime soon. But until then, here are some details about the topics it covers:

  • Introduction to the Business Process Model and Notation (BPMN)
  • Modeling BPMN-based processes with the Process Composer, the design time of SAP NetWeaver BPM
  • Generation of user interfaces
  • Modeling and integrating business rules with Business Rules Management
  • Analytics and reporting of business processes
  • Usage of the SAP BPM public API and the BPM OData service
  • Running and administering processes and tasks
  • Configuration of SAP NetWeaver BPM and performance optimization
  • Outlook on SAP NetWeaver Process Orchestration and SAP Operational Process Intelligence opint and the integration of SAP NetWeaver BPM in these two solutions.

 

More about the authors and their endeavors:

Birgit Heilig has been working in Application and technology development at SAP for more than 7 years. As Knowledge Architect, she is responsible for the documentation of SAP NetWeaver Business Process Management and Process Orchestration. She has been involved in the development of SAP NetWeaver BPM from the very beginning. Birgit is working as moderator and author in several SCN areas. Prior to SAP, she worked as a trainer, project manager and technical writer for a service company in Munich for more than 9 years. She has a degree in Computer Science at the Ludwig Maximilian University in Munich.

 

Martin Moeller has been working in SAP Software development for more than 10 years. Since 2005 he is focusing on the Business Process Management topic. One of his tasks is to connect the technical side (Java) with the business side (business processes). He has been involved in the development of SAP NetWeaver BPM right from the start and has comprehensive knowledge of the solution overall. During the introduction of SAP NetWeaver BPM, Martin was part of a team that supported customers and partners implementing the solution. Martin has built a strong customer focus and regularly participates and contributes to BPM conferences. Furthermore, he is very interested in Lean, Agile software development and design thinking and he uses them to develop added-value software faster and in high quality. Martin is also an SCN author and moderator.

 

The new book can be ordered online already on www.sap-press.de or amazon.de. I checked and it is indeed in German. Strange enough to invite both authors for a short interview (in English)

 

Q: The immediate question: why there is chocolate box on the cover?

A: SAP NetWeaver BPM is a solution to model, execute, monitor and optimize the business processes of your organization. In order to achieve that, the modelling part also requires picking the right services out of your heterogeneous system landscape and orchestrating them together with the right user interaction to get a real-life value. So it’s like choosing your beloved chocolates out of a chocolate box and the pleasure of melting chocolate in your mouth ;-)

 

Q: What was your experience when writing the book?

A: Firstly, the effort was more than we expected. However we also learned even more about business process management and orchestration and gained a better understanding of the big picture. On the other hand it was really exciting to have external reviewers asking good and absolutely valid questions in particular about SAP-specific terminology. This was the kind of immediate feedback an author loves to receive during the software development cycle as well. Last, but not least, writing in German was challenging as well since most of the common IT terms we are using in our daily work are of course English terms.

 

Q: And what is the key message of the book?

A: The short answer? It gives you all the necessary information on how to automate and optimize your business processes with SAP NetWeaver.

How do we do that? The book gives a short motivation for the discipline of Business Process Management (BPM). After that we introduce the established standard Business Process Model and Notation (BPMN) that is used with SAP NetWeaver BPM as well. Building on that foundation we use a practical example to address all SAP NetWeaver BPM features from A to Z. This enables the reader to model their (potentially first) business process step by step and run it without writing any code. So on top of modelling aspects as runtime user interfaces, administration and configuration are highlighted as well. But the book is not only for beginners: Readers with BPMN and SAP NetWeaver BPM background can use it as a reference and for techies we present the Public API of SAP NetWeaver BPM, which helps you to extend your solution whenever the standard functionality offered by SAP is not sufficient for your scenarios.

 

Q: Sounds like an IT answer. How would you explain it to someone outside SAP and IT like your grandma or grandpa?

A: Tricky as we might have to first explain why we put the television behind the typewriter. However let’s give it a try: in every organization there are a lot of repeating activities including manual processes such as filling and submitting forms, e.g. for purchasing goods or requesting approval for budgets or vacation to name just a few examples. Every organization must automate, organize and prioritize these processes to ensure high quality and make their execution easier and faster. Therefore, in today’s world, Business Process Management system such as SAP NetWeaver BPM to model, implement and execute business processes is a must. The book explains with examples how to achieve just that. And if grandma or grandpa did not get it they will definitely love having a book of their grandchildren with a chocolate cover they can show around to their friends.

 

Q: So once I finished the book and became a SAP NetWeaver BPM expert I would ask “What’s next? What comes after BPM with SAP?”

A: With SAP NetWeaver BPM you took the first step in making your business processes transparent and achieve faster and easier execution. Once this becomes the routine more and more processes will be executed and thereby a lot of data will be produced. While you only reacted on single process exceptions in SAP NetWeaver BPM it now becomes more and more necessary to see bottlenecks coming before they actually occur and proactively drive countermeasures to keep the business up and running. This is achieved with the bundling of SAP NetWeaver BPM into the Process Orchestration solution which is a powerful platform for all your integration needs and allows extending your SAP investment beyond your SAP domain.

 

In our book we give an outlook on a new solution called SAP Operational Process Intelligence powered by SAP HANA which addresses this space. It enables you to monitor business scenarios with a lot of data across various systems. Source could be SAP NetWeaver BPM or SAP NetWeaver PI, however the data could also be hidden in applications, transactions or on database level. With SAP Operational Process Intelligence you get real time information on that data and forecasts to immediately take actions when or - at best - before problems occur.

 

The new SAP Middleware offering in this space is called Intelligent Business Operations. We will be publishing more on this topic on SCN, however as a start you may want to review this comprehensive Introduction to Intelligent Business Operations with SAP HANA by SAP Middleware expert Silvio Arcangeli.


< If you are learning both German and SAP NetWeaver BPM this is a unique opportunity! >

Ok, so I've previously coached you on the importance of teamwork in hockey. Scrap everything I said. It's so much more important to have a hot goalie.

 

Oh wait. That was the little Canadian Hockey devil on my right shoulder out-shouting the Process Optimization Angel on my left.

 

Emotion is a powerful ally and has been on stunning display for the last couple of weeks. I am a steadfast college sports fan because, it could be argued, the student athletes have yet to be tainted by a monumental payday. That's what the Olympics used to be, according to my fading memory. But irrespective of whether you are an amateur or a professional, you are likely subject to the disruptive effect of emotions.

 

Take the goal tender for the Latvian Men’s ice hockey team, Kristers Gudlevskis.  Facing 57 shots in a recent game from some of the planet’s premier hockey stars, this young man had emotion on his side.  He could do very little wrong and carried the hopes of his country in what would have been a significant upset had they beaten the Canadians.  This athlete, whose name is not known to the NHL fan base – or wasn’t until these Games, turned aside wrist shots and slap shots with ease.  Yes there was teamwork, but there was a whole lot of heart from a single player.

 

As we reflect on our work-life experiences and seek ways to motivate our teams, it is perhaps worthwhile to consider how channeling positive energy and personal commitment can make a significant difference to our teams.  We can turn up the level of performance by setting examples of what is possible, even as individual contributors.   And delivering results in super-human fashion doesn’t hurt. Congratulations Kristers – you have taught us something important about facing challenges in an inspiring way.

Many of the astounding feats from the Winter Olympics are borne of intense personal drive, determination and fortitude. They are individual sports from a participant perspective, yet there is considerable teamwork that has gone into the preparation and training.

 

Ice hockey has superstars, yet it is undeniably a team sport.  It is fast paced, filled with athleticism, skill and coordination. When the puck moves quickly and accurately from stick to stick to back of net, well that elevates the teamwork to something more akin to poetry.

 

Teamwork is at the heart of our everyday existence, at home or work. Our efforts to continuously improve our business processes are not achieved by one person trying to move the mountain. Perhaps it is the right-winger who starts the play out of the defensive zone and coordinates an offensive rush.  Seldom does that individual successfully make a scoring play 200 feet down the ice without some assistance.  Likewise, the defensive play relies on communication and understanding each other’s role before it ultimately falls to the goalie to make a stunning save.  Our project and work teams are the same.

 

The project manager cannot be busy changing configuration or setting up new business scenarios without communicating to the rest of the team and allowing others to carry out their own unique roles on the line.  To study the game of hockey is really to study the characteristics of a well-tuned team activity.  Disciplined hard work gets results not dissimilar to what we must do on a weekly/daily/hourly basis to deliver successful results for our organizations.  Oh, and there is sometimes bloodshed.  Just saying.  Enjoy the games and watch out for flying pucks.

Actions

Filter Blog

By author:
By date:
By tag: