sap|SAP订单上Shipping抬头和行项目字段的持久化实现原理

It is known that we can maintain shipping data for order header and order item separately.
For example, suppose when I have maintained the following data, what happens when save button is clicked?
sap|SAP订单上Shipping抬头和行项目字段的持久化实现原理
文章图片

First all links to this service order is retrieved by function module CRM_GET_ALL_LINKS which works based on database table CRMD_LINK.
sap|SAP订单上Shipping抬头和行项目字段的持久化实现原理
文章图片

The link data has the following format:
sap|SAP订单上Shipping抬头和行项目字段的持久化实现原理
文章图片

The persistence of shipping data is done in function module CRM_SHIPPING_SAVE_OB:
sap|SAP订单上Shipping抬头和行项目字段的持久化实现原理
文章图片

The header guid together with all link data is put into the generic function module CRM_ORDER_UPDATE_TABLES_DETERM, which will calculate current change mode ( insert, update or delete ) by comparing object buffer with database buffer.
sap|SAP订单上Shipping抬头和行项目字段的持久化实现原理
文章图片

In this example, the determined change are two update operations as expected.
sap|SAP订单上Shipping抬头和行项目字段的持久化实现原理
文章图片

Now let’s write a standalone report to perform the change on both header and item shipping data and try to interpret these two changes by our own code.

REPORT crms4_change_shipping.PARAMETERS: inhTYPE crmd_shipping-incoterms2 OBLIGATORY DEFAULT 'header', iniLIKE inh OBLIGATORY DEFAULT 'item', srvo_id TYPE crmd_orderadm_h-object_id OBLIGATORY DEFAULT '8000000111'.DATA: lv_srvo_guidTYPE crmd_orderadm_h-guid, lt_changed_fields TYPE crmt_input_field_tab, ls_changed_fields LIKE LINE OF lt_changed_fields, lt_orderadm_iTYPE TABLE OF crmd_orderadm_i, lt_shippingTYPE crmt_shipping_comt, ls_shippingLIKE LINE OF lt_shipping.START-OF-SELECTION.SELECT SINGLE * INTO @DATA(ls_header) FROM crmd_orderadm_h WHERE object_id = @srvo_id.IF sy-subrc <> 0. WRITE:/ 'Service order not found for id:', srvo_id. RETURN. ENDIF.lv_srvo_guid = ls_header-guid.SELECT SINGLE guid INTO @DATA(lv_item_guid) FROM crmd_orderadm_i WHERE header = @lv_srvo_guid.IF sy-subrc <> 0. WRITE:/ 'No item found for service order:', srvo_id. RETURN. ENDIF.SELECT * INTO TABLE @DATA(lt_link) FROM crmd_link WHERE ( guid_hi = @lv_srvo_guid OR guid_hi = @lv_item_guid ) AND objtype_set = '12'.SELECT * INTO TABLE @DATA(lt_shipping_db) FROM crmd_shipping FOR ALL ENTRIES IN @lt_link WHERE guid = @lt_link-guid_set.IF lines( lt_shipping_db ) <> 2. WRITE:/ 'corrupted shipping data'. RETURN. ENDIF.READ TABLE lt_link ASSIGNING FIELD-SYMBOL() WITH KEY objtype_hi = '05'. IF sy-subrc <> 0. WRITE:/ 'header data does not exist'. RETURN. ENDIF.READ TABLE lt_shipping_db ASSIGNING FIELD-SYMBOL() WITH KEY guid = -guid_set. -incoterms2 = inh. MOVE-CORRESPONDINGTO ls_shipping. ls_shipping-ref_guid = lv_srvo_guid. ls_shipping-ref_kind = 'A'. INSERT ls_shipping INTO TABLE lt_shipping.ls_changed_fields-ref_guid = -guid_hi. ls_changed_fields-ref_kind = 'A'. ls_changed_fields-objectname = 'SHIPPING'. APPEND 'INCOTERMS2' TO ls_changed_fields-field_names. APPEND ls_changed_fields TO lt_changed_fields.READ TABLE lt_link ASSIGNING FIELD-SYMBOL() WITH KEY objtype_hi = '06'. IF sy-subrc <> 0. WRITE:/ 'item data does not exist'. RETURN. ENDIF.READ TABLE lt_shipping_db ASSIGNING FIELD-SYMBOL() WITH KEY guid = -guid_set. -incoterms2 = ini. MOVE-CORRESPONDING TO ls_shipping. ls_shipping-ref_guid = lv_item_guid. ls_shipping-ref_kind = 'B'. INSERT ls_shipping INTO TABLE lt_shipping.CLEAR: ls_changed_fields. ls_changed_fields-ref_guid = -guid_hi. ls_changed_fields-objectname = 'SHIPPING'. ls_changed_fields-ref_kind = 'B'. APPEND 'INCOTERMS2' TO ls_changed_fields-field_names. INSERT ls_changed_fields INTO TABLE lt_changed_fields.CALL FUNCTION 'CRM_ORDER_MAINTAIN' EXPORTING it_shipping= lt_shipping CHANGING ct_input_fields= lt_changed_fields EXCEPTIONS error_occurred= 1 document_locked= 2 no_change_allowed = 3 no_authority= 4.IF sy-subrc <> 0. WRITE: / 'error during quantity change'. RETURN. ENDIF.

Execute the report, specify new incoterms for header and item:
【sap|SAP订单上Shipping抬头和行项目字段的持久化实现原理】sap|SAP订单上Shipping抬头和行项目字段的持久化实现原理
文章图片

And use the following code to capture the change:
DATA: lt_update TYPE crmt_shipping_du_tab, lt_insert TYPE crmt_shipping_du_tab, lt_delete TYPE crmt_shipping_du_tab, lt_guidTYPE crmt_object_guid_tab.DO 2 TIMES. CLEAR: lt_guid. IF sy-index = 1. APPEND -guid TO lt_guid. ELSE. APPEND -guid TO lt_guid. ENDIF. CALL FUNCTION 'CRM_ORDER_UPDATE_TABLES_DETERM' EXPORTING iv_object_name= 'SHIPPING' iv_field_name_key= 'GUID' it_guids_to_process= lt_guid iv_header_to_save= lv_srvo_guid IMPORTING et_records_to_insert = lt_insert et_records_to_update = lt_update et_records_to_delete = lt_delete.READ TABLE lt_update ASSIGNING FIELD-SYMBOL() INDEX 1. IF IS ASSIGNED. CASE sy-index. WHEN 1. WRITE:/ |changes on header, new incoterms: { -incoterms2 }| COLOR COL_GROUP. WHEN 2. WRITE:/ |changes on item, new incoterms: { -incoterms2 }| COLOR COL_KEY. ENDCASE. ENDIF. ENDDO.

And you will see the output, the change is detected correctly as expected.
sap|SAP订单上Shipping抬头和行项目字段的持久化实现原理
文章图片

要获取更多Jerry的原创文章,请关注公众号"汪子熙":
sap|SAP订单上Shipping抬头和行项目字段的持久化实现原理
文章图片

    推荐阅读