Создание пакетов документов программно с помощью BAPI_GOODSMVT_CREATE? - PullRequest
4 голосов
/ 30 октября 2019

Краткое описание проблемы

Автоматическая обработка документальных партий с помощью пользовательского кода ABAP

Мой работодатель хочет выполнить автоматическую обработку документов для некоторых продуктов от внешних поставщиков, и я пытаюсь понятькак это настроить с помощью пользовательской настройки и ABAP.

Мне кажется, что документальные партии предназначены только для использования через MIGO - в любом случае я не могу найти правильное решение для их назначения программно, и любое взломанное решение, которое я могу придуматькажется недостаточным и нестабильным.

Какие пути у меня есть, чтобы решить эту проблему?

Улучшение BAPI_GOODSMVT_CREATE?

Можно ли как-то сделать это с помощью таких вещей, как BAPI_GOODSMVT_CREATE?

Улучшение адресатов сообщений PPPI?

Мне также это особенно нужно дляработать для обмена сообщениями потребления через PPPI, и я подумал построить поверх стандартного назначения сообщений PI04, FM COCI_CONFIRM_MATERIAL_CONS.

Этот FM создает документ с материалом, но не проходит через BAPI_GOODSMVT_CREATE FM.

Однако используется MB_CREATE_GOODS_MOVEMENT.

То, что я уже пробовал

Одноразовое решение для взлома на основе снимков MIGO

Я создал решение для взлома для одной области, где я наблюдал, какиеТаблицы обновлений MIGO выполнялись и с какими данными (через FM VB_INSERT_BATCH и VB_BATCH_WHERE_USED_LIST), а затем заполняли эти структуры вручную.

Однако предоставление всей необходимой информации не представляется возможным для других областей реализации, поскольку они не имеют всех необходимых значений и не охватывают непредвиденные ситуации, когда могут потребоваться другие параметры.

Чтение через код BAPI_GOODSMVT_CREATE

Я пытался следить за тем, выполняет ли BAPI_GOODSMVT_CREATE те же FM, но только обнаружил, что он получает доступ к VB_BATCH_WHERE_USED_LIST.

Возможно активировать эту функцию, управляя идентификаторами памяти Documentary Batch #1, Documentary Batch #2, Documentary Batch #3 и Documentary Batch #5 (см. FM VBDBDM_DATA_POST_IM), но для этого необходимо заполнить много данныхвключая структуру с именем DOCUBATCH_SCREEN_FIELDS, что опять-таки заставляет думать, что это может быть неправильным подходом.

Несмотря на это, это все еще не позволяет мне поддерживать пакетную обработку через таблицы MCHA и MCH1.

Собранное решение на основе снимка MIGO

Здесьтак выглядит мое взломанное решение. Опять же, это неосуществимый способ решения проблемы, так как в других областях реализации нет результирующего Материального документа, доступного немедленно:

    FUNCTION zproxy_mdr_goodsreceipt.
    *"----------------------------------------------------------------------
    *"*"Local Interface:
    *"  IMPORTING
    *"     VALUE(IS_GOODSRECEIPT_HEAD) TYPE  ZPROXY_GOODSREC_HEAD
    *"     VALUE(IT_GOODSRECEIPT_ITEM) TYPE  ZPROXY_GOODSREC_ITEM_T
    *"     REFERENCE(I_CREATE_TO_FROM_REQUIREMENTS) TYPE  FLAG DEFAULT '-'
    *"  EXPORTING
    *"     REFERENCE(E_GOODSMVT_MSG_IDNO) TYPE  CHAR23
    *"     REFERENCE(E_MBLNR) TYPE  MBLNR
    *"     REFERENCE(E_TO_CREATION_SUBRC) TYPE  SY-SUBRC
    *"     REFERENCE(E_LGNUM_ERROR) TYPE  LGNUM
    *"     REFERENCE(E_TBNUM_ERROR) TYPE  TBNUM
    *"     REFERENCE(E_DOCBATCH_SUBRC) TYPE  SY-SUBRC
    *"     REFERENCE(E_DOCBATCH_MSG_IDNO) TYPE  CHAR23
    *"     REFERENCE(E_CLASSNUM) TYPE  BAPI1003_KEY-CLASSNUM
    *"     REFERENCE(E_OBJKEY) TYPE  BAPI1003_KEY-OBJECT
    *"  EXCEPTIONS
    *"      GOODSMVT_FAILED
    *"      NO_TRANSFER_REQUIREMENTS
    *"      TRANSFER_ORDER_CREATION_ERROR
    *"----------------------------------------------------------------------

      FIELD-SYMBOLS: <return>         TYPE bapiret2,
                     <goods_rec_item> TYPE zproxy_goodsrec_item,
                     <mseg>           TYPE mseg,
                     <char_char>      TYPE bapi1003_alloc_values_char,
                     <ltap_creat>     TYPE LTAP_CREAT.

      DATA: ls_header   TYPE bapi2017_gm_head_01,
            ls_code     TYPE bapi2017_gm_code,
            ls_item     TYPE bapi2017_gm_item_create,
            lt_item     TYPE STANDARD TABLE OF bapi2017_gm_item_create,
            lt_return   TYPE STANDARD TABLE OF bapiret2,
            ls_headret  TYPE bapi2017_gm_head_ret,
            l_mblnr     LIKE bapi2017_gm_head_ret-mat_doc,
            l_docubatch TYPE charg_d,
            l_subrc     TYPE sy-subrc,
            lt_mseg     TYPE STANDARD TABLE OF mseg.

      CLEAR l_subrc.


    *     ############################## Create goods movement ##############################
    *     Build structures
      MOVE-CORRESPONDING is_goodsreceipt_head TO ls_header.
      ls_code-gm_code = '01'.

      LOOP AT it_goodsreceipt_item ASSIGNING <goods_rec_item>.
        MOVE-CORRESPONDING <goods_rec_item> TO ls_item.
        APPEND ls_item TO lt_item.
      ENDLOOP.

    *     BAPI call
      CALL FUNCTION 'BAPI_GOODSMVT_CREATE'
        EXPORTING
          goodsmvt_header  = ls_header
          goodsmvt_code    = ls_code
        IMPORTING
          goodsmvt_headret = ls_headret
          materialdocument = l_mblnr
        TABLES
          goodsmvt_item    = lt_item
          return           = lt_return.
    *     Check errors
      READ TABLE lt_return ASSIGNING <return> WITH KEY type = 'E'.
      IF sy-subrc = 0.
        e_goodsmvt_msg_idno = <return>-id && <return>-number.
        ROLLBACK WORK.
        RAISE goodsmvt_failed.
      ELSE.
        e_mblnr = l_mblnr.
        COMMIT WORK AND WAIT. "Wait for TO requirements to be created
      ENDIF.

    *     Only proceede if Material Document has been successfully posted
      CHECK l_subrc = 0 AND l_mblnr IS NOT INITIAL.

    *     ############################## Update with Documentary Batch ###################################

      DATA: lt_chvw      TYPE STANDARD TABLE OF chvw,
            ls_chvw      TYPE chvw,
            lt_mch1      TYPE STANDARD TABLE OF mch1,
            ls_mch1      TYPE mch1,
            lt_mcha      TYPE STANDARD TABLE OF mcha,
            ls_mcha      TYPE mcha,
            lt_mchb      TYPE STANDARD TABLE OF mchb,
            lt_mska      TYPE STANDARD TABLE OF mska,
            lt_mspr      TYPE STANDARD TABLE OF mspr,
            lt_char_num  TYPE STANDARD TABLE OF bapi1003_alloc_values_num,
            lt_char_char TYPE STANDARD TABLE OF bapi1003_alloc_values_char,
            lt_char_curr TYPE STANDARD TABLE OF bapi1003_alloc_values_curr,
            l_objkey     TYPE bapi1003_key-object,
            l_classnum   TYPE bapi1003_key-classnum,
            l_atnam      TYPE atnam.

      REFRESH lt_chvw.

    *     Get material document items
      SELECT *
          FROM mseg
          INTO TABLE lt_mseg
          WHERE mblnr = l_mblnr.

    *     Perpare docubatch registration data
      LOOP AT it_goodsreceipt_item ASSIGNING <goods_rec_item>.
    *       Generate class num and atnam from plant
        CONCATENATE 'PI_' <goods_rec_item>-plant INTO l_classnum.
        CONCATENATE 'Z_DOC_BATCH_' <goods_rec_item>-plant INTO l_atnam.

    *       Get material docubatch usage characteristic
        REFRESH: lt_return,
                 lt_char_num,
                 lt_char_char,
                 lt_char_curr.

        l_objkey(18) = <goods_rec_item>-material.
        CALL FUNCTION 'BAPI_OBJCL_GETDETAIL'
          EXPORTING
            objectkey       = l_objkey
            objecttable     = 'MARA'
            classnum        = l_classnum
            classtype       = '001'
          TABLES
            allocvaluesnum  = lt_char_num
            allocvalueschar = lt_char_char
            allocvaluescurr = lt_char_curr
            return          = lt_return.
        LOOP AT lt_return ASSIGNING <return> WHERE type = 'E'. "Check for errors
    *         Couldn't read characteristic, assume no docubatch handling
          e_docbatch_subrc = '1'.
          e_docbatch_msg_idno = <return>-id && <return>-number.
          e_classnum = l_classnum.
          e_objkey = l_objkey.
          CONTINUE.
        ENDLOOP.

        READ TABLE lt_char_char ASSIGNING <char_char> WITH KEY charact = l_atnam.
        IF sy-subrc <> 0 OR <char_char>-value_neutral = 0.
    *         No docubatch value
          CONTINUE.
        ENDIF.



    *       Get associated material document item
        READ TABLE lt_mseg ASSIGNING <mseg>
              WITH KEY mblnr = ls_headret-mat_doc
                       mjahr = ls_headret-doc_year
                       bwart = <goods_rec_item>-move_type
                       matnr = <goods_rec_item>-material
                       werks = <goods_rec_item>-plant
                       menge = <goods_rec_item>-entry_qnt
                       meins = <goods_rec_item>-entry_uom
                       hsdat = <goods_rec_item>-prod_date
                       kzbew = <goods_rec_item>-mvt_ind
                       lgort = <goods_rec_item>-stge_loc.
        IF sy-subrc <> 0.
    *         No associated material document item
          CONTINUE.
        ENDIF.

    *       Check docubatch type
        IF <char_char>-value_neutral <> 0.
    *         Perform basic docubatch actions (MCHA and MCH1)
    *         Verify that docubatch nr is assigned
          IF <goods_rec_item>-vendrbatch IS INITIAL.
    *            !!!!!!!!!!!!! Venderbatch not filled even though material is docubatch managed, what to do? !!!!!!!!!!!!!!!
            CONTINUE.
          ENDIF.

    *         Prepare data for docubatch registration
          CLEAR: ls_mch1,
                 ls_mcha.

          ls_mch1-matnr = <goods_rec_item>-material.
          ls_mch1-charg = <goods_rec_item>-vendrbatch.
          ls_mch1-ersda = sy-datum.
          ls_mch1-ernam = sy-uname.
          ls_mch1-ersda_tmstp = sy-datum && sy-uzeit.
          ls_mch1-ersda_tz_sys = sy-tzone.
          ls_mch1-ersda_tz_usr = sy-zonlo.

          MOVE-CORRESPONDING ls_mch1 TO ls_mcha. "Same fields from MCH1 are included in MCHA
          ls_mcha-werks = <goods_rec_item>-plant.

          APPEND: ls_mch1 TO lt_mch1,
                  ls_mcha TO lt_mcha.
        ENDIF.

        IF <char_char>-value_neutral = 2. "Also include batch where-used
    *         Perpare data for batch where-used registration
          CLEAR ls_chvw.
          ls_chvw-matnr = <goods_rec_item>-material.
          ls_chvw-werks = <goods_rec_item>-plant.
          ls_chvw-charg = <goods_rec_item>-vendrbatch.
          ls_chvw-ebeln = <goods_rec_item>-po_number.
          ls_chvw-ebelp = <goods_rec_item>-po_item.
          ls_chvw-mblnr = ls_headret-mat_doc.
          ls_chvw-mjahr = ls_headret-doc_year.
          ls_chvw-zeile = <mseg>-zeile.
          ls_chvw-budat = is_goodsreceipt_head-pstng_date.
          ls_chvw-shkzg = 'S'. "??? VALUE ???
          ls_chvw-bwart = <goods_rec_item>-move_type.
          ls_chvw-kzbew = <goods_rec_item>-mvt_ind. "Goods Movement for Purchase Order
          ls_chvw-menge = <goods_rec_item>-entry_qnt.
          ls_chvw-meins = <goods_rec_item>-entry_uom.
          APPEND ls_chvw TO lt_chvw.
        ENDIF.
      ENDLOOP.

    *     Perform batch registration
      CALL FUNCTION 'VB_INSERT_BATCH'
        TABLES
          zmch1         = lt_mch1
          zmcha         = lt_mcha
          zmchb         = lt_mchb
          zmska         = lt_mska
          zmspr         = lt_mspr
                .

    *     Perform batch where-used registration
      CALL FUNCTION 'VB_BATCH_WHERE_USED_LIST'
        TABLES
          xchvw = lt_chvw.

Почему это недостаточно хорошо, и чтоМне нужно

. Это снимок MIGO, сконфигурированный с документированной пакетной обработкой, но не обязательно охватывающий все случаи.

Работает только в контексте документа покупки и не распространяется на другие случаи, такие как заказы и заказы на продажу.

Кроме того, у меня есть только необходимая дата из-за документа материала, созданного непосредственно выше, что не возможно для всех случаев реализации.

Я хотел бы знать, существует ли предполагаемый способвыполнить документальную пакетную обработку из пользовательского кода.

1 Ответ

4 голосов
/ 30 октября 2019

Цитирование из документации :

Если вы работаете с функциями RFID или TRM или вызываете IDoc / BAPI, вы можете регистрировать только документальные партии, вызывая RFC-заключаемый функциональный модуль VBDBDM_DATA_MAINTAIN_RFC заранее или включение его в процесс.

Так может этот функциональный модуль является ключевым? Однако, возможно, вы не первый, кто испытал эту боль. Комментарий к этой документации гласит:

Документарная партия имеет множество ограничений и, похоже, является полуфабрикатом SAP, поскольку в ней отсутствуют многие функции реальных партий.

Будьте готовы сделать множество пользовательских улучшений ...

ADDENDUM от сообщества: ниже приведено решение, взятое из оригинального плаката через два дня после этого ответа, отошедшего от его вопроса.

Решение

Пример вызова для поступления заказа на поставку товара

  LOOP AT it_goodsreceipt_item ASSIGNING <goods_rec_item>.

    CALL FUNCTION 'VBDBDM_DATA_MAINTAIN_RFC'
      EXPORTING
        i_matnr            = <goods_rec_item>-material
        i_werks            = <goods_rec_item>-plant
        i_quantity         = <goods_rec_item>-entry_qnt
        i_uom              = <goods_rec_item>-entry_uom
        i_docubatch_charg  = <goods_rec_item>-vendrbatch
*       IT_DOCUBATCHES     =
        i_process_id       = '01' "Goods Receipt for External Procurement
*       I_REPLACE_EXISTING_DATA       =
        i_ebeln            = <goods_rec_item>-po_number
        i_ebelp            = <goods_rec_item>-po_item
*       I_AUFNR            =
*       I_AUFPS            =
*       I_RSNUM            =
*       I_RSPOS            =
*       I_RSART            =
*       I_VBELN            =
*       I_POSNR            =
*       IS_DOCUBATCH_COM   =
*       I_LINE_ID          =
*       I_LGNUM            =
*       I_TANUM            =
*       I_TAPOS            =
      EXCEPTIONS
        parameter_error    = 1
        process_not_active = 2.
  ENDLOOP.

* Follow up by creating Material Document, for example through BAPI_GOODSMVT_CREATE
...