Transportation Management : Update Means of Transport in Freight Order
Welcome to the technical series of the SAP Transportation Management where we are aiming to learn basic codes that are used in SAP TM.
In this blog post, we will see how to update data in Freight order document through enhancement.
Our requirement here is to update the means of transport in freight order document and we will fetch means of transport from another custom table based on SPI code which is available in outbound delivery.
We have found standard class /SCMTMS/CL_TOR_D_ROOT_BS that gets called when freight document is saved. ( Please let me know if you know any better place to write this enhancement).
My aim here is to make you all aware about the code to update the data in the freight document using BOPF framework.
- So we created post-exit in the method /BOBF/IF_FRW_DETERMINATION~EXECUTE of the class /SCMTMS/CL_TOR_D_ROOT_BS
- First step is to Read the Freight Order and Freight Unit Data
*-- Read the Freight Order and Freight Unit data CALL METHOD io_read->retrieve( EXPORTING it_key = it_key iv_node = /scmtms/if_tor_c=>sc_node-root IMPORTING et_data = lt_d_root ). " This will have FO and FU data
- Then we stored the keys of various documents in different internal table
*-- Get the Key of Freight Order, freight Booking and freight Unit LOOP AT lt_d_root ASSIGNING FIELD-SYMBOL(<lfs_d_root>). CASE <lfs_d_root>-tor_cat. WHEN 'TO' . "Freight Order ( Road) IF <lfs_d_root>-mtr IS INITIAL. " If Means of Transport is initial, then only consider it for processing lt_fo_key = VALUE #( BASE lt_fo_key ( key = <lfs_d_root>-key ) ). ENDIF. WHEN 'BO'. "Freight Booking (Sea) IF <lfs_d_root>-mtr IS INITIAL. " If Means of Transport is initial, then only consider it for processing lt_fb_key = VALUE #( BASE lt_fo_key ( key = <lfs_d_root>-key ) ). ENDIF. WHEN 'FU'. "Freight Unit lt_fu_key = VALUE #( BASE lt_fu_key ( key = <lfs_d_root>-key ) ). APPEND <lfs_d_root> TO lt_d_freight_unit_root. WHEN OTHERS. ENDCASE. ENDLOOP.
- Please note that as of now, we are doing this change for single mode scenario As logic would be complex for multimode scenario.
- Third step is to Get the Delivery Number from Freight Unit
" Get the Delivery Number DATA(lv_delivery_no) = VALUE vbeln( lt_d_freight_unit_root[ 1 ]-labeltxt OPTIONAL ) .
- Next Step is to Get the Means of Transport as per the special processing indicator maintained in the delivery
IF lv_delivery_no IS NOT INITIAL. CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT' EXPORTING input = lv_delivery_no IMPORTING output = lv_delivery_no. DATA : lt_likp TYPE STANDARD TABLE OF likp. CALL FUNCTION 'LIKP_READ' EXPORTING i_vbeln = lv_delivery_no TABLES e_likp = lt_likp EXCEPTIONS no_entry_found = 1 OTHERS = 2. IF sy-subrc = 0. DATA(lv_sdabw) = VALUE #( lt_likp[ 1 ]-sdabw OPTIONAL ). ENDIF. ENDIF.
- Next step is to Fetch the means of Transport value based on Special Processing Indicator from Custom table ZTM_MTR_MAPPING
SELECT SINGLE mtr INTO @DATA(lv_mtr) FROM ztm_mtr_mapping WHERE sdabw = @lv_sdabw. IF sy-subrc = 0 AND lv_mtr IS NOT INITIAL.
- Final Step is to Update the means of Transport value on the freight order. So first Read the freight order Line item data
data lt_item_tr_data TYPE /scmtms/t_tor_item_tr_k. CALL METHOD io_read->retrieve_by_association EXPORTING iv_node = /scmtms/if_tor_c=>sc_node-root it_key = lt_fo_key iv_association = /scmtms/if_tor_c=>sc_association-root-item_tr iv_fill_data = abap_true IMPORTING et_target_key = DATA(lt_fo_tem_tr_key) et_data = lt_item_tr_data EXCEPTIONS OTHERS = 1. IF sy-subrc <> 0. CLEAR lt_item_tr_data. ENDIF.
- Now Create the modification Table to update freight order
DATA : ls_root TYPE /scmtms/s_tor_item_tr_k, lt_chg_fields TYPE /bobf/t_frw_name, lt_mod TYPE /bobf/t_frw_modification. *-- Create the Update table CLEAR lt_chg_fields. INSERT /scmtms/if_tor_c=>sc_node_attribute-item_tr-mtr INTO TABLE lt_chg_fields. LOOP AT lt_order_item_data INTO DATA(ls_fo_item_data). ls_root = CORRESPONDING #( ls_fo_item_data ) . ls_root-mtr = lv_mtr. "UPDATE MTR here IF ls_root IS NOT INITIAL. /scmtms/cl_mod_helper=>mod_update_single( EXPORTING is_data = ls_root it_changed_fields = lt_chg_fields iv_key = ls_root-key iv_node = /scmtms/if_tor_c=>sc_node-item_tr CHANGING ct_mod = lt_mod ). ENDIF. ENDLOOP.
- Final step is to call modify method and pass LT_mod table to it
IF lt_mod IS NOT INITIAL. io_modify->do_modify( EXPORTING it_modification = lt_mod ). io_modify->end_modify( IMPORTING eo_message = lo_message eo_change = lo_change ). ENDIF. "lt_mod IS NOT INITIAL.
- This will Update the Means of transport in the freight order
Hope you enjoyed reading. Please note in real time, we will have to raise various error messages like MTR not available in custom table etc, But here, just to explain how LT_mod is created and how data is updated have kept the example simple.
After the execution of this enhancement, MTR will be updated in below field in freight order
Great blog for technical requirements. Also from functional standpoint you can still use the Condition for Def MTR at the Freight Order type config.
This will give you more flexibility to maintain the condition which is helpful for Functional as well as business users who are going to maintain it longterm.