# SAP Workflow Integration

## Set-up

In order to integrate Looply with SAP workflow, you must first create a standard task: In transaction PFTC select *"Standard task*" as the *Task type* and click on the *Create* button:&#x20;

<figure><img src="https://2821138577-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFijY43dc9KNMQtgqYko2%2Fuploads%2FjEHmY0tRfC2alzoVm63K%2FSAP%20WF%20integration%201.png?alt=media&#x26;token=f360ebc3-a933-49ab-b9e9-1eec126c39dd" alt=""><figcaption></figcaption></figure>

Enter an *Abbreviation*, *Name* and *Work item text*. Select "*ABAP Class*" from the *Object Category* dropdown and enter "*/LOOPLY/WF\_OUT*" as the *Object Type* and *"TRIGGER"* or *"RESUME"* depending on whether you wish your standard task to trigger or to resume a Looply workflow. (You may of course create both a *Trigger* and a *Resume* task). Select the *Background processing* checkbox and click  *Save*. Click on *Yes* in the pop-up to transfer missing elements from the object method. Next, select the *Background processing* checkbox and *Save.* Make a note of the number assigned to your standard task:

<figure><img src="https://2821138577-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFijY43dc9KNMQtgqYko2%2Fuploads%2F7zRyX5uHHcYBLkOMGHnG%2FSAP%20WF%20integration%202.png?alt=media&#x26;token=25ec4b42-0426-4751-a525-3258d3092c6b" alt=""><figcaption></figcaption></figure>

The task only needs to be created once. It can then be used any number of times in different (or in the same) workflow(s).

## Triggering a Looply workflow from a SAP workflow

In transaction swdd, add a new activity to your workflow, and enter the number of your newly created task to the *Task* field, preceded by TS  (for example TS90000004) and press *Enter.* Dismiss the "Define Container Elements and Binding" pop-up as this will create unwanted fields in your container and instead perform the binding manually. You may bind data from your workflow (or pass in static-hardcoded values) to the following fields:

<table><thead><tr><th width="211">Parameter Name</th><th width="81">Type<select><option value="7PeeNLqDkkwr" label="Import" color="blue"></option><option value="pPvjjLIx59Z2" label="Export" color="blue"></option><option value="XVv1Ysr6YD4W" label="Changing" color="blue"></option></select></th><th width="182">ABAP Type</th><th>Description</th></tr></thead><tbody><tr><td>IM_WFD_ID</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWD_WFD_ID</td><td>Use to pass in the workflow id. This will then be used to read the "<em>Process Determination</em>" <em>configuration</em> for a matching Scenario Id to determine which Looply workflow to trigger.</td></tr><tr><td>IM_WF_VERSION</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWD_VERSIO</td><td>You may have multiple versions of the same SAP workflow and wish to trigger a different Looply workflow depending on the SAP workflow version. Use this field in order to achieve this. Please note that using the field is optional but it's value must match the value in the "<em>Process Determination</em>" <em>configuration</em></td></tr><tr><td>IM_STEP</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>/LOOPLY/STEP</td><td>You may wish to trigger different Looply workflows at different points of the same SAP workflow. Use this field in order to achieve this. Please note that using the field is optional but it's value must match the value in the "<em>Process Determination</em>" <em>configuration</em></td></tr><tr><td>IM_WORKITEMID</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWW_WIID</td><td>Can be used to pass in the workitem id. This can then be used to get data from the workflow container using function SAP_WAPI_READ_CONTAINER</td></tr><tr><td>IM_REC_UNAME</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWF_STRING</td><td>Not actually passed to Looply. Used in here in case you want to get data for a certain SAP user</td></tr><tr><td>IM_REC_EMAIL</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWF_STRING</td><td>Can be used to send a card to a certain user (of course you can bind the recipient to any field in the data you like on the Looply side)</td></tr><tr><td>IM_DATA</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWF_STRING</td><td>Can be used to pass in any (string) data from the workflow container</td></tr><tr><td>IM_PROCESS_ID_T</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>/LOOPLY/PROCESS_ID_T</td><td>Table of process ids of the Looply workflows that will be triggered (see below for more details)</td></tr><tr><td>IM_IGNORE_ERRORS</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>FLAG</td><td>If this flag is not set, any potential errors that occur while triggering Looply will raise an exception and stop the workflow execution. Setting this flag will ignore errors so that the workflow execution continues to the next step</td></tr><tr><td>EX_DATA</td><td><span data-option="pPvjjLIx59Z2">Export</span></td><td>SWF_STRING</td><td>Use to pass back any (string) data to the Workflow container</td></tr><tr><td>EX_PROCESS_ID_T</td><td><span data-option="XVv1Ysr6YD4W">Changing</span></td><td>/LOOPLY/PROCESS_ID_T</td><td>Table of process ids of the Looply workflows that have been triggered (see below for more details). You may want to pass this to the workflow container so that you know which Looply workflows to resume at a later stage</td></tr></tbody></table>

As part of the standard task to trigger Looply, core method /LOOPLY/WF\_OUT=>TRIGGER will be triggered. The method will read the ["*Process Determination*" *configuration*](https://academy.looply.ai/integrations/triggering-or-resuming-a-looply-workflow-from-sap#process-determination-configuration) based on the values of IM\_WFD\_ID, IM\_WF\_VERSION and IM\_STEP passed in above to determine which Looply workflow to trigger and a Z-function which will be called to get the data to be passed  in to the workflow. You can create such a function by copying sample function /LOOPLY/SAMPLE\_WF\_TRIGGER. Based on the binding done in the workflow step above, the following parameters will be available in the function:

<table><thead><tr><th width="193">Parameter Name</th><th width="91">Type<select><option value="7PeeNLqDkkwr" label="Import" color="blue"></option><option value="pPvjjLIx59Z2" label="Export" color="blue"></option><option value="XVv1Ysr6YD4W" label="Changing" color="blue"></option></select></th><th width="187">ABAP Type</th><th>Description</th></tr></thead><tbody><tr><td>IM_WORKITEMID</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWW_WIID</td><td>Passed in from binding parameter</td></tr><tr><td>IM_DATA</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWF_STRING</td><td>Passed in from binding parameter</td></tr><tr><td>EX_CONT_DATA</td><td><span data-option="pPvjjLIx59Z2">Export</span></td><td>SWF_STRING</td><td>Passed back to binding parameter EX_DATA</td></tr><tr><td>EX_SUBRC</td><td><span data-option="pPvjjLIx59Z2">Export</span></td><td>SYSUBRC</td><td>Assuming parameter IM_IGNORE_ERRRORS of the standard task has not been set to X via the binding, setting a subrc != 0, will cause an exception to be raised</td></tr><tr><td>EX_MESS</td><td><span data-option="pPvjjLIx59Z2">Export</span></td><td>BAPIRET2</td><td>When the exception is raised you can use this parameter to insert a certain message in the workflow log</td></tr><tr><td>CH_LOOPLY_DATA</td><td><span data-option="XVv1Ysr6YD4W">Changing</span></td><td>/LOOPLY/TRIGGER_DATA_T</td><td>(see below)</td></tr></tbody></table>

Table CH\_LOOPLY\_DATA can be pre-filled by the SAP workflow via the binding with one row for every row in the process id table IM\_PROCESS\_ID\_T. If IM\_PROCESS\_ID\_T is not bound to anything or left blank,   CH\_LOOPLY\_DATA will still be pre-filled with a row (with a blank process id) assuming binding parameters  IM\_RECIPIENT\_EMAIL or RECIPIENT\_UNAME are not blank. The table can be edited inside the Z-function, after which, one Looply workflow will be triggered for each row of the table with the relevant data. The table contains the following fields:

<table><thead><tr><th width="200">Field Name</th><th width="209">ABAP Type</th><th>Description</th></tr></thead><tbody><tr><td>PROCESS_ID</td><td>/LOOPLY/PROCESS_ID</td><td>The process id of the Looply workflow that will get triggered. Note that you can only have one active workflow per process id</td></tr><tr><td>RECIPIENT_EMAIL</td><td>AD_SMTPADR</td><td>Can be used to send a card to a certain user (of course you can bind the recipient to any field in the data you like on the Looply side)</td></tr><tr><td>RECIPIENT_UNAME</td><td>STRING</td><td>Not actually passed to Looply. Used in here in case you want to get data for a certain SAP user in your function</td></tr><tr><td>DATA</td><td>STRING</td><td>Data string we pass to Looply. You can use method /ui2/cl_json=>serialize to convert an internal table to a json string if needed</td></tr><tr><td>UTIL_DATA</td><td>STRING</td><td>Second data string in case you'd like to pass a second/separate string to Looply</td></tr></tbody></table>

Please note that filling in any of the above fields is optional. You can if you wish trigger a Looply workflow without passing in any data and without a process id (Looply will automatically assign a process id in this case)

<figure><img src="https://2821138577-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFijY43dc9KNMQtgqYko2%2Fuploads%2Fk5HGMccAQMZkcfHNHqlb%2FWF%20integration.png?alt=media&#x26;token=16e3462e-cd8b-429b-9e1f-77bdec2b3ac2" alt=""><figcaption><p>Trigger Looply from SAP Workflow</p></figcaption></figure>

## Resuming a Looply workflow from a SAP workflow

You may also wish to resume a Looply workflow from your SAP workflow - you may have sent out a request for approval that should now be escalated, edited, or deleted for example. The mechanism for doing so is very similar to the mechanism for triggering a workflow. You must first add an activity to your workflow which points to a task that calls method /LOOPLY/WF\_OUT=> RESUME (instead of /LOOPLY/WF\_OUT=> TRIGGER). The fields available for binding will be slightly different in this case:

<table><thead><tr><th width="212">Parameter Name</th><th width="87">Type<select><option value="7PeeNLqDkkwr" label="Import" color="blue"></option><option value="pPvjjLIx59Z2" label="Export" color="blue"></option><option value="XVv1Ysr6YD4W" label="Changing" color="blue"></option></select></th><th width="182">ABAP Type</th><th>Description</th></tr></thead><tbody><tr><td>IM_WFD_ID</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWD_WFD_ID</td><td>Use to pass in the workflow id. This will then be used to read the "<em>Process Determination</em>" <em>configuration</em> for a matching Scenario Id to determine which Looply workflow to trigger.</td></tr><tr><td>IM_WF_VERSION</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWD_VERSIO</td><td>Use to determine the SAP workflow version. Please note that using the field is optional but it's value must match the value in the "<em>Process Determination</em>" <em>configuration</em></td></tr><tr><td>IM_STEP</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>/LOOPLY/STEP</td><td>You may wish to include different "Resume Looply Workflow" steps workflows at different points of the same SAP workflow. Use this field in order to achieve this. Please note that using the field is optional but it's value must match the value in the "<em>Process Determination</em>" <em>configuration</em></td></tr><tr><td>IM_WORKITEMID</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWW_WIID</td><td>Can be used to pass in the workitem id. This can then be used to get data from the workflow container using function SAP_WAPI_READ_CONTAINER</td></tr><tr><td>IM_REC_UNAME</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWF_STRING</td><td>Not actually passed to Looply. Used in here in case you want to get data for a certain SAP user</td></tr><tr><td>IM_DATA</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWF_STRING</td><td>Can be used to pass in any (string) data from the workflow container</td></tr><tr><td>IM_PROCESS_ID_T</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>/LOOPLY/PROCESS_ID_T</td><td>Table of process ids of the Looply workflows that will be resumed (see below for more details)</td></tr><tr><td>IM_IGNORE_ERRORS</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>FLAG</td><td>If this flag is not set, any potential errors that occur while triggering Looply will raise an exception and stop the workflow execution. Setting this flag will ignore errors so that the workflow execution continues to the next step</td></tr><tr><td>EX_DATA</td><td><span data-option="pPvjjLIx59Z2">Export</span></td><td>SWF_STRING</td><td>Use to pass back any (string) data to the Workflow container</td></tr><tr><td>EX_PROCESS_ID_T</td><td><span data-option="XVv1Ysr6YD4W">Changing</span></td><td>/LOOPLY/PROCESS_ID_T</td><td>Table of process ids of the Looply workflows that have been resumed (see below for more details). You may want to pass this to the workflow container so that you know which Looply workflows to resume at a later stage</td></tr></tbody></table>

As part of the standard task, core method /LOOPLY/WF\_OUT=>RESUME will be triggered. The method will read the ["*Process Determination*" *configuration*](https://academy.looply.ai/integrations/triggering-or-resuming-a-looply-workflow-from-sap#process-determination-configuration) based on the values of IM\_WFD\_ID, IM\_WF\_VERSION and IM\_STEP passed in above to determine a Z-function which will be called to determine which workflows to resume, as well as the data to pass  to the Looply workflow. You can create such a function by copying sample function /LOOPLY/SAMPLE\_WF\_RESUME. Based on the binding done in the workflow step above, the following parameters will be available in the function:

<table><thead><tr><th width="193">Parameter Name</th><th width="91">Type<select><option value="7PeeNLqDkkwr" label="Import" color="blue"></option><option value="pPvjjLIx59Z2" label="Export" color="blue"></option><option value="XVv1Ysr6YD4W" label="Changing" color="blue"></option></select></th><th width="187">ABAP Type</th><th>Description</th></tr></thead><tbody><tr><td>IM_WORKITEMID</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWW_WIID</td><td>Passed in from binding parameter</td></tr><tr><td>IM_DATA</td><td><span data-option="7PeeNLqDkkwr">Import</span></td><td>SWF_STRING</td><td>Passed in from binding parameter</td></tr><tr><td>EX_CONT_DATA</td><td><span data-option="pPvjjLIx59Z2">Export</span></td><td>SWF_STRING</td><td>Passed back to binding parameter EX_DATA</td></tr><tr><td>EX_SUBRC</td><td><span data-option="pPvjjLIx59Z2">Export</span></td><td>SYSUBRC</td><td>Assuming parameter IM_IGNORE_ERRRORS of the standard task has not been set to X via the binding, setting a subrc != 0, will cause an exception to be raised</td></tr><tr><td>EX_MESS</td><td><span data-option="pPvjjLIx59Z2">Export</span></td><td>BAPIRET2</td><td>When the exception is raised you can use this parameter to insert a certain message in the workflow log</td></tr><tr><td>CH_LOOPLY_DATA</td><td><span data-option="XVv1Ysr6YD4W">Changing</span></td><td>/LOOPLY/RESUME_DATA_T</td><td>(see below)</td></tr></tbody></table>

Table CH\_LOOPLY\_DATA can be pre-filled by the SAP workflow via the binding with one row for every row in the process id table IM\_PROCESS\_ID\_T. If IM\_PROCESS\_ID\_T is not bound to anything or left blank,   CH\_LOOPLY\_DATA will still be pre-filled with a row (with a blank process id) assuming binding parameters  IM\_RECIPIENT\_EMAIL or RECIPIENT\_UNAME are not blank. The table can be edited inside the Z-function, after which, the table will contain a row for each Looply workflow to be resumed. The table contains the following fields:

<table><thead><tr><th width="200">Field Name</th><th width="209">ABAP Type</th><th>Description</th></tr></thead><tbody><tr><td>PROCESS_ID</td><td>/LOOPLY/PROCESS_ID</td><td>The process id of the Looply workflow that will be resumed</td></tr><tr><td>RECIPIENT_UNAME</td><td>STRING</td><td>Not actually passed to Looply. Used in here in case you want to get data for a certain SAP user in your function</td></tr><tr><td>DATA</td><td>STRING</td><td>Data string we pass to Looply. You can use method /ui2/cl_json=>serialize to convert an internal table to a json string if needed</td></tr><tr><td>UTIL_DATA</td><td>STRING</td><td>Second data string in case you'd like to pass a second/separate string to Looply</td></tr><tr><td>ACTION</td><td>STRING</td><td>Can be used to pass a certain action to Looply (ie Approve, Reject, Cancel) so that you can get to it easily without having to parse DATA or UTIL_DATA</td></tr><tr><td>MESSAGE</td><td>STRING</td><td>Can be used to pass a (string) message to Looply</td></tr></tbody></table>

Filling in any of the above fields is optional and depends on what data you wish to pass to your Looply workflow. If field *PROCESS\_ID* is not filled with the process\_id of a Looply workflow at a wait state however, the workflow will not be resumed. This is not treated as an error by the framework as there may be cases in your SAP workflow where it is not possible to determine whether a Looply workflow has already been resumed or not.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://academy.looply.ai/integrations/sap-integration/sap-workflow-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
