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?
First all links to this service order is retrieved by function module CRM_GET_ALL_LINKS which works based on database table CRMD_LINK.
The link data has the following format:
The persistence of shipping data is done in function module CRM_SHIPPING_SAVE_OB:
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.
In this example, the determined change are two update operations as expected.
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: inh TYPE crmd_shipping-incoterms2 OBLIGATORY DEFAULT 'header',
ini LIKE inh OBLIGATORY DEFAULT 'item',
srvo_id TYPE crmd_orderadm_h-object_id OBLIGATORY DEFAULT '8000000111'.
DATA: lv_srvo_guid TYPE crmd_orderadm_h-guid,
lt_changed_fields TYPE crmt_input_field_tab,
ls_changed_fields LIKE LINE OF lt_changed_fields,
lt_orderadm_i TYPE TABLE OF crmd_orderadm_i,
lt_shipping TYPE crmt_shipping_comt,
ls_shipping LIKE 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(<head_link>) 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(<head>) WITH KEY
guid = <head_link>-guid_set.
<head>-incoterms2 = inh.
MOVE-CORRESPONDING <head> TO 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 = <head_link>-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(<item_link>) 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(<item>) WITH KEY
guid = <item_link>-guid_set.
<item>-incoterms2 = ini.
MOVE-CORRESPONDING <item> 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 = <item_link>-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:
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_guid TYPE crmt_object_guid_tab.
DO 2 TIMES.
CLEAR: lt_guid.
IF sy-index = 1.
APPEND <head>-guid TO lt_guid.
ELSE.
APPEND <item>-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(<update>) INDEX 1.
IF <update> IS ASSIGNED.
CASE sy-index.
WHEN 1.
WRITE:/ |changes on header, new incoterms: {<update>-incoterms2}| COLOR COL_GROUP.
WHEN 2.
WRITE:/ |changes on item, new incoterms: {<update>-incoterms2}| COLOR COL_KEY.
ENDCASE.
ENDIF.
ENDDO.
And you will see the output, the change is detected correctly as expected.
要获取更多 Jerry 的原创文章,请关注公众号 ” 汪子熙 ”: