Dynamic Message Creation/b>
In this case, during the initialization of an attribute when creating a process, specify the procedure where a string with parameters is passed. Parameters are enumerated using a delimiter and parsed:
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');
Procedure 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);
In this example, the NOTIFICATION_ID is inserted into the message body, which cannot be transmitted by any other method.
Commits in WF API
Transactions cannot be committed in functions called from the WF process. If you need to work with data in custom tables, use autonomous transactions.
Post-processing Handler for Notification Responses
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; --get notification_id
l_result := wf_notification.GetAttrText(l_nid, 'RESULT'); --
-- If a button from the notification is clicked, display a hint and close the message
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;
Predefined Message Attributes
#HIDE_REASSIGN - Hide the "Reassign" button
#HIDE_MOREINFO - Hide the "More Information" button
#FROM_ROLE - Override the "Sender" parameter
#HDR_ - Prefix that adds an attribute to the message header
Working with Attributes
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');
Creating and Deleting Ad-hoc Roles
Workflow can work with global OeBS roles. However, for some tasks, it is necessary to temporarily group users by a certain criterion, send messages, and then delete the grouping. For such short-term purposes, it is easier to use an AD-HOC role. Creating a role:
-- create 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);
To delete a role, it must first be deactivated:
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
Creating a Child Process
To link processes, use the call:
wf_engine.SetItemParent(itemtype => WF_ITEM_TYPE,--child process
itemkey => l_itemkey_num,
parent_itemtype => WF_ITEM_TYPE,--parent process
parent_itemkey => l_itemkey,
parent_context => null);
Creating and Starting a Process
--Get the process number from the sequence
l_itemkey_num := XXXX_WF_S.NEXTVAL;
--get the WF unique key
select WF_PROCESS_KEY_BASE || l_itemkey_num
into l_itemkey
from dual;
--create object of class
wf_engine.CreateProcess( itemtype => WF_ITEM_TYPE
, itemkey => l_itemkey
, process => WF_PROCESS_NAME);
-- parameters
wf_engine.SetItemAttrNumber(itemtype => WF_ITEM_TYPE,
itemkey => l_itemkey,
aname => WF_ANAME,
avalue => p_id);
--start the process created
wf_engine.startprocess( itemtype => WF_ITEM_TYPE
, itemkey => l_itemkey);
Pushing the Process Further
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 - skip, RETRY - retry :)}
end loop;
close cur;
commit;
end;
/
Programmatic Attribute Creation
begin
WF_ENGINE.AddItemAttr(itemtype => 'MYITEMTYPE',
itemkey => l_itemkey,
aname => 'ATTR_NAME',
text_value => 'VALUE');
-- If the attribute already exists
exception
when others then
if SQLCODE = 3123 then
null;
end if;
end;
/
Open Notifications for the Current User
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
Explanation: XXMY343_WF_PROCESS(ENTITY_ID, PROCESS_KEY) - A custom table linking entity ID and itemkey, XXMY343 = itemtype.