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