The OData service that has been generated in the first part of this blog is read only.
In the second part of the blog OData service development with SAP Gateway using CDS via Referenced Data Sources I would like to show how we can make the description of the sales order updatable.
This will show
- how simple updates can be implemented and in particular
- how this can be done for Texts that are accessed by the SADL framework via a join and the annotation @ObjectModel.text.association: ‘_Text’.
In another blog I also showed how eTags can be handled for this service and how you can even add a function import
- 17.06.2016 – Fixed a typo that the DEFINE method is located in the DPC_EXT class rather than in the MPC_EXT class
- 24.11.2016 – Moved code samples to code boxes to avoid problems with cut and paste
- 05.05.2017 – Added information how to handle etags for updates and how to implement a function import
- Open the Service Builder project ZE2E100_<XX>_2 again that has been built based on the blog mentioned above.
- Expand the folder Runtime artifacts and right-click on ZZCL_ZE2E100_XX_2_DPC_EXT and choose the entry Go To ABAP Workbench.
- Switch to edit mode, scroll down to the method ZSEPM_C_SALESORD_UPDATE_ENTITY and make sure to select it and click on the Redefine Method button.
- Copy and Paste the coding into the Update method
method zsepm_c_salesord_update_entity. data: lt_keys type /iwbep/t_mgw_tech_pairs, ls_key type /iwbep/s_mgw_tech_pair, ls_so_id type bapi_epm_so_id, ls_headerdata_update type bapi_epm_so_header, ls_headerdatax type bapi_epm_so_headerx, ls_headerdata_key type zcl_ze2e100_xx_2_mpc=>ts_zsepm_c_salesorder_tpltype, ls_headerdata_payload type zcl_ze2e100_xx_2_mpc=>ts_zsepm_c_salesorder_tpltype, lt_return type table of bapiret2, ls_return type bapiret2, err_msg type string, ls_message type scx_t100key. call method io_tech_request_context->get_converted_keys importing es_key_values = ls_headerdata_key. io_data_provider->read_entry_data( importing es_data = ls_headerdata_payload ). ls_so_id-so_id = ls_headerdata_key-salesorder. " Product header data (non-key) fields that can be updated " via the BAPI are marked with an 'X' ls_headerdatax-so_id = ls_headerdata_key-salesorder. ls_headerdatax-note = 'X'. " move content of the fields that should be " updated from payload to the corresponding " field of the BAPI move ls_headerdata_key-salesorder to ls_headerdata_update-so_id. move ls_headerdata_payload-t_salesorder to ls_headerdata_update-note. call function 'BAPI_EPM_SO_CHANGE' exporting so_id = ls_so_id " EPM: SO Id soheaderdata = ls_headerdata_update " EPM: so header data of BOR object soheaderdatax = ls_headerdatax tables return = lt_return. " Return Parameter if lt_return is not initial. loop at lt_return into ls_return. err_msg = ls_return-message . endloop. ls_message-msgid = 'SY'. ls_message-msgno = '002'. ls_message-attr1 = err_msg. raise exception type /iwbep/cx_mgw_busi_exception exporting textid = ls_message. endif. endmethod.
Info: The replaced coding above retrieves the content of the properties of the incoming request.
Since different DDIC structures are used by the entity type and the BAPI that is used to update the sales order the incoming fields are moved to the data structure used by the BAPI.
- To make the SAP Web IDE CUD Master Detail Template aware that the property SalesOrder_Text is now updatatable we have to annotate the property using the annoation sap:updatable=true.In this special case this cannot be done in the CDS view. So we have to use the option to add additional metadata by implementing the DEFINE method in the model provider extension class.
- Expand the folder Runtime artifacts and right-click on ZZCL_ZE2E100_XX_2_MPC_EXT and choose the entry Go To ABAP Workbench.
- Copy and paste the following coding into the DEFINE method.
method define. data: lo_entity_type type ref to /iwbep/if_mgw_odata_entity_typ, lo_property type ref to /iwbep/if_mgw_odata_property. call method super->define( ). lo_entity_type = model->get_entity_type( iv_entity_name = 'Zsepm_C_Salesorder_TplType'). lo_property = lo_entity_type->get_property( iv_property_name = 'SalesOrder_Text'). lo_property->set_updatable( abap_true ). endmethod.
- Click on Activate.
- Confirm the activation popup.
Since the update method is now implemented you can now test your service. This can be done by the built in REST client, the SAP Gateway Client which I can really recommend.
After you have tested the service successfully using the SAP Gateway Client you can use SAP Web IDE to generate an application based on the Master Detail CUD template.
Test the service using the SAP Gateway Client
- Navigate back to the Service Builder by pressing the “Back-Button” several times
- In the navigation tree right-click on GW_HUB and select SAP Gateway Client.Alternatively start the SAP Gateway Client in a separate window by starting transaction /n/IWFND/GW_CLIENTIf we now test the update using the SAP Gateway Client this should work fine.
- Enter the following URI/sap/opu/odata/SAP/ZE2E100_XX_2_SRV/Zsepm_C_Salesorder_Tpl(‘5000000<XX>’)After pressing Execute button you see a single sales order.Replace ‘<XX>’ with your group name
- Press the Use as Request button to create a proper http request body.
Change the content of the field SalesOrder_Text for example to ‘Test Update Text’.
Change the http method from GET to PUT.
- As a result you get an empty http response with the return code 204.
- Now again perform a GET request to verify that the data has been changed
Enter the following URI
After pressing Execute button you see a single sales order with the changed text.
Replace ‘<XX>’ with your group name
Testing the service with SAP Web IDE
When creating an application based on the CRUD-Q Master Detail template you will be able to build an application that allows you to update sales orders as shown in the following screen shot.