ITPub博客

首页 > 应用开发 > IT综合 > SAP订单上Shipping抬头和行项目字段的持久化实现原理

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

原创 IT综合 作者:i042416 时间:2020-08-26 20:35:36 0 删除 编辑

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.
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.

And you will see the output, the change is detected correctly as expected.



要获取更多Jerry的原创文章,请关注公众号"汪子熙":


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/24475491/viewspace-2714998/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
测试

注册时间:2018-01-20

  • 博文量
    3822
  • 访问量
    1987309