SAP EWM 参考/N/SCWM/PRDI创建内向交货单

简介:

在SAP EWM模块中,没有能直接在本地创建内向交货单的BAPI或Function Module,不过可以通过调用类的方法进行内向交货单创建。

(在DEMO程序:/SCWM/CREATE_DELIVERY中的BAPI(/SCWM/INB_DLV_SAVEREPLICA),其逻辑流程依然是调用SAP ERP的icf进行交货单创建的,而不是直接在本地创建内向交货单)

在SAP NOTE里查询到可以通过调用类的方法进行内向交货单创建,里面的附件有调用类的示例

1414179 - Technical documents for software development in EWM

使用到的类:/SCWM/CL_SP_PRD_INB(UI服务提供商)、/SCDL/CL_SP_PRD_INB(交付服务提供商)

示例:

内向交货单创建

FUNCTION zewm_fm_inb_delivery_create.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(IV_LGNUM) TYPE  /SCWM/LGNUM OPTIONAL
*"     VALUE(IV_RECEIVING_OFFICE) TYPE  /SCMB/SCU_RO OPTIONAL
*"     VALUE(IV_ENTITLED) TYPE  /SCWM/DE_ENTITLED OPTIONAL
*"     VALUE(IV_DOCTYPE) TYPE  /SCDL/DL_DOCTYPE OPTIONAL
*"     VALUE(IV_DOCCAT) TYPE  /SCDL/DL_DOCCAT OPTIONAL
*"     VALUE(IV_ITEMTYPE) TYPE  /SCDL/DL_ITEMTYPE OPTIONAL
*"  EXPORTING
*"     VALUE(EV_TYPE) TYPE  CHAR1
*"     VALUE(EV_MSG) TYPE  STRING
*"     VALUE(EV_DOCNO) TYPE  /SCDL/DL_DOCNO_INT
*"  TABLES
*"      IT_HEAD_PARTY STRUCTURE  /SCWM/S_SP_A_HEAD_PARTY OPTIONAL
*"      IT_HEAD_REFDOC STRUCTURE  /SCWM/S_SP_A_HEAD_REFDOC OPTIONAL
*"      IT_ITEM STRUCTURE  /SCWM/S_SP_A_ITEM_PRDI OPTIONAL
*"      OT_REFDOC STRUCTURE  ZEWMS0087 OPTIONAL
*"----------------------------------------------------------------------

  DATA: lo_sp_inb            TYPE REF TO /scwm/cl_sp_prd_inb,
        lo_message_box       TYPE REF TO /scdl/cl_sp_message_box,
        lo_adapter_handler   TYPE REF TO /scwm/cl_dlv_handler_adapter,
        ls_details           TYPE /scmb/s_default_values_det,
        ls_dynpro_data       TYPE /scmb/s_dynpro_data,
        ls_default_values    TYPE /scmb/s_default_values,
        lv_rejected          TYPE boole_d,
        lv_synchronously     TYPE boole_d,
        lt_return_codes      TYPE /scdl/t_sp_return_code,
        lt_messages          TYPE /scdl/dm_message_tab,
        ls_a_head_prdi       TYPE /scwm/s_sp_a_head_prdi,
        lt_a_head_prdi       TYPE /scwm/t_sp_a_head_prdi,
        lt_a_head_prdi_out   TYPE /scwm/t_sp_a_head_prdi,
        ls_a_head_party      TYPE /scwm/s_sp_a_head_party,
        lt_a_head_party      TYPE /scwm/t_sp_a_head_party,
        lt_a_head_party_out  TYPE /scwm/t_sp_a_head_party,
        ls_a_head_party_rel  TYPE /scdl/s_sp_a_head,
        ls_a_head_refdoc     TYPE /scwm/s_sp_a_head_refdoc,
        lt_a_head_refdoc     TYPE /scwm/t_sp_a_head_refdoc,
        lt_a_head_refdoc_out TYPE /scwm/t_sp_a_head_refdoc,
        ls_a_head_refdoc_rel TYPE /scdl/s_sp_a_head,
        ls_k_head_refdoc     TYPE /scdl/s_sp_k_head_refdoc,
        lt_k_head_refdoc     TYPE /scdl/t_sp_k_head_refdoc,
        ls_a_item_prdi       TYPE /scwm/s_sp_a_item_prdi,
        lt_a_item_prdi       TYPE /scwm/t_sp_a_item_prdi,
        lt_a_item_prdi_out   TYPE /scwm/t_sp_a_item_prdi,
        ls_a_item_prdi_rel   TYPE /scdl/s_sp_a_head,
        ls_a_item_refdoc     TYPE /scwm/s_sp_a_item_refdoc,
        lt_a_item_refdoc     TYPE /scwm/t_sp_a_item_refdoc,
        lt_a_item_refdoc_out TYPE /scwm/t_sp_a_item_refdoc,
        ls_a_item_refdoc_rel TYPE /scdl/s_sp_a_head,
        ls_k_head            TYPE /scdl/s_sp_k_head,
        lt_k_head            TYPE /scdl/t_sp_k_head,
        ls_k_item            TYPE /scdl/s_sp_k_item,
        lt_k_item            TYPE /scdl/t_sp_k_item.
  DATA: lv_ebeln TYPE ebeln,
        lv_posnr TYPE posnr.

  DATA: lv_aspect_name TYPE string.
  DATA: lv_relation TYPE string.
  DATA: lv_type TYPE c,
        lv_msg  TYPE string.

  DATA: lv_docid    TYPE /scdl/dl_docid.

*&---create service provider for processing delivery and and message box
  TRY.
      CREATE OBJECT lo_adapter_handler.

      CREATE OBJECT lo_sp_inb
        EXPORTING
          iv_mode              = /scdl/cl_sp=>sc_mode_classic
          io_attribute_handler = lo_adapter_handler
          io_message_handler   = lo_adapter_handler.
  ENDTRY.

  PERFORM frm_cleanup USING lo_sp_inb.

*&---设置初始值
  ls_details-v_fieldname = 'LGNUM'.
  ls_details-v_mandatory = abap_true.
  ls_details-v_memoryid = '/SCWM/LGN'.
  ls_details-v_no_dropdown = 'X'.
  APPEND ls_details TO ls_default_values-t_details.
  CLEAR ls_details.
  ls_details-v_fieldname = 'RECEIVING_OFFICE'.
  ls_details-v_mandatory = abap_true.
  ls_details-v_memoryid = '/SCMB/SCU_RO'.
  ls_details-v_no_dropdown = 'X'.
  APPEND ls_details TO ls_default_values-t_details.
  ls_details-v_fieldname = 'ENTITLED'.
  ls_details-v_mandatory = abap_true.
  ls_details-v_memoryid = '/SCWM/ENTITLED'.
  ls_details-v_no_dropdown = 'X'.
  APPEND ls_details TO ls_default_values-t_details.
  ls_details-v_fieldname = 'HU_DISPLAY'.
  APPEND ls_details TO ls_default_values-t_details.

  ls_default_values-v_identifier = '/SCWM/PRDI'.
  ls_default_values-v_values_structure = '/SCWM/S_SP_DEFAULT'.
  ls_default_values-v_extended = abap_true.

  SET PARAMETER ID '/SCWM/LGN' FIELD iv_lgnum.  "仓库编号/综合仓库
  SET PARAMETER ID '/SCMB/SCU_RO' FIELD iv_receiving_office."供应链单位:收货办公室 (RO)
  SET PARAMETER ID '/SCWM/ENTITLED' FIELD iv_entitled."授权处理方

  /scmb/cl_base=>set_process_data( io_attribute_handler     = lo_adapter_handler->mo_attr_handler
                               io_service_provider      = lo_sp_inb
                               io_message_handler       = lo_adapter_handler->mo_msg_handler
                               is_dynpro_data           = ls_dynpro_data
                               is_default_values        = ls_default_values
                               iv_disable_standard_save = abap_true ).

  CALL METHOD /scmb/cl_base=>end_of_initialization.

*&---设置仓库编号
  /scwm/cl_tm=>set_lgnum( iv_lgnum ).

*&---INSERT HEAD
  CLEAR: lv_aspect_name.
  lv_aspect_name = /scwm/if_sp_c=>sc_asp_head."'/SCWM/S_SP_A_HEAD'

  CLEAR: ls_a_head_prdi.
  ls_a_head_prdi-doctype = iv_doctype."凭证类型
  ls_a_head_prdi-doccat  = iv_doccat. "凭证类别
  APPEND ls_a_head_prdi TO lt_a_head_prdi.

  CLEAR: lt_a_head_prdi_out,lv_rejected,lt_return_codes.
  CALL METHOD lo_sp_inb->insert
    EXPORTING
      inrecords    = lt_a_head_prdi
      aspect       = lv_aspect_name
    IMPORTING
      outrecords   = lt_a_head_prdi_out
      rejected     = lv_rejected
      return_codes = lt_return_codes.
  READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
  IF sy-subrc = 0 OR lv_rejected = abap_true.
    MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
      INTO lv_msg.
    ev_type = 'E'.
    ev_msg  = '抬头创建失败!' && lv_msg.

    PERFORM frm_cleanup USING lo_sp_inb.
    EXIT.
  ELSE.
    CLEAR: lv_docid,ls_a_head_prdi.
    READ TABLE lt_a_head_prdi_out INTO ls_a_head_prdi INDEX 1.
    IF sy-subrc EQ 0.
      lv_docid = ls_a_head_prdi-docid.
    ENDIF.
    CLEAR: ls_a_head_prdi.
  ENDIF.

*&---INSERT HEAD_PARTY
  IF it_head_party[] IS NOT INITIAL.
    CLEAR: lv_aspect_name.
    lv_aspect_name = /scwm/if_sp_c=>sc_asp_head_party."/SCWM/S_SP_A_HEAD_PARTY

    CLEAR: lv_relation.
    lv_relation = /scwm/if_sp_c=>sc_rel_head_to_party."/SCWM/HEAD_TO_PARTY

    CLEAR: ls_k_head.
    ls_k_head-docid = lv_docid.

    LOOP AT it_head_party.
      CLEAR: ls_a_head_party.
      ls_a_head_party-party_role = it_head_party-party_role."合作伙伴角色
      ls_a_head_party-partyno    = it_head_party-partyno."业务合作伙伴编号
      APPEND ls_a_head_party TO lt_a_head_party.
    ENDLOOP.

    CLEAR: lt_a_head_party_out,ls_a_head_party_rel,lv_rejected,lt_return_codes.
    CALL METHOD lo_sp_inb->insert
      EXPORTING
        inrecords          = lt_a_head_party
        aspect             = lv_aspect_name
        relation           = lv_relation
        relation_inkey     = ls_k_head
      IMPORTING
        outrecords         = lt_a_head_party_out
        relation_outrecord = ls_a_head_party_rel
        rejected           = lv_rejected
        return_codes       = lt_return_codes.
    READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
    IF sy-subrc = 0 OR lv_rejected = abap_true.
      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '合作伙伴添加失败!' && lv_msg.

      PERFORM frm_cleanup USING lo_sp_inb.
      EXIT.
    ENDIF.
  ENDIF.

*&---INSERT HEAD_REFDOC
  IF it_head_refdoc[] IS NOT INITIAL.
    "添加参考凭证
    CLEAR: lv_aspect_name.
    lv_aspect_name = /scwm/if_sp_c=>sc_asp_head_refdoc."/SCWM/S_SP_A_HEAD_REFDOC

    CLEAR: lv_relation.
    lv_relation = /scdl/if_sp_c=>sc_rel_head_to_refdoc."'/SCDL/HEAD_TO_REFDOC'

    CLEAR: ls_k_head.
    ls_k_head-docid = lv_docid.

    CLEAR: lt_a_head_refdoc[].
    LOOP AT it_head_refdoc.
      CLEAR: ls_a_head_refdoc.
      ls_a_head_refdoc-refdoccat = it_head_refdoc-refdoccat."参考凭证类别
      ls_a_head_refdoc-refdocno  = it_head_refdoc-refdocno. "参考凭证编号
      ls_a_head_refdoc-date      = sy-datum."日期
      ls_a_head_refdoc-time      = sy-uzeit."时间
      APPEND ls_a_head_refdoc TO lt_a_head_refdoc.
    ENDLOOP.

    CLEAR: lt_a_head_refdoc_out,ls_a_head_refdoc_rel,lv_rejected,lt_return_codes.
    CALL METHOD lo_sp_inb->insert
      EXPORTING
        inrecords          = lt_a_head_refdoc
        aspect             = lv_aspect_name
        relation           = lv_relation
        relation_inkey     = ls_k_head
      IMPORTING
        outrecords         = lt_a_head_refdoc_out
        relation_outrecord = ls_a_head_refdoc_rel
        rejected           = lv_rejected
        return_codes       = lt_return_codes.
    READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
    IF sy-subrc = 0 OR lv_rejected = abap_true.
      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '参考凭证添加失败!' && lv_msg.

      PERFORM frm_cleanup USING lo_sp_inb.
      EXIT.
    ENDIF.

    "由于ASN类型的参考凭证必输,故先获取初始的参考凭证,将其作为ASN的参考凭证
    CLEAR: lv_aspect_name.
    lv_aspect_name = /scwm/if_sp_c=>sc_asp_head_refdoc."/SCWM/S_SP_A_HEAD_REFDOC

    CLEAR: ls_k_head_refdoc,lt_k_head_refdoc.
    ls_k_head_refdoc-docid = lv_docid.
    ls_k_head_refdoc-refdoccat = 'ERP'.
    APPEND ls_k_head_refdoc TO lt_k_head_refdoc.

    CLEAR: lt_a_head_refdoc_out,lv_rejected,lt_return_codes.
    CALL METHOD lo_sp_inb->select
      EXPORTING
        inkeys       = lt_k_head_refdoc
        aspect       = lv_aspect_name
      IMPORTING
        outrecords   = lt_a_head_refdoc_out
        rejected     = lv_rejected
        return_codes = lt_return_codes.
    READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
    IF sy-subrc = 0 OR lv_rejected = abap_true.
      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '参考凭证获取失败!' && lv_msg.

      PERFORM frm_cleanup USING lo_sp_inb.
      EXIT.
    ENDIF.

    IF lt_a_head_refdoc_out[] IS NOT INITIAL.
      READ TABLE lt_a_head_refdoc_out INTO DATA(ls_head_refdoc)
        WITH KEY docid = lv_docid
                 refdoccat = 'ERP'.
      IF sy-subrc EQ 0.
        CLEAR: ls_a_head_refdoc,lt_a_head_refdoc[].
        ls_a_head_refdoc-refdoccat = 'ASN'."参考凭证类别
        ls_a_head_refdoc-refdocno  = ls_head_refdoc-refdocno. "参考凭证编号
        ls_a_head_refdoc-date      = sy-datum."日期
        ls_a_head_refdoc-time      = sy-uzeit."时间
        APPEND ls_a_head_refdoc TO lt_a_head_refdoc.
      ENDIF.

      "添加参考凭证
      CLEAR: lv_aspect_name.
      lv_aspect_name = /scwm/if_sp_c=>sc_asp_head_refdoc."/SCWM/S_SP_A_HEAD_REFDOC

      CLEAR: lv_relation.
      lv_relation = /scdl/if_sp_c=>sc_rel_head_to_refdoc."'/SCDL/HEAD_TO_REFDOC'

      CLEAR: ls_k_head.
      ls_k_head-docid = lv_docid.

      CLEAR: lt_a_head_refdoc_out,ls_a_head_refdoc_rel,lv_rejected,lt_return_codes.
      CALL METHOD lo_sp_inb->insert
        EXPORTING
          inrecords          = lt_a_head_refdoc
          aspect             = lv_aspect_name
          relation           = lv_relation
          relation_inkey     = ls_k_head
        IMPORTING
          outrecords         = lt_a_head_refdoc_out
          relation_outrecord = ls_a_head_refdoc_rel
          rejected           = lv_rejected
          return_codes       = lt_return_codes.
      READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
      IF sy-subrc = 0 OR lv_rejected = abap_true.
        MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
          INTO lv_msg.
        ev_type = 'E'.
        ev_msg  = 'ASN参考凭证添加失败!' && lv_msg.

        PERFORM frm_cleanup USING lo_sp_inb.
        EXIT.
      ENDIF.
    ENDIF.
  ENDIF.

*&---INSERT ITEM
  IF it_item[] IS NOT INITIAL.
    CLEAR: lv_aspect_name.
    lv_aspect_name = /scwm/if_sp_c=>sc_asp_item."'/SCWM/S_SP_A_ITEM'

    CLEAR: lv_relation.
    lv_relation = /scdl/if_sp_c=>sc_rel_head_to_item."'/SCDL/HEAD_TO_ITEM'

    CLEAR: ls_k_head.
    ls_k_head-docid = lv_docid.

    DATA(lv_lines) = lines( it_item[] ).
    DO lv_lines TIMES.
      CLEAR: ls_a_item_prdi.
      ls_a_item_prdi-itemtype       = iv_itemtype."项目类型
      ls_a_item_prdi-manual_header  = 'X'.        "手动生成
      ls_a_item_prdi-doccat         = iv_doccat.  "凭证类别
      ls_a_item_prdi-doctype        = iv_doctype. "凭证类型
      APPEND ls_a_item_prdi TO lt_a_item_prdi.
    ENDDO.

    CLEAR: lt_a_item_prdi_out,ls_a_item_prdi_rel,lv_rejected,lt_return_codes.
    CALL METHOD lo_sp_inb->insert
      EXPORTING
        inrecords          = lt_a_item_prdi
        aspect             = lv_aspect_name
        relation           = lv_relation
        relation_inkey     = ls_k_head
      IMPORTING
        outrecords         = lt_a_item_prdi_out
        relation_outrecord = ls_a_item_prdi_rel
        rejected           = lv_rejected
        return_codes       = lt_return_codes.
    READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
    IF sy-subrc = 0 OR lv_rejected = abap_true.
      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '行项目创建失败!' && lv_msg.

      PERFORM frm_cleanup USING lo_sp_inb.
      EXIT.
    ENDIF.

*&---COMPLETE ITEM
    CLEAR: lt_a_item_prdi.
    lt_a_item_prdi = lt_a_item_prdi_out.
    LOOP AT lt_a_item_prdi ASSIGNING FIELD-SYMBOL(<fs_item>).
      READ TABLE it_item INDEX sy-tabix.
      IF sy-subrc EQ 0.
        <fs_item>-manual        = 'X'."手动生成
        <fs_item>-changeable    = 'X'."
*      <fs_item>-productid     = it_item-productid.      "产品标识
        <fs_item>-productno     = it_item-productno.    "产品
*      <fs_item>-productno_ext = it_item-productno_ext.  "外部产品
        <fs_item>-qty_ui        = it_item-qty_ui. "数量
        <fs_item>-qty           = it_item-qty.    "数量
        <fs_item>-uom           = it_item-uom.    "计量单位
        <fs_item>-/scwm/gmbin   = it_item-/scwm/gmbin.    "货物移动过帐的存储位
        <fs_item>-stock_category = it_item-stock_category."库存类型
      ENDIF.
    ENDLOOP.

    CLEAR: lv_aspect_name.
    lv_aspect_name = /scwm/if_sp_c=>sc_asp_item."'/SCWM/S_SP_A_ITEM'

    CLEAR: lt_a_item_prdi_out,ls_a_item_prdi_rel,lv_rejected,lt_return_codes.
    CALL METHOD lo_sp_inb->update
      EXPORTING
        inrecords    = lt_a_item_prdi
        aspect       = lv_aspect_name
      IMPORTING
        outrecords   = lt_a_item_prdi_out
        rejected     = lv_rejected
        return_codes = lt_return_codes.
    READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
    IF sy-subrc = 0 OR lv_rejected = abap_true.
      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '行项目数据添加失败!' && lv_msg.

      PERFORM frm_cleanup USING lo_sp_inb.
      EXIT.
    ENDIF.
  ENDIF.


*&---SAVE
  CLEAR: lv_rejected.
  CALL METHOD lo_sp_inb->before_save
    IMPORTING
      rejected = lv_rejected.
  IF lv_rejected = abap_true.
    MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
      INTO lv_msg.
    ev_type = 'E'.
    ev_msg  = '保存前校验失败!' && lv_msg.

    PERFORM frm_cleanup USING lo_sp_inb.
    EXIT.
  ENDIF.

  CLEAR: lv_rejected.
  CALL METHOD lo_sp_inb->save
    EXPORTING
      synchronously = lv_synchronously
    IMPORTING
      rejected      = lv_rejected.
  CASE lv_rejected.
    WHEN abap_false.
      COMMIT WORK AND WAIT .

      SELECT DISTINCT
          a~docid,
          a~itemid,
          a~docno,
          a~itemno,
          a~productno,
          b~refdoccat,
          a~docno AS refdocno,
          a~itemno AS refitemno
        FROM /scdl/db_proci_i AS a
          INNER JOIN /scdl/db_refdoc AS b
              ON b~docid EQ a~docid AND b~itemid EQ a~itemid
        WHERE a~docid EQ @lv_docid
          AND b~refdoccat EQ 'ERP'
        INTO TABLE @ot_refdoc.
      IF sy-subrc EQ 0.
        READ TABLE ot_refdoc INDEX 1.
        ev_docno = ot_refdoc-docno.
      ENDIF.

      "将交货单和行号作为行的参考
      IF ot_refdoc[] IS NOT INITIAL.
        lt_k_head = CORRESPONDING #(  ot_refdoc[] MAPPING docid = docid ).
        SORT lt_k_head .
        DELETE ADJACENT DUPLICATES FROM lt_k_head COMPARING ALL FIELDS.

        CLEAR: lt_a_item_refdoc[].
        LOOP AT ot_refdoc INTO DATA(ls_refdoc).
          CLEAR: lv_ebeln,lv_posnr.
          lv_ebeln = |{ ls_refdoc-docno ALPHA = OUT }|.
          lv_ebeln = |{ lv_ebeln ALPHA = IN }|.
          lv_posnr = |{ ls_refdoc-itemno ALPHA = OUT }|.
          lv_posnr = |{ lv_posnr ALPHA = IN }|.

          CLEAR: ls_a_item_refdoc.
          ls_a_item_refdoc-docid     = ls_refdoc-docid.
          ls_a_item_refdoc-itemid    = ls_refdoc-itemid.
          ls_a_item_refdoc-refdoccat = 'ERP'.
          ls_a_item_refdoc-refdocno  = lv_ebeln.
          ls_a_item_refdoc-refitemno = lv_posnr.
          ls_a_item_refdoc-date      = sy-datum.
          ls_a_item_refdoc-time      = sy-uzeit.
          APPEND ls_a_item_refdoc TO lt_a_item_refdoc.

          CLEAR: ls_a_item_refdoc,ls_refdoc.
          CLEAR: lv_ebeln,lv_posnr.
        ENDLOOP.
        SORT lt_a_item_refdoc.
        DELETE ADJACENT DUPLICATES FROM lt_a_item_refdoc COMPARING ALL FIELDS.

        IF lt_k_head[] IS NOT INITIAL AND lt_a_item_refdoc[] IS NOT INITIAL.
          CLEAR: lv_type,lv_msg.
          CALL FUNCTION 'ZEWM_FM_INBDLV_ITEMREFDOC'
            EXPORTING
              iv_lgnum            = iv_lgnum
              iv_receiving_office = iv_receiving_office
              iv_entitled         = iv_entitled
            IMPORTING
              ev_type             = lv_type
              ev_msg              = lv_msg
            TABLES
              it_head             = lt_k_head
              it_item_refdoc      = lt_a_item_refdoc.
          IF lv_type EQ 'E'.
            "由于交货单行项目的参考凭证写入失败,会影响后续业务流程的处理,故需要删除该交货单
            DO 5 TIMES.
              CLEAR: lv_type,lv_msg.
              CALL FUNCTION 'ZEWM_FM_INBDLV_DELETE'
                EXPORTING
                  iv_lgnum            = iv_lgnum
                  iv_receiving_office = iv_receiving_office
                  iv_entitled         = iv_entitled
                IMPORTING
                  ev_type             = lv_type
                  ev_msg              = lv_msg
                TABLES
                  it_head             = lt_k_head.

              IF lv_type EQ 'E'.
                WAIT UP TO 1 SECONDS.
              ELSE.
                EXIT.
              ENDIF.
            ENDDO.

            ev_type = 'E'.
            ev_msg  = '创建失败!'.
            CLEAR: ot_refdoc[].
          ELSE.
            ev_type = 'S'.
            ev_msg  = '创建成功!'.
          ENDIF.
        ENDIF.
      ENDIF.
    WHEN abap_true.
      ROLLBACK WORK.

      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '提交数据库失败!' && lv_msg.
    WHEN OTHERS.
  ENDCASE.

  PERFORM frm_cleanup USING lo_sp_inb.

  CALL METHOD lo_sp_inb->cleanup
    EXPORTING
      reason = /scmb/if_sp_transaction=>sc_cleanup_commit.


ENDFUNCTION.

FORM frm_cleanup USING fo_sp_inb TYPE REF TO /scwm/cl_sp_prd_inb.

  CALL METHOD fo_sp_inb->cleanup
    EXPORTING
      reason = /scmb/if_sp_transaction=>sc_cleanup_commit.

ENDFORM.

交货单行项目参考凭证添加

FUNCTION zewm_fm_inbdlv_itemrefdoc.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(IV_LGNUM) TYPE  /SCWM/LGNUM OPTIONAL
*"     VALUE(IV_RECEIVING_OFFICE) TYPE  /SCMB/SCU_RO OPTIONAL
*"     VALUE(IV_ENTITLED) TYPE  /SCWM/DE_ENTITLED OPTIONAL
*"  EXPORTING
*"     VALUE(EV_TYPE) TYPE  CHAR1
*"     VALUE(EV_MSG) TYPE  STRING
*"  TABLES
*"      IT_HEAD TYPE  /SCDL/T_SP_K_HEAD OPTIONAL
*"      IT_ITEM_REFDOC TYPE  /SCWM/T_SP_A_ITEM_REFDOC OPTIONAL
*"----------------------------------------------------------------------

  DATA: lo_sp_inb            TYPE REF TO /scwm/cl_sp_prd_inb,
        lo_adapter_handler   TYPE REF TO /scwm/cl_dlv_handler_adapter,
        ls_details           TYPE /scmb/s_default_values_det,
        ls_dynpro_data       TYPE /scmb/s_dynpro_data,
        ls_default_values    TYPE /scmb/s_default_values,
        lv_rejected          TYPE boole_d,
        lv_synchronously     TYPE boole_d,
        ls_a_head_prdi       TYPE /scwm/s_sp_a_head_prdi,
        lt_a_head_prdi       TYPE /scwm/t_sp_a_head_prdi,
        lt_a_head_prdi_out   TYPE /scwm/t_sp_a_head_prdi,
        lt_return_codes      TYPE /scdl/t_sp_return_code,
        ls_a_head_refdoc     TYPE /scwm/s_sp_a_head_refdoc,
        lt_a_head_refdoc     TYPE /scwm/t_sp_a_head_refdoc,
        lt_a_head_refdoc_out TYPE /scwm/t_sp_a_head_refdoc,
        ls_a_head_refdoc_rel TYPE /scdl/s_sp_a_head,
        ls_a_item_prdi       TYPE /scwm/s_sp_a_item_prdi,
        lt_a_item_prdi       TYPE /scwm/t_sp_a_item_prdi,
        lt_a_item_prdi_out   TYPE /scwm/t_sp_a_item_prdi,
        ls_a_item_refdoc     TYPE /scwm/s_sp_a_item_refdoc,
        lt_a_item_refdoc     TYPE /scwm/t_sp_a_item_refdoc,
        lt_a_item_refdoc_out TYPE /scwm/t_sp_a_item_refdoc,
        ls_a_item_refdoc_rel TYPE /scdl/s_sp_a_head,
        ls_k_head            TYPE /scdl/s_sp_k_head,
        lt_k_head            TYPE /scdl/t_sp_k_head,
        ls_k_item            TYPE /scdl/s_sp_k_item,
        lt_k_item            TYPE /scdl/t_sp_k_item,
        ls_k_item_refdoc     TYPE /scdl/s_sp_k_item_refdoc,
        lt_k_item_refdoc     TYPE /scdl/t_sp_k_item_refdoc,
        ls_sp_action         TYPE /scdl/s_sp_act_action.
  DATA: lv_ebeln TYPE ebeln,
        lv_posnr TYPE posnr.

  DATA: lv_msg TYPE string.

  CHECK it_head[] IS NOT INITIAL.
  CHECK it_item_refdoc[] IS NOT INITIAL.

*&---create service provider for processing delivery and and message box
  TRY.
      CREATE OBJECT lo_adapter_handler.

      CREATE OBJECT lo_sp_inb
        EXPORTING
          iv_mode              = /scdl/cl_sp=>sc_mode_classic
          io_attribute_handler = lo_adapter_handler
          io_message_handler   = lo_adapter_handler.
  ENDTRY.

  PERFORM frm_cleanup USING lo_sp_inb.

*&---设置初始值
  ls_details-v_fieldname = 'LGNUM'.
  ls_details-v_mandatory = abap_true.
  ls_details-v_memoryid = '/SCWM/LGN'.
  ls_details-v_no_dropdown = 'X'.
  APPEND ls_details TO ls_default_values-t_details.
  CLEAR ls_details.
  ls_details-v_fieldname = 'RECEIVING_OFFICE'.
  ls_details-v_mandatory = abap_true.
  ls_details-v_memoryid = '/SCMB/SCU_RO'.
  ls_details-v_no_dropdown = 'X'.
  APPEND ls_details TO ls_default_values-t_details.
  ls_details-v_fieldname = 'ENTITLED'.
  ls_details-v_mandatory = abap_true.
  ls_details-v_memoryid = '/SCWM/ENTITLED'.
  ls_details-v_no_dropdown = 'X'.
  APPEND ls_details TO ls_default_values-t_details.
  ls_details-v_fieldname = 'HU_DISPLAY'.
  APPEND ls_details TO ls_default_values-t_details.

  ls_default_values-v_identifier = '/SCWM/PRDI'.
  ls_default_values-v_values_structure = '/SCWM/S_SP_DEFAULT'.
  ls_default_values-v_extended = abap_true.

  SET PARAMETER ID '/SCWM/LGN' FIELD iv_lgnum.  "仓库编号/综合仓库
  SET PARAMETER ID '/SCMB/SCU_RO' FIELD iv_receiving_office."供应链单位:收货办公室 (RO)
  SET PARAMETER ID '/SCWM/ENTITLED' FIELD iv_entitled."授权处理方

  /scmb/cl_base=>set_process_data( io_attribute_handler     = lo_adapter_handler->mo_attr_handler
                               io_service_provider      = lo_sp_inb
                               io_message_handler       = lo_adapter_handler->mo_msg_handler
                               is_dynpro_data           = ls_dynpro_data
                               is_default_values        = ls_default_values
                               iv_disable_standard_save = abap_true ).

  CALL METHOD /scmb/cl_base=>end_of_initialization.

*&---设置仓库编号
  /scwm/cl_tm=>set_lgnum( iv_lgnum ).

*&---fill GUID of delivery header
  CLEAR: lt_k_head.
  lt_k_head[] = it_head[].
  SORT lt_k_head BY docid.
  DELETE ADJACENT DUPLICATES FROM lt_k_head COMPARING docid.

*&---try to lock (also creates the delivery instance immediately)
  CLEAR: lv_rejected,lt_return_codes.
  CALL METHOD lo_sp_inb->lock
    EXPORTING
      inkeys       = lt_k_head[]
      aspect       = /scwm/if_sp_c=>sc_asp_head
      lockmode     = /scdl/if_sp1_locking=>sc_exclusive_lock
    IMPORTING
      rejected     = lv_rejected
      return_codes = lt_return_codes.

  "check if any error occurred
  READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
  IF sy-subrc = 0 OR lv_rejected = abap_true.
    MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
      INTO lv_msg.
    ev_type = 'E'.
    ev_msg = '锁定交货单失败!' && lv_msg.

    PERFORM frm_cleanup USING lo_sp_inb.
    EXIT.
  ENDIF.

*&---select head data
  CLEAR: lt_k_head.
  lt_k_head[] = it_head[].

  CLEAR: lt_a_head_prdi_out,lv_rejected,lt_return_codes.
  CALL METHOD lo_sp_inb->select
    EXPORTING
      inkeys       = lt_k_head
      aspect       = /scwm/if_sp_c=>sc_asp_head
    IMPORTING
      outrecords   = lt_a_head_prdi_out
      rejected     = lv_rejected
      return_codes = lt_return_codes.
  "check if any error occurred
  READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
  IF sy-subrc = 0 OR lv_rejected = abap_true.
    MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
      INTO lv_msg.
    ev_type = 'E'.
    ev_msg = '获取交货单抬头数据失败!' && lv_msg.

    PERFORM frm_cleanup USING lo_sp_inb.
    EXIT.
  ENDIF.


*&---insert item refdoc
  IF it_item_refdoc[] IS NOT INITIAL.
    LOOP AT it_head.
      CLEAR: lt_a_head_refdoc[].

      LOOP AT it_item_refdoc WHERE docid EQ it_head-docid.
        CLEAR: ls_a_head_refdoc.
        ls_a_head_refdoc-docid     = it_item_refdoc-docid."
        ls_a_head_refdoc-refdoccat = it_item_refdoc-refdoccat."参考凭证类别
        ls_a_head_refdoc-refdocno  = it_item_refdoc-refdocno. "参考凭证编号
        ls_a_head_refdoc-date      = sy-datum."日期
        ls_a_head_refdoc-time      = sy-uzeit."时间
        APPEND ls_a_head_refdoc TO lt_a_head_refdoc.

        CLEAR: lt_a_item_refdoc.
        APPEND it_item_refdoc TO lt_a_item_refdoc.

        CLEAR: ls_k_item.
        ls_k_item-docid  = it_item_refdoc-docid.
        ls_k_item-itemid = it_item_refdoc-itemid.

        CLEAR: lt_a_item_refdoc_out,ls_a_item_refdoc_rel,lv_rejected,lt_return_codes.
        CALL METHOD lo_sp_inb->insert
          EXPORTING
            inrecords          = lt_a_item_refdoc
            aspect             = /scwm/if_sp_c=>sc_asp_item_refdoc
            relation           = /scdl/if_sp_c=>sc_rel_item_to_refdoc
            relation_inkey     = ls_k_item
          IMPORTING
            outrecords         = lt_a_item_refdoc_out
            relation_outrecord = ls_a_item_refdoc_rel
            rejected           = lv_rejected
            return_codes       = lt_return_codes.
        "check if any error occurred
        READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
        IF sy-subrc = 0 OR lv_rejected = abap_true.
          MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
            INTO lv_msg.
          ev_type = 'E'.
          ev_msg = '添加交货单行项目参考凭证失败!' && lv_msg.

          PERFORM frm_cleanup USING lo_sp_inb.
          EXIT.
        ENDIF.
        CLEAR: it_item_refdoc.
      ENDLOOP.

      CHECK ev_type NE 'E'.

      CLEAR: ls_k_head.
      ls_k_head-docid = it_head-docid.

      SORT lt_a_head_refdoc.
      DELETE ADJACENT DUPLICATES FROM lt_a_head_refdoc COMPARING ALL FIELDS.

      CLEAR: lt_a_head_refdoc_out,ls_a_head_refdoc_rel,lv_rejected,lt_return_codes.
      CALL METHOD lo_sp_inb->insert
        EXPORTING
          inrecords          = lt_a_head_refdoc
          aspect             = /scwm/if_sp_c=>sc_asp_head_refdoc
          relation           = /scdl/if_sp_c=>sc_rel_head_to_refdoc
          relation_inkey     = ls_k_head
        IMPORTING
          outrecords         = lt_a_head_refdoc_out
          relation_outrecord = ls_a_head_refdoc_rel
          rejected           = lv_rejected
          return_codes       = lt_return_codes.
      READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
      IF sy-subrc = 0 OR lv_rejected = abap_true.
        MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
          INTO lv_msg.
        ev_type = 'E'.
        ev_msg  = '添加交货单抬头参考凭证失败!' && lv_msg.

        PERFORM frm_cleanup USING lo_sp_inb.
        EXIT.
      ENDIF.

      CLEAR: it_head.
      CLEAR: lt_a_head_refdoc.
    ENDLOOP.

  ENDIF.

  CHECK ev_type NE 'E'.

*&---save delivery dependant on if error occurred or not.
  CLEAR: lv_rejected.
  CALL METHOD lo_sp_inb->before_save
    IMPORTING
      rejected = lv_rejected.
  IF lv_rejected = abap_true.
    MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
      INTO lv_msg.
    ev_type = 'E'.
    ev_msg  = '保存前校验失败!' && lv_msg.

    PERFORM frm_cleanup USING lo_sp_inb.
    EXIT.
  ENDIF.

  CLEAR: lv_rejected.
  CALL METHOD lo_sp_inb->save
    EXPORTING
      synchronously = lv_synchronously
    IMPORTING
      rejected      = lv_rejected.
  CASE lv_rejected.
    WHEN abap_false.
      COMMIT WORK AND WAIT .
      ev_type = 'S'.
      ev_msg  = '交货单更新成功'.
    WHEN abap_true.
      ROLLBACK WORK.

      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '交货单更新失败!' && lv_msg.
    WHEN OTHERS.
  ENDCASE.

  PERFORM frm_cleanup USING lo_sp_inb.


ENDFUNCTION.

 交货单删除

FUNCTION zewm_fm_inbdlv_delete.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(IV_LGNUM) TYPE  /SCWM/LGNUM OPTIONAL
*"     VALUE(IV_RECEIVING_OFFICE) TYPE  /SCMB/SCU_RO OPTIONAL
*"     VALUE(IV_ENTITLED) TYPE  /SCWM/DE_ENTITLED OPTIONAL
*"  EXPORTING
*"     VALUE(EV_TYPE) TYPE  CHAR1
*"     VALUE(EV_MSG) TYPE  STRING
*"  TABLES
*"      IT_HEAD TYPE  /SCDL/T_SP_K_HEAD OPTIONAL
*"----------------------------------------------------------------------

  DATA: lo_sp_inb          TYPE REF TO /scwm/cl_sp_prd_inb,
        lo_adapter_handler TYPE REF TO /scwm/cl_dlv_handler_adapter,
        ls_details         TYPE /scmb/s_default_values_det,
        ls_dynpro_data     TYPE /scmb/s_dynpro_data,
        ls_default_values  TYPE /scmb/s_default_values,
        lv_rejected        TYPE boole_d,
        lv_synchronously   TYPE boole_d,
        lt_return_codes    TYPE /scdl/t_sp_return_code,
        ls_k_head          TYPE /scdl/s_sp_k_head,
        lt_k_head          TYPE /scdl/t_sp_k_head,
        ls_sp_action       TYPE /scdl/s_sp_act_action.
  DATA: lv_ebeln TYPE ebeln,
        lv_posnr TYPE posnr.

  DATA: lv_aspect_name TYPE string.
  DATA: lv_relation TYPE string.
  DATA: lv_msg TYPE string.

  CHECK it_head[] IS NOT INITIAL.

*&---create service provider for processing delivery and and message box
  TRY.
      CREATE OBJECT lo_adapter_handler.

      CREATE OBJECT lo_sp_inb
        EXPORTING
          iv_mode              = /scdl/cl_sp=>sc_mode_classic
          io_attribute_handler = lo_adapter_handler
          io_message_handler   = lo_adapter_handler.
  ENDTRY.

  PERFORM frm_cleanup USING lo_sp_inb.

*&---设置初始值
  ls_details-v_fieldname = 'LGNUM'.
  ls_details-v_mandatory = abap_true.
  ls_details-v_memoryid = '/SCWM/LGN'.
  ls_details-v_no_dropdown = 'X'.
  APPEND ls_details TO ls_default_values-t_details.
  CLEAR ls_details.
  ls_details-v_fieldname = 'RECEIVING_OFFICE'.
  ls_details-v_mandatory = abap_true.
  ls_details-v_memoryid = '/SCMB/SCU_RO'.
  ls_details-v_no_dropdown = 'X'.
  APPEND ls_details TO ls_default_values-t_details.
  ls_details-v_fieldname = 'ENTITLED'.
  ls_details-v_mandatory = abap_true.
  ls_details-v_memoryid = '/SCWM/ENTITLED'.
  ls_details-v_no_dropdown = 'X'.
  APPEND ls_details TO ls_default_values-t_details.
  ls_details-v_fieldname = 'HU_DISPLAY'.
  APPEND ls_details TO ls_default_values-t_details.

  ls_default_values-v_identifier = '/SCWM/PRDI'.
  ls_default_values-v_values_structure = '/SCWM/S_SP_DEFAULT'.
  ls_default_values-v_extended = abap_true.

  SET PARAMETER ID '/SCWM/LGN' FIELD iv_lgnum.  "仓库编号/综合仓库
  SET PARAMETER ID '/SCMB/SCU_RO' FIELD iv_receiving_office."供应链单位:收货办公室 (RO)
  SET PARAMETER ID '/SCWM/ENTITLED' FIELD iv_entitled."授权处理方

  /scmb/cl_base=>set_process_data( io_attribute_handler     = lo_adapter_handler->mo_attr_handler
                               io_service_provider      = lo_sp_inb
                               io_message_handler       = lo_adapter_handler->mo_msg_handler
                               is_dynpro_data           = ls_dynpro_data
                               is_default_values        = ls_default_values
                               iv_disable_standard_save = abap_true ).

  CALL METHOD /scmb/cl_base=>end_of_initialization.

*&---设置仓库编号
  /scwm/cl_tm=>set_lgnum( iv_lgnum ).

*&---fill GUID of delivery header
  CLEAR: lt_k_head.
  lt_k_head[] = it_head[].
  SORT lt_k_head BY docid.
  DELETE ADJACENT DUPLICATES FROM lt_k_head COMPARING docid.

*&---try to lock (also creates the delivery instance immediately)
  CLEAR: lv_rejected,lt_return_codes.
  CALL METHOD lo_sp_inb->lock
    EXPORTING
      inkeys       = lt_k_head[]
      aspect       = /scwm/if_sp_c=>sc_asp_head
      lockmode     = /scdl/if_sp1_locking=>sc_exclusive_lock
    IMPORTING
      rejected     = lv_rejected
      return_codes = lt_return_codes.

  "check if any error occurred
  READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
  IF sy-subrc = 0 OR lv_rejected = abap_true.
    MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
      INTO lv_msg.
    ev_type = 'E'.
    ev_msg = '锁定交货单失败!' && lv_msg.

    PERFORM frm_cleanup USING lo_sp_inb.
    EXIT.
  ENDIF.

*&---delete inbound delivery
  CLEAR: lv_rejected,lt_return_codes.
  CALL METHOD lo_sp_inb->delete
    EXPORTING
      inkeys       = lt_k_head[]
      aspect       = /scwm/if_sp_c=>sc_asp_head
    IMPORTING
      rejected     = lv_rejected
      return_codes = lt_return_codes.

  "check if any error occurred
  READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
  IF sy-subrc = 0 OR lv_rejected = abap_true.
    MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
      INTO lv_msg.
    ev_type = 'E'.
    ev_msg = '删除交货单失败!' && lv_msg.

    PERFORM frm_cleanup USING lo_sp_inb.
    EXIT.
  ENDIF.

*&---save delivery dependant on if error occurred or not.
  CLEAR: lv_rejected.
  CALL METHOD lo_sp_inb->before_save
    IMPORTING
      rejected = lv_rejected.
  IF lv_rejected = abap_true.
    MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
      INTO lv_msg.
    ev_type = 'E'.
    ev_msg  = '保存前校验失败!' && lv_msg.

    PERFORM frm_cleanup USING lo_sp_inb.
    EXIT.
  ENDIF.

  CLEAR: lv_rejected.
  CALL METHOD lo_sp_inb->save
    EXPORTING
      synchronously = lv_synchronously
    IMPORTING
      rejected      = lv_rejected.
  CASE lv_rejected.
    WHEN abap_false.
      COMMIT WORK AND WAIT .
      ev_type = 'S'.
      ev_msg  = '交货单删除成功'.
    WHEN abap_true.
      ROLLBACK WORK.

      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '交货单删除失败!' && lv_msg.
    WHEN OTHERS.
  ENDCASE.

  PERFORM frm_cleanup USING lo_sp_inb.


ENDFUNCTION.

拆解步骤(与/N/SCWM/PRDI事务码前台操作相对应)

1、类的定义及实例化

*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(IV_LGNUM) TYPE  /SCWM/LGNUM OPTIONAL
*"     VALUE(IV_RECEIVING_OFFICE) TYPE  /SCMB/SCU_RO OPTIONAL
*"     VALUE(IV_ENTITLED) TYPE  /SCWM/DE_ENTITLED OPTIONAL
*"     VALUE(IV_DOCTYPE) TYPE  /SCDL/DL_DOCTYPE OPTIONAL
*"     VALUE(IV_DOCCAT) TYPE  /SCDL/DL_DOCCAT OPTIONAL
*"     VALUE(IV_ITEMTYPE) TYPE  /SCDL/DL_ITEMTYPE OPTIONAL
*"  EXPORTING
*"     VALUE(EV_TYPE) TYPE  CHAR1
*"     VALUE(EV_MSG) TYPE  STRING
*"     VALUE(EV_DOCNO) TYPE  /SCDL/DL_DOCNO_INT
*"  TABLES
*"      IT_HEAD_PARTY STRUCTURE  /SCWM/S_SP_A_HEAD_PARTY OPTIONAL
*"      IT_HEAD_REFDOC STRUCTURE  /SCWM/S_SP_A_HEAD_REFDOC OPTIONAL
*"      IT_ITEM STRUCTURE  /SCWM/S_SP_A_ITEM_PRDI OPTIONAL
*"      OT_REFDOC STRUCTURE  ZEWMS0087 OPTIONAL
*"----------------------------------------------------------------------

DATA: lo_sp_inb            TYPE REF TO /scwm/cl_sp_prd_inb,
      lo_message_box       TYPE REF TO /scdl/cl_sp_message_box,
      lo_adapter_handler   TYPE REF TO /scwm/cl_dlv_handler_adapter,
      ls_details           TYPE /scmb/s_default_values_det,
      ls_dynpro_data       TYPE /scmb/s_dynpro_data,
      ls_default_values    TYPE /scmb/s_default_values.


*&---create service provider for processing delivery and and message box
  TRY.
      CREATE OBJECT lo_adapter_handler.

      CREATE OBJECT lo_sp_inb
        EXPORTING
          iv_mode              = /scdl/cl_sp=>sc_mode_classic
          io_attribute_handler = lo_adapter_handler
          io_message_handler   = lo_adapter_handler.
  ENDTRY.

2、优先设定仓库编号等数据

前台操作

后台代码


  "初始化
  PERFORM frm_cleanup USING lo_sp_inb.

*&---设置初始值
  ls_details-v_fieldname = 'LGNUM'.
  ls_details-v_mandatory = abap_true.
  ls_details-v_memoryid = '/SCWM/LGN'.
  ls_details-v_no_dropdown = 'X'.
  APPEND ls_details TO ls_default_values-t_details.
  CLEAR ls_details.
  ls_details-v_fieldname = 'RECEIVING_OFFICE'.
  ls_details-v_mandatory = abap_true.
  ls_details-v_memoryid = '/SCMB/SCU_RO'.
  ls_details-v_no_dropdown = 'X'.
  APPEND ls_details TO ls_default_values-t_details.
  ls_details-v_fieldname = 'ENTITLED'.
  ls_details-v_mandatory = abap_true.
  ls_details-v_memoryid = '/SCWM/ENTITLED'.
  ls_details-v_no_dropdown = 'X'.
  APPEND ls_details TO ls_default_values-t_details.
  ls_details-v_fieldname = 'HU_DISPLAY'.
  APPEND ls_details TO ls_default_values-t_details.

  ls_default_values-v_identifier = '/SCWM/PRDI'.
  ls_default_values-v_values_structure = '/SCWM/S_SP_DEFAULT'.
  ls_default_values-v_extended = abap_true.

  SET PARAMETER ID '/SCWM/LGN' FIELD iv_lgnum.  "仓库编号/综合仓库
  SET PARAMETER ID '/SCMB/SCU_RO' FIELD iv_receiving_office."供应链单位:收货办公室 (RO)
  SET PARAMETER ID '/SCWM/ENTITLED' FIELD iv_entitled."授权处理方

  /scmb/cl_base=>set_process_data( io_attribute_handler     = lo_adapter_handler->mo_attr_handler
                               io_service_provider      = lo_sp_inb
                               io_message_handler       = lo_adapter_handler->mo_msg_handler
                               is_dynpro_data           = ls_dynpro_data
                               is_default_values        = ls_default_values
                               iv_disable_standard_save = abap_true ).

  CALL METHOD /scmb/cl_base=>end_of_initialization.

*&---设置仓库编号(该步骤是必须的)
  /scwm/cl_tm=>set_lgnum( iv_lgnum ).

3、创建抬头数据

前台操作

后台代码


*&---INSERT HEAD
  CLEAR: lv_aspect_name.
  lv_aspect_name = /scwm/if_sp_c=>sc_asp_head."'/SCWM/S_SP_A_HEAD'

  CLEAR: ls_a_head_prdi.
  ls_a_head_prdi-doctype = iv_doctype."凭证类型
  ls_a_head_prdi-doccat  = iv_doccat. "凭证类别
  APPEND ls_a_head_prdi TO lt_a_head_prdi.

  CLEAR: lt_a_head_prdi_out,lv_rejected,lt_return_codes.
  CALL METHOD lo_sp_inb->insert
    EXPORTING
      inrecords    = lt_a_head_prdi
      aspect       = lv_aspect_name
    IMPORTING
      outrecords   = lt_a_head_prdi_out
      rejected     = lv_rejected
      return_codes = lt_return_codes.
  READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
  IF sy-subrc = 0 OR lv_rejected = abap_true.
    MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
      INTO lv_msg.
    ev_type = 'E'.
    ev_msg  = '抬头创建失败!' && lv_msg.

    PERFORM frm_cleanup USING lo_sp_inb.
    EXIT.
  ELSE.
    CLEAR: lv_docid,ls_a_head_prdi.
    READ TABLE lt_a_head_prdi_out INTO ls_a_head_prdi INDEX 1.
    IF sy-subrc EQ 0.
      lv_docid = ls_a_head_prdi-docid.
    ENDIF.
    CLEAR: ls_a_head_prdi.
  ENDIF.

4、添加合作伙伴

前台操作

后台代码


*&---INSERT HEAD_PARTY
  IF it_head_party[] IS NOT INITIAL.
    CLEAR: lv_aspect_name.
    lv_aspect_name = /scwm/if_sp_c=>sc_asp_head_party."/SCWM/S_SP_A_HEAD_PARTY

    CLEAR: lv_relation.
    lv_relation = /scwm/if_sp_c=>sc_rel_head_to_party."/SCWM/HEAD_TO_PARTY

    CLEAR: ls_k_head.
    ls_k_head-docid = lv_docid.

    LOOP AT it_head_party.
      CLEAR: ls_a_head_party.
      ls_a_head_party-party_role = it_head_party-party_role."合作伙伴角色
      ls_a_head_party-partyno    = it_head_party-partyno."业务合作伙伴编号
      APPEND ls_a_head_party TO lt_a_head_party.
    ENDLOOP.

    CLEAR: lt_a_head_party_out,ls_a_head_party_rel,lv_rejected,lt_return_codes.
    CALL METHOD lo_sp_inb->insert
      EXPORTING
        inrecords          = lt_a_head_party
        aspect             = lv_aspect_name
        relation           = lv_relation
        relation_inkey     = ls_k_head
      IMPORTING
        outrecords         = lt_a_head_party_out
        relation_outrecord = ls_a_head_party_rel
        rejected           = lv_rejected
        return_codes       = lt_return_codes.
    READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
    IF sy-subrc = 0 OR lv_rejected = abap_true.
      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '合作伙伴添加失败!' && lv_msg.

      PERFORM frm_cleanup USING lo_sp_inb.
      EXIT.
    ENDIF.
  ENDIF.

5、添加抬头参考凭证

前台操作

ASN和BOL类型的参考凭证必须要有1个,不然会报错

后台代码


*&---INSERT HEAD_REFDOC
  IF it_head_refdoc[] IS NOT INITIAL.
    "添加参考凭证
    CLEAR: lv_aspect_name.
    lv_aspect_name = /scwm/if_sp_c=>sc_asp_head_refdoc."/SCWM/S_SP_A_HEAD_REFDOC

    CLEAR: lv_relation.
    lv_relation = /scdl/if_sp_c=>sc_rel_head_to_refdoc."'/SCDL/HEAD_TO_REFDOC'

    CLEAR: ls_k_head.
    ls_k_head-docid = lv_docid.

    CLEAR: lt_a_head_refdoc[].
    LOOP AT it_head_refdoc.
      CLEAR: ls_a_head_refdoc.
      ls_a_head_refdoc-refdoccat = it_head_refdoc-refdoccat."参考凭证类别
      ls_a_head_refdoc-refdocno  = it_head_refdoc-refdocno. "参考凭证编号
      ls_a_head_refdoc-date      = sy-datum."日期
      ls_a_head_refdoc-time      = sy-uzeit."时间
      APPEND ls_a_head_refdoc TO lt_a_head_refdoc.
    ENDLOOP.

    CLEAR: lt_a_head_refdoc_out,ls_a_head_refdoc_rel,lv_rejected,lt_return_codes.
    CALL METHOD lo_sp_inb->insert
      EXPORTING
        inrecords          = lt_a_head_refdoc
        aspect             = lv_aspect_name
        relation           = lv_relation
        relation_inkey     = ls_k_head
      IMPORTING
        outrecords         = lt_a_head_refdoc_out
        relation_outrecord = ls_a_head_refdoc_rel
        rejected           = lv_rejected
        return_codes       = lt_return_codes.
    READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
    IF sy-subrc = 0 OR lv_rejected = abap_true.
      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '参考凭证添加失败!' && lv_msg.

      PERFORM frm_cleanup USING lo_sp_inb.
      EXIT.
    ENDIF.

    "由于ASN类型的参考凭证必输,故先获取初始的参考凭证,将其作为ASN的参考凭证
    CLEAR: lv_aspect_name.
    lv_aspect_name = /scwm/if_sp_c=>sc_asp_head_refdoc."/SCWM/S_SP_A_HEAD_REFDOC

    CLEAR: ls_k_head_refdoc,lt_k_head_refdoc.
    ls_k_head_refdoc-docid = lv_docid.
    ls_k_head_refdoc-refdoccat = 'ERP'.
    APPEND ls_k_head_refdoc TO lt_k_head_refdoc.

    CLEAR: lt_a_head_refdoc_out,lv_rejected,lt_return_codes.
    CALL METHOD lo_sp_inb->select
      EXPORTING
        inkeys       = lt_k_head_refdoc
        aspect       = lv_aspect_name
      IMPORTING
        outrecords   = lt_a_head_refdoc_out
        rejected     = lv_rejected
        return_codes = lt_return_codes.
    READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
    IF sy-subrc = 0 OR lv_rejected = abap_true.
      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '参考凭证获取失败!' && lv_msg.

      PERFORM frm_cleanup USING lo_sp_inb.
      EXIT.
    ENDIF.

    IF lt_a_head_refdoc_out[] IS NOT INITIAL.
      READ TABLE lt_a_head_refdoc_out INTO DATA(ls_head_refdoc)
        WITH KEY docid = lv_docid
                 refdoccat = 'ERP'.
      IF sy-subrc EQ 0.
        CLEAR: ls_a_head_refdoc,lt_a_head_refdoc[].
        ls_a_head_refdoc-refdoccat = 'ASN'."参考凭证类别
        ls_a_head_refdoc-refdocno  = ls_head_refdoc-refdocno. "参考凭证编号
        ls_a_head_refdoc-date      = sy-datum."日期
        ls_a_head_refdoc-time      = sy-uzeit."时间
        APPEND ls_a_head_refdoc TO lt_a_head_refdoc.
      ENDIF.

      "添加参考凭证
      CLEAR: lv_aspect_name.
      lv_aspect_name = /scwm/if_sp_c=>sc_asp_head_refdoc."/SCWM/S_SP_A_HEAD_REFDOC

      CLEAR: lv_relation.
      lv_relation = /scdl/if_sp_c=>sc_rel_head_to_refdoc."'/SCDL/HEAD_TO_REFDOC'

      CLEAR: ls_k_head.
      ls_k_head-docid = lv_docid.

      CLEAR: lt_a_head_refdoc_out,ls_a_head_refdoc_rel,lv_rejected,lt_return_codes.
      CALL METHOD lo_sp_inb->insert
        EXPORTING
          inrecords          = lt_a_head_refdoc
          aspect             = lv_aspect_name
          relation           = lv_relation
          relation_inkey     = ls_k_head
        IMPORTING
          outrecords         = lt_a_head_refdoc_out
          relation_outrecord = ls_a_head_refdoc_rel
          rejected           = lv_rejected
          return_codes       = lt_return_codes.
      READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
      IF sy-subrc = 0 OR lv_rejected = abap_true.
        MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
          INTO lv_msg.
        ev_type = 'E'.
        ev_msg  = 'ASN参考凭证添加失败!' && lv_msg.

        PERFORM frm_cleanup USING lo_sp_inb.
        EXIT.
      ENDIF.
    ENDIF.
  ENDIF.

6、创建行项目数据

前台操作

后台代码


*&---INSERT ITEM
  IF it_item[] IS NOT INITIAL.
    CLEAR: lv_aspect_name.
    lv_aspect_name = /scwm/if_sp_c=>sc_asp_item."'/SCWM/S_SP_A_ITEM'

    CLEAR: lv_relation.
    lv_relation = /scdl/if_sp_c=>sc_rel_head_to_item."'/SCDL/HEAD_TO_ITEM'

    CLEAR: ls_k_head.
    ls_k_head-docid = lv_docid.

    DATA(lv_lines) = lines( it_item[] ).
    DO lv_lines TIMES.
      CLEAR: ls_a_item_prdi.
      ls_a_item_prdi-itemtype       = iv_itemtype."项目类型
      ls_a_item_prdi-manual_header  = 'X'.        "手动生成
      ls_a_item_prdi-doccat         = iv_doccat.  "凭证类别
      ls_a_item_prdi-doctype        = iv_doctype. "凭证类型
      APPEND ls_a_item_prdi TO lt_a_item_prdi.
    ENDDO.

    CLEAR: lt_a_item_prdi_out,ls_a_item_prdi_rel,lv_rejected,lt_return_codes.
    CALL METHOD lo_sp_inb->insert
      EXPORTING
        inrecords          = lt_a_item_prdi
        aspect             = lv_aspect_name
        relation           = lv_relation
        relation_inkey     = ls_k_head
      IMPORTING
        outrecords         = lt_a_item_prdi_out
        relation_outrecord = ls_a_item_prdi_rel
        rejected           = lv_rejected
        return_codes       = lt_return_codes.
    READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
    IF sy-subrc = 0 OR lv_rejected = abap_true.
      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '行项目创建失败!' && lv_msg.

      PERFORM frm_cleanup USING lo_sp_inb.
      EXIT.
    ENDIF.

7、填充行项目数据(物料、数量等)

前台操作

后台代码


*&---COMPLETE ITEM
    CLEAR: lt_a_item_prdi.
    lt_a_item_prdi = lt_a_item_prdi_out.
    LOOP AT lt_a_item_prdi ASSIGNING FIELD-SYMBOL(<fs_item>).
      READ TABLE it_item INDEX sy-tabix.
      IF sy-subrc EQ 0.
        <fs_item>-manual        = 'X'."手动生成
        <fs_item>-changeable    = 'X'."
*      <fs_item>-productid     = it_item-productid.      "产品标识
        <fs_item>-productno     = it_item-productno.    "产品
*      <fs_item>-productno_ext = it_item-productno_ext.  "外部产品
        <fs_item>-qty_ui        = it_item-qty_ui. "数量
        <fs_item>-qty           = it_item-qty.    "数量
        <fs_item>-uom           = it_item-uom.    "计量单位
        <fs_item>-/scwm/gmbin   = it_item-/scwm/gmbin.    "货物移动过帐的存储位
        <fs_item>-stock_category = it_item-stock_category."库存类型
      ENDIF.
    ENDLOOP.

    CLEAR: lv_aspect_name.
    lv_aspect_name = /scwm/if_sp_c=>sc_asp_item."'/SCWM/S_SP_A_ITEM'

    CLEAR: lt_a_item_prdi_out,ls_a_item_prdi_rel,lv_rejected,lt_return_codes.
    CALL METHOD lo_sp_inb->update
      EXPORTING
        inrecords    = lt_a_item_prdi
        aspect       = lv_aspect_name
      IMPORTING
        outrecords   = lt_a_item_prdi_out
        rejected     = lv_rejected
        return_codes = lt_return_codes.
    READ TABLE lt_return_codes TRANSPORTING NO FIELDS WITH KEY failed = abap_true.
    IF sy-subrc = 0 OR lv_rejected = abap_true.
      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '行项目数据添加失败!' && lv_msg.

      PERFORM frm_cleanup USING lo_sp_inb.
      EXIT.
    ENDIF.
  ENDIF.

8、保存前检查

前台操作

后台代码


*&---SAVE
  CLEAR: lv_rejected.
  CALL METHOD lo_sp_inb->before_save
    IMPORTING
      rejected = lv_rejected.
  IF lv_rejected = abap_true.
    MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
      INTO lv_msg.
    ev_type = 'E'.
    ev_msg  = '保存前校验失败!' && lv_msg.

    PERFORM frm_cleanup USING lo_sp_inb.
    EXIT.
  ENDIF.

9、保存

前台操作

后台代码


  CLEAR: lv_rejected.
  CALL METHOD lo_sp_inb->save
    EXPORTING
      synchronously = lv_synchronously
    IMPORTING
      rejected      = lv_rejected.
  CASE lv_rejected.
    WHEN abap_false.
      COMMIT WORK AND WAIT .
    WHEN abap_true.
      ROLLBACK WORK.

      MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
        INTO lv_msg.
      ev_type = 'E'.
      ev_msg  = '提交数据库失败!' && lv_msg.
    WHEN OTHERS.
  ENDCASE.

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值