Workflow. Использование ФМ в правилах ответственности

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

См. заметку Правила ответственности при настройке Workflow

В этой заметке я хотел бы продолжить обзор возможностей правил ответственности. На этот раз с блэкджеком и ... применением ABAP, и на вполне себе реальном примере.

0. Постановка задачи

Создать правило ответственности, посредством которого будут определяться обработчики диалоговой задачи в потоке операций. На вход в правило ответственности будет передаваться идентификатор объекта S - «Position», для которого в инфотипе 1001 - «Relationships» заведено несколько соединений вида _ZZ1 _c объектами P - «Person».  Нужно считать идентификаторы объектов P, и затем прочитать значение инфотипа **0105 **- «Communication», подтип 0001 - «System user name (SY-UNAME)» для каждого из найденных табельных номеров.

1. Создание функционального модуля

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

В качестве исходных данных, на которых будет производиться тестирование, я воспользуюсь объектом S, для которого создано 2 необходимых соединения

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


DATA:
lw_appraiser TYPE hrhap_apper
,lw_couch TYPE hrhap_others
,lw_actor TYPE swhactor.

DATA: lt_1001 TYPE TABLE OF p1001,
lw_1001 TYPE p1001,
lv_pernr TYPE prelp-pernr.

CALL FUNCTION 'RH_READ_INFTY_1001'
EXPORTING
plvar = '01'
otype = 'S'
objid = '50005809' "
istat = '1'
begda = '19000101'
endda = '99991231'
TABLES
i1001 = lt_1001
EXCEPTIONS
nothing_found = 1
wrong_condition = 2
wrong_parameters = 3
OTHERS = 4.
IF sy-subrc is INITIAL.
IF lt_1001 IS NOT INITIAL.
LOOP AT lt_1001 INTO lw_1001 WHERE relat = 'ZZ1'.

  lv_pernr = lw_1001-sobid.

  CLEAR lw_actor.
  lw_actor-otype = 'US'.
  lw_actor-objid = zcl_demo_utility=>get_userid( lv_pernr = lv_pernr ).
  APPEND lw_actor TO actor_tab.
ENDLOOP.

ENDIF.
ENDIF.

Тестируем

Идентификаторы пользователей, которые будут обработчиками задачи потока операций, успешно записаны в таблицу ACTOR_TAB.

См. Interface of Function Module for Agent Determination

См. стандартный ФМ SWX_GET_MANAGER

2. Создание правила ответственности

Правила ответственности бывают нескольких типов. Тип, про который пойдет речь в рамках данной заметки, превосходно описан в справочном материале вендора

См. Defining Rules Using Function to Be Executed

С помощью транзакции PFAC создайте правило ответственности с типом F - Agent Determination Function to be Executed

3. Подготовка потока операций

В используемом потоке операций должен присутствовать элемент контейнера, в котором будет содержаться значение штатной должности, от которого необходимо найти обработчиков. Я назову его «TEST_OBJID». Для демонстрации в этой заметке я определю начальное значение для этого элемента контейнера

Значение элемента контейнера "TEST_OBJID" будет в последующем передаваться в правило ответственности для определения обработчиков.

Присвойте созданное правило ответственности (См. пункт 2. Создание правила ответственности) задаче потока операций, посредством которой будет выполняться пользовательское согласование

4. Внесение корректировок в функциональный метод

В пункте # 1. Создание функционального модуля, я создал ФМ, в котором явно прописан идентификатор объекта. Для тестирования - это более чем достаточно. Теперь необходимо скорректировать код таким образом, чтобы значение объекта S - "Position" динамически считывалось из контейнера потока операций (элемент TEST_OBJID). Вносим соответствующие корректировки в исходный код функционального модуля

DATA:
lw_appraiser TYPE hrhap_apper
,lw_couch TYPE hrhap_others
,lw_actor TYPE swhactor
, test_objid TYPE p1001-objid.

DATA: lt_1001 TYPE TABLE OF p1001,
lw_1001 TYPE p1001,
lv_pernr TYPE prelp-pernr.

FIELD-SYMBOLS: <fs_cont> TYPE swcont.

READ TABLE ac_container ASSIGNING <fs_cont> WITH KEY element = 'TEST_OBJID'.
test_objid = <fs_cont>-value.

CALL FUNCTION 'RH_READ_INFTY_1001'
EXPORTING
plvar = '01'
otype = 'S'
objid = test_objid
istat = '1'
begda = '19000101'
endda = '99991231'
TABLES
i1001 = lt_1001

EXCEPTIONS
  nothing_found    = 1
  wrong_condition  = 2
  wrong_parameters = 3
  OTHERS           = 4.

IF sy-subrc <> 0.

ENDIF.
IF lt_1001 IS NOT INITIAL.
LOOP AT lt_1001 INTO lw_1001 WHERE relat = 'ZZ1'.

  lv_pernr = lw_1001-sobid.

  CLEAR lw_actor.
  lw_actor-otype = 'US'.
  lw_actor-objid = zcl_demo_utility=>get_userid( lv_pernr = lv_pernr ).
  APPEND lw_actor TO actor_tab.
ENDLOOP.

ENDIF.

В коде опять отсутствуют необходимые проверки и обработки, но главное здесь - понять принцип. Ну а довести код "до ума" - не так сложно, как кажется.

См. Function Module for Rule Resolution

5. Тестирование

Для нужд тестирования можно воспользоваться фоновой отладкой задачи

См. заметку Workflow. Отладка фоновых задач

В общем и целом, получилось все довольно успешно. Спасибо за внимание!