Skip to Content
Author's profile photo Andre Fischer

OData service development with SAP Gateway – code-based service development – Part II

Since the editor didn’t let me enter additional screen shots I am continuing my last blog post OData service development with SAP Gateway – code-based service development – Part I in a new one: 😉

Change Log

  • 24.11.2016 – Moved ABAP Code to code boxes

Overview

We will continue our service implementation by implementing

 

  1. the GET_ENTITY method for the SalesOrderSet entity set and
  2. by implementing navigation to the items of a sales order

 

Provision the GET_ENTITY method of the service using ABAP code

 

  • Open the Service Builder Project again
  • Expand the node Service Implementation and SalesOrderSet and choose the entry
    GetEntity (Read).
    Now right-click on
    GetEntity (Read) and choose
    Go to ABAP Workbench.

/wp-content/uploads/2016/05/image044_964984.png

  • Confirm the warning“Operation SALESORDERSET_GET_ENTITY has not yet been implemented”

 

  • Switch to edit mode, scroll down to the method SALESORDERSET_GET_ENTITY and make sure to select it.Click on the Redefine Method button.

    Please note that the method SALESORDERSET_GET_ENTITYSET has already been redefined and therefore appears in black color.

/wp-content/uploads/2016/05/image045_964997.png

  • Use Cut&Paste to copy the entire coding into the ABAP editor.Replace ‘<XX>’ by your group numberThe code first calls the method io_tech_request_context->get_converted_keys.

    The retrieved key value is used to select a single entry which is stored in the return structure
    er_entityof the method.

 

  method salesorderset_get_entity.

    data: lt_keys       type /iwbep/t_mgw_tech_pairs,
          ls_key        type /iwbep/s_mgw_tech_pair,
          ls_bp_key     type zcl_ze2e100_xx_mpc=>ts_salesorder-salesorder,
          ls_headerdata type zcl_ze2e100_xx_mpc=>ts_salesorder.

    call method io_tech_request_context->get_converted_keys
      importing
        es_key_values = ls_headerdata.

    ls_bp_key = ls_headerdata-salesorder.

    select single *
      into corresponding fields of @er_entity
      from sepm_i_salesorder_e
      where salesorder = @ls_headerdata-salesorder.


  endmethod.

   

 

 

  • Click on Activate
  • Confirm the Activation popup
  • Navigate back to the Service Builder main screen using the back button  multiple times.
  • In the navigation tree right-click on GW_HUB and select SAP Gateway Client.
  • Alternatively click on the SAP Gateway Client button in the detail section.Enter the following URI
    /sap/opu/odata/SAP/ZE2E100_<XX>_SRV/SalesOrderSet('500000000')​

    Replace ‘<XX>’ by your group number and Execute.
    You will get the details of a single business partner as a response

 

/wp-content/uploads/2016/05/image046_964998.png

 

Add an additional entity set for Sales Order Items

  • Open the Service Builder Project again
  • We will now create a second entity type for sales order items and entity set.Right-click again on Data Model and select Import –> DDIC Structure.

 

  • In the first step of the wizard provide:In the field Name, enter SalesOrderItem.
    In the field ABAP Structure, enter SEPM_ISOIE.
    Click Next.

/wp-content/uploads/2016/05/image047_964999.png

  • In the second step of the wizard provide:Select the checkbox for SEPM_ISOIE.
    Deselect the checkbox for MANDT,Click Next.

/wp-content/uploads/2016/05/image048_965003.png

  • In the third screen of the wizard:
    Select the checkbox Is Key for the fields SALESORDER and SALESORDERITEM.
    Click Finish.

/wp-content/uploads/2016/05/image049_965004.png

  • Press Save

Add an association and navigation properties

  • Expand Data Model and Right-click on Association and select Create

/wp-content/uploads/2016/05/image050_965005.png

  • In the first step of the wizard provide:Association Name
    Assoc_SalesOrder_SalesOrderItem

 

Principal Entity

Entity Type Name

SalesOrder

Cardinality

1

 

Leave the checkbox Create related Navigation Property checked

 

Enter ToItems in the field Navigation Property

 

Dependent Entity

Entity Type Name

SalesOrderItem

Cardinality

1..n

Select the checkbox Create related Navigation Property checked

Enter ToSalesOrder in the field Navigation Property

/wp-content/uploads/2016/05/image051_965015.png

  • Click Next
  • In the second step of the wizard in the field Dependent Property, enter SalesOrder by using the value help.
    Click
    Next

/wp-content/uploads/2016/05/image052_965016.png

  • In the third step of the wizard press Finish.
  • Press the Check Project Consistency button.
  • Verify that no errors were found.
  • Press Generate Runtime Objects

Provision the GET_ENTITY_SET method of the entity set SalesOrderItemSet

 

  • Open the Service Builder Project again
  • Expand the node Service Implementation and SalesOrderItemSet and choose the entry GetEntitySet (Query).
    Now right-click on GetEntitySet (Query) and choose Go to ABAP Workbench.

/wp-content/uploads/2016/05/image057_965017.png

  • Confirm the warning“Operation SALESORDERITEMSE_GET_ENTITYSET has not yet been implemented”
  • Switch to edit mode, scroll down to the method SALESORDERITEMSE_GET_ENTITYSET and make sure to select it.Click on the Redefine Method button.

/wp-content/uploads/2016/05/image059_965024.png

  • Use Cut&Paste to copy the entire code shown below.Replace ‘<XX>’ by your group numberThe code first calls the method
    io_tech_request_context->get_navigation_path

    If the entity set is accessed via the navigation property ‘TOITEMS’ the sales order id is retrieved from the URI.

    If the entity set is accessed directly the where clause is retrieved from io_tech_request_context.

    Please note that the methods SALESORDERSET_GET_ENTITY and SALESORDERSET_GET_ENTITYSET have already been redefined and therefore appear in black color.

 

 method salesorderitemse_get_entityset.
    data: lt_nav_path   type /iwbep/t_mgw_tech_navi,
          ls_nav_path   type /iwbep/s_mgw_tech_navi,
          lt_keys       type /iwbep/t_mgw_tech_pairs,
          ls_key        type /iwbep/s_mgw_tech_pair,
          ls_so_key     type zcl_ze2e100_xx_mpc=>ts_salesorder-salesorder,
          ls_headerdata type zcl_ze2e100_xx_mpc=>ts_salesorder.


    data: lv_osql_where_clause type string.

    lt_nav_path = io_tech_request_context->get_navigation_path( ).

    read table lt_nav_path into ls_nav_path with key nav_prop = 'TOITEMS'.

    if sy-subrc = 0.

      call method io_tech_request_context->get_converted_source_keys
        importing
          es_key_values = ls_headerdata.

      ls_so_key = ls_headerdata-salesorder.

      select * from sepm_i_salesorderitem_e
      into corresponding fields of table @et_entityset
      where salesorder = @ls_so_key.

    else.

      lv_osql_where_clause = io_tech_request_context->get_osql_where_clause_convert( ).

      select * from sepm_i_salesorderitem_e
     into corresponding fields of table @et_entityset
     where (lv_osql_where_clause).

    endif.

  endmethod.

    

      

 

     

 

 

  • Click on Activate
  • Confirm the Activation popup
  • Navigate back to the Service Builder main screen using the back button  multiple times.
  • In the navigation tree right-click on GW_HUB and select SAP Gateway Client.Alternatively click on the SAP Gateway Client button in the detail section.

 

  • Enter the following URI

    /sap/opu/odata/SAP/ZE2E100_<XX>_SRV/SalesOrderSet('500000000')/ToItems

    Replace <XX> by your group number and Execute.
    You will get the items of the sales order
    500000000 as a response.

 

  • Enter the following URI
    /sap/opu/odata/SAP/ZE2E100_<XX>_SRV/SalesOrderItemSet?$filter=Salesorder eq '500000000'​

    Replace <XX> by your group number and Execute.

    Also here you will get the items of the sales order
    500000000 as a response

 

If you now want to annotate this service so that you are able to use the list report template from SAP Web IDE please check out my following blog:

How to add annotations to an OData service using code based implementation

Assigned Tags

      13 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Chris Whealy
      Chris Whealy

      Thanks, nice blogs André.

      The only thing to be careful about is that in some of the ABAP code samples, after you paste the code into the editor, there are some space characters missing between the parameters and keywords in the SELECT statements.

      Apart from that small detail, it all works nicely.

      Author's profile photo Andre Fischer
      Andre Fischer
      Blog Post Author

      Hi Chris,

      thanks for the hint.

      I changed the code snippets. This time copying from the ABAP Editor and not from Word 😉 .

      Best Regards,

      Andre

      Author's profile photo Former Member
      Former Member

      Basic but good stuff. Are you planning on covering $expand and $batch? For a sales order, one $expand makes more sense then first header and then items. I recently implemented a project with 15 entities, max. 3 levels deep (including nested tables) and there are a lot of unclear/undocumented details that you'll discover once you start digging deeper.

      Author's profile photo Tudor Riscutia
      Tudor Riscutia

      Good exercise!

      I like the combination of 7.40 syntax and CALL METHOD statements 🙂

      Are there any guidelines regarding the entity type naming? Except the CamelCase.

      I see the methods generated for the SalesOrderItem get truncated in ABAP.

      BR,

      Tudor

      Author's profile photo Nils Lutz
      Nils Lutz

      Hi Andre,

      nice blog. Are you going to do it for create/update entity methods also? 😏

      BR,

      Nils

      Author's profile photo Joachim Rees
      Joachim Rees

      [I originaly ment to comment on https://blogs.sap.com/2016/06/02/sap-codejam/ , but comments seem to be switched off there]

      Hey André,

      may I give you a littel suggestion on how you can improve your CodeJams even more:

      Used the modern tools that are available, in your examples and also give the participants that chance to use them.
      I'm talking about using SAP BusinessClient (instead of SAP Gui) and using Eclipse/AdT (instead of SE80).

      You allready nicely explained how easy using eclipse is here: https://blogs.sap.com/2016/06/14/using-segw-and-abap-in-eclipse/comment-page-1/ .

      And I'm sure it would not be a big deal to make your demo system "Business-Client ready".

      Let me clarify: I'm not talking about forcing anyone to use the new, shiny tools - if anyone feels more comfortable learning new stuff (like SAP Gateway) on old, familiar tools (like SAPGui or SE80), by all means let them do that!
      I'm just suggesting to make the modern tools (AdT, Business Client) the default by using them in blogs, documentations, books and presentations.

      (I think FlorianHenninger made a similar suggestion in regards to TechEd presentations).

      Best
      Joachim

      Author's profile photo Wolfgang Röckelein
      Wolfgang Röckelein

      Thanks for the blogs!
      Why is GET_OSQL_WHERE_CLAUSE_CONVERT not documented on http://help.sap.com/saphelp_gateway20sp12/helpdata/en/fa/4f24c7dd064726b4913c2424b33208/content.htm or on http://help.sap.com/saphelp_nw75/helpdata/en/0e/9b2451f8c0266ee10000000a445394/content.htm or on http://help.sap.com/saphelp_nw751abap/helpdata/en/0e/9b2451f8c0266ee10000000a445394/content.htm ?

      Author's profile photo Former Member
      Former Member

      Hello Andre,

      thank you for your block. i have a requirement for which i can't unfortunately find a solution yet.
      I want to provide a ZIP file for downloading based on a complex data selection from the backend with a lot of filter parameters.
      I suppose I can provide the ZIP file as a xstring by redefining the get_stream method in the DPC and the define method in the MPC classes. I've found plenty examples for that. But it only works in combination with the get_entity method and $value request.
      My requirement is to provide a ZIP file based on the result of the get_entityset method with filter parameters which are not necessarily key attributes of the entity. I would appreciate your help a lot.

      Best Regards,
      Eskender
       

      Author's profile photo Former Member
      Former Member

      I’ve got a solution for my problem in another thread. Who is interested can find it at http://www.techippo.com/2016/03/how-to-get-image-through-sap-netweaver.html?showComment=1482182008794#c1992973375391282915

      Author's profile photo Arthur Parisius
      Arthur Parisius

      Hello Andre,

      Quick question.

      As you created all your work as local objects, what would need to be done to place all this in a transport to move it across the system landscape?

      I'm asking this because at a client I'm working for they messed up their system which resulted in incorrect versions and different version on the systems and know way of knowing the correct order for the transports to correct it.

      Therefore I would like to be able to add everything completely in a new transport and hopefully correct it this way.

       

      Thanks in advance,

      Arthur Parisius

      Author's profile photo Andre Fischer
      Andre Fischer
      Blog Post Author

      Hi Arthur,

      have a look at my following blog:

      https://blogs.sap.com/2016/03/21/how-to-change-dev-class-tmp-for-the-repository-objects-of-an-odata-service/

      I assume this will hopefully solve the issues of your customer.

      Best Regards,

      Andre

      Author's profile photo Arthur Parisius
      Arthur Parisius

      Hi Andre,

      Thanks for this and I do indeed hope this will solve the issue. I'll try it, I just hope none of the objects need key values.

      Regards,

      Arthur

       

      Author's profile photo Martin Ceronio
      Martin Ceronio

      Thanks for the example with the explanation.

      Is there not a more generic way to obtain the property values of the source navigation object?

      In my scenario, I am coding a generic GET_ENTITY and GET_ENTITYSET handler in which I want to rely on the property values in the source and target having the same names.

      This is fine e.g. for reusing the keys of the source (e.g. header -> items or item -> header), but not when you are relying on navigation via non-key attributes because, now, I have to know specifically which entities I am dealing with.

      (Arguably the property names may not be the same, but it would be nice if you could specify the mappings in the OData model associations also).