Automatic Posting GI After VLPOD Save in SAP
This guide explains how to enhance SAP to automatically perform
Goods Issue (GI) with movement type Z55 after
VLPOD
(Proof of Delivery) is confirmed or canceled.
The solution uses BADI implementation and
custom function modules.
Business Requirement
After confirming or canceling POD in transaction
VLPOD
, the system should automatically trigger a
MIGO Goods Issue (Z55) posting without requiring
manual intervention.
Technical Design
BADI Implementations
- LE_SHP_DELIVERY_PROC : ZIMPL_POD_TRANSFER
- DELIVERY_PUBLISH : ZIM_DELIVERY_PUBLISH
Custom Function Modules
- ZFG_VLPOD_POST_Z55 → To post Goods Issue
- ZFG_VLPOD_CNCL_Z55 → To cancel Goods Issue
Enhancement Implementation
1. ZIMPL_POD_TRANSFER
METHOD if_ex_le_shp_delivery_proc~save_document_prepare.
IF sy-tcode = 'VLPOD'.
" Capture POD action and delivery data
...
ENDIF.
ENDMETHOD.
2. ZIM_DELIVERY_PUBLISH
METHOD if_ex_delivery_publish~publish_after_save.
IF sy-tcode = 'VLPOD' AND sy-ucomm = 'SICH_T'.
DATA lt_lipsvb TYPE TABLE OF lipsvb.
DATA:
ct_xlikp TYPE shp_likp_t,
lv_pod_act TYPE char10.
REFRESH : lt_lipsvb, ct_xlikp.
IMPORT ct_xlikp TO ct_xlikp FROM MEMORY ID 'ZZ_VLPOD_HDR'.
IMPORT lt_lipsvb TO lt_lipsvb FROM MEMORY ID 'ZZ_VLPOD_ITEM'.
CLEAR lv_pod_act.
IMPORT lv_pod_act TO lv_pod_act FROM MEMORY ID 'ZZ_VLPOD'.
READ TABLE ct_xlikp INTO DATA(ls_likp) INDEX 1.
CASE lv_pod_act.
WHEN 'A'. " Confirm POD
CALL FUNCTION 'ZFG_VLPOD_POST_Z55' IN UPDATE TASK.
COMMIT WORK AND WAIT.
WAIT UP TO 1 SECONDS.
WHEN 'X'. " Cancel POD
CALL FUNCTION 'ZFG_VLPOD_CNCL_Z55' IN UPDATE TASK.
COMMIT WORK AND WAIT.
WAIT UP TO 1 SECONDS.
ENDCASE.
FREE MEMORY ID 'ZZ_VLPOD_HDR'.
FREE MEMORY ID 'ZZ_VLPOD_ITEM'.
FREE MEMORY ID 'ZZ_VLPOD'.
ENDIF.
ENDMETHOD.
Custom Function Modules
ZFG_VLPOD_POST_Z55
Posts the Goods Issue (Z55) by calling BAPI_GOODSMVT_CREATE
with dynamically prepared items.
FUNCTION zfg_vlpod_post_z55.
DATA:
ls_header TYPE bapi2017_gm_head_01,
ls_code TYPE bapi2017_gm_code,
testrun TYPE bapi2017_gm_gen-testrun,
lv_matnr18 TYPE matnr18,
goodsmvt_headret TYPE bapi2017_gm_head_ret,
materialdocument TYPE bapi2017_gm_head_ret-mat_doc,
matdocumentyear TYPE bapi2017_gm_head_ret-doc_year,
lt_smvt_item TYPE TABLE OF bapi2017_gm_item_create,
ls_smvt_item TYPE bapi2017_gm_item_create,
lt_return TYPE TABLE OF bapiret2,
lt_tvpod TYPE TABLE OF zcds_lips_tvpod,
ct_xlikp TYPE shp_likp_t,
lv_pod_act TYPE char10.
DATA :
ls_return TYPE bapiret2,
ex_mblnr TYPE mblnr,
ex_mjahr TYPE mjahr.
CLEAR ct_xlikp.
IMPORT ct_xlikp TO ct_xlikp FROM MEMORY ID 'ZZ_VLPOD_HDR'.
READ TABLE ct_xlikp INTO DATA(ls_likp) INDEX 1.
REFRESH lt_tvpod.
SELECT * FROM zcds_lips_tvpod
INTO TABLE @lt_tvpod
WHERE vbeln = @ls_likp-vbeln AND lfimg_diff NE 0.
ls_code = '03'.
CLEAR: ls_header.
ls_header-pstng_date = ls_likp-podat.
ls_header-doc_date = sy-datum.
ls_header-header_txt = 'INTRANSIT'.
REFRESH lt_smvt_item.
LOOP AT lt_tvpod INTO DATA(ls_tvpod).
CLEAR ls_smvt_item.
CLEAR ls_smvt_item.
CLEAR lv_matnr18.
lv_matnr18 = |{ ls_tvpod-matnr ALPHA = IN }|.
ls_smvt_item-material = lv_matnr18.
ls_smvt_item-plant = ls_tvpod-werks.
ls_smvt_item-batch = ls_tvpod-charg.
ls_smvt_item-move_type = 'Z55'.
ls_smvt_item-spec_stock = 'T'.
ls_smvt_item-entry_qnt = ls_tvpod-lfimg_diff.
ls_smvt_item-entry_uom = ls_tvpod-meins.
ls_smvt_item-val_type = ls_tvpod-bwtar.
ls_smvt_item-costcenter = 'BMC0202'.
ls_smvt_item-deliv_numb = ls_tvpod-vbeln.
ls_smvt_item-deliv_item = ls_tvpod-posnr.
APPEND ls_smvt_item TO lt_smvt_item.
CLEAR ls_tvpod.
ENDLOOP.
CALL FUNCTION 'BAPI_GOODSMVT_CREATE'
EXPORTING
goodsmvt_header = ls_header
goodsmvt_code = ls_code
IMPORTING
materialdocument = ex_mblnr
matdocumentyear = ex_mjahr
TABLES
goodsmvt_item = lt_smvt_item
return = lt_return.
ENDFUNCTION.
ZFG_VLPOD_CNCL_Z55
Cancels the previously posted Goods Issue using
BAPI_GOODSMVT_CANCEL
.
FUNCTION zfg_vlpod_cncl_z55.
*"----------------------------------------------------------------------
*"*"Update Function Module:
*"
*"*"Local Interface:
*"----------------------------------------------------------------------
DATA:
im_mblnr TYPE mblnr,
im_mjahr TYPE mjahr,
im_budat TYPE budat,
im_uname TYPE uname,
im_bktxt TYPE bktxt,
ct_xlikp TYPE shp_likp_t,
lv_pod_act TYPE char10.
DATA :
ex_headret TYPE bapi2017_gm_head_ret,
lt_return TYPE TABLE OF bapiret2,
ls_return TYPE bapiret2,
ex_mblnr TYPE mblnr,
ex_mjahr TYPE mjahr.
CLEAR ct_xlikp.
IMPORT ct_xlikp TO ct_xlikp FROM MEMORY ID 'ZZ_VLPOD_HDR'.
READ TABLE ct_xlikp INTO DATA(ls_likp) INDEX 1.
SELECT SINGLE mblnr, mjahr, budat, bktxt
FROM matdoc
INTO @DATA(ls_matdoc)
WHERE vbeln_im = @ls_likp-vbeln AND
cancelled = '' AND bwart = 'Z55'.
IF ls_matdoc IS NOT INITIAL.
REFRESH lt_return.
CLEAR: im_mblnr, im_mjahr, im_budat, im_uname, im_bktxt.
im_mblnr = ls_matdoc-mblnr.
im_mjahr = ls_matdoc-mjahr.
im_bktxt = ls_matdoc-bktxt.
im_budat = ls_likp-podat.
im_uname = sy-uname.
CALL FUNCTION 'BAPI_GOODSMVT_CANCEL'
EXPORTING
materialdocument = im_mblnr
matdocumentyear = im_mjahr
goodsmvt_pstng_date = im_budat
goodsmvt_pr_uname = im_uname
documentheader_text = im_bktxt
IMPORTING
goodsmvt_headret = ex_headret
TABLES
return = lt_return.
ENDIF.
ENDFUNCTION.
Best Practices
- Always use update tasks to ensure data consistency.
- Free memory IDs after processing to avoid data conflicts.
- Use
WAIT UP TO
carefully to synchronize update tasks.
Conclusion
By implementing BADI enhancements and custom function modules, SAP can automatically handle GI postings after VLPOD confirmation or cancellation. This ensures process efficiency and reduces manual errors in outbound logistics.
Comments
Post a Comment