We got an interesting scenario where a product manager wanted to store documents in an SAP Easy DMS.
SAP Easy DMS is a Document Management System that tracks, manages, and stores documents.
Power Automate is a service that helps you create automated workflows between your favourite apps and services to synchronise files, get notifications, collect data, and more.
As we have no direct connectors from Power Automate to SAP Easy DMS, hence we had to build our own ODATA Services in SAP Abap and consume it from Power Automate.
Let us get started
Steps to Create OData to Upload file in SAP
1. Create a structure with field type string to capture data in ODATA service with other required fields as shown below.

2. Create OData service in SEGW using the above Structure (Entity Types & Entity Set). Generate and Activate Services.
3. Redefine Create Method and use the below code sequence.
4. Read data into method
5. Convert Base 64 input data into Xtring
6. Convert XSTRING_TO_BINARY
7. Create document using FM BAPI_DOCUMENT_CREATE2
8. Once document creation is successful use FM CVAPI_DOC_CHECKIN to upload file in Document.
some sample code
DATA : lv_xstring TYPE xstring,
lv_op_length TYPE i,
lv_doctype TYPE dokar,
lv_docnumber TYPE doknr,
lv_docpart TYPE doktl_d,
lv_docversion TYPE dokvr,
ls_return TYPE bapiret2,
ls_entity TYPE zst_dms_doc_upload,
ls_docdata TYPE bapi_doc_draw2,
ls_objectdescr TYPE bapi_doc_drat,
lt_objectdescr TYPE TABLE OF bapi_doc_drat,
ls_pdf_checkin TYPE drao,
lt_pdf_checkin TYPE STANDARD TABLE OF drao,
ls_files TYPE cvapi_doc_file,
lt_files TYPE STANDARD TABLE OF cvapi_doc_file,
lt_content TYPE STANDARD TABLE OF orblk WITH DEFAULT KEY,
ls_msg TYPE messages,
ls_api_control TYPE cvapi_api_control.
io_data_provider->read_entry_data( IMPORTING es_data = ls_entity ).
CALL FUNCTION 'SCMS_BASE64_DECODE_STR'
EXPORTING
input = ls_entity-file_content
IMPORTING
output = lv_xstring
EXCEPTIONS
failed = 1
OTHERS = 2.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_xstring
IMPORTING
output_length = lv_op_length
TABLES
binary_tab = lt_content.
" SET VALUES
ls_docdata-documenttype = 'Mention Document Type'.
ls_docdata-documentversion = '00'.
ls_docdata-documentpart = '000'.
ls_docdata-laboratory = '000 '.
ls_objectdescr-description = 'Test Document Aditya' && ':' && sy-datum && '-' && sy-uzeit.
ls_objectdescr-language = 'E'.
ls_objectdescr-language_iso = 'EN'.
APPEND ls_objectdescr TO lt_objectdescr.
" CREATE ATTACHMENT
CALL FUNCTION 'BAPI_DOCUMENT_CREATE2'
EXPORTING
documentdata = ls_docdata
IMPORTING
documenttype = lv_doctype
documentnumber = lv_docnumber
documentpart = lv_docpart
documentversion = lv_docversion
return = ls_return
TABLES
documentdescriptions = lt_objectdescr.
COMMIT WORK AND WAIT.
* Files Data
ls_files-filename = ls_entity-file_name.
ls_files-storage_cat = ‘Mention Storage Category’.
ls_files-appnr = '1'.
ls_files-dappl = ls_entity-file_application. "PDF/WIN
ls_files-description = ls_entity-file_description.
ls_files-checked_in = 'X'.
ls_files-updateflag = 'I'.
APPEND ls_files TO lt_files.
* Control Data
ls_api_control-no_update_task = 'X'.
ls_api_control-api_mode = 'X'.
ls_api_control-commit_flag = 'X'.
* Prepare checkin file data.
LOOP AT lt_content INTO DATA(lw_content).
ls_pdf_checkin-dokar = lv_doctype.
ls_pdf_checkin-doknr = lv_docnumber.
ls_pdf_checkin-dokvr = lv_docversion.
ls_pdf_checkin-doktl = lv_docpart.
ls_pdf_checkin-appnr = '1'.
ls_pdf_checkin-zaehl = sy-tabix.
ls_pdf_checkin-orln = lv_op_length.
ls_pdf_checkin-orblk = lw_content.
APPEND ls_pdf_checkin TO lt_pdf_checkin.
CLEAR : ls_pdf_checkin.
ENDLOOP.
* Wait for 10 seconds
WAIT UP TO 5 SECONDS.
CALL FUNCTION 'CVAPI_DOC_CHECKIN'
EXPORTING
pf_dokar = lv_doctype
pf_doknr = lv_docnumber
pf_dokvr = lv_docversion
pf_doktl = lv_docpart
pf_ftp_dest = 'SAPFTPA'
pf_http_dest = 'SAPHTTPA'
ps_api_control = ls_api_control
IMPORTING
psx_message = ls_msg
TABLES
pt_files_x = lt_files
pt_content = lt_pdf_checkin.
COMMIT WORK AND WAIT.
Consume ODATA from Power Automate
Before we did into Power Automate, it is important to mention that we tested the endpoint using Postman and it worked really well – however while automating it using Power Automate, it failed with the following error “CSRF Token Validation Failed”.
I found from this blog that we had to pass the Cookie – from the initial POST while getting the x-csrf token – to the next POST while posting the document; that too in some specific format.
We are going to see all these in detail.
This is how the entire flow looks alike

1. Trigger the flow on a Selected File from SharePoint Online

2. Get file properties

3. Get file content

4. HTTP – GET x-csrf-token
in ODATA, on change requests (PUT, POST, and DELETE) of REST clients to an ABAP server, the client has to provide a CSRF (Cross-Site Request Forgery) token.
Such a token can be retrieved via a previous service call to the ABAP server. For this, first on a none-changing call (GET, HEAD, OPTIONS), the client has to get this token by setting the HTTP header X-CSRF-Token to the value Fetch. A CSRF token is returned by the ABAP server in the same header and can be used for subsequent, server state changing calls using header X-CSRF-Token.
If this header is not present on a server state changing REST call, the server will respond with a HTTP 403 (“Forbidden”) return code, the HTTP header is set to “Required” and an error text (for example, “CSRF token validation failed”) is returned.
The validity of the CSRF token depends on the release of the ABAP component SAP_BASIS and on the activation of the security session management (which is controlled via the transaction SICF_SESSIONS on the granularity of SAP clients):
a) Release < 7.03/7.31 or the security session management is inactive: An own CSRF cookie gets generated (sap-XSRF_<SystemID>_<SAPClient>) and this CSRF token remains valid for 24 hours (86400 seconds).
b) Release >= 7.03/7.31, the validity is bound to the security session, which depends on the system parameter http/security_session_timeout value (see transaction RZ11 for details on this parameter). By default, the security session management is active in these releases.

5. Compose – Base64
base64(outputs(‘Get_file_content’)?[‘body’])

6. Initialize variable – FileName

7. Variable – Set x-csrf-token

8. Variable – Set-Cookie

9. Various compose actions are needed to set the cookie
Compose – Split All
split(variables(‘varSet-Cookie’),’;’)
Compose – Sap-client
split(variables(‘varSet-Cookie’),’;’)[0]
Compose – MYSAPSSO2
split(split(variables(‘varSet-Cookie’),’;’)[1],’,’)[1]
Compose – SAP SESSIONID
split(split(variables(‘varSet-Cookie’),’;’)[4],’,’)[1]
Compose – SPNegoTokenRequested
formatDateTime(utcNow(),’yyyy-MM-dd HH:mm:ss’)
Compose – Postman Cookie Format
concat(outputs(‘Compose_-MYSAPSSO2′),’; ‘,outputs(‘Compose-SAP_SESSIONID’),’; ‘,outputs(‘Compose-SPNegoTokenRequested’),’; ‘,outputs(‘Compose-_Sap-client’))
Compose – Document Extension
split(variables(‘varFileName’),’.’)[1]

10. Check whether the uploaded file is a PDF or an OFFICE File

11. Finally HTTP – POST to SAP Easy DMS

This was an interesting approach to connecting SAP using ODATA from a Microsoft Power Platform.
Hoping to share my knowledge soon.
Thanks for reading this post 🙂