Workflow

    API ответа на уведомление
    //проставляем значение глобальной переменной
    WF_NOTIFICATION.SetAttrText(p_notification_id, 'RESULT', p_status);
    //отправляем ответ
    WF_NOTIFICATION.Respond(nid => p_notification_id);
    
    вставка ссылок в уведомления

    динамическое создание сообщения
    В данном случае на этапе инициализации атрибута при создании процесса необходимо прописать процедуру, куда передается строка с параметрами. Параметры перечисляются через delimiter и распарсиваются:
    wf_engine.SetItemAttrText(itemtype => WF_ITEM_TYPE,
       itemkey  => l_itemkey,
       aname    => 'MESSAGE_BODY',
       avalue   => 'PLSQLCLOB:XXXX_WF_PKG.ATTDYN_GETURL/' || to_char(p_param) || ':' || l_itemkey || ':&#NID');
    
    API процедуры:
    procedure attdyn_geturl(p_document_id   IN VARCHAR2,
                            p_display_type  IN VARCHAR2,
                            p_document      IN OUT NOCOPY CLOB,
                            p_document_type IN OUT NOCOPY VARCHAR2);
    
    В данном примере в тело сообщения подставляется NOTIFICATION_ID, который нельзя транслировать никаким другим методом.
    коммиты в WF API
    Фиксировать транзакцию в функциях, вызываемых из процесса WF, нельзя. Если требуется работа с данными в кастомных таблицах, используем автономные транзации.
    пост-обработчик ответа на уведомление
    procedure wf_post_notify ( itemtype          in varchar2
                                          ,itemkey             in varchar2
                                          ,actid                 in number
                                          ,funcmode          in varchar2
                                          ,resultout           out nocopy varchar2)
    is
          l_result varchar2(255);
          l_nid    number;
    begin
          l_nid := wf_engine.context_nid; --получаем notification_id
          l_result := wf_notification.GetAttrText(l_nid, 'RESULT'); --
         -- если нажата кнопка из уведомления, выводим хинт и закрываем сообщение
          if (l_result = 'OK') then
             raise_application_error(G_ERROR_NUMBER,
                     fnd_message.get_string(G_APP_SHORT_NAME, G_ERROR_MESSAGE));
          end if;
    end wf_post_notify;
    предустановленные атрибуты сообщения
    #HIDE_REASSIGN - скрыть кнопку "Перенаправить"
    #HIDE_MOREINFO - скрыть кнопку "Больше информации"
    #FROM_ROLE - переопределение параметра "Отправитель"
    #HDR_ - префикс, добавляющий атрибут в заголовок сообщения
    работа с атрибутами
    wf_engine.SetItemAttrText(itemtype => WF_ITEM_TYPE,
                                  itemkey  => l_itemkey_num,
                                  aname    => 'INITIATOR',
                                  avalue   => l_org_name); 
    l_org_name := wf_engine.GetItemAttrText(itemtype => WF_ITEM_TYPE,
                                                itemkey  => l_itemkey,
                                                aname    => 'INITIATOR');
    
    создание и удаление ad-hoc роли
    Workflow может работать и с глобальными ролями OeBS. Но для ряда задач требуется временно сгруппировать пользователей по какому-либо признаку, разосласть сообщения и удалить группировку. Для таких кратковременных целей проще использовать AD-HOC роль. Создание роли:
    -- создаем AdHocRole
    wf_directory.createadhocrole(     role_name               =>  l_role_name
                                    , role_display_name       =>  l_role_display_name
                                    , language                =>  null
                                    , territory               =>  null
                                    , role_description        =>  l_role_display_name
                                    , notification_preference =>  'MAILHTML'
                                    , role_users              =>  l_user_names --список пользователей через запятую
                                    , email_address           =>  null
                                    , fax                     =>  null
                                    , status                  =>  'ACTIVE' --активность
                                    -- срок годности роли - 90 дней 
                                    , expiration_date         =>  trunc(sysdate)+ 90);
    
    
    Для удаления роли её нужно сначала деактивировать
    wf_directory.SetAdHocRoleStatus(role_name => p_role_name,
                                       status => 'INACTIVE');
    
    wf_directory.SetAdHocRoleExpiration(role_name => p_role_name,
                                       expiration_date => trunc(sysdate)
                                       );
    wf_directory.DeleteRole(p_name => p_role_name,
                               p_origSystem => p_origSystem, --default 'WF_LOCAL_ROLES'
                               p_origSystemID => p_origSystemID); --default 0
    
    создание дочернего процесса
    Для связывания процессов используется вызов
    wf_engine.SetItemParent(itemtype => WF_ITEM_TYPE,--дочерний процесс
                                itemkey => l_itemkey_num,
                                parent_itemtype => WF_ITEM_TYPE,--родительский процесс
                                parent_itemkey => l_itemkey,
                                parent_context => null);
    
    создание и запуск процесса
    --получаем номер процесса из последовательности
    l_itemkey_num := XXXX_WF_S.NEXTVAL;
    --получаем уникальный ключ WF
    select WF_PROCESS_KEY_BASE || l_itemkey_num
          into l_itemkey
          from dual;
    --создаем экземпляр процесса
    wf_engine.CreateProcess( itemtype => WF_ITEM_TYPE
                               , itemkey  => l_itemkey
                               , process  => WF_PROCESS_NAME);
    -- параметры
    wf_engine.SetItemAttrNumber(itemtype => WF_ITEM_TYPE,
                                    itemkey => l_itemkey,
                                    aname => WF_ANAME,
                                    avalue => p_id);
    --запуск на выполнение созданного процесса
    wf_engine.startprocess( itemtype => WF_ITEM_TYPE
                              , itemkey  => l_itemkey);
    
    проталкивание процесса дальше
    declare 
      -- Local variables here
      cursor cur is select s.item_key from WF_ITEM_ACTIVITY_STATUSES s where item_type = 'MYITEMTYPE'
      and activity_status = 'ERROR';
      l_item_key varchar2(150);
    begin
       open cur;
        loop
          fetch cur into l_item_key;
          exit when cur%NOTFOUND;
              wf_engine.HandleError(
               'MYITEMTYPE',
               l_item_key,
               'CURRENT_NODE',
               'SKIP'); --{SKIP - пропустить, RETRY - повторить}
        end loop;
        close cur;  
        commit;
    end;
    /
    
    программное создание атрибутов
    begin
         WF_ENGINE.AddItemAttr(itemtype => 'MYITEMTYPE',
                               itemkey  => l_itemkey,
                               aname    => 'ATTR_NAME',
                               text_value => 'VALUE');
         -- если атрибут уже есть
         exception 
           when others then
             if SQLCODE = 3123 then
               null;
             end if;
    end;
    /
    
    открытые уведомления для текущего пользователя
    select wfn.notification_id 
        from WF_NOTIFICATIONS wfn, 
          XXMY343_WF_PROCESS prc, 
          WF_LOCAL_ROLES wlr, 
          WF_LOCAL_USER_ROLES wlur, 
          WF_ACTIVITIES wact  
        where wlr.name = wlur.role_name  
          and   wlr.name = wfn.original_recipient  
          and   wfn.item_key = prc.process_key   
          and   wact.message = wfn.message_name 
          and sysdate between wact.begin_date and 
              nvl(wact.end_date, to_date('31.12.4212', 'DD.MM.YYYY')) 
          and wact.type = 'NOTICE' 
          and wact.result_type != '*' 
          and wfn.message_type = 'XXMY343' 
          and   wfn.status = 'OPEN'  
          and   prc.process_status = 'P'  
          and   prc.entity_id = :ENTITY_ID  
          and   wlur.user_name = fnd_global.USER_NAME
    
    Пояснения: XXMY343_WF_PROCESS(ENTITY_ID, PROCESS_KEY) - кастомная таблица со связью ID сущности и itemkey, XXMY343 = itemtype.

    Комментариев нет :