Professional Documents
Culture Documents
resultout := wf_engine.eng_null;
exception
when others then
Wf_Core.Context('Wf_Standard', 'OrJoin', itemtype, itemkey,
to_char(actid), funcmode);
raise;
end OrJoin;
-- AndJoin
-- Parallel And Join
-- Returns 'NULL' if all in-transition activities have completed.
-- Returns 'WAITING' if at least one in-transition activity is not
-- complete, or is complete with the wrong result.
-- OUT
-- result
- 'WAITING' | 'NULL'
procedure AndJoin(itemtype in varchar2,
itemkey in varchar2,
actid
in number,
funcmode in varchar2,
resultout in out nocopy varchar2)
is
cnt pls_integer;
begin
-- Do nothing in cancel or timeout mode
if (funcmode <> wf_engine.eng_run) then
resultout := wf_engine.eng_null;
return;
end if;
-- SYNCHMODE: Not allowed
if (itemkey = wf_engine.eng_synch) then
Wf_Core.Token('OPERATION', 'Wf_Standard.AndJoin');
Wf_Core.Raise('WFENG_SYNCH_DISABLED');
end if;
-- The And fails if there is at least one in-transition which is either
-- incomplete or complete with the wrong result.
SELECT count(1)
into cnt
FROM WF_ACTIVITY_TRANSITIONS WAT
WHERE WAT.TO_PROCESS_ACTIVITY = actid
AND NOT EXISTS
(SELECT NULL
FROM WF_ITEM_ACTIVITY_STATUSES WIAS
WHERE WIAS.PROCESS_ACTIVITY = WAT.FROM_PROCESS_ACTIVITY
AND WIAS.ITEM_TYPE = itemtype
AND WIAS.ITEM_KEY = itemkey
AND WIAS.ACTIVITY_STATUS = 'COMPLETE'
AND (WAT.RESULT_CODE in (WIAS.ACTIVITY_RESULT_CODE,
wf_engine.eng_trans_any)
OR (WAT.RESULT_CODE = wf_engine.eng_trans_default
AND NOT EXISTS
(SELECT NULL
FROM WF_ACTIVITY_TRANSITIONS WAT2
WHERE WAT2.FROM_PROCESS_ACTIVITY =
WAT.FROM_PROCESS_ACTIVITY
AND WAT2.RESULT_CODE = WIAS.ACTIVITY_RESULT_CODE)
)
)
);
if (cnt > 0) then
-- This means there is at least one in-transition either incomplete
-- or complete with the wrong result.
-- The LogicalAnd fails, return a result of 'WAITING'.
resultout := wf_engine.eng_waiting;
else
-- This means there are no in-transition activities that are either
-- incomplete or complete with the wrong result.
-- The LogicalAnd succeeds, return a result of 'NULL' to continue.
resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
end if;
return;
exception
when others then
Wf_Core.Context('Wf_Standard', 'AndJoin', itemtype,
itemkey, to_char(actid), funcmode);
raise;
end AndJoin;
-- Assign
-- Assign a value to an item attribute
-- OUT
-- result - null
-- ACTIVITY ATTRIBUTES REFERENCED
-- ATTR
- Item attribute
-- DATE_VALUE - date value
-- NUMBER_VALUE - number value
-- TEXT_VALUE - text value
procedure Assign(itemtype in varchar2,
itemkey in varchar2,
actid
in number,
funcmode in varchar2,
resultout in out nocopy varchar2)
is
atype
varchar2(8);
asubtype varchar2(8);
aformat varchar2(240);
aname
varchar2(30);
begin
-- Do nothing in cancel or timeout mode
if (funcmode <> wf_engine.eng_run) then
resultout := wf_engine.eng_null;
return;
end if;
-- Get attribute info
aname := wf_engine.GetActivityAttrText(itemtype, itemkey, actid, 'ATTR');
wf_engine.GetItemAttrInfo(itemtype, aname, atype, asubtype, aformat);
-- NUMBER value
if (atype = 'NUMBER') then
wf_engine.SetItemAttrNumber(itemtype,itemkey,aname,
wf_engine.GetActivityAttrNumber(itemtype,itemkey,actid, 'NUMBER_VALUE'));
-- DATE value
elsif (atype = 'DATE') then
wf_engine.SetItemAttrDate(itemtype,itemkey,aname,
wf_engine.GetActivityAttrDate(itemtype,itemkey,actid, 'DATE_VALUE'));
-- TEXT value (VARCHAR2, LOOKUP, FORM, URL, DOCUMENT, etc)
else
wf_engine.SetItemAttrText(itemtype,itemkey,aname,
wf_engine.GetActivityAttrText(itemtype,itemkey,actid, 'TEXT_VALUE'));
end if;
resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
exception
when others then
Wf_Core.Context('Wf_Standard', 'Assign', itemtype,
itemkey, to_char(actid), funcmode);
raise;
end Assign;
-- GetURL
-- Get monitor URL, store in item attribute
-- OUT
-- result
- 'NULL'
-- ACTIVITY ATTRIBUTES REFERENCED
-- ATTR
- Item attribute to set
-- ADMIN_MODE - administration mode (Y / N)
procedure GetURL(itemtype in varchar2,
itemkey in varchar2,
actid
in number,
funcmode in varchar2,
resultout in out nocopy varchar2)
is
aname
varchar2(30);
admin
varchar2(8);
begin
-- Do nothing in cancel or timeout mode
if (funcmode <> wf_engine.eng_run) then
resultout := wf_engine.eng_null;
return;
end if;
-- SYNCHMODE: Not allowed
if (itemkey = wf_engine.eng_synch) then
Wf_Core.Token('OPERATION', 'Wf_Standard.GetUrl');
Wf_Core.Raise('WFENG_SYNCH_DISABLED');
end if;
-- Get item attribute name
aname := wf_engine.GetActivityAttrText(itemtype,itemkey,actid, 'ATTR');
-- Get admin mode
admin := wf_engine.GetActivityAttrText(itemtype,itemkey,actid, 'ADMIN_MODE');
-- Set item attribute
wf_engine.SetItemAttrText(itemtype, itemkey, aname,
wf_monitor.geturl(
wf_core.translate('WF_WEB_AGENT'), itemtype, itemkey, admin));
resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
exception
when others then
Wf_Core.Context('Wf_Standard', 'GetUrl', itemtype,
is
etime
delta
processid
ptype
number;
number;
number;
varchar2(30);
exception
when others then
Wf_Core.Context('Wf_Standard', 'CompareExecutionTime', itemtype,
itemkey, to_char(actid), funcmode);
raise;
end CompareExecutionTime;
-- CompareEventProperty
-- Compare a property on an event
-- IN
-- itemtype - item type
-- itemkey - item key
-- actid
- process activity instance id
-- funcmode - execution mode
-- OUT
-- comparison result (WFSTD_COMPARISON lookup code)
-- GT LT EQ NULL
-- ACTIVITY ATTRIBUTES REFERENCED
-- EVENT - Event whose property is to be compared
-- PROPERTY - Event Property Reference (Based on the lookup of EVENTPROPERTY
-- PARAMETER - Parameter Name if Lookup type = Parameter
-- VALUE - Constant value of correct type
procedure CompareEventProperty(itemtype in varchar2,
itemkey in varchar2,
actid
in number,
funcmode in varchar2,
resultout in out nocopy varchar2)
is
lEvent WF_EVENT_T;
lAgent WF_AGENT_T;
lNVal NUMBER;
lDVal DATE;
lTVal VARCHAR2 (4000);
lProperty VARCHAR2 (20);
lParameter VARCHAR2(200);
lType VARCHAR2 (20);
lSubType VARCHAR2 (20);
lFormat VARCHAR2 (20);
begin
lEvent := wf_engine.getActivityAttrEvent(itemtype, itemkey,
actid, 'EVENT');
lProperty := wf_engine.getActivityAttrText(itemtype, itemkey,
actid, 'PROPERTY');
if (lProperty = 'PRIORITY') then
lNVal := wf_engine.getActivityAttrNumber(itemtype, itemkey,
actid, 'NUMBER_VALUE');
if (lEvent.priority is NULL or lNVal is NULL) then
resultout := wf_engine.eng_completed||':NULL';
elsif (lEvent.priority < lNVal) then
resultout := wf_engine.eng_completed||':LT';
elsif (lEvent.priority > lNVal) then
resultout := wf_engine.eng_completed||':GT';
elsif (lEvent.priority = lNVal) then
resultout := wf_engine.eng_completed||':EQ';
end if;
end if;
elsif (lProperty = 'TO_AGENT') then
lTVal := wf_engine.getActivityAttrText(itemtype, itemkey,
actid, 'TEXT_VALUE');
if (LEvent.To_Agent.Name is NULL
or LEvent.To_Agent.System is NULL or lTVal is NULL) then
resultout := wf_engine.eng_completed||':NULL';
elsif (LEvent.To_Agent.Name||'@'||LEvent.To_Agent.System < lTVal) then
resultout := wf_engine.eng_completed||':LT';
elsif (LEvent.To_Agent.Name||'@'||LEvent.To_Agent.System > lTVal) then
resultout := wf_engine.eng_completed||':GT';
elsif (LEvent.To_Agent.Name||'@'||LEvent.To_Agent.System = lTVal) then
resultout := wf_engine.eng_completed||':EQ';
end if;
elsif (lProperty = 'PARAMETER') then
lTVal := wf_engine.getActivityAttrText(itemtype, itemkey,
actid, 'TEXT_VALUE');
lParameter := wf_engine.getActivityAttrText(itemtype => itemtype,
itemkey => itemkey,
actid => actid,
aname => 'PARAMETER');
if (LEvent.GetValueForParameter(lParameter)) is NULL then
resultout := wf_engine.eng_completed||':NULL';
elsif (LEvent.GetValueForParameter(lParameter) < lTVal) then
resultout := wf_engine.eng_completed||':LT';
elsif (LEvent.GetValueForParameter(lParameter) > lTVal) then
resultout := wf_engine.eng_completed||':GT';
elsif (LEvent.GetValueForParameter(lParameter) = lTVal) then
resultout := wf_engine.eng_completed||':EQ';
end if;
else
-- Unhandled property. Return NULL
resultout := wf_engine.eng_completed||':NULL';
end if;
exception
when others then
Wf_Core.Context('Wf_Standard', 'CompareEventProperty', itemtype,
itemkey, to_char(actid), funcmode);
raise;
end CompareEventProperty;
-- SetEventProperty
-- Set the property in an Event to a given value
-- IN
-- itemtype - item type
-- itemkey - item key
-- actid
- process activity instance id
-- funcmode - execution mode
-- OUT
-- NONE
-- ACTIVITY ATTRIBUTES REFERENCED
-- EVENT - Event whose property is to be compared
-- PROPERTY - Event Property Reference (Based on the lookup of EVENTPROPERTY
-- PARAMETER - Parameter name
-- VALUE - Constant value of correct type
procedure SetEventProperty(itemtype in varchar2,
itemkey in varchar2,
actid
in number,
funcmode in varchar2,
-- LaunchProcess
-- launches a process
-- IN
-- itemtype - item type
-- itemkey - item key
-- actid
- process activity instance id
-- funcmode - execution mode
-- OUT
-- result
- NULL
-- ACTIVITY ATTRIBUTES REFERENCED
-- START_ITEMTYPE,START_ITEMKEY,START_PROCESS,START_USER_KEY,START_OWNER
procedure LaunchProcess
(itemtype in varchar2,
itemkey
in varchar2,
actid
in number,
funcmode in varchar2,
resultout in out nocopy varchar2) is
SItemtype varchar2(8);
SItemKey varchar2(30);
SProcess varchar2(30);
SUserKey varchar2(320);
SOwner
varchar2(320);
Deferit varchar2(2);
Launch_count number;
status
varchar2(8);
result
varchar2(30);
loop_flag BOOLEAN;
begin
-- Do nothing in cancel or timeout mode
if (funcmode <> wf_engine.eng_run) then
resultout := wf_engine.eng_null;
return;
end if;
SItemtype := upper(Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'IT
EMTYPE'));
Deferit := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'DEFER');
if SItemtype is null then
wf_core.token('ITEMTYPE','NULL');
wf_core.raise('WFSQL_ARGS');
end if;
if deferit = 'Y' then
-- Check if this is the first or second execution of this activity.
-- First -> result_code will be null (really null).
-- Second -> result_code will be '#NULL' (set that way by execution 1).
Wf_Item_Activity_Status.Result(itemtype, itemkey, actid, status, result);
if (result = wf_engine.eng_null) then
-- Second execution.
-- Defer must have been picked up by the background engine,
-- so return complete result.
resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
else
-- Return deferred result
resultout := wf_engine.eng_deferred;
return;
end if;
end if;
-- if we have got this far, go ahead and launch the process.
SItemkey := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'ITEMKEY'
);
SProcess := upper(Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'PR
OCESS_NAME'));
SUserkey := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'USER_KEY
');
SOwner
:= Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'OWNER');
if sItemkey is not null then
wf_engine.LaunchProcess(SItemtype, SItemkey, SProcess, SUserkey, SOwner);
else
begin
launch_count := wf_engine.GetItemAttrNumber(
itemtype, itemkey, 'LAUNCH_COUNT');
exception
when others then
--- If item attribute does not exist then create it;
-if ( wf_core.error_name = 'WFENG_ITEM_ATTR' ) then
wf_engine.AddItemAttr(itemtype,itemkey, 'LAUNCH_COUNT');
launch_count := 0;
else
raise;
end if;
end;
loop_flag:=TRUE;
while loop_flag loop
begin
launch_count:=launch_count+1;
-- imtetype:itemkey is unique so the new itemkey should be unique
sItemkey := itemtype||':'||itemkey||'-'||to_char(launch_count);
wf_engine.LaunchProcess(SItemtype, SItemkey, SProcess,
SUserkey, SOwner);
loop_flag:=FALSE;
exception
when others then
--- Dont raise error if its a dup name: instead we will loop
-- around and increment the counter.
if ( wf_core.error_name <> 'WFENG_ITEM_UNIQUE' ) then
raise;
end if;
end;
end loop;
wf_engine.SetItemAttrNumber(
itemtype, itemkey, 'LAUNCH_COUNT',launch_count);
end if;
resultout := wf_engine.eng_completed;
exception
when others then
Wf_Core.Context('Wf_Standard', 'LaunchProcess', itemtype,
itemkey, to_char(actid), Sitemtype||':'||Sitemkey||SProcess)
;
raise;
end LaunchProcess;
-- LaunchProcess
-- Forks the item by creating a duplicate item with the same history.
-- The new forked item will be identical up to the point of this activity.
-- However this activity will be marked as NOTIFIED. It will be upto the user
-- to push it forward using CompleteActivity.
-- NOTE: this is not permitted for #SYNCH items.
-- IN
-- itemtype - item type
-- itemkey - item key
-- actid
- process activity instance id
-- funcmode - execution mode
-- OUT
-- result
- NULL
-- ACTIVITY ATTRIBUTES REFERENCED
-- NEW_ITEMKEY - the itemkey for the new item (required)
-- SAME_VERSION - TRUE creates a duplicate, FALSE uses the latest version
procedure ForkItem(itemtype in varchar2,
itemkey
in varchar2,
actid
in number,
funcmode in varchar2,
resultout in out nocopy varchar2) is
sitemkey varchar2(30);
sameversion boolean;
sameversionFlag varchar2(1);
begin
-- Do nothing in cancel or timeout mode
if (funcmode <> wf_engine.eng_run) then
resultout := wf_engine.eng_null;
return;
end if;
if (itemkey = wf_engine.eng_synch) then
Wf_Core.Token('OPERATION', 'Wf_Standard.ForkItem');
Wf_Core.Raise('WFENG_SYNCH_DISABLED');
end if;
begin
-- Do nothing in cancel or timeout mode
if (funcmode <> wf_engine.eng_run) then
resultout := wf_engine.eng_null;
return;
end if;
-- lookup notification base info
Wf_Activity.Notification_Info(itemtype, itemkey, actid, msg, msgtype,
expand_role);
-- see if this activity is already assigned to a role
prole := Wf_Activity.Perform_Role(itemtype, itemkey, actid);
-- if it isnt then use the value from activity attribute
if prole is null then
prole := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'PERFORME
R');
end if;
if prole is null then
Wf_Core.Token('TYPE', itemtype);
Wf_Core.Token('ACTID', to_char(actid));
Wf_Core.Raise('WFENG_NOTIFICATION_PERFORMER');
end if;
-- message name and expand roles will be null. Get these from attributes
avalue := upper(Wf_Engine.GetActivityAttrText(itemtype, itemkey,
actid, 'MESSAGE'));
-- let notification_send catch a missing message name.
expand_role := nvl(Wf_Engine.GetActivityAttrText(itemtype, itemkey,
actid, 'EXPANDROLES'),'N');
-- parse out the message type if given
colon := instr(avalue, ':');
if colon = 0 then
msgtype := itemtype;
msg := avalue;
else
msgtype := substr(avalue, 1, colon - 1);
msg := substr(avalue, colon + 1);
end if;
-- Actually send the notification
Wf_Engine_Util.Notification_Send(itemtype, itemkey, actid,
msg, msgtype, prole, expand_role,
resultout);
--resultout is determined by Notification_Send as either
--NULL
if notification is FYI
--NOTIFIED:notid:role if notification requires responce
exception
when others then
Wf_Core.Context('Wf_Standard', 'Notify', itemtype,
status
varchar2(8);
result
varchar2(30);
wait_mode varchar2(30);
wait_date date;
wakeup
date;
daybuf
varchar2(30);
time
date;
wf_invalid_mode exception;
begin
-- Do nothing in cancel or timeout mode
if (funcmode <> wf_engine.eng_run) then
resultout := wf_engine.eng_null;
return;
end if;
-- SYNCHMODE: Not allowed
if (itemkey = wf_engine.eng_synch) then
Wf_Core.Token('OPERATION', 'Wf_Standard.Wait');
Wf_Core.Raise('WFENG_SYNCH_DISABLED');
end if;
-- Check if this is the first or second execution of this activity.
-- First -> result_code will be null (really null).
-- Second -> result_code will be '#NULL' (set that way by execution 1).
Wf_Item_Activity_Status.Result(itemtype, itemkey, actid, status, result);
if (result = wf_engine.eng_null) then
-- Second execution.
-- Wait is completed, return complete result.
resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
else
-- First execution.
wait_mode := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid,
'WAIT_MODE');
if (wait_mode = 'ABSOLUTE') then
-- Absolute date
wakeup := Wf_Engine.GetActivityAttrDate(itemtype, itemkey, actid,
'WAIT_ABSOLUTE_DATE');
elsif (wait_mode = 'RELATIVE') then
-- Relative date. Figure offset from sysdate.
wakeup := Wf_Engine.GetActivityAttrNumber(itemtype, itemkey, actid,
'WAIT_RELATIVE_TIME') + sysdate;
elsif (wait_mode = 'DAY_OF_WEEK') then
-- Day of week.
daybuf := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid,
'WAIT_DAY_OF_WEEK');
wakeup := next_day(trunc(sysdate), daybuf);
elsif (wait_mode = 'DAY_OF_MONTH') then
daybuf := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid,
'WAIT_DAY_OF_MONTH');
-- Figure wakeup time as offset from beginning of current month
if (daybuf = 'LAST') then
-- Set to last day of current month
wakeup := last_day(to_date('01/'||to_char(sysdate, 'MM/YYYY'),
'DD/MM/YYYY'));
else
-- Set to day x of current month
wakeup := to_date('01/'||to_char(sysdate, 'MM/YYYY'),
'DD/MM/YYYY') + to_number(daybuf) - 1;
end if;
-- If wakeup is before current date, then shift to next month
if (wakeup <= sysdate) then
if (daybuf = 'LAST') then
-- Set to last day of following month
wakeup := last_day(add_months(to_date('01/'||to_char(sysdate,
'MM/YYYY'),
'DD/MM/YYYY'), 1));
else
-- Set to day x of the following month
wakeup := add_months(to_date('01/'||to_char(sysdate, 'MM/YYYY'),
'DD/MM/YYYY'), 1)
+ to_number(daybuf) - 1;
end if;
end if;
else
raise wf_invalid_mode;
end if;
-- Add the WAIT_TIME to the wakeup if specified
time := Wf_Engine.GetActivityAttrDate(itemtype, itemkey, actid,
'WAIT_TIME');
if (time is not null) then
wakeup := to_date(to_char(wakeup, 'DD/MM/YYYY')||
to_char(time, ' HH24:MI'), 'DD/MM/YYYY HH24:MI');
end if;
-- Return deferred result with wakeup time appended
resultout := wf_engine.eng_deferred||':'||
to_char(wakeup, wf_engine.date_format);
end if;
exception
when wf_invalid_mode then
Wf_Core.Context('Wf_Standard', 'Wait', itemtype, itemkey,
to_char(actid), funcmode);
Wf_Core.Token('COMMAND', wait_mode);
Wf_Core.Raise('WFSQL_COMMAND');
when others then
Wf_Core.Context('Wf_Standard', 'Wait', itemtype, itemkey,
to_char(actid), funcmode);
raise;
end Wait;
-- ResetError
-- Reset the status of an errored activity in an WFERROR process.
-- OUT
-- result
- 'NULL'
-- ACTIVITY ATTRIBUTES REFERENCED
-- COMMAND - 'SKIP' or 'RETRY'
-'SKIP' marks the errored activity complete and continues processing
-'RETRY' clears the errored activity and runs it again
-- RESULT - Result code to complete the activity with if COMMAND = 'SKIP'
Wf_Core.Token('COMMAND', cmd);
Wf_Core.Raise('WFSQL_COMMAND');
when others then
Wf_Core.Context('Wf_Standard', 'ResetError', itemtype,
itemkey, to_char(actid), funcmode);
raise;
end ResetError;
-- RoleResolution
-- Resolve A Role which comprises a group to an individual
-- OUT
-- result
- 'NULL'
-- ACTIVITY ATTRIBUTES REFERENCED
-- COMMAND - 'LOAD_BALANCE' or 'ROUND_ROBIN'
-'LOAD_BALANCE' Assigns to user with least open notifications
-'ROUND_ROBIN' Assigns notification to users sequencially
procedure RoleResolution(itemtype in varchar2,
itemkey
in varchar2,
actid
in number,
funcmode in varchar2,
resultout in out nocopy varchar2) is
cmd
varchar2(30);
wf_invalid_command
exception;
actdate
date;
label
varchar2(30);
prole
varchar2(320);
--- select all out-transitions of RoleResolution Activity
-cursor out_transitions is
SELECT wat.to_process_activity,
wpa.activity_name,
wpa.perform_role,
wpa.perform_role_type
FROM
wf_activity_transitions wat,
wf_process_activities wpa
WHERE wat.from_process_activity
= actid
AND
wat.result_code
= wf_engine.eng_trans_default
AND
wat.to_process_activity
= wpa.instance_id;
--- select number of activities the user currently has in worklist
-cursor load_balance(user in varchar2, act_name varchar2 ) is
select count(1)
from
wf_item_activity_statuses wias,
wf_process_activities wpa
where wias.item_type
= itemtype
and
wias.activity_status
= 'NOTIFIED'
and
wias.process_activity = wpa.instance_id
and
wpa.activity_name
= act_name
and
assigned_user
= user;
--- select the date of the last time the user was notified
-cursor round_robin(user in varchar2, act_name varchar2 ) is
select max(begin_date)
from
wf_item_activity_statuses wias,
wf_process_activities wpa
where wias.item_type
= itemtype
and
wias.process_activity = wpa.instance_id
and
wpa.activity_name
= act_name
and
wias.assigned_user
= user;
-begin
--- Do nothing in cancel mode
-if (funcmode <> wf_engine.eng_run ) then
resultout := wf_engine.eng_null;
return;
end if;
-- SYNCHMODE: Not allowed
if (itemkey = wf_engine.eng_synch) then
Wf_Core.Token('OPERATION', 'Wf_Standard.AndJoin');
Wf_Core.Raise('WFENG_SYNCH_DISABLED');
end if;
actdate := wf_item.active_date(itemtype, itemkey);
cmd := Wf_Engine.GetActivityAttrText(itemtype,itemkey,actid,'METHOD');
-- loop thru all out-transiations of role resolution activity
for trans_rec in out_transitions loop
declare
usertab
wf_directory.UserTable;
min_assigned_activities number := -1;
min_begin_date
date;
assigned_performer
varchar2(320);
begin
-if (Wf_Activity.Type(itemtype, trans_rec.activity_name, actdate) =
wf_engine.eng_notification) then
-- Get perform_role from constant or itemattr value
if (trans_rec.perform_role_type = 'CONSTANT') then
prole := trans_rec.perform_role;
else
prole := Wf_Engine.GetItemAttrText(itemtype, itemkey,
trans_rec.perform_role);
end if;
wf_directory.GetRoleUsers(prole,usertab);
if ( cmd = 'LOAD_BALANCE' ) then
declare
assigned_activities
number := 0;
indx
number := 1;
begin
loop -- loop until NO_DATA_FOUND
open
load_balance(usertab(indx),
trans_rec.activity_name);
fetch load_balance into assigned_activities;
close load_balance;
if ((assigned_activities < min_assigned_activities or
min_assigned_activities = -1) and
wf_directory.UserActive(usertab(indx))) then
min_assigned_activities := assigned_activities;
assigned_performer
:= usertab(indx);
end if;
indx := indx + 1;
end loop;
exception
when NO_DATA_FOUND then
null;
end;
elsif ( cmd = 'ROUND_ROBIN' ) then
declare
begin_date
date;
indx
number :=1;
begin
loop -- until access of usertab raises NO_DATA_FOUND
open
round_robin(usertab(indx),
trans_rec.activity_name);
fetch round_robin into begin_date;
close round_robin;
if (begin_date is null) then
begin_date := to_date('01/01/0001','DD/MM/YYYY');
end if;
if ((begin_date < min_begin_date or
min_begin_date is null) and
wf_directory.UserActive(usertab(indx))) then
min_begin_date
:= begin_date;
assigned_performer
:= usertab(indx);
end if;
indx := indx + 1;
end loop;
exception
when NO_DATA_FOUND then
null;
end;
else
raise wf_invalid_command;
end if;
if ( assigned_performer is not null ) then
--- Retreieve instance_label for activity
-select wpa.instance_label
into label
from wf_process_activities wpa
where wpa.instance_id = trans_rec.to_process_activity;
wf_engine.AssignActivity(itemtype,itemkey,label,
assigned_performer);
end if;
resultout := wf_engine.eng_null;
end if;
end;
end loop;
exception
when wf_invalid_command then
wf_core.context('Wf_Standard', 'RoleResoluion',
itemtype, itemkey, to_char(actid), funcmode);
wf_core.token('COMMAND', cmd);
wf_core.raise('WFSQL_COMMAND');
when others then
wf_core.Context('Wf_Standard', 'RoleResolution',
itemtype, itemkey, to_char(actid), funcmode);
raise;
end RoleResolution;
-- ContinueFlow
-- Signal Flow to continue
-- OUT
-- result
- 'NULL'
-- ACTIVITY ATTRIBUTES REFERENCED
-- WAITING_ACTIVITY
-- WAITING_FLOW
procedure ContinueFlow( itemtype in varchar2,
itemkey
in varchar2,
actid
in number,
funcmode in varchar2,
resultout in out nocopy varchar2 ) is
l_waiting_activity
varchar2(30);
l_waiting_flow
varchar2(30);
wf_invalid_command
exception;
begin
if (funcmode <> wf_engine.eng_run) then
resultout := wf_engine.eng_null;
return;
end if;
-- SYNCHMODE: Not allowed
if (itemkey = wf_engine.eng_synch) then
Wf_Core.Token('OPERATION', 'Wf_Standard.AndJoin');
Wf_Core.Raise('WFENG_SYNCH_DISABLED');
end if;
l_waiting_activity := upper(Wf_Engine.GetActivityAttrText(
itemtype, itemkey, actid,'WAITING_ACTIVITY'));
l_waiting_flow
:= Wf_Engine.GetActivityAttrText(
itemtype, itemkey, actid,'WAITING_FLOW');
if ( l_waiting_flow = 'MASTER' ) then
ContinueMasterFlow(itemtype,itemkey,actid,l_waiting_activity,resultout);
elsif ( l_waiting_flow = 'DETAIL' ) then
ContinueDetailFlow(itemtype,itemkey,actid,l_waiting_activity,resultout);
else
raise wf_invalid_command;
end if;
exception
when wf_invalid_command then
Wf_Core.Context('Wf_Standard', 'ContinueFlow',
itemtype,itemkey, to_char(actid), funcmode);
Wf_Core.Token('COMMAND', l_waiting_flow );
Wf_Core.Raise('WFSQL_COMMAND');
when others then
Wf_Core.Context('Wf_Standard', 'ContinueFlow',
itemtype,itemkey, to_char(actid), funcmode);
raise;
end continueflow;
-- WaitForFlow
-- Wait for flow to complete
-- OUT
-- result
- 'NULL'
-- ACTIVITY ATTRIBUTES REFERENCED
-- CONTINUATION_ACTIVITY
-- CONTINUATION_FLOW
procedure WaitForFlow( itemtype in varchar2,
itemkey
in varchar2,
actid
in number,
funcmode in varchar2,
resultout in out nocopy varchar2) is
l_continuation_activity varchar2(30);
l_continuation_flow
varchar2(30);
wf_invalid_command
exception;
begin
if (funcmode <> wf_engine.eng_run) then
resultout := wf_engine.eng_null;
return;
end if;
-- SYNCHMODE: Not allowed
if (itemkey = wf_engine.eng_synch) then
Wf_Core.Token('OPERATION', 'Wf_Standard.WaitForFlow');
Wf_Core.Raise('WFENG_SYNCH_DISABLED');
end if;
l_continuation_activity := upper(Wf_Engine.GetActivityAttrText(
itemtype, itemkey, actid,
'CONTINUATION_ACTIVITY'));
l_continuation_flow
:= Wf_Engine.GetActivityAttrText(
itemtype,itemkey,actid,'CONTINUATION_FLOW');
if ( l_continuation_flow = 'MASTER' ) then
WaitForMasterFlow(itemtype,itemkey,actid,
l_continuation_activity,resultout);
elsif ( l_continuation_flow = 'DETAIL' ) then
WaitForDetailFlow(itemtype,itemkey,actid,
l_continuation_activity,resultout);
else
raise wf_invalid_command;
end if;
exception
when wf_invalid_command then
Wf_Core.Context('Wf_Standard', 'WaitForFlow',
itemtype,itemkey, to_char(actid), funcmode);
Wf_Core.Token('COMMAND', l_continuation_flow );
Wf_Core.Raise('WFSQL_COMMAND');
when others then
Wf_Core.Context('Wf_Standard', 'WaitForFlow',
itemtype,itemkey, to_char(actid), funcmode);
raise;
end WaitForFlow;
-- LoopCounter
-Count the number of times the activity has been visited.
-- OUT
-- result
-- ACTIVITY ATTRIBUTES REFERENCED
-MAX_TIMES
procedure LoopCounter( itemtype in varchar2,
itemkey
in varchar2,
actid
in number,
funcmode in varchar2,
resultout in out nocopy varchar2) is
max_times
pls_integer;
loop_count
pls_integer;
begin
--- Do nothing in cancel mode
-if (funcmode <> wf_engine.eng_run) then
resultout := wf_engine.eng_null;
return;
end if;
-- Get maximum times activity can be executed.
max_times := wf_engine.GetActivityAttrNumber(
itemtype, itemkey, actid, 'MAX_TIMES');
if ( max_times is null ) then
wf_core.token('MAX_TIMES',max_times);
wf_core.raise('WFSQL_ARGS');
end if;
begin
loop_count := wf_engine.GetItemAttrNumber(
itemtype, itemkey, 'LOOP_COUNT'||':'||actid);
exception
when others then
--- If item attribute does not exist then create it;
-if ( wf_core.error_name = 'WFENG_ITEM_ATTR' ) then
wf_engine.AddItemAttr(
itemtype,itemkey, 'LOOP_COUNT'||':'||actid);
loop_count := 0;
else
raise;
end if;
end;
if ( loop_count >= max_times ) then
loop_count := 0;
resultout := 'EXIT';
else
loop_count := loop_count +1;
resultout := 'LOOP';
end if;
wf_engine.SetItemAttrNumber(
itemtype, itemkey, 'LOOP_COUNT'||':'||actid,loop_count);
exception
when others then
wf_core.context('Wf_Standard','LoopCount',
itemtype, itemkey, to_char(actid), funcmode);
raise;
end loopcounter;
-- VoteForResultType
-Standard Voting Function
-- IN
-- itemtype - A valid item type from (WF_ITEM_TYPES table).
-- itemkey - A string generated from the application object's primary key.
-- actid
- The process activity(instance id).
-- funcmode - Run/Cancel
-- OUT
-- result
--- USED BY ACTIVITIES
--- WFSTD.VoteForResultType
--- ACTIVITY ATTRIBUTES REFERENCED
-VOTING_OPTION
-- WAIT_FOR_ALL_VOTES - Evaluate voting after all votes are cast
-- or a Timeout condition closes the voting
-- polls. When a Timeout occurs the
-- voting percentages are calculated as a
-- percentage ofvotes cast.
--- REQUIRE_ALL_VOTES - Evaluate voting after all votes are cast.
-- If a Timeout occurs and all votes have not
-- been cast then the standard timeout
-- transition is taken. Votes are calculated
-- as a percenatage of users notified to vote.
--- TALLY_ON_EVERY_VOTE - Evaluate voting after every vote or a
-- Timeout condition closes the voting polls.
-- After every vote voting percentages are
-- calculated as a percentage of user notified
-- to vote. After a timeout voting
-- percentages are calculated as a percentage
-- of votes cast.
--"One attribute for each of the activities result type codes"
--- The standard Activity VOTEFORRESULTTYPE has the WFSTD_YES_NO
-- result type assigned.
-- Thefore activity has two activity attributes.
--Y
- Percenatage required for Yes transition
-N
- Percentage required for No transition
-procedure VoteForResultType(
itemtype in varchar2,
itemkey
in varchar2,
actid
in number,
funcmode in varchar2,
resultout in out nocopy varchar2)
is
-- Select all lookup codes for an activities result type
cursor result_codes is
select wfl.lookup_code result_code
from
wf_lookups wfl,
wf_activities wfa,
wf_process_activities wfpa,
wf_items wfi
where
and
and
and
and
and
and
and
wfl.lookup_type
wfa.name
wfi.begin_date
wfi.begin_date
wfpa.activity_item_type
wfpa.instance_id
wfi.item_key
wfi.item_type
= wfa.result_type
= wfpa.activity_name
>= wfa.begin_date
< nvl(wfa.end_date,wfi.begin_date+1)
= wfa.item_type
= actid
= itemkey
= itemtype;
l_code_count
pls_integer;
l_group_id
pls_integer;
l_user
varchar2(320);
l_voting_option varchar2(30);
l_per_of_total number;
l_per_of_vote number;
l_per_code
number;
per_success
number;
max_default
pls_integer := 0;
default_result varchar2(30) := '';
result
varchar2(30) := '';
wf_invalid_command exception;
begin
-- Do nothing unless in RUN or TIMEOUT modes
if (funcmode <> wf_engine.eng_run)
and (funcmode <> wf_engine.eng_timeout) then
resultout := wf_engine.eng_null;
return;
end if;
-- SYNCHMODE: Not allowed
if (itemkey = wf_engine.eng_synch) then
Wf_Core.Token('OPERATION', 'Wf_Standard.VotForResultType');
Wf_Core.Raise('WFENG_SYNCH_DISABLED');
end if;
-- Get Notifications group_id for activity
Wf_Item_Activity_Status.Notification_Status(itemtype,itemkey,actid,
l_group_id,l_user);
l_voting_option := Wf_Engine.GetActivityAttrText(itemtype,itemkey,
actid,'VOTING_OPTION');
if (l_voting_option not in ('REQUIRE_ALL_VOTES', 'WAIT_FOR_ALL_VOTES',
'TALLY_ON_EVERY_VOTE')) then
raise wf_invalid_command;
end if;
------if
wf_notification.OpenNotificationsExist(l_group_id)) then
-- Not timed out and still open notifications.
-- Return waiting to continue voting.
resultout := wf_engine.eng_waiting;
elsif (default_result is not null) then
-- Either timeout or all notifications closed
-- Return default result if one found.
resultout := wf_engine.eng_completed||':'||default_result;
elsif (funcmode = wf_engine.eng_timeout) then
-- If Timeout has occured then return result Timeout so the Timeout
-- transition will occur - BUG2885157
resultout := wf_engine.eng_completed||':'||wf_engine.eng_timedout;
else
-- All notifications closed, and no default.
-- Return nomatch
resultout := wf_engine.eng_completed||':'||wf_engine.eng_nomatch;
end if;
end if;
return;
exception
when wf_invalid_command then
Wf_Core.Context('Wf_Standard', 'VoteForResultType', itemtype,
itemkey, to_char(actid), funcmode);
Wf_Core.Token('COMMAND', l_voting_option);
Wf_Core.Raise('WFSQL_COMMAND');
when others then
Wf_Core.Context('Wf_Standard', 'VoteForResultType',itemtype,
itemkey, to_char(actid), funcmode);
raise;
end VoteForResultType;
------------------------------------------------------------------------------------------------------------- PRIVATE APIs ------------------------------------------------------------------------------------------------------------------ WaitForMasterFlow
-- Wait for Master flow to complete continuation activity
-- OUT
-- result
- 'NULL'
procedure WaitForMasterFlow(
itemtype
in varchar2,
itemkey
in varchar2,
actid
in number,
continuation_activity in varchar2,
resultout
out nocopy varchar2 )
is
l_parent_itemtype
varchar2(8);
l_parent_itemkey
varchar2(240);
l_activity_status
varchar2(30);
colon pls_integer;
process varchar2(30);
label varchar2(30);
instid pls_integer;
dummy varchar2(50);
begin
-- Parse activity arg into <process_name> and <instance_label> components.
colon := instr(continuation_activity, ':');
parent_item_type, parent_item_key
l_parent_itemtype, l_parent_itemkey
wf_items
item_type
= WaitForMasterFlow.itemtype
item_key
= WaitForMasterFlow.itemkey;
begin
select 'master activity not complete'
into dummy
from WF_ITEM_ACTIVITY_STATUSES WIAS, WF_PROCESS_ACTIVITIES WPA
where WIAS.ITEM_TYPE = l_parent_itemtype
and WIAS.ITEM_KEY = l_parent_itemkey
and WIAS.PROCESS_ACTIVITY = WPA.INSTANCE_ID
and WPA.INSTANCE_LABEL = label
and WPA.PROCESS_NAME = nvl(process, WPA.PROCESS_NAME)
and wias.activity_status in (wf_engine.eng_completed, wf_engine.eng_act
ive);
exception
-- When not complete return NOTIFIED to cause engine to stall
when NO_DATA_FOUND then
resultout := wf_engine.eng_notified||':'||wf_engine.eng_null|| ':'||
wf_engine.eng_null;
return;
end;
resultout := wf_engine.eng_null;
exception
when others then
wf_core.context('Wf_Standard', 'WaitForMasterFlow',
itemtype,itemkey,to_char(actid),continuation_activity);
raise;
end WaitForMasterFlow;
-- WaitForDetailFlow
-- Wait for detail flows to complete continuation activity
-- OUT
-- result
- 'NULL'
procedure WaitForDetailFlow(
itemtype
in varchar2,
itemkey
in varchar2,
actid
in number,
continuation_activity in varchar2,
resultout
out nocopy varchar2) is
cursor child_flows is
-- select all active children of parent flow
select count(1)
from
wf_items
where parent_item_type
= itemtype
and
parent_item_key
= itemkey
and
end_date
is null;
resultout := wf_engine.eng_null;
else
open child_activities(itemtype, itemkey, process, label);
fetch child_activities into number_complete;
close child_activities;
if number_active > number_complete then
resultout := wf_engine.eng_notified||':'||
wf_engine.eng_null||':'||wf_engine.eng_null;
else
resultout := wf_engine.eng_null;
end if;
end if; --There are no children
else --#WAITFORDETAIL exists
WF_ENGINE.AddItemAttr(itemtype=>WaitForDetailFlow.itemtype,
itemkey=>WaitForDetailFlow.itemkey,
aname=>'#CNT_'||l_waitLabel,
number_value=>l_childCount);
if (l_childCount > 0) then
resultout := wf_engine.eng_notified||':'||
wf_engine.eng_null||':'||wf_engine.eng_null;
else
resultout := wf_engine.eng_null;
end if; --l_childCount > 0
end if; -- #WAITFORDETAIL
elsif (l_labelCount > 0) then
--The #CNT_ attribute exists and is 1 or greater so this will remain
--notified.
resultout := wf_engine.eng_notified||':'||wf_engine.eng_null||
':'||wf_engine.eng_null;
else --The labelcount exists and is < 1 so we can continue.
resultout := wf_engine.eng_null;
end if;
exception
when others then
wf_core.context('Wf_Standard', 'WaitForDetailFlow',
itemtype,itemkey,to_char(actid),continuation_activity);
raise;
end WaitForDetailFlow;
-- ContinueDetailFlow
-- Signal Detail Flows to continue
-- IN
-- itemtype - A valid item type from (WF_ITEM_TYPES table).
-- itemkey - A string generated from the application object's primary key.
-- actid
- The process activity(instance id).
-- waiting_activity - The Name of the activity that in waiting
-- OUT
-- resultout
- 'NULL'
procedure ContinueDetailFlow( itemtype
in varchar2,
itemkey
in varchar2,
actid
in number,
waiting_activity
in varchar2,
resultout
out nocopy varchar2
) is
-cursor child_flows is
--- select all active children of parent flow
-select item_type, item_key
from
wf_items
where parent_item_type
= itemtype
and
parent_item_key
= itemkey
and
end_date
is null;
-begin
for child_flows_rec in child_flows loop
--- Complete Waiting Activity in All Detail Flows
-begin
wf_engine.CompleteActivity(child_flows_rec.item_type,
child_flows_rec.item_key, waiting_activity,wf_engine.eng_null);
exception
when others then
-- If call to CompleteActivity cannot find activity, return null
-- As either the detail flows does not have a waiting activity OR
-- the detail flow has not reach the waiting activity
if ( wf_core.error_name = 'WFENG_NOT_NOTIFIED' ) then
wf_core.clear;
else
raise;
end if;
end;
end loop;
ContinueDetailFlow.resultout := wf_engine.eng_null;
exception
when others then
wf_core.context('Wf_Standard','ContinueDetailFlow',
itemtype, itemkey, to_char(actid),waiting_activity);
raise;
end ContinueDetailFlow;
-- ContinueMasterFlow
-- Signal Master Flow to continue if all Detail flows have
-- executed Continuation Activity
-- OUT
-- result
- 'NULL'
procedure ContinueMasterFlow( itemtype
in varchar2,
itemkey
in varchar2,
actid
in number,
waiting_activity
in varchar2,
resultout
in out nocopy varchar2)
is
l_activity_status
varchar2(8);
l_parent_itemtype
varchar2(8);
l_parent_itemkey
varchar2(240);
label
varchar2(30);
number_active pls_integer;
number_complete pls_integer;
-- CTILLEY bug 1941013
l_parent_context varchar2(2000);
cursor child_flows_mwf is
-- This cursor is used if there are multiple WaitForFlow Activities in the
-- parent flow (the parent_context must be set). CTILLEY bug 1941013
-- select all active children of parent flow excluding current work item
select count(1)
from
wf_items
where parent_item_type
= l_parent_itemtype
and
parent_item_key
= l_parent_itemkey
and
parent_context
= l_parent_context
and
(item_type
<> ContinueMasterFlow.itemtype
or item_key
<> ContinueMasterFlow.itemkey)
and
end_date
is null;
cursor child_flows2 is
-- select all active children of parent flow excluding current work item
select count(1)
from
wf_items
where parent_item_type
= l_parent_itemtype
and
parent_item_key
= l_parent_itemkey
and
(item_type
<> ContinueMasterFlow.itemtype
or item_key
<> ContinueMasterFlow.itemkey)
and
end_date
is null;
cursor child_activities2 is
select count(1)
from WF_ITEM_ACTIVITY_STATUSES WIAS, WF_PROCESS_ACTIVITIES WPA,
WF_ITEMS WI
where WIAS.ITEM_TYPE
= itemtype
and WIAS.ITEM_KEY
= WI.item_key
and WI.parent_item_type = l_parent_itemtype
and WI.parent_item_key = l_parent_itemkey
and (WI.item_type <> itemtype OR WI.item_key <> itemkey )
and WI.end_date is null
and WIAS.PROCESS_ACTIVITY = WPA.INSTANCE_ID
and WPA.INSTANCE_LABEL = label
and wias.activity_status in (wf_engine.eng_completed,
wf_engine.eng_active);
dummy varchar2(240);
status varchar2(8);
result varchar2(30);
l_count number;
l_defer varchar2(4000);
l_childwaiting number;
begin
--- select parent details
-select parent_item_type, parent_item_key, parent_context
into
l_parent_itemtype, l_parent_itemkey, l_parent_context
from
wf_items
where item_type = ContinueMasterFlow.itemtype
and
item_key = ContinueMasterFlow.itemkey;
select instance_label
into
from
where
label
wf_process_activities
instance_id
= actid;
resultout := wf_engine.eng_null;
exception
when OTHERS then
if ( wf_core.error_name = 'WFENG_NOT_NOTIFIED' ) then
wf_core.clear;
ContinueMasterFlow.resultout := wf_engine.eng_null;
else
raise;
end if;
end;
else
open child_activities2;
fetch child_activities2 into number_complete;
close child_activities2;
begin
if number_active = number_complete then
wf_engine.CompleteActivity(l_parent_itemtype,l_parent_itemkey,
waiting_activity,wf_engine.eng_null);
end if;
resultout := wf_engine.eng_null;
exception
when others then
--- If call to CompleteActivity cannot find activity, return
-- null and wait for master flow
-if ( wf_core.error_name = 'WFENG_NOT_NOTIFIED' ) then
wf_core.clear;
ContinueMasterFlow.resultout := wf_engine.eng_null;
else
raise;
end if;
end;
end if; -- number_active was more than 0
return; -- done with old code path
end if; --#WAITFORDETAIL exists in the parent
end if; --#LBL_ is not null
-- If we come to here, we must be progressing in the new code path.
--Now we will try to decrement the corresponding #CNT_ attribute if it
--exists, and will create it with a value of 0 if it does not yet exist.
l_count := WF_ENGINE.AddToItemAttrNumber(l_parent_itemtype,
l_parent_itemkey,
'#CNT_'||waiting_activity, -1);
if (l_count is NULL) then
WF_ENGINE.AddItemAttr(itemtype=>l_parent_itemtype,
itemkey=>l_parent_itemkey,
aname=>'#CNT_'||waiting_activity,
number_value=>l_childwaiting - 1);
elsif (l_count < 1) then
begin
wf_engine.CompleteActivity(l_parent_itemtype,l_parent_itemkey,
waiting_activity,wf_engine.eng_null);
exception
when OTHERS then
if ( wf_core.error_name = 'WFENG_NOT_NOTIFIED' ) then
wf_core.clear;
ContinueMasterFlow.resultout := wf_engine.eng_null;
else
raise;
end if;
end;
end if;
l_defer := WF_ENGINE.GetActivityAttrText(itemtype, itemkey, actid,
'#HINT', TRUE);
--If #HINT is not set to 'NO_DEFER', or is null we will set the
--threshold to cause the next activity to defer.
if ((l_defer is null) or (l_defer <> 'NO_DEFER')) then
resultout := wf_engine.eng_deferred;
else
resultout := wf_engine.eng_null;
end if;
end if; --First execution
exception
when others then
wf_core.context('Wf_Standard', 'ContinueMasterFlow',
itemtype, itemkey, to_char(actid), waiting_activity);
raise;
end ContinueMasterFlow;
-- -------------------------------------------------------------------- InitializeErrors
-- checks if an item attribute for Workflow administrator exists in
-- the item that just errored out. If it does, then it uses this
-- role to send notifications to, overriding the default role
-- in this item.
-- NOTE: the item attibute in the workflow-in-error must have an
-- internal name of WF_ADMINISTRATOR.
--- Called by default error process.
-- ------------------------------------------------------------------PROCEDURE InitializeErrors(
itemtype
VARCHAR2,
itemkey
VARCHAR2,
actid
NUMBER,
funcmode
VARCHAR2,
result
OUT NOCOPY VARCHAR2 ) IS
l_error_itemtype
l_error_itemkey
l_error_name
l_error_msg
l_timeout
l_administrator
VARCHAR2(8);
VARCHAR2(240);
VARCHAR2(30);
VARCHAR2(2000);
PLS_INTEGER;
VARCHAR2(100);
BEGIN
IF (funcmode = 'RUN') THEN
--
-- Get the type and the key of the process that errored out
-- these were set in the erroring out process by Execute_Error_Process
-l_error_itemkey := WF_ENGINE.GetItemAttrText(
itemtype
=> itemtype,
itemkey
=> itemkey,
aname
=> 'ERROR_ITEM_KEY' );
l_error_itemtype := WF_ENGINE.GetItemAttrText(
itemtype
=> itemtype,
itemkey
=> itemkey,
aname
=> 'ERROR_ITEM_TYPE' );
--- Check if the workflow administrator exists
-- If it does, then assign the notification to this role
-begin
--if this item type doesnt exist an exception is raised.
l_administrator := WF_ENGINE.GetItemAttrText(
itemtype
=> l_error_itemtype,
itemkey
=> l_error_itemkey,
aname
=> 'WF_ADMINISTRATOR' );
--<rwunderl:2775132> Put first assignemt in their own block
--in case DEFAULT_RESET_ERROR_NTF does not exist.
begin
wf_engine.AssignActivity(itemtype,itemkey,
'DEFAULT_RESET_ERROR_NTF',
l_administrator);
exception
when OTHERS then
null; --We only null this exception because the parent
--block nulls the expeption.
end;
wf_engine.AssignActivity(itemtype,itemkey,'RETRY_ONLY_NTF',
l_administrator);
exception
when others then null;
end;
--- Check if a timeout value exists
-- If it does, then set the error timeout
-begin
--if this item type doesnt exist an exception is raised.
l_timeout := WF_ENGINE.GetItemAttrNumber(
itemtype
=> l_error_itemtype,
itemkey
=> l_error_itemkey,
aname
=> 'ERROR_TIMEOUT' );
wf_engine.SetItemAttrNumber(itemtype,itemkey,'TIMEOUT_VALUE',l_tim
eout);
exception
when others then null;
end;
result := wf_engine.eng_completed;
ELSIF (funcmode = 'CANCEL') THEN
result := wf_engine.eng_completed;
END IF;
EXCEPTION
WHEN OTHERS THEN
WF_CORE.Context('WF_STANDARD', 'InitializeErrors',
itemtype, itemkey, actid, funcmode);
RAISE;
END InitializeErrors;
-- -------------------------------------------------------------------- CheckErrorActive
-- checks if an error is still active and returns TRUE/FALSE.
-- Use this in an error process to exit out of a timeout loop
-- Called by default error process.
-- ------------------------------------------------------------------PROCEDURE CheckErrorActive(
itemtype
IN VARCHAR2,
itemkey
IN VARCHAR2,
actid
IN NUMBER,
funcmode
IN VARCHAR2,
result
OUT NOCOPY VARCHAR2 ) IS
l_error_itemtype
l_error_itemkey
l_error_actid
status
VARCHAR2(8);
VARCHAR2(240);
NUMBER;
VARCHAR2(30);
aname
=> 'ERROR_TYPE');
--- If the error type is null, this must be an UNEXPECTED event
-IF l_error_type IS NULL THEN
l_error_type := 'UNEXPECTED';
wf_engine.SetItemAttrText(itemtype
=> itemtype,
itemkey
=> itemkey,
aname
=> 'ERROR_TYPE',
avalue
=> l_error_type);
END IF;
--- Determine if this event is LOCAL or EXTERNAL
-if l_subscription is not null then
-- If a subscription found, look at its source
select source_type into l_source
from wf_event_subscriptions
where guid = l_subscription;
if l_source = 'ERROR' then
l_source := 'LOCAL';
end if;
else
-- Since no subscription found, look at from agent details
begin
select 'LOCAL' into l_source
from wf_systems ws
where ws.guid = hextoraw(wf_core.translate('WF_SYSTEM_GUID'))
and ws.name = nvl(l_event_t.GetFromAgent().GetSystem(),ws.name);
exception
when no_data_found then
l_source := 'EXTERNAL';
end;
end if;
--- Get the Error Message, or set it if UNEXPECTED
-l_error_message := substr(l_event_t.GetErrorMessage(),1,2000);
IF (l_error_message is null) THEN
l_error_message := wf_core.translate('NO_MATCHING_SUBSCRIPTIONS');
END IF;
-- Get the Error Stack
l_error_stack := substr(l_event_t.GetErrorStack(),1,2000);
-- Get the Errored Subscription GUID
l_subscription := l_event_t.GetErrorSubscription();
-- Generate the URL
wf_event_html.GetFWKEvtSubscriptionUrl(l_subscription, l_url);
l_eventdataurl := wf_oam_util.GetViewXMLURL(p_eventattribute => 'EVENT_MESSA
GE',
p_itemtype => itemtype,
p_itemkey => itemkey);
-- Set the Item Attributes
wf_engine.SetItemAttrText(itemtype
itemkey
aname
avalue
=>
=>
=>
=>
itemtype,
itemkey,
'ERROR_MESSAGE',
l_error_message);
wf_engine.SetItemAttrText(itemtype
itemkey
aname
avalue
=>
=>
=>
=>
itemtype,
itemkey,
'ERROR_STACK',
l_error_stack);
Details
=> itemtype,
=> itemkey,
=> 'EVENT_DETAILS',
=> 'PLSQL:WF_STANDARD.EVENTDETAILS
wf_engine.SetItemAttrText(itemtype
itemkey
aname
avalue
||ItemType||':'||ItemKey);
=>
=>
=>
=>
itemtype,
itemkey,
'ERROR_DETAILS',
'PLSQL:WF_STANDARD.ErrorDetails/'
wf_engine.SetItemAttrText(itemtype
itemkey
aname
avalue
tails/'||ItemType||':'||ItemKey);
=>
=>
=>
=>
itemtype,
itemkey,
'SUBSCRIPTION_DETAILS',
'PLSQL:WF_STANDARD.SubscriptionDe
-- EventDetails
-- PL/SQL Document for Event Attributes
-- -------------------------------------------------------------------procedure EventDetails ( document_id in varchar2,
display_type in varchar2,
document
in out nocopy varchar2,
document_type in out nocopy varchar2) IS
ItemType
ItemKey
varchar2(30);
varchar2(30);
l_to_agent
varchar2(60);
l_to_system varchar2(60);
l_from_agent varchar2(60);
l_from_system varchar2(60);
l_priority
varchar2(10);
l_send_date date;
l_send_date_text
varchar2(60);
l_receive_date date;
l_receive_date_text varchar2(60);
i
pls_integer;
l_event_t
l_parmlist_t
l_cells
j
l_result
wf_event_t;
wf_parameter_list_t;
wf_notification.tdType;
number;
varchar2(32000);
begin
-- parse document_id for the ':' dividing item type name from item key value
-- document_id value will take the form <ITEMTYPE>:<ITEMKEY> starting with
-- release 2.5
ItemType := nvl(substr(document_id, 1, instr(document_id,':')-1),'WFERROR');
ItemKey := substr(document_id
, instr(document_id,':')+1);
l_event_t := wf_engine.GetItemAttrEvent(
itemtype
itemkey
name
=> itemtype,
=> itemkey,
=> 'EVENT_MESSAGE' );
--- Get the Agent Details, we don't want any errors if the Agent
-- didn't get populated with anything
-if l_event_t.To_Agent is not null then
l_to_agent := l_event_t.GetToAgent().GetName();
l_to_system := l_event_t.GetToAgent().GetSystem();
end if;
if l_event_t.From_Agent is not null then
l_from_agent := l_event_t.GetFromAgent().GetName();
l_from_system := l_event_t.GetFromAgent().GetSystem();
end if;
--
'S:'||wf_core.translate('WF_TO_AGENT_NAME');
'S:'||l_to_agent;
'S:'||wf_core.translate('WF_TO_AGENT_SYSTEM');
'S:'||l_to_system;
i := i + 1;
l_cells(i) := 'S:'||wf_core.translate('WF_FROM_AGENT_NAME');
i := i + 1;
l_cells(i) := 'S:'||l_from_agent;
i := i + 1;
l_cells(i) := 'S:'||wf_core.translate('WF_FROM_AGENT_SYSTEM');
i := i + 1;
l_cells(i) := 'S:'||l_from_system;
i := i + 1;
l_cells(i) := 'S:'||wf_core.translate('WF_SEND_DATE');
i := i + 1;
l_cells(i) := 'S:<BDO DIR="LTR">'||l_send_date_text||'</BDO>';
i := i + 1;
l_cells(i) := 'S:'||wf_core.translate('WF_RECEIVE_DATE');
i := i + 1;
l_cells(i) := 'S:<BDO DIR="LTR">'||l_receive_date_text||'</BDO>';
i := i + 1;
l_cells(i) := 'S:'||wf_core.translate('WF_PRIORITY');
i := i + 1;
l_cells(i) := 'S:'||l_priority;
i := i + 1;
l_cells(i) := 'S:'||wf_core.translate('WF_CORRELATION');
i := i + 1;
l_cells(i) := 'S:'||nvl(l_event_t.GetCorrelationId(),'&'||'nbsp');
else
l_result := Wf_Core.Newline||rpad(wf_core.translate('WF_EVENT_HEADING'),40)
||wf_core.translate('WF_VALUE')||Wf_Core.Newline;
l_result := l_result||rpad(wf_core.translate('WF_EVENT_NAME'),40)||
l_event_t.GetEventName()||Wf_Core.Newline||
rpad(wf_core.translate('WF_EVENT_KEY'),40)||
l_event_t.GetEventKey()||Wf_Core.Newline||
rpad(wf_core.translate('WF_FROM_AGENT_NAME'),40)||
l_From_Agent||Wf_Core.Newline||
rpad(wf_core.translate('WF_FROM_AGENT_SYSTEM'),40)||
l_From_System||Wf_Core.Newline||
rpad(wf_core.translate('WF_TO_AGENT_NAME'),40)||
l_To_Agent||Wf_Core.Newline||
rpad(wf_core.translate('WF_TO_AGENT_SYSTEM'),40)||
l_To_System||Wf_Core.Newline||
rpad(wf_core.translate('WF_PRIORITY'),40)||
l_Priority||Wf_Core.Newline||
rpad(wf_core.translate('WF_SEND_DATE'),40)||
l_send_date_text||Wf_Core.Newline||
rpad(wf_core.translate('WF_RECEIVE_DATE'),40)||
l_receive_date_text||Wf_Core.Newline||
rpad(wf_core.translate('WF_CORRELATION'),40)||
l_event_t.GetCorrelationId()||Wf_Core.Newline;
end if;
-- Display the Parameter List
l_parmlist_t := l_event_t.getParameterList();
if (l_parmlist_t is not null) then
j := l_parmlist_t.FIRST;
while (j <= l_parmlist_t.LAST) loop
if (display_type = wf_notification.doc_html) then
i := i + 1;
l_cells(i) := 'S:'||wf_core.translate('WF_PARAMETER')||' : '||l_parmlist
_t(j).getName();
i := i + 1;
l_cells(i) :=
'S:'||substr(nvl(l_parmlist_t(j).getValue(),'&'||'nbsp'),1,20);
else
l_result := l_result||rpad(wf_core.translate('WF_PARAMETER')
||l_parmlist_t(j).getName(),40)
||substr(l_parmlist_t(j).getValue(),1,20)||Wf_Core.Newline;
end if;
j := l_parmlist_t.NEXT(j);
end loop;
end if;
if (display_type = wf_notification.doc_html) then
document_type := wf_notification.doc_html;
wf_notification.NTF_Table(cells => l_cells,
col => 2,
type => 'H',
rs
=> l_result);
-- Display title
l_result := '<table width="100%" border="0" cellspacing="1" cellpadding="1"
>' ||
'<tr><td class="x3w">'||wf_core.Translate('WFITD_EVENT_DETAILS')
||
'</td></tr>'||'<tr><td>'||l_result||'</td></tr></table>';
else
document_type := wf_notification.doc_text;
end if;
document := l_result;
exception
when others then
wf_core.context('WF_STANDARD','EventDetails',document_id, display_type);
raise;
end EventDetails;
-- --------------------------------------------------------------------- Retry Raise
-- Executes command depending on notification response
-- -------------------------------------------------------------------PROCEDURE RetryRaise
( itemtype in
varchar2,
itemkey in
varchar2,
actid
in
number,
funcmode in
varchar2,
resultout out nocopy varchar2 ) IS
aname
varchar2(100);
l_event_t
wf_event_t;
l_toagent
wf_agent_t;
l_skip_sub varchar2(300) := null;
l_parameterList wf_parameter_list_t := null;
begin
IF (funcmode = 'RUN') THEN
l_event_t := wf_engine.GetItemAttrEvent(
itemtype
itemkey
=> itemtype,
=> itemkey,
name
=> 'EVENT_MESSAGE' );
aname := wf_engine.GetActivityAttrText(itemtype,
itemkey,
actid,
'COMMAND');
-- Bug 4198975
-- If the SKIP_ERROR_SUB is not null, then this parameber will
-- be passed over to raise in all the cases.
l_skip_sub := l_event_t.GETVALUEFORPARAMETER('SKIP_ERROR_SUB');
if (l_skip_sub is not null) then
l_parameterList := wf_parameter_list_t();
wf_event.addParameterToList('SKIP_ERROR_SUB', l_skip_sub, l_parameterLis
t);
end if;
IF aname = 'RAISE_KEY' THEN
wf_event.raise(p_event_name => l_event_t.GetEventName(),
p_event_key => l_event_t.GetEventKey(),
p_parameters => l_parameterList);
ELSIF aname = 'RAISE_KEY_DATA' THEN
wf_event.raise(p_event_name => l_event_t.GetEventName(),
p_event_key => l_event_t.GetEventKey(),
p_event_data => l_event_t.GetEventData(),
p_parameters => l_parameterList);
ELSIF aname = 'RAISE_KEY_DATA_PARAM' THEN
wf_event.raise(l_event_t.GetEventName(),
l_event_t.GetEventKey(),
l_event_t.GetEventData(),
l_event_t.GetParameterList());
ELSIF aname = 'ENQUEUE' THEN
l_toagent := l_event_t.GetToAgent();
l_event_t.SetPriority(-1); -- want this dequeued ASAP
wf_event.enqueue(l_event_t, l_toagent);
ELSE
wf_core.raise('WFSQL_ARGS');
END IF;
resultout := wf_engine.eng_completed;
ELSIF (funcmode = 'CANCEL') THEN
resultout := wf_engine.eng_completed;
END IF;
EXCEPTION
WHEN OTHERS THEN
WF_CORE.Context('WF_STANDARD', 'RetryRaise',
itemtype, itemkey, actid, funcmode);
RAISE;
end RetryRaise;
-- --------------------------------------------------------------------- GetAgents
-- Gets the Event Subscription Out and To Agent
-- -------------------------------------------------------------------procedure GetAgents
( itemtype in
varchar2,
itemkey in
varchar2,
actid
in
number,
funcmode in
varchar2,
resultout out nocopy varchar2)
is
--l_subguid
l_subguid
l_outagentattr
l_toagentattr
l_outagentguid
l_toagentguid
l_outagent
l_toagent
cursor
select
from
where
raw(16);
varchar2(100);
varchar2(100);
varchar2(100);
raw(16);
raw(16);
varchar2(100);
varchar2(100);
c_agents is
out_agent_guid, to_agent_guid
wf_event_subscriptions
guid = l_subguid;
begin
IF (funcmode = 'RUN') THEN
l_subguid := wf_engine.GetActivityAttrText(itemtype,
itemkey,
actid,
'SUB_GUID');
l_outagentattr := wf_engine.GetActivityAttrText(itemtype,
itemkey,
actid,
'FROMAGENT');
l_toagentattr := wf_engine.GetActivityAttrText(itemtype,
itemkey,
actid,
'TOAGENT');
-- Get the Agent Guids
open c_agents;
fetch c_agents into l_outagentguid, l_toagentguid;
close c_agents;
if l_toagentguid is not null then
-- Get the Out Agent in the agent@system format
if l_outagentguid is not null then
select wfa.name||'@'||wfs.name
into l_outagent
from wf_agents wfa, wf_systems wfs
where wfa.guid = l_outagentguid
and wfa.system_guid = wfs.guid;
end if;
-- Get the To Agent in the agent@system format
select wfa.name||'@'||wfs.name
into l_toagent
from wf_agents wfa, wf_systems wfs
where wfa.guid = l_toagentguid
and wfa.system_guid = wfs.guid;
wf_event_t;
varchar2(100);
varchar2(30);
varchar2(30);
cursor c_return_agent is
select wfa.name agent
from wf_systems wfs,
wf_agents wfa
where wfs.name = l_system
and wfa.status = 'ENABLED'
and wfa.direction = 'IN'
and wfa.name not in ('WF_ERROR','WF_DEFERRED');
begin
IF (funcmode = 'RUN') THEN
l_event_t := wf_engine.GetActivityAttrEvent(
itemtype
itemkey
actid
name
=>
=>
=>
=>
itemtype,
itemkey,
actid,
'EVENTMESSAGE');
l_toagentattr := wf_engine.GetActivityAttrText(itemtype,
itemkey,
actid,
'ACKTOAGENT');
l_system := l_event_t.GetFromAgent().GetSystem();
open c_return_agent;
fetch c_return_agent into l_agent;
close c_return_agent;
if l_agent is not null then
wf_engine.SetItemAttrText(itemtype => itemtype,
itemkey => itemkey,
aname => l_toagentattr,
avalue => l_agent||'@'||l_system);
end if;
resultout := wf_engine.eng_completed;
ELSIF (funcmode = 'CANCEL') THEN
resultout := wf_engine.eng_completed;
END IF;
EXCEPTION
WHEN OTHERS THEN
WF_CORE.Context('WF_STANDARD', 'GetAckAgent',
itemtype, itemkey, actid, funcmode);
RAISE;
end GetAckAgent;
-- SubscriptionDetails
-- PL/SQL Document to display subscription
-- IN
-- document_id
-- display_type
-- document
-- document_type
procedure SubscriptionDetails (document_id
display_type
document
document_type
is
l_item_type
varchar2(10);
l_item_key
varchar2(240);
l_subscription raw(16);
l_params
varchar2(4000);
l_rule_func
varchar2(240);
l_cells
wf_notification.tdType;
l_cells2
wf_notification.tdType;
i
pls_integer;
j
pls_integer;
l_document
varchar2(32000);
l_sub_param_list wf_parameter_list_t;
l_event_t
wf_event_t;
l_result
varchar2(22000);
l_result2
varchar2(10000);
l_url
varchar2(500);
l_sub_url
varchar2(1000);
l_evt_url
varchar2(1000);
begin
parameter details
in
in
in
in
varchar2,
varchar2,
out nocopy varchar2,
out nocopy varchar2)
l_item_type := nvl(substr(document_id, 1,
instr(document_id,':')-1),'WFERROR');
l_item_key := substr(document_id, instr(document_id,':')+1);
l_event_t := wf_engine.GetItemAttrEvent(itemtype => l_item_type,
itemkey => l_item_key,
name
=> 'EVENT_MESSAGE');
l_subscription := l_event_t.GetErrorSubscription();
if (l_subscription is not null) then
SELECT
INTO
FROM
WHERE
parameters, java_rule_func
l_params, l_rule_func
wf_event_subscriptions
guid = l_subscription;
l_sub_param_list := wf_event.GetParamListFromString(l_params);
if (display_type = wf_notification.doc_html) then
i := 1;
l_cells(i) := 'S30%:'||wf_core.Translate('WF_PARAMETER');
i := i + 1;
l_cells(i) := 'S70%:'||wf_core.Translate('WF_VALUE');
else
l_result := Wf_Core.Newline||rpad(wf_core.Translate('WF_PARAMETER'), 40)
||wf_core.translate('WF_VALUE')||Wf_Core.Newline;
end if;
-- Show all Subscription Parameters that are currently used as
-- meta-data store for WS definition
if (l_sub_param_list is not null) then
j := l_sub_param_list.FIRST;
while (j is not null) loop
if (display_type = wf_notification.doc_html) then
i := i + 1;
l_cells(i) := 'S:'||l_sub_param_list(j).getName();
i := i + 1;
l_cells(i) := 'S:'||l_sub_param_list(j).getValue();
else
l_result := l_result||rpad(l_sub_param_list(j).getName(),40)||
rpad(l_sub_param_list(j).getValue(),40)||wf_core
.newline;
end if;
j := l_sub_param_list.NEXT(j);
end loop;
end if;
-- Show Invoker Rule Function since it may be a Custom one extended from
-- seeded. Also the Event Payload is WS input message
l_evt_url := wf_engine.GetItemAttrText(itemtype => l_item_type,
itemkey => l_item_key,
aname
=> 'EVENT_DATA_URL');
l_sub_url := wf_engine.GetItemAttrText(itemtype => l_item_type,
itemkey => l_item_key,
aname
=> 'EVENT_SUBSCRIPTION');
if (display_type = wf_notification.doc_html) then
i := i + 1;
l_cells(i) := 'S:'||wf_core.Translate('WF_INOKER_RULE_FUNC');
i := i + 1;
l_cells(i) := 'S:'||l_rule_func;
i := i + 1;
l_cells(i) := 'S:'||wf_core.Translate('WF_WS_INPUT_MESG');
i := i + 1;
l_url := '<a href="'||l_evt_url||'" class="xd">'||wf_core.Translate('WF_CL
ICK_HERE')||'</a>';
l_cells(i) := 'S:'||l_url;
i := i + 1;
l_cells(i) := 'S:'||wf_core.Translate('WF_SUBSCRIPTION_PAGE');
i := i + 1;
l_url := '<a href="'||l_sub_url||'" class="xd">'||wf_core.Translate('WF_CL
ICK_HERE')||'</a>';
l_cells(i) := 'S:'||l_url;
wf_notification.Ntf_Table(l_cells, 2, 'H', l_result);
-- Display title "Web Service Details"
l_result := '<table width="100%" border="0" cellspacing="1" cellpadding="
1">' ||
'<tr><td class="x3w">'||wf_core.Translate('WF_WEBSERVICE_DETAILS
')||'</td></tr>'||
'<tr><td>'||l_result||'</td></tr></table>';
else
l_result := l_result||rpad(wf_core.Translate('WF_INOKER_RULE_FUNC'),40)||
rpad(l_rule_func,40)||wf_core.newline||
rpad(wf_core.Translate('WF_WS_INPUT_MESG'),40)||
rpad(l_evt_url,40)||wf_core.newline||
rpad(wf_core.Translate('WF_SUBSCRIPTION_PAGE'),40)||
rpad(l_sub_url,40)||wf_core.newline;
end if;
end if;
document := l_result;
exception
when others then
wf_core.context('WF_STANDARD', 'SubscriptionDetails', document_id);
raise;
end SubscriptionDetails;
-- ErrorDetails
-- PL/SQL Document to display event
-- IN
-- document_id
-- display_type
-- document
-- document_type
procedure ErrorDetails (document_id
display_type
document
document_type
is
l_result
varchar2(32000);
l_error_name varchar2(240);
l_item_type varchar2(30);
l_item_key varchar2(240);
error details
in
in
in
in
varchar2,
varchar2,
out nocopy varchar2,
out nocopy varchar2)
l_error_message varchar2(2000);
l_error_stack varchar2(2000);
l_cells
wf_notification.tdType;
i
pls_integer;
begin
l_item_type := nvl(substr(document_id, 1, instr(document_id,':')-1),'WFERROR')
;
l_item_key := substr(document_id, instr(document_id,':')+1);
l_error_name := wf_engine.GetItemAttrText(itemtype => l_item_type,
itemkey => l_item_key,
aname
=> 'ERROR_NAME');
l_error_message := wf_engine.GetItemAttrText(itemtype => l_item_type,
itemkey => l_item_key,
aname
=> 'ERROR_MESSAGE');
l_error_stack := wf_engine.GetItemAttrText(itemtype => l_item_type,
itemkey => l_item_key,
aname
=> 'ERROR_STACK');
if (display_type = wf_notification.doc_html) then
document_type := wf_notification.doc_html;
i := 1;
if (l_error_name is not null) then
l_cells(i) := 'E20%:'||wf_core.Translate('WFMON_ERROR_NAME');
i := i + 1;
l_cells(i) := 'S:'||l_error_name;
i := i + 1;
end if;
l_cells(i) := 'E20%:'||wf_core.Translate('WFMON_ERROR_MESSAGE');
i := i + 1;
l_cells(i) := 'S:'||l_error_message;
i := i + 1;
l_cells(i) := 'E20%:'||wf_core.Translate('WFMON_ERROR_STACK');
i := i + 1;
l_cells(i) := 'S:'||l_error_stack;
wf_notification.NTF_Table(cells
col
type
rs
=>
=>
=>
=>
l_cells,
2,
'V',
l_result);
-- Display title
l_result := '<table width="100%" border="0" cellspacing="1" cellpadding="1"
>' ||
'<tr><td class="x3w">'||wf_core.Translate('WF_ERROR_DETAILS') ||
'</td></tr>'||'<tr><td>'||l_result||'</td></tr></table>';
else
document_type := wf_notification.doc_text;
l_result := rpad(wf_core.Translate('WFMON_ERROR_NAME'),40)||' : '||l_error_n
ame||wf_core.newline||
rpad(wf_core.Translate('WFMON_ERROR_MESSAGE'),40)||' : '||l_erro
r_message||wf_core.newline||
rpad(wf_core.Translate('WFMON_ERROR_STACK'),40)||' : '||l_error_
stack||wf_core.newline;
end if;
document := l_result;
exception
when others then
wf_core.context('WF_STANDARD', 'ErrorDetails', document_id);
raise;
end ErrorDetails;
-- SubscriptionAction
-- Returns Subscription's Action Code based on which a specific notification
-- could be sent
procedure SubscriptionAction(itemtype in varchar2,
itemkey in varchar2,
actid
in number,
funcmode in varchar2,
resultout in out nocopy varchar2)
is
l_event_t
wf_event_t;
l_subscription raw(16);
l_action_code varchar2(30);
begin
if (funcmode = 'RUN') then
l_event_t := wf_engine.GetItemAttrEvent(itemtype => itemtype,
itemkey => itemkey,
name
=> 'EVENT_MESSAGE');
l_subscription := l_event_t.GetErrorSubscription();
SELECT
INTO
FROM
WHERE
action_code
l_action_code
wf_event_subscriptions
guid = l_subscription;