Skip to Content

How to map the Update Operation for SalesOrder using Data Source name BAPI_EMP_SO_CHANGE

Hello all, I'm trying to make an OData Service using the following BAPIs as Entity Types:

-BAPI_SO_EMP_SO_GETLIST;
-BAPI_SO_EMP_SO_GETDETAIL;

I followed all the steps in this guide written by Volker Drees (very useful!), however, he only maps the Read and Query operations. I was able to tinker with the Data Mapping wizard and map the Create and Delete operation (which I tested and worked as intended), however, I'm not able to map the Update Operation. I tried the following:

But when I try to Update an entry in the /IWFND/GW_CLIENT transaction, I get the following error:

My logical solution would be to change the Data Source parameter, as shown below:

Which I came upon a new error, which I couldn't deduce any solution:

How can I fix this? I even considered going to the ABAP Workbench to redefine the UpdateEntity Method, but my knowledge on ABAP is close to nil. What makes me even more confused, is that I'm creating a oData service using a RFC module, why it outputs invalid BOR key?

Thanks in advance,

William

attempt1.jpg (44.8 kB)
attempt2.jpg (195.7 kB)
attempt3.jpg (44.7 kB)
attempt4.jpg (213.9 kB)
Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

3 Answers

  • Best Answer
    Sep 07, 2017 at 09:54 AM

    Hi,

    Elaborating and adding on Pavan's suggestions.

    You should have used - BAPI_EPM_SO_CHANGE. These BAPIs behave in a certain way. They have two structures - one for actual data and another called as 'X' structures to denote what data has changed.

    In your case, try mapping data as below.

    If only creating header then pass data to SOHEADERDATA and pass the key i.e. Sales Order Id and true/false values to SOHEADERDATAX. Whatever data you pass in SOHEADERDATA for that corresponding property in SOHEADERDATAX you need to pass as true for changes to reflect. Also, note and use PERSIST_TO_DB flag to commit changes to database.

    BR.

    Add comment
    10|10000 characters needed characters exceeded

    • Thanks for your answer! In the end I did everything in the ABAP Workbench, and I finally understood what the SOHEADERDATAX was for. If anyone stumbles to a similar problem, here's the my ABAP code:

      METHOD SALESORDER_UPDATE_ENTITY.
          DATA:
                lwa_key_tab       TYPE /iwbep/s_mgw_name_value_pair,
                lv_so_id          TYPE bapi_epm_so_id,
                ls_salesorder     LIKE er_entity,
                ls_headerdata     TYPE bapi_epm_so_header,
                ls_headerdatax    TYPE bapi_epm_so_headerx,
                lt_return         TYPE STANDARD TABLE OF bapiret2,
                ld_persist_to_db  TYPE BAPI_EPM_BOOLEAN.
      * MAP THE RUNTIME REQUEST TO THE RFC - ONLY MAPPED ATTRIBUTES
      io_data_provider->read_entry_data( IMPORTING es_data = ls_salesorder ).
          READ TABLE it_key_tab INTO lwa_key_tab WITH KEY name = 'SoId'.
          IF sy-subrc = 0.
            lv_so_id = lwa_key_tab-value.
          ENDIF.
      * alpha conversion
          CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
          EXPORTING
            input = lv_so_id
          IMPORTING
            output = lv_so_id.
      
      * Read the new data from the service that needs to be updated io_data_provider->read_entry_data
          CALL FUNCTION 'BAPI_EPM_SO_GET_DETAIL'
          EXPORTING
            so_id = lv_so_id
          IMPORTING
            headerdata = ls_headerdata.
      * Update the data
          ld_persist_to_db = ABAP_TRUE.
          ls_headerdata-Note = ls_salesorder-note.
          ls_headerdata-Buyer_Id = ls_salesorder-Buyer_Id.
          ls_headerdata-Buyer_Name = ls_salesorder-Buyer_Name.
          ls_headerdata-currency_code = ls_salesorder-currency_code.
          ls_headerdatax-so_id = lv_so_id.
          ls_headerdatax-currency_code = 'X'.
          ls_headerdatax-note = 'X'.
          ls_headerdatax-Buyer_Id = 'X'.
          ls_headerdatax-Buyer_Name = 'X'.
          CALL FUNCTION 'BAPI_EPM_SO_CHANGE'
            EXPORTING
              so_id         = lv_so_id
              soheaderdata  = ls_headerdata
              soheaderdatax = ls_headerdatax
      *        PERSIST_TO_DB = ABAP_TRUE
              persist_to_db = ld_persist_to_db
            TABLES
              return        = lt_return.
            IF lt_return IS INITIAL.
              er_entity = ls_salesorder.
            ENDIF.
       ENDMETHOD.
      **TRY.
      *CALL METHOD SUPER->SALESORDER_UPDATE_ENTITY
      *  EXPORTING
      *    IV_ENTITY_NAME          =
      *    IV_ENTITY_SET_NAME      =
      *    IV_SOURCE_NAME          =
      *    IT_KEY_TAB              =
      **    IO_TECH_REQUEST_CONTEXT =
      *    IT_NAVIGATION_PATH      =
      **    IO_DATA_PROVIDER        =
      **  IMPORTING
      **    ER_ENTITY               =
      *    .
      ** CATCH /IWBEP/CX_MGW_BUSI_EXCEPTION .
      ** CATCH /IWBEP/CX_MGW_TECH_EXCEPTION .
      **ENDTRY.
      
  • Sep 07, 2017 at 05:21 AM

    Hi,

    Well, This this happens usually when new to OData and Gateway...

    If I were you, would carry out few points before this OData development:

    1st: Check the update of SO via BAPI BAPI_EMP_SO_CHANGE.

    If its success full then I would pass the same parameters to the BAPI in its Import/Tables via OData. make sure your mapping in SEGW (gateway Builder) is correctly done.

    2nd: Once completed the above step, I'd put a break-point at odata DPC_EXT class and check if the data is passed correctly to BAPI via OData service.

    Thanks,

    PG

    Add comment
    10|10000 characters needed characters exceeded

  • Sep 07, 2017 at 05:22 AM

    P.S When we say Below lines we mean to check the BAPI in SE37 in Test mode. ( with Commit)

    1st: Check the update of SO via BAPI BAPI_EMP_SO_CHANGE
    
    Add comment
    10|10000 characters needed characters exceeded