https://raw.githubusercontent.com/ajmaradiaga/feeds/main/scmt/topics/NW-ABAP-Gateway-(OData)-blog-posts.xml SAP Community - NW ABAP Gateway (OData) 2024-05-20T11:11:10.248765+00:00 python-feedgen NW ABAP Gateway (OData) blog posts in SAP Community https://community.sap.com/t5/technology-blogs-by-members/problems-with-zero-dates/ba-p/13568637 Problems with zero dates 2023-04-13T12:27:08+02:00 Sschlegel https://community.sap.com/t5/user/viewprofilepage/user-id/37925 <STRONG>Introduction:</STRONG><BR /> <BR /> There is a very common problem, that while doing a post request or any kind of update containing empty dates are not allowed by default via SEGW based OData-Services.<BR /> <BR /> How to enable this is described here: <A href="https://blogs.sap.com/2020/02/03/datetime-field-in-odata-entity-points-to-take-care-when-the-ui-is-throwing-run-time-error./" target="_blank" rel="noopener noreferrer">DateTime field in OData entity – Points to take care when the UI is throwing run-time error. | SAP Blogs</A><BR /> <BR /> <STRONG>Problem:</STRONG><BR /> <BR /> But maybe you struggle here anyway, even when using the workaround as described before - but why? Take a look here at the column DEL_DATE:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/Screenshot-2023-04-03-200443.png" height="300" width="848" /></P><BR /> It looks fine in the ADT Data-Preview, even if 0000-00-00 is not a very nice date.<BR /> <BR /> But testing the OData-Service based on this CDS View returns an error "the Value ____ is no valid Date according to XML-formats for ABAP":<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/Screenshot-2023-04-03-200646.png" height="330" width="764" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Error in /IWFND/ERROR_LOG</P><BR /> <STRONG>Rescue from the past - thank you SE16:</STRONG><BR /> <BR /> The solution can be found via our old tooling like the good, old SE16 - here we see the true value of DEL_DATE:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/Screenshot-2023-04-03-200858.png" /></P><BR /> The field does not contain any value - its empty, space or even null, but not 0000-00-00 as shown in ADT! And "space" or "empty string" can't be interpreted as a date! How to fix it? Simply extend your CDS with an easy CASE-Statement, that sets a value OData can handle - like the one mistakenly shown in ADT:<BR /> <PRE class="language-abap"><CODE>define view entity ZABC<BR /> as select from toa01<BR /> {<BR /> key sap_object as SapObject,<BR /> @UI.hidden: true<BR /> key object_id as ObjectId,<BR /> @EndUserText.label: 'Content Repository'<BR /> key archiv_id as ArchivId,<BR /> key arc_doc_id as ArcDocId,<BR /> <BR /> case del_date<BR /> when '' then '00000000'<BR /> else del_date end as DelDate<BR /> }<BR /> </CODE></PRE><BR /> This should normally not be necessary and is clearly due to a program error, but still: some kind of solution.<BR /> <BR /> Enjoy!<BR /> <BR /> &nbsp; 2023-04-13T12:27:08+02:00 https://community.sap.com/t5/technology-blogs-by-members/rap-eml-dynamic-operations-dynamic-eml-requests/ba-p/13549261 RAP EML Dynamic Operations: Dynamic EML Requests 2023-06-05T11:46:19+02:00 juliandanho https://community.sap.com/t5/user/viewprofilepage/user-id/144313 <STRONG>Introduction</STRONG><BR /> <BR /> In the world of ABAP development, the RAP framework has revolutionized the way we build robust and flexible applications. One of the key features of RAP is the ability to dynamically generate EML (Entity Manipulation Language) requests. In this blog post, we will explore the dynamic form of MODIFY ENTITIES OPERATIONS, which allows us to perform operations on multiple business objects within a single statement.<BR /> <BR /> &nbsp;<BR /> <BLOCKQUOTE><STRONG>Understanding MODIFY ENTITIES OPERATIONS</STRONG><BR /> <BR /> The MODIFY ENTITIES OPERATIONS statement in RAP enables us to manipulate entities by performing various operations such as CREATE, UPDATE, DELETE, or EXECUTE (Actions). What makes the dynamic form of this statement particularly powerful is its ability to handle operations on multiple business objects simultaneously. Operations expects an internal table of the type ABP_BEHV_CHANGES.</BLOCKQUOTE><BR /> &nbsp;<BR /> <BR /> <EM>The ABAP Documentation you can find here</EM>: <A href="https://help.sap.com/doc/abapdocu_754_index_htm/7.54/en-US/index.htm?file=abeneml_modify_entities_op.htm" target="_blank" rel="noopener noreferrer">https://help.sap.com/doc/abapdocu_754_index_htm/7.54/en-US/index.htm?file=abeneml_modify_entities_op.htm</A><BR /> <BR /> Here you will find my example in the business partner context (based on the CDS root view entity I_BusinessPartnerTP_3).<BR /> <PRE class="language-abap"><CODE>DATA:<BR /> _BP_ROOT TYPE TABLE FOR CREATE I_BusinessPartnerTP_3,<BR /> _BP_ADDRESS TYPE TABLE FOR CREATE I_BusinessPartnerTP_3\_BusinessPartnerAddress,<BR /> _BP_IDENTIFICATION TYPE TABLE FOR CREATE I_BUSINESSPARTNERTP_3\_BusinessPartnerIdentification,<BR /> _BP_ADDRESS_USAGE TYPE TABLE FOR CREATE I_BusinessPartnerAddressTP_3\_BusinessPartnerAddressUsage.<BR /> <BR /> MODIFY ENTITIES OPERATIONS<BR /> VALUE ABP_BEHV_CHANGES_TAB(<BR /> ( VALUE ABP_BEHV_CHANGES(<BR /> OP = IF_ABAP_BEHV=&gt;OP-M-CREATE<BR /> ENTITY_NAME = 'I_BUSINESSPARTNERTP_3'<BR /> INSTANCES = REF #( _BP_ROOT )<BR /> ) )<BR /> ( VALUE ABP_BEHV_CHANGES(<BR /> OP = IF_ABAP_BEHV=&gt;OP-M-CREATE_BA<BR /> ENTITY_NAME = 'I_BUSINESSPARTNERTP_3'<BR /> SUB_NAME = '_BUSINESSPARTNERADDRESS'<BR /> INSTANCES = REF #( _BP_ADDRESS )<BR /> ) )<BR /> ( VALUE ABP_BEHV_CHANGES(<BR /> OP = IF_ABAP_BEHV=&gt;OP-M-CREATE_BA<BR /> ENTITY_NAME = 'I_BUSINESSPARTNERTP_3'<BR /> SUB_NAME = '_BUSINESSPARTNERIDENTIFICATION'<BR /> INSTANCES = REF #( _BP_IDENTIFICATION )<BR /> ) )<BR /> ( VALUE abp_behv_changes(<BR /> op = if_abap_behv=&gt;op-m-create_ba<BR /> entity_name = 'I_BUSINESSPARTNERADDRESSTP_3'<BR /> sub_name = '_BUSINESSPARTNERADDRESSUSAGE'<BR /> instances = REF #( _bp_address_usage )<BR /> ) )<BR /> )<BR /> <BR /> MAPPED DATA(_MAPPED)<BR /> REPORTED DATA(_REPORTED)<BR /> FAILED DATA(_FAILED).</CODE></PRE><BR /> The Structure of Operations<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/ABP_BEHV_CHANGES-1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">Operation Structure</P><BR /> <EM><STRONG>Important</STRONG></EM>: The name/value of <STRONG>ENTITY_NAME and SUB_NAME</STRONG> should be in upper case. Otherwise you will get an unknown shortdump. This seems to be a bug in the standard SAP operation. Normally the upper case conversion could be done in the standard functionality.<BR /> <BR /> But how should the instances (here e.g. _bp_root, _bp_address) be filled?<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/06/Instances-1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">Instances</P><BR /> The <STRONG>%cid</STRONG> attribute is the <STRONG>content ID</STRONG> which are used as <STRONG>unique and temporary ID for RAP BO</STRONG> Operations. In this case, we assign the <STRONG>%cid "bp_root"</STRONG> to the root object, which must be assigned as <STRONG>%cid_ref</STRONG> for the underlying object address.<BR /> <BR /> The attribute %data is self-speaking for the transfer of the data to be created.<BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG>"Usual" equivalent</STRONG><BR /> <BR /> This would be the "usual" equivalent of the dynamic EML call:<BR /> <PRE class="language-abap"><CODE>MODIFY ENTITIES OF I_BusinessPartnerTP_3<BR /> ENTITY BusinessPartner<BR /> CREATE<BR /> SET FIELDS WITH _BP_ROOT<BR /> CREATE BY \_BusinessPartnerAddress<BR /> SET FIELDS WITH _bp_address<BR /> CREATE BY \_BusinessPartnerIdentification<BR /> SET FIELDS WITH _bp_identification<BR /> ENTITY BusPartAddress<BR /> CREATE BY \_BusinessPartnerAddressUsage<BR /> SET FIELDS WITH _bp_address_usage<BR /> MAPPED DATA(_mapped)<BR /> FAILED DATA(_failed)<BR /> REPORTED DATA(_reported).</CODE></PRE><BR /> &nbsp;<BR /> <BR /> <STRONG>Dynamic Flexibility</STRONG><BR /> <BR /> One of the significant advantages of using the dynamic form of MODIFY ENTITIES OPERATIONS is the flexibility it offers. By allowing operations on multiple business objects within a single statement, developers can streamline their code and enhance efficiency. It eliminates the need for repetitive operations and simplifies the overall development process. It offers the possibility to create a generic EML concept in case of dynamic requests regarding the operation (CRUD) or the entity or associations.<BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG>Conclusion</STRONG><BR /> <BR /> In this blog post, we delved into the dynamic form of MODIFY ENTITIES OPERATIONS. Leveraging the power of RAP's dynamic EML requests opens up new possibilities for building advanced applications in ABAP development. By harnessing this flexibility, developers can achieve greater productivity and maintainability in their projects. So, go ahead and explore the dynamic world of RAP EML Dynamic Operations and take your ABAP development to the next level!<BR /> <BR /> &nbsp; 2023-06-05T11:46:19+02:00 https://community.sap.com/t5/technology-blogs-by-members/overcoming-technical-and-system-constraints-exposing-an-abap-calculated/ba-p/13552508 Overcoming Technical and System Constraints: Exposing an ABAP Calculated Field with OData 2023-07-06T13:18:30+02:00 yavuzasik https://community.sap.com/t5/user/viewprofilepage/user-id/10289 Firstly, the requirement of this post was originated from quite a basic problem; however it later became really complicated due to the following constraints which we were restricted to.<BR /> <UL><BR /> <LI>technical constraints of ABAP CDS object</LI><BR /> <LI>SAP system constraints in terms of the technology stack and version</LI><BR /> </UL><BR /> Let me first talk about the actual requirement and then I will write down all the possible solutions I tried out and why I ended up with the current one. Our initial requirement was to expose an SAP field with OData and consume it from a Fiori application. This field was the well-known WBS element field, which is a concatenation of a couple of other fields separated by a '-' symbol. Of course, I was supposed to split this field into different strings and extract the components of the original field. It might sound like a problem with a quite straightforward solution. However once I started researching to find out the possibilities, it was quite frustrating.<BR /> <BR /> Of course, I started with the CDS built-in functions. I have checked them and find out a couple of useful functions including "instr", "substring", "left" etc. However, none of them has completely resolved our problem without certain assumptions (making an assumption on the number of characters for each part of the string for instance). Therefore, unfortunately there is no built-in function, which we could utilize to split up a string into multiple strings at a certain character, '-' in our case.<BR /> <BR /> Second option I came up with was to use some of the powerful tools in ABAP stack, for instance, CDS table function or AMDB, that I can plug our custom ABAP code. That way, I could enhance/enrich our CDS object with some custom ABAP coding, which contains the ABAP command SPLIT ... AT ... INTO ...<BR /> <PRE class="language-abap"><CODE>@AccessControl.authorizationCheck: #NOT_REQUIRED<BR /> @EndUserText.label: 'Demo Table Function Parse'<BR /> @ClientDependent: false<BR /> define table function Z_DEMO_TF_PARSE_WBS<BR /> returns { <BR /> wbs_element : string40 ,<BR /> component1 : string10 ,<BR /> component2 : string10 , <BR /> component3 : string10 , <BR /> }<BR /> implemented by method<BR /> Z_Cl_AMDP_PARSE_STRING=&gt;SPLIT; </CODE></PRE><BR /> That way I planned to implement the parsing of the WBS string with custom Z_Cl_AMDP_PARSE_STRING class. Unfortunately, that also did not work out because our system had a SAP_ABA 750-0010 component version, which this feature is not yet supported.<BR /> <BR /> The final option I could think of was to manually add an extra implementation into the OData runtime artifacts, which was generated by adding the CDS as a reference object to the SEGW service.<BR /> <BR /> I did that extra implementation inside the data provider extension class. In order to implement the parsing of WBS field, I should have first created dummy fields in my CDS object, which was only possible with the CAST command. Hence, I extended my CDS view with the three field from the result of parsing.<BR /> <PRE class="language-abap"><CODE>@AbapCatalog.compiler.compareFilter: true<BR /> @AccessControl.authorizationCheck: #NOT_REQUIRED<BR /> @AbapCatalog.preserveKey: true<BR /> @EndUserText.label: 'Demo CDS Parse'<BR /> @VDM.viewType: #BASIC<BR /> <BR /> define view Z_DEMO_CDS_PARSE_WBS as select from prps<BR /> {<BR /> key wbs_element ,<BR /> cast(' ' as abap.char(3) ) as component1 , <BR /> cast(' ' as abap.char(10) ) as component2 , <BR /> cast(' ' as abap.char(8) ) as component3 <BR /> }</CODE></PRE><BR /> Afterwards I started to overwrite some of the methods of the DPC_EXT class, which were necessary for my requirement. For instance I implemented the custom logic to split the WBS by overwriting the GET_ENTITYSET method of the respective CDS entity. This method already has a reference to the super method inherited from DPC class. Because the SEGW service was built on top of the reference to the data source which points to the CDS view. I preserved it and finally added my extra code to split the WBS element and hence the returned entity set is updated.<BR /> <PRE class="language-abap"><CODE> METHOD Z_DEMO_CDS_PARSE_WBS_GET_ENTITY_SET.<BR /> TRY.<BR /> CALL METHOD super-&gt;Z_DEMO_CDS_PARSE_WBS_GET_ENTITY_SET<BR /> EXPORTING<BR /> iv_entity_name = iv_entity_name<BR /> iv_entity_set_name = iv_entity_set_name<BR /> iv_source_name = iv_source_name<BR /> it_filter_select_options = it_filter_select_options<BR /> is_paging = is_paging<BR /> it_key_tab = it_key_tab<BR /> it_navigation_path = it_navigation_path<BR /> it_order = it_order<BR /> iv_filter_string = iv_filter_string<BR /> iv_search_string = iv_search_string<BR /> io_tech_request_context = io_tech_request_context<BR /> IMPORTING<BR /> et_entityset = et_entityset<BR /> es_response_context = es_response_context.<BR /> CATCH /iwbep/cx_mgw_busi_exception .<BR /> CATCH /iwbep/cx_mgw_tech_exception .<BR /> ENDTRY.<BR /> <BR /> LOOP AT et_entityset REFERENCE INTO DATA(lr_entityset).<BR /> SPLIT lr_entityset-&gt;wbs_element AT '-' INTO lr_entityset-&gt;component1<BR /> lr_entityset-&gt;component2<BR /> lr_entityset-&gt;component3.<BR /> <BR /> ENDLOOP.<BR /> <BR /> ENDMETHOD.</CODE></PRE><BR /> I want to emphasize a few points what I have learned from the solution of this issue.<BR /> <UL><BR /> <LI>Whenever CDS toolset is not adequate for my requirement , I can still use CDS to expose data by referencing it as data source and then exploit the DPC_EXT class to implement own coding. This makes it a hybrid solution whereas on one hand, I can take advantage of CDS features (performance, annotations etc.) and on the other hand, I can still make manual interventions to the entity set that I expose through OData by overwriting the related DPC_EXT class methods.</LI><BR /> <LI>Second thing is that CAST operator is the only option to create dummy fields since CDS is not a database object but actually a view on real database objects. This could be its side role in addition to its actual role, which is casting some data types into some other types.</LI><BR /> </UL><BR /> &nbsp; 2023-07-06T13:18:30+02:00 https://community.sap.com/t5/technology-blogs-by-sap/performance-testing-of-independent-odata-using-hdb/ba-p/13402975 Performance testing of Independent OData using HDB 2023-07-21T05:50:10+02:00 DilipMami https://community.sap.com/t5/user/viewprofilepage/user-id/1295 Hello ,<BR /> <BR /> This blog will walk you through the concept of<BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG>Performance Improvement: $batch Parallelization</STRONG><BR /> <BR /> The performance optimizations for $batch processing described here are only available for a hub system NW release 7.0x or 7.3x SP08 or NW release 7.4x SP06 and backend system NW release 7.0x or 7.3x SP08 or NW release 7.4x SP06.<BR /> <BR /> In older support package stacks, the SAP NetWeaver Gateway framework issues one separate Remote Function Call (RFC) for each retrieve operation or each change set.<BR /> <BR /> In the newer support package stacks described above only one RFC is used to send all operations contained in a batch request to the backend system (batch at once). Due to the till now implementation of the etag handling in the REST/OData library and gateway framework, all modifying operations using etag in a batch request are delivered separately to the backend system. Based on the configuration settings in the backend system (via IMG, transaction SPRO see below), all consecutive retrieve operations are parallelized to improve the processing performance. The parallelization is active per default.<BR /> <BR /> The processing performance increases with more number of consecutive retrieve operations in a $batch request.<BR /> <BR /> The following performance trace summary shows the performance statistics and also illustrates how a $batch request is processed in the backend system.<BR /> <BR /> The $batch example contains<BR /> <UL><BR /> <LI>3 consecutive retrieve operations</LI><BR /> <LI>1 changeset with create, update and execute action</LI><BR /> <LI>2 consecutive retrieve operations</LI><BR /> <LI>1 changeset with delete</LI><BR /> <LI>1 single retrieve operation</LI><BR /> </UL><BR /> &nbsp;<BR /> <BR /> From within a backend system you can use the SAP project reference object (transaction SPRO) to activate or deactivate the parallelization as follows:<BR /> <BR /> <EM>SPRO -&gt; SAP Reference IMG -&gt; SAP NetWeaver -&gt; Gateway Service Enablement -&gt; Backend OData Channel -&gt; Configuration Settings -&gt; Define Parallelization of Batch Queries</EM>.<BR /> <BR /> <STRONG>Changesets in Multiple Origin Composition</STRONG><BR /> <BR /> Changeset is a collection of one or more modifying operations having the feature "all or nothing" when processing (same meaning as Logical-Unit-of-Work in an ABAP system).<BR /> <BR /> Multiple Origin Composition (MOC) is the ability to collect data from different backend systems, aggregate them in one single service and updating different backend systems while using the same user. Thus a service can be made available for several system aliases.<BR /> <BR /> In the context of multiple origin composition, not only retrieve operations such as read entity, read entityset but now also changesets are supported. All operations of a changeset must be defined for one and the same system alias (SAP__Origin=&lt;xx...x&gt;). They are collected and sent to the backend defined by the system alias and via one RFC. You can find an example in SAP Note 1890049.<BR /> <BR /> A changeset containing operations for different system aliases will be terminated with error text "<EM>Changeset containing different system aliases not supported</EM>".<BR /> <BR /> SAP Fiori Apps are based on&nbsp;OData&nbsp;Services, One SAP Fiori application shall have one dedicated&nbsp;OData&nbsp;Service.<BR /> <BR /> We continuously thrive to optimize Fiori applications/. functionality to run within sub-second timeframe which generates huge value addition to our customers when using SAP software to run their critical business scenarios<BR /> <BR /> Developers who wish to develop new&nbsp;OData&nbsp;can easily run performance tests on their local Env to validate prior to pushing it into new/existing development or publishing it to SAP&nbsp;API&nbsp;Hub. During the test/delivery phase this solution/framework will have flexibility to configure the tests and then ODATA services are fired according to the user scenarios.<BR /> <P style="margin: 7.5pt 0cm 0cm 0cm"><SPAN lang="EN-US" style="font-size: 10.5pt;font-family: 'Arial',sans-serif;color: black">To independently measure the Performance of an&nbsp;<SPAN class="sapedia-acronym">OData</SPAN>&nbsp;for S4HANA to build faster optimized applications</SPAN> : this solution approach through an application facilitates to automatically identify and performance test OData independently during a release. It can further be leveraged to be used only by Developers who are interested to test only API class use cases. The results of performance metrics are validated against the defined thresholds</P><BR /> &nbsp;<BR /> <BR /> The parameters used in sap-statistics=true ( response headers of the HTTP request)<BR /> <UL><BR /> <LI>SAP&nbsp;NWGateway (OData&nbsp;request processing)</LI><BR /> <LI>GW Total = gwtotal</LI><BR /> <LI>GW&nbsp;DB= gwappdb</LI><BR /> <LI>App time = gwapp</LI><BR /> </UL><BR /> Other metrics<BR /> <UL><BR /> <LI>E2E Client time = Client specific time</LI><BR /> <LI>Content length</LI><BR /> </UL><BR /> Status: Calculated after the excel is generated<BR /> <BR /> Sample values:<BR /> <BR /> "totalTime":"44","count":1,"elapsedTime":249,"icmTotal":"58","wdTotal":"63","gwapp":"10","gwappdb":"","contentLength":"556"<BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG>Solution (iTOP 1.0)</STRONG><BR /> <BR /> iTOP : independently test OData Performance<BR /> <BR /> As users constantly need to validate the performance of an&nbsp;OData&nbsp;prior to deployment/during development our implementation addresses this requirement. The solution works together seamlessly and offers a consistent end-to-end experience.<BR /> <BR /> OData&nbsp;calls&nbsp;are executed for these iterations = Main runs&nbsp;<STRONG>(10)&nbsp;</STRONG>+ Buffered runs (3)<BR /> <BR /> To test an&nbsp;OData&nbsp;call which leads to Performance identification, developers can start with this solution which helps them in identifying or pointing towards&nbsp;RCA<BR /> <UL><BR /> <LI>The proposed model captures&nbsp;ODataServices automatically under test</LI><BR /> <LI>Users have a provision to add new&nbsp;OData/modify any existing</LI><BR /> <LI>The resulting performance metrics are validated against the thresholds and rendered back to UI and downloaded as an Excel</LI><BR /> </UL><BR /> Identify and Report OData behaviour across releases<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/07/itop.jpg" /></P> 2023-07-21T05:50:10+02:00 https://community.sap.com/t5/technology-blogs-by-members/fiori-po-approver-app-forward-button-customization-from-ecc-backend/ba-p/13580901 Fiori PO Approver app Forward button customization from ECC backend 2023-08-25T22:43:06+02:00 jayesh_mudaliar https://community.sap.com/t5/user/viewprofilepage/user-id/230182 <P>Hello Fellow Developers,<BR /><BR />Let me directly dive into the requirement, We are currently hosting Fiori on top of ECC backend. The requirement came while enabling the PO approval using My Inbox.<BR /><BR />The first part of customization comes on the Forward Button. As per the approval matrix the approvers were maintained in the PPOME structure. The problem occurred when the approver was forwarding the PO to another approver. However, on clicking the Forward button it was displaying all the list of Users from SU01. This was creating a lot of confusion for the approvers. So the initial requirement came as to fix the list that was appearing on clicking the Forward Button.<BR /><BR />I will be displaying the 2 possible approach for Forward Button customization from the Backend.<BR /><BR /><STRONG>Approach 1 – Creating the custom class and attaching it in Service Implementation.</STRONG><BR /><BR /><STRONG>Approach 2 – Implement the BADI to change the values fetched from the Standard. </STRONG><BR /><BR />Let’s start with the first approach.<BR /><BR />The standard ODATA for PO approval is GBAPP_POAPPROVAL.<BR /><BR />Step 1 . Open your Gateway system -&gt; Execute /IWBEP/REG_SERVICE and maintain the service details</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture1-37.png" border="0" width="591" height="210" /></P><P><BR />Step 2 Maintain the Class name in DPC.</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture2-23.png" border="0" width="474" height="487" /></P><P><BR /><STRONG>Note : Creating of the class would be in the Backend System</STRONG><BR /><BR /><STRONG>Step 3 Open Backend System and Create the class maintained in Gateway system.</STRONG><BR /><BR />You can copy/maintain the redefinition of the methods as per your need. Super class should be maintained as the /IWBEP/CL_MGW_PUSH_ABS_DATA. This will redirect the data flow of standard Odata call into the Custom Implementation.</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture3-16.png" border="0" /></P><P><BR />I have copied all the methods from the standard class into my custom class to avoid any discrepancies. My requirement is also very small that’s why I didn’t wanted to touch other functionality so copying worked for me.</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture4-18.png" border="0" /></P><P><BR />Just for showing from where the whole list of users were displaying. Please follow through as this is kind of RCA.<BR /><BR />If you drill down into the GET_ENTITYSET. You may find this<BR />WHEN&nbsp;cl_gbapp_apv_po_mdp=&gt;cty_entities-agent.</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture5-16.png" border="0" /></P><P><BR />This gets triggered for the event of Forwarding the work item to another approver. However, if you go into GET_AGENT_LIST method. You may find<BR /><BR />CALL&nbsp;METHOD&nbsp;lo_cmn-&gt;get_users_for_forwarding.<BR /><BR />This method is responsible for displaying all the lists of user from SU01 which is kind of misleading in our case.</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture6-14.png" border="0" /></P><P><BR />&nbsp;<BR /><BR /><STRONG>Step 4 Modify the Approver List</STRONG><BR /><BR />So to suffice this requirement you can write your own logic and bypass the GET_AGENT_LIST method at the following place and the new list will be forwarded to the UI again as the output.<BR /><BR />Create the list of approvers which you want to show and pass the list in lt_forward_users.</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture7-15.png" border="0" /></P><P><BR />This is a long way approach where a lot of customization can be done as per your requirements.<BR /><BR />&nbsp;<BR /><BR /><STRONG>Approach 2 – BADI Extensibility Approach</STRONG><BR /><BR /><STRONG>Normally for any custom enhancements we can directly enhance the ODATA however for the case of PO Approver app SAP has provided an option for BADI Extensibility for PO Approve application.</STRONG><BR /><BR /><STRONG>Step 1 </STRONG><BR /><BR /><STRONG>Go to SE18 in the backed system.</STRONG></P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture8-16.png" border="0" /></P><P><BR /><STRONG>Step 2 Create Implementation under Definition GBAPP_APV_PO_RDP</STRONG><BR /><BR />&nbsp;<BR /><BR />If you are not familiar with creating implementations follow through / skip to next step.<BR /><BR />Right click on implementation -&gt; Create Badi Implementation -&gt; Specify the Enhancement Implementation &amp; Short Text.</P><P><STRONG><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture9-14.png" border="0" /></STRONG></P><P>&nbsp;</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture10-13.png" border="0" /></P><P><BR />Once you specify the Enhancement Implementation system will ask for BADI Implementation.<BR /><BR />Maintain them.</P><P><STRONG><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture11-14.png" border="0" /></STRONG></P><P>&nbsp;</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture12-13.png" border="0" /></P><P><BR />&nbsp;<BR /><BR /><STRONG><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture13-11.png" border="0" /></STRONG><BR /><BR /><STRONG>Note : You can reuse the same enhancement implementation for other requirements as well related to PO approve applications extensibility . No need to create every time.</STRONG><BR /><BR /><STRONG>&nbsp;</STRONG><BR /><BR /><STRONG>Step 3 – Implementation of Class </STRONG><BR /><BR />In the Implementing class you may find all the lists of methods present.</P><P><STRONG><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture14-11.png" border="0" /><BR /></STRONG></P><P><BR />The first method IF_GBAPP_EX_APV_PO_RDP~CHANGE_AGENT_LIST_API is the one which is used to modify the list of Approvers. Modify this method as per you requirement.<BR /><BR />Incase of my requirement the approvers were maintained in PPOME under the Organizational structure. The data is maintained in HRP1001 table. I have deleted the approvers which are not maintained in PPOME here .<BR /><BR />It is easier to go for 1st approach however I chose this because there are furthermore modification as part of different requirement in various methods present here. So I thought to consolidate all my changes at once for ease of understanding.</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Picture15-12.png" border="0" /></P><P><BR />METHOD&nbsp;IF_GBAPP_EX_APV_PO_RDP~CHANGE_AGENT_LIST_API.<BR />*&nbsp;Intended&nbsp;use:<BR />*&nbsp;Customer&nbsp;uses&nbsp;the&nbsp;BAdI&nbsp;Enhancement&nbsp;Framework&nbsp;for&nbsp;own&nbsp;content&nbsp;/&nbsp;logik<BR /><BR />*&nbsp;Here&nbsp;you&nbsp;can&nbsp;change/enhance&nbsp;the&nbsp;data,&nbsp;which&nbsp;is&nbsp;retrieved&nbsp;for&nbsp;the&nbsp;GET&nbsp;call&nbsp;for<BR />*&nbsp;the&nbsp;results&nbsp;list&nbsp;of&nbsp;the&nbsp;Search&nbsp;for&nbsp;Forwarding&nbsp;Agents.<BR /><BR />*&nbsp;Note:<BR />*&nbsp;If&nbsp;you&nbsp;want&nbsp;to&nbsp;have&nbsp;a&nbsp;employee&nbsp;image&nbsp;to&nbsp;be&nbsp;displayed&nbsp;on&nbsp;the&nbsp;UI&nbsp;list<BR />*&nbsp;of&nbsp;Forwarding&nbsp;Agents&nbsp;you&nbsp;need&nbsp;to&nbsp;do&nbsp;the&nbsp;following&nbsp;steps.<BR />*&nbsp;-&nbsp;In&nbsp;this&nbsp;method:<BR />*&nbsp;&nbsp;&nbsp;Fill&nbsp;the&nbsp;field&nbsp;MIME_TYPE&nbsp;with&nbsp;the&nbsp;MIMETYPE&nbsp;of&nbsp;the&nbsp;image.<BR />*&nbsp;&nbsp;&nbsp;This&nbsp;will&nbsp;trigger&nbsp;the&nbsp;execution&nbsp;of&nbsp;method&nbsp;'get_image_binary_file'<BR />*&nbsp;&nbsp;&nbsp;for&nbsp;retrieval&nbsp;of&nbsp;the&nbsp;binary&nbsp;data&nbsp;for&nbsp;the&nbsp;image.<BR />*&nbsp;-&nbsp;In&nbsp;method&nbsp;'get_user_image_binary_file':<BR />*&nbsp;&nbsp;&nbsp;Implement&nbsp;the&nbsp;retrieval&nbsp;of&nbsp;binary&nbsp;image&nbsp;data.<BR />*&nbsp;&nbsp;BREAK-POINT.<BR />TYPES&nbsp;:&nbsp;BEGIN&nbsp;OF&nbsp;gty_usr,<BR />SOBID&nbsp;TYPE&nbsp;HRP1001-SOBID,<BR />END&nbsp;OF&nbsp;gty_usr.<BR /><BR />data&nbsp;:&nbsp;lwa_user&nbsp;TYPE&nbsp;GBAPPS_APV_USER_FORWARDING,<BR />lwa_ppome&nbsp;TYPE&nbsp;hrp1001,<BR />lt_ppome&nbsp;TYPE&nbsp;STANDARD&nbsp;TABLE&nbsp;OF&nbsp;hrp1001,<BR />lt_usr&nbsp;TYPE&nbsp;STANDARD&nbsp;TABLE&nbsp;OF&nbsp;gty_usr,<BR />lwa_usr&nbsp;TYPE&nbsp;gty_usr.<BR /><BR />LOOP&nbsp;AT&nbsp;ct_user&nbsp;INTO&nbsp;lwa_user.<BR />lwa_usr-SOBID&nbsp;=&nbsp;lwa_user-USER_ID.<BR />APPEND&nbsp;lwa_usr&nbsp;to&nbsp;lt_usr.<BR />CLEAR&nbsp;lwa_usr.<BR />ENDLOOP.<BR /><BR />select&nbsp;*&nbsp;from&nbsp;hrp1001&nbsp;into&nbsp;TABLE&nbsp;lt_ppome&nbsp;FOR&nbsp;ALL&nbsp;ENTRIES&nbsp;IN&nbsp;lt_usr<BR />where&nbsp;SOBID&nbsp;=&nbsp;lt_usr-SOBID.<BR /><BR />sort&nbsp;lt_ppome&nbsp;by&nbsp;SOBID.<BR /><BR />LOOP&nbsp;AT&nbsp;ct_user&nbsp;INTO&nbsp;lwa_user.<BR />READ&nbsp;TABLE&nbsp;lt_ppome&nbsp;INTO&nbsp;lwa_ppome&nbsp;with&nbsp;key&nbsp;SOBID&nbsp;=&nbsp;lwa_user-USER_ID&nbsp;BINARY&nbsp;SEARCH.<BR />IF&nbsp;sy-subrc&nbsp;ne&nbsp;'0'.<BR />delete&nbsp;ct_user&nbsp;where&nbsp;USER_ID&nbsp;=&nbsp;lwa_user-USER_ID.<BR />*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;ct_user&nbsp;from&nbsp;lwa_user.<BR />ENDIF.<BR />ENDLOOP.<BR /><BR />ENDMETHOD. <STRONG>&nbsp;</STRONG></P><P>This is a Series of Blogs. Please find the below post for further details.<BR /><BR /><STRONG>&nbsp;<A title="Fiori PO Approver app Accept and Reject button customization from ECC backend" href="https://community.sap.com/t5/technology-blogs-by-members/fiori-po-approver-app-accept-and-reject-button-customization-from-ecc/ba-p/13690701" target="_self">Part 2 : Accept &amp; Reject Button Customization</A></STRONG></P> 2023-08-25T22:43:06+02:00 https://community.sap.com/t5/technology-blogs-by-members/amount-field-decimal-places-display-issue-in-fiori-elements-list-report/ba-p/13575812 Amount field decimal places display issue in Fiori Elements list report 2023-09-06T15:49:32+02:00 asimchandra https://community.sap.com/t5/user/viewprofilepage/user-id/869413 <STRONG>Background:</STRONG><BR /> <BR /> SAP generally stores all the amount values with two decimal places in tables like VBRP, VBAP and so on. This is because most of the currencies have 2 decimal places by default. But there are a lot of currencies that have decimal places no equal to two. Mostly for large currency markets, the default number of decimal places for the currency is not 2.<BR /> <BR /> For example, for VND (Vietnamese Dong), the default number of decimal places is 0 and this is stored in the table TCURX.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/Picture1-4.png" /></P><BR /> For example, a billing invoice (with currency VND) has net value with 0 decimal places, but it is stored with 2 decimal places in SAP Table VBRP because SAP shifts the decimal place in tables so as to not change the data type of the amount and maintain a standard throughout SAP.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/Picture11-3.png" /></P><BR /> This invoice has no decimal places for VND but below shows how it is stored in SAP table.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/Picture3-2.png" /></P><BR /> Moreover, when we display this amount in a Fiori elements list report through a CDS view or normally it displays with 3 decimal places by default.<BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG>Issue: Display the amount according to the correct decimal places as maintained in TCURX table in the list report</STRONG><STRONG>&nbsp;</STRONG><BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG>Solution:</STRONG><BR /> <OL><BR /> <LI style="text-align: left">Create an extra entity in your OData service (CDS data source). The data source exposed should be I_CURRENCY, an SAP standard CDS View.</LI><BR /> </OL><BR /> <P style="text-align: left">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; This CDS view has the number of decimal places for currencies maintained in TCURX table.</P><BR /> <P style="overflow: hidden;margin-bottom: 0px">&nbsp; &nbsp; &nbsp; &nbsp; <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/Picture4.png" /></P><BR /> <BR /> <OL start="2"><BR /> <LI>Add the same CDS view I_Currency in your main data source CDS view as an association. <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/Picture5-1.png" /></LI><BR /> <LI>Add a foreign key annotation for the above association to the currency field in the main CDS View.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/Picture9-1.png" /></LI><BR /> <LI>Do not forget the add the annotation &nbsp;@Semantics.amount.currencyCode: 'waerk' to your amount field.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/Picture6-4.png" /></LI><BR /> </OL><BR /> &nbsp;<BR /> <OL start="5"><BR /> <LI>Last step would be to add the below annotation to your annotation file in your Business Application Studio List report project.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/Picture10-1.png" /></LI><BR /> </OL><BR /> <DIV><BR /> <DIV>&lt;Annotation Term="com.sap.vocabularies.CodeList.v1.CurrencyCodes"&gt;</DIV><BR /> <DIV>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;Record&gt;</DIV><BR /> <DIV>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;PropertyValue Property="Url" String="./$metadata"/&gt;</DIV><BR /> <DIV>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;PropertyValue Property="CollectionPath" String="I_CurrencyType"/&gt;</DIV><BR /> <DIV>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/Record&gt;</DIV><BR /> <DIV>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/Annotation&gt;</DIV><BR /> <DIV>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;Annotations Target="ZOTD_VIETNAM_CUSTOMS_REP_SRV.I_CurrencyType/Currency"&gt;</DIV><BR /> <DIV>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;Annotation Term="Common.UnitSpecificScale" Path="Decimals"/&gt;</DIV><BR /> <DIV>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;Annotation Term="Common.Text" Path="Currency_Text"/&gt;</DIV><BR /> <DIV>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/Annotations&gt;</DIV><BR /> </DIV><BR /> <STRONG>The list report will now show the appropriate number of decimal places in the Amount field along with the&nbsp;</STRONG><B>Currency.</B><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/Picture8-1.png" /></P><BR /> <B>For example, it shows 0 decimal places for VND now.</B> 2023-09-06T15:49:32+02:00 https://community.sap.com/t5/technology-blogs-by-sap/sap-earlywatch-alert-dashboard-new-statistics-about-quot-used-sapui5/ba-p/13576919 SAP EarlyWatch Alert Dashboard - New statistics about "Used SAPUI5 Applications" 2023-09-11T08:59:40+02:00 michael_albrecht https://community.sap.com/t5/user/viewprofilepage/user-id/192401 <P>New content has been released for the User Experience section of the <A href="https://me.sap.com/ewasop/soopDetail" target="_blank" rel="noopener noreferrer">EarlyWatch Alert (EWA) Dashboard!</A><BR /><BR />Several weeks ago we&nbsp;already&nbsp;extended the chart "Usable SAPUI5 Applications" with an additional default view about the number of used applications. You still have the option to switch to the legacy statistics regarding the number of configured apps by selecting 'Number of Activated Apps in the last 5 weeks' from the dropdown menu:</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/Used-SAPUI5-Apps-chart-1.gif" border="0" width="328" height="346" /></P><P><BR />Alongside these enhancements, the chart now includes an additional button, providing you access to our new detail page where you can gain valuable insights into the UI5 Fiori apps in use.<BR /><BR />The new page follows the familiar structure found in the 'OData Service Requests' or 'Transactions' detail pages:</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/Detail-Page.gif" border="0" /></P><P><BR />The statistics for the selected apps in the table are represented as a line on the right side of the page. For each app, you can display the number of OData requests, the average OData request time, and the number of distinct users. You can easily switch between these three measured values in the line item chart using the dropdown field.<BR /><BR />You can utilize the filters in the page header to narrow down the list of displayed apps. It's important to note that the current 'SAP Standard Business Role' filter includes standard business roles through which SAP standard apps are distributed, rather than customer-specific roles. We are in the process of replacing this filter with a more appropriate custom role filter.<BR /><BR />The 'Application Name' and 'Fiori ID' columns are equipped with clickable links. Clicking on the 'Fiori ID' will direct you to its corresponding entry in the <A href="https://fioriappslibrary.hana.ondemand.com/sap/fix/externalViewer/" target="_blank" rel="noopener nofollow noreferrer">Fiori Apps Reference Library</A>. On the other hand, clicking on the application name will open a pop-up window containing supplementary details such as its Application Component, ICF Service, and SAP Standard Business Role.<BR /><BR />Clicking the 'OData Service Details' link will open the 'OData Service Requests' detail page, where you will find specific details related to the selected app.</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/App-Details-Pop-Up.gif" border="0" width="329" height="152" /></P><P>&nbsp;<BR /><BR /><FONT color="#FF0000"><SPAN><STRONG>IMPORTANT </STRONG>for SAP on-Premise and SAP S/4HANA private cloud systems<STRONG>:</STRONG></SPAN></FONT></P><UL><UL><LI>The accuracy of the statistics displayed on the page improves as your ST-PI and ST-A/PI versions increase.</LI></UL></UL><UL><UL><LI><STRONG>We strongly recommend applying the latest version of SAP Note <A href="https://me.sap.com/notes/2603238/E" target="_blank" rel="noopener noreferrer">2603238.</A><BR /><BR /></STRONG></LI><LI>If the metric for the <STRONG>number of distinct users</STRONG> is missing, then check in the chapter "Service Preparation Check (RTCCTOOL)" of the latest <A href="https://me.sap.com/ewa/report" target="_blank" rel="noopener noreferrer">SAP EarlyWatch Alert Report</A>&nbsp;if the usage of Online Data Collectors is allowed. Setting the permission for this type of collector is explained in SAP note <A href="https://me.sap.com/notes/69455/E" target="_blank" rel="noopener noreferrer">69455</A>&nbsp;.</LI></UL></UL><P><BR /><BR /><FONT color="#FF0000"><SPAN><STRONG>IMPORTANT </STRONG>for all system types including SAP S/4HANA Public Cloud<STRONG>:</STRONG></SPAN></FONT></P><UL><UL><LI>As some applications utilize the same OData service and ICF service, it may not always be possible to identify app usage with complete precision. To address this, we have introduced aliases for such apps. For example, several non-identifiable Smart Business (KPI) apps have been designated as 'Smart Business Runtime App'. Please refer to SAP KBA&nbsp;<A href="https://me.sap.com/notes/3441199" target="_blank" rel="noopener noreferrer">3441199</A>.</LI></UL></UL><P>&nbsp;</P> 2023-09-11T08:59:40+02:00 https://community.sap.com/t5/technology-blogs-by-sap/how-to-modify-filters-in-gateway-dpc-ext-class-before-get-entity-set/ba-p/13581317 How to modify filters in GATEWAY DPC EXT class before GET ENTITY_SET 2023-09-26T23:35:57+02:00 ray_lv https://community.sap.com/t5/user/viewprofilepage/user-id/186833 In some cases we need to modify the filter options in DPC EXT class before it&nbsp;<SPAN class="sapedia-incword" data-template="sapediaItexecute">execute</SPAN>&nbsp;<SPAN class="sapedia-acronym sapedia-acronym-text-color" role="mark" data-template="sapediaAdGET">GET</SPAN>&nbsp;ENTITY_SET method,<BR /> <BR /> so how to modify the filter options and make them work? follow the following steps:<BR /> <BR /> ( you could find sample code in class method /US4G/CL_METERREAD_DAT_DPC_EXT =&gt; XUS4GXC_METERR02_GET_ENTITYSET and /US4G/CL_METERREAD_DAT_DPC_EXT =&gt; XUS4GXC_MALO_MEL_GET_ENTITYSET )<BR /> <BR /> 1)&nbsp; &nbsp;cast the object&nbsp;<STRONG>io_tech_request_context</STRONG>&nbsp;to type of&nbsp;<STRONG>/iwbep/cl_mgw_request</STRONG>:<BR /> <PRE class="language-abap"><CODE>DATA(lo_tech_request_context) = CAST /iwbep/cl_mgw_request( io_tech_request_context ).</CODE></PRE><BR /> <PRE data-bidi-marker="true"><CODE class="language-abap"></CODE></PRE><BR /> 2)&nbsp; get the structure of request details by calling&nbsp;&nbsp;<STRONG>lo_tech_request_context<SPAN class="s1">-&gt;</SPAN>get_request_details</STRONG><SPAN class="s2"><STRONG>( )</STRONG>&nbsp;into a local structure&nbsp;</SPAN>ls_request_details:<BR /> <PRE class="language-abap"><CODE>DATA(ls_request_details) = lo_tech_request_context-&gt;get_request_details( ).<BR /> </CODE></PRE><BR /> &nbsp;<BR /> <BR /> 3)&nbsp; &nbsp;writhe your own logic to construct filter options, and fill them into structure ls_request_details<SPAN class="s1">-</SPAN>technical_request<SPAN class="s1">-</SPAN>filter_select_options,<BR /> <BR /> important: clear the structure ls_request_details<SPAN class="s1">-</SPAN>technical_request<SPAN class="s1">-</SPAN>filter_expressions ls_request_details<SPAN class="s1">-</SPAN>technical_request<SPAN class="s1">-</SPAN>filter_functions if your are query root entity;<BR /> <BR /> clear the structure ls_request_details<SPAN class="s1">-</SPAN>technical_request<SPAN class="s1">-</SPAN>navigation_path if your are query a navigation entity set to avoid query root entity again.<BR /> <BR /> them must be cleared otherwise the modified filters won't work.<BR /> <PRE class="language-abap"><CODE>*** modify the structure ls_request_details-technical_request-filter_select_options *** <BR /> CLEAR cs_request_details-technical_request-navigation_path. <BR /> CLEAR: cs_request_details-technical_request-filter_expressions, cs_request_details-technical_request-filter_functions.</CODE></PRE><BR /> &nbsp;<BR /> <BR /> 4)&nbsp; create an new&nbsp;lo_model object by calling method&nbsp;/iwbep/cl_mgw_med_provider<SPAN class="s1">=&gt;</SPAN>get_med_provider<SPAN class="s2">( )-&gt;</SPAN>get_service_metadata, passing the service name and version:<BR /> <PRE class="language-abap"><CODE>DATA(lo_med_provider) = /iwbep/cl_mgw_med_provider=&gt;get_med_provider( ). <BR /> DATA(lo_model) = lo_med_provider-&gt;get_service_metadata( <BR /> EXPORTING iv_internal_service_name = '****SRV' <BR /> iv_internal_service_version = '0001' ).</CODE></PRE><BR /> &nbsp;<BR /> <BR /> 5)&nbsp; create an new lo_new_tech_request_context by using constructor of class /iwbep/cl_mgw_request, and passing the ls_request_details and lo_model:<BR /> <PRE class="language-abap"><CODE>ro_tech_request = NEW /iwbep/cl_mgw_request( <BR /> ir_request_details = REF #( is_request_details ) <BR /> it_headers = VALUE #( ) <BR /> io_model = CAST #( lo_model ) ).</CODE></PRE><BR /> &nbsp;<BR /> <BR /> 6) finally pass the new object lo_new_tech_request_context to super class's&nbsp;<SPAN class="sapedia-acronym sapedia-acronym-text-color" role="mark" data-template="sapediaAdGET">GET</SPAN>&nbsp;ENTITY_SET method:<BR /> <PRE class="language-abap"><CODE>TRY.<BR /> CALL METHOD super-&gt;xus4gxc_malo_mel_get_entityset<BR /> EXPORTING<BR /> iv_entity_name = iv_entity_name<BR /> iv_entity_set_name = iv_entity_set_name<BR /> iv_source_name = iv_source_name<BR /> it_filter_select_options = it_filter_select_options<BR /> is_paging = is_paging<BR /> it_key_tab = it_key_tab<BR /> it_navigation_path = it_navigation_path<BR /> it_order = it_order<BR /> iv_filter_string = iv_filter_string<BR /> iv_search_string = iv_search_string<BR /> io_tech_request_context = lo_new_tech_request_context<BR /> IMPORTING<BR /> et_entityset = et_entityset<BR /> es_response_context = es_response_context.<BR /> CATCH /iwbep/cx_mgw_busi_exception.<BR /> CATCH /iwbep/cx_mgw_tech_exception.<BR /> ENDTRY.</CODE></PRE> 2023-09-26T23:35:57+02:00 https://community.sap.com/t5/technology-blogs-by-members/sap-api-odata-security-part-i-terminologies/ba-p/13577651 SAP API OData Security Part I - Terminologies 2023-10-04T23:39:49+02:00 ravi_paul https://community.sap.com/t5/user/viewprofilepage/user-id/216731 <H4 id="toc-hId-1222212765">This blog series will explain how to secure your outbound OData services (created in SAP ABAP system) with the Basic and OAuth 2.0 authentication mechanism.</H4><BR /> &nbsp;<BR /> <H3 id="toc-hId-896616541">Assumptions:</H3><BR /> <OL><BR /> <LI>You have an overview understanding on Fiori OData Service</LI><BR /> <LI>You have a basic idea to create roles and how to add IWSG &amp; IWSV services. If not please follow <A href="https://help.sap.com/docs/FIORI_IMPLEMENTATION_740/79e3aabeb90d45299fbad56d5e7911a5/d23bf6aec23d47e4a0d054bfec9a980b.html" target="_blank" rel="noopener noreferrer">this</A> document</LI><BR /> <LI>How to create user in SU01 and assign roles. Follow <A href="https://blogs.sap.com/2023/06/16/su01-how-to-create-a-new-user-in-sap/" target="_blank" rel="noopener noreferrer">this</A> blog</LI><BR /> </OL><BR /> <H3 id="toc-hId-700103036"></H3><BR /> &nbsp;<BR /> <H3 id="toc-hId-503589531">Part I is about general terminology used in OData/API authorization.</H3><BR /> <H3 id="toc-hId-307076026"><A href="https://blogs.sap.com/2023/10/10/sap-api-odata-security-part-ii-api-basic-authentication/" target="_blank" rel="noopener noreferrer">Part II</A> gives you details on basic authentication and the flavor of OAuth mechanism.</H3><BR /> <H3 id="toc-hId-110562521"><A href="https://blogs.sap.com/2023/10/11/sap-api-odata-security-part-iii-oauth2.0-authorization-code-flow/" target="_blank" rel="noopener noreferrer">Part III</A> will guide you to the OAuth2.0 Authorization Code Flow setup.</H3><BR /> &nbsp;<BR /> <BR /> In today’s rapidly changing world, the need for sustainability and security has grown exponentially. Companies need to create an ecosystem where their codes or developments are interchangeable across the application, or you can say the code should be so robust that it should be as easy as plug and play. Well, SAP ABAP ECC, S/4 systems are not far behind such development by using its component SAP Gateway Foundation SAP_GWFND with OData protocol.<BR /> <H4 id="toc-hId-43131735"><U>What is OData</U> →</H4><BR /> The Open Data Protocol (OData) is an open protocol, which allows the creation and consumption of query-able and interoperable RESTful APIs in a simple and standardized way. Retrieval and modification of data is done with URL based service calls. They can be easily built and used.<BR /> <H4 id="toc-hId--153381770"><U>What is API</U> →</H4><BR /> API stands for application programming interface, which is a set of definitions and protocols for building and integrating application software. APIs let your product or service communicate with other products and services without having to know how they’re implemented.<BR /> <BLOCKQUOTE><BR /> <H3 id="toc-hId--478977994">Question1: How is API different from SAP web services which are available under SICF from ages.</H3><BR /> <EM>A web service is a software component that can be accessed and facilitates data transfers via a web address. Because a web service exposes an application’s data and functionality to other applications, in effect, every web service is an API. However, not every API is a web service.</EM><BR /> <BR /> <EM>APIs are any software component that serves as an intermediary between two disconnected applications. While web services also connect applications, they require a network to do so. Where some APIs are open source, web services are typically private and only approved partners may access them.</EM></BLOCKQUOTE><BR /> Though there are different types of API’s available, but we would talk about REST API. Reason being OData model is built on RESTful API.<BR /> <H4 id="toc-hId--546408780"><U>What is REST</U> →</H4><BR /> REST (REpresentational State Transfer) is a software architectural style that defines how to send messages between two different systems using the HTTP protocol. REST defines a set of functions like GET, POST, PUT, DELETE, etc. that clients can use to access server data using HTTP.<BR /> <BR /> OData builds on top of the REST framework to define best practices for building REST APIs<BR /> <BR /> Well, we spoke some terminology and definitions (received from various sources) but don’t limit yourself to explore more on such. I’m trying to make this blog series as much crisp I can.<BR /> <H4 id="toc-hId--1240639380"><U>How to create REST API in SAP</U> →</H4><BR /> It is same as creating OData services under SEGW transaction. With my experience an ABAP or Fiori Developer will help you create one. Although its not a rocket science, being a naïve, you can create a basic SAP API on your own. You can follow other blogs available over web however I found <A href="https://blogs.sap.com/2021/05/06/a-step-by-step-process-to-create-odata-services-in-sap-sap-hana-system/" target="_blank" rel="noopener noreferrer">this </A>as easiest.<BR /> <BR /> Now, lets go bit technical and focus on our agenda to secure OData Service<BR /> <H4 id="toc-hId--1437152885"><U>How to secure OData Service / SAP REST API</U> →</H4><BR /> When we call about security SAP always believe to secure its user logins in two ways – One with Authentication and other with Authorization. At this stage, I’m believing you understand the difference between two.<BR /> <H3 id="toc-hId--1340263383">Let us see how authorization &amp; authentication is setup in SAP for OData Services in <A href="https://blogs.sap.com/2023/10/10/sap-api-odata-security-part-ii-api-basic-authentication/" target="_blank" rel="noopener noreferrer">next</A> series with a use case.</H3> 2023-10-04T23:39:49+02:00 https://community.sap.com/t5/technology-blogs-by-members/sap-api-odata-security-part-ii-api-basic-authentication/ba-p/13577623 SAP API OData Security Part II - API Basic Authentication 2023-10-10T22:43:54+02:00 ravi_paul https://community.sap.com/t5/user/viewprofilepage/user-id/216731 <H4 id="toc-hId-1222212674">Welcome to the second part of our SAP API Security journey. If you want to learn more about terminology, I recommend you read <A href="https://blogs.sap.com/2023/10/04/sap-api-odata-security-part-i-terminologies/" target="_blank" rel="noopener noreferrer">Part I</A>.</H4><BR /> &nbsp;<BR /> <BR /> Today, we take it a step further. In this installment, we will accelerate into the practical applications with a Use Case.<BR /> <BLOCKQUOTE><BR /> <H3 id="toc-hId-896616450"><SPAN style="text-decoration: underline">Use Case</SPAN>: ASDF, a pharmaceutical company, wants its customer to create records in its custom table ZOVBAK using an external tool or application via API. The development should meet these minimum criteria:</H3><BR /> &nbsp;<BR /> <OL><BR /> <LI><BR /> <H3 id="toc-hId-700102945">Since ASDF has various customers around the world, the development should be robust enough to create records in the ZOVBAK table using one or more applications.</H3><BR /> </LI><BR /> <LI><BR /> <H3 id="toc-hId-503589440">For the ASDF company, the ZOVBAK table is critical, so only authorized and authenticated users are allowed to create records.</H3><BR /> </LI><BR /> </OL><BR /> </BLOCKQUOTE><BR /> Created OData service and add service under <STRONG>/iwfnd/maint_service</STRONG> transaction. For this exercise we created <STRONG>ZTEST_API_TEST_SRV</STRONG> service. The purpose of this service is to update a custom table record <STRONG>ZOVBAK</STRONG> in local SAP system<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/1-70.png" /><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 1: Activate and Maintain OData Service</P><BR /> <U>Authorization</U> → As we know, we grant permissions to users of SAP in the form of roles. At this stage, we only need to create two roles:<BR /> <OL><BR /> <LI>Authorization to modify the table <STRONG>ZOVBAK </STRONG>Table</LI><BR /> </OL><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/2-44.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 2: SAP PFCG Role to maintain ZOVBAK Table</P><BR /> <BR /> <OL start="2"><BR /> <LI>Authorization to access the OData service ZTEST_API_TEST_SRV</LI><BR /> </OL><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/3-36.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 3: SAP PFCG Role to access OData service</P><BR /> So we have created minimum authorization to provide to a user in order to perform action in table <STRONG>ZOVBAK</STRONG>.<BR /> <BR /> <U>Authentication</U> → API supports various Authentication, and each have its own pros &amp; cons however I would be covering <STRONG>Basic Authentication</STRONG> mechanism and <STRONG>OAuth 2.0</STRONG> mechanism in this series.<BR /> <BR /> <STRONG>Basic authentication</STRONG> is an HTTP-based authentication approach and is the simplest way to secure REST APIs. It uses a Base64 format to encode usernames and passwords, both of which are stored in the HTTP header. This is an effective approach to set up various API access credentials when the priority is for an application to remain lightweight and simple.<BR /> <BR /> Before I explain OAuth2.0 mechanism, lets deep dive under Basic Authentication –<BR /> <BR /> Let’s look at the use case again: Criterion #1 is met by using Basic Authentication, where the developed API is robust enough to connect to any end application that supports REST. Let us assume <STRONG>Mr. John Doe</STRONG>, ASDF's non-technical customer, is given a front-end application (for this exercise, let us assume it's Microsoft SharePoint). He is expected to enter the required details into <STRONG>MS SharePoint</STRONG> so that records are created in the ZOVBAK table.<BR /> <BR /> For such a configuration, the SharePoint developer asks for generic SAP user credentials that will be used to perform the action in SAP on behalf of the user or, say, Mr. John.<BR /> <BLOCKQUOTE><BR /> <H3 id="toc-hId-307075935">Question 2: Why is a generic user used and why not Mr. John his SAP account?</H3><BR /> &nbsp;<BR /> <BR /> Basic authentication requires you to pass application’s usernames and passwords (see Basic Authentication Definition) in header with Base64 encoding.<BR /> <BR /> If Mr. John’s SAP account is used, the SharePoint application must store Mr. John’s SAP credentials to encrypt and send in the header. The same is true for all other business users who will use the SharePoint application to update SAP table. Remember that each business user must enter their SAP credentials into a form and that the SharePoint application stores them, encrypts them, and then sends them to the API in the HTTP header. It is very riskier that the SharePoint admin can get hold of the users' SAP credentials of users and misuse it.</BLOCKQUOTE><BR /> Created ‘APPUSER01’ generic system user (GUI login not possible) with the access we created to run OData service successfully.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/4-39.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 4: Basic-Authentication Generic user SAP profile</P><BR /> In the SharePoint application, let us look at the configuration for calling and sending information from SharePoint to SAP. (You can also use Postman to make calls to SAP API).<BR /> <BR /> Now, the logical or configuration part of SharePoint is done in the <STRONG>Microsoft</STRONG> <STRONG>Power Automate</STRONG> tool. Just don’t get carried away by the name, since you are in SAP and don’t have to worry about configuring the front application. However, the most important part is the HTTP connection. In the given use case, we will perform <STRONG>GET</STRONG> &amp; <STRONG>POST</STRONG> operation.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/5-35.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 5: Microsoft Power Automate workflow Configuration</P><BR /> <STRONG>GET</STRONG> operation is to view information from given API. <STRONG>POST</STRONG> operation is used when you want to create a new data to API application.<BR /> <BR /> There is additional validation stein in POST operation along with Basic Authentication to pass <STRONG>x-csrf-token </STRONG>value in header and this token expires after certain duration. Easiest way to retrieve <STRONG>x-csrf-token </STRONG>is from GET operation and the retrieved value needs to pass in POST operation.<BR /> <BR /> Mr. John is equipped with a SharePoint front-end application. He has entered the following data:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/6-30.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 6: Microsoft SharePoint Form to maintain ZOVBAK Table</P><BR /> Field Label <STRONG>Vbeln</STRONG> is key attribute in OData service and same in SharePoint we have set it as mandatory field. As soon user Save the information the Power Automate workflow will trigger the logic –<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/7-31.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 7: Microsoft Power Automate workflow real time flow result</P><BR /> In API you get various status code which helps to troubleshoot. Status ‘201’ means ‘Created’<BR /> <BR /> Let’s see in SAP Table –<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/8-23.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 8: SAP ZOVBAK Table entry</P><BR /> You may notice that the <U>remark</U> entered in SharePoint form is different from the one that appears in SAP. Let’s explore the reason while understanding the OAuth logic.<BR /> <BR /> With this, we have established that the #1 criterion of the use case for the ASDF company is met. But now there is an additional requirement, i.e. #2, to be met - <EM>only authorized &amp; authenticated user only should be allowed to create records.</EM><BR /> <BR /> With the basic authentication mechanism, the information is posted from a generic account, causing SAP to lose traceability of who changed what. If the SharePoint form is accessible to unauthorized users, SAP still allows them to post the data to their ZOVBAK table because the data is posted by a generic user. SharePoint Admin can control this access, but let SharePoint handle their restriction, our goal is to protect the SAP with our controls.<BR /> <BR /> This problem can be solved by other authentication mechanisms in the API world. However, we will see how the OAuth2.0 mechanism solves this problem.<BR /> <H4 id="toc-hId-239645149"><U>What is OAuth</U> →</H4><BR /> It is an authentication protocol that allows you to approve one application interacting with another on your behalf without giving away your password. OAuth doesn’t share password data but instead uses authorization tokens to prove an identity between consumers and service providers. At present OAuth1.0 is deprecated and Oauth2.0 is redesigned with enrich features.<BR /> <BR /> In a day-to-day life you have been using OAuth2.0 without realizing it, like – when you browse a random webpage, and it asks you to sign in using Google or Facebook or others. Say you choose Google and then it prompts you with Google login credentials, after successful authentication Google asks your permission to Authorize sharing blah-blah information with webpage you are browsing. Well, its OAuth2.0. Here is the architecture –<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/9-25.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 9: OAuth2.0 Architecture</P><BR /> The best thing about technology is that – people are given options. Basically, OAuth2.0 options differ in the way an access token (step 7 in the figure) is obtained from the OAuth 2.0 client application. Till date, SAP supports two types of OAuth2.0 flows –<BR /> <BLOCKQUOTE><BR /> <OL><BR /> <LI>Authorization Code Flow</LI><BR /> <LI>SAML 2.0 Bearer Assertion Flow</LI><BR /> </OL><BR /> </BLOCKQUOTE><BR /> We may discuss SAML 2.0 Bearer Assertion Flow another time, but in the <A href="https://blogs.sap.com/2023/10/11/sap-api-odata-security-part-iii-oauth2.0-authorization-code-flow/" target="_blank" rel="noopener noreferrer">next</A> series we will accelerate on the <STRONG>Authorization Code Flow</STRONG> but this time we will see practical on our favorite tool Postman. Happy Learning!! 2023-10-10T22:43:54+02:00 https://community.sap.com/t5/technology-blogs-by-members/sap-api-odata-security-part-iii-oauth2-0-authorization-code-flow/ba-p/13580972 SAP API OData Security Part III – OAuth2.0 Authorization Code Flow 2023-10-11T09:39:05+02:00 ravi_paul https://community.sap.com/t5/user/viewprofilepage/user-id/216731 Welcome to the third part of our SAP API Security journey. In <A href="https://blogs.sap.com/2023/10/10/sap-api-odata-security-part-ii-api-basic-authentication/" target="_blank" rel="noopener noreferrer">second</A> series, we learnt about Basic Authentication, OAuth definition and OAuth flows that SAP supports. Now lets gear up to OAuth authentication with some screenshots.<BR /> <BR /> SAP got one of the best documentations in market. <A href="https://wiki.scn.sap.com/wiki/display/Security/OAuth+2.0+-+Constrained+Authorization+and+Single+Sign-On+for+OData+Services" target="_blank" rel="noopener noreferrer">Wiki</A> will give you end to end guide for OAuth implementation with SAP tailored made use case.<BR /> <BR /> But for our use case, let's see how to enable OAuth in the OData service we created and implement the OAuth authorization code flow.<BR /> <BR /> Select the OData service under transaction <STRONG>/iwfnd/maint_service</STRONG>, click on OAuth from available menu. Once your services is under OAuth scope then a check mark will appear beside OData services.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/10-27.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 10: Activate OAuth in OData Service</P><BR /> Create a generic user that will be used for all OAuth flows, to be specific it will be used to <U>exchange tokens</U> between consumers and service providers, but NOT for posting which is our goal.<BR /> <BR /> At this point no need to assign any access/roles to this user. And this user must be setup as <STRONG>SYSTEM</STRONG> user type.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/11-35.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 11: OAuth Generic user SAP profile</P><BR /> Now execute transaction <STRONG>SOAUTH2</STRONG> to create OAuth client here is how it looks –<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/12-22.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 12: OAuth configuration in SAP</P><BR /> <U>Client ID</U>: It is generic user you created in earlier step “SECTEST99”<BR /> <BR /> <U>Client Authentication</U>: User “Client User ID and Password” so that front-end application needs to provide generic user account id and password to exchange token.<BR /> <BR /> <U>Resource Owner Authentication</U>: Select checkbox “Grant Type Authorization Code Active”<BR /> <BR /> With that you must provide “Redirect URI”.<BR /> <BLOCKQUOTE><BR /> <H3 id="toc-hId-1093847976">Question 3: What is Redirect URI</H3><BR /> &nbsp;<BR /> <BR /> It is the location where the authorization server sends the user once the app has been successfully authorized and granted an authorization code or access token. The authorization server sends the code or token to the redirect URI, so it's important you register the correct location as part of the app registration process.</BLOCKQUOTE><BR /> <U>Redirect URI</U>: It is given to you by front-end application admin. For this exercise we will use Postman web as our front-end application, as like for Basic-Authentication we used Microsoft SharePoint. Postman has static Redirect URI for developers. Remember, Postman web has different redirect uri than Postman native app. For this exercise we are using Postman Web.<BR /> <BR /> <U>Refresh Allowed</U>: It is another key feature in OAuth2.0 that SAP supports as well. In this blog series we are not going to use this feature so you can keep it unchecked.<BR /> <BR /> <U>Scope Assignment</U>: Add the OData service that you created. Pre-requisite to appear your OData Service here to add under OAuth scope under transaction /iwfnd/maint_service. You can add multiple OData services under one client id.<BR /> <BR /> Note: Remember Client ID is <U>case-sensitive</U>. I’ll recommend use <U>upper case</U> wherever it is prompted.<BR /> <BR /> Now we will create an authorization role (Z:API_TEST_ROLE_OAUTH) with OAuth related object. This role is added to the user who uses this service as an OAuth and generic user, who has access to the service<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/13-21.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 13: SAP PFCG Role to access OAuth Client and Scope</P><BR /> Assign this role to generic OAuth user SECTEST99 and NO other access is needed as the purpose of this generic user is to exchange access token.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/14-19.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 14: OAuth Generic user access</P><BR /> In this case, as data will be created in SAP using Mr. John’s account and not by any generic user, he must have SAP account with required permission. Required permissions are – OAuth role itself along with OData service role and permission to modify table ZOVBAK.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/15-22.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 15: Business User account to access OData, OAuth scope and modify ZOVBAK Table</P><BR /> Let’s see practical in Postman app by calling OData service using “Get” Method.<BR /> <BR /> For “Get” method we are using Basic-Authentication (although OAuth can be used as well), our goal is to get the <STRONG>x-csrf-token</STRONG> from Get method which we will utilize in “Post” method. For that under Headers I’m requesting (x-csrf-token = fetch) from OData service. After Status is 200 Ok then under response section of Header, we will get the x-csrf-token value.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/16-16.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 16: Postman GET configuration</P><BR /> Let’s see “Post” Method configuration with OAuth2.0 authentication –<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/17-20.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 17: Postman OAuth2.0 configuration to fetch Access Token</P><BR /> <BR /> <BLOCKQUOTE><U>Token Name</U>: Give random name<BR /> <BR /> <U>Grant Type</U>: Authorization Code<BR /> <BR /> <U>Callback URL</U>: This url should match with redirect URI that is configured in SOAUTH2 transaction in SAP.<BR /> <BR /> <U>Auth URL</U>: <A href="https://&lt;hostname&gt;/sap/bc/sec/oauth2/authorize" target="test_blank" rel="nofollow noopener noreferrer">https://&lt;hostname&gt;/sap/bc/sec/oauth2/authorize</A><BR /> <BR /> <U>Access Token URL</U>: <A href="https://&lt;hostname&gt;/sap/bc/sec/oauth2/token" target="test_blank" rel="nofollow noopener noreferrer">https://&lt;hostname&gt;/sap/bc/sec/oauth2/token</A><BR /> <BR /> <U>Client ID</U>: SAP ID of generic account<BR /> <BR /> <U>Client Secret</U>: Password of generic account<BR /> <BR /> <U>Scope</U>: Name of the OData service to generate token</BLOCKQUOTE><BR /> Now hit on “Get New Access Token” button that will open a pop-up for you to authorize.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/18-15.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure18: End User step to authorize request</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/19-18.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure19: Access Token details post end user authorized request</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/20-15.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure20: POST headers and body configuration</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/21-14.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure21: Result of POST operation</P><BR /> Status <STRONG>201</STRONG> means – entry is <SPAN style="text-decoration: underline">created</SPAN>.<BR /> <BR /> These configurations made in Postman are technical specifications that we (SAP team) must provide to the administrator of the front-end application (be it SharePoint or ServiceNow or any other application). With that, the frontend administrator must deploy the configuration to the respective application to make a successful connection.<BR /> <BR /> As far as Mr. John (or any business user) is concerned, he will simply enter the required details in the front-end application form and authorize the transaction using his SAP credentials, which should then publish the details in the SAP ZOVBAK table.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/22-13.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Figure 22: SAP ZOVBAK Table entry</P><BR /> You will notice that REMARK, which is added to the body of Postman or during Basic Authentication of SharePoint, is also changed. I have set up logic to update REMARK as SAP ID of the user creating a record in the table. This logic changes the REMARK specified in Body or SharePoint with the person creating the record.<BR /> <H3 id="toc-hId-897334471">The Outcome</H3><BR /> With basic authentication, the table record is created by a generic service account, while with OAuth authentication, the record is created by Mr. John’s ID. By using OAuth authentication method ASDF's both requirement is fulfilled:<BR /> <OL><BR /> <LI>Since ASDF has various customers around the world, the development should be robust enough to create records in the ZOVBAK table using one or more applications.</LI><BR /> </OL><BR /> <BLOCKQUOTE>“https://&lt;hostname&gt;/sap/opu/odata/sap/ZTEST_API_TEST_SRV/SOHEADERSet” OData service is robust to utilize in any application that supports REST calls.</BLOCKQUOTE><BR /> <OL start="2"><BR /> <LI>For the ASDF company, the ZOVBAK table is critical, so only authorized, and authenticated users are allowed to create records.</LI><BR /> </OL><BR /> <BLOCKQUOTE>OAuth2.0 will ensure that only authorized, and authenticated users are creating records in table</BLOCKQUOTE><BR /> &nbsp;<BR /> <BR /> This was the final series and ThankYou for reading it. I'll be happy to answer your query or if you have any feedback for me. 2023-10-11T09:39:05+02:00 https://community.sap.com/t5/technology-blogs-by-members/extension-of-standard-task-summary-view-with-custom-fields/ba-p/13580097 Extension of Standard Task Summary View with Custom fields 2023-10-26T18:07:35+02:00 maheshpuligilli https://community.sap.com/t5/user/viewprofilepage/user-id/191143 Hello All,<BR /> <BR /> I Hope everyone doing well! <span class="lia-unicode-emoji" title=":slightly_smiling_face:">🙂</span><BR /> <BR /> <SPAN style="text-decoration: underline"><STRONG>Introduction:</STRONG></SPAN><BR /> <BR /> Recently, we got a requirement to enhance standard Fiori application with custom fields for one of the tile, when the tile is clicked we will have access to My inbox application. In this application the window is divided into main &amp; detail window. Please refer to the below screenshot.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/first-1.png" height="146" width="355" /></P><BR /> From above screenshot we have a option for Multi selection(Multi select button). When approver clicks on multi-select for bulk approval, the following is displayed with standard fields (Title, Created by and Due on).<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/1-158.png" /></P><BR /> In this blog, I am going to explain you how to extend the Task Summary View with custom fields in My inbox application.<BR /> <BR /> When multi-select check box is selected and requests are checked/selected either via <EM>Select All</EM> or individually selecting the requests, Task Summary section should display the details of the selected requests with below custom fields.<BR /> <OL><BR /> <LI>Name</LI><BR /> <LI>Period</LI><BR /> <LI>Requested</LI><BR /> <LI>Type</LI><BR /> <LI>Comments</LI><BR /> </OL><BR /> In order to achieve the above requirement I have followed below steps.<BR /> <BR /> <STRONG><U>OData extension in Gateway System:</U></STRONG><BR /> <BR /> <SPAN style="text-decoration: underline"><STRONG>Step 1</STRONG></SPAN>:&nbsp; Created a new project in SEGW transaction code and redefine the standard OData service (/IWPGW/TASKPROCESSING) as shown in below.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/2-47.png" height="247" width="425" /><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/3-37.png" height="258" width="431" /><BR /> <BR /> Click on next button then following screen will be displayed. Just select all the properties and click on finish button. <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/4-30.png" height="271" width="443" /><SPAN style="text-decoration: underline"><STRONG>Step 2:</STRONG></SPAN> Now, we need to extend the “TASK” Entity type with custom field as per requirement (NAME, PERIOD, REQUESTED, TYPE, COMMENTS).<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/5-31.png" height="198" width="469" /></P><BR /> <STRONG>Note:&nbsp; Here we need to add one more property “SAP__Origin” as KEY along with above new custom fields.</STRONG><BR /> <BR /> This “SAP_Origin” field would play important role while extending the TASK entity this field will capture the system alias.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/6-32.png" height="161" width="476" /><BR /> <BR /> <SPAN style="text-decoration: underline"><STRONG>Step 3:</STRONG> </SPAN>&nbsp;&nbsp;Extension of Entity Type- TASKDEFINITION as shown in below.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/7-31.png" /><BR /> <BR /> <SPAN style="text-decoration: underline"><STRONG>Step 4:</STRONG></SPAN> Once project is generated, Redefined the ENTITYSET_TASK method in DPC_EXT and added new custom code to fill new fields.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/8-24.png" /><BR /> <UL><BR /> <LI>Here, I have created a new RFC function module in ECC system as there is no data in Gateway system and calling that RFC in ENTITYSET_TASK method and filling the Custom fields data.</LI><BR /> <LI>Passing “Workitem” (LT_TASKS) information to RFC FM and get the data From ECC System.</LI><BR /> <LI>Getting “SAP__Origin” information from table /iwfnd/c_mgdeam by passing Service_ID.</LI><BR /> </UL><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/9-22.png" /></P><BR /> <SPAN style="text-decoration: underline"><STRONG>Step 5:</STRONG></SPAN> Redefined the ENTITYSET_TASK_DEFINITION method in DPC_EXT and getting data to “SAP_Origin” from table /iwfnd/c_mgdeam.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/10-19.png" /><SPAN style="text-decoration: underline"><STRONG>Step 6:</STRONG></SPAN> Go to transaction code: /iwfnd/maint_Service and add the service and System alias.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/11-14.png" /><BR /> <BR /> <STRONG>Note:</STRONG> Here system alias should be ECC system alias.<BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG><U>Frontend application UI5 Extension:</U></STRONG><BR /> <BR /> <STRONG><U>View Design:</U></STRONG><BR /> <BR /> To add new columns in Task Summary, extension point is not available so replaced the Multiselectsummary View as Multiselectsummarycustom and added new columns as below.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/12-11.png" height="339" width="466" /><BR /> <BR /> <STRONG><U>Controller Extension:</U></STRONG><BR /> <BR /> To retrieve the data of new properties added new properties to select in the hook method extHookGetPropertiesToSelect by extending S2 controller as below.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/13-11.png" /><BR /> <UL><BR /> <LI>To refresh the Master data modified <STRONG>sendMultiSelectActionSuccess </STRONG>function in S2Custom Controller, and <STRONG>sendAction </STRONG>function in S3Custom controller.</LI><BR /> </UL><BR /> Added the code (this.oDataManager.refreshListOnAddInboxDone()) as below.<BR /> <BR /> <STRONG>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <SPAN style="text-decoration: underline">S2Custom Controller</SPAN></STRONG><SPAN style="text-decoration: underline">:</SPAN><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/14-9.png" height="88" width="444" /><BR /> <BR /> <SPAN style="text-decoration: underline"><STRONG>S3Custom controller</STRONG>:</SPAN><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/15-24.png" height="170" width="440" /><BR /> <BR /> <SPAN style="text-decoration: underline">Result:</SPAN><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/16-5.png" /></P><BR /> <SPAN style="text-decoration: underline"><STRONG>Summary:</STRONG></SPAN><BR /> <BR /> By following the above steps, we can enhance the standard Fiori application with custom fields.<BR /> <BR /> Hope this blog will be helpful <span class="lia-unicode-emoji" title=":slightly_smiling_face:">🙂</span><BR /> <BR /> Thanks for reading .<BR /> <BR /> Please provide your valuable feedback on comment section.<BR /> <BR /> &nbsp;<BR /> <BR /> -Please follow Puligilli Mahesh for future posts.<BR /> <BR /> -Ask or follow questions about SAP NetWeaver .<BR /> <BR /> -Read other SAP NetWeaver and follow blog posts.<BR /> <BR /> &nbsp;<BR /> <BR /> Thanks &amp; Regards<BR /> <BR /> Mahesh<BR /> <BR /> &nbsp; 2023-10-26T18:07:35+02:00 https://community.sap.com/t5/technology-blogs-by-sap/request-s-n-from-external-system-and-respond-to-corporate-serialization/ba-p/13571226 Request S/N from External System and respond to Corporate Serialization 2023-11-06T23:36:34+01:00 chun_jiang https://community.sap.com/t5/user/viewprofilepage/user-id/775467 <H2 id="toc-hId-963864649"><STRONG>1. Introduction:</STRONG></H2><BR /> In this article, I will describe the way for serial number management. Basiclly, there are four variants. I would like to emphasis following two patterns. Both of them management S/N at Exteral System(e.g. Non-SAP) but in different way. I will focun on the differences on setting and operation.<BR /> <UL><BR /> <LI>SAP CorS Managed (External)</LI><BR /> <LI>SAP CorS Tracked (with MD reference)</LI><BR /> </UL><BR /> In addition, I will also introduce encoding/decoding Badi for well explain how S/N can be request from external and integration to CorS by utilizing customer own numbering rule.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/12/画像1-1.png" /></P><BR /> &nbsp;<BR /> <H2 id="toc-hId-767351144"><STRONG>2. Contents:</STRONG></H2><BR /> <STRONG>Pattern1. SAP CorS Managed (External)---Take SAP CorS as subordinate management system</STRONG><BR /> <UL><BR /> <LI>Approach1: Request of Serial Numbers from Cors -&gt; External</LI><BR /> <LI>Approach2: Upload Serial Number from CorS directly</LI><BR /> </UL><BR /> <STRONG>Pattern2. SAP CorS Tracked (with MD reference)---S/N is not management at SAP CorS, take CorS as S/N tracking system</STRONG><BR /> <UL><BR /> <LI>Approach: Posting S/N with EPCIS event directly from using Warehouse Toolbox</LI><BR /> </UL><BR /> &nbsp;<BR /> <H2 id="toc-hId-570837639"><STRONG>3. SAP CorS Managed (External): </STRONG></H2><BR /> <BLOCKQUOTE><BR /> <H6 id="toc-hId-890655010"><EM><A href="https://help.sap.com/docs/SAP_CORPORATE_SERIALIZATION/0954280172964ef3afa9d711d4cc1846/59bd79c40cf648e3a047aa78d3367538.html?locale=en-US" target="_blank" rel="noopener noreferrer">Serial Number Request and Distribution | SAP Help Portal</A></EM></H6><BR /> <H6 id="toc-hId-694141505"><EM><A href="https://help.sap.com/docs/SAP_CORPORATE_SERIALIZATION/0954280172964ef3afa9d711d4cc1846/a907bc6e3bbd456d8efec94c6c8856a4.html?locale=en-US&amp;q=request%20serial%20number%20external" target="_blank" rel="noopener noreferrer">Request Serial Numbers from an External System | SAP Help Portal</A></EM></H6><BR /> <H6 id="toc-hId-497628000"><EM><A href="https://help.sap.com/docs/SAP_CORPORATE_SERIALIZATION/0954280172964ef3afa9d711d4cc1846/99a9575f7caf462993a9a0576fd205ee.html?locale=en-US&amp;version=1.1&amp;q=%2FCORS%2FSNR_UPLOAD" target="_blank" rel="noopener noreferrer">Upload Serial Numbers | SAP Help Portal</A></EM></H6><BR /> <H6 id="toc-hId-301114495"><EM><A href="https://help.sap.com/docs/SAP_CORPORATE_SERIALIZATION/0954280172964ef3afa9d711d4cc1846/0f896c67a45445a7aca9e7ad602a4af4.html?locale=en-US&amp;q=request%20serial%20number%20external" target="_blank" rel="noopener noreferrer">Serial Number Request Services | SAP Help Portal</A></EM></H6><BR /> </BLOCKQUOTE><BR /> ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー<BR /> <H3 id="toc-hId--282647167"><STRONG>●Approach1: Request of Serial Numbers from External -&gt; CorS</STRONG></H3><BR /> ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/12/2022-12-09_12-28-03.jpg" /></P><BR /> <BR /> <H4 id="toc-hId--350077953"></H4><BR /> <H4 id="toc-hId--546591458"><STRONG>■Operation&nbsp; ※Take "List Managed S/N" as Example</STRONG></H4><BR /> <STRONG>1. &lt;External&gt;&nbsp; &nbsp; &nbsp; Generate S/N at External System(e.g. 300 List Managed S/N)</STRONG><BR /> <STRONG>2. &lt;SAP CorS&gt;&nbsp; &nbsp;Request S/N from Cors -&gt; External(e.g.10 List Managed S/N)<EM>   </EM></STRONG><BR /> Trcd:「/CORS/SNR_REQUEST - Request of Serial Numbers」<BR /> <STRONG>3. &lt;External&gt;&nbsp; &nbsp; &nbsp; S/N will be sent from External -&gt; CorS(e.g.10 List Managed S/N)</STRONG><BR /> <BR /> <EM>&nbsp;=&gt;As a result, CorS will recieve S/N and S/N Status:1-Create</EM><BR /> <BR /> <STRONG>4. &lt;SAP CorS&gt;&nbsp; &nbsp;Encoding S/N for GTIN</STRONG><BR /> Trcd: DataCockpit-&gt;Serial Numbers Node-&gt;Create Serial Number Request<BR /> BAdi here is possible.<BR /> <BR /> <EM>=&gt;As a result, S/N Status:2-Assign</EM><BR /> <BR /> <STRONG>5. &lt;SAP CorS&gt;&nbsp; &nbsp;Decoding S/N for Serialization Object</STRONG><BR /> Trcd:「/CORS/POSTEVENT - Post Manual Event 」or using Warehouse Toolbox.<BR /> BAdi here is possible.<BR /> <BR /> <EM>=&gt;As a result, S/N Status:3-Commission</EM><BR /> <BR /> &nbsp;<BR /> <H4 id="toc-hId--1240822058"><STRONG>■Setting</STRONG></H4><BR /> <B>1. Set up </B><B>Range Definition/Range (=Range Definition is must in this Pattern)</B><BR /> <BR /> ① Rng.Def.Origin.Ind=1(External)<BR /> ② Ener External System Name into Range Definition Origin tab<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/12/2022-12-09_01-17-15.jpg" /></P><BR /> <B style="font-size: 1rem">2. Assign </B><B style="font-size: 1rem">External </B><B style="font-size: 1rem">Range to </B><B style="font-size: 1rem">Product, </B><B style="font-size: 1rem">Serial Number Management Type</B><B style="font-size: 1rem">=</B><B style="font-size: 1rem">E</B><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/12/2022-12-09_17-06-24.jpg" /></P><BR /> <STRONG>3. Maintain External System Master</STRONG><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/12/2022-12-09_17-05-22.jpg" /></P><BR /> <STRONG>4. Set up Web Service Binding</STRONG><BR /> <BR /> <STRONG>-For SAP CorS system</STRONG><BR /> <BR /> Following SAP standard web service is used for external S/N request, which need to be setup by SOAMANAGER.<BR /> <UL><BR /> <LI>Service Definition: /CORS/SERIALNUMBERREQUEST</LI><BR /> <LI>Consumer Proxy: /CORS/CO_SNR_REQUEST</LI><BR /> </UL><BR /> You need to Import WSDL Binding in SAP CorS as well.<BR /> <UL><BR /> <LI>Go to SE80 -&gt; Enterprise Services Browser</LI><BR /> <LI>Select a package and right click to "Create a new object"</LI><BR /> <LI>Select "Service Consumer"</LI><BR /> <LI>Select "External WSDL"</LI><BR /> <LI>Select "WSDL source"</LI><BR /> <LI>…</LI><BR /> </UL><BR /> <STRONG>-For external (e.g. Non-SAP) system</STRONG><BR /> <UL><BR /> <LI>external(e.g. Non-SAP) system needs to facilitate a WebService binding for the SerialNumberRequest</LI><BR /> <LI>The WebService binding includes the endpoint where SAP CorS will direct its S/N Request towards</LI><BR /> </UL><BR /> <STRONG>-How to confirm what WSDL Binding at SAP CorS needed</STRONG><BR /> <UL><BR /> <LI>Open Trcd-SOAMANAGER</LI><BR /> <LI>Click「Web Service Configuration」 menu</LI><BR /> <LI>Click and open Service: /CORS/SERIALNUMBERREQUEST</LI><BR /> <LI>Click “Earth” mark and find「Binding WSDL Generation」tab</LI><BR /> <LI>Execute「WSDL URL for Binding」button, then we will see the exact payload and well format WSDL, which contain the required S/N infromation CorS needed from External.</LI><BR /> </UL><BR /> ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー<BR /> <H3 id="toc-hId--1143932556"><STRONG>●</STRONG><STRONG>Approach2:</STRONG><STRONG>&nbsp;Upload Serial Number from CorS directly</STRONG></H3><BR /> ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー<BR /> <H4 id="toc-hId--1633849068"><STRONG>■Operation</STRONG></H4><BR /> <STRONG>1.&nbsp; &lt;SAP CorS&gt;&nbsp; Upload S/N</STRONG><BR /> <SPAN style="font-size: 1rem">&nbsp;</SPAN><EM style="font-size: 1rem">Trcd:「/CORS/SNR_REQUEST - Request of Serial Numbers」</EM><BR /> <BR /> <EM>=&gt;As a result, S/N Status:1-Create</EM><BR /> <BR /> <STRONG>2. &lt;SAP CorS&gt;&nbsp; &nbsp;Encoding S/N for GTIN</STRONG><BR /> <EM>&nbsp;Trcd: DataCockpit-&gt;Serial Numbers Node-&gt;Create Serial Number Request</EM><BR /> <BR /> <EM>=&gt;As a result, S/N Status:2-Assign </EM><BR /> <BR /> <STRONG>3. &lt;SAP CorS&gt;&nbsp; Decoding S/N for Serialization Object</STRONG><BR /> <EM>&nbsp;Trcd:「/CORS/POSTEVENT - Post Manual Event 」or using Warehouse Toolbox</EM><BR /> <BR /> <EM>=&gt;As a result, S/N Status:3-Commission</EM><BR /> <H4 id="toc-hId--1830362573"></H4><BR /> <H4 id="toc-hId--2026876078"><STRONG>■Setting</STRONG></H4><BR /> <H4 id="toc-hId-2071577713"><STRONG>※Same with Approach1 and No need web service setting up.</STRONG></H4><BR /> &nbsp;<BR /> <H4 id="toc-hId-1875064208"><STRONG>■BAdi</STRONG></H4><BR /> For example, in case customer require EWM HU number to be used as a GRAI serial. GRAI serial number has a limit of 16 characters or less, EWM HU may have a lenth of more then 16 characters, in that case, a Badi implementation for encoding and decoding with customer own numbering logic is recommended.<BR /> <BR /> ・<STRONG>Pre-requisite</STRONG><BR /> <BR /> Using Trcd: /CORS/C_OBJENCTYPE - Maintain Object and Encoding Types<BR /> ①XXXXXX・・・Define Customer Z* Encoding Type<BR /> ②XX・・・Define Customer Z* Object Type<BR /> ③Assign①to②<BR /> <BR /> <B>・</B><B>Badi </B><B>Enhancement Spot</B><BR /> <BR /> Enhancement Spot: /CORS/ES_ID_ENC_DEC<BR /> BadI Definition: /CORS/BADI_ID_ENC_DEC<BR /> Interface: /CORS/IF_BADI_ID_ENC_DEC<BR /> Method: ENCODE or DECODE<BR /> <BR /> <B>・</B><B>Badi Sample</B><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/12/2022-12-12_14-21-57.jpg" /></P><BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId--2029610579"><STRONG>4. </STRONG><STRONG>SAP CorS Tracked (with MD reference):</STRONG></H2><BR /> <STRONG>※Take "</STRONG><STRONG>List Managed S/N" as Example</STRONG><BR /> <BR /> ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー<BR /> <H3 id="toc-hId-1775440205"><STRONG>●Approach: Posting S/N with EPCIS event directly from using Warehouse Toolbox&nbsp;</STRONG></H3><BR /> ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー<BR /> <BR /> <B>■Concept</B><BR /> 1. Customer do not use CorS to manage S/N, <STRONG>Range/Range definition is not required</STRONG>.<BR /> Instead, "Serial Number Management Not Used" flag must be set on the detail tab of CorS product or BP master.<BR /> <BR /> 2. <STRONG>No need to request or upload external S/N</STRONG> from CorS.<BR /> <BR /> 3. It is possible to manage S/N events in CorS. S/N from an external system can be <STRONG>recorded directly and tracked within CorS</STRONG> by posting EPCIS event.<BR /> <BR /> <SPAN style="font-size: 1rem">For information on how to <STRONG>post an EPCIS event, you can use Warehouse Toolbox(Trcd:/STTPEC/WHS) </STRONG>, which is always used for register EPCIS event that related to warehouse task, or you can<STRONG> directly register EPCIS event with manual posting</STRONG>.</SPAN><BR /> <BR /> The advantage of this pattern is that if S/N can be managed centrally in an external system, there is no need for double management within SAP CorS. We use SAP CorS only for tracking and tracing S/N by posting EPCIS event to a partical serialization object.<BR /> <H4 id="toc-hId-1285523693"></H4><BR /> <H4 id="toc-hId-1257193879"><STRONG>■Setting Up Point</STRONG></H4><BR /> <B>1. Set up </B><B>“</B><B>Serial Number Management Not Used</B><B>” flag on the detail tab of CorS Product or BP Master.</B><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/12/2022-12-09_01-33-43-1.jpg" /></P><BR /> <B>2. Register EPCIS Event (Commission) by Warehouse Toolbox (Post Manual Event is also worked)</B><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/12/2022-12-09_01-34-10.jpg" /></P><BR /> <STRONG>3. Here is the posting result at DataCockpit.</STRONG><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2022/12/2022-12-12_14-29-29.jpg" /></P><BR /> END.<BR /> <BR /> &nbsp; 2023-11-06T23:36:34+01:00 https://community.sap.com/t5/technology-blogs-by-sap/service-consumption-model-2-for-odata-client-proxy/ba-p/13573733 Service Consumption Model 2 for OData Client Proxy 2023-11-06T23:45:15+01:00 bernhard_grusie https://community.sap.com/t5/user/viewprofilepage/user-id/257088 <H1 id="toc-hId-834846345">Updates</H1><BR /> <UL><BR /> <LI>16/11/2023: ADT wizard robustness, see section "What comes next?".</LI><BR /> <LI>13/12/2023: Hint for error log integration in section "Tips for developers".</LI><BR /> </UL><BR /> <H1 id="toc-hId-638332840"></H1><BR /> <H1 id="toc-hId-441819335">Introduction</H1><BR /> This blog post will describe the Service Consumption Model 2 for OData. I will describe its benefits, provide a description of the model, take a look at the OData Client Proxy at runtime and also dive into the ABAP cross trace integration as well.<BR /> <BR /> If you want to receive or send data to an OData V2 or V4 service within SAP BTP, ABAP Environment or SAP S/4HANA ABAP Environment, you can use the "Service Consumption Model 2" for OData. As of release 2311, it is possible to <STRONG>consume Complex Types, Complex Collection, Action (bound) and Functions (bound).</STRONG> Of course, the consumption of Entity Types and Entity Sets is also possible.<BR /> <BR /> In addition you get <STRONG>fewer generated artifacts</STRONG>. The persistence of the underlying model has changed completely. In the first version you get an abstract CDS View for each Entity Type. For large services with multiple Entity Types, you could end up with a lot of artifacts. Now only one class with type definitions is created.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/SCM1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Many artifacts in the first version of the Service Consumption Model for OData</P><BR /> <BR /> <H1 id="toc-hId-245305830"></H1><BR /> <H1 id="toc-hId-48792325">Use case</H1><BR /> If you have an SAP BTP, ABAP Environment or SAP S/4HANA Cloud, ABAP Environment system you can use the Service Consumption Model for OData. From here you can connect to a Cloud or an on-premise system.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/Scenario.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Scenario</P><BR /> &nbsp;<BR /> <BR /> In my scenario I am consuming the <EM>/dmo/travel</EM> service from another Cloud system. A call to the Entity Set <EM>Travel</EM> returns the following data:<BR /> <PRE class="language-markup"><CODE>GET /sap/opu/odata4/dmo/api_travel_u_v4/srvd_a2x/dmo/travel_u/0001/Travel</CODE></PRE><BR /> <PRE class="language-javascript"><CODE>{<BR /> "@odata.context": "$metadata#Travel",<BR /> "@odata.metadataEtag": "W/\"20230919122803\"",<BR /> "@odata.nextLink": "/sap/opu/odata4/dmo/api_travel_u_v4/srvd_a2x/dmo/travel_u/0001/Travel?$skiptoken=100",<BR /> "value": [<BR /> {<BR /> "@odata.etag": "W/\"SADL-202305191948080000000C~20230519194808.0000000\"",<BR /> "AgencyID": "70041",<BR /> "AgencyName": "Maxitrip",<BR /> "BeginDate": "2023-06-03",<BR /> "BookingFee": 40.0,<BR /> "CurrencyCode": "USD",<BR /> "CustomerID": "594",<BR /> "CustomerName": "Ryan",<BR /> "EndDate": "2024-03-31",<BR /> "LastChangedAt": "2023-05-19T19:48:08Z",<BR /> "Memo": "Vacation",<BR /> "SAP__Messages": [<BR /> ],<BR /> "Status": "P",<BR /> "StatusText": "Planned",<BR /> "TotalPrice": 1889.0,<BR /> "TravelID": "1"<BR /> },<BR /> ...</CODE></PRE><BR /> <H1 id="toc-hId--147721180"></H1><BR /> <H1 id="toc-hId--344234685">Service Consumption Model 2 for OData</H1><BR /> As of release 1808, you can use the Service Consumption Model for OData. From release 2311 on, the wizard in the ABAP Development Tools (ADT)<SPAN style="font-size: 1rem">&nbsp;will </SPAN><STRONG style="font-size: 1rem">automatically</STRONG><SPAN style="font-size: 1rem"> use the new version.</SPAN><BR /> <H2 id="toc-hId--411665471">Wizard</H2><BR /> Select <EM>File</EM> --&gt;&nbsp; <EM>New</EM> --&gt; <EM>Service Consumption Model</EM> and choose <EM>OData</EM> as <EM>Consumption mode</EM> in ADT.<BR /> <BR /> The consumption system requires a representation of the remote service. This knowledge is used to create the URL, write and read the JSON form the HTTP requests and responses. Therefore, the wizard needs the EDMX file (a service metadata document that describes the data model exposed by the service as an HTTP endpoint). OData uses EDMX as the format for this description of the remote service. You can get this by adding <EM>$metadata</EM> to the end of the service document, in my case it is the following URL:<BR /> <PRE class="language-markup"><CODE>GET /sap/opu/odata4/dmo/api_travel_u_v4/srvd_a2x/dmo/travel_u/0001/$metadata</CODE></PRE><BR /> I saved this file on my computer to use this in the wizard. In addition I chose <EM>ZBG_TRAVEL_SCM</EM> as the class name. This class is the model representation and will contain all the types for my client.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/w3.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">EDMX import and class name</P><BR /> &nbsp;<BR /> <BR /> The EDMX file is analyzed beforehand to identify potential problems. It could be that certain artifacts are ignored, for example, parts of them violate the OData metadata <A href="http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part3-csdl.html" target="_blank" rel="nofollow noopener noreferrer">rules</A>. In my case, the EDMX file describes several Entity Types, Entity Sets, a Complex Type and a Bound Action.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/w4.png" height="926" width="500" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Analysis of EDMX file</P><BR /> &nbsp;<BR /> <BR /> The next step looks for the <EM>OptimisticConcurrency</EM> annotation of the <EM>Org.OData.Core.V1</EM> vocabulary. If an Entity Set has this annotation, modifying requests must use an ETag. If an Entity Set does not have this annotation, you can select the ETag support here.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/w5.png" height="509" width="435" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">ETag support</P><BR /> Finally, I get the Service Consumption Model 2 for OData:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/scm2-1.png" height="504" width="688" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">Service Consumption Model 2 for OData</P><BR /> In the upper left section, you can see the model class that describes the /dmo/travel service. I use the code snippets from Travel EntitySet and Read list as operation, as a starting point for my OData client.<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId--608178976">Model class</H2><BR /> The model class has the following parts:<BR /> <OL><BR /> <LI>Type definitions that can be used in my client code. I use a table of <EM>zbg_travel_scm=&gt;tys_travel_type</EM> to retrieve the travel data.</LI><BR /> <LI>To find the corresponding types, constants are created for Entity Sets, Entity Types, Complex Types, Actions and Functions. Here is the ABAP doc for the <EM>Entity Type</EM> constant, including the link to the type:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/scm_constant2.png" height="426" width="431" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif"></P><BR /> </LI><BR /> <LI>The model definition is done in several method implementations. The types are used to define all the artifacts of the remote service. In addition a mapping between the ABAP and the EDMX name is done here. ABAP artifacts are limited to 30 characters. In EDMX they can be up to 128 characters long in camel case.</LI><BR /> </OL><BR /> If you need to customize the result of the wizard, for example because you need to adapt to certain naming conventions, you can modify the source code of the generated class and adapt it to your needs.<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId--804692481">Support for Action and Functions</H2><BR /> To call an action or a function, structures and tables for the parameter are generated. With release 2311 the ADT integration is still missing. So I can't select a bound action, an action import, a bound function or a function import and use the code snippet from the ADT. However, the parameter structure is there and I can use it at runtime to call the operation. You can find examples in <A href="https://help.sap.com/docs/btp/sap-business-technology-platform/actions-and-functions?locale=en-US&amp;version=Cloud" target="_blank" rel="noopener noreferrer">SAP Help portal</A>.<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId--653951629">Connecting to a Remote Service</H2><BR /> In a cloud system I need an outbound communication scenario, an outbound service and a communication arrangement for the http connection. <A href="https://developers.sap.com/tutorials/abap-environment-create-service-consumption-model.html" target="_blank" rel="noopener noreferrer">Tutorial: Prepare Consuming System and Service Consumption Model</A> describes the steps to achieve this.<BR /> <BR /> &nbsp;<BR /> <H1 id="toc-hId--557062127">OData Client Proxy at Runtime</H1><BR /> <SPAN id="p1028">For my&nbsp;<SPAN id="1098-1099">client,</SPAN>&nbsp;I have&nbsp;<SPAN id="1130-1131">used</SPAN> the code snippet from ADT <SPAN id="p1027">(<SPAN id="1038">right hand</SPAN>&nbsp;side in the Service Consumption Model)</SPAN>&nbsp;to&nbsp;<SPAN id="1132-1133">read</SPAN>&nbsp;the&nbsp;<SPAN id="1039">Entity Set</SPAN>&nbsp;<EM>Travel</EM>.</SPAN><SPAN id="p1029">&nbsp;The&nbsp;<SPAN id="1100-1101">client</SPAN> code <SPAN id="1046-1134-1135">uses</SPAN>&nbsp;the&nbsp;<SPAN id="1102-1103">type</SPAN> from the <SPAN id="1104-1105">model</SPAN>. </SPAN><SPAN id="p1030">I&nbsp;<SPAN id="1048-1136-1137">changed</SPAN>&nbsp;three&nbsp;<SPAN id="1106-1107">things after that</SPAN>:</SPAN><BR /> <OL><BR /> <LI><SPAN id="p1031"><SPAN id="1138-1139">Established</SPAN>&nbsp;the&nbsp;<SPAN id="1108-1109">HTTP connection</SPAN> using the communication scenario and the outbound service.</SPAN></LI><BR /> <LI><SPAN id="p1150"><SPAN id="1160-1201-1202">Changed</SPAN>&nbsp;the&nbsp;<EM><SPAN id="1155-1183-1184" class="s-rg">IV_RELATIVE_SERVICE_ROOT</SPAN></EM><SPAN id="1183-1184">&nbsp;</SPAN><SPAN id="1161-1183-1184">parameter</SPAN>&nbsp;of the&nbsp;<SPAN id="1185-1186">factory</SPAN>&nbsp;<SPAN id="p1149">(line 56 in the screenshot below)</SPAN>&nbsp;to&nbsp;<SPAN id="1203-1204">point</SPAN>&nbsp;to the&nbsp;<SPAN id="1156-1187-1188" class="s-rg">OData</SPAN><SPAN id="1187-1188">&nbsp;service</SPAN>.</SPAN><SPAN id="p1151">&nbsp;This&nbsp;<SPAN id="1189-1190">path</SPAN>&nbsp;<SPAN id="1205-1206">depends</SPAN> on the c<SPAN id="1191-1192">ommunication system</SPAN>.</SPAN></LI><BR /> <LI><SPAN id="p1153"><SPAN id="1207-1208">Added</SPAN>&nbsp;the&nbsp;<EM><SPAN id="1157">out-&gt;write()</SPAN>&nbsp;</EM><SPAN id="1193-1194">statement</SPAN>&nbsp;at the&nbsp;<SPAN id="1195-1196">end</SPAN>&nbsp;<SPAN id="p1152">(line 81)</SPAN>.</SPAN></LI><BR /> </OL><BR /> <SPAN id="p1154">And voila, the <EM>GET</EM> request and <SPAN id="1197-1198">transformation</SPAN>&nbsp;of the&nbsp;<SPAN id="1158-1199-1200">JSON</SPAN><SPAN id="1199-1200">&nbsp;response</SPAN>&nbsp;to ABAP was&nbsp;<SPAN id="1209-1210">done</SPAN>&nbsp;for me.</SPAN><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/runtime.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">OData Client Proxy at Runtime</P><BR /> <BR /> <H2 id="toc-hId--1046978639">Conclusion</H2><BR /> <SPAN id="p1311">The Service Consumption Model 2 for <SPAN id="1315-1317">OData</SPAN> supports more <SPAN id="1316-1318">OData</SPAN> features and generates fewer artifacts.</SPAN><SPAN id="p1312"> The model class can be adapted to <SPAN id="1319">my</SPAN>&nbsp;needs, if the&nbsp;<SPAN id="1347-1348">result</SPAN>&nbsp;of the&nbsp;<SPAN id="1349-1350">wizard</SPAN> does not meet <SPAN id="1320">my</SPAN>&nbsp;<SPAN id="1351-1352">expectations</SPAN>.</SPAN><SPAN id="p1313"> <SPAN class="TextRun SCXW33805480 BCX0" lang="EN-US" lang="EN-US" data-contrast="none"><SPAN class="NormalTextRun SCXW33805480 BCX0">It would be great to get feedback from you</SPAN></SPAN><SPAN class="TrackChangeTextInsertion TrackedChange SCXW33805480 BCX0"><SPAN class="TextRun SCXW33805480 BCX0" lang="EN-US" lang="EN-US" data-contrast="none"><SPAN class="NormalTextRun SCXW33805480 BCX0">, so that we can </SPAN></SPAN></SPAN><SPAN class="TrackChangeTextInsertion TrackedChange SCXW33805480 BCX0"><SPAN class="TextRun SCXW33805480 BCX0" lang="EN-US" lang="EN-US" data-contrast="none"><SPAN class="NormalTextRun SCXW33805480 BCX0">further </SPAN></SPAN></SPAN><SPAN class="TrackChangeTextInsertion TrackedChange SCXW33805480 BCX0"><SPAN class="TextRun SCXW33805480 BCX0" lang="EN-US" lang="EN-US" data-contrast="none"><SPAN class="NormalTextRun SCXW33805480 BCX0">improve the wizard</SPAN></SPAN></SPAN><SPAN class="TextRun SCXW33805480 BCX0" lang="EN-US" lang="EN-US" data-contrast="none"><SPAN class="NormalTextRun SCXW33805480 BCX0"> if this is indeed the case.</SPAN></SPAN></SPAN><BR /> <H2 id="toc-hId--1243492144">What comes next?</H2><BR /> <UL><BR /> <LI><DEL>Make the ADT wizard more robust when importing EDMX files. Skipped elements will be part of the generated model to identify them later.&nbsp;</DEL><BR /> <UL><BR /> <LI>As of release 2405, the ADT wizard skips elements that violate the OData specification (for example trying to create a key property inside a complex type). You find skipped elements in the <EM>gcs*</EM> constants.<BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/11/Screenshot-2023-11-16-143150.png" /></LI><BR /> </UL><BR /> </LI><BR /> <LI>Full support for actions and functions in the ADT, including code snippets.</LI><BR /> <LI>On-premise shipping of the Service Consumption Model for OData.</LI><BR /> <LI>Multiple namespace support for SuccessFactors services.</LI><BR /> <LI>OpenAPI importer to support REST services.</LI><BR /> </UL><BR /> <H2 id="toc-hId--1440005649">Links</H2><BR /> <DIV>For more details on the OData Client Proxy, Service Consumption Model and communication scenario, see <A href="https://help.sap.com/docs/btp/sap-business-technology-platform/odata-services?locale=en-US&amp;version=Cloud" target="_blank" rel="noopener noreferrer">Developing External Service Consumption: OData Services</A></DIV><BR /> <DIV></DIV><BR /> <DIV></DIV><BR /> <DIV></DIV><BR /> Feel free to ask me questions, provide feedback or to share this blog with others. Thank you.<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> <HR /><BR /> <BR /> &nbsp;<BR /> <H1 id="toc-hId--1343116147">Tips for developers</H1><BR /> <H2 id="toc-hId--1833032659">Error log integration</H2><BR /> You can see errors in the SAP Gateway error log of ADT. To configure the feed, you can follow Andre's blog:: <A href="https://blogs.sap.com/2020/07/22/how-to-use-the-sap-gateway-error-log-in-adt/" target="_blank" rel="noopener noreferrer">how-to-use-the-sap-gateway-error-log-in-adt</A><BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId--2029546164">Cross trace integration</H2><BR /> Sometimes it is good to know what the OData Client Proxy does under the hood. Especially connecting to another system can be tricky. Therefore the OData Client Proxy is part of the ABAP Cross trace (ADT Windows --&gt; Show View --&gt; ABAP Cross trace):<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/cross_trace1-2.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Activate OData Client Proxy in cross trace</P><BR /> &nbsp;<BR /> <BR /> In the trace result you can see for example the response payload and the CSRF token fetch:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/cross_trace2.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">HTTP payload in cross trace</P><BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId-2068907627"></H2><BR /> &nbsp; 2023-11-06T23:45:15+01:00 https://community.sap.com/t5/application-development-blog-posts/understanding-authorization-in-odata/ba-p/13589238 Understanding Authorization in OData 2024-02-01T14:38:15.118000+01:00 Ravikumar_H https://community.sap.com/t5/user/viewprofilepage/user-id/1386926 <P><STRONG>Introduction:</STRONG></P><P><STRONG>Authorization</STRONG> refers to controlling access to resources and operations within an OData service. OData is a protocol that standardizes the way data is exposed and consumed over the web, typically using RESTful APIs.</P><P><STRONG>OData(Open Data Protocol)</STRONG> is a widely adopted standard for building and consuming RESTful APIs. It simplifies data sharing across disparate systems, making it easier for developers to expose and consume data in a standardized manner. However, with great power comes great responsibility, and securing OData services is paramount to protect sensitive information. In this blog post, we'll delve into the intricacies of authorization in OData and explore best practices for securing your OData services.</P><P>Role-based authorization is a common practice in securing OData services. Assigning specific roles to users and granting permissions based on these roles helps control access to different resources. This approach ensures that users only have the necessary privileges required for their tasks.</P><P><STRONG>Authentication vs. Authorization</STRONG></P><P>Before delving into OData authorization, it's crucial to distinguish between authentication and authorization:</P><P><STRONG>Authentication:</STRONG> Verifying the identity of users or systems making requests. Common methods include OAuth, API keys, or username/password.</P><P><STRONG>Authorization:</STRONG> Determining the actions and data access permissions granted to authenticated users or systems.</P><TABLE><TBODY><TR><TD width="623"><P>Here I am creating a Odata project in Tcode <STRONG>SEGW </STRONG>by providing Project name and Description.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_0-1706700294884.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57364i43AA171B9C1F0131/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_0-1706700294884.png" alt="ravi_kumar_0-1706700294884.png" /></span><P>&nbsp;Import the Database table to the project by following the below steps</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_1-1706700294894.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57365iBD9C8D228D62BD2F/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_1-1706700294894.png" alt="ravi_kumar_1-1706700294894.png" /></span><P>&nbsp; Provide the name of Database table in ABAP Structure.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_2-1706700294898.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57366iA350D0860E7E0B37/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_2-1706700294898.png" alt="ravi_kumar_2-1706700294898.png" /></span><P>&nbsp; Here Check out the Required fields for your Requirement and Click on Next.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_3-1706700294903.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57367i52429160AFCF98CD/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_3-1706700294903.png" alt="ravi_kumar_3-1706700294903.png" /></span><P>&nbsp; Here Check on the Key fields present in the Table and click on finish.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_4-1706700294907.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57368i43C4EDC9A294FCAB/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_4-1706700294907.png" alt="ravi_kumar_4-1706700294907.png" /></span><P>&nbsp;</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_5-1706700294922.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57369iB1166F267D163601/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_5-1706700294922.png" alt="ravi_kumar_5-1706700294922.png" /></span><P>Then Generate the OData Service, After Generating Components and methods will get Generated.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_6-1706700294928.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57372i349493125CD50754/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_6-1706700294928.png" alt="ravi_kumar_6-1706700294928.png" /></span><P>&nbsp; Here in Get Entityset I'm writing select Query to fetch the data.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_7-1706700294932.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57371iC1FBF0C60063A8F6/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_7-1706700294932.png" alt="ravi_kumar_7-1706700294932.png" /></span><P>&nbsp;</P></TD></TR><TR><TD width="623"><P><STRONG>To Provide Authorization to OData&nbsp;we need to follow below Steps.</STRONG></P><P><STRONG><U>Step 1</U></STRONG><STRONG>: </STRONG>Go to <STRONG>Tcode :- SU20</STRONG>, Create Authorization field as shown below</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_8-1706700294935.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57370i9A6DB3F89B93966C/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_8-1706700294935.png" alt="ravi_kumar_8-1706700294935.png" /></span><P>Then Create Authorization Object in <STRONG>Tcode SU21</STRONG> and Assign Authorization field to the Authorization Object.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_9-1706700294939.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57373iE31E77F9F21F7052/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_9-1706700294939.png" alt="ravi_kumar_9-1706700294939.png" /></span><P><STRONG><U>Step 2</U></STRONG><STRONG>: </STRONG>Create authorization for the role <STRONG>Tcode : PFCG</STRONG></P><P>we'll see how to Provide Authorization to ODATA by Assigning roles.</P><P>Go to Tcode : PFCG and Provide Role and Description.</P><P>Then&nbsp; Select the Role as per your Requirement, Here i am Selecting Single Role.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_10-1706700294942.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57374iD32E1EA970780A27/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_10-1706700294942.png" alt="ravi_kumar_10-1706700294942.png" /></span><P>After selecting Single Role New Page will get displayed, Here click On <STRONG>Menu </STRONG>Tab.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_11-1706700294947.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57375iA39DA9681406FD46/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_11-1706700294947.png" alt="ravi_kumar_11-1706700294947.png" /></span><P>&nbsp; In Transaction Arrow symbol, choose Authorization default.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_12-1706700294949.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57376i47A56C3076500D62/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_12-1706700294949.png" alt="ravi_kumar_12-1706700294949.png" /></span><P>&nbsp;Choose the SAP Gateway Business Suite Enablement - Service</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_13-1706700294953.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57377iC04C6A2E690839AD/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_13-1706700294953.png" alt="ravi_kumar_13-1706700294953.png" /></span><P>&nbsp;Then choose your service</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_14-1706700294959.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57378i13CC07836E071428/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_14-1706700294959.png" alt="ravi_kumar_14-1706700294959.png" /></span><P>&nbsp;</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_15-1706700294963.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57379i9A3C8180765859EB/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_15-1706700294963.png" alt="ravi_kumar_15-1706700294963.png" /></span><P>&nbsp; Here we can see that our Service is Added to the role.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_16-1706700294969.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57380i704FDD883B075645/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_16-1706700294969.png" alt="ravi_kumar_16-1706700294969.png" /></span><P>&nbsp;Then Click on <STRONG>Authorization</STRONG> Tab</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_17-1706700294974.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57381iC23EF9248523C2D7/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_17-1706700294974.png" alt="ravi_kumar_17-1706700294974.png" /></span><P>&nbsp; Then Click on Change Authorization Data.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_18-1706700294975.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57382i88441B0483ADB243/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_18-1706700294975.png" alt="ravi_kumar_18-1706700294975.png" /></span><P>Click on Manually and provide your Authorization Name and select the Action and Click on Generate.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_19-1706700294982.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57384iAC15C05DCFD6B2C5/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_19-1706700294982.png" alt="ravi_kumar_19-1706700294982.png" /></span><P>After Generating will get the Message '<STRONG>Profiles were Updated</STRONG>'.</P><P>Then Go to Transaction Code ‘<STRONG>SU01</STRONG>’ to set role for the User.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_20-1706700294984.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57383iA8D56303BD8FA90D/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_20-1706700294984.png" alt="ravi_kumar_20-1706700294984.png" /></span><P>&nbsp;</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_21-1706700294991.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57386iB7B17F3399A47C1C/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_21-1706700294991.png" alt="ravi_kumar_21-1706700294991.png" /></span><P>&nbsp;Enter your Role name and click enter.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_22-1706700294997.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57387i675B0F266A970C5A/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_22-1706700294997.png" alt="ravi_kumar_22-1706700294997.png" /></span><P>Then in Profiles click on generate which is located next to the Role name.</P><P>By Performing this we can Provide Authorization to ODATA Service.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_23-1706700295010.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57388i87BFCA5DBAA41AC6/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_23-1706700295010.png" alt="ravi_kumar_23-1706700295010.png" /></span><P>Output for the HANAUSER18(My user). When Authorized user try to access.</P></TD></TR></TBODY></TABLE><P><STRONG>&nbsp;</STRONG></P><TABLE><TBODY><TR><TD width="623"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ravi_kumar_24-1706700295027.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/57389i6A95E394FA972596/image-size/large?v=v2&amp;px=999" role="button" title="ravi_kumar_24-1706700295027.png" alt="ravi_kumar_24-1706700295027.png" /></span><P>Output for HANAUSER24 (Other user) When Non authorized user try to Access it will throw error.</P></TD></TR></TBODY></TABLE> 2024-02-01T14:38:15.118000+01:00 https://community.sap.com/t5/technology-blogs-by-sap/sap-learning-journey-building-odata-services-with-sap-gateway/ba-p/13623812 SAP Learning Journey – Building OData Services with SAP Gateway 2024-02-29T15:30:09.480000+01:00 StefanFell https://community.sap.com/t5/user/viewprofilepage/user-id/4321 <P>Since it was announced at SAP TechEd 2021, SAP offers digital learnings free of charge to everybody interested in SAP products on <A href="https://learning.sap.com" target="_blank" rel="noopener noreferrer">https://learning.sap.com</A>. In this blog post, I want to present to you the learning journey <A href="https://learning.sap.com/learning-journey/building-odata-services-with-sap-gateway" target="_blank" rel="noopener noreferrer">Building OData Services with SAP Gateway</A> and keep you up to date on the latest additions.</P><P>If you are more interested in a customer course for SAP Gateway, please read my blog post:<BR /><A href="https://community.sap.com/t5/blogs/blogworkflowpage/blog-id/technology-blog-sap/article-id/170557" target="_blank">Customer course GW100 (SAP Gateway – Building OData Services) available for SAP S/4HANA 2021</A><BR /><BR /></P><H3 id="toc-hId-1117024227"><STRONG>Latest Additions</STRONG></H3><P>2023-11 Learning journey available<BR /><BR /></P><H2 id="toc-hId-791428003"><STRONG>Introduction</STRONG></H2><P>This learning journey is based on the customer course <A href="https://training.sap.com/course/GW100" target="_blank" rel="noopener noreferrer">GW100 (SAP Gateway – Building OData Services)</A>. The course structure was reworked to provide a clear path following the learning goals of each unit. Many animations and videos support the digital learning experience inviting you to interact with the material.</P><P>Nearly every lesson provides at least one exercise showing steps in a written form. Some can be performed directly by using some public resource like the <A href="https://community.sap.com/t5/technology-blogs-by-sap/new-sap-gateway-demo-system-available/ba-p/13353480" target="_blank">SAP Gateway Demo System</A>, but most exercises are based on SAP S/4HANA 2021 FPS02. In addition to the written form, these exercises provide a simulation of the steps in an SAP Learning system.</P><P>The units in the current version are the following:</P><OL><LI>SAP Gateway Overview</LI><LI>OData Overview</LI><LI>SAP Gateway and CDS Views<BR /><BR /></LI></OL><H2 id="toc-hId-594914498"><STRONG>Content</STRONG></H2><H3 id="toc-hId-527483712"><STRONG>1. SAP Gateway Overview</STRONG></H3><P>Unit 1 first describes <A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway/describing-sap-gateway_a26e5530-f09b-4419-a331-5ec1b0a031fd" target="_blank" rel="noopener noreferrer">SAP Gateway</A> in general showing examples of where and how it is used in todays SAP solutions. The second lesson digs deeper in the releases and the components of SAP Gateway culminating in the <A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway/describing-sap-gateway-deployment-options_fd6c68c5-e698-48cb-8772-9188e982284c" target="_blank" rel="noopener noreferrer">deployment options</A> for on-premise and SAP Business Technology Platform (BTP).</P><P>The following is exercised:</P><UL><LI><A href="https://education.hana.ondemand.com/education/pub/mmcp/index.html?show=project!PR_21105BC84BF0B19A:uebung#2" target="_blank" rel="noopener nofollow noreferrer">Prepare the SAP Learning System</A></LI></UL><H3 id="toc-hId-330970207"><STRONG>2. OData Overview</STRONG></H3><P>Unit 2 covers the OData standard from the perspective of SAP Gateway. A short introduction to <A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway/explaining-representational-state-transfer-rest-_d2855a5f-d583-496f-b6ef-267308618734" target="_blank" rel="noopener noreferrer">REST</A> is followed by a comprehensive explanation of the <A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway/explaining-open-data-protocol-odata-_f617c2ae-47ee-451f-9aec-61a99440abe7" target="_blank" rel="noopener noreferrer">OData protocol</A>, how to perform <A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway/performing-odata-operations_a5b5c828-6206-4091-a74e-cf009bb171e4" target="_blank" rel="noopener noreferrer">OData operations</A> and how to handle <A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway/performing-odata-queries_ee225809-f372-4580-ad9e-a062e1f7c916" target="_blank" rel="noopener noreferrer">OData queries</A>. &nbsp;</P><P>The following is exercised:</P><UL><LI><A href="https://education.hana.ondemand.com/education/wa/mmcp/index.html?show=project!PR_2851D15943F47A8F:uebung" target="_blank" rel="noopener nofollow noreferrer">Examine an OData Service</A></LI><LI><A href="https://education.hana.ondemand.com/education/wa/mmcp/index.html?show=project!PR_943CFD1FEF51DAA9:uebung" target="_blank" rel="noopener nofollow noreferrer">Perform OData Operations</A></LI><LI><A href="https://education.hana.ondemand.com/education/wa/mmcp/index.html?show=project!PR_9150ED20234FA59E:uebung" target="_blank" rel="noopener nofollow noreferrer">Perform OData Queries</A></LI></UL><H3 id="toc-hId-134456702"><STRONG>3. SAP Gateway and CDS Views</STRONG></H3><P>Unit 3 jumps to the world of Core Data Services (CDS) and shows the four ways an SAP Gateway service can be <A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway/explaining-sap-gateway-services-based-on-cds-views_d2f6bd5c-f5ab-43bd-8538-2edb14470a98" target="_blank" rel="noopener noreferrer">generated based on CDS views</A>. This includes a short excursion to the ABAP RESTful Application Programming Model (RAP) but without getting into the details. The focus is to provide SAP Gateway services first by <A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway/mapping-cds-views-as-data-source_cff6ac93-0bf7-4ccc-9a54-1c899d0d544b" target="_blank" rel="noopener noreferrer">mapping</A> or <A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway/referencing-a-data-source_e4a63b0d-3052-482f-884e-4d941042af62" target="_blank" rel="noopener noreferrer">referencing</A> a CDS view as data source in the SAP Gateway Service Builder (SEGW). <A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway/publishing-cds-views-as-sap-gateway-services_f056a12d-3e0f-483e-9e3e-09643cae7f46" target="_blank" rel="noopener noreferrer">Publishing</A> a CDS view as SAP Gateway service or defining <A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway/defining-business-services_dbe161ff-1b51-4f5f-9971-ade9a0f21cb8" target="_blank" rel="noopener noreferrer">business services</A> are performed in the ABAP Development Tools (ADT).</P><P>The following is exercised:</P><UL><LI><A href="https://education.hana.ondemand.com/education/wa/mmcp/index.html?show=project!PR_30BADA87BCED2B4:uebung" target="_blank" rel="noopener nofollow noreferrer">Create an SAP Gateway Service by Mapping CDS Views – Part 1</A></LI><LI><A href="https://education.hana.ondemand.com/education/wa/mmcp/index.html?show=project!PR_35635B35C55648AB:uebung" target="_blank" rel="noopener nofollow noreferrer">Create an SAP Gateway Service by Mapping CDS Views – Part 2</A></LI><LI><A href="https://education.hana.ondemand.com/education/wa/mmcp/index.html?show=project!PR_FA170E13F64432A4:uebung" target="_blank" rel="noopener nofollow noreferrer">Create and SAP Gateway Service by Referencing a Data Source</A></LI><LI><A href="https://education.hana.ondemand.com/education/wa/mmcp/index.html?show=project!PR_95DEE198F60E78F:uebung" target="_blank" rel="noopener nofollow noreferrer">Implement OData.Publish in a CDS View – Part 1</A></LI><LI><A href="https://education.hana.ondemand.com/education/wa/mmcp/index.html?show=project!PR_364C21AAFEFDAF85:uebung" target="_blank" rel="noopener nofollow noreferrer">Implement OData.Publish in a CDS View – Part 2</A></LI><LI><A href="https://education.hana.ondemand.com/education/wa/mmcp/index.html?show=project!PR_402562F5679A1AB3:uebung" target="_blank" rel="noopener nofollow noreferrer">Implement a Navigation Using Associations in CDS Views</A></LI><LI><A href="https://education.hana.ondemand.com/education/wa/mmcp/index.html?show=project!PR_8EC6F389FCF2349E:uebung" target="_blank" rel="noopener nofollow noreferrer">Define a Business Service Definition and Binding</A><BR /><BR /></LI></UL><H2 id="toc-hId--191139522"><STRONG>Summary</STRONG></H2><P>If you have read so far, it seems that you are really thinking about consuming the learning journey. Don’t hesitate and jump right in:</P><P><A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway" target="_blank" rel="noopener noreferrer">https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway</A></P><P>If you are more interested in a customer course for SAP Fiori, please visit <A href="https://training.sap.com" target="_blank" rel="noopener noreferrer">https://training.sap.com</A>. The GW100 (SAP Gateway – Building OData Services) is a 5-day-course offered as physical and virtual event:</P><P><A href="https://training.sap.com/course/GW100" target="_blank" rel="noopener noreferrer">https://training.sap.com/course/GW100</A></P><P>For any other questions around the offerings of SAP Learning Services, please jump to our community page and get in contact with us:</P><P><A href="https://pages.community.sap.com/topics/training-certification" target="_blank" rel="noopener noreferrer">https://pages.community.sap.com/topics/training-certification</A></P><P>Happy learning<BR />Stefan</P> 2024-02-29T15:30:09.480000+01:00 https://community.sap.com/t5/technology-blogs-by-sap/customer-course-gw100-sap-gateway-building-odata-services-available-for-sap/ba-p/13623919 Customer Course GW100 (SAP Gateway – Building OData Services) Available for SAP S/4HANA 2021 2024-02-29T15:33:56.276000+01:00 StefanFell https://community.sap.com/t5/user/viewprofilepage/user-id/4321 <P>Now that I finished the course development of the GW100 (again), I thought it is time to summarize all the new and updated topics in a central place. I decided that a blog post here would be a good way to share this to fellow ABAP developers. So welcome to my first blog post about the customer training <A href="https://training.sap.com/course/GW100" target="_blank" rel="noopener noreferrer">GW100 (SAP Gateway – Building OData Services)</A>.</P><P>If you are more interested in a digital learning for SAP Gateway, please read my blog post:<BR /><A href="https://community.sap.com/t5/blogs/blogworkflowpage/blog-id/technology-blog-sap/article-id/170554" target="_blank">SAP Learning Journey – Building OData Services with SAP Gateway</A><BR /><BR /></P><H2 id="toc-hId-987942476"><STRONG>Introduction</STRONG></H2><P>Starting in 2014, this is now the seventh incarnation of how to develop OData services with SAP Gateway. The course shows all parts of SAP Gateway, which are available since SAP NetWeaver Application Server 7.0 (SAP Gateway 2.0), as well as parts added up to SAP S/4HANA 2021. The whole bandwidth of SAP Gateway covering all releases is shown.</P><P>The units in the current version are the following:</P><OL><LI>SAP Gateway Overview</LI><LI>OData Overview</LI><LI>SAP Gateway Service Implementation</LI><LI>SAP Gateway Service Generation</LI><LI>SAP Gateway Service Redefinition</LI><LI>SAP Gateway and CDS Views</LI><LI>SAP Gateway Hub Functionalities</LI><LI>Advanced OData Options</LI><LI>SAP Gateway Security</LI><LI>Further Information</LI></OL><P>If customers are interested, they can order a <A href="https://training.sap.com/content/CSTEN" target="_blank" rel="noopener noreferrer">customer specific</A> version of the course including only those topics suitable for their release or purpose.<BR /><BR /></P><H2 id="toc-hId-791428971"><STRONG>System Landscape</STRONG></H2><P>Let’s start with the system release: SAP S/4HANA 2021 FPS02. Our system landscape – we call it universal target – is used in many technology courses and offers full access for the participants from the SAP Fiori launchpad (FLP) in the browser down to SAP HANA on the SUSE Linux Enterprise server (SLES). Everything is set up following the newest guidelines of SAP so that it can really act as a template for customers.<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="GW100 System Landscape (Screenshot from System Setup Guide)" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/73544i8B80F0D078B6E608/image-size/large?v=v2&amp;px=999" role="button" title="Folie1.PNG" alt="GW100 System Landscape (Screenshot from System Setup Guide)" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">GW100 System Landscape (Screenshot from System Setup Guide)</span></span></P><P>In addition, we offer an instance of the SAP Business Application Studio (BAS) to show the consumption of OData services. If you want to know more about this topic, check out our courses for <A href="https://training.sap.com/trainingpath/Database+&amp;+Technology-Development-SAP+Fiori" target="_blank" rel="noopener noreferrer">SAP Fiori development</A>.<BR /><BR /></P><H2 id="toc-hId-594915466"><STRONG>OData</STRONG></H2><P>The unit explaining the OData foundation was greatly increased to cover all aspects of the protocol including OData V4. Many more slides were added to visualize the structure of an OData service. Here is an example about function and action imports:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Function and Action Imports (Screenshot from GW100)" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/73440i81E17C1DCC254BEC/image-size/large?v=v2&amp;px=999" role="button" title="Folie2.PNG" alt="Function and Action Imports (Screenshot from GW100)" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Function and Action Imports (Screenshot from GW100)</span></span><SPAN>A new section covering <EM>?sap-ds-debug=true</EM> was added to explain the features of this debugging query option. Although it was always part of exercises, there was only one slide showing it. Now the following one is just the first one:</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="SAP Debugging Query Option for Any Browser (Screenshot from GW100)" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/73441i509322C564BF3CCF/image-size/large?v=v2&amp;px=999" role="button" title="Folie3.PNG" alt="SAP Debugging Query Option for Any Browser (Screenshot from GW100)" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">SAP Debugging Query Option for Any Browser (Screenshot from GW100)</span></span><SPAN>The lesson about performing OData requests was enhanced in its visualization and some additional slides were added like this one for batch processing:</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="OData Option $batch (Screenshot from GW100)" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/73442i3C09DDD6904F933A/image-size/large?v=v2&amp;px=999" role="button" title="Folie4.PNG" alt="OData Option $batch (Screenshot from GW100)" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">OData Option $batch (Screenshot from GW100)</span></span></P><H2 id="toc-hId-398401961"><STRONG>Implementation</STRONG></H2><P>The structure of the units covering code-based implementation got refined to better fit the current state of development. This includes more graphical explanations of how the source code is structured in the system like this one:<span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Data Provider Base Class – Source Code (Screenshot from GW100)" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/73443iF2E7178F95D50793/image-size/large?v=v2&amp;px=999" role="button" title="Folie5.PNG" alt="Data Provider Base Class – Source Code (Screenshot from GW100)" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Data Provider Base Class – Source Code (Screenshot from GW100)</span></span><SPAN>Other slides were enhanced using semantical colors consistently throughout the material. In this example, you see blue used for ABAP code, gold for HTTP requests, and green for (successful) HTTP responses:</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Create Operation Essentials (Screenshot from GW100)" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/73447i67DE01F6A0AE60F0/image-size/large?v=v2&amp;px=999" role="button" title="Folie6.PNG" alt="Create Operation Essentials (Screenshot from GW100)" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Create Operation Essentials (Screenshot from GW100)</span></span><SPAN>But of course, at the end of the day, it is all about source code. There are now more code snippets outside of exercises and the code is explained in more detail on slides:</SPAN><EM><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Implement Paging (Screenshot from GW100)" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/73543i7BC97F497B451431/image-size/large?v=v2&amp;px=999" role="button" title="Folie7.PNG" alt="Implement Paging (Screenshot from GW100)" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Implement Paging (Screenshot from GW100)</span></span></EM></P><H2 id="toc-hId-201888456"><STRONG>CDS Views</STRONG></H2><P>The evolution of CDS views was driving SAP Gateway from the beginning. That is why there is an own unit keeping track of all possibilities to generate SAP Gateway services based on CDS views:<EM><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="OData Service Development with CDS – Comparison (Screenshot from GW100)" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/73450i9FF4AF7B8252A3BE/image-size/large?v=v2&amp;px=999" role="button" title="Folie8.PNG" alt="OData Service Development with CDS – Comparison (Screenshot from GW100)" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">OData Service Development with CDS – Comparison (Screenshot from GW100)</span></span></EM>The decision, which generator is the right one for your project, does not only depend on the release you are using. Especially in a brown field approach, the data source reference in the SAP Gateway Service Builder (SEGW) is still a viable option for reusing existing source code in SAP Gateway services based on CDS views:<SPAN>&nbsp;</SPAN><EM><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="How to Reference a Data Source (Screenshot from GW100)" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/73455iEDC6674ABF666C3B/image-size/large?v=v2&amp;px=999" role="button" title="Folie9.PNG" alt="How to Reference a Data Source (Screenshot from GW100)" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">How to Reference a Data Source (Screenshot from GW100)</span></span></EM>The newest generators are Business Services, which are part of the ABAP RESTful Application Programming Model (RAP). They are recommended by SAP as soon as they are available in your system and include the generation of OData V4 services:<EM><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="How to Create a Service Definition and Binding (Screenshot from GW100)" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/73453i27475A6F26C77DF8/image-size/large?v=v2&amp;px=999" role="button" title="Folie10.PNG" alt="How to Create a Service Definition and Binding (Screenshot from GW100)" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">How to Create a Service Definition and Binding (Screenshot from GW100)</span></span></EM></P><H2 id="toc-hId-5374951"><STRONG>Summary</STRONG></H2><P>If you have read so far, it seems that you are really thinking about attending the course. Don’t hesitate and check out the physical and virtual events we offer:</P><P><A href="https://training.sap.com/course/GW100" target="_blank" rel="noopener noreferrer">https://training.sap.com/course/GW100</A></P><P>If you are more interested in a digital learning, please visit <A href="https://learning.sap.com" target="_blank" rel="noopener noreferrer">https://learning.sap.com</A>. Some parts of the GW100 are already available free-of-charge:</P><P><A href="https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway" target="_blank" rel="noopener noreferrer">https://learning.sap.com/learning-journeys/building-odata-services-with-sap-gateway</A></P><P>For any other questions around the offerings of SAP Learning Services, please jump to our community page and get in contact with us:</P><P><A href="https://pages.community.sap.com/topics/training-certification" target="_blank" rel="noopener noreferrer">https://pages.community.sap.com/topics/training-certification</A></P><P>I hope even if you won’t attend the GW100 in any kind, you found some useful information around SAP Gateway in this blog post.</P><P>Happy learning<BR />Stefan</P> 2024-02-29T15:33:56.276000+01:00 https://community.sap.com/t5/financial-management-blogs-by-members/inbound-interface-to-receive-the-uuid-pdf-and-xml-details-through-odata/ba-p/13637696 Inbound Interface to receive the UUID, PDF and XML details through ODATA - MEXICO 2024-03-15T11:00:09.958000+01:00 d4449 https://community.sap.com/t5/user/viewprofilepage/user-id/144905 <H2 id="toc-hId-988982523">Requirement</H2><P>In Mexico, it is necessary that all companies receive tax authority validated XML and PDF files that contain the details of the payment made to vendors.</P><P>Its mandatory to extract the UUID number from the file that is received from the vendors and save it in a way that makes it easily accessible, in S4 it would be easier to store it in a custom table.</P><P>The importance of this interface is to store UUID in S4 system in order to facilitate users identify which invoices were payed to which vendors as well as reconciliation between EDICOM Portal and S4 system. The risk of not having this interface, is that files (PDF and XML) and UUID data will only be stored in EDICOM Portal and reconciliation to corresponding payments would be time consuming for users.&nbsp;&nbsp;&nbsp;</P><H2 id="toc-hId-792469018">Technical Requirement</H2><P>Interaction of SAP with EDICOM portal where SAP CPI is the middleware which sends the XML, PDF to S4. The technical requirement was to create a ODATA which can receive XML and PDF, also should extract UUID details from XML structure and update it to the respective document.</P><P>Simple flow chart:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="d4449_0-1710394374539.jpeg" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/80376i2B821A1012A14C62/image-size/medium?v=v2&amp;px=400" role="button" title="d4449_0-1710394374539.jpeg" alt="d4449_0-1710394374539.jpeg" /></span></P><P>Detailed Flow chart:</P><P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</P><H2 id="toc-hId-595955513">Technical Solution</H2><P>To receive and extract the details from XML file, ODATA interface is developed and the received XML and PDF files are attached to the respective FI document.</P><P>XML and PDF files are sent in base64 encoded format from SAP CPI then in S4 we make use of various function modules to convert it and make the attachment.</P><P>Created ODATA service in tcode SEGW - <STRONG>ZFI_PAYMENT_COMPLEMENT_002</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="d4449_1-1710394472271.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/80377i0BAB77F38F83D1E0/image-size/medium?v=v2&amp;px=400" role="button" title="d4449_1-1710394472271.png" alt="d4449_1-1710394472271.png" /></span></P><P>In Data model the custom table ZFI_IF020_PAYCOM is used to give ODATA the reference structure. The last two fields ZPDF &amp; ZXML are created in RAWSTRING format to store the XML and PDF files.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="d4449_2-1710394501348.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/80378iF0286B4B47588873/image-size/medium?v=v2&amp;px=400" role="button" title="d4449_2-1710394501348.png" alt="d4449_2-1710394501348.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="d4449_3-1710394536606.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/80379iCEB53401EB9F2ACF/image-size/medium?v=v2&amp;px=400" role="button" title="d4449_3-1710394536606.png" alt="d4449_3-1710394536606.png" /></span></P><P>Regenerate the Runtime Artifact ZCL_ZFI_PAYMENT_COM_01_DPC_EXT</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="d4449_4-1710394558273.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/80380iD064CA6CA87E74F5/image-size/medium?v=v2&amp;px=400" role="button" title="d4449_4-1710394558273.png" alt="d4449_4-1710394558273.png" /></span></P><P>This gives us the class where we can write the required logic, here we have redefined the method PAY_COMPSET_CREATE_ENTITY – holds the logic to validate the inputs received from SAP CPI and the logic to add PDF and XML to the FI document.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="d4449_5-1710394576668.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/80381i72DD2D5FCE09D59C/image-size/medium?v=v2&amp;px=400" role="button" title="d4449_5-1710394576668.png" alt="d4449_5-1710394576668.png" /></span></P><P>FI_DOCUMENT_CHANGE FM is used to update UUID to the respecting FI document.</P><P>The above FM is passed with the required importing parameters.</P><P>PDF Attachment:</P><P>PDF file is sent in Base64 format from CPI to S4.</P><UL><LI>SCMS_XSTRING_TO_BINARY – using this FM the received base64 format is converted to binary</LI><LI>ARCHIV_CREATE_TABLE – using this FM the converted binary file is attached to the FI document</LI></UL><P>XML Attachment:</P><P>XML is also sent in Base64 format from CPI to S4.</P><UL><LI>SCMS_XSTRING_TO_BINARY – using this FM the received base64 format is converted to binary</LI><LI>SO_CONVERT_CONTENTS_BIN – to get the binary file in tab format</LI><LI>SO_FOLDER_ROOT_ID_GET – this FM is used to fetch the folder ID</LI><LI>SO_OBJECT_INSERT – used to insert the converted XML file</LI><LI>BINARY_RELATION_CREATE_COMMIT – create relation between attachment and the document (Reference code is attached)</LI></UL><P>If there is any error in the attachment the file is sent to AL11.</P><P>All the received inputs including XML and PDF are saved in a custom table.</P><P>Report:</P><P>Tcode - ZFI_PAYCOMP_MONITOR</P><P>A report is created to display the details received using custom table in which the entries made through ODATA Service and displayed in ALV format.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="d4449_6-1710394659675.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/80383iDC2EEEF48F9B63B7/image-size/medium?v=v2&amp;px=400" role="button" title="d4449_6-1710394659675.png" alt="d4449_6-1710394659675.png" /></span></P><P>User can view the error details in description and also can select and reprocess the particular file after updating the missed details.</P><P>Created and activated the service <STRONG>ZFI_PAYMENT_COMPLEMENT_002_SRV</STRONG> in following tcode /n/iwfnd/maint_service</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="d4449_7-1710394683788.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/80384i8AF112BF888E7F49/image-size/medium?v=v2&amp;px=400" role="button" title="d4449_7-1710394683788.png" alt="d4449_7-1710394683788.png" /></span></P><P>The ICF Node should be in active status as shown in the screenshot.<BR /><BR />Hope this helps someone!&nbsp;<span class="lia-unicode-emoji" title=":smiling_face_with_smiling_eyes:">😊</span></P><P>&nbsp;</P><P><a href="https://community.sap.com/t5/c-khhcw49343/OData/pd-p/551580658536717501828021060147962" class="lia-product-mention" data-product="323-1">OData</a>&nbsp;<a href="https://community.sap.com/t5/c-khhcw49343/NW+ABAP+Gateway+%252528OData%252529/pd-p/181161894649260056016734803547327" class="lia-product-mention" data-product="1007-1">NW ABAP Gateway (OData)</a>&nbsp;&nbsp;</P> 2024-03-15T11:00:09.958000+01:00 https://community.sap.com/t5/application-development-blog-posts/creation-of-odata-service-with-implementation-of-crud-methods-and-deep/ba-p/13685666 Creation of OData service with implementation of CRUD methods and `deep insert` method from scratch 2024-05-03T08:33:54.245000+02:00 lukcad https://community.sap.com/t5/user/viewprofilepage/user-id/888780 <P><STRONG>Overview</STRONG></P><P><STRONG>-- Goal: </STRONG></P><P>Using SAP instance with SAP NW 7.40 or higher without RAP and without BOPF be able to create OData service upon business data model with these specific requirements:</P><P>- inserting of main business record support deep inserting (we save main record of main entity and all enclosed records in child entity)</P><P>- all CRUD methods of modification records for entities should be supported .</P><P>- code after regenerating OData service after adding of new changes is under control of developer via implemented overridden methods.</P><P><STRONG>-- Considered model:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_0-1714379019619.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103015i554C30430D128FF4/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_0-1714379019619.png" alt="lukcad_0-1714379019619.png" /></span></P><P><STRONG>-- Main steps of implementation:</STRONG></P><P>Using Eclipse + ADT you will go through this main steps and with all necessary code:</P><P>1-- Prepare data model with data</P><P>2-- Create project for OData service</P><P>3-- Add data model and generate service</P><P>4-- Register service and do initial test</P><P>5-- Implementation of `deep insert` MODEL via override</P><P>6-- Implementation of entity modification methods</P><P>7-- Implementation of OData CRUD methods using override</P><P>8-- Testing CRUD methods by SAP Gateway Client</P><P>9-- Verification of achieved code</P><P><STRONG>-- As result of you will have:</STRONG></P><P>-- Transportable package ZMLODATA which includes:</P><P>-- Data model with samples of data</P><P>-- OData service ZML_TRAVELLING_ODT</P><P>-- Classes where _EXT implementation decupled from regenerating process of OData service</P><P>Package ZMLODATA will contain these files:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_1-1714379019620.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103016iC4AD829F8CA20943/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_1-1714379019620.png" alt="lukcad_1-1714379019620.png" /></span></P><P>Service Project `ZML_TRAVELLING_ODT` will be like this one:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_2-1714379019622.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103017i991F516D7EAAC659/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_2-1714379019622.png" alt="lukcad_2-1714379019622.png" /></span></P><P><STRONG>Process of implementation</STRONG></P><P><STRONG>1-- Prepare data model with data</STRONG></P><P>1--1-- create package ZMLODATA</P><P>1--2-- create data elements in package</P><P>&nbsp;</P><TABLE><TBODY><TR><TD><P>ZMLNAME</P></TD><TD><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_3-1714379019623.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103020iE2434676C7EDBE35/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_3-1714379019623.png" alt="lukcad_3-1714379019623.png" /></span><P>&nbsp;</P><P>&nbsp;</P></TD></TR><TR><TD><P>ZMLDATEFROM</P></TD><TD><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_4-1714379019623.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103018i6D1C52D4440A41A6/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_4-1714379019623.png" alt="lukcad_4-1714379019623.png" /></span><P>&nbsp;</P><P>&nbsp;</P></TD></TR><TR><TD><P>ZMLDATETO</P></TD><TD><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_5-1714379019624.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103019i2853B948EE23C7C9/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_5-1714379019624.png" alt="lukcad_5-1714379019624.png" /></span><P>&nbsp;</P><P>&nbsp;</P></TD></TR></TBODY></TABLE><P><STRONG>1--3-- create table ZML_TRAVEL</STRONG></P><P>Using package ZMLODATA you create database table in Eclipse ADT by opening `New ABAP Repository Object` for `Database Table`&nbsp; and using this code definition:</P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>@EndUserText.label : 'ZML_TRAVEL' @AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE @AbapCatalog.tableCategory : #TRANSPARENT @AbapCatalog.deliveryClass : #A @AbapCatalog.dataMaintenance : #ALLOWED define table zml_travel { key client : abap.clnt not null; key travel_id : sysuuid_x16 not null; name : zmlname; }</code></pre><P><STRONG>1--4-- create table ZML_BOOKING</STRONG></P><P>You add new Database Table `ZML_BOOKING` by this code into package ZMLODATA:</P><pre class="lia-code-sample language-abap"><code>@EndUserText.label : 'ZML_BOOKING' @AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE @AbapCatalog.tableCategory : #TRANSPARENT @AbapCatalog.deliveryClass : #A @AbapCatalog.dataMaintenance : #ALLOWED define table zml_booking { key client : abap.clnt not null; @AbapCatalog.foreignKey.screenCheck : false key travel_id : sysuuid_x16 not null with foreign key [0..*,1] zml_travel where travel_id = zml_booking.travel_id; key booking_id : sysuuid_x16 not null; hotel : zmlname; dayfrom : zmldatefrom; dayto : zmldateto; }</code></pre><P><STRONG>1--5-- Create Class `zml_gen_data_travels`</STRONG></P><P>In package ZMLODATA you add new ABAP class&nbsp;<STRONG>`zml_gen_data_travels`</STRONG> by this code:&nbsp;</P><pre class="lia-code-sample language-abap"><code>CLASS zml_gen_data_travels DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_oo_adt_classrun . PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zml_gen_data_travels IMPLEMENTATION. METHOD if_oo_adt_classrun~main. DATA it_travel TYPE TABLE OF zml_travel. DATA it_booking TYPE TABLE OF zml_booking. DATA lv_long_time_stamp TYPE timestampl. GET TIME STAMP FIELD lv_long_time_stamp. DATA: l_uuid_x16 TYPE sysuuid_x16. DATA: system_uuid TYPE REF TO if_system_uuid. DATA: oref TYPE REF TO cx_uuid_error. system_uuid = cl_uuid_factory=&gt;create_system_uuid( ). TRY. it_travel = VALUE #( ( client = sy-mandt travel_id = system_uuid-&gt;create_uuid_x16( ) name = 'Travel Minsk - Dubai' ) ( client = sy-mandt travel_id = system_uuid-&gt;create_uuid_x16( ) name = 'Travel Minsk - Moscow' ) ( client = sy-mandt travel_id = system_uuid-&gt;create_uuid_x16( ) name = 'Travel Minsk - Warsaw' ) ( client = sy-mandt travel_id = system_uuid-&gt;create_uuid_x16( ) name = 'Travel Minsk - Dushanbe' ) ( client = sy-mandt travel_id = system_uuid-&gt;create_uuid_x16( ) name = 'Travel Minsk - Batumi' ) ). it_booking = VALUE #( ( client = sy-mandt booking_id = system_uuid-&gt;create_uuid_x16( ) travel_id = it_travel[ name = 'Travel Minsk - Dubai' ]-travel_id dayfrom = '20240101' dayto = '20240104' hotel = 'Amirates Dubai' ) ( client = sy-mandt booking_id = system_uuid-&gt;create_uuid_x16( ) travel_id = it_travel[ name = 'Travel Minsk - Moscow' ]-travel_id dayfrom = '20240105' dayto = '20240107' hotel = 'Marriot' ) ( client = sy-mandt booking_id = system_uuid-&gt;create_uuid_x16( ) travel_id = it_travel[ name = 'Travel Minsk - Warsaw' ]-travel_id dayfrom = '20240108' dayto = '20240114' hotel = 'Outstanding WSW' ) ( client = sy-mandt booking_id = system_uuid-&gt;create_uuid_x16( ) travel_id = it_travel[ name = 'Travel Minsk - Dushanbe' ]-travel_id dayfrom = '20240115' dayto = '20240124' hotel = 'Marriot Hayat' ) ( client = sy-mandt booking_id = system_uuid-&gt;create_uuid_x16( ) travel_id = it_travel[ name = 'Travel Minsk - Batumi' ]-travel_id dayfrom = '20240125' dayto = '20240130' hotel = 'Amber Sea' ) ). out-&gt;write( it_travel ). out-&gt;write( it_booking ). * delete existing entries in the database table DELETE FROM zml_booking. DELETE FROM zml_travel. * insert the new table entries INSERT zml_travel FROM TABLE <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1442952">@IT</a>_travel. INSERT zml_booking FROM TABLE <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1442952">@IT</a>_booking. out-&gt;write( |Demo data generated for tables...| ). CATCH cx_uuid_error. "handle exception ENDTRY. ENDMETHOD. ENDCLASS.</code></pre><P><STRONG>1--6-- Run this class by pressing F9</STRONG></P><P>You execute previously created class to add initial records into your data model by pressing F9.</P><P>5 records with travels and 5 records connected to each travel for bookings will be added after executing.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_6-1714379019625.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103023iE0F7B036AEF8ECB4/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_6-1714379019625.png" alt="lukcad_6-1714379019625.png" /></span></P><P><STRONG>1--7-- at this moment you should have package with your dictionary and class</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_7-1714379019627.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103022i528506E8D85AE55C/image-size/medium?v=v2&amp;px=400" role="button" title="lukcad_7-1714379019627.png" alt="lukcad_7-1714379019627.png" /></span></P><P><STRONG>1--8-- you open data tables by preview of data&nbsp; to find that test records exist:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_8-1714379019628.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103021i011646A5AE2F4111/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_8-1714379019628.png" alt="lukcad_8-1714379019628.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_9-1714379019629.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103025i980159BA3FDABE5F/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_9-1714379019629.png" alt="lukcad_9-1714379019629.png" /></span></P><P><STRONG>2-- create project for OData service</STRONG></P><P>You press Alt-F8 and enter and run transaction:&nbsp;<STRONG>SEGW</STRONG></P><P>In opened form you press icon of "Create project"</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_10-1714379019629.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103026iA3C1577DC7BEE318/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_10-1714379019629.png" alt="lukcad_10-1714379019629.png" /></span></P><P>You fill in this information on form of creating project:</P><TABLE><TBODY><TR><TD><P>Project</P></TD><TD><P>ZML_TRAVELLING_ODT</P></TD></TR><TR><TD><P>Description</P></TD><TD><P>OData for travelling data</P></TD></TR><TR><TD><P>Package</P></TD><TD><P>ZMLODATA</P></TD></TR></TBODY></TABLE><P>You get a project `ZML_TRAVELLING_ODT` which has initial skeleton without connectivity to your model at this moment:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_11-1714379019630.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103024iBA8FC188F2D000BF/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_11-1714379019630.png" alt="lukcad_11-1714379019630.png" /></span></P><P><STRONG>3-- Add data model and generate service</STRONG></P><P>Using project `ZML_TRAVELLING_ODT` you do the next steps to import your entitles of model one by one, make necessary association between entities and generate project.</P><P><STRONG>3--1-- Add Entity Type for ZML_TRAVEL table</STRONG></P><P>Change project `ZML_TRAVELLING_ODT` to Edit mode.</P><P>Using context menu of<STRONG> Data model</STRONG> node you have to choose: Import -&gt; DDIC Stucture</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_12-1714379019630.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103027i328AE5AE05C57F8B/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_12-1714379019630.png" alt="lukcad_12-1714379019630.png" /></span></P><P>On first step of import wizard you provide the next information:</P><TABLE><TBODY><TR><TD><P>Name of type which we want create:</P></TD><TD><P>ZML_ITRAVEL</P></TD></TR><TR><TD><P>ABAP Structure (existing our table):</P></TD><TD><P>ZML_TRAVEL</P></TD></TR></TBODY></TABLE><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_13-1714379019631.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103028iDA0F53394ED06AAC/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_13-1714379019631.png" alt="lukcad_13-1714379019631.png" /></span></P><P>On second step mark all fields:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_14-1714379019631.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103029i4FADEC10D9E6FEE0/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_14-1714379019631.png" alt="lukcad_14-1714379019631.png" /></span></P><P>On third step point the key of your records as TRAVEL_ID</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_15-1714379019632.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103032i389438640E4F598D/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_15-1714379019632.png" alt="lukcad_15-1714379019632.png" /></span></P><P>In imported properties provide correctly operations:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_16-1714379019632.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103030i3CEB819484666FE8/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_16-1714379019632.png" alt="lukcad_16-1714379019632.png" /></span></P><P>if you open Entity Sets you should be able to find there `ZML_ITRAVELSet`</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_17-1714379019633.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103031i5966F73DBCEC1944/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_17-1714379019633.png" alt="lukcad_17-1714379019633.png" /></span></P><P><STRONG>3--2-- Add Entity Type for ZML_BOOKING table</STRONG></P><P>Again, you using context menu of<STRONG> Data model</STRONG> node choose Import -&gt; DDIC Structure to open Wizard of importing.</P><P>On the first step of import wizard you provide:</P><TABLE><TBODY><TR><TD><P>Name of type which we want create:</P></TD><TD><P>ZML_IBOOKING</P></TD></TR><TR><TD><P>ABAP Structure (existing our table):</P></TD><TD><P>ZML_BOOKING</P></TD></TR></TBODY></TABLE><P>On second step of wizard you select all fields of entity.</P><P>And on the 3d&nbsp; step of wizard you point key id BOOKING_ID :</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_18-1714379019634.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103033iECE83CFB16A6964B/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_18-1714379019634.png" alt="lukcad_18-1714379019634.png" /></span></P><P><STRONG>3--3-- Add association between ZML_ITRAVEL and ZML_IBOOKING</STRONG></P><P>Using context menu on <STRONG>Association node</STRONG> you choose `Create` to start the wizard of creating association.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_19-1714379019635.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103034i990537FBA61CF5F4/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_19-1714379019635.png" alt="lukcad_19-1714379019635.png" /></span></P><P>You should provide these parameters on Step 1 of association wizard:</P><TABLE><TBODY><TR><TD><P>Association Name</P></TD><TD><P>ZML_TRAVEL_TO_BOOKING</P></TD></TR><TR><TD><P>Principal Entity Type Name</P></TD><TD><P>ZML_ITRAVEL</P></TD></TR><TR><TD><P>Principal Cardinality</P></TD><TD><P>1</P></TD></TR><TR><TD><P>Principal Navigation Property</P></TD><TD><P>TO_BOOKING</P></TD></TR><TR><TD><P>Dependent Entity Type Name</P></TD><TD><P>ZML_IBOOKING</P></TD></TR><TR><TD><P>Dependent Cardinality</P></TD><TD><P>0..n</P></TD></TR><TR><TD><P>Dependent Navigation Property</P></TD><TD><P>&nbsp;</P></TD></TR></TBODY></TABLE><P>On Step 2 of wizard association you point principal key TravelId for `Dependent Property`:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_20-1714379019635.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103035i2978F2E551CD271F/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_20-1714379019635.png" alt="lukcad_20-1714379019635.png" /></span></P><P>On Step 3 of wizard association you press Finish</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_21-1714379019636.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103036i6C3CD3D047E2E333/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_21-1714379019636.png" alt="lukcad_21-1714379019636.png" /></span></P><P>You can check association in node Associations:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_22-1714379019636.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103038i33407E849CF27326/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_22-1714379019636.png" alt="lukcad_22-1714379019636.png" /></span></P><P>Also, you can check as `Navigation Property` with name `TO_BOOKING` if you expand <STRONG>Entity Types</STRONG> nodes in Data Model of project. The existence of this navigation property after applying association and the name `TO_BOOKING` we will use for `expand` functionality as well as for `deep insert` functionality</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_23-1714379019637.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103037iA60FE5810F8554AF/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_23-1714379019637.png" alt="lukcad_23-1714379019637.png" /></span></P><P><STRONG>3--4-- Generate Runtime Objects of OData service</STRONG></P><P>You press icon `Generate Runtime Objects`</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_24-1714379019638.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103039i9595DEB3592E2F72/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_24-1714379019638.png" alt="lukcad_24-1714379019638.png" /></span></P><P>As a result, 4 classes with prefix `<STRONG>ZCL_</STRONG>` will be generated in your package. Currently, all methods to serve ZML_IBTRAVELSET and ZML_IBOOKINGSET entity types will be pre-filled in with pattern of raising exception to generate message that method is not implemented yet.&nbsp; Later on, you will do implementation of each method in classes with `<STRONG>_EXT</STRONG>` suffix by overriding methods.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_25-1714379019638.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103041iF7BC923D87585097/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_25-1714379019638.png" alt="lukcad_25-1714379019638.png" /></span></P><P><STRONG>4-- Register service and do initial test</STRONG></P><P>You should register service into SAP gateway and verify that service is maintained by initial test. It is better to do now, before you start implementation of methods to let you be ensured that service engin is generated correctly and you were able to maintain it correctly into SAP Gateway.</P><P><STRONG>4--1-- Register service</STRONG></P><P>In project open node `Service maintenance` and choose accessible SAP Gateway and press button `+Register` and then on prefilled form choose package ZMLODATA and save registration.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_26-1714379019639.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103040i9C2BC56C78DAC13C/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_26-1714379019639.png" alt="lukcad_26-1714379019639.png" /></span></P><P>After registration you will be re-directed to Service Maintenance list ( also you can use transaction to be there in any time: /IWFND/MAINT_SERVICE ) where you can choose your service by technical name 1ZML_TRAVELLING_ODT`.</P><P><STRONG>4--2-- Initial test</STRONG></P><P>Once your service is registered you can test it by `SAP Gateway Client` through opening Maintenance list and then after choosing your service using ICF Nodes panel do pressing on `SAP Gateway Client` or you can directly start testing client form Service Maintenance of chosen gateway by pressing button `SAP Gateway Client` on form of Service registration.</P><P>Press `SAP Gateway Client` and and execute proposed URI and check that you have HTTP response with status 200 OK</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_27-1714379019640.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103044i25445BED109D63EC/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_27-1714379019640.png" alt="lukcad_27-1714379019640.png" /></span></P><P>change URI to ask provide operations with format JSON (just change format=xml to <STRONG>format=json</STRONG>)</P><P><STRONG>/sap/opu/odata/sap/ZML_TRAVELLING_ODT_SRV/?$format=json</STRONG></P><P>and execute to verify that you can get JSON response with status <STRONG>200 Ok</STRONG> :</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_28-1714379019642.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103042iE1AAD493C68B0F45/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_28-1714379019642.png" alt="lukcad_28-1714379019642.png" /></span></P><P>So currently OData which you created has information about your entities but if you try to use those entities (datasets) you will have error, because entities are not still connected to your data in databases.</P><P>if you will try to run this request:</P><P><STRONG>/sap/opu/odata/sap/ZML_TRAVELLING_ODT_SRV/ZML_ITRAVELSet?$format=json</STRONG></P><P>instead of data in response you will find <STRONG>error 501</STRONG> and message "<STRONG>Method 'ZML_ITRAVELSET_GET_ENTITYSET' not implemented in data provider class</STRONG>"</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_29-1714379019643.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103043i1CF80F9769FB3C99/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_29-1714379019643.png" alt="lukcad_29-1714379019643.png" /></span></P><P>In next steps (5,6,7) you will implement all necessary methods.</P><P><STRONG>5-- Implementation of `deep insert` MODEL via override</STRONG></P><P>As developer, you should modify class which is dedicated for extending object model of implementation: `<STRONG>zcl_zml_travelling_odt_mpc_ext`</STRONG> where name of class is proposed during generating service and the name of class for extending model by default is a combination:&nbsp; `ZCL`_ + &lt;name_of_service&gt; + `_MPC_EXT`</P><P>you will add manually the new deep structure there and do override of existing method `<STRONG>define</STRONG>` to be able map structure to certain entity.</P><P>This implementation is important to enable using structure for `<STRONG>deep insert</STRONG>` which will be needing to write correctly code for method CREATE of entity ZML_ITRAVELSet,.</P><P><STRONG>5--1-- Add structure for `deep insert`</STRONG></P><P>Open class for extending `<STRONG>zcl_zml_travelling_odt_mpc_ext`</STRONG> which is here:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_30-1714379019643.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103046iF7918FD1097BE8FA/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_30-1714379019643.png" alt="lukcad_30-1714379019643.png" /></span></P><P>You should add new type for structure of deep insert which is based on your types of data sets.</P><P>Goal to create hierarchy of types:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_50-1714381260523.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103085iBD9EDE6F12480701/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_50-1714381260523.png" alt="lukcad_50-1714381260523.png" /></span></P><P>In public section of extension class <STRONG>zcl_zml_travelling_odt_mpc_ext</STRONG> you should add new structure:</P><pre class="lia-code-sample language-abap"><code> TYPES: BEGIN OF ty_s_trv_book. INCLUDE TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. TYPES: to_booking TYPE STANDARD TABLE OF zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking WITH DEFAULT KEY, END OF ty_s_trv_book.</code></pre><P>Name of structure for this particular example is `<STRONG>ty_s_trv_book</STRONG>`.</P><P><STRONG>5--2-- Override method `define`</STRONG></P><P>Open in editor class <STRONG>zcl_zml_travelling_odt_mpc_ext</STRONG> and press Ctrl + space and choose <STRONG>Override `define`</STRONG>.</P><P>In overridden method is main aim is to map entity type of service to new structure of `deep insert`.&nbsp;Code of overridden method `<STRONG>define</STRONG>`:</P><pre class="lia-code-sample language-abap"><code> METHOD define. DATA lo_entity_type TYPE REF TO /iwbep/if_mgw_odata_entity_typ. super-&gt;define( ). lo_entity_type = model-&gt;get_entity_type( iv_entity_name = 'ZML_ITRAVEL' ). lo_entity_type-&gt;bind_structure( iv_structure_name = 'zcl_zml_travelling_odt_mpc_ext=&gt;ty_s_trv_book' ). ENDMETHOD.</code></pre><P>&nbsp;</P><P><STRONG>5--3-- Full code of extension method after preparation of `deep insert`:</STRONG></P><pre class="lia-code-sample language-abap"><code>CLASS zcl_zml_travelling_odt_mpc_ext DEFINITION PUBLIC INHERITING FROM zcl_zml_travelling_odt_mpc CREATE PUBLIC . PUBLIC SECTION. TYPES: BEGIN OF ty_s_trv_book. INCLUDE TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. TYPES: to_booking TYPE STANDARD TABLE OF zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking WITH DEFAULT KEY, END OF ty_s_trv_book. METHODS define REDEFINITION. PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_zml_travelling_odt_mpc_ext IMPLEMENTATION. METHOD define. DATA lo_entity_type TYPE REF TO /iwbep/if_mgw_odata_entity_typ. super-&gt;define( ). lo_entity_type = model-&gt;get_entity_type( iv_entity_name = 'ZML_ITRAVEL' ). lo_entity_type-&gt;bind_structure( iv_structure_name = 'zcl_zml_travelling_odt_mpc_ext=&gt;ty_s_trv_book' ). ENDMETHOD. ENDCLASS.</code></pre><P><STRONG>6-- Implementation of entity modification methods</STRONG></P><P>As developer, you should modify class which is dedicated for extending methods to work with data: `<STRONG>zcl_zml_travelling_odt_dpc_ext`</STRONG> where name of class is proposed during generating service and the name of class for extending data methods is combination of by default:&nbsp; `ZCL`_ + &lt;name_of_service&gt; + `_DPC_EXT`</P><P>Before start extending OData CRUD methods, you add 3 custom methods in this particular case:</P><P><STRONG>6--1-- add custom method `zml_create_uuid` for getting UUID:</STRONG></P><P>In protected section of class definition add:</P><pre class="lia-code-sample language-abap"><code> METHODS zml_create_uuid RETURNING VALUE(es_uuid) TYPE sysuuid_x16.</code></pre><P>In implementation area of class add:</P><pre class="lia-code-sample language-abap"><code> METHOD zml_create_uuid. DATA lv_long_time_stamp TYPE timestampl. GET TIME STAMP FIELD lv_long_time_stamp. DATA: l_uuid_x16 TYPE sysuuid_x16. DATA: system_uuid TYPE REF TO if_system_uuid. DATA: oref TYPE REF TO cx_uuid_error. system_uuid = cl_uuid_factory=&gt;create_system_uuid( ). TRY. es_uuid = system_uuid-&gt;create_uuid_x16( ). CATCH cx_uuid_error. "handle exception ENDTRY. ENDMETHOD.</code></pre><P>&nbsp;</P><P><STRONG>6--2-- add custom method `zml_modify_travel` for update or insert ZML_TRAVEL entity:</STRONG></P><P>In protected section of class definition add:</P><pre class="lia-code-sample language-abap"><code> METHODS zml_modify_travel IMPORTING !ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel RETURNING VALUE(es_entity) TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel.</code></pre><P>&nbsp;In implementation area of class add:</P><pre class="lia-code-sample language-abap"><code> METHOD zml_modify_travel. DATA: it_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. MOVE-CORRESPONDING ls_entity TO it_entity. IF ( it_entity-client IS INITIAL ). it_entity-client = sy-mandt. ENDIF. TRY. it_entity-name = ls_entity-name. DATA itb_entity TYPE TABLE OF zml_travel. IF ( it_entity-travel_id IS INITIAL ). it_entity-travel_id = zml_create_uuid( ). itb_entity = VALUE #( ( it_entity ) ). INSERT zml_travel FROM TABLE <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1074930">@itb</a>_entity. ELSE. itb_entity = VALUE #( ( it_entity ) ). MODIFY zml_travel FROM TABLE <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1074930">@itb</a>_entity. ENDIF. es_entity = it_entity. CATCH cx_uuid_error. ENDTRY. ENDMETHOD.</code></pre><P>&nbsp;</P><P><STRONG>6--3-- add custom method `zml_modify_booking` for update or insert ZML_BOOKING entity:</STRONG></P><P>In protected section of class definition add:</P><pre class="lia-code-sample language-abap"><code> METHODS zml_modify_booking IMPORTING !ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking RETURNING VALUE(es_entity) TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking.</code></pre><P>&nbsp;In implementation area of class add:</P><pre class="lia-code-sample language-abap"><code> METHOD zml_modify_booking. DATA: it_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking. MOVE-CORRESPONDING ls_entity TO it_entity. IF ( ls_entity-client IS INITIAL ). it_entity-client = sy-mandt. ENDIF. IF ( ls_entity-travel_id IS NOT INITIAL ). TRY. DATA itb_entity TYPE TABLE OF zml_booking. IF ( it_entity-booking_id IS INITIAL ). it_entity-booking_id = zml_create_uuid( ). itb_entity = VALUE #( ( it_entity ) ). INSERT zml_booking FROM TABLE <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1074930">@itb</a>_entity. ELSE. itb_entity = VALUE #( ( it_entity ) ). MODIFY zml_booking FROM TABLE <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1074930">@itb</a>_entity. ENDIF. es_entity = it_entity. CATCH cx_uuid_error. ENDTRY. ENDIF. ENDMETHOD.</code></pre><P>&nbsp;<SPAN>&nbsp; &nbsp;</SPAN></P><P><STRONG>6--4-- add custom method `deep_insert_travel_booking` for insert ZML_TRAVEL and ZML_BOOKING entities:</STRONG></P><P>In protected section of class definition add:</P><pre class="lia-code-sample language-abap"><code> METHODS deep_insert_travel_booking IMPORTING !io_data_provider TYPE REF TO /iwbep/if_mgw_entry_provider EXPORTING !es_s_trv_book TYPE zcl_zml_travelling_odt_mpc_ext=&gt;ty_s_trv_book RAISING /iwbep/cx_mgw_busi_exception /iwbep/cx_mgw_tech_exception .</code></pre><P>&nbsp; In implementation area of class add:</P><pre class="lia-code-sample language-abap"><code> METHOD deep_insert_travel_booking. DATA: ls_travel_booking_data TYPE zcl_zml_travelling_odt_mpc_ext=&gt;ty_s_trv_book. DATA: ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. DATA: ls_childentity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking. DATA: ar_childentities TYPE STANDARD TABLE OF zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking WITH DEFAULT KEY. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_travel_booking_data ). MOVE-CORRESPONDING ls_travel_booking_data TO ls_entity. ls_entity = zml_modify_travel( ls_entity = ls_entity ). MOVE-CORRESPONDING ls_travel_booking_data-to_booking TO ar_childentities. LOOP AT ar_childentities INTO ls_childentity. ls_childentity-travel_id = ls_entity-travel_id. ls_childentity = zml_modify_booking( ls_entity = ls_childentity ). ar_childentities[ sy-index ] = ls_childentity. ENDLOOP. MOVE-CORRESPONDING ls_entity TO es_s_trv_book. MOVE-CORRESPONDING ar_childentities TO es_s_trv_book-to_booking. ENDMETHOD.</code></pre><P>&nbsp;<STRONG>7-- Implementation of OData CRUD methods using override</STRONG></P><P><STRONG>7--1-- Start override methods</STRONG></P><P>Open class `<STRONG>ZCL_ZML_TRAVELLING_ODT_DPC_EXT</STRONG>` (name of class is proposed during generating for overriding and the name of class is combination of by default:&nbsp; `ZCL`_ + &lt;name_of_service&gt; + `_DPC_EXT`</P><P>This is generated class and will be regenerated if you need put changes in model and generate service once again.</P><P>SAP has classes for extending generated code, and those classes will not be re-created during generating, so your changes will be applicable after regenerating once again.</P><P>You can override any method by using Ctrl + space and choosing method for override from list:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_31-1714379019645.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103047iCAD883F3845C5B31/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_31-1714379019645.png" alt="lukcad_31-1714379019645.png" /></span></P><P><STRONG>7--2-- override method `/iwbep/if_mgw_appl_srv_runtime~create_deep_entity` manually </STRONG></P><P>This is single method which we do overriding manually and with definition in PUBLIC SECTION of class.</P><P>Add to PUBLIC SECTION this redefinition:</P><pre class="lia-code-sample language-abap"><code>METHODS /iwbep/if_mgw_appl_srv_runtime~create_deep_entity REDEFINITION.</code></pre><P>&nbsp; Add to implementation area:</P><pre class="lia-code-sample language-abap"><code> METHOD /iwbep/if_mgw_appl_srv_runtime~create_deep_entity. DATA: ls_travel_booking_data TYPE zcl_zml_travelling_odt_mpc_ext=&gt;ty_s_trv_book. CLEAR: er_deep_entity. TRY. CALL METHOD deep_insert_travel_booking EXPORTING io_data_provider = io_data_provider IMPORTING es_s_trv_book = ls_travel_booking_data. copy_data_to_ref( EXPORTING is_data = ls_travel_booking_data CHANGING cr_data = er_deep_entity ). CATCH /iwbep/cx_mgw_busi_exception. ENDTRY. ENDMETHOD.</code></pre><P>&nbsp;<STRONG>7--3-- override method `zml_itravelset_update_entity`</STRONG></P><pre class="lia-code-sample language-abap"><code> METHOD zml_itravelset_update_entity. DATA: ls_converted_keys TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel, ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). IF ( ls_entity-travel_id IS INITIAL ). io_tech_request_context-&gt;get_converted_keys( IMPORTING es_key_values = ls_converted_keys ). ls_entity-travel_id = ls_converted_keys-travel_id. ENDIF. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). CLEAR er_entity. er_entity = zml_modify_travel( ls_entity = ls_entity ). ENDMETHOD.</code></pre><P>&nbsp;<STRONG>7--4-- override method `zml_itravelset_delete_entity`</STRONG></P><pre class="lia-code-sample language-abap"><code> METHOD zml_itravelset_delete_entity. DATA: ls_converted_keys TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. io_tech_request_context-&gt;get_converted_keys( IMPORTING es_key_values = ls_converted_keys ). DELETE FROM zml_booking WHERE travel_id = ls_converted_keys-travel_id. DELETE FROM zml_travel WHERE travel_id = ls_converted_keys-travel_id. ENDMETHOD.</code></pre><P>&nbsp;<STRONG>7--5-- override method `zml_itravelset_create_entity`</STRONG></P><pre class="lia-code-sample language-abap"><code> METHOD zml_itravelset_create_entity. DATA: ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). CLEAR er_entity. er_entity = zml_modify_travel( ls_entity = ls_entity ). ENDMETHOD.</code></pre><P>&nbsp;<STRONG>7--6-- override method `zml_ibookingset_get_entity`</STRONG></P><pre class="lia-code-sample language-abap"><code> METHOD zml_ibookingset_get_entity. DATA:ls_keytab TYPE LINE OF /iwbep/t_mgw_name_value_pair. LOOP AT it_key_tab INTO ls_keytab. ENDLOOP. IF ( ls_keytab-name = 'BookingId' ). SELECT SINGLE * FROM zml_booking INTO CORRESPONDING FIELDS OF er_entity WHERE booking_id = ls_keytab-value. ELSEIF ( ls_keytab-name = 'TravelId' ). SELECT SINGLE * FROM zml_booking INTO CORRESPONDING FIELDS OF er_entity WHERE travel_id = ls_keytab-value. ENDIF. ENDMETHOD.</code></pre><P>&nbsp;<STRONG>7--7-- override method `zml_itravelset_get_entity`</STRONG></P><pre class="lia-code-sample language-abap"><code> METHOD zml_itravelset_get_entity. DATA:ls_keytab TYPE LINE OF /iwbep/t_mgw_name_value_pair. LOOP AT it_key_tab INTO ls_keytab. ENDLOOP. IF ( ls_keytab-name = 'BookingId' ). DATA: lv_travel_id TYPE zml_booking-travel_id. SELECT SINGLE travel_id FROM zml_booking INTO lv_travel_id WHERE booking_id = ls_keytab-value. IF sy-subrc = 0. SELECT SINGLE * FROM zml_travel INTO CORRESPONDING FIELDS OF er_entity WHERE travel_id = lv_travel_id. ENDIF. ELSEIF ( ls_keytab-name = 'TravelId' ). SELECT SINGLE * FROM zml_travel INTO CORRESPONDING FIELDS OF er_entity WHERE travel_id = ls_keytab-value. ENDIF. ENDMETHOD.</code></pre><P>&nbsp;<STRONG>7--8-- override method `zml_ibookingset_get_entityset`</STRONG></P><pre class="lia-code-sample language-abap"><code> METHOD zml_ibookingset_get_entityset. DATA:ls_keytab TYPE LINE OF /iwbep/t_mgw_name_value_pair. LOOP AT it_key_tab INTO ls_keytab. ENDLOOP. IF ( ls_keytab IS NOT INITIAL ). IF ( ls_keytab-name = 'BookingId' ). SELECT * FROM zml_booking INTO CORRESPONDING FIELDS OF TABLE et_entityset WHERE booking_id = ls_keytab-value. ELSEIF ( ls_keytab-name = 'TravelId' ). DATA: lv_travel_id TYPE zml_travel-travel_id. SELECT SINGLE travel_id FROM zml_booking INTO lv_travel_id WHERE travel_id = ls_keytab-value. SELECT * FROM zml_booking INTO CORRESPONDING FIELDS OF TABLE et_entityset WHERE travel_id = lv_travel_id. ENDIF. ELSE. SELECT * FROM zml_booking INTO CORRESPONDING FIELDS OF TABLE et_entityset. ENDIF. ENDMETHOD.</code></pre><P>&nbsp;<STRONG>7--9-- override method `zml_itravelset_get_entityset`</STRONG></P><pre class="lia-code-sample language-abap"><code> METHOD zml_itravelset_get_entityset. DATA: lv_source_entity_set_name TYPE /iwbep/mgw_tech_name. lv_source_entity_set_name = io_tech_request_context-&gt;get_source_entity_set_name( ). IF lv_source_entity_set_name IS INITIAL. SELECT * FROM zml_travel INTO CORRESPONDING FIELDS OF TABLE et_entityset. ELSE. SELECT * FROM zml_travel INTO CORRESPONDING FIELDS OF TABLE et_entityset. ENDIF. ENDMETHOD.</code></pre><P>&nbsp;<STRONG>7--10-- override method `zml_ibookingset_update_entity`</STRONG></P><pre class="lia-code-sample language-abap"><code> method zml_ibookingset_update_entity. DATA: ls_converted_keys TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking, ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). IF ( ls_entity-booking_id IS INITIAL ). io_tech_request_context-&gt;get_converted_keys( IMPORTING es_key_values = ls_converted_keys ). ls_entity-booking_id = ls_converted_keys-booking_id. ENDIF. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). CLEAR er_entity. er_entity = zml_modify_booking( ls_entity = ls_entity ). endmethod.</code></pre><P>&nbsp;<STRONG>7--11-- override method `zml_ibookingset_delete_entity`</STRONG></P><pre class="lia-code-sample language-abap"><code> method zml_ibookingset_delete_entity. DATA: ls_converted_keys TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking. io_tech_request_context-&gt;get_converted_keys( IMPORTING es_key_values = ls_converted_keys ). DELETE FROM zml_booking WHERE booking_id = ls_converted_keys-booking_id. endmethod.</code></pre><P><STRONG>7--12-- override method `zml_ibookingset_create_entity`</STRONG></P><pre class="lia-code-sample language-abap"><code> method zml_ibookingset_create_entity. DATA: ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). CLEAR er_entity. er_entity = zml_modify_booking( ls_entity = ls_entity ). endmethod.</code></pre><P>&nbsp;<STRONG>8-- Testing CRUD methods by SAP Gateway Client</STRONG></P><P><STRONG>8--1-- GET all records from entities</STRONG></P><P><STRONG>8--1--1-- GET entities with query parameter $format=json</STRONG></P><P>Check again by SAP Gateway Client that you can extract data from ZML_ITRAVELSet and for ZML_IBOOKINGSet</P><P><STRONG>/sap/opu/odata/sap/ZML_TRAVELLING_ODT_SRV/ZML_ITRAVELSet?$format=json</STRONG></P><P><STRONG>/sap/opu/odata/sap/ZML_TRAVELLING_ODT_SRV/ZML_IBOOKINGSet?$format=json</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_32-1714379019646.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103045iCA6B82061A9A4A40/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_32-1714379019646.png" alt="lukcad_32-1714379019646.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_33-1714379019647.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103049i50982F6F23320FD0/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_33-1714379019647.png" alt="lukcad_33-1714379019647.png" /></span></P><P><STRONG>8--1--2-- GET entities by using header parameters instead of query parameter</STRONG></P><P>You need to be able to add header parameters because in json it is easier to operate and some operation will work only with header (POST, PATCH, PUT and DELETE)</P><P>So look at screenshots below how you can add parameters and all rest screenshots will have always header parameters for your understanding.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_34-1714379019648.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103050i5CD956B3E9BB1666/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_34-1714379019648.png" alt="lukcad_34-1714379019648.png" /></span></P><P>It is right to keep these two parameters added&nbsp; for all operations:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_35-1714379019649.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103048i97FBC061FBD6644C/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_35-1714379019649.png" alt="lukcad_35-1714379019649.png" /></span></P><P>and add this parameter only for PATCH, PUT, and DELETE:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_36-1714379019649.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103051iDDEA37ED95556505/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_36-1714379019649.png" alt="lukcad_36-1714379019649.png" /></span></P><P><STRONG>8--2-- GET specific record from entity</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_37-1714379019650.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103052i36B24FEC513B071E/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_37-1714379019650.png" alt="lukcad_37-1714379019650.png" /></span></P><P><STRONG>8--3-- GET specific record with details using EXPAND</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_38-1714379019651.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103053i13EBC1523650A38C/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_38-1714379019651.png" alt="lukcad_38-1714379019651.png" /></span></P><P><STRONG>8--4-- PUT change record to change.</STRONG></P><P>8--4--1-- PUT for ZML_ITRAVELSet it will be:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_39-1714379019652.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103054i99AE990DBF0E6A9C/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_39-1714379019652.png" alt="lukcad_39-1714379019652.png" /></span></P><P><STRONG>8--4--2-- PUT for ZML_IBOOKINGSet it will be:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_40-1714379019653.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103055i2E9BB74257CDEC1B/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_40-1714379019653.png" alt="lukcad_40-1714379019653.png" /></span></P><P>You can verify if data were successfully applied by GET:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_41-1714379019654.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103056i9E49A99D6613EFB0/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_41-1714379019654.png" alt="lukcad_41-1714379019654.png" /></span></P><P><STRONG>8--6-- PATCH change only pointed parameters.</STRONG></P><P><STRONG>8--6--1-- PATCH for entity ZML_ITRAVELSet:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_42-1714379019655.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103058iACA5861B4E0A7CEE/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_42-1714379019655.png" alt="lukcad_42-1714379019655.png" /></span></P><P><STRONG>8--6--2-- PATCH for entity ZML_IBOOKINGSet:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_43-1714379019656.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103057iE1C25F3C49E2182C/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_43-1714379019656.png" alt="lukcad_43-1714379019656.png" /></span></P><P>You can verify if it was changes by GET:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_44-1714379019656.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103059iB4A064835DE1765D/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_44-1714379019656.png" alt="lukcad_44-1714379019656.png" /></span></P><P><STRONG>8--8-- DELETE -remove record and all child records</STRONG></P><P><STRONG>8--8--1-- DELETE for entity ZML_ITRAVELSet</STRONG></P><P>Your code you can check and in code we delete child records from ZML_IBOOKINGSet and then record from ZML_ITRAVELSet. But it is up to you have this logic. You can allow delete only if childe records were delete previously. Just for simplicity we do deleting as cascade.</P><P><STRONG>Notice</STRONG>: parameter `if-match` should be removed from header, overwise you will have error.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_45-1714379019657.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103060iA102B6961282F514/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_45-1714379019657.png" alt="lukcad_45-1714379019657.png" /></span></P><P><STRONG>8--8--2-- DELETE for entity ZML_IBOOKINGSet</STRONG></P><P><STRONG>Notice</STRONG>: parameter `if-match` should be removed from header, overwise you will have error.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_46-1714379019658.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103061i675D2A05E6927194/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_46-1714379019658.png" alt="lukcad_46-1714379019658.png" /></span></P><P><STRONG>8--9-- INSERT - add new records</STRONG></P><P><STRONG>8--9--1-- INSERT for entity set `ZML_ITRAVELSet`</STRONG></P><P>You have implemented `<STRONG>deep insert</STRONG>` with deep structure. So you expect to create complex records when you POST entity ZML_ITRAVELSet. It will be one record for ZML_ITRAVELSet and related records (child records) for entity ZML_IBOOKINGSet. Deep structure supposes to use head structure from ZML_ITRAVELSet and child structure with name `TO_BOOK` from ZML_IBOOKINGSet. So you have to prepare request with such payload:</P><pre class="lia-code-sample language-json"><code>{ "Client" : "001", "Name" : "Travel Minsk - Milano", "TO_BOOKING": [ { "Client" : "001", "Hotel" : "Ahmat hotel", "Dayfrom" : "\/Date(1481760000000)\/", "Dayto" : "\/Date(1481760000000)\/" }, { "Client" : "001", "Hotel" : "Yes hotel", "Dayfrom" : "\/Date(1481760000000)\/", "Dayto" : "\/Date(1481760000000)\/" } ] }</code></pre><P>you point this URI:</P><P><STRONG>/sap/opu/odata/SAP/ZML_TRAVELLING_ODT_SRV/ZML_ITRAVELSet</STRONG></P><P>and you choose method: <STRONG>POST</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_47-1714379019659.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103062iFE4D42269C5C37B0/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_47-1714379019659.png" alt="lukcad_47-1714379019659.png" /></span></P><P><STRONG>8--9--2-- INSERT for entity set `ZML_IBOOKINGSet`</STRONG></P><P>You should know GUID of your parent record for ZML_ITRAVELSet</P><pre class="lia-code-sample language-json"><code>{ "TravelId" : "0242ac11-0002-1eef-80aa-0315685dd657", "Hotel" : "Amirates Dubai stars", "Dayfrom" : "\/Date(1704067200000)\/", "Dayto" : "\/Date(1704326400000)\/" }</code></pre><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_48-1714379019660.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103063i36B631197164C122/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_48-1714379019660.png" alt="lukcad_48-1714379019660.png" /></span></P><P>Response contains payload about what has been added and and which Booking Id was created.</P><P>If you wish you can GET particular record by using (guid' value of Booking Id ') :</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lukcad_49-1714379019661.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/103064iA6A0F31D5751ACC3/image-size/large?v=v2&amp;px=999" role="button" title="lukcad_49-1714379019661.png" alt="lukcad_49-1714379019661.png" /></span></P><P><STRONG>9-- Verification of achieved code</STRONG></P><P>You can compare your code or if you feel that it is better to apply ready to use project and go through this document you can find this project here on GitHub:</P><P><A href="https://github.com/lukcad/ZMLODATA.git" target="_blank" rel="nofollow noopener noreferrer">https://github.com/lukcad/ZMLODATA.git</A></P><P>Also, you can verify your overridden methods for class&nbsp;<SPAN><STRONG>zcl_zml_travelling_odt_dpc_ext</STRONG> here:</SPAN></P><pre class="lia-code-sample language-abap"><code>CLASS zcl_zml_travelling_odt_dpc_ext DEFINITION PUBLIC INHERITING FROM zcl_zml_travelling_odt_dpc CREATE PUBLIC . PUBLIC SECTION. METHODS /iwbep/if_mgw_appl_srv_runtime~create_deep_entity REDEFINITION. PROTECTED SECTION. methods zml_ibookingset_update_entity redefinition. methods zml_ibookingset_delete_entity redefinition. methods zml_ibookingset_create_entity redefinition. METHODS zml_create_uuid RETURNING VALUE(es_uuid) TYPE sysuuid_x16. METHODS zml_modify_travel IMPORTING !ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel RETURNING VALUE(es_entity) TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. METHODS zml_modify_booking IMPORTING !ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking RETURNING VALUE(es_entity) TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking. METHODS deep_insert_travel_booking IMPORTING !io_data_provider TYPE REF TO /iwbep/if_mgw_entry_provider EXPORTING !es_s_trv_book TYPE zcl_zml_travelling_odt_mpc_ext=&gt;ty_s_trv_book RAISING /iwbep/cx_mgw_busi_exception /iwbep/cx_mgw_tech_exception . METHODS zml_itravelset_update_entity REDEFINITION. METHODS zml_itravelset_delete_entity REDEFINITION. METHODS zml_itravelset_create_entity REDEFINITION. METHODS zml_ibookingset_get_entity REDEFINITION. METHODS zml_itravelset_get_entity REDEFINITION. METHODS zml_ibookingset_get_entityset REDEFINITION. METHODS zml_itravelset_get_entityset REDEFINITION. PRIVATE SECTION. ENDCLASS. CLASS zcl_zml_travelling_odt_dpc_ext IMPLEMENTATION. METHOD zml_itravelset_get_entityset. DATA: lv_source_entity_set_name TYPE /iwbep/mgw_tech_name. lv_source_entity_set_name = io_tech_request_context-&gt;get_source_entity_set_name( ). IF lv_source_entity_set_name IS INITIAL. SELECT * FROM zml_travel INTO CORRESPONDING FIELDS OF TABLE et_entityset. ELSE. SELECT * FROM zml_travel INTO CORRESPONDING FIELDS OF TABLE et_entityset. ENDIF. ENDMETHOD. METHOD zml_ibookingset_get_entityset. DATA:ls_keytab TYPE LINE OF /iwbep/t_mgw_name_value_pair. LOOP AT it_key_tab INTO ls_keytab. ENDLOOP. IF ( ls_keytab IS NOT INITIAL ). IF ( ls_keytab-name = 'BookingId' ). SELECT * FROM zml_booking INTO CORRESPONDING FIELDS OF TABLE et_entityset WHERE booking_id = ls_keytab-value. ELSEIF ( ls_keytab-name = 'TravelId' ). DATA: lv_travel_id TYPE zml_travel-travel_id. SELECT SINGLE travel_id FROM zml_booking INTO lv_travel_id WHERE travel_id = ls_keytab-value. SELECT * FROM zml_booking INTO CORRESPONDING FIELDS OF TABLE et_entityset WHERE travel_id = lv_travel_id. ENDIF. ELSE. SELECT * FROM zml_booking INTO CORRESPONDING FIELDS OF TABLE et_entityset. ENDIF. ENDMETHOD. METHOD zml_itravelset_get_entity. DATA:ls_keytab TYPE LINE OF /iwbep/t_mgw_name_value_pair. LOOP AT it_key_tab INTO ls_keytab. ENDLOOP. IF ( ls_keytab-name = 'BookingId' ). DATA: lv_travel_id TYPE zml_booking-travel_id. SELECT SINGLE travel_id FROM zml_booking INTO lv_travel_id WHERE booking_id = ls_keytab-value. IF sy-subrc = 0. SELECT SINGLE * FROM zml_travel INTO CORRESPONDING FIELDS OF er_entity WHERE travel_id = lv_travel_id. ENDIF. ELSEIF ( ls_keytab-name = 'TravelId' ). SELECT SINGLE * FROM zml_travel INTO CORRESPONDING FIELDS OF er_entity WHERE travel_id = ls_keytab-value. ENDIF. ENDMETHOD. METHOD zml_ibookingset_get_entity. DATA:ls_keytab TYPE LINE OF /iwbep/t_mgw_name_value_pair. LOOP AT it_key_tab INTO ls_keytab. ENDLOOP. IF ( ls_keytab-name = 'BookingId' ). SELECT SINGLE * FROM zml_booking INTO CORRESPONDING FIELDS OF er_entity WHERE booking_id = ls_keytab-value. ELSEIF ( ls_keytab-name = 'TravelId' ). SELECT SINGLE * FROM zml_booking INTO CORRESPONDING FIELDS OF er_entity WHERE travel_id = ls_keytab-value. ENDIF. ENDMETHOD. METHOD zml_itravelset_create_entity. DATA: ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). CLEAR er_entity. er_entity = zml_modify_travel( ls_entity = ls_entity ). ENDMETHOD. method zml_ibookingset_create_entity. DATA: ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). CLEAR er_entity. er_entity = zml_modify_booking( ls_entity = ls_entity ). endmethod. METHOD zml_itravelset_delete_entity. DATA: ls_converted_keys TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. io_tech_request_context-&gt;get_converted_keys( IMPORTING es_key_values = ls_converted_keys ). DELETE FROM zml_booking WHERE travel_id = ls_converted_keys-travel_id. DELETE FROM zml_travel WHERE travel_id = ls_converted_keys-travel_id. ENDMETHOD. method zml_ibookingset_delete_entity. DATA: ls_converted_keys TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking. io_tech_request_context-&gt;get_converted_keys( IMPORTING es_key_values = ls_converted_keys ). DELETE FROM zml_booking WHERE booking_id = ls_converted_keys-booking_id. endmethod. METHOD zml_itravelset_update_entity. DATA: ls_converted_keys TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel, ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). IF ( ls_entity-travel_id IS INITIAL ). io_tech_request_context-&gt;get_converted_keys( IMPORTING es_key_values = ls_converted_keys ). ls_entity-travel_id = ls_converted_keys-travel_id. ENDIF. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). CLEAR er_entity. er_entity = zml_modify_travel( ls_entity = ls_entity ). ENDMETHOD. method zml_ibookingset_update_entity. DATA: ls_converted_keys TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking, ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). IF ( ls_entity-booking_id IS INITIAL ). io_tech_request_context-&gt;get_converted_keys( IMPORTING es_key_values = ls_converted_keys ). ls_entity-booking_id = ls_converted_keys-booking_id. ENDIF. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_entity ). CLEAR er_entity. er_entity = zml_modify_booking( ls_entity = ls_entity ). endmethod. METHOD /iwbep/if_mgw_appl_srv_runtime~create_deep_entity. DATA: ls_travel_booking_data TYPE zcl_zml_travelling_odt_mpc_ext=&gt;ty_s_trv_book. CLEAR: er_deep_entity. TRY. CALL METHOD deep_insert_travel_booking EXPORTING io_data_provider = io_data_provider IMPORTING es_s_trv_book = ls_travel_booking_data. copy_data_to_ref( EXPORTING is_data = ls_travel_booking_data CHANGING cr_data = er_deep_entity ). CATCH /iwbep/cx_mgw_busi_exception. ENDTRY. ENDMETHOD. METHOD deep_insert_travel_booking. DATA: ls_travel_booking_data TYPE zcl_zml_travelling_odt_mpc_ext=&gt;ty_s_trv_book. DATA: ls_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. DATA: ls_childentity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking. DATA: ar_childentities TYPE STANDARD TABLE OF zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking WITH DEFAULT KEY. io_data_provider-&gt;read_entry_data( IMPORTING es_data = ls_travel_booking_data ). MOVE-CORRESPONDING ls_travel_booking_data TO ls_entity. ls_entity = zml_modify_travel( ls_entity = ls_entity ). MOVE-CORRESPONDING ls_travel_booking_data-to_booking TO ar_childentities. LOOP AT ar_childentities INTO ls_childentity. ls_childentity-travel_id = ls_entity-travel_id. ls_childentity = zml_modify_booking( ls_entity = ls_childentity ). ar_childentities[ sy-index ] = ls_childentity. ENDLOOP. MOVE-CORRESPONDING ls_entity TO es_s_trv_book. MOVE-CORRESPONDING ar_childentities TO es_s_trv_book-to_booking. ENDMETHOD. METHOD zml_create_uuid. DATA lv_long_time_stamp TYPE timestampl. GET TIME STAMP FIELD lv_long_time_stamp. DATA: l_uuid_x16 TYPE sysuuid_x16. DATA: system_uuid TYPE REF TO if_system_uuid. DATA: oref TYPE REF TO cx_uuid_error. system_uuid = cl_uuid_factory=&gt;create_system_uuid( ). TRY. es_uuid = system_uuid-&gt;create_uuid_x16( ). CATCH cx_uuid_error. "handle exception ENDTRY. ENDMETHOD. METHOD zml_modify_travel. DATA: it_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_itravel. MOVE-CORRESPONDING ls_entity TO it_entity. IF ( it_entity-client IS INITIAL ). it_entity-client = sy-mandt. ENDIF. TRY. it_entity-name = ls_entity-name. DATA itb_entity TYPE TABLE OF zml_travel. IF ( it_entity-travel_id IS INITIAL ). it_entity-travel_id = zml_create_uuid( ). itb_entity = VALUE #( ( it_entity ) ). INSERT zml_travel FROM TABLE <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1074930">@itb</a>_entity. ELSE. itb_entity = VALUE #( ( it_entity ) ). MODIFY zml_travel FROM TABLE <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1074930">@itb</a>_entity. ENDIF. es_entity = it_entity. CATCH cx_uuid_error. ENDTRY. ENDMETHOD. METHOD zml_modify_booking. DATA: it_entity TYPE zcl_zml_travelling_odt_mpc=&gt;ts_zml_ibooking. MOVE-CORRESPONDING ls_entity TO it_entity. IF ( ls_entity-client IS INITIAL ). it_entity-client = sy-mandt. ENDIF. IF ( ls_entity-travel_id IS NOT INITIAL ). TRY. DATA itb_entity TYPE TABLE OF zml_booking. IF ( it_entity-booking_id IS INITIAL ). it_entity-booking_id = zml_create_uuid( ). itb_entity = VALUE #( ( it_entity ) ). INSERT zml_booking FROM TABLE <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1074930">@itb</a>_entity. ELSE. itb_entity = VALUE #( ( it_entity ) ). MODIFY zml_booking FROM TABLE <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1074930">@itb</a>_entity. ENDIF. es_entity = it_entity. CATCH cx_uuid_error. ENDTRY. ENDIF. ENDMETHOD. ENDCLASS.</code></pre><P>&nbsp;</P><P>You can use this example of OData service as start point of developing your own package with own model and own project for OData by SEGW transaction. Now you have clear understanding how it can be implemented and fulfill business requirements, especially when those require none generative approach because particular changes of methods business consider as most effective approach on working production instances.&nbsp;</P><P>Thank you for your attention and happy programming,</P><P>Yours sincerely,</P><P>Mikhail.</P><P>PS: if you missed this link:&nbsp;<A href="https://github.com/lukcad/ZMLODATA.git" target="_blank" rel="nofollow noopener noreferrer">https://github.com/lukcad/ZMLODATA.git</A></P><P>&nbsp;</P> 2024-05-03T08:33:54.245000+02:00 https://community.sap.com/t5/technology-blogs-by-members/fiori-po-approver-app-accept-and-reject-button-customization-from-ecc/ba-p/13690701 Fiori PO Approver app Accept and Reject button customization from ECC backend 2024-05-03T12:45:30.531000+02:00 jayesh_mudaliar https://community.sap.com/t5/user/viewprofilepage/user-id/230182 <P><BR />Please go through the <A title="Fiori PO Approver app Forward button customization from ECC backend" href="https://community.sap.com/t5/technology-blogs-by-members/fiori-po-approver-app-forward-button-customization-from-ecc-backend/ba-p/13580901" target="_self">Part 1 Forward Button customization</A> for better understanding.<BR /><BR />Many time there are custom requirements for which it requires the need of creating Enhancement in standard SAP functionality.</P><P><STRONG>Overview</STRONG> : PO Approvers are maintained in Release Strategy. Once the PO is generated it is set to be approved by PO approvers based on the levels maintained in PPOME structure. Only then the PO will be set to 03 status in EKKO.</P><P><STRONG>Pre-requisite</STRONG> : All the roles and authorization must be given to the approvers to access the PO Approval Tile in SAP Fiori.</P><P><STRONG>Requirement :</STRONG>&nbsp; If the approver find the PO is incorrect, he will reject the PO. The rejection of PO must contain the rejection text. Since the Text is an optional there comes up the challenge to make it mandatory.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_0-1714728155246.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/105445i32339ED69C7F9204/image-size/medium?v=v2&amp;px=400" role="button" title="jayesh_mudaliar_0-1714728155246.png" alt="jayesh_mudaliar_0-1714728155246.png" /></span></P><P>Solution:&nbsp;</P><P>There are many ways to do this&nbsp;<BR />1. Doing changes in Front-End using <STRONG>BTP/WEB IDE</STRONG>.</P><P>2. Making it mandatory from ECC</P><P>I chose the 2nd method since there was some issue in licensing the BTP and it was not configured correctly.</P><P style=" text-align: center; "><STRONG>Making it mandatory from ECC</STRONG></P><P><BR />My PO tile looks like this&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_1-1714728363065.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/105446iF97130EE3239AD3D/image-size/large?v=v2&amp;px=999" role="button" title="jayesh_mudaliar_1-1714728363065.png" alt="jayesh_mudaliar_1-1714728363065.png" /></span></P><P>When the approver click on the Reject button , he must enter the Rejection note. If he doesn't then the PO should not be rejected.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_0-1714728155246.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/105445i32339ED69C7F9204/image-size/large?v=v2&amp;px=999" role="button" title="jayesh_mudaliar_0-1714728155246.png" alt="jayesh_mudaliar_0-1714728155246.png" /></span></P><P>SAP has provided only few objects which can be modified without the BTP framework. PO Approval is one of it. The main thing to note and find the Odata.</P><P><BR /><STRONG>How to find the OData&nbsp;which will can be used for my development?</STRONG><BR />You can find the OData from going to Fiori tile -&gt; Do Frontend debugging-&gt; Refresh the page-&gt; Navigate&nbsp;to Network Tab -&gt; Find Path starting with key words&nbsp;<SPAN>/sap/opu/odata</SPAN></P><P>In my case the OData is&nbsp;<SPAN><FONT color="#00FFFF"><FONT color="#FF0000">GBAPP_POAPPROVAL</FONT></FONT></SPAN><BR /><SPAN>/sap/opu/odata/SAP/<FONT color="#00FFFF"><FONT color="#FF0000">GBAPP_POAPPROVAL</FONT></FONT></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_4-1714730619543.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/105473iCFE3D31B0F477579/image-size/large?v=v2&amp;px=999" role="button" title="jayesh_mudaliar_4-1714730619543.png" alt="jayesh_mudaliar_4-1714730619543.png" /></span></P><P>You can also find it through the XML file&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_5-1714730797939.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/105474iF251FFB9B0616D94/image-size/large?v=v2&amp;px=999" role="button" title="jayesh_mudaliar_5-1714730797939.png" alt="jayesh_mudaliar_5-1714730797939.png" /></span></P><P>Now you have the Standard OData name, it must be implemented so that it could connect with the backend system by providing the system name in External system.&nbsp;</P><P><STRONG>Odata Implementation</STRONG>: The ODATA deployment is Central HUB . We have separate GW systems for hosting Fiori Tiles.</P><P>Tcode : /n/iwfnd/maint_service</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_2-1714729367937.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/105456iC3B2581217FA8B08/image-size/large?v=v2&amp;px=999" role="button" title="jayesh_mudaliar_2-1714729367937.png" alt="jayesh_mudaliar_2-1714729367937.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_3-1714729398317.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/105457i60B32F9842C23355/image-size/large?v=v2&amp;px=999" role="button" title="jayesh_mudaliar_3-1714729398317.png" alt="jayesh_mudaliar_3-1714729398317.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_7-1714731093754.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/105476i8F62AAB6848CB0FD/image-size/large?v=v2&amp;px=999" role="button" title="jayesh_mudaliar_7-1714731093754.png" alt="jayesh_mudaliar_7-1714731093754.png" /></span></P><P>Now one must get 200 response after connecting it with backend system.&nbsp;<BR />Tcode : /n/iwfnd/gw_client</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_8-1714731232808.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/105477i7302CB66ECBDA47D/image-size/large?v=v2&amp;px=999" role="button" title="jayesh_mudaliar_8-1714731232808.png" alt="jayesh_mudaliar_8-1714731232808.png" /></span></P><P>Till now OData is successfully configured. Now its time to find the BADI in ECC system to implement. This can be found in my previous&nbsp;<A title="Fiori PO Approver app Forward button customization from ECC backend" href="https://community.sap.com/t5/technology-blogs-by-members/fiori-po-approver-app-forward-button-customization-from-ecc-backend/ba-p/13580901" target="_self">Blog</A><BR />Let me directly jump to the method which would be required to implement.<BR />The method is&nbsp;<STRONG>Change SET_DECISION method</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_9-1714731665289.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/105482iE231BA2816773A03/image-size/large?v=v2&amp;px=999" role="button" title="jayesh_mudaliar_9-1714731665289.png" alt="jayesh_mudaliar_9-1714731665289.png" /></span></P><P>Here the SAP Standard documentation is pretty clear about the way of processing. You can go through it.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_10-1714731777859.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/105487i5BCB7CF143028431/image-size/large?v=v2&amp;px=999" role="button" title="jayesh_mudaliar_10-1714731777859.png" alt="jayesh_mudaliar_10-1714731777859.png" /></span></P><P><!-- StartFragment --><STRONG>Accept : iv_decision&nbsp;= 1.</STRONG><BR /><STRONG>Reject :&nbsp;<!-- StartFragment -->iv_decision&nbsp; = 2.<BR />If you want nothing should happen mark&nbsp;<!-- StartFragment -->ev_decision_processed&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'X'</SPAN><SPAN class="">.</SPAN>&nbsp;</STRONG></P><P><!-- StartFragment --><SPAN><SPAN class="">METHOD&nbsp;</SPAN>IF_GBAPP_EX_APV_PO_RDP<SPAN class="">~</SPAN>CHANGE_SET_DECISION<SPAN class="">.</SPAN><BR /><SPAN class="">"&nbsp;Standard&nbsp;Documentation:&nbsp;Do&nbsp;not&nbsp;delete</SPAN><BR /><BR /><SPAN class="">*&nbsp;This&nbsp;method&nbsp;can&nbsp;be&nbsp;used&nbsp;to&nbsp;enable&nbsp;execution&nbsp;of&nbsp;a&nbsp;workitem</SPAN><BR /><SPAN class="">*&nbsp;without&nbsp;updating&nbsp;a&nbsp;purchase&nbsp;order.&nbsp;The&nbsp;customer&nbsp;should</SPAN><BR /><SPAN class="">*&nbsp;implement&nbsp;the&nbsp;method&nbsp;and&nbsp;call&nbsp;a&nbsp;corresponding&nbsp;function&nbsp;to&nbsp;execute</SPAN><BR /><SPAN class="">*&nbsp;the&nbsp;workitem&nbsp;followed&nbsp;by&nbsp;COMMIT&nbsp;WORK.</SPAN><BR /><SPAN class="">*&nbsp;To&nbsp;avoid&nbsp;update&nbsp;of&nbsp;the&nbsp;purchase&nbsp;order,&nbsp;it&nbsp;is&nbsp;necessary&nbsp;to&nbsp;set&nbsp;the</SPAN><BR /><SPAN class="">*&nbsp;output&nbsp;parameter&nbsp;EV_DECISION_PROCESSED&nbsp;to&nbsp;'X'.</SPAN><BR /><SPAN class="">*&nbsp;Preventing&nbsp;update&nbsp;of&nbsp;a&nbsp;document&nbsp;can&nbsp;be&nbsp;necessary,&nbsp;if&nbsp;the&nbsp;customer</SPAN><BR /><SPAN class="">*&nbsp;uses&nbsp;his&nbsp;own&nbsp;workflow&nbsp;where&nbsp;update&nbsp;of&nbsp;purchase&nbsp;order&nbsp;takes&nbsp;place</SPAN><BR /><SPAN class="">*&nbsp;in&nbsp;a&nbsp;separate&nbsp;background&nbsp;workflow&nbsp;step.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>iv_decision&nbsp;<SPAN class="">EQ&nbsp;</SPAN><SPAN class="">2</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>iv_rejection_text&nbsp;<SPAN class="">IS&nbsp;</SPAN><SPAN class="">INITIAL</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ev_decision_processed&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'X'</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ELSE</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">DATA&nbsp;</SPAN><SPAN class="">:&nbsp;</SPAN>t_return&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">STANDARD&nbsp;</SPAN><SPAN class="">TABLE&nbsp;</SPAN><SPAN class="">OF&nbsp;&nbsp;</SPAN>BAPIRET2<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CALL&nbsp;</SPAN><SPAN class="">FUNCTION&nbsp;</SPAN><SPAN class="">'ZFIORI_PO_APPROVAL_REJ_CHG'&nbsp;</SPAN><SPAN class="">IN&nbsp;</SPAN><SPAN class="">UPDATE&nbsp;</SPAN><SPAN class="">TASK</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iv_ebeln&nbsp;<SPAN class="">=&nbsp;</SPAN>iv_pc_number<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TABLES</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_return&nbsp;<SPAN class="">=&nbsp;</SPAN>t_return<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">COMMIT&nbsp;</SPAN><SPAN class="">WORK</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR /><SPAN class="">ENDMETHOD</SPAN><SPAN class="">.</SPAN></SPAN></P><P><BR />As per my requirement if the approver accept I should not check anything and simply make it happen, hence I have not done anything with<!-- StartFragment --> <SPAN>iv_decision</SPAN>&nbsp;= 1. If you want, you can add your custom requirement under it.&nbsp;<BR />For me I have marked&nbsp;<!-- StartFragment --><SPAN>ev_decision_processed&nbsp;<SPAN class="">=&nbsp;</SPAN><SPAN class="">'X', if rejection text/ note in not provided.<BR />I have used a Update Task FM because these were the async call hence the system was giving dump while updating the EKKO. So as to correct&nbsp;this I have divided it in 2 Logical unit. A wait of 5 secs have introduced so that the previous&nbsp;task gets over.<BR /></SPAN></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jayesh_mudaliar_12-1714732313298.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/105495i06177F492E739D15/image-size/large?v=v2&amp;px=999" role="button" title="jayesh_mudaliar_12-1714732313298.png" alt="jayesh_mudaliar_12-1714732313298.png" /></span></P><P><SPAN><SPAN class=""><BR /><!-- StartFragment --><SPAN class="">FUNCTION&nbsp;</SPAN>zfiori_po_approval_rej_chg<SPAN class="">.</SPAN><BR /><SPAN class="">*"----------------------------------------------------------------------</SPAN><BR /><SPAN class="">*"*"Update&nbsp;Function&nbsp;Module:</SPAN><BR /><SPAN class="">*"</SPAN><BR /><SPAN class="">*"*"Local&nbsp;Interface:</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;IMPORTING</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VALUE(IV_EBELN)&nbsp;TYPE&nbsp;&nbsp;EBELN</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;TABLES</SPAN><BR /><SPAN class="">*"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T_RETURN&nbsp;STRUCTURE&nbsp;&nbsp;BAPIRET2</SPAN><BR /><SPAN class="">*"----------------------------------------------------------------------</SPAN><BR /><SPAN class="">*"*"Update&nbsp;Function&nbsp;Module:</SPAN><BR />&nbsp;&nbsp;<SPAN class="">WAIT&nbsp;</SPAN><SPAN class="">UP&nbsp;</SPAN><SPAN class="">TO&nbsp;</SPAN><SPAN class="">5&nbsp;</SPAN>SECONDS<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">DATA</SPAN><SPAN class="">:&nbsp;</SPAN>lr_po&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN><SPAN class="">REF&nbsp;</SPAN><SPAN class="">TO&nbsp;</SPAN>cl_po_header_handle_mm<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_bapi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>bapiret2<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l_result&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>mmpur_bool<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lv_procstat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>ekko<SPAN class="">-</SPAN>procstat<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ls_document&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>mepo_document<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">CONSTANTS</SPAN><SPAN class="">:&nbsp;</SPAN>lc_status&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>ekko<SPAN class="">-</SPAN>procstat&nbsp;<SPAN class="">VALUE&nbsp;</SPAN>'08'<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lc_set_status&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>ekko<SPAN class="">-</SPAN>procstat&nbsp;<SPAN class="">VALUE&nbsp;</SPAN>'03'<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lc_process&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>char16&nbsp;<SPAN class="">VALUE&nbsp;</SPAN>'PO_PROCESS'<SPAN class="">,</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lc_trtyp&nbsp;TYPE&nbsp;char1&nbsp;VALUE&nbsp;'VER',</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lc_trtyp&nbsp;TYPE&nbsp;char1&nbsp;VALUE&nbsp;'V',</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lc_ind&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>char40&nbsp;<SPAN class="">VALUE&nbsp;</SPAN>'RELEASE'<SPAN class="">,</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lc_tcode&nbsp;<SPAN class="">TYPE&nbsp;</SPAN>SY<SPAN class="">-</SPAN>TCODE&nbsp;<SPAN class="">VALUE&nbsp;</SPAN>'ME29N'<SPAN class="">.</SPAN><BR /><BR /><BR />&nbsp;&nbsp;<SPAN class="">SELECT&nbsp;</SPAN><SPAN class="">SINGLE&nbsp;</SPAN>procstat&nbsp;<SPAN class="">FROM&nbsp;</SPAN>ekko&nbsp;<SPAN class="">INTO&nbsp;</SPAN>lv_procstat&nbsp;<SPAN class="">WHERE&nbsp;</SPAN>ebeln&nbsp;<SPAN class="">=&nbsp;&nbsp;</SPAN>iv_ebeln<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>lv_procstat&nbsp;<SPAN class="">EQ&nbsp;</SPAN>lc_status<SPAN class="">.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;prepare&nbsp;creation&nbsp;of&nbsp;PO&nbsp;instance</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;ls_document<SPAN class="">-</SPAN>process&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>'PO_PROCESS'<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;ls_document<SPAN class="">-</SPAN>trtyp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>'VER'<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;ls_document<SPAN class="">-</SPAN>doc_key<SPAN class="">(</SPAN><SPAN class="">10</SPAN><SPAN class="">)&nbsp;</SPAN><SPAN class="">=&nbsp;</SPAN>iv_ebeln<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;ls_document<SPAN class="">-</SPAN>initiator<SPAN class="">-</SPAN>initiator&nbsp;<SPAN class="">=&nbsp;</SPAN>'RELEASE'<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CREATE&nbsp;</SPAN>OBJECT&nbsp;lr_po<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;lr_po<SPAN class="">-&gt;</SPAN>for_bapi&nbsp;<SPAN class="">=&nbsp;</SPAN>'X'<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;lr_po<SPAN class="">-&gt;</SPAN>po_initialize<SPAN class="">(&nbsp;</SPAN>ls_document&nbsp;<SPAN class="">)</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;lr_po<SPAN class="">-&gt;</SPAN>set_po_number<SPAN class="">(&nbsp;</SPAN>iv_ebeln&nbsp;<SPAN class="">)</SPAN><SPAN class="">.</SPAN><BR /><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CALL&nbsp;</SPAN><SPAN class="">FUNCTION&nbsp;</SPAN>'MEPO_DOC_READ'<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EXPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;im_ebeln&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>iv_ebeln<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;im_tcode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>lc_tcode<SPAN class="">"'ME29N'</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;im_trtyp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>ls_document<SPAN class="">-</SPAN>trtyp<BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;IM_ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;im_document&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>ls_document<BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;IM_NO_MESSAGING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;IM_NO_MESSAGE_REQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;IM_NO_AUTHORITY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=</SPAN><BR /><SPAN class="">*&nbsp;EXCEPTIONS</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;DOC_NUMBER_MISSING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;1</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;TRANSACTION_CODE_MISSING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;2</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;TRANSACTION_TYPE_MISSING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;3</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;INVALID_CALL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;4</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;OTHERS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;5</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>sy<SPAN class="">-</SPAN>subrc&nbsp;&lt;&gt;&nbsp;<SPAN class="">0</SPAN><SPAN class="">.</SPAN><BR /><SPAN class="">*&nbsp;Implement&nbsp;suitable&nbsp;error&nbsp;handling&nbsp;here</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">DATA&nbsp;</SPAN><SPAN class="">:&nbsp;</SPAN>ex_data&nbsp;&nbsp;<SPAN class="">LIKE&nbsp;&nbsp;</SPAN>mepoheader<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">CALL&nbsp;</SPAN><SPAN class="">FUNCTION&nbsp;</SPAN>'MEPO_DOC_HEADER_GET'<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IMPORTING</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ex_ekko&nbsp;<SPAN class="">=&nbsp;</SPAN>ex_data<SPAN class="">.</SPAN><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">IF&nbsp;</SPAN>cl_process_state_mm<SPAN class="">=&gt;</SPAN>is_allowed<SPAN class="">(</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;im_bstyp&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>ex_data<SPAN class="">-</SPAN>bstyp<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;im_state&nbsp;&nbsp;&nbsp;<SPAN class="">=&nbsp;</SPAN>ex_data<SPAN class="">-</SPAN>procstat<BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;im_process&nbsp;<SPAN class="">=&nbsp;</SPAN>cl_process_state_mm<SPAN class="">=&gt;</SPAN>c_pr_reset_rej&nbsp;<SPAN class="">)</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">EQ&nbsp;</SPAN>mmpur_no<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">MESSAGE&nbsp;</SPAN>e806<SPAN class="">(</SPAN>mepo<SPAN class="">)&nbsp;</SPAN><SPAN class="">WITH&nbsp;</SPAN>ex_data<SPAN class="">-</SPAN>procstat&nbsp;<SPAN class="">RAISING&nbsp;</SPAN>failed<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;ex_data<SPAN class="">-</SPAN>procstat&nbsp;<SPAN class="">=&nbsp;</SPAN>cl_process_state_mm<SPAN class="">=&gt;</SPAN>c_active<SPAN class="">.</SPAN><BR />&nbsp;&nbsp;&nbsp;&nbsp;lr_po<SPAN class="">-&gt;</SPAN>set_data<SPAN class="">(&nbsp;</SPAN>ex_data&nbsp;<SPAN class="">)</SPAN><SPAN class="">.</SPAN><BR /><BR /><BR />&nbsp;&nbsp;&nbsp;&nbsp;<SPAN class="">UPDATE&nbsp;</SPAN>ekko&nbsp;<SPAN class="">SET&nbsp;</SPAN>procstat&nbsp;<SPAN class="">=&nbsp;</SPAN>lc_set_status&nbsp;<SPAN class="">WHERE&nbsp;</SPAN>ebeln&nbsp;<SPAN class="">EQ&nbsp;</SPAN>iv_ebeln<SPAN class="">.</SPAN><BR /><SPAN class="">*&nbsp;&nbsp;&nbsp;&nbsp;UPDATE&nbsp;ekko&nbsp;SET&nbsp;PROCSTAT&nbsp;=&nbsp;ex_data-procstat&nbsp;where&nbsp;ebeln&nbsp;eq&nbsp;iv_ebeln.</SPAN><BR />&nbsp;&nbsp;<SPAN class="">ENDIF</SPAN><SPAN class="">.</SPAN><BR /><BR /><SPAN class="">ENDFUNCTION</SPAN><SPAN class="">.</SPAN><BR /></SPAN></SPAN></P> 2024-05-03T12:45:30.531000+02:00