zoukankan      html  css  js  c++  java
  • 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?


    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的原创文章,请关注公众号"汪子熙":

  • 相关阅读:
    Xcode 10 关于 CocoaPods 安装失败的问题RuntimeError
    iOS 解决xcode设置全局断点后 执行视频播放时自动进入断点cxa_throw
    iOS swift String 换行显示
    iOS wkWebView点击链接无反应
    iOS swift跑马灯滚动可以点击
    iOS swift版本无限滚动轮播图
    iOS swift中比较模型数组是否相等
    iOS valueForKeyPath快速计算求和、平均值、最大、最小
    iOS 全屏播放网页视频退出后状态栏被隐藏
    vacabulary1
  • 原文地址:https://www.cnblogs.com/sap-jerry/p/13548920.html
Copyright © 2011-2022 走看看