https://raw.githubusercontent.com/ajmaradiaga/feeds/main/scmt/topics/NW-ABAP-Gateway-(OData)-blog-posts.xmlSAP Community - NW ABAP Gateway (OData)2026-03-04T00:11:09.888543+00:00python-feedgenNW ABAP Gateway (OData) blog posts in SAP Communityhttps://community.sap.com/t5/financial-management-blog-posts-by-sap/fscm-collections-extend-manage-customer-line-items-app-f0711-odata-mpc-amp/ba-p/13890031[FSCM Collections]: Extend Manage Customer Line Items(App F0711) – OData MPC & DPC Code Enhancement2024-10-06T22:52:27.703000+02:00robinthakralhttps://community.sap.com/t5/user/viewprofilepage/user-id/801057<H3 id="toc-hId-1180650176"><STRONG>INTRODUCTION</STRONG><STRONG>:</STRONG></H3><P>We have been given a requirement to add a set of custom fields to be extended in <EM><STRONG>Manage Customer Line Items</STRONG> </EM>(App ID <A href="https://fioriappslibrary.hana.ondemand.com/sap/fix/externalViewer/#/detail/Apps('F0711')/S22OP" target="_blank" rel="noopener nofollow noreferrer">F0711</A>) – Credit Management.</P><P>Challenge: The current system is an S4 HANA system version 2021, where CFL (Custom Fields and Logic) has been introduced but isn't available for the required App. Given is a SEGW Project with <A href="https://help.sap.com/docs/SAP_NETWEAVER_AS_ABAP_752/cc0c305d2fab47bd808adcad3ca7ee9d/820b24ce35c745bb9e0fb3a6e8d6dbd4.html?version=7.52.4&locale=en-US" target="_blank" rel="noopener noreferrer">OData Services based on a Mapped Data Source (MDS)</A>. Redefinition w/ Extension of the project isn't possible, and we should not Overwrite the Std. Project.</P><P>Solution (<FONT color="#FF0000">Not a Clean-Core </FONT><span class="lia-unicode-emoji" title=":disappointed_face:">😞</span>) -This app is an OData Service application, so enhancing the MPC & DPC will be able to view the fields but can’t sort & filter the list as they are not part of the standard mapped CDS view and can’t be handled in SADL query options.</P><P>In this blog post, we will cover the required steps:</P><UL><LI>Extend the DDIC Structure, CDS View (if any) – Database Layer</LI><LI>Enhance the Service MPC (Model) – w/ BADI or Implicit (<FONT color="#FF0000">not recommended</FONT>) Enhancement</LI><LI>Enhance the Service DPC (Data) – w/ BADI or Implicit (<FONT color="#FF0000">not recommended</FONT>) Enhancement</LI></UL><P>to handle the requirement.</P><P> </P><H3 id="toc-hId-984136671"><STRONG>MAIN CONTENT</STRONG><STRONG>:</STRONG></H3><OL><LI>From the Fiori Application Console (F12 / Cntrl+Shift+I) or Fiori Library, get the service name to open the respective SEGW Project and look for the Responsible Entity.<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Entity Types.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/176035i5182723D47C0AF24/image-size/medium?v=v2&px=400" role="button" title="Entity Types.png" alt="Entity Types.png" /></span> You can check the Mapping for Ease<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Items Mapping I_ARLINEITEM.png" style="width: 200px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/176036i2ECD2330F7841A1E/image-size/small?v=v2&px=200" role="button" title="Items Mapping I_ARLINEITEM.png" alt="Items Mapping I_ARLINEITEM.png" /></span><P> Open the DDIC Structure and look for the Persistent/Transient Include for our required, but here we found SQL Structure for CDS View itself.<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Include Structure.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/176039i0A86FDA7B6F60C35/image-size/medium?v=v2&px=400" role="button" title="Include Structure.png" alt="Include Structure.png" /></span></P><P> <SPAN>So, let's better extend the required custom fields in there with the help of an APPEND structure.<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="AppendStructure.png" style="width: 200px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/176040iAF65697AEFCB97F7/image-size/small?v=v2&px=200" role="button" title="AppendStructure.png" alt="AppendStructure.png" /></span></SPAN></P></LI><LI>Let’s try to find some BADI with Enhancement Spots first for OData, which we didn’t find for our App scenario. Hence, proceeded with Implicit Enhancement at MPC_EXT – Method DEFINE.</LI></OL><P> </P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>DATA: lo_entity_type TYPE REF TO /iwbep/if_mgw_odata_entity_typ, "#EC NEEDED
lo_property TYPE REF TO /iwbep/if_mgw_odata_property, "#EC NEEDED
lv_text_ele TYPE textpoolky,
lv_char TYPE i.
" Map the Entity Type
lo_entity_type = model->get_entity_type( iv_entity_name = 'Item' ).
" Loop For no of Custom fields
DO 2 TIMES. "#EC CI_NESTED
IF sy-index = 1.
lo_entity_type->create_property(
EXPORTING
iv_property_name = 'CollectionNotes1'
iv_abap_fieldname = 'ZZ_COMMENT1'
RECEIVING
ro_property = DATA(lo_pro_item1) ). " LO_PROPERTY
lv_text_ele = |CN1| . " Literal for Text-Element
ELSE.
lo_entity_type->create_property(
EXPORTING
iv_property_name = 'CollectionNotes2'
iv_abap_fieldname = 'ZZ_COMMENT2'
RECEIVING
ro_property = lo_pro_item1 ). " LO_PROPERTY
lv_text_ele = |CN2| .
ENDIF.
lv_char = 128.
" Create the Property Details
lo_pro_item1->set_type_edm_string( ).
lo_pro_item1->set_maxlength( lv_char ).
lo_pro_item->set_nullable( abap_true ).
lo_pro_item1->set_updatable( abap_true ).
lo_pro_item1->set_sortable( abap_false ).
lo_pro_item1->set_filterable( abap_false ).
" When to Map Front-End Labels different from ABAP field's DATA ELEMENT.
" Create Text CN1 & CN2 in Custom Class
lo_pro_item1->set_label_from_text_element(
EXPORTING
iv_text_element_symbol = lv_text_ele
iv_text_element_container zfscmcl_customer_line_comment=>gc_class_name " Constant - Custom Class Name
** io_object_ref = me " when Text-elements of MPC_EXT is used
).
lo_pro_item1->set_internal_type( 'C' ).
lo_pro_item1->set_internal_length( lv_char ). "( '128' ).
CLEAR: lv_text_ele.
ENDDO.
cl_afle_mpc_ext_utility_class=>adjust_model( model ). "AFLE</code></pre><P> </P><P> </P><P>Adjusting the Model is necessary to handle action redefinition/addition. The front end can be handled by the Extension/Adaptation Project (if needed).</P><UL><LI><P>All the Data handling for the enhanced fields must be handled in this class methods to related entities & entity sets. Now Field values can be database stored or Run-time calculated. <SPAN>Here, </SPAN>Values are fetched at the Item level first. Values for multiple or single records have been fetched. So, create Enhancement at ITEMSET_GET_ENTITYSET:</P></LI></UL><P> </P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>************************************************************************
"Create Key Field Structure in Custom Class
types:
BEGIN OF gty_cli_key ,
bukrs TYPE bukrs,
belnr TYPE belnr_d,
gjahr TYPE gjahr,
buzei TYPE buzei,
kunnr TYPE kunnr,
END OF gty_cli_key .
types:
gtt_cli_key TYPE SORTED TABLE OF gty_cli_key WITH UNIQUE KEY bukrs belnr gjahr buzei .
************************************************************************
" In GET_ENTITYSET
lt_cli_key = VALUE #( FOR ls_entity IN et_entityset
WHERE ( companycode IS NOT INITIAL "#EC CI_STDSEQ
AND accountingdocument IS NOT INITIAL )
( bukrs = ls_entity-companycode
belnr = ls_entity-accountingdocument
buzei = ls_entity-accountingdocumentitem
gjahr = ls_entity-fiscalyear )
).
IF lt_cli_key IS NOT INITIAL.
"Custom Method to process the data.
DATA(lt_comments) = zfscmcl_customer_line_comment=>get_comments(
it_cli_key = lt_cli_key ).
UNASSIGN <ls_entity>.
LOOP AT lt_comments ASSIGNING FIELD-SYMBOL(<ls_comments>).
ASSIGN et_entityset[
companycode = <ls_comments>-company_code "#EC CI_STDSEQ
accountingdocument = <ls_comments>-document_number
accountingdocumentitem = <ls_comments>-line_item_number
fiscalyear = <ls_comments>-fiscal_year
] TO <ls_entity>.
IF <ls_entity> IS ASSIGNED.
<ls_entity>-zz_comment1 = <ls_comments>-comment1.
<ls_entity>-zz_comment2 = <ls_comments>-comment2.
UNASSIGN <ls_entity>.
ENDIF.
ENDLOOP.
IF <ls_comments> IS ASSIGNED. UNASSIGN <ls_comments>. ENDIF.
CLEAR: lt_comments.
ENDIF.</code></pre><P> </P><P> </P><P> </P><P>4. Now check the fields in Adapt Settings. Better Clear Caches & Refresh Service Metdata with: </P><UL><LI>/IWBEP/CACHE_CLEANUP</LI><LI>IWFND/CACHE_CLEANUP</LI><LI>Refresh Metadata Layer at IWFND/MAINT_SERVICE</LI></UL>2024-10-06T22:52:27.703000+02:00https://community.sap.com/t5/application-development-and-automation-blog-posts/odata-versioning-in-sap-streamlining-parallel-development-for-backend-and/ba-p/13904545OData Versioning in SAP - Streamlining Parallel Development for Backend and Frontend Teams2024-10-24T11:43:17.153000+02:00AbhiDaggubatihttps://community.sap.com/t5/user/viewprofilepage/user-id/12172<P><STRONG>OData</STRONG> <STRONG>(Open Data Protocol)</STRONG> versioning refers to managing the evolution of an OData service over time without disrupting existing clients. As services grow and change, updates may be necessary for various reasons, such as adding new features, enhancing performance, or fixing issues. OData versioning ensures these updates are implemented in a way that maintains compatibility with existing clients.</P><P>Every ODATA Service will have version by default it is 1 we can increment the version by 1,2 and 3 and so on. Changes are noted as version Initial Version -> Version 1 -> Version 2 -> Version3</P><P>Backend and frontend teams can develop independently. Backend can implement business changes and release them under a version (e.g., version 1), allowing the frontend team to catch up later.</P><P> </P><TABLE><TBODY><TR><TD width="190px" height="50px"><P><STRONG>Back End </STRONG></P></TD><TD width="190px" height="50px"><P><STRONG>Communication</STRONG></P></TD><TD width="190px" height="50px"><P><STRONG>Front End</STRONG></P></TD></TR><TR><TD width="190px" height="104px"><P>Initial Version</P><P> </P></TD><TD width="190px" height="104px"><P>Communication Happens through URI and URI doesn’t change</P></TD><TD width="190px" height="104px"><P>Initial Version</P></TD></TR><TR><TD width="190px" height="242px"><P>Version 1</P></TD><TD width="190px" height="242px"><P> </P></TD><TD width="190px" height="242px"><P>They can complete their work and check with version 1 and 2 if we have and we don’t need versions after few days we can combine all versions in 1 and keep in one.</P></TD></TR></TBODY></TABLE><P><STRONG>SEGW -></STRONG><STRONG>RUNTIME ARTIFACTS -></STRONG><STRONG> DPC CLASS -> </STRONG><STRONG>MPC CLASS</STRONG></P><P>Registered Service/ Technical Service name.</P><P>Registered Model / Technical Model name.</P><P>These two-play major role in achieving OData versioning.</P><P><STRONG>Technical Model Name -></STRONG> Technical Service Name – Version 1</P><P> Technical Service Name – Version 2</P><P> Technical Service Name – Version 3</P><P><STRONG>Best Practices: </STRONG>In OData Service whatever design we do technical service name should be same if we make change in technical service name automatically it will change OData service URI.As the Technical Service Name remains consistent, the URI doesn’t change.</P><P><STRONG>Example:</STRONG> If we have business scenario with 3 versions keep all 3 versions technical service names same.</P><P><STRONG>Technical Model Name -></STRONG> Technical Service Name – Version 1</P><P> <STRONG>DPC_EXT</STRONG></P><P> Technical Service Name – Version 2</P><P> <STRONG>DPC_EXT -2</STRONG></P><P> Technical Service Name – Version 3</P><P> <STRONG>DPC_EXT – 3</STRONG></P><P>Logically we will have different DPC_EXT classes for versioning we are going to copy exiting DPC_EXT class and make it as a 1,2,3 only class name changes.</P><P>To register the services, create, change, delete we have a transaction /IWBEP/REG_SERVICE</P><P>To register the model, we have a transaction /IWBEP/REG_MODEL</P><P>Note: Model we are not going to change much.</P><P>Go to SEGW create a project with entity type and entity sets</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_0-1729269008153.png" style="width: 675px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181020iA05BDE0905E33D0E/image-dimensions/675x110?v=v2" width="675" height="110" role="button" title="AbhiDaggubati_0-1729269008153.png" alt="AbhiDaggubati_0-1729269008153.png" /></span></P><P>Click on save and generate project</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_1-1729266824601.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180984i9A70515F6403DBFE/image-size/medium?v=v2&px=400" role="button" title="AbhiDaggubati_1-1729266824601.png" alt="AbhiDaggubati_1-1729266824601.png" /></span></P><P>Runtime artifacts will be generated</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_2-1729266824603.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180983i9DB6B66E82339B4A/image-size/medium?v=v2&px=400" role="button" title="AbhiDaggubati_2-1729266824603.png" alt="AbhiDaggubati_2-1729266824603.png" /></span></P><P>Double click on the DPC_EXT and go to the methods select the entity set required and redefine the method.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_3-1729266824605.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180987i0F9F88F763CA5983/image-size/medium?v=v2&px=400" role="button" title="AbhiDaggubati_3-1729266824605.png" alt="AbhiDaggubati_3-1729266824605.png" /></span></P><P>Once we redefine the method it will be as below</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_4-1729266824607.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180988i81AFDC74E69879D0/image-size/medium?v=v2&px=400" role="button" title="AbhiDaggubati_4-1729266824607.png" alt="AbhiDaggubati_4-1729266824607.png" /></span></P><P>Double click on the redefined method and write the code</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_5-1729266824610.png" style="width: 676px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180986i7EE283E6B8FE9C67/image-dimensions/676x121?v=v2" width="676" height="121" role="button" title="AbhiDaggubati_5-1729266824610.png" alt="AbhiDaggubati_5-1729266824610.png" /></span></P><P>To register the service, we need use transaction code /IWFND/MAINT_SERVICE and execute.</P><P>Click on Add Service</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_6-1729266824613.png" style="width: 672px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180990iA44BCF795C7DB47E/image-dimensions/672x96?v=v2" width="672" height="96" role="button" title="AbhiDaggubati_6-1729266824613.png" alt="AbhiDaggubati_6-1729266824613.png" /></span></P><P>Specify Gateway system and Technical Service Name and click on Get Services</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_7-1729266824615.png" style="width: 571px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180991i593322F653904CE9/image-dimensions/571x140?v=v2" width="571" height="140" role="button" title="AbhiDaggubati_7-1729266824615.png" alt="AbhiDaggubati_7-1729266824615.png" /></span></P><P>Select the Technical Service and click on Add selected service.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_8-1729266824616.png" style="width: 491px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180989iEDC8FA961B64486E/image-dimensions/491x80?v=v2" width="491" height="80" role="button" title="AbhiDaggubati_8-1729266824616.png" alt="AbhiDaggubati_8-1729266824616.png" /></span></P><P>Select the Technical Service Name</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_9-1729266824617.png" style="width: 687px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180992i759B42A02B46DF45/image-dimensions/687x55?v=v2" width="687" height="55" role="button" title="AbhiDaggubati_9-1729266824617.png" alt="AbhiDaggubati_9-1729266824617.png" /></span></P><P>Click on SAP Gateway Client</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_10-1729266824620.png" style="width: 697px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180993i2011CF5C4B82883A/image-dimensions/697x121?v=v2" width="697" height="121" role="button" title="AbhiDaggubati_10-1729266824620.png" alt="AbhiDaggubati_10-1729266824620.png" /></span></P><P>Select the entity set and execute.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_11-1729266824625.png" style="width: 715px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180994i53DCC87F65601092/image-dimensions/715x188?v=v2" width="715" height="188" role="button" title="AbhiDaggubati_11-1729266824625.png" alt="AbhiDaggubati_11-1729266824625.png" /></span></P><P><STRONG>Fetching Records with Different Versions</STRONG></P><P>Using OData URI parameters (e.g., $Count), it is possible to test different versions and fetch different numbers of records.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_12-1729266824633.png" style="width: 657px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180997i3A4DB8C2A27ACF4D/image-dimensions/657x321?v=v2" width="657" height="321" role="button" title="AbhiDaggubati_12-1729266824633.png" alt="AbhiDaggubati_12-1729266824633.png" /></span></P><P>10 Rows are fetched in V=1 using URI option</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_13-1729266824635.png" style="width: 594px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180996i90ED21FDCF04E5E3/image-dimensions/594x144?v=v2" width="594" height="144" role="button" title="AbhiDaggubati_13-1729266824635.png" alt="AbhiDaggubati_13-1729266824635.png" /></span></P><P>Copying Technical service Version1 to Version 2</P><P>Example: In version 2 we had more records to be fetched, and we can modify code in Version2 DPC_EXT class that is possible.</P><P>Go to SE24 and specify DPC_EXT class name and click on Copy Class/Interface</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_14-1729266824637.png" style="width: 560px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180995iED41EDCBCC16906C/image-dimensions/560x147?v=v2" width="560" height="147" role="button" title="AbhiDaggubati_14-1729266824637.png" alt="AbhiDaggubati_14-1729266824637.png" /></span></P><P>Select entity set and double click on it</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_15-1729266824641.png" style="width: 603px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180998i9BAC7A236B305827/image-dimensions/603x202?v=v2" width="603" height="202" role="button" title="AbhiDaggubati_15-1729266824641.png" alt="AbhiDaggubati_15-1729266824641.png" /></span></P><P>In version 1. I had fetched up to 10 rows only and now in our version 2 I had just modified code</P><P>With a small change fetching up to 20 rows.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_16-1729266824644.png" style="width: 624px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/180999iDB55372418420891/image-dimensions/624x172?v=v2" width="624" height="172" role="button" title="AbhiDaggubati_16-1729266824644.png" alt="AbhiDaggubati_16-1729266824644.png" /></span></P><P>Same as above we need to maintain our service and now, we will be able to see two versions.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_17-1729266824647.png" style="width: 602px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181000i8A42E5D6D7F746B5/image-dimensions/602x140?v=v2" width="602" height="140" role="button" title="AbhiDaggubati_17-1729266824647.png" alt="AbhiDaggubati_17-1729266824647.png" /></span></P><P>Select the service and click on SAP Gateway Client.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_18-1729266824648.png" style="width: 637px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181002i58C102AC276238DC/image-dimensions/637x142?v=v2" width="637" height="142" role="button" title="AbhiDaggubati_18-1729266824648.png" alt="AbhiDaggubati_18-1729266824648.png" /></span></P><P>Now we can observe our URI with V=2 as below</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_19-1729266824650.png" style="width: 632px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181001i78FBE05D1AB99CA2/image-dimensions/632x120?v=v2" width="632" height="120" role="button" title="AbhiDaggubati_19-1729266824650.png" alt="AbhiDaggubati_19-1729266824650.png" /></span></P><P>Click on Execute by selecting URI Option $ count in V=2 and processed records are 20</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_20-1729266824652.png" style="width: 581px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181003i595DD4F15474FEAD/image-dimensions/581x157?v=v2" width="581" height="157" role="button" title="AbhiDaggubati_20-1729266824652.png" alt="AbhiDaggubati_20-1729266824652.png" /></span></P><P><STRONG>Structural changes in ODATA SEGW</STRONG></P><P>SEGW -> PROJECT 1 ----> Technical Model Name1</P><P>SEGW -> PROJECT 2 ----> Technical Model Name2</P><P>Suppose there is a structure change in initial version has 4 fields and version 2 has 3 fields only according to requirement.</P><P>If we copy project 1 to project 2 also with separate model names will be generated also still, we Should keep technical service name same to ensure consistency.</P><P>Go to SEGW Select the Project and click on copy project</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_21-1729266824656.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181007i2A1FBF9FE821D510/image-size/medium?v=v2&px=400" role="button" title="AbhiDaggubati_21-1729266824656.png" alt="AbhiDaggubati_21-1729266824656.png" /></span></P><P>A new project will be copied from original source project.</P><P>Sample requirement previous Entity type we had 4 fields no we need to keep only 3 select the field and click on remove</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_22-1729266824659.png" style="width: 684px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181006i0970D399CE12F700/image-dimensions/684x135?v=v2" width="684" height="135" role="button" title="AbhiDaggubati_22-1729266824659.png" alt="AbhiDaggubati_22-1729266824659.png" /></span></P><P>Once field is removed click on save.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_23-1729266824662.png" style="width: 680px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181004i528552A27858997B/image-dimensions/680x104?v=v2" width="680" height="104" role="button" title="AbhiDaggubati_23-1729266824662.png" alt="AbhiDaggubati_23-1729266824662.png" /></span></P><P>Click on Generate Project</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_24-1729266824663.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181010iA3C624B3F4600C1B/image-size/medium?v=v2&px=400" role="button" title="AbhiDaggubati_24-1729266824663.png" alt="AbhiDaggubati_24-1729266824663.png" /></span></P><P>Always Technical service name should be same as Initial Version 1and we need to mention version number as well.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_25-1729266824666.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181008iE6EA5A11CA88449E/image-size/medium?v=v2&px=400" role="button" title="AbhiDaggubati_25-1729266824666.png" alt="AbhiDaggubati_25-1729266824666.png" /></span></P><P>Check Runtime Artifacts all are copied by default all will be copied just a cross-check would be helpful sometimes.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_26-1729266824668.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181009iC3119F6F08A22A7E/image-size/medium?v=v2&px=400" role="button" title="AbhiDaggubati_26-1729266824668.png" alt="AbhiDaggubati_26-1729266824668.png" /></span></P><P>Select the DPC_EXT and click on it</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_27-1729266824670.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181013i40592B5829C7947F/image-size/medium?v=v2&px=400" role="button" title="AbhiDaggubati_27-1729266824670.png" alt="AbhiDaggubati_27-1729266824670.png" /></span></P><P>Select the method and go to the required entity set and redefine the method.</P><P><STRONG>Best Practices: </STRONG>When copying a project or making changes to the entity structure, ensure that custom methods are redefined again.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_28-1729266824672.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181012i29C3330E1348D9EE/image-size/medium?v=v2&px=400" role="button" title="AbhiDaggubati_28-1729266824672.png" alt="AbhiDaggubati_28-1729266824672.png" /></span></P><P>In the custom method I am adding same code with slight modification over fetching</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_29-1729266824674.png" style="width: 682px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181011i41F26775995DE961/image-dimensions/682x81?v=v2" width="682" height="81" role="button" title="AbhiDaggubati_29-1729266824674.png" alt="AbhiDaggubati_29-1729266824674.png" /></span></P><P>Same as above we need to maintain our service and now, we will be able to see two versions.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_30-1729266824677.png" style="width: 682px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181014iDFA3AF6BD27C0AF9/image-dimensions/682x82?v=v2" width="682" height="82" role="button" title="AbhiDaggubati_30-1729266824677.png" alt="AbhiDaggubati_30-1729266824677.png" /></span></P><P>Select the service and click on SAP Gateway Client.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_31-1729266824678.png" style="width: 704px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181015iDCC7BFE2C9EC5E05/image-dimensions/704x157?v=v2" width="704" height="157" role="button" title="AbhiDaggubati_31-1729266824678.png" alt="AbhiDaggubati_31-1729266824678.png" /></span></P><P>Now we can observe our URI with V=3 as below</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_32-1729266824680.png" style="width: 702px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181016i47AEA88BB779F09A/image-dimensions/702x137?v=v2" width="702" height="137" role="button" title="AbhiDaggubati_32-1729266824680.png" alt="AbhiDaggubati_32-1729266824680.png" /></span></P><P>Click on Execute by selecting URI Option $ count in V=3 and processed records are 30.</P><P>This versioning method allows you to manage changes efficiently, ensuring compatibility and facilitating independent development between teams.</P><P><SPAN>For more details, please follow the below development topic pages</SPAN></P><P><A href="https://pages.community.sap.com/topics/abap" target="_blank" rel="noopener noreferrer">ABAP Development | SAP Community</A></P><P><A href="https://community.sap.com/t5/c-khhcw49343/OData/pd-p/551580658536717501828021060147962" target="_blank">OData - SAP Community</A></P><P><A href="https://community.sap.com/t5/c-khhcw49343/NW+ABAP+Gateway+%252528OData%252529/pd-p/181161894649260056016734803547327" target="_blank">NW ABAP Gateway (OData) - SAP Community</A></P><P><SPAN>Questions, comments, or further details required? Use the Comments section below.</SPAN><BR /><BR /><SPAN>Follow my profile Abhilash Daggubati for similar blog posts.</SPAN></P><P><SPAN>Thanks All </SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="AbhiDaggubati_2-1729273499419.png" style="width: 13px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/181067iB4CAA7B64416D5B9/image-dimensions/13x13?v=v2" width="13" height="13" role="button" title="AbhiDaggubati_2-1729273499419.png" alt="AbhiDaggubati_2-1729273499419.png" /></span></P><P> </P><P> </P><P> </P><P> </P>2024-10-24T11:43:17.153000+02:00https://community.sap.com/t5/technology-blog-posts-by-members/how-to-enhance-system-generated-odata-service-in-sap-bw4hana/ba-p/13940273How to enhance system generated ODATA service in SAP BW4HANA2024-11-22T10:45:03.656000+01:00yogeswara_adapahttps://community.sap.com/t5/user/viewprofilepage/user-id/251873<P><STRONG>Overview:</STRONG> This blog will guide you through the steps to enhance the system generated OData service In BW4HANA.</P><P><STRONG>Prerequisites: </STRONG></P><UL><LI>SAP BW4HANA - SAP BW Query</LI><LI>SAP BW4HANA – OData Services</LI></UL><P>In BW4HANA Odata service can be generated automatically from BW query by clicking checkbox “By Odata”, this service is then can be activated in any SAP Gateway system and consumed from there.</P><P>In case of any requirements to enhance the system generated service below steps can be followed.</P><P><STRONG>Steps:</STRONG></P><P> Step 1: Generate OData service from BW Query.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture1.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191870iD2098118C9137E03/image-size/medium?v=v2&px=400" role="button" title="Picture1.png" alt="Picture1.png" /></span></P><P>Step 2: Create a project in t-code SEGW. Please remember <Project Name>_SRV is going to be the new service name, so please name the project accordingly.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture2.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191871iE24979FD442A07F1/image-size/medium?v=v2&px=400" role="button" title="Picture2.png" alt="Picture2.png" /></span></P><P>Step 3: Right click on the Data Model and click on “Redefine” -> “OData Service (SAP GW)</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture3.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191872iD3748E06B43ECDDE/image-size/medium?v=v2&px=400" role="button" title="Picture3.png" alt="Picture3.png" /></span></P><P>Step 4: In this screen it will ask for a service where we need to select the system generated service that needs to be enhanced and click “Next”</P><DIV class=""><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture4.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191873iCB18899C8C6A012C/image-size/medium?v=v2&px=400" role="button" title="Picture4.png" alt="Picture4.png" /></span></DIV><P>Step 5: Click Select all and click on Finish</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture5.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191874i1E5F01ED71D0E45B/image-size/medium?v=v2&px=400" role="button" title="Picture5.png" alt="Picture5.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture5-2.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191876i47B05D876238499D/image-size/medium?v=v2&px=400" role="button" title="Picture5-2.png" alt="Picture5-2.png" /></span></P><P>Step 6: Enhance the Result set with new field and Save.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture6.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191877iF66682AB83CF504F/image-size/medium?v=v2&px=400" role="button" title="Picture6.png" alt="Picture6.png" /></span></P><P>Step 7: Right click on project and click on “Generate Runtime”</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture7.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191878i18F888FCE1DEB1F9/image-size/medium?v=v2&px=400" role="button" title="Picture7.png" alt="Picture7.png" /></span></P><P>Runtime artifacts will be generated like shown below</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture7-2.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191879i34BBF193B09902F8/image-size/medium?v=v2&px=400" role="button" title="Picture7-2.png" alt="Picture7-2.png" /></span></P><P>Step 8: Go to DPC_EXT (Data provider extended class)</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture8.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191880iD0A7F11CC76AC99B/image-size/medium?v=v2&px=400" role="button" title="Picture8.png" alt="Picture8.png" /></span></P><P>Select GET_ENTITYSET method and click on Redefine button</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture8-2.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191881i4177F7EC8A8CF312/image-size/medium?v=v2&px=400" role="button" title="Picture8-2.png" alt="Picture8-2.png" /></span></P><P>Step 9: Write the logic to populate the newly added field here. Super class get_entityset code will be shown by default, start the new logic after the default code. Please note that this code will be executed for each and every row in output.</P><DIV class=""><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture9.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191883i7A7EB7060FF5B1C6/image-size/medium?v=v2&px=400" role="button" title="Picture9.png" alt="Picture9.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture9-2.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191884i187297CCCE5456A7/image-size/medium?v=v2&px=400" role="button" title="Picture9-2.png" alt="Picture9-2.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture9-3.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191885i342F64E1168D9F3C/image-size/medium?v=v2&px=400" role="button" title="Picture9-3.png" alt="Picture9-3.png" /></span></DIV><P>Step 10: Test the output of OData service.</P><P>Go to TCODE /IWFND/GW_CLIENT, give the URL in Request URI and click on execute.</P><P>Validate the output with written logic.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture10.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/191886i551824CBB0884F05/image-size/medium?v=v2&px=400" role="button" title="Picture10.png" alt="Picture10.png" /></span></P>2024-11-22T10:45:03.656000+01:00https://community.sap.com/t5/technology-blog-posts-by-members/steps-to-replace-odata-in-business-application-studio-ui5-extension-project/ba-p/13951391Steps to Replace OData in Business Application Studio UI5 Extension Project2024-12-02T17:35:04.959000+01:00bhaskar_indiahttps://community.sap.com/t5/user/viewprofilepage/user-id/575081<P class="lia-align-justify" style="text-align : justify;"><STRONG>How to change OData service when using BAS Extension Project for Standard Apps</STRONG></P><P class="lia-align-justify" style="text-align : justify;"><STRONG><U>Background</U></STRONG>: Sometimes, standard FIORI apps cannot be extended via BAS Adaptation Project. This limitation arises if the app contains synchronous views. In such cases, you may need an alternative approach to customize the app effectively. </P><P class="lia-align-justify" style="text-align : justify;"><STRONG><U>Requirement:</U></STRONG> The standard app ‘Transfer Stock - Cross-Plant’, includes buttons to transfer stock between plants. My requirement is to customize the app to grey out the buttons based on the plant category. </P><P class="lia-align-justify" style="text-align : justify;"><STRONG><U>Solution:</U></STRONG></P><P class="lia-align-justify" style="text-align : justify;">This standard app uses OData service MMIM_MATERIAL_DATA_SRV. To implement the required changes, I created a custom OData service ZMMIM_MATERIAL_DATA_SRV, based on the standard service with an additional field. While the creation of this service is beyond the scope of this blog, I will focus on integrating it into the app.</P><P class="lia-align-justify" style="text-align : justify;">The buttons I customized are highlighted in the below image.</P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_0-1732844523656.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196648i18D3C28EE16B1E3B/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_0-1732844523656.png" alt="bhaskar_india_0-1732844523656.png" /></span></P><P class="lia-align-justify" style="text-align : justify;">Image source: <A href="https://fioriappslibrary.hana.ondemand.com/sap/fix/externalViewer/#/detail/Apps('F1957')/S21OP" target="_blank" rel="noopener nofollow noreferrer">https://fioriappslibrary.hana.ondemand.com/sap/fix/externalViewer/#/detail/Apps('F1957')/S21OP</A></P><P class="lia-align-justify" style="text-align : justify;">Steps to Implement the Customization</P><P class="lia-align-justify" style="text-align : justify;">1. Start by opening the BAS tool and selecting the Adaptation Project option.</P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_1-1732844523663.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196649iD08943FEA02339A9/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_1-1732844523663.png" alt="bhaskar_india_1-1732844523663.png" /></span></P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_2-1732844523668.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196647i6DD4D91B295DF1C8/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_2-1732844523668.png" alt="bhaskar_india_2-1732844523668.png" /></span>2. Fill in the necessary details for the project setup and proceed to the next step.</P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_3-1732844523673.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196650i4779B5EDBF7AA333/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_3-1732844523673.png" alt="bhaskar_india_3-1732844523673.png" /></span></P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_4-1732844523678.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196651i882476629B0A6915/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_4-1732844523678.png" alt="bhaskar_india_4-1732844523678.png" /></span></P><P>3. Select the relevant system associated with the project.</P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_5-1732844523683.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196652i483456639900DEC9/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_5-1732844523683.png" alt="bhaskar_india_5-1732844523683.png" /></span>4. Upon choosing the standard app, a message will appear indicating that the app contains synchronous views.</P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_6-1732844523688.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196653i55475B41D6840D22/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_6-1732844523688.png" alt="bhaskar_india_6-1732844523688.png" /></span></P><P>5. Due to the limitation, you cannot proceed with an Adaptation Project. Instead, create an Extension Project and click Finish.</P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_7-1732844523694.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196654i6558204303BBD1FF/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_7-1732844523694.png" alt="bhaskar_india_7-1732844523694.png" /></span></P><P class="lia-align-justify" style="text-align : justify;">6. Once the Extension Project is created, open it separately (optional). Then, create an extension by right-clicking the .extconfig.json file.</P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_8-1732844523700.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196655i5C08CF066C3DB34E/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_8-1732844523700.png" alt="bhaskar_india_8-1732844523700.png" /></span></P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_9-1732844523705.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196656iAF3027B6E7C59CD7/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_9-1732844523705.png" alt="bhaskar_india_9-1732844523705.png" /></span></P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_10-1732844523712.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196657iA6AAEF83AC69F224/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_10-1732844523712.png" alt="bhaskar_india_10-1732844523712.png" /></span></P><P class="lia-align-justify" style="text-align : justify;">7. In the context menu, choose ‘Extend Controller’ and then select ‘Copy of the Original Controller’.</P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_11-1732844523717.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196658i849BF4EBF369F6C0/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_11-1732844523717.png" alt="bhaskar_india_11-1732844523717.png" /></span></P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_12-1732844523729.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196660i1F4C31D592C2DB63/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_12-1732844523729.png" alt="bhaskar_india_12-1732844523729.png" /></span></P><P>8. Uncomment the function ‘_loadMaterial’ in the file ‘S1Custom.controller.js’. This is where the oData service needs to be replaced.</P><P>9. Replace references to the standard OData service with the custom OData service ZMMIM_MATERIAL_DATA_SRV in your UI5 extension project. The required changes are shown below:</P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_13-1732844523733.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196659i6268CED1D023C3D2/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_13-1732844523733.png" alt="bhaskar_india_13-1732844523733.png" /></span></P><P>10. Search for all occurrences of the model ‘oMaterialData’ in the code. Update them accordingly to use the custom service.</P><P>11. In the custom OData service, I added a new property ‘PlantCategory’ to the existing entity type ‘MaterialPlant’.</P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="bhaskar_india_14-1732844523797.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196661i00DA4DCAEEA4E4DF/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_14-1732844523797.png" alt="bhaskar_india_14-1732844523797.png" /></span></P><P class="lia-align-justify" style="text-align : justify;"><SPAN>12. Update the UI5 code to use new property ‘PlantCategory’ in the function ‘_checkFirstClickIsAllowed’. This ensures the buttons are always greyed out based on the plant category.</SPAN></P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_15-1732844523800.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196662i2B7A78047C180396/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_15-1732844523800.png" alt="bhaskar_india_15-1732844523800.png" /></span></P><P class="lia-align-justify" style="text-align : justify;"><STRONG><U>Testing:</U></STRONG></P><P class="lia-align-justify" style="text-align : justify;"><STRONG><U>Before the change (in the standard app):</U></STRONG></P><P class="lia-align-justify" style="text-align : justify;"> </P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_16-1732844523821.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196664i3A9FBC1230A0812D/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_16-1732844523821.png" alt="bhaskar_india_16-1732844523821.png" /></span></P><P class="lia-align-justify" style="text-align : justify;"><STRONG><U>After the change (in the enhanced app):</U></STRONG></P><P class="lia-align-justify" style="text-align : justify;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="bhaskar_india_17-1732844523839.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/196663i63DDD71502B2CCD3/image-size/large?v=v2&px=999" role="button" title="bhaskar_india_17-1732844523839.png" alt="bhaskar_india_17-1732844523839.png" /></span></P><P class="lia-align-justify" style="text-align : justify;">As it can be seen from the above output, the buttons in the entire row are disabled. Requirement has been achieved.</P>2024-12-02T17:35:04.959000+01:00https://community.sap.com/t5/technology-blog-posts-by-members/new-aws-option-for-sap-odp-data-extraction-through-aws-glue/ba-p/13962632New AWS option for SAP ODP data extraction through AWS Glue2024-12-13T09:34:58.207000+01:00MarioDeFelipehttps://community.sap.com/t5/user/viewprofilepage/user-id/13491<P>In November 2024, AWS updated its guidance for SAP Data Extraction with a Glue connector.</P><P>This adds to the previous guidance using <STRONG>Amazon AppFlow</STRONG> service. But when to use what? lets dive in</P><P> </P><P> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2024-12-06 at 00.26.57.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199053i43E1135778E438E3/image-size/large?v=v2&px=999" role="button" title="Screenshot 2024-12-06 at 00.26.57.png" alt="Screenshot 2024-12-06 at 00.26.57.png" /></span></P><P> </P><H2 id="toc-hId-1077491394">Amazon Appflow Approach</H2><P data-unlink="true">AppFlow is the AWS pre-configured <STRONG>integration service</STRONG>, if you are familiar with SAP Integration Suite, Fivetran, Airbyte or similars, you already know the drill. One tool to connect all, highly transactional, easy to configure.</P><P data-unlink="true">AppFlow has a pre-configured <STRONG>SAP OData Connector</STRONG>, so we don't need to build it. Since its launch, it has been super easy to set up a data flow from SAP to AWS in just a few clicks, great for prototyping and relative small data sets replication.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2024-12-06 at 00.15.32.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199038i527B8A6ABCEE061A/image-size/large?v=v2&px=999" role="button" title="Screenshot 2024-12-06 at 00.15.32.png" alt="Screenshot 2024-12-06 at 00.15.32.png" /></span></P><P> </P><P>AppFlow makes it simple, in 4 steps you define the flow, you prepare the data, add transformations, partitioning and aggregation if necessary and in a few clicks you have your raw data on AWS.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2024-12-06 at 00.16.27.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199039i27BED35824F15DD8/image-size/large?v=v2&px=999" role="button" title="Screenshot 2024-12-06 at 00.16.27.png" alt="Screenshot 2024-12-06 at 00.16.27.png" /></span></P><P> </P><P>Integration is quite flexible in a low-code no-code fashion and allows modern file formats, t<SPAN>he next step, depending of the case, would be to curate the data, with services like Glue.</SPAN></P><P> </P><H2 id="toc-hId-880977889"><FONT color="#FF0000">New</FONT> AWS Glue Approach</H2><P>Now, AWS has introduced an <STRONG>AWS Glue OData connector for SAP</STRONG>, contrary to an Integration service, Glue provides a serverless <STRONG>data processing (ETL)</STRONG> service. It's based on Spark.</P><P>Glue is more suitable for extensive data integration as well as distributed data processing capabilities, complex transformations, and analytics.</P><P>So this week, AWS announced the <STRONG>Odata Connector</STRONG> on Glue. Great because we dont need to learn Scala to build our own connector.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2024-12-06 at 01.26.07.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199102i2BF87CD84FF74FDE/image-size/large?v=v2&px=999" role="button" title="Screenshot 2024-12-06 at 01.26.07.png" alt="Screenshot 2024-12-06 at 01.26.07.png" /></span></P><P> </P><P> </P><P>AWS provides more than 40 predefined connectors, plus hundreds of more connectors available through the AWS Marketplace. Glue capabilities are immense, they not only provide extensive ETL capabilities, but most importantly, they store the Data Catalog, a critical feature for search and query using Amazon Athena or Amazon Redshift.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="AWS Glue ETL Workflow. Courtesy of AWS" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199078i5E9F77A2EB852A04/image-size/large?v=v2&px=999" role="button" title="BDB-4789-image28-new.png" alt="AWS Glue ETL Workflow. Courtesy of AWS" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">AWS Glue ETL Workflow. Courtesy of AWS</span></span></P><P> For entire details of the new Glue connector to SAP, read this blog;</P><P><A href="https://aws.amazon.com/blogs/big-data/scaling-rise-with-sap-data-and-aws-glue/" target="_blank" rel="noopener nofollow noreferrer">https://aws.amazon.com/blogs/big-data/scaling-rise-with-sap-data-and-aws-glue/</A></P><P> <STRONG>Key Differences and when to use</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2024-12-06 at 01.11.50.png" style="width: 812px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199099i372589CDFDA3315C/image-size/large?v=v2&px=999" role="button" title="Screenshot 2024-12-06 at 01.11.50.png" alt="Screenshot 2024-12-06 at 01.11.50.png" /></span></P><H2 id="toc-hId-684464384">Literature</H2><P><A href="https://docs.aws.amazon.com/glue/latest/dg/connecting-to-data-sap-odata.html" target="_blank" rel="noopener nofollow noreferrer">https://docs.aws.amazon.com/glue/latest/dg/connecting-to-data-sap-odata.html</A></P><P><A href="https://aws.amazon.com/blogs/big-data/scaling-rise-with-sap-data-and-aws-glue/" target="_blank" rel="noopener nofollow noreferrer">https://aws.amazon.com/blogs/big-data/scaling-rise-with-sap-data-and-aws-glue/</A></P><P> </P>2024-12-13T09:34:58.207000+01:00https://community.sap.com/t5/technology-blog-posts-by-members/enable-odata-streams-in-rap/ba-p/13990426Enable OData Streams in RAP2025-01-20T06:28:13.387000+01:00pavankumar_reddy90https://community.sap.com/t5/user/viewprofilepage/user-id/189954<P><SPAN><STRONG>Problem statement:</STRONG><BR />How to enable OData Streams such as excel, pdf, Images and other large objects using standard RAP Based application development without using UI5 tooling?</SPAN></P><P><STRONG>Solution:</STRONG></P><P><SPAN>With the latest SAP BTP ABAP Environment 2208 release the RAP framework now supports OData streams. It is now possible to enable your RAP application to maintain and handle Large Objects(LOBs).This feature provides end users an option to upload external files of different file formats such as PDF, XLSX , binary file format and other types hence allowing media handling.<BR /><BR />I am on of the presenter for this topic at ABAP Conference and int the below youtube recording. This topic covers content related to how to enable large objects using RAP (ABAP RESTful Programming Model ). Upload functionality using custom actions, download functionality using custom actions, how to use XCO library to read and write XLSX content and some useful links which can be explored about OData Streams in RAP.</SPAN></P><P><BR />ABAP Conference recording: <A href="https://www.youtube.com/watch?v=QyPEzRHA9Lo&ab_channel=ABAPConf" target="_blank" rel="noopener nofollow noreferrer">Enable OData Streams in RAP</A></P><P>Slides: <A href="https://abapconf.org/abapconf2024/#/agenda" target="_blank" rel="noopener nofollow noreferrer">https://abapconf.org/abapconf2024/#/agenda</A></P><P>Check for topic "<A class="" href="https://abapconf.org/abapconf2024/#" target="_blank" rel="noopener nofollow noreferrer">Enable OData Streams in RAP</A>" where you can find the link to download slides in pdf document.<BR /><BR />Use cases covered:</P><OL><LI><STRONG>Working with Large Objects</STRONG></LI><LI><STRONG>Upload Functionality using Custom Action</STRONG></LI><LI><STRONG>Download Functionality using Custom Action</STRONG></LI><LI><STRONG>Use XCO library to read and write XLSX Content</STRONG></LI></OL><P><STRONG>Code based GitHub URL's:</STRONG></P><P>1. Upload and Download Functionality application : <A href="https://github.com/rvrrpk/OdataStreamsRAP" target="_blank" rel="noopener nofollow noreferrer">https://github.com/rvrrpk/OdataStreamsRAP</A></P><P>2. Download History Application : <A href="https://github.com/rvrrpk/DownloadHistory" target="_blank" rel="noopener nofollow noreferrer">https://github.com/rvrrpk/DownloadHistory</A></P><P> </P><P> </P><P> </P><P> </P>2025-01-20T06:28:13.387000+01:00https://community.sap.com/t5/technology-blog-posts-by-members/create-deep-entity-using-rap-unmanaged/ba-p/13993060CREATE_DEEP_ENTITY using RAP ( Unmanaged )2025-01-24T16:44:09.141000+01:00Mahmoud_Waelhttps://community.sap.com/t5/user/viewprofilepage/user-id/178735<P>Hello Experts,</P><P><SPAN>In this blog, We will learn how to create a simple RAP OData API and use it to achieve a Deep entity set creation operation which is requested in lot of projects and Custom services especially in complex integration scenarios .</SPAN></P><P><SPAN>In this example, we will be using a custom cds view entities based on standard tables for header and items, unmanaged behavior definition, service definition and binding . </SPAN></P><P>Step 1 : Parent CDS :</P><P> </P><pre class="lia-code-sample language-javascript"><code>@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Production order Cds view'
@Metadata.ignorePropagatedAnnotations: true
define root view entity z7pi_production_order
as select from aufk as _order
composition [1..*] of z7pi_serial_number as _serial
{
key aufnr as Production_order,
auart,
_serial
}</code></pre><P> </P><P> </P><P>Step 2 : Child CDS :</P><P> </P><pre class="lia-code-sample language-javascript"><code>@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'serial Number Cds view'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define view entity z7pi_serial_number
as select from objk
association [0..1] to ser05 on objk.obknr = ser05.obknr
association [0..1] to ser06 on objk.obknr = ser06.obknr
association to parent z7pi_production_order as _order
on $projection.Production_order = _order.Production_order
{
key ser05.ppaufart as Production_order,
key objk.sernr as serial,
key ser06.exidv as hu,
_order
}</code></pre><P> </P><P> </P><P>Step 3 : Unmanaged Behavior Definition :</P><P> </P><pre class="lia-code-sample language-abap"><code>unmanaged implementation in class z7pbp_7pi_production_order unique;
strict ( 2 );
define behavior for z7pi_production_order alias _order
//late numbering
lock master
authorization master ( instance )
//etag master <field_name>
{
field ( features : instance ) auart ;
create;
update;
delete;
association _serial { create; }
}
define behavior for z7pi_serial_number alias _serial
//late numbering
lock dependent by _order
authorization dependent by _order
//etag master <field_name>
{
update;
delete;
field ( readonly ) Production_order;
association _order;
}</code></pre><P> </P><P> </P><P>Step 4 : using quick fix create the implementation Class</P><P>Step 5 : comment or remove the <SPAN>create and cba_association create methods</SPAN></P><P><SPAN>we remove both methods and create a new method using the events from the removed ones</SPAN></P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>CLASS lhc__order DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
IMPORTING keys REQUEST requested_authorizations FOR _order RESULT result.
* METHODS create FOR MODIFY
* IMPORTING entities FOR CREATE _order.
METHODS deep_create FOR MODIFY
IMPORTING
order FOR CREATE _order
serial FOR CREATE _order\_serial.
METHODS update FOR MODIFY
IMPORTING entities FOR UPDATE _order.
METHODS delete FOR MODIFY
IMPORTING keys FOR DELETE _order.
METHODS read FOR READ
IMPORTING keys FOR READ _order RESULT result.
METHODS lock FOR LOCK
IMPORTING keys FOR LOCK _order.
METHODS rba_serial FOR READ
IMPORTING keys_rba FOR READ _order\_serial FULL result_requested RESULT result LINK association_links.
METHODS get_instance_features FOR INSTANCE FEATURES
IMPORTING keys REQUEST requested_features FOR _order RESULT result.
* METHODS cba_serial FOR MODIFY
* IMPORTING entities_cba FOR CREATE _order\_serial.
ENDCLASS.</code></pre><P> </P><P> </P><P>then in the implementation of the new method we should be able to access both the header and child entities</P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>METHOD deep_create.
DATA(lv_import) = order.
DATA(lv_import_sr) = serial.
LOOP AT lv_import_sr ASSIGNING FIELD-SYMBOL(<sr>) .
LOOP AT <sr>-%target ASSIGNING FIELD-SYMBOL(<tr>).
wa_order_ser = VALUE #(
%key-production_order = lv_ord_no
%key-serial = <tr>-serial
production_order = lv_ord_no
).
wa_report_ser = VALUE #(
%key-production_order = lv_ord_no
%key-serial = <tr>-serial
production_order = lv_ord_no
).
wa_fail_ser = VALUE #(
%key-production_order = lv_ord_no
%key-serial = <tr>-serial
production_order = lv_ord_no
).
SELECT SINGLE obknr
FROM objk
WHERE sernr EQ @<tr>-serial
AND taser EQ 'SER05'
INTO (obj_list).
ENDLOOP.
ENDLOOP.
ENDMETHOD.</code></pre><P> </P><P> </P><P> </P><P>Finally we create the service binding and service definition</P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>@EndUserText.label: 'Blocking zrep order type serials'
define service Z7PAPI_ZREP_BLOCK {
expose z7pi_production_order as prd_ord;
expose z7pi_serial_number as serial;
}</code></pre><P> </P><P> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Mahmoud_Wael_0-1737544514045.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/215320iD6323D9F434F9C40/image-size/large?v=v2&px=999" role="button" title="Mahmoud_Wael_0-1737544514045.png" alt="Mahmoud_Wael_0-1737544514045.png" /></span></P><P>then we move to testing</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Mahmoud_Wael_1-1737544929653.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/215325iDD5B5B368E9750DC/image-size/large?v=v2&px=999" role="button" title="Mahmoud_Wael_1-1737544929653.png" alt="Mahmoud_Wael_1-1737544929653.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Mahmoud_Wael_2-1737544939552.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/215326i7FE0588AA79FF693/image-size/large?v=v2&px=999" role="button" title="Mahmoud_Wael_2-1737544939552.png" alt="Mahmoud_Wael_2-1737544939552.png" /></span></P><P>as shown you can access your header and child entities however you see fit</P><P> </P>2025-01-24T16:44:09.141000+01:00https://community.sap.com/t5/technology-blog-posts-by-members/retrieve-data-from-rest-api-to-abap/ba-p/14109609Retrieve Data from Rest API to ABAP2025-05-27T09:27:13.029000+02:00Aravindhahttps://community.sap.com/t5/user/viewprofilepage/user-id/1442730<P><STRONG>Introduction</STRONG></P><P>In abap, we create and expose API service through the OData gateway client for integration with third-party systems. This blog focuses on how to retrieve data from a REST API using a standard ABAP class. I have created the OData service using the GET_ENTITY method in an OData project and consumed that API using the approach described below.</P><UL><LI><EM>cl_http_client</EM></LI><LI><EM>if_http_client</EM></LI></UL><pre class="lia-code-sample language-abap"><code>****Data Declarations****
TYPES: BEGIN OF tt_json,
MaterialCode TYPE matnr, "Material
UserName TYPE ernam, "Creator Name
mtart TYPE mtart, "Material Type
END OF tt_json.
TYPES: BEGIN OF ty_field,
fielname TYPE char40, "Field Name
END OF ty_field.
DATA: lt_material TYPE TABLE OF tt_json,
lt_tab TYPE TABLE OF ty_field,
ls_material TYPE tt_json,
lo_http TYPE REF TO if_http_client, "HTTP Client Abstraction
lr_data TYPE REF TO data,
lv_result TYPE string,
lv_content_type TYPE string,
lv_action_type TYPE string.
FIELD-SYMBOLS: <ls_data> TYPE data,
<ls_d> TYPE data,
<ls_struct> TYPE data,
<lv_any> TYPE any,
<lv_char>.
SELECTION-SCREEN BEGIN OF BLOCK a1 WITH FRAME TITLE TEXT-002.
PARAMETERS: p_mat TYPE matnr OBLIGATORY.
SELECTION-SCREEN END OF BLOCK a1.
*Get URL
DATA(lv_url) = |{ TEXT-001 }'{ p_mat }')| .</code></pre><P>The API and selection screen look likes,</P><P> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Aravindha_0-1747933764005.png" style="width: 635px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/265182iF3F80F92AA75BE26/image-dimensions/635x81?v=v2" width="635" height="81" role="button" title="Aravindha_0-1747933764005.png" alt="Aravindha_0-1747933764005.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Select Screen.png" style="width: 697px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/265201iD6D1B6CEA04CB76A/image-dimensions/697x122?v=v2" width="697" height="122" role="button" title="Select Screen.png" alt="Select Screen.png" /></span></P><P> </P><pre class="lia-code-sample language-abap"><code>"To perform the HTTP communication using factory method.
cl_http_client=>create_by_url(
EXPORTING
url = lv_url " URL
IMPORTING
client = lo_http " HTTP Client Abstraction
EXCEPTIONS
argument_not_found = 1 " Communication parameter (host or service) not available
plugin_not_active = 2 " HTTP/HTTPS communication not available
internal_error = 3 " Internal error (e.g. name too long)
OTHERS = 7
).
"
IF sy-subrc = 0.
lv_content_type = 'application/json'.
lv_action_type = 'GET'.
lo_http->request->set_content_type( lv_content_type ).
lo_http->request->set_method( lv_action_type ).
"The output shows a json format.
lo_http->request->set_header_field(
EXPORTING
name = 'Accept' " Name of the header field
value = 'application/json' " HTTP header field value
).
"To ignore the authentication during execution.
lo_http->propertytype_logon_popup = if_http_client=>co_disabled.
lo_http->authenticate(
EXPORTING
proxy_authentication = ' ' " Proxy Logon (= 'X')
client = '800' " R/3 system (client number from logon)
username = 'username' " ABAP System, User Logon Name
password = 'password' " Logon ID
language = 'E' " SAP System, Current Language
).
ENDIF.
lo_http->send(
EXPORTING
timeout = 15 " Timeout of Answer Waiting Time
EXCEPTIONS
http_communication_failure = 1 " Communication Error
http_invalid_state = 2 " Invalid state
http_processing_failed = 3 " Error when processing method
http_invalid_timeout = 4 " Invalid Time Entry
OTHERS = 5
).
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
lo_http->receive(
EXCEPTIONS
http_communication_failure = 1 " Communication Error
http_invalid_state = 2 " Invalid state
http_processing_failed = 3 " Error when processing method
OTHERS = 4
).
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
*Get the response from target as character string cdata( ).
lv_result = lo_http->response->get_cdata( ).
lo_http->close( ).</code></pre><P>We have the response from target system and need to retrieve the data from the string variable lv_result.</P><P> </P><pre class="lia-code-sample language-abap"><code>*Deserialize the data from Json to Abap
/ui2/cl_json=>deserialize(
EXPORTING
json = lv_result " JSON string
CHANGING
data = lr_data " Data to serialize
).
lt_tab = VALUE #( ( fielname = 'MATERIALCODE')
( fielname = 'USERNAME')
( fielname = 'MTART' ) ).
ASSIGN lr_data->* TO <ls_data>.
ASSIGN COMPONENT 'd' OF STRUCTURE <ls_data> TO <ls_d>.
DATA(lo_typedescr) = cl_abap_typedescr=>describe_by_data( <ls_d> ).
ASSIGN <ls_d>->* TO <ls_struct>.
IF <ls_struct> IS ASSIGNED.
LOOP AT lt_tab INTO DATA(ls_tab).
ASSIGN COMPONENT ls_tab-fielname OF STRUCTURE <ls_struct> TO <lv_any>.
IF <lv_any> IS ASSIGNED.
ASSIGN <lv_any>->* TO <lv_char>.
IF <lv_char> IS ASSIGNED.
ASSIGN COMPONENT ls_tab-fielname OF STRUCTURE ls_material TO FIELD-SYMBOL(<lv_target>).
IF <lv_target> IS ASSIGNED.
<lv_target> = <lv_char>.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
ENDIF.
UNASSIGN: <ls_data>,<ls_d>,<ls_struct>,<lv_any>,<lv_char>,<lv_target>.
cl_demo_output=>begin_section( 'Material Detail' ).
cl_demo_output=>write_data( ls_material ).
cl_demo_output=>next_section( 'OData Service URL' ).
cl_demo_output=>write_text( lv_url ).
cl_demo_output=>display( ).
CLEAR: ls_material.</code></pre><P>The output should be like below in debugger level.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Debugger Level.png" style="width: 571px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/265202i641ED9C9567251A4/image-dimensions/571x239?v=v2" width="571" height="239" role="button" title="Debugger Level.png" alt="Debugger Level.png" /></span></P><P> </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/265205i35F15273B8391E9B/image-size/large?v=v2&px=999" role="button" title="Output.png" alt="Output.png" /></span></P><P>Test the above service URI to postman app in GET method.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Post 1.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/265207iC803123558A9A968/image-size/large?v=v2&px=999" role="button" title="Post 1.png" alt="Post 1.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Post 2.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/265208i4CE7DF673C51A334/image-size/large?v=v2&px=999" role="button" title="Post 2.png" alt="Post 2.png" /></span></P><P><STRONG>Note:</STRONG> In the example above, I retrieved data from an OData HTTP API that does not require an SSL certificate. However, when communication with external APIs. an SSL certificate is typically required. We will cover this in detail in a separate blog post.</P><P>Thank you!</P>2025-05-27T09:27:13.029000+02:00https://community.sap.com/t5/application-development-and-automation-blog-posts/implementing-bopf-actions-using-cds-based-business-objects-in-s-4hana/ba-p/14132840Implementing BOPF Actions Using CDS-Based Business Objects in S/4HANA2025-06-24T09:40:16.716000+02:00Ruhoolla_Khanhttps://community.sap.com/t5/user/viewprofilepage/user-id/1451103<P><STRONG><SPAN>Introduction</SPAN></STRONG><SPAN> </SPAN></P><P><SPAN>In SAP S/4HANA, Core Data Services (CDS) are widely used to define meaningful and reusable data models. When these CDS views are annotated correctly, they can automatically create a Business Object Processing Framework (BOPF) model. This helps in building business objects faster and with less manual effort.</SPAN><SPAN> </SPAN></P><P><SPAN>In real-world applications, we often need to perform actions that go beyond just creating, reading, updating, or deleting data. For example, we might need to "Active Status" the status of a record, "Cancel" a request. These kinds of operations are called actions in BOPF.</SPAN><SPAN> </SPAN></P><P><SPAN>This object explains how to add such custom actions to a CDS-based BOPF model. It helps developers extend standard functionality by including business-specific logic that users can trigger when needed.</SPAN><SPAN> </SPAN></P><P><STRONG><SPAN>Steps for implementing Action for the CDS-Based Business Objects.</SPAN></STRONG><SPAN> </SPAN></P><P><SPAN>Enhancing CDS-Based BOPF Objects with Custom Actions in S/4HANA.</SPAN><SPAN> </SPAN></P><P><SPAN>Defining and Implementing Actions in BOPF via CDS Views.</SPAN><SPAN> </SPAN></P><pre class="lia-code-sample language-abap"><code>@AbapCatalog.sqlViewName: 'ZCFMEAL_SQL'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Flight Meal Application, Consumption View'
@OData.publish: true
@Metadata.allowExtensions: true
@ObjectModel:{
modelCategory: #BUSINESS_OBJECT,
compositionRoot: true,
transactionalProcessingEnabled: true,
createEnabled: true,
updateEnabled: true,
deleteEnabled: true,
writeActivePersistence: 'ZAP_FLIGHT_MEAL'
}
define view ZCFMEAL
as select from zap_flight_meal
association [1] to scarr as _Airline on $projection.carrid = _Airline.carrid
association [1] to sflight as _FlightInfo on $projection.carrid = _FlightInfo.carrid
and $projection.connid = _FlightInfo.connid
association [1] to smeal as _Meals on $projection.carrid = _Meals.carrid
and $projection.meal = _Meals.mealnumber
{
@UI.facet: [{
purpose: #STANDARD,
label: 'Meals',
type: #IDENTIFICATION_REFERENCE,
position: 10
}]
@UI.lineItem: [{ position: 10, label: 'Meal ID' },
{ position: 10, type: #FOR_ACTION, dataAction: 'BOPF:SET_STATUS', label: 'Active Status' }
]
@UI.identification: [{ position: 10, label: 'Meal ID' }]
key meal_id,
@UI.lineItem: [{ position: 20, label: 'Carrier' }]
@UI.identification: [{ position: 20, label: 'Carrier' }]
@ObjectModel.foreignKey.association: '_Airline'
carrid,
@UI.lineItem: [{ position: 30, label: 'Connection' }]
@UI.identification: [{ position: 30, label: 'Connection' }]
@ObjectModel.foreignKey.association: '_FlightInfo'
connid,
@UI.lineItem: [{ position: 40, label: 'Meal' }]
@UI.identification: [{ position: 40, label: 'Meal' }]
@ObjectModel.foreignKey.association: '_Meals'
meal,
@UI.lineItem: [{ position: 50, label: 'Total seats' }]
@UI.identification: [{ position: 50, label: 'Total seats' }]
total_seats,
@UI.lineItem: [{ position: 10, label: 'Status' }]
@UI.identification: [{ position: 10, label: 'Status' }]
status,
_Airline,
_FlightInfo,
_Meals
} </code></pre><P><SPAN class=""><SPAN class="">Once the CDS view is activated, the corresponding BOPF object is automatically generated. You can view it using transaction code BOBX and </SPAN><SPAN class="">proceed</SPAN><SPAN class=""> to define the action.</SPAN></SPAN><SPAN class=""> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ruhoolla_Khan_0-1750417416815.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/277067i27A30AF97850D8B2/image-size/large?v=v2&px=999" role="button" title="Ruhoolla_Khan_0-1750417416815.png" alt="Ruhoolla_Khan_0-1750417416815.png" /></span></P><P><SPAN>Next, implement the business logic for the action in the corresponding BOPF action class.</SPAN><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ruhoolla_Khan_1-1750417483251.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/277073iCB5D6C61A220C0E3/image-size/large?v=v2&px=999" role="button" title="Ruhoolla_Khan_1-1750417483251.png" alt="Ruhoolla_Khan_1-1750417483251.png" /></span></P><P><SPAN>The action implementation class inherits predefined methods from the BOPF framework, such as EXECUTE_ACTION.</SPAN><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ruhoolla_Khan_2-1750417483252.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/277074i2980B0ABB310C0D0/image-size/large?v=v2&px=999" role="button" title="Ruhoolla_Khan_2-1750417483252.png" alt="Ruhoolla_Khan_2-1750417483252.png" /></span><SPAN> </SPAN></P><P><SPAN>Implementation:</SPAN><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ruhoolla_Khan_0-1750419067172.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/277113iD1D97EA89D842DEB/image-size/large?v=v2&px=999" role="button" title="Ruhoolla_Khan_0-1750419067172.png" alt="Ruhoolla_Khan_0-1750419067172.png" /></span></P><P><SPAN>Activate and generate the BOPF object.</SPAN><SPAN> </SPAN></P><P><SPAN>Now add the service and utilize it in the front-end.</SPAN><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ruhoolla_Khan_4-1750417483254.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/277077i426517115DDC3F48/image-size/large?v=v2&px=999" role="button" title="Ruhoolla_Khan_4-1750417483254.png" alt="Ruhoolla_Khan_4-1750417483254.png" /></span></P><P><SPAN>Add the service by Selecting and provide the package name. </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ruhoolla_Khan_5-1750417483255.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/277078iBC9CCB55F5663122/image-size/large?v=v2&px=999" role="button" title="Ruhoolla_Khan_5-1750417483255.png" alt="Ruhoolla_Khan_5-1750417483255.png" /></span></P><P>You'll get an information that the metadata has been loaded for that service.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ruhoolla_Khan_6-1750417483256.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/277076iCAC7BF6466C2C60B/image-size/large?v=v2&px=999" role="button" title="Ruhoolla_Khan_6-1750417483256.png" alt="Ruhoolla_Khan_6-1750417483256.png" /></span></P><P><SPAN>Test the service.</SPAN><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ruhoolla_Khan_7-1750417483257.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/277080i76170F7BD361CE8F/image-size/large?v=v2&px=999" role="button" title="Ruhoolla_Khan_7-1750417483257.png" alt="Ruhoolla_Khan_7-1750417483257.png" /></span></P><P><SPAN>Now by using the Odata service create the basic Fiori application</SPAN><SPAN> </SPAN></P><P><STRONG><SPAN>Steps to create basic Fiori application:</SPAN></STRONG><SPAN> </SPAN></P><P><SPAN>Use any tool for creating Fiori like VS Code or SAP Business Application Studio (BAS).</SPAN><SPAN> </SPAN></P><P><SPAN>Open Application generator-> select the template -> provide the service ->select the entity-> finish and run the application</SPAN><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ruhoolla_Khan_8-1750417483257.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/277081i50E984F46D52C41F/image-size/large?v=v2&px=999" role="button" title="Ruhoolla_Khan_8-1750417483257.png" alt="Ruhoolla_Khan_8-1750417483257.png" /></span><SPAN> </SPAN><SPAN>Once the application has been generated, you can see that an action button will appear in the Fiori front-end application. </SPAN><SPAN> </SPAN></P><P><STRONG><SPAN>Result:</SPAN></STRONG><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ruhoolla_Khan_9-1750417483258.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/277079iE48718AB41E3C5DC/image-size/large?v=v2&px=999" role="button" title="Ruhoolla_Khan_9-1750417483258.png" alt="Ruhoolla_Khan_9-1750417483258.png" /></span></P><P><SPAN>As all the status are in ‘NO’ once we select the record and click on that action the records get updated as shown below.</SPAN><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ruhoolla_Khan_10-1750417483259.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/277082i99B5BAF53AD2E07B/image-size/large?v=v2&px=999" role="button" title="Ruhoolla_Khan_10-1750417483259.png" alt="Ruhoolla_Khan_10-1750417483259.png" /></span></P><P><STRONG><SPAN>Conclusion:</SPAN></STRONG><SPAN> </SPAN></P><P><SPAN>Implementing BOPF actions via CDS views in S/4HANA demonstrates the power of combining declarative modeling with robust transactional logic. By leveraging CDS annotations and standard frameworks, developers can deliver efficient, user-friendly, and scalable business applications—reducing custom code while staying aligned with SAP’s clean core principles.</SPAN><SPAN> </SPAN></P>2025-06-24T09:40:16.716000+02:00https://community.sap.com/t5/technology-blog-posts-by-members/i-skipped-fiori-and-i-d-do-it-again/ba-p/14138288I Skipped Fiori (And I'd Do It Again)2025-06-26T23:31:10.570000+02:00Alice_Vhttps://community.sap.com/t5/user/viewprofilepage/user-id/609259<H3 id="ember576" id="toc-hId-1862449086">Or: How TRIZ Taught Me The Best UI Is No UI</H3><P class=""><span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="Fiori-02-Untitled.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/284552i9A02460A468C2F87/image-size/large?v=v2&px=999" role="button" title="Fiori-02-Untitled.png" alt="Fiori-02-Untitled.png" /></span></P><P> Hey SAP folks! <span class="lia-unicode-emoji" title=":waving_hand:">👋</span></P><P> </P><P class=""><EM>Deep breath.</EM></P><P class=""><SPAN>I have a confession: I skipped Fiori. Just like I skipped SAP Smart Forms (jumping straight from SAPscript to Adobe Forms) and WebDynpro (leaping from SAPGUI to Fiori). Before you assume I'm just another anti-Fiori rebel, hear me out.</SPAN></P><P class="">I loved Fiori when it launched in 2013. Finally, SAP that didn't look like Windows 95! Responsive design! Tiles! But it's 2025, and we're still... clicking... through... tiles... to... do... everything.</P><P class="">After working with Fiori since 2015, I had an epiphany that would make any TRIZ (innovation theory) person weep with joy:</P><P class=""><STRONG>"The ideal system is one that doesn't exist but its function is performed."</STRONG></P><HR /><H3 id="ember583" id="toc-hId-1665935581">The "This Can't Be The Future" Moment</H3><P class="">Picture this: <STRONG>9 AM Monday.</STRONG> CFO pings you: <EM>"Need the latest P&L for company 1000 — compare this quarter to last, right now."</EM></P><H3 id="ember585" id="toc-hId-1469422076">The Fiori Way™:</H3><UL><LI>Open Fiori Launchpad (wait for tiles to load)</LI><LI>Find "Financial Statement Analysis" app</LI><LI>Click tile (wait for app to load)</LI><LI>Select company code from dropdown</LI><LI>Choose fiscal period and year</LI><LI>Apply profit center filters</LI><LI>Navigate through multiple screens</LI><LI>Export to Excel for actual analysis</LI></UL><P class=""><STRONG>Time</STRONG>: ~4 minutes · 23 clicks · 8 screens · <STRONG>Frustration</STRONG>: Daily</P><H3 id="toc-hId-1272908571"> </H3><H3 id="ember588" id="toc-hId-1076395066">The 2025 Way:</H3><PRE>Me: Show me P&L breakdown for company code 1000,
this quarter vs last quarter
Claude: Q4 2024 vs Q3 2024 analysis ready:
Revenue: +12% ($2.4M → $2.7M)
EBITDA margin improved 3.2%
(cost optimization in logistics)
Key driver: 18% increase in Product Line A</PRE><P class=""><STRONG>Time</STRONG>: 8 seconds · Clicks: 0 · <STRONG>Sanity</STRONG>: Preserved</P><HR /><H3 id="ember1392" id="toc-hId-879881561">How I Built The Bridge to Skip Ahead</H3><P class="">I knew exactly what I wanted to track. After years with Fiori, I understood the game. So I built a Chrome extension that captures:</P><UL><LI>Every click, input, form submission</LI><LI>Every OData request triggered by those clicks</LI><LI>Complete UI5 context and metadata</LI><LI><STRONG>Atomic action decomposition with parametrization</STRONG></LI></UL><P class=""><STRONG>The pattern was always there:</STRONG></P><P class=""><EM> User Action → UI Update </EM>→ <STRONG>OData Call → Backend Logic</STRONG></P><P class=""><STRONG>The TRIZ insight:</STRONG> Why do we need the first two steps at all?</P><P class=""><STRONG> OData Call → Backend Logic</STRONG></P><P class=""><EM> (Whisper: </EM><A href="https://community.sap.com/t5/technology-blog-posts-by-members/universal-odata-mcp-bridge-or-how-i-accidentally-made-15-000-enterprise/bc-p/14134777" target="_self"><EM>MCP - OData Bridge!)</EM></A></P><HR /><H3 id="ember598" id="toc-hId-683368056">The Shocking Truth: 80% Pure Waste</H3><P class="">My extension analysed hundreds of Fiori sessions across different apps. The results?</P><P class=""><STRONG>Real data from "Manage Detection Methods":</STRONG></P><UL><LI>Duration: 27.7 seconds</LI><LI>Clicks: 10</LI><LI>OData requests: 15</LI><LI><a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1445379">@ui</a>annotations involved: 23</LI><LI>Actual business logic: Update one field</LI></UL><P class=""><STRONG>Pattern discovery:</STRONG></P><UL><LI><STRONG>UI Layer:</STRONG> 80% overhead (pure translation)</LI><LI><STRONG>Business Logic:</STRONG> 20% actual work</LI><LI><STRONG>Innovation opportunity:</STRONG> Eliminate the 80%</LI></UL><HR /><H3 id="ember604" id="toc-hId-486854551">Liberation from <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1445379">@ui</a> Annotation Hell</H3><P class="">Remember wrestling with cryptic <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1445379">@ui</a> annotations? Hours spent debugging why fields don't appear, fighting responsive design, calling consultants when layouts break.</P><P class=""><STRONG>When you eliminate the UI, you eliminate the entire annotation ecosystem.</STRONG> Clean CDS views with pure business logic. No more <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1445379">@ui</a>.* black magic.</P><HR /><H2 id="ember1409" id="toc-hId-161258327">The Three Pillars That Let Me Skip Fiori</H2><OL><LI><STRONG>Parametrized Automation</STRONG>→ Record once, replay forever with different parameters</LI><LI><STRONG>Intelligent Test Generation</STRONG> → Describe in English, auto-generate reliable tests</LI><LI><STRONG>AI-Ready Business Tools</STRONG> → Convert interactions to semantic tools Claude understands</LI></OL><P> </P><HR /><H3 id="ember609" id="toc-hId-93827541">The Transformation Results</H3><DIV class=""><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="2025-06-26_20-21-31.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/279549iF2F58D3CD6857F2C/image-size/large?v=v2&px=999" role="button" title="2025-06-26_20-21-31.png" alt="2025-06-26_20-21-31.png" /></span></DIV><P class=""><STRONG>95% time reduction. 100% complexity elimination.</STRONG></P><H2 id="ember612" id="toc-hId-115485674">The "But What About..." Section</H2><P class=""><STRONG>"But what about data visualization?"</STRONG> Great question! Complex charts and graphs? Keep those Fiori apps. But for the 80% of interactions that are just CRUD operations? Dead.</P><P class=""><STRONG>"But what about user permissions?"</STRONG> The OData services already handle that. If you can't do something in Fiori, the AI can't do it either. Security preserved, clicking eliminated.</P><P class=""><STRONG>"But what about complex workflows?"</STRONG> You mean like "Create PO → Route for approval → Update inventory"? Watch this:</P><P class=""><STRONG>"But what about mobile?"</STRONG> You know what works great on mobile? Chat. You know what doesn't? Trying to click tiny Fiori tiles on a phone screen.</P><HR /><H3 id="ember617" id="toc-hId--374430838">What This Means For You</H3><UL><LI><STRONG>For Functional Consultants:</STRONG> Demonstrate a process once, get automation forever. No coding required.</LI><LI><STRONG>For Developers:</STRONG> Focus on business logic. Let AI handle the interaction layer.</LI><LI><STRONG>For Managers:</STRONG> Measure ROI in seconds saved × transactions per day. The math is beautiful.</LI><LI><STRONG>For Everyone:</STRONG> The future isn't better UIs — it's no UIs at all.</LI></UL><HR /><H3 id="ember619" id="toc-hId--570944343">Your Turn</H3><P class=""><SPAN>Ready to skip your own Fiori apps</SPAN>? The extension turns any SAP professional into an automation architect.</P><P class=""><STRONG>What's your most time-wasting Fiori workflow?</STRONG> Comment below with your biggest pain point — I'll analyse the potential time savings and show you the elimination path.</P><P class="">The ideal interface is one that doesn't exist but gets the job done.</P><P class="">Time to evolve beyond clicking. <span class="lia-unicode-emoji" title=":rocket:">🚀</span></P><HR /><P class=""><STRONG>Technical deep-dive and extension demo ➜ [Coming Soon]</STRONG> <STRONG>Next week:</STRONG> "How TRIZ Principle 13 Made SAP Read My Mind"</P><HR /><H3 id="ember625" id="toc-hId--767457848">Quick Reference/Glossary: see in comments.</H3><P class="">Let me know in comments what you want me to eliminate next <span class="lia-unicode-emoji" title=":grinning_face_with_big_eyes:">😃</span></P>2025-06-26T23:31:10.570000+02:00https://community.sap.com/t5/technology-blog-posts-by-members/api-to-delete-gos-attachment-from-transaction-code-amp-their-applications/ba-p/14170904API to Delete GOS Attachment from Transaction Code & their Applications2025-08-11T12:26:01.244000+02:00vikas_naikdesaihttps://community.sap.com/t5/user/viewprofilepage/user-id/243708<P><U><STRONG>Summary</STRONG></U></P><P>This technical blog is subject to simplify process of attachment deletion and how best way it can be applicable to act as an API.</P><P><U><STRONG>Introduction</STRONG></U></P><P><SPAN>We have come across multiple technical blogs on attachment( can be PDF, image or MS Office objects) in the specific T-Code of the Transactions, such as for Sales Order, Billing Invoice or other relevant business transactions.</SPAN></P><P><SPAN>Here we will focus on the business requirement to delete an already enclosed/attached one of the attachment in the Inspection Lot(QA03) Transaction and methods of implementations.</SPAN></P><P><SPAN>The solution is bifurcated in the simple <STRONG>3 steps and we will use a simple and straight standard class (<STRONG>CL_GOS_DOCUMENT_SERVICE) which will be generic to use for other transactions as well.</STRONG></STRONG></SPAN></P><UL><LI><SPAN>Step 1. Pass Object Types Object Key along with Doc ID</SPAN></LI><LI><SPAN>Step 2: Call DELETE_ATTACHMENT method of CL_GOS_DOCUMENT_SERVICE Class</SPAN></LI><LI><SPAN><SPAN>Step 3: Commit and wait.</SPAN></SPAN><P><STRONG>Code Snippet will give a complete solution </STRONG></P><P><SPAN>***************************************************************************************************</SPAN></P><P><SPAN>** Work area declare</SPAN><SPAN> </SPAN></P></LI></UL><pre class="lia-code-sample language-abap"><code> DATA: LS_LPORB TYPE SIBFLPORB,
LS_LINK TYPE OBL_S_LINK.
DATA: LO_REF TYPE REF TO CL_GOS_DOCUMENT_SERVICE.</code></pre><P><SPAN>************************* <U>Step 1 ***************************************<SPAN> </SPAN></U></SPAN></P><P><SPAN>** Value assignment</SPAN></P><pre class="lia-code-sample language-abap"><code> LS_LPORB-INSTID = <Key Field> . "Pass Key field, in this case it can be Inspection Lot Number
LS_LPORB-TYPEID = <Business Object>. "For Example 'BUS2045'Business Object of Inspection Lot
LS_LPORB-CATID = <Object Type>. " For Example'BO' Object Type
LS_LINK-INSTID_B = <Doc ID>. “Pass Doc ID here </code></pre><P><SPAN>*********************** <U>Step 2 *************************************</U></SPAN></P><P><SPAN>** Calling Standard Class </SPAN> </P><pre class="lia-code-sample language-abap"><code>CREATE OBJECT LO_REF.
CALL METHOD LO_REF->DELETE_ATTACHMENT
EXPORTING
IS_LPORB = IS_LPORB
IP_ATTACHMENT = IS_LINK-INSTID_B.</code></pre><P><SPAN>*************************** <U>Step 3 ******************************</U></SPAN></P><pre class="lia-code-sample language-abap"><code> COMMIT WORK AND WAIT.</code></pre><P><SPAN>***************************************************************************************************</SPAN></P><P><SPAN><U><STRONG>Application</STRONG></U></SPAN></P><P><SPAN>Above Snippet can be fix in the below box, shows a simple Application approach interface with UI/BTP or any Non-SAP application sending request via any Interface or middle layer can be Odata service using SAP gateway using Client-Server response methodology. </SPAN></P><P><SPAN>Simple above code snippet can be placed as part of API logic which will perform its deletion operation in the SAP Transactions such as Inspection Lot/Sales Order/Billing Invoice.</SPAN></P><P> </P><P> </P><P><U><STRONG>Conclusion</STRONG></U></P><P>Deletion of attached document can be deleted by using simple standard class.</P><P> </P><P>Will come up with another series technical developments around Inspection Lot.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="vikas_naikdesai_0-1754305452490.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/295967iA66A0C5D21EFE53A/image-size/medium?v=v2&px=400" role="button" title="vikas_naikdesai_0-1754305452490.png" alt="vikas_naikdesai_0-1754305452490.png" /></span></P>2025-08-11T12:26:01.244000+02:00https://community.sap.com/t5/technology-blog-posts-by-members/pagination-concept-in-odata-ecc-for-sp-7-3/ba-p/14170923Pagination concept in OData - ECC for SP - 7.32025-08-12T08:07:32.133000+02:00vikas_naikdesaihttps://community.sap.com/t5/user/viewprofilepage/user-id/243708<P><U><STRONG>Summary</STRONG></U></P><P>This technical blog will open option to include pagination concept in Odata Service running on ECC system.</P><P><U><STRONG>Introduction</STRONG></U></P><P>This article is specific for developer who are still developing Odata Services on ECC on Pagination Concept.</P><P>There are multiple blogs available on Pagination on S4 system but eventually same concept or logical approach is challenging while working in the ECC system.</P><P><U><STRONG>How pagination works in S4 HANA system</STRONG></U></P><P>Will talk on the existing solutioning part on S4 end before we come to ECC.</P><P>There are two keywords being used to restrict the count - <SPAN>one is <STRONG>$top<SPAN> and the other is <STRONG>$skip. Both of the them play roles to restrict the count. I will not go in details about their operations as there are already existing blogs on it.</STRONG></SPAN></STRONG></SPAN></P><P>In S4, above keywords are used in the follows syntax to perform Pagination.</P><P> </P><DIV> SELECT <field1>,<DIV><SPAN><SPAN> <field2>,</SPAN></SPAN><DIV><SPAN><SPAN> ... ,</SPAN></SPAN><DIV><SPAN><SPAN> ... ,</SPAN></SPAN><DIV><SPAN><SPAN> <fieldn></SPAN></SPAN><DIV> FROM <SAP DB table><DIV> ORDER by <Key_field><DIV> INTO TABLE @<internal_table><DIV> OFFSET @paging-skip UP TO @paging-top ROWS.<DIV> <DIV><U><U><STRONG>Challenge in ECC system</STRONG></U></U><DIV>But when it comes to ECC, above syntax difficult to apply directly as SKIP & ROWS are being used with OFFSET and UPTO keywords, which are not applicable for SAP-ECC system.<DIV> <DIV><U><U><STRONG>Solution</STRONG></U></U><DIV>But, there are other approaches to handle paging in ECC. Here instead of restricting at the time of data fetch using SELECT query, will narrate how paging can be used using SAP standard class.<DIV>Below steps to follow to implement pagination in ECC system.<DIV>1. Pull<SPAN><SPAN> <STRONG>TOP<SPAN> &<SPAN> <STRONG>SKIP<SPAN> from <STRONG>IO_TECH_REQUEST_CONTEXT into work area.</STRONG></SPAN></STRONG></SPAN></SPAN></STRONG></SPAN></SPAN><DIV>2. Use<SPAN><SPAN> <STRONG>PAGING<SPAN> Method of SAP Utility Class - <STRONG>/IWBEP/CL_MGW_DATA_UTIL.</STRONG></SPAN></STRONG></SPAN></SPAN><DIV>3. Pass work area with TOP & SKIP in<SPAN><SPAN> <STRONG>PAGING<SPAN> method.</SPAN></STRONG></SPAN></SPAN><DIV> <DIV>Working Code is below<DIV>******************Data Declaration ***************************<DIV><P>DATA: WA_PAGING TYPE /IWBEP/S_MGW_PAGING.</P><P>******************Assign Top & Bottom***********************</P><P>WA_PAGING-TOP = IO_TECH_REQUEST_CONTEXT->GET_TOP( ).<BR />WA_PAGING-SKIP = IO_TECH_REQUEST_CONTEXT->GET_SKIP( ).</P><P>****************Call Data Utility Class*************************<BR />CALL METHOD /IWBEP/CL_MGW_DATA_UTIL=>PAGING<BR /> EXPORTING<BR /> IS_PAGING = WA_PAGING<BR /> CHANGING<BR /> CT_DATA = <ENTITY_SET>. "This table can be EntitySet of Odata Service</P><DIV> <DIV><U><U><STRONG>Conclusion</STRONG></U></U><DIV>CT_DATA will have only specific number of counts (Skip & Top) as specified in the URI.</DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV>2025-08-12T08:07:32.133000+02:00https://community.sap.com/t5/application-development-and-automation-blog-posts/enabling-background-job-execution-in-s-4hana-from-fiori-using-cds-and-odata/ba-p/14146744Enabling Background Job Execution in S/4HANA from Fiori Using CDS and OData2025-08-21T08:04:03.004000+02:00Ravikumar_H1https://community.sap.com/t5/user/viewprofilepage/user-id/1386926<P><FONT face="arial,helvetica,sans-serif"><STRONG><SPAN class=""><SPAN class=""><SPAN class=""><SPAN class="">Business Scenario</SPAN></SPAN></SPAN></SPAN></STRONG></FONT></P><P><FONT face="arial,helvetica,sans-serif"><SPAN class=""><SPAN class="">Imagine a purchasing department needing to update material prices based on market conditions. Instead of manually running a report in background mode, users can </SPAN></SPAN><SPAN class=""><SPAN class="">select materials in a Fiori app</SPAN></SPAN><SPAN class=""><SPAN class=""> and click </SPAN></SPAN><SPAN class=""><SPAN class="">“Update Prices</SPAN><SPAN class="">”</SPAN></SPAN><SPAN class=""><SPAN class="">,</SPAN><SPAN class=""> which triggers a background job with selected data.</SPAN></SPAN><SPAN class=""> </SPAN></FONT></P><P><FONT face="arial,helvetica,sans-serif">Component Purpose</FONT></P><TABLE><TBODY><TR><TD><FONT face="arial,helvetica,sans-serif"><STRONG>CDS View</STRONG></FONT></TD><TD><FONT face="arial,helvetica,sans-serif">For showing material list in Fiori</FONT></TD></TR><TR><TD><FONT face="arial,helvetica,sans-serif"><STRONG>OData Function Import</STRONG></FONT></TD><TD><FONT face="arial,helvetica,sans-serif">Triggers a background job</FONT></TD></TR><TR><TD><FONT face="arial,helvetica,sans-serif"><STRONG>Fiori App</STRONG></FONT></TD><TD><FONT face="arial,helvetica,sans-serif">Allows selection + button click</FONT></TD></TR><TR><TD><FONT face="arial,helvetica,sans-serif"><STRONG>ABAP Report</STRONG></FONT></TD><TD><FONT face="arial,helvetica,sans-serif">Executes price update logic</FONT></TD></TR><TR><TD><FONT face="arial,helvetica,sans-serif"><STRONG>SM37</STRONG></FONT></TD><TD><FONT face="arial,helvetica,sans-serif">Monitor the job execution</FONT></TD></TR></TBODY></TABLE><P><FONT face="arial,helvetica,sans-serif"><STRONG><SPAN>Step-by-Step Implementation</SPAN></STRONG><SPAN> </SPAN></FONT></P><P><FONT face="arial,helvetica,sans-serif"><STRONG><SPAN>Step 1: CDS View for Material Selection</SPAN></STRONG><SPAN> </SPAN></FONT></P><P><FONT face="arial,helvetica,sans-serif"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ravikumar_H1_0-1754300000109.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/295913i0DA005DB17F3D326/image-size/large?v=v2&px=999" role="button" title="Ravikumar_H1_0-1754300000109.png" alt="Ravikumar_H1_0-1754300000109.png" /></span></FONT></P><P><FONT face="arial,helvetica,sans-serif"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ravikumar_H1_1-1754300069711.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/295914i385F50635E1F9706/image-size/large?v=v2&px=999" role="button" title="Ravikumar_H1_1-1754300069711.png" alt="Ravikumar_H1_1-1754300069711.png" /></span></FONT></P><P><FONT face="arial,helvetica,sans-serif"><SPAN class="">This will expose a simple material list for </SPAN><SPAN class="">selection</SPAN><SPAN class="">.</SPAN></FONT></P><P><FONT face="arial,helvetica,sans-serif"><STRONG><SPAN>Step 2: Create SEGW Project and Import CDS View</SPAN></STRONG><SPAN> </SPAN></FONT></P><UL><LI><FONT face="arial,helvetica,sans-serif"><SPAN>T-code: </SPAN><STRONG><SPAN>SEGW</SPAN></STRONG><SPAN> </SPAN></FONT></LI></UL><UL><LI><FONT face="arial,helvetica,sans-serif"><SPAN>Create project: </SPAN><SPAN>Z_MATERIAL_JOB_API</SPAN><SPAN> </SPAN></FONT></LI></UL><UL><LI><FONT face="arial,helvetica,sans-serif"><SPAN>Import </SPAN><STRONG><SPAN>CDS view as Entity Type</SPAN></STRONG><SPAN> </SPAN></FONT></LI></UL><UL><LI><FONT face="arial,helvetica,sans-serif"><SPAN>Generate runtime artifacts</SPAN><SPAN> </SPAN></FONT></LI></UL><P><FONT face="arial,helvetica,sans-serif"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ravikumar_H1_2-1754300136662.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/295915i85FA634FC4F6794E/image-size/large?v=v2&px=999" role="button" title="Ravikumar_H1_2-1754300136662.png" alt="Ravikumar_H1_2-1754300136662.png" /></span></FONT></P><P><FONT face="arial,helvetica,sans-serif"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ravikumar_H1_3-1754300155702.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/295916iB67EEF45EFF4C993/image-size/large?v=v2&px=999" role="button" title="Ravikumar_H1_3-1754300155702.png" alt="Ravikumar_H1_3-1754300155702.png" /></span></FONT></P><P><FONT face="arial,helvetica,sans-serif"><STRONG><SPAN>Step 3: Add Function Import to SEGW</SPAN></STRONG><SPAN> </SPAN></FONT></P><OL><LI><FONT face="arial,helvetica,sans-serif"><STRONG>In SEGW: </STRONG></FONT></LI></OL><OL><LI><FONT face="arial,helvetica,sans-serif"><SPAN>Right-click </SPAN><STRONG><SPAN>Data Model → Function Imports → Create</SPAN></STRONG><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ravikumar_H1_5-1754300284637.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/295923i65F2D0743DB82447/image-size/large?v=v2&px=999" role="button" title="Ravikumar_H1_5-1754300284637.png" alt="Ravikumar_H1_5-1754300284637.png" /></span></FONT></LI><LI><P> </P><FONT face="arial,helvetica,sans-serif"><SPAN> </SPAN><SPAN>Name: </SPAN><SPAN>TRIGGER_PRICE_JOB</SPAN><SPAN> </SPAN></FONT></LI><LI><FONT face="arial,helvetica,sans-serif"><SPAN>Return Type: </SPAN><STRONG><SPAN>None</SPAN></STRONG><SPAN> </SPAN></FONT></LI><LI><FONT face="arial,helvetica,sans-serif"><SPAN>HTTP Method: </SPAN><STRONG><SPAN>POST</SPAN></STRONG><SPAN> </SPAN></FONT></LI></OL><P><FONT face="arial,helvetica,sans-serif"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ravikumar_H1_6-1754300284640.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/295922i670644909A6ACFEB/image-size/large?v=v2&px=999" role="button" title="Ravikumar_H1_6-1754300284640.png" alt="Ravikumar_H1_6-1754300284640.png" /></span>2. <SPAN>In </SPAN><STRONG><SPAN>Modeling</SPAN></STRONG><SPAN>, assign an Entity Set if needed (optional).</SPAN><SPAN> </SPAN></FONT></P><P><FONT face="arial,helvetica,sans-serif"><STRONG><SPAN class=""><SPAN class="">Step 4: Implement Function Import Logic</SPAN></SPAN><SPAN class=""> </SPAN></STRONG></FONT></P><P><FONT face="arial,helvetica,sans-serif"><STRONG><SPAN class=""><SPAN class=""><SPAN class="">In class: </SPAN></SPAN><SPAN class=""><SPAN class="">ZCL_Z_MATERIAL_JOB_API_DPC_EXT</SPAN></SPAN><SPAN class=""> </SPAN></SPAN></STRONG></FONT></P><pre class="lia-code-sample language-abap"><code>method /iwbep/if_mgw_appl_srv_runtime~execute_action.
data: lv_jobname type tbtcjob value 'ZPRICE_UPDATE_JOB',
lv_jobcount type tbtco-jobcount,
lv_msg type string,
lt_materials type standard table of mara-matnr.
if iv_action_name = 'TRIGGER_PRICE_JOB'.
" (Optional) collect materials from CDS selection or payload
append 'MATERIAL1' to lt_materials.
append 'MATERIAL2' to lt_materials.
" Submit the job
call function 'JOB_OPEN'
exporting
jobname = lv_jobname
importing
jobcount = lv_jobcount
exceptions
others = 1.
if sy-subrc = 0.
" Submit custom report in background
submit zmat_price_update_report
with so_matnr in lt_materials
user sy-uname
via job lv_jobname
number lv_jobcount
and return.
call function 'JOB_CLOSE'
exporting
jobname = lv_jobname
jobcount = lv_jobcount
strtimmed = 'X'
exceptions
others = 1.
lv_msg = |Job { lv_jobname } triggered successfully.|.
else.
lv_msg = 'Job could not be started.'.
endif.
" Send response back to OData
data: lr_return type ref to /iwbep/if_message_container.
lr_return = me->get_message_container( ).
lr_return->add_message(
exporting
iv_msg_text = lv_msg
iv_msg_type = /iwbep/if_message_container=>gcs_msg_type-success
).
endif.
endmethod. </code></pre><P><FONT face="arial,helvetica,sans-serif"><STRONG><SPAN class=""><SPAN class="">Step 5: Background Report </SPAN></SPAN><SPAN class=""><SPAN class="">ZMAT_PRICE_UPDATE_REPORT</SPAN></SPAN></STRONG></FONT></P><pre class="lia-code-sample language-abap"><code>REPORT zmat_price_update_report.
PARAMETERS: so_matnr TYPE mara-matnr RANGE.
START-OF-SELECTION.
LOOP AT so_matnr INTO DATA(lr).
" Dummy logic - Simulate price update
WRITE: / 'Updating price for material:', lr-low.
ENDLOOP. </code></pre><H2 id="toc-hId-1734234983"><FONT face="arial,helvetica,sans-serif">Output – What Happens in Fiori</FONT></H2><OL><LI><P><FONT face="arial,helvetica,sans-serif">User opens the <STRONG>Fiori app</STRONG> showing materials from CDS.</FONT></P></LI><LI><P><FONT face="arial,helvetica,sans-serif">Selects a few materials → clicks <STRONG>“Update Prices”</STRONG>.</FONT></P></LI><LI><P><FONT face="arial,helvetica,sans-serif">The TRIGGER_PRICE_JOB function import is called.</FONT></P></LI><LI><P><FONT face="arial,helvetica,sans-serif">SAP triggers a job: <STRONG>ZPRICE_UPDATE_JOB</STRONG></FONT></P></LI><LI><P><FONT face="arial,helvetica,sans-serif">The custom report runs in background → <STRONG>check SM37</STRONG></FONT></P></LI></OL><P><FONT face="arial,helvetica,sans-serif"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ravikumar_H1_11-1754302243870.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/295940iDBFDC76188836172/image-size/large?v=v2&px=999" role="button" title="Ravikumar_H1_11-1754302243870.png" alt="Ravikumar_H1_11-1754302243870.png" /></span></FONT></P><P><FONT face="arial,helvetica,sans-serif">Log: </FONT></P><P><FONT face="arial,helvetica,sans-serif"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ravikumar_H1_12-1754302498216.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/295943iEC630F0DD79EDD1C/image-size/large?v=v2&px=999" role="button" title="Ravikumar_H1_12-1754302498216.png" alt="Ravikumar_H1_12-1754302498216.png" /></span></FONT></P><P><FONT face="arial,helvetica,sans-serif"><STRONG>Conclusion:</STRONG></FONT></P><P><FONT face="arial,helvetica,sans-serif">This approach bridges <STRONG>Modern UI and robust backend logic</STRONG>. You can now let Fiori apps initiate background-heavy tasks — like price updates, data migration, or batch jobs — with traceable and efficient execution.</FONT></P>2025-08-21T08:04:03.004000+02:00https://community.sap.com/t5/londrina-blog-posts/sitlon-2025-seguran%C3%A7a-em-aplica%C3%A7%C3%B5es-servi%C3%A7os-no-btp-em-%C3%A9pocas-de-ia-e-toda/ba-p/14192829SITLON 2025 - Segurança em Aplicações/Serviços no BTP em épocas de IA, e toda sua história/evolução!2025-08-26T22:48:18.118000+02:00jose_sequeirahttps://community.sap.com/t5/user/viewprofilepage/user-id/285608<P>Hello World! Tudo bem?</P><P>Após o encerramento com sucesso do primeiro SAP Inside Track Londrina (2025), que foi um evento somente presencial e contou com muitas apresentações de qualidade, resolvi criar esse material aqui na comunidade para aqueles que não puderam comparecer pessoalmente.<SPAN class=""> </SPAN></P><P><SPAN class=""><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Evento 2025.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/305144i1F014271F2B730B8/image-size/large?v=v2&px=999" role="button" title="Evento 2025.jpeg" alt="Evento 2025.jpeg" /></span></SPAN></P><P>Então segue a apresentação do conteúdo do SIT Londrina 2025, em formato "Live":</P><P><div class="video-embed-center video-embed"><iframe class="embedly-embed" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FNcAlhFdOR5A%3Ffeature%3Doembed&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DNcAlhFdOR5A&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FNcAlhFdOR5A%2Fhqdefault.jpg&type=text%2Fhtml&schema=youtube" width="400" height="225" scrolling="no" title="Segurança em Aplicações/Serviços no BTP em épocas de IA - SIT Londrina 2025" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture;" allowfullscreen="true"></iframe></div></P><P><EM>Mas se ainda não se contextualizou, sugiro antes de assistir o material acima ler todo o conteúdo abaixo e entender a evolução até o evento SIT Londrina 2025, ok?</EM></P><P>Se você não conhece SAP e chegou até aqui, segue um pequeno resumo:</P><P><I>SAP é um software de gestão empresarial usado pelas maiores e mais importantes empresas do mundo para integrar e otimizar processos de negócios cruciais, como finanças e logística. Ele centraliza dados para fornecer uma visão completa e em tempo real, permitindo decisões estratégicas mais rápidas e eficientes. A sua importância reside em ser uma espinha dorsal tecnológica que garante a eficiência e a competitividade global dessas corporações.</I></P><P>No evento, realizei a apresentação “Segurança em Aplicações/Serviços no BTP em épocas de IA” sobre Cyber Security no mundo SAP, para aplicações desenvolvidas em um modelo bem específico. Mas com esse post aqui, o objetivo é atingir e disponibilizar o conteúdo a todos da comunidade SAP, bem como os curiosos e interessados pelo tema de segurança da informação. Como muitos podem estar lendo pela primeira vez sobre o tema e o que eu já fiz até então, vou detalhar a historia desde o começo de uma maneira resumida até chegar no SIT Londrina 2025, ok?</P><P>Tudo começou na Pandemia, no ano de 2020/2021, onde estava fazendo uma pesquisa para um blog que iria escrever sobre um tutorial de um tipo desenvolvimento Web especifico (SAPUI5) . Esse tutorial seria sobre o desenvolvimento de aplicações UI5/FIORI ao publico B2C, ou seja usuários que em sua maioria nunca teriam visto nada sobre SAP e que para eles seria como uma aplicação Web qualquer, também aplicações essas que seriam disponibilizadas na internet para acesso do publico em geral. No Blog eu iria abordar a arquitetura recomendada, exemplos de códigos fonte, etc., porém na etapa de pesquisa para apresentar alguns “exemplos” já existentes no mercado, me deparei com cenários muito assustadores!</P><P>Para contextualizar, “o sistema SAP” sempre é em sua maioria um sistema “fechado”, onde o acesso é feito geralmente por quem de fato precisa do mesmo (até por questão de custo de licença). Analisando a minha experiencia, de colegas e muitos estudos, conseguia afirmar então que os profissionais que desenvolvem, desenham e/ou especificam soluções SAP ao “publico geral”, em sua maioria não tem uma preocupação com os quesitos de segurança. No mundo SAP, os desenvolvimentos geralmente ficam dentro do sistema e/ou na rede interna do cliente, então esse tópico nunca foi muito explorado pelos profissionais e consultorias que desenvolvem soluções customizadas, e esse aqui foi o principal motivador de iniciar todo o conteúdo. Ou seja, profissionais do mundo SAP precisam se atentar e se preparar ao criar soluções desse tipo, pois os impactos de não fazer algo correto podem ser enormes (que verá logo mais alguns exemplos). Pois se algum desses casos caísse nas mãos erradas, não só a imagem da empresa em questão que usa SAP, independente do país que está localizada, seria impactada com prejuízos financeiros e até implicações legais, mas nós profissionais do mundo SAP também seriamos impactados pela “imagem” que seria passada que o sistema SAP é de alguma maneira "inseguro".</P><P>Antes de entrarmos no detalhe tenho que falar algo importante, tudo que falarei daqui em diante diz respeito a <STRONG>aplicações/serviços customizados</STRONG> e <U>não standard SAP</U>, ou seja foram soluções desenvolvidas por alguém para atender o requisito daquele cliente em específico, e não algo que “vem” no produto SAP. Soluções SAP a nível de produto no geral são muitos seguras, onde a mesma investe muito para manter o mais alto nível de segurança, utilizando todas as ferramentas e métodos de mercado para tal. Até ter programas onde pode “contratar” profissionais de cyber segurança para tentar explorar e descobrir como deixar seus produtos mais seguros (onde eu posso ou não ter participado. NDA). Recomendo os links <A href="https://www.sap.com/about/trust-center/security.html%20" target="_self" rel="noopener noreferrer">1</A> e <A href="https://www.sap.com/products/financial-management/what-is-cybersecurity.html%20" target="_self" rel="noopener noreferrer">2</A> para quem deseja se aprofundar mais no tema de segurança no nível de produto SAP. Outro ponto importante, é que demonstro como essas aplicações customizadas podem ser facilmente encontradas na internet por ferramentas como Google Buscador.<SPAN class=""> </SPAN></P><P>Na pesquisa fui encontrando muitas empresas vulneráveis em um numero altíssimo, quase podendo afirmar que mais 30% das que encontrei, tinham algum problema. Então o que era um tutorial mudou para uma pesquisa mais aprofundada do tema, e com isso resolvi criar o movimento <A href="https://safesapui5.web.app/" target="_self" rel="nofollow noopener noreferrer">#SafeSAPUI5</A>. Que basicamente iniciaria com a criação de material e conscientização dos profissionais para termos aplicações e serviços SAP seguros que estão expostos na internet. Pois aqui entra um detalhe técnico bem agravante, para muitos casos o requerimento do cliente (ou seja, o que ele precisa) é ter uma aplicação customizada porem sem ter a necessidade de <STRONG>nenhum tipo de autenticação</STRONG> por parte do usuário que vai acessar. Ou seja, ao clicar na URL ele já deve entrar na aplicação customizada e poder fazer a ação necessária, cenário esse que foge bem do “padrão” SAP e existem muitas e <U>muitas aplicações como essa espalhadas pelo mundo</U>.<SPAN class=""> </SPAN></P><P>Os materiais do #SafeSAPUI5 podem ser encontrados <A href="https://safesapui5.web.app/" target="_self" rel="nofollow noopener noreferrer">aqui</A>.</P><P>Além dos mesmos, como já estava pronto para escrever, resolvi criar um Ebook gratuito sobre o tema, juntando um pouco de historia, exemplos, dicas e casos reais. Com isso, nasceu o ebook UI5 Hacker, que pode ser encontrado gratuitamente <A href="https://ui5hacker.web.app/" target="_self" rel="nofollow noopener noreferrer">aqui</A> (Português e Inglês).<SPAN class=""> </SPAN></P><P>Juntando tudo isso apresentei a primeira palestra do tema, ainda na Pandemia, no evento UI5 Con 2021 (em Inglês) que é a conferencia global de SAPUI5, biblioteca utilizada para realizar esses desenvolvimentos (mais detalhes na palestra ou ebook).</P><P>UI5CON 2021: #SafeSAPUI5: <SPAN class=""><BR /></SPAN></P><P><SPAN class=""><div class="video-embed-center video-embed"><iframe class="embedly-embed" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FIyLPftaF8CA%3Ffeature%3Doembed&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DIyLPftaF8CA&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FIyLPftaF8CA%2Fhqdefault.jpg&type=text%2Fhtml&schema=youtube" width="400" height="225" scrolling="no" title="#SafeSAPUI5" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture;" allowfullscreen="true"></iframe></div></SPAN></P><P>Depois da mesma, com a ajuda da própria SAP, consegui espalhar essa conscientização e também comunicar os clientes ao redor do mundo que estavam inseguros e foram citados nos exemplos da palestra e ebook (alguns com vulnerabilidades muito graves, como cópia do passaporte de todos os usuários pronta para ser extraída por exemplo). Importante, era possível conseguir isso sem precisar realizar nenhum tipo de hack, apenas saber executar um serviço/API que está exposto na internet (até pelo próprio navegador).<SPAN class=""> </SPAN></P><P>Então em 2023, resolvi fazer um compilado do material de 2021 em Português (com alguns novos exemplos) e apresentar no SIT SP 2023 (Serviços Seguros & Aplicações Seguras), trazendo a tona novamente o material e o tema (agora focado mais em Português).</P><P>A palestra pode ser vista no Youtube aqui:</P><P><div class="video-embed-center video-embed"><iframe class="embedly-embed" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FrBvyOuJZDHA%3Fstart%3D2219%26feature%3Doembed%26start%3D2219&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DrBvyOuJZDHA&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FrBvyOuJZDHA%2Fhqdefault.jpg&type=text%2Fhtml&schema=youtube" width="400" height="225" scrolling="no" title="Serviços Seguros & Aplicações Seguras (BTP, FIORI, S/4 e Segurança da Informação)" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture;" allowfullscreen="true"></iframe></div></P><P>Com isso tive muitos feedbacks positivos de profissionais e de clientes SAP que resolveram suas vulnerabilidades e passaram a adotar as praticas em seu dia a dia, para esse e outros requisitos. Mas é importante falar, <STRONG>é possível SIM</STRONG> fazer uma aplicação WEB como essa que descrevi acima de maneira segura e protegida para o seu cliente, só seguir as boas praticas e utilizar as ferramentas corretas. Acontece que nesse "meio tempo", a adoção do <A href="https://help.sap.com/docs/btp" target="_self" rel="noopener noreferrer">SAP BTP</A> (oferta da SAP de serviços Cloud, assim como os outros grandes players de tecnologia) cresceu exponencialmente no mundo todo. Se iniciou então um movimento de muitos clientes para levarem suas soluções para o BTP (conhecido como o movimento “move to cloud”), e alguns deles com aplicações se enquadrando nas possíveis vulnerabilidades descritas.<SPAN class=""> </SPAN></P><P>Mas e então, apenas levar as aplicações ao BTP as deixam seguras?<SPAN class=""> </SPAN></P><P>E com a chegada, popularização e massiva utilização/evolução das <A href="https://pt.wikipedia.org/wiki/Intelig%C3%AAncia_artificial" target="_self" rel="nofollow noopener noreferrer">Inteligências Artificiais (IAs)</A> impactam nisso tudo?</P><P>Para responder as questões acima e trazer a tona novamente o tema, resolvi criar o material da palestra apresentada no SIT Londrina 2025: “Segurança em Aplicações/Serviços no BTP em épocas de IA”. Mas como comentei antes, o evento foi somente presencial e por conta disso resolvi realizar uma “live” com o mesmo material e conteúdo para disponibilizar a todos o mesmo. Colocando em uma linha do tempo então, ficaria assim:</P><P><SPAN class=""><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="MKT.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/305145i1798EC4FADAC8DCB/image-size/large/is-moderation-mode/true?v=v2&px=999" role="button" title="MKT.png" alt="MKT.png" /></span></SPAN></P><P>O PDF do material apresentado no SIT Londrina 2025 pode ser encontrado <A href="http://tiny.cc/SITLON2025" target="_self" rel="nofollow noopener noreferrer">aqui</A>.</P><P>Após a apresentação desse material (PDF e "Live"), demonstro que uma simples ida ao SAP BTP com aplicações nesse modelo não te deixará mais seguro. E com a chegada das IAs, existe hoje uma rápida revolução no segmento de Cyber Security (assim como o mundo em geral) que as empresas que utilizam soluções SAP devem estar atentas e preparadas.<SPAN class=""> </SPAN></P><P>Espero que tenha gostado do conteúdo e lhe ajudado, e que de alguma maneira tenha agregando algo ao seu conhecimento atual.<SPAN class=""> </SPAN></P><P>Obrigado e nos vemos nas próximas aventuras do “Hacker do Bem”.</P>2025-08-26T22:48:18.118000+02:00https://community.sap.com/t5/technology-blog-posts-by-members/how-to-connect-with-sap-s-4hana-odata-services-from-sap-apim/ba-p/14268027How to connect with SAP S/4HANA OData Services from SAP APIM?2025-11-13T17:45:49.137000+01:00Sookriti_Mishrahttps://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&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&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&px=999" role="button" title="Sookriti_Mishra_1-1763043548225.png" alt="Sookriti_Mishra_1-1763043548225.png" /></span></P><P>Select the API & 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&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&px=999" role="button" title="Sookriti_Mishra_0-1763050329413.png" alt="Sookriti_Mishra_0-1763050329413.png" /></span></P><P> </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&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> <!--Specify in the APIKey element where to look for the variable containing the api key-->
<VerifyAPIKey async='true' continueOnError='false' enabled='true'
xmlns='http://www.sap.com/apimgmt'>
<APIKey ref='request.header.apikey '/>
</VerifyAPIKey></code></pre><P><STRONG>Key Value Map Operations </STRONG>- To fetch the credentials saved in the Key Value Mapping</P><pre class="lia-code-sample language-markup"><code><KeyValueMapOperations mapIdentifier="SAP_S4HANA_Credentials" async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<Get assignTo="private.usernameFromKVM" index="1">
<Key>
<Parameter>Username</Parameter>
</Key>
</Get>
<Get assignTo="private.passwordFromKVM" index="1">
<Key>
<Parameter>Password</Parameter>
</Key>
</Get>
<Scope>environment</Scope>
</KeyValueMapOperations></code></pre><P><STRONG>Basic Authentication </STRONG>- To pass the credentials fetched in the previous step.</P><pre class="lia-code-sample language-markup"><code><BasicAuthentication async='true' continueOnError='false' enabled='true' xmlns='http://www.sap.com/apimgmt'>
<Operation>Encode</Operation>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<User ref='private.usernameFromKVM'></User>
<Password ref='private.passwordFromKVM'></Password>
<AssignTo>request.header.Authorization</AssignTo>
</BasicAuthentication></code></pre><P><STRONG>Assign Message </STRONG>- So you get an error as, "<STRONG><SPAN>{"fault":{"faultstring":"Unsupported Encoding \"br\"","detail":{"errorcode":"protocol.http.UnsupportedEncoding"}}}</SPAN></STRONG><SPAN>". <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><!-- This policy can be used to create or modify the standard HTTP request and response messages -->
<AssignMessage async="false" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
<!-- Sets a new value to the existing parameter -->
<Set>
<Headers>
<Header name="Accept-Encoding">gzip,deflate</Header>
</Headers>
</Set>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<AssignTo createNew="false" type="request"></AssignTo>
</AssignMessage></code></pre><H3 id="toc-hId-1107792671">5. Create Product & 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&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&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&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?v=v2&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&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&px=999" role="button" title="Sookriti_Mishra_2-1763052043480.png" alt="Sookriti_Mishra_2-1763052043480.png" /></span></P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P>2025-11-13T17:45:49.137000+01:00https://community.sap.com/t5/artificial-intelligence-blogs-posts/hands-on-guide-sap-build-joule-skill-for-purchase-order-listing-approval-or/ba-p/14266886Hands-On Guide: SAP Build + Joule Skill for Purchase Order Listing, Approval, or Modification2025-12-22T08:09:03.721000+01:00Batuhannhttps://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> </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> </P><P> </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. ( 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> </P><H3 id="toc-hId-1893794982"><STRONG>1. Create an Environment</STRONG></H3><P> </P><P>We need to create an environment for testing joule skill.</P><P>Open the SAP Build Lobby, choose Control Tower->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?v=v2&px=999" role="button" title="Batuhann_0-1762951486194.png" alt="Batuhann_0-1762951486194.png" /></span></P><P> </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?v=v2&px=999" role="button" title="Batuhann_1-1762951486194.png" alt="Batuhann_1-1762951486194.png" /></span></P><P> </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?v=v2&px=400" role="button" title="Batuhann_2-1762951486194.png" alt="Batuhann_2-1762951486194.png" /></span></P><P> </P><H3 id="toc-hId-1697281477"><STRONG>2. Exposing the Destination</STRONG></H3><P> </P><P>Url of the destination on BTP is the url of our SAP system and the destination must have these properties:<SPAN class=""> </SPAN></P><P>sap.applicationdevelopment.actions.enabled -> true</P><P>sap.processautomation.enabled -> true</P><P>sap.build.usage -> odata_gen</P><P> </P><P>Also the destination’s user will be used for set an external break-point for debugging the ABAP code.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_3-1762951486194.png" alt="Batuhann_3-1762951486194.png" /></span></P><P> </P><P>Open the SAP Build Lobby, choose Control Tower->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?v=v2&px=999" role="button" title="Batuhann_4-1762951486193.png" alt="Batuhann_4-1762951486193.png" /></span></P><P> </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?v=v2&px=999" role="button" title="Batuhann_5-1762951486194.png" alt="Batuhann_5-1762951486194.png" /></span></P><P> </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?v=v2&px=999" role="button" title="Batuhann_6-1762951486194.png" alt="Batuhann_6-1762951486194.png" /></span></P><P> </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> </P><P>Fill the table:</P><P> </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?v=v2&px=999" role="button" title="Batuhann_7-1762951486194.png" alt="Batuhann_7-1762951486194.png" /></span></P><P> </P><H3 id="toc-hId-1304254467"><STRONG>4. Create a CDS from the ZTABLE for Odata</STRONG></H3><P> </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> </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?v=v2" width="552" height="491" role="button" title="Batuhann_8-1762951486194.png" alt="Batuhann_8-1762951486194.png" /></span></P><P> </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?v=v2" width="531" height="469" role="button" title="Batuhann_9-1762951486194.png" alt="Batuhann_9-1762951486194.png" /></span></P><P> </P><P>Extend the project, right click to ‘Data Model’, select the Reference->Source</P><P> </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?v=v2" width="524" height="205" role="button" title="Batuhann_10-1762951486195.png" alt="Batuhann_10-1762951486195.png" /></span></P><P> </P><P>Fill the CDS name that you created. Choose ‘Next’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_11-1762951486195.png" alt="Batuhann_11-1762951486195.png" /></span></P><P> </P><P>Choose ‘Finish’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_12-1762951486195.png" alt="Batuhann_12-1762951486195.png" /></span></P><P> </P><P>Activate and generate the Service:</P><P> </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?v=v2&px=999" role="button" title="Batuhann_13-1762951486195.png" alt="Batuhann_13-1762951486195.png" /></span></P><P> </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> </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?v=v2&px=999" role="button" title="Batuhann_14-1762951486195.png" alt="Batuhann_14-1762951486195.png" /></span></P><P> </P><P>In the method, update the approved field with the below code and activate it.</P><P> </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=>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->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> </P><H3 id="toc-hId-911227457"><STRONG>6. Activate the Odata service via /iwfnd/maint_service T-code</STRONG></H3><P> </P><P>Choose ‘Add Service’</P><P> </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?v=v2&px=999" role="button" title="Batuhann_15-1762951486195.png" alt="Batuhann_15-1762951486195.png" /></span></P><P> </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> </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?v=v2&px=999" role="button" title="Batuhann_16-1762951486195.png" alt="Batuhann_16-1762951486195.png" /></span></P><P> </P><P>Assign the package and continue.</P><P> </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?v=v2" width="586" height="482" role="button" title="Batuhann_17-1762951486195.png" alt="Batuhann_17-1762951486195.png" /></span></P><P> </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> </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?v=v2&px=999" role="button" title="Batuhann_18-1762951486195.png" alt="Batuhann_18-1762951486195.png" /></span></P><P> </P><P>Select the HTTP method as ‘GET’. Press ‘EntitySets’ to choose entity set. Choose the one that you created.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_19-1762951486195.png" alt="Batuhann_19-1762951486195.png" /></span></P><P> </P><P>Press ‘Execute’ button for testing and response should appear as follows.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_20-1762951486196.png" alt="Batuhann_20-1762951486196.png" /></span></P><P> </P><H3 id="toc-hId-714713952"><STRONG>7. Crete an Action in SAP Build</STRONG></H3><P> </P><P>Open the SAP Build Lobby, choose Connectors->Actions and press the ‘Create’ button. Choose ‘OData Destinations’ and select the Destination that we created.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_21-1762951486196.png" alt="Batuhann_21-1762951486196.png" /></span></P><P> </P><P>Fill the Resource Path as follows and click ‘Next’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_22-1762951486196.png" alt="Batuhann_22-1762951486196.png" /></span></P><P> </P><P>The available methods are listed in this window. Select ‘Next’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_23-1762951486196.png" alt="Batuhann_23-1762951486196.png" /></span></P><P> </P><P>Fill the name and description for your action and create.</P><P> </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> </P><P>The action Purchase_Order_Action is created. Click the action and open it.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_25-1762951486196.png" alt="Batuhann_25-1762951486196.png" /></span></P><P> </P><P>Select the methods in the OData Service.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_26-1762951486196.png" alt="Batuhann_26-1762951486196.png" /></span></P><P> </P><P>The GET method's input has no required fields, only optional GET parameters.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_27-1762951486196.png" alt="Batuhann_27-1762951486196.png" /></span></P><P> </P><P>Output parameters are the fields in the CDS that we created.<SPAN class=""> </SPAN></P><P> </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?v=v2&px=999" role="button" title="Batuhann_28-1762951486197.png" alt="Batuhann_28-1762951486197.png" /></span></P><P> </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> </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?v=v2&px=999" role="button" title="Batuhann_29-1762951486197.png" alt="Batuhann_29-1762951486197.png" /></span></P><P> </P><P>The data appears on the ‘Test Preview’ section.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_30-1762951486197.png" alt="Batuhann_30-1762951486197.png" /></span></P><P> </P><P>The PATCH method requires purchaseorder, purchaseorderitem and reservationitem, all of which are key fields in our ZTABLE and CDS.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_31-1762951486197.png" alt="Batuhann_31-1762951486197.png" /></span></P><P> </P><P>There are no standard output in PATCH method.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_32-1762951486197.png" alt="Batuhann_32-1762951486197.png" /></span></P><P> </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> </P><P>Also the link on the Test section can be used in the SAP Gateway Client to test the PATCH method.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_33-1762951486197.png" alt="Batuhann_33-1762951486197.png" /></span></P><P> </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?v=v2&px=999" role="button" title="Batuhann_34-1762951486197.png" alt="Batuhann_34-1762951486197.png" /></span></P><P> </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> </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?v=v2&px=999" role="button" title="Batuhann_35-1762951486197.png" alt="Batuhann_35-1762951486197.png" /></span></P><P> </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> </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?v=v2&px=999" role="button" title="Batuhann_36-1762951486198.png" alt="Batuhann_36-1762951486198.png" /></span></P><P> </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> </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?v=v2&px=999" role="button" title="Batuhann_37-1762951486198.png" alt="Batuhann_37-1762951486198.png" /></span></P><P> </P><P>For the PATCH method, our key fields in the internal table IT_KEY_TAB.<SPAN class=""> </SPAN></P><P> </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?v=v2&px=999" role="button" title="Batuhann_38-1762951486198.png" alt="Batuhann_38-1762951486198.png" /></span></P><P> </P><H3 id="toc-hId-518200447"><STRONG>8. Create A Joule Skill to Get Purchase Order</STRONG></H3><P> </P><P>Open the SAP Build Lobby, choose Create->Joule Skill and fill the name and description. Open the created skill.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_39-1762951486198.png" alt="Batuhann_39-1762951486198.png" /></span></P><P> </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> </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?v=v2&px=999" role="button" title="Batuhann_40-1762951486198.png" alt="Batuhann_40-1762951486198.png" /></span></P><P> </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> </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?v=v2&px=999" role="button" title="Batuhann_41-1762951486198.png" alt="Batuhann_41-1762951486198.png" /></span></P><P> </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?v=v2&px=999" role="button" title="Batuhann_42-1762951486198.png" alt="Batuhann_42-1762951486198.png" /></span></P><P> </P><P>Press ‘+’ and choose ‘Call Action’, ‘Browse All Actions’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_43-1762951486199.png" alt="Batuhann_43-1762951486199.png" /></span></P><P> </P><P>Search for ‘ZSLV_V_BUILD_TEST’ or your Service Name. Add the ‘Get entities from ZSLV_V_BUILD_TEST’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_44-1762951486199.png" alt="Batuhann_44-1762951486199.png" /></span></P><P> </P><P>Select the ‘Destination Variable’ as Destination we created.<SPAN class=""> </SPAN></P><P> </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?v=v2&px=999" role="button" title="Batuhann_45-1762951486199.png" alt="Batuhann_45-1762951486199.png" /></span></P><P> </P><P>We can skip the input tab because there are no input for GET method.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_46-1762951486199.png" alt="Batuhann_46-1762951486199.png" /></span></P><P> </P><P>We can see the output parameters in this tab.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_47-1762951486199.png" alt="Batuhann_47-1762951486199.png" /></span></P><P> </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> </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?v=v2&px=999" role="button" title="Batuhann_48-1762951486199.png" alt="Batuhann_48-1762951486199.png" /></span></P><P> </P><P>Save the Joule Skill.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_49-1762951486199.png" alt="Batuhann_49-1762951486199.png" /></span></P><P> </P><P>And Release.</P><P> </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&px=999" role="button" title="Batuhann_50-1762951486199.png" alt="Batuhann_50-1762951486199.png" /></span></P><P> </P><P>Now Deploy.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_51-1762951486199.png" alt="Batuhann_51-1762951486199.png" /></span></P><P> </P><P>Choose the Environment we created and click ‘Upgrade’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_52-1762951486199.png" alt="Batuhann_52-1762951486199.png" /></span></P><P> </P><P>Match the destinations, and the skill will be ready to use by Joule after deployment.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_53-1762951486200.png" alt="Batuhann_53-1762951486200.png" /></span></P><P> </P><H3 id="toc-hId-321686942"><STRONG>9. Create A Joule Skill to Approve Purchase Order</STRONG></H3><P> </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> </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?v=v2&px=999" role="button" title="Batuhann_54-1762951486200.png" alt="Batuhann_54-1762951486200.png" /></span></P><P> </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> </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?v=v2&px=999" role="button" title="Batuhann_55-1762951486200.png" alt="Batuhann_55-1762951486200.png" /></span></P><P> </P><P>Choose ‘+’ and ‘Call Action’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_56-1762951486200.png" alt="Batuhann_56-1762951486200.png" /></span></P><P> </P><P>Browse All Actions.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_57-1762951486200.png" alt="Batuhann_57-1762951486200.png" /></span></P><P> </P><P>Search update or the service name. Add the Update entity in ZSLV_V_BUILD_TEST.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_58-1762951486200.png" alt="Batuhann_58-1762951486200.png" /></span></P><P> </P><P>On the ‘General’ tab, assign the Destination.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_59-1762951486200.png" alt="Batuhann_59-1762951486200.png" /></span></P><P> </P><P>On the ‘Inputs’ tab, assign the purchaseorder, purchaseorderitem and reservationitem to the parameters created on the "Trigger" step.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_60-1762951486200.png" alt="Batuhann_60-1762951486200.png" /></span></P><P> </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=""> </SPAN></P><P> </P><P>Choose ‘approved’ field and ‘Apply a formula’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_61-1762951486200.png" alt="Batuhann_61-1762951486200.png" /></span></P><P>Type ‘true’ and click ‘Apply’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_62-1762951486200.png" alt="Batuhann_62-1762951486200.png" /></span></P><P> </P><P>Choose ‘+’ and ‘Check Condition’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_63-1762951486201.png" alt="Batuhann_63-1762951486201.png" /></span></P><P> </P><P>Choose the ‘Condition Editor’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_64-1762951486201.png" alt="Batuhann_64-1762951486201.png" /></span></P><P> </P><P>Add the following conditions and Click ‘Apply’. If PATCH method is executed successfully, the result will be empty.<SPAN class=""> </SPAN></P><P> </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?v=v2&px=999" role="button" title="Batuhann_65-1762951486201.png" alt="Batuhann_65-1762951486201.png" /></span></P><P> </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> </P><P>Choose the ‘+’ on the left branch and ‘Send Response’.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_66-1762951486201.png" alt="Batuhann_66-1762951486201.png" /></span></P><P> </P><P>Open Message Editor.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_67-1762951486201.png" alt="Batuhann_67-1762951486201.png" /></span></P><P> </P><P>Fill the parameters as shown below and save.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_68-1762951486201.png" alt="Batuhann_68-1762951486201.png" /></span></P><P> </P><P>You can add parameters to the title and message with the ‘<>’ button.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_69-1762951486201.png" alt="Batuhann_69-1762951486201.png" /></span></P><P> </P><P>Do the same steps for the right branch of the condition. ‘+’ -> ’Send Response’ -> ‘Open Message Editor’</P><P> </P><P>Fill the parameters as shown below and save.</P><P> </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?v=v2&px=999" role="button" title="Batuhann_70-1762951486201.png" alt="Batuhann_70-1762951486201.png" /></span></P><P> </P><P>Save, Release and Deploy just like the previous GET_PURCHASE_ORDER skill.</P><P> </P><H3 id="toc-hId-125173437"><STRONG>10. Launch The Joule and Test The Skills</STRONG></H3><P> </P><P>Open the SAP Build Lobby, choose Control Tower->Environments->Joule</P><P> </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?v=v2&px=999" role="button" title="Batuhann_71-1762951486201.png" alt="Batuhann_71-1762951486201.png" /></span></P><P> </P><P>Launch the joule, ask for Purchase Orders and get the details.</P><P> </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&px=999" role="button" title="Batuhann_72-1762951486202.png" alt="Batuhann_72-1762951486202.png" /></span></P><P> </P><P>Ask joule to approve the purchase orders and get the illustrated success message card we create.</P><P> </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&px=999" role="button" title="Batuhann_73-1762951486202.png" alt="Batuhann_73-1762951486202.png" /></span></P><P> </P>2025-12-22T08:09:03.721000+01:00https://community.sap.com/t5/technology-blog-posts-by-sap/how-to-test-oauth-enabled-inbound-communication-in-sap-using-an-api-client/ba-p/14077042How to Test OAuth-Enabled Inbound Communication in SAP Using an API Client2025-12-22T11:34:21.364000+01:00Eugenieyahttps://community.sap.com/t5/user/viewprofilepage/user-id/1803647<H1 id="toc-hId-1579316738">Introduction</H1><P><SPAN>This blog post explains how to test OAuth-enabled inbound communication in SAP using an API client. It walks through the configuration steps and provides practical examples for validating the setup.</SPAN></P><P><SPAN>When working with inbound communication in SAP S/4HANA Cloud or on-premises systems, developers and integration specialists often need a lightweight tool to test APIs secured with OAuth 2.0. </SPAN></P><P>While there are many API testing tools available today, this guide focuses on <STRONG>Bruno</STRONG>—a modern, open-source similar to the more established <STRONG>Postman</STRONG>. Personally I think of Postman as the old guard, and Bruno as the new pup on the block: sleek, efficient, and eager to fetch your tokens! <EM>(And yes, my love for dogs may have influenced this choice just a little.) </EM><BR /> </P><P class="lia-align-center" style="text-align: center;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Image was created by the author using an AI illustration tool and is original content." style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/354623i7F1B810BDECDDEA9/image-size/medium/is-moderation-mode/true?v=v2&px=400" role="button" title="Eugenieya_0-1766399067671.png" alt="Image was created by the author using an AI illustration tool and is original content." /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Image was created by the author using an AI illustration tool and is original content.</span></span></P><P> <span class="lia-unicode-emoji" title=":paw_prints:">🐾</span><SPAN> </SPAN><SPAN>In this post, I’ll walk you through how to:</SPAN></P><OL><LI><SPAN>Configure a custom communication arrangement based on an existing communication scenario for OAuth 2.0</SPAN></LI><LI><SPAN>Use an API client to test inbound communication secured with OAuth 2.0</SPAN></LI></OL><P><STRONG><SPAN>Note:</SPAN></STRONG><SPAN> This guide assumes you already have a communication scenario that supports OAuth 2.0.<BR /><BR /></SPAN></P><H1 id="toc-hId-1382803233"><SPAN>Prerequisites</SPAN></H1><UL><LI><SPAN>A communication scenario in your S/4HANA system that supports OAuth 2.0</SPAN></LI><LI><SPAN><SPAN>An API client installed on your operating system </SPAN></SPAN>(for example, Bruno<SPAN>, </SPAN>Postman<SPAN>, or any equivalent tool)</SPAN></LI></UL><P><SPAN>So, grab your treats and let’s get our paws dirty—Bruno’s ready to sniff out those OAuth tokens and help you unleash smoother integrations!<BR /><BR /></SPAN></P><H1 id="toc-hId-1186289728"><SPAN>Step 1: Enable a Custom Communication Arrangement for OAuth</SPAN></H1><H2 id="toc-hId-1118858942"><SPAN>1. Create a Communication System and Communication User</SPAN></H2><P><span class="lia-unicode-emoji" title=":paw_prints:">🐾</span> <EM>Think of the Communication System as Bruno’s doghouse—it needs to be cozy, secure, and ready for visitors. </EM><span class="lia-unicode-emoji" title=":paw_prints:">🐾</span></P><P><SPAN>Open the <STRONG>Communication Systems</STRONG> app and create a new system:<BR /><BR /></SPAN></P><TABLE border="1" width="100%"><TBODY><TR><TD width="50%" height="30px"><SPAN><STRONG>System ID</STRONG></SPAN></TD><TD width="50%" height="30px"><SPAN><EM>Z_BRUNO</EM></SPAN></TD></TR><TR><TD width="50%" height="30px"><SPAN><STRONG>System Name</STRONG></SPAN></TD><TD width="50%" height="30px"><SPAN><EM>Z_BRUNO</EM></SPAN></TD></TR></TBODY></TABLE><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Bruno1.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/287795i75DBF04F18F36CB1/image-size/large?v=v2&px=999" role="button" title="Bruno1.png" alt="Bruno1.png" /></span></P><P><SPAN><BR />Under </SPAN><STRONG>Technical Data</STRONG><SPAN>:</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Bruno2.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/287802i64E76A747645169E/image-size/large?v=v2&px=999" role="button" title="Bruno2.png" alt="Bruno2.png" /></span></P><OL><LI><SPAN>Enable <STRONG>Inbound Only</STRONG>.</SPAN></LI><LI><SPAN>In OAuth 2.0 Settings:</SPAN><SPAN> </SPAN><UL><LI><SPAN>Set <STRONG>Client Redirect URI Type</STRONG> to <EM><STRONG>Loopback</STRONG></EM></SPAN></LI><LI><SPAN>Set a path in the <STRONG>Path</STRONG> field, e.g., <EM>/bruno/redirect<BR /></EM> → This becomes your <STRONG>Callback URL</STRONG>: <EM><A href="http://127.0.0.1/bruno/redirect" target="_blank" rel="noopener nofollow noreferrer">http://127.0.0.1/bruno/redirect</A></EM> (used in Step 2)</SPAN></LI></UL></LI></OL><P><span class="lia-unicode-emoji" title=":paw_prints:">🐾</span> <EM>When you set the redirect path to <FONT face="helvetica"><FONT face="lucida sans unicode,lucida sans">/</FONT><FONT face="mingliu,biaukai"><FONT face="lucida sans unicode,lucida sans">b</FONT>runo/redirect</FONT></FONT>, you’re basically telling Bruno where to wag his tail when he’s done fetching the token. </EM><span class="lia-unicode-emoji" title=":paw_prints:">🐾</span></P><P><SPAN>Under <STRONG>Users for Inbound Communication</STRONG></SPAN></P><P><EM><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Bruno3.1.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/287810iEA937BBABCC3ACA0/image-size/large?v=v2&px=999" role="button" title="Bruno3.1.png" alt="Bruno3.1.png" /></span></EM></P><OL><LI><SPAN> Add a new communication user</SPAN></LI><LI> <SPAN>Set <STRONG>Authentication Method</STRONG> to <EM>OAuth 2.0</EM></SPAN></LI><LI> <SPAN><SPAN>Define <STRONG>OAuth 2.0 Client ID</STRONG>, e.g., <EM>Z_BRUNO</EM></SPAN></SPAN><SPAN><EM>_ID</EM></SPAN></LI><LI>Enable <STRONG>Refresh Allowed</STRONG><SPAN> and set </SPAN><STRONG>Refresh Token Expiry Time</STRONG><SPAN>, e.g., <EM>5 Days</EM></SPAN></LI></OL><P><SPAN>Save your communication system and inbound communication user for your future testing with Bruno acting as OAuth client. This user will be later used for the <STRONG>Authorization Code Grant with PKCE</STRONG>.</SPAN></P><H2 id="toc-hId-922345437"><SPAN>2. Create a Communication Arrangement<BR /></SPAN></H2><P><SPAN>Open the <STRONG>Communication Arrangements</STRONG> app and create a new arrangement based on a communication scenario that supports OAuth 2.0 as an authentication method, e.g., <FONT face="lucida sans unicode,lucida sans">SAP_COM_0053</FONT> (<EM>Purchase Order Integration</EM>).<BR /><BR /></SPAN></P><TABLE border="1" width="100%"><TBODY><TR><TD width="50%" height="30px"><SPAN><STRONG>Scenario</STRONG></SPAN></TD><TD width="50%" height="30px"><SPAN><EM>SAP_COM_0053</EM> (exists only in S/4HANA Cloud)</SPAN></TD></TR><TR><TD width="50%" height="30px"><STRONG>A</STRONG><SPAN><STRONG>rrangement Name</STRONG></SPAN></TD><TD width="50%" height="30px"><SPAN><EM>TEST_COM_0053_WITH_BRUNO</EM></SPAN></TD></TR><TR><TD width="50%" height="30px"><SPAN><STRONG>Communication System</STRONG></SPAN></TD><TD width="50%" height="30px"> <SPAN><EM>Z_BRUNO </EM>(defined earlier)</SPAN></TD></TR></TBODY></TABLE><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Bruno4.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/287805iEAD7C74CB7A46A07/image-size/large?v=v2&px=999" role="button" title="Bruno4.png" alt="Bruno4.png" /></span></P><P><SPAN>Under <STRONG>Inbound Communication</STRONG>:<BR /></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2025-05-26 at 14.01.56.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/289855iFB9C9233A1D50658/image-size/large?v=v2&px=999" role="button" title="Screenshot 2025-05-26 at 14.01.56.png" alt="Screenshot 2025-05-26 at 14.01.56.png" /></span></P><P> </P><OL><LI><SPAN>Enter the <STRONG>OAuth 2.0 Client ID</STRONG> you defined earlier: <EM>Z_BRUNO_ID.</EM></SPAN></LI><LI>Save your communication arrangement.</LI></OL><P><SPAN><STRONG>Note:</STRONG> Only after saving the arrangement, the previously defined OAuth client gets actually created. A clickable label <STRONG>OAuth 2.0 Details</STRONG> will apear.<BR /><BR /></SPAN><SPAN>In <STRONG>OAuth 2.0 Details,</STRONG> you will find all the necessary data for your API client:</SPAN></P><OL><LI><SPAN>Client ID</SPAN></LI><LI><SPAN>Token Service URL</SPAN></LI><LI><SPAN> Authorization URL<BR /></SPAN></LI></OL><P><SPAN>These are needed to fetch a token with Bruno.<BR /></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Jane13_5-1752675913592.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/287345iFE1C16A0468F53DB/image-size/large?v=v2&px=999" role="button" title="Jane13_5-1752675913592.png" alt="Jane13_5-1752675913592.png" /></span></P><P><SPAN>Now you are ready to test your OAuth-secured API using Bruno!</SPAN></P><H1 id="toc-hId-596749213"><SPAN><BR /></SPAN><SPAN>Step 2: Use Bruno to Test the OAuth Communication<BR /></SPAN></H1><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Image was created by the author using an AI illustration tool and is original content." style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/289857i9B523AAF8196F79B/image-size/medium/is-moderation-mode/true?v=v2&px=400" role="button" title="Screenshot 2025-07-22 at 14.52.37.png" alt="Image was created by the author using an AI illustration tool and is original content." /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Image was created by the author using an AI illustration tool and is original content.</span></span></P><P> </P><P> </P><H2 id="toc-hId-529318427"><SPAN>1. Create a New Collection</SPAN></H2><P><span class="lia-unicode-emoji" title=":paw_prints:">🐾</span> <SPAN><EM>Creating a new collection in Bruno is like giving your dog a new toy—name it, set it up, and let the fun begin! </EM> </SPAN><span class="lia-unicode-emoji" title=":paw_prints:">🐾</span></P><OL><LI><SPAN>Open Bruno</SPAN></LI><LI><SPAN>Create a <STRONG>New Collection</STRONG></SPAN></LI><LI><SPAN>Name it, e.g., <EM>My_test_collection</EM></SPAN></LI></OL><H2 id="toc-hId-332804922"><SPAN>2. Set Up OAuth in the Auth Tab</SPAN></H2><OL><LI><SPAN>Go to the <STRONG>Auth</STRONG> tab and choose <STRONG>OAuth 2.0</STRONG></SPAN></LI><LI><SPAN>Set up the configurations:</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2025-05-26 at 14.57.27.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/289856i4355B5383D364050/image-size/large?v=v2&px=999" role="button" title="Screenshot 2025-05-26 at 14.57.27.png" alt="Screenshot 2025-05-26 at 14.57.27.png" /></span><P> </P></LI></OL><TABLE border="1" width="100%"><TBODY><TR><TD width="50%" height="30px"><SPAN><STRONG>Grant Type</STRONG></SPAN></TD><TD width="50%" height="30px"><SPAN>Authorization Code</SPAN></TD></TR><TR><TD width="50%" height="30px"><SPAN><STRONG>Callback URL</STRONG></SPAN></TD><TD width="50%" height="30px"><SPAN><EM><A href="http://127.0.0.1/bruno/redirect" target="_blank" rel="noopener nofollow noreferrer">http://127.0.0.1/bruno/redirect</A></EM></SPAN></TD></TR><TR><TD width="50%" height="30px"><SPAN><STRONG>Authorization URL</STRONG></SPAN></TD><TD width="50%" height="30px"><SPAN>From Communication Arrangement</SPAN></TD></TR><TR><TD width="50%" height="30px"><SPAN><STRONG>Access Token URL</STRONG></SPAN></TD><TD width="50%" height="30px"><SPAN>From Communication Arrangement</SPAN></TD></TR><TR><TD width="50%" height="30px"><SPAN><STRONG>Client ID</STRONG></SPAN></TD><TD width="50%" height="30px"><SPAN>From Communication Arrangement</SPAN></TD></TR><TR><TD width="50%" height="30px"><SPAN><STRONG>State</STRONG></SPAN></TD><TD width="50%" height="30px"><SPAN>dummy</SPAN></TD></TR><TR><TD width="50%" height="30px"><SPAN><STRONG>Use PKCE</STRONG> check box</SPAN></TD><TD width="50%" height="30px"><SPAN><span class="lia-unicode-emoji" title=":white_heavy_check_mark:">✅</span>enabled</SPAN></TD></TR></TBODY></TABLE><P><span class="lia-unicode-emoji" title=":paw_prints:">🐾</span> <EM>Don’t forget to enable PKCE—it’s like putting a leash on your OAuth flow. Keeps things secure and under control. </EM><span class="lia-unicode-emoji" title=":paw_prints:">🐾</span></P><H2 id="toc-hId-136291417"><SPAN>3. Send a Test Request</SPAN></H2><OL><LI><SPAN>Choose <STRONG>Get Access Token </STRONG></SPAN></LI><LI><SPAN>A browser window will open - logon as a <STRONG>Business User</STRONG></SPAN></LI><LI><SPAN>Approve the request by clicking <STRONG>Allow<BR /><BR /></STRONG></SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Jane13_7-1752675913682.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/287349iED8E702C3F077EFF/image-size/large?v=v2&px=999" role="button" title="Jane13_7-1752675913682.png" alt="Jane13_7-1752675913682.png" /></span></LI><LI><SPAN>If successful, you’ll receive an <STRONG>Access Token</STRONG>. <BR /></SPAN><SPAN>The response typically appears in the </SPAN><STRONG>Response</STRONG><SPAN> tab in JSON format like this:</SPAN><SPAN><SPAN><BR /><BR /><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="BrunoToken.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/290378i8446F574B74757AA/image-size/large?v=v2&px=999" role="button" title="BrunoToken.png" alt="BrunoToken.png" /></span></SPAN></SPAN><P> </P></LI><LI><SPAN>Use this token to call your API services:<BR /><BR /><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2025-07-18 at 00.04.06.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/288205i90696A990F59E779/image-size/large?v=v2&px=999" role="button" title="Screenshot 2025-07-18 at 00.04.06.png" alt="Screenshot 2025-07-18 at 00.04.06.png" /></span></SPAN></LI></OL><H1 id="toc-hId--189304807"><STRONG><SPAN><BR /></SPAN></STRONG>Troubleshooting Tips</H1><UL><LI>Make sure you log in with a<SPAN> </SPAN><STRONG>Business User</STRONG><SPAN> </SPAN>assigned to the correct<SPAN> </SPAN><STRONG>Business Roles</STRONG><SPAN> </SPAN>for the API.</LI><LI>If you see the following screen after logging in:</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Jane13_8-1752675913684.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/287348i0A338B29F1531D03/image-size/large?v=v2&px=999" role="button" title="Jane13_8-1752675913684.png" alt="Jane13_8-1752675913684.png" /></span></P><P><SPAN>it likely means the user lacks the required authorizations or the wrong user was used.</SPAN></P><H1 id="toc-hId-383921771"><SPAN>Summary<BR /></SPAN></H1><P><SPAN>With this setup, you can securely test OAuth-protected endpoints in SAP using Bruno or similar tools. This approach is useful for validating integration scenarios and troubleshooting authentication issues.<BR /><BR />Bruno provides a clean and open-source alternative to Postman for testing OAuth-secured APIs in SAP S/4HANA. With just a few configuration steps, you can simulate real-world OAuth flows and validate your communication scenarios with ease.<BR /><BR /><span class="lia-unicode-emoji" title=":paw_prints:">🐾</span> <EM>With Bruno by your side, testing OAuth APIs is less of a chore and more of a walk in the park. Just don’t forget the treats (a.k.a. access tokens)!</EM> <span class="lia-unicode-emoji" title=":paw_prints:">🐾</span></SPAN></P><P> </P><H2 id="toc-hId--105994741"><STRONG>Image Attribution and Licensing<BR /></STRONG></H2><P>All illustrations in this post were created by the author using Microsoft Copilot (AI-based design tool) for educational purposes. The images are original content and free to use under the author’s permission for non-commercial, educational purposes. No external branding or promotional elements are included.</P><P><SPAN><BR /><BR /><BR /></SPAN></P>2025-12-22T11:34:21.364000+01:00https://community.sap.com/t5/technology-blog-posts-by-members/how-to-use-sap-extensibility-wizard-in-sap-s-4hana-clean-core/ba-p/14290385How to Use SAP Extensibility Wizard in SAP S/4HANA Clean Core2025-12-23T07:13:48.565000+01:00ahmedyehia9https://community.sap.com/t5/user/viewprofilepage/user-id/803721<P><!-- StartFragment --></P><P><STRONG>A Comprehensive Guide to Extending SAP S/4HANA with the SAP Extensibility Wizard — Without Compromising Your Clean Core</STRONG></P><P><U><STRONG>Introduction</STRONG></U></P><P>Extensibility is a critical aspect of SAP S/4HANA, enabling organizations to tailor the system to their unique business needs while maintaining stability and upgrade readiness. In this guide, we will explore the <STRONG>SAP Extensibility Wizard</STRONG>, a powerful tool designed to help developers extend SAP S/4HANA in a clean and controlled way.</P><P><STRONG><U>What Is the SAP Extensibility Wizard?</U></STRONG></P><P>The <STRONG>SAP Extensibility Wizard</STRONG> is a guided tool provided by SAP that simplifies the process of creating extensions. It ensures that developers can add custom functionality without modifying the core system, thereby preserving the <EM>clean core</EM> principle. This approach guarantees that upgrades remain smooth and that the system stays resilient over time.</P><P><U><STRONG>Availability: Public Cloud vs. Private Cloud</STRONG></U></P><P>A common question arises: <EM>Is the SAP Extensibility Wizard available only in the Public Cloud, or also in the Private Cloud?</EM></P><UL><LI><STRONG>Public Cloud (SAP S/4HANA Cloud – Public Edition):</STRONG><BR />The wizard is primarily available here. It supports clean-core extensibility and helps organizations build safe, upgrade‑friendly extensions.</LI><LI><STRONG>Private Cloud / On‑Premise:</STRONG><BR />Extensibility is possible through other approaches such as <STRONG>in‑app extensibility</STRONG>, <STRONG>ABAP Cloud</STRONG>, and <STRONG>side‑by‑side extensions on SAP BTP</STRONG>. However, the wizard itself is not provided in the same way as in the Public Cloud.</LI></UL><P><!-- StartFragment --></P><P><STRONG>In summary:</STRONG></P><UL><LI>Public Cloud → Wizard available.</LI><LI>Private Cloud / On‑Premise → Extensibility options exist, but without the wizard.</LI></UL><P><U><STRONG>Focus of This Blog</STRONG></U></P><P>This blog will focus on the <STRONG>SAP Extensibility Wizard for SAP S/4HANA Cloud – Public Edition</STRONG>.</P><P><!-- EndFragment --><!-- StartFragment --></P><P>How to Use the Extensibility Wizard</P><P>With the SAP S/4HANA Cloud Public Edition extensibility wizard, developers can:</P><UL><LI><STRONG>Create on‑stack extensions</STRONG> such as custom fields and custom logic.</LI><LI><STRONG>Build side‑by‑side extensions</STRONG> like custom processes using <STRONG>SAP Build Process Automation</STRONG>.</LI></UL><P>This guided approach ensures that extensions are implemented efficiently, securely, and in alignment with SAP’s clean‑core strategy.</P><P><U><STRONG>Conclusion</STRONG></U></P><P>The <STRONG>SAP Extensibility Wizard</STRONG> is a key enabler for organizations running SAP S/4HANA Cloud Public Edition. By leveraging this tool, businesses can extend their systems with confidence, ensuring that customizations remain upgrade‑safe and future‑proof.</P><P> </P><P><!-- EndFragment --></P><P><!-- EndFragment --></P><P><!-- EndFragment --></P><P><STRONG><SPAN><U>Detailed Steps:</U></SPAN></STRONG></P><P><STRONG><SPAN><U>Use Case :</U></SPAN><SPAN> We will create a sales order approval process .</SPAN></STRONG></P><P class="lia-indent-padding-left-30px" style="padding-left : 30px;"><STRONG><SPAN><U>1. Navigate to SAP S4/HANA Fiori Launchpad.</U></SPAN></STRONG></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><STRONG>1.1 <SPAN><U>Select Business Application Manage Sales Orders. </U></SPAN></STRONG></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_0-1765834104246.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352339i91F62F84C5AB9BDE/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_0-1765834104246.png" alt="ahmedyehia9_0-1765834104246.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.2 <SPAN class="">Navigate to Create Extension</SPAN></STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_1-1765835538668.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352344i459BD0772768EF2C/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_1-1765835538668.png" alt="ahmedyehia9_1-1765835538668.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_2-1765835643824.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352345iBD182EF1112D4E2B/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_2-1765835643824.png" alt="ahmedyehia9_2-1765835643824.png" /></span></P><P> </P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.3 In this case , we will select custom process.</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_3-1765835770046.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352346i9861EC014341E37E/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_3-1765835770046.png" alt="ahmedyehia9_3-1765835770046.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;">The process can start based on various triggers </P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.4 Select Business Event from SAP S4/HANA, that Triggers the process</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_3-1765964349459.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352986i5DF86AB2863FD894/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_3-1765964349459.png" alt="ahmedyehia9_3-1765964349459.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.5 Select Event Object</STRONG></SPAN></P><DIV><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_0-1766054851277.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/353528i8F3DABA18FBD5A90/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_0-1766054851277.png" alt="ahmedyehia9_0-1766054851277.png" /></span></DIV><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.6 Select the SalesOrder create event.</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_6-1765836099992.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352349i6FBE6C976C5237A6/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_6-1765836099992.png" alt="ahmedyehia9_6-1765836099992.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.7 Click Preview to see all the options you selected on previous screens, and make any necessary corrections.</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_7-1765836274304.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352350i7E8D51F75B7D8373/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_7-1765836274304.png" alt="ahmedyehia9_7-1765836274304.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.8 Click Create , to create the process in SAP Build.</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_8-1765836432554.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352351i115237BDD9C3F187/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_8-1765836432554.png" alt="ahmedyehia9_8-1765836432554.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.9 The extension is now available and can also be opened in SAP Build.</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_9-1765836549398.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352352i31CCC05F9800CFB1/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_9-1765836549398.png" alt="ahmedyehia9_9-1765836549398.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.10 When you select Open Extension, the system launches another tab that opens the process.</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_10-1765836669849.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352353i1BB38AA5DD08A534/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_10-1765836669849.png" alt="ahmedyehia9_10-1765836669849.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.11 The Process Automation project overview page is now displayed. Select SalesOrder Approval.</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_11-1765836836220.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352355i47B44A41CDB28FE0/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_11-1765836836220.png" alt="ahmedyehia9_11-1765836836220.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.12 Extension is now openEd in SAP Build , Start design of the process.</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>The Business context is carried over from SAP S4/HANA to SAP Build .</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_0-1765874183680.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352505iF1FDFBE39F95630B/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_0-1765874183680.png" alt="ahmedyehia9_0-1765874183680.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.13 You can add an action, form , or approval . To get further details on the sales order, you need to call an action .</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_1-1765874475245.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352517iCBB3B0B64C54F079/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_1-1765874475245.png" alt="ahmedyehia9_1-1765874475245.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.14 In this use case , we will call sales order read API , to fetch the sales order details.</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_2-1765874611731.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352518i440DB912AD85229E/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_2-1765874611731.png" alt="ahmedyehia9_2-1765874611731.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.15 Browse the library to search for the relevant APIs .</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_3-1765874731152.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352519i5596679844740296/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_3-1765874731152.png" alt="ahmedyehia9_3-1765874731152.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.16 Select read sales order API to get details of the sales order, The business context and system ID were automatically pulled in from SAP S4/HANA .</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_4-1765874972943.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352522i36CE20BEFFDBCE90/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_4-1765874972943.png" alt="ahmedyehia9_4-1765874972943.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.17 The action to read the sales order has now been added . Now users can design the process according to their needs. The user now wants to initiate a workflow that sends an email to the approver for sales order approval .</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_5-1765875108309.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352524iC01561336C140883/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_5-1765875108309.png" alt="ahmedyehia9_5-1765875108309.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.18 The email will include the sales order details , allowing approver to review and approve it . we're utilizing AI to generate the process , Enter the prompt to add an approval step and send the sales order details to the approver via email.</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_6-1765875296166.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352526i795E93D5EFBDF600/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_6-1765875296166.png" alt="ahmedyehia9_6-1765875296166.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><SPAN><STRONG>1.19 AI has now added the process step to read the sales order and email, The sales order details to the approver .</STRONG></SPAN></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ahmedyehia9_0-1765896023701.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/352780iED7CB3058677CB55/image-size/medium?v=v2&px=400" role="button" title="ahmedyehia9_0-1765896023701.png" alt="ahmedyehia9_0-1765896023701.png" /></span></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"> </P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><!-- StartFragment --></P><P><U><STRONG>Conclusion</STRONG></U></P><P>The <STRONG>SAP Extensibility Wizard</STRONG> empowers organizations running SAP S/4HANA Cloud Public Edition to extend their systems safely and efficiently, without compromising the clean core. By leveraging guided tools for custom fields, logic, and side‑by‑side processes, businesses can innovate while staying upgrade‑ready.</P><P>Extensibility in SAP is not just about adding features—it’s about doing so in a way that keeps your system future‑proof. With the wizard, you can confidently build the extensions your business needs today, while ensuring smooth upgrades tomorrow.</P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><!-- EndFragment --></P><P class="lia-indent-padding-left-60px" style="padding-left : 60px;"><!-- StartFragment --></P><P><!-- EndFragment --></P><P> </P>2025-12-23T07:13:48.565000+01:00https://community.sap.com/t5/integration-blog-posts/how-to-create-a-servicenow-incident-via-rest-api-using-abap-oauth-2-0/ba-p/14297267How to Create a ServiceNow Incident via REST API Using ABAP (OAuth 2.0)2025-12-29T08:34:25.619000+01:00shasankgupta024https://community.sap.com/t5/user/viewprofilepage/user-id/877731<P><STRONG>Prerequisites</STRONG></P><UL><LI>ServiceNow instance access with API credentials (Client ID, Client Secret)</LI><LI>SAP NetWeaver with HTTP Client (CL_HTTP_CLIENT) and JSON support (/UI2/CL_JSON)</LI></UL><P><STRONG>Step 1: Obtain OAuth2 Token from ServiceNow</STRONG></P><P>First, you need to POST your client credentials to ServiceNow’s /oauth_token endpoint to get a bearer token. This token authorizes subsequent API calls.</P><P class="lia-indent-padding-left-30px" style="padding-left : 30px;"><STRONG>ABAP Code:</STRONG></P><pre class="lia-code-sample language-abap"><code>FORM get_servicenow_token USING iv_token_url TYPE string
iv_client_id TYPE string
iv_client_secret TYPE string
CHANGING cv_token TYPE ty_token
cv_errmsg TYPE string.
DATA: lv_payload TYPE string,
lo_http_client TYPE REF TO if_http_client,
lv_response TYPE string,
lt_token TYPE STANDARD TABLE OF ty_token,
lo_json TYPE REF TO /ui2/cl_json.
CLEAR: cv_errmsg, cv_token.
lv_payload = |grant_type=client_credentials&client_id={ iv_client_id }&client_secret={ iv_client_secret }|.
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = iv_token_url
IMPORTING
client = lo_http_client
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0 OR lo_http_client IS INITIAL.
cv_errmsg = 'Failed to create HTTP client for token.'.
EXIT.
ENDIF.
lo_http_client->request->set_method( 'POST' ).
lo_http_client->request->set_header_field( name = 'Content-Type' value = 'application/x-www-form-urlencoded' ).
lo_http_client->request->set_cdata( lv_payload ).
TRY.
lo_http_client->send( ).
lo_http_client->receive( ).
lv_response = lo_http_client->response->get_cdata( ).
lo_http_client->close( ).
CONCATENATE '[' lv_response ']' INTO lv_response.
CREATE OBJECT lo_json.
lo_json->deserialize( EXPORTING json = lv_response CHANGING data = lt_token ).
IF lt_token IS NOT INITIAL.
READ TABLE lt_token INDEX 1 INTO cv_token.
ELSE.
cv_errmsg = 'Could not parse token from JSON.'.
ENDIF.
CATCH cx_root INTO DATA(lx_err).
cv_errmsg = lx_err->get_text( ).
ENDTRY.
ENDFORM.</code></pre><P>If successful, the access_token can now be used as a Bearer token.</P><P><STRONG>Step 2: Build the JSON Payload</STRONG></P><P>Create a JSON structure that describes the incident.</P><P class="lia-indent-padding-left-30px" style="padding-left : 30px;"><STRONG>ABAP Code:</STRONG></P><pre class="lia-code-sample language-abap"><code>lv_json_body =
'{' &&
'"caller_id":"ABC Corp",' &&
'"service_offering":"SAP Material",' &&
'"category":"Data",' &&
'"subcategory":"Incorrect Data",' &&
'"short_description":"Test Incident from SAP",' &&
'"description":"Test Incident from SAP",' &&
'"impact":"2",' &&
'"urgency":"2"' &&
'}'.</code></pre><P><STRONG>Step 3: Create the Incident via POST API</STRONG></P><P>Now, make a POST request to the ServiceNow incident table, including your access token for authorization.</P><P><STRONG>ABAP Code:</STRONG></P><pre class="lia-code-sample language-abap"><code>FORM create_servicenow_incident
USING iv_post_url TYPE string
iv_access_token TYPE string
iv_body TYPE string
CHANGING cv_result TYPE string
cv_errmsg TYPE string.
DATA: lo_http_client TYPE REF TO if_http_client.
CLEAR: cv_errmsg, cv_result.
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = iv_post_url
IMPORTING
client = lo_http_client.
lo_http_client->request->set_method( 'POST' ).
lo_http_client->request->set_header_field( name = 'Content-Type' value = 'application/json' ).
lo_http_client->request->set_header_field( name = 'Accept' value = 'application/json' ).
lo_http_client->request->set_header_field( name = 'Authorization' value = |Bearer { iv_access_token }| ).
lo_http_client->request->set_cdata( iv_body ).
TRY.
lo_http_client->send( ).
lo_http_client->receive( ).
cv_result = lo_http_client->response->get_cdata( ).
lo_http_client->close( ).
CATCH cx_root INTO DATA(lx_err).
cv_errmsg = lx_err->get_text( ).
ENDTRY.
ENDFORM.</code></pre><P>If successful, cv_result will contain the incident response from ServiceNow.</P><P><STRONG>Step 4: Combine the Steps in Your Report</STRONG></P><P>Your main program calls these subroutines in sequence.</P><P class="lia-indent-padding-left-30px" style="padding-left : 30px;"><STRONG>Example Main Logic:</STRONG></P><pre class="lia-code-sample language-abap"><code>* Get the access token
PERFORM get_servicenow_token
USING lv_token_url
lv_client_id
lv_client_secret
CHANGING ls_token
lv_err.
IF lv_err IS NOT INITIAL OR ls_token-access_token IS INITIAL.
WRITE: / 'Token Error:', lv_err.
EXIT.
ENDIF.
* Create the incident
PERFORM create_servicenow_incident
USING lv_post_url
ls_token-access_token
lv_json_body
CHANGING lv_result
lv_err.
IF lv_err IS INITIAL.
WRITE: / 'Incident Response:', lv_result.
ELSE.
WRITE: / 'Incident Creation Error:', lv_err.
ENDIF.</code></pre><P><STRONG>Final Notes</STRONG></P><UL><LI><STRONG>Security:</STRONG> Never hardcode sensitive data in productive programs—use secure storage.</LI><LI><STRONG>Error Handling:</STRONG> Always add robust error handling and log failures for troubleshooting.</LI><LI><STRONG>Data Mapping:</STRONG> Adjust JSON fields based on ServiceNow table and your organization’s requirements.</LI></UL><P><STRONG>Conclusion</STRONG></P><P>Integrating SAP and ServiceNow allows you to automatically manage ITSM incidents directly from SAP ABAP. The above example demonstrates OAuth token retrieval and incident creation using ABAP. Adapt and build on this foundation to suit your business requirements.</P><P><STRONG>Happy Integrating! </STRONG>Let me know in the comments if you have any questions or need clarification on any step.</P><P> </P><P><STRONG>Complete ABAP CODE:</STRONG></P><pre class="lia-code-sample language-abap"><code>*&---------------------------------------------------------------------*
*& Report ZSNOW
*---------------------------------------------------------------------*
* Utility: ServiceNow Incident API Integration
*---------------------------------------------------------------------*
REPORT zsnow.
TYPES: BEGIN OF ty_token,
access_token TYPE string,
scope TYPE string,
token_type TYPE string,
expires_in TYPE i,
END OF ty_token.
DATA: lv_token_url TYPE string VALUE 'https://://<your-comapny-domain>.service-now.com/oauth_token',
lv_client_id TYPE string VALUE '...your-client-id...',
lv_client_secret TYPE string VALUE '...your-client-secret...',
lv_post_url TYPE string VALUE 'https://://<your-comapny-domain>.service-now.com/api/now/table/incident',
lv_json_body TYPE string,
ls_token TYPE ty_token,
lv_err TYPE string,
lv_result TYPE string.
* Prepare JSON Body
lv_json_body = '{' &&
'"caller_id":"ABC Corp",' &&
'"service_offering":"SAP Material",' &&
'"category":"Data",' &&
'"subcategory":"Incorrect Data",' &&
'"short_description":"Test Incident from SAP",' &&
'"description":"Test Incident from SAP",' &&
'"impact":"2",' &&
'"urgency":"2"' &&
'}'.
* Step 1: Get the Token
PERFORM get_servicenow_token USING lv_token_url
lv_client_id
lv_client_secret
CHANGING ls_token
lv_err.
IF lv_err IS NOT INITIAL OR ls_token-access_token IS INITIAL.
WRITE: / 'Token Error:', lv_err.
EXIT.
ENDIF.
* Step 2: Create Incident
PERFORM create_servicenow_incident USING lv_post_url
ls_token-access_token
lv_json_body
CHANGING lv_result
lv_err.
IF lv_err IS INITIAL.
WRITE: / 'Incident Response:', lv_result.
ELSE.
WRITE: / 'Incident Creation Error:', lv_err.
ENDIF.
*--------------------------------------------------------*
* Get OAuth Token from ServiceNow
*--------------------------------------------------------*
FORM get_servicenow_token
USING iv_token_url TYPE string
iv_client_id TYPE string
iv_client_secret TYPE string
CHANGING cv_token TYPE ty_token
cv_errmsg TYPE string.
DATA: lv_payload TYPE string,
lo_http_client TYPE REF TO if_http_client,
lv_response TYPE string,
lt_token TYPE STANDARD TABLE OF ty_token,
lo_json TYPE REF TO /ui2/cl_json.
CLEAR: cv_errmsg, cv_token.
lv_payload = |grant_type=client_credentials&client_id={ iv_client_id }&client_secret={ iv_client_secret }|.
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = iv_token_url
IMPORTING
client = lo_http_client
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0 OR lo_http_client IS INITIAL.
cv_errmsg = 'Failed to create HTTP client for token.'.
EXIT.
ENDIF.
lo_http_client->request->set_method( 'POST' ).
lo_http_client->request->set_header_field( name = 'Content-Type' value = 'application/x-www-form-urlencoded' ).
lo_http_client->request->set_cdata( lv_payload ).
TRY.
lo_http_client->send( ).
lo_http_client->receive( ).
lv_response = lo_http_client->response->get_cdata( ).
lo_http_client->close( ).
CONCATENATE '[' lv_response ']' INTO lv_response.
CREATE OBJECT lo_json.
lo_json->deserialize( EXPORTING json = lv_response CHANGING data = lt_token ).
IF lt_token IS NOT INITIAL.
READ TABLE lt_token INDEX 1 INTO cv_token.
ELSE.
cv_errmsg = 'Could not parse token from JSON.'.
ENDIF.
CATCH cx_root INTO DATA(lx_err).
cv_errmsg = lx_err->get_text( ).
ENDTRY.
ENDFORM. " get_servicenow_token
*--------------------------------------------------------*
* Create an Incident in ServiceNow
*--------------------------------------------------------*
FORM create_servicenow_incident
USING iv_post_url TYPE string
iv_access_token TYPE string
iv_body TYPE string
CHANGING cv_result TYPE string
cv_errmsg TYPE string.
DATA: lo_http_client TYPE REF TO if_http_client.
CLEAR: cv_errmsg, cv_result.
CALL METHOD cl_http_client=>create_by_url
EXPORTING
url = iv_post_url
IMPORTING
client = lo_http_client.
lo_http_client->request->set_method( 'POST' ).
lo_http_client->request->set_header_field( name = 'Content-Type' value = 'application/json' ).
lo_http_client->request->set_header_field( name = 'Accept' value = 'application/json' ).
lo_http_client->request->set_header_field( name = 'Authorization' value = |Bearer { iv_access_token }| ).
lo_http_client->request->set_cdata( iv_body ).
TRY.
lo_http_client->send( ).
lo_http_client->receive( ).
cv_result = lo_http_client->response->get_cdata( ).
lo_http_client->close( ).
CATCH cx_root INTO DATA(lx_err).
cv_errmsg = lx_err->get_text( ).
ENDTRY.
ENDFORM. " create_servicenow_incident</code></pre><P> </P>2025-12-29T08:34:25.619000+01:00https://community.sap.com/t5/technology-blog-posts-by-members/building-an-email-based-sap-sales-order-automation-with-n8n-amp-ai-function/ba-p/14312716Building an Email-Based SAP Sales Order Automation with n8n & AI Function Calling2026-01-27T08:02:05.123000+01:00aliulashayirhttps://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&px=999" role="button" title="aliulashayir_4-1769196684258.png" alt="aliulashayir_4-1769196684258.png" /></span></P><P> </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&px=999" role="button" title="aliulashayir_1-1769196530510.png" alt="aliulashayir_1-1769196530510.png" /></span></P><P> </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=""> </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&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&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