ME_PROCESS_PO_CUST - Розширення для обробки замовлення на купівлю: клієнт

Автор Uukrul, Червень 23, 2018, 09:36:16 ДП

Попередня тема - Наступна тема

0 Користувачі і 1 Гість дивляться цю тему.

Uukrul

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

Не знаю как в футболе, но в жизни, какого хрена бразильцев пустили еще и сап писать не знаю. На входе имеем S4/HANA версия 1709, создаю свою реализацию расширения ME_PROCESS_PO_CUST и получаю сообщение, что активация расширения не может быть выполнена с параллельно активным расширением /ACCGO/CAS_IM_CALLOFF_UI_PO? Во-первых, какого хрена стандартное расширение воткнуто в пользовательское пространство имен, если для SAP есть соответствующее расширение ME_PROCESS_PO, которое запрещено к использованию клиентами? А во-вторых, расширение не активно, оно находится в бизнес функции /ACCGO/BF_ECC, что-то там для Бразилии из решения IS-OIL, и само собой, бизнес функция не активирована, но короче создать свое расширение к заказу на закупку нельзя.

Решение вылилось в то, что пришлось зайти в реализацию расширения /ACCGO/CAS_IM_CALLOFF_UI_PO, и там снять галку "Внедрение активно", конечно же прочитав, про то, как не хорошо менять стандарты SAP. Не хорошо конечно, а что делать если оно все так плохо? Кстати, активировать класс внедрения данного расширения так же нельзя, так как он содержит синтаксические ошибки. Правда на этот счет есть соответствующая нота, но мне было не нужно, я вообще бразильское решение не собираюсь активировать, так что кому надо найдете.

Uukrul

Как обычно или лыжи не едут или что-то поменялось в S/4HANA, но возникла проблема позиционирования ошибки в стандартном заказе для журнала сообщений.  Проблема возникла в том, что в ходе проверки позиций, находим например позицию которая заполнена не правильно, формируем согласно документации сообщение об ошибке и на выходе получаем, что в журнале и по статусам данное сообщение почему-то относится всегда к последней позиции заказа, т.е. все ошибки отражаются в журнале так, как будто они возникли на последней позиции заказа. В документации, да и в мировом разуме написано все довольно прозрачно.

1. В реализации метода включаем стандартную группу макросов по работе с журналом ошибок документа

*   ---------------------------------------------------------------------*
    INCLUDE mm_messages_mac. "useful macros for message handling
*   ---------------------------------------------------------------------*

2. Далее в месте где возникла ошибка связываем класс ошибки с пользовательским кодом расширения, для этого вызываем макрос, с кодом сообщения пользовательская ошибка mmmfd_cust_01 (таких констант, там определено с 01 по 09)

mmpur_metafield mmmfd_cust_01.

3. Далее по вкусу или вызываем ошибку сами, для быстрого поиска места возникновения сообщения, а потом вызываем макрос записи в журнал или сразу вызываем макрос записи ошибки/сообщения в журнал, я вставляю обычно вызов сообщения с ключем INTO l_dummy, где l_dummy определено как строка 132 символа. После чего вызываю макрос записи в журнал.

MESSAGE e001(zmm_013) WITH ls_position-matnr INTO l_dummy.
mmpur_message_forced sy-msgty sy-msgid sy-msgno
                     sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

4. Если нужно дальше отметить позицию как ошибочную то после записи ошибки в журнал, для выбранной позиции вызываем метод invalidate( ).

CALL METHOD is_item-item->invalidate( ).

На этом вроде как все должно работать, однако в 1710 не работает, точнее работает, но выдает всегда позиционирование ошибки в последней строке заказа. Как оказалось в группе макросов появились еще дополнительные определения, которые там написаны не просто, так. В общем перед вызовом всего этого барахла, нужно через макрос mmpur_business_obj_id позиционировать для журнала место возникновения ошибки. При этом позиционирование выполняем или для заголовка, если хотим чтобы сообщение выдавалось для всего заказа или для конкретной позиции. Вызов простой, для этого в структуре полей заголовка и каждой позиции есть поле ID, которое и нужно передать в макрос. Таким образом структура вызова сообщения об ошибке в методе CHECK должна выглядеть следующим образом:

DATA: l_dummy TYPE c LENGTH 128.

DATA(ls_header) = im_header->get_data( ).

IF <ошибка в заголовке>.
  mmpur_business_obj_id ls_header-id.
  mmpur_metafield mmmfd_cust_01.
  MESSAGE e014(zmm_013) INTO l_dummy.
  mmpur_message_forced sy-msgty sy-msgid sy-msgno
                         sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  im_header->invalidate( ).
  ch_failed = abap_true.
ENDIF.

LOOP AT im_header->get_items( ) INTO DATA(ls_item).
  DATA(ls_position) = ls_item-item->get_data( ).

  IF <ошибка в позиции>.
    mmpur_business_obj_id ls_position-id.
    mmpur_metafield mmmfd_cust_01.
    MESSAGE e012(zmm_013) WITH ls_position-matnr INTO l_dummy.
    mmpur_message_forced sy-msgty sy-msgid sy-msgno
                         sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    CALL METHOD ls_item-item->invalidate( ).
    ch_failed = abap_true.
  ENDIF.
ENDLOOP.

Таким образом получаем правильное позиционирование сообщения об ошибке в позиции или заголовке заказа, в зависимости от необходимости. Само собой, если возникло критическое сообщение в позиции то в заголовок будет всегда выдано автоматически сообщение, что заказ в позициях все еще содержит ошибки, поэтому сохранение не возможно. Как на рисунке mmpur_business_obj_id.png ниже.