https://raw.githubusercontent.com/ajmaradiaga/feeds/main/scmt/topics/OData-blog-posts.xml SAP Community - OData 2026-02-21T12:11:20.076708+00:00 python-feedgen OData blog posts in SAP Community https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-members/saml-oauth2-powerapps-gt-sap/ba-p/14246108 SAML+OAuth2 (PowerApps --> SAP) 2025-10-17T12:14:09.642000+02:00 Jakub-Kocourek https://community.sap.com/t5/user/viewprofilepage/user-id/86328 <P><ul =""><li style="list-style-type:disc; margin-left:0px; margin-bottom:1px;"><a href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-members/saml-oauth2-powerapps-gt-sap/ba-p/14246108#toc-hId-1633775529">Overview</a></li><li style="list-style-type:disc; margin-left:0px; margin-bottom:1px;"><a href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-members/saml-oauth2-powerapps-gt-sap/ba-p/14246108#toc-hId-1437262024">Basic setup</a></li><li style="list-style-type:disc; margin-left:0px; margin-bottom:1px;"><a href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-members/saml-oauth2-powerapps-gt-sap/ba-p/14246108#toc-hId-1240748519">Postman test</a></li><li style="list-style-type:disc; margin-left:0px; margin-bottom:1px;"><a href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-members/saml-oauth2-powerapps-gt-sap/ba-p/14246108#toc-hId-1044235014">SAP Integration Suite setup</a></li><li style="list-style-type:disc; margin-left:0px; margin-bottom:1px;"><a href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-members/saml-oauth2-powerapps-gt-sap/ba-p/14246108#toc-hId-847721509">Microsoft PowerPlatform test</a></li><li style="list-style-type:disc; margin-left:0px; margin-bottom:1px;"><a href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-members/saml-oauth2-powerapps-gt-sap/ba-p/14246108#toc-hId-651208004">Troubleshooting</a></li></ul></P><H1 id="toc-hId-1633775529">Overview</H1><P><SPAN><!-- ScriptorStartFragment --></SPAN></P><DIV class=""><SPAN>This setup describes SAP data consumption (S/4HANA) in Microsoft PowerApps with user authentication using Microsoft EntraID. So you could login to Microsoft PowerApps with your EntraID account and use there data from S/4HANA.</SPAN></DIV><DIV class=""><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_37-1760621266734.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328469iE7A22D144F52B734/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="JakubKocourek_37-1760621266734.png" alt="JakubKocourek_37-1760621266734.png" /></span></DIV><DIV class=""><SPAN>If you're interested in the theory and architecture behind this setup, please read this excellent </SPAN><A href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-members/integrating-low-code-solutions-with-microsoft-using-sap-integration-suite/ba-p/13789298" target="_blank">article</A><SPAN> written by Martin Pankraz.</SPAN></DIV><DIV class=""><SPAN>Steps described here are compatible with S/4HANA On-premise, S/4HANA Private Cloud and ECC 6 EHP8, but some screens may look different as screenshots were captured in S/4HANA Private Cloud 2023.</SPAN></DIV><H1 id="toc-hId-1437262024"><STRONG>Basic setup</STRONG></H1><P>Start by checking that all required services are enabled in T-Code SICF.</P><UL><LI>/sap/bc/webdynpro/sap/saml2</LI><LI>/sap/public/bc/sec/saml2</LI><LI>/sap/public/bc/sec/cdc_ext_service</LI><LI>/sap/public/myssocntl</LI><LI>/sap/bc/sec/oauth2/token</LI></UL><P>Open T-Code SAML2 and enable SAML support. Provider name could be any string, but must be <U>URL compliant</U>! It's best practice to use http://&lt;SID&gt;&lt;client&gt;. Switch selection mode to automatic if you intent to use only one IDP.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_0-1760621638802.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328501i31CE1200E6484425/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_0-1760621638802.png" alt="JakubKocourek_0-1760621638802.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_1-1760621638804.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328502iA8F012C105071BAD/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_1-1760621638804.png" alt="JakubKocourek_1-1760621638804.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_2-1760621638808.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328503iC6E260CB32AD5C56/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_2-1760621638808.png" alt="JakubKocourek_2-1760621638808.png" /></span></P><P>Local provider is created. Download metadata needed for next steps.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_3-1760621638811.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328506i820D01B39C54D62F/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_3-1760621638811.png" alt="JakubKocourek_3-1760621638811.png" /></span></P><P>Now go to EntraID and create Enterprise App of type "SAP NetWeaver".</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_4-1760621638811.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328504i51D618885D01D54D/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="JakubKocourek_4-1760621638811.png" alt="JakubKocourek_4-1760621638811.png" /></span></P><P>On "Single sign-on" tab click "SAML". New blank configuration will be created. Use "Upload metadata file" button and select metadata file downloaded from SAP. This loads SAP's metadata into EntraID.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_5-1760621638814.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328505iC631E517DD93AB92/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_5-1760621638814.png" alt="JakubKocourek_5-1760621638814.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_6-1760621638818.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328507iC76758AEEA3363AA/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_6-1760621638818.png" alt="JakubKocourek_6-1760621638818.png" /></span></P><P>Edit "Reply URL" to point to Token service of OAuth2 and don't forget to set correct client in parameter "sap-client". "Sign on URL" could be any URL compliant string (ex. <A href="https://dummy.com/" target="_blank" rel="noopener nofollow noreferrer">https://dummy.com</A>).</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_7-1760621638824.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328509iD0EA646835FE1411/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_7-1760621638824.png" alt="JakubKocourek_7-1760621638824.png" /></span></P><P>Edit "Attributes &amp; Claims". Click on "Unique User Identifier (Name ID)".</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_8-1760621638825.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328508iC8B3A1100FF36C95/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_8-1760621638825.png" alt="JakubKocourek_8-1760621638825.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_9-1760621638826.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328512i078E5CC5733CCF1D/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_9-1760621638826.png" alt="JakubKocourek_9-1760621638826.png" /></span></P><P>You have two options here, based on attribute that you like to use as user identifier.</P><OL><LI>If you don't have any email address assigned to more than one user in SAP and you use email as UPN in EntraID, you could match EntraID and SAP user based on email. In this case select "Name identifier format" = "Email address" and "Source attribute" = "user.userprincipalname".</LI><LI>Otherwise find source attribute that contains SAP username. Ex. sAMAccountName. For this scenario choose "Name identifier format" = "Unspecified".</LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_10-1760621638827.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328510iACD46CC3CA9F3D28/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_10-1760621638827.png" alt="JakubKocourek_10-1760621638827.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_11-1760621638827.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328511iCECE96D4FCD10C2C/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_11-1760621638827.png" alt="JakubKocourek_11-1760621638827.png" /></span></P><P>Save and return to "Single sign-on" tab of your Enterprise App configuration. In "SAML Certificates" section download the certificate and federation metadata.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_12-1760621638831.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328513i21C25A73960E7F0D/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_12-1760621638831.png" alt="JakubKocourek_12-1760621638831.png" /></span></P><P>Go back to SAP backend and open T-Code SAML2. Switch to "Trusted Providers" tab and select "OAuth 2.0 Identity providers" under the "List of Trusted providers". Add a new provider using the metadata you just downloaded from EntraID.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_13-1760621638833.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328515i10EB02B34042B78F/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_13-1760621638833.png" alt="JakubKocourek_13-1760621638833.png" /></span></P><P>In the next step, upload the certificate downloaded from EntraID. In the "Provider" and "Signature and Encryption" steps, click "Next" and then "Finish".</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_14-1760621638835.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328514iC656328C6FF53B75/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_14-1760621638835.png" alt="JakubKocourek_14-1760621638835.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_15-1760621638838.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328516i342A1CCC3A3EC939/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_15-1760621638838.png" alt="JakubKocourek_15-1760621638838.png" /></span></P><P>Edit the new trusted IDP and select the name format "Unspecified" or "E-mail", depending on the user mapping scenario. Scenario 1 is "E-mail", scenario 2 is "Unspecified".</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_16-1760621638843.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328517i84C13995C18EE921/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_16-1760621638843.png" alt="JakubKocourek_16-1760621638843.png" /></span></P><P>Set the "User ID Mapping Mode" according to the scenario. For scenario 1 "email" or "Logon ID" for scenario 2.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_17-1760621638846.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328518i7083347D5555A069/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_17-1760621638846.png" alt="JakubKocourek_17-1760621638846.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_18-1760621638849.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328519i3E2EDC1852182594/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_18-1760621638849.png" alt="JakubKocourek_18-1760621638849.png" /></span></P><P>Save and enable the configuration.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_19-1760621638851.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328520i489CB1B7167AF75F/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_19-1760621638851.png" alt="JakubKocourek_19-1760621638851.png" /></span></P><P>Open EntraID again and create new App registration (not Enterprise app) that will be used as client.</P><P>On "Authentication" tab, section "Platform configurations" click "Add a platform" and select "Web". Set "Redirect URIs" = "<A href="https://localhost:44326/signin-oidc" target="_blank" rel="noopener nofollow noreferrer">https://localhost:44326/signin-oidc</A>" and select both tokens to be issued.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_20-1760621638853.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328522i36B619803B3A91AF/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_20-1760621638853.png" alt="JakubKocourek_20-1760621638853.png" /></span></P><P>On "Certificates &amp; secrets" tab generate new client secrete. <U>Save</U> the content of <U>"Value"</U> field as you can't access it later!</P><P>Next, on "API permissions" tab add a permission "Microsoft Graph" as delegated. Select "openid" (Sign users in).</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_21-1760621638856.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328523i45C121F776066FD5/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_21-1760621638856.png" alt="JakubKocourek_21-1760621638856.png" /></span></P><P>On "Expose and API" tab add a scope. URI should be predefined. After clicking "Save" new configuration panel will be shown. Fill there "Scope name" = "user_impersonation" and switch consent to "Admins and users". Set some display name and description. Finally click "Add scope".</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_22-1760621638857.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328524iBBE870AB7925CCD8/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_22-1760621638857.png" alt="JakubKocourek_22-1760621638857.png" /></span></P><P>On the same tab add a client application. Set "Client ID" = "6bee4d13-fd19-43de-b82c-4b6401d174c3" and set our scope in "Authorized scopes". This fixed client ID is identifier of SAP OData connector in PowerApps platform.</P><P>Copy "Application (client) ID" from "Overview" tab.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_23-1760621638863.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328525i3998F1B936ECD05A/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_23-1760621638863.png" alt="JakubKocourek_23-1760621638863.png" /></span></P><P>Now switch to App registration (not Enterprise app) that corresponds to the server part (same name as our Enterprise app defined in the beginning). Go to "Expose and API" tab and add a client application. Add there copied client ID and set scope.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_24-1760621638864.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328526iE172836C1EFFFA56/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_24-1760621638864.png" alt="JakubKocourek_24-1760621638864.png" /></span></P><P>One again switch to SAP system. Create technical user for impersonation. This user must be type B (System) and has correct permission role assigned. You need these permissions:</P><UL><LI>S_RFC: RFC_TYPE=Function group, RFC_NAME=SYST, ACTVT=Execute</LI><LI>S_SCOPE: OA2_CLIENT=SOAUTH2 (set same as ID of technical user), OA2_SCOPE=&lt;required_scopes&gt; (start with "*" for testing and restrict later)</LI></UL><P>Call T-Code SOAUTH2. On the screen click "Create". Set ID of technical user as "OAuth 2.0 Client ID" and write some description.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_25-1760621638868.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328527i0DA068E4C0584351/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_25-1760621638868.png" alt="JakubKocourek_25-1760621638868.png" /></span></P><P>In "Grant Type Setting" step select our trusted IDP from the list and set "Refresh Allowed".</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_26-1760621638872.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328528iBA20222140F0AD7C/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_26-1760621638872.png" alt="JakubKocourek_26-1760621638872.png" /></span></P><P>In "Scope Assignment" step set some service that you'd like to expose.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_27-1760621638875.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328529i2847B4327E772875/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_27-1760621638875.png" alt="JakubKocourek_27-1760621638875.png" /></span></P><H1 id="toc-hId-1240748519"><STRONG>Postman test</STRONG></H1><P>It's time for first test. You could use <A href="https://1drv.ms/u/c/6839f139c797b9bf/EcjYSwlb5rBMs8CCPEIUxSkBEEDijKDKeBGk1XPpX_ZQmA?e=6oh2xA" target="_blank" rel="noopener nofollow noreferrer">attached Postman collection</A>. Edit variables of the collection.</P><TABLE><TBODY><TR><TD><P><STRONG>Variable</STRONG></P></TD><TD><P><STRONG>Content</STRONG></P></TD><TD><P><STRONG>Example</STRONG></P></TD></TR><TR><TD><P>SAP GW IP Address</P></TD><TD><P>Address of SAP AS</P></TD><TD><P>vhigyi4aci.*************</P></TD></TR><TR><TD><P>SAP GW Port</P></TD><TD><P>Https port of SAP AS</P></TD><TD><P>44300</P></TD></TR><TR><TD><P>AAD tenant ID</P></TD><TD><P>Entra tenant ID (visible on app registration overview)</P></TD><TD><P>d3f10f6d-****************</P></TD></TR><TR><TD><P>AAD Application ID for SAP GW</P></TD><TD><P>SAP AS SAML local provider name</P></TD><TD><P><A href="http://I4A400" target="_blank" rel="noopener nofollow noreferrer">http://I4A400</A></P></TD></TR><TR><TD><P>Frontend App Client Id</P></TD><TD><P>Client ID of client app registration</P></TD><TD><P>b20e44f0-d88a-4558-8a53-b34484425e3f</P></TD></TR><TR><TD><P>Frontend App Client Secret</P></TD><TD><P>Generated client secret of client app registration</P></TD><TD><P>HZ48Q~NDBD38a4XW~************</P></TD></TR><TR><TD><P>Frontend App custom scope</P></TD><TD><P>Exposed API scope of client app registration</P></TD><TD><P>api://b20e44f0-d88a-4558-8a53-b34484425e3f/user_impersonation</P></TD></TR><TR><TD><P>SAP OAuth Client ID</P></TD><TD><P>SAP AS technical user ID</P></TD><TD><P>SOAUTH2</P></TD></TR><TR><TD><P>SAP OAuth Client Pwd</P></TD><TD><P>SAP AS technical user password</P></TD><TD><P>krnsW)************</P></TD></TR><TR><TD><P>SAP OAuth Scope</P></TD><TD><P>Scope (service) defined in OAuth config on SAP AS</P></TD><TD><P>ZAPI_BUSINESS_PARTNER_0001</P></TD></TR><TR><TD><P>SAPBearerToken</P></TD><TD><P>Leave blank, generated in process</P></TD><TD>&nbsp;</TD></TR><TR><TD><P>bearerToken</P></TD><TD><P>Leave blank, generated in process</P></TD><TD>&nbsp;</TD></TR></TBODY></TABLE><P>Please also change service name and parameters in request number 4 based on your use case (if not calling BP OData service as in example).</P><P>Now open first call of the collection and send request. Ignore output and open console (bottom left corner). Copy whole link (without GET keyword) and paste it in the web browser. After successful EntraID login blank error page will be shown. Go to the address bar and copy content of parameter "access_token". Open request number 2 and paste token to the "assertion" parameter.</P><P>After sending request number 2 you should see "access_token" in the output. Open request number 3 and send it. If successfull you would get new (short) "access_token" and also "refresh_token" and correct "scope".</P><P>Finally open and send request number 4. You should see data from your service.</P><H1 id="toc-hId-1044235014"><STRONG>SAP Integration Suite setup</STRONG></H1><P>In order to use this setup from internet / public cloud you have to expose SAP AS over SAP Cloud Connector.</P><P>In case that you don't have SAP Integration Suite BTP subaccount already added in SAP Cloud Connector, please use official guide to add it: <A href="https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/managing-subaccounts?locale=en-US" target="_blank" rel="noopener noreferrer">SAP Help Portal | SAP Online Help</A></P><P>Now go to the Cloud Connector subaccount and select "Cloud to On-Premises" in the left menu. On "Access Control" tab add new system (Mapping Virtual to Internal System). Backend type is "ABAP System", protocol "HTTPS". Fill in hostname and port of SAP AS.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_28-1760621638877.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328532i4FD0535130720DA1/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_28-1760621638877.png" alt="JakubKocourek_28-1760621638877.png" /></span></P><P>Use same values for virtual host and port. Disable Principal Propagation and Certificate Logon as you don't need these in this scenario. Host in request header should be Virtual Host. Set SID (ex. I4A) as System ID.</P><P>Expose services (your OData) in "Resources" section. On this example I'm exposing whole system (don't do this with productive SAP AS!).</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_29-1760621638878.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328530i76024A238BF67BE2/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_29-1760621638878.png" alt="JakubKocourek_29-1760621638878.png" /></span></P><P>Open SAP Integration Suite and begin with setup there. In left menu select Configure -&gt; APIs and select "API Providers" tab.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_30-1760621638879.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328533iFDA3B0BFD46AA8E8/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_30-1760621638879.png" alt="JakubKocourek_30-1760621638879.png" /></span></P><P>Create new provider. Fill some meaningful name on "Overview" tab. Switch to "Connection" tab and set "Type" = "On Premise", "Host" = &lt;AS_ABAP_HOST&gt;, "Port" = &lt;AS_ABAP_PORT&gt;, leave "Authentication" = "None". Set "sap-client" = &lt;AS_ABAP_CLIENT&gt; in Additional Properties.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_31-1760621638882.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328534i40D1B0CE72B32A3D/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_31-1760621638882.png" alt="JakubKocourek_31-1760621638882.png" /></span></P><P>Save provider and test connection. It should return "<EM>System is up and reachable. However, the ping check responded with code : 404; Message : Not found</EM>". That's correct state because we're calling base URL and not any reachable service.</P><P>Go to "Policy Templates" tab and import definition that's available in <A href="https://api.sap.com/policytemplate/Principal_Propagation_via_Entra_Id" target="_blank" rel="noopener noreferrer">SAP Business Accelerator Hub</A>. This policy needs some mapping. So switch to "Key Value Maps" tab and create new mapping (ex. name "I4ACLNT400_EntraID"). Use table bellow as an example.</P><TABLE><TBODY><TR><TD><P><STRONG>Key</STRONG></P></TD><TD><P><STRONG>Content</STRONG></P></TD><TD><P><STRONG>Example value</STRONG></P></TD></TR><TR><TD><P>issuer</P></TD><TD><P>Standard Microsoft issuer value (constant)</P></TD><TD><P><A href="https://sts.windows.net/d3f10f6d-4a4d-4cde-acb6-284a54d78b3a/" target="_blank" rel="noopener nofollow noreferrer">https://sts.windows.net/d3f10f6d-4a4d-4cde-acb6-284a54d78b3a/</A></P></TD></TR><TR><TD><P>AADSAPResource</P></TD><TD><P>SAP AS SAML local provider name</P></TD><TD><P><A href="http://I4A400" target="_blank" rel="noopener nofollow noreferrer">http://I4A400</A></P></TD></TR><TR><TD><P>entra-id-audience</P></TD><TD><P>Exposed API scope of client app registration (without scope name)</P></TD><TD><P>api://b20e44f0-d88a-4558-8a53-b34484425e3f</P></TD></TR><TR><TD><P>AADRegisteredAppClientSecret</P></TD><TD><P>Generated client secret of client app registration</P></TD><TD><P>HZ48Q~NDBD38a4XW~************</P></TD></TR><TR><TD><P>sap-oauth-client-password</P></TD><TD><P>SAP AS technical user password</P></TD><TD><P>krnsW)************</P></TD></TR><TR><TD><P>AADRegisteredAppClientId</P></TD><TD><P>Client ID of client app registration</P></TD><TD><P>b20e44f0-d88a-4558-8a53-b34484425e3f</P></TD></TR><TR><TD><P>SAPOAuthServerAdressForTokenEndpoint</P></TD><TD><P>SAP AS host + port</P></TD><TD><P>vhigyi4aci.**********:44300</P></TD></TR><TR><TD><P>sap-oauth-client-username</P></TD><TD><P>SAP AS technical user ID</P></TD><TD><P>SOAUTH2</P></TD></TR><TR><TD><P>sap-oauth-scope</P></TD><TD><P>Scope (service) defined in OAuth config on SAP AS</P></TD><TD><P>ZAPI_BUSINESS_PARTNER_0001</P></TD></TR><TR><TD><P>entra-id-tenant-id</P></TD><TD><P>Entra tenant ID (visible on app registration overview)</P></TD><TD><P>d3f10f6d-*****************</P></TD></TR></TBODY></TABLE><P>Finally switch to "API Proxies" tab and create new proxy. Select your API Provider, set URL to OData service that you have in the scope. Define some name and title of proxy. API Base Path could be anything you like - it's simply prefix for OData calls to this service (ex. /sap/utility/odata).</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_32-1760621638884.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328535i7C3844581615B5FA/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_32-1760621638884.png" alt="JakubKocourek_32-1760621638884.png" /></span></P><P>Ignore error "<EM>Unable to fetch metadata</EM>" - it's normal as we didn't applied policy yet.</P><P>In the new API provider click "..." in top right corner and select "Policies". Again in top right corner click "Policy Template" -&gt; "Apply". Select policy that you downloaded earlier and apply it. You should now see it under target endpoint's post flow.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_33-1760621638885.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328536i335AC81ABC899C1A/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_33-1760621638885.png" alt="JakubKocourek_33-1760621638885.png" /></span></P><P>Now go step by step through the policy. In second step (MapVariables) replace value of "mapIdentifier" with the name of your value map (ex. I4ACLNT400_EntraID). In steps "RefreshSAPToken", "fetchSAPOAuthToken" and "GetCSRFToken" change value of tag "APIProvider" from "PM1-via-SCC" to your provider name (ex. I4ACLNT400_NOAUTH).</P><P>Click "Update", "Save" and "Deploy".</P><H1 id="toc-hId-847721509"><STRONG>Microsoft PowerPlatform test</STRONG></H1><P>Login to Microsoft PowerApps at <A href="https://make.powerapps.com/" target="_blank" rel="noopener nofollow noreferrer">Power Apps</A> and switch to correct environment (if using more). In the left menu click "Flows" and create new cloud flow "Instant cloud flow". Fill some name and choose "Manually trigger a flow".</P><P>Add new step with connector "SAP OData", action "Read OData entity".</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_34-1760621638888.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328537i816803373E4CB1A9/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_34-1760621638888.png" alt="JakubKocourek_34-1760621638888.png" /></span></P><P>Set authentication type "Microsoft Entra ID Integrated (with APIM)". OData base URI is URL of you API Proxy service (ex. https://******<STRONG>.</STRONG>test.apimanagement.<STRONG>******</STRONG>.hana.ondemand.com/sap/utility/odata/BusinessPartner), Entra ID resource URI is API scope of client app (ex. api://b20e44f0-d88a-4558-8a53-b34484425e3f/user_impersonation). Set "API Key Name" = "APIKey (constant), "API Key Value" = &lt;Client_secret&gt; (ex. HZ48Q~NDBD38a4XW~************) and SAP's client name / password.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="JakubKocourek_35-1760621638893.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/328538iC884AC87A75BD85A/image-size/medium?v=v2&amp;px=400" role="button" title="JakubKocourek_35-1760621638893.png" alt="JakubKocourek_35-1760621638893.png" /></span></P><P>You should see Entra ID popup for login. After that service should be authenticated and entities readable.</P><H1 id="toc-hId-651208004"><STRONG>Troubleshooting</STRONG></H1><P>In case you're struggling with the basic setup (Postman testing), start T-Code SEC_DIAG_TOOL_VIEWER and capture the login traffic. You can find errors there and search SAP for Me. Always double check that user calling API (your business user, not SOAUTH2) is valid and has correct permission assigned (check SU53 for errors).</P><P>If calling OData API from PowerApps fails immediately with authentication error, check EntraID tenant log for errors associated with your registered client app.</P><P>Sometimes it fails later in login process and this could be debuged on Integration Suite. Open definition of your API Proxy, click "Debug" (top right corner) and "Start Debug" (bottom right corner). Now call API from PowerApps, refresh debugged window and check for errors.</P> 2025-10-17T12:14:09.642000+02:00 https://community.sap.com/t5/technology-blog-posts-by-sap/explore-the-potential-of-sap-fiori-development-portal-using-complex/ba-p/14257622 Explore the potential of SAP Fiori development portal using complex building blocks (3 of 6) 2025-10-31T07:43:01.269000+01:00 marcel_waechter https://community.sap.com/t5/user/viewprofilepage/user-id/302397 <P>In our previous posts, we introduced the SAP Fiori development portal and explored its structure. Now it's time to see the real power in action. Complex building blocks like the table don't just display data - they bring intelligent behavior, enterprise-grade features, and multiple visualization options that adapt to your business needs. Let's dive into how the portal helps you explore and understand these sophisticated capabilities.</P><P><STRONG>Beyond Visual Display: Intelligent Behavior</STRONG></P><P>The table building block exemplifies how SAP Fiori elements transforms simple annotations into comprehensive business functionality. When you annotate your UI.LineItems, you're not just defining columns - you're enabling a complete data management experience.</P><P>The table automatically adapts its behavior based on your entity's capabilities which are defined in the service metadata and annotations, for example:</P><UL><LI><STRONG>Insertable entities</STRONG>&nbsp;enable users to create new records directly in the table</LI><LI><STRONG>Deletable entities</STRONG>&nbsp;provide deletion capabilities with proper confirmation dialogs</LI><LI><STRONG>Updatable entities</STRONG>&nbsp;allow inline editing, with optional mass edit features for bulk changes</LI><LI><STRONG>Annotated actions</STRONG>&nbsp;become available as table actions, properly integrated with selection states</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Built-in Delete Feature" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/334589i2CF6EC89DC0AF46A/image-size/medium?v=v2&amp;px=400" role="button" title="marcel_waechter_0-1761892835790.png" alt="Built-in Delete Feature" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Built-in Delete Feature</span></span></P><P>This intelligence means your users get the functionality they need without additional development effort on your part.</P><P><STRONG>Multiple Visualizations at Your Fingertips</STRONG></P><P>The portal showcases how a single building block can transform into different visualizations based on your requirements:</P><UL><LI><STRONG>Responsive Table</STRONG>&nbsp;- Optimized for mobile and varying screen sizes</LI><LI><STRONG>Grid Table</STRONG>&nbsp;- High-performance display for large datasets</LI><LI><STRONG>Analytical Table</STRONG>&nbsp;- Built-in aggregation and grouping capabilities</LI><LI><STRONG>Tree Table</STRONG>&nbsp;- Hierarchical data representation</LI></UL><P>But the capabilities don't stop there. The table building block comes packed with enterprise-grade features that users expect from modern business applications:</P><UL><LI><STRONG>File Operations</STRONG>&nbsp;- Upload and download functionality for seamless document management</LI><LI><STRONG>Data Export</STRONG>&nbsp;- Export to Excel and PDF for offline analysis</LI><LI><STRONG>Clipboard Integration</STRONG>&nbsp;- Copy and paste operations for efficient data entry</LI><LI><STRONG>Personalization</STRONG>&nbsp;- Column reordering, resizing, and hiding based on user preferences</LI><LI><STRONG>Variant Management</STRONG>&nbsp;- Save and share different table configurations across users</LI><LI><STRONG>Filtering &amp; Sorting</STRONG>&nbsp;- Built-in capabilities for data exploration and organization</LI><LI><STRONG>Mass Operations</STRONG>&nbsp;- Bulk actions and mass editing for productivity</LI></UL><P>And this is just the beginning - the portal showcases dozens of additional features that activate automatically based on your metadata annotations, entity capabilities and configuration. Each feature is documented with examples showing exactly how to enable it in your application.</P><P><STRONG>Extensibility When Standard Features Aren't Enough</STRONG></P><P>The portal demonstrates how building blocks balance out-of-the-box functionality with extensibility. When standard features don't meet your specific needs for, you can:</P><UL><LI><STRONG>Add custom controls</STRONG>&nbsp;to display calculated or derived data</LI><LI><STRONG>Integrate custom actions</STRONG>&nbsp;for business-specific operations</LI><LI><STRONG>Use the building block API</STRONG>&nbsp;in your controller code for advanced scenarios</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Custom Column in Table" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/334582iFD199F4B779C3DCE/image-size/medium?v=v2&amp;px=400" role="button" title="marcel_waechter_0-1761892181262.png" alt="Custom Column in Table" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Custom Column in Table</span></span></P><P>This extensibility ensures you're never locked into standard behavior while still benefiting from enterprise-grade foundation features.</P><P><STRONG>Multi-Format Code Examples: A New Level of Support</STRONG></P><P>One of the portal's newest and most valuable features is showing the same annotations in multiple formats. When you explore a building block like the table, you'll see the implementation in:</P><UL><LI><STRONG>CAP CDS</STRONG>&nbsp;- For SAP Cloud Application Programming Model development</LI><LI><STRONG>RAP CDS</STRONG>&nbsp;- For ABAP RESTful Application Programming (since 1.142)</LI><LI><STRONG>XML annotations</STRONG>&nbsp;- For local annotations when service changes aren't possible</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Line Item Implementation" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/334585iE8A19980B8F617A2/image-size/medium?v=v2&amp;px=400" role="button" title="marcel_waechter_2-1761892442161.png" alt="Line Item Implementation" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Line Item Implementation</span></span></P><P>The portal's multi-format code examples ensure every developer can find the implementation pattern that fits their development context.&nbsp;<STRONG>CAP CDS</STRONG>&nbsp;examples offer full interactivity - modify annotations and see immediate results in the preview.&nbsp;<STRONG>RAP CDS</STRONG>&nbsp;examples provide static but comprehensive guidance for ABAP developers working in modern SAP environments, showing exactly how to implement the same functionality using ABAP RESTful Application Programming patterns. It also helps you find a running sample in the RAP Feature Showcase.&nbsp;<STRONG>XML annotations</STRONG>&nbsp;serve as your fallback option when service-level changes aren't feasible. This comprehensive approach means whether you're building with CAP, RAP, or working with existing services, you have the code examples you need to implement any building block feature.</P><P><STRONG>See It in Action: Table Building Block Example</STRONG></P><P>Let's explore the table's responsive behavior. When you open the Table Overview on a desktop, you'll see columns for ID, begin date, end date, agency, and status. But here's where the intelligence kicks in:</P><OL><LI>Click "Show Code" next to the UI.LineItems annotation.</LI><LI>The code editor opens, the preview adjusts to a smaller viewport, and you'll notice fewer columns are displayed.<BR />Note that the status column remains visible even though it's the 5th column in the annotation. This happens because of its&nbsp;<a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1445379">@ui</a>.Importance: #High&nbsp;setting.</LI><LI>Now try changing&nbsp;<a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1445379">@ui</a>.Importance&nbsp;from&nbsp;#High&nbsp;to&nbsp;#Low&nbsp;and watch the status column disappear from the table in real-time.</LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Changing UI.Importance" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/334586i76B3CBF16A1F8C24/image-size/medium?v=v2&amp;px=400" role="button" title="marcel_waechter_3-1761892570467.png" alt="Changing UI.Importance" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Changing UI.Importance</span></span></P><P>This demonstrates how building blocks intelligently prioritize content based on your annotations and available screen space.</P><P><STRONG>Interactive Learning Through Live Code</STRONG></P><P>The portal's live code editing capability transforms learning from passive reading to active experimentation. You can:</P><UL><LI>Modify annotations and see immediate visual results</LI><LI>Test different configuration combinations</LI><LI>Understand the relationship between metadata and UI behavior</LI><LI>Experiment safely without affecting your actual development environment</LI></UL><P>This hands-on approach helps you understand not just what's possible, but how different annotation patterns affect the user experience and can serve as input for your app development.</P><P><STRONG>What's Next</STRONG></P><P>In our next post, "Use SAP Fiori development portal to understand extension options for standard floorplans (4 of 6)," we'll shift focus from individual building blocks to complete pages. We'll explore how the portal guides you through extending standard floorplans like List Report and Object Page, showing you exactly where and how to add custom functionality while maintaining the enterprise-grade foundation these pages provide.</P><P>To get the full overview about the SAP Fiori development portal, check out the following blog posts of the mini-series:</P><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/introducing-the-sap-fiori-development-portal-your-gateway-to-rapid-sap/ba-p/14236768" target="_self">Introducing the SAP Fiori Development Portal: Your Gateway to Rapid SAP Fiori App Creation (1 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/get-familiar-with-sap-fiori-development-portal-and-the-power-of-the/ba-p/14240041" target="_self">Get familiar with SAP Fiori development portal and the power of the building blocks (2 of 6)</A></LI><LI>Explore the potential of SAP Fiori development portal using complex building blocks (3 of 6)</LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/use-sap-fiori-development-portal-to-understand-extension-options-for/ba-p/14270914" target="_self">Use SAP Fiori development portal to understand extension options for standard floorplans (4 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/prepare-building-custom-pages-by-using-sap-fiori-development-portal-5-of-6/ba-p/14277842" target="_blank">Prepare building custom pages by using SAP Fiori development portal (5 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/bringing-the-sap-fiori-development-portal-and-its-use-to-the-next-level-6/ba-p/14285025" target="_self">Bringing the SAP Fiori development portal and its use to the next level (6 of 6)</A></LI></UL> 2025-10-31T07:43:01.269000+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/sap-datasphere-export-data-of-analyticalmodel-via-odata-url-amp-oauth/ba-p/14256993 SAP Datasphere : Export Data of AnalyticalModel via Odata URL & Oauth Client of type Technical User 2025-11-05T07:58:30.289000+01:00 vikasparmar88 https://community.sap.com/t5/user/viewprofilepage/user-id/1528256 <P>In this blog, I have explained how to export data from an analytical model into CSV file securely using an OData URL and a technical user OAuth client.</P><P>Step - 1) Create an Oauth Client with Purpose as Technical User and select required roles. get client ID and secret and save it.&nbsp;<A href="https://help.sap.com/docs/SAP_DATASPHERE/9f804b8efa8043539289f42f372c4862/88b13468fc3c4ebd972bcb8faa6cafbf.html" target="_self" rel="noopener noreferrer">How to Guide</A>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Oauth.png" style="width: 347px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/334244iFF68CE80547515B7/image-dimensions/347x368?v=v2" width="347" height="368" role="button" title="Oauth.png" alt="Oauth.png" /></span></P><P>Step - 2) Create Odata_Tech_User_OauthClient.py file with below code&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-python"><code># --- IMPORTS --- import requests # For making HTTP requests to token and OData endpoints import pandas as pd # For handling tabular data from the OData response import os # For file path resolution and environment variable access from dotenv import load_dotenv # For loading credentials from a .env file # --- LOAD ENV VARIABLES --- load_dotenv() # Load environment variables from .env file into the runtime # --- CONFIG: Read credentials and endpoints from environment --- odata_url = os.getenv("ODATA_URL") # OData service endpoint token_url = os.getenv("TOKEN_URL") # OAuth token endpoint client_id = os.getenv("CLIENT_ID") # OAuth client ID client_secret = os.getenv("CLIENT_SECRET") # OAuth client secret # --- GET TOKEN: Request access token using client credentials --- token_payload = { "grant_type": "client_credentials", # OAuth flow type "client_id": client_id, # Injected from .env "client_secret": client_secret # Injected from .env } token_resp = requests.post(token_url, data=token_payload) # POST request to token endpoint token_resp.raise_for_status() # Raise error if token request fails access_token = token_resp.json()["access_token"] # Extract access token from response # --- CALL ODATA SERVICE: Fetch data using bearer token --- headers = {"Authorization": f"Bearer {access_token}"} # Auth header with token response = requests.get(odata_url, headers=headers) # GET request to OData endpoint response.raise_for_status() # Raise error if data fetch fails # --- PARSE RESULTS: Convert JSON payload to DataFrame --- data = response.json()["value"] # Extract 'value' list from OData response df = pd.DataFrame(data) # Convert list of records to pandas DataFrame # --- DISPLAY OR EXPORT: Show preview and optionally save to CSV --- print() print("🔍 Displaying top rows for quick inspection:") print() print(df.head()) # Display top rows for quick inspection print() # --- Extract view name from OData URL --- view_name = odata_url.rstrip("/").split("/")[-1] # Gets 'AM_EXPORT' from the URL # --- Construct filename --- filename = f"{view_name}.csv" # --- Display and save --- df.to_csv(filename, index=False) print(f"📁 Exported data Saved to: {os.path.abspath(filename)}")</code></pre><P>&nbsp;</P><P>Step - 3) Create .env file with all values of variables.</P><P>ODATA_URL : Copy the Odata link from analytical model</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="odata.png" style="width: 630px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/334255i61C52D8A5777AD69/image-dimensions/630x162?v=v2" width="630" height="162" role="button" title="odata.png" alt="odata.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="odata.png" style="width: 517px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/334257iF036F0A98768B92D/image-dimensions/517x297?v=v2" width="517" height="297" role="button" title="odata.png" alt="odata.png" /></span></P><P>&nbsp;</P><P>TOKEN_URL : get it from Datasphere -&gt; System -&gt; App Integration page</P><P>CLIENT ID &amp; Secret : Get it from Step-1</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Variables.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/334246iBF8AA617FEDF18B0/image-size/large?v=v2&amp;px=999" role="button" title="Variables.png" alt="Variables.png" /></span></P><P>Step-&nbsp; 4) Create .bat file with blow code&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-python"><code> off chcp 65001 &gt;nul REM ─────────────────────────────────────────────── REM 🚀 ODATA TECH USER OAUTH CLIENT EXECUTION SCRIPT REM ─────────────────────────────────────────────── echo. echo ============================================== echo 🔄 Starting OData export process... echo ============================================== REM --- Navigate to script directory --- cd /d "%~dp0" REM --- Run the Python script --- echo 🐍 Running Python script: Odata_Tech_User_OauthClient.py python Odata_Tech_User_OauthClient.py REM --- Completion message --- echo. echo ✅ Script execution completed. echo ============================================== REM --- Keep window open --- pause</code></pre><P>&nbsp;</P><P>Keep all files in same directory</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Folder.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/334250i25167CB60103AFB0/image-size/large?v=v2&amp;px=999" role="button" title="Folder.png" alt="Folder.png" /></span></P><P><!-- StartFragment --></P><P>Once everything is set up, just double-click the .bat&nbsp;file to run the process. It will execute the Python script and, once finished, generate a .csv file name exactly same name as the analytical model name. As part of the execution, the first five rows of data will also be displayed on screen for quick preview</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="output.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/334261i1BE9F41A80C0F984/image-size/large?v=v2&amp;px=999" role="button" title="output.png" alt="output.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Folder.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/334248iA75EC24BCB3F6067/image-size/large?v=v2&amp;px=999" role="button" title="Folder.png" alt="Folder.png" /></span></P><P>Thanks</P><P>Vikas Parmar</P><P>&nbsp;</P> 2025-11-05T07:58:30.289000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-simulation-apis-odata-v4/ba-p/14253152 Solution Order Simulation APIs - OData V4 2025-11-10T11:10:34.647000+01:00 babuganesh1982 https://community.sap.com/t5/user/viewprofilepage/user-id/197549 <H2 id="toc-hId-1763692545">Table of Contents</H2><P><ul =""><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-simulation-apis-odata-v4/ba-p/14253152#toc-hId-1763692545">Table of Contents</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-simulation-apis-odata-v4/ba-p/14253152#toc-hId-1567179040">Introduction</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-simulation-apis-odata-v4/ba-p/14253152#toc-hId-1370665535">Authentication and Access</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-simulation-apis-odata-v4/ba-p/14253152#toc-hId-977638525">Metadata</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-simulation-apis-odata-v4/ba-p/14253152#toc-hId-781125020">API Capabilities and Entities</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-simulation-apis-odata-v4/ba-p/14253152#toc-hId-388098010">BusinessSolutionOrder – Solution Order Header</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-simulation-apis-odata-v4/ba-p/14253152#toc-hId-191584505">BusSolnOrdPartner – Solution Order Header Partner</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-simulation-apis-odata-v4/ba-p/14253152#toc-hId-145811852">BusSolnOrdItmPartner – Solution Order Item Partner</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-simulation-apis-odata-v4/ba-p/14253152#toc-hId--247215158">BusSolnOrdItmPriceElement – Item Price Element</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-simulation-apis-odata-v4/ba-p/14253152#toc-hId--640242168">BusSolnOrdItmBillgReqItem – Item Billing Request Item(Contract Item)</a></li></ul></P><P>&nbsp;</P><H2 id="toc-hId-1567179040">Introduction</H2><P><SPAN>Solution Order is a business transaction in SAP Cloud ERP, used to sell solutions which can be a combination of either physical goods, one time services, recurring services, subscriptions, or projects bundled as one integrated customer offering. With the 2508 release of SAP Cloud ERP,&nbsp; the OData V4 APIs for simulation of solution order is available. Simulation APIs can be used to simulate various entities of solution order without creating a solution order. Various determination logic like partner determination, price determination, billing plan etc can be simulated without creating a solution order. This can be used to provide a quote using a quoting engine outside of SAP Cloud ERP. Such external quoting solutions can benefit from the possibility of quoting a real time price calculated in SAP Cloud ERP using the Solution Order simulation APIs.&nbsp; In this blog, you will find more information about the API, the entities available for consumption and the operations on these entities.</SPAN></P><P>&nbsp;</P><H2 id="toc-hId-1370665535">Authentication and Access</H2><P>The communication arrangement with the Business Solution Order Integration scenario(SAP_COM_0706) needs<BR />to be in place to access the API. You will need to create a communication arrangement for the communication scenario<BR />SAP_COM_0706, A communication system with an inbound user. You can as well configure OAUTH 2.0 if<BR />needed.</P><P>The API supports Basic Authentication(username/password), OAUTH2.0, and X.509 Certificate Authentication</P><H2 id="toc-hId-1174152030">&nbsp;</H2><H2 id="toc-hId-977638525">Metadata</H2><P>Metadata provides a description of the service, detailing the structure of the data, available entities, their<BR />properties, relationships, and supported operations. It acts as a blueprint that allows both developers and tools<BR />to understand how to interact with the service without needing prior knowledge of its design.<BR />It can be accessed using the below URL<BR />https://&lt;&lt;SERVER&gt;&gt;/sap/opu/odata4/sap/api_bussolnordsimulation/srvd_a2x/sap/api_bussolnordsimulation/0001/$metadata<BR />Below is a screenshot, with a part of the metadata of the Business Solution Order API.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="babuganesh1982_0-1761385625323.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/332344iB2401FBA57A62193/image-size/large?v=v2&amp;px=999" role="button" title="babuganesh1982_0-1761385625323.png" alt="babuganesh1982_0-1761385625323.png" /></span></P><P>In the above partial view of the metadata,&nbsp;you can see the Entity BusinessSolutionOrderItem, it has 2 key fields - BusinessSolutionOrder and BusinessSolutionOrderItem, a set of properties like Product, Quantity, <SPAN>BusSolnOrdItmCategory</SPAN>, etc. it also specifies the type, max length, precision etc of the properties. There are a set of navigational properties(or associations) for the entity. Associations are other entities related to the current entity.</P><P><STRONG>&nbsp;</STRONG></P><H2 id="toc-hId-781125020"><STRONG>API Capabilities and Entities</STRONG></H2><TABLE border="1" width="100%"><TBODY><TR><TD width="25%" height="30px"><STRONG>Entity</STRONG></TD><TD width="25%" height="30px"><STRONG>Supported Operations</STRONG></TD><TD width="25%" height="30px"><STRONG>Description</STRONG></TD><TD width="25%" height="30px"><STRONG>Associations</STRONG></TD></TR><TR><TD width="25%" height="30px"><SPAN>BusinessSolutionOrder</SPAN></TD><TD width="25%" height="30px">CREATE (Simulate)</TD><TD width="25%" height="30px"><STRONG>Solution Order Header</STRONG></TD><TD width="25%" height="30px"><P>_Item</P><P>_Partner</P></TD></TR><TR><TD width="25%" height="85px"><SPAN>BusinessSolutionOrderItem</SPAN></TD><TD width="25%" height="85px">CREATE (Simulate) only using deep insert on&nbsp;<SPAN>BusinessSolutionOrder</SPAN></TD><TD width="25%" height="85px"><STRONG>Solution Order Item</STRONG></TD><TD width="25%" height="85px"><P><SPAN>_BusinessSolutionOrder</SPAN></P><P><SPAN>_Partner</SPAN></P><P><SPAN>_PriceElement</SPAN></P><P><SPAN>_BillingRequestItem</SPAN></P></TD></TR><TR><TD width="25%" height="85px"><SPAN>BusSolnOrdPartner</SPAN><SPAN><BR /></SPAN></TD><TD width="25%" height="85px">CREATE (Simulate) only using deep insert on&nbsp;<SPAN>BusinessSolutionOrder</SPAN></TD><TD width="25%" height="85px"><STRONG>Header Partner</STRONG></TD><TD width="25%" height="85px"><SPAN>_BusinessSolutionOrder</SPAN></TD></TR><TR><TD width="25%" height="85px"><SPAN>BusSolnOrdItmPartner</SPAN><SPAN><BR /></SPAN></TD><TD width="25%" height="85px">CREATE (Simulate) only using deep insert on&nbsp;<SPAN>BusinessSolutionOrder</SPAN></TD><TD width="25%" height="85px"><STRONG>Item Partner</STRONG></TD><TD width="25%" height="85px"><P><SPAN>_BusinessSolutionOrder</SPAN></P><P>_Item</P></TD></TR><TR><TD width="25%" height="85px"><SPAN>BusSolnOrdItmPriceElement</SPAN><SPAN><BR /></SPAN></TD><TD width="25%" height="85px">CREATE (Simulate) only using deep insert on&nbsp;<SPAN>BusinessSolutionOrder</SPAN></TD><TD width="25%" height="85px"><STRONG>Item Price Element</STRONG></TD><TD width="25%" height="85px"><P><SPAN>_BusinessSolutionOrder</SPAN></P><P>_Item</P></TD></TR><TR><TD width="25%" height="97px"><SPAN>BusSolnOrdItmBillgReqItem</SPAN></TD><TD width="25%" height="97px">CREATE (Simulate) only using deep insert on&nbsp;<SPAN>BusinessSolutionOrder</SPAN></TD><TD width="25%" height="97px"><P><STRONG>Billing Request Line of a Contract Item</STRONG></P></TD><TD width="25%" height="97px"><P><SPAN>_BusinessSolutionOrder</SPAN></P><P>_Item</P></TD></TR></TBODY></TABLE><H2 id="toc-hId-584611515">&nbsp;</H2><H2 id="toc-hId-581989039" id="toc-hId-388098010"><STRONG>BusinessSolutionOrder – Solution Order Header</STRONG></H2><P><STRONG>Simulate solution order with one item to get header and item entities with simulated net value</STRONG></P><P>You can add any number of items to simulate.</P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt; /sap/opu/odata4/sap/api_bussolnordsimulation/srvd_a2x/sap/bussolnordersimulation/0001 /BusinessSolutionOrder X-CSRF-Token: abc { "BusSolnOrdType": "SOLO", "BusSolnOrdDescription": "Simulation Demo", "SoldToParty": "17100001", "PayerParty": "17100001", "PaymentTerms": "0001", "SalesOrganization": "1710", "DistributionChannel": "10", "Division": "00", "RespEmployeeBusinessPartnerId": "9980000549", "_Item": [ { "Product": "TG11", "Quantity": 1, "BusSolnOrdItmQtyUnitISOCode": "PCE" } ] }</code></pre><P>&nbsp;</P><H2 id="toc-hId-188962029" id="toc-hId-191584505"><STRONG>BusSolnOrdPartner – Solution Order Header Partner</STRONG></H2><P>You can pass an empty _Partner:[] entity in the payload to read the header partners that are determined based on the partner determination procedure assigned to the solution order transaction.</P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt; /sap/opu/odata4/sap/api_bussolnordsimulation/srvd_a2x/sap/bussolnordersimulation/0001 /BusinessSolutionOrder X-CSRF-Token: abc { "BusSolnOrdType": "SOLO", "BusSolnOrdDescription": "Simulation Demo", "SoldToParty": "17100001", "PayerParty": "17100001", "PaymentTerms": "0001", "SalesOrganization": "1710", "DistributionChannel": "10", "Division": "00", "RespEmployeeBusinessPartnerId": "9980000549", //Empty Partner association in payload to return the simulated entity in response "_Partner":[], "_Item": [ { "Product": "TG11", "Quantity": 1, "BusSolnOrdItmQtyUnitISOCode": "PCE" } ] }</code></pre><H2 id="toc-hId--4929000">&nbsp;</H2><H2 id="toc-hId--7551476" id="toc-hId-145811852"><STRONG>BusSolnOrdItmPartner – Solution Order Item Partner</STRONG></H2><P>Similar to header partner,&nbsp;You can pass an empty _Partner:[] entity in the payload to read the item partners that are determined based on the partner determination procedure assigned to the item category.</P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt; /sap/opu/odata4/sap/api_bussolnordsimulation/srvd_a2x/sap/bussolnordersimulation/0001 /BusinessSolutionOrder X-CSRF-Token: abc { "BusSolnOrdType": "SOLO", "BusSolnOrdDescription": "Simulation Demo", "SoldToParty": "17100001", "PayerParty": "17100001", "PaymentTerms": "0001", "SalesOrganization": "1710", "DistributionChannel": "10", "Division": "00", "RespEmployeeBusinessPartnerId": "9980000549", "_Item": [ { "Product": "TG11", "Quantity": 1, "BusSolnOrdItmQtyUnitISOCode": "PCE", //Empty Partner association in payload to return the simulated entity in response "_Partner": [] } ] }</code></pre><P>You can also override a partner determined in simulation by passing the updated partner in the payload. This can be useful to for example simulate changes in shipping cost based on the address of a new partner that is passed which is different from the determined partner.&nbsp;</P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt; /sap/opu/odata4/sap/api_bussolnordsimulation/srvd_a2x/sap/bussolnordersimulation/0001 /BusinessSolutionOrder X-CSRF-Token: abc { "BusSolnOrdType": "SOLO", "BusSolnOrdDescription": "Simulation Demo", "SoldToParty": "17100001", "PayerParty": "17100001", "PaymentTerms": "0001", "SalesOrganization": "1710", "DistributionChannel": "10", "Division": "00", "RespEmployeeBusinessPartnerId": "9980000549", "_Item": [ { "Product": "TG11", "Quantity": 1, "ShipToParty": "17100002", "BusSolnOrdItmQtyUnitISOCode": "PCE", "_Partner": [ { "CustMgmtPartnerFunction": "00000055", "CustMgmtBusinessPartner": "17100002" } ] } ] }</code></pre><H2 id="toc-hId--50701653">&nbsp;</H2><H2 id="toc-hId--249837634" id="toc-hId--247215158"><STRONG>BusSolnOrdItmPriceElement – Item Price Element</STRONG></H2><P>Similar to partners,&nbsp;You can pass an empty _PriceElement[] entity in the payload to read the item price elements that are calculated based on the pricing procedure assigned.</P><P>How ever you can also pass a new price element in simulation request like a discount to simulate the solution order with the discount condition</P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt; /sap/opu/odata4/sap/api_bussolnordsimulation/srvd_a2x/sap/bussolnordersimulation/0001 /BusinessSolutionOrder X-CSRF-Token: abc { "BusSolnOrdType": "SOLO", "BusSolnOrdDescription": "Simulation Demo", "Language": "EN", "SoldToParty": "17100001", "SalesOrganization": "1710", "DistributionChannel": "10", "Division": "00", "RespEmployeeBusinessPartnerId": "9980000549", "_Item": [ { "Product": "TG12", "Quantity": 1, "BusSolnOrdItmQtyUnitISOCode": "EA", //Adding a fixed discount "_PriceElement": [ { "ConditionType": "DRV1", "ConditionRateValue": -10, "ConditionCurrency": "USD" } ] } ] }</code></pre><H2 id="toc-hId--443728663">&nbsp;</H2><H2 id="toc-hId-1855151293" id="toc-hId--640242168"><STRONG>BusSolnOrdItmBillgReqItem – Item Billing Request Item(Contract Item)</STRONG></H2><P>Billing Request Line item is relevant for a service contract item of type SOSC(Service Contract Item) and SOPA(Service Contract Item with Price Adaptation). You can simulate the billing plan by providing the billing date and settlement period in the payload and you will see the Billing Request Items accordingly. For example if you provide a settlement period as monthly for a contract running for 1 year, you will see 12 Billing Request Items in the simulation response.</P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt; /sap/opu/odata4/sap/api_bussolnordsimulation/srvd_a2x/sap/bussolnordersimulation/0001 /BusinessSolutionOrder { "BusSolnOrdType": "SOLO", "BusSolnOrdDescription": "Simulation of BRLs", "SoldToParty": "17100001", "SalesOrganization": "1710", "DistributionChannel": "10", "Division": "00", "RespEmployeeBusinessPartnerId": "9980000549", "_Item": [ { "BusinessSolutionOrderItem": "10", "Product": "SRV_CONTRACT", "BusSolnOrdItmCategory": "SOSC", "Quantity": 1, "QuantityUnit": "AU", "BusSolnOrdItmQtyUnitISOCode": "C62", // Billing date first of the month "SrvcMgmtBillgPlanBillgDateRule": "BILL0002", // Settlement period - monthly billing "SettlementPeriodRule": "BILL0001", "ServiceContrItemStartDateTime": "2025-08-13T00:00:00Z", "ServiceContrItemEndDateTime": "2026-08-13T00:00:00Z", "_BillingRequestItem": [], "_PriceElement": [] } ] }</code></pre><P>&nbsp;</P> 2025-11-10T11:10:34.647000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082 Solution Order APIs - OData V4 2025-11-11T15:16:58.766000+01:00 babuganesh1982 https://community.sap.com/t5/user/viewprofilepage/user-id/197549 <H1 id="toc-hId-1631987350">Table of Contents</H1><P><ul =""><li style="list-style-type:disc; margin-left:0px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-1631987350">Table of Contents</a></li><li style="list-style-type:disc; margin-left:0px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-1238960340">Introduction</a></li><li style="list-style-type:disc; margin-left:0px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-1042446835">Authentication and Access</a></li><li style="list-style-type:disc; margin-left:0px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-845933330">Metadata</a></li><li style="list-style-type:disc; margin-left:0px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-649419825">API Capabilities and Entities</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-581989039">BusinessSolutionOrder – Solution Order Header</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-385475534">BusinessSolutionOrderItem – Solution Order Item</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-188962029">BusSolnOrdPartner – Solution Order Header Partner</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--7551476">BusSolnOrdItmPartner – Solution Order Item Partner</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-143189376">BusSolnOrdPartnerAddress – Address of Header Partner</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--53324129">BusSolnOrdItmPartnerAddr - Address of Item Partner</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--249837634">BusSolnOrdItmPriceElement – Item Price Element</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--446351139">BusSolnOrdItmScheduleLine – Item Schedule Line(Sales Item)</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--642864644">BSOrdItmRateElement – Item Rate Element (Subscription Item)</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--839378149">BSOrdItmSubscrpnParameter – Item Subscription Parameter(Subscription Item)</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--1035891654">BSOrdItmSubscrpnPriceAgrmt Item Price Agreement(Subscription Item)</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--1232405159">BusSolnOrdItmProduct – Item Product(Contract Item)</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--1428918664">BusSolnOrdItmRefObject – Item Reference Object(Service or Contract Item)</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--1625432169">BusSolnOrdItemRelationship – Solution Order Item Relationship</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--1653761983">BusSolnOrdUserStatus – Header User Status</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--1850275488">BusSolnOrdItmUserStatus – Item User Status</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--2046788993">BusinessSolutionOrderLongText – Header Long Text</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-2051664798">BusSolnOrdItmLongTxt – Item Long Text</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-1855151293">BusSolnOrdItmBillgReqItem – Billing Request Item(of a Contract Item)</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-1658637788">BSOrdItmBillgReqItmPrcElm – Price element of Billing Request Item (Contract Item)</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-1462124283">BusSolnOrdAppointment – Header Appointment</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-1265610778">BusSolnOrdItmAppointment – Item Appointment</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-1069097273">BusSolnOrdItmDuration – Item Duration</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-872583768">BusSolnOrdFUPSalesOrder – Follow-up Sales Order</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-844253954">BusSolnOrdFUPSrvcOrd – Follow-up Service Order</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-647740449">BusSolnOrdFUPSrvcContr – Follow-up Service Contract</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-451226944">BusSolnOrdFUPSubscrpn – Follow-up Subscription</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-254713439">BusSolnOrdFUPEntProject – Follow-up Enterprise Project</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId-58199934">BusSolnOrdItmFUPSalesOrder - Follow-up Sales Order Item</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--138313571">BusSolnOrdItmFUPSrvcOrd – Follow-up Service Order Item</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--334827076">BusSolnOrdItmFUPSrvcContr – Follow-up Service Contract Item</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--531340581">BusSolnOrdItmFUPSubscrpn – Follow-up Subscription Item</a></li><li style="list-style-type:disc; margin-left:15px; margin-bottom:1px;"><a href="https://community.sap.com/t5/technology-blog-posts-by-sap/solution-order-apis-odata-v4/ba-p/14228082#toc-hId--727854086">BusSolnOrdItmFUPEntProject - Follow-up Enterprise Project Item</a></li></ul></P><H1 id="toc-hId-1435473845">&nbsp;</H1><H1 id="toc-hId-1238960340"><STRONG>Introduction</STRONG></H1><P>Solution Order is a business transaction in SAP Cloud ERP, used to sell solutions which can be a combination of either physical goods, one time services, recurring services, subscriptions, or projects bundled as one integrated customer offering. With the 2508 release of SAP Cloud ERP, the OData V4 APIs for solution order is available. In this blog, you will find more information about the API, the entities available for consumption and the operations on these entities and some key differentiators of the V4 API.&nbsp;</P><P>&nbsp;</P><H1 id="toc-hId-1042446835"><STRONG>Authentication and Access</STRONG></H1><P>The communication arrangement with the&nbsp;Business Solution Order Integration scenario(SAP_COM_0706) needs to be in place to access the APIs. You will need to create a communication arrangement for the communication scenario SAP_COM_0706,&nbsp; A Communication System with an inbound user. You can as well configure OAUTH 2.0 if needed.</P><P>The API allows Basic Authentication(Username/password), OAUTH2.0, and X.509 Certificate Authentication</P><P>&nbsp;</P><H1 id="toc-hId-845933330"><STRONG>Metadata</STRONG></H1><P>Metadata provides a description of the service, detailing the structure of the data, available entities, their properties, relationships, and supported operations. It acts as a blueprint that allows both developers and tools to understand how to interact with the service without needing prior knowledge of its design.</P><P>It can be accessed using the below URL</P><P>https://&lt;&lt;SERVER&gt;&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001/$metadata</P><P>Below is a screenshot, with a part of the metadata of the Business Solution Order API.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="babuganesh1982_1-1761284172112.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/331805i58A66F70A28255D2/image-size/large?v=v2&amp;px=999" role="button" title="babuganesh1982_1-1761284172112.png" alt="babuganesh1982_1-1761284172112.png" /></span></P><P>In the above partial view of the metadata,&nbsp;you can see the Entity BusinessSolutionOrder, it has key- BusinessSolutionOrder, and a set of properties like BusinesssSolutionOrder, BusSolnOrdType, BusSolnOrdDescription, etc. it also specifies the type, max length, precision etc of the property. There are a set of navigational properties(or associations) for the entity. Associations are other entities related to the current entity.</P><P><STRONG>&nbsp;</STRONG></P><H1 id="toc-hId-649419825"><STRONG>API Capabilities and Entities</STRONG></H1><TABLE width="95%"><TBODY><TR><TD width="27%"><P><STRONG>Entity</STRONG></P></TD><TD width="16%"><P><STRONG>Supported Operations</STRONG></P></TD><TD width="25%"><P><STRONG>Comments</STRONG></P></TD><TD width="29%"><P><STRONG>Associations</STRONG></P></TD></TR><TR><TD width="27%"><P data-unlink="true">BusinessSolutionOrder&nbsp;</P></TD><TD width="16%"><P>CREATE / READ / UPDATE</P></TD><TD width="25%"><P><STRONG>Solution Order Header</STRONG></P></TD><TD width="29%"><P>_Items</P><P>_Partner</P><P>_Text</P><P>_UserStatus</P><P>_ItemRelationship</P><P>_FUPSalesOrder</P><P>_FUPServiceOrder</P><P>_FUPServiceContr</P><P>_FUPEntProject</P><P>_FUPSubscrpn</P><P>_Appointment</P></TD></TR><TR><TD width="27%"><P>BusinessSolutionOrderItem</P></TD><TD width="16%"><P>CREATE / READ / UPDATE / DELETE</P></TD><TD width="25%"><P><STRONG>Solution Order Item</STRONG> For&nbsp;<STRONG>Create</STRONG>&nbsp;operation, you can only use this entity in association with BusinessSolutionOrder</P></TD><TD width="29%"><P>_Partner</P><P>_PriceElement</P><P>_Text</P><P>_ScheduleLine</P><P>_UserStatus</P><P>_Product</P><P>_ReferenceObject</P><P>_BillingRequestItem</P><P>_RateElement</P><P>_SubscriptionParameter</P><P>_SubscriptionPriceAgreement</P><P>_FUPSalesOrderItem</P><P>_FUPServiceOrderItem</P><P>_FUPServiceContrItem</P><P>_FUPEntProjectItem</P><P>_FUPSubscrpnItem</P><P>_Appointment</P><P>_Duration</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdPartner</P></TD><TD width="16%"><P>CREATE / READ / UPDATE / DELETE</P></TD><TD width="25%"><P><STRONG>Header Partner</STRONG> For&nbsp;<STRONG>Create</STRONG>&nbsp;operation, you can only use this entity in association with BusinessSolutionOrder</P></TD><TD width="29%"><P>_PartnerAddress</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmPartner</P></TD><TD width="16%"><P>CREATE / READ / UPDATE / DELETE</P></TD><TD width="25%"><P><STRONG>Item Partner</STRONG></P><P>For&nbsp;<STRONG>Create</STRONG>&nbsp;operation, you can only use this entity in association with BusinessSolutionOrderItem</P></TD><TD width="29%"><P>_PartnerAddress</P><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdPartnerAddress</P></TD><TD width="16%"><P>READ / UPDATE</P></TD><TD width="25%"><P><STRONG>Header Partner Address</STRONG></P></TD><TD width="29%"><P>_Partner</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmPartnerAddr</P></TD><TD width="16%"><P>READ / UPDATE</P></TD><TD width="25%"><P><STRONG>Item Partner Address</STRONG></P></TD><TD width="29%"><P>_Partner</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmPriceElement</P></TD><TD width="16%"><P>CREATE / READ / UPDATE / DELETE</P></TD><TD width="25%"><P><STRONG>Item Price Element</STRONG></P><P>For&nbsp;<STRONG>Create</STRONG>&nbsp;operation, you can only use this entity in association with BusinessSolutionOrderItem</P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmScheduleLine</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P>Schedule Line of Sales Item</P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BSOrdItmRateElement</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P><STRONG>Rate Element of a Subscription Item</STRONG></P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BSOrdItmSubscrpnParameter</P></TD><TD width="16%"><P>CREATE / READ / UPDATE / DELETE</P></TD><TD width="25%"><P><STRONG>Subscription Parameter of a Subscription Item</STRONG></P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BSOrdItmSubscrpnPriceAgrmt</P></TD><TD width="16%"><P>CREATE / READ / UPDATE / DELETE</P></TD><TD width="25%"><P><STRONG>Price Agreement of&nbsp; Subscription Item</STRONG></P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmProduct</P></TD><TD width="16%"><P>CREATE / READ / UPDATE / DELETE</P></TD><TD width="25%"><P><STRONG>Item Product</STRONG></P><P>For&nbsp;<STRONG>Create</STRONG>&nbsp;operation, you can only use this entity in association with BusinessSolutionOrderItem</P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmRefObject</P></TD><TD width="16%"><P>CREATE / READ / UPDATE / DELETE</P></TD><TD width="25%"><P><STRONG>Item Reference Object</STRONG></P><P>For&nbsp;<STRONG>Create</STRONG>&nbsp;operation, you can only use this entity in association with BusinessSolutionOrderItem</P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItemRelationship</P></TD><TD width="16%"><P>CREATE / READ / DELETE</P></TD><TD width="25%"><P><STRONG>Item Relationship</STRONG></P><P>For&nbsp;<STRONG>Create</STRONG>&nbsp;operation, you can only use this entity in association with BusinessSolutionOrderItem</P></TD><TD width="29%"><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdUserStatus</P></TD><TD width="16%"><P>CREATE / READ</P></TD><TD width="25%"><P><STRONG>Header User Status</STRONG></P><P>For&nbsp;<STRONG>Create</STRONG>&nbsp;operation, you can only use this entity in association with BusinessSolutionOrder</P></TD><TD width="29%"><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmUserStatus</P></TD><TD width="16%"><P>CREATE / READ</P></TD><TD width="25%"><P><STRONG>Item User Status</STRONG></P><P>For&nbsp;<STRONG>Create</STRONG>&nbsp;operation, you can only use this entity in association with BusinessSolutionOrderItem</P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusinessSolutionOrderLongText</P></TD><TD width="16%"><P>CREATE / READ / UPDATE / DELETE</P></TD><TD width="25%"><P><STRONG>Header Text</STRONG></P></TD><TD width="29%"><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmLongTxt</P></TD><TD width="16%"><P>CREATE / READ / UPDATE / DELETE</P></TD><TD width="25%"><P><STRONG>Item Text</STRONG></P><P>For&nbsp;<STRONG>Create</STRONG>&nbsp;operation, you can only use this entity in association with BusinessSolutionOrderItem</P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmBillgReqItem</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P><STRONG>Billing Request Item of a Contract Item</STRONG></P></TD><TD width="29%"><P>_PriceElement</P><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BSOrdItmBillgReqItmPrcElm</P></TD><TD width="16%"><P>CREATE/READ / UPDATE/DELETE</P></TD><TD width="25%"><P><STRONG>Price Element of Billing Request Line</STRONG></P><P>For&nbsp;<STRONG>Create</STRONG>&nbsp;operation, you can only use this entity in association with BusSolnOrdItmBillgReqItem</P></TD><TD width="29%"><P>_BillingRequestItem</P><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdAppointment</P></TD><TD width="16%"><P>CREATE / READ / UPDATE</P></TD><TD width="25%"><P><STRONG>Header Appointments</STRONG></P></TD><TD width="29%"><P>_BusinessSolutionOrderTP</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmAppointment</P></TD><TD width="16%"><P>CREATE / READ / UPDATE</P></TD><TD width="25%"><P><STRONG>Item Appointments</STRONG></P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmDuration</P></TD><TD width="16%"><P>CREATE / READ / UPDATE</P></TD><TD width="25%"><P><STRONG>Item Duration</STRONG></P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrderTP</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdFUPSalesOrder</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P><STRONG>Follow Up Sales Orders</STRONG></P></TD><TD width="29%"><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdFUPSrvcOrd</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P><STRONG>Follow Up Service Orders</STRONG></P></TD><TD width="29%"><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdFUPSrvcContr</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P><STRONG>Follow Up Service Contracts</STRONG></P></TD><TD width="29%"><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdFUPSubscrpn</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P><STRONG>Follow Up Subscriptions</STRONG></P></TD><TD width="29%"><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdFUPEntProject</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P><STRONG>Follow Up Projects</STRONG></P></TD><TD width="29%"><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmFUPSalesOrder</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P><STRONG>Follow Up Sales Order Items</STRONG></P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmFUPSrvcOrd</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P><STRONG>Follow Up Service Order Items</STRONG></P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmFUPSrvcContr</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P><STRONG>Follow Up Service Contract Items</STRONG></P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmFUPSubscrpn</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P><STRONG>Follow Up Subscription Items</STRONG></P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR><TR><TD width="27%"><P>BusSolnOrdItmFUPEntProject</P></TD><TD width="16%"><P>READ</P></TD><TD width="25%"><P><STRONG>Follow Up Project Items</STRONG></P></TD><TD width="29%"><P>_Item</P><P>_BusinessSolutionOrder</P></TD></TR></TBODY></TABLE><P>&nbsp;</P><H2 id="toc-hId-581989039"><STRONG>BusinessSolutionOrder – Solution Order Header</STRONG></H2><P>With the Solution Order Header entity and its associations, you can create a solution order with the header and one or more of its associated entity(and its associated entities).</P><P>For Example: You can create a solution order by using the BusinessSolutionOrder along with Items, Partner, Item Partner, PriceElement, ItemRelationship, Text, UserStatus etc.</P><P>In the below example you will see creation of a solution order, adding items to the solution orders, creating a header text, and creating an item relationship between two items, all in separate OData calls and also to see how this can be achieved in one deep insert ODATA calls</P><P><STRONG>Create a solution order with just header</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder X-CSRF-Token: abc { "BusSolnOrdType": "SOLO", "BusSolnOrdDescription": "Solution Order", "Language": "EN", "SoldToParty": "17100001", "SalesOrganization": "1710", "DistributionChannel": "10", "Division": "00", "RespEmployeeBusinessPartnerId": "9980000549", "PurchaseOrderByCustomer": "External Reference" }</code></pre><P><STRONG>&nbsp;</STRONG></P><P><STRONG>Create an Item for an existing solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100004251/_Item X-CSRF-Token: abc { "Product": "TG11", "BusinessSolutionOrderItem": "10", "Quantity": 1, "QuantityUnit": "PC", "BusSolnOrdItmQtyUnitISOCode": "PCE" }</code></pre><P>&nbsp;</P><P><STRONG>Create another Item for an existing solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100004251/_Item X-CSRF-Token: abc { "Product": "SRV_01", "BusinessSolutionOrderItem": "20", "Quantity": 1, "SrvcContrDetnIsSpprsd": true, "QuantityUnit": "HR", "BusSolnOrdItmQtyUnitISOCode": "HUR" }</code></pre><P>&nbsp;</P><P><STRONG>Create a Header Text for an existing solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100004251/_Text X-CSRF-Token: abc { "TextObjectType": "0001", "Language": "EN", "BusinessSolutionOrderLongText": "This is a Header Note" }</code></pre><P><STRONG>&nbsp;</STRONG></P><P><STRONG>Create an item relationship between item 10 and item 20 of an existing solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100004251/_ItemRelationship X-CSRF-Token: abc { "BusinessSolutionOrder":"&lt;&lt;SOLUTION_ORDER_ID&gt;&gt;", "SrvcItemRelshpFromItemNumber": "10", "SrvcItemRelshpType": "001", "SrvcItemRelshpToItemNumber": "20" }</code></pre><P>&nbsp;</P><P>You can also perform all the above in one deep insert OData request by specifying all the related entities in a single request</P><P><STRONG>Create a solution order with deep insert: 2 items, override header partner, override item partner, add a header note and create an item relationship between item 10 and 20</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder X-CSRF-Token: abc { "BusSolnOrdType": "SOLO", "BusSolnOrdDescription": "Solution Order", "Language": "EN", "SoldToParty": "17100001", "SalesOrganization": "1710", "DistributionChannel": "10", "Division": "00", "RespEmployeeBusinessPartnerId": "9980000549", "PurchaseOrderByCustomer": "External Reference", //Solution Order Item "_Item": [ { "Product": "TG11", "BusinessSolutionOrderItem": "10", "Quantity": 1, "QuantityUnit": "PC", "BusSolnOrdItmQtyUnitISOCode": "PCE", "_Partner": [ { "CustMgmtPartnerFunction": "00000055", "CustMgmtBusinessPartner": "17100003" } ] }, { "Product": "SRV_01", "BusinessSolutionOrderItem": "20", "SrvcContrDetnIsSpprsd": true, "Quantity": 1, "QuantityUnit": "HR", "BusSolnOrdItmQtyUnitISOCode": "HUR" } ], //Partner at Header "_Partner": [ { "CustMgmtPartnerFunction": "00000055", "CustMgmtBusinessPartner": "17100002" } ], //Notes at Header "_Text": [ { "TextObjectType": "0001", "Language": "EN", "BusinessSolutionOrderLongText": "This is a Header Note" } ], //Relationship between Items "_ItemRelationship": [ { "SrvcItemRelshpFromItemNumber": "10", "SrvcItemRelshpType": "001", "SrvcItemRelshpToItemNumber": "20" } ] }</code></pre><P>&nbsp;</P><P><STRONG>Read all the entities of a solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100003509?$expand=*</code></pre><P>&nbsp;</P><P><STRONG>Read one or more associated entities of a solution order header</STRONG></P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100003509?$expand=_Partner,_ItemRelationship</code></pre><P>&nbsp;</P><H2 id="toc-hId-385475534"><STRONG>BusinessSolutionOrderItem – Solution Order Item</STRONG></H2><P>With the Solution Order Item entity, you can create one ore more of its associated entity. However, to create a solution order item, you will have to use the BusinessSolutionOrder along with _Item association.</P><P>For Example: You can create an Item Partner, PriceElement, Text, UserStatus etc for an item using the BusinessSolutionOrderItem along with the respective associations.</P><P>In the below examples you will see creation of a discount price condition, Item Text, Item Product, Reference Object, Item Appointment, Item Duration, Price Agreement &nbsp;for an existing solution order item,</P><P>&nbsp;</P><P><STRONG>Create a discount price element for an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100003519/20/_PriceElement X-CSRF-Token: abc { "ConditionType": "DRV1", "ConditionRateValue": -10 }</code></pre><P>&nbsp;</P><P><STRONG>Create an item text for an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100003519/10/_Text X-CSRF-Token: abc { "TextObjectType": "0001", "Language": "EN", "BusSolnOrdItmLongText": "This is an Item Note" }</code></pre><P>&nbsp;</P><P><STRONG>Create an item product for an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100003519/30/_Product X-CSRF-Token: abc { "ServiceProductListItem": "1", "SrvcProductListProduct": "SRV_01" }</code></pre><P>&nbsp;</P><P><STRONG>Create item reference object for an existing solution order Service item</STRONG></P><P>For a service item, you can create a reference object by passing either the functional location id or the equipment id.</P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100003519/20/_ReferenceObject X-CSRF-Token: abc { "ServiceReferenceEquipment":"10001405" }</code></pre><P>&nbsp;</P><P><STRONG>Create item reference object for an existing solution order Service item</STRONG></P><P>For a contract item, you can create a reference object by passing either the functional location id or the equipment id or the Reference Product.</P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100003519/20/_ReferenceObject X-CSRF-Token: abc { "ServiceReferenceProduct":"10001405" }</code></pre><P><STRONG>&nbsp;</STRONG></P><P><STRONG>Create an item appointment for an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100003519/50/_Appointment X-CSRF-Token: abc { "SrvcDocAppointmentType":"SUBS_PRIC_DT", "SrvcDocApptStartDateTime":"2025-09-28T10:00:00Z", "SrvcDocApptEndDateTime":"2025-09-28T10:00:00Z" }</code></pre><P>Appointment entities are used to persist various date fields in solution order.&nbsp;</P><P><SPAN>You define the Appointment type using the configuration activity&nbsp;</SPAN><STRONG><SPAN class="">Define Date Types, Duration Types and Date Rules for Service Transactions</SPAN></STRONG><SPAN>&nbsp;in your configuration environment. The system uses the duration, dates types, and date rules that are combined in a specific date profile to display dates in a transaction and to automatically determine them.&nbsp;</SPAN><SPAN>Make sure to assign the date profile to transaction types.&nbsp;</SPAN></P><P>&nbsp;</P><P><STRONG>Create an item duration for an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100003519/30/_Duration X-CSRF-Token: abc { "SrvcDocDurationType": "CONTDURA", "SrvcDocDurationValue": 18, "SrvcDocDurationUnit": "MONTH" }</code></pre><P>Fields on the UI like Fixed Term, Minimum Term, Minimum Term End, Renewal Term, Withdrawal Period, Withdrawal Period End, Term of Notice, Expected Term, Expected Term End, Expected Term Extension (visible under the Subscription Terms section in the UI), and Contact Validity Period (visible in the Dates Section of a contract item)are available in the Item Duration entity. These are persisted against the duration types below. The subscription terms can be updated in the UI as well as API only if the field “Override Default Terms” is selected (field in API - SubscrpnContrTrmsAreSpecified)</P><P><SPAN>You define the Duration type using the configuration activity&nbsp;</SPAN><STRONG><SPAN class="">Define Date Types, Duration Types and Date Rules for Service Transactions</SPAN></STRONG><SPAN>&nbsp;in your configuration environment. The system uses the duration, dates types, and date rules that are combined in a specific date profile to display dates in a transaction and to automatically determine them.&nbsp;</SPAN><SPAN>Make sure to assign the date profile to transaction types.&nbsp;</SPAN></P><P>&nbsp;</P><P><STRONG>Create an item price agreement for an existing solution order subscription item</STRONG></P><P>Price agreements are originally persisted in the subscription system, however this can be customised in the S/4HANA system. In such cases, the customised values are additionally persisted in S/4HANA systems.</P><P>Under the Price Calculation section you will see the prices that can be customisable. You can customize the price using the POST operation on the&nbsp; BusinessSolutionOrderItem entity using the _SubscriptionPriceAgreement association.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="babuganesh1982_5-1761293565529.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/331924i5AFE2DB68632FF84/image-size/large?v=v2&amp;px=999" role="button" title="babuganesh1982_5-1761293565529.png" alt="babuganesh1982_5-1761293565529.png" /></span></P><P>&nbsp;&nbsp;</P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100003519/50/_SubscriptionPriceAgreement X-CSRF-Token: abc { "SubscriptionRateElement": "ONETIME", "SubscrpnBillgPrcElmntSpec": "OneTimePrice", "SubscrpnBillgPricingField": "price", "SubscrpnBillgPricingScaleType": "A", "SubscrpnBillgCndnCalcType": "B", "ConditionCurrency": "USD", "ConditionRateValue": 190, "SbscrBilgCndnScaleLineIsUnlmtd": false }</code></pre><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="image.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/338772i0603A3F9B9244996/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="image.png" alt="image.png" /></span></P><P>Once the price is updated in S/4HANA it is persisted and you will notice under the customization status as Is Customized.</P><P>Since there is no persistency in the S/4HANA system until it is customised, the first time the customising of the price can be done using a POST operation of the API, and to update the prices again a PATCH operation can be used.</P><P>Multiple Price calculation is not supported. However if you still use the POST again after the initial customising, there will be 2 entries of the price which will be persisted in the table.</P><DIV class="">&nbsp;</DIV><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="babuganesh1982_7-1761293565538.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/331922i6CA2BF7C2254A50A/image-size/large?v=v2&amp;px=999" role="button" title="babuganesh1982_7-1761293565538.png" alt="babuganesh1982_7-1761293565538.png" /></span></P><P>In such case the entire Price calculation section will become empty and the solution order item will unusable in the UI along with a simulation error. This cannot be corrected from the UI. To correct this, you will have to delete the record using the DELETE operation on the Item Price Agreement entity (BSOrdItmSubscrpnPriceAgrmt).</P><P>&nbsp;</P><H2 id="toc-hId-188962029"><STRONG>BusSolnOrdPartner – Solution Order Header Partner</STRONG></H2><P>Solution Order determines header partners based on the partner determination procedure assigned to the transaction type.</P><P>To override the determined partners, you can pass the partner information either using the partner functions available as properties in the BusinessSolutionOrder entity like ShipToParty, BillToParty, PayerParty, RespEmployeeBusinessPartnerId and ContactPersonBusinessPartnerId or by passing the respective partners in the _Partner association while creating a solution order using deep insert.</P><P>The header partner entity can also be created using the association _Partner of the BusinessSolutionOrder entity but this may result in a too many partner error on the document. So If you use the _Partner association to create a partner at header make sure the entry you are trying to create doesn’t create an additional partner of an existing type.</P><P>&nbsp;</P><P><STRONG>Create a header partner for an existing solution order </STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100003561/_Partner X-CSRF-Token: abc IF-Match: * { "BusinessSolutionOrder":"100003561", "CustMgmtPartnerFunction":"00000003", "CustMgmtBusinessPartner":"17100002" }</code></pre><P>&nbsp;</P><P>If you observe the metadata of the header partner entity, You will notice that both the properties CustMgmtPartnerFunction and CustMgmtBusinessPartner are key properties and hence they cannot be updated via a PATCH call. So to update a header partner, you can use the properties ShipToParty, BillToParty, PayerParty, RespEmployeeBusinessPartnerId and ContactPersonBusinessPartnerId in the BusinessSolutionOrder entity.</P><P>You should not try to update the SoldToPrarty property either at the header or the item.</P><P>&nbsp;</P><P><STRONG>Delete a header partner of an existing solution order </STRONG></P><pre class="lia-code-sample language-abap"><code>DELETE &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdPartner/100003561/00000003/17100001 X-CSRF-Token: abc IF-Match: *</code></pre><P>Deleting a header partner might result in an error if the partner function is mandatory.</P><P>&nbsp;</P><H2 id="toc-hId--7551476"><STRONG>BusSolnOrdItmPartner – Solution Order Item Partner</STRONG></H2><P>Solution Order determines item partners based on the partner determination procedure assigned to the transaction type and the header partner.</P><P>To override the determined partners, you can pass the partner information either using the partner functions available as properties in the BusinessSolutionOrderItem entity like ShipToParty, BillToParty, PayerParty, RespEmployeeBusinessPartnerId and ContactPersonBusinessPartnerId or by passing the respective partners in the _Partner association while creating a solution order using deep insert.</P><P>The item partner entity can also be created using the association _Partner of the BusinessSolutionOrderItem entity but this may result in a too many partner error on the document. So If you use the _Partner association to create a partner at the item make sure the entry you are trying to create doesn’t create an additional partner of an existing type.</P><P>&nbsp;</P><P><STRONG>Create an item partner for an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100003561/10/_Partner X-CSRF-Token: abc { "BusinessSolutionOrder":"100003561", "BusinessSolutionOrderItem":"10", "CustMgmtPartnerFunction":"00000003", "CustMgmtBusinessPartner":"17100002" }</code></pre><P>If you observe the metadata of the item partner entity, You will notice that both the properties CustMgmtPartnerFunction and CustMgmtBusinessPartner are key properties and hence they cannot be updated via a PATCH call. So to update an item partner, you can use the properties ShipToParty, BillToParty, PayerParty, RespEmployeeBusinessPartnerId and ContactPersonBusinessPartnerId in the BusinessSolutionOrderItem entity. You should not try to update the SoldToPrarty property either at the header or the item.</P><P>&nbsp;</P><P><STRONG>Delete an item partner of an existing solution order item </STRONG></P><pre class="lia-code-sample language-abap"><code>DELETE &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdPartnerItem/100003561/10/00000003/17100001 X-CSRF-Token: abc IF-Match: *</code></pre><P>Deleting an item partner might result in an error if the partner function is mandatory.</P><P>&nbsp;</P><H2 id="toc-hId-143189376"><STRONG>BusSolnOrdPartnerAddress – Address of Header Partner</STRONG></H2><P>Address of header partner can be read and updated</P><P>&nbsp;</P><P><STRONG>Update address of header partner of an existing solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>PATCH &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdPartnerAddress/100004251/00000003/17100001 X-CSRF-Token: abc IF-Match: * { "HouseNumber": "138", "StreetName": "ITPL Main Road", "CityName": "Banglaore", "Country": "IN", "Region": "KA", "PostalCode": "560066", "MobilePhoneCountry": "IN", "MobileNumber": "9988776655", "PhoneNumberCountry": "US", "PhoneNumber": "20204040", "PhoneExtensionNumber": "1234", "FaxNumberCountry": "IN", "FaxAreaCodeSubscriberNumber": "1234567890", "FaxExtensionNumber": "5678", "EmailAddress": "newmailaddr@mailbox.com" }</code></pre><P>&nbsp;</P><P>&nbsp;</P><H2 id="toc-hId--53324129"><STRONG>BusSolnOrdItmPartnerAddr - Address of Item Partner</STRONG></H2><P>Address of item partner can be read and updated</P><P>&nbsp;</P><P><STRONG>Update address of item partner of an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>PATCH &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmPartnerAddr/100004251/10/00000003/17100001 X-CSRF-Token: abc IF-Match: * { "HouseNumber": "138", "StreetName": "ITPL Main Road", "CityName": "Banglaore", "Country": "IN", "Region": "KA", "PostalCode": "560066", "MobilePhoneCountry": "IN", "MobileNumber": "9988776655", "PhoneNumberCountry": "US", "PhoneNumber": "20204040", "PhoneExtensionNumber": "1234", "FaxNumberCountry": "IN", "FaxAreaCodeSubscriberNumber": "1234567890", "FaxExtensionNumber": "5678", "EmailAddress": "newmailaddr@mailbox.com" }</code></pre><P>&nbsp;</P><H2 id="toc-hId--249837634"><STRONG>BusSolnOrdItmPriceElement – Item Price Element</STRONG></H2><P>Item price element of a solution order item can be created by passing the price element in the _PriceElement association at the item while creating a solution order using deep insert.</P><P>The item price element entity can also be created using the association _ PriceElement of the BusinessSolutionOrderItem entity.</P><P>&nbsp;</P><P><STRONG>Create an item price element for an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100004251/10/_PriceElement X-CSRF-Token: abc { "ConditionType": "DRV1", "ConditionRateValue": -10 }</code></pre><P>If you create a price element with the same condition type as existing, it will override the existing price element and will mark it inactive and make the new one active. &nbsp;</P><P>&nbsp;</P><P><STRONG>Update item price element of an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>PATCH &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmPriceElement/100004251/10/240/1 X-CSRF-Token: abc IF-Match: * { "BusinessSolutionOrder": "100004251", "BusinessSolutionOrderItem": "10", "PricingProcedureStep": "240", "PricingProcedureCounter": "1", "ConditionType": "DRV1", "ConditionRateValue": -5 }</code></pre><P>The PricingProcedureStep and PricingProcedureCounter needs to be passed in the parameter</P><P>&nbsp;</P><P><STRONG>Delete an item price element of an existing solution order item </STRONG></P><pre class="lia-code-sample language-abap"><code>DELETE &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmPriceElement/100004251/10/240/1 X-CSRF-Token: abc IF-Match: *</code></pre><P>To Deleting an item price element, PricingProcedureStep and PricingProcedureCounter needs to be passed in the parameter.</P><P>&nbsp;</P><H2 id="toc-hId--446351139"><STRONG>BusSolnOrdItmScheduleLine – Item Schedule Line(Sales Item)</STRONG></H2><P><STRONG>You can only read a schedule line entity and no other operations are supported on this entity, and this is only relevant for a sales item</STRONG></P><P>&nbsp;</P><P><STRONG>Read a schedule line of a sales item of an existing solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmScheduleLine/100004251/10/1</code></pre><P>You can also use the $filter parameter to filter by the solution order you will get all the schedule line entities for the solution order</P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmScheduleLine?$filter=BusinessSolutionOrder eq '100004251'</code></pre><P>&nbsp;</P><H2 id="toc-hId--642864644"><STRONG>BSOrdItmRateElement – Item Rate Element (Subscription Item)</STRONG></H2><P>You cannot update a rate element but can read an existing rate element for a solution order subscription item using BSOrdItmRateElement</P><P>&nbsp;By passing the solution order number, item and rate element number. You can also read the rate element when you read a solution order item with an expand=_RateElement</P><P>&nbsp;</P><H2 id="toc-hId--839378149"><STRONG>BSOrdItmSubscrpnParameter – Item Subscription Parameter(Subscription Item)</STRONG></H2><P>You can read a subscription parameter using a GET operation on the BSOrdItmSubscrpnParameter entity by passing the solution order number, item and the subscription parameter sequence number or by reading the solution order item with a $expand = _SubscriptionParameter</P><P><STRONG>Update subscription parameter of an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>PATCH &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BSOrdItmSubscrpnParameter/100004251/70/1 X-CSRF-Token: abc IF-Match: * { "SubscriptionParameter": "ONETIME_CREDIT", "SubscrpnParameterIntegerValue": 2 }</code></pre><P>You can update a subscription parameter of a subscription item only if the item is not released or completed already</P><P>&nbsp;</P><P><STRONG>Delete subscription parameter of an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>DELETE &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BSOrdItmSubscrpnParameter/100004251/70/1 X-CSRF-Token: abc IF-Match: *</code></pre><P>&nbsp;</P><P>You can delete a subscription parameter of a subscription item only if the item is not released or completed already</P><P>&nbsp;</P><P><STRONG>Create subscription parameter of an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100004251/70/_SubscriptionParameter X-CSRF-Token: abc IF-Match: * { "SubscriptionParameter": "ONETIME_CREDIT", "SubscrpnParameterIntegerValue": 1 }</code></pre><P>You can create a subscription parameter of a subscription item using the POST operation on BusinessSolutionOrderItem using the association _SubscriptionParameter</P><P>&nbsp;</P><P>&nbsp;</P><H2 id="toc-hId--1035891654"><STRONG>BSOrdItmSubscrpnPriceAgrmt Item Price Agreement(Subscription Item)</STRONG></H2><P>Price agreements are originally persisted in the subscription system, however this can be customised in the S/4HANA system. In such cases, the customised values are additionally persisted in S/4HANA systems.</P><P>&nbsp;</P><P><STRONG>Update subscription price agreement of an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>PATCH &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BSOrdItmSubscrpnPriceAgrmt(BusinessSolutionOrder='100004251',BusinessSolutionOrderItem='000070',SubscriptionRateElement='ONETIME_CRDT',SubscriptionRateSubElement='',SubscrpnBillgPrcElmntSpec='OneTimePrice',SubscrpnBillgPricingField='price',SubscrpnBillgPrcAgreementLine='900001') X-CSRF-Token: abc IF-Match: * { "SubscrpnBillgPricingScaleType": "A", "SubscrpnBillgCndnCalcType": "B", "ConditionRateValue": 1001, "ConditionCurrency": "USD" }</code></pre><P>&nbsp;</P><P><STRONG>Delete subscription price agreement of an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>DELETE &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BSOrdItmSubscrpnPriceAgrmt(BusinessSolutionOrder='100004251',BusinessSolutionOrderItem='000070',SubscriptionRateElement='ONETIME_CRDT',SubscriptionRateSubElement='',SubscrpnBillgPrcElmntSpec='OneTimePrice',SubscrpnBillgPricingField='price',SubscrpnBillgPrcAgreementLine='900001') X-CSRF-Token: abc IF-Match: *</code></pre><P>You can update or delete a subscription price agreement of a subscription item only if the item is not released or completed already. To be sure you pass the mandatory information correctly, you can do a GET operation on the BSOrdItmSubscrpnPriceAgrmt entity for the subscription item you want to update the price Agreement. It is required to pass the scale type and calculation type in the payload even though you do not intend to modify them</P><H2 id="toc-hId--1232405159"><STRONG>BusSolnOrdItmProduct – Item Product(Contract Item)</STRONG></H2><P>&nbsp;</P><P><STRONG>Update item product list of an existing solution order contract item</STRONG></P><pre class="lia-code-sample language-abap"><code>PATCH &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmProduct/100004251/100/1 X-CSRF-Token: abc IF-Match: * { "SrvcProductListProduct":"SRV_05" }</code></pre><P>&nbsp;</P><P><STRONG>Delete subscription price agreement of an existing solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>DELETE &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmProduct/100004251/100/1 X-CSRF-Token: abc IF-Match: *</code></pre><P>You can update or delete an Item Product List of contract item only if the item is not released or completed already.</P><P>&nbsp;</P><H2 id="toc-hId--1428918664"><STRONG>BusSolnOrdItmRefObject – Item Reference Object(Service or Contract Item)</STRONG></H2><P>&nbsp;</P><P><STRONG>Update item reference object list of an existing solution order contract item</STRONG></P><pre class="lia-code-sample language-abap"><code>PATCH &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmProduct/100004251/100/1 X-CSRF-Token: abc IF-Match: * { "SrvcProductListProduct":"SRV_05" }</code></pre><P>&nbsp;</P><P><STRONG>Delete item reference object list of an existing solution order contract item</STRONG></P><pre class="lia-code-sample language-abap"><code>DELETE &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmRefObject/100004251/100/1 X-CSRF-Token: abc IF-Match: *</code></pre><P>&nbsp;</P><P>You can update an Item Reference object of a service item by passing the equipment id or the functional location id in the payload or that of a contract item by passing the reference product id or the equipment id or the functional location id in the payload.</P><P>&nbsp;</P><H2 id="toc-hId--1625432169"><STRONG>BusSolnOrdItemRelationship – Solution Order Item Relationship</STRONG></H2><P>&nbsp;</P><P><STRONG>Get all item relationships in a solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItemRelationship?$filter=BusinessSolutionOrder eq '100004251'</code></pre><P>&nbsp;</P><P><STRONG>Delete an item relationship of type 001 (Depends on) between item 10 and 20</STRONG></P><pre class="lia-code-sample language-abap"><code>DELETE &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItemRelationship/100004251/10/001/20 X-CSRF-Token: abc IF-Match: *</code></pre><P>&nbsp;</P><H2 id="toc-hId--1653761983"><STRONG>BusSolnOrdUserStatus – Header User Status</STRONG></H2><P>&nbsp;</P><P><STRONG>Create user status at header for an existing solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/&lt;&lt;SOLO_ID&gt;&gt;/_UserStatus X-CSRF-Token: abc { "BusinessSolutionOrder": "100004251", "UserStatus": "E0002" }</code></pre><P>&nbsp;</P><P><STRONG>Create user status at header using deep insert while creating a solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder X-CSRF-Token: abc { "BusSolnOrdType": "SOLO", "BusSolnOrdDescription": "Solution Order with User Status", "Language": "EN", "SoldToParty": "17100001", "SalesOrganization": "1710", "DistributionChannel": "10", "Division": "00", "RespEmployeeBusinessPartnerId": "9980000549", "PurchaseOrderByCustomer": "External Reference", "_UserStatus": [ { "UserStatus": "E0002" } ] }</code></pre><P>&nbsp;</P><H2 id="toc-hId--1850275488"><STRONG>BusSolnOrdItmUserStatus – Item User Status</STRONG></H2><P>Prerequisites: Make sure to assign the status profile to which the user status belongs to the respective item category of the solution order item. To do this, using SSCUI, define status profile for User Status and assign the status profile to item categories</P><P><STRONG>Create item user status at item for an existing solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100004251/10/_UserStatus X-CSRF-Token: abc { "UserStatus": "E0002" }</code></pre><P>&nbsp;</P><P><STRONG>Create item user status using deep insert while creating a solution order item</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100004251/_Item X-CSRF-Token: abc { "Product": "TG11", "Quantity": 1, "BusSolnOrdItmQtyUnitISOCode": "EA", "_UserStatus": [ { "UserStatus": "E0002" } ] }</code></pre><P>&nbsp;</P><H2 id="toc-hId--2046788993"><STRONG>BusinessSolutionOrderLongText – Header Long Text</STRONG></H2><P>&nbsp;</P><P><STRONG>Get all header text of a solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderLongText?$filter=BusinessSolutionOrder eq '100004251'</code></pre><P>&nbsp;</P><P><STRONG>Get a specific header text of a solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderLongText/100004251/0001/EN</code></pre><P><STRONG>&nbsp;</STRONG></P><P><STRONG>Update a header text of a solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>DELETE &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderLongText/100004251/0001/EN X-CSRF-Token: abc IF-Match: * { "BusinessSolutionOrderLongText":"Updated Header Text" }</code></pre><P><STRONG>&nbsp;</STRONG></P><P><STRONG>Delete a header text of a solution order</STRONG></P><pre class="lia-code-sample language-abap"><code>DELETE &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderLongText/100004251/0001/EN X-CSRF-Token: abc IF-Match: *</code></pre><P>&nbsp;</P><H2 id="toc-hId-2051664798"><STRONG>BusSolnOrdItmLongTxt – Item Long Text</STRONG></H2><P>&nbsp;</P><P><STRONG>Get item text of a solution order item 10</STRONG></P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmLongTxt?$filter=BusinessSolutionOrder eq '100004251'and BusinessSolutionOrderItem eq '10'</code></pre><P>&nbsp;</P><P><STRONG>Update item text of a solution order item 10</STRONG></P><pre class="lia-code-sample language-abap"><code>PATCH &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmLongTxt/100004251/10/001/EN X-CSRF-Token: abc IF-Match: * { "BusSolnOrdItmLongText": "Updated Item Text" }</code></pre><P>&nbsp;</P><P><STRONG>Delete item text of a solution order item 10</STRONG></P><pre class="lia-code-sample language-abap"><code>DELETE &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmLongTxt/100004251/10/001/EN X-CSRF-Token: abc IF-Match: *</code></pre><P>&nbsp;</P><H2 id="toc-hId-1855151293"><STRONG>BusSolnOrdItmBillgReqItem – Billing Request Item(of a Contract Item)</STRONG></H2><P>Only READ operation is supported on the BusSolnOrdItmBillgReqItem entity. This will be available only for service contract item with item category SOSC (Service Contract Item) and SOPA (Service Contract Price Adaptation)</P><P>&nbsp;</P><P><STRONG>Get all Billing Request Items of a solution order contract item</STRONG></P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmBillgReqItem?$filter=BusinessSolutionOrder eq '100004251'</code></pre><P>&nbsp;</P><P><STRONG>Get a specific billing request item of a solution order contract item by id</STRONG></P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmBillgReqItem/100004251/100/800001</code></pre><P>&nbsp;</P><H2 id="toc-hId-1658637788"><STRONG>BSOrdItmBillgReqItmPrcElm – Price element of Billing Request Item (Contract Item)</STRONG></H2><P>You can create a Price Element for a Billing request Item of a Contract item of a solution order using the _PriceElement association of the BusSolnOrdItmBillgReqItem entity.</P><P>&nbsp;</P><P><STRONG>Create a discount price element for a specific billing item a solution order service contract item</STRONG></P><pre class="lia-code-sample language-abap"><code>POST &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmBillgReqItem/100004251/100/800001/_PriceElement X-CSRF-Token: abc { "ConditionType": "DRV1", "ConditionRateValue": -10, "ConditionCurrency": "USD" }</code></pre><P>Above payload will create a price element (Fixed Discount DRV1) for billing item 800001 of the service contract item</P><P>&nbsp;</P><P><STRONG>Read all the price element for a billing request item of a solution order contract item</STRONG></P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmBillgReqItem/100004251/100/800001/_PriceElement</code></pre><P>&nbsp;</P><P><STRONG>Update a price element for a billing request item of a solution order contract item</STRONG></P><pre class="lia-code-sample language-abap"><code>PATCH &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BSOrdItmBillgReqItmPrcElm/100004251/100/800001/90/1 X-CSRF-Token: abc IF-Match: * { "ConditionType": "PSI1", "ConditionRateValue": 120 }</code></pre><P>&nbsp;</P><H2 id="toc-hId-1462124283"><STRONG>BusSolnOrdAppointment – Header Appointment</STRONG></H2><P>Appointment entities are used to persist various date fields in solution order.&nbsp;</P><P><SPAN>You define the Appointment type using the configuration activity&nbsp;</SPAN><STRONG><SPAN class="">Define Date Types, Duration Types and Date Rules for Service Transactions</SPAN></STRONG><SPAN>&nbsp;in your configuration environment. The system uses the duration, dates types, and date rules that are combined in a specific date profile to display dates in a transaction and to automatically determine them.&nbsp;</SPAN><SPAN>Make sure to assign the date profile to transaction types.&nbsp;</SPAN></P><P>&nbsp;</P><P><STRONG>Update BILL_DATE at solution order header using the Appointment Entity </STRONG></P><P>Billing Date is a single date field and does not have a start and end date, in such case in the payload, the SrvcDocApptStartDateTime needs to be passed.</P><pre class="lia-code-sample language-abap"><code>PATCH &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdAppointment/100004251/BILL_DATE X-CSRF-Token: abc IF-Match: * { "SrvcDocAppointmentType": "BILL_DATE", "SrvcDocApptStartDateTime": "2025-10-23T00:00:00Z", }</code></pre><P>&nbsp;</P><P><STRONG>Read BILL_DATE at solution order header using the Appointment Entity </STRONG></P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdAppointment/100004251/BILL_DATE</code></pre><H2 id="toc-hId-1265610778"><STRONG>BusSolnOrdItmAppointment – Item Appointment</STRONG></H2><P>To update subscription end date of a subscription item, use the ServiceContrItemEndDateTime field at the BusinessSolutionOrderItem entity instead of the CONTEND Appointment type.</P><P>&nbsp;</P><P><STRONG>Update Requested delivery date of a sales item of a solution order using the Appointment Entity </STRONG></P><pre class="lia-code-sample language-abap"><code>PATCH &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmAppointment/100004251/10/REQ_DLV_DATE X-CSRF-Token: abc IF-Match: * { "SrvcDocAppointmentType": "REQ_DLV_DATE", "SrvcDocApptStartDateTime": "2025-10-28T00:00:00Z" }</code></pre><P>&nbsp;</P><H2 id="toc-hId-1069097273"><STRONG>BusSolnOrdItmDuration – Item Duration</STRONG></H2><P>Various durations like subscription terms, contract duration, renewal terms, etc are stored as durations in the BusSolnOrdItmDuration entity which has an association with the BusinessSolutionOrderItem entity. The different duration types in solution order are persisted across the duration types specified in the below table.</P><P><SPAN>You define the Duration type using the configuration activity&nbsp;</SPAN><STRONG><SPAN class="">Define Date Types, Duration Types and Date Rules for Service Transactions</SPAN></STRONG><SPAN>&nbsp;in your configuration environment. The system uses the duration, dates types, and date rules that are combined in a specific date profile to display dates in a transaction and to automatically determine them.&nbsp;</SPAN><SPAN>Make sure to assign the date profile to transaction types.&nbsp;</SPAN></P><P>&nbsp;</P><P><STRONG>Update Contract Duration of a contract item of a solution order using the Duration Entity </STRONG></P><pre class="lia-code-sample language-abap"><code>PATCH &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusSolnOrdItmDuration/100004251/100/CONTDURA X-CSRF-Token: abc IF-Match: * { "SrvcDocDurationType": "CONTDURA", "SrvcDocDurationValue": 48, "SrvcDocDurationUnit": "Month" }</code></pre><P>&nbsp;</P><H2 id="toc-hId-872583768"><STRONG>BusSolnOrdFUPSalesOrder – Follow-up Sales Order</STRONG></H2><P>You can only read the follow up sales order and no other operations are supported on this entity. This will list all the follow-up sales order document for the solution order. Once a sales item is released, the follow up document gets created. This corresponds to the “Transaction History” section on the UI</P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100003541/_FUPSalesOrder</code></pre><P>&nbsp;</P><H2 id="toc-hId-844253954"><STRONG>BusSolnOrdFUPSrvcOrd – Follow-up Service Order</STRONG></H2><P>You can only read the follow up service order and no other operations are supported on this entity. This will list all the follow-up service order document for the solution order. Once a service item is released, the follow up document gets created. This corresponds to the “Transaction History” section on the UI</P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100003541/_FUPServiceOrder</code></pre><P>&nbsp;</P><H2 id="toc-hId-647740449"><STRONG>BusSolnOrdFUPSrvcContr – Follow-up Service Contract</STRONG></H2><P>You can only read the follow up service contract and no other operations are supported on this entity. This will list all the follow-up service contract document for the solution order. Once a service contract item is released, the follow up document gets created. This corresponds to the “Transaction History” section on the UI</P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100003541/_FUPServiceContr</code></pre><P>&nbsp;</P><H2 id="toc-hId-451226944"><STRONG>BusSolnOrdFUPSubscrpn – Follow-up Subscription</STRONG></H2><P>You can only read the follow up subscription and no other operations are supported on this entity. This will list all the follow-up subscription document for the solution order. Once a subscription item is released, the follow up document gets created. This corresponds to the “Transaction History” section on the UI</P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100003541/_FUPSubscrpn</code></pre><P>&nbsp;</P><P>&nbsp;</P><H2 id="toc-hId-254713439"><STRONG>BusSolnOrdFUPEntProject – Follow-up Enterprise Project</STRONG></H2><P>Only read operation is supported on this entity. This will list all the follow-up project document for the solution order. Once a project item is released, the follow up document gets created. This corresponds to the “Transaction History” section on the UI</P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrder/100003541/_FUPEntProject</code></pre><P>&nbsp;</P><H2 id="toc-hId-58199934"><STRONG>BusSolnOrdItmFUPSalesOrder - Follow-up Sales Order Item</STRONG></H2><P>Only read operation is supported on this entity. This will list all the follow-up sales order along with its corresponding item numbers. Once a sales item is released, the follow up document gets created.</P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100004251/10/_FUPSalesOrderItem</code></pre><P>&nbsp;</P><H2 id="toc-hId--138313571"><STRONG>BusSolnOrdItmFUPSrvcOrd – Follow-up Service Order Item</STRONG></H2><P>Only read operation is supported on this entity. This will list all the follow-up service order along with its corresponding item numbers. Once a sales item is released, the follow up document gets created.</P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100004251/20/_FUPServiceOrderItem</code></pre><P>&nbsp;</P><H2 id="toc-hId--334827076"><STRONG>BusSolnOrdItmFUPSrvcContr – Follow-up Service Contract Item</STRONG></H2><P>Only read operation is supported on this entity. This will list all the follow-up service contract along with its corresponding item numbers. Once a service contract item is released, the follow up document gets created.</P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100004251/30/_FUPServiceContrItem</code></pre><P>&nbsp;</P><H2 id="toc-hId--531340581"><STRONG>BusSolnOrdItmFUPSubscrpn – Follow-up Subscription Item</STRONG></H2><P>Only read operation is supported on this entity. This will list all the follow-up subscription. Once a subscription item is released, the follow up document gets created.</P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100004251/40/_FUPSubscrpnItem</code></pre><P>&nbsp;</P><H2 id="toc-hId--727854086"><STRONG>BusSolnOrdItmFUPEntProject - Follow-up Enterprise Project Item</STRONG></H2><P>Only read operation is supported on this entity. This will list all the follow-up project document for the solution order. Once a service contract item is released, the follow up document gets created.</P><pre class="lia-code-sample language-abap"><code>GET &lt;host&gt;/sap/opu/odata4/sap/api_businesssolutionorder/srvd_a2x/sap/businesssolutionorder/0001 /BusinessSolutionOrderItem/100004251/50/_FUPEntProjectItem</code></pre><P>&nbsp;</P> 2025-11-11T15:16:58.766000+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/how-to-connect-with-sap-s-4hana-odata-services-from-sap-apim/ba-p/14268027 How to connect with SAP S/4HANA OData Services from SAP APIM? 2025-11-13T17:45:49.137000+01:00 Sookriti_Mishra https://community.sap.com/t5/user/viewprofilepage/user-id/173946 <P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Sookriti_Mishra_2-1763103908104.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/340423iE851AD135CF15CAE/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Sookriti_Mishra_2-1763103908104.png" alt="Sookriti_Mishra_2-1763103908104.png" /></span></P><P>Assuming that you have enabled the API Management capability in Integration Suite, I will start with API Provider creation.</P><H3 id="toc-hId-1893846691">1. Create API Provider</H3><P>Connection</P><TABLE border="1" width="80%"><TBODY><TR><TD width="50%">Type</TD><TD width="50%"><SPAN>On Premise</SPAN></TD></TR><TR><TD>Host</TD><TD><SPAN>Virtual Host, as mentioned in Cloud Connector</SPAN></TD></TR><TR><TD>Port</TD><TD><SPAN>Virtual Port, as mentioned in Cloud Connector</SPAN></TD></TR><TR><TD>Location ID</TD><TD><SPAN>As mentioned in Cloud Connector</SPAN></TD></TR><TR><TD><SPAN>Authentication</SPAN></TD><TD><SPAN>NONE</SPAN></TD></TR><TR><TD><SPAN class="">Additional Properties:</SPAN></TD><TD><SPAN>sap-client: XXX</SPAN></TD></TR></TBODY></TABLE><P>Catalog Service Settings</P><TABLE border="1" width="80%"><TBODY><TR><TD width="50%"><SPAN>Path Prefix</SPAN></TD><TD width="50%"><SPAN>/sap/opu/odata</SPAN></TD></TR><TR><TD><SPAN class="">Service Collection URL</SPAN><SPAN><BR /></SPAN></TD><TD><DIV class=""><SPAN class=""><SPAN class="">/IWFND/CATALOGSERVICE;v=2/ServiceCollection</SPAN></SPAN></DIV></TD></TR><TR><TD><SPAN class="">Authentication type</SPAN><SPAN class=""><BR /></SPAN></TD><TD><DIV class=""><SPAN class=""><SPAN class=""><SPAN>BASIC</SPAN></SPAN></SPAN></DIV></TD></TR><TR><TD><SPAN class="">Username</SPAN></TD><TD><DIV class=""><EM><SPAN class=""><SPAN class="">SAP's User Name for communication</SPAN></SPAN></EM></DIV></TD></TR><TR><TD><SPAN class="">Password</SPAN></TD><TD><DIV class=""><SPAN class=""><SPAN class=""><SPAN>***</SPAN></SPAN></SPAN></DIV></TD></TR></TBODY></TABLE><P>Test connection:<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Sookriti_Mishra_0-1763043320161.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/340168i30F55D49B33F64C5/image-size/large?v=v2&amp;px=999" role="button" title="Sookriti_Mishra_0-1763043320161.png" alt="Sookriti_Mishra_0-1763043320161.png" /></span></P><H3 id="toc-hId-1697333186">2. Create API Proxy</H3><P>Select the API Provider, click on Discover to select the API which you wanted to use<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Sookriti_Mishra_1-1763043548225.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/340170iBCCFE224FB2180B0/image-size/large?v=v2&amp;px=999" role="button" title="Sookriti_Mishra_1-1763043548225.png" alt="Sookriti_Mishra_1-1763043548225.png" /></span></P><P>Select the API &amp; then click on Create.<BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Sookriti_Mishra_2-1763043754144.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/340176i26CC96AF73762D81/image-size/large?v=v2&amp;px=999" role="button" title="Sookriti_Mishra_2-1763043754144.png" alt="Sookriti_Mishra_2-1763043754144.png" /></span></P><H3 id="toc-hId-1500819681">3. Create Key Value Map to store the credentials to S/4HANA</H3><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Sookriti_Mishra_0-1763050329413.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/340240iF0E0E1D6ED361F24/image-size/large?v=v2&amp;px=999" role="button" title="Sookriti_Mishra_0-1763050329413.png" alt="Sookriti_Mishra_0-1763050329413.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId-1304306176">4. Add Policies</H3><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Sookriti_Mishra_0-1763046040766.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/340201iA871775B983A75FE/image-size/large?v=v2&amp;px=999" role="button" title="Sookriti_Mishra_0-1763046040766.png" alt="Sookriti_Mishra_0-1763046040766.png" /></span></P><P><STRONG>Verify API Key</STRONG> - To verify the key which you are going to pass while calling the API.<BR />Where do you get the API? - When you create the Product, and a Subscription, after creating a Subscription in the Developer Hub you will get a Key. That key is to be provided to the Consumer, and this Policy will verify the key sent by the consumer.</P><pre class="lia-code-sample language-markup"><code> &lt;!--Specify in the APIKey element where to look for the variable containing the api key--&gt; &lt;VerifyAPIKey async='true' continueOnError='false' enabled='true' xmlns='http://www.sap.com/apimgmt'&gt; &lt;APIKey ref='request.header.apikey '/&gt; &lt;/VerifyAPIKey&gt;</code></pre><P><STRONG>Key Value Map Operations&nbsp;</STRONG>- To fetch the credentials saved in the Key Value Mapping</P><pre class="lia-code-sample language-markup"><code>&lt;KeyValueMapOperations mapIdentifier="SAP_S4HANA_Credentials" async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt"&gt; &lt;Get assignTo="private.usernameFromKVM" index="1"&gt; &lt;Key&gt; &lt;Parameter&gt;Username&lt;/Parameter&gt; &lt;/Key&gt; &lt;/Get&gt; &lt;Get assignTo="private.passwordFromKVM" index="1"&gt; &lt;Key&gt; &lt;Parameter&gt;Password&lt;/Parameter&gt; &lt;/Key&gt; &lt;/Get&gt; &lt;Scope&gt;environment&lt;/Scope&gt; &lt;/KeyValueMapOperations&gt;</code></pre><P><STRONG>Basic Authentication&nbsp;</STRONG>- To pass the credentials fetched in the previous step.</P><pre class="lia-code-sample language-markup"><code>&lt;BasicAuthentication async='true' continueOnError='false' enabled='true' xmlns='http://www.sap.com/apimgmt'&gt; &lt;Operation&gt;Encode&lt;/Operation&gt; &lt;IgnoreUnresolvedVariables&gt;false&lt;/IgnoreUnresolvedVariables&gt; &lt;User ref='private.usernameFromKVM'&gt;&lt;/User&gt; &lt;Password ref='private.passwordFromKVM'&gt;&lt;/Password&gt; &lt;AssignTo&gt;request.header.Authorization&lt;/AssignTo&gt; &lt;/BasicAuthentication&gt;</code></pre><P><STRONG>Assign Message&nbsp;</STRONG>- So you get an error as, "<STRONG><SPAN>{"fault":{"faultstring":"Unsupported Encoding \"br\"","detail":{"errorcode":"protocol.http.UnsupportedEncoding"}}}</SPAN></STRONG><SPAN>".&nbsp;<BR /><SPAN><A href="https://community.sap.com/t5/technology-q-a/unsupported-encoding-quot-br-getting-error-message-in-api-service-neo-in/qaq-p/12276410" target="_self">BR is a data format Brotli which is often defined by backend for webpage loading and not accepted by default</A>. And this Assign Message will help your message reach the target.</SPAN></SPAN></P><pre class="lia-code-sample language-markup"><code>&lt;!-- This policy can be used to create or modify the standard HTTP request and response messages --&gt; &lt;AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'&gt; &lt;!-- Sets a new value to the existing parameter --&gt; &lt;Set&gt; &lt;Headers&gt; &lt;Header name="Accept-Encoding"&gt;gzip,deflate&lt;/Header&gt; &lt;/Headers&gt; &lt;/Set&gt; &lt;IgnoreUnresolvedVariables&gt;false&lt;/IgnoreUnresolvedVariables&gt; &lt;AssignTo createNew="false" type="request"&gt;&lt;/AssignTo&gt; &lt;/AssignMessage&gt;</code></pre><H3 id="toc-hId-1107792671">5. Create Product &amp; Add the API</H3><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Sookriti_Mishra_1-1763051389193.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/340242i8CB1F77782E08185/image-size/large?v=v2&amp;px=999" role="button" title="Sookriti_Mishra_1-1763051389193.png" alt="Sookriti_Mishra_1-1763051389193.png" /></span></P><H3 id="toc-hId-911279166">6. Create a Subscription for the Product created</H3><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Sookriti_Mishra_2-1763051447796.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/340243i431E2D706E2273AD/image-size/large?v=v2&amp;px=999" role="button" title="Sookriti_Mishra_2-1763051447796.png" alt="Sookriti_Mishra_2-1763051447796.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Sookriti_Mishra_3-1763051502613.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/340244i99B391BA560F887D/image-size/large?v=v2&amp;px=999" role="button" title="Sookriti_Mishra_3-1763051502613.png" alt="Sookriti_Mishra_3-1763051502613.png" /></span></P><H3 id="toc-hId-714765661">7. It's time to test!</H3><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="APIM2.jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/340251i6B79ABA5218B4519/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="APIM2.jpg" alt="APIM2.jpg" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Sookriti_Mishra_1-1763051977603.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/340252i82F3F82B3984FF95/image-size/large?v=v2&amp;px=999" role="button" title="Sookriti_Mishra_1-1763051977603.png" alt="Sookriti_Mishra_1-1763051977603.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Sookriti_Mishra_2-1763052043480.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/340253i4F97CEE80ADDC522/image-size/large?v=v2&amp;px=999" role="button" title="Sookriti_Mishra_2-1763052043480.png" alt="Sookriti_Mishra_2-1763052043480.png" /></span></P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P> 2025-11-13T17:45:49.137000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/use-sap-fiori-development-portal-to-understand-extension-options-for/ba-p/14270914 Use SAP Fiori Development Portal to Understand Extension Options for Standard Floorplans (4 of 6) 2025-11-17T12:15:41.843000+01:00 marcel_waechter https://community.sap.com/t5/user/viewprofilepage/user-id/302397 <P>In our previous posts, we explored individual building blocks and their sophisticated capabilities. Now it's time to see how these building blocks come together in predefined layouts called standard floorplans delivered by SAP Fiori elements for OData V4. The SAP Fiori development portal not only showcases these proven layouts but also reveals the rich set of extension options available to customize them for your specific business needs. Let's explore how you can leverage standard floorplans while maintaining the flexibility to extend when necessary.</P><H2 id="toc-hId-1765457780">Understanding Standard Floorplans</H2><P>Standard floorplans are predefined layouts of building blocks provided to enable efficient SAP Fiori elements application development. These floorplans inherit all the qualities of their building blocks while adding optimizations for component interaction at the floorplan level. Think of them as proven blueprints that combine the building blocks we explored in previous posts into coherent, user-friendly experiences.<BR /><BR />In the portal's section for <A href="https://sapui5.hana.ondemand.com/test-resources/sap/fe/core/fpmExplorer/index.html#/topic/floorplans" target="_self" rel="nofollow noopener noreferrer">Standard Floorplans</A> we demonstrate why this is the most efficient approach for building your SAP Fiori elements application. These layouts represent years of UX research, customer feedback, and real-world usage patterns. When your requirements align closely with a standard floorplan, you get enterprise ready functionality with minimal development effort.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="The list report – object page layouts are the most common floorplans in SAP Fiori elements" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/341881iD47B53BBA9F416FC/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="marcel_waechter_5-1763376268405.png" alt="The list report – object page layouts are the most common floorplans in SAP Fiori elements" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">The list report – object page layouts are the most common floorplans in SAP Fiori elements</span></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="marcel_waechter_7-1763376349704.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/341883iF5C8BDEDA6F322A8/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="marcel_waechter_7-1763376349704.png" alt="marcel_waechter_7-1763376349704.png" /></span></P><H2 id="toc-hId-1568944275">Exploring Floorplans in the Portal</H2><P>The portal showcases different types of standard floorplans, each optimized for specific use cases:</P><UL><LI>List Report Page - The classic combination of filter bar and table for comprehensive data exploration and management<UL><LI>Worklist - A streamlined version focusing purely on the table when filtering isn't the primary concern</LI><LI>Analytical List Page – An enhanced version with visual filters and charts for data analysis and insights</LI></UL></LI><LI>Overview Page - Visual card-based interface for quick access to vital business information and immediate action</LI><LI>Object Page - Comprehensive detail views with headers, forms, tables, charts, and draft-enabled editing capabilities for seamless document management</LI></UL><P>What's important to understand is that all these floorplans make use of the same building blocks we explored in our previous posts – like the table, chart, field, and filter bar components. The difference lies in how these building blocks are orchestrated and optimized to work together at the page level.</P><H2 id="toc-hId-1372430770">Extensions: When Standard Isn't Enough</H2><P>Every standard floorplan provides extension points, and the portal's Extensions chapter is where you discover how to customize these proven layouts for your unique requirements. Let's look at a practical example that demonstrates both the power and philosophy of the extensibility that SAP Fiori elements for OData V4 offers.</P><P>In the <A href="https://sapui5.hana.ondemand.com/test-resources/sap/fe/core/fpmExplorer/index.html#/topic/floorplanObjectPage/customSection" target="_self" rel="nofollow noopener noreferrer">Custom Section</A> example, you'll see how to add a custom FlightMap section to an Object Page. This FlightMap control from SAPUI5 isn't natively supported by SAP Fiori elements, yet it integrates seamlessly into the standard floorplan structure.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Custom Section in Object Page" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/341870i82A4131B03C1124E/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="marcel_waechter_0-1763375914063.png" alt="Custom Section in Object Page" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Custom Section in Object Page</span></span></P><P>This example beautifully illustrates a key principle: your SAP Fiori elements application is never locked in. When you need functionality that goes beyond standard building blocks, you can extend the framework while retaining all the enterprise-grade features of the underlying floorplan.</P><P>However - and this is crucial - whenever functionality can be implemented using native SAP Fiori elements support (like adding a table or chart through annotations), it should be implemented that way. The closer your application stays to standard SAP Fiori elements patterns, the better your UI consistency, and the less development and maintenance effort you'll require over time.</P><H2 id="toc-hId-1175917265">Global Patterns: The Invisible Foundation</H2><P>Don't overlook the Global Patterns chapter in the portal. These non-visual building blocks provide the enterprise-grade foundation that makes SAP Fiori applications truly business-ready, like:</P><UL><LI>Draft Handling - Seamless save and restore functionality</LI><LI>Routing and Navigation - Consistent navigation patterns across your application</LI><LI>Side Effects - Automatic field updates triggered by user interactions, maintaining data consistency across the UI</LI></UL><P>These global patterns are automatically used by standard floorplans, providing the robust foundation that users expect from SAP applications. Like their visual counterparts, they support extensions when your business logic requires custom behavior.</P><H2 id="toc-hId-979403760">TypeScript Support: Modern Development Made Easy</H2><P>The portal provides the code examples in TypeScript, reflecting the modern development practices we recommend for SAP Fiori elements applications. Take the <A href="https://sapui5.hana.ondemand.com/test-resources/sap/fe/core/fpmExplorer/index.html#/controllerExtensions/editFlow" target="_self" rel="nofollow noopener noreferrer">Draft Handling</A> page as an example. When you click "Show Code" next to "Implementing a Hook," you'll see TypeScript implementations that leverage our new BaseControllerExtension types.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Type Script Example in Fiori Development Portal" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/341871i51C42EFE538C5CEC/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="marcel_waechter_1-1763375968162.png" alt="Type Script Example in Fiori Development Portal" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Type Script Example in Fiori Development Portal</span></span></P><P>These new types make it significantly easier to implement hooks in TypeScript, providing better IntelliSense, type safety, and development experience. The portal even includes live transpiling in the browser, so you can see the immediate effects of your code changes. Try this yourself by changing the line:</P><pre class="lia-code-sample language-javascript"><code>return this.openDialog("Do you want to edit this travel request?", true);</code></pre><P>to:</P><pre class="lia-code-sample language-javascript"><code>return this.openDialog("Do you really want to edit this travel request?", true);</code></pre><P>Click the Edit button in the sample preview, and you'll see your modified dialog text appear immediately.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Updated Sample" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/341876iC541AFF11ABB24DA/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="marcel_waechter_2-1763376073370.png" alt="Updated Sample" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Updated Sample</span></span></P><P>This interactive learning approach helps you understand not just what's possible, but how your changes affect the user experience in real-time.</P><H2 id="toc-hId-782890255">Conclusion</H2><P>The SAP Fiori development portal proves to be an invaluable resource for exploring standard floorplans and understanding their extension capabilities. Whether you're building a straightforward List Report or a complex Object Page with custom sections, the portal guides you through the possibilities while helping you make informed decisions about when to use standard functionality versus custom extensions. The beauty of SAP Fiori elements lies in this balance: start with proven, enterprise-ready standard floorplans, then extend precisely where your business requirements demand it. The portal ensures you understand both the power of the standards and the flexibility of the extensions, enabling you to build applications that are both efficient to develop and maintain.</P><H2 id="toc-hId-586376750">What's Next</H2><P>In our next post, "Prepare building custom pages by using SAP Fiori development portal (5 of 6)," we'll explore how to move beyond standard floorplans entirely. We'll show you how the portal guides you through creating completely custom page layouts using the same building blocks, giving you maximum creative freedom while retaining all the enterprise-grade features that make SAP Fiori elements applications so powerful.</P><P>To get the full overview about the SAP Fiori development portal, check out the following blog posts of the mini-series:</P><UL class=""><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/introducing-the-sap-fiori-development-portal-your-gateway-to-rapid-sap/ba-p/14236768" target="_blank">Introducing the SAP Fiori Development Portal: Your Gateway to Rapid SAP Fiori App Creation (1 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/get-familiar-with-sap-fiori-development-portal-and-the-power-of-the/ba-p/14240041" target="_self">Get familiar with SAP Fiori development portal and the power of the building blocks (2 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/explore-the-potential-of-sap-fiori-development-portal-using-complex/ba-p/14257622" target="_self">Explore the potential of SAP Fiori development portal using complex building blocks (3 of 6)</A></LI><LI>Use SAP Fiori development portal to understand extension options for standard floorplans (4 of 6)</LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/prepare-building-custom-pages-by-using-sap-fiori-development-portal-5-of-6/ba-p/14277842" target="_self">Prepare building custom pages by using SAP Fiori development portal (5 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/bringing-the-sap-fiori-development-portal-and-its-use-to-the-next-level-6/ba-p/14285025" target="_self">Bringing the SAP Fiori development portal and its use to the next level (6 of 6)</A></LI></UL> 2025-11-17T12:15:41.843000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/handling-filter-search-and-orderby-in-sap-cap-when-consuming-external-rest/ba-p/14276281 Handling $filter,$search and $orderby in SAP CAP when consuming External REST APIs 2025-11-25T05:57:09.692000+01:00 prajnaparmita https://community.sap.com/t5/user/viewprofilepage/user-id/589135 <P><STRONG>Introduction</STRONG></P><P>When building applications with the <STRONG>SAP Cloud Application Programming Model (CAP)</STRONG>, a very common real-world scenario is:</P><UL><LI>Your CAP service acts as a proxy</LI><LI>Data is fetched from an external REST API</LI><LI>The external API does not&nbsp;support OData</LI></UL><P>But&nbsp;your Fiori/UI5 frontend still sends OData queries like:&nbsp;</P><pre class="lia-code-sample language-abap"><code>$filter=country eq 'IN'&amp;$search=Bangalore&amp;$orderby=name desc</code></pre><P>This blog explains how to handle <STRONG>OData query options</STRONG> like $filter, $search, and $orderby in <STRONG>SAP CAP Node.js</STRONG> when your service consumes a <STRONG>non-OData external REST API</STRONG>.</P><P>Here is a lightweight JavaScript utility (handleOData.js) that:</P><UL><LI>Interprets CAP’s query structure (req.query.SELECT)</LI><LI>Applies filtering logic directly on API responses</LI><LI>Adds full-text search capability</LI><LI>Supports dynamic sorting based on $orderby</LI></UL><P>With this approach, your Fiori/UI applications can continue using rich OData queries without any dependency on the external API.</P><P>This solution is ideal for building <STRONG>CAP-based proxy services</STRONG> on SAP BTP that integrate with legacy or third-party REST systems.</P><P><STRONG>Problem Statement :&nbsp;</STRONG></P><P>Consider this scenario:&nbsp;Your frontend sends</P><pre class="lia-code-sample language-abap"><code>GET /odata/v4/srv/DemandAreas?$filter=country eq 'IN'&amp;$orderby=name asc</code></pre><P>But your backend actually calls ,&nbsp; &nbsp;</P><pre class="lia-code-sample language-abap"><code>GET https://external.api/demandAreas</code></pre><P>The external API:</P><UL><LI>Does not support $filter</LI><LI>Does not support $search</LI><LI>Does not support $orderby</LI></UL><P>Yet you still want your frontend to fully leverage OData features.</P><P>So how do we bridge this gap?</P><P><STRONG>Architecture Overview:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Architecture.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/344663i95131553C4F7EA6A/image-size/medium?v=v2&amp;px=400" role="button" title="Architecture.png" alt="Architecture.png" /></span></P><P><STRONG>Solution Overview:&nbsp;</STRONG></P><P>Utility file , handleOData.js exposes three main functions:</P><pre class="lia-code-sample language-javascript"><code>module.exports = { handleFilter, handleSearch, handleSort }</code></pre><P>Each function handles a specific OData concept.</P><P><STRONG>1. Handling $filter</STRONG></P><P>CAP provides filters in a structured format (req.query.SELECT.where).</P><P>This utility interprets this structure and evaluates it against each result record.</P><P>Core logic idea:</P><pre class="lia-code-sample language-javascript"><code>function handleFilter(filters, item) { const stack = []; const applyComparison = (field, op, value) =&gt; { const fieldValue = item[field]; switch (op) { case '=': return fieldValue == value; case '!=': return fieldValue != value; case '&gt;': return fieldValue &gt; value; case '&gt;=': return fieldValue &gt;= value; case '&lt;': return fieldValue &lt; value; case '&lt;=': return fieldValue &lt;= value; default: return false; } }; // Logic continues to resolve AND / OR conditions}</code></pre><P>This supports:</P><UL><LI>eq, ne, gt, ge, lt, le</LI><LI>Logical operations: AND, OR</LI><LI>Nested conditions</LI></UL><P><STRONG>2. Handling $search</STRONG></P><P>CAP exposes the search phrase via req.query.SELECT.search. The utility applies search across properties of each record.</P><P>Simplified logic:</P><pre class="lia-code-sample language-javascript"><code>function handleSearch(searchTerm, data) { return data.filter(item =&gt; Object.values(item).some(val =&gt; String(val).toLowerCase().includes(searchTerm.toLowerCase()) ) ); }</code></pre><P>This allows our Fiori/UI app to use for example , $search=Bangalore</P><P>Even if the external API has no search support at all.</P><P><STRONG>3. Handling $orderby</STRONG></P><P>Ordering is handled using CAP’s orderBy structure.</P><P>Logic overview:</P><pre class="lia-code-sample language-javascript"><code>function handleSort(req, result) { const [orderClause] = req.query.SELECT.orderBy; const field = orderClause.ref[0]; const dir = orderClause.sort === 'desc' ? -1 : 1; return [...result].sort((a, b) =&gt; a[field] &gt; b[field] ? 1 * dir : -1 * dir ); }</code></pre><P>Supported:</P><UL><LI>$orderby=name asc</LI><LI>$orderby=createdAt desc</LI></UL><P><STRONG>CAP Service Integration Example</STRONG></P><P>Below is how you can plug this into your service implementation file:</P><pre class="lia-code-sample language-javascript"><code>const { handleFilter, handleSearch, handleSort } = require('./code/handleOData'); module.exports = (srv) =&gt; { srv.on('READ', 'DemandAreas', async (req) =&gt; { // 1. Call external REST APIlet data = await fetchExternalData(); // 2. Apply $filterif (req.query.SELECT.where) { data = data.filter(item =&gt; handleFilter(req.query.SELECT.where, item)); } // 3. Apply $searchif (req.query.SELECT.search) { data = handleSearch(req.query.SELECT.search, data); } // 4. Apply $orderbyif (req.query.SELECT.orderBy) { data = handleSort(req, data); } return data; }); };</code></pre><P><STRONG>Benefits of this Approach</STRONG></P><UL><LI>Clean separation between CAP and external REST API</LI><LI>Full OData filtering support for Fiori/UI apps</LI><LI>No dependency on the external service supporting OData</LI><LI>Plug-and-play in any Node.js CAP project</LI><LI>Easy to extend with more operators</LI></UL><P><STRONG>Conclusion:</STRONG></P><P>This utility helps bridge the gap between <STRONG>OData-driven applications</STRONG> and <STRONG>non-OData REST services</STRONG>, while keeping our CAP service clean and the UI fully functional. If you’re building similar integrations, I hope this helps accelerate your work.</P> 2025-11-25T05:57:09.692000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/prepare-building-custom-pages-by-using-sap-fiori-development-portal-5-of-6/ba-p/14277842 Prepare building custom pages by using SAP Fiori development portal (5 of 6) 2025-11-26T10:03:47.891000+01:00 marcel_waechter https://community.sap.com/t5/user/viewprofilepage/user-id/302397 <P>In our previous posts,&nbsp;we explored individual building blocks,&nbsp;their sophisticated capabilities,&nbsp;and how they come together in standard floorplans.&nbsp;We also learned how to extend these standard floorplans when needed.&nbsp;But what happens when your business requirements demand a layout that doesn't match any standard floorplan?&nbsp;The SAP Fiori development portal has you covered.&nbsp;In this post,&nbsp;we'll show you how to build a completely custom page layout while leveraging SAP Fiori elements building blocks to maintain enterprise-grade functionality.</P><H2 id="toc-hId-1765665447">When to Choose Custom Pages</H2><P>Before we dive into creating custom pages,&nbsp;let's be clear about the decision path.&nbsp;If your UI requirements fit one of the existing <A href="https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/topic/floorplans" target="_blank" rel="noopener noreferrer">standard floorplans</A>&nbsp;(List Report,&nbsp;Object Page,&nbsp;Analytical List Page,&nbsp;Overview Page,&nbsp;or Worklist),&nbsp;you should absolutely use them.&nbsp;Standard floorplans offer:</P><UL><LI>Reduced development and maintenance costs</LI><LI>Automatic UI consistency across your application landscape</LI><LI>Built-in enterprise features that would take months to develop from scratch</LI><LI>Future-proof compatibility with SAP Fiori elements updates</LI></UL><P>However,&nbsp;when you need a special layout&nbsp;-&nbsp;like a wizard,&nbsp;shopping cart,&nbsp;or any non-standard UI pattern&nbsp;-&nbsp;you're not blocked.&nbsp;You can implement your custom layout while using as many SAP Fiori elements building blocks as possible to retain the benefits of the framework.</P><H2 id="toc-hId-1569151942">Exploring Custom Pages in the Portal</H2><P>The SAP Fiori development portal's&nbsp;<A href="https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/topic/customPage" target="_blank" rel="noopener noreferrer">Custom Page</A> <SPAN>&nbsp;chapter provides comprehensive guidance for building custom layouts.&nbsp;</SPAN>Let's explore its key sections:</P><UL><LI><STRONG>Overview</STRONG>&nbsp;-&nbsp;Shows a simple custom page demonstrating how building blocks integrate into custom layouts</LI><LI><STRONG>Building Blocks Usage</STRONG>&nbsp;-&nbsp;Explains how to use SAP Fiori elements building blocks in existing UI5 freestyle applications,&nbsp;bridging the gap between traditional UI5 development and the SAP Fiori elements approach</LI><LI><STRONG>Custom Root View</STRONG>&nbsp;-&nbsp;Demonstrates how to create and register custom root views when the standard options&nbsp;(FullScreen and Flexible Column Layout)&nbsp;don't meet your needs</LI><LI><STRONG>Draft Handling</STRONG>&nbsp;-&nbsp;Shows how to leverage the Draft controller extension in your custom pages for seamless draft management</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Fiori Development Portal: Custom page sample" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/345265i3868261C9F29960C/image-size/medium?v=v2&amp;px=400" role="button" title="marcel_waechter_0-1764143518983.png" alt="Fiori Development Portal: Custom page sample" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Fiori Development Portal: Custom page sample</span></span></P><P>These sections provide the foundation for understanding custom page development.&nbsp;Now let's put this knowledge into practice with a real-world example.</P><H2 id="toc-hId-1372638437">Building a Wizard:&nbsp;A Step-by-Step Journey</H2><P>Let's create a wizard for travel request creation&nbsp;-&nbsp;a floorplan currently not available as a standard in SAP Fiori elements.&nbsp;We'll build this step by step,&nbsp;just as you would when developing your own custom page.&nbsp;The beauty of the portal is that you can experiment with code changes&nbsp;-&nbsp;auto-run is enabled by default,&nbsp;automatically refreshing the preview when you make simple changes.&nbsp;For more complex modifications,&nbsp;you can disable auto-run and manually click the&nbsp;"Run"&nbsp;button to update the sample when you're ready.</P><H3 id="toc-hId-1305207651">Step 1: Setting Up the Wizard Structure</H3><P>Navigate to the <A href="https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/topic/customPage" target="_blank" rel="noopener noreferrer">Custom Pages Overview</A> section in the portal.&nbsp;Click&nbsp;"Show Code"&nbsp;to open the code editor.&nbsp;We'll transform this simple page into a wizard.</P><P>First,&nbsp;let's add the wizard structure without any content in the steps.&nbsp;Replace the content of the CustomPageSample view with:</P><pre class="lia-code-sample language-markup"><code>&lt;mvc:View id="application-product" height="100%" controllerName="sap.fe.core.fpmExplorer.customPage.CustomPageSample" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" xmlns:macros="sap.fe.macros" &gt; &lt;macros:Page title="Create New Travel Request" class="sapUiContentPadding"&gt; &lt;Wizard id="travelWizard" enableBranching="false" class="sapUiResponsivePadding--header sapUiResponsivePadding--content" &gt; &lt;WizardStep id="travelDataStep" title="Travel Information" validated="true" &gt; &lt;!-- We'll add content here --&gt; &lt;/WizardStep&gt; &lt;WizardStep id="approvalDataStep" title="Budget and Approval" validated="true" &gt; &lt;!-- We'll add content here --&gt; &lt;/WizardStep&gt; &lt;WizardStep id="bookingsStep" title="Bookings" validated="true" &gt; &lt;!-- We'll add content here --&gt; &lt;/WizardStep&gt; &lt;WizardStep id="reviewStep" title="Submit Travel Request" validated="true" &gt; &lt;!-- We'll add content here --&gt; &lt;/WizardStep&gt; &lt;/Wizard&gt; &lt;/macros:Page&gt; &lt;/mvc:View&gt;</code></pre><P>Now update the controller to support the wizard functionality.&nbsp;In the controller code editor,&nbsp;replace the CustomPageSample controller with:</P><pre class="lia-code-sample language-javascript"><code>import PageController from "sap/fe/core/PageController"; import MessageBox from "sap/m/MessageBox"; import type Context from "sap/ui/model/odata/v4/Context"; /** * Controller for the custom travel request wizard page. */ export default class CustomPageSampleController extends PageController { /** * Creates a new travel request draft context and binds it to the view before rendering. */ public onBeforeRendering(): void { const view = this.getView(); try { const model = view.getModel(); // Create list binding and create a draft context const listBinding = model.bindList("/Travel"); const wizardContext = listBinding.create({ CurrencyCode_code: "EUR", BookingFee: 0, TotalPrice: 0, TravelStatus_code: "O" }); // Bind the view to the created context view.setBindingContext(wizardContext); // Set the UI model property to make the forms and table editable view.getModel("ui").setProperty("/isEditable", true); } catch (error) { MessageBox.error("Failed to create travel request: " + (error as Error).message); } } /** * Handler called when the submit button is pressed. */ public async onSubmitTravelRequest(): Promise&lt;void&gt; { // Navigate to the Object Page const routing = this.getExtensionAPI().getRouting(); routing.navigate(this.getView().getBindingContext() as Context); } }</code></pre><P>You now have a working wizard structure with four steps!&nbsp;Before rendering the view,&nbsp;the controller's&nbsp;onBeforeRendering()&nbsp;method creates a new draft travel request and binds it to the view,&nbsp;so all our building blocks automatically work with this draft data.&nbsp;The&nbsp;onSubmitTravelRequest()&nbsp;method will be used later to finalize the wizard.&nbsp;For now,&nbsp;notice how the wizard steps are empty but navigable.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Preview wizard without step content" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/345266i9C19FC023C8054E9/image-size/medium?v=v2&amp;px=400" role="button" title="marcel_waechter_1-1764143518984.png" alt="Preview wizard without step content" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Preview wizard without step content</span></span></P><H2 id="toc-hId-979611427">Step 2: Adding the First Form</H2><P>Now let's add content to our first wizard step.&nbsp;This is where the portal becomes invaluable.&nbsp;You can either navigate to the <A href="https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/buildingBlocks/form/formDefault" target="_blank" rel="noopener noreferrer">Form Building Block</A> in the same tab&nbsp;(the portal keeps your changes in memory as long as you don't refresh the browser),&nbsp;or better yet,&nbsp;open the portal in a second browser tab so you can reference the Form documentation while working on your wizard.</P><P>Open the Form page in the portal.&nbsp;You'll see it demonstrates the&nbsp;UI.FieldGroup#ApprovalData&nbsp;annotation.&nbsp;But we want to use a different field group for our first step.&nbsp;To see what's available,&nbsp;click&nbsp;"Show Code"&nbsp;next to the annotations example and look at the&nbsp;annotations.cds&nbsp;file in the code editor.&nbsp;You'll find several field groups,&nbsp;including&nbsp;TravelData,&nbsp;which is perfect for our first step.</P><P>Back in your wizard code,&nbsp;update the first&nbsp;WizardStep&nbsp;to include the form:</P><pre class="lia-code-sample language-markup"><code>&lt;WizardStep id="travelDataStep" title="Travel Information" validated="true" &gt; &lt;MessageStrip text="Please provide the basic information about your travel request." type="Information" class="sapUiSmallMarginBottom" /&gt; &lt;macros:Form id="travelDataForm" metaPath="@UI.FieldGroup#TravelData" /&gt; &lt;/WizardStep&gt;</code></pre><P>Run the sample and navigate to the first step.&nbsp;You'll see the form with the travel data fields.&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Preview of first wizard step" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/345264i667C6ECE39B8819B/image-size/medium?v=v2&amp;px=400" role="button" title="marcel_waechter_2-1764143518985.png" alt="Preview of first wizard step" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Preview of first wizard step</span></span></P><P>Notice that the&nbsp;TravelID&nbsp;field appears as the first field.&nbsp;However,&nbsp;since travel IDs are calculated in the backend,&nbsp;it doesn't make sense to show this field here.</P><P>Let's remove it from the field group.&nbsp;Go back to the&nbsp;annotations.cds&nbsp;code editor and locate the&nbsp;TravelData&nbsp;field group.&nbsp;Remove the&nbsp;TravelID&nbsp;field:</P><pre class="lia-code-sample language-abap"><code>FieldGroup #TravelData : { { Value : BeginDate }, { Value : EndDate }, { Value : AgencyID }, { Value : CustomerID } }</code></pre><P>Click the&nbsp;"Run"&nbsp;button to refresh the preview with your changes&nbsp;-&nbsp;the&nbsp;TravelID&nbsp;field disappears!&nbsp;This demonstrates the power of annotation-driven UIs:&nbsp;simple metadata changes directly affect the user interface without touching the view code.</P><P><EM><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Preview without travel ID" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/345306iB37CEFACBEAF8EAE/image-size/medium?v=v2&amp;px=400" role="button" title="marcel_waechter_0-1764147451097.png" alt="Preview without travel ID" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Preview without travel ID</span></span></EM></P><H2 id="toc-hId-783097922">Step 3: Adding the Budget &amp; Approval Form</H2><P>Now let's add the second form.&nbsp;Update the second&nbsp;WizardStep:</P><pre class="lia-code-sample language-markup"><code>&lt;WizardStep id="approvalDataStep" title="Budget and Approval" validated="true" &gt; &lt;MessageStrip text="Provide budget information for approval." type="Information" class="sapUiSmallMarginBottom" /&gt; &lt;macros:Form id="approvalDataForm" metaPath="@UI.FieldGroup#ApprovalData" /&gt; &lt;/WizardStep&gt;</code></pre><P>This step uses the&nbsp;ApprovalData&nbsp;field group,&nbsp;which contains financial information like booking fee and total price.&nbsp;The same building block,&nbsp;configured differently through the&nbsp;metaPath&nbsp;property,&nbsp;delivers completely different content.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Preview second wizard step" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/345268i05F6F6EE590A547B/image-size/medium?v=v2&amp;px=400" role="button" title="marcel_waechter_4-1764143518987.png" alt="Preview second wizard step" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Preview second wizard step</span></span></P><H2 id="toc-hId-586584417">Step 4: Adding the Bookings Table</H2><P>The third step needs a table for managing flight bookings.&nbsp;Navigate to the <A href="https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/buildingBlocks/table/tableDefault" target="_blank" rel="noopener noreferrer">Table Building Blocks</A>&nbsp;in the portal.&nbsp;Study how the table building block works,&nbsp;paying special attention to the&nbsp;metaPath&nbsp;property.</P><P>For our wizard,&nbsp;we want to display bookings that are associated with the travel request.&nbsp;Since our view is bound to a Travel context,&nbsp;we need to set the&nbsp;metaPath&nbsp;to the bookings navigation.&nbsp;Update the third&nbsp;WizardStep:<BR />&nbsp;</P><pre class="lia-code-sample language-markup"><code>&lt;WizardStep id="bookingsStep" title="Bookings" validated="true" &gt; &lt;VBox&gt; &lt;MessageStrip text="Add flight bookings for your travel. You can add multiple bookings." type="Information" class="sapUiSmallMarginBottom" /&gt; &lt;macros:Table id="bookingsTable" metaPath="/Travel/to_Booking/@UI.LineItem" personalization="Sort,Column" header="Flight Bookings" creationMode="NewPage" /&gt; &lt;/VBox&gt; &lt;/WizardStep&gt;</code></pre><P>Run the sample and navigate to the Bookings step.&nbsp;Click the&nbsp;"Create"&nbsp;button in the table toolbar.&nbsp;You can now create bookings!&nbsp;The table building block automatically provides creation,&nbsp;editing,&nbsp;and deletion capabilities based on the entity's capabilities defined in the service metadata.&nbsp;This is enterprise-grade functionality delivered through a single building block with minimal configuration.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Preview third wizard step" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/345269iF504D90B273DCFF0/image-size/medium?v=v2&amp;px=400" role="button" title="marcel_waechter_5-1764143518989.png" alt="Preview third wizard step" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Preview third wizard step</span></span></P><H2 id="toc-hId-390070912">Step 5: Submitting the Travel Request</H2><P>The final step allows users to review and submit their travel request.&nbsp;Update the fourth&nbsp;WizardStep:</P><pre class="lia-code-sample language-markup"><code>&lt;WizardStep id="reviewStep" title="Submit Travel Request" validated="true" &gt; &lt;VBox class="sapUiContentPadding"&gt; &lt;Text text="You have successfully completed all steps. Your travel request is ready to be submitted." class="sapUiMediumMarginBottom" /&gt; &lt;HBox justifyContent="End" class="sapUiMediumMarginTop"&gt; &lt;Button text="Submit" type="Emphasized" press="onSubmitTravelRequest" icon="sap-icon://paper-plane" /&gt; &lt;/HBox&gt; &lt;/VBox&gt; &lt;/WizardStep&gt;</code></pre><P>&nbsp;Notice that we're not saving the draft directly using the EditFlow controller extension.&nbsp;Instead,&nbsp;when users click&nbsp;"Submit",&nbsp;the&nbsp;onSubmitTravelRequest&nbsp;method in our controller uses the routing API to navigate to the travel request's Object Page:</P><pre class="lia-code-sample language-javascript"><code>public async onSubmitTravelRequest(): Promise&lt;void&gt; { // Navigate to the Object Page const routing = this.getExtensionAPI().getRouting(); routing.navigate(this.getView().getBindingContext() as Context); }</code></pre><P>With this approach, users can review their complete travel request in the standard Object Page layout,&nbsp;make any final changes,&nbsp;and then save it using the familiar Object Page header actions.&nbsp;This demonstrates an important principle:&nbsp;you can mix custom pages with standard floorplans in the same application,&nbsp;using each where it fits best.</P><H2 id="toc-hId-193557407">The Power of Building Blocks in Custom Pages</H2><P>What we've built demonstrates the core value proposition of SAP Fiori elements building blocks in custom pages:</P><UL><LI><STRONG>Rapid Development</STRONG>&nbsp;- We created a sophisticated multi-step wizard with forms, tables, and draft handling in minutes, not days</LI><LI><STRONG>Enterprise Features</STRONG>&nbsp;- Each building block brings personalization, validation, error handling, and accessibility automatically</LI><LI><STRONG>Annotation-Driven</STRONG>&nbsp;- Business logic changes (like removing the TravelID field) require only metadata updates, not code changes</LI><LI><STRONG>Consistency</STRONG>&nbsp;- The forms and table in our wizard look and behave exactly like those in standard floorplans, ensuring UI consistency</LI><LI><STRONG>Flexibility</STRONG>&nbsp;- We combined building blocks with standard UI5 controls (Wizard, MessageStrip, Button) to create a layout not available in standard floorplans</LI></UL><H2 id="toc-hId--2956098">Key Takeaways</H2><P>When building custom pages with SAP Fiori elements:</P><UL><LI><STRONG>Choose Wisely</STRONG>&nbsp;- Use standard floorplans whenever possible. Resort to custom pages only when your layout requirements genuinely don't fit standard patterns</LI><LI><STRONG>Maximize Building Block Usage</STRONG>&nbsp;- The more you use SAP Fiori elements building blocks in your custom pages, the more enterprise features you get for free</LI><LI><STRONG>Leverage the Portal</STRONG>&nbsp;- Use the SAP Fiori development portal to understand building block capabilities, experiment with configurations, and see immediate results</LI><LI><STRONG>Mix and Match</STRONG>&nbsp;- Combine custom pages with standard floorplans in the same application, using each where appropriate</LI><LI><STRONG>Stay Annotation-Driven</STRONG>&nbsp;- Even in custom pages, let annotations drive as much behavior as possible to minimize code and maximize maintainability</LI></UL><H2 id="toc-hId-147784754">What's Next</H2><P>In our final post, "Bringing the SAP Fiori development portal and its use to the next level (6 of 6)," we'll explore options to advance portal features and how to best include all project team members for maximizing productivity.</P><P>&nbsp;</P><DIV class="">To get the full overview about the SAP Fiori development portal, check out the following blog posts of the mini-series:</DIV><UL class=""><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/introducing-the-sap-fiori-development-portal-your-gateway-to-rapid-sap/ba-p/14236768" target="_blank">Introducing the SAP Fiori Development Portal: Your Gateway to Rapid SAP Fiori App Creation (1 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/get-familiar-with-sap-fiori-development-portal-and-the-power-of-the/ba-p/14240041" target="_self">Get familiar with SAP Fiori development portal and the power of the building blocks (2 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/explore-the-potential-of-sap-fiori-development-portal-using-complex/ba-p/14257622" target="_self">Explore the potential of SAP Fiori development portal using complex building blocks (3 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/use-sap-fiori-development-portal-to-understand-extension-options-for/ba-p/14270914" target="_self">Use SAP Fiori development portal to understand extension options for standard floorplans (4 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/prepare-building-custom-pages-by-using-sap-fiori-development-portal-5-of-6/ba-p/14277842" target="_self">Prepare building custom pages by using SAP Fiori development portal (5 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/bringing-the-sap-fiori-development-portal-and-its-use-to-the-next-level-6/ba-p/14285025" target="_self">Bringing the SAP Fiori development portal and its use to the next level (6 of 6)</A></LI></UL> 2025-11-26T10:03:47.891000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/bringing-the-sap-fiori-development-portal-and-its-use-to-the-next-level-6/ba-p/14285025 Bringing the SAP Fiori Development Portal and Its Use to the Next Level (6 of 6) 2025-12-05T21:46:54.974000+01:00 katrin_polloczek https://community.sap.com/t5/user/viewprofilepage/user-id/188039 <P><SPAN>As we conclude our mini-series on the <A href="https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html" target="_blank" rel="noopener noreferrer">SAP Fiori development portal</A>, where we provided you with everything needed to make the best possible choices for your project, it is now up to you to pick your set of building blocks and decide where to use what for your targeted SAP Fiori app. Let's consolidate key learnings that will help you maximize the portal's potential in your development workflow and look at the way forward.</SPAN></P><P><STRONG><SPAN>Transform how you approach SAP Fiori app development</SPAN></STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-right" image-alt="katrin_polloczek_0-1764967051780.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/349109i14AB93FA83B56468/image-size/medium?v=v2&amp;px=400" role="button" title="katrin_polloczek_0-1764967051780.png" alt="katrin_polloczek_0-1764967051780.png" /></span></P><P><SPAN>The SAP Fiori development portal represents more than just documentation - it's a comprehensive platform that transforms how you approach SAP Fiori app development. Whether you're a seasoned developer, a business analyst defining requirements, or a designer crafting user experiences, the portal provides real-time exploration options for building apps based on SAP Fiori elements for OData V4 to make informed decisions and build enterprise-grade applications efficiently.</SPAN></P><P><SPAN>Now it's time to consolidate what we've learned into actionable guidance that will help you maximize the portal's potential in your development workflow.</SPAN></P><P><STRONG><SPAN>Tips and Tricks for Maximum Productivity</SPAN></STRONG></P><P><SPAN>It is all about balancing standardization with customization. The portal structure and feature help you navigate the SAP Fiori elements for OData V4 options to maximize your success.</SPAN></P><P><EM>Portal Structure</EM></P><P><SPAN>The portal structure supports you in balancing standardization with customization.</SPAN></P><P><SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="katrin_polloczek_0-1764968329059.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/349118i003A606CE858ADC1/image-size/large?v=v2&amp;px=999" role="button" title="katrin_polloczek_0-1764968329059.png" alt="katrin_polloczek_0-1764968329059.png" /></span></SPAN></P><UL><LI><SPAN>Map business requirements to building blocks first - use the portal to identify which components can address your function&nbsp;</SPAN>needs out-of-the-box&nbsp;</LI><LI><SPAN><SPAN>Leverage Global Patterns&nbsp;early in your project planning - these non-visual building blocks like draft handling and navigation patterns are often overlooked but critical for enterprise applications</SPAN></SPAN>   </LI><LI><SPAN>Evaluate standard floorplans against your use cases before building custom solutions - List Report and Object Page patterns handle the majority of business scenarios. Together with the extension points provided by SAP Fiori elements, they can often meet your requirements with minimal effort</SPAN></LI><LI><SPAN>Use Custom Pages&nbsp;for more creative app layouts - if the target picture of your application is too far from the standard floorplans, opt for custom page creation using building blocks and global patterns to get the benefits of the metadata-driven UIs, or leverage freestyle <A href="https://pages.community.sap.com/topics/ui5" target="_blank" rel="noopener noreferrer">SAPUI5</A> to achieve your goal.</SPAN></LI></UL><P><EM>Portal Features</EM></P><UL><LI><SPAN>Use "Show Code" consistently - every page offers this feature to reveal the underlying annotations and implementation details<BR /></SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="katrin_polloczek_2-1764967051783.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/349108i9C238CCEDFAA5D78/image-size/medium?v=v2&amp;px=400" role="button" title="katrin_polloczek_2-1764967051783.png" alt="katrin_polloczek_2-1764967051783.png" /></span></LI><LI><SPAN>Experiment with live code editing - modify annotations in real-time to understand how changes affect the UI behavior. Switch off live mode for more complex code changes<BR /></SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="katrin_polloczek_3-1764967051785.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/349110i74358C28BAD350C8/image-size/medium?v=v2&amp;px=400" role="button" title="katrin_polloczek_3-1764967051785.png" alt="katrin_polloczek_3-1764967051785.png" /></span></LI><LI><SPAN>Explore both display and edit modes - many building blocks behave differently in these modes, and the portal shows both scenarios</SPAN></LI><LI><SPAN>Follow "Documentation" links&nbsp;for detailed product documentation - the portal provides focused overviews while official docs offer comprehensive details</SPAN></LI></UL><P><STRONG>The Portal as Your Companion </STRONG></P><P><SPAN>The SAP Fiori development portal isn't just a reference - it's an active participant in your development process, already starting when designing the target picture. When mapping the business user needs to how this translates into application UI, you want to review the options in the SAP Fiori development portal since following standard patterns or use standard building blocks will reduce implementation and maintenance efforts drastically. By including the portal in your everyday development process, you'll find that it becomes an indispensable tool for delivering high-quality SAP Fiori applications efficiently</SPAN><SPAN>.</SPAN></P><P><SPAN>As the portal continues to evolve, these fundamental approaches will serve you well. The combination of hands-on experimentation, systematic evaluation, and informed decision-making creates a development workflow that scales with your team's growth and adapts to changing business requirements.</SPAN></P><P><SPAN>While using it in your day-to-day work, help us understand what helps you the most, where things go in the right direction but lack the last mile, and inspire us for things we haven't even thought about yet.</SPAN></P><P><STRONG><SPAN>Looking Forward – SAP Fiori elements is compatible with AI tooling</SPAN></STRONG></P><P><SPAN>The SAP Fiori development portal represents our commitment to making SAP Fiori elements development more accessible, efficient, and collaborative. That also includes using its content and the learning when providing AI-based development support by SAP Fiori tools. As we continue to enhance the portal, remember that it's designed to grow with your expertise.</SPAN></P><P><SPAN>We can think in the following directions right now:</SPAN></P><UL><LI><SPAN>Enhance the level of detail for developers, e.g. </SPAN><SPAN>. This also make makes the portal useful as a grounding document for AI tools and LLMs that assist developers with creating SAP Fiori elements apps</SPAN></LI><LI><SPAN>Include the designer persona much more - bridging to the <A href="https://www.sap.com/design/design-system" target="_blank" rel="noopener noreferrer">SAP Design System</A>&nbsp;for the basics and providing guidance for the use of available features of SAP Fiori elements based on the context</SPAN></LI><LI><SPAN>Connect the explorer world of the portal with the implementation world of <A href="https://pages.community.sap.com/topics/fiori-tools" target="_blank" rel="noopener noreferrer">SAP Fiori tools</A></SPAN></LI></UL><P><SPAN>Whether you're building your first SAP Fiori application or extending an existing enterprise solution, the portal provides the foundation for making informed decisions that balance rapid development with enterprise-grade quality. The building blocks, patterns, and guidance we've explored throughout this series are your tools for creating applications that users love and businesses depend on.</SPAN></P><P><SPAN>Thank you for joining us on this journey through the SAP Fiori development portal. We're excited to see the innovative applications you'll build using these tools and techniques. And maybe you are already one of the next customers presenting how the portal helped you in crafting your SAP Fiori app in the&nbsp;<A href="https://tinyurl.com/elementsroundtable" target="_blank" rel="noopener nofollow noreferrer">SAP Fiori development roundtable</A>. Your feedback and experiences will continue to shape the portal's evolution, making it an even more powerful resource for the entire SAP Fiori development community</SPAN><SPAN>.</SPAN></P><P><STRONG><SPAN>Complete Blog Series Overview</SPAN></STRONG></P><P><SPAN>To get the full overview of the SAP Fiori development portal, check out the following blog posts of the mini-series:</SPAN></P><UL><LI><SPAN><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/introducing-the-sap-fiori-development-portal-your-gateway-to-rapid-sap/ba-p/14236768" target="_blank">Introducing the SAP Fiori Development Portal: Your Gateway to Rapid SAP Fiori App Creation (1 of 6)</A></SPAN></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/get-familiar-with-sap-fiori-development-portal-and-the-power-of-the/ba-p/14240041" target="_blank">Get familiar with SAP Fiori development portal and the power of the building blocks (2 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/explore-the-potential-of-sap-fiori-development-portal-using-complex/ba-p/14257622" target="_blank">Explore the potential of SAP Fiori development portal using complex building blocks (3 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/use-sap-fiori-development-portal-to-understand-extension-options-for/ba-p/14270914" target="_blank">Use SAP Fiori development portal to understand extension options for standard floorplans (4 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/prepare-building-custom-pages-by-using-sap-fiori-development-portal-5-of-6/ba-p/14277842" target="_blank">Prepare building custom pages by using SAP Fiori development portal (5 of 6)</A></LI><LI><SPAN>Bringing the SAP Fiori development portal and its use to the next level (6 of 6)</SPAN></LI></UL><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P> 2025-12-05T21:46:54.974000+01:00 https://community.sap.com/t5/abap-blog-posts/building-a-real-rap-application-step-by-step-vlog-series-introduction/ba-p/14290896 Building a Real RAP Application Step by Step — Vlog Series Introduction 2025-12-15T21:13:47.721000+01:00 Kinsbrunner https://community.sap.com/t5/user/viewprofilepage/user-id/124164 <H1 id="toc-hId-1638221392">Introduction</H1><P>This vlog series aims to demonstrate how to build a real-life ABAP RAP application, following a practical, incremental, and production-oriented approach.</P><BLOCKQUOTE><P>Disclaimer:</P><P>This series focuses on showcasing how a RAP application can be built incrementally from real functional requirements. The app is intentionally kept practical and educational, rather than exhaustive or fully hardened for production. Some edge cases or potential enhancements are intentionally not covered.</P><P>The purpose of the vlog is to share knowledge, demonstrate real development workflows, and contribute to the SAP community, not to deliver a fully polished commercial-grade application.</P><P>To allow anyone to follow the vlog series, I will be using an SAP BTP Pay-As-You-Go platform with ABAP free-tier. This environment carries several limitations compared to a customer system (i.e. I do not have I_Product available), but it is perfectly sufficient for demonstrating the concepts and end-to-end implementation.</P></BLOCKQUOTE><P>Instead of showing a pre-built demo or isolated RAP examples, the series walks through the development process from scratch, implementing the application one requirement at a time, exactly as it would be done in an actual ABAP Cloud project.</P><P>Each episode focuses on a small, well-defined set of user stories, keeping the learning process smooth and allowing you to see how the application grows after every step. The structure ensures the app is testable from the very beginning, and every enhancement is immediately visible in the UI preview.</P><P>If you want to understand RAP not just in theory but in practice, including determinations, validations, feature control, actions, side effects, completeness checks, semantic keys, and UI configuration, this series is for you.</P><P>&nbsp;</P><H1 id="toc-hId-1441707887">What are we going to build?</H1><P>We’ll be developing an internal equipment request application for a consulting firm.</P><P>Employees can request items kept in internal stock (laptops, monitors, headsets, etc.).</P><P>Each request follows a simple lifecycle:</P><UL><LI>Not Prepared / In Preparation / Delivered / <EM>(later also Cancelled)</EM></LI></UL><P>Each request includes header data (requester, deadline, priority, status) and one or more items referencing products from a customizing table of available materials.</P><P>The scenario is intentionally simple but rich enough to cover the most important RAP concepts: CDS data modeling, RAP behavior definitions in managed scenarios, Semantic keys, Determinations &amp; validations, UI annotations, Feature control, Prechecks, Popup actions, Value helps, Inline editing, Integration with customizing tables, ABAP Cloud–compliant development practices.</P><P>&nbsp;</P><H1 id="toc-hId-1245194382">How the Vlog is structured</H1><P>The application is built based on a list of functional requirements expressed as user stories. These stories are implemented in the same order they would typically be addressed in a real project. The format of each episode is:</P><UL><LI><STRONG>Short and focused</STRONG> (usually covering 1-3 user stories)</LI><LI><STRONG>Incremental</STRONG> (the app evolves visibly every episode)</LI><LI><STRONG>Practical</STRONG> (every change is immediately testable)</LI><LI><STRONG>Aligned with ABAP Cloud guidelines</STRONG></LI><LI><STRONG>Designed for long-term learning and reference</STRONG></LI></UL><P>Whether you're starting with RAP or expanding your expertise, this series aims to provide a clear, realistic, and reusable learning path.</P><P>&nbsp;</P><H1 id="toc-hId-1048680877">Episode Roadmap</H1><P>Each episode implements a specific subset of user stories.&nbsp;Episodes are planned to be released on a <STRONG>weekly basis (approx.)</STRONG>.&nbsp;Episode 1 will be released shortly, before end of year!</P><P>&nbsp;</P><TABLE width="617px"><TBODY><TR><TD width="40.071px" height="30px">01</TD><TD width="472.836px" height="30px">Project introduction + Data model basics (<A href="https://youtu.be/6V54APzzdbo" target="_blank" rel="noopener nofollow noreferrer">Video</A>&nbsp;|&nbsp;<A href="https://github.com/kinsbrunner/abap-rap-request-vlog/releases/tag/Ep01" target="_blank" rel="noopener nofollow noreferrer">Repo</A>)</TD><TD width="103.182px" height="30px">US-01</TD></TR><TR><TD width="40.071px" height="30px">02</TD><TD width="472.836px" height="30px">Service exposure + First UI (read-only) preview (<A href="https://youtu.be/-N88u9Y0VY0" target="_self" rel="nofollow noopener noreferrer">Video</A> | <A href="https://github.com/kinsbrunner/abap-rap-request-vlog/releases/tag/Ep02" target="_self" rel="nofollow noopener noreferrer">Repo</A>)</TD><TD width="103.182px" height="30px">US-01</TD></TR><TR><TD width="40.071px" height="57px">03</TD><TD width="472.836px" height="57px">Basic behavior + Search fields (Part 1): Free text + Requester (<A href="https://youtu.be/hLbJ64AwixY" target="_blank" rel="noopener nofollow noreferrer">Video</A> | <A href="https://github.com/kinsbrunner/abap-rap-request-vlog/releases/tag/Ep03" target="_self" rel="nofollow noopener noreferrer">Repo</A>)</TD><TD width="103.182px" height="57px">US-02 (part 1)</TD></TR><TR><TD width="40.071px" height="30px">04</TD><TD width="472.836px" height="30px">Search fields (Part 2): Status &amp; Priority (<A href="https://youtu.be/S0a4UotT0qo" target="_self" rel="nofollow noopener noreferrer">Video</A> | <A href="https://github.com/kinsbrunner/abap-rap-request-vlog/releases/tag/Ep04" target="_self" rel="nofollow noopener noreferrer">Repo</A>)</TD><TD width="103.182px" height="30px">US-02 (part 2)</TD></TR><TR><TD width="40.071px" height="30px">05</TD><TD width="472.836px" height="30px">Semantic key &amp; Sequential numbering (<A href="https://youtu.be/cgRJdp7anxE" target="_self" rel="nofollow noopener noreferrer">Video</A> | <A href="https://github.com/kinsbrunner/abap-rap-request-vlog/releases/tag/Ep05" target="_self" rel="nofollow noopener noreferrer">Repo</A>)</TD><TD width="103.182px" height="30px">US-03</TD></TR><TR><TD width="40.071px" height="30px">06</TD><TD width="472.836px" height="30px">Mandatory fields + Deadline validation (<A href="https://youtu.be/vK2wDZCLfaI" target="_self" rel="nofollow noopener noreferrer">Video</A> | <A href="https://github.com/kinsbrunner/abap-rap-request-vlog/releases/tag/Ep06" target="_self" rel="nofollow noopener noreferrer">Repo</A>)</TD><TD width="103.182px" height="30px">US-04 + US-05</TD></TR><TR><TD width="40.071px" height="57px">07</TD><TD width="472.836px" height="57px">Automatic Priority determination + Status icons &amp; visual enhancements (<A href="https://youtu.be/h2grDbUKHz4" target="_self" rel="nofollow noopener noreferrer">Video</A> | <A href="https://github.com/kinsbrunner/abap-rap-request-vlog/releases/tag/Ep07" target="_self" rel="nofollow noopener noreferrer">Repo</A>)</TD><TD width="103.182px" height="57px">US-06 + US-07</TD></TR><TR><TD width="40.071px" height="30px">08</TD><TD width="472.836px" height="30px"><P>Status behavior rules (<A href="https://youtu.be/aglhMzbt34o" target="_self" rel="nofollow noopener noreferrer">Video</A>&nbsp;|&nbsp;<A href="https://github.com/kinsbrunner/abap-rap-request-vlog/releases/tag/Ep08" target="_self" rel="nofollow noopener noreferrer">Repo</A>)</P></TD><TD width="103.182px" height="30px">US-08 + US-09 + US-10</TD></TR><TR><TD width="40.071px" height="30px">09</TD><TD width="472.836px" height="30px">Cancel feature (Part 1) (<A href="https://youtu.be/_slypflWl8w" target="_self" rel="nofollow noopener noreferrer">Video</A> | <A href="https://github.com/kinsbrunner/abap-rap-request-vlog/releases/tag/Ep09" target="_self" rel="nofollow noopener noreferrer">Repo</A>)</TD><TD width="103.182px" height="30px">US-11 + US-12</TD></TR><TR><TD width="40.071px" height="30px">10</TD><TD width="472.836px" height="30px">Cancel feature (Part 2)</TD><TD width="103.182px" height="30px">US-13 + US-13b + US-14</TD></TR><TR><TD width="40.071px" height="30px">11</TD><TD width="472.836px" height="30px">Item popup creation &amp; inline editing</TD><TD width="103.182px" height="30px">US-18 + US-19</TD></TR><TR><TD width="40.071px" height="30px">12</TD><TD width="472.836px" height="30px">Product customizing + availability</TD><TD width="103.182px" height="30px">US-15 + US-16</TD></TR><TR><TD width="40.071px" height="30px">13</TD><TD width="472.836px" height="30px">Item consistency: prevent duplicates</TD><TD width="103.182px" height="30px">US-17 + US-20</TD></TR><TR><TD width="40.071px">14</TD><TD width="472.836px">Additional rules</TD><TD width="103.182px">US-21 + US-22</TD></TR></TBODY></TABLE><P><!-- notionvc: 901e9484-b00c-44be-842e-77412ea38c89 --><STRONG>If this introduction was helpful, a like or follow would be appreciated as it helps others in the community find the series.</STRONG></P><P>&nbsp;</P><H1 id="toc-hId-852167372">Full requirement backlog (User Stories)</H1><P>Below is the collection of user stories implemented throughout the series, listed in almost the exact order used for development:</P><P><STRONG>US-01: Basic request object:</STRONG> As an employee, I want to create internal equipment requests so that I can receive the products I need.</P><P><STRONG>US-02: Search and Filter capabilities:</STRONG> As a user, I want to search requests using structured filters so that I can quickly locate relevant orders. I need to be able to search through the following criteria:</P><UL><LI>free search field,</LI><LI>by Requester (with search help),</LI><LI>by Priority (drop-down )</LI><LI>by Status (drop-down with multiple selections).</LI></UL><P><STRONG>US-03: Sequential External ID and semantic key:</STRONG> As the system, I want to assign each request a sequential external number so that users can reference meaningful IDs.</P><P><STRONG>US-04: Mandatory fields:</STRONG> As a user, I want the system to require Requester Name and Deadline Date so that requests are always complete.</P><P><STRONG>US-05: Deadline validation:</STRONG> As the system, I want to validate that the deadline date is at least one day in the future so that operations can prepare on time.</P><P><STRONG>US-06: Automatic priority determination:</STRONG> As the system, I want priority to be set based on deadline so that urgent requests receive proper attention (High: &lt; 3 days, Medium: &lt;7 days, otherwise, Low).</P><P><STRONG>US-07: Status icons:</STRONG> As a user, I want statuses displayed with colored icons so that I can understand them at a glance.</P><P><STRONG>US-08: Cancel status restrictions:</STRONG> As a user, I want to search for cancelled requests but not manually set status as “Cancelled” so that lifecycle rules are respected.</P><P><STRONG>US-09: Default status:</STRONG> As the system, I want new requests to default to “Not Prepared” so that the lifecycle begins correctly.</P><P><STRONG>US-10: Status editability rules:</STRONG> As a user, I want status to be editable only after creation so that inconsistencies are avoided.</P><P><STRONG>US-11: Cancel action:</STRONG> As a user, I want to cancel one or more requests from the list so that I can invalidate unnecessary requests.</P><P><STRONG>US-12: Cancellation popup:</STRONG> As a user, I want to cancel and justify cancellations through a popup so that the system enforces to have reasons registered.</P><P><STRONG>US-13: Cancel reason rules:</STRONG> As a user, I want “Cancellation Reason” to be editable only when status is “Cancelled” so that it appears available only when relevant.</P><P><STRONG>US-13b:</STRONG> changing dynamic field hiding approach from CDS into virtual element.</P><P><STRONG>US-14: No editing after cancellation:</STRONG> As the system, I want cancelled requests to become read-only so that historical data is kept intact.</P><P><STRONG>US-15: Product catalog restriction:</STRONG> As a user, I want to select products only from internal stock so that I request only available items. Internal stock is customized through a customizing table.</P><P><STRONG>US-16: Product value help:</STRONG> As a user, I want a value help showing only available products so that selection is efficient.</P><P><STRONG>US-17: Unique product per request:</STRONG> As a system, I want to prevent duplicate products within a request so that items remain consistent.</P><P><STRONG>US-18: Item creation via popup:</STRONG> As a user, I want to create items in a popup and edit them inline so that maintenance is fast and intuitive.</P><P><STRONG>US-19: Make popup fields mandatory:</STRONG> As a system, I want to ensure that the data entered through the Product popup is complete.</P><P><STRONG>US-20: Make item fields mandatory:</STRONG> As a system, I want to ensure that the data entered through the Product object page is complete.</P><P><STRONG>US-21: Show product description at item level:</STRONG> As a system, I want to show the item description instead of the Product ID at item level.</P><P><STRONG>US-22: No editing after completion:</STRONG> As the system, I want completed requests to become read-only so that historical data is kept intact.</P><P><!-- notionvc: a6408df4-7d25-4b7b-ac5f-fe15a840c99c --></P> 2025-12-15T21:13:47.721000+01:00 https://community.sap.com/t5/artificial-intelligence-blogs-posts/hands-on-guide-sap-build-joule-skill-for-purchase-order-listing-approval-or/ba-p/14266886 Hands-On Guide: SAP Build + Joule Skill for Purchase Order Listing, Approval, or Modification 2025-12-22T08:09:03.721000+01:00 Batuhann https://community.sap.com/t5/user/viewprofilepage/user-id/175881 <P><FONT size="6"><STRONG>Introduction</STRONG></FONT></P><P>In this tutorial, we will build an AI powered Purchase Order listing, modification or approval app using SAP Build and Joule. This step by step guide covers everything from OData integration to creating a working Joule Skill.</P><P>&nbsp;</P><P><FONT size="6"><STRONG>Table of Contents</STRONG></FONT></P><P><ul =""><li style="list-style-type:disc; margin-left:30px; margin-bottom:1px;"><a href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/hands-on-guide-sap-build-joule-skill-for-purchase-order-listing-approval-or/ba-p/14266886#toc-hId-1893794982">1. Create an Environment</a></li><li style="list-style-type:disc; margin-left:30px; margin-bottom:1px;"><a href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/hands-on-guide-sap-build-joule-skill-for-purchase-order-listing-approval-or/ba-p/14266886#toc-hId-1697281477">2. Exposing the Destination</a></li><li style="list-style-type:disc; margin-left:30px; margin-bottom:1px;"><a href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/hands-on-guide-sap-build-joule-skill-for-purchase-order-listing-approval-or/ba-p/14266886#toc-hId-1500767972">3. Create a database table to store purchase orders</a></li><li style="list-style-type:disc; margin-left:30px; margin-bottom:1px;"><a href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/hands-on-guide-sap-build-joule-skill-for-purchase-order-listing-approval-or/ba-p/14266886#toc-hId-1304254467">4. Create a CDS from the ZTABLE for Odata</a></li><li style="list-style-type:disc; margin-left:30px; margin-bottom:1px;"><a href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/hands-on-guide-sap-build-joule-skill-for-purchase-order-listing-approval-or/ba-p/14266886#toc-hId-1107740962">5. Create OData service with T-code SEGW</a></li><li style="list-style-type:disc; margin-left:30px; margin-bottom:1px;"><a href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/hands-on-guide-sap-build-joule-skill-for-purchase-order-listing-approval-or/ba-p/14266886#toc-hId-911227457">6. Activate the Odata service via /iwfnd/maint_service T-code</a></li><li style="list-style-type:disc; margin-left:30px; margin-bottom:1px;"><a href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/hands-on-guide-sap-build-joule-skill-for-purchase-order-listing-approval-or/ba-p/14266886#toc-hId-714713952">7. Crete an Action in SAP Build</a></li><li style="list-style-type:disc; margin-left:30px; margin-bottom:1px;"><a href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/hands-on-guide-sap-build-joule-skill-for-purchase-order-listing-approval-or/ba-p/14266886#toc-hId-518200447">8. Create A Joule Skill to Get Purchase Order</a></li><li style="list-style-type:disc; margin-left:30px; margin-bottom:1px;"><a href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/hands-on-guide-sap-build-joule-skill-for-purchase-order-listing-approval-or/ba-p/14266886#toc-hId-321686942">9. Create A Joule Skill to Approve Purchase Order</a></li><li style="list-style-type:disc; margin-left:30px; margin-bottom:1px;"><a href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/hands-on-guide-sap-build-joule-skill-for-purchase-order-listing-approval-or/ba-p/14266886#toc-hId-125173437">10. Launch The Joule and Test The Skills</a></li></ul></P><P>&nbsp;</P><P>&nbsp;</P><P>In today’s SAP ecosystem, intelligent automation is an expectation, not a future goal. SAP Build allows developers to quickly create business applications without extensive coding and SAP Joule brings AI-driven intelligence to these experiences.</P><P>In this hands-on guide, I’ll walk you through the process of building a Joule skill that connects to an OData service, allowing users to list, approve, and update purchase orders directly through SAP Build. (&nbsp;This guide uses ZTABLE to store purchase order data because the standard SAP tables in the test system I work on don't have enough or the right kind of data. However, you can use the standard tables instead of ZTABLE. )</P><P>This project shows how AI capabilities can seamlessly integrate into SAP’s low-code environment, enabling automation and human decision-making in one interface. Whether you want to enhance your workflow with intelligent actions or explore real-world Joule integration scenarios, this guide will provide a practical starting point.</P><P>&nbsp;</P><H3 id="toc-hId-1893794982"><STRONG>1. Create an Environment</STRONG></H3><P>&nbsp;</P><P>We need to create an environment for testing joule skill.</P><P>Open the SAP Build Lobby, choose Control Tower-&gt;Environments and press the Create button.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_0-1762951486194.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339448iE91253DFE78B5C5E/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_0-1762951486194.png" alt="Batuhann_0-1762951486194.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_1-1762951486194.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339449i8E4F825B4231DE6C/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_1-1762951486194.png" alt="Batuhann_1-1762951486194.png" /></span></P><P>&nbsp;</P><P>Name your environment and add Description.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_2-1762951486194.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339447i02DDA528EE106A2C/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="Batuhann_2-1762951486194.png" alt="Batuhann_2-1762951486194.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId-1697281477"><STRONG>2. Exposing the Destination</STRONG></H3><P>&nbsp;</P><P>Url of the destination on BTP is the url of our SAP system and the destination must have these properties:<SPAN class="">&nbsp;</SPAN></P><P>sap.applicationdevelopment.actions.enabled -&gt; true</P><P>sap.processautomation.enabled -&gt; true</P><P>sap.build.usage -&gt; odata_gen</P><P>&nbsp;</P><P>Also the destination’s user will be used for set an external break-point for debugging the ABAP code.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_3-1762951486194.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339452i025CC33442B1A0E0/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_3-1762951486194.png" alt="Batuhann_3-1762951486194.png" /></span></P><P>&nbsp;</P><P>Open the SAP Build Lobby, choose Control Tower-&gt;Destinations and press the Add button.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_4-1762951486193.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339451iDA52A8ADE7E8B3CE/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_4-1762951486193.png" alt="Batuhann_4-1762951486193.png" /></span></P><P>&nbsp;</P><P>Select the Destination and choose next.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_5-1762951486194.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339450i2A1504F4B8D14CD7/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_5-1762951486194.png" alt="Batuhann_5-1762951486194.png" /></span></P><P>&nbsp;</P><P>Choose the environment in which you want to use the target. For this tutorial you can choose the Test Environment that you create.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_6-1762951486194.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339453i50B41BBA23341F33/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_6-1762951486194.png" alt="Batuhann_6-1762951486194.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId-1500767972">3. Create a database table to store purchase orders</H3><pre class="lia-code-sample language-abap"><code>@EndUserText.label : 'Purchase Order Change With Sap Build' @AbapCatalog.enhancementCategory : #NOT_CLASSIFIED @AbapCatalog.tableCategory : #TRANSPARENT @AbapCatalog.deliveryClass : #A @AbapCatalog.dataMaintenance : #ALLOWED define table zbg_build_test { key mandt : mandt not null; key purchaseorder : ebeln not null; key purchaseorderitem : ebelp not null; key reservationitem : ebelp not null; material : matnr; materialcompisvariablesized : boolean; materialcomponentisphantomitem : boolean; reservation : char10; @Semantics.quantity.unitOfMeasure : 'zbg_build_test.entryunit' requiredquantity : menge_d; requirementdate : dats; reservationisfinallyissued : boolean; baseunit : meins; @Semantics.quantity.unitOfMeasure : 'zbg_build_test.entryunit' quantityinentryunit : menge_d; entryunit : meins; plant : werks_d; latestrequirementdate : dats; billofmaterialitemnumber : ebelp; bomitemcategory : char1; isbulkmaterialcomponent : boolean; debitcreditcode : shkzg; @Semantics.quantity.unitOfMeasure : 'zbg_build_test.entryunit' withdrawnquantity : menge_d; approver : uname; appoved : flag; }</code></pre><P>&nbsp;</P><P>Fill the table:</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_7-1762951486194.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339455i588019ABAC52100D/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_7-1762951486194.png" alt="Batuhann_7-1762951486194.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId-1304254467"><STRONG>4. Create a CDS from the ZTABLE for Odata</STRONG></H3><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>@AbapCatalog.sqlViewName: 'ZSLV_BUILD_TST_V' @AbapCatalog.compiler.compareFilter: true @AbapCatalog.preserveKey: true @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Purchasing Document Informations CDS' @Metadata.ignorePropagatedAnnotations: true @ObjectModel.deleteEnabled: true @ObjectModel.createEnabled: true @ObjectModel.updateEnabled: true define view ZSLV_V_BUILD_TEST as select from zbg_build_test as z { @EndUserText.label: 'Purchase Order' key purchaseorder, @EndUserText.label: 'Purchase Order Item' key purchaseorderitem, @EndUserText.label: 'Reservation Item' key reservationitem, @EndUserText.label: 'Material' material, @EndUserText.label: 'Material Size' materialcompisvariablesized, @EndUserText.label: 'Material Item' materialcomponentisphantomitem, @EndUserText.label: 'Reservation' reservation, @EndUserText.label: 'Quantity' requiredquantity, @EndUserText.label: 'Date' requirementdate, @EndUserText.label: 'Reservation Issue' reservationisfinallyissued, @EndUserText.label: 'Unit' baseunit, @EndUserText.label: 'Entry Unit' entryunit, @EndUserText.label: 'Quantity In Entry Unit' quantityinentryunit, @EndUserText.label: 'Plant' plant, @EndUserText.label: 'Latest Requirement Date' latestrequirementdate, @EndUserText.label: 'Bill Of Material Number' billofmaterialitemnumber, @EndUserText.label: 'BOM Item Category' bomitemcategory, @EndUserText.label: 'Is Bulk Material' isbulkmaterialcomponent, @EndUserText.label: 'Debit Credit Code' debitcreditcode, @EndUserText.label: 'With Drawn Quantity' withdrawnquantity, @EndUserText.label: 'Approver' approver, @EndUserText.label: 'Approved' appoved }</code></pre><P>&nbsp;</P><H3 id="toc-hId-1107740962"><STRONG>5. Create OData service with T-code SEGW</STRONG></H3><P>(Because of the version of the system I work on, this guide uses SEGW instead of RAP to create an OData service. However, you can easily create your own OData service with RAP.)</P><P>Press ‘Create Project’ button, fill the fields and assign the package, request (For this tutorial it will be local object).</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_8-1762951486194.png" style="width: 552px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339454iA442249332DC10C3/image-dimensions/552x491/is-moderation-mode/true?v=v2" width="552" height="491" role="button" title="Batuhann_8-1762951486194.png" alt="Batuhann_8-1762951486194.png" /></span></P><P>&nbsp;</P><P>Complete the creation.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_9-1762951486194.png" style="width: 531px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339458i4C371D0DB2FF2A4D/image-dimensions/531x469/is-moderation-mode/true?v=v2" width="531" height="469" role="button" title="Batuhann_9-1762951486194.png" alt="Batuhann_9-1762951486194.png" /></span></P><P>&nbsp;</P><P>Extend the project, right click to ‘Data Model’, select the Reference-&gt;Source</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_10-1762951486195.png" style="width: 524px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339456iADCCAF8BCBF3F0F2/image-dimensions/524x205/is-moderation-mode/true?v=v2" width="524" height="205" role="button" title="Batuhann_10-1762951486195.png" alt="Batuhann_10-1762951486195.png" /></span></P><P>&nbsp;</P><P>Fill the CDS name that you created. Choose ‘Next’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_11-1762951486195.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339457iE178E9FF8808137F/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_11-1762951486195.png" alt="Batuhann_11-1762951486195.png" /></span></P><P>&nbsp;</P><P>Choose ‘Finish’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_12-1762951486195.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339460i162C954A12A77E87/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_12-1762951486195.png" alt="Batuhann_12-1762951486195.png" /></span></P><P>&nbsp;</P><P>Activate and generate the Service:</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_13-1762951486195.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339462i0C776D5B90B9187A/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_13-1762951486195.png" alt="Batuhann_13-1762951486195.png" /></span></P><P>&nbsp;</P><P>Go to the class ZCL_ZSLV_BUILD_DPC_EXT. At the bottom of the method list redefine the update method ZSLV_V_BUILD_TES_UPDATE_ENTITY.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_14-1762951486195.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339461iFB95781DC614B3CF/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_14-1762951486195.png" alt="Batuhann_14-1762951486195.png" /></span></P><P>&nbsp;</P><P>In the method, update the approved field with the below code and activate it.</P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>METHOD zslv_v_build_tes_update_entity. DATA: lv_ebeln TYPE ebeln, lv_ebelp TYPE ebelp, lv_item TYPE ebelp, ls_entity TYPE zcl_zslv_build_mpc=&gt;ts_zslv_v_build_testtype, lr_entity TYPE REF TO data, ls_table TYPE zbg_build_test. LOOP AT it_key_tab INTO DATA(ls_key). CASE ls_key-name. WHEN 'purchaseorder'. lv_ebeln = ls_key-value. WHEN 'purchaseorderitem'. lv_ebelp = ls_key-value. WHEN 'reservationitem'. lv_item = ls_key-value. ENDCASE. ENDLOOP. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). MOVE-CORRESPONDING ls_entity TO ls_table. er_entity = ls_entity. UPDATE zbg_build_test FROM ls_table. COMMIT WORK. ENDMETHOD.</code></pre><P>&nbsp;</P><H3 id="toc-hId-911227457"><STRONG>6. Activate the Odata service via /iwfnd/maint_service T-code</STRONG></H3><P>&nbsp;</P><P>Choose ‘Add Service’</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_15-1762951486195.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339464i247926CE41613662/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_15-1762951486195.png" alt="Batuhann_15-1762951486195.png" /></span></P><P>&nbsp;</P><P>Select the ‘System Alias’, fill the ‘Technical Service Name’ and press ‘Get Services’. Select the service that you create and press ‘Add Selected Services’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_16-1762951486195.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339463iE26394B5578D33BF/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_16-1762951486195.png" alt="Batuhann_16-1762951486195.png" /></span></P><P>&nbsp;</P><P>Assign the package and continue.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_17-1762951486195.png" style="width: 586px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339465i93701DCF6F84A375/image-dimensions/586x482/is-moderation-mode/true?v=v2" width="586" height="482" role="button" title="Batuhann_17-1762951486195.png" alt="Batuhann_17-1762951486195.png" /></span></P><P>&nbsp;</P><P>We have added the service, which should appear as follows. In the ICF Nodes section, there is a button labeled "SAP Gateway Client" that provides a testing environment for the service. Press that button.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_18-1762951486195.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339466i257E4502887B7CD2/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_18-1762951486195.png" alt="Batuhann_18-1762951486195.png" /></span></P><P>&nbsp;</P><P>Select the HTTP method as ‘GET’. Press ‘EntitySets’ to choose entity set. Choose the one that you created.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_19-1762951486195.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339467iD26BA638EA695D04/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_19-1762951486195.png" alt="Batuhann_19-1762951486195.png" /></span></P><P>&nbsp;</P><P>Press ‘Execute’ button for testing and response should appear as follows.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_20-1762951486196.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339468iB19EEFFE1A96F079/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_20-1762951486196.png" alt="Batuhann_20-1762951486196.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId-714713952"><STRONG>7. Crete an Action in SAP Build</STRONG></H3><P>&nbsp;</P><P>Open the SAP Build Lobby, choose Connectors-&gt;Actions and press the ‘Create’ button. Choose ‘OData Destinations’ and select the Destination that we created.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_21-1762951486196.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339469i75D4226E6210AAA0/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_21-1762951486196.png" alt="Batuhann_21-1762951486196.png" /></span></P><P>&nbsp;</P><P>Fill the Resource Path as follows and click ‘Next’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_22-1762951486196.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339470iC98AD9718467DDBE/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_22-1762951486196.png" alt="Batuhann_22-1762951486196.png" /></span></P><P>&nbsp;</P><P>The available methods are listed in this window. Select ‘Next’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_23-1762951486196.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339471iB4B087B4930D98F9/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_23-1762951486196.png" alt="Batuhann_23-1762951486196.png" /></span></P><P>&nbsp;</P><P>Fill the name and description for your action and create.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_24-1762951486196.png" style="width: 699px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339472i6C840202272BF07C/image-dimensions/699x517/is-moderation-mode/true?v=v2" width="699" height="517" role="button" title="Batuhann_24-1762951486196.png" alt="Batuhann_24-1762951486196.png" /></span></P><P>&nbsp;</P><P>The action Purchase_Order_Action is created. Click the action and open it.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_25-1762951486196.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339473i36F970231CEAF229/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_25-1762951486196.png" alt="Batuhann_25-1762951486196.png" /></span></P><P>&nbsp;</P><P>Select the methods in the OData Service.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_26-1762951486196.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339474i9B7B2A2ACC5EF572/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_26-1762951486196.png" alt="Batuhann_26-1762951486196.png" /></span></P><P>&nbsp;</P><P>The GET method's input has no required fields, only optional GET parameters.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_27-1762951486196.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339476iF63E82D70E99586D/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_27-1762951486196.png" alt="Batuhann_27-1762951486196.png" /></span></P><P>&nbsp;</P><P>Output parameters are the fields in the CDS that we created.<SPAN class="">&nbsp;</SPAN></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_28-1762951486197.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339477i2981064B998D3F65/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_28-1762951486197.png" alt="Batuhann_28-1762951486197.png" /></span></P><P>&nbsp;</P><P>Methods can be tested in the action interface. For the GET method we don’t need to fill any input parameters. Click ‘Test’ button.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_29-1762951486197.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339475iD784417B4363F97F/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_29-1762951486197.png" alt="Batuhann_29-1762951486197.png" /></span></P><P>&nbsp;</P><P>The data appears on the ‘Test Preview’ section.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_30-1762951486197.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339481iF9B10249BA8AE7F3/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_30-1762951486197.png" alt="Batuhann_30-1762951486197.png" /></span></P><P>&nbsp;</P><P>The PATCH method requires purchaseorder, purchaseorderitem and reservationitem, all of which are key fields in our ZTABLE and CDS.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_31-1762951486197.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339480i05AB260CD5D83103/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_31-1762951486197.png" alt="Batuhann_31-1762951486197.png" /></span></P><P>&nbsp;</P><P>There are no standard output in PATCH method.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_32-1762951486197.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339478iA6B33D61E44BFE31/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_32-1762951486197.png" alt="Batuhann_32-1762951486197.png" /></span></P><P>&nbsp;</P><P>In the Test section, all required fields and fields that need to be changed must be filled out. In this scenario these fields are purchaseorder, purchaseorderitem, reservationitem and approved fields.</P><P>&nbsp;</P><P>Also the link on the Test section can be used in the SAP Gateway Client to test the PATCH method.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_33-1762951486197.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339482i07D1694EC91827A8/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_33-1762951486197.png" alt="Batuhann_33-1762951486197.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_34-1762951486197.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339483iDD0AB9C12A72FCCB/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_34-1762951486197.png" alt="Batuhann_34-1762951486197.png" /></span></P><P>&nbsp;</P><P>PATCH method return “204: NO CONTENT” and empty Response. This means the update is successful and we will use this emptiness in our joule skill.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_35-1762951486197.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339484i698F6AA58FBFF6D2/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_35-1762951486197.png" alt="Batuhann_35-1762951486197.png" /></span></P><P>&nbsp;</P><P>After checking and testing, save the methods using the ‘Save’ button and select ‘Release’. After the release process, the action should appear as shown below. Then, press 'Publish'.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_36-1762951486198.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339486iBE26FA144B5FA082/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_36-1762951486198.png" alt="Batuhann_36-1762951486198.png" /></span></P><P>&nbsp;</P><P>You can debug when testing methods via the SAP Gateway Client or the SAP Build Action. Set an external breakpoint for the user in your destination that we created at the beginning.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_37-1762951486198.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339487i89CC14AD81B73696/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_37-1762951486198.png" alt="Batuhann_37-1762951486198.png" /></span></P><P>&nbsp;</P><P>For the PATCH method, our key fields in the internal table IT_KEY_TAB.<SPAN class="">&nbsp;</SPAN></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_38-1762951486198.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339485i6B0D4AB7F117B580/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_38-1762951486198.png" alt="Batuhann_38-1762951486198.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId-518200447"><STRONG>8. Create A Joule Skill to Get Purchase Order</STRONG></H3><P>&nbsp;</P><P>Open the SAP Build Lobby, choose Create-&gt;Joule Skill and fill the name and description. Open the created skill.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_39-1762951486198.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339489i6C3CFA0CA8BB54F5/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_39-1762951486198.png" alt="Batuhann_39-1762951486198.png" /></span></P><P>&nbsp;</P><P>Select the ’Trigger’ step. On the ‘General’ tab fill the name and description. Allow Joule to generate a response and skill to be started directly by user.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_40-1762951486198.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339488i8AF6014A0B2D3A60/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_40-1762951486198.png" alt="Batuhann_40-1762951486198.png" /></span></P><P>&nbsp;</P><P>We don't need input, but outputs can vary according to our needs. In this tutorial, the parameters shown below have been added as outputs.</P><P>Choose ‘Configure’ and add parameters you want to show to the user. For this example, all parameters are string except the ‘approved’ which is boolean.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_41-1762951486198.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339490i37CAFB717C9518BB/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_41-1762951486198.png" alt="Batuhann_41-1762951486198.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_42-1762951486198.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339491i71B08C51F4AFAA8E/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_42-1762951486198.png" alt="Batuhann_42-1762951486198.png" /></span></P><P>&nbsp;</P><P>Press ‘+’ and choose ‘Call Action’, ‘Browse All Actions’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_43-1762951486199.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339493iD9A8E33D18BB36DC/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_43-1762951486199.png" alt="Batuhann_43-1762951486199.png" /></span></P><P>&nbsp;</P><P>Search for ‘ZSLV_V_BUILD_TEST’ or your Service Name. Add the ‘Get entities from ZSLV_V_BUILD_TEST’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_44-1762951486199.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339492i29CD84E55DC3D4A0/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_44-1762951486199.png" alt="Batuhann_44-1762951486199.png" /></span></P><P>&nbsp;</P><P>Select the ‘Destination Variable’ as Destination we created.<SPAN class="">&nbsp;</SPAN></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_45-1762951486199.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339494i1ADC6AED50920631/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_45-1762951486199.png" alt="Batuhann_45-1762951486199.png" /></span></P><P>&nbsp;</P><P>We can skip the input tab because there are no input for GET method.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_46-1762951486199.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339495iCF826E2C172819B2/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_46-1762951486199.png" alt="Batuhann_46-1762951486199.png" /></span></P><P>&nbsp;</P><P>We can see the output parameters in this tab.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_47-1762951486199.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339496i0D79C6DE47F87320/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_47-1762951486199.png" alt="Batuhann_47-1762951486199.png" /></span></P><P>&nbsp;</P><P>On the "End" step, we need to assign the input and output parameters for the skills. Since we don't have any inputs, let's assign the outputs added in the "Trigger" step as our action's outputs.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_48-1762951486199.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339498iF065B601C1E42425/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_48-1762951486199.png" alt="Batuhann_48-1762951486199.png" /></span></P><P>&nbsp;</P><P>Save the Joule Skill.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_49-1762951486199.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339497i22EAD020264F75C1/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_49-1762951486199.png" alt="Batuhann_49-1762951486199.png" /></span></P><P>&nbsp;</P><P>And Release.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_50-1762951486199.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339499iC941DB003C70EDDF/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_50-1762951486199.png" alt="Batuhann_50-1762951486199.png" /></span></P><P>&nbsp;</P><P>Now Deploy.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_51-1762951486199.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339501i38DBD6FDEEC0D97D/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_51-1762951486199.png" alt="Batuhann_51-1762951486199.png" /></span></P><P>&nbsp;</P><P>Choose the Environment we created and click ‘Upgrade’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_52-1762951486199.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339503i8DA5330F08DEC060/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_52-1762951486199.png" alt="Batuhann_52-1762951486199.png" /></span></P><P>&nbsp;</P><P>Match the destinations, and the skill will be ready to use by Joule after deployment.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_53-1762951486200.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339502iD7925260EAAA33B7/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_53-1762951486200.png" alt="Batuhann_53-1762951486200.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId-321686942"><STRONG>9. Create A Joule Skill to Approve Purchase Order</STRONG></H3><P>&nbsp;</P><P>On the ‘Trigger’ step, fill the name and description. Deactivate the ‘Allow Joule to generate a response’ feature because in this skill we will create our own messages. The other feature should be active.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_54-1762951486200.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339506iCF2B4B09A81CFE1A/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_54-1762951486200.png" alt="Batuhann_54-1762951486200.png" /></span></P><P>&nbsp;</P><P>Configure the input parameters. Add purchaseorder, purchaseorderitem and reservationitem key fields as string. For approve skill we don’t need any output field.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_55-1762951486200.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339504i795B12BB0A5FDD06/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_55-1762951486200.png" alt="Batuhann_55-1762951486200.png" /></span></P><P>&nbsp;</P><P>Choose ‘+’ and ‘Call Action’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_56-1762951486200.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339505iF137892C308443DC/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_56-1762951486200.png" alt="Batuhann_56-1762951486200.png" /></span></P><P>&nbsp;</P><P>Browse All Actions.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_57-1762951486200.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339507iCB188F4B80EEF892/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_57-1762951486200.png" alt="Batuhann_57-1762951486200.png" /></span></P><P>&nbsp;</P><P>Search update or the service name. Add the Update entity in ZSLV_V_BUILD_TEST.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_58-1762951486200.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339508i9195BC6AC1EBB8EF/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_58-1762951486200.png" alt="Batuhann_58-1762951486200.png" /></span></P><P>&nbsp;</P><P>On the ‘General’ tab, assign the Destination.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_59-1762951486200.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339509i6AEAF116350A3717/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_59-1762951486200.png" alt="Batuhann_59-1762951486200.png" /></span></P><P>&nbsp;</P><P>On the ‘Inputs’ tab, assign the purchaseorder, purchaseorderitem and reservationitem to the parameters created on the "Trigger" step.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_60-1762951486200.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339510iD7BE5A293F78E88D/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_60-1762951486200.png" alt="Batuhann_60-1762951486200.png" /></span></P><P>&nbsp;</P><P>We only need to fill the fields ‘approved’ from the fields to be updated. We need to configure the ‘approved’ field because action inputs can only be string.<SPAN class="">&nbsp;</SPAN></P><P>&nbsp;</P><P>Choose ‘approved’ field and ‘Apply a formula’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_61-1762951486200.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339511i1CC892148E0E938B/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_61-1762951486200.png" alt="Batuhann_61-1762951486200.png" /></span></P><P>Type ‘true’ and click ‘Apply’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_62-1762951486200.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339512iD53F3F6D975D989B/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_62-1762951486200.png" alt="Batuhann_62-1762951486200.png" /></span></P><P>&nbsp;</P><P>Choose ‘+’ and ‘Check Condition’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_63-1762951486201.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339513i9D767715D97E0E68/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_63-1762951486201.png" alt="Batuhann_63-1762951486201.png" /></span></P><P>&nbsp;</P><P>Choose the ‘Condition Editor’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_64-1762951486201.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339514iD1DEADEE783168CA/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_64-1762951486201.png" alt="Batuhann_64-1762951486201.png" /></span></P><P>&nbsp;</P><P>Add the following conditions and Click ‘Apply’. If PATCH method is executed successfully, the result will be empty.<SPAN class="">&nbsp;</SPAN></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_65-1762951486201.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339515i1085590800299A9E/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_65-1762951486201.png" alt="Batuhann_65-1762951486201.png" /></span></P><P>&nbsp;</P><P>If the condition is met, the left branch of the condition executes. In the opposite case, the ‘Default’ branch of the condition executes.</P><P>&nbsp;</P><P>Choose the ‘+’ on the left branch and ‘Send Response’.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_66-1762951486201.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339517iEEA27BCE03F23CCC/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_66-1762951486201.png" alt="Batuhann_66-1762951486201.png" /></span></P><P>&nbsp;</P><P>Open Message Editor.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_67-1762951486201.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339518i12FD6CF1135905F9/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_67-1762951486201.png" alt="Batuhann_67-1762951486201.png" /></span></P><P>&nbsp;</P><P>Fill the parameters as shown below and save.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_68-1762951486201.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339516i834CCF9C092AAC55/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_68-1762951486201.png" alt="Batuhann_68-1762951486201.png" /></span></P><P>&nbsp;</P><P>You can add parameters to the title and message with the ‘&lt;&gt;’ button.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_69-1762951486201.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339520i22FFEB9A68D1170B/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_69-1762951486201.png" alt="Batuhann_69-1762951486201.png" /></span></P><P>&nbsp;</P><P>Do the same steps for the right branch of the condition. ‘+’ -&gt; ’Send Response’ -&gt; ‘Open Message Editor’</P><P>&nbsp;</P><P>Fill the parameters as shown below and save.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_70-1762951486201.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339519iB1B455C7EC155E26/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_70-1762951486201.png" alt="Batuhann_70-1762951486201.png" /></span></P><P>&nbsp;</P><P>Save, Release and Deploy just like the previous GET_PURCHASE_ORDER skill.</P><P>&nbsp;</P><H3 id="toc-hId-125173437"><STRONG>10. Launch The Joule and Test The Skills</STRONG></H3><P>&nbsp;</P><P>Open the SAP Build Lobby, choose Control Tower-&gt;Environments-&gt;Joule</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_71-1762951486201.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339521i4845A290D81D0EBA/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_71-1762951486201.png" alt="Batuhann_71-1762951486201.png" /></span></P><P>&nbsp;</P><P>Launch the joule, ask for Purchase Orders and get the details.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_72-1762951486202.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339522i923E80477DF51C05/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_72-1762951486202.png" alt="Batuhann_72-1762951486202.png" /></span></P><P>&nbsp;</P><P>Ask joule to approve the purchase orders and get the illustrated success message card we create.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Batuhann_73-1762951486202.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/339523iCB0F2C77FC1078DA/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="Batuhann_73-1762951486202.png" alt="Batuhann_73-1762951486202.png" /></span></P><P>&nbsp;</P> 2025-12-22T08:09:03.721000+01:00 https://community.sap.com/t5/abap-blog-posts/how-to-consume-external-apis-in-s-4hana-private-cloud-edition-pce-2023-via/ba-p/14297278 How To Consume External APIs in S/4HANA Private Cloud Edition (PCE) 2023 via RAP Framework 2026-01-08T14:08:04.222000+01:00 shasankgupta024 https://community.sap.com/t5/user/viewprofilepage/user-id/877731 <P><STRONG>Scenario:</STRONG><BR />Suppose we need to expose images related to a "PickTicket" from an external system, making them available in SAP via a custom OData service.</P><P><STRONG>Steps Overview</STRONG></P><P>1. Create a Custom Entity CDS View<BR />2. Create Service Definition<BR />3. Create Service Binding<BR />4. Implement ABAP Class to Consume the External API<BR />5. Test the OData Service</P><P><STRONG>1. Create a Custom Entity (CDS View)</STRONG></P><P>Start by defining a **custom entity** to represent the data structure for the API response:</P><pre class="lia-code-sample language-abap"><code>@EndUserText.label: 'Custom Entity for Image Data' @ObjectModel: { query: { implementedBy: 'ABAP:ZCL_IMAGESET' } } define root custom entity ZCE_IMAGESET { key pickticketid : abap.char(20); key urlshortlivedthumbnail : abap.char(255); trigger_ : abap.char(20); source : abap.char(40); imageid : abap.char(20); urlthumbnail : abap.char(255); urlshortlived : abap.char(255); }</code></pre><P>This entity acts as a **virtual view**—data retrieval is handled by an ABAP class (see `implementedBy` above).</P><P><STRONG>2. Create a Service Definition</STRONG></P><P>Expose the custom entity in your service definition:</P><pre class="lia-code-sample language-abap"><code>@EndUserText.label: 'zsd_imageset' define service Zsd_imageset { expose ZCE_IMAGESET; }</code></pre><P><STRONG>3. Create a Service Binding</STRONG></P><P>Next, create a **service binding**—for example, `ZSB_IMAGESET` for OData V4—which generates the OData endpoint for your application.&nbsp;<EM>*Use the standard RAP tools in Eclipse or ADT to create this binding from the CDS service definition.*</EM></P><P><STRONG>4. Implement the ABAP Class to Handle API Call</STRONG></P><P>Define the ABAP class (`zcl_imageset`) to fetch and provide data from the external API.<BR />Use the **RAP Query Provider Interface** (`if_rap_query_provider`) for custom data provisioning:</P><P><U>Class Definition</U></P><pre class="lia-code-sample language-abap"><code>CLASS zcl_imageset DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. TYPES: BEGIN OF ty_imageset, trigger TYPE char20, pickticketid TYPE char20, source TYPE char40, imageid TYPE char20, urlthumbnail TYPE char255, urlshortlived TYPE char255, urlshortlivedthumbnail TYPE char255, END OF ty_imageset. TYPES: tt_imageset TYPE STANDARD TABLE OF ty_imageset WITH EMPTY KEY. INTERFACES if_rap_query_provider. PROTECTED SECTION. PRIVATE SECTION. ENDCLASS.</code></pre><P><U>Class Implementation</U></P><pre class="lia-code-sample language-abap"><code>CLASS ZCL_IMAGESET IMPLEMENTATION. METHOD if_rap_query_provider~select. DATA lt_images TYPE tt_imageset. DATA lv_pickticketid TYPE string. " Get filter (PickTicketId) DATA(lo_filter) = io_request-&gt;get_filter( )-&gt;get_as_sql_string( ). DATA(lv_offset) = io_request-&gt;get_paging( )-&gt;get_offset( ). DATA(lv_page_size) = io_request-&gt;get_paging( )-&gt;get_page_size( ). DATA(lv_max_rows) = COND #( WHEN lv_page_size = if_rap_query_paging=&gt;page_size_unlimited THEN 0 ELSE lv_page_size ). DATA(lt_sort_table) = VALUE string_table( FOR ls_sort_element IN io_request-&gt;get_sort_elements( ) ( ls_sort_element-element_name &amp;&amp; COND #( WHEN ls_sort_element-descending = abap_true THEN ` descending` ELSE ` ascending` ) ) ). CONCATENATE 'PICKTICKETID ' 'SOURCE' INTO DATA(lv_default_sort) SEPARATED BY ',' . DATA(lv_sort_string) = COND #( WHEN lt_sort_table IS INITIAL THEN lv_default_sort ELSE concat_lines_of( table = lt_sort_table sep = ',' ) ). IF io_request IS BOUND. DATA(lt_expressions) = io_request-&gt;get_filter( )-&gt;get_as_ranges( ). LOOP AT lt_expressions INTO DATA(ls_expr). IF ls_expr-name = 'PICKTICKETID'. LOOP AT ls_expr-range INTO DATA(ls_range). IF ls_range-option = 'EQ'. lv_pickticketid = ls_range-low. EXIT. ENDIF. ENDLOOP. EXIT. ENDIF. ENDLOOP. ENDIF. " Build target URL for the external request DATA(lv_url) = |https://&lt;external domain url&gt;/pickTickets/{ lv_pickticketid }/images|. " Create HTTP client and set headers DATA lo_http_client TYPE REF TO if_http_client. cl_http_client=&gt;create_by_url( EXPORTING url = lv_url IMPORTING client = lo_http_client ). lo_http_client-&gt;request-&gt;set_header_field( name = 'client_id' value = '&lt;your_client_id&gt;' ). lo_http_client-&gt;request-&gt;set_header_field( name = 'client_secret' value = '&lt;your_client_secret&gt;' ). lo_http_client-&gt;send( ). lo_http_client-&gt;receive( ). DATA(lv_response) = lo_http_client-&gt;response-&gt;get_cdata( ). lo_http_client-&gt;close( ). " Parse JSON response to ABAP table DATA(lo_json) = NEW /ui2/cl_json( ). lo_json-&gt;deserialize( EXPORTING json = lv_response CHANGING data = lt_images ). " Return the data io_response-&gt;set_total_number_of_records( lines( lt_images ) ). io_response-&gt;set_data( lt_images ). ENDMETHOD. ENDCLASS.</code></pre><P><U><EM>*Replace* `&lt;external domain url&gt;`, `&lt;your_client_id&gt;`, and `&lt;your_client_secret&gt;` *with real values.*</EM></U></P><P><STRONG>5. Publish and Test Your OData Service</STRONG></P><UL><LI>Use `/IWFND/MAINT_SERVICE` or the service binding UI in Eclipse/ADT to publish your OData service.</LI><LI>Test the endpoint with a filter on `PickTicketId`:<BR />Example:&nbsp;<SPAN>/sap/opu/odata/sap/ZSB_IMAGESET/ZCE_IMAGESET?$filter= pickticketid eq '123456'</SPAN></LI></UL><P><U><STRONG>Key Takeaways</STRONG></U></P><UL><LI>Custom Entities in RAP allow you to virtualize data from external sources as standard OData.</LI><LI>You can leverage the **HTTP client functionalities** in ABAP to fetch data from any REST API.</LI><LI>RAP and ABAP Cloud stack are open for API-driven architectures.</LI><LI>Make sure to treat secrets and API credentials securely—avoid hardcoding in productive code.</LI></UL><P><STRONG>Conclusion</STRONG></P><P>You now have a **custom OData service** in SAP S/4HANA PCE, powered by the RAP framework, which brings in dynamic data from an **external API**. You can enhance, secure, and extend this pattern for many integration use cases—be it analytics dashboards, mobile apps, or UI5/Fiori apps!</P><P>Let me know your feedback, or reach out for specific questions.</P> 2026-01-08T14:08:04.222000+01:00 https://community.sap.com/t5/integration-blog-posts/sap-ecc-vs-s-4hana-integration-capabilities-a-practical-guide-for/ba-p/14306910 SAP ECC vs S/4HANA Integration Capabilities: A Practical Guide for Integration Architects 2026-01-16T17:05:43.629000+01:00 azhariqbal https://community.sap.com/t5/user/viewprofilepage/user-id/869409 <P class="lia-align-center" style="text-align: center;"><FONT size="6"><STRONG>SAP System Exposure: The Complete Integration Capability Guide for ECC &amp; S/4HANA&nbsp;<BR /></STRONG></FONT></P><P><STRONG>IMPORTANT NOTE:</STRONG></P><P>This guide is based on practical hands-on experience across SAP ECC and S/4HANA landscapes. While we've referenced official SAP documentation and community resources throughout, capabilities may vary based on:</P><UL><LI>NetWeaver version and support package levels</LI><LI>Installed add-ons and components</LI><LI>System configuration and authorizations</LI><LI>SAP release versions.</LI></UL><P>For architecture decisions and production implementations, always consult:</P><UL><LI>Official SAP Help documentation (<A href="https://help.sap.com" target="_blank" rel="noopener noreferrer">https://help.sap.com</A>)</LI><LI>SAP Notes for specific component details</LI><LI>SAP Business Accelerator Hub (<A href="https://api.sap.com" target="_blank" rel="noopener noreferrer">https://api.sap.com</A>) for released APIs</LI><LI>Your SAP Basis team for system-specific configurations</LI></UL><P>This document focuses on what SAP systems CAN expose and consume. Integration&nbsp;middleware patterns (SAP Integration Suite, PI/PO) are mentioned for context&nbsp;but are not the primary focus.</P><P><FONT size="5"><STRONG>1. INTRODUCTION</STRONG></FONT></P><P>When I'm asked to integrate an external system with SAP, the first question isn't "which tool should I use?" It's <STRONG>"what can SAP actually expose?"</STRONG></P><P>After few years working across SAP ECC and S/4HANA landscapes with Integration Suite, I've learned that understanding what's <EM>available</EM> in your SAP system is just as critical as knowing <EM>how</EM> to integrate it. Yet most integration guides skip this foundation and jump straight to implementation.</P><P>This is the reference guide, it maps every integration capability available in SAP ECC and S/4HANA On-Premises systems, explains when to use each protocol, and provides the checklists you need to prepare your systems for Integration Suite connectivity.</P><P><STRONG>What You'll Learn:</STRONG></P><UL><LI>Complete inventory of integration capabilities in ECC &amp; S/4HANA</LI><LI>RFC/BAPI, IDoc, OData, SOAP, and file interface fundamentals</LI><LI>Protocol comparison matrix with use case recommendations.</LI><LI>System preparation checklists for production readiness</LI><LI>Integration architecture patterns</LI><LI>Decision framework for choosing the right protocol.</LI></UL><P><STRONG>Who This Is For:</STRONG></P><UL><LI>Integration consultants working with SAP landscapes.</LI><LI>Solution architects designing SAP integrations.</LI><LI>Developers building connections to SAP systems.</LI><LI>Functional consultants exploring integration possibilities.</LI><LI>Anyone planning Integration Suite implementations.</LI></UL><P>Let's start with what SAP can actually give us.</P><P>&nbsp;</P><P><FONT size="5"><STRONG>2. SAP ECC INTEGRATION CAPABILITIES</STRONG></FONT></P><P>SAP ECC has been the backbone of enterprise operations for decades., it provides robust, battle-tested integration interfaces that still power thousands of integrations today.</P><P><STRONG>2.1 RFC (Remote Function Call) &amp; BAPIs</STRONG></P><P>RFC is SAP's proprietary protocol for synchronous communication between systems. BAPIs (Business Application Programming Interfaces) are standardized RFCs that provide access to SAP business objects and processes.</P><P><STRONG>Key Characteristics:</STRONG></P><UL><LI><STRONG>Synchronous:</STRONG> Call and wait for response</LI><LI><STRONG>Transactional:</STRONG> Can commit or rollback</LI><LI><STRONG>Type-safe:</STRONG> Strongly typed parameters.</LI><LI><STRONG>Widely available:</STRONG> Broad range of reusable standard BAPIs in ECC</LI></UL><P><STRONG>Common BAPIs You'll Use:</STRONG></P><TABLE><TBODY><TR><TD width="299px" height="50px"><P><STRONG>BAPI Name</STRONG></P></TD><TD width="161px" height="50px"><P><STRONG>Purpose</STRONG></P></TD><TD width="195px" height="50px"><P><STRONG>Use Case</STRONG></P></TD></TR><TR><TD width="299px" height="77px"><P>BAPI_PO_CREATE1</P></TD><TD width="161px" height="77px"><P>Create Purchase Order</P></TD><TD width="195px" height="77px"><P>External procurement systems posting POs</P></TD></TR><TR><TD width="299px" height="77px"><P>BAPI_GOODSMVT_CREATE</P></TD><TD width="161px" height="77px"><P>Post Goods Movement</P></TD><TD width="195px" height="77px"><P>Warehouse systems updating inventory</P></TD></TR><TR><TD width="299px" height="77px"><P>BAPI_MATERIAL_GETDETAIL</P></TD><TD width="161px" height="77px"><P>Get Material Master</P></TD><TD width="195px" height="77px"><P>E-commerce platforms fetching product data</P></TD></TR><TR><TD width="299px" height="77px"><P>BAPI_ACC_DOCUMENT_POST</P></TD><TD width="161px" height="77px"><P>Post Financial Document</P></TD><TD width="195px" height="77px"><P>External systems creating FI documents</P></TD></TR><TR><TD width="299px" height="77px"><P>BAPI_SALESORDER_CREATEFROMDAT2</P></TD><TD width="161px" height="77px"><P>Create Sales Order</P></TD><TD width="195px" height="77px"><P>CRM systems posting orders to SAP</P></TD></TR><TR><TD width="299px" height="77px"><P>BAPI_CUSTOMER_GETDETAIL</P></TD><TD width="161px" height="77px"><P>Get Customer Master</P></TD><TD width="195px" height="77px"><P>External apps accessing customer data</P></TD></TR></TBODY></TABLE><P class=""><U><STRONG>NOTE:</STRONG>&nbsp;</U></P><P class="">BAPIs do NOT auto-commit. The calling program must explicitly control transaction boundaries:</P><P class=""><STRONG>To Save Changes:</STRONG> Call BAPI_TRANSACTION_COMMIT</P><P class=""><STRONG>To Discard Changes</STRONG>: Call BAPI_TRANSACTION_ROLLBACK</P><P class="">This allows multiple BAPIs to be grouped in a single <STRONG>Logical Unit of Work (LUW).</STRONG></P><P class=""><STRONG><U>Reference: SAP Note 0131838</U></STRONG></P><P><STRONG>Technical Details:</STRONG></P><UL><LI><STRONG>Access:</STRONG> Transaction <STRONG>SE37</STRONG> (Function Builder)</LI><LI><STRONG>Discovery:</STRONG> Search pattern "BAPI_*"</LI><LI><STRONG>Testing:</STRONG> SE37 → Test/Execute</LI><LI><STRONG>Authentication:</STRONG> RFC destination in SM59</LI></UL><P><STRONG>When to Use RFCs/BAPIs:</STRONG></P><P><STRONG>Use When:</STRONG></P><UL><LI>You need real-time, synchronous responses</LI><LI>Transaction integrity is critical (commit/rollback)</LI><LI>Complex business logic required</LI><LI>Creating or updating SAP documents</LI><LI>Reading data with complex selection criteria</LI></UL><P><STRONG>&nbsp;</STRONG><STRONG>Integration Pattern:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_17-1768327525598.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361080i9302A9BD0DA4D490/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_17-1768327525598.png" alt="azhariqbal_17-1768327525598.png" /></span></P><P><STRONG>EXAMPLE SCENARIO: </STRONG></P><P><STRONG>Purchase Order Creation from Web Portal</STRONG></P><P><STRONG>Business Context:</STRONG><BR />Manufacturing company has external procurement portal where buyers create purchase requests. Once approved, these need to become POs in SAP ECC instantly.</P><P><STRONG>Technical Setup:</STRONG></P><UL><LI>Source: Custom web portal (Node.js/React)</LI><LI>Target: SAP ECC 6.0</LI><LI>BAPI: BAPI_PO_CREATE1</LI><LI>Frequency: Real-time (on PR approval)</LI><LI>Volume: 50-100 POs per day</LI></UL><P><STRONG>Process Flow:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_1-1768326928992.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361064i0DC26261B3AEC874/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_1-1768326928992.png" alt="azhariqbal_1-1768326928992.png" /></span></P><P><STRONG>2.2 IDoc (Intermediate Document)</STRONG></P><P>IDoc (Intermediate Document) is SAP’s <STRONG>standard asynchronous integration mechanism</STRONG>.<BR />It is designed for <STRONG>high-volume, reliable, loosely coupled</STRONG> data exchange between SAP and external systems.</P><P>An IDoc is:</P><UL><LI>Self-contained</LI><LI>Status-driven</LI><LI>Processed independently of user interaction</LI></UL><P>This makes IDocs ideal for <STRONG>batch integrations, master data replication, and guaranteed delivery scenarios</STRONG>.</P><P><STRONG>Key Characteristics:</STRONG></P><UL><LI><STRONG>Asynchronous:</STRONG> Fire-and-forget or guaranteed delivery</LI><LI><STRONG>Bulk-friendly:</STRONG> Efficient for large volumes</LI><LI><STRONG>Loosely coupled:</STRONG> Systems don't need to be online simultaneously</LI><LI><STRONG>Status-tracked:</STRONG> Built-in monitoring (WE02, WE05)</LI></UL><P><STRONG>IDoc Structure:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_2-1768326928994.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361063i41FA3611E2107FB3/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_2-1768326928994.png" alt="azhariqbal_2-1768326928994.png" /></span></P><P><STRONG>Common IDoc Types:</STRONG></P><TABLE width="604"><TBODY><TR><TD width="123"><P><STRONG>IDoc Type</STRONG></P></TD><TD width="132"><P><STRONG>Message Type</STRONG></P></TD><TD width="170"><P><STRONG>Purpose</STRONG></P></TD><TD width="180"><P><STRONG>Direction</STRONG></P></TD></TR><TR><TD width="123"><P>ORDERS05</P></TD><TD width="132"><P>ORDERS</P></TD><TD width="170"><P>Purchase Orders</P></TD><TD width="180"><P>Outbound/Inbound</P></TD></TR><TR><TD width="123"><P>INVOIC02</P></TD><TD width="132"><P>INVOIC</P></TD><TD width="170"><P>Invoices</P></TD><TD width="180"><P>Outbound</P></TD></TR><TR><TD width="123"><P>MATMAS05</P></TD><TD width="132"><P>MATMAS</P></TD><TD width="170"><P>Material Master</P></TD><TD width="180"><P>Outbound</P></TD></TR><TR><TD width="123"><P>DESADV01</P></TD><TD width="132"><P>DESADV</P></TD><TD width="170"><P>Delivery Notes</P></TD><TD width="180"><P>Outbound</P></TD></TR><TR><TD width="123"><P>WMMBXY03</P></TD><TD width="132"><P>WMMBXY</P></TD><TD width="170"><P>Goods Movements</P></TD><TD width="180"><P>Outbound</P></TD></TR><TR><TD width="123"><P>DEBMAS06</P></TD><TD width="132"><P>DEBMAS</P></TD><TD width="170"><P>Customer Master</P></TD><TD width="180"><P>Outbound</P></TD></TR><TR><TD width="123"><P>CREMAS03</P></TD><TD width="132"><P>CREMAS</P></TD><TD width="170"><P>Vendor Master</P></TD><TD width="180"><P>Outbound</P></TD></TR></TBODY></TABLE><P><STRONG>Technical Details:</STRONG></P><UL><LI><STRONG>Access</STRONG>: Transaction WE30 (IDoc Type Development)</LI><LI><STRONG>Partner Setup</STRONG>: WE20 (Partner Profiles)</LI><LI><STRONG>Port Config</STRONG>: WE21 (Port Definition)</LI><LI><STRONG>Testing</STRONG>: WE19 (Test Tool)</LI><LI><STRONG>Monitoring</STRONG>: WE02 (IDoc Display), WE05 (IDoc List)</LI><LI><STRONG>Triggering</STRONG>: Message Control, Change Pointers, IDOC_OUTPUT_* FMs</LI></UL><P><STRONG>When to Use IDocs:</STRONG></P><P><STRONG>Use When:</STRONG></P><UL><LI>High-volume data transfer (thousands of records)</LI><LI>Asynchronous processing acceptable</LI><LI>Standard SAP business documents (PO, Invoice, etc.)</LI><LI>Batch processing requirements.</LI><LI>Need for guaranteed delivery with retry.</LI><LI>Master data replication</LI></UL><P><STRONG>Integration Patterns:</STRONG></P><P><STRONG>Outbound (ECC </STRONG><STRONG>→</STRONG><STRONG> External):</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_18-1768327554627.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361081i567E7A9E12FD1622/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_18-1768327554627.png" alt="azhariqbal_18-1768327554627.png" /></span></P><P><STRONG>Inbound (External </STRONG><STRONG>→</STRONG><STRONG> ECC):</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_19-1768327566112.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361082iF0A48F297A6ADFE4/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_19-1768327566112.png" alt="azhariqbal_19-1768327566112.png" /></span></P><P><STRONG>EXAMPLE SCENARIO: </STRONG></P><P><STRONG>Nightly Material Master Sync to Data Warehouse</STRONG></P><P>Company needs to send all material master changes from ECC to external data warehouse every night for reporting and analytics.</P><P><STRONG>Technical Setup:</STRONG></P><UL><LI><STRONG>Source</STRONG>: SAP ECC 6.0</LI><LI><STRONG>Target</STRONG>: External Data Warehouse (Snowflake)</LI><LI><STRONG>IDoc Type</STRONG>: MATMAS05</LI><LI><STRONG>Frequency</STRONG>: Nightly batch (2 AM)</LI><LI><STRONG>Volume</STRONG>: 5,000-10,000 materials per night</LI></UL><P><STRONG>&nbsp;</STRONG><STRONG>End-to-End IDoc Asynchronous Integration Flow </STRONG></P><OL><LI>Material master records are created or updated in SAP ECC throughout the day (MM01/MM02).</LI><LI>Change pointers capture only relevant delta changes for the MATMAS message type.</LI><LI>At 2:00 AM, the BD21 batch job executes during off-peak hours.</LI><LI>The system reads accumulated change pointers.</LI><LI>A MATMAS05 IDoc is generated for each changed material.</LI><LI>IDocs are sent via partner profile <STRONG>WAREHOUSE</STRONG> using an HTTP port.</LI><LI>SAP CPI receives the IDoc XML through the IDoc adapter.</LI><LI>CPI parses the hierarchical IDoc structure.</LI><LI>Business data is transformed into a target JSON format.</LI><LI>Records are grouped into batches of 1,000 for optimized processing.</LI><LI>CPI posts each batch to the Snowflake bulk API.</LI><LI>On success, IDocs are updated to status <STRONG>53 (Posted)</STRONG>.</LI><LI>On failure, IDocs move to <STRONG>51 (Error)</STRONG> and are retried in the next batch cycle.</LI><LI>A consolidated processing report is emailed to the data team at 3:00 AM.</LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_5-1768326929160.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361066i9ABF593BDC4B6DC5/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_5-1768326929160.png" alt="azhariqbal_5-1768326929160.png" /></span></P><P><STRONG>2.3 SOAP Web Services</STRONG></P><P>SAP ECC exposes business functionality as <STRONG>SOAP-based web services</STRONG>.<BR />These services are <STRONG>WSDL-driven</STRONG>, <STRONG>XML-based</STRONG>, and follow a strict <STRONG>request–response</STRONG> contract over HTTP/HTTPS.</P><P>SOAP services are widely used in <STRONG>legacy enterprise landscapes</STRONG>, especially where Java or .NET middleware already exists.</P><P><STRONG>Key Characteristics:</STRONG></P><UL><LI><STRONG>Standards-based:</STRONG> WSDL, SOAP 1.1/1.2, WS-* standards</LI><LI><STRONG>Synchronous:</STRONG> Request-response pattern</LI><LI><STRONG>Platform-agnostic:</STRONG> Any SOAP client can consume</LI><LI><STRONG>Structured:</STRONG> XSD-defined schemas</LI></UL><P><STRONG>Technical Details:</STRONG></P><UL><LI>Access: Transaction SOAMANAGER (Service Administration)</LI><LI>Development: SPROXY (Proxy Development)</LI><LI>Types:<UL><LI>Provider Services (ECC exposes to external)</LI><LI>Consumer Services (ECC consumes from external)</LI></UL></LI></UL><P><STRONG>When to Use SOAP:</STRONG></P><P><STRONG>Use When:</STRONG></P><UL><LI>External system requires SOAP/WSDL</LI><LI>Enterprise service repository already defined.</LI><LI>Need WS-Security features.</LI><LI>Cross-platform integration with Java/.NET systems</LI></UL><P><STRONG>Integration Pattern:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_20-1768327603077.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361083i5F5C63D4D5FCE4DD/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_20-1768327603077.png" alt="azhariqbal_20-1768327603077.png" /></span></P><P><STRONG>EXAMPLE SCENARIO: </STRONG></P><P><STRONG>Legacy Java Middleware Posting Financial Documents</STRONG></P><P>Existing Java-based middleware system (10 years old) collects invoice data from multiple subsidiaries and needs to post consolidated financial documents to ECC.</P><P><STRONG>Technical Setup:</STRONG></P><UL><LI><STRONG>Source</STRONG>: Java middleware (Spring Boot)</LI><LI><STRONG>Target</STRONG>: SAP ECC 6.0</LI><LI><STRONG>Service</STRONG>: FinancialDocumentCreate (Enterprise Service)</LI><LI><STRONG>Frequency</STRONG>: Real-time as invoices arrive</LI><LI><STRONG>Volume</STRONG>: 200-300 documents per day</LI></UL><P><STRONG>Process Flow:</STRONG></P><OL><LI>Java app collects invoice from subsidiaries.</LI><LI>Validates and enriches data.</LI><LI>Builds SOAP XML per WSDL specification.</LI><LI>Sends SOAP request to CPI endpoint.</LI><LI>CPI routes to ECC SOAMANAGER</LI><LI>Enterprise service validates structure.</LI><LI>Calls backend BAPI for FI posting.</LI><LI>Document posted, accounting entries created.</LI><LI>Returns FI document number in SOAP response.</LI><LI>Java app stores document number for reference.</LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_7-1768326929256.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361070iECCE50961C5A53E3/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_7-1768326929256.png" alt="azhariqbal_7-1768326929256.png" /></span></P><P><STRONG>2.4 File Interfaces</STRONG></P><P>File interfaces are one of the oldest and most reliable integration mechanisms in <STRONG>SAP ECC</STRONG>, designed for <STRONG>scheduled, high-volume, non-real-time</STRONG> data exchange.<BR />Data is exchanged using physical files that are picked up, processed, and archived in batch cycles.</P><P>This pattern is still widely used for:</P><UL><LI>Vendor uploads</LI><LI>Price lists</LI><LI>Mass master data changes</LI><LI>One-time or recurring migrations</LI></UL><P><STRONG>File Formats:</STRONG></P><UL><LI>Flat files (fixed width, delimited)</LI><LI>CSV/Excel</LI><LI>XML</LI><LI>Custom formats</LI></UL><P><STRONG>Technical Approaches:</STRONG></P><UL><LI><STRONG>Output:</STRONG> Report programs, BDC, LSMW</LI><LI><STRONG>Input:</STRONG> Batch Input (BDC), Direct Input, BAPI calls</LI></UL><P><STRONG>When to Use Files:</STRONG></P><P><STRONG>Use When:</STRONG></P><UL><LI>Batch processing windows.</LI><LI>Large data migrations</LI><LI>Legacy system integration</LI><LI>Offline scenarios</LI></UL><P><STRONG>Example Scenario: Nightly Vendor Price Upload (CSV)</STRONG></P><P>The procurement team receives <STRONG>daily price updates</STRONG> from multiple vendors.<BR />Each vendor uploads a <STRONG>CSV file</STRONG> containing updated material prices, which must be reflected in SAP ECC before business hours.</P><P><STRONG>Technical Setup</STRONG></P><UL><LI><STRONG>Source:</STRONG> Vendor SFTP servers</LI><LI><STRONG>Integration Layer:</STRONG> SAP CPI</LI><LI><STRONG>Target:</STRONG> SAP ECC 6.0</LI><LI><STRONG>File Type:</STRONG> CSV</LI><LI><STRONG>Schedule:</STRONG> Nightly (4:00 AM)</LI><LI><STRONG>Volume:</STRONG> ~50 files, 10,000–15,000 records</LI></UL><P><STRONG>Process Flow (Clear &amp; Sequential)</STRONG></P><OL><LI>Vendors upload CSV price files to the <STRONG>SFTP server</STRONG> between <STRONG>1:00–3:00 AM</STRONG></LI><LI>At <STRONG>4:00 AM</STRONG>, SAP CPI scheduler triggers the batch job</LI><LI>CPI connects to SFTP and downloads all available files</LI><LI>For each file, CPI:</LI><UL><LI>Identifies the vendor from the file name</LI><LI>Parses the CSV line by line</LI><LI>Validates mandatory fields and price values</LI></UL><LI>For each valid record:</LI><UL><LI>CPI calls BAPI_MATERIAL_SAVEDATA</LI><LI>Updates the vendor price / info record</LI></UL><LI>Processing continues even if individual records fail</LI><LI>CPI writes:</LI><UL><LI>Success entries to the success log</LI><LI>Failed records to the error log with reason</LI></UL><LI>Processed files are archived to /archive</LI><LI>A summary report is generated</LI><LI>Email notification is sent to the procurement team</LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_8-1768326929324.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361071i13A73C45565D562A/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_8-1768326929324.png" alt="azhariqbal_8-1768326929324.png" /></span></P><P><STRONG>2.5 OData Services via SAP NetWeaver Gateway</STRONG></P><P>SAP NetWeaver Gateway is a fully supported SAP component that enables ECC to expose RESTful OData services with JSON and XML support.</P><P class=""><STRONG>Key Characteristics</STRONG></P><UL><LI><STRONG>Protocol</STRONG>: HTTP/HTTPS (RESTful)</LI><LI><STRONG>Data Format</STRONG>: JSON or XML (via $format=json or Accept header)</LI><LI><STRONG>Query Capabilities</STRONG>: $filter, $select, $expand, $orderby, $top, $skip</LI><LI><STRONG>CRUD Operations:</STRONG> GET, POST, PUT, PATCH, DELETE Self-Describing: $metadata endpoint</LI></UL><P class=""><STRONG>Technical Access</STRONG></P><UL><LI><STRONG>Service Builder:</STRONG> Transaction SEGW (Service Artifact Generation Wizard)</LI><LI><STRONG>Service Registration:</STRONG> Transaction /IWFND/MAINT_SERVICE</LI><LI><STRONG>Service Testing:</STRONG> Transaction /IWFND/GW_CLIENT</LI><LI><STRONG>Error Monitoring:</STRONG> Transaction /IWFND/ERROR_LOG</LI><LI><STRONG>ICF Nodes:</STRONG> Transaction SICF (activate HTTP services)</LI></UL><P class=""><STRONG>OData Query Examples</STRONG></P><P class=""><STRONG>Basic Read:</STRONG> GET /sap/opu/odata/sap/Z_PRODUCT_SRV/Products</P><P class=""><STRONG>Filtering:</STRONG> GET /sap/opu/odata/sap/Z_PRODUCT_SRV/Products?$filter=Price gt 100</P><P class=""><STRONG>JSON Format:</STRONG> GET /sap/opu/odata/sap/Z_PRODUCT_SRV/Products?$format=json</P><P class=""><STRONG>Metadata Discovery:</STRONG> GET /sap/opu/odata/sap/Z_PRODUCT_SRV/$metadata</P><P class=""><STRONG>When to Use Gateway OData</STRONG></P><P class=""><STRONG>Use When:</STRONG></P><UL class=""><LI>Building Fiori applications on ECC</LI><LI>Modern web/mobile applications need REST APIs</LI><LI>External developers need API access</LI><LI>JSON format preferred over XML</LI></UL><P><FONT size="4"><STRONG>2.6 Event Mechanisms in ECC</STRONG></FONT></P><P><FONT size="4">SAP ECC provides several mechanisms to trigger integrations based on business events. While not as standardized as S/4HANA's Event Enablement Framework, these are widely used in production environments.</FONT></P><P class=""><STRONG>Available Event Mechanisms:</STRONG></P><P class=""><STRONG>Change Pointers</STRONG></P><P class="">Track changes to master data and trigger IDoc generation.</P><P class="">Technical Details:</P><UL class=""><LI>Purpose: Master data change detection (Material, Customer, Vendor)</LI><LI>Transaction BD50: Activate change pointers</LI><LI>Transaction BD51: Activate for message types</LI><LI>Transaction BD52: Assign fields to monitor</LI><LI>Transaction BD21: Create IDocs from change pointers</LI><LI>Processing: Batch-driven (scheduled job RBDMIDOC)</LI></UL><P><STRONG>Workflow Events</STRONG></P><P class="">Trigger when specific business transactions occur.</P><P class="">Technical Details:</P><UL class=""><LI>Purpose: React to business document lifecycle events</LI><LI>Transaction SWE2: Event Type Linkages</LI><LI>Transaction SWEL: Event Trace</LI><LI>Event Pattern: BusinessObject.EventName Example: BUS2032.CREATED (Sales Order Created)</LI><LI>Subscribers: Workflows, function modules</LI></UL><P class=""><STRONG>Output Determination (Message Control)</STRONG></P><UL class=""><LI>Application-specific (MM, SD, FI)</LI><LI>Condition-based triggering</LI><LI>Can generate IDocs, emails, print outputs</LI><LI>Transaction: <CODE>NACE</CODE> (Output Control)</LI></UL><P class=""><STRONG>BAdIs (Business Add-Ins)</STRONG></P><UL class=""><LI>Enhancement points in standard SAP code</LI><LI>Can call external systems via RFC</LI><LI>Transaction: <FONT color="#000000"><CODE>SE18</CODE></FONT> (BAdI Definition), <CODE>SE19</CODE> (BAdI Implementation)</LI></UL><P class=""><STRONG>User Exits / Enhancement Points</STRONG></P><UL class=""><LI>Custom code injection points</LI><LI>Can trigger HTTP calls, RFCs to external systems</LI><LI>Transaction: <CODE>CMOD</CODE> (Enhancements)</LI></UL><P><FONT size="6"><STRONG>3. SAP S/4HANA ON-PREMISE INTEGRATION CAPABILITIES</STRONG></FONT></P><P>S/4HANA builds on everything ECC provides and adds modern integration capabilities that change the game.</P><P><STRONG>3.1 EVERYTHING ECC HAS, ENHANCED</STRONG></P><P><STRONG>RFCs/BAPIs:</STRONG></P><UL><LI>All ECC BAPIs available</LI><LI>New S/4HANA-specific BAPIs</LI><LI>Better performance (HANA database)</LI><LI>CDS view consumption via RFCs</LI></UL><P><STRONG>IDocs:</STRONG></P><UL><LI>All ECC IDoc types</LI><LI>Improved processing speed</LI><LI>Better error handling</LI><LI>Enhanced monitoring</LI></UL><P><STRONG>SOAP Services:</STRONG></P><UL><LI>All enterprise services</LI><LI>Service adaptation framework</LI><LI>Better performance</LI></UL><P><STRONG>3.2 ODATA SERVICES (Enhanced in S/4HANA)</STRONG></P><P>OData is the REST-based protocol that makes SAP data accessible like modern APIs. OData introduces <STRONG>true RESTful APIs</STRONG>, designed for:</P><UL><LI>Web applications</LI><LI>Mobile apps</LI><LI>External developer consumption</LI><LI>Real-time queries</LI></UL><P class="">S/4HANA enhances OData capabilities with native support, pre-built APIs, and the RAP framework for OData V4.</P><P class="">What's Enhanced from ECC:</P><UL class=""><LI>OData V2 embedded by default&nbsp;</LI><LI>OData V4 support via RAP framework (new capability)</LI><LI>Pre-built released APIs in SAP Business Accelerator Hub</LI><LI>HANA-optimized query performance</LI></UL><P><STRONG>Why OData Matters</STRONG></P><UL><LI>REST over HTTP</LI><LI>JSON-first</LI><LI>Queryable data access</LI><LI>Self-describing APIs</LI></UL><P><STRONG>Key Characteristics:</STRONG></P><UL><LI>RESTful: Standard HTTP methods (GET, POST, PUT, DELETE)</LI><LI>JSON/XML: Modern data formats</LI><LI>Query-capable: $filter, $select, $expand, $orderby, $top, $skip</LI><LI>Self-documenting: $metadata endpoint</LI><LI>Stateless: No session management needed</LI></UL><P><STRONG>SAP Gateway Architecture:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_21-1768327761911.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361085iDF2D4DEB3B735116/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_21-1768327761911.png" alt="azhariqbal_21-1768327761911.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_22-1768327773791.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361086iC596D410AA82FF17/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_22-1768327773791.png" alt="azhariqbal_22-1768327773791.png" /></span></P><P><STRONG>Standard S/4HANA APIs (Examples):</STRONG></P><TABLE><TBODY><TR><TD width="264"><P><STRONG>API Service</STRONG></P></TD><TD width="192"><P><STRONG>Business Purpose</STRONG></P></TD><TD width="167"><P><STRONG>Key Entity Sets</STRONG></P></TD></TR><TR><TD width="264"><P><STRONG>API_PURCHASEORDER_PROCESS_SRV</STRONG></P></TD><TD width="192"><P>Purchase Order lifecycle management</P></TD><TD width="167"><P>A_PurchaseOrder, A_PurchaseOrderItem</P></TD></TR><TR><TD width="264"><P><STRONG>API_PRODUCT_SRV</STRONG></P></TD><TD width="192"><P>Material / Product master data</P></TD><TD width="167"><P>A_Product, A_ProductDescription</P></TD></TR><TR><TD width="264"><P><STRONG>API_SALES_ORDER_SRV</STRONG></P></TD><TD width="192"><P>Sales order processing</P></TD><TD width="167"><P>A_SalesOrder, A_SalesOrderItem</P></TD></TR><TR><TD width="264"><P><STRONG>API_BUSINESS_PARTNER</STRONG></P></TD><TD width="192"><P>Unified business partner model</P></TD><TD width="167"><P>A_BusinessPartner, A_BPContactAddress</P></TD></TR><TR><TD width="264"><P><STRONG>API_MATERIAL_STOCK_SRV</STRONG></P></TD><TD width="192"><P>Inventory and stock levels</P></TD><TD width="167"><P>A_MaterialStock</P></TD></TR></TBODY></TABLE><P><STRONG>Technical Details:</STRONG></P><UL><LI><STRONG>Service Registration:</STRONG> /IWFND/MAINT_SERVICE</LI><LI><STRONG>Testing:</STRONG> /IWFND/GW_CLIENT</LI><LI><STRONG>Development</STRONG>: SEGW (Gateway Service Builder)</LI><LI><STRONG>Monitoring:</STRONG> /IWFND/ERROR_LOG</LI></UL><P><STRONG>OData Query Capabilities</STRONG></P><P><STRONG>Basic Read</STRONG></P><P>GET /sap/opu/odata/sap/API_PURCHASEORDER_PROCESS_SRV/A_PurchaseOrder</P><P><STRONG>Filtering</STRONG></P><P>GET .../A_PurchaseOrder</P><P>?$filter=DocumentDate ge datetime'2025-01-01'</P><P>&nbsp;and PurchaseOrderType eq 'NB'</P><P><STRONG>Selecting Specific Fields</STRONG></P><P>GET .../A_PurchaseOrder</P><P>?$select=PurchaseOrder,Supplier,DocumentDate,TotalAmount</P><P><STRONG>Expanding Navigation Properties</STRONG></P><P>GET .../A_PurchaseOrder('4500000001')</P><P>?$expand=to_PurchaseOrderItem</P><P><STRONG>Pagination</STRONG></P><P>GET .../A_PurchaseOrder?$top=100&amp;$skip=0</P><P><STRONG>Response:</STRONG></P><P>"__next": "...&amp;$skiptoken=100"</P><P><STRONG>Metadata Discovery</STRONG></P><P>GET /sap/opu/odata/sap/API_PURCHASEORDER_PROCESS_SRV/$metadata</P><P>Returns:</P><UL><LI>Entity sets</LI><LI>Properties</LI><LI>Associations</LI></UL><P><STRONG>When to Use OData</STRONG></P><P><STRONG>Use When</STRONG></P><UL><LI>Modern web or mobile applications</LI><LI>Real-time queries required</LI><LI>REST/JSON integration</LI><LI>Flexible query support needed</LI></UL><P><STRONG>EXAMPLE SCENARIO: Mobile Sales App Querying Products</STRONG></P><P><STRONG>Business Context:</STRONG></P><P>Sales representatives use mobile app to check product availability, pricing, and specifications while visiting customers. Need instant access to product catalog with real-time stock levels.</P><P><STRONG>Technical Setup:</STRONG></P><UL><LI><STRONG>Source</STRONG>: React Native mobile app</LI><LI><STRONG>Target</STRONG>: S/4HANA On-Premise</LI><LI><STRONG>API</STRONG>: API_PRODUCT_SRV, API_MATERIAL_STOCK_SRV</LI><LI><STRONG>Frequency</STRONG>: Real-time as sales rep searches</LI><LI><STRONG>Volume</STRONG>: 500-1,000 queries per day</LI></UL><P><STRONG>Process Flow:</STRONG></P><OL><LI>Sales rep searches "Bearing" in mobile app</LI><LI>App sends HTTP GET to CPI endpoint</LI><LI>CPI forwards to S/4HANA Gateway</LI><LI>Gateway routes to Data Provider Class</LI><LI>DPC queries HANA database (ultra-fast)</LI><LI>Returns matching products as JSON</LI><LI>For each product, fetch stock level</LI><LI>Combine product + stock data</LI><LI>Response returns to mobile app</LI><LI>Rep sees list: 15 products with prices and stock</LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_23-1768327892187.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361087i913B499A5A45BBB0/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_23-1768327892187.png" alt="azhariqbal_23-1768327892187.png" /></span></P><P><STRONG>3.3 CDS Views as Integration Endpoints</STRONG></P><P>Core Data Services (CDS) views are <STRONG>HANA-optimized semantic data models</STRONG> defined in S/4HANA. They represent business entities and logic at the database level and can be exposed directly for integration.</P><P><STRONG>CDS views can be:</STRONG></P><UL><LI>Exposed as <STRONG>OData services</STRONG> via SAP Gateway</LI><LI>Consumed internally or externally via <STRONG>RFC-enabled function modules</STRONG></LI></UL><P><STRONG>Key Benefits</STRONG></P><UL><LI><STRONG>High performance:</STRONG> Logic is pushed down to the HANA database</LI><LI><STRONG>Pre-aggregated data:</STRONG> Reduces processing in the application layer</LI><LI><STRONG>Embedded business logic:</STRONG> Calculations, annotations, and semantics included</LI><LI><STRONG>Rich relationships:</STRONG> Associations allow navigation across related entities</LI></UL><P><STRONG>Process Flow</STRONG></P><P>CDS View → Gateway Service → OData → Integration Suite</P><P><STRONG>3.4 SAP Business Events &amp; Real-Time Integration</STRONG></P><P>S/4HANA introduces <STRONG>native event-driven integration capabilities</STRONG>, allowing systems to react immediately to business changes instead of relying on batch jobs or polling.</P><P>Key enhancements include:</P><UL><LI>Standardized <STRONG>business event triggers</STRONG></LI><LI>Improved <STRONG>change detection</STRONG></LI><LI>Workflow-driven event publishing</LI><LI>Native integration with <STRONG>SAP Event Mesh</STRONG></LI></UL><P><STRONG>Note: Event Mesh provides additional capabilities like publish/subscribe, guaranteed delivery queues, and multiple independent subscribers.</STRONG></P><P><STRONG>Event-Driven Integration Pattern</STRONG></P><P>S/4HANA Business Event → Event Mesh Topic → Multiple Subscribers (CPI iFlows) → External Systems</P><P><STRONG>Typical Use Cases</STRONG></P><UL><LI>Purchase order approved → Notify procurement portal</LI><LI>Stock level falls below threshold → Trigger replenishment</LI><LI>Sales order created → Update CRM system</LI><LI>Invoice posted → Notify payment or reporting systems</LI></UL><P><STRONG>EXAMPLE SCENARIO: </STRONG></P><P><STRONG>Real-Time Stock Alerts to E-Commerce</STRONG></P><P>E-commerce website needs instant notifications when product stock falls below threshold to display "Low Stock" warnings and trigger replenishment.</P><P><STRONG>Technical Setup:</STRONG></P><UL><LI><STRONG>Source</STRONG>: S/4HANA On-Premises</LI><LI><STRONG>Targets</STRONG>: E-commerce website, Replenishment system, Analytics dashboard</LI><LI><STRONG>Event</STRONG>: Material.StockChanged</LI><LI><STRONG>Frequency</STRONG>: Real-time (as goods movements occur)</LI><LI><STRONG>Volume</STRONG>: 2,000-3,000 events per day</LI></UL><P><STRONG>Step-by-Step Flow</STRONG></P><OL><LI><STRONG>Goods Issue Posted</STRONG><UL><LI>A goods issue is posted in <STRONG>S/4HANA</STRONG> using transaction <STRONG>MIGO</STRONG>.</LI></UL></LI><LI><STRONG>Stock Update in HANA</STRONG><UL><LI>The stock quantity is immediately updated in the <STRONG>HANA database</STRONG>.</LI></UL></LI><LI><STRONG>Business Event Triggered</STRONG><UL><LI>The system triggers the business event <STRONG>Material.StockChanged</STRONG>.</LI></UL></LI><LI><STRONG>Event Published</STRONG><UL><LI>The event is published to <STRONG>SAP Event Mesh</STRONG>.</LI><LI><STRONG>Topic:</STRONG> inventory/changes</LI></UL></LI><LI><STRONG>Parallel Event Consumption</STRONG><UL><LI>Multiple systems subscribe to the same event and process it independently.</LI></UL></LI></OL><P><STRONG>Subscriber A – E-Commerce System</STRONG></P><UL><LI>Receives the event through a <STRONG>CPI iFlow</STRONG></LI><LI>Updates the product page inventory</LI><LI>Displays a <STRONG>“Low Stock”</STRONG> indicator (e.g., <EM>“Only 75 left”</EM>)</LI></UL><P><STRONG>Subscriber B – Replenishment System</STRONG></P><UL><LI>Evaluates stock against reorder threshold (<STRONG>100 units</STRONG>)</LI><LI>If below threshold:<UL><LI>Creates a <STRONG>Purchase Requisition</STRONG></LI><LI>Notifies the purchasing team</LI></UL></LI></UL><P><STRONG>Subscriber C – Analytics Dashboard</STRONG></P><UL><LI>Updates real-time inventory charts</LI><LI>Stores event data in the data warehouse for reporting</LI></UL><OL><LI><STRONG>Independent Processing</STRONG><UL><LI>Each subscriber processes the event <STRONG>independently and in parallel</STRONG>.</LI></UL></LI><LI><STRONG>Acknowledgement</STRONG><UL><LI>Each system sends an acknowledgement back to <STRONG>Event Mesh</STRONG>.</LI></UL></LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_24-1768328032789.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361088i79A0CFE9EABEB64B/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_24-1768328032789.png" alt="azhariqbal_24-1768328032789.png" /></span></P><P>&nbsp;</P><P>Events are published once and delivered to <STRONG>multiple consumers in parallel</STRONG>, without tight coupling.</P><P><FONT size="6"><STRONG>4. INTEGRATION SCENARIOS &amp; COMPARISON</STRONG></FONT></P><P>Now that we understand what each system offers, let's look at how to choose the right protocol and see complete integration scenarios.</P><P><STRONG>4.2&nbsp; Decision Tree</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_25-1768328094839.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361089iDE99D1369B302D0F/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_25-1768328094839.png" alt="azhariqbal_25-1768328094839.png" /></span></P><P><STRONG>4.3 Cross-Protocol Integration Scenarios</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_14-1768326929726.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361075iB6216ABB781A5DA3/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_14-1768326929726.png" alt="azhariqbal_14-1768326929726.png" /></span></P><P>&nbsp;</P><P><STRONG>Scenario 1: Manufacturing Company - Complete Landscape</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_15-1768326929770.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361078iBB7B1B3472921A27/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_15-1768326929770.png" alt="azhariqbal_15-1768326929770.png" /></span></P><P><STRONG>Integration Breakdown</STRONG></P><OL><LI><STRONG>Web Portal </STRONG><STRONG>→</STRONG><STRONG> SAP ECC (Purchase Orders)</STRONG></LI><UL><LI><STRONG>Protocol:</STRONG> REST → RFC/BAPI</LI><LI><STRONG>Purpose:</STRONG> Real-time purchase order creation</LI><LI><STRONG>Volume:</STRONG> ~100 purchase orders per day</LI></UL><LI><STRONG>SAP ECC </STRONG><STRONG>→</STRONG><STRONG> Data Warehouse (Material Master)</STRONG></LI><UL><LI><STRONG>Protocol:</STRONG> IDoc → JSON</LI><LI><STRONG>Purpose:</STRONG> Nightly master data synchronization</LI><LI><STRONG>Volume:</STRONG> ~10,000 materials per night</LI></UL><LI><STRONG>Mobile App </STRONG><STRONG>→</STRONG><STRONG> SAP S/4HANA (Product Catalog)</STRONG></LI><UL><LI><STRONG>Protocol:</STRONG> REST → OData</LI><LI><STRONG>Purpose:</STRONG> Real-time product search and availability</LI><LI><STRONG>Volume:</STRONG> ~1,000 queries per day</LI></UL><LI><STRONG>SAP S/4HANA </STRONG><STRONG>→</STRONG><STRONG> E-Commerce Platform (Stock Alerts)</STRONG></LI><UL><LI><STRONG>Protocol:</STRONG> Business Events via Event Mesh</LI><LI><STRONG>Purpose:</STRONG> Real-time inventory notifications</LI><LI><STRONG>Volume:</STRONG> ~3,000 events per day</LI></UL></OL><P><FONT size="6"><STRONG>5. System Preparation Checklists</STRONG></FONT></P><P>Before starting integration development, systems must be technically and operationally ready. The following checklists reflect <STRONG>production-grade prerequisites</STRONG>.</P><P><STRONG>5.1 SAP ECC Preparation</STRONG></P><P><STRONG>Technical Configuration</STRONG></P><P><STRONG>RFC Destinations (SM59)</STRONG><BR />&nbsp;☐ &nbsp;&nbsp;HTTP/RFC destination created for Integration Suite<BR />&nbsp;☐&nbsp; &nbsp;Connection test successful<BR />&nbsp;☐ &nbsp;&nbsp;Timeout parameters adjusted<BR />&nbsp;☐ &nbsp;&nbsp;Trusted RFC configured (if applicable)</P><P><STRONG>IDoc Configuration (If IDocs Are Used)</STRONG><BR />&nbsp;☐ &nbsp;&nbsp;Partner profiles maintained (WE20)<BR />   ☐&nbsp; &nbsp;Inbound parameters<BR />   ☐ &nbsp;&nbsp;Outbound parameters<BR />   ☐ &nbsp;&nbsp;Message types assigned<BR />&nbsp;☐ &nbsp;&nbsp;Ports configured (WE21)<BR />  ☐ &nbsp;&nbsp;HTTP port to Integration Suite<BR />  ☐&nbsp; &nbsp;Port connectivity tested<BR />&nbsp;☐ &nbsp;&nbsp;Message control configured (for outbound IDocs)<BR />  ☐&nbsp; &nbsp;Application (ME, VL, VF, etc.)<BR />  ☐ &nbsp;&nbsp;Output type<BR />  ☐ &nbsp;&nbsp;Medium = 6 (IDoc)<BR />&nbsp;☐ &nbsp;&nbsp;Test IDocs generated successfully (WE19)</P><P><STRONG>Web Services (SOAMANAGER)</STRONG><BR />&nbsp;☐ &nbsp;&nbsp;Service definitions created<BR />&nbsp;☐&nbsp; &nbsp;Endpoints configured and reachable<BR />&nbsp;☐&nbsp; &nbsp;WSDL accessible externally<BR />&nbsp;☐ &nbsp;&nbsp;Authentication configured</P><P><STRONG>User &amp; Authorization</STRONG><BR />&nbsp;☐ &nbsp;&nbsp;Technical user created (SU01)<BR />&nbsp;☐ &nbsp;&nbsp;Required authorizations assigned:<BR />  ☐ &nbsp;&nbsp;S_RFC<BR />  ☐ &nbsp;&nbsp;S_IDOCDEFT<BR />  ☐ &nbsp;&nbsp;Relevant business authorizations<BR />&nbsp;☐ &nbsp;&nbsp;Password policy compliant<BR />&nbsp;☐ &nbsp;&nbsp;Dialog access restricted for security</P><P><STRONG>Network &amp; Security</STRONG></P><P><STRONG>Firewall Rules</STRONG><BR />&nbsp;☐&nbsp; &nbsp;Outbound: ECC → Integration Suite (HTTPS 443)<BR />&nbsp;☐ &nbsp;&nbsp;Inbound: Integration Suite → ECC (HTTP/HTTPS)<BR />&nbsp;☐ &nbsp;&nbsp;IP whitelisting completed</P><P><STRONG>SSL / TLS Configuration</STRONG><BR />&nbsp;&nbsp;☐ &nbsp;&nbsp;Certificates imported (STRUST)<BR />&nbsp;&nbsp;☐ &nbsp;&nbsp;Certificate chain verified<BR />&nbsp;&nbsp;☐ &nbsp;&nbsp;Expiry monitoring in place</P><P><STRONG>Cloud Connector (If On-Premise Connectivity Is Required)</STRONG><BR />&nbsp;&nbsp;☐ &nbsp;&nbsp;Installed and connected to BTP subaccount<BR />&nbsp;&nbsp;☐ &nbsp;&nbsp;Access control rules defined<BR />&nbsp;&nbsp;☐ &nbsp;&nbsp;Resource mapping configured<BR />&nbsp;&nbsp;☐ &nbsp;&nbsp;Audit logging enabled</P><P><STRONG>5.2 SAP S/4HANA Preparation</STRONG></P><P><STRONG>All ECC prerequisites apply, plus the following.</STRONG></P><P><STRONG>OData / Gateway Configuration</STRONG></P><P>&nbsp;&nbsp;☐ &nbsp;&nbsp;Services activated (/IWFND/MAINT_SERVICE)<BR />  ☐ &nbsp;&nbsp;System alias assigned<BR />  ☐&nbsp; &nbsp;Service registration complete<BR />  ☐ &nbsp;&nbsp;ICF nodes active (SICF)<BR />&nbsp;☐ &nbsp;&nbsp;Service testing completed (/IWFND/GW_CLIENT)<BR />  ☐ &nbsp;&nbsp;$metadata accessible<BR />  ☐ &nbsp;&nbsp;Entity sets queryable<BR />  ☐ &nbsp;&nbsp;CRUD operations verified<BR />&nbsp;☐ &nbsp;&nbsp;Authorization configured (S_SERVICE, PFCG roles)</P><P><STRONG>Custom OData Services (If Applicable)</STRONG><BR />&nbsp;☐ &nbsp;&nbsp;Data model designed (SEGW)<BR />&nbsp;☐ &nbsp;&nbsp;DPC_EXT implemented<BR />&nbsp;☐&nbsp; &nbsp;Runtime objects generated<BR />&nbsp;☐ &nbsp;&nbsp;Service registered and tested</P><P><STRONG>Event Configuration (If Event-Driven Integration Is Used)</STRONG><BR />&nbsp;☐ &nbsp;&nbsp;Business events identified<BR />&nbsp;☐&nbsp; &nbsp;Event Mesh connectivity established<BR />&nbsp;☐ &nbsp;&nbsp;Topic and queue structure defined<BR />&nbsp;☐ &nbsp;&nbsp;Payload format designed<BR />&nbsp;☐ &nbsp;&nbsp;End-to-end testing completed.</P><P><STRONG>CDS View Exposure</STRONG><BR />&nbsp;☐ &nbsp;&nbsp;CDS views created and optimized<BR />&nbsp;☐ &nbsp;&nbsp;Exposed via OData<BR />&nbsp;☐ &nbsp;&nbsp;Authorization validated<BR />&nbsp;☐ &nbsp;&nbsp;Performance tested.</P><P><STRONG>5.3 SAP BTP Integration Suite Preparation</STRONG></P><P><STRONG>Platform Enablement</STRONG></P><P>&nbsp;☐ &nbsp;&nbsp;Integration Suite provisioned<BR />&nbsp;☐ &nbsp;&nbsp;Cloud Integration enabled<BR />&nbsp;☐ &nbsp;&nbsp;API Management enabled (if required)<BR />&nbsp;☐ &nbsp;&nbsp;Event Mesh enabled (if required)<BR />&nbsp;☐ &nbsp;&nbsp;Integration Advisor enabled (if B2B scenarios)</P><P><STRONG>Connectivity</STRONG></P><P>&nbsp;☐ &nbsp;&nbsp;Destinations configured<BR />   ☐&nbsp; &nbsp;HTTP destinations to ECC/S/4HANA<BR />   ☐ &nbsp;&nbsp;Authentication defined<BR />   ☐&nbsp; &nbsp;Proxy type set (Internet / On-Premise)<BR />&nbsp;☐ &nbsp;&nbsp;Cloud Connector configured<BR />   ☐ &nbsp;&nbsp;Location ID assigned<BR />   ☐&nbsp; &nbsp;Virtual host mapping<BR />   ☐ &nbsp;&nbsp;Access control lists maintained</P><P><STRONG>Security</STRONG></P><P>&nbsp;☐ &nbsp;&nbsp;Credentials stored securely<BR />&nbsp;☐ &nbsp;&nbsp;OAuth tokens configured (if applicable)<BR />&nbsp;☐ &nbsp;&nbsp;Certificates uploaded and validated<BR />&nbsp;☐ &nbsp;&nbsp;Secure parameters used for sensitive values<BR />&nbsp;☐ &nbsp;&nbsp;Known hosts configured for SFTP</P><P><STRONG>Design &amp; Operations</STRONG></P><P>&nbsp;☐ &nbsp;&nbsp;Integration packages created<BR />&nbsp;☐ &nbsp;&nbsp;Naming conventions defined<BR />&nbsp;☐ &nbsp;&nbsp;Versioning and transport strategy agreed<BR />&nbsp;☐ &nbsp;&nbsp;Message monitoring enabled<BR />&nbsp;☐ &nbsp;&nbsp;Alerts configured<BR />&nbsp;☐ &nbsp;&nbsp;Log retention policy set<BR />&nbsp;☐ &nbsp;&nbsp;Operational dashboards created</P><P><FONT size="6"><STRONG>6. INTEGRATION ARCHITECTURE OVERVIEW</STRONG></FONT></P><P>Understanding how all pieces fit together:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="azhariqbal_26-1768328373927.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361090i7E0C49CBE06FB9E2/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="azhariqbal_26-1768328373927.png" alt="azhariqbal_26-1768328373927.png" /></span></P><P><STRONG>Component Explanations</STRONG></P><P><STRONG>Cloud Connector</STRONG></P><UL><LI>Provides a <STRONG>secure tunnel</STRONG> between SAP BTP and on-premise SAP systems</LI><LI>Eliminates the need for VPN connectivity</LI><LI>Enables <STRONG>resource-level access control</STRONG></LI><LI>Supports <STRONG>audit logging</STRONG> for compliance and security monitoring</LI></UL><P><STRONG>CPI Adapters</STRONG></P><UL><LI>Enable <STRONG>protocol translation</STRONG> (RFC ↔ REST, IDoc ↔ JSON, SOAP ↔ HTTP)</LI><LI>Handle authentication and credential management</LI><LI>Support <STRONG>connection pooling</STRONG> for performance optimization</LI><LI>Provide built-in <STRONG>retry mechanisms</STRONG> for transient failures</LI></UL><P><STRONG>API Management</STRONG></P><UL><LI>Enforces <STRONG>rate limiting and quotas</STRONG></LI><LI>Supports <STRONG>API key and OAuth-based validation</STRONG></LI><LI>Offers <STRONG>analytics and usage monitoring</STRONG></LI><LI>Includes a <STRONG>developer portal</STRONG> for API discovery and onboarding</LI></UL><P><STRONG>Event Mesh</STRONG></P><UL><LI>Supports <STRONG>publish / subscribe messaging</STRONG></LI><LI>Provides <STRONG>queue-based guaranteed delivery</STRONG></LI><LI>Enables <STRONG>topic-based routing</STRONG></LI><LI>Allows <STRONG>multiple subscribers</STRONG> to process events independently</LI></UL><P><FONT size="6"><STRONG>7. Key Takeaways</STRONG></FONT></P><P><STRONG>Understanding System Capabilities</STRONG></P><P><STRONG>SAP ECC Strengths</STRONG></P><UL><LI>Mature and stable <STRONG>RFC/BAPI framework</STRONG></LI><LI>Robust <STRONG>IDoc infrastructure</STRONG> for asynchronous processing</LI><LI>Battle-tested reliability in enterprise landscapes</LI><LI>Rich <STRONG>Enterprise Services Repository</STRONG></LI></UL><P><STRONG>SAP S/4HANA Advantages</STRONG></P><UL><LI>Native <STRONG>OData / REST APIs</STRONG></LI><LI>Built-in <STRONG>event-driven integration</STRONG></LI><LI>High performance powered by <STRONG>SAP HANA</STRONG></LI><LI><STRONG>CDS views</STRONG> for optimized data access</LI><LI>Includes everything ECC offers — <STRONG>enhanced and modernized</STRONG></LI></UL><P><STRONG>SAP BTP Integration Suite as the Bridge</STRONG></P><UL><LI>Centralized <STRONG>protocol translation</STRONG></LI><LI>Secure <STRONG>cloud connectivity</STRONG></LI><LI>End-to-end <STRONG>orchestration layer</STRONG></LI><LI>Enterprise-grade <STRONG>monitoring and governance</STRONG></LI></UL><P><STRONG>Protocol Selection Guidance</STRONG></P><UL><LI><STRONG>RFC / BAPI:</STRONG> Synchronous transactions with immediate validation</LI><LI><STRONG>IDoc:</STRONG> Bulk data processing with guaranteed delivery</LI><LI><STRONG>OData:</STRONG> REST APIs for modern applications</LI><LI><STRONG>SOAP:</STRONG> Legacy enterprise web services</LI><LI><STRONG>File Interfaces:</STRONG> Batch processing and data migrations</LI><LI><STRONG>Events:</STRONG> Real-time, decoupled integration (S/4HANA)</LI></UL><P><STRONG>Preparation Is Critical</STRONG></P><UL><LI>System configuration must be completed <STRONG>before development</STRONG></LI><LI>Security and authorizations must be <STRONG>production-ready</STRONG></LI><LI>Network connectivity should be <STRONG>fully tested</STRONG></LI><LI>Monitoring and alerting should be established <STRONG>early</STRONG></LI></UL><P><FONT size="6"><STRONG>8. What’s Next</STRONG></FONT></P><P>This blog explained <STRONG>what is possible</STRONG>.<BR />The next blogs series will be focused on <STRONG>how to implement</STRONG>.</P><P>&nbsp;</P><P><STRONG><SPAN class="">Acknowledgments &amp; Corrections</SPAN> </STRONG></P><P><SPAN>This document was refined based on valuable feedback from the SAP Community, </SPAN><SPAN>particularly regarding:</SPAN></P><UL><LI><SPAN>NetWeaver Gateway as a standard, supported component in ECC</SPAN></LI><LI><SPAN>JSON support in OData V2 for both ECC and S/4HANA </SPAN></LI><LI><SPAN>BAPI transaction control requirements </SPAN></LI><LI><SPAN>Event architecture distinctions </SPAN></LI></UL><P><SPAN>I welcome continued feedback to ensure this remains an accurate, </SPAN><SPAN>community-validated resource.</SPAN></P><P>&nbsp;</P> 2026-01-16T17:05:43.629000+01:00 https://community.sap.com/t5/abap-blog-posts/step-by-step-guide-creating-your-first-rap-application-using-odata-v4-and/ba-p/14308388 Step-By-Step Guide: Creating Your First RAP Application using OData V4 and Transporting to Quality 2026-01-20T07:14:41.239000+01:00 RajkumarGouda https://community.sap.com/t5/user/viewprofilepage/user-id/1768161 <P><STRONG>Introduction</STRONG></P><P>In this blog, we will walk through the detailed steps to create your<SPAN>&nbsp;</SPAN><STRONG>first RAP (RESTful ABAP Programming Model) application and correctly move it to the Quality system. This blog also highlights mandatory steps before transport and common mistakes that beginners usually make, based on real project experience.</STRONG></P><P><STRONG>Target Audience &amp; Prerequisites</STRONG></P><UL><LI>ABAP developers who are<SPAN>&nbsp;</SPAN><STRONG>new to RAP</STRONG></LI><LI>Basic knowledge of<SPAN>&nbsp;</SPAN><STRONG>CDS Views and ABAP Development Tools (ADT)</STRONG></LI><LI>System used:<SPAN>&nbsp;</SPAN><STRONG>SAP S/4HANA (On-Premise / Private Cloud)</STRONG></LI><LI>Exposure type:<SPAN>&nbsp;</SPAN><STRONG>OData V4</STRONG></LI><LI>Scenario covered:<SPAN>&nbsp;</SPAN><STRONG>Basic Read-only RAP application</STRONG><P><STRONG>Mandatory Objects in a RAP Application<SPAN>:</SPAN></STRONG></P><UL><LI>Package</LI><LI><SPAN>Interface CDS View</SPAN></LI><LI>Projection CDS View (Optional we can directly create service definition on Interface view also)</LI><LI><SPAN>Service Definition</SPAN></LI><LI><SPAN>Service Binding</SPAN></LI></UL></LI></UL><OL><LI><SPAN><STRONG>Create Package:&nbsp;</STRONG></SPAN><P>Create a package in ADT:</P><UL><LI>Right-click on project → New → ABAP Package</LI><LI>Enter package name and description</LI><LI>Do not create it as a local package ($TMP)</LI><LI>Capture it in a transport request&nbsp; &nbsp; &nbsp;</LI><LI><SPAN>Only transportable packages can be moved to Quality and Production systems.</SPAN></LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RajkumarGouda_0-1768540851654.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361795i80BEFC048D01BE3F/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="RajkumarGouda_0-1768540851654.png" alt="RajkumarGouda_0-1768540851654.png" /></span><P>&nbsp;</P></LI></UL></LI><LI><P><STRONG>Interface CDS View:</STRONG>&nbsp;A CDS View is a virtual data model in ABAP that defines how data from database tables is accessed and represented. In RAP, it often serves as the “Interface View.”</P><OL class="lia-list-style-type-lower-roman"><LI><P><STRONG>Why It Matters:</STRONG></P><UL><LI>Reusable logic: Centralizes data access for transactional and analytical purposes.</LI><LI>Foundation: Serves as the starting point for business object modeling in RAP.</LI></UL></LI><LI><P><STRONG>Steps:</STRONG></P><UL><LI>Right-click your database table (e.g., ZTRAVEL_RAJ_M), select New Data Definition.</LI><LI>Provide a name, description, and use the Define View Entity template.</LI><LI>Assign to transport, activate, and check for errors.</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RajkumarGouda_1-1768540851889.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361797i21F33B8BD3337DAE/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="RajkumarGouda_1-1768540851889.png" alt="RajkumarGouda_1-1768540851889.png" /></span><P>&nbsp;</P></LI></UL></LI></OL></LI><LI><P><STRONG>Service Definition:</STRONG><SPAN>&nbsp;</SPAN>The Service Definition specifies which data elements (entities) of a RAP business object are exposed as OData services.</P><OL class="lia-list-style-type-lower-roman"><LI><P><STRONG>Why It Matters:</STRONG></P><UL><LI>Exposure Layer: Decides what consumers (e.g., Fiori apps, external APIs) can interact with.</LI><LI>It’s the contract between your backend logic and external consumers.</LI></UL><STRONG>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</STRONG></LI><LI><P><STRONG>Steps:</STRONG></P><UL><LI>Right-click on the projection view, select New Service Definition.</LI><LI>Name, description, assign transport, and activate.</LI><LI>This exposes your RAP objects as a service.</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RajkumarGouda_2-1768540851660.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361796iB05AE8FEED3D5387/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="RajkumarGouda_2-1768540851660.png" alt="RajkumarGouda_2-1768540851660.png" /></span><P>&nbsp;</P></LI></UL></LI></OL></LI><LI><STRONG>Service Binding:&nbsp;</STRONG>Service Binding links a service definition to an actual communication protocol (such as OData V4) and activation state.<OL class="lia-list-style-type-lower-roman"><LI><STRONG>Why It Matters:</STRONG><UL><LI>Enables Consumption: Without binding, your service cannot be called or used.</LI><LI>Protocol Choice: Determines how front ends communicate with your service (e.g., OData V4 for Fiori/UI5 apps).</LI></UL></LI><LI><P><STRONG>Steps:</STRONG></P><UL><LI>Right-click on the service definition, select New Service Binding.</LI><LI>Choose OData V4 protocol (for most Fiori/RAP apps).</LI><LI>Assign transport, describe, finish, and activate.</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RajkumarGouda_3-1768540851892.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361799i93A775EDADFD75DB/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="RajkumarGouda_3-1768540851892.png" alt="RajkumarGouda_3-1768540851892.png" /></span><P>&nbsp;</P></LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RajkumarGouda_4-1768540851678.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361798i2CDE5542D59CBFC4/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="RajkumarGouda_4-1768540851678.png" alt="RajkumarGouda_4-1768540851678.png" /></span><P>&nbsp;</P></LI></UL></LI></OL></LI><LI><STRONG>Why You Should NOT Publish from ADT:&nbsp;</STRONG>Publishing directly from ADT is meant only for local testing.<OL class="lia-list-style-type-lower-roman"><LI><P><STRONG>Issues with ADT Publishing</STRONG></P><UL><LI>Service is registered as a local ($TMP) object</LI><LI>Cannot be transported to Quality or Production</LI><LI>Not supported for productive landscapes</LI></UL></LI><LI><P><STRONG>Correct Way: Publish via /IWFND/V4_ADMIN</STRONG></P><UL><LI><P>Transaction /IWFND/V4_ADMIN is the recommended way to publish RAP services.</P></LI></UL></LI><LI><STRONG>Steps:&nbsp;</STRONG><UL><LI>Open /IWFND/V4_ADMIN and click Publish Service Groups</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RajkumarGouda_5-1768540851905.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361800i3FDA30E4725FB5E9/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="RajkumarGouda_5-1768540851905.png" alt="RajkumarGouda_5-1768540851905.png" /></span><P>&nbsp;</P></LI><LI>Enter System Alias = LOCAL, Service Binding name click on get service groups</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RajkumarGouda_6-1768540851979.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361801i4B52A6A134A3EB33/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="RajkumarGouda_6-1768540851979.png" alt="RajkumarGouda_6-1768540851979.png" /></span><P>&nbsp;</P></LI><LI>Select service and Publish</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RajkumarGouda_7-1768540851966.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361802i92F33C5A6583AA89/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="RajkumarGouda_7-1768540851966.png" alt="RajkumarGouda_7-1768540851966.png" /></span><P>&nbsp;</P></LI><LI>From the service group list, right click on your service group and click on transport publishing. It will prompt for customizing TR enter the transport and save. After that Click on transport routing assignment and capture in the customizing TR.</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RajkumarGouda_8-1768540852149.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361803i130B341E8A389C81/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="RajkumarGouda_8-1768540852149.png" alt="RajkumarGouda_8-1768540852149.png" /></span><P>&nbsp;</P></LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RajkumarGouda_9-1768540852154.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361806i63A955753D40677D/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="RajkumarGouda_9-1768540852154.png" alt="RajkumarGouda_9-1768540852154.png" /></span><P>&nbsp;</P></LI><LI>Service is now published</LI><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RajkumarGouda_10-1768540852425.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361804i00101429ECA3147F/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="RajkumarGouda_10-1768540852425.png" alt="RajkumarGouda_10-1768540852425.png" /></span><P>&nbsp;</P></LI></UL></LI></OL></LI><LI><STRONG>Preview:&nbsp;</STRONG>Finally, let’s preview the application to verify that the service is working as expected.&nbsp;<UL><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RajkumarGouda_11-1768540852445.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/361805i72DD1E4FFCF22D6F/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="RajkumarGouda_11-1768540852445.png" alt="RajkumarGouda_11-1768540852445.png" /></span><P>&nbsp;</P></LI></UL></LI></OL><P><STRONG>Conclusion:&nbsp;</STRONG></P><UL><LI>In this blog, we learned how to create a basic RAP application and the correct approach to publish and transport OData V4 services to the Quality system.</LI><LI>Using /IWFND/V4_ADMIN ensures transport safety and helps avoid common deployment issues that beginners often face.</LI></UL><P><STRONG>Note:&nbsp;</STRONG></P><P>To customize the user interface of your RAP application, add appropriate UI annotations in the CDS view (interface or projection, depending on your design). Common annotations include<SPAN>&nbsp;</SPAN><A href="https://community.sap.com/t5/user/viewprofilepage/user-id/1445379" target="_blank">@ui</A>.headerInfo,<SPAN>&nbsp;</SPAN><A href="https://community.sap.com/t5/user/viewprofilepage/user-id/1445379" target="_blank">@ui</A>.lineItem, and<SPAN>&nbsp;</SPAN><A href="https://community.sap.com/t5/user/viewprofilepage/user-id/1445379" target="_blank">@ui</A>.selectionField.</P><P>After publishing the service, share the service URL (available in the Service Binding) with the Fiori development team so they can create the required Fiori tile.<BR />After&nbsp;transporting to the Quality system, SICF activation is a manual step. Without activating the relevant SICF nodes, the service will not be accessible. Coordinate with your Basis team to complete this step.</P> 2026-01-20T07:14:41.239000+01:00 https://community.sap.com/t5/crm-and-cx-blog-posts-by-members/connecting-sap-sales-cloud-v2-to-a-standalone-sap-analytics-cloud-a/ba-p/14310439 Connecting SAP Sales Cloud V2 to a Standalone SAP Analytics Cloud - A Practical Alternative 2026-01-21T05:54:01.435000+01:00 jaripie https://community.sap.com/t5/user/viewprofilepage/user-id/515129 <P><U><STRONG><FONT size="5">The Customer Challenge</FONT></STRONG></U></P><P>A customer approached me with what seemed like a straightforward request: "We want to analyze our <a href="https://community.sap.com/t5/c-khhcw49343/SAP+Sales+Cloud+Version+2/pd-p/73555000100800003822" class="lia-product-mention" data-product="1240-1">SAP Sales Cloud Version 2</a>&nbsp;data in <a href="https://community.sap.com/t5/c-khhcw49343/SAP+Analytics+Cloud/pd-p/67838200100800006884" class="lia-product-mention" data-product="3-1">SAP Analytics Cloud</a>."</P><P>Their situation was common for mid-sized companies adopting SAP's CX portfolio:</P><UL><LI><STRONG><a href="https://community.sap.com/t5/c-khhcw49343/SAP+Sales+Cloud+Version+2/pd-p/73555000100800003822" class="lia-product-mention" data-product="1240-2">SAP Sales Cloud Version 2</a>&nbsp;</STRONG>was live and running well</LI><LI><STRONG><a href="https://community.sap.com/t5/c-khhcw49343/SAP+Analytics+Cloud/pd-p/67838200100800006884" class="lia-product-mention" data-product="3-2">SAP Analytics Cloud</a>&nbsp;</STRONG>was licensed separately (not the embedded version)</LI><LI><STRONG>No SAP BTP</STRONG>&nbsp;subscription yet, it wasn't part of the initial scope</LI><LI><STRONG>No <a href="https://community.sap.com/t5/c-khhcw49343/SAP+Integration+Suite/pd-p/73554900100800003241" class="lia-product-mention" data-product="23-1">SAP Integration Suite</a>&nbsp;</STRONG>same reason</LI><LI><STRONG>No <a href="https://community.sap.com/t5/c-khhcw49343/SAP+Datasphere/pd-p/73555000100800002141" class="lia-product-mention" data-product="16-1">SAP Datasphere</a></STRONG>, they wanted to avoid another data platform</LI></UL><P>The goal was simple: import Accounts, Contacts, and Opportunities into SAC for custom dashboards that combined CX data with data from other sources</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jaripie_0-1768847989030.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/363033iDB190F632455A48F/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="jaripie_0-1768847989030.png" alt="jaripie_0-1768847989030.png" /></span></P><P><U><STRONG><FONT size="5">What SAP Officially Recommends</FONT></STRONG></U></P><P>Before building anything custom, I researched SAP's official guidance. The recommended architecture for Sales Cloud V2 analytics integration involves:</P><OL><LI><STRONG><a href="https://community.sap.com/t5/c-khhcw49343/SAP+Datasphere/pd-p/73555000100800002141" class="lia-product-mention" data-product="16-2">SAP Datasphere</a>&nbsp;</STRONG>as a central data layer</LI><LI><STRONG><a href="https://community.sap.com/t5/c-khhcw49343/SAP+Integration+Suite/pd-p/73554900100800003241" class="lia-product-mention" data-product="23-2">SAP Integration Suite</a>&nbsp;</STRONG>for event-driven data replication</LI><LI><STRONG>SAP Advanced Event Mesh</STRONG>&nbsp;(optional but recommended) for resilience</LI></OL><P>SAP published a detailed two-part blog series on this:&nbsp;<A title="Event-Driven Data Integration from SAP Sales and Service Cloud V2 to SAP Datasphere" href="https://community.sap.com/t5/crm-and-cx-blog-posts-by-sap/event-driven-data-integration-from-sap-sales-and-service-cloud-v2-to-sap/ba-p/14003914)." target="_blank">Event-Driven Data Integration from SAP Sales and Service Cloud V2 to SAP Datasphere</A></P><P>This architecture is elegant and production-grade. It's also <STRONG>significant additional investment</STRONG>&nbsp;for a customer who just wants to run a few reports.</P><P><U><STRONG><FONT size="5">Cost Implications</FONT></STRONG></U></P><P><SPAN>The official path requires more than you might expect:</SPAN></P><TABLE border="1" width="99.78858350951374%"><TBODY><TR><TD><U><STRONG>Component</STRONG></U></TD><TD><U><STRONG>Status for this Customer</STRONG></U></TD></TR><TR><TD width="45.87737843551797%">SAP Datasphere</TD><TD width="53.911205073995774%">Not licensed (€€€/month)</TD></TR><TR><TD width="45.87737843551797%">SAP Integration Suite</TD><TD width="53.911205073995774%">Not licensed (€€/month)</TD></TR><TR><TD width="45.87737843551797%">SAP BTP subscription</TD><TD width="53.911205073995774%">Not available</TD></TR><TR><TD width="45.87737843551797%">Implementation effort</TD><TD width="53.911205073995774%">Significant (weeks)</TD></TR></TBODY></TABLE><P><BR />For a customer with ~24,000 accounts who wants three dashboards, this felt like using a sledgehammer to crack a nut.</P><P><STRONG><FONT size="6"><FONT size="5">The Obvious First Attempt: SAC's Built-in Connectors</FONT></FONT></STRONG></P><P>SAC has connectors for various SAP sources. Surely there's something for Sales Cloud?</P><P><STRONG>Attempt 1: The "SAP Cloud for Customer" Connector</STRONG></P><P>SAC includes a dedicated connector called "SAP Cloud for Customer" that works beautifully with the older C4C (Cloud for Customer) system. It connects to OData services like:</P><pre class="lia-code-sample language-markup"><code>https://&lt;tenant&gt;/sap/c4c/odata/v1/c4codataapi/AccountCollection</code></pre><P><STRONG>The problem:&nbsp;</STRONG>Sales Cloud V2 is not C4C. So the OData connector won’t work:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="jaripie_1-1768847293558.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/363030i9FFD16C2D8EF8F2C/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="jaripie_1-1768847293558.png" alt="jaripie_1-1768847293558.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="jaripie_2-1768847303349.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/363031i061589235888315A/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="jaripie_2-1768847303349.png" alt="jaripie_2-1768847303349.png" /></span></P><P><STRONG>Attempt 2: The Generic OData Connector</STRONG></P><P>SAC also has a generic "OData Services" connector. Maybe that works?</P><P><STRONG>The problem:</STRONG> Sales Cloud V2 doesn't expose OData endpoints. The APIs on the&nbsp;<A title="SAP APIs" href="https://api.sap.com/package/SAPSalesServiceCloudV2/rest" target="_self" rel="noopener noreferrer">SAP Business Accelerator Hub</A>&nbsp;are REST, not OData.</P><pre class="lia-code-sample language-markup"><code>GET /sap/c4c/api/v1/account-service/accounts ← REST, not OData GET /sap/c4c/api/v1/contact-service/contacts ← REST, not OData</code></pre><P><STRONG>Attempt 3: Live Connection</STRONG></P><P>Sales Cloud V2 has embedded SAC capabilities. Could we establish a live connection?</P><P><STRONG>The problem:</STRONG>&nbsp;The embedded analytics are designed for "embedded" use cases. Connecting a standalone SAC tenant to Sales Cloud V2 for custom reporting seems to be... let's say "not a focus area" right now.</P><P>I opened a support ticket to clarify the expected behavior and it was put in development after a little back and forth.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="jaripie_3-1768847352603.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/363032i9299CBF8774B4C83/image-size/medium/is-moderation-mode/true?v=v2&amp;px=400" role="button" title="jaripie_3-1768847352603.png" alt="jaripie_3-1768847352603.png" /></span></P><P><STRONG><FONT size="5">The Hidden Challenge: Real-Time vs. Import</FONT></STRONG></P><P>At this point, I had to step back and discuss architecture with the customer.</P><P>Even if a direct connector existed, there are implications to consider:</P><P>&nbsp;</P><TABLE border="1" width="100%"><TBODY><TR><TD width="33.333333333333336%"><U><STRONG>Approach</STRONG></U></TD><TD width="33.333333333333336%"><U><STRONG>Pros</STRONG></U></TD><TD width="33.333333333333336%"><U><STRONG>Cons</STRONG></U></TD></TR><TR><TD width="33.333333333333336%"><STRONG>Live Connection</STRONG></TD><TD width="33.333333333333336%">Always current data</TD><TD width="33.333333333333336%">Query performance depends on source; cannot combine with other data sources easily</TD></TR><TR><TD width="33.333333333333336%"><STRONG>Import Connection</STRONG></TD><TD width="33.333333333333336%">Fast queries; can blend with other sources</TD><TD width="33.333333333333336%">Data has latency; storage costs</TD></TR></TBODY></TABLE><P>The customer wanted to combine Sales Cloud V2 data with <a href="https://community.sap.com/t5/c-khhcw49343/SAP+S%25252F4HANA/pd-p/73554900100800000266" class="lia-product-mention" data-product="799-1">SAP S/4HANA</a>&nbsp;data in the same dashboard. This essentially requires import connections for both sources, plus a data model in SAC that joins them.</P><P><STRONG>Real-time was never really an option</STRONG>&nbsp;as they needed data at rest in <a href="https://community.sap.com/t5/c-khhcw49343/SAP+Analytics+Cloud/pd-p/67838200100800006884" class="lia-product-mention" data-product="3-3">SAP Analytics Cloud</a>&nbsp;</P><P><STRONG>The Solution: A Lightweight REST-to-OData Proxy</STRONG></P><P>Since the customer had:</P><UL><LI>No appetite for <a href="https://community.sap.com/t5/c-khhcw49343/SAP+Datasphere/pd-p/73555000100800002141" class="lia-product-mention" data-product="16-3">SAP Datasphere</a></LI><LI>No CPI license</LI><LI>A clear, limited scope (three entity types)</LI><LI>Tolerance for daily data refresh (not real-time)</LI></UL><P>I proposed building a thin proxy server that:</P><OL><LI>Authenticates with Sales Cloud V2</LI><LI>Fetches data via REST APIs</LI><LI>Transforms responses to OData format</LI><LI>Exposes endpoints that SAC can consume natively</LI></OL><P><FONT size="5"><STRONG>Architecture<BR /></STRONG></FONT></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jaripie_0-1768849266375.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/363037i9170806DBF5BDABA/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="jaripie_0-1768849266375.png" alt="jaripie_0-1768849266375.png" /></span></P><P><SPAN>This sounds straightforward... until you start building it...</SPAN></P><H2 id="toc-hId-1788541067">Challenge 1: The 999 vs. 1000 Mismatch</H2><P>This one deserves its own section because it’s so unexpected.</P><P><STRONG>SAP Sales Cloud V2</STRONG> REST APIs have a maximum page size of <STRONG>999 records</STRONG>. You can request <CODE>$top=999</CODE>, but not more.</P><P><STRONG>SAP Analytics Cloud</STRONG> OData import has a minimum batch size of <STRONG>1000 records</STRONG>.</P><P>Yes, you read that correctly. The source maxes out at 999. The target starts at 1000.&nbsp;I'll admit I stared at the logs for longer than I'd like to admit before I realized what was happening. The first 999 records imported perfectly. Then nothing. It took me a while to connect that SAC was waiting for a 1000-record batch that would never arrive.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jaripie_0-1768849762690.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/363038i94545C28BB7CCB17/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="jaripie_0-1768849762690.png" alt="jaripie_0-1768849762690.png" /></span></P><H3 id="toc-hId-1721110281">The Solution</H3><P>The proxy implements <STRONG>on-demand parallel fetching</STRONG>:</P><pre class="lia-code-sample language-javascript"><code>async function fetchAllRecords(entityType: string): Promise&lt;any[]&gt; { // Get first page to determine total count const firstPage = await fetchFromSalesCloud(entityType, { $top: 999, $skip: 0 }); if (firstPage.value.length &lt; 999) { // All records fit in first page return firstPage.value; } // Calculate remaining pages and fetch in parallel const totalEstimate = firstPage.totalCount || 10000; const remainingPages = Math.ceil((totalEstimate - 999) / 999); const pagePromises = Array.from({ length: remainingPages }, (_, i) =&gt; fetchFromSalesCloud(entityType, { $top: 999, $skip: 999 * (i + 1) }) ); const results = await Promise.all(pagePromises); return [firstPage.value, ...results.map(r =&gt; r.value)].flat(); }</code></pre><P><SPAN>The proxy fetches pages in parallel (not sequentially), caches the combined result, and serves it to SAC in appropriately sized batches. The cache has a configurable TTL (e.g., 1 hour) and automatically refreshes on the next request after expiry.</SPAN></P><H2 id="toc-hId-1395514057">Challenge 2: Nested Objects and Flattening</H2><P>Sales Cloud V2 returns nicely structured JSON with nested objects:</P><pre class="lia-code-sample language-javascript"><code>{ "value": [{ "accountId": "A001", "accountName": "ACME Corp", "primaryContact": { "contactId": "C001", "firstName": "John", "lastName": "Doe" }, "addresses": [ { "type": "BILL_TO", "city": "Berlin" }, { "type": "SHIP_TO", "city": "Munich" } ] }] }</code></pre><P><STRONG>SAC’s OData importer cannot handle this.</STRONG> The SAP Help documentation states clearly: Embedded Complex types are not supported.</P><H3 id="toc-hId-1328083271">The Solution</H3><P>The proxy must flatten nested structures into separate entity sets:</P><pre class="lia-code-sample language-markup"><code>/odata/Accounts → Flat account records /odata/Contacts → Flat contact records /odata/AccountAddresses → One row per address, linked by accountId</code></pre><H2 id="toc-hId-1002487047">Challenge 3: REST APIs Behave Differently Than OData</H2><P>Coming from the OData world, I expected certain conventions:</P><UL><LI><CODE>$filter</CODE> for filtering</LI><LI><CODE>$select</CODE> for field selection</LI><LI><CODE>$expand</CODE> for related entities</LI><LI>Standardized metadata endpoint</LI></UL><P>Sales Cloud V2 REST APIs have their own conventions:</P><UL><LI>Different query parameter syntax</LI><LI>No <CODE>$metadata</CODE> endpoint</LI><LI>Pagination via custom headers or response properties</LI></UL><P>The proxy needs to translate between these worlds, implementing just enough OData semantics to satisfy SAC’s importer.</P><H2 id="toc-hId-805973542">Challenge 4: The $skip 10,000 Limit</H2><P>Just when you think you’ve handled pagination, there’s another surprise waiting for datasets with more than 10,000 records.</P><P><STRONG>Sales Cloud V2 returns an error if <CODE>$skip</CODE> is 10,000 or greater.</STRONG></P><pre class="lia-code-sample language-markup"><code>// This works GET /accounts?$top=999&amp;$skip=9000 ✅ // This fails GET /accounts?$top=999&amp;$skip=10000 ❌ Error!</code></pre><P><SPAN>So even if you’ve cleverly worked around the 999 page size limit, you hit a wall at record 10,001. Simple offset-based pagination (</SPAN><CODE>$skip</CODE><SPAN>) just stops working.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jaripie_1-1768850122802.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/363039i449B3D34E0148933/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="jaripie_1-1768850122802.png" alt="jaripie_1-1768850122802.png" /></span></P><H3 id="toc-hId-738542756">The Solution</H3><P>Instead of offset-based pagination, the proxy uses <STRONG>keyset pagination</STRONG> with <CODE>$skiptoken</CODE>:</P><pre class="lia-code-sample language-javascript"><code>// src/constants.ts export const SC_MAX_SKIP = 10000; // When approaching the skip limit, switch to skiptoken async function fetchWithKeysetPagination(entityType: string): Promise&lt;any[]&gt; { const allRecords: any[] = []; let nextLink: string | null = buildInitialUrl(entityType); while (nextLink) { const response = await fetch(nextLink); const data = await response.json(); allRecords.push(...data.value); // Use the skiptoken from the response for next page nextLink = data['@odata.nextLink'] || null; } return allRecords; }</code></pre><P>Keyset pagination uses a token (typically based on the last record’s ID or timestamp) rather than a numeric offset. This approach:</P><UL><LI>Has no upper limit on the number of records</LI><LI>Is actually more performant than large offsets</LI><LI>Is the pattern SAP recommends for large datasets</LI></UL><P>If you have more than 10,000 records in any entity, you <EM>must</EM> use <CODE>$skiptoken</CODE>-based pagination. Simple <CODE>$skip</CODE> won’t cut it.</P><H2 id="toc-hId-412946532">Implementation Notes</H2><H3 id="toc-hId-345515746">Technology Choice</H3><P>I built the proxy with:</P><UL><LI><STRONG>Node.js + Fastify:&nbsp;</STRONG>Lightweight, fast, excellent TypeScript support</LI><LI><STRONG>On-demand caching:&nbsp;</STRONG>No scheduled jobs; cache fills dynamically on first request</LI><LI><STRONG>Docker deployment:&nbsp;</STRONG>Runs on any container platform (I use Coolify on a VPS)</LI></UL><P>This is a production-ready setup. The proxy has been running reliably for the customer with no issues.</P><H3 id="toc-hId-149002241">Smart Caching: On-Demand Parallel Fetching</H3><P>Rather than running scheduled batch jobs, the proxy uses an on-demand approach:</P><OL><LI><STRONG>First page served instantly</STRONG>: When SAC requests data, the proxy immediately returns the first page (up to 999 records) from Sales Cloud V2</LI><LI><STRONG>Parallel fetching in background</STRONG>: While SAC processes the first page, the proxy fetches remaining pages in parallel</LI><LI><STRONG>Cache populated for subsequent requests</STRONG>: By the time SAC requests page 2, the data is already cached</LI></OL><pre class="lia-code-sample language-javascript"><code>async function handleODataRequest(req: Request): Promise&lt;Response&gt; { // Check cache first if (cache.has(entityType) &amp;&amp; !cache.isExpired(entityType)) { return serveFromCache(entityType, req.query); } // Fetch first page immediately const firstPage = await fetchPage(entityType, 0, 999); // Start parallel fetching of remaining pages (non-blocking) fetchRemainingPagesInBackground(entityType, firstPage.totalCount); // Return first page immediately return formatAsOData(firstPage); }</code></pre><P>This approach has several advantages:</P><UL><LI><STRONG>No unnecessary background jobs</STRONG>: Data is only fetched when actually needed</LI><LI><STRONG>Fast initial response</STRONG>: User doesn’t wait for full dataset</LI><LI><STRONG>Self-healing cache</STRONG>: Expired cache automatically refreshes on next request</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jaripie_0-1768854131159.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/363045iD5F6B2D8C7AAC998/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="jaripie_0-1768854131159.png" alt="jaripie_0-1768854131159.png" /></span></P><H3 id="toc-hId--122742633">Optional: Deploying to SAP BTP Cloud Foundry</H3><P>If you already have a BTP subscription with available credits, deploying there can make sense. You’re using infrastructure you’re already paying for. The migration is straightforward:</P><P>Standalone Setup Cloud Foundry Setup</P><TABLE><TBODY><TR><TD width="272.867px" height="30px">Environment variables for credentials</TD><TD width="370.578px" height="30px">Destination Service binding</TD></TR><TR><TD width="272.867px" height="30px">In-memory cache</TD><TD width="370.578px" height="30px">PostgreSQL Hyperscaler Option (free tier available)</TD></TR><TR><TD width="272.867px" height="30px">Direct HTTP endpoint</TD><TD width="370.578px" height="30px">XSUAA + AppRouter</TD></TR></TBODY></TABLE><P><STRONG>Why PostgreSQL if you move to BTP?</STRONG></P><P>On a single-container deployment (VPS e.g. with Coolify), in-memory caching works perfectly. But Cloud Foundry typically runs multiple app instances for high availability. If you need persistence across instances, <STRONG>PostgreSQL Hyperscaler Option</STRONG> is the lightweight choice. It has a <A href="https://www.sap.com/germany/products/technology-platform/postgresql-on-sap-btp-hyperscaler-option.html#pricing-section" target="_blank" rel="noopener noreferrer">free tier</A> (since November 2025) and requires no additional management.</P><P>The additional effort for Cloud Foundry deployment is roughly:</P><UL><LI>Add <CODE>mta.yaml</CODE> with service bindings (~1 hour)</LI><LI>Configure Destination Service for Sales Cloud V2 credentials (~30 min)</LI><LI>Add XSUAA for authentication (~1 hour)</LI><LI>Test and deploy (~2 hours)</LI></UL><P><STRONG>Total: Less than one additional day</STRONG> if you decide BTP is the right fit.</P><P><STRONG>Don’t just default to BTP just because it’s SAP.</STRONG> Evaluate what you already have and what makes sense for your situation. A €5/month VPS running Docker might be exactly right for your use case.</P><H3 id="toc-hId--319256138">OData Response Format</H3><P>SAC expects OData V2or V4 responses. The minimum viable format:</P><pre class="lia-code-sample language-javascript"><code>{ "d": { "results": [ { "AccountID": "A001", "AccountName": "ACME Corp", ... }, { "AccountID": "A002", "AccountName": "Globex", ... } ] } }</code></pre><P>Plus a <CODE>$metadata</CODE> endpoint returning EDMX that describes your entity types.</P><H3 id="toc-hId--515769643">Authentication</H3><P>Sales Cloud V2 supports:</P><UL><LI>Basic Authentication (simplest for server-to-server)</LI><LI>OAuth 2.0 (more secure, recommended for production)</LI></UL><P>The proxy stores credentials securely and handles token refresh for OAuth.</P><HR /><H2 id="toc-hId--418880141">Results</H2><P>After implementing the proxy:</P><UL><LI>SAC successfully imports Accounts, Contacts, and Opportunities</LI><LI>Data refreshes nightly via scheduled import</LI><LI>Customer can blend CX data with S/4HANA data in unified dashboards</LI><LI>No additional SAP platform licenses required</LI><LI>Total implementation time: ~2 days</LI></UL><HR /><H2 id="toc-hId--615393646">When This Approach Makes Sense</H2><P>The right solution depends on what you have and what you need. Here’s how I think about it:</P><P><STRONG>A lightweight proxy makes sense when:</STRONG></P><UL><LI>Limited scope (specific entities, not the entire data model)</LI><LI>Import/batch refresh is acceptable (not real-time requirements)</LI><LI>You don’t have Datasphere or CPI licensed and don’t need them for other use cases</LI><LI>You want to validate the integration quickly before investing in bigger infrastructure</LI></UL><P><STRONG>Datasphere + CPI makes sense when:</STRONG></P><UL><LI>You need event-driven, near real-time data replication</LI><LI>You’re integrating many entity types with complex relationships</LI><LI>You already have Datasphere or CPI licensed then use what you’re paying for</LI><LI>You have a broader data strategy where Datasphere is the central hub anyway</LI></UL><P><STRONG>The key question:</STRONG> What do you already have, and does this use case justify adding more?</P><P>SAP’s platforms are excellent, no question! But sometimes a focused solution that solves exactly your problem is better than pulling in the big guns for a straightforward requirement.</P><HR /><H2 id="toc-hId--811907151">Lessons Learned</H2><H3 id="toc-hId--1301823663">1. Don’t Assume SAP Products Integrate Seamlessly</H3><P>Sales Cloud V2 and SAC are both modern SAP cloud products. The integration gap exists because V2’s move away from OData wasn’t accompanied by a new native SAC connector (yet).</P><H3 id="toc-hId--1498337168">2. Check API Patterns Before Committing to Architecture</H3><P>The shift from OData to REST in Sales Cloud V2 is documented, but easy to miss if you’re coming from C4C experience. Always verify on <A href="https://api.sap.com" target="_blank" rel="noopener noreferrer">api.sap.com</A>.</P><H3 id="toc-hId--1694850673">3. Test with Realistic Data Volumes</H3><P>The 999/1000 mismatch only surfaces with more than 999 records. Demo systems with 50 accounts work fine. Production breaks.</P><H3 id="toc-hId--1891364178">4. Use What You Have, Validate What You Need</H3><P>The official architecture is powerful. But if you don’t already have Datasphere and CPI licensed, ask yourself: does this specific use case justify adding them? Sometimes a focused solution that solves exactly your problem is the right call. You can always scale up later if requirements grow.</P><HR /><H2 id="toc-hId--1626290985">What’s Next?</H2><P>I’ve published a <STRONG>reference implementation</STRONG> on GitHub that demonstrates the core patterns:</P><UL><LI>REST-to-OData transformation</LI><LI>Parallel fetching with caching</LI><LI>The 999→1000 batch bridging logic</LI><LI>Keyset pagination with <CODE>$skiptoken</CODE> for large datasets (&gt;10k records)</LI></UL><P><span class="lia-unicode-emoji" title=":backhand_index_pointing_right:">👉</span>&nbsp;<A title="GitHub Repo" href="https://github.com/JariPie/sap-sales-cloud-v2-proxy" target="_blank" rel="noopener nofollow noreferrer">GitHub: SAP Sales Cloud V2 OData Proxy</A></P><P><STRONG>A note on scope:</STRONG> The repository shows <EM>how</EM> the solution works, but doesn’t include everything from my production implementation. Some aspects are tied to specific client configurations that I can’t share. If you’re facing a similar challenge and want help getting to production faster, feel free to reach out.</P><P>If you’ve built something similar or found a better approach I’d love to hear about it in the comments.</P> 2026-01-21T05:54:01.435000+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/building-an-email-based-sap-sales-order-automation-with-n8n-amp-ai-function/ba-p/14312716 Building an Email-Based SAP Sales Order Automation with n8n & AI Function Calling 2026-01-27T08:02:05.123000+01:00 aliulashayir https://community.sap.com/t5/user/viewprofilepage/user-id/2035254 <H1 id="toc-hId-1659520748">Building an Email-Based SAP Sales Order Assistant with AI Function Calling</H1><H2 id="toc-hId-1592089962">The Problem That Started This</H2><P>A few weeks ago, I was watching a colleague struggle with a simple request: "Can you check if order 10850 shipped?" They had to VPN in, open SAP GUI, navigate to VA03, enter the order number, and finally get the answer. For one question. That took 3 minutes.</P><P>I thought - what if they could just send an email and get an answer back?</P><H2 id="toc-hId-1395576457">Why Not Just Use Rules or Keywords?</H2><P>My first instinct was simple pattern matching. Look for "create order" then run the create flow. Look for "check status" then run the query flow. Easy, right?</P><P>Then I looked at actual emails people send:</P><UL><LI>"Hey, can you set up an order for 17100003? They need 5 of TG11 and 10 of TG12"</LI><LI>"pls make SO for cust 17100003 - TG11 x5, TG12 x10"</LI><LI>"Customer 17100003 wants to place an order. Materials: TG11 (5 units), TG12 (10 units)"</LI></UL><P>Same request, completely different wording. Building regex patterns for every variation? That's a maintenance nightmare waiting to happen. And what about typos, abbreviations, or when someone writes in a mix of languages?</P><P>This is exactly where AI shines - understanding intent regardless of how it's expressed.</P><H2 id="toc-hId-1199062952">Why Function Calling Instead of Free-Form AI?</H2><P>I didn't want the AI making up SAP field names or guessing at API structures. That's a recipe for errors. Function calling gives you the best of both worlds:</P><UL><LI><STRONG>The AI handles the messy, unpredictable part</STRONG> (understanding what the user wants)</LI><LI><STRONG>The code handles the precise, structured part</STRONG> (calling SAP correctly)</LI></UL><P>You define exactly what functions exist and what parameters they accept. The AI picks the right function and extracts the right values. No hallucinated field names, no invented API calls.</P><H2 id="toc-hId-1002549447">The Architecture</H2><P>Four components working together:</P><OL><LI><STRONG>Microsoft Outlook</STRONG> - Triggers when an email arrives</LI><LI><STRONG>LLM with Function Calling</STRONG> - Interprets the email, picks the operation</LI><LI><STRONG>n8n</STRONG> - Orchestrates everything, handles data transformation</LI><LI><STRONG>SAP S/4HANA OData APIs</STRONG> - Does the actual work</LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="aliulashayir_4-1769196684258.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364754i93149DF16A5C76A6/image-size/large?v=v2&amp;px=999" role="button" title="aliulashayir_4-1769196684258.png" alt="aliulashayir_4-1769196684258.png" /></span></P><P>&nbsp;</P><H2 id="toc-hId-806035942">Setting Up n8n with Docker (The Network Gotchas)</H2><P>I run n8n locally in Docker, and connecting it to an on-premise SAP system over VPN was... an adventure. Here's what I learned.</P><H3 id="toc-hId-738605156">The Basic Setup</H3><PRE>docker run -it --rm \ --name n8n \ -p 5678:5678 \ --add-host=host.docker.internal:host-gateway \ -v n8n_data:/home/node/.n8n \ docker.n8n.io/n8nio/n8n</PRE><P>That <CODE>--add-host=host.docker.internal:host-gateway</CODE> flag is crucial. It lets containers reference your host machine's network. Without it, your container is isolated and can't see anything your host can see - including VPN connections.</P><H3 id="toc-hId-542091651">The VPN Problem</H3><P>Here's the thing: when you connect to a VPN on your Mac, the VPN routes are available to your host machine, but Docker containers live in their own network namespace. They can't directly reach <CODE>172.16.0.11:44300</CODE> even though your browser can.</P><P>You might think "just use <CODE>--network host</CODE>" - but on macOS, that doesn't work the way you'd expect. Docker Desktop on Mac runs containers in a Linux VM, so <CODE>--network host</CODE> gives you the VM's network, not your Mac's network.</P><H3 id="toc-hId-345578146">The socat Bridge Solution</H3><P>The workaround is to run a TCP forwarder on your host that bridges the connection:</P><PRE>socat TCP-LISTEN:15001,fork,reuseaddr TCP:172.16.0.11:44300</PRE><P>This listens on port 15001 on your Mac and forwards traffic to the SAP server at <CODE>172.16.0.11:44300</CODE>. Now from inside Docker, you can reach SAP at:</P><PRE>https://host.docker.internal:15001/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder</PRE><P><STRONG>The flow is:</STRONG> Docker container → <CODE>host.docker.internal:15001</CODE> → socat on your Mac → VPN → SAP server</P><P>Keep the socat command running in a terminal while you're working. Kill it when you're done.</P><P><STRONG>Quick Tip:</STRONG> If you're getting "connection refused" errors, check that:</P><OL><LI>Your VPN is connected</LI><LI>socat is running</LI><LI>You're using <CODE>host.docker.internal</CODE>, not <CODE>localhost</CODE> or the direct IP</LI></OL><H2 id="toc-hId-19981922">The Functions I Defined</H2><P>Three operations cover most daily requests:</P><H3 id="toc-hId--122680233">get_sales_orders</H3><P><I>"Show me recent orders," "What's the status of order X?"</I></P><P>Parameters: <CODE>$top</CODE>, <CODE>$filter</CODE>, <CODE>$orderby</CODE></P><H3 id="toc-hId--319193738">create_sales_order</H3><P><I>"Create an order for customer X with these items"</I></P><P>Parameters: <CODE>SoldToParty</CODE>, <CODE>items[]</CODE> (Material, RequestedQuantity), plus optional fields</P><H3 id="toc-hId--515707243">update_sales_order</H3><P><I>"Change the PO reference on order 10904"</I></P><P>Parameters: <CODE>SalesOrder</CODE> (required), plus any fields to update</P><P>When an email comes in, the AI returns structured JSON:</P><PRE>{ "function": "create_sales_order", "arguments": { "SoldToParty": "17100003", "items": [ {"Material": "TG11", "RequestedQuantity": "5"}, {"Material": "TG12", "RequestedQuantity": "10"} ] } }</PRE><P>Clean, predictable, easy to work with.</P><H2 id="toc-hId--418817741">The CSRF Token Headache</H2><P>I have to mention this because it cost me hours. SAP OData APIs require CSRF tokens for write operations. Sounds simple - fetch a token, send it with your POST. But here's what the documentation doesn't make obvious:</P><P><STRONG>The token is tied to your session cookies.</STRONG> You need to:</P><OL><LI>GET request with <CODE>x-csrf-token: fetch</CODE> header</LI><LI>Capture the token AND the <CODE>SAP_SESSIONID</CODE> cookie from the response</LI><LI>Send BOTH with your write request</LI></OL><P>I kept getting "CSRF token validation failed" with a perfectly valid token. Turns out I was missing the session cookie. The token alone is useless without it.</P><H3 id="toc-hId--908734253">Another gotcha in n8n</H3><P>The cookie header comes back with extra metadata like <CODE>path=/; secure; HttpOnly</CODE>. If you pass that whole string in your Cookie header, you'll get "Invalid character in header content." You need to extract just the cookie value:</P><PRE>// In an Edit Fields node, clean the cookie $json.headers['set-cookie'][0].split(';')[0] + '; ' + $json.headers['set-cookie'][1].split(';')[0]</PRE><P>This gives you a clean <CODE>sap-usercontext=sap-client=100; SAP_SESSIONID_S4H_100=abc123...</CODE> that SAP will accept.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="aliulashayir_1-1769196530510.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364750iD27461C0A7AF2BFA/image-size/large?v=v2&amp;px=999" role="button" title="aliulashayir_1-1769196530510.png" alt="aliulashayir_1-1769196530510.png" /></span></P><P>&nbsp;</P><H2 id="toc-hId--811844751">Data Transformation for Deep Insert</H2><P>One more SAP quirk: when creating an order with line items, you can't just send an <CODE>items</CODE> array. SAP expects a nested structure called <CODE>to_Item.results</CODE>. In n8n's Code node:</P><PRE>const args = JSON.parse( $input.first().json.choices[0].message.tool_calls[0].function.arguments ); const body = { ...args }; if (body.items) { body.to_Item = { results: body.items }; delete body.items; } return [{ json: { sapBody: body } }];</PRE><P>This transforms the AI's clean output into SAP's expected format.</P><DIV class="">&nbsp;</DIV><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="aliulashayir_3-1769196652079.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364753iBC7A07435CD0BBB4/image-size/medium?v=v2&amp;px=400" role="button" title="aliulashayir_3-1769196652079.png" alt="aliulashayir_3-1769196652079.png" /></span></P><H2 id="toc-hId--1008358256">A Real Example</H2><H3 id="toc-hId--1498274768">Input Email</H3><PRE>Hello, please create a sales order with the following details: Customer: 17100003 Sales Org: 1710 Items: TG11 (qty 5), TG12 (qty 10) Currency: USD</PRE><H3 id="toc-hId--1694788273">What Happens</H3><OL><LI>AI identifies this as <CODE>create_sales_order</CODE></LI><LI>Extracts: customer, items array, currency</LI><LI>Workflow fetches CSRF token + session cookie</LI><LI>Transforms <CODE>items</CODE> array to SAP's <CODE>to_Item.results</CODE> format</LI><LI>POSTs to <CODE>/sap/opu/odata/sap/API_SALES_ORDER_SRV/A_SalesOrder</CODE></LI><LI>SAP creates order, returns details</LI></OL><H3 id="toc-hId--1891301778">Response Email</H3><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="aliulashayir_5-1769196764931.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364756i8B05CA94E2926F2F/image-size/medium?v=v2&amp;px=400" role="button" title="aliulashayir_5-1769196764931.png" alt="aliulashayir_5-1769196764931.png" /></span></P><P>The user never touched SAP. They just sent an email.</P><H2 id="toc-hId--1626228585">What's Next</H2><P>The same pattern works for anything with an OData API:</P><UL><LI>Invoice queries</LI><LI>Delivery status checks</LI><LI>Material lookups</LI><LI>Customer master updates</LI></UL><P>Define the function, connect the endpoint, done.</P><H2 id="toc-hId--1822742090">The Takeaway</H2><P>AI isn't replacing SAP knowledge here - it's translating between human language and system requirements. The business logic, the validations, the actual processing - that's all still SAP. The AI just makes it accessible to people who don't speak SAP.</P><P>And honestly? That's the kind of AI use case I find most valuable. Not replacing expertise, but removing friction.</P> 2026-01-27T08:02:05.123000+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/how-to-call-as-abap-from-sap-datasphere/ba-p/14313818 How to call AS ABAP from SAP Datasphere 2026-01-27T08:11:27.946000+01:00 vitvas https://community.sap.com/t5/user/viewprofilepage/user-id/136079 <H2 id="toc-hId-1788634221">Introduction</H2><P>For communication between SAP systems based on AS ABAP, RFC connections are the standard method. For example, when extracting from SAP ERP, the SAP BW system first launches the extractor in the source system via a BW-&gt;ERP RFC connection. The source system then returns the data collected by the extractor via an ERP-&gt;BW RFC connection.</P><P>For SAP Datasphere (hereinafter referred to as DSP), the natural successor to this approach is the BW Bridge use. However, not all projects justify using BW Bridge in terms of system landscape, architecture, project scope, and implementation costs.</P><P>This blog proposes an approach that allows DSP to execute code in a system running AS ABAP (without using BW Bridge). We will call this code as target code. The idea is to leverage CDS functionality known such as Virtual Elements. A Virtual Element is a field in a CDS View Entity, specifically defined using annotations. This field is not retrieved from the database table level and is not calculated by formulas within the CDS View itself. Instead, accessing the CDS View triggers execution of specialized ABAP code that implements the calculation logic for this field. For BW specialists this may remember well-known virtual characteristics and key figures. On the other hand, the CDS View is an object accessible to DSPs, for example, as a Source for Data Flow. Thus, by running Data Flow Run on the DSP side, we automatically initiate execution of the code that calculates the Virtual Element values ​​in AS ABAP. We can, in turn, include calls of any desired programs, functional modules, or class methods to this code—that is, achieve the execution of the target code.</P><P>Unfortunately, this approach has one significant drawback that complicates its implementation: Virtual elements are only function within OData services generated from CDS views. This means that we cannot use connections of type SAP S/4HANA On-Premise, SAP ABAP, or SAP BW on the DSP side. You will need to create a Generic OData connection.</P><P>Implementation plan is following:</P><OL><LI>Create a CDS View Entity in S/4HANA using a Virtual Element.</LI><LI>Create an ABAP class that implements the calculation of this Virtual Element. The class code will include the target code call.</LI><LI>Register and test the OData Service.</LI><LI>Review the permissions required for the technical user on whose behalf the connection will be made. These permissions should be broader than the standard permissions for connections of type SAP S/4HANA On-Premise or SAP ABAP.</LI><LI>Notes regarding creating a Generic OData connection in DSP.</LI><LI>Create a simple Data Flow in DSP using the OData connection to the created CDS View. Running this Data Flow (manually, scheduled, or as part of a Task Chain) will trigger our target code in S/4HANA.</LI></OL><H2 id="toc-hId-1592120716">CDS View Entity with Virtual Element</H2><P>We will create a dummy CDS View. It doesn't need to provide any meaningful data. We only need the ability to add a Virtual Element field to it. Therefore, as an example, we'll use a selection from the TKA01 (Controlling Areas) table. Typically, a single Controlling Area with a value of 1000 is used. Based on this assumption, we'll create the CDS View. Of course, you can use other selections that are guaranteed to return a single record in your system. The following code is proposed:</P><pre class="lia-code-sample language-abap"><code>@EndUserText.label: 'CDS Virtual Element Test' @analytics.dataCategory: #DIMENSION @AccessControl.authorizationCheck: #NOT_REQUIRED @vdm.viewType: #BASIC @Metadata.ignorePropagatedAnnotations:true @ObjectModel.usageType.serviceQuality: #A @ObjectModel.usageType.sizeCategory: #S @ObjectModel.usageType.dataClass: #MASTER @analytics.dataExtraction.enabled: true @analytics.dataExtraction.delta.changeDataCapture.automatic: true @ObjectModel.supportedCapabilities:[#EXTRACTION_DATA_SOURCE] @AbapCatalog.viewEnhancementCategory: [#NONE] @odata.publish: true define view entity Z_CDS_VIRT_ELEM as select from tka01 { key kokrs, substring( cast( tstmp_current_utctimestamp() as abap.char(17) ), 1, 8 ) as dat, @ObjectModel.readOnly: true @ObjectModel.virtualElement: true @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_CDS_VIRT_ELEM_CALC' cast('' as abap.sstring( 1 )) as flag } where kokrs = '1000'</code></pre><UL><LI>&nbsp;The annotation at line 13 enables access to the CDS View via the OData Service.</LI><LI>The ‘dat’ field is added as a simple log: to see the date of the last calculation run.</LI><LI>The ‘flag’ field of the Virtual Element type is defined at line 22. It has the simplest form of a flag field. By default, as can be seen from the code, this field is empty. However, upon completion of calculations on the AS ABAP side, it will be filled with the value 'X'. This flag confirms at DSP side the successful completion of ABAP calculations.</LI><LI>The annotations at lines 19-21 define the "flag" field as a Virtual Element. In particular, the<SPAN>&nbsp;</SPAN><EM>@ObjectModel.virtualElementCalculatedBy</EM><SPAN>&nbsp;</SPAN>annotation specifies the name of the ABAP class that should calculate the ‘flag’ field.</LI></UL><P>When you initially activate this code, you'll receive, in particular, two warnings. For line 13 the system reports that the corresponding OData service is not active. For line 21 the system reports that the corresponding class doesn't exist. In the next steps, we'll resolve these issues.</P><P>If we use the context menu command 'Open With -&gt; Data Preview' on our CDS View at this point, the result will be as follows:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_0-1769288322366.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364869i9093A3B6E8D1A137/image-size/large?v=v2&amp;px=999" role="button" title="vitvas_0-1769288322366.jpeg" alt="vitvas_0-1769288322366.jpeg" /></span>Here the 'kokrs' and 'dat' fields are populated using standard CDS syntax. The virtual 'flag' field is left blank.</P><H2 id="toc-hId-1395607211" id="toc-hId-1395607211">Creation of ABAP Class implementing our calculations</H2><P>A Virtual Element calculation implementing&nbsp; class must use two standard interfaces: IF_SADL_EXIT и IF_SADL_EXIT_CALC_ELEMENT_READ:</P><pre class="lia-code-sample language-abap"><code>class ZCL_CDS_VIRT_ELEM_CALC definition public final create public . public section. interfaces IF_SADL_EXIT . interfaces IF_SADL_EXIT_CALC_ELEMENT_READ . protected section. private section. ENDCLASS.</code></pre><P>Second of these interfaces has two standard methods. A detailed description of these methods and their parameters can be found in the official documentation:<SPAN>&nbsp;</SPAN><A href="https://help.sap.com/docs/ABAP_PLATFORM_BW4HANA/cc0c305d2fab47bd808adcad3ca7ee9d/4b5e56ec6f28453f81ac370bd91fb06d.html" target="_blank" rel="noopener noreferrer">https://help.sap.com/docs/ABAP_PLATFORM_BW4HANA/cc0c305d2fab47bd808adcad3ca7ee9d/4b5e56ec6f28453f81a...</A></P><P>In our example, the following code is proposed for the GET_CALCULATION_INFO method:</P><pre class="lia-code-sample language-abap"><code>METHOD if_sadl_exit_calc_element_read~get_calculation_info. IF iv_entity = 'Z_CDS_VIRT_ELEM'. "Here we'll list which fields of CDS View will be used in virtual element calculation IF line_exists( it_requested_calc_elements[ table_line = 'FLAG' ] ). APPEND 'KOKRS' TO et_requested_orig_elements. ENDIF. ELSE. " Potential errors should be processed by public constants, " described in exceptional class, inherited from CX_SADL_EXIT. " For example, if CDS View is unknown: RAISE EXCEPTION TYPE zcx_ds_virt_elem_exceptions EXPORTING textid = zcx_ds_virt_elem_exceptions=&gt;c_entity_not_known. ENDIF. ENDMETHOD.</code></pre><P><SPAN>Errors occurring during execution of the class described above must be handled using system messages. For this purpose, public constants will be created in a separate exception class. The class must be a child of the standard CX_SADL_EXIT class. An example of such an exception class is provided in the official documentation:</SPAN><SPAN>&nbsp;</SPAN><A href="https://help.sap.com/docs/SAP_NETWEAVER_AS_ABAP_751_IP/cc0c305d2fab47bd808adcad3ca7ee9d/8cf4517994764710be0486af54cfb8ab.html" target="_blank" rel="noopener noreferrer">https://help.sap.com/docs/SAP_NETWEAVER_AS_ABAP_751_IP/cc0c305d2fab47bd808adcad3ca7ee9d/8cf451799476...</A><SPAN>&nbsp;&nbsp;</SPAN></P><P>As we can see, after specifying the parent class, a small constructor override is required. Each error is then declared as a public constant attribute. Naturally, such attribute contains a system message, previously defined in the Message Class relevant to the task.</P><P>Since our CDS View is designed to be as simple as possible, the IT_REQUESTED_CALC_ELEMENTS table will contain a single row with the ‘FLAG’ field. The ET_REQUESTED_ORIG_ELEMENTS table of regular source fields also contains only one record with the ‘KOKRS’ field.</P><P>Let's move on to the CALCULATE method:</P><pre class="lia-code-sample language-abap"><code>METHOD if_sadl_exit_calc_element_read~calculate. CHECK NOT it_original_data IS INITIAL. DATA lit_calculated_data TYPE STANDARD TABLE OF z_cds_virt_elem WITH DEFAULT KEY. MOVE-CORRESPONDING it_original_data TO lit_calculated_data. LOOP AT lit_calculated_data ASSIGNING FIELD-SYMBOL(&lt;lfs_calculated_data&gt;). "Here we need to add a call to the code that we wanted to initiate from the DSP side. "For example, we can submit some program: " SUBMIT z_some_program AND RETURN. &lt;lfs_calculated_data&gt;-flag = 'X'. "Formal flag of the calculation readiness EXIT. "Additional guarantee that calculation will be performed only once ENDLOOP. MOVE-CORRESPONDING lit_calculated_data TO ct_calculated_data. ENDMETHOD.</code></pre><P>Our CDS View is intentionally designed to return exactly one record. This means that in the CALCULATE method, the IT_ORIGINAL_DATA table also contains exactly one record. Consequently, the LOOP/ENDLOOP loop will only be executed once, and the target code will also be called only once.</P><P>After the ZCL_CDS_VIRT_ELEM_CALC class is activated, the warning on line 21 of our CDS View code will disappear.</P><H2 id="toc-hId-1199093706" id="toc-hId-1199093706">OData Service activation</H2><P>Our CDS View annotation specifies that it can be accessed via an OData Service. When we activate the CDS code, the corresponding OData Service will be created but not activated. Activation must be performed manually in the /IWFND/MAINT_SERVICE transaction. The OData Service name consists of the name of our CDS View followed by the _CDS suffix. In our example, the resulting name is Z_CDS_VIRT_ELEM_CDS.</P><P>Click the 'Add Service' button:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_4-1769288322417.jpeg" style="width: 540px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364872i49DF386BD4A8539A/image-dimensions/540x264?v=v2" width="540" height="264" role="button" title="vitvas_4-1769288322417.jpeg" alt="vitvas_4-1769288322417.jpeg" /></span></P><P>&nbsp;<SPAN>An ‘Add Selected Services’ window will appear. Enter Z_CDS_VIRT_ELEM_CDS as the technical name, and select LOCAL from the list in the 'System Alias' field. Then click 'Get Services'. A line with our service should appear:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2026-01-22 144602.jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364903iCE9192EFEDAD4077/image-size/large?v=v2&amp;px=999" role="button" title="Screenshot 2026-01-22 144602.jpg" alt="Screenshot 2026-01-22 144602.jpg" /></span></SPAN></P><P>&nbsp;<SPAN>Select the row with service description and press the ‘Add Selected Services’ button:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2026-01-22 144916.jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364904iBA1DDB808023FFBA/image-size/large?v=v2&amp;px=999" role="button" title="Screenshot 2026-01-22 144916.jpg" alt="Screenshot 2026-01-22 144916.jpg" /></span></SPAN><SPAN>In the 'Package Assignment' field, specify the appropriate package for subsequent import of developed objects to the production system. In the 'ICF Node' section, select the 'SAP Gateway OData V2' setting. An important setting is the 'Enable OAuth for Service' checkbox. Check with your BASIS Team to determine whether OAuth will be used when connecting the DSP to the ABAP system. If so, enable this checkbox. After confirming the settings, service activation will begin. Upon completion, the following message will appear:&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_7-1769288322396.jpeg" style="width: 590px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364875i0DC57C6BA63E46F0/image-dimensions/590x204?v=v2" width="590" height="204" role="button" title="vitvas_7-1769288322396.jpeg" alt="vitvas_7-1769288322396.jpeg" /></span></P><P>Now you need to return to the main transaction window and filter the newly activated service in the list:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2026-01-22 151814.jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364905iE2AFDB6B44E248EB/image-size/large?v=v2&amp;px=999" role="button" title="Screenshot 2026-01-22 151814.jpg" alt="Screenshot 2026-01-22 151814.jpg" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Picture7.jpg" style="width: 903px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364906i35FBCA17C138A5F7/image-size/large?v=v2&amp;px=999" role="button" title="Picture7.jpg" alt="Picture7.jpg" /></span></P><P>&nbsp;<SPAN>Check the traffic light in the 'Status' field (the leftmost field in the ICF Nodes section). If it's yellow, select the drop-down list from the 'ICF Node' button directly above it and execute the 'Activate' command:</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_10-1769288322438.jpeg" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364878iCD05D2C4FD8B5D16/image-size/medium?v=v2&amp;px=400" role="button" title="vitvas_10-1769288322438.jpeg" alt="vitvas_10-1769288322438.jpeg" /></span></P><P>The window for selecting a package for importing activated objects into production will appear again:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_11-1769288322453.jpeg" style="width: 513px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364879i5E60655091582319/image-dimensions/513x108?v=v2" width="513" height="108" role="button" title="vitvas_11-1769288322453.jpeg" alt="vitvas_11-1769288322453.jpeg" /></span></P><P>After this, the traffic light will change to green. You can now test the service by clicking the 'SAP Gateway Client' button:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_12-1769288322381.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364881i8D27B1695748C09C/image-size/large?v=v2&amp;px=999" role="button" title="vitvas_12-1769288322381.jpeg" alt="vitvas_12-1769288322381.jpeg" /></span></P><P>&nbsp;By default, the test transaction specifies a URI that reads the service description:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_13-1769288322424.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364884iFD190E19E523142F/image-size/large?v=v2&amp;px=999" role="button" title="vitvas_13-1769288322424.jpeg" alt="vitvas_13-1769288322424.jpeg" /></span></P><P>But we're interested in what entities this service can provide. This can be found by clicking the 'Entity Set' button:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_14-1769288322350.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364883iA33215136874B20E/image-size/large?v=v2&amp;px=999" role="button" title="vitvas_14-1769288322350.jpeg" alt="vitvas_14-1769288322350.jpeg" /></span></P><P>Here we see that the service can read data for CDS View Z_CDS_VIRT_ELEM. By double-clicking this name, we can change the URI:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_15-1769288322373.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364886i2B5637354B48010F/image-size/large?v=v2&amp;px=999" role="button" title="vitvas_15-1769288322373.jpeg" alt="vitvas_15-1769288322373.jpeg" /></span></P><P>If you now click the 'Execute' button, data will be read from the CDS View Z_CDS_VIRT_ELEM via the OData Service. This is precisely the operation that should trigger the calculation of the 'flag' field via the ABAP class described above. If you need to study or debug this class, you can set breakpoints there before clicking 'Execute'. The calculation results will be presented here in XML format:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2026-01-22 161759.jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364914i69CCC583187E5E8E/image-size/large?v=v2&amp;px=999" role="button" title="Screenshot 2026-01-22 161759.jpg" alt="Screenshot 2026-01-22 161759.jpg" /></span><SPAN>Here you can see that the 'flag' field is filled with the value 'X'. This means that the CALCULATE method was executed along with the target code call.</SPAN></P><H2 id="toc-hId-1002580201" id="toc-hId-1002580201">System user authorizations</H2><P>When creating a DSP connection to an ABAP system, a special user of the System type is used. Typically, the BASIS Team assigns this user a standard set of permissions sufficient for connections of SAP S/4HANA On-Premise, SAP ABAP, or SAP BW types. Experience has shown that a Generic OData connection requires a number of additional permissions.</P><P>First, you need to add authorizations to launch the created OData Service. This is the S_SERVICE authorization object. Editing it differs from most standard authorization objects. After adding the object to the role profile, click the edit button for the SRV_NAME field. In the window that appears, select 'TADIR Service' from the Type drop-down list, which will display a list of services allowed to launch:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_17-1769288322449.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364885i8650D66A295FF367/image-size/large?v=v2&amp;px=999" role="button" title="vitvas_17-1769288322449.jpeg" alt="vitvas_17-1769288322449.jpeg" /></span></P><P>We need to add two types of objects for our service: IWSG and IWSV. First, select the appropriate type from the list in the 'Object Type' column. Then, use the search (for example, by pressing F4) in the 'Object Name' column. In both cases, you can use the name of our service (i.e. - &nbsp;Z_CDS_VIRT_ELEM_CDS) to search for the desired value:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_18-1769288322501.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364889i87FCE802AE976638/image-size/large?v=v2&amp;px=999" role="button" title="vitvas_18-1769288322501.jpeg" alt="vitvas_18-1769288322501.jpeg" /></span>The name of the object being searched consists of the service name and the ordinal number of the active version of this service (four digits). For the first version of service in our example, the IWSG type value is 'Z_CDS_VIRT_ELEM_CDS_0001', and the IWSV type value is 'Z_CDS_VIRT_ELEM_CDS 0001'.</P><P>After saving the selected values, you will see that the value 'HT' is automatically added to the SRV_TYPE field. Thus, the S_SERVICE authorizations have been added and the values ​​specified.</P><P>It is also important to note that specific authorizations may be required, which depend on the specific target code you want to run in the CALCULATE method described above. For example, if you plan to use a command like 'SUBMIT z_some_program AND RETURN' to launch a program, you will need the corresponding authorizations in the S_PROGRAM object. If the target code performs, for example, calculations related to the FI module, the system user may require authorizations specific to that module. If the target code accesses the contents of database tables, authorizations in the S_TABU_DIS and S_TABU_NAM objects may be required. And so on. Most likely, during the OData service testing phase (as described in the previous section), you will need to collaborate with the BASIS Team to monitor missing authorizations and add them to the system user's roles. The simplest solution is to temporarily (and only in the development system!) change the user type from system to dialog. In this case, you can log in to the SAP GUI with this user's login and manually run OData service testing while simultaneously monitoring the authorizations being checked.</P><P>The security issue of assigning such non-typical authorizations to a system user is mitigated by the fact that this user is created only to connect DSP to the ABAP system and cannot be used for manual data access, like a dialog user.</P><H2 id="toc-hId-806066696" id="toc-hId-806066696">DSP OData Connection</H2><P>Creating a Generic OData connection should be performed by BASIS Team specialists, as the required settings depend on the system landscape used in your specific project, as well as the security settings applied (for example, whether OAuth is enabled). Here's an example of the settings used in our project:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_19-1769288322316.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364890iBB98D5C13345890F/image-size/large?v=v2&amp;px=999" role="button" title="vitvas_19-1769288322316.jpeg" alt="vitvas_19-1769288322316.jpeg" /></span><SPAN>The address entered in the ‘URL’ field ends with the technical name of our OData service. Therefore, a separate connection will need to be created for each OData service.</SPAN></P><P>In the ‘Version’ field, V2 is selected. This is because we specified OData V2 when activating the service above and didn't have the option to select V4:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_20-1769288322477.jpeg" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364888i9FAF1FC8B0406D18/image-size/medium?v=v2&amp;px=400" role="button" title="vitvas_20-1769288322477.jpeg" alt="vitvas_20-1769288322477.jpeg" /></span></P><P>The example also shows that OAuth is used. That's why the corresponding checkbox was enabled earlier when activating the service:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_21-1769288322383.jpeg" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364891i4E5A1CDB1A371F13/image-size/medium?v=v2&amp;px=400" role="button" title="vitvas_21-1769288322383.jpeg" alt="vitvas_21-1769288322383.jpeg" /></span></P><P>At the bottom of the connection settings window, click the ‘Show Advanced Properties’ button:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_22-1769288322357.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364892iAB63E00A23049750/image-size/large?v=v2&amp;px=999" role="button" title="vitvas_22-1769288322357.jpeg" alt="vitvas_22-1769288322357.jpeg" /></span></P><P>Here you need to specify for the OData service the client number of the ABAP system we are connecting to:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_23-1769288322479.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364893iB6A73B22B92EA7E5/image-size/large?v=v2&amp;px=999" role="button" title="vitvas_23-1769288322479.jpeg" alt="vitvas_23-1769288322479.jpeg" /></span></P><P>&nbsp;</P><H2 id="toc-hId-609553191" id="toc-hId-609553191">DSP Data Flow to use OData connection and trigger the target code</H2><P>We need to create a Data Flow with our OData service as a source. To do this, open Data Builder (in the same Space where you created OData service connection). In the left pane, select the 'Sources' tab and open the 'Connections' folder:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_24-1769288322401.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364896i7546FBCE3CF163EA/image-size/large?v=v2&amp;px=999" role="button" title="vitvas_24-1769288322401.jpeg" alt="vitvas_24-1769288322401.jpeg" /></span></P><P>If all connection settings and system user authorizations were configured correctly, you will see the connection, and when you expand it, you will see the name of our CDS View:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_25-1769288322407.jpeg" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364894i654970E6A0C0836C/image-size/medium?v=v2&amp;px=400" role="button" title="vitvas_25-1769288322407.jpeg" alt="vitvas_25-1769288322407.jpeg" /></span></P><P><SPAN>The icon next to the CDS View is the same as for a regular table. You can drag and drop this View into the Data Flow being created. It will be automatically recognized as a Source. At this step, you can select the 'Preview Data' command for this table:</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_26-1769288322381.jpeg" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364895i5C83380C45F8F4B1/image-size/medium?v=v2&amp;px=400" role="button" title="vitvas_26-1769288322381.jpeg" alt="vitvas_26-1769288322381.jpeg" /></span></P><P>The result should look like this:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_27-1769288322289.jpeg" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364897iEEB3120BABBCC2AC/image-size/medium?v=v2&amp;px=400" role="button" title="vitvas_27-1769288322289.jpeg" alt="vitvas_27-1769288322289.jpeg" /></span></P><P>The presence of an 'X' in the 'flag' field means that the target code has been executed on the ABAP system side. If the target code execution takes a long time, you will also notice the delay when viewing it in the DSP.</P><P>As a final step, you need to complete the Data Flow by adding the target table to it, which in this case only serves as a dummy. Save the Data Flow and deploy it.</P><H2 id="toc-hId-413039686">Result</H2><P>Now you can initiate execution of the target code in the ABAP system in any way convenient for you: by manually starting the Data Flow, scheduling it, or including the Data Flow in a Task Chain.</P><P>&nbsp;</P><P>&nbsp;</P><H3 id="toc-hId-542122405" id="toc-hId-345608900"><EM>Note: Data Preview is not working for Virtual Element</EM></H3><P>As a result of our implementation, OData Service is activated and implementing ABAP class exist for our Virtual Element. And &nbsp;we can repeat attempt of CDS data preview in ABAP Development Tools (CDS editor context menu command 'Open With -&gt; Data Preview'). Unfortunately, result will be the same: field ‘flag’ is empty:&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="vitvas_28-1769288322404.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/364898i13E8077EA80F571A/image-size/large?v=v2&amp;px=999" role="button" title="vitvas_28-1769288322404.jpeg" alt="vitvas_28-1769288322404.jpeg" /></span>This is explained by the fact that the Virtual Element calculation is performed only when accessing the CDS through OData Service.</P><P>&nbsp;</P> 2026-01-27T08:11:27.946000+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/when-synchronous-odata-failed-for-bulk-data-processing-how-i-solved-problem/ba-p/14322933 When Synchronous OData Failed for bulk data processing: How I Solved Problem Using OData V4 Async : 2026-02-09T07:33:18.454000+01:00 pavanKolla https://community.sap.com/t5/user/viewprofilepage/user-id/2108029 <P><STRONG>The Business Context:</STRONG></P><UL><LI>BlueYonder sends planning and operational data</LI><LI>The data volume is large</LI><LI>Data needs to be posted into SAP S/4HANA Public Cloud</LI><LI>SAP exposes this functionality via OData V2 and V4 APIs</LI></UL><P>The expectation was simple: “Send data from BlueYonder and create/update records in S/4HANA.” But in reality, it was not that easy.</P><P><STRONG>Introduction:</STRONG></P><P>In real projects, integrations look simple on paper but behave very differently in production.</P><P>This blog is about a real-time problem I faced while integrating BlueYonder planning data into SAP S/4HANA Public Cloud using OData V2 Inbound.</P><P>The solution was understanding how OData V4 async processing works and using one small but powerful HTTP header.</P><P>In this blog, I will explain:</P><UL><LI>What problem I faced</LI><LI>Why synchronous processing failed</LI><LI>How I implemented async OData V4 processing with API proxy(through URL).</LI><LI>What changed after enabling async</LI></UL><P>&nbsp;</P><P><STRONG>The Actual Problem</STRONG></P><P>Initially, I implemented the integration in a synchronous way.</P><P><STRONG>What Happened</STRONG></P><UL><LI>CPI sent data to S/4HANA public cloud using standard OData V2 synchronous Api</LI><LI>The backend took time to process the payload</LI><LI>CPI waited for the response</LI><LI>Requests started failing due to:</LI><UL><LI>Timeouts</LI><LI>Long-running backend processing</LI><LI>Unstable behaviour during peak loads</LI></UL></UL><P><STRONG>The Key Issue</STRONG></P><P>OData V2 APIs are synchronous by default. This means:</P><UL><LI>CPI waits until S/4HANA public cloud finishes posting</LI><LI>Large payloads increase risk</LI><LI>One slow request can block the entire flow This was not acceptable for a production-grade integration.</LI><LI>Chunking the payload using General splitter and streaming could increase the number of API Calls and may increase the load on Public cloud.</LI></UL><P><STRONG>Design:</STRONG></P><P>While analysing SAP documentation, I came across the asynchronous processing capability of OData V4. SAP provides a standard way to tell the backend: “Accept the request, process it in the background, and do not keep the connection open.”<BR />This is done using the HTTP header:&nbsp;<STRONG>Prefer = respond-async<BR /><BR /></STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pavanKolla_0-1770374072960.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/369530i2E4E8CCAF4947A46/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="pavanKolla_0-1770374072960.png" alt="pavanKolla_0-1770374072960.png" /></span></P><P><STRONG>Step-by-Step Implementation :</STRONG></P><P><STRONG>Step 1: Receiving HighRadiusData in CPI</STRONG></P><UL><LI>BlueYonder sends data in Flatten File.</LI><LI>CPI receives the data and prepares it for S/4HANA public cloud.</LI></UL><P>Data structure is aligned to OData V4 expectations At this point, the flow is still normal.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pavanKolla_1-1770374153452.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/369531iA175F35EB2526E64/image-size/large?v=v2&amp;px=999" role="button" title="pavanKolla_1-1770374153452.png" alt="pavanKolla_1-1770374153452.png" /></span></P><P>&nbsp;</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pavanKolla_2-1770374153460.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/369532iE3F7F3E059F819E8/image-size/large?v=v2&amp;px=999" role="button" title="pavanKolla_2-1770374153460.png" alt="pavanKolla_2-1770374153460.png" /></span></P><P>&nbsp;</P><UL><LI>*Here I had implemented the Retry mechanism using JMS Queues which is the best practice for the SAP integrations ,If you like you implement it do check out my previous Blog that I had posted in the SAP Community.<BR />Blog URL – {<A href="https://community.sap.com/t5/technology-blog-posts-by-members/handling-connectivity-and-recoverable-errors-in-sap-cpi-with-jms-queues/ba-p/14137974" target="_blank">https://community.sap.com/t5/technology-blog-posts-by-members/handling-connectivity-and-recoverable-errors-in-sap-cpi-with-jms-queues/ba-p/14137974</A>}</LI></UL><P><STRONG>Step 2: Setting the Async Header (Most Important Step)</STRONG></P><P>In CPI, I used a Content Modifier to add HTTP headers.</P><P><STRONG>Header : Prefer Header</STRONG>&nbsp;<STRONG>Prefer = respond-async</STRONG>&nbsp;This header completely changes how the request is handled.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pavanKolla_3-1770374217703.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/369533i85DDC82758842987/image-size/large?v=v2&amp;px=999" role="button" title="pavanKolla_3-1770374217703.png" alt="pavanKolla_3-1770374217703.png" /></span></P><P>&nbsp;</P><P><STRONG>What Happens After Adding respond-async</STRONG></P><P>Once this header is added:</P><UL><LI>CPI sends the request</LI><LI>S/4HANA immediately responds with HTTP 202 – Accepted</LI><LI>Backend processing continues asynchronously</LI><LI>CPI does not wait for the final processing result This single header removed timeout risks completely.</LI></UL><P><STRONG>Step 3: Posting Data via API Proxy<BR /><BR /></STRONG>* Here, I had used OAuth 2.0 Authentication between Integration suite to API Proxy and between API Proxy and S/4 Hana public cloud I had used Certificate Based Authentication.<STRONG><BR /><BR /></STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pavanKolla_4-1770374264097.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/369534i7B9D79BD1A281884/image-size/large?v=v2&amp;px=999" role="button" title="pavanKolla_4-1770374264097.png" alt="pavanKolla_4-1770374264097.png" /></span></P><P>&nbsp;</P><UL><LI>CPI sends the request to an API Proxy</LI><LI>The proxy forwards the call to the OData V4 API from SAP Business Accelerator Hub</LI><LI>The proxy is created using the URL-based option</LI></UL><P><STRONG>Note : </STRONG><EM>OData V4 services do not appear in the API Provider’s service catalog in SAP API Management</EM>, so discovery isn’t possible — and that’s why I go with the URL method, so if you want to create proxy for OData V4 public cloud the correct approach is just go with the URL Option don’t fall for this pitfall.</P><P>If you want to leverage more on how to create API Proxy with URL option follow SAP Official Documentation.<BR />Official documentation: {<A href="https://help.sap.com/docs/sap-api-management/sap-api-management/create-api-proxy-by-providing-direct-target-endpoint-url" target="_blank" rel="noopener noreferrer">https://help.sap.com/docs/sap-api-management/sap-api-management/create-api-proxy-by-providing-direct-target-endpoint-url</A>}</P><P>From CPI’s perspective:</P><UL><LI>The request is completed successfully</LI></UL><P>No long-running connection is maintained</P><UL><LI><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pavanKolla_5-1770374298201.png"><img src="https://community.sap.com/skins/images/9B9B919129011BEAB02AD89C27767D82/responsive_peak/images/image_rejected.gif" alt="pavanKolla_5-1770374298201.png" /></span><P><STRONG>What Changed After This Implementation</STRONG></P><P><STRONG>Before Async</STRONG></P><UL><LI>Timeouts during high data volume</LI><LI>Unstable integration behaviour</LI><LI>Risk of message failures</LI></UL><P><STRONG>After Async</STRONG></P><UL><LI>Immediate response to CPI</LI><LI>Backend processing happens safely</LI><LI>No timeout issues</LI><LI>Integration became stable and predictable</LI></UL><P>This was a real production-grade improvement, not just a theoretical change, I hope this helps you folks that don’t fall for this pitfall in your production.</P><P>&nbsp;</P></LI></UL><P><BR /><BR /></P><P><BR /><BR /><BR /><BR /></P><P>&nbsp;</P><P><BR /><BR /></P> 2026-02-09T07:33:18.454000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/using-adapter-http-response-403-for-odata-api-post-method-how-to-solve-the/ba-p/14333246 Using Adapter HTTP - Response 403 for OData API Post Method- How to solve the big challenge 2026-02-21T11:06:08.764000+01:00 Yogananda https://community.sap.com/t5/user/viewprofilepage/user-id/75 <DIV>Connecting SAP S/4 HANA or ERP systems with external applications using OData services is becoming the backbone of modern enterprise integrations. Tools such as <STRONG>SAP Cloud Integration (CPI)</STRONG> or <STRONG>Integration Suite’s using HTTP Adapter</STRONG> make it easy to consume or&nbsp;<SPAN>expose APIs—until you hit a frustrating roadblock:</SPAN><DIV><BLOCKQUOTE><P><FONT color="#FF0000"><STRONG>“HTTP 403 – Forbidden” when calling an OData API POST method.</STRONG></FONT></P></BLOCKQUOTE><P>This error is notoriously deceptive. Your GET requests work fine. Your endpoint is correct. Your payload is correct. Yet POST still fails.<BR />Why?</P><P>In this blog, we’ll break down <STRONG>why <FONT color="#FF0000">HTTP 403 happens</FONT></STRONG><FONT color="#FF0000">,</FONT> <STRONG>what makes POST requests special</STRONG>, and—most importantly—<STRONG>how to solve this challenge with proven, real-world fixes</STRONG>.</P></DIV></DIV><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="2026-02-16_20-20-23.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374961i951DD275017D4977/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="2026-02-16_20-20-23.png" alt="2026-02-16_20-20-23.png" /></span></P><DIV><H2 id="toc-hId-1790475588"><STRONG>1. <FONT color="#993300">Understanding the 403 Forbidden Error</FONT></STRONG></H2><P>A <STRONG>403 Forbidden</STRONG> response means:</P><BLOCKQUOTE><P>The server understood your request but refuses to authorize it.</P></BLOCKQUOTE><P>In the context of OData POST calls via the HTTP adapter, this almost always indicates an <STRONG>authorization</STRONG>, <STRONG>CSRF</STRONG>, or <STRONG>policy-related</STRONG> issue.</P></DIV><DIV><H2 id="toc-hId-1593962083"><STRONG>2. <FONT color="#993300">Why GET Works but POST Fails</FONT></STRONG></H2><P>Many developers test an OData service with a GET call, find that it works, and assume the setup is correct. But POST behaves differently because it:</P><UL><LI><STRONG>Modifies data</STRONG>, triggering stricter authorization checks</LI><LI><STRONG>Requires CSRF token handling</STRONG> (depending on the endpoint)</LI><LI>May require <STRONG>additional headers</STRONG></LI></UL><P>This is why GET succeeding does <EM>not</EM> prove the integration is fully configured.</P></DIV><DIV><H2 id="toc-hId-1397448578"><STRONG>3. <FONT color="#993300">The Top Causes of HTTP 403 for OData POST (and How to Fix Them)</FONT></STRONG></H2><H3 id="toc-hId-1330017792"><STRONG>Cause 1 — Missing or Incorrect CSRF Token</STRONG></H3><P>Many SAP OData services require a valid <STRONG>X-CSRF-Token</STRONG> for <FONT color="#FF00FF">POST/PUT/PATCH/DELETE.</FONT></P><P>✔ <STRONG>Solution:</STRONG><BR />Perform a <STRONG>GET request with header</STRONG>:</P></DIV><pre class="lia-code-sample language-abap"><code>X-CSRF-Token: Fetch</code></pre><DIV><DIV><P>and capture:</P><UL><LI>Returned CSRF token</LI><LI>Returned cookies</LI></UL><P>Then send them along in your POST call:</P></DIV></DIV><pre class="lia-code-sample language-abap"><code>X-CSRF-Token: &lt;token&gt; Cookie: &lt;cookies&gt;</code></pre><DIV><H3 id="toc-hId-1133504287"><STRONG>Cause 2 — Incorrect or Missing Headers</STRONG></H3><P>Some OData services enforce additional constraints.</P><P>Mandatory headers may include:</P><PRE><CODE>Content-Type: application/json Accept: application/json</CODE></PRE></DIV><DIV><H2 id="toc-hId-807908063"><STRONG>4. How to Troubleshoot 403 Efficiently</STRONG></H2><H3 id="toc-hId-740477277"><STRONG>Step 1 — Test POST via Postman</STRONG></H3><UL><LI>Fetch CSRF token first</LI><LI>Send cookies + token in POST</LI><LI>Add all required headers</LI></UL><DIV><H3 id="toc-hId-543963772"><STRONG>Step 2 — Check SAP Gateway Error Logs</STRONG></H3><P>Use transaction <STRONG>/IWFND/ERROR_LOG</STRONG> or <STRONG>/IWBEP/ERROR_LOG</STRONG>.</P><P>You may see:</P><UL><LI>"No CREATE authorization"</LI><LI>"CSRF Token validation failed"</LI><LI>"Request method not allowed"</LI></UL><P>These messages are extremely helpful.</P></DIV></DIV><DIV><H2 id="toc-hId-218367548"><FONT color="#993300"><STRONG>5. Example Adapter HTTP Configuration for POST (CPI)</STRONG></FONT></H2><H3 id="toc-hId-150936762"><STRONG>Headers</STRONG><SPAN>&nbsp;</SPAN></H3></DIV><pre class="lia-code-sample language-abap"><code>Method: POST Content-Type: application/json Accept: application/json X-CSRF-Token: &lt;fetched token&gt; Cookie: &lt;SAP cookies&gt;</code></pre><DIV>Body (Example)</DIV><pre class="lia-code-sample language-abap"><code>{ "Name": "Sample Item", "Quantity": 10 }</code></pre><H2 id="toc-hId-172594895">Set Header for Cookie + CSRF token&nbsp;<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="2026-02-21_10-48-43.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374958i031B49CEE0F5D5CE/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="2026-02-21_10-48-43.png" alt="2026-02-21_10-48-43.png" /></span></H2><H2 id="toc-hId--23918610">&nbsp;Groovy Script 1(Shown from above Iflow image)</H2><pre class="lia-code-sample language-java"><code>import com.sap.gateway.ip.core.customdev.util.Message; def Message processData(Message message) { def headers = message.getHeaders(); def cookie = headers.get("Set-Cookie"); def csrf = headers.get("x-csrf-token"); StringBuffer bufferedCookie = new StringBuffer(); for (Object item : cookie) { bufferedCookie.append(item + "; "); } message.setHeader("Cookie", bufferedCookie.toString()); message.setHeader("x-csrf-token", csrf) return message }</code></pre><H2 id="toc-hId--220432115">POST Method&nbsp;&nbsp;<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="2026-02-21_10-52-56.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374960i7691E0FCEACED76A/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="2026-02-21_10-52-56.png" alt="2026-02-21_10-52-56.png" /></span></H2><H2 id="toc-hId--416945620"><FONT color="#993300"><STRONG>6. Conclusion – Turning a Frustrating 403 into a Successful POST</STRONG></FONT></H2><P>The <STRONG>HTTP 403 Forbidden</STRONG> error for OData POST calls is one of the most common yet misunderstood issues when integrating SAP systems. But once you understand:</P><UL><LI>CSRF handling</LI><LI>Role/authorization requirements</LI><LI>Header and policy rules</LI><LI>Gateway restrictions</LI></UL><P>…the problem becomes easy to solve.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="2026-02-21_10-46-10.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374956iE509568CB3CB28EB/image-size/large/is-moderation-mode/true?v=v2&amp;px=999" role="button" title="2026-02-21_10-46-10.png" alt="2026-02-21_10-46-10.png" /></span></P><P>Following the troubleshooting guidelines above will help you quickly identify the root cause and ensure your POST requests work reliably—whether you're integrating via CPI, API Management, BTP, or direct HTTP calls.</P> 2026-02-21T11:06:08.764000+01:00