Skip to Content
Technical Articles

G/W Service for Inbound Delivery Creation(VL31N) in SAP

Hi Everyone,

i come across many blog posts where there was no specific answer for Creation of the Inbound delivery. i struggled to get the logic for it and finally i achieved it. Hence thought of sharing the experience and the process which i followed for Inbound Delivery Creation through this blog post. Hope it would be helpful for some one like me.

Introduction :

When a purchase order is created in the system, and if there is a need of Inbound Delivery Creation, we use to go to VL31N to create it Manually, but when it comes to a Technical scenario, it would require a BAPI to get that Created. But there is no specific/Direct BAPI for this requirement, we need to use Standard BAPI GN_DELIVERY_CREATE to proceed. Here in this Blog post i created an OData service for the same.

Requirement : 

VL31N Creation – OData Service

Steps :

 

Dictionary Structures:

 

Table Type : ZTT_PO_INBD_ITM

 

Table Type : ZTT_MSG_INBD

 

i created a Custom RFC for Inbound Delivery Creation to segregate the logic part from Odata service creation .

Function Module :

FUNCTION zfm_create_inbd_delivery.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(I_PONO) TYPE  EBELN
*"  EXPORTING
*"     REFERENCE(E_INB_DELIVERY) TYPE  LIKP-VBELN
*"     REFERENCE(E_MSG) TYPE  ZCUS_MSG
*"  TABLES
*"      IT_ITEM TYPE  ZTT_PO_INBD_ITM
*"      ET_MSGS TYPE  ZTT_MSG_INBD OPTIONAL
*"----------------------------------------------------------------------

  DATA : ls_header  TYPE  bbp_inbd_l,
         lt_detail  TYPE TABLE OF bbp_inbd_d,
         ls_detail  LIKE LINE OF lt_detail,
         lv_vbeln   TYPE likp-vbeln,
         lt_return  TYPE TABLE OF bapireturn,
         ls_return  LIKE LINE OF lt_return,
         lv_matdesc TYPE maktx.

  DATA: ls_vbsk TYPE vbsk,
        lt_komd TYPE TABLE OF komdlgn,
        ls_komd TYPE komdlgn,
        lt_vbfs TYPE TABLE OF vbfs,
        ls_vbfs LIKE LINE OF lt_vbfs,
        lt_vbls TYPE TABLE OF vbls,
        ls_vbls LIKE LINE OF lt_vbls,
        lt_LIPS TYPE TABLE OF lips,
        ls_lips LIKE LINE OF lt_lips,
        ls_ekpo TYPE ekpo,
        ls_ekko TYPE ekko,
        ls_item TYPE zstr_po_inbd_itm.

  CLEAR: ls_vbsk.
  ls_vbsk-sammg = '3895799'.
  ls_vbsk-smart = 'L'.
  ls_vbsk-erdat = sy-datum.
  ls_vbsk-ernam = sy-uname.
  ls_vbsk-uzeit = sy-uzeit.

  IF i_pono IS NOT INITIAL.
    SELECT SINGLE * FROM ekko INTO ls_ekko WHERE ebeln = i_pono.
*Looping the items
    LOOP AT it_item INTO ls_item.
      SELECT SINGLE * FROM ekpo INTO ls_ekpo WHERE ebeln = ls_ekko-ebeln
                                                AND ebelp = ls_item-poitem.
      CLEAR:ls_komd.
      ls_komd-lfart = 'EL'.
      ls_komd-matnr = ls_ekpo-matnr.
      IF ls_item-matnr IS NOT INITIAL.
        SELECT SINGLE maktx FROM makt INTO lv_matdesc
                  WHERE matnr = ls_ekpo-matnr
                  AND spras = 'E'.
        ls_komd-arktx = lv_matdesc.
      ENDIF.
      ls_komd-werks = ls_ekpo-werks.
      ls_komd-lfdat = sy-datum.
      ls_komd-lfimg = '1'.
      ls_komd-umvkz = ls_item-quantity.
      ls_komd-umvkn = '1'.
      ls_komd-vrkme = ls_item-unit.

      ls_komd-meins = ls_ekpo-lmein.
      ls_komd-vgbel = ls_ekko-ebeln.
      ls_komd-vgpos = ls_ekpo-ebelp.
      ls_komd-vgtyp = 'V'.
      ls_komd-lprio = ls_ekpo-lprio.
      ls_komd-lgort = ls_ekpo-lgort.
      ls_komd-lifnr = ls_ekko-lifnr.
      ls_komd-kzazu = 'X'.
      APPEND ls_komd TO lt_komd.
      CLEAR: ls_komd, ls_item, ls_ekpo.
    ENDLOOP.

    CALL FUNCTION 'GN_DELIVERY_CREATE'
      EXPORTING
        vbsk_i               = ls_vbsk
        if_synchron          = 'X'
        if_no_partner_dialog = 'X'
      TABLES
        xkomdlgn             = lt_komd
        xvbfs                = lt_vbfs
        xvbls                = lt_vbls
        xxlips               = lt_lips.
    .
    IF lt_lips IS NOT INITIAL.
      READ TABLE lt_lips INTO ls_lips INDEX 1.
      IF sy-subrc EQ 0.
        e_inb_delivery = ls_lips-vbeln.
        CONCATENATE 'Inbound Delivery' e_inb_delivery 'Created' INTO e_msg SEPARATED BY space.
      ENDIF.
    ELSE.
      DATA: ls_msg TYPE zstr_msg_inbd,
            lv_txt TYPE char255.
      LOOP AT lt_vbfs INTO ls_vbfs.
        CALL FUNCTION 'FORMAT_MESSAGE'
          EXPORTING
            id        = ls_vbfs-msgid
            lang      = 'EN'
            no        = LS_VBFs-msgno
            v1        = sy-msgv1
            v2        = sy-msgv2
            v3        = sy-msgv3
            v4        = sy-msgv4
          IMPORTING
            msg       = lv_txt
          EXCEPTIONS
            not_found = 1
            OTHERS    = 2.
        IF sy-subrc <> 0.
* Implement suitable error handling here
        ENDIF.
        ls_msg-msgtyp = ls_vbfs-msgty.
        ls_msg-msgtxt = lv_txt.
        APPEND ls_msg TO et_msgs.
        CLEAR: ls_msg, lv_txt.
      ENDLOOP.
    ENDIF.
  ENDIF.

ENDFUNCTION.

 

Gateway Service Creation:

 

I created the Model creation like as below:

Transaction SEGW

After defining the model Save Check and Generate Run Time Objects and then go to the DPC_EXT class to redefine the Standard method “Create_deep_entity” and also here i created a custom create method for Create Deep Entity.

Then go to MPC_EXT class and create Types definition .

Here is the code in TS_DEEP_ENTITY . This includes the Header fields as well as how many table types you’ve been using in your Model. (Ex : Header & Multiple Item Levels)

Also redefine the “Define” Method in the same class.

The code in the define method is as follows:

super->define( ).
    DATA:
      lo_annotation   TYPE REF TO /iwbep/if_mgw_odata_annotation,
      lo_entity_type  TYPE REF TO /iwbep/if_mgw_odata_entity_typ,
      lo_complex_type TYPE REF TO /iwbep/if_mgw_odata_cmplx_type,
      lo_property     TYPE REF TO /iwbep/if_mgw_odata_property,
      lo_entity_set   TYPE REF TO /iwbep/if_mgw_odata_entity_set.

***********************************************************************************************************************************
*   ENTITY – Deep Entity
***********************************************************************************************************************************

    lo_entity_type = model->get_entity_type( iv_entity_name = 'PurhcaseOrder' ).

    lo_entity_type->bind_structure( iv_structure_name  = 'zcl_zgw_XXX_mpc_ext=>ts_deep_entity' ).

 

 

Now as part of  DPC_EXT Class am going to create a custom method and inserting our logic into it.

  • Create a Custom Method called CUSTOM_CREATE_DEEP_ENTITY and give the following Parameters

Method name : CUSTOM_CREATE_DEEP_ENTITY

Parameters :

IV_ENTITY_NAME                         Importing            Type      STRING

IV_ENTITY_SET_NAME                 Importing            Type      STRING

IV_SOURCE_NAME                       Importing            Type      STRING

IT_KEY_TAB                                   Importing            Type      /IWBEP/T_MGW_NAME_VALUE_PAIR

IT_NAVIGATION_PATH                Importing            Type      /IWBEP/T_MGW_NAVIGATION_PATH

IO_EXPAND                                   Importing            Type Ref To        /IWBEP/IF_MGW_ODATA_EXPAND

IO_TECH_REQUEST_CONTEXT    Importing            Type Ref To        /IWBEP/IF_MGW_REQ_ENTITY_C

IO_DATA_PROVIDER                    Importing            Type Ref To        /IWBEP/IF_MGW_ENTRY_PROVIDER

ER_DEEP_ENTITY                           Exporting             Type      ZCL_ZGW_XXX_MPC_EXT=>TS_DEEP_ENTITY

 

Code in the method is as follows:

 

Code Snippet:

 

METHOD custom_create_deep_entity.
    DATA: lr_deep_entity TYPE zcl_zgw_XXX_mpc_ext=>ts_deep_entity,
          lv_vbeln       TYPE likp-vbeln,
          lv_pono        TYPE ebeln,
          lt_itm         TYPE ztt_po_inbd_itm,
          ls_itm         TYPE zstr_po_inbd_itm,
          lv_msg         TYPE zcus_msg.

    FIELD-SYMBOLS: <ls_itm> TYPE zcl_zgw_XXX_mpc=>ts_deliverydetails.

*  Transform data into the internal structure
    io_data_provider->read_entry_data(
    IMPORTING
    es_data = lr_deep_entity ).

    lv_pono = lr_deep_entity-pono.

    LOOP AT lr_deep_entity-po2delivery ASSIGNING <ls_itm> .
      ls_itm-poitem = <ls_itm>-poitem.
      ls_itm-matnr = <ls_itm>-matnr.
      ls_itm-quantity = <ls_itm>-quantity.
      ls_itm-unit = <ls_itm>-unit.
      APPEND ls_itm TO lt_itm.
      CLEAR: ls_itm.
    ENDLOOP.

    CALL FUNCTION 'ZFM_CREATE_INBD_DELIVERY'
      EXPORTING
        i_pono         = lr_deep_entity-pono
      IMPORTING
        e_inb_delivery = lv_vbeln
        e_msg          = lv_msg
      TABLES
        it_item        = lt_itm
*       ET_MSGS        =
      .
    IF lv_vbeln IS NOT INITIAL.
      er_deep_entity-message = lv_msg.
    ENDIF.

  ENDMETHOD.

 

Now Since we’ve already Re-defined CreateDeepEntity Method we’re going to call our Custom method inside it.

Code Snippet:

 

DATA: custom_create_deep_entity TYPE zcl_zgw_XXX_mpc_ext=>ts_deep_entity.
    CASE iv_entity_set_name.
      WHEN 'PurhcaseOrderSet'.
*         Call the Entity Set Generated Method
        CALL METHOD me->custom_create_deep_entity
          EXPORTING
            iv_entity_name          = iv_entity_name
            iv_entity_set_name      = iv_entity_set_name
            iv_source_name          = iv_source_name
            it_key_tab              = it_key_tab
            it_navigation_path      = it_navigation_path
            io_expand               = io_expand
            io_tech_request_context = io_tech_request_context
            io_data_provider        = io_data_provider
          IMPORTING
            er_deep_entity          = custom_create_deep_entity.
        copy_data_to_ref(
        EXPORTING
        is_data = custom_create_deep_entity
        CHANGING
        cr_data = er_deep_entity
        ).
    ENDCASE.

Coding part is finished. let’s move to Test the Service.

Testing:

 

  1. Go to Transaction /N/IWFND/MAINT_SERVICE and click on the “Add Service” Button to add your service.
  2. Then click on that service and click on “SAP Gateway Client”.

 

 

3. Execute the $Metadata URL to check the service execution.

           4. Pass the URL for Inbound Delivery Creation and the Payload.

URL:

/sap/opu/odata/sap/ZGW_XXX_SRV/PurhcaseOrderSet

Payload:

{
“Pono” : “4500373800”,
“Message” : ” “,
“PO2Delivery” : [
{
“Poitem” : “00010”,
“Matnr” : “MR311653”,
“Quantity” : “1”,
“Unit” : “CAR”
},
{
“Poitem” : “00020”,
“Matnr” : “MR311551”,
“Quantity” : “1”,
“Unit” : “CAR”
}
]
}

 

Sample Output:

 

Now lets confirm from the Transaction whether the Inbound Delivery was created as we expected or not.

Confirmation:

 

Go to Transaction VL33N to check the Inbound delivery Document.

 

Conclusion:

 

Congratulations! Now you’ll be able to Create an Inbound Delivery by using Odata Service.

 

I hope the above content was useful. Please provide your comments in the comments section.

 

Thank You !

 

Regards

Sri Ram

 

 

2 Comments
You must be Logged on to comment or reply to a post.
  • Hi Sriram!

    Thanks for sharing but I’m a bit confused why this was necessary in S/4HANA since there is a standard API for inbound deliveries: https://api.sap.com/api/API_INBOUND_DELIVERY_SRV_0002/overview/?section=Documentation

    The function module suggested is not a BAPI. Also I’m confused even more why did you create a function module for this and why aren’t you using BOPF and CDS views that would be more appropriate for S/4 environment.

    It would be understandable if this blog was for an older ECC version (pre 7.4) but the title says S/4HANA. Not to mention, the code itself looks very outdated, with Hungarian notation and not using new syntax. Sorry to say but I had to look closely at the date in the blog since something like this would have been typically posted 5 years ago (and there are already many old blogs that describe this type of GW development).

    With regards to ABAP code, please refer to Clean ABAP. There is a lot of information online on CDS views and BOPF. However, even that model is being phased out already and replaced by ABAP RAP as we speak. So you might want to take openSAP class on that too: https://open.sap.com/courses/cp13

    Please reach out to SAP developer advocates internally, it looks like you might have a lot of catching up to do in your skillset. Even I don’t write code like that and I’m an ABAPosaurus. 🙂

  • Hi Jelena,

    Thanks for your valuable suggestions.

    There area few points which i would like to mention here.

    1. There are no standard BAPI’s which are available for this requirement, Hence i am using the FM for this Purpose. (Which i got by debugging the standard Code)
    2. The API which you mentioned was a standard API Provided by SAP which is not related to this topic. (Since i can’t use it directly in my ABAP code)
    3. i mentioned S/4 Hana since am using the system which is a S/4 System to do this OData service development, but as you mentioned it was not completely into S/4 Hana, i will take out that point.
    4. i will definitely catch up my skills with 7.4 Syntaxes and  add BOPF Code from Next blog. also will look into Clean Thanks for that point.
    5. Am already in the process of learning RAP. Hopefully I’ll also write a blog in that in near future.

    Once again Thanks a lot for your suggestions.

    Regards

    Sri Ram