DBA Data[Home] [Help]

PACKAGE BODY: APPS.WF_STANDARD

Source


1 package body WF_STANDARD as
2 /* $Header: wfstdb.pls 120.17.12020000.2 2012/11/13 19:39:29 alsosa ship $ */
3 
4 
5 
6 -------------------------------------------------------------------------------
7 ------------------------------- PRIVATE API DECLARATIONS ----------------------
8 -------------------------------------------------------------------------------
9 -- ContinueMasterFlow
10 --   Signal Master Flow to continue if all Detail flows have executed
11 --   Continuation Activity
12 -- OUT
13 --   result    - 'NULL'
14 procedure ContinueMasterFlow(   itemtype                in varchar2,
15                                 itemkey                 in varchar2,
16                                 actid                   in number,
17                                 waiting_activity        in varchar2,
18                                 resultout               in out nocopy varchar2);
19 
20 -- ContinueDetailFlow
21 --   Signal Detail Flows to continue
22 -- IN
23 --   waiting_activity - The Name of the activity that is waiting
24 -- OUT
25 --   resultout    - 'NULL'
26 procedure ContinueDetailFlow(   itemtype                in varchar2,
27                                 itemkey                 in varchar2,
28                                 actid                   in number,
29                                 waiting_activity        in varchar2,
30                                 resultout               out nocopy varchar2
31                                  );
32 
33 -- WaitForDetailFlow
34 --   Wait for all detail flows to complete continuation activity
35 -- IN
36 --   continuation_activity - The Name of the activity that in waiting
37 -- OUT
38 --   result    - 'NULL'
39 procedure WaitForDetailFlow(    itemtype                in varchar2,
40                                 itemkey                 in varchar2,
41                                 actid                   in number,
42                                 continuation_activity   in varchar2,
43                                 resultout               out nocopy varchar2);
44 
45 -- WaitForMasterFlow
46 --   Wait for Master flows to complete continuation activity
47 -- IN
48 --   itemtype  - item type
49 --   itemkey   - item key
50 --   actid     - process activity instance id
51 --   funcmode  - execution mode
52 -- OUT
53 --   result    - 'NULL'
54 procedure WaitForMasterFlow(    itemtype                in varchar2,
55                                 itemkey                 in varchar2,
56                                 actid                   in number,
57                                 continuation_activity   in varchar2,
58                                 resultout               out nocopy varchar2 );
59 
60 -------------------------------------------------------------------------------
61 ------------------------------- PUBLIC APIs -----------------------------------
62 -------------------------------------------------------------------------------
63 
64 
65 -- AbortProcess
66 --   cover to wf_engine abort process used in error process.
67 procedure AbortProcess(itemtype   in varchar2,
68                      itemkey    in varchar2,
69                      actid      in number,
70                      funcmode   in varchar2,
71                      resultout  in out nocopy varchar2) is
72 
73  l_error_itemtype varchar2(8);
74  l_error_itemkey  varchar2(240);
75 
76 begin
77   -- Do nothing in cancel or timeout mode
78   if (funcmode <> wf_engine.eng_run) then
79     resultout := wf_engine.eng_null;
80     return;
81   end if;
82 
83     --
84     -- Get the type and the key of the process that errored out
85     -- these were set in the erroring out process by Execute_Error_Process
86     --
87     l_error_itemkey := WF_ENGINE.GetItemAttrText(
88                                 itemtype        => itemtype,
89                                 itemkey         => itemkey,
90                                 aname           => 'ERROR_ITEM_KEY' );
91     l_error_itemtype := WF_ENGINE.GetItemAttrText(
92                                 itemtype        => itemtype,
93                                 itemkey         => itemkey,
94                                 aname           => 'ERROR_ITEM_TYPE' );
95 
96    -- now abort the process: dont specify the process so it defaults to the root
97    Wf_Engine.AbortProcess(itemtype => l_error_itemtype, itemkey=>l_error_itemkey);
98    resultout := wf_engine.eng_null;
99 
100 exception
101   when others then
102     Wf_Core.Context('Wf_Standard', 'AbortProcess', itemtype,
103                     itemkey, to_char(actid), funcmode);
104     raise;
105 end AbortProcess;
106 
107 -- OrJoin
108 --   Parallel Or Join.
109 --   Always returns 'NULL' result immediately, since an 'Or' succeeds
110 --   as soon as first in-transition activity completes.
111 -- OUT
112 --   result    - 'NULL'
113 procedure OrJoin(itemtype  in varchar2,
114                  itemkey   in varchar2,
115                  actid   in number,
116                  funcmode  in varchar2,
117                  resultout in out nocopy varchar2)
118 is
119 begin
120   resultout := wf_engine.eng_null;
121 exception
122   when others then
123     Wf_Core.Context('Wf_Standard', 'OrJoin', itemtype, itemkey,
124                     to_char(actid), funcmode);
125     raise;
126 end OrJoin;
127 
128 
129 -- AndJoin
130 --   Parallel And Join
131 --   Returns 'NULL' if all in-transition activities have completed.
132 --   Returns 'WAITING' if at least one in-transition activity is not
133 --   complete, or is complete with the wrong result.
134 -- OUT
135 --   result    - 'WAITING' | 'NULL'
136 procedure AndJoin(itemtype  in varchar2,
137                   itemkey   in varchar2,
138                   actid     in number,
139                   funcmode  in varchar2,
140                   resultout in out nocopy varchar2)
141 is
142     cnt pls_integer;
143 begin
144   -- Do nothing in cancel or timeout mode
145   if (funcmode <> wf_engine.eng_run) then
146     resultout := wf_engine.eng_null;
147     return;
148   end if;
149 
150   -- SYNCHMODE: Not allowed
151   if (itemkey = wf_engine.eng_synch) then
152     Wf_Core.Token('OPERATION', 'Wf_Standard.AndJoin');
153     Wf_Core.Raise('WFENG_SYNCH_DISABLED');
154   end if;
155 
156   -- The And fails if there is at least one in-transition which is either
157   -- incomplete or complete with the wrong result.
158   SELECT count(1)
159   into cnt
160   FROM WF_ACTIVITY_TRANSITIONS WAT
161   WHERE WAT.TO_PROCESS_ACTIVITY = actid
162   AND NOT EXISTS
163     (SELECT NULL
164      FROM WF_ITEM_ACTIVITY_STATUSES WIAS
165      WHERE WIAS.PROCESS_ACTIVITY = WAT.FROM_PROCESS_ACTIVITY
166      AND WIAS.ITEM_TYPE = itemtype
167      AND WIAS.ITEM_KEY = itemkey
168      AND WIAS.ACTIVITY_STATUS = 'COMPLETE'
169      AND (WAT.RESULT_CODE in (WIAS.ACTIVITY_RESULT_CODE,
170                               wf_engine.eng_trans_any)
171           OR (WAT.RESULT_CODE = wf_engine.eng_trans_default
172               AND NOT EXISTS
173                   (SELECT NULL
174                    FROM WF_ACTIVITY_TRANSITIONS WAT2
175                    WHERE WAT2.FROM_PROCESS_ACTIVITY =
176                          WAT.FROM_PROCESS_ACTIVITY
177                    AND WAT2.RESULT_CODE = WIAS.ACTIVITY_RESULT_CODE)
178              )
179          )
180     );
181 
182   if (cnt > 0) then
183     -- This means there is at least one in-transition either incomplete
184     -- or complete with the wrong result.
185     -- The LogicalAnd fails, return a result of 'WAITING'.
186     resultout := wf_engine.eng_waiting;
187   else
188     -- This means there are no in-transition activities that are either
189     -- incomplete or complete with the wrong result.
190     -- The LogicalAnd succeeds, return a result of 'NULL' to continue.
191     resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
192   end if;
193   return;
194 exception
195   when others then
196     Wf_Core.Context('Wf_Standard', 'AndJoin', itemtype,
197                     itemkey, to_char(actid), funcmode);
198     raise;
199 end AndJoin;
200 
201 
202 -- Assign
203 --   Assign a value to an item attribute
204 -- OUT
205 --   result - null
206 -- ACTIVITY ATTRIBUTES REFERENCED
207 --   ATTR         - Item attribute
208 --   DATE_VALUE   - date value
209 --   NUMBER_VALUE - number value
210 --   TEXT_VALUE   - text value
211 procedure Assign(itemtype  in varchar2,
212                   itemkey   in varchar2,
213                   actid     in number,
214                   funcmode  in varchar2,
215                   resultout in out nocopy varchar2)
216 is
217   atype    varchar2(8);
218   asubtype varchar2(8);
219   aformat  varchar2(240);
220   aname    varchar2(30);
221 begin
222   -- Do nothing in cancel or timeout mode
223   if (funcmode <> wf_engine.eng_run) then
224     resultout := wf_engine.eng_null;
225     return;
226   end if;
227 
228   -- Get attribute info
229   aname := wf_engine.GetActivityAttrText(itemtype, itemkey, actid, 'ATTR');
230   wf_engine.GetItemAttrInfo(itemtype, aname, atype, asubtype, aformat);
231 
232   -- NUMBER value
233   if (atype = 'NUMBER') then
234     wf_engine.SetItemAttrNumber(itemtype,itemkey,aname,
235       wf_engine.GetActivityAttrNumber(itemtype,itemkey,actid, 'NUMBER_VALUE'));
236 
237   -- DATE value
238   elsif (atype = 'DATE') then
239     wf_engine.SetItemAttrDate(itemtype,itemkey,aname,
240       wf_engine.GetActivityAttrDate(itemtype,itemkey,actid, 'DATE_VALUE'));
241 
242   -- TEXT value (VARCHAR2, LOOKUP, FORM, URL, DOCUMENT, etc)
243   else
244     wf_engine.SetItemAttrText(itemtype,itemkey,aname,
245       wf_engine.GetActivityAttrText(itemtype,itemkey,actid, 'TEXT_VALUE'));
246   end if;
247 
248   resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
249 exception
250   when others then
251     Wf_Core.Context('Wf_Standard', 'Assign', itemtype,
252                     itemkey, to_char(actid), funcmode);
253     raise;
254 end Assign;
255 
256 
257 -- GetURL
258 --   Get monitor URL, store in item attribute
259 -- OUT
260 --   result    - 'NULL'
261 -- ACTIVITY ATTRIBUTES REFERENCED
262 --   ATTR         - Item attribute to set
263 --   ADMIN_MODE   - administration mode (Y / N)
264 procedure GetURL(itemtype  in varchar2,
265                  itemkey   in varchar2,
266                  actid     in number,
267                  funcmode  in varchar2,
268                  resultout in out nocopy varchar2)
269 is
270   aname    varchar2(30);
271   admin    varchar2(8);
272 begin
273   -- Do nothing in cancel or timeout mode
274   if (funcmode <> wf_engine.eng_run) then
275     resultout := wf_engine.eng_null;
276     return;
277   end if;
278 
279   -- SYNCHMODE: Not allowed
280   if (itemkey = wf_engine.eng_synch) then
281     Wf_Core.Token('OPERATION', 'Wf_Standard.GetUrl');
282     Wf_Core.Raise('WFENG_SYNCH_DISABLED');
283   end if;
284 
285   -- Get item attribute name
286   aname := wf_engine.GetActivityAttrText(itemtype,itemkey,actid, 'ATTR');
287 
288   -- Get admin mode
289   admin := wf_engine.GetActivityAttrText(itemtype,itemkey,actid, 'ADMIN_MODE');
290 
291   -- Set item attribute
292   wf_engine.SetItemAttrText(itemtype, itemkey, aname,
293     wf_monitor.geturl(
294       wf_core.translate('WF_WEB_AGENT'), itemtype, itemkey, admin));
295 
296   resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
297 exception
298   when others then
299     Wf_Core.Context('Wf_Standard', 'GetUrl', itemtype,
300                     itemkey, to_char(actid), funcmode);
301     raise;
302 end GetURL;
303 
304 
305 -- Compare
306 --   Standard Compare function.
307 -- OUT
308 --   comparison value (LT, EQ, GT, NULL)
309 -- ACTIVITY ATTRIBUTES REFERENCED
310 --   VALUE1 - Test value
311 --   VALUE2 - Reference value
312 procedure Compare(itemtype  in varchar2,
313                   itemkey   in varchar2,
314                   actid     in number,
315                   funcmode  in varchar2,
316                   resultout in out nocopy varchar2)
317 is
318   atype    varchar2(8);
319   asubtype varchar2(8);
320   aformat  varchar2(240);
321   aname    varchar2(30);
322   nval1    number;
323   nval2    number;
324   dval1    date;
325   dval2    date;
326   tval1    varchar2(4000);
327   tval2    varchar2(4000);
328 begin
329   -- Do nothing in cancel or timeout mode
330   if (funcmode <> wf_engine.eng_run) then
331     resultout := wf_engine.eng_null;
332     return;
333   end if;
334 
335   -- Get comparison data type
336   Wf_Engine.GetActivityAttrInfo(itemtype, itemkey, actid, 'VALUE1',
337                                 atype, asubtype, aformat);
338 
339   tval1 := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'VALUE1');
340 
341 
342   --
343   -- NUMBER value
344   --
345   if (atype = 'NUMBER') then
346     -- Get the two number values
347     nval1 := Wf_Engine.GetActivityAttrNumber(itemtype,itemkey,actid, 'VALUE1');
348     nval2 := Wf_Engine.GetActivityAttrNumber(itemtype,itemkey,actid, 'VALUE2');
349 
350     -- Compare
351     if (nval1 is null or nval2 is null) then
352       resultout := wf_engine.eng_completed||':NULL';
353     elsif (nval1 < nval2) then
354       resultout := wf_engine.eng_completed||':LT';
355     elsif (nval1 > nval2) then
356       resultout := wf_engine.eng_completed||':GT';
357     elsif (nval1 = nval2) then
358       resultout := wf_engine.eng_completed||':EQ';
359     end if;
360 
361   --
362   -- DATE value
363   --
364   elsif (atype = 'DATE') then
365     -- Get the two date values
366     dval1 := Wf_Engine.GetActivityAttrDate(itemtype,itemkey,actid, 'VALUE1');
367     dval2 := Wf_Engine.GetActivityAttrDate(itemtype,itemkey,actid, 'VALUE2');
368 
369     -- Compare
370     if (dval1 is null or dval2 is null) then
371       resultout := wf_engine.eng_completed||':NULL';
372     elsif (dval1 < dval2) then
373       resultout := wf_engine.eng_completed||':LT';
374     elsif (dval1 > dval2) then
375       resultout := wf_engine.eng_completed||':GT';
376     elsif (dval1 = dval2) then
377       resultout := wf_engine.eng_completed||':EQ';
378     end if;
379 
380   --
381   -- TEXT value (VARCHAR2, LOOKUP, FORM, URL, DOCUMENT, etc)
382   --
383   else
384     -- Get the two text values
385     tval1 := Wf_Engine.GetActivityAttrText(itemtype,itemkey,actid, 'VALUE1');
386     tval2 := Wf_Engine.GetActivityAttrText(itemtype,itemkey,actid, 'VALUE2');
387 
388     -- Compare
389     if (tval1 is null or tval2 is null) then
390       resultout := wf_engine.eng_completed||':NULL';
391     elsif (tval1 < tval2) then
392       resultout := wf_engine.eng_completed||':LT';
393     elsif (tval1 > tval2) then
394       resultout := wf_engine.eng_completed||':GT';
395     elsif (tval1 = tval2) then
396       resultout := wf_engine.eng_completed||':EQ';
397     end if;
398   end if;
399 
400 exception
401   when others then
402     Wf_Core.Context('Wf_Standard', 'Compare', itemtype,
403                     itemkey, to_char(actid), funcmode);
404     raise;
405 end Compare;
406 
407 
408 -- CompareExecutionTime
409 --   Compare Execution Time function.
410 -- OUT
411 --   comparison value (LT, EQ, GT, NULL)
412 -- ACTIVITY ATTRIBUTES REFERENCED
413 --   EXECUTIONTIME - Execution time Test value in seconds
414 --   PARENTTYPE    - Either ROOT or SUBPROCESS
415 procedure CompareExecutionTime(itemtype  in varchar2,
416                   itemkey   in varchar2,
417                   actid     in number,
418                   funcmode  in varchar2,
419                   resultout in out nocopy varchar2)
420 is
421   etime     number;
422   delta     number;
423   processid number;
424   ptype     varchar2(30);
425 
426   cursor GetRunningTime (itemtype in varchar2,
427                          itemkey in varchar2, actid in number) is
428   select (sysdate - nvl(begin_date,sysdate))*86400
429   from   wf_item_activity_statuses
430   where  item_type = itemtype
431   and    item_key = itemkey
432   and    process_activity = actid;
433 
434   cursor GetExecutionTime (itemtype in varchar2,
435                          itemkey in varchar2) is
436   select (sysdate - begin_date)*86400
437   from   wf_items
438   where  item_type = itemtype
439   and    item_key = itemkey;
440 
441 begin
442   -- Do nothing in cancel or timeout mode
443   if (funcmode <> wf_engine.eng_run) then
444     resultout := wf_engine.eng_null;
445     return;
446   end if;
447 
448   Ptype := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'PARENTTYPE');
449 
450   if Ptype = 'ROOT' then
451      -- calculate the execution time
452      open  GetExecutionTime(itemtype, itemkey);
453      fetch GetExecutionTime into delta;
454      close GetExecutionTime;
455   else
456      processid := WF_ENGINE_UTIL.activity_parent_process(itemtype, itemkey, actid);
457 
458      -- calculate the execution time
459      open  GetRunningTime(itemtype, itemkey, processid);
460      fetch GetRunningTime into delta;
461      close GetRunningTime;
462   end if;
463 
464   -- look up the test value for execution time
465   Etime := Wf_Engine.GetActivityAttrNumber(itemtype, itemkey, actid, 'EXECUTIONTIME');
466 
467   -- execute comparison
468   if (delta is null or etime is null) then
469     resultout := wf_engine.eng_completed||':NULL';
470   elsif (delta < etime) then
471     resultout := wf_engine.eng_completed||':LT';
472   elsif (delta > etime) then
473     resultout := wf_engine.eng_completed||':GT';
474   elsif (delta = etime) then
475     resultout := wf_engine.eng_completed||':EQ';
476   end if;
477 
478 exception
479   when others then
480     Wf_Core.Context('Wf_Standard', 'CompareExecutionTime', itemtype,
481                     itemkey, to_char(actid), funcmode);
482     raise;
483 end CompareExecutionTime;
484 
485 
486 -- CompareEventProperty
487 --  Compare a property on an event
488 -- IN
489 --   itemtype  - item type
490 --   itemkey   - item key
491 --   actid     - process activity instance id
492 --   funcmode  - execution mode
493 -- OUT
494 --   comparison result (WFSTD_COMPARISON lookup code)
495 --   GT LT EQ NULL
496 -- ACTIVITY ATTRIBUTES REFERENCED
497 --   EVENT - Event whose property is to be compared
498 --   PROPERTY - Event Property Reference (Based on the lookup of EVENTPROPERTY
499 --   PARAMETER - Parameter Name if Lookup type = Parameter
500 --   VALUE - Constant value of correct type
501 procedure CompareEventProperty(itemtype  in varchar2,
502                   itemkey   in varchar2,
503                   actid     in number,
504                   funcmode  in varchar2,
505                   resultout in out nocopy varchar2)
506 is
507   lEvent WF_EVENT_T;
508   lAgent WF_AGENT_T;
509   lNVal NUMBER;
510   lDVal DATE;
511   lTVal VARCHAR2 (4000);
512   lProperty VARCHAR2 (20);
513   lParameter VARCHAR2(200);
514   lType VARCHAR2 (20);
515   lSubType VARCHAR2 (20);
516   lFormat VARCHAR2 (20);
517 
518 begin
519    lEvent := wf_engine.getActivityAttrEvent(itemtype, itemkey,
520                                             actid, 'EVENT');
521    lProperty := wf_engine.getActivityAttrText(itemtype, itemkey,
522                                               actid, 'PROPERTY');
523 
524    if (lProperty = 'PRIORITY') then
525       lNVal := wf_engine.getActivityAttrNumber(itemtype, itemkey,
526                                                   actid, 'NUMBER_VALUE');
527       if (lEvent.priority is NULL or lNVal is NULL) then
528          resultout := wf_engine.eng_completed||':NULL';
529       elsif (lEvent.priority < lNVal) then
530          resultout := wf_engine.eng_completed||':LT';
531       elsif (lEvent.priority > lNVal) then
532          resultout := wf_engine.eng_completed||':GT';
533       elsif (lEvent.priority = lNVal) then
534          resultout := wf_engine.eng_completed||':EQ';
535       end if;
536 
537    elsif (lProperty = 'SEND_DATE') then
538       lDVal := wf_engine.getActivityAttrDate(itemtype, itemkey,
539                                                   actid, 'DATE_VALUE');
540       if (lEvent.send_date is NULL or lDVal is null) then
541          resultout := wf_engine.eng_completed||':NULL';
542       elsif (lEvent.send_date < lDVal) then
543          resultout := wf_engine.eng_completed||':LT';
544       elsif (lEvent.send_date > lDVal) then
545          resultout := wf_engine.eng_completed||':GT';
546       elsif (lEvent.send_date = lDVal) then
547          resultout := wf_engine.eng_completed||':EQ';
548       end if;
549    elsif (lProperty = 'RECEIVE_DATE') then
550       lDVal := wf_engine.getActivityAttrDate(itemtype, itemkey,
551                                                   actid, 'DATE_VALUE');
552       if (lEvent.receive_date is NULL or lDVal is null) then
553          resultout := wf_engine.eng_completed||':NULL';
554       elsif (lEvent.receive_date < lDVal) then
555          resultout := wf_engine.eng_completed||':LT';
556       elsif (lEvent.receive_date > lDVal) then
557          resultout := wf_engine.eng_completed||':GT';
558       elsif (lEvent.receive_date = lDVal) then
559          resultout := wf_engine.eng_completed||':EQ';
560       end if;
561    elsif (lProperty = 'CORRELATION_ID') then
562       lTVal := wf_engine.getActivityAttrText(itemtype, itemkey,
563                                             actid, 'TEXT_VALUE');
564       if (LEvent.correlation_id is NULL or lTVal is NULL) then
565          resultout := wf_engine.eng_completed||':NULL';
566       elsif (LEvent.correlation_id < lTVal) then
567          resultout := wf_engine.eng_completed||':LT';
568       elsif (LEvent.correlation_id > lTVal) then
569          resultout := wf_engine.eng_completed||':GT';
570       elsif (LEvent.correlation_id = lTVal) then
571          resultout := wf_engine.eng_completed||':EQ';
572       end if;
573    elsif (lProperty = 'EVENT_NAME') then
574       lTVal := wf_engine.getActivityAttrText(itemtype, itemkey,
575                                             actid, 'TEXT_VALUE');
576       if (LEvent.event_name is NULL or lTVal is NULL) then
577          resultout := wf_engine.eng_completed||':NULL';
578       elsif (LEvent.event_name < lTVal) then
579          resultout := wf_engine.eng_completed||':LT';
580       elsif (LEvent.event_name > lTVal) then
581          resultout := wf_engine.eng_completed||':GT';
582       elsif (LEvent.event_name = lTVal) then
583          resultout := wf_engine.eng_completed||':EQ';
584       end if;
585    elsif (lProperty = 'EVENT_KEY') then
586       lTVal := wf_engine.getActivityAttrText(itemtype, itemkey,
587                                             actid, 'TEXT_VALUE');
588       if (LEvent.event_key is NULL or lTVal is NULL) then
589          resultout := wf_engine.eng_completed||':NULL';
590       elsif (LEvent.event_key < lTVal) then
591          resultout := wf_engine.eng_completed||':LT';
592       elsif (LEvent.event_key > lTVal) then
593          resultout := wf_engine.eng_completed||':GT';
594       elsif (LEvent.event_key = lTVal) then
595          resultout := wf_engine.eng_completed||':EQ';
596       end if;
597    elsif (lProperty = 'FROM_AGENT_NAME') then
598       lTVal := wf_engine.getActivityAttrText(itemtype, itemkey,
599                                             actid, 'TEXT_VALUE');
600       if (LEvent.From_Agent.Name is NULL or lTVal is NULL) then
601          resultout := wf_engine.eng_completed||':NULL';
602       elsif (LEvent.From_Agent.Name < lTVal) then
603          resultout := wf_engine.eng_completed||':LT';
604       elsif (LEvent.From_Agent.Name > lTVal) then
605          resultout := wf_engine.eng_completed||':GT';
606       elsif (LEvent.From_Agent.Name = lTVal) then
607          resultout := wf_engine.eng_completed||':EQ';
608       end if;
609    elsif (lProperty = 'FROM_AGENT_SYSTEM') then
610       lTVal := wf_engine.getActivityAttrText(itemtype, itemkey,
611                                             actid, 'TEXT_VALUE');
612       if (LEvent.From_Agent.System is NULL or lTVal is NULL) then
613          resultout := wf_engine.eng_completed||':NULL';
614       elsif (LEvent.From_Agent.System < lTVal) then
615          resultout := wf_engine.eng_completed||':LT';
616       elsif (LEvent.From_Agent.System > lTVal) then
617          resultout := wf_engine.eng_completed||':GT';
618       elsif (LEvent.From_Agent.System = lTVal) then
619          resultout := wf_engine.eng_completed||':EQ';
620       end if;
621    elsif (lProperty = 'TO_AGENT_NAME') then
622       lTVal := wf_engine.getActivityAttrText(itemtype, itemkey,
623                                             actid, 'TEXT_VALUE');
624       if (LEvent.To_Agent.Name is NULL or lTVal is NULL) then
625          resultout := wf_engine.eng_completed||':NULL';
626       elsif (LEvent.To_Agent.Name < lTVal) then
627          resultout := wf_engine.eng_completed||':LT';
628       elsif (LEvent.To_Agent.Name > lTVal) then
629          resultout := wf_engine.eng_completed||':GT';
630       elsif (LEvent.To_Agent.Name = lTVal) then
631          resultout := wf_engine.eng_completed||':EQ';
632       end if;
633    elsif (lProperty = 'TO_AGENT_SYSTEM') then
634       lTVal := wf_engine.getActivityAttrText(itemtype, itemkey,
635                                             actid, 'TEXT_VALUE');
636       if (LEvent.To_Agent.System is NULL or lTVal is NULL) then
637          resultout := wf_engine.eng_completed||':NULL';
638       elsif (LEvent.To_Agent.System < lTVal) then
639          resultout := wf_engine.eng_completed||':LT';
640       elsif (LEvent.To_Agent.System > lTVal) then
641          resultout := wf_engine.eng_completed||':GT';
642       elsif (LEvent.To_Agent.System = lTVal) then
643          resultout := wf_engine.eng_completed||':EQ';
644       end if;
645    elsif (lProperty = 'FROM_AGENT') then
646       lTVal := wf_engine.getActivityAttrText(itemtype, itemkey,
647                                             actid, 'TEXT_VALUE');
648       if (LEvent.From_Agent.Name is NULL
649 	  or LEvent.From_Agent.System is NULL or lTVal is NULL) then
650          resultout := wf_engine.eng_completed||':NULL';
651       elsif (LEvent.From_Agent.Name||'@'||LEvent.From_Agent.System < lTVal) then
652          resultout := wf_engine.eng_completed||':LT';
653       elsif (LEvent.From_Agent.Name||'@'||LEvent.From_Agent.System > lTVal) then
654          resultout := wf_engine.eng_completed||':GT';
655       elsif (LEvent.From_Agent.Name||'@'||LEvent.From_Agent.System = lTVal) then
656          resultout := wf_engine.eng_completed||':EQ';
657       end if;
658    elsif (lProperty = 'TO_AGENT') then
659       lTVal := wf_engine.getActivityAttrText(itemtype, itemkey,
660                                             actid, 'TEXT_VALUE');
661       if (LEvent.To_Agent.Name is NULL
662           or LEvent.To_Agent.System is NULL or lTVal is NULL) then
663          resultout := wf_engine.eng_completed||':NULL';
664       elsif (LEvent.To_Agent.Name||'@'||LEvent.To_Agent.System < lTVal) then
665          resultout := wf_engine.eng_completed||':LT';
666       elsif (LEvent.To_Agent.Name||'@'||LEvent.To_Agent.System > lTVal) then
667          resultout := wf_engine.eng_completed||':GT';
668       elsif (LEvent.To_Agent.Name||'@'||LEvent.To_Agent.System = lTVal) then
669          resultout := wf_engine.eng_completed||':EQ';
670       end if;
671    elsif (lProperty = 'PARAMETER') then
672       lTVal := wf_engine.getActivityAttrText(itemtype, itemkey,
673                                             actid, 'TEXT_VALUE');
674       lParameter := wf_engine.getActivityAttrText(itemtype => itemtype,
675                                                  itemkey => itemkey,
676                                                  actid => actid,
677                                                  aname => 'PARAMETER');
678       if (LEvent.GetValueForParameter(lParameter)) is NULL then
679          resultout := wf_engine.eng_completed||':NULL';
680       elsif (LEvent.GetValueForParameter(lParameter) < lTVal) then
681          resultout := wf_engine.eng_completed||':LT';
682       elsif (LEvent.GetValueForParameter(lParameter) > lTVal) then
683          resultout := wf_engine.eng_completed||':GT';
684       elsif (LEvent.GetValueForParameter(lParameter) = lTVal) then
685          resultout := wf_engine.eng_completed||':EQ';
686       end if;
687    else
688       -- Unhandled property. Return NULL
689       resultout := wf_engine.eng_completed||':NULL';
690    end if;
691 
692 exception
693   when others then
694     Wf_Core.Context('Wf_Standard', 'CompareEventProperty', itemtype,
695                     itemkey, to_char(actid), funcmode);
696     raise;
697 end CompareEventProperty;
698 
699 --  SetEventProperty
700 --  Set the property in an Event to a given value
701 -- IN
702 --   itemtype  - item type
703 --   itemkey   - item key
704 --   actid     - process activity instance id
705 --   funcmode  - execution mode
706 -- OUT
707 --   NONE
708 -- ACTIVITY ATTRIBUTES REFERENCED
709 --   EVENT - Event whose property is to be compared
710 --   PROPERTY - Event Property Reference (Based on the lookup of EVENTPROPERTY
711 --   PARAMETER - Parameter name
712 --   VALUE - Constant value of correct type
713 procedure SetEventProperty(itemtype  in varchar2,
714                            itemkey   in varchar2,
715                            actid     in number,
716                            funcmode  in varchar2,
717                            resultout in out nocopy varchar2)
718 is
719   lEvent WF_EVENT_T;
720   lNVal NUMBER;
721   lDVal DATE;
722   lTVal VARCHAR2 (4000);
723   lAName VARCHAR2(30);
724   lProperty VARCHAR2 (20);
725   lParameter VARCHAR2(200);
726   lType VARCHAR2 (20);
727   lSubType VARCHAR2 (20);
728   lFormat VARCHAR2 (20);
729   lRefFlag VARCHAR2(8);
730   lAtSign PLS_INTEGER;
731   lFromAgent WF_AGENT_T := WF_AGENT_T(NULL, NULL);
732   lToAgent WF_AGENT_T := WF_AGENT_T(NULL, NULL);
733 
734 begin
735    if (funcmode = 'RUN') then
736 
737       -- First get the name of the Item Attribute that EVENT points to
738       select WAAV.VALUE_TYPE, substrb(WAAV.TEXT_VALUE, 1, 30)
739       into LRefflag, LAName
740       from WF_ACTIVITY_ATTR_VALUES WAAV
741       where WAAV.PROCESS_ACTIVITY_ID = actid
742       and WAAV.NAME = 'EVENT';
743 
744      /* Should be able to use the GetActivityAttrEvent to do this
745      lEvent := wf_engine.getItemAttrEvent(itemtype => itemtype,
746                                            itemkey => itemkey,
747                                            name => LAName);
748      */
749 
750 
751       lEvent := wf_engine.getActivityAttrEvent(itemtype, itemkey,
752                                             actid, 'EVENT');
753 
754       lProperty := wf_engine.getActivityAttrText(itemtype => itemtype,
755                                                  itemkey => itemkey,
756                                                  actid => actid,
757                                                  aname => 'PROPERTY');
758       if (lProperty = 'PRIORITY') then
759          lNVal := wf_engine.getActivityAttrNumber(itemtype => itemtype,
760                                                   itemkey => itemkey,
761                                                   actid => actid,
762                                                   aname => 'NUMBER_VALUE');
763          lEvent.setPriority(lNVal);
764       elsif (lProperty = 'SEND_DATE') then
765          lDVal := wf_engine.getActivityAttrDate(itemtype => itemtype,
766                                                 itemkey => itemkey,
767                                                 actid =>  actid,
768                                                 aname => 'DATE_VALUE');
769          lEvent.setSendDate(lDVal);
770       elsif (lProperty = 'RECEIVE_DATE') then
771          lDVal := wf_engine.getActivityAttrDate(itemtype => itemtype,
772                                                 itemkey => itemkey,
773                                                 actid => actid,
774                                                 aname => 'DATE_VALUE');
775          lEvent.setReceiveDate(lDVal);
776       elsif (lProperty = 'CORRELATION_ID') then
777          lTVal := wf_engine.getActivityAttrText(itemtype => itemtype,
778                                                 itemkey => itemkey,
779                                                 actid => actid,
780                                                 aname => 'TEXT_VALUE');
781          lEvent.setCorrelationID(lTVal);
782       elsif (lProperty = 'EVENT_NAME') then
783          lTVal := wf_engine.getActivityAttrText(itemtype => itemtype,
784                                                 itemkey => itemkey,
785                                                 actid => actid,
786                                                 aname => 'TEXT_VALUE');
787          lEvent.setEventName(lTVal);
788       elsif (lProperty = 'EVENT_KEY') then
789          lTVal := wf_engine.getActivityAttrText(itemtype => itemtype,
790                                                 itemkey => itemkey,
791                                                 actid => actid,
792                                                 aname => 'TEXT_VALUE');
793          lEvent.setEventKey(lTVal);
794       elsif (lProperty = 'FROM_AGENT_NAME') then
795          lTVal := wf_engine.getActivityAttrText(itemtype => itemtype,
796                                                 itemkey => itemkey,
797                                                 actid => actid,
798                                                 aname => 'TEXT_VALUE');
799          if lEvent.GetFromAgent() is not null then
800            lFromAgent := lEvent.GetFromAgent();
801          end if;
802          lFromAgent.SetName(lTVal);
803          lEvent.SetFromAgent(lFromAgent);
804       elsif (lProperty = 'FROM_AGENT_SYSTEM') then
805          lTVal := wf_engine.getActivityAttrText(itemtype => itemtype,
806                                                 itemkey => itemkey,
807                                                 actid => actid,
808                                                 aname => 'TEXT_VALUE');
809          if lEvent.GetFromAgent() is not null then
810            lFromAgent := lEvent.GetFromAgent();
811          end if;
812          lFromAgent.SetSystem(lTVal);
813          lEvent.SetFromAgent(lFromAgent);
814       elsif (lProperty = 'TO_AGENT_NAME') then
815          lTVal := wf_engine.getActivityAttrText(itemtype => itemtype,
816                                                 itemkey => itemkey,
817                                                 actid => actid,
818                                                 aname => 'TEXT_VALUE');
819          if lEvent.GetToAgent() is not null then
820            lToAgent := lEvent.GetToAgent();
821          end if;
822          lToAgent.SetName(lTVal);
823          lEvent.SetToAgent(lToAgent);
824       elsif (lProperty = 'TO_AGENT_SYSTEM') then
825          lTVal := wf_engine.getActivityAttrText(itemtype => itemtype,
826                                                 itemkey => itemkey,
827                                                 actid => actid,
828                                                 aname => 'TEXT_VALUE');
829          if lEvent.GetToAgent() is not null then
830            lToAgent := lEvent.GetToAgent();
831          end if;
832          lToAgent.SetSystem(lTVal);
833          lEvent.SetToAgent(lToAgent);
834       elsif (lProperty = 'FROM_AGENT') then
835          lTVal := wf_engine.getActivityAttrText(itemtype => itemtype,
836                                                 itemkey => itemkey,
837                                                 actid => actid,
838                                                 aname => 'TEXT_VALUE');
839          lAtSign := instr(lTVal, '@');
840          lFromAgent.SetName(substr(lTVal, 1, lAtSign-1));
841          lFromAgent.SetSystem(substr(lTVal, lAtSign+1));
842          lEvent.SetFromAgent(lFromAgent);
843       elsif (lProperty = 'TO_AGENT') then
844          lTVal := wf_engine.getActivityAttrText(itemtype => itemtype,
845                                                 itemkey => itemkey,
846                                                 actid => actid,
847                                                 aname => 'TEXT_VALUE');
848          lAtSign := instr(lTVal, '@');
849          lToAgent.SetName(substr(lTVal, 1, lAtSign-1));
850          lToAgent.SetSystem(substr(lTVal, lAtSign+1));
851          lEvent.SetToAgent(lToAgent);
852       elsif (lProperty = 'PARAMETER') then
853          lTVal := wf_engine.getActivityAttrText(itemtype => itemtype,
854                                                 itemkey => itemkey,
855                                                 actid => actid,
856                                                 aname => 'TEXT_VALUE');
857          lParameter := wf_engine.getActivityAttrText(itemtype => itemtype,
858                                                  itemkey => itemkey,
859                                                  actid => actid,
860                                                  aname => 'PARAMETER');
861          lEvent.AddParameterToList(lParameter, lTVal);
862       end if;
863 
864       wf_engine.setItemAttrEvent(itemtype => itemtype,
865                                  itemkey => itemkey,
866                                  name => lAName,
867                                  event => lEvent);
868       resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
869    end if; -- RUN
870 
871 exception
872   when others then
873     Wf_Core.Context('Wf_Standard', 'SetEventProperty', itemtype,
874                     itemkey, to_char(actid), funcmode);
875     raise;
876 end SetEventProperty;
877 
878 
879 --  GetEventProperty
880 --  Get a property of an Event and assign it to an Item Attribute
881 -- IN
882 --   itemtype  - item type
883 --   itemkey   - item key
884 --   actid     - process activity instance id
885 --   funcmode  - execution mode
886 -- OUT
887 --   NONE
888 -- ACTIVITY ATTRIBUTES REFERENCED
889 --   EVENT - Event whose property is to be compared
890 --   PROPERTY - Event Property Reference (Based on the lookup of EVENTPROPERTY
891 --   PARAMETER - Event Parameter Name
892 --   VALUE - Constant value of correct type
893 procedure GetEventProperty(itemtype  in varchar2,
894                            itemkey   in varchar2,
895                            actid     in number,
896                            funcmode  in varchar2,
897                            resultout in out nocopy varchar2)
898 is
899   lEvent WF_EVENT_T;
900   lNVal NUMBER;
901   lDVal DATE;
902   lTVal VARCHAR2 (4000);
903   lAName VARCHAR2(30);
904   lProperty VARCHAR2 (20);
905   lParameter VARCHAR2(200);
906   lType VARCHAR2 (20);
907   lSubType VARCHAR2 (20);
908   lFormat VARCHAR2 (20);
909   lRefFlag VARCHAR2(8);
910 
911 begin
912    if (funcmode = 'RUN') then
913 
914 
915       lEvent := wf_engine.getActivityAttrEvent(itemtype => itemtype,
916                                                itemkey => itemkey,
917                                                actid => actid,
918                                                name => 'EVENT');
919 
920       lProperty := wf_engine.getActivityAttrText(itemtype => itemtype,
921                                                  itemkey => itemkey,
922                                                  actid => actid,
923                                                  aname => 'PROPERTY');
924 
925 
926       lAName := wf_engine.getActivityAttrText(itemtype => itemtype,
927                                               itemkey => itemkey,
928                                               actid => actid,
929                                               aname => 'ATTR');
930       if (lProperty = 'PRIORITY') then
931          wf_engine.SetItemAttrNumber(itemtype => itemtype,
932                                      itemkey => itemkey,
933                                      aname => LAName,
934                                      avalue => lEvent.getPriority());
935          lEvent.setPriority(lNVal);
936       elsif (lProperty = 'SEND_DATE') then
937          wf_engine.SetItemAttrDate(itemtype => itemtype,
938                                    itemkey => itemkey,
939                                    aname => LAName,
940                                    avalue => lEvent.getSendDate());
941       elsif (lProperty = 'RECEIVE_DATE') then
942          wf_engine.SetItemAttrDate(itemtype => itemtype,
943                                    itemkey => itemkey,
944                                    aname => LAName,
945                                    avalue => lEvent.getReceiveDate());
946       elsif (lProperty = 'CORRELATION_ID') then
947          wf_engine.SetItemAttrText(itemtype => itemtype,
948                                    itemkey => itemkey,
949                                    aname => LAName,
950                                    avalue => lEvent.getCorrelationID());
951       elsif (lProperty = 'EVENT_NAME') then
952          wf_engine.SetItemAttrText(itemtype => itemtype,
953                                    itemkey => itemkey,
954                                    aname => LAName,
955                                    avalue => lEvent.getEventName());
956       elsif (lProperty = 'EVENT_KEY') then
957          wf_engine.SetItemAttrText(itemtype => itemtype,
958                                    itemkey => itemkey,
959                                    aname => LAName,
960                                    avalue => lEvent.getEventKey());
961       elsif (lProperty = 'FROM_AGENT_NAME') then
962          wf_engine.SetItemAttrText(itemtype => itemtype,
963                                    itemkey => itemkey,
964                                    aname => LAName,
965                                    avalue => lEvent.getFromAgent().getName());
966       elsif (lProperty = 'FROM_AGENT_SYSTEM') then
967          wf_engine.SetItemAttrText(itemtype => itemtype,
968                                    itemkey => itemkey,
969                                    aname => LAName,
970                                    avalue => lEvent.getFromAgent().getSystem());
971       elsif (lProperty = 'TO_AGENT_NAME') then
972          wf_engine.SetItemAttrText(itemtype => itemtype,
973                                    itemkey => itemkey,
974                                    aname => LAName,
975                                    avalue => lEvent.getToAgent().getName());
976       elsif (lProperty = 'TO_AGENT_SYSTEM') then
977          wf_engine.SetItemAttrText(itemtype => itemtype,
978                                    itemkey => itemkey,
979                                    aname => LAName,
980                                    avalue => lEvent.getToAgent().getSystem());
981       elsif (lProperty = 'FROM_AGENT') then
982          wf_engine.SetItemAttrText(itemtype => itemtype,
983                                    itemkey => itemkey,
984                                    aname => LAName,
985                                    avalue =>
986 					lEvent.getFromAgent().getName()||
987 					'@'||lEvent.getFromAgent().getSystem());
988       elsif (lProperty = 'TO_AGENT') then
989          wf_engine.SetItemAttrText(itemtype => itemtype,
990                                    itemkey => itemkey,
991                                    aname => LAName,
992                                    avalue =>
993                                         lEvent.getToAgent().getName()||
994                                         '@'||lEvent.getToAgent().getSystem());
995       elsif (lProperty = 'PARAMETER') then
996          lParameter := wf_engine.getActivityAttrText(itemtype => itemtype,
997                                                  itemkey => itemkey,
998                                                  actid => actid,
999                                                  aname => 'PARAMETER');
1000 
1001          wf_engine.SetItemAttrText(itemtype => itemtype,
1002                                    itemkey => itemkey,
1003                                    aname => LAName,
1004                                    avalue =>
1005                                       lEvent.GetValueForParameter(lParameter));
1006       end if;
1007       resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
1008    end if; -- RUN
1009 
1010 exception
1011   when others then
1012     Wf_Core.Context('Wf_Standard', 'GetEventProperty', itemtype,
1013                     itemkey, to_char(actid), funcmode);
1014     raise;
1015 end GetEventProperty;
1016 
1017 
1018 -- LaunchProcess
1019 --   launches a process
1020 -- IN
1021 --   itemtype  - item type
1022 --   itemkey   - item key
1023 --   actid     - process activity instance id
1024 --   funcmode  - execution mode
1025 -- OUT
1026 --   result    - NULL
1027 -- ACTIVITY ATTRIBUTES REFERENCED
1028 --   START_ITEMTYPE,START_ITEMKEY,START_PROCESS,START_USER_KEY,START_OWNER
1029 procedure LaunchProcess
1030               (itemtype   in varchar2,
1031                itemkey    in varchar2,
1032                actid      in number,
1033                funcmode   in varchar2,
1034                resultout  in out nocopy varchar2) is
1035 SItemtype varchar2(8);
1036 SItemKey  varchar2(30);
1037 SProcess  varchar2(30);
1038 SUserKey  varchar2(320);
1039 SOwner    varchar2(320);
1040 Deferit   varchar2(2);
1041 Launch_count number;
1042 status    varchar2(8);
1043 result    varchar2(30);
1044 
1045 loop_flag BOOLEAN;
1046 begin
1047   -- Do nothing in cancel or timeout mode
1048   if (funcmode <> wf_engine.eng_run) then
1049     resultout := wf_engine.eng_null;
1050     return;
1051   end if;
1052 
1053 
1054   SItemtype := upper(Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'ITEMTYPE'));
1055   Deferit   := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'DEFER');
1056 
1057   if SItemtype is null then
1058      wf_core.token('ITEMTYPE','NULL');
1059      wf_core.raise('WFSQL_ARGS');
1060   end if;
1061 
1062   if deferit = 'Y' then
1063      -- Check if this is the first or second execution of this activity.
1064      -- First -> result_code will be null (really null).
1065      -- Second -> result_code will be '#NULL' (set that way by execution 1).
1066      Wf_Item_Activity_Status.Result(itemtype, itemkey, actid, status, result);
1067 
1068      if (result = wf_engine.eng_null) then
1069        -- Second execution.
1070        -- Defer must have been picked up by the background engine,
1071        -- so return complete result.
1072        resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
1073      else
1074        -- Return deferred result
1075        resultout := wf_engine.eng_deferred;
1076        return;
1077      end if;
1078   end if;
1079 
1080   -- if we have got this far, go ahead and launch the process.
1081   SItemkey  := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'ITEMKEY');
1082   SProcess  := upper(Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'PROCESS_NAME'));
1083   SUserkey  := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'USER_KEY');
1084   SOwner    := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'OWNER');
1085   if sItemkey is not null then
1086      wf_engine.LaunchProcess(SItemtype, SItemkey, SProcess, SUserkey, SOwner);
1087 
1088   else
1089        begin
1090         launch_count := wf_engine.GetItemAttrNumber(
1091                           itemtype, itemkey, 'LAUNCH_COUNT');
1092        exception
1093         when others then
1094             --
1095             -- If item attribute does not exist then create it;
1096             --
1097             if ( wf_core.error_name = 'WFENG_ITEM_ATTR' ) then
1098                 wf_engine.AddItemAttr(itemtype,itemkey, 'LAUNCH_COUNT');
1099                 launch_count := 0;
1100             else
1101                 raise;
1102             end if;
1103        end;
1104 
1105        loop_flag:=TRUE;
1106        while loop_flag loop
1107        begin
1108 	 launch_count:=launch_count+1;
1109          -- imtetype:itemkey is unique so the new itemkey should be unique
1110 	 sItemkey := itemtype||':'||itemkey||'-'||to_char(launch_count);
1111 	 wf_engine.LaunchProcess(SItemtype, SItemkey, SProcess,
1112                                  SUserkey, SOwner);
1113          loop_flag:=FALSE;
1114 	 exception
1115 	  when others then
1116 	      --
1117 	      -- Dont raise error if its a dup name: instead we will loop
1118 	      -- around and increment the counter.
1119 	      if ( wf_core.error_name <> 'WFENG_ITEM_UNIQUE' ) then
1120 		  raise;
1121 	      end if;
1122        end;
1123        end loop;
1124 
1125        wf_engine.SetItemAttrNumber(
1126             itemtype, itemkey, 'LAUNCH_COUNT',launch_count);
1127 
1128   end if;
1129 
1130 
1131   resultout := wf_engine.eng_completed;
1132 
1133 exception
1134   when others then
1135     Wf_Core.Context('Wf_Standard', 'LaunchProcess', itemtype,
1136                     itemkey, to_char(actid), Sitemtype||':'||Sitemkey||SProcess);
1137     raise;
1138 end LaunchProcess;
1139 
1140 -- LaunchProcess
1141 --   Forks the item by creating a duplicate item with the same history.
1142 --   The new forked item will be identical up to the point of this activity.
1143 --   However this activity will be marked as NOTIFIED. It will be upto the user
1144 --   to push it forward using CompleteActivity.
1145 --   NOTE: this is not permitted for #SYNCH items.
1146 -- IN
1147 --   itemtype  - item type
1148 --   itemkey   - item key
1149 --   actid     - process activity instance id
1150 --   funcmode  - execution mode
1151 -- OUT
1152 --   result    - NULL
1153 -- ACTIVITY ATTRIBUTES REFERENCED
1154 --   NEW_ITEMKEY   - the itemkey for the new item (required)
1155 --   SAME_VERSION  - TRUE creates a duplicate, FALSE uses the latest version
1156 procedure ForkItem(itemtype   in varchar2,
1157                itemkey    in varchar2,
1158                actid      in number,
1159                funcmode   in varchar2,
1160                resultout  in out nocopy varchar2) is
1161 
1162 sitemkey varchar2(30);
1163 sameversion boolean;
1164 sameversionFlag varchar2(1);
1165 
1166 begin
1167 
1168   -- Do nothing in cancel or timeout mode
1169   if (funcmode <> wf_engine.eng_run) then
1170     resultout := wf_engine.eng_null;
1171     return;
1172   end if;
1173 
1174   if (itemkey = wf_engine.eng_synch) then
1175     Wf_Core.Token('OPERATION', 'Wf_Standard.ForkItem');
1176     Wf_Core.Raise('WFENG_SYNCH_DISABLED');
1177   end if;
1178 
1179 
1180 
1181   SItemkey := upper(Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'NEW_ITEMKEY'));
1182   SameVersionFlag   := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'SAME_VERSION');
1183 
1184   if SItemkey is null
1185   or SameVersionFlag is null then
1186      wf_core.token('ITEMKEY',Sitemkey);
1187      wf_core.token('SAME_VERSION',SameVersionFlag);
1188      wf_core.raise('WFSQL_ARGS');
1189   end if;
1190 
1191   if SameVersionFlag = 'T' then
1192      sameversion := TRUE;
1193   else
1194      sameversion := FALSE;
1195   end if;
1196 
1197   -- go ahead and create the new process.
1198   wf_engine.CreateForkProcess(Itemtype, Itemkey, SItemkey, SameVersion);
1199 
1200   -- start the new process
1201   wf_engine.StartForkProcess(Itemtype, SItemkey);
1202 
1203   resultout := wf_engine.eng_completed;
1204 
1205 exception
1206   when others then
1207     Wf_Core.Context('Wf_Standard', 'ForkItem', itemtype,
1208                     itemkey, to_char(actid), Sitemkey);
1209     raise;
1210 end ForkItem;
1211 
1212 -- Noop
1213 --   Does nothing
1214 -- OUT
1215 --   result    - NULL
1216 procedure Noop(itemtype   in varchar2,
1217                itemkey    in varchar2,
1218                actid      in number,
1219                funcmode   in varchar2,
1220                resultout  in out nocopy varchar2)
1221 is
1222 begin
1223   resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
1224 exception
1225   when others then
1226     Wf_Core.Context('Wf_Standard', 'Noop', itemtype,
1227                     itemkey, to_char(actid), funcmode);
1228     raise;
1229 end Noop;
1230 
1231 -- Notify
1232 --   Public wrapper to engine notification call
1233 --   the engine notification package will retrieve the activity attributes.
1234 -- OUT
1235 --   result    - NULL
1236 procedure Notify(itemtype   in varchar2,
1237                  itemkey    in varchar2,
1238                  actid      in number,
1239                  funcmode   in varchar2,
1240                  resultout  in out nocopy varchar2)
1241 is
1242     msg varchar2(30);
1243     msgtype varchar2(8);
1244     prole varchar2(320);
1245     expand_role varchar2(1);
1246 
1247     colon pls_integer;
1248     avalue varchar2(240);
1249 
1250 begin
1251    -- Do nothing in cancel or timeout mode
1252    if (funcmode <> wf_engine.eng_run) then
1253      resultout := wf_engine.eng_null;
1254      return;
1255    end if;
1256 
1257 
1258    -- lookup notification base info
1259    Wf_Activity.Notification_Info(itemtype, itemkey, actid, msg, msgtype,
1260                                  expand_role);
1261 
1262    -- see if this activity is already assigned to a role
1263    prole := Wf_Activity.Perform_Role(itemtype, itemkey, actid);
1264 
1265    -- if it isnt then use the value from activity attribute
1266    if prole is null then
1267       prole := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'PERFORMER');
1268    end if;
1269 
1270    if prole is null then
1271     Wf_Core.Token('TYPE', itemtype);
1272     Wf_Core.Token('ACTID', to_char(actid));
1273     Wf_Core.Raise('WFENG_NOTIFICATION_PERFORMER');
1274    end if;
1275 
1276    -- message name and expand roles will be null. Get these from attributes
1277    avalue := upper(Wf_Engine.GetActivityAttrText(itemtype, itemkey,
1278                  actid, 'MESSAGE'));
1279 
1280    -- let notification_send catch a missing message name.
1281    expand_role := nvl(Wf_Engine.GetActivityAttrText(itemtype, itemkey,
1282                  actid, 'EXPANDROLES'),'N');
1283 
1284    -- parse out the message type if given
1285    colon := instr(avalue, ':');
1286    if colon = 0   then
1287       msgtype := itemtype;
1288       msg := avalue;
1289    else
1290      msgtype := substr(avalue, 1, colon - 1);
1291      msg := substr(avalue, colon + 1);
1292    end if;
1293 
1294 
1295    -- Actually send the notification
1296    Wf_Engine_Util.Notification_Send(itemtype, itemkey, actid,
1297                        msg, msgtype, prole, expand_role,
1298                        resultout);
1299 
1300 
1301    --resultout is determined by Notification_Send as either
1302    --NULL                  if notification is FYI
1303    --NOTIFIED:notid:role   if notification requires responce
1304 
1305 
1306 exception
1307   when others then
1308     Wf_Core.Context('Wf_Standard', 'Notify', itemtype,
1309                     itemkey, to_char(actid), funcmode);
1310     raise;
1311 end Notify;
1312 
1313 
1314 -- Block
1315 --   Stop and wait for external completion
1316 -- OUT
1317 --   result    - NOTIFIED
1318 procedure Block(itemtype   in varchar2,
1319                itemkey    in varchar2,
1320                actid      in number,
1321                funcmode   in varchar2,
1322                resultout  in out nocopy varchar2)
1323 is
1324 begin
1325   -- Do nothing in cancel or timeout mode
1326   if (funcmode <> wf_engine.eng_run) then
1327     resultout := wf_engine.eng_null;
1328     return;
1329   end if;
1330 
1331   resultout := wf_engine.eng_notified||':'||wf_engine.eng_null||
1332                  ':'||wf_engine.eng_null;
1333 exception
1334   when others then
1335     Wf_Core.Context('Wf_Standard', 'Block', itemtype,
1336                     itemkey, to_char(actid), funcmode);
1337     raise;
1338 end Block;
1339 
1340 
1341 -- Block
1342 --   Defers the thread by requesting a wait of zero seconds
1343 -- OUT
1344 --   result    - DEFERRED
1345 --
1346 procedure Defer(itemtype   in varchar2,
1347                 itemkey    in varchar2,
1348                 actid      in number,
1349                 funcmode   in varchar2,
1350                 resultout  in out nocopy varchar2)
1351 is
1352   status    varchar2(8);
1353   result    varchar2(30);
1354 begin
1355   -- Do nothing in cancel or timeout mode
1356   if (funcmode <> wf_engine.eng_run) then
1357     resultout := wf_engine.eng_null;
1358     return;
1359   end if;
1360 
1361   -- Check if this is the first or second execution of this activity.
1362   -- First -> result_code will be null (really null).
1363   -- Second -> result_code will be '#NULL' (set that way by execution 1).
1364   Wf_Item_Activity_Status.Result(itemtype, itemkey, actid, status, result);
1365 
1366   if (result = wf_engine.eng_null) then
1367     -- Second execution.
1368     -- Defer must have been picked up by the background engine,
1369     -- so return complete result.
1370     resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
1371   else
1372     -- Return deferred result
1373     resultout := wf_engine.eng_deferred;
1374   end if;
1375 
1376 exception
1377   when others then
1378     Wf_Core.Context('Wf_Standard', 'Defer', itemtype, itemkey,
1379                     to_char(actid), funcmode);
1380     raise;
1381 end Defer;
1382 
1383 -- Wait
1384 --   Wait until given date and time.
1385 -- OUT
1386 --   result    - 'DEFERRED' or 'NULL'
1387 --     'DEFERRED' if this is the first call and wait is beginning
1388 --     'NULL' if this is the second call and wait period has completed
1389 -- ACTIVITY ATTRIBUTES REFERENCED
1390 --   WAIT_MODE - Lookup
1391 --     'ABSOLUTE' - Wait until date in WAIT_ABSOLUTE_DATE
1392 --     'RELATIVE' - Wait until time WAIT_RELATIVE_TIME after current date
1393 --     'DAY_OF_WEEK' - Wait until next occurrence of day of week
1394 --     'DAY_OF_MONTH' - Wait until next occurrence of day of month
1395 --   WAIT_ABSOLUTE_DATE - Date
1396 --     Date to wait until if WAIT_MODE = 'ABSOLUTE'
1397 --     (Ignored if mode <> 'ABSOLUTE')
1398 --   WAIT_RELATIVE_TIME - Number (expressed in <days>.<fraction of days>)
1399 --     Time to wait after current date if WAIT_MODE = 'RELATIVE'
1400 --     (Ignored if mode <> 'RELATIVE')
1401 --   WAIT_DAY_OF_WEEK - Lookup
1402 --     Next day of week (SUNDAY, MONDAY, etc) after current date
1403 --     (Ignored if mode <> 'DAY_OF_WEEK')
1404 --   WAIT_DAY_OF_MONTH - Lookup
1405 --     Next day of month (1, 2, ..., 31, LAST) after current date
1406 --     (Ignored if mode <> 'DAY_OF_MONTH')
1407 --   WAIT_TIME - Date (format HH24:MI)
1408 --     Time of day to complete activity.   Valid for all wait modes.
1409 --     If null default time to 00:00 (midnight), except RELATIVE mode.
1410 --     For RELATIVE mode, if time is null then complete relative to current
1411 --     date and time.
1412 -- NOTE:
1413 --     For all WAIT_MODEs, the completion day is determined by the attribute
1414 --   associated with the mode, and the completion time by the WAIT_TIME
1415 --   attribute.
1416 --     For all modes except RELATIVE, the completion time is WAIT_TIME on
1417 --   the day selected by the mode's attribute.  If WAIT_TIME is null, the
1418 --   default is 00:00 (midnight).
1419 --     For RELATIVE mode, if WAIT_TIME is null the completion time is
1420 --   figured relative to the current date and time.  If WAIT_TIME is not
1421 --   null the completion time is WAIT_TIME on the day selected regardless
1422 --   of the current time.
1423 procedure Wait(itemtype   in varchar2,
1424                itemkey    in varchar2,
1425                actid      in number,
1426                funcmode   in varchar2,
1427                resultout  in out nocopy varchar2)
1428 is
1429   status    varchar2(8);
1430   result    varchar2(30);
1431   wait_mode varchar2(30);
1432   wait_date date;
1433   wakeup    date;
1434   daybuf    varchar2(30);
1435   time      date;
1436   wf_invalid_mode exception;
1437 begin
1438   -- Do nothing in cancel or timeout mode
1439   if (funcmode <> wf_engine.eng_run) then
1440     resultout := wf_engine.eng_null;
1441     return;
1442   end if;
1443 
1444   -- SYNCHMODE: Not allowed
1445   if (itemkey = wf_engine.eng_synch) then
1446     Wf_Core.Token('OPERATION', 'Wf_Standard.Wait');
1447     Wf_Core.Raise('WFENG_SYNCH_DISABLED');
1448   end if;
1449 
1450   -- Check if this is the first or second execution of this activity.
1451   -- First -> result_code will be null (really null).
1452   -- Second -> result_code will be '#NULL' (set that way by execution 1).
1453   Wf_Item_Activity_Status.Result(itemtype, itemkey, actid, status, result);
1454 
1455   if (result = wf_engine.eng_null) then
1456     -- Second execution.
1457     -- Wait is completed, return complete result.
1458     resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
1459   else
1460     -- First execution.
1461     wait_mode := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid,
1462                    'WAIT_MODE');
1463 
1464     if (wait_mode = 'ABSOLUTE') then
1465       -- Absolute date
1466       wakeup := Wf_Engine.GetActivityAttrDate(itemtype, itemkey, actid,
1467                    'WAIT_ABSOLUTE_DATE');
1468 
1469     elsif (wait_mode = 'RELATIVE') then
1470       -- Relative date.  Figure offset from sysdate.
1471       wakeup := Wf_Engine.GetActivityAttrNumber(itemtype, itemkey, actid,
1472                    'WAIT_RELATIVE_TIME') + sysdate;
1473 
1474     elsif (wait_mode = 'DAY_OF_WEEK') then
1475       -- Day of week.
1476       daybuf := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid,
1477                    'WAIT_DAY_OF_WEEK');
1478       wakeup := next_day(trunc(sysdate), daybuf);
1479 
1480     elsif (wait_mode = 'DAY_OF_MONTH') then
1481       daybuf := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid,
1482                    'WAIT_DAY_OF_MONTH');
1483 
1484       -- Figure wakeup time as offset from beginning of current month
1485       if (daybuf = 'LAST') then
1486         -- Set to last day of current month
1487         wakeup := last_day(to_date('01/'||to_char(sysdate, 'MM/YYYY'),
1488                                    'DD/MM/YYYY'));
1489       else
1490         -- Set to day x of current month
1491         wakeup := to_date('01/'||to_char(sysdate, 'MM/YYYY'),
1492                           'DD/MM/YYYY') + to_number(daybuf) - 1;
1493       end if;
1494 
1495       -- If wakeup is before current date, then shift to next month
1496       if (wakeup <= sysdate) then
1497         if (daybuf = 'LAST') then
1498           -- Set to last day of following month
1499           wakeup := last_day(add_months(to_date('01/'||to_char(sysdate,
1500                                                               'MM/YYYY'),
1501                                                'DD/MM/YYYY'), 1));
1502         else
1503           -- Set to day x of the following month
1504           wakeup := add_months(to_date('01/'||to_char(sysdate, 'MM/YYYY'),
1505                                        'DD/MM/YYYY'), 1)
1506                     + to_number(daybuf) - 1;
1507 
1508         end if;
1509       end if;
1510     else
1511       raise wf_invalid_mode;
1512     end if;
1513 
1514     -- Add the WAIT_TIME to the wakeup if specified
1515     time := Wf_Engine.GetActivityAttrDate(itemtype, itemkey, actid,
1516                    'WAIT_TIME');
1517     if (time is not null) then
1518       wakeup := to_date(to_char(wakeup, 'DD/MM/YYYY')||
1519                         to_char(time, ' HH24:MI'), 'DD/MM/YYYY HH24:MI');
1520     end if;
1521 
1522     -- Return deferred result with wakeup time appended
1523     resultout := wf_engine.eng_deferred||':'||
1524                  to_char(wakeup, wf_engine.date_format);
1525   end if;
1526 
1527 exception
1528   when wf_invalid_mode then
1529     Wf_Core.Context('Wf_Standard', 'Wait', itemtype, itemkey,
1530                     to_char(actid), funcmode);
1531     Wf_Core.Token('COMMAND', wait_mode);
1532     Wf_Core.Raise('WFSQL_COMMAND');
1533   when others then
1534     Wf_Core.Context('Wf_Standard', 'Wait', itemtype, itemkey,
1535                     to_char(actid), funcmode);
1536     raise;
1537 end Wait;
1538 
1539 
1540 -- ResetError
1541 --   Reset the status of an errored activity in an WFERROR process.
1542 -- OUT
1543 --   result    - 'NULL'
1544 -- ACTIVITY ATTRIBUTES REFERENCED
1545 --   COMMAND - 'SKIP' or 'RETRY'
1546 --        'SKIP' marks the errored activity complete and continues processing
1547 --        'RETRY' clears the errored activity and runs it again
1548 --   RESULT - Result code to complete the activity with if COMMAND = 'SKIP'
1549 procedure ResetError(itemtype   in varchar2,
1550                      itemkey    in varchar2,
1551                      actid      in number,
1552                      funcmode   in varchar2,
1553                      resultout  in out nocopy varchar2)
1554 is
1555   cmd varchar2(8);
1556   result varchar2(30);
1557   err_itemtype varchar2(8);
1558   err_itemkey varchar2(240);
1559   err_actlabel varchar2(62);
1560   wf_invalid_command exception;
1561 begin
1562   -- Do nothing in cancel or timeout mode
1563   if (funcmode <> wf_engine.eng_run) then
1564     resultout := wf_engine.eng_null;
1565     return;
1566   end if;
1567 
1568   -- SYNCHMODE: Not allowed
1569   if (itemkey = wf_engine.eng_synch) then
1570     Wf_Core.Token('OPERATION', 'Wf_Standard.ResetError');
1571     Wf_Core.Raise('WFENG_SYNCH_DISABLED');
1572   end if;
1573 
1574   -- Get RETRY or SKIP command
1575   cmd := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid, 'COMMAND');
1576 
1577   -- Get original errored activity info
1578   err_itemtype := Wf_Engine.GetItemAttrText(itemtype, itemkey,
1579                                             'ERROR_ITEM_TYPE');
1580   err_itemkey := Wf_Engine.GetItemAttrText(itemtype, itemkey,
1581                                            'ERROR_ITEM_KEY');
1582   err_actlabel := Wf_Engine.GetItemAttrText(itemtype, itemkey,
1583                                            'ERROR_ACTIVITY_LABEL');
1584 
1585   if (cmd = wf_engine.eng_retry) then
1586     -- Rerun activity
1587     Wf_Engine.HandleError(err_itemtype, err_itemkey, err_actlabel,
1588                           cmd, '');
1589 
1590 /* Disallow skip mode because it is too difficult to
1591    assign and validate the RESULT value
1592   elsif (cmd = wf_engine.eng_skip) then
1593     -- Get result code
1594     result := Wf_Engine.GetActivityAttrText(itemtype, itemkey, actid,
1595               'RESULT');
1596     -- Mark activity complete and continue processing
1597     Wf_Engine.HandleError(err_itemtype, err_itemkey, err_actlabel,
1598                           cmd, result);
1599 */
1600   else
1601     raise wf_invalid_command;
1602   end if;
1603 
1604   resultout := wf_engine.eng_null;
1605 exception
1606   when wf_invalid_command then
1607     Wf_Core.Context('Wf_Standard', 'ResetError', itemtype,
1608                     itemkey, to_char(actid), funcmode);
1609     Wf_Core.Token('COMMAND', cmd);
1610     Wf_Core.Raise('WFSQL_COMMAND');
1611   when others then
1612     Wf_Core.Context('Wf_Standard', 'ResetError', itemtype,
1613                     itemkey, to_char(actid), funcmode);
1614     raise;
1615 end ResetError;
1616 
1617 
1618 -- RoleResolution
1619 --   Resolve A Role which comprises a group to an individual
1620 -- OUT
1621 --   result    - 'NULL'
1622 -- ACTIVITY ATTRIBUTES REFERENCED
1623 --   COMMAND - 'LOAD_BALANCE' or 'ROUND_ROBIN'
1624 --        'LOAD_BALANCE' Assigns to user with least open notifications
1625 --        'ROUND_ROBIN'  Assigns notification to users sequencially
1626 procedure RoleResolution(itemtype   in varchar2,
1627                          itemkey    in varchar2,
1628                          actid      in number,
1629                          funcmode   in varchar2,
1630                          resultout  in out nocopy varchar2) is
1631     cmd                     varchar2(30);
1632     wf_invalid_command      exception;
1633     actdate                 date;
1634     label                   varchar2(30);
1635     prole                   varchar2(320);
1636     --
1637     --  select all out-transitions of RoleResolution Activity
1638     --
1639     cursor  out_transitions is
1640     SELECT  wat.to_process_activity,
1641             wpa.activity_name,
1642             wpa.perform_role,
1643             wpa.perform_role_type
1644     FROM    wf_activity_transitions wat,
1645             wf_process_activities wpa
1646     WHERE   wat.from_process_activity       = actid
1647     AND     wat.result_code                 = wf_engine.eng_trans_default
1648     AND     wat.to_process_activity         = wpa.instance_id;
1649     --
1650     -- select number of activities the user currently has in worklist
1651     --
1652     cursor load_balance(user in varchar2, act_name varchar2 ) is
1653     select  count(1)
1654     from    wf_item_activity_statuses wias,
1655             wf_process_activities wpa
1656     where   wias.item_type          = itemtype
1657     and     wias.activity_status    = 'NOTIFIED'
1658     and     wias.process_activity   = wpa.instance_id
1659     and     wpa.activity_name       = act_name
1660     and     assigned_user           = user;
1661     --
1662     -- select the date of the last time the user was notified
1663     --
1664     cursor round_robin(user in varchar2, act_name varchar2 ) is
1665     select max(begin_date)
1666     from    wf_item_activity_statuses wias,
1667             wf_process_activities wpa
1668     where   wias.item_type          = itemtype
1669     and     wias.process_activity   = wpa.instance_id
1670     and     wpa.activity_name       = act_name
1671     and     wias.assigned_user      = user;
1672     --
1673 begin
1674     --
1675     -- Do nothing in cancel mode
1676     --
1677     if (funcmode <> wf_engine.eng_run ) then
1678           resultout := wf_engine.eng_null;
1679           return;
1680     end if;
1681 
1682     -- SYNCHMODE: Not allowed
1683     if (itemkey = wf_engine.eng_synch) then
1684       Wf_Core.Token('OPERATION', 'Wf_Standard.AndJoin');
1685       Wf_Core.Raise('WFENG_SYNCH_DISABLED');
1686     end if;
1687 
1688     actdate :=  wf_item.active_date(itemtype, itemkey);
1689     cmd :=  Wf_Engine.GetActivityAttrText(itemtype,itemkey,actid,'METHOD');
1690 
1691     -- loop thru all out-transiations of role resolution activity
1692     for trans_rec in out_transitions loop
1693     declare
1694         usertab                 wf_directory.UserTable;
1695         min_assigned_activities number := -1;
1696         min_begin_date          date;
1697         assigned_performer      varchar2(320);
1698     begin
1699         --
1700         if (Wf_Activity.Type(itemtype, trans_rec.activity_name, actdate) =
1701             wf_engine.eng_notification) then
1702             -- Get perform_role from constant or itemattr value
1703             if (trans_rec.perform_role_type = 'CONSTANT') then
1704               prole := trans_rec.perform_role;
1705             else
1706               prole := Wf_Engine.GetItemAttrText(itemtype, itemkey,
1707                            trans_rec.perform_role);
1708             end if;
1709             wf_directory.GetRoleUsers(prole,usertab);
1710             if ( cmd = 'LOAD_BALANCE' ) then
1711                 declare
1712                     assigned_activities     number := 0;
1713                     indx                    number := 1;
1714                 begin
1715                     loop -- loop until NO_DATA_FOUND
1716                         open    load_balance(usertab(indx),
1717                                              trans_rec.activity_name);
1718                         fetch   load_balance into assigned_activities;
1719                         close   load_balance;
1720 
1721                         if ((assigned_activities < min_assigned_activities or
1722                              min_assigned_activities = -1) and
1723                             wf_directory.UserActive(usertab(indx))) then
1724                             min_assigned_activities := assigned_activities;
1725                             assigned_performer      := usertab(indx);
1726                         end if;
1727 
1728                         indx := indx + 1;
1729                     end loop;
1730                 exception
1731                     when NO_DATA_FOUND then
1732                         null;
1733                 end;
1734             elsif ( cmd = 'ROUND_ROBIN' ) then
1735                 declare
1736                     begin_date      date;
1737                     indx            number :=1;
1738                 begin
1739                     loop -- until access of usertab raises NO_DATA_FOUND
1740                         open    round_robin(usertab(indx),
1741                                             trans_rec.activity_name);
1742                         fetch   round_robin into begin_date;
1743                         close   round_robin;
1744 
1745                         if (begin_date is null) then
1746                             begin_date := to_date('01/01/0001','DD/MM/YYYY');
1747                         end if;
1748 
1749                         if ((begin_date < min_begin_date or
1750                              min_begin_date is null) and
1751                              wf_directory.UserActive(usertab(indx))) then
1752                             min_begin_date          := begin_date;
1753                             assigned_performer      := usertab(indx);
1754                         end if;
1755 
1756                         indx := indx + 1;
1757                     end loop;
1758                 exception
1759                     when NO_DATA_FOUND then
1760                         null;
1761                 end;
1762             else
1763                 raise wf_invalid_command;
1764             end if;
1765 
1766             if ( assigned_performer is not null ) then
1767                 --
1768                 -- Retreieve instance_label for activity
1769                 --
1770                 select wpa.instance_label
1771                 into   label
1772                 from   wf_process_activities wpa
1773                 where  wpa.instance_id = trans_rec.to_process_activity;
1774 
1775                 wf_engine.AssignActivity(itemtype,itemkey,label,
1776                                          assigned_performer);
1777 
1778             end if;
1779 
1780             resultout := wf_engine.eng_null;
1781         end if;
1782     end;
1783     end loop;
1784 exception
1785     when wf_invalid_command then
1786         wf_core.context('Wf_Standard', 'RoleResoluion',
1787                         itemtype, itemkey, to_char(actid), funcmode);
1788         wf_core.token('COMMAND', cmd);
1789         wf_core.raise('WFSQL_COMMAND');
1790     when others then
1791         wf_core.Context('Wf_Standard', 'RoleResolution',
1792                         itemtype, itemkey, to_char(actid), funcmode);
1793         raise;
1794 end RoleResolution;
1795 
1796 
1797 -- ContinueFlow
1798 --   Signal Flow to continue
1799 -- OUT
1800 --   result    - 'NULL'
1801 -- ACTIVITY ATTRIBUTES REFERENCED
1802 --   WAITING_ACTIVITY
1803 --   WAITING_FLOW
1804 procedure ContinueFlow( itemtype   in varchar2,
1805                         itemkey    in varchar2,
1806                         actid      in number,
1807                         funcmode   in varchar2,
1808                         resultout  in out nocopy varchar2 ) is
1809     l_waiting_activity      varchar2(30);
1810     l_waiting_flow          varchar2(30);
1811     wf_invalid_command      exception;
1812 begin
1813     if (funcmode <> wf_engine.eng_run) then
1814         resultout := wf_engine.eng_null;
1815         return;
1816     end if;
1817 
1818     -- SYNCHMODE: Not allowed
1819     if (itemkey = wf_engine.eng_synch) then
1820       Wf_Core.Token('OPERATION', 'Wf_Standard.AndJoin');
1821       Wf_Core.Raise('WFENG_SYNCH_DISABLED');
1822     end if;
1823 
1824     l_waiting_activity := upper(Wf_Engine.GetActivityAttrText(
1825                                 itemtype, itemkey, actid,'WAITING_ACTIVITY'));
1826     l_waiting_flow     := Wf_Engine.GetActivityAttrText(
1827                               itemtype, itemkey, actid,'WAITING_FLOW');
1828 
1829     if ( l_waiting_flow = 'MASTER' ) then
1830         ContinueMasterFlow(itemtype,itemkey,actid,l_waiting_activity,resultout);
1831     elsif ( l_waiting_flow = 'DETAIL' ) then
1832         ContinueDetailFlow(itemtype,itemkey,actid,l_waiting_activity,resultout);
1833     else
1834         raise wf_invalid_command;
1835     end if;
1836 
1837 exception
1838     when wf_invalid_command then
1839         Wf_Core.Context('Wf_Standard', 'ContinueFlow',
1840                         itemtype,itemkey, to_char(actid), funcmode);
1841         Wf_Core.Token('COMMAND', l_waiting_flow );
1842         Wf_Core.Raise('WFSQL_COMMAND');
1843     when others then
1844         Wf_Core.Context('Wf_Standard', 'ContinueFlow',
1845                         itemtype,itemkey, to_char(actid), funcmode);
1846         raise;
1847 end continueflow;
1848 
1849 
1850 -- WaitForFlow
1851 --   Wait for flow to complete
1852 -- OUT
1853 --   result    - 'NULL'
1854 -- ACTIVITY ATTRIBUTES REFERENCED
1855 --   CONTINUATION_ACTIVITY
1856 --   CONTINUATION_FLOW
1857 procedure WaitForFlow(  itemtype   in varchar2,
1858                         itemkey    in varchar2,
1859                         actid      in number,
1860                         funcmode   in varchar2,
1861                         resultout  in out nocopy varchar2) is
1862     l_continuation_activity varchar2(30);
1863     l_continuation_flow     varchar2(30);
1864     wf_invalid_command      exception;
1865 begin
1866     if (funcmode <> wf_engine.eng_run) then
1867         resultout := wf_engine.eng_null;
1868         return;
1869     end if;
1870 
1871     -- SYNCHMODE: Not allowed
1872     if (itemkey = wf_engine.eng_synch) then
1873       Wf_Core.Token('OPERATION', 'Wf_Standard.WaitForFlow');
1874       Wf_Core.Raise('WFENG_SYNCH_DISABLED');
1875     end if;
1876 
1877     l_continuation_activity := upper(Wf_Engine.GetActivityAttrText(
1878                                          itemtype, itemkey, actid,
1879                                          'CONTINUATION_ACTIVITY'));
1880     l_continuation_flow     := Wf_Engine.GetActivityAttrText(
1881                                    itemtype,itemkey,actid,'CONTINUATION_FLOW');
1882 
1883     if ( l_continuation_flow = 'MASTER' ) then
1884         WaitForMasterFlow(itemtype,itemkey,actid,
1885                           l_continuation_activity,resultout);
1886     elsif ( l_continuation_flow = 'DETAIL' ) then
1887         WaitForDetailFlow(itemtype,itemkey,actid,
1888                           l_continuation_activity,resultout);
1889     else
1890         raise wf_invalid_command;
1891     end if;
1892 
1893 exception
1894     when wf_invalid_command then
1895         Wf_Core.Context('Wf_Standard', 'WaitForFlow',
1896                         itemtype,itemkey, to_char(actid), funcmode);
1897         Wf_Core.Token('COMMAND', l_continuation_flow );
1898         Wf_Core.Raise('WFSQL_COMMAND');
1899     when others then
1900         Wf_Core.Context('Wf_Standard', 'WaitForFlow',
1901                         itemtype,itemkey, to_char(actid), funcmode);
1902         raise;
1903 end WaitForFlow;
1904 
1905 
1906 -- LoopCounter
1907 --     Count the number of times the activity has been visited.
1908 -- OUT
1909 --   result    -
1910 -- ACTIVITY ATTRIBUTES REFERENCED
1911 --      MAX_TIMES
1912 procedure LoopCounter(  itemtype   in varchar2,
1913                         itemkey    in varchar2,
1914                         actid      in number,
1915                         funcmode   in varchar2,
1916                         resultout  in out nocopy varchar2) is
1917     max_times       pls_integer;
1918     loop_count      pls_integer;
1919 begin
1920     --
1921     -- Do nothing in cancel mode
1922     --
1923     if (funcmode <> wf_engine.eng_run) then
1924         resultout := wf_engine.eng_null;
1925         return;
1926     end if;
1927 
1928     -- Get maximum times activity can be executed.
1929     max_times := wf_engine.GetActivityAttrNumber(
1930                      itemtype, itemkey, actid, 'MAX_TIMES');
1931     if ( max_times is null ) then
1932         wf_core.token('MAX_TIMES',max_times);
1933         wf_core.raise('WFSQL_ARGS');
1934     end if;
1935 
1936     begin
1937         loop_count := wf_engine.GetItemAttrNumber(
1938                           itemtype, itemkey, 'LOOP_COUNT'||':'||actid);
1939     exception
1940         when others then
1941             --
1942             -- If item attribute does not exist then create it;
1943             --
1944             if ( wf_core.error_name = 'WFENG_ITEM_ATTR' ) then
1945                 wf_engine.AddItemAttr(
1946                     itemtype,itemkey, 'LOOP_COUNT'||':'||actid);
1947                 loop_count := 0;
1948             else
1949                 raise;
1950             end if;
1951     end;
1952 
1953     if ( loop_count >= max_times ) then
1954         loop_count := 0;
1955         resultout := 'EXIT';
1956     else
1957         loop_count := loop_count +1;
1958         resultout := 'LOOP';
1959     end if;
1960 
1961     wf_engine.SetItemAttrNumber(
1962         itemtype, itemkey, 'LOOP_COUNT'||':'||actid,loop_count);
1963 exception
1964     when others then
1965         wf_core.context('Wf_Standard','LoopCount',
1966                         itemtype, itemkey, to_char(actid), funcmode);
1967         raise;
1968 end loopcounter;
1969 
1970 
1971 -- VoteForResultType
1972 --     Standard Voting Function
1973 -- IN
1974 --   itemtype  - A valid item type from (WF_ITEM_TYPES table).
1975 --   itemkey   - A string generated from the application object's primary key.
1976 --   actid     - The process activity(instance id).
1977 --   funcmode  - Run/Cancel
1978 -- OUT
1979 --   result    -
1980 --
1981 -- USED BY ACTIVITIES
1982 --
1983 --   WFSTD.VoteForResultType
1984 --
1985 -- ACTIVITY ATTRIBUTES REFERENCED
1986 --      VOTING_OPTION
1987 --          - WAIT_FOR_ALL_VOTES  - Evaluate voting after all votes are cast
1988 --                                - or a Timeout condition closes the voting
1989 --                                - polls.  When a Timeout occurs the
1990 --                                - voting percentages are calculated as a
1991 --                                - percentage ofvotes cast.
1992 --
1993 --          - REQUIRE_ALL_VOTES   - Evaluate voting after all votes are cast.
1994 --                                - If a Timeout occurs and all votes have not
1995 --                                - been cast then the standard timeout
1996 --                                - transition is taken.  Votes are calculated
1997 --                                - as a percenatage of users notified to vote.
1998 --
1999 --          - TALLY_ON_EVERY_VOTE - Evaluate voting after every vote or a
2000 --                                - Timeout condition closes the voting polls.
2001 --                                - After every vote voting percentages are
2002 --                                - calculated as a percentage of user notified
2003 --                                - to vote.  After a timeout voting
2004 --                                - percentages are calculated as a percentage
2005 --                                - of votes cast.
2006 --
2007 --      "One attribute for each of the activities result type codes"
2008 --
2009 --          - The standard Activity VOTEFORRESULTTYPE has the WFSTD_YES_NO
2010 --          - result type assigned.
2011 --          - Thefore activity has two activity attributes.
2012 --
2013 --                  Y       - Percenatage required for Yes transition
2014 --                  N       - Percentage required for No transition
2015 --
2016 procedure VoteForResultType(    itemtype   in varchar2,
2017                                 itemkey    in varchar2,
2018                                 actid      in number,
2019                                 funcmode   in varchar2,
2020                                 resultout  in out nocopy varchar2)
2021 is
2022   -- Select all lookup codes for an activities result type
2023   cursor result_codes is
2024   select  wfl.lookup_code result_code
2025   from    wf_lookups wfl,
2026           wf_activities wfa,
2027           wf_process_activities wfpa,
2028           wf_items wfi
2029   where   wfl.lookup_type         = wfa.result_type
2030   and     wfa.name                = wfpa.activity_name
2031   and     wfi.begin_date          >= wfa.begin_date
2032   and     wfi.begin_date          < nvl(wfa.end_date,wfi.begin_date+1)
2033   and     wfpa.activity_item_type = wfa.item_type
2034   and     wfpa.instance_id        = actid
2035   and     wfi.item_key            = itemkey
2036   and     wfi.item_type           = itemtype;
2037 
2038   l_code_count    pls_integer;
2039   l_group_id      pls_integer;
2040   l_user          varchar2(320);
2041   l_voting_option varchar2(30);
2042   l_per_of_total  number;
2043   l_per_of_vote   number;
2044   l_per_code      number;
2045   per_success     number;
2046   max_default     pls_integer := 0;
2047   default_result  varchar2(30) := '';
2048   result          varchar2(30) := '';
2049   wf_invalid_command exception;
2050 begin
2051   -- Do nothing unless in RUN or TIMEOUT modes
2052   if  (funcmode <> wf_engine.eng_run)
2053   and (funcmode <> wf_engine.eng_timeout) then
2054     resultout := wf_engine.eng_null;
2055     return;
2056   end if;
2057 
2058   -- SYNCHMODE: Not allowed
2059   if (itemkey = wf_engine.eng_synch) then
2060     Wf_Core.Token('OPERATION', 'Wf_Standard.VotForResultType');
2061     Wf_Core.Raise('WFENG_SYNCH_DISABLED');
2062   end if;
2063 
2064   -- Get Notifications group_id for activity
2065   Wf_Item_Activity_Status.Notification_Status(itemtype,itemkey,actid,
2066       l_group_id,l_user);
2067   l_voting_option := Wf_Engine.GetActivityAttrText(itemtype,itemkey,
2068                          actid,'VOTING_OPTION');
2069   if (l_voting_option not in ('REQUIRE_ALL_VOTES', 'WAIT_FOR_ALL_VOTES',
2070                                'TALLY_ON_EVERY_VOTE')) then
2071     raise wf_invalid_command;
2072   end if;
2073 
2074   -- If the mode is one of:
2075   --   a. REQUIRE_ALL_VOTES
2076   --   b. WAIT_FOR_ALL_VOTES and no timeout has occurred
2077   -- and there are still open notifications, then return WAITING to
2078   -- either continue voting (in run mode) or trigger timeout processing
2079   -- (in timeout mode).
2080   if ((l_voting_option = 'REQUIRE_ALL_VOTES') or
2081       ((funcmode = wf_engine.eng_run) and
2082        (l_voting_option = 'WAIT_FOR_ALL_VOTES'))) then
2083     if (wf_notification.OpenNotificationsExist(l_group_id)) then
2084       resultout := wf_engine.eng_waiting;
2085       return;
2086     end if;
2087   end if;
2088 
2089   -- If here, then the mode is one of:
2090   --   a. TALLY_ON_ALL_VOTES
2091   --   b. WAIT_FOR_ALL_VOTES and timeout has occurred
2092   --   c. WAIT_FOR_ALL_VOTES and all votes are cast
2093   --   d. REQUIRE_ALL_VOTES and all votes are cast
2094   -- Tally votes.
2095   for result_rec in result_codes loop
2096     -- Tally Vote Count for this result code
2097     Wf_Notification.VoteCount(l_group_id,result_rec.result_code,
2098         l_code_count,l_per_of_total,l_per_of_vote);
2099 
2100     -- If this is timeout mode, then use the percent of votes cast so far.
2101     -- If this is run mode, then use the percent of total votes possible.
2102     if (funcmode = wf_engine.eng_timeout) then
2103       l_per_code := l_per_of_vote;
2104     else
2105       l_per_code := l_per_of_total;
2106     end if;
2107 
2108     -- Get percent vote needed for this result to succeed
2109     per_success := Wf_Engine.GetActivityAttrNumber(itemtype,itemkey,
2110                        actid,result_rec.result_code);
2111 
2112     if (per_success is null) then
2113       -- Null value means this is a default result.
2114       -- Save the default result with max code_count.
2115       if (l_code_count > max_default) then
2116         max_default := l_code_count;
2117         default_result := result_rec.result_code;
2118       elsif (l_code_count = max_default) then
2119         -- Tie for default result.
2120         default_result := wf_engine.eng_tie;
2121       end if;
2122     else
2123       -- If:
2124       --   a. % vote for this result > % needed for success OR
2125       --   b. % vote is 100% AND
2126       --   c. at least 1 vote for this result
2127       -- then this result succeeds.
2128       if (((l_per_code > per_success) or (l_per_code = 100)) and
2129           (l_code_count > 0))
2130       then
2131         if (result is null) then
2132           -- Save satisfied result.
2133           result := result_rec.result_code;
2134         else
2135           -- This is the second result to be satisfied.  Return a tie.
2136           resultout := wf_engine.eng_completed||':'||wf_engine.eng_tie;
2137           return;
2138         end if;
2139       end if;
2140     end if;
2141   end loop;
2142 
2143   if (result is not null) then
2144     -- Return the satisfied result code.
2145     resultout := wf_engine.eng_completed||':'||result;
2146   else
2147     -- If we get here no non-default results were satisfied.
2148     if (funcmode = wf_engine.eng_run and
2149         wf_notification.OpenNotificationsExist(l_group_id)) then
2150       -- Not timed out and still open notifications.
2151       -- Return waiting to continue voting.
2152       resultout := wf_engine.eng_waiting;
2153     elsif (default_result is not null) then
2154       -- Either timeout or all notifications closed
2155       -- Return default result if one found.
2156       resultout := wf_engine.eng_completed||':'||default_result;
2157     elsif (funcmode =  wf_engine.eng_timeout) then
2158       -- If Timeout has occured then return result Timeout so the Timeout
2159       -- transition will occur - BUG2885157
2160       resultout := wf_engine.eng_completed||':'||wf_engine.eng_timedout;
2161     else
2162       -- All notifications closed, and no default.
2163       -- Return nomatch
2164       resultout := wf_engine.eng_completed||':'||wf_engine.eng_nomatch;
2165     end if;
2166   end if;
2167   return;
2168 exception
2169   when wf_invalid_command then
2170     Wf_Core.Context('Wf_Standard', 'VoteForResultType', itemtype,
2171                     itemkey, to_char(actid), funcmode);
2172     Wf_Core.Token('COMMAND', l_voting_option);
2173     Wf_Core.Raise('WFSQL_COMMAND');
2174   when others then
2175     Wf_Core.Context('Wf_Standard', 'VoteForResultType',itemtype,
2176                     itemkey, to_char(actid), funcmode);
2177     raise;
2178 end VoteForResultType;
2179 
2180 
2181 -------------------------------------------------------------------------------
2182 ------------------------------- PRIVATE APIs ----------------------------------
2183 -------------------------------------------------------------------------------
2184 
2185 --
2186 -- WaitForMasterFlow
2187 --   Wait for Master flow to complete continuation activity
2188 -- OUT
2189 --   result    - 'NULL'
2190 procedure WaitForMasterFlow(    itemtype                in varchar2,
2191                                 itemkey                 in varchar2,
2192                                 actid                   in number,
2193                                 continuation_activity   in varchar2,
2194                                 resultout               out nocopy varchar2 )
2195 is
2196   l_parent_itemtype       varchar2(8);
2197   l_parent_itemkey        varchar2(240);
2198   l_activity_status       varchar2(30);
2199 
2200   colon pls_integer;
2201   process varchar2(30);
2202   label varchar2(30);
2203   instid pls_integer;
2204   dummy varchar2(50);
2205 begin
2206 
2207   -- Parse activity arg into <process_name> and <instance_label> components.
2208   colon := instr(continuation_activity, ':');
2209   if (colon <> 0) then
2210     -- Activity arg is <process name>:<instance label>
2211     process := substr(continuation_activity, 1, colon-1);
2212     label := substr(continuation_activity, colon+1);
2213   else
2214     -- Activity arg is just instance label
2215     process := '';
2216     label := continuation_activity;
2217   end if;
2218 
2219     select  parent_item_type, parent_item_key
2220     into    l_parent_itemtype, l_parent_itemkey
2221     from    wf_items
2222     where   item_type       = WaitForMasterFlow.itemtype
2223     and     item_key    = WaitForMasterFlow.itemkey;
2224 
2225 
2226     begin
2227         select  'master activity not complete'
2228         into dummy
2229 	from WF_ITEM_ACTIVITY_STATUSES WIAS, WF_PROCESS_ACTIVITIES WPA
2230 	where WIAS.ITEM_TYPE = l_parent_itemtype
2231 	and WIAS.ITEM_KEY = l_parent_itemkey
2232 	and WIAS.PROCESS_ACTIVITY = WPA.INSTANCE_ID
2233 	and WPA.INSTANCE_LABEL = label
2234 	and WPA.PROCESS_NAME = nvl(process, WPA.PROCESS_NAME)
2235 	and wias.activity_status  in (wf_engine.eng_completed, wf_engine.eng_active);
2236     exception
2237         -- When not complete return NOTIFIED to cause engine to stall
2238         when NO_DATA_FOUND then
2239             resultout := wf_engine.eng_notified||':'||wf_engine.eng_null|| ':'||wf_engine.eng_null;
2240             return;
2241     end;
2242     resultout := wf_engine.eng_null;
2243 exception
2244     when others then
2245         wf_core.context('Wf_Standard', 'WaitForMasterFlow',
2246                         itemtype,itemkey,to_char(actid),continuation_activity);
2247         raise;
2248 end WaitForMasterFlow;
2249 
2250 
2251 -- WaitForDetailFlow
2252 --   Wait for detail flows to complete continuation activity
2253 -- OUT
2254 --   result    - 'NULL'
2255 procedure WaitForDetailFlow(    itemtype                in varchar2,
2256                                 itemkey                 in varchar2,
2257                                 actid                   in number,
2258                                 continuation_activity   in varchar2,
2259                                 resultout               out nocopy varchar2) is
2260 cursor  child_flows is
2261     -- select all active children of parent flow
2262     select  count(1)
2263     from    wf_items
2264     where   parent_item_type    = itemtype
2265     and     parent_item_key     = itemkey
2266     and     end_date        is null;
2267 
2268 cursor child_activities (itemtype varchar2, itemkey varchar2,
2269                          pname varchar2, plabel varchar2) is
2270     select count(1)
2271     from WF_ITEM_ACTIVITY_STATUSES WIAS, WF_PROCESS_ACTIVITIES WPA
2272     where (WIAS.ITEM_TYPE, WIAS.ITEM_KEY) in (select item_type,item_key
2273                          from wf_items
2274                          where  parent_item_type =itemtype
2275                          and parent_item_key  =itemkey
2276                          and end_date is null)
2277     and WIAS.PROCESS_ACTIVITY = WPA.INSTANCE_ID
2278     and WPA.INSTANCE_LABEL = plabel
2279     and WPA.PROCESS_NAME = nvl(pname, WPA.PROCESS_NAME)
2280     and wias.activity_status  in (wf_engine.eng_completed, wf_engine.eng_active);
2281 
2282 cursor current_process (p_actid number) is
2283   select instance_label
2284   from   wf_process_activities
2285   where  instance_id = p_actid;
2286 
2287   colon pls_integer;
2288   process varchar2(30);
2289   label varchar2(30);
2290   instid pls_integer;
2291   number_active   pls_integer;
2292   number_complete pls_integer;
2293   l_childCount number;
2294   l_labelCount number;
2295   l_waitLabel varchar2(30);
2296   --Bug 14784055. Need to validate the activity LABEL is not too large
2297   ValTooLarge EXCEPTION;
2298   pragma exception_init(ValTooLarge, -01401);
2299   ValTooLargeNew EXCEPTION;
2300   pragma exception_init(ValTooLargeNew, -12899);
2301   l_module varchar2(20) := 'WaitForDetailFlow';
2302 
2303 begin
2304   -- Parse activity arg into <process_name> and <instance_label> components.
2305   colon := instr(continuation_activity, ':');
2306   if (colon <> 0) then
2307      -- Activity arg is <process name>:<instance label>
2308      process := substr(continuation_activity, 1, colon-1);
2309      label := substr(continuation_activity, colon+1);
2310   else
2311      -- Activity arg is just instance label
2312      process := '';
2313      label := continuation_activity;
2314   end if;
2315 
2316   --Retrieve the label for the WaitForFlow activity.
2317   open current_process(actid);
2318     fetch current_process into l_waitLabel;
2319   close current_process;
2320 
2321   l_labelCount := WF_ENGINE.GetItemAttrNumber(itemType, itemKey,
2322                                               '#CNT_'||l_waitLabel, TRUE);
2323   if (l_labelCount is NULL) then
2324     l_childCount := WF_ENGINE.GetItemAttrNumber(itemType, itemKey,
2325                                                 '#WAITFORDETAIL', TRUE);
2326     if (l_childCount is NULL) then --Fall back to the old path.
2327       open   child_flows;
2328       fetch  child_flows into number_active;
2329       close  child_flows;
2330 
2331       if (number_active < 1) then
2332         resultout := wf_engine.eng_null;
2333       else
2334         open   child_activities(itemtype, itemkey, process, label);
2335         fetch  child_activities into number_complete;
2336         close  child_activities;
2337 
2338         if number_active > number_complete then
2339           resultout := wf_engine.eng_notified||':'||
2340                        wf_engine.eng_null||':'||wf_engine.eng_null;
2341         else
2342           resultout := wf_engine.eng_null;
2343         end if;
2344 
2345       end if; --There are no children
2346     else --#WAITFORDETAIL exists
2347       begin
2348         WF_ENGINE.AddItemAttr(itemtype=>WaitForDetailFlow.itemtype,
2349                               itemkey=>WaitForDetailFlow.itemkey,
2350                               aname=>'#CNT_'||l_waitLabel,
2351                               number_value=>l_childCount);
2352       exception
2353         when ValTooLarge OR ValTooLargeNew then
2354           Wf_Core.Context('WF_ENGINE', l_module, WaitForDetailFlow.itemtype,
2355                           WaitForDetailFlow.itemkey);
2356           WF_CORE.Token('LABEL', '#CNT_'||l_waitLabel);
2357           WF_CORE.Token('LENGTH', 30);
2358           WF_CORE.Raise('WFENG_LABEL_TOO_LARGE');
2359       end;
2360       if (l_childCount > 0) then
2361         resultout := wf_engine.eng_notified||':'||
2362                      wf_engine.eng_null||':'||wf_engine.eng_null;
2363       else
2364         resultout := wf_engine.eng_null;
2365       end if; --l_childCount > 0
2366     end if; -- #WAITFORDETAIL
2367   elsif (l_labelCount > 0) then
2368     --The #CNT_ attribute exists and is 1 or greater so this will remain
2369     --notified.
2370     resultout := wf_engine.eng_notified||':'||wf_engine.eng_null||
2371                  ':'||wf_engine.eng_null;
2372 
2373   else --The labelcount exists and is < 1 so we can continue.
2374      resultout := wf_engine.eng_null;
2375   end if;
2376 
2377 
2378 exception
2379     when others then
2380         wf_core.context('Wf_Standard', 'WaitForDetailFlow',
2381                         itemtype,itemkey,to_char(actid),continuation_activity);
2382         raise;
2383 end WaitForDetailFlow;
2384 
2385 
2386 -- ContinueDetailFlow
2387 --   Signal Detail Flows to continue
2388 -- IN
2389 --   itemtype  - A valid item type from (WF_ITEM_TYPES table).
2390 --   itemkey   - A string generated from the application object's primary key.
2391 --   actid     - The process activity(instance id).
2392 --   waiting_activity - The Name of the activity that in waiting
2393 -- OUT
2394 --   resultout    - 'NULL'
2395 procedure ContinueDetailFlow(   itemtype                in varchar2,
2396                                 itemkey                 in varchar2,
2397                                 actid                   in number,
2398                                 waiting_activity        in varchar2,
2399                                 resultout               out nocopy varchar2
2400                                  ) is
2401 --
2402 cursor child_flows is
2403     --
2404     -- select all active children of parent flow
2405     --
2406     select  item_type, item_key
2407     from    wf_items
2408     where   parent_item_type    = itemtype
2409     and     parent_item_key     = itemkey
2410     and     end_date        is null;
2411 --
2412 begin
2413     for child_flows_rec in child_flows loop
2414         --
2415         -- Complete Waiting Activity in All Detail Flows
2416         --
2417         begin
2418             wf_engine.CompleteActivity(child_flows_rec.item_type,
2419                 child_flows_rec.item_key, waiting_activity,wf_engine.eng_null);
2420         exception
2421             when others then
2422             -- If call to CompleteActivity cannot find activity, return null
2423             -- As either the detail flows does not have a waiting activity OR
2424             -- the detail flow has not reach the waiting activity
2425             if ( wf_core.error_name = 'WFENG_NOT_NOTIFIED' ) then
2426                 wf_core.clear;
2427             else
2428                 raise;
2429             end if;
2430         end;
2431     end loop;
2432 
2433     ContinueDetailFlow.resultout := wf_engine.eng_null;
2434 
2435 exception
2436     when others then
2437         wf_core.context('Wf_Standard','ContinueDetailFlow',
2438                         itemtype, itemkey, to_char(actid),waiting_activity);
2439         raise;
2440 end ContinueDetailFlow;
2441 
2442 
2443 -- ContinueMasterFlow
2444 --   Signal Master Flow to continue if all Detail flows have
2445 --   executed Continuation Activity
2446 -- OUT
2447 --   result    - 'NULL'
2448 procedure ContinueMasterFlow(   itemtype                in varchar2,
2449                                 itemkey                 in varchar2,
2450                                 actid                   in number,
2451                                 waiting_activity        in varchar2,
2452                                 resultout               in out nocopy varchar2) is
2453 
2454 
2455   l_activity_status      varchar2(8);
2456   l_parent_itemtype      varchar2(8);
2457   l_parent_itemkey       varchar2(240);
2458   label                  varchar2(30);
2459   number_active   pls_integer;
2460   number_complete pls_integer;
2461 
2462   -- CTILLEY bug 1941013
2463   l_parent_context varchar2(2000);
2464 
2465   cursor  child_flows_mwf is
2466       -- This cursor is used if there are multiple WaitForFlow Activities in the
2467       -- parent flow (the parent_context must be set).  CTILLEY bug 1941013
2468       -- select all active children of parent flow excluding current work item
2469       select  count(1)
2470       from    wf_items
2471       where   parent_item_type    = l_parent_itemtype
2472       and     parent_item_key     = l_parent_itemkey
2473       and     parent_context      = l_parent_context
2474       and     (item_type          <> ContinueMasterFlow.itemtype
2475                or item_key        <> ContinueMasterFlow.itemkey)
2476       and     end_date        is null;
2477 
2478   cursor  child_flows2 is
2479       -- select all active children of parent flow excluding current work item
2480       select  count(1)
2481       from    wf_items
2482       where   parent_item_type    = l_parent_itemtype
2483       and     parent_item_key     = l_parent_itemkey
2484       and     (item_type          <> ContinueMasterFlow.itemtype
2485                or item_key        <> ContinueMasterFlow.itemkey)
2486       and     end_date        is null;
2487 
2488   cursor child_activities2 is
2489       select count(1)
2490       from  WF_ITEM_ACTIVITY_STATUSES WIAS, WF_PROCESS_ACTIVITIES WPA,
2491             WF_ITEMS WI
2492       where WIAS.ITEM_TYPE      = itemtype
2493       and   WIAS.ITEM_KEY       = WI.item_key
2494       and   WI.parent_item_type = l_parent_itemtype
2495       and   WI.parent_item_key  = l_parent_itemkey
2496       and  (WI.item_type <> itemtype OR WI.item_key <> itemkey )
2497       and   WI.end_date is null
2498       and   WIAS.PROCESS_ACTIVITY = WPA.INSTANCE_ID
2499       and   WPA.INSTANCE_LABEL = label
2500       and   wias.activity_status  in (wf_engine.eng_completed,
2501             wf_engine.eng_active);
2502 
2503   dummy varchar2(240);
2504   status varchar2(8);
2505   result varchar2(30);
2506   l_count number;
2507   l_defer varchar2(4000);
2508   l_childwaiting number;
2509   --Bug 14784055. Need to validate the activity LABEL is not too large
2510   ValTooLarge EXCEPTION;
2511   pragma exception_init(ValTooLarge, -01401);
2512   ValTooLargeNew EXCEPTION;
2513   pragma exception_init(ValTooLargeNew, -12899);
2514   l_module varchar2(20) := 'ContinueMasterFlow';
2515   l_activity_label varchar2(50);
2516 
2517 begin
2518   --
2519   -- select parent details
2520   --
2521   select  parent_item_type,   parent_item_key, parent_context
2522   into    l_parent_itemtype, l_parent_itemkey, l_parent_context
2523   from    wf_items
2524   where   item_type = ContinueMasterFlow.itemtype
2525   and     item_key  = ContinueMasterFlow.itemkey;
2526 
2527   select  instance_label
2528   into    label
2529   from    wf_process_activities
2530   where   instance_id     = actid;
2531 
2532   -- Check if this is the first or second execution of this activity.
2533   -- First -> result_code will be null (really null).
2534   -- Second -> result_code will be '#NULL' (set that way by execution 1).
2535   Wf_Item_Activity_Status.Result(itemtype, itemkey, actid, status, result);
2536 
2537   if (result = wf_engine.eng_null) then
2538     -- Second execution.
2539     -- ContinueFlow() completed and was deferred.
2540     resultout := wf_engine.eng_completed||':'||wf_engine.eng_null;
2541     return;
2542   else
2543     --First execution.
2544 
2545     -- lock the parent item, so only one child can execute this at the time.
2546     select  item_key
2547     into    dummy
2548     from    wf_items
2549     where   item_type    = l_parent_itemtype
2550     and     item_key     = l_parent_itemkey
2551     for update;
2552 
2553     --Nulling out the #LBL_ attribute, if it does not exist, we will check the
2554     --parent flow for #WAITFORDETAIL to see if we can create the #LBL_
2555     --attribute.
2556     l_activity_label := '#LBL_'||waiting_activity;
2557     if NOT (WF_ENGINE.SetItemAttrText2(ContinueMasterFlow.itemtype,
2558                                        ContinueMasterFlow.itemkey,
2559                                        l_activity_label,
2560                                        NULL)) then
2561       l_childwaiting := WF_ENGINE.GetItemAttrNumber(
2562                           l_parent_itemtype, l_parent_itemkey,
2563                           '#WAITFORDETAIL', TRUE);
2564       if (l_childwaiting is NOT NULL) then
2565         --The parent has #WAITFORDETAIL, so we can create the #LBL_ attribute
2566         WF_ENGINE.AddItemAttr(ContinueMasterFlow.itemtype,
2567                               ContinueMasterFlow.itemkey,
2568                               l_activity_label, NULL);
2569     else --#WAITFORDETAIL does not exist in the parent, so we will fall back
2570            --to old code path.
2571         --  If parent_context is not set then there is one WaitForFlow Activity
2572         --  use original cursor.
2573 
2574         if (l_parent_context is null) then
2575           open   child_flows2;
2576           fetch  child_flows2 into number_active;
2577           close  child_flows2;
2578         else
2579           open child_flows_mwf;
2580           fetch  child_flows_mwf into number_active;
2581           close  child_flows_mwf;
2582         end if;
2583 
2584         if (number_active < 1) then
2585           begin
2586             wf_engine.CompleteActivity(l_parent_itemtype,l_parent_itemkey,
2587                                        waiting_activity,wf_engine.eng_null);
2588             resultout := wf_engine.eng_null;
2589           exception
2590             when OTHERS then
2591               if ( wf_core.error_name = 'WFENG_NOT_NOTIFIED' ) then
2592                 wf_core.clear;
2593                 ContinueMasterFlow.resultout := wf_engine.eng_null;
2594               else
2595                 raise;
2596               end if;
2597           end;
2598         else
2599           open   child_activities2;
2600           fetch  child_activities2 into number_complete;
2601           close  child_activities2;
2602 
2603           begin
2604             if number_active = number_complete then
2605               wf_engine.CompleteActivity(l_parent_itemtype,l_parent_itemkey,
2606                                          waiting_activity,wf_engine.eng_null);
2607             end if;
2608             resultout := wf_engine.eng_null;
2609 
2610           exception
2611             when others then
2612               --
2613               -- If call to CompleteActivity cannot find activity, return
2614               -- null and wait for master flow
2615               --
2616               if ( wf_core.error_name = 'WFENG_NOT_NOTIFIED' ) then
2617                   wf_core.clear;
2618                   ContinueMasterFlow.resultout := wf_engine.eng_null;
2619               else
2620                   raise;
2621               end if;
2622           end;
2623         end if; -- number_active was more than 0
2624         return; -- done with old code path
2625 
2626       end if; --#WAITFORDETAIL exists in the parent
2627     end if; --#LBL_ is not null
2628 
2629     -- If we come to here, we must be progressing in the new code path.
2630     --Now we will try to decrement the corresponding #CNT_ attribute if it
2631     --exists, and will create it with a value of 0 if it does not yet exist.
2632     l_activity_label := '#CNT_'||waiting_activity;
2633     l_count := WF_ENGINE.AddToItemAttrNumber(l_parent_itemtype,
2634                                              l_parent_itemkey,
2635                                              l_activity_label, -1);
2636 
2637     if (l_count is NULL) then
2638       WF_ENGINE.AddItemAttr(itemtype=>l_parent_itemtype,
2639                             itemkey=>l_parent_itemkey,
2640                             aname=>l_activity_label,
2641                             number_value=>l_childwaiting - 1);
2642     elsif (l_count < 1) then
2643       begin
2644         wf_engine.CompleteActivity(l_parent_itemtype,l_parent_itemkey,
2645                                       waiting_activity,wf_engine.eng_null);
2646       exception
2647         when OTHERS then
2648           if ( wf_core.error_name = 'WFENG_NOT_NOTIFIED' ) then
2649             wf_core.clear;
2650             ContinueMasterFlow.resultout := wf_engine.eng_null;
2651           else
2652             raise;
2653           end if;
2654         end;
2655     end if;
2656 
2657     l_defer := WF_ENGINE.GetActivityAttrText(itemtype, itemkey, actid,
2658                                                '#HINT', TRUE);
2659 
2660     --If #HINT is not set to 'NO_DEFER', or is null we will set the
2661     --threshold to cause the next activity to defer.
2662     if ((l_defer is null) or (l_defer <> 'NO_DEFER')) then
2663       resultout := wf_engine.eng_deferred;
2664     else
2665       resultout := wf_engine.eng_null;
2666     end if;
2667 
2668   end if; --First execution
2669 
2670 exception
2671     when ValTooLarge OR ValTooLargeNew then
2672       Wf_Core.Context('WF_ENGINE', l_module, ContinueMasterFlow.itemtype,
2673                       ContinueMasterFlow.itemkey);
2674       WF_CORE.Token('LABEL', l_activity_label);
2675       WF_CORE.Token('LENGTH', 30);
2676       WF_CORE.Raise('WFENG_LABEL_TOO_LARGE');
2677 
2678     when others then
2679         wf_core.context('Wf_Standard', 'ContinueMasterFlow',
2680                         itemtype, itemkey, to_char(actid), waiting_activity);
2681         raise;
2682 end ContinueMasterFlow;
2683 
2684 
2685 
2686 
2687 -- -------------------------------------------------------------------
2688 -- InitializeErrors
2689 --   checks if an item attribute for Workflow administrator exists in
2690 --   the item that just errored out. If it does, then it uses this
2691 --   role to send notifications to, overriding the default role
2692 --   in this item.
2693 -- NOTE: the item attibute in the workflow-in-error must have an
2694 -- internal name of WF_ADMINISTRATOR.
2695 --
2696 -- Called by default error process.
2697 -- -------------------------------------------------------------------
2698 PROCEDURE InitializeErrors(     itemtype        VARCHAR2,
2699                                 itemkey         VARCHAR2,
2700                                 actid           NUMBER,
2701                                 funcmode        VARCHAR2,
2702                                 result          OUT NOCOPY VARCHAR2 ) IS
2703 
2704   l_error_itemtype      VARCHAR2(8);
2705   l_error_itemkey       VARCHAR2(240);
2706   l_error_name          VARCHAR2(30);
2707   l_error_msg           VARCHAR2(2000);
2708   l_timeout             PLS_INTEGER;
2709   l_administrator       VARCHAR2(100);
2710 
2711 BEGIN
2712 
2713   IF (funcmode = 'RUN') THEN
2714 
2715     --
2716     -- Get the type and the key of the process that errored out
2717     -- these were set in the erroring out process by Execute_Error_Process
2718     --
2719     l_error_itemkey := WF_ENGINE.GetItemAttrText(
2720                                 itemtype        => itemtype,
2721                                 itemkey         => itemkey,
2722                                 aname           => 'ERROR_ITEM_KEY' );
2723     l_error_itemtype := WF_ENGINE.GetItemAttrText(
2724                                 itemtype        => itemtype,
2725                                 itemkey         => itemkey,
2726                                 aname           => 'ERROR_ITEM_TYPE' );
2727 
2728     --
2729     -- Check if the workflow administrator exists
2730     -- If it does, then assign the notification to this role
2731     --
2732 
2733         begin
2734               --if this item type doesnt exist an exception is raised.
2735               l_administrator := WF_ENGINE.GetItemAttrText(
2736                                 itemtype        => l_error_itemtype,
2737                                 itemkey         => l_error_itemkey,
2738                                 aname           => 'WF_ADMINISTRATOR' );
2739 
2740               --<rwunderl:2775132> Put first assignemt in their own block
2741               --in case DEFAULT_RESET_ERROR_NTF does not exist.
2742               begin
2743                 wf_engine.AssignActivity(itemtype,itemkey,
2744                                          'DEFAULT_RESET_ERROR_NTF',
2745                                          l_administrator);
2746               exception
2747                 when OTHERS then
2748                   null; --We only null this exception because the parent
2749                         --block nulls the expeption.
2750               end;
2751 
2752               wf_engine.AssignActivity(itemtype,itemkey,'RETRY_ONLY_NTF',
2753                                          l_administrator);
2754 
2755         exception
2756           when others then null;
2757         end;
2758 
2759     --
2760     -- Check if a timeout value exists
2761     -- If it does, then set the error timeout
2762     --
2763 
2764         begin
2765               --if this item type doesnt exist an exception is raised.
2766               l_timeout  := WF_ENGINE.GetItemAttrNumber(
2767                                 itemtype        => l_error_itemtype,
2768                                 itemkey         => l_error_itemkey,
2769                                 aname           => 'ERROR_TIMEOUT' );
2770               wf_engine.SetItemAttrNumber(itemtype,itemkey,'TIMEOUT_VALUE',l_timeout);
2771               exception
2772                  when others then null;
2773         end;
2774 
2775      result := wf_engine.eng_completed;
2776   ELSIF (funcmode = 'CANCEL') THEN
2777      result := wf_engine.eng_completed;
2778   END IF;
2779 EXCEPTION
2780   WHEN OTHERS THEN
2781     WF_CORE.Context('WF_STANDARD', 'InitializeErrors',
2782                       itemtype, itemkey, actid, funcmode);
2783     RAISE;
2784 END InitializeErrors;
2785 
2786 -- -------------------------------------------------------------------
2787 -- CheckErrorActive
2788 --   checks if an error is still active and returns TRUE/FALSE.
2789 --   Use this in an error process to exit out of a timeout loop
2790 -- Called by default error process.
2791 -- -------------------------------------------------------------------
2792 PROCEDURE CheckErrorActive(     itemtype        IN VARCHAR2,
2793                                 itemkey         IN VARCHAR2,
2794                                 actid           IN NUMBER,
2795                                 funcmode        IN VARCHAR2,
2796                                 result          OUT NOCOPY VARCHAR2 ) IS
2797 
2798   l_error_itemtype      VARCHAR2(8);
2799   l_error_itemkey       VARCHAR2(240);
2800   l_error_actid         NUMBER;
2801   status                VARCHAR2(30);
2802 
2803   cursor activity_status (litemtype varchar2, litemkey  varchar2, lactid number ) is
2804   select WIAS.ACTIVITY_STATUS
2805   from WF_ITEM_ACTIVITY_STATUSES WIAS
2806   where WIAS.ITEM_TYPE = litemtype
2807   and WIAS.ITEM_KEY = litemkey
2808   and WIAS.PROCESS_ACTIVITY = lactid;
2809 
2810 
2811 BEGIN
2812 
2813   IF (funcmode = 'RUN') THEN
2814 
2815     --
2816     -- Get the type and the key of the process that errored out
2817     -- these were set in the erroring out process by Execute_Error_Process
2818     --
2819     l_error_itemkey := WF_ENGINE.GetItemAttrText(
2820                                 itemtype        => itemtype,
2821                                 itemkey         => itemkey,
2822                                 aname           => 'ERROR_ITEM_KEY' );
2823     l_error_itemtype := WF_ENGINE.GetItemAttrText(
2824                                 itemtype        => itemtype,
2825                                 itemkey         => itemkey,
2826                                 aname           => 'ERROR_ITEM_TYPE' );
2827 
2828     l_error_actid := WF_ENGINE.GetItemAttrText(
2829                                 itemtype        => itemtype,
2830                                 itemkey         => itemkey,
2831                                 aname           => 'ERROR_ACTIVITY_ID' );
2832 
2833     open activity_status(l_error_itemtype, l_error_itemkey, l_error_actid);
2834     fetch activity_status into status;
2835     close activity_status;
2836 
2837     if status = 'ERROR' then
2838        result:='T';
2839     else
2840        result:='F';
2841     end if;
2842 
2843   END IF;
2844 
2845 EXCEPTION
2846   WHEN OTHERS THEN
2847     WF_CORE.Context('WF_STANDARD', 'CheckErrorActive',
2848                       itemtype, itemkey, actid, funcmode);
2849     RAISE;
2850 END CheckErrorActive;
2851 -- -------------------------------------------------------------------
2852 -- InitializeEventError
2853 --   Called by the  Error Process, this sets up various
2854 --   item attributes.
2855 -- -------------------------------------------------------------------
2856 PROCEDURE InitializeEventError( itemtype        VARCHAR2,
2857                                 itemkey         VARCHAR2,
2858                                 actid           NUMBER,
2859                                 funcmode        VARCHAR2,
2860                                 resultout          OUT NOCOPY VARCHAR2 ) IS
2861   l_event_t		wf_event_t;
2862   l_error_name		varchar2(240);
2863   l_error_type		varchar2(240);
2864   l_error_message	varchar2(2000);
2865   l_error_stack		varchar2(2000);
2866   l_subscription 	RAW(16);
2867   l_url                 varchar2(4000);
2868   l_eventdataurl        varchar2(4000);
2869   l_source		varchar2(8);
2870 
2871 
2872 begin
2873 
2874   IF (funcmode = 'RUN') THEN
2875     --
2876     -- Get the Event Item Attribute
2877     --
2878 
2879     l_event_t := WF_ENGINE.GetItemAttrEvent(
2880                                 itemtype        => itemtype,
2881                                 itemkey         => itemkey,
2882                                 name           => 'EVENT_MESSAGE' );
2883     --
2884     -- Get the Errored Subscription GUID
2885     --
2886     l_subscription := l_event_t.GetErrorSubscription();
2887 
2888     --
2889     -- Get the Error Type from the Item Attribute - set by Engine
2890     --
2891     l_error_type := WF_ENGINE.GetItemAttrText(
2892 				itemtype        => itemtype,
2893                                 itemkey         => itemkey,
2894                                 aname           => 'ERROR_TYPE');
2895     --
2896     -- If the error type is null, this must be an UNEXPECTED event
2897     --
2898     IF l_error_type IS NULL THEN
2899       l_error_type := 'UNEXPECTED';
2900       wf_engine.SetItemAttrText(itemtype        => itemtype,
2901                                 itemkey       => itemkey,
2902                                 aname         => 'ERROR_TYPE',
2903                                 avalue        => l_error_type);
2904     END IF;
2905 
2906     --
2907     -- Determine if this event is LOCAL or EXTERNAL
2908     --
2909     if l_subscription is not null then
2910       -- If a subscription found, look at its source
2911       select source_type into l_source
2912       from wf_event_subscriptions
2913       where guid = l_subscription;
2914 
2915       if l_source = 'ERROR' then
2916 	l_source := 'LOCAL';
2917       end if;
2918     else
2919       -- Since no subscription found, look at from agent details
2920       begin
2921         select 'LOCAL' into l_source
2922         from wf_systems ws
2923         where ws.guid = hextoraw(wf_core.translate('WF_SYSTEM_GUID'))
2924         and   ws.name = nvl(l_event_t.GetFromAgent().GetSystem(),ws.name);
2925       exception
2926         when no_data_found then
2927           l_source := 'EXTERNAL';
2928       end;
2929     end if;
2930 
2931     --
2932     -- Get the Error Message, or set it if UNEXPECTED
2933     --
2934     l_error_message := substr(l_event_t.GetErrorMessage(),1,2000);
2935     IF (l_error_message is null) THEN
2936       -- Bug 10126673: Show 'NO_ERROR_MESSAGE' message token when error message is null
2937       l_error_message := wf_core.translate('NO_ERROR_MESSAGE');
2938     END IF;
2939 
2940     -- Get the Error Stack
2941     l_error_stack := substr(l_event_t.GetErrorStack(),1,2000);
2942 
2943     -- Get the Errored Subscription GUID
2944     l_subscription := l_event_t.GetErrorSubscription();
2945 
2946     -- Generate the URL
2947     wf_event_html.GetFWKEvtSubscriptionUrl(l_subscription, l_url);
2948     l_eventdataurl := wf_oam_util.GetViewXMLURL(p_eventattribute => 'EVENT_MESSAGE',
2949                                                 p_itemtype => itemtype,
2950                                                 p_itemkey => itemkey);
2951 
2952     -- Set the Item Attributes
2953 
2954     wf_engine.SetItemAttrText(itemtype        => itemtype,
2955                                 itemkey       => itemkey,
2956                                 aname         => 'ERROR_MESSAGE',
2957                                 avalue        => l_error_message);
2958 
2959     wf_engine.SetItemAttrText(itemtype        => itemtype,
2960                                 itemkey       => itemkey,
2961                                 aname         => 'ERROR_STACK',
2962 				avalue	      => l_error_stack);
2963 
2964     -- Set the PL/SQL Document for the Event Details
2965     wf_engine.SetItemAttrText(itemtype        => itemtype,
2966                                 itemkey       => itemkey,
2967                                 aname         => 'EVENT_DETAILS',
2968 				avalue        => 'PLSQL:WF_STANDARD.EVENTDETAILS/'||ItemType||':'||ItemKey);
2969 
2970     wf_engine.SetItemAttrText(itemtype      => itemtype,
2971                               itemkey       => itemkey,
2972                               aname         => 'ERROR_DETAILS',
2973                               avalue        => 'PLSQL:WF_STANDARD.ErrorDetails/'||ItemType||':'||ItemKey);
2974 
2975     wf_engine.SetItemAttrText(itemtype      => itemtype,
2976                               itemkey       => itemkey,
2977                               aname         => 'SUBSCRIPTION_DETAILS',
2978                               avalue        => 'PLSQL:WF_STANDARD.SubscriptionDetails/'||ItemType||':'||ItemKey);
2979 
2980     -- Set the Value for the Error Subscription URL
2981     wf_engine.SetItemAttrText(itemtype        => itemtype,
2982                                 itemkey       => itemkey,
2983                                 aname         => 'EVENT_SUBSCRIPTION',
2984                                 avalue        => l_url);
2985     -- Set the Value for the Event Data URL
2986     wf_engine.SetItemAttrText(itemtype        => itemtype,
2987                                 itemkey       => itemkey,
2988                                 aname         => 'EVENT_DATA_URL',
2989 				avalue        => l_eventdataurl);
2990 
2991     IF l_error_type IN ('ERROR','UNEXPECTED') THEN
2992       IF l_source = 'LOCAL' THEN
2993 	resultout := 'EVENT_ERROR';
2994       ELSE
2995         resultout := 'EVENT_EXTERNAL_ERROR';
2996       END IF;
2997     ELSE
2998 	resultout := 'EVENT_WARNING';
2999     END IF;
3000 
3001   ELSIF (funcmode = 'CANCEL') THEN
3002      resultout := wf_engine.eng_completed;
3003   END IF;
3004 EXCEPTION
3005   WHEN OTHERS THEN
3006     WF_CORE.Context('WF_STANDARD', 'InitializeEventError',
3007                       itemtype, itemkey, actid, funcmode);
3008     RAISE;
3009 END InitializeEventError;
3010 -- --------------------------------------------------------------------
3011 -- EventDetails
3012 --   PL/SQL Document for Event Attributes
3013 -- --------------------------------------------------------------------
3014 procedure EventDetails   ( document_id   in varchar2,
3015                            display_type  in varchar2,
3016                            document      in out nocopy varchar2,
3017                            document_type in out nocopy varchar2) IS
3018 
3019   ItemType	varchar2(30);
3020   ItemKey	varchar2(30);
3021 
3022   l_to_agent	varchar2(60);
3023   l_to_system	varchar2(60);
3024   l_from_agent	varchar2(60);
3025   l_from_system	varchar2(60);
3026   l_priority	varchar2(10);
3027   l_send_date	date;
3028   l_send_date_text	varchar2(60);
3029   l_receive_date date;
3030   l_receive_date_text	varchar2(60);
3031 
3032   i		pls_integer;
3033 
3034   l_event_t	wf_event_t;
3035   l_parmlist_t	wf_parameter_list_t;
3036   l_cells       wf_notification.tdType;
3037   j             number;
3038   l_result      varchar2(32000);
3039 
3040 begin
3041 
3042   -- parse document_id for the ':' dividing item type name from item key value
3043   -- document_id value will take the form <ITEMTYPE>:<ITEMKEY> starting with
3044   -- release 2.5
3045   ItemType := nvl(substr(document_id, 1, instr(document_id,':')-1),'WFERROR');
3046   ItemKey  := substr(document_id
3047 		, instr(document_id,':')+1);
3048 
3049 
3050 
3051   l_event_t := wf_engine.GetItemAttrEvent(
3052                                 itemtype        => itemtype,
3053                                 itemkey         => itemkey,
3054                                 name            => 'EVENT_MESSAGE' );
3055 
3056   --
3057   -- Get the Agent Details, we don't want any errors if the Agent
3058   -- didn't get populated with anything
3059   --
3060   if l_event_t.To_Agent is not null then
3061 	l_to_agent := l_event_t.GetToAgent().GetName();
3062 	l_to_system := l_event_t.GetToAgent().GetSystem();
3063   end if;
3064 
3065   if l_event_t.From_Agent is not null then
3066 	l_from_agent := l_event_t.GetFromAgent().GetName();
3067 	l_from_system := l_event_t.GetFromAgent().GetSystem();
3068   end if;
3069 
3070   --
3071   -- Get any date values and format if required
3072   --
3073   l_send_date := l_event_t.GetSendDate();
3074 
3075   IF l_send_date IS NOT NULL THEN
3076 	l_send_date_text := WF_NOTIFICATION_UTIL.GetCalendarDate(-1, l_send_date, null, true);
3077   END IF;
3078 
3079   l_receive_date := l_event_t.GetReceiveDate();
3080 
3081   IF l_receive_date IS NOT NULL THEN
3082 	l_receive_date_text := WF_NOTIFICATION_UTIL.GetCalendarDate(-1, l_receive_date, null, true);
3083   END IF;
3084 
3085   --
3086   -- Get the Priority
3087   --
3088   l_priority := l_event_t.GetPriority();
3089 
3090   --
3091   -- Build up the PL/SQL Document depending on the User Mail Preference
3092   --
3093   -- bug 6955474
3094   -- Using WF_NOTIFICATION.NTF_Table API to maintain consistency with BLAF
3095   --
3096   -- Build the Table
3097   if (display_type = wf_notification.doc_html) then
3098     i := 1;
3099     l_cells(i) := wf_core.translate('WF_EVENT_HEADING');
3100     l_cells(i) := 'S30%:'||l_cells(i);
3101 
3102     i := i + 1;
3103     l_cells(i) := wf_core.translate('WF_VALUE');
3104     l_cells(i) := 'S70%:'||l_cells(i);
3105 
3106     i := i + 1;
3107     l_cells(i) := 'S:'||wf_core.translate('WF_EVENT_NAME');
3108     i := i + 1;
3109     l_cells(i) := 'S:'||nvl(l_event_t.GetEventName(),'&'||'nbsp');
3110 
3111     i := i + 1;
3112     l_cells(i) := 'S:'||wf_core.translate('WF_EVENT_KEY');
3113     i := i + 1;
3114     l_cells(i) := 'S:'||nvl(l_event_t.GetEventKey(),'&'||'nbsp');
3115 
3116     i := i + 1;
3117     l_cells(i) := 'S:'||wf_core.translate('WF_TO_AGENT_NAME');
3118     i := i + 1;
3119     l_cells(i) := 'S:'||l_to_agent;
3120     i := i + 1;
3121     l_cells(i) := 'S:'||wf_core.translate('WF_TO_AGENT_SYSTEM');
3122     i := i + 1;
3123     l_cells(i) := 'S:'||l_to_system;
3124 
3125     i := i + 1;
3126     l_cells(i) := 'S:'||wf_core.translate('WF_FROM_AGENT_NAME');
3127     i := i + 1;
3128     l_cells(i) := 'S:'||l_from_agent;
3129     i := i + 1;
3130     l_cells(i) := 'S:'||wf_core.translate('WF_FROM_AGENT_SYSTEM');
3131     i := i + 1;
3132     l_cells(i) := 'S:'||l_from_system;
3133 
3134     i := i + 1;
3135     l_cells(i) := 'S:'||wf_core.translate('WF_SEND_DATE');
3136     i := i + 1;
3137     l_cells(i) := 'S:<BDO DIR="LTR">'||l_send_date_text||'</BDO>';
3138 
3139     i := i + 1;
3140     l_cells(i) := 'S:'||wf_core.translate('WF_RECEIVE_DATE');
3141     i := i + 1;
3142     l_cells(i) := 'S:<BDO DIR="LTR">'||l_receive_date_text||'</BDO>';
3143 
3144     i := i + 1;
3145     l_cells(i) := 'S:'||wf_core.translate('WF_PRIORITY');
3146     i := i + 1;
3147     l_cells(i) := 'S:'||l_priority;
3148 
3149     i := i + 1;
3150     l_cells(i) := 'S:'||wf_core.translate('WF_CORRELATION');
3151     i := i + 1;
3152     l_cells(i) := 'S:'||nvl(l_event_t.GetCorrelationId(),'&'||'nbsp');
3153 
3154   else
3155     l_result := Wf_Core.Newline||rpad(wf_core.translate('WF_EVENT_HEADING'),40)
3156  		||wf_core.translate('WF_VALUE')||Wf_Core.Newline;
3157 
3158     l_result := l_result||rpad(wf_core.translate('WF_EVENT_NAME'),40)||
3159 		l_event_t.GetEventName()||Wf_Core.Newline||
3160 		rpad(wf_core.translate('WF_EVENT_KEY'),40)||
3161 		l_event_t.GetEventKey()||Wf_Core.Newline||
3162 		rpad(wf_core.translate('WF_FROM_AGENT_NAME'),40)||
3163 		l_From_Agent||Wf_Core.Newline||
3164 		rpad(wf_core.translate('WF_FROM_AGENT_SYSTEM'),40)||
3165 		l_From_System||Wf_Core.Newline||
3166 		rpad(wf_core.translate('WF_TO_AGENT_NAME'),40)||
3167 		l_To_Agent||Wf_Core.Newline||
3168 		rpad(wf_core.translate('WF_TO_AGENT_SYSTEM'),40)||
3169                 l_To_System||Wf_Core.Newline||
3170 		rpad(wf_core.translate('WF_PRIORITY'),40)||
3171 		l_Priority||Wf_Core.Newline||
3172 		rpad(wf_core.translate('WF_SEND_DATE'),40)||
3173 		l_send_date_text||Wf_Core.Newline||
3174 		rpad(wf_core.translate('WF_RECEIVE_DATE'),40)||
3175                 l_receive_date_text||Wf_Core.Newline||
3176 		rpad(wf_core.translate('WF_CORRELATION'),40)||
3177                 l_event_t.GetCorrelationId()||Wf_Core.Newline;
3178 
3179   end if;
3180 
3181   -- Display the Parameter List
3182   l_parmlist_t := l_event_t.getParameterList();
3183   if (l_parmlist_t is not null) then
3184     j := l_parmlist_t.FIRST;
3185     while (j <= l_parmlist_t.LAST) loop
3186       if (display_type = wf_notification.doc_html) then
3187         i := i + 1;
3188         l_cells(i) := 'S:'||wf_core.translate('WF_PARAMETER')||' : '||l_parmlist_t(j).getName();
3189 
3190         i := i + 1;
3191         l_cells(i) :=
3192 'S:'||substr(nvl(l_parmlist_t(j).getValue(),'&'||'nbsp'),1,20);
3193       else
3194 	l_result := l_result||rpad(wf_core.translate('WF_PARAMETER')
3195 		||l_parmlist_t(j).getName(),40)
3196 		||substr(l_parmlist_t(j).getValue(),1,20)||Wf_Core.Newline;
3197       end if;
3198       j := l_parmlist_t.NEXT(j);
3199     end loop;
3200   end if;
3201 
3202   if (display_type = wf_notification.doc_html) then
3203     document_type := wf_notification.doc_html;
3204     wf_notification.NTF_Table(cells => l_cells,
3205                               col   => 2,
3206                               type  => 'H',
3207                               rs    => l_result);
3208     -- Display title
3209     l_result := '<table  width="100%" border="0" cellspacing="1" cellpadding="1">' ||
3210                 '<tr><td class="x3w">'||wf_core.Translate('WFITD_EVENT_DETAILS')||
3211                 '</td></tr>'||'<tr><td>'||l_result||'</td></tr></table>';
3212 
3213   else
3214     document_type := wf_notification.doc_text;
3215   end if;
3216   document := l_result;
3217 
3218 exception
3219 when others then
3220 	wf_core.context('WF_STANDARD','EventDetails',document_id, display_type);
3221 	raise;
3222 end EventDetails;
3223 -- --------------------------------------------------------------------
3224 -- Retry Raise
3225 --   Executes command depending on notification response
3226 -- --------------------------------------------------------------------
3227 PROCEDURE RetryRaise	      ( itemtype in	varchar2,
3228                                 itemkey  in     varchar2,
3229                                 actid    in     number,
3230                                 funcmode in     varchar2,
3231                                 resultout out nocopy   varchar2 ) IS
3232 
3233   aname		varchar2(100);
3234   l_event_t	wf_event_t;
3235   l_toagent	wf_agent_t;
3236   l_skip_sub varchar2(300) := null;
3237   l_parameterList wf_parameter_list_t := null;
3238 
3239 begin
3240 
3241   IF (funcmode = 'RUN') THEN
3242 
3243      l_event_t := wf_engine.GetItemAttrEvent(
3244                                 itemtype        => itemtype,
3245                                 itemkey         => itemkey,
3246                                 name            => 'EVENT_MESSAGE' );
3247 
3248      aname := wf_engine.GetActivityAttrText(itemtype,
3249 						itemkey,
3250 						actid,
3251 						'COMMAND');
3252 
3253      -- Bug 4198975
3254      -- If the SKIP_ERROR_SUB is not null, then this parameber will
3255      -- be passed over to raise in all the cases.
3256      l_skip_sub := l_event_t.GETVALUEFORPARAMETER('SKIP_ERROR_SUB');
3257      if (l_skip_sub is not null) then
3258         l_parameterList := wf_parameter_list_t();
3259         wf_event.addParameterToList('SKIP_ERROR_SUB', l_skip_sub, l_parameterList);
3260      end if;
3261 
3262      IF aname = 'RAISE_KEY' THEN
3263        wf_event.raise(p_event_name => l_event_t.GetEventName(),
3264 			          p_event_key => l_event_t.GetEventKey(),
3265 			          p_parameters => l_parameterList);
3266 
3267      ELSIF aname = 'RAISE_KEY_DATA' THEN
3268        wf_event.raise(p_event_name => l_event_t.GetEventName(),
3269 			p_event_key => l_event_t.GetEventKey(),
3270 			p_event_data => l_event_t.GetEventData(),
3271 			p_parameters => l_parameterList);
3272 
3273      ELSIF aname = 'RAISE_KEY_DATA_PARAM' THEN
3274        wf_event.raise(l_event_t.GetEventName(),
3275 			l_event_t.GetEventKey(),
3276 			l_event_t.GetEventData(),
3277 			l_event_t.GetParameterList());
3278      ELSIF aname = 'ENQUEUE' THEN
3279        l_toagent := l_event_t.GetToAgent();
3280        l_event_t.SetPriority(-1); -- want this dequeued ASAP
3281        wf_event.enqueue(l_event_t, l_toagent);
3282      ELSE
3283        wf_core.raise('WFSQL_ARGS');
3284 
3285      END IF;
3286 
3287      resultout := wf_engine.eng_completed;
3288 
3289   ELSIF (funcmode = 'CANCEL') THEN
3290      resultout := wf_engine.eng_completed;
3291   END IF;
3292 
3293 EXCEPTION
3294   WHEN OTHERS THEN
3295     WF_CORE.Context('WF_STANDARD', 'RetryRaise',
3296                       itemtype, itemkey, actid, funcmode);
3297     RAISE;
3298 end RetryRaise;
3299 -- --------------------------------------------------------------------
3300 -- GetAgents
3301 --   Gets the Event Subscription Out and To Agent
3302 -- --------------------------------------------------------------------
3303 procedure GetAgents           ( itemtype in     varchar2,
3304                                 itemkey  in     varchar2,
3305                                 actid    in     number,
3306                                 funcmode in     varchar2,
3307                                 resultout out nocopy   varchar2)
3308 is
3309 
3310   --l_subguid      raw(16);
3311   l_subguid      varchar2(100);
3312   l_outagentattr varchar2(100);
3313   l_toagentattr  varchar2(100);
3314   l_outagentguid raw(16);
3315   l_toagentguid  raw(16);
3316   l_outagent     varchar2(100);
3317   l_toagent      varchar2(100);
3318 
3319   cursor c_agents is
3320   select out_agent_guid, to_agent_guid
3321   from   wf_event_subscriptions
3322   where  guid = l_subguid;
3323 
3324 begin
3325 
3326   IF (funcmode = 'RUN') THEN
3327 
3328      l_subguid := wf_engine.GetActivityAttrText(itemtype,
3329                                                 itemkey,
3330                                                 actid,
3331                                                 'SUB_GUID');
3332 
3333      l_outagentattr := wf_engine.GetActivityAttrText(itemtype,
3334                                                 itemkey,
3335                                                 actid,
3336                                                 'FROMAGENT');
3337 
3338      l_toagentattr := wf_engine.GetActivityAttrText(itemtype,
3339                                                 itemkey,
3340                                                 actid,
3341                                                 'TOAGENT');
3342 
3343      -- Get the Agent Guids
3344      open c_agents;
3345      fetch c_agents into l_outagentguid, l_toagentguid;
3346      close c_agents;
3347 
3348      if l_toagentguid is not null then
3349        -- Get the Out Agent in the agent@system format
3350        if l_outagentguid is not null then
3351          select wfa.name||'@'||wfs.name
3352          into l_outagent
3353          from wf_agents wfa, wf_systems wfs
3354          where wfa.guid = l_outagentguid
3355          and   wfa.system_guid = wfs.guid;
3356        end if;
3357 
3358        -- Get the To Agent in the agent@system format
3359        select wfa.name||'@'||wfs.name
3360        into l_toagent
3361        from wf_agents wfa, wf_systems wfs
3362        where wfa.guid = l_toagentguid
3363        and   wfa.system_guid = wfs.guid;
3364 
3365        -- Update the agent item attributes
3366        wf_engine.SetItemAttrText(itemtype => itemtype,
3367                                itemkey => itemkey,
3368                                aname => l_outagentattr,
3369 			       avalue => l_outagent);
3370 
3371        wf_engine.SetItemAttrText(itemtype => itemtype,
3372                                itemkey => itemkey,
3373                                aname => l_toagentattr,
3374                                avalue => l_toagent);
3375        resultout := 'T';
3376      else
3377        resultout := 'F';
3378      end if;
3379   ELSIF (funcmode = 'CANCEL') THEN
3380      resultout := wf_engine.eng_completed;
3381   END IF;
3382 
3383 EXCEPTION
3384   WHEN OTHERS THEN
3385     WF_CORE.Context('WF_STANDARD', 'GetAgents',
3386                       itemtype, itemkey, actid, funcmode);
3387     RAISE;
3388 end GetAgents;
3389 -- --------------------------------------------------------------------
3390 -- GetAckAgent
3391 --   Gets the Acknowledge To Agent based on the Event Message
3392 -- --------------------------------------------------------------------
3393 procedure GetAckAgent           ( itemtype in     varchar2,
3394                                 itemkey  in     varchar2,
3395                                 actid    in     number,
3396                                 funcmode in     varchar2,
3397                                 resultout out nocopy   varchar2)
3398 is
3399 
3400   l_event_t	wf_event_t;
3401   l_toagentattr varchar2(100);
3402   l_system      varchar2(30);
3403   l_agent       varchar2(30);
3404 
3405   cursor c_return_agent is
3406   select  wfa.name agent
3407   from  wf_systems wfs,
3408         wf_agents wfa
3409   where wfs.name = l_system
3410   and   wfa.status = 'ENABLED'
3411   and   wfa.direction = 'IN'
3412   and   wfa.name not in ('WF_ERROR','WF_DEFERRED');
3413 
3414 begin
3415 
3416   IF (funcmode = 'RUN') THEN
3417 
3418     l_event_t := wf_engine.GetActivityAttrEvent(
3419 					itemtype => itemtype,
3420 					itemkey  => itemkey,
3421 					actid    => actid,
3422 					name     => 'EVENTMESSAGE');
3423 
3424     l_toagentattr := wf_engine.GetActivityAttrText(itemtype,
3425                                                 itemkey,
3426                                                 actid,
3427                                                 'ACKTOAGENT');
3428 
3429     l_system := l_event_t.GetFromAgent().GetSystem();
3430 
3431     open c_return_agent;
3432     fetch c_return_agent into l_agent;
3433     close c_return_agent;
3434 
3435     if l_agent is not null then
3436       wf_engine.SetItemAttrText(itemtype => itemtype,
3437                                itemkey => itemkey,
3438                                aname => l_toagentattr,
3439                                avalue => l_agent||'@'||l_system);
3440     end if;
3441 
3442     resultout := wf_engine.eng_completed;
3443 
3444   ELSIF (funcmode = 'CANCEL') THEN
3445      resultout := wf_engine.eng_completed;
3446   END IF;
3447 
3448 EXCEPTION
3449   WHEN OTHERS THEN
3450     WF_CORE.Context('WF_STANDARD', 'GetAckAgent',
3451                       itemtype, itemkey, actid, funcmode);
3452     RAISE;
3453 end GetAckAgent;
3454 
3455 -- SubscriptionDetails
3456 --   PL/SQL Document to display subscription parameter details
3457 -- IN
3458 --   document_id
3459 --   display_type
3460 --   document
3461 --   document_type
3462 procedure SubscriptionDetails (document_id   in varchar2,
3463                                display_type  in varchar2,
3464                                document      in out nocopy varchar2,
3465                                document_type in out nocopy varchar2)
3466 is
3467   l_item_type    varchar2(10);
3468   l_item_key     varchar2(240);
3469   l_subscription raw(16);
3470   l_params       varchar2(4000);
3471   l_rule_func    varchar2(240);
3472   l_cells        wf_notification.tdType;
3473   l_cells2       wf_notification.tdType;
3474   i              pls_integer;
3475   j              pls_integer;
3476   l_document     varchar2(32000);
3477   l_sub_param_list wf_parameter_list_t;
3478   l_event_t      wf_event_t;
3479   l_result       varchar2(22000);
3480   l_result2      varchar2(10000);
3481   l_url          varchar2(500);
3482   l_sub_url      varchar2(1000);
3483   l_evt_url      varchar2(1000);
3484 begin
3485   l_item_type := nvl(substr(document_id, 1,
3486 instr(document_id,':')-1),'WFERROR');
3487   l_item_key  := substr(document_id, instr(document_id,':')+1);
3488 
3489   l_event_t := wf_engine.GetItemAttrEvent(itemtype => l_item_type,
3490                                           itemkey  => l_item_key,
3491                                           name     => 'EVENT_MESSAGE');
3492   l_subscription := l_event_t.GetErrorSubscription();
3493 
3494   if (l_subscription is not null) then
3495 
3496     SELECT parameters, java_rule_func
3497     INTO   l_params, l_rule_func
3498     FROM   wf_event_subscriptions
3499     WHERE  guid = l_subscription;
3500 
3501     l_sub_param_list := wf_event.GetParamListFromString(l_params);
3502 
3503     if (display_type = wf_notification.doc_html) then
3504       i := 1;
3505       l_cells(i) := 'S30%:'||wf_core.Translate('WF_PARAMETER');
3506 
3507       i := i + 1;
3508       l_cells(i) := 'S70%:'||wf_core.Translate('WF_VALUE');
3509     else
3510       l_result := Wf_Core.Newline||rpad(wf_core.Translate('WF_PARAMETER'), 40)
3511                   ||wf_core.translate('WF_VALUE')||Wf_Core.Newline;
3512     end if;
3513 
3514     -- Show all Subscription Parameters that are currently used as
3515     -- meta-data store for WS definition
3516     if (l_sub_param_list is not null) then
3517       j := l_sub_param_list.FIRST;
3518       while (j is not null) loop
3519         if (display_type = wf_notification.doc_html) then
3520           i := i + 1;
3521           l_cells(i) := 'S:'||l_sub_param_list(j).getName();
3522 
3523           i := i + 1;
3524           l_cells(i) := 'S:'||l_sub_param_list(j).getValue();
3525         else
3526           l_result := l_result||rpad(l_sub_param_list(j).getName(),40)||
3527                                 rpad(l_sub_param_list(j).getValue(),40)||wf_core.newline;
3528         end if;
3529         j := l_sub_param_list.NEXT(j);
3530       end loop;
3531     end if;
3532 
3533     -- Show Invoker Rule Function since it may be a Custom one extended from
3534     -- seeded. Also the Event Payload is WS input message
3535     l_evt_url := wf_engine.GetItemAttrText(itemtype => l_item_type,
3536                                            itemkey  => l_item_key,
3537                                            aname    => 'EVENT_DATA_URL');
3538     l_sub_url := wf_engine.GetItemAttrText(itemtype => l_item_type,
3539                                            itemkey  => l_item_key,
3540                                            aname    => 'EVENT_SUBSCRIPTION');
3541 
3542     if (display_type = wf_notification.doc_html) then
3543       i := i + 1;
3544       l_cells(i) := 'S:'||wf_core.Translate('WF_INOKER_RULE_FUNC');
3545       i := i + 1;
3546       l_cells(i) := 'S:'||l_rule_func;
3547 
3548       i := i + 1;
3549       l_cells(i) := 'S:'||wf_core.Translate('WF_WS_INPUT_MESG');
3550       i := i + 1;
3551       l_url := '<a href="'||l_evt_url||'" class="xd">'||wf_core.Translate('WF_CLICK_HERE')||'</a>';
3552       l_cells(i) := 'S:'||l_url;
3553 
3554       i := i + 1;
3555       l_cells(i) := 'S:'||wf_core.Translate('WF_SUBSCRIPTION_PAGE');
3556       i := i + 1;
3557       l_url := '<a href="'||l_sub_url||'" class="xd">'||wf_core.Translate('WF_CLICK_HERE')||'</a>';
3558       l_cells(i) := 'S:'||l_url;
3559 
3560       wf_notification.Ntf_Table(l_cells, 2, 'H', l_result);
3561 
3562       -- Display title "Web Service Details"
3563       l_result := '<table  width="100%" border="0" cellspacing="1" cellpadding="1">' ||
3564                 '<tr><td class="x3w">'||wf_core.Translate('WF_WEBSERVICE_DETAILS')||'</td></tr>'||
3565                 '<tr><td>'||l_result||'</td></tr></table>';
3566 
3567     else
3568       l_result := l_result||rpad(wf_core.Translate('WF_INOKER_RULE_FUNC'),40)||
3569                             rpad(l_rule_func,40)||wf_core.newline||
3570                             rpad(wf_core.Translate('WF_WS_INPUT_MESG'),40)||
3571                             rpad(l_evt_url,40)||wf_core.newline||
3572                             rpad(wf_core.Translate('WF_SUBSCRIPTION_PAGE'),40)||
3573                             rpad(l_sub_url,40)||wf_core.newline;
3574 
3575     end if;
3576   end if;
3577   document := l_result;
3578 exception
3579   when others then
3580     wf_core.context('WF_STANDARD', 'SubscriptionDetails', document_id);
3581     raise;
3582 end SubscriptionDetails;
3583 
3584 -- ErrorDetails
3585 --   PL/SQL Document to display event error details
3586 -- IN
3587 --   document_id
3588 --   display_type
3589 --   document
3590 --   document_type
3591 procedure ErrorDetails (document_id   in varchar2,
3592                         display_type  in varchar2,
3593                         document      in out nocopy varchar2,
3594                         document_type in out nocopy varchar2)
3595 is
3596   l_result     varchar2(32000);
3597   l_error_name varchar2(240);
3598   l_item_type  varchar2(30);
3599   l_item_key   varchar2(240);
3600   l_error_message varchar2(2000);
3601   l_error_stack   varchar2(2000);
3602   l_cells     wf_notification.tdType;
3603   i           pls_integer;
3604 begin
3605 
3606   l_item_type := nvl(substr(document_id, 1, instr(document_id,':')-1),'WFERROR');
3607   l_item_key  := substr(document_id, instr(document_id,':')+1);
3608 
3609   l_error_name := wf_engine.GetItemAttrText(itemtype => l_item_type,
3610                                             itemkey  => l_item_key,
3611                                             aname     => 'ERROR_NAME');
3612   l_error_message := wf_engine.GetItemAttrText(itemtype => l_item_type,
3613                                                itemkey  => l_item_key,
3614                                                aname     => 'ERROR_MESSAGE');
3615   l_error_stack := wf_engine.GetItemAttrText(itemtype => l_item_type,
3616                                              itemkey  => l_item_key,
3617                                              aname     => 'ERROR_STACK');
3618 
3619   if (display_type = wf_notification.doc_html) then
3620     document_type := wf_notification.doc_html;
3621 
3622     i := 1;
3623     if (l_error_name is not null) then
3624       l_cells(i) := 'E20%:'||wf_core.Translate('WFMON_ERROR_NAME');
3625       i := i + 1;
3626       l_cells(i) := 'S:'||l_error_name;
3627       i := i + 1;
3628     end if;
3629 
3630     l_cells(i) := 'E20%:'||wf_core.Translate('WFMON_ERROR_MESSAGE');
3631     i := i + 1;
3632     l_cells(i) := 'S:'||l_error_message;
3633 
3634     i := i + 1;
3635     l_cells(i) := 'E20%:'||wf_core.Translate('WFMON_ERROR_STACK');
3636     i := i + 1;
3637     l_cells(i) := 'S:'||l_error_stack;
3638 
3639     wf_notification.NTF_Table(cells => l_cells,
3640                               col   => 2,
3641                               type  => 'V',
3642                               rs    => l_result);
3643 
3644     -- Display title
3645     l_result := '<table  width="100%" border="0" cellspacing="1" cellpadding="1">' ||
3646                 '<tr><td class="x3w">'||wf_core.Translate('WF_ERROR_DETAILS') ||
3647                 '</td></tr>'||'<tr><td>'||l_result||'</td></tr></table>';
3648   else
3649     document_type := wf_notification.doc_text;
3650     l_result := rpad(wf_core.Translate('WFMON_ERROR_NAME'),40)||' : '||l_error_name||wf_core.newline||
3651                 rpad(wf_core.Translate('WFMON_ERROR_MESSAGE'),40)||' : '||l_error_message||wf_core.newline||
3652                 rpad(wf_core.Translate('WFMON_ERROR_STACK'),40)||' : '||l_error_stack||wf_core.newline;
3653   end if;
3654   document := l_result;
3655 exception
3656   when others then
3657     wf_core.context('WF_STANDARD', 'ErrorDetails', document_id);
3658     raise;
3659 end ErrorDetails;
3660 
3661 -- SubscriptionAction
3662 --   Returns Subscription's Action Code based on which a specific notification
3663 --   could be sent
3664 procedure SubscriptionAction(itemtype  in varchar2,
3665                              itemkey   in varchar2,
3666                              actid     in number,
3667                              funcmode  in varchar2,
3668                              resultout in out nocopy varchar2)
3669 is
3670   l_event_t      wf_event_t;
3671   l_subscription raw(16);
3672   l_action_code  varchar2(30);
3673 begin
3674 
3675   if (funcmode = 'RUN') then
3676     l_event_t := wf_engine.GetItemAttrEvent(itemtype => itemtype,
3677                                             itemkey  => itemkey,
3678                                             name     => 'EVENT_MESSAGE');
3679     l_subscription := l_event_t.GetErrorSubscription();
3680 
3681     SELECT action_code
3682     INTO   l_action_code
3683     FROM   wf_event_subscriptions
3684     WHERE  guid = l_subscription;
3685 
3686     if (l_action_code is not null) then
3687       resultout := wf_engine.eng_completed||':'||l_action_code;
3688     else
3689       resultout := wf_engine.eng_completed||':CUSTOM_RG';
3690     end if;
3691   elsif (funcmode = 'CANCEL') then
3692     resultout := wf_engine.eng_completed;
3693   end if;
3694 
3695 end SubscriptionAction;
3696 
3697 --
3698 -- InitializeErrorInfo
3699 --  ER 10177347: Called by the Error Process in the deferred notification
3700 --  response processing mode, this sets up various item attributes.
3701 -- IN
3702 --   itemtype  - item type
3703 --   itemkey   - item key
3704 --   actid     - process activity instance id
3705 --   funcmode  - execution mode
3706 -- OUT
3707 --   result    - 'NULL'
3708 procedure InitializeErrorInfo (itemtype  in  varchar2,
3709                                itemkey   in  varchar2,
3710                                actid     in  number,
3711                                funcmode  in  varchar2,
3712                                resultout out nocopy varchar2)
3713 is
3714 
3715   l_event_t		 wf_event_t;
3716   l_error_type		 varchar2(240);
3717   l_error_message	 varchar2(2000);
3718   l_error_stack		 varchar2(2000);
3719   l_parmlist_t	         wf_parameter_list_t;
3720 
3721 
3722   l_nid                  number;
3723   l_subject              WF_NOTIFICATIONS.SUBJECT%TYPE;
3724   l_messageType          WF_NOTIFICATIONS.MESSAGE_TYPE%TYPE;
3725   l_messageName          WF_NOTIFICATIONS.MESSAGE_NAME%TYPE;
3726   l_recipient            WF_LOCAL_ROLES.NAME%TYPE;
3727   l_recipient_dispname   WF_LOCAL_ROLES.DISPLAY_NAME%TYPE;
3728   l_responder            WF_LOCAL_ROLES.NAME%TYPE;
3729   l_responder_dispname   WF_LOCAL_ROLES.DISPLAY_NAME%TYPE;
3730   l_error_recipient      WF_LOCAL_ROLES.NAME%TYPE;
3731   l_subscription 	 RAW(16);
3732   l_url                  varchar2(4000);
3733 
3734 
3735 begin
3736 
3737   IF (funcmode = 'RUN') THEN
3738 
3739     -- Get the Event Item Attribute
3740     l_event_t := WF_ENGINE.GetItemAttrEvent(itemtype        => itemtype,
3741                                             itemkey         => itemkey,
3742                                             name            => 'EVENT_MESSAGE' );
3743 
3744     -- Get the Error Type from the Item Attribute - set by Engine
3745     l_error_type := WF_ENGINE.GetItemAttrText(itemtype      => itemtype,
3746                                               itemkey       => itemkey,
3747                                               aname         => 'ERROR_TYPE');
3748 
3749     -- If the error type is null, this must be an UNEXPECTED event
3750     IF l_error_type IS NULL THEN
3751       l_error_type := 'UNEXPECTED';
3752       wf_engine.SetItemAttrText(itemtype      => itemtype,
3753                                 itemkey       => itemkey,
3754                                 aname         => 'ERROR_TYPE',
3755                                 avalue        => l_error_type);
3756     END IF;
3757 
3758     l_error_message := substr(l_event_t.GetErrorMessage(),1,2000);
3759     IF (l_error_message is null) THEN
3760       l_error_message := wf_core.translate('NO_ERROR_MESSAGE');
3761     END IF;
3762 
3763     -- Get the Error Stack
3764     l_error_stack := substr(l_event_t.GetErrorStack(),1,2000);
3765 
3766     -- Get the Errored Subscription GUID
3767     l_subscription := l_event_t.GetErrorSubscription();
3768 
3769     -- Generate the URL
3770     wf_event_html.GetFWKEvtSubscriptionUrl(l_subscription, l_url);
3771 
3772 
3773     -- Set the Item Attributes
3774 
3775     wf_engine.SetItemAttrText(itemtype      => itemtype,
3776                               itemkey       => itemkey,
3777                               aname         => 'ERROR_MESSAGE',
3778                               avalue        => l_error_message);
3779 
3780     wf_engine.SetItemAttrText(itemtype      => itemtype,
3781                               itemkey       => itemkey,
3782                               aname         => 'ERROR_STACK',
3783 			      avalue	    => l_error_stack);
3784 
3785 
3786     -- Set the Value for the Error Subscription URL
3787     wf_engine.SetItemAttrText(itemtype      => itemtype,
3788                                 itemkey     => itemkey,
3789                                 aname       => 'EVENT_SUBSCRIPTION',
3790                                 avalue      => l_url);
3791 
3792 
3793     ---  Get notification id
3794     l_nid := l_event_t.getValueForParameter('NOTIFICATION_ID');
3795 
3796     select message_type, message_name, subject, recipient_role, responder
3797     into l_messageType, l_messageName, l_subject, l_recipient, l_responder
3798     from wf_notifications
3799     where notification_id = l_nid;
3800 
3801     l_responder_dispname := WF_DIRECTORY.GetRoleDisplayName(l_responder);
3802     l_recipient_dispname := WF_DIRECTORY.GetRoleDisplayName(l_recipient);
3803 
3804     wf_engine.SetItemAttrText(itemtype, itemkey, 'PARENT_NTF_ID', l_nid);
3805     wf_engine.SetItemAttrText(itemtype, itemkey, 'PARENT_NTF_SUBJECT', l_subject);
3806     wf_engine.SetItemAttrText(itemtype, itemkey, 'PARENT_NTF_MSG_TYPE', l_messageType);
3807     wf_engine.SetItemAttrText(itemtype, itemkey, 'PARENT_NTF_MSG_NAME', l_messageName);
3808     wf_engine.SetItemAttrText(itemtype, itemkey, 'PARENT_NTF_RECIPIENT_ROLE', l_recipient);
3809     wf_engine.SetItemAttrText(itemtype, itemkey, 'PARENT_NTF_RECIPIENT_DISPNAME', l_recipient_dispname);
3810     wf_engine.SetItemAttrText(itemtype, itemkey, 'PARENT_NTF_RESPONDER_ROLE', l_responder);
3811     wf_engine.SetItemAttrText(itemtype, itemkey, 'PARENT_NTF_RESPONDER_DISPNAME', l_responder_dispname);
3812 
3813 
3814     -- Get WF Admin Role to receive error notification
3815     select text
3816     into l_error_recipient
3817     from wf_resources
3818     where name = 'WF_ADMIN_ROLE'
3819     and language = userenv('LANG');
3820 
3821     -- If WF Admini Role is '*', then set the recipient as SYSADMIN
3822     if(l_error_recipient = '*') then
3823        l_error_recipient := 'SYSADMIN';
3824     end if;
3825 
3826     wf_engine.SetItemAttrText(itemtype, itemkey, 'ERROR_NTF_RECIPIENT_ROLE', l_error_recipient);
3827 
3828 
3829   ELSIF (funcmode = 'CANCEL') THEN
3830      resultout := wf_engine.eng_completed;
3831   END IF;
3832 
3833 
3834 end InitializeErrorInfo;
3835 
3836 
3837 --
3838 -- RetryEvent
3839 --  ER 10177347: Called by the Error Process, to re-enqueue
3840 --  the notification response message into WF_NOTIFICATION_IN queue
3841 -- IN
3842 --   itemtype  - item type
3843 --   itemkey   - item key
3844 --   actid     - process activity instance id
3845 --   funcmode  - execution mode
3846 -- OUT
3847 --   result    - 'NULL'
3848 procedure RetryEvent (itemtype  in  varchar2,
3849                       itemkey   in  varchar2,
3850                       actid     in  number,
3851                       funcmode  in  varchar2,
3852                       resultout out nocopy varchar2)
3853 IS
3854 
3855   l_event	wf_event_t;
3856   l_paramlist   wf_parameter_list_t := null;
3857   l_sysName     WF_SYSTEMS.NAME%TYPE := null;
3858   l_agent       wf_agent_t := null ;
3859 
3860 
3861 begin
3862 
3863     -- Get the Event Message Item Attribute
3864     l_event := wf_engine.GetItemAttrEvent(itemtype    =>  itemtype,
3865                                            itemkey    =>  itemkey,
3866                                            name       =>  'EVENT_MESSAGE' );
3867 
3868     l_agent := wf_agent_t(null, null);
3869     l_agent.name := 'WF_NOTIFICATION_IN';
3870     l_agent.SYSTEM := wf_event.local_system_name;
3871 
3872     -- enqueue the event message in to WF_NOTIFIOCATION_IN queue again
3873     wf_event_ojmstext_qh.enqueue( l_event,  l_agent);
3874 
3875 
3876 EXCEPTION
3877   WHEN OTHERS THEN
3878     WF_CORE.Context('WF_STANDARD', 'RetryEvent',
3879                       itemtype, itemkey, actid, funcmode);
3880     RAISE;
3881 
3882 end RetryEvent;
3883 
3884 
3885 --
3886 -- Validate_Response
3887 --  ER 10177347: --   Post-notification function to verify whether the parent
3888 --  notification is completed when the result string is 'RESOLVED'
3889 -- IN
3890 --   itemtype  - item type
3891 --   itemkey   - item key
3892 --   actid     - process activity instance id
3893 --   funcmode  - execution mode
3894 -- OUT
3895 --   result    - 'NULL'
3896 PROCEDURE Validate_Response (itemtype  in  varchar2,
3897                              itemkey   in  varchar2,
3898                              actid     in  number,
3899                              funcmode  in  varchar2,
3900                              resultout out nocopy varchar2)
3901 is
3902 
3903   l_event_t	wf_event_t;
3904   l_paramlist   wf_parameter_list_t := null;
3905   l_nid         number;
3906   l_user        WF_LOCAL_ROLES.NAME%TYPE;
3907   l_itemtype    WF_NOTIFICATIONS.MESSAGE_TYPE%TYPE;
3908   l_itemkey     WF_NOTIFICATIONS.ITEM_KEY%TYPE;
3909   l_context     WF_NOTIFICATIONS.CONTEXT%TYPE;
3910   l_actid       number;
3911   l_status      WF_ITEM_ACTIVITY_STATUSES.ACTIVITY_STATUS%TYPE;
3912   l_result      varchar2(20);
3913   l_err_nid     number;
3914 
3915   wf_incomplete_ntf exception;
3916 
3917 
3918 begin
3919 
3920 
3921     if(funcmode = 'VALIDATE') then
3922 
3923       l_event_t := wf_engine.GetItemAttrEvent(
3924                                 itemtype        => itemtype,
3925                                 itemkey         => itemkey,
3926                                 name            => 'EVENT_MESSAGE' );
3927 
3928       -- Get the parent notification id
3929       l_nid := l_event_t.getValueForParameter('NOTIFICATION_ID');
3930 
3931       -- Get the error notification id from Notification_Status() API by passing itemtype, itemkey and activity id
3932       WF_ITEM_ACTIVITY_STATUS.Notification_Status(itemtype, itemkey, actid, l_err_nid, l_user);
3933 
3934       l_result :=  Wf_Notification.GetAttrText(l_err_nid, 'RESULT');
3935 
3936       -- If the result attribute value is 'RESOLVED', then get the activity status of parent notification
3937       if( l_result = 'RESOLVED') then
3938 
3939          begin
3940 
3941 	    select message_type, item_key, context
3942 	    into l_itemtype,  l_itemkey, l_context
3943 	    from wf_notifications
3944 	    where notification_id = l_nid;
3945 
3946             -- extract the activity id
3947 	    l_actid := to_number(SubStr(l_context, instr(l_context,':',1,2)+1));
3948             WF_ITEM_ACTIVITY_STATUS.status(l_itemtype, l_itemkey, l_actid, l_status);
3949 
3950          exception
3951             when others then
3952               SELECT activity_status into l_status  FROM wf_item_activity_statuses WHERE notification_id = l_nid;
3953          end;
3954 
3955          -- close the error notification only if the parent notification activity is complete,
3956 	 -- otherwise raise the WFNTF_NOT_COMPLETE error on screen
3957          if(l_status = 'COMPLETE') then
3958 	    resultout := wf_engine.eng_completed;
3959          else
3960 	    raise wf_incomplete_ntf;
3961          end if;
3962 
3963       end if;
3964 
3965     end if;
3966 
3967 
3968 EXCEPTION
3969   WHEN wf_incomplete_ntf THEN
3970      WF_CORE.Context('WF_STANDARD', 'VALIDATE_RESPONSE',
3971                           itemtype, itemkey, actid, funcmode);
3972      wf_core.clear;
3973      Wf_Core.Token('NID', l_nid);
3974      Wf_Core.Raise('WFNTF_NOT_COMPLETE');
3975 
3976   WHEN OTHERS THEN
3977     WF_CORE.Context('WF_STANDARD', 'VALIDATE_RESPONSE',
3978                           itemtype, itemkey, actid, funcmode);
3979     RAISE;
3980 
3981 
3982 end VALIDATE_RESPONSE;
3983 
3984 
3985 END WF_STANDARD;