DBA Data[Home] [Help]

PACKAGE BODY: APPS.JTF_TASK_WF_UTIL

Source


1 PACKAGE BODY jtf_task_wf_util AS
2   /* $Header: jtftkwub.pls 120.4.12010000.3 2008/11/18 10:51:56 rkamasam ship $ */
3   FUNCTION do_notification(p_task_id IN NUMBER)
4     RETURN BOOLEAN IS
5     CURSOR c_task_flag(b_task_id jtf_tasks_b.task_id%TYPE) IS
6       SELECT tt.notification_flag
7            , ta.notification_flag
8         FROM jtf_task_types_b tt, jtf_tasks_b ta
9        WHERE ta.task_id = b_task_id AND ta.task_type_id = tt.task_type_id;
10 
11     l_type_notif_flag jtf_tasks_b.notification_flag%TYPE;
12     l_task_notif_flag jtf_tasks_b.notification_flag%TYPE;
13   BEGIN
14     ---
15     --- Check if notification flag is set on the Task or for the Task type
16     ---
17     OPEN c_task_flag(p_task_id);
18     FETCH c_task_flag INTO l_type_notif_flag, l_task_notif_flag;
19     IF c_task_flag%NOTFOUND THEN
20       CLOSE c_task_flag;
21       RETURN FALSE;
22     END IF;
23     CLOSE c_task_flag;
24 
25     IF l_type_notif_flag = 'Y' OR l_task_notif_flag = 'Y' THEN
26       RETURN TRUE;
27     ELSE
28       RETURN FALSE;
29     END IF;
30   END do_notification;
31 
32   FUNCTION wf_process(p_task_id IN NUMBER)
33     RETURN VARCHAR2 IS
34     CURSOR c_process(b_task_id jtf_tasks_b.task_id%TYPE) IS
35       SELECT tt.workflow_type || ',' || tt.workflow workflow
36         FROM jtf_task_types_b tt, jtf_tasks_b ta
37        WHERE ta.task_id = b_task_id AND ta.task_type_id = tt.task_type_id;
38 
39     l_workflow VARCHAR2(200);   --jtf_task_types_b.workflow%type; --Bug 4289436
40   BEGIN
41     ---
42     --- Find the name of the Workflow process to be run
43     ---
44     OPEN c_process(p_task_id);
45     FETCH c_process INTO l_workflow;
46     CLOSE c_process;
47 
48     IF (l_workflow IS NULL) OR(l_workflow = ',') THEN
49       l_workflow  := 'JTFTASK,TASK_WORKFLOW';
50     END IF;
51 
52     RETURN l_workflow;
53   END wf_process;
54 
55   FUNCTION get_resource_name(p_resource_type IN VARCHAR2, p_resource_id IN NUMBER)
56     RETURN VARCHAR2 IS
57     TYPE cur_typ IS REF CURSOR;
58 
59     c               cur_typ;
60     l_sql_statement VARCHAR2(500)                         := NULL;
61     l_resource_name jtf_tasks_b.source_object_name%TYPE   := NULL;
62     l_where_clause  jtf_objects_b.where_clause%TYPE       := NULL;
63 
64     -------------------------------------------------------------------------
65     -- Create a SQL statement for getting the resource name
66     -------------------------------------------------------------------------
67     CURSOR c_get_res_name(b_resource_type jtf_tasks_b.owner_type_code%TYPE) IS
68       SELECT where_clause
69            , 'SELECT ' || select_name || ' FROM ' || from_table || ' WHERE ' || select_id || ' = :RES'
70         FROM jtf_objects_vl
71        WHERE object_code = b_resource_type;
72   BEGIN
73     OPEN c_get_res_name(p_resource_type);
74     FETCH c_get_res_name INTO l_where_clause, l_sql_statement;
75     IF c_get_res_name%NOTFOUND THEN
76       CLOSE c_get_res_name;
77       RETURN NULL;
78     END IF;
79     CLOSE c_get_res_name;
80 
81     -- assign the value again so it is null-terminated, to avoid ORA-600 [12261]
82     l_sql_statement  := l_sql_statement;
83 
84     IF l_sql_statement IS NOT NULL THEN
85       IF l_where_clause IS NOT NULL THEN
86         l_sql_statement  := l_sql_statement || ' AND ' || l_where_clause;
87       END IF;
88 
89       OPEN c FOR l_sql_statement USING p_resource_id;
90       FETCH c INTO l_resource_name;
91       CLOSE c;
92 
93       RETURN l_resource_name;
94     ELSE
95       RETURN NULL;
96     END IF;
97   EXCEPTION
98     WHEN OTHERS THEN
99       RETURN NULL;
100   END get_resource_name;
101 
102   FUNCTION check_backcomp(p_itemtype IN VARCHAR2)
103     RETURN VARCHAR2 IS
104     l_type     VARCHAR2(100);
105     l_subtype  VARCHAR2(100);
106     l_format   VARCHAR2(100);
107     e_wf_error EXCEPTION;
108     PRAGMA EXCEPTION_INIT(e_wf_error, -20002);
109   BEGIN
110     ---
111     --- Using this procedure to find out if the Workflow we are
112     --- calling has to have the backward-compatible attributes set
113     ---
114     wf_engine.getitemattrinfo(
115       itemtype => p_itemtype
116     , aname    => 'TASK_EVENT'
117     , atype    => l_type
118     , SUBTYPE  => l_subtype
119     , format   => l_format
120     );
121 
122     RETURN('N');
123   EXCEPTION
124     WHEN e_wf_error THEN
125       IF SUBSTR(SQLERRM, 12, 4) = '3103' THEN
126         RETURN('Y');
127       ELSE
128         RAISE;
129       END IF;
130   END check_backcomp;
131 
132   PROCEDURE include_role(p_role_name IN VARCHAR2) IS
133     l_index        NUMBER               := jtf_task_wf_util.notiflist.COUNT;
134     l_search_index NUMBER;
135     l_role_name    wf_roles.NAME%TYPE;
136   BEGIN
137     -- check to see if the role is already in the list
138     l_role_name  := p_role_name;
139 
140     IF l_index > 0 THEN
141       FOR l_search_index IN jtf_task_wf_util.notiflist.FIRST .. jtf_task_wf_util.notiflist.LAST LOOP
142         IF l_role_name = jtf_task_wf_util.notiflist(l_search_index).NAME THEN
143           l_role_name  := NULL;
144           EXIT;
145         END IF;
146       END LOOP;
147     END IF;
148 
149     IF l_role_name IS NOT NULL THEN
150       -- add the role to the list
151       jtf_task_wf_util.notiflist(l_index + 1).NAME  := l_role_name;
152     END IF;
153   END include_role;
154 
155   PROCEDURE get_party_details(p_resource_id IN NUMBER, p_resource_type_code IN VARCHAR2, x_role_name OUT NOCOPY VARCHAR2) IS
156     CURSOR c_resource_party(b_resource_id jtf_tasks_b.owner_id%TYPE) IS
157       SELECT source_id
158         FROM jtf_rs_resource_extns
159        WHERE resource_id = b_resource_id;
160 
161     l_party_id     hz_parties.party_id%TYPE;
162     l_display_name VARCHAR2(100);   -- check this declaration
163   BEGIN
164     x_role_name  := NULL;
165 
166     IF p_resource_type_code IN('RS_SUPPLIER_CONTACT', 'RS_PARTNER', 'RS_PARTY') THEN
167       -- supplier or party resource
168       OPEN c_resource_party(p_resource_id);
169       FETCH c_resource_party INTO l_party_id;
170       IF c_resource_party%NOTFOUND THEN
171         CLOSE c_resource_party;
172         RETURN;
173       END IF;
174       CLOSE c_resource_party;
175     ELSE
176       -- party
177       l_party_id  := p_resource_id;
178     END IF;
179 
180     wf_directory.getusername('HZ_PARTY', l_party_id, x_role_name, l_display_name);
181   END get_party_details;
182 
183   PROCEDURE find_role(p_resource_id IN NUMBER, p_resource_type_code IN VARCHAR2) IS
184     CURSOR c_group_members(b_group_id jtf_rs_group_members.GROUP_ID%TYPE) IS
185       SELECT resource_id
186            , 'RS_' || CATEGORY resource_type_code
187         FROM jtf_rs_resource_extns
188        WHERE resource_id IN(SELECT resource_id
189                               FROM jtf_rs_group_members
190                              WHERE GROUP_ID = b_group_id AND NVL(delete_flag, 'N') = 'N');
191 
192     CURSOR c_team_members(b_team_id jtf_rs_team_members.team_id%TYPE) IS
193       SELECT resource_id
194            , 'RS_' || CATEGORY resource_type_code
195         FROM jtf_rs_resource_extns
196        WHERE resource_id IN(SELECT team_resource_id
197                               FROM jtf_rs_team_members
198                              WHERE team_id = b_team_id AND NVL(delete_flag, 'N') = 'N');
199 
200     CURSOR c_group_team_role(b_orig_system wf_local_roles.orig_system%TYPE, b_orig_system_id wf_local_roles.orig_system_id%TYPE) IS
201 		  SELECT name
202         FROM wf_local_roles
203 			 WHERE orig_system = b_orig_system
204          AND orig_system_id = b_orig_system_id
205          AND user_flag='N';
206 
207     l_group_rec c_group_members%ROWTYPE;
208     l_team_rec  c_team_members%ROWTYPE;
209     l_role_name wf_roles.NAME%TYPE;
210     l_members   VARCHAR2(80)              := fnd_profile.VALUE('JTF_TASK_NOTIFY_MEMBERS');
211   BEGIN
212     l_role_name  := NULL;
213 
214     IF p_resource_type_code = 'RS_EMPLOYEE' THEN
215       -- employee resource
216       l_role_name  := jtf_rs_resource_pub.get_wf_role(p_resource_id);
217 
218       IF l_role_name IS NOT NULL THEN
219         include_role(p_role_name => l_role_name);
220       ELSE
221         fnd_message.set_name('JTF', 'JTF_RS_ROLE_NOTFOUND');
222         fnd_message.set_token('P_RESOURCE_NAME', get_resource_name(p_resource_type_code, p_resource_id));
223         fnd_msg_pub.ADD;
224       END IF;
225     ELSIF p_resource_type_code IN('RS_GROUP', 'RS_TEAM') THEN
226       -- group or team resource
227       IF l_members = 'Y' THEN
228         -- expand into individual members
229         IF p_resource_type_code = 'RS_GROUP' THEN
230           FOR l_group_rec IN c_group_members(p_resource_id) LOOP
231             IF l_group_rec.resource_type_code = 'RS_EMPLOYEE' THEN
232               -- employee resource
233               l_role_name  := jtf_rs_resource_pub.get_wf_role(l_group_rec.resource_id);
234 
235               IF l_role_name IS NOT NULL THEN
236                 include_role(p_role_name => l_role_name);
237               ELSE
238                 fnd_message.set_name('JTF', 'JTF_RS_ROLE_NOTFOUND');
239                 fnd_message.set_token('P_RESOURCE_NAME', get_resource_name(p_resource_type_code, p_resource_id));
240                 fnd_msg_pub.ADD;
241               END IF;
242             ELSIF l_group_rec.resource_type_code IN('RS_SUPPLIER_CONTACT', 'RS_PARTNER', 'RS_PARTY', 'PARTY_PERSON') THEN
243               get_party_details(
244                 p_resource_id                => l_group_rec.resource_id
245               , p_resource_type_code         => l_group_rec.resource_type_code
246               , x_role_name                  => l_role_name
247               );
248 
249               IF l_role_name IS NOT NULL THEN
250                 include_role(p_role_name => l_role_name);
251               ELSE
252                 fnd_message.set_name('JTF', 'JTF_RS_ROLE_NOTFOUND');
253                 fnd_message.set_token('P_RESOURCE_NAME', get_resource_name(p_resource_type_code, p_resource_id));
254                 fnd_msg_pub.ADD;
255               END IF;
256             ELSE
257               fnd_message.set_name('JTF', 'JTF_RS_ROLE_NOTFOUND');
258               fnd_message.set_token('P_RESOURCE_NAME', get_resource_name(p_resource_type_code, p_resource_id));
259               fnd_msg_pub.ADD;
260             END IF;
261           END LOOP;
262         ELSIF p_resource_type_code = 'RS_TEAM' THEN
263           FOR l_team_rec IN c_team_members(p_resource_id) LOOP
264             IF l_team_rec.resource_type_code = 'RS_EMPLOYEE' THEN
265               -- employee resource
266               l_role_name  := jtf_rs_resource_pub.get_wf_role(l_team_rec.resource_id);
267 
268               IF l_role_name IS NOT NULL THEN
269                 include_role(p_role_name => l_role_name);
270               ELSE
271                 fnd_message.set_name('JTF', 'JTF_RS_ROLE_NOTFOUND');
272                 fnd_message.set_token('P_RESOURCE_NAME', get_resource_name(p_resource_type_code, p_resource_id));
273                 fnd_msg_pub.ADD;
274               END IF;
275             ELSIF l_team_rec.resource_type_code IN('RS_SUPPLIER_CONTACT', 'RS_PARTNER', 'RS_PARTY', 'PARTY_PERSON') THEN
276               get_party_details(
277                 p_resource_id         => l_team_rec.resource_id
278               , p_resource_type_code  => l_team_rec.resource_type_code
279               , x_role_name           => l_role_name
280               );
281 
282               IF l_role_name IS NOT NULL THEN
283                 include_role(p_role_name => l_role_name);
284               ELSE
285                 fnd_message.set_name('JTF', 'JTF_RS_ROLE_NOTFOUND');
286                 fnd_message.set_token('P_RESOURCE_NAME', get_resource_name(p_resource_type_code, p_resource_id));
287                 fnd_msg_pub.ADD;
288               END IF;
289             ELSE
290               fnd_message.set_name('JTF', 'JTF_RS_ROLE_NOTFOUND');
291               fnd_message.set_token('P_RESOURCE_NAME', get_resource_name(p_resource_type_code, p_resource_id));
292               fnd_msg_pub.ADD;
293             END IF;
294           END LOOP;
295         ELSE
296           fnd_message.set_name('JTF', 'JTF_RS_ROLE_NOTFOUND');
297           fnd_message.set_token('P_RESOURCE_NAME', get_resource_name(p_resource_type_code, p_resource_id));
298           fnd_msg_pub.ADD;
299         END IF;
300       ELSE
301         IF p_resource_type_code = 'RS_GROUP' THEN
302           OPEN c_group_team_role('JRES_GRP', p_resource_id);
303           FETCH c_group_team_role INTO l_role_name;
304           CLOSE c_group_team_role;
305 
306           IF l_role_name IS NOT NULL Then
307            include_role(p_role_name => l_role_name);
308           ELSE
309            fnd_message.set_name('JTF', 'JTF_RS_ROLE_NOTFOUND');
310            fnd_message.set_token('P_RESOURCE_NAME', get_resource_name(p_resource_type_code, p_resource_id));
311            fnd_msg_pub.add;
312           END IF;
313         ELSIF p_resource_type_code = 'RS_TEAM' THEN
314           OPEN c_group_team_role('JRES_TEAM', p_resource_id);
315           FETCH c_group_team_role INTO l_role_name;
316           CLOSE c_group_team_role;
317 
318           IF l_role_name IS NOT NULL THEN
319             include_role(p_role_name => l_role_name);
320           ELSE
321             fnd_message.set_name('JTF', 'JTF_RS_ROLE_NOTFOUND');
322             fnd_message.set_token('P_RESOURCE_NAME', get_resource_name(p_resource_type_code, p_resource_id) );
323             fnd_msg_pub.add;
324           END IF;
325         END IF;
326       END IF;
327     ELSIF p_resource_type_code IN('RS_SUPPLIER_CONTACT', 'RS_PARTNER', 'RS_PARTY', 'PARTY_PERSON') THEN
328       get_party_details(
329         p_resource_id        => p_resource_id
330       , p_resource_type_code => p_resource_type_code
331       , x_role_name          => l_role_name
332       );
333 
334       IF l_role_name IS NOT NULL THEN
335         include_role(p_role_name => l_role_name);
336       ELSE
337         fnd_message.set_name('JTF', 'JTF_RS_ROLE_NOTFOUND');
338         fnd_message.set_token('P_RESOURCE_NAME', get_resource_name(p_resource_type_code, p_resource_id));
339         fnd_msg_pub.ADD;
340       END IF;
341     ELSE
342       fnd_message.set_name('JTF', 'JTF_RS_ROLE_NOTFOUND');
343       fnd_message.set_token('P_RESOURCE_NAME', get_resource_name(p_resource_type_code, p_resource_id));
344       fnd_msg_pub.ADD;
345     END IF;
346   END find_role;
347 
348   PROCEDURE set_text_attr(
349     p_itemtype   IN VARCHAR2
350   , p_itemkey    IN VARCHAR2
351   , p_attr_name  IN VARCHAR2
352   , p_attr_value IN VARCHAR2
353   ) IS
354     e_wf_error EXCEPTION;
355     PRAGMA EXCEPTION_INIT(e_wf_error, -20002);
356   BEGIN
357     ---
358     --- Using this procedure to ignore Workflow error 3103 when an
359     --- attribute does not exist
360     ---
361     wf_engine.setitemattrtext(
362       itemtype => p_itemtype
363     , itemkey  => p_itemkey
364     , aname    => p_attr_name
365     , avalue   => p_attr_value
366     );
367   EXCEPTION
368     WHEN e_wf_error THEN
369       IF SUBSTR(SQLERRM, 12, 4) = '3103' THEN
370         NULL;
371       ELSE
372         RAISE;
373       END IF;
374   END set_text_attr;
375 
376   PROCEDURE set_num_attr(p_itemtype IN VARCHAR2, p_itemkey IN VARCHAR2, p_attr_name IN VARCHAR2, p_attr_value IN NUMBER) IS
377     e_wf_error EXCEPTION;
378     PRAGMA EXCEPTION_INIT(e_wf_error, -20002);
379   BEGIN
380     ---
381     --- Using this procedure to ignore Workflow error 3103 when an
382     --- attribute does not exist
383     ---
384     wf_engine.setitemattrnumber(
385       itemtype => p_itemtype
386     , itemkey  => p_itemkey
387     , aname    => p_attr_name
388     , avalue   => p_attr_value
389     );
390   EXCEPTION
391     WHEN e_wf_error THEN
392       IF SUBSTR(SQLERRM, 12, 4) = '3103' THEN
393         NULL;
394       ELSE
395         RAISE;
396       END IF;
397   END set_num_attr;
398 
399   PROCEDURE list_notify_roles(
400     p_event             IN VARCHAR2
401   , p_task_id           IN VARCHAR2
402   , p_old_owner_id      IN NUMBER DEFAULT jtf_task_utl.g_miss_number
403   , p_old_owner_code    IN VARCHAR2 DEFAULT jtf_task_utl.g_miss_char
404   , p_new_owner_id      IN NUMBER
405   , p_new_owner_code    IN VARCHAR2
406   , p_old_assignee_id   IN NUMBER DEFAULT jtf_task_utl.g_miss_number
407   , p_old_assignee_code IN VARCHAR2 DEFAULT jtf_task_utl.g_miss_char
408   , p_new_assignee_id   IN NUMBER DEFAULT jtf_task_utl.g_miss_number
409   , p_new_assignee_code IN VARCHAR2 DEFAULT jtf_task_utl.g_miss_char
410   ) IS
411     CURSOR c_assignees(b_task_id jtf_tasks_b.task_id%TYPE) IS
412       SELECT resource_id
413            , resource_type_code
414         FROM jtf_task_all_assignments
415        WHERE task_id = b_task_id AND assignee_role = 'ASSIGNEE';
416 
417     l_assignees c_assignees%ROWTYPE;
418   BEGIN
419     -- Always notify the current owner
420     find_role(p_resource_id => p_new_owner_id, p_resource_type_code => p_new_owner_code);
421 
422     -- For DELETE_TASK, CHANGE_TASK_DETAILS and NO_UPDATE events, notify all assignees
423     -- For CREATE_TASK, Assignees are not notified (Refer Bug# 4251583)
424     IF p_event IN('DELETE_TASK', 'CHANGE_TASK_DETAILS', 'NO_UPDATE') THEN
425       FOR l_assignees IN c_assignees(p_task_id) LOOP
426         find_role(p_resource_id => l_assignees.resource_id, p_resource_type_code => l_assignees.resource_type_code);
427       END LOOP;
428     END IF;
429 
430     -- For CHANGE_OWNER notify the old owner
431     IF p_event = 'CHANGE_OWNER' THEN
432       find_role(p_resource_id => p_old_owner_id, p_resource_type_code => p_old_owner_code);
433     END IF;
434 
435     -- For ADD_ASSIGNEE and CHANGE_ASSIGNEE notify the new assignee
436     IF p_event IN('ADD_ASSIGNEE', 'CHANGE_ASSIGNEE') THEN
437       find_role(p_resource_id => p_new_assignee_id, p_resource_type_code => p_new_assignee_code);
438     END IF;
439 
440     -- For CHANGE_ASSIGNEE and DELETE_ASSIGNEE notify the old assignee
441     IF p_event IN('CHANGE_ASSIGNEE', 'DELETE_ASSIGNEE') THEN
442       find_role(p_resource_id => p_old_assignee_id, p_resource_type_code => p_old_assignee_code);
443     END IF;
444   END list_notify_roles;
445 
446   PROCEDURE abort_previous_wf(p_task_id IN NUMBER, p_workflow_process_id IN NUMBER) IS
447     l_itemtype    VARCHAR2(8);
448     l_itemkey     wf_item_activity_statuses.item_key%TYPE;
449     l_context     VARCHAR2(100);
450     wf_not_active EXCEPTION;
451     l_end_date    DATE;
452     l_result      VARCHAR2(1);
453 
454     CURSOR l_wf_date(b_itemtype VARCHAR2, b_itemkey wf_item_activity_statuses.item_key%TYPE) IS
455       SELECT end_date
456         FROM wf_items
457        WHERE item_type = b_itemtype AND item_key = b_itemkey;
458   BEGIN
459     l_itemkey   := TO_CHAR(p_task_id) || '-' || TO_CHAR(p_workflow_process_id);
460     l_itemtype  := 'JTFTASK';
461 
462     --
463     -- An item is considered active if its end_date is NULL
464     --
465     OPEN l_wf_date(l_itemtype, l_itemkey);
466 
467     FETCH l_wf_date
468      INTO l_end_date;
469 
470     IF ((l_wf_date%NOTFOUND) OR(l_end_date IS NOT NULL)) THEN
471       l_result  := 'N';
472     ELSE
473       l_result  := 'Y';
474     END IF;
475 
476     CLOSE l_wf_date;
477 
478     IF l_result = 'Y' THEN
479       wf_engine.abortprocess(itemtype => l_itemtype, itemkey => l_itemkey);
480     END IF;
481   END abort_previous_wf;
482 
483   PROCEDURE create_notification(
484     p_event                    IN            VARCHAR2
485   , p_task_id                  IN            NUMBER
486   , p_old_owner_id             IN            NUMBER DEFAULT jtf_task_utl.g_miss_number
487   , p_old_owner_code           IN            VARCHAR2 DEFAULT jtf_task_utl.g_miss_char
488   , p_old_assignee_id          IN            NUMBER DEFAULT jtf_task_utl.g_miss_number
489   , p_old_assignee_code        IN            VARCHAR2 DEFAULT jtf_task_utl.g_miss_char
490   , p_new_assignee_id          IN            NUMBER DEFAULT jtf_task_utl.g_miss_number
491   , p_new_assignee_code        IN            VARCHAR2 DEFAULT jtf_task_utl.g_miss_char
492   , p_old_type                 IN            NUMBER DEFAULT jtf_task_utl.g_miss_number
493   , p_old_priority             IN            NUMBER DEFAULT jtf_task_utl.g_miss_number
494   , p_old_status               IN            NUMBER DEFAULT jtf_task_utl.g_miss_number
495   , p_old_planned_start_date   IN            DATE DEFAULT jtf_task_utl.g_miss_date
496   , p_old_planned_end_date     IN            DATE DEFAULT jtf_task_utl.g_miss_date
497   , p_old_scheduled_start_date IN            DATE DEFAULT jtf_task_utl.g_miss_date
498   , p_old_scheduled_end_date   IN            DATE DEFAULT jtf_task_utl.g_miss_date
499   , p_old_actual_start_date    IN            DATE DEFAULT jtf_task_utl.g_miss_date
500   , p_old_actual_end_date      IN            DATE DEFAULT jtf_task_utl.g_miss_date
501   , p_old_description          IN            VARCHAR2 DEFAULT jtf_task_utl.g_miss_char
502   , p_abort_workflow           IN            VARCHAR2 DEFAULT fnd_profile.VALUE('JTF_TASK_ABORT_PREV_WF')
503   , x_return_status            OUT NOCOPY    VARCHAR2
504   , x_msg_count                OUT NOCOPY    NUMBER
505   , x_msg_data                 OUT NOCOPY    VARCHAR2
506   ) IS
507     l_format_mask  CONSTANT VARCHAR2(80) := fnd_profile.VALUE('ICX_DATE_FORMAT_MASK') || ' HH24:MI:SS';
508 
509     l_process       jtf_task_types_b.workflow%TYPE;
510     l_itemtype      VARCHAR2(8)  := 'JTFTASK';
511     l_itemkey       wf_item_activity_statuses.item_key%TYPE;
512     l_wf_process_id NUMBER;
513 
514     CURSOR c_task_details IS
515       SELECT t.task_number
516            , t.owner_id
517            , t.owner_type_code
518            , t.planned_start_date
519            , t.planned_end_date
520            , t.scheduled_start_date
521            , t.scheduled_end_date
522            , t.actual_start_date
523            , t.actual_end_date
524            , t.workflow_process_id
525            , tl.task_name
526            , tl.description
527            , t.task_type_id
528            , tt.name task_type_name
529            , t.task_priority_id
530            , tp.name task_priority_name
531            , t.task_status_id
532            , ts.name task_status_name
533         FROM jtf_tasks_b t
534            , jtf_tasks_tl tl
535            , jtf_task_statuses_tl ts
536            , jtf_task_types_tl tt
537            , jtf_task_priorities_tl tp
538        WHERE t.task_id = p_task_id
539          AND tl.language = userenv('LANG')
540          AND tl.task_id = t.task_id
541          AND ts.task_status_id(+) = t.task_status_id
542          AND ts.language(+) = userenv('LANG')
543          AND tt.task_type_id(+) = t.task_type_id
544          AND tt.language(+) = userenv('LANG')
545          AND tp.task_priority_id(+) = t.task_priority_id
546          AND tp.language(+) = userenv('LANG');
547 
548     CURSOR c_wf_processs_id IS
549       SELECT jtf_task_workflow_process_s.NEXTVAL
550         FROM DUAL;
551 
552     CURSOR c_type_name(b_type jtf_tasks_b.task_type_id%TYPE) IS
553       SELECT NAME
554         FROM jtf_task_types_vl
555        WHERE task_type_id = b_type;
556 
557     CURSOR c_priority_name(b_priority jtf_tasks_b.task_priority_id%TYPE) IS
558       SELECT NAME
559         FROM jtf_task_priorities_vl
560        WHERE task_priority_id = b_priority;
561 
562     CURSOR c_status_name(b_status jtf_tasks_b.task_status_id%TYPE) IS
563       SELECT NAME
564         FROM jtf_task_statuses_vl
565        WHERE task_status_id = b_status;
566 
567     CURSOR c_logged_res_id IS
568     SELECT resource_id
569       FROM jtf_rs_resource_extns
570      WHERE user_id = fnd_global.user_id;
571 
572     l_task_rec                c_task_details%ROWTYPE;
573 
574     l_old_type_name           jtf_task_types_tl.name%TYPE;
575     l_old_priority_name       jtf_task_priorities_tl.name%TYPE;
576     l_old_status_name         jtf_task_statuses_tl.name%TYPE;
577     l_old_desc                jtf_tasks_tl.description%TYPE;
578 
579     l_type_change_text        VARCHAR2(70);
580     l_status_change_text      VARCHAR2(70);
581     l_priority_change_text    VARCHAR2(70);
582     l_pln_start_change_text   VARCHAR2(100);
583     l_pln_end_change_text     VARCHAR2(100);
584     l_sch_start_change_text   VARCHAR2(100);
585     l_sch_end_change_text     VARCHAR2(100);
586     l_act_start_change_text   VARCHAR2(100);
587     l_act_end_change_text     VARCHAR2(100);
588 
589     l_old_date                VARCHAR2(50);
590     l_not_entered             VARCHAR2(2000);
591 
592     l_task_text               VARCHAR2(1050);
593     l_backcomp_flag           VARCHAR2(1);
594 
595     l_logged_res_id           jtf_rs_resource_extns.resource_id%TYPE;
596 
597     l_wf_items      VARCHAR2(500);
598   BEGIN
599     x_return_status := fnd_api.g_ret_sts_success;
600 
601     -- check whether we need to be backward-compatible for this Workflow
602     l_backcomp_flag := check_backcomp(p_itemtype => 'JTFTASK');
603 
604     IF l_backcomp_flag = 'Y' AND p_event IN('CREATE_TASK', 'DELETE_TASK') THEN
605       -- previous functionality did not have CREATE_TASK or DELETE_TASK events,
606       -- so we can bail out now
607       RETURN;
608     END IF;
609 
610     l_wf_items := wf_process(p_task_id => p_task_id);
611 
612     OPEN c_task_details;
613     FETCH c_task_details INTO l_task_rec;
614     IF c_task_details%NOTFOUND THEN
615       CLOSE c_task_details;
616       RETURN;
617     END IF;
618     CLOSE c_task_details;
619 
620     OPEN  c_logged_res_id;
621     FETCH c_logged_res_id INTO l_logged_res_id;
622     CLOSE c_logged_res_id;
623 
624     l_itemtype := SUBSTR(l_wf_items, 1, INSTR(l_wf_items, ',') - 1);
625     l_process  := SUBSTR(l_wf_items, INSTR(l_wf_items, ',') + 1);
626 
627     --- Set global attributes so we can use this data later
628     jtf_task_wf_util.g_event              := p_event;
629     jtf_task_wf_util.g_task_id            := p_task_id;
630     jtf_task_wf_util.g_old_owner_id       := p_old_owner_id;
631     jtf_task_wf_util.g_old_owner_code     := p_old_owner_code;
632     jtf_task_wf_util.g_owner_id           := l_task_rec.owner_id;
633     jtf_task_wf_util.g_owner_type_code    := l_task_rec.owner_type_code;
634     jtf_task_wf_util.g_old_assignee_id    := p_old_assignee_id;
635     jtf_task_wf_util.g_old_assignee_code  := p_old_assignee_code;
636     jtf_task_wf_util.g_new_assignee_id    := p_new_assignee_id;
637     jtf_task_wf_util.g_new_assignee_code  := p_new_assignee_code;
638 
639     -- Get the Translated Text for 'Not Entered' from message dictionary
640     fnd_message.set_name('JTF', 'JTF_TASK_DATA_NOT_ENTERED');
641     l_not_entered := fnd_message.get;
642 
643     l_type_change_text      := l_task_rec.task_type_name;
644     l_status_change_text    := l_task_rec.task_status_name;
645 
646     l_priority_change_text  := NVL(l_task_rec.task_priority_name, l_not_entered);
647     l_task_rec.description  := NVL(l_task_rec.description, l_not_entered);
648 
649     l_pln_start_change_text := NVL(TO_CHAR(l_task_rec.planned_start_date, l_format_mask), l_not_entered);
650     l_pln_end_change_text   := NVL(TO_CHAR(l_task_rec.planned_end_date, l_format_mask), l_not_entered);
651     l_sch_start_change_text := NVL(TO_CHAR(l_task_rec.scheduled_start_date, l_format_mask), l_not_entered);
652     l_sch_end_change_text   := NVL(TO_CHAR(l_task_rec.scheduled_end_date, l_format_mask), l_not_entered);
653     l_act_start_change_text := NVL(TO_CHAR(l_task_rec.actual_start_date, l_format_mask), l_not_entered);
654     l_act_end_change_text   := NVL(TO_CHAR(l_task_rec.actual_end_date, l_format_mask), l_not_entered);
655 
656     -- Find out the changed Attributes in the Task
657     IF p_event = 'CHANGE_TASK_DETAILS' THEN
658       l_old_desc  := NVL(p_old_description, l_not_entered);
659 
660       -- Task Type
661       IF p_old_type NOT IN(l_task_rec.task_type_id, jtf_task_utl.g_miss_number) THEN
662         OPEN c_type_name(p_old_type);
663         FETCH c_type_name INTO l_old_type_name;
664         IF c_type_name%NOTFOUND THEN
665           l_old_type_name  := NULL;
666         END IF;
667         CLOSE c_type_name;
668 
669         -- for backward compatibility
670         IF l_backcomp_flag = 'Y' THEN
671           l_task_text  := l_task_text || 'Task Type             ' || l_task_rec.task_type_name || '             ' || l_old_type_name;
672         END IF;
673 
674         l_task_rec.task_type_name := l_task_rec.task_type_name || ' (' || l_old_type_name || ')';
675       END IF;
676 
677       -- Task Priority
678       IF l_task_rec.task_priority_id IS NULL THEN
679         l_task_rec.task_priority_name  := l_not_entered;
680       END IF;
681 
682       IF p_old_priority IS NULL THEN
683         IF l_task_rec.task_priority_id IS NOT NULL THEN
684           l_task_rec.task_priority_name  := l_task_rec.task_priority_name || ' (' || l_not_entered || ')';
685         END IF;
686       ELSIF p_old_priority NOT IN(NVL(l_task_rec.task_priority_id, 0), jtf_task_utl.g_miss_number) THEN
687         OPEN c_priority_name(p_old_priority);
688         FETCH c_priority_name INTO l_old_priority_name;
689         IF c_priority_name%NOTFOUND THEN
690           l_old_priority_name := NULL;
691         END IF;
692         CLOSE c_priority_name;
693 
694         l_task_rec.task_priority_name := l_task_rec.task_priority_name || ' (' || l_old_priority_name || ')';
695       END IF;
696 
697       -- Task Status
698       IF p_old_status NOT IN(l_task_rec.task_status_id, jtf_task_utl.g_miss_number) THEN
699         OPEN c_status_name(p_old_status);
700         FETCH c_status_name INTO l_old_status_name;
701         IF c_status_name%NOTFOUND THEN
702           l_old_status_name  := NULL;
703         END IF;
704         CLOSE c_status_name;
705 
706         -- for backward compatibility
707         IF l_backcomp_flag = 'Y' THEN
708           l_task_text  := l_task_text || 'Status Type             ' || l_task_rec.task_status_name || '             ' || l_old_status_name;
709         END IF;
710 
711         l_task_rec.task_status_name := l_task_rec.task_status_name || ' (' || l_old_status_name || ')';
712       END IF;
713 
714       -- Planned Start Date
715       IF (p_old_planned_start_date NOT IN (l_task_rec.planned_start_date, jtf_task_utl.g_miss_date))
716          OR (p_old_planned_start_date IS NULL AND l_task_rec.planned_start_date IS NOT NULL)
717       THEN
718         IF p_old_planned_start_date IS NULL THEN
719           l_old_date  := l_not_entered;
720         ELSE
721           l_old_date  := TO_CHAR(p_old_planned_start_date, l_format_mask);
722         END IF;
723 
724         -- for backward compatibility
725         IF l_backcomp_flag = 'Y' THEN
726           l_task_text  := l_task_text || 'Planned Start Date             ' || l_pln_start_change_text || '             ' || l_old_date;
727         END IF;
728 
729         l_pln_start_change_text  := l_pln_start_change_text || ' (' || l_old_date || ')';
730       END IF;
731 
732       -- Planned End Date
733       IF (p_old_planned_end_date NOT IN (l_task_rec.planned_end_date, jtf_task_utl.g_miss_date))
734          OR (p_old_planned_end_date IS NULL AND l_task_rec.planned_end_date IS NOT NULL)
735       THEN
736         IF p_old_planned_end_date IS NULL THEN
737           l_old_date  := l_not_entered;
738         ELSE
739           l_old_date  := TO_CHAR(p_old_planned_end_date, l_format_mask);
740         END IF;
741 
742         -- for backward compatibility
743         IF l_backcomp_flag = 'Y' THEN
744           l_task_text  := l_task_text || 'Planned End Date             ' || l_pln_end_change_text || '             ' || l_old_date;
745         END IF;
746 
747         l_pln_end_change_text  := l_pln_end_change_text || ' (' || l_old_date || ')';
748       END IF;
749 
750       -- Scheduled Start Date
751       IF ( p_old_scheduled_start_date NOT IN (l_task_rec.scheduled_start_date, jtf_task_utl.g_miss_date) )
752          OR (p_old_scheduled_start_date IS NULL AND l_task_rec.scheduled_start_date IS NOT NULL)
753       THEN
754         IF p_old_scheduled_start_date IS NULL THEN
755           l_old_date  := l_not_entered;
756         ELSE
757           l_old_date  := TO_CHAR(p_old_scheduled_start_date, l_format_mask);
758         END IF;
759 
760         -- for backward compatibility
761         IF l_backcomp_flag = 'Y' THEN
762           l_task_text  := l_task_text || 'Scheduled Start Date             ' || l_sch_start_change_text || '             ' || l_old_date;
763         END IF;
764 
765         l_sch_start_change_text  := l_sch_start_change_text || ' (' || l_old_date || ')';
766       END IF;
767 
768       -- Scheduled End Date
769       IF ( p_old_scheduled_end_date NOT IN (l_task_rec.scheduled_end_date, jtf_task_utl.g_miss_date) )
770          OR (p_old_scheduled_end_date IS NULL AND l_task_rec.scheduled_end_date IS NOT NULL)
771       THEN
772         IF p_old_scheduled_end_date IS NULL THEN
773           l_old_date  := l_not_entered;
774         ELSE
775           l_old_date  := TO_CHAR(p_old_scheduled_end_date, l_format_mask);
776         END IF;
777 
778         -- for backward compatibility
779         IF l_backcomp_flag = 'Y' THEN
780           l_task_text  := l_task_text || 'Scheduled End Date             ' || l_sch_end_change_text || '             ' || l_old_date;
781         END IF;
782 
783         l_sch_end_change_text  := l_sch_end_change_text || ' (' || l_old_date || ')';
784       END IF;
785 
786       -- Actual Start Date
787       IF ( p_old_actual_start_date NOT IN (l_task_rec.actual_start_date, jtf_task_utl.g_miss_date) )
788          OR (p_old_actual_start_date IS NULL AND l_task_rec.actual_start_date IS NOT NULL)
789       THEN
790         IF p_old_actual_start_date IS NULL THEN
791           l_old_date  := l_not_entered;
792         ELSE
793           l_old_date  := TO_CHAR(p_old_actual_start_date, l_format_mask);
794         END IF;
795 
796         l_act_start_change_text  := l_act_start_change_text || ' (' || l_old_date || ')';
797       END IF;
798 
799       -- Actual End Date
800       IF ( p_old_actual_end_date NOT IN (l_task_rec.actual_end_date, jtf_task_utl.g_miss_date) )
801          OR (p_old_actual_end_date IS NULL AND l_task_rec.actual_end_date IS NOT NULL)
802       THEN
803         IF p_old_actual_end_date IS NULL THEN
804           l_old_date  := l_not_entered;
805         ELSE
806           l_old_date  := TO_CHAR(p_old_actual_end_date, l_format_mask);
807         END IF;
808 
809         l_act_end_change_text  := l_act_end_change_text || ' (' || l_old_date || ')';
810       END IF;
811     END IF;
812 
813     jtf_task_wf_util.notiflist.DELETE;
814 
815     -- Abort the previous WF if the parameter is set
816     IF p_abort_workflow = 'Y' AND l_task_rec.workflow_process_id IS NOT NULL THEN
817       abort_previous_wf(p_task_id => p_task_id, p_workflow_process_id => l_task_rec.workflow_process_id);
818     END IF;
819 
820     -- Create the itemkey for the WF process
821     OPEN c_wf_processs_id;
822     FETCH c_wf_processs_id INTO l_wf_process_id;
823     CLOSE c_wf_processs_id;
824 
825     l_itemkey := TO_CHAR(p_task_id) || '-' || TO_CHAR(l_wf_process_id);
826 
827     -- initialise the WF using the itemkey
828     wf_engine.createprocess(itemtype => l_itemtype, itemkey => l_itemkey, process => l_process);
829     wf_engine.setitemuserkey(itemtype => l_itemtype, itemkey => l_itemkey, userkey => l_task_rec.task_name);
830 
831     set_text_attr(l_itemtype, l_itemkey, 'MESSAGE_NAME', 'MESSAGE_' || p_event);
832     set_text_attr(l_itemtype, l_itemkey, 'TASK_EVENT', p_event);
833     set_text_attr(l_itemtype, l_itemkey, 'TASK_ID', p_task_id);
834     set_text_attr(l_itemtype, l_itemkey, 'TASK_NUMBER', l_task_rec.task_number);
835     set_text_attr(l_itemtype, l_itemkey, 'TASK_NAME', l_task_rec.task_name);
836     set_text_attr(l_itemtype, l_itemkey, 'TASK_TYPE_NAME', l_type_change_text);
837     set_text_attr(l_itemtype, l_itemkey, 'TASK_PRIORITY_NAME', l_priority_change_text);
838     set_text_attr(l_itemtype, l_itemkey, 'TASK_STATUS_NAME', l_status_change_text);
839     set_text_attr(l_itemtype, l_itemkey, 'TASK_DESC', l_task_rec.description);
840     set_text_attr(l_itemtype, l_itemkey, 'PLANNED_START_DATE', l_pln_start_change_text);
841     set_text_attr(l_itemtype, l_itemkey, 'PLANNED_END_DATE', l_pln_end_change_text);
842     set_text_attr(l_itemtype, l_itemkey, 'SCHEDULED_START_DATE', l_sch_start_change_text);
843     set_text_attr(l_itemtype, l_itemkey, 'SCHEDULED_END_DATE', l_sch_end_change_text);
844     set_text_attr(l_itemtype, l_itemkey, 'ACTUAL_START_DATE', l_act_start_change_text);
845     set_text_attr(l_itemtype, l_itemkey, 'ACTUAL_END_DATE', l_act_end_change_text);
846     set_text_attr(l_itemtype, l_itemkey, 'PREV_PROCESS_ID', l_task_rec.workflow_process_id);
847     set_text_attr(l_itemtype, l_itemkey, 'MESSAGE_SENDER', jtf_rs_resource_pub.get_wf_role(l_logged_res_id));
848 
849     IF p_event IN('DELETE_TASK', 'CHANGE_OWNER') THEN
850       -- set the old owner
851       set_text_attr(
852         l_itemtype
853       , l_itemkey
854       , 'OLD_TASK_OWNER_NAME'
855       , get_resource_name(p_old_owner_code, p_old_owner_id)
856       );
857     END IF;
858 
859     IF p_event IN('DELETE_TASK', 'CHANGE_OWNER') THEN
860       -- set the old owner
861       IF p_event = 'DELETE_TASK' THEN
862         set_text_attr(
863           l_itemtype
864         , l_itemkey
865         , 'OLD_TASK_OWNER_NAME'
866         , get_resource_name(l_task_rec.owner_type_code, l_task_rec.owner_id)
867         );
868       ELSE
869         set_text_attr(
870           l_itemtype
871         , l_itemkey
872         , 'OLD_TASK_OWNER_NAME'
873         , get_resource_name(p_old_owner_code, p_old_owner_id)
874         );
875       END IF;
876     END IF;
877 
878     IF p_event <> 'DELETE_TASK' THEN
879       -- set the new owner
880       set_text_attr(
881         l_itemtype
882       , l_itemkey
883       , 'NEW_TASK_OWNER_NAME'
884       , get_resource_name(l_task_rec.owner_type_code, l_task_rec.owner_id)
885       );
886 
887       set_text_attr(
888         l_itemtype
889       , l_itemkey
890       , 'OWNER_NAME'
891       , get_resource_name(l_task_rec.owner_type_code, l_task_rec.owner_id)
892       );
893     END IF;
894 
895     IF p_event IN('CHANGE_ASSIGNEE', 'DELETE_ASSIGNEE') THEN
896       -- set the old assignee
897       set_text_attr(
898         l_itemtype
899       , l_itemkey
900       , 'OLD_TASK_ASSIGNEE_NAME'
901       , get_resource_name(p_old_assignee_code, p_old_assignee_id)
902       );
903     END IF;
904 
905     IF p_event IN('ADD_ASSIGNEE', 'CHANGE_ASSIGNEE') THEN
906       -- set the new assignee
907       set_text_attr(
908         l_itemtype
909       , l_itemkey
910       , 'NEW_TASK_ASSIGNEE_NAME'
911       , get_resource_name(p_new_assignee_code, p_new_assignee_id)
912       );
913     END IF;
914 
915     -- for backward compatibility
916     IF l_backcomp_flag = 'Y' THEN
917       -- set the old owner
918       IF p_event IN('DELETE_TASK', 'CHANGE_OWNER')  AND p_old_owner_code = 'RS_EMPLOYEE' THEN
919         set_text_attr(
920           l_itemtype
921         , l_itemkey
922         , 'OLD_TASK_OWNER_ID'
923         , jtf_rs_resource_pub.get_wf_role(p_old_owner_id)
924         );
925       END IF;
926 
927       -- set the new owner
928       IF p_event <> 'DELETE_TASK' AND l_task_rec.owner_type_code = 'RS_EMPLOYEE' THEN
929         set_text_attr(
930           l_itemtype
931         , l_itemkey
932         , 'NEW_TASK_OWNER_ID'
933         , jtf_rs_resource_pub.get_wf_role(l_task_rec.owner_id)
934         );
935 
936         set_text_attr(
937           l_itemtype
938         , l_itemkey
939         , 'OWNER_ID'
940         , jtf_rs_resource_pub.get_wf_role(l_task_rec.owner_id)
941         );
942       END IF;
943 
944       -- set the old assignee
945       IF p_event IN('CHANGE_ASSIGNEE', 'DELETE_ASSIGNEE') AND p_old_assignee_code = 'RS_EMPLOYEE' THEN
946         set_text_attr(
947           l_itemtype
948         , l_itemkey
949         , 'OLD_TASK_ASSIGNEE_ID'
950         , jtf_rs_resource_pub.get_wf_role(p_old_assignee_id)
951         );
952       END IF;
953 
954       -- set the new assignee
955       IF p_event IN('ADD_ASSIGNEE', 'CHANGE_ASSIGNEE') AND p_new_assignee_code = 'RS_EMPLOYEE' THEN
956         set_text_attr(
957           l_itemtype
958         , l_itemkey
959         , 'NEW_TASK_ASSIGNEE_ID'
960         , jtf_rs_resource_pub.get_wf_role(p_new_assignee_id)
961         );
962       END IF;
963 
964       -- Task Details
965       IF p_event = 'CHANGE_TASK_DETAILS' THEN
966         set_text_attr(
967           l_itemtype
968         , l_itemkey
969         , 'TASK_TEXT'
970         , l_task_text
971         );
972       END IF;
973 
974       IF p_event = 'ADD_ASSIGNEE' THEN
975         set_text_attr(
976           l_itemtype
977         , l_itemkey
978         , 'EVENT'
979         , 'NOTIFY_NEW_ASSIGNEE'
980         );
981       ELSIF p_event = 'DELETE_ASSIGNEE' THEN
982         set_text_attr(
983           l_itemtype
984         , l_itemkey
985         , 'EVENT'
986         , 'ASSIGNEE_REMOVAL'
987         );
988       ELSIF p_event IN('CHANGE_OWNER', 'CHANGE_ASSIGNEE', 'CHANGE_TASK_DETAILS') THEN
989         set_text_attr(
990           l_itemtype
991         , l_itemkey
992         , 'EVENT'
993         , p_event
994         );
995       END IF;
996     END IF;
997 
998     wf_engine.startprocess(itemtype => l_itemtype, itemkey => l_itemkey);
999 
1000     UPDATE jtf_tasks_b
1001        SET workflow_process_id = l_wf_process_id
1002      WHERE task_id = p_task_id;
1003   EXCEPTION
1004     WHEN fnd_api.g_exc_unexpected_error THEN
1005       fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
1006     WHEN OTHERS THEN
1007       x_return_status  := fnd_api.g_ret_sts_unexp_error;
1008       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error) THEN
1009         fnd_msg_pub.add_exc_msg(g_pkg_name, 'CREATE_NOTIFICATION');
1010       END IF;
1011       fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
1012   END create_notification;
1013 
1014   PROCEDURE set_notif_message(
1015     itemtype  IN            VARCHAR2
1016   , itemkey   IN            VARCHAR2
1017   , actid     IN            NUMBER
1018   , funcmode  IN            VARCHAR2
1019   , resultout OUT NOCOPY    VARCHAR2
1020   ) IS
1021     l_event VARCHAR2(200);
1022   BEGIN
1023     IF funcmode = 'RUN' THEN
1024       l_event    := wf_engine.getitemattrtext(itemtype => itemtype, itemkey => itemkey, aname => 'TASK_EVENT');
1025       set_text_attr(
1026         p_itemtype                   => itemtype
1027       , p_itemkey                    => itemkey
1028       , p_attr_name                  => 'MESSAGE_NAME'
1029       , p_attr_value                 => 'NOTIFY_' || l_event
1030       );
1031       resultout  := 'COMPLETE';
1032       RETURN;
1033     END IF;
1034 
1035     IF funcmode = 'CANCEL' THEN
1036       resultout  := 'COMPLETE';
1037       RETURN;
1038     END IF;
1039 
1040     IF funcmode = 'TIMEOUT' THEN
1041       resultout  := 'COMPLETE';
1042       RETURN;
1043     END IF;
1044   EXCEPTION
1045     WHEN OTHERS THEN
1046       wf_core.CONTEXT(g_pkg_name, 'Set_Notif_Message', itemtype, itemkey, TO_CHAR(actid), funcmode);
1047       RAISE;
1048   END set_notif_message;
1049 
1050   PROCEDURE set_notif_performer(
1051     itemtype  IN            VARCHAR2
1052   , itemkey   IN            VARCHAR2
1053   , actid     IN            NUMBER
1054   , funcmode  IN            VARCHAR2
1055   , resultout OUT NOCOPY    VARCHAR2
1056   ) IS
1057     l_counter BINARY_INTEGER;
1058     l_role    wf_roles.NAME%TYPE;
1059   BEGIN
1060     IF funcmode = 'RUN' THEN
1061       l_counter  := wf_engine.getitemattrnumber(itemtype => itemtype, itemkey => itemkey, aname => 'LIST_COUNTER');
1062       l_role     := jtf_task_wf_util.notiflist(l_counter).NAME;
1063 
1064       IF l_role IS NOT NULL THEN
1065         set_text_attr(p_itemtype       => itemtype, p_itemkey => itemkey, p_attr_name => 'MESSAGE_RECIPIENT'
1066         , p_attr_value                 => l_role);
1067       END IF;
1068 
1069       l_counter  := l_counter + 1;
1070       set_num_attr(
1071         p_itemtype   => itemtype
1072       , p_itemkey    => itemkey
1073       , p_attr_name  => 'LIST_COUNTER'
1074       , p_attr_value => l_counter
1075       );
1076       resultout  := 'COMPLETE';
1077       RETURN;
1078     END IF;
1079 
1080     IF funcmode = 'CANCEL' THEN
1081       resultout  := 'COMPLETE';
1082       RETURN;
1083     END IF;
1084 
1085     IF funcmode = 'TIMEOUT' THEN
1086       resultout  := 'COMPLETE';
1087       RETURN;
1088     END IF;
1089   EXCEPTION
1090     WHEN OTHERS THEN
1091       wf_core.CONTEXT(g_pkg_name, 'Set_Notif_Performer', itemtype, itemkey, TO_CHAR(actid), funcmode);
1092       RAISE;
1093   END set_notif_performer;
1094 
1095   PROCEDURE set_notif_list(
1096     itemtype  IN            VARCHAR2
1097   , itemkey   IN            VARCHAR2
1098   , actid     IN            NUMBER
1099   , funcmode  IN            VARCHAR2
1100   , resultout OUT NOCOPY    VARCHAR2
1101   ) IS
1102     l_counter BINARY_INTEGER;
1103   BEGIN
1104     IF funcmode = 'RUN' THEN
1105       -------------------------------------------------------------------------
1106       -- Set the Notification List
1107       -------------------------------------------------------------------------
1108       list_notify_roles(
1109         p_event                      => jtf_task_wf_util.g_event
1110       , p_task_id                    => jtf_task_wf_util.g_task_id
1111       , p_old_owner_id               => jtf_task_wf_util.g_old_owner_id
1112       , p_old_owner_code             => jtf_task_wf_util.g_old_owner_code
1113       , p_new_owner_id               => jtf_task_wf_util.g_owner_id
1114       , p_new_owner_code             => jtf_task_wf_util.g_owner_type_code
1115       , p_old_assignee_id            => jtf_task_wf_util.g_old_assignee_id
1116       , p_old_assignee_code          => jtf_task_wf_util.g_old_assignee_code
1117       , p_new_assignee_id            => jtf_task_wf_util.g_new_assignee_id
1118       , p_new_assignee_code          => jtf_task_wf_util.g_new_assignee_code
1119       );
1120 
1121       IF jtf_task_wf_util.notiflist.COUNT > 0 THEN
1122         -------------------------------------------------------------------------
1123         -- Set the process counters
1124         -------------------------------------------------------------------------
1125         l_counter  := jtf_task_wf_util.notiflist.COUNT;
1126         set_num_attr(
1127           p_itemtype => itemtype
1128         , p_itemkey => itemkey
1129         , p_attr_name => 'LIST_COUNTER'
1130         , p_attr_value => 1
1131         );
1132         set_num_attr(
1133           p_itemtype   => itemtype
1134         , p_itemkey    => itemkey
1135         , p_attr_name  => 'PERFORMER_LIMIT'
1136         , p_attr_value => l_counter
1137         );
1138         resultout  := 'COMPLETE:T';
1139       ELSE
1140         resultout  := 'COMPLETE:F';
1141       END IF;
1142 
1143       RETURN;
1144     END IF;
1145 
1146     IF funcmode = 'CANCEL' THEN
1147       resultout  := 'COMPLETE:F';
1148       RETURN;
1149     END IF;
1150 
1151     IF funcmode = 'TIMEOUT' THEN
1152       resultout  := 'COMPLETE:F';
1153       RETURN;
1154     END IF;
1155   EXCEPTION
1156     WHEN OTHERS THEN
1157       wf_core.CONTEXT(g_pkg_name, 'Set_Notif_List', itemtype, itemkey, TO_CHAR(actid), funcmode);
1158       RAISE;
1159   END set_notif_list;
1160 END jtf_task_wf_util;