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:
- Go to Transaction /N/IWFND/MAINT_SERVICE and click on the “Add Service” Button to add your service.
- 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
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.
Once again Thanks a lot for your suggestions.
Regards
Sri Ram