Blogs

The one with the generic Workflow UI
Dirk Lehmann SAP Employee 
Business Card
Company: SAP AG
Posted on Sep. 16, 2009 02:30 AM in Alloy, Emerging Technologies, Interoperability IBM, SAP xApps, Scripting Languages

URL: https://weblogs.sdn.sap.com/pub/wlg/15809

Subscribe.Subscribe
Print. Print
Permalink Permalink
Share

As described in Volker Drees' blog, sometimes it might be necessary to add a bit more generic to the delivered Alloy workflow forms, in order to save implementation efforts.
One way of adding more generic to the Alloy forms is described in Volker Drees' blog.

In a summary:

  • Use one or two predefined fields to add the relevant business object data in those fields (do this by using a custom Alloy Outbound Handler (see Volker Drees' blog for an example)).
  • The data inside these fields is separated by some agreed separators. (here: colon and semicolon)
  • Add a simple Lotus Script to the delivered (ERPApprovalWorkflow) form that parses the content (of the predefined fields) and extracts it in order to display the data in a HTML table

Let's see this in real life. After adding the custom Alloy Outbound Handler (here: Z_S_OSP_WF_PO1_CH_OB), the Alloy workflow note comes with two additional fields: WF_HEADER and WF_ITEMS.
Additional fields to Alloy workflow note


The content in these two fields is separated by colons and semicolons, as described by Volker Drees.
The below given Lotus Script code parses these fields, extracts the data and creates a HTML table with that data.

Place a call to the DisplayReport function in the QueryOpen part of your (ERPApprovalWorkflow) form (or better: make a copy of it and use the copy) to make sure the script is called, once the form is opened.


If the script is called the first time on a document, it reads out the WF_HEADER and WF_ITEMS data, and creates a HTML table out of it. The HTML data is stored in the Notes document, so that we don't need to parse the data a second time in case the form is opened again.
Additional fields created by Lotus Script


In order to display the header and item HTML data, two rich text fields are added to (ERPApprovalWorkflow) that have the same name as the stored HTML data fields in the Notes document.
Additional fields to notes form

For sure this example can be enhanced. E.g. it should be ensured that the separator characters colon and semicolon are escaped properly, the Lotus Script coding could be moved to the CustomAgent section of the Domino Workflow configuration and so on and so forth.

The result

 

Dirk Lehmann   is currently working as a Regional Group Specialist for Alloy (formerly known as project "Atlantic") in the Information Worker Division. He began his SAP career in 2001 as an SAP NetWeaver developer for Java. Prior to this career at SAP, Dirk worked for IBM Germany.


Comment on this article
Comment on this weblog
Showing messages 1 through 4 of 4.

Titles Only Main Topics Oldest First

  • Enhance this example even a bit more...
    2009-12-14 06:18:43 Dirk Lehmann SAP Employee Business Card [Reply]

    Hi all,


    as you might notice the above listed solution works on the client side. So the HTML rendering is done on every notes client.
    If you wanna run the solution server-side, create a new agent in NDERPws.nsf. Here's the agents listing:


    Declaration part:
    ---------------------------------------------
    Dim UpdateCheck As String


    Type t_headerRow
    name As String
    value As String
    End Type


    Dim header List As t_headerRow


    Dim items List As Variant
    Dim itemEntries() As String
    Dim columns As Integer


    Dim authorizedEntry As Integer
    ---------------------------------------------



    Initialize function:
    ---------------------------------------------
    Sub Initialize
    Dim tempdir$, h_filename$, i_filename$, h_fn%, i_fn%
    Dim preview As Integer
    Dim i As Integer

    Dim header List As t_headerRow
    Dim items List As Variant
    Dim itemEntries() As String
    Dim columns As Integer

    ' Create session
    Dim session As New NotesSession
    session.ConvertMime = False

    Dim agent As NotesAgent
    Set agent = session.CurrentAgent

    Dim db As NotesDatabase
    Set db = session.CurrentDatabase

    ' Get NotesDocument
    Dim doc As NotesDocument
    Set doc = db.GetDocumentByID(agent.ParameterDocID)

    doc.RemoveItem("body")


    ' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
    ' Load HeaderData

    Dim Token As String
    Dim s As String

    Dim TestHeaderString As String

    If( doc.HasItem("WF_HEADER") ) Then
    TestHeaderString = doc.GetItemValue("WF_HEADER")(0)
    Else
    TestHeaderString = doc.GetItemValue("WorkflowContainer00WF_HEADER")(0)
    End If


    Token = "bla"
    Dim headerI As Integer
    headerI = 1
    Do While Not Token = ""
    Token = Strtoken(TestHeaderString, ":", headerI)
    If Not (Token = "") Then
    s = Strtoken(Token, ";",1)
    header(headerI).name=s
    s = Strtoken(Token, ";",2)
    header(headerI).value=s
    headerI = headerI +1
    End If
    Loop

    ' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
    ' Load ItemData

    Dim itemIndex As Integer
    Dim sIndex As Integer

    Dim TestItemString As String

    If( doc.HasItem("WF_ITEMS") ) Then
    TestItemString = doc.GetItemValue("WF_ITEMS")(0)
    Else
    TestItemString = doc.GetItemValue("WorkflowContainer00WF_ITEMS")(0)
    End If

    s = "bla"
    sIndex = 1
    Token = Strtoken(TestItemString, ":", 1)
    If Not (Token = "") Then
    ' Get column number
    Do While Not s = ""
    s = Strtoken(Token, ";", sIndex)
    If Not ( s = "") Then
    columns = columns +1
    sIndex = sIndex +1
    End If
    Loop

    sIndex = 1
    s = "bla"
    Redim itemEntry(1 To columns) As String ' Set size and clear array
    Do While Not s = ""
    s = Strtoken(Token, ";", sIndex)
    If Not ( s = "") Then
    itemEntry(sIndex) = s
    sIndex = sIndex +1
    End If
    Loop
    items(1) = itemEntry
    Else
    ' Unable to parse table header...so we do not know how many columns we need
    Exit Sub
    End If

    itemIndex = 2
    Do While Not Token = ""
    Token = Strtoken(TestItemString, ":", itemIndex)
    If Not (Token = "") Then
    Redim itemEntry(1 To columns) As String ' Set size and clear array
    For i = 1 To columns
    s = Strtoken(Token, ";", i)
    If Not ( s = "") Then
    itemEntry(i) = s
    End If
    Next
    items(itemIndex) = itemEntry
    itemIndex = itemIndex + 1
    End If
    Loop

    ' ----------------------------------------------------------------------------------------------------------------------------------------------------------------

    ' Print header into stream
    Dim body As NotesMimeEntity
    Dim HFmimeChild As NotesMimeEntity
    Dim HFmimeHeader As NotesMimeHeader
    Dim HFstream As NotesStream

    Set body = doc.CreateMIMEEntity("body")
    Set HFmimeHeader = body.CreateHeader("Content-Type")
    Call HFmimeHeader.SetHeaderVal("text/html")

    Set HFmimeChild = body.CreateChildEntity

    Set HFstream = session.CreateStream

    ' HTML Header for CSS
    Call HFstream.WriteText(|<head>|)
    Call HFstream.WriteText(|<style type="text/css">table { width:40%; } td { font-family:Arial,helvetica,sans-serif; border:2px solid #999999; vertical-align:top; overflow:hidden;}</style>|)
    Call HFstream.WriteText(|</head>|)

    Call HFstream.WriteText(|<body>|)

    ' The Header HTML table
    Call HFstream.WriteText(|<TABLE WIDTH=40% BORDER=1>|)
    Forall headerIndex In header
    Call HFstream.WriteText(|<TR><TD ALIGN=LEFT BGCOLOR="#cccccc"><FONT COLOR=WHITE>| & headerIndex.name & |</FONT></TD><TD ALIGN=LEFT>| & headerIndex.value & |</TD></TR>|)
    End Forall
    Call HFstream.WriteText(|</TABLE>|)

    ' Item HTML table
    Call HFstream.WriteText(|<TABLE WIDTH=80% BORDER=1>|)
    Dim hc As Integer
    Forall itemE In items
    If( hc = 0 ) Then
    Call HFstream.WriteText(|<TR ALIGN=CENTER BGCOLOR="#f0ab00">|)
    Else
    Call HFstream.WriteText(|<TR>|)
    End If
    For i = 1 To columns
    If( hc = 0 ) Then
    Call HFstream.WriteText(|<TD><FONT COLOR=WHITE>| & itemE(i) & |</FONT></TD>|)
    Else
    Call HFstream.WriteText(|<TD ALIGN=CENTER>| & itemE(i) & |</TD>|)
    End If
    Next
    Call HFstream.WriteText(|</TR>|)
    If( hc = 0 ) Then
    hc = hc +1
    End If
    End Forall

    Call HFstream.WriteText(|</TABLE>|)

    Call HFstream.WriteText(|</body>|)

    Call HFmimeChild.SetContentFromText(HFstream,"text/html",ENC_NONE)
    Call HFstream.Close()
    Call HFstream.Truncate

    ' ----------------------------------------------------------------------------------------------------------------------------------------------------------------

    Call doc.CloseMIMEEntities(True)
    Call doc.Save(True, False, False)
    End Sub


    ---------------------------------------------


    Save the agent, and put it in the "Custom agent" field on Dominos' workflow application configuration (where you set the BoundItem Type, etc. ).


    Doing it that way, the agent is executed on server side, while creating the end-users work item.


    Hope this helps...


    Best regards


    Dirk



  • Lotusscript example is not working
    2009-12-14 05:55:39 Theo Aemmer Business Card [Reply]

    Hi Dirk
    The Lotusscript is not working, the global header and item definition are missing. They would descripe how those variables are composed. Could you please profide this information. This is the last pice of the puzzle and then our ALLOY work should work!


    Many thanks



    • Lotusscript example is not working
      2009-12-14 06:08:38 Dirk Lehmann SAP Employee Business Card [Reply]

      Hi Theo,


      you're absolutly right.


      Here's the missing part:


      <---snip--->


      Dim UpdateCheck As String


      Type t_headerRow
      name As String
      value As String
      End Type


      Dim header List As t_headerRow


      Dim items List As Variant
      Dim itemEntries() As String
      Dim columns As Integer


      Dim authorizedEntry As Integer


      <---snap--->


      Hope this helps


      Best regards


      Dirk


Showing messages 1 through 4 of 4.