Introduction
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'.
Implementation
- 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_DPC_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.
- 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_CLIENT
If 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.
Press Execute
- 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
/sap/opu/odata/SAP/ZE2E100_XX_2_SRV/Zsepm_C_Salesorder_Tpl('5000000<XX>')
After pressing Execute button you see a single sales order with the changed text.
Replace ‘<XX>’ with your group name
Testing with SAP Web IDE
When testing with the CUD Master Detail Template in SAP Web IDE it turns out that the update of the field will not work.
This is because to a small bug that is planned to be fixed with SAP NetWeaver 750 SP04.
As a workaround we have to redefine the method /IWBEP/IF_MGW_CORE_SRV_RUNTIME~CHANGESET_BEGIN.
After you have added the following code
method /IWBEP/IF_MGW_CORE_SRV_RUNTIME~CHANGESET_BEGIN.
cv_defer_mode = abap_false.
endmethod.
The text will be updated as you can check with the SAP Gateway Client