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.