DBA Data[Home] [Help]

PACKAGE BODY: APPS.PO_REQAPPROVAL_FINDAPPRV1

Source


1 PACKAGE BODY PO_REQAPPROVAL_FINDAPPRV1 AS
2 /* $Header: POXWPA3B.pls 120.5.12010000.2 2008/08/04 08:35:58 rramasam ship $ */
3 
4 -- Read the profile option that enables/disables the debug log
5 g_po_wf_debug VARCHAR2(1) := NVL(FND_PROFILE.VALUE('PO_SET_DEBUG_WORKFLOW_ON'),'N');
6 
7 
8  /*=======================================================================+
9  | FILENAME
10  |   POXWPA3B.sql
11  |
12  | DESCRIPTION
13  |   PL/SQL body for package:  PO_REQAPPROVAL_FINDAPPRV1
14  |
15  | NOTES        Ben Chihaoui Created 6/15/97
16  | MODIFIED    (MM/DD/YY)
17  *=======================================================================*/
18 
19 
20 -- The following are local/Private procedure that support the workflow APIs:
21 
22 FUNCTION IsForwardToProvided(itemtype in varchar2, itemkey in varchar2) RETURN VARCHAR2;
23 
24 --
25 -- change CheckForward as public procedure.
26 --
27 --FUNCTION CheckForwardTo( p_username varchar2,  x_user_id IN OUT number) RETURN VARCHAR2;
28 --
29 --
30 PROCEDURE GetApprovalPathId(itemtype VARCHAR2, itemkey VARCHAR2);
31 
32 --
33 FUNCTION GetForwardMode(itemtype VARCHAR2, itemkey VARCHAR2) RETURN VARCHAR2;
34 
35 --
36 FUNCTION UsePositionFlag RETURN VARCHAR2;
37 
38 --
39 FUNCTION GetMgrHRHier(itemtype VARCHAR2, itemkey VARCHAR2) RETURN VARCHAR2;
40 
41 --
42 FUNCTION GetMgrPOHier(itemtype VARCHAR2, itemkey VARCHAR2) RETURN VARCHAR2;
43 
44 --
45 /* Bug# 1496490
46 ** New Procedure to check the owner can approve flag value
47 */
48 
49 PROCEDURE CheckOwnerCanApprove (itemtype in VARCHAR2, itemkey in VARCHAR2,
50 CanOwnerApprove out NOCOPY VARCHAR2);
51 
52 
53 /******************************************************************************/
54 
55 --
56 procedure Set_Forward_To_From_App_fwd(     itemtype        in varchar2,
57                                 itemkey         in varchar2,
58                                 actid           in number,
59                                 funcmode        in varchar2,
60                                 resultout       out NOCOPY varchar2    ) is
61 x_progress varchar2(100);
62 
63 l_doc_string varchar2(200);
64 l_preparer_user_name varchar2(100);
65 
66 BEGIN
67 
68   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Set_Forward_To_From_App_fwd: 01';
69   IF (g_po_wf_debug = 'Y') THEN
70      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
71   END IF;
72 
73 
74   -- Do nothing in cancel or timeout mode
75   --
76   if (funcmode <> wf_engine.eng_run) then
77 
78       resultout := wf_engine.eng_null;
79       return;
80 
81   end if;
82 
83   /* Bug 2114328: Need to set fnd_context for responder */
84 
85    PO_WF_UTIL_PKG.SetItemAttrNumber ( itemtype   => itemType,
86                                 itemkey    => itemkey,
87                                 aname      => 'RESPONDER_USER_ID',
88                                 avalue     => fnd_global.USER_ID);
89 
90    PO_WF_UTIL_PKG.SetItemAttrNumber ( itemtype   => itemType,
91                                 itemkey    => itemkey,
92                                 aname      => 'RESPONDER_RESP_ID',
93                                 avalue     => fnd_global.RESP_ID);
94 
95    PO_WF_UTIL_PKG.SetItemAttrNumber ( itemtype   => itemType,
96                                 itemkey    => itemkey,
97                                 aname      => 'RESPONDER_APPL_ID',
98                                 avalue     => fnd_global.RESP_APPL_ID);
99 
100   --   resultout := wf_engine.eng_completed || ':' ||  'ACTIVITY_PERFORMED';
101 
102   resultout := 'COMPLETE' ;
103 
104   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Set_Forward_To_From_App_fwd: 02';
105   IF (g_po_wf_debug = 'Y') THEN
106      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
107   END IF;
108 
109 
110 EXCEPTION
111 
112   WHEN OTHERS THEN
113     l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey);
114     l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey);
115     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','Set_Forward_To_From_App_fwd',x_progress);
116     PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name, l_doc_string, sqlerrm, 'PO_REQAPPROVAL_FINDAPPRV1.SET_FORWARD_TO_FROM_APP_FWD');
117     raise;
118 
119 END Set_Forward_To_From_App_fwd;
120 --
121 --
122 procedure Set_Fwd_To_From_App_timeout(     itemtype        in varchar2,
123                                 itemkey         in varchar2,
124                                 actid           in number,
125                                 funcmode        in varchar2,
126                                 resultout       out NOCOPY varchar2    ) is
127 
128 l_approver_id        number;
129 l_approver_username  varchar2(100);
130 l_approver_disp_name varchar2(100);
131 l_error_msg          varchar2(200);
132 x_progress           varchar2(100);
133 
134 l_doc_string varchar2(200);
135 l_preparer_user_name varchar2(100);
136 
137 BEGIN
138 
139   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Set_Fwd_To_From_App_timeout: 01';
140   IF (g_po_wf_debug = 'Y') THEN
141      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
142   END IF;
143 
144 
145   -- Do nothing in cancel or timeout mode
146   --
147   if (funcmode <> wf_engine.eng_run) then
148 
149       resultout := wf_engine.eng_null;
150       return;
151 
152   end if;
153 
154   /* Bug 2114328: Need to set fnd_context for responder */
155 
156    PO_WF_UTIL_PKG.SetItemAttrNumber ( itemtype   => itemType,
157                                 itemkey    => itemkey,
158                                 aname      => 'RESPONDER_USER_ID',
159                                 avalue     => fnd_global.USER_ID);
160 
161    PO_WF_UTIL_PKG.SetItemAttrNumber ( itemtype   => itemType,
162                                 itemkey    => itemkey,
163                                 aname      => 'RESPONDER_RESP_ID',
164                                 avalue     => fnd_global.RESP_ID);
165 
166    PO_WF_UTIL_PKG.SetItemAttrNumber ( itemtype   => itemType,
167                                 itemkey    => itemkey,
168                                 aname      => 'RESPONDER_APPL_ID',
169                                 avalue     => fnd_global.RESP_APPL_ID);
170 
171       /* If the responder chooses APPROVE or the notification times out, then
172       ** Set the Approver to be the old forward-to
173       */
174       l_approver_id := wf_engine.GetItemAttrNumber (itemtype  => itemtype,
175                                    itemkey         => itemkey,
176                                    aname           => 'FORWARD_TO_ID');
177 
178       l_approver_username := wf_engine.GetItemAttrText (itemtype => itemType,
179                               itemkey    => itemkey,
180                               aname      => 'FORWARD_TO_USERNAME');
181 
182       l_approver_disp_name := wf_engine.GetItemAttrText (itemtype => itemType,
183                               itemkey    => itemkey,
184                               aname      => 'FORWARD_TO_DISPLAY_NAME');
185       --
186       wf_engine.SetItemAttrNumber (itemtype        => itemtype,
187                                    itemkey         => itemkey,
188                                    aname           => 'APPROVER_EMPID',
189                                    avalue          =>  l_approver_id);
190 
191       wf_engine.SetItemAttrText ( itemtype   => itemType,
192                               itemkey    => itemkey,
193                               aname      => 'APPROVER_USER_NAME' ,
194                               avalue     => l_approver_username);
195 
196       wf_engine.SetItemAttrText ( itemtype   => itemType,
197                               itemkey    => itemkey,
198                               aname      => 'APPROVER_DISPLAY_NAME' ,
199                               avalue     => l_approver_disp_name);
200 
201       /*
202       ** Reset the Forward-to and Forward-From.
203       */
204       wf_engine.SetItemAttrNumber (itemtype        => itemtype,
205                                    itemkey         => itemkey,
206                                    aname           => 'FORWARD_TO_ID',
207                                    avalue          =>  NULL);
208       --
209       wf_engine.SetItemAttrText ( itemtype   => itemType,
210                               itemkey    => itemkey,
211                               aname      => 'FORWARD_TO_USERNAME' ,
212                               avalue     => NULL);
213 
214       wf_engine.SetItemAttrText ( itemtype   => itemType,
215                               itemkey    => itemkey,
216                               aname      => 'FORWARD_TO_DISPLAY_NAME' ,
217                               avalue     => NULL);
218       --
219 
220 /* Bug# 1325552: kagarwal
221 ** Desc: In Main Requistion approval Process, when the 'Requisition Approval
222 ** Reminder 2' times out the forward from and forward to data is all reset to
223 ** Null.
224 **
225 ** Now when the approval process is unable to Find a new approver it 'Returns
226 ** Requisition to Submitter'. This process sends Notification to the preparer
227 ** and the last approver, which is the forward from person. Since the Forward
228 ** From data is not set the workflow errors out.
229 **
230 ** Hence we need to set the forward from data to the last approver in the
231 ** Set_Fwd_To_From_App_timeout procedure which is the forward to person
232 ** when the timeout occurs.
233 */
234 
235       wf_engine.SetItemAttrNumber (itemtype        => itemtype,
236                                    itemkey         => itemkey,
237                                    aname           => 'FORWARD_FROM_ID',
238                                    avalue          =>  l_approver_id);
239       --
240       wf_engine.SetItemAttrText ( itemtype   => itemType,
241                               itemkey    => itemkey,
242                               aname      => 'FORWARD_FROM_USER_NAME' ,
243                               avalue     => l_approver_username);
244 
245       wf_engine.SetItemAttrText ( itemtype   => itemType,
246                               itemkey    => itemkey,
247                               aname      => 'FORWARD_FROM_DISP_NAME' ,
248                               avalue     => l_approver_disp_name);
249 
250 
251     /* Reset the FORWARD_TO_USERNAME_RESPONSE attribute */
252     wf_engine.SetItemAttrText (itemtype => itemtype,
253                                          itemkey  => itemkey,
254                                          aname    => 'FORWARD_TO_USERNAME_RESPONSE',
255                                          avalue   => NULL);
256 
257      /* Set the Subject of the Approval notification to "requires your approval".
258      ** Since the user did not enter a forward-to, then set the
259      ** "Invalid Forward-to" message to NULL.
260      */
261      fnd_message.set_name ('PO','PO_WF_NOTIF_REQUIRES_APPROVAL');
262      l_error_msg := fnd_message.get;
263 
264      wf_engine.SetItemAttrText ( itemtype   => itemType,
265                                  itemkey    => itemkey,
266                                  aname      => 'REQUIRES_APPROVAL_MSG' ,
267                                  avalue     => l_error_msg);
268 
269      wf_engine.SetItemAttrText ( itemtype   => itemType,
270                                  itemkey    => itemkey,
271                                  aname      => 'WRONG_FORWARD_TO_MSG' ,
272                                  avalue     => '');
273 
274   --   resultout := wf_engine.eng_completed || ':' ||  'ACTIVITY_PERFORMED';
275 
276   resultout := 'COMPLETE' ;
277 
278   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Set_Fwd_To_From_App_timeout: 02';
279   IF (g_po_wf_debug = 'Y') THEN
280      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
281   END IF;
282 
283 EXCEPTION
284 
285   WHEN OTHERS THEN
286     l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey);
287     l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey);
288     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','Set_Fwd_To_From_App_timeout',x_progress);
289     PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name, l_doc_string, sqlerrm, 'PO_REQAPPROVAL_FINDAPPRV1.SET_FWD_TO_FROM_APP_TIMEOUT');
290     raise;
291 
292 END Set_Fwd_To_From_App_timeout;
293 --
294 
295 -- Is_Forward_To_Valid
296 --  Is Forward-To userame entered in the Forward-To field in response to the
297 --  the approval notification, a valid username. If not resend the
298 --  notification back to the user.
299 --
300 -- IN
301 --   itemtype --   itemkey --   actid  --   funcmode
302 -- OUT
303 --   Resultout
304 --    - Y/N
305 --
306 procedure Is_Forward_To_Valid(  itemtype        in varchar2,
307                                 itemkey         in varchar2,
308                                 actid           in number,
309                                 funcmode        in varchar2,
310                                 resultout       out NOCOPY varchar2    ) is
311 
312 x_user_id         number;
313 l_approver_empid  number;
314 l_forward_to_username_response varchar2(100);
315 l_forward_to_username          varchar2(100);
316 l_forward_to_username_disp     varchar2(240);
317 l_forward_to_id                number;
318 l_error_msg                    varchar2(500);
319 x_progress  varchar2(200);
320 
321 l_doc_string varchar2(200);
322 l_preparer_user_name varchar2(100);
323 
324 /* Bug# 1496490 */
325 l_preparer_id number;
326 x_CanOwnerApproveFlag varchar2(1);
327 
328 l_orgid         number;
329 
330 BEGIN
331 
332   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Is_Forward_To_Valid: 01';
333   IF (g_po_wf_debug = 'Y') THEN
334      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
335   END IF;
336 
337 
338   -- Do nothing in cancel or timeout mode
339   --
340   if (funcmode <> wf_engine.eng_run) then
341 
342       resultout := wf_engine.eng_null;
343       return;
344 
345   end if;
346 
347   /* Bug# 2353153
348   ** Setting application context
349   */
350   -- Context Setting revamp
351   /* PO_REQAPPROVAL_INIT1.Set_doc_mgr_context(itemtype, itemkey); */
352 
353 
354 /* Bug# 1796605: kagarwal
355 ** Desc: When responding from the E-mail notifications, the forward
356 ** to failed as the org context was not set.
357 */
358 
359   l_orgid := wf_engine.GetItemAttrNumber (itemtype => itemtype,
360                                          itemkey  => itemkey,
361                                          aname    => 'ORG_ID');
362 
363   IF l_orgid is NOT NULL THEN
364 
365     po_moac_utils_pvt.set_org_context(l_orgid); --<R12 MOAC>
366 
367   END IF;
368 
369   /* Check that the value entered by responder as the FORWARD-TO user, is actually
370   ** a valid employee (has an employee id).
371   ** If valid, then set the FORWARD-FROM USERNAME and ID from the old FORWARD-TO.
372   ** Then set the Forward-To to the one the user entered in the response.
373   */
374   /* NOTE: We take the value entered by the user and set it to ALL CAPITAL LETTERS!!!
375   */
376   l_forward_to_username_response := wf_engine.GetItemAttrText (itemtype => itemtype,
377                                          itemkey  => itemkey,
378                                          aname    => 'FORWARD_TO_USERNAME_RESPONSE');
379 
380   l_forward_to_username_response := UPPER(l_forward_to_username_response);
381 
382   x_progress := 'Set_Forward_To_From_App_fwd: 02';
383   x_progress := x_progress || ' Forward-To=' || l_forward_to_username_response;
384   IF (g_po_wf_debug = 'Y') THEN
385      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
386   END IF;
387 
388   IF  CheckForwardTo(l_forward_to_username_response, x_user_id) = 'Y' THEN
389 
390      x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Is_Forward_To_Valid: 010 '||
391                    'x_user_id: ' ||x_user_id;
392      IF (g_po_wf_debug = 'Y') THEN
393         /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
394      END IF;
395 
396      /* The FORWARD-FROM is now the old FORWARD-TO and the NEW FORWARD-TO is set
397      ** to what the user entered in the response
398      */
399 
400      l_forward_to_username:= wf_engine.GetItemAttrText (itemtype => itemtype,
401                                          itemkey  => itemkey,
402                                          aname    => 'FORWARD_TO_USERNAME');
403 
404 /* Bug# 1352995: kagarwal
405 ** Desc: When the approver takes approve action from the Notification form after
406 ** modifying the PO. The Approver attributes are set but forward-to attributes
407 ** are set to Null. Now if any error is encountered, the Notification is sent to
408 ** the approver and if after the error the approver forwards the PO, the
409 ** is_forward_to_valid function sets the forward-from and approver attributes
410 ** from the forward-to attributes (it has not changed as of now) and then sets
411 ** the forward-to attributes to the the response-forward person but in this case
412 ** the forward-to attributes had been set to null by previous approve action
413 ** hence the approver_username was set to NULL by this function.
414 **
415 ** If the forward-to attributes are null when taking the forward action we
416 ** should use the approver attributes. This will ensure that the approver
417 ** attributes and the forward-from attributes are not set to NULL on
418 ** forwarding the document.
419 */
420 
421      IF l_forward_to_username is NOT NULL THEN
422 
423      	l_forward_to_username_disp:= wf_engine.GetItemAttrText (itemtype => itemtype,
424                                          itemkey  => itemkey,
425                                          aname    => 'FORWARD_TO_DISPLAY_NAME');
426 
427      	l_forward_to_id:= wf_engine.GetItemAttrNumber (itemtype => itemtype,
428                                          itemkey  => itemkey,
429                                          aname    => 'FORWARD_TO_ID');
430      ELSE /* get the approver name who took this action */
431           l_forward_to_username:= wf_engine.GetItemAttrText (itemtype => itemtype,
432                                          itemkey  => itemkey,
433                                          aname    => 'APPROVER_USER_NAME');
434 
435           l_forward_to_username_disp:= wf_engine.GetItemAttrText (itemtype => itemtype,
436                                          itemkey  => itemkey,
437                                          aname    => 'APPROVER_DISPLAY_NAME');
438 
439           l_forward_to_id:= wf_engine.GetItemAttrNumber (itemtype => itemtype,
440                                          itemkey  => itemkey,
441                                          aname    => 'APPROVER_EMPID');
442      END IF;
443 
444 /* Bug# 1496490: kagarwal
445 ** Desc: If the forward to person is the preparer and the
446 ** owner can approve flag is set to N then return the Notification
447 ** to the responder with Invalid Forward to Message
448 */
449        x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Is_Forward_To_Valid: 015';
450      IF (g_po_wf_debug = 'Y') THEN
451         /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
452      END IF;
453 
454            l_preparer_id := wf_engine.GetItemAttrText(itemtype => itemtype,
455                                                 itemkey => itemkey,
456                                                 aname => 'PREPARER_ID');
457 
458            if (x_user_id = l_preparer_id) then
459                PO_REQAPPROVAL_FINDAPPRV1.CheckOwnerCanApprove(itemtype, itemkey,
460 								x_CanOwnerApproveFlag);
461 
462                 x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Is_Forward_To_Valid: 020 ' ||
463                                'x_CanOwnerApproveFlag: '||x_CanOwnerApproveFlag;
464                IF (g_po_wf_debug = 'Y') THEN
465                   /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
466                END IF;
467 
468                if x_CanOwnerApproveFlag = 'N' then
469 
470                   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Is_Forward_To_Valid: 025';
471                  IF (g_po_wf_debug = 'Y') THEN
472                     /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
473                  END IF;
474 
475 		  fnd_message.set_name('PO', 'PO_WF_NOTIF_INVALID_FORWARD');
476 		  l_error_msg := fnd_message.get;
477 
478                   wf_engine.SetItemAttrText (itemtype => itemtype,
479                                    itemkey => itemkey,
480                                    aname   => 'REQUIRES_APPROVAL_MSG',
481                                    avalue  => '');
482 
483                   wf_engine.SetItemAttrText (itemtype => itemtype,
484                                    itemkey => itemkey,
485                                    aname => 'WRONG_FORWARD_TO_MSG',
486                                    avalue => l_error_msg);
487 
488                   resultout := wf_engine.eng_completed || ':' || 'N';
489 
490                   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Is_Forward_To_Valid: 050';
491                   IF (g_po_wf_debug = 'Y') THEN
492                      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
493                   END IF;
494 
495 		  return;
496 		end if;
497            end if;
498 
499 /* end fix Bug# 1496490 */
500 
501       x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Is_Forward_To_Valid: 060';
502       IF (g_po_wf_debug = 'Y') THEN
503          /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
504       END IF;
505 
506 
507      /* Set the FORWARD_FROM */
508      wf_engine.SetItemAttrNumber (     itemtype        => itemtype,
509                                         itemkey         => itemkey,
510                                         aname           => 'FORWARD_FROM_ID',
511                                         avalue          =>  l_forward_to_id);
512 
513      wf_engine.SetItemAttrText (     itemtype        => itemtype,
514                                         itemkey         => itemkey,
515                                         aname           => 'FORWARD_FROM_USER_NAME',
516                                         avalue          =>  l_forward_to_username);
517 
518      wf_engine.SetItemAttrText (     itemtype        => itemtype,
519                                         itemkey         => itemkey,
520                                         aname           => 'FORWARD_FROM_DISP_NAME',
521                                         avalue          =>  l_forward_to_username_disp);
522 
523      /* Set the approver to the person who took the action on the notification,
524      ** i.e. the old forward-to person
525      */
526      wf_engine.SetItemAttrNumber (     itemtype        => itemtype,
527                                         itemkey         => itemkey,
528                                         aname           => 'APPROVER_EMPID',
529                                         avalue          =>  l_forward_to_id);
530 
531      wf_engine.SetItemAttrText (     itemtype        => itemtype,
532                                         itemkey         => itemkey,
533                                         aname           => 'APPROVER_USER_NAME',
534                                         avalue          =>  l_forward_to_username);
535 
536      wf_engine.SetItemAttrText (     itemtype        => itemtype,
537                                         itemkey         => itemkey,
538                                         aname           => 'APPROVER_DISPLAY_NAME',
539                                         avalue          =>  l_forward_to_username_disp);
540 
541      /* Set the FORWARD-TO */
542 
543      wf_engine.SetItemAttrText (     itemtype        => itemtype,
544                                         itemkey         => itemkey,
545                                         aname           => 'FORWARD_TO_USERNAME',
546                                         avalue          =>  l_forward_to_username_response);
547 
548      wf_engine.SetItemAttrNumber ( itemtype   => itemType,
549                                    itemkey    => itemkey,
550                                    aname      => 'FORWARD_TO_ID',
551                                    avalue     => x_user_id);
552 
553     /* Get the Display name for the user from the WF Directory  */
554     wf_engine.SetItemAttrText ( itemtype        => itemtype,
555                         itemkey         => itemkey,
556                         aname           => 'FORWARD_TO_DISPLAY_NAME',
557                         avalue          =>
558                         wf_directory.GetRoleDisplayName(l_forward_to_username_response));
559 
560     /* Reset the FORWARD_TO_USERNAME_RESPONSE attribute */
561     wf_engine.SetItemAttrText (itemtype => itemtype,
562                                          itemkey  => itemkey,
563                                          aname    => 'FORWARD_TO_USERNAME_RESPONSE',
564                                          avalue   => NULL);
565 
566      /* Set the Subject of the Approval notification to "requires your approval".
567      ** Since the user entered a valid forward-to, then set the
568      ** "Invalid Forward-to" message to NULL.
569      */
570      fnd_message.set_name ('PO','PO_WF_NOTIF_REQUIRES_APPROVAL');
571      l_error_msg := fnd_message.get;
572 
573      wf_engine.SetItemAttrText ( itemtype   => itemType,
574                                  itemkey    => itemkey,
575                                  aname      => 'REQUIRES_APPROVAL_MSG' ,
576                                  avalue     => l_error_msg);
577 
578      wf_engine.SetItemAttrText ( itemtype   => itemType,
579                                  itemkey    => itemkey,
580                                  aname      => 'WRONG_FORWARD_TO_MSG' ,
581                                  avalue     => '');
582 
583     --
584     resultout := wf_engine.eng_completed || ':' ||  'Y';
585     --
586 
587   ELSE
588 
589      /* Set the error message that will be shown to the user in the ERROR MESSAGE
590      ** Field in the Notification.
591      */
592 
593      /* Set the Subject of the Approval notification to "Invalid forward-to"
594      ** Since the user entered an invalid forward-to, then set the
595      ** "requires your approval" message to NULL.
596      */
597      fnd_message.set_name ('PO','PO_WF_NOTIF_INVALID_FORWARD');
598      l_error_msg := fnd_message.get;
599 
600      wf_engine.SetItemAttrText ( itemtype   => itemType,
601                                  itemkey    => itemkey,
602                                  aname      => 'REQUIRES_APPROVAL_MSG' ,
603                                  avalue     => '');
604 
605      wf_engine.SetItemAttrText ( itemtype   => itemType,
606                                  itemkey    => itemkey,
607                                  aname      => 'WRONG_FORWARD_TO_MSG' ,
608                                  avalue     => l_error_msg);
609 
610     --
611     resultout := wf_engine.eng_completed || ':' ||  'N';
612     --
613 
614   END IF;
615 
616 
617 END Is_Forward_To_Valid  ;
618 --
619 
620 
621 -- Is_forward_to_provided
622 --   Did the submitter or the person responding to the approval notification provide
623 --   a Forward_to.
624 --
625 -- IN
626 --   itemtype, itemkey, actid, funcmode
627 -- OUT
628 --   Resultout
629 --    - Completed   - Activity was completed without any errors.
630 --
631 procedure Is_forward_to_provided(     itemtype        in varchar2,
632                                 itemkey         in varchar2,
633                                 actid           in number,
634                                 funcmode        in varchar2,
635                                 resultout       out NOCOPY varchar2    ) is
636 
637 l_forward_to_id number;
638 x_progress  varchar2(100);
639 
640 l_doc_string varchar2(200);
641 l_preparer_user_name varchar2(100);
642 
643 BEGIN
644 
645   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Is_forward_to_provided: 01';
646   IF (g_po_wf_debug = 'Y') THEN
647      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
648   END IF;
649 
650 
651   -- Do nothing in cancel or timeout mode
652   --
653   if (funcmode <> wf_engine.eng_run) then
654 
655       resultout := wf_engine.eng_null;
656       return;
657 
658   end if;
659 
660 
661   l_forward_to_id :=  wf_engine.GetItemAttrNumber (itemtype => itemtype,
662                                          itemkey  => itemkey,
663                                          aname    => 'FORWARD_TO_ID');
664 
665   IF l_forward_to_id is NOT NULL THEN
666 
667          /* Set the Approver to be the person receiving the approval notification */
668          wf_engine.SetItemAttrNumber (itemtype => itemtype,
669                                  itemkey  => itemkey,
670                                  aname    => 'APPROVER_EMPID',
671                                  avalue   => l_forward_to_id);
672 
673          resultout := wf_engine.eng_completed || ':' ||  'Y';
674 
675     ELSE
676 
677      resultout := wf_engine.eng_completed || ':' ||  'N';
678 
679   END IF;
680 
681 
682   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Is_forward_to_provided: 03';
683   IF (g_po_wf_debug = 'Y') THEN
684      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
685   END IF;
686 
687 EXCEPTION
688 
689   WHEN OTHERS THEN
690     l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey);
691     l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey);
692     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','Is_forward_to_provided',x_progress);
693     PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name, l_doc_string, sqlerrm, 'PO_REQAPPROVAL_FINDAPPRV1.IS_FORWARD_TO_PROVIDED');
694     raise;
695 
696 END Is_forward_to_provided;
697 
698 
699 -- Is_Forward_To_User_Name_Valid
700 --   Is the user_name valid for the next approver?
701 --
702 -- IN
703 --   itemtype --   itemkey --   actid  --   funcmode
704 -- OUT
705 --   Resultout
706 --    - Y/N
707 procedure Is_Forward_To_User_Name_Valid(itemtype	in varchar2,
708 					itemkey  	in varchar2,
709 					actid		in number,
710 					funcmode	in varchar2,
711 					resultout	out NOCOPY varchar2	) IS
712 
713   l_user_name VARCHAR2(100);
714   l_id NUMBER;
715   l_disp_name VARCHAR2(100);
716   x_progress varchar2(100);
717 
718   l_doc_string varchar2(200);
719   l_preparer_user_name varchar2(100);
720 
721 BEGIN
722 
723   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Is_forward_to_user_name_valid: 01';
724   IF (g_po_wf_debug = 'Y') THEN
725      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
726   END IF;
727 
728 
729   -- Do nothing in cancel or timeout mode
730   --
731   if (funcmode <> wf_engine.eng_run) then
732 
733       resultout := wf_engine.eng_null;
734       return;
735 
736   end if;
737 
738   l_user_name :=  wf_engine.GetItemAttrText (itemtype => itemtype,
739                                          itemkey  => itemkey,
740                                          aname    => 'FORWARD_TO_USERNAME');
741 
742   IF l_user_name is NOT NULL THEN
743 
744          resultout := wf_engine.eng_completed || ':' ||  'Y';
745 
746   ELSE
747      l_id := wf_engine.GetItemAttrNumber (itemtype => itemtype,
748                                        itemkey  => itemkey,
749                                        aname    => 'FORWARD_TO_ID');
750 
751 	/* Bug# 1312794: kagarwal
752 	** Desc: The SQL below would retun multiple rows for a person_id
753 	**       if the person has changed names or status or was rehired.
754 	**
755 	**       Added addition clause:
756 	**       trunc(sysdate) BETWEEN effective_start_date
757 	**                      AND effective_end_date
758 	*/
759 
760      SELECT full_name
761      INTO   l_disp_name
762      FROM   PER_ALL_PEOPLE_F    -- <BUG 6615913>
763      WHERE  person_id = l_id
764      AND    trunc(sysdate) BETWEEN effective_start_date
765                                AND effective_end_date;
766 
767      wf_engine.SetItemAttrText ( itemtype   => itemType,
768                                      itemkey    => itemkey,
769                                      aname      => 'APPROVER_DISPLAY_NAME' ,
770                                      avalue     => l_disp_name);
771 
772      resultout := wf_engine.eng_completed || ':' ||  'N';
773 
774   END IF;
775 
776   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Is_forward_to_user_name_valid: 02';
777   IF (g_po_wf_debug = 'Y') THEN
778      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
779   END IF;
780 
781 EXCEPTION
782 
783   WHEN OTHERS THEN
784     l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey);
785     l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey);
786     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','Is_forward_to_user_name_valid',x_progress);
787     PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name, l_doc_string, sqlerrm, 'PO_REQAPPROVAL_FINDAPPRV1.IS_FORWARD_TO_USER_NAME_VALID');
788     raise;
789 
790 END Is_Forward_To_User_Name_Valid;
791 
792 
793 
794 --
795 -- Get_approval_path_id
796 --   Get the requisition values on the doc header and assigns then to workflow attributes
797 --
798 procedure Get_approval_path_id(     itemtype        in varchar2,
799                                 itemkey         in varchar2,
800                                 actid           in number,
801                                 funcmode        in varchar2,
802                                 resultout       out NOCOPY varchar2    ) is
803 
804 l_document_type varchar2(25);
805 l_document_id   number;
806 l_orgid         number;
807 l_requisition_header_id NUMBER;
808 x_progress              varchar2(100);
809 
810 l_doc_string varchar2(200);
811 l_preparer_user_name varchar2(100);
812 
813 BEGIN
814 
815   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Get_approval_path_id: 01';
816   IF (g_po_wf_debug = 'Y') THEN
817      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
818   END IF;
819 
820 
821   -- Do nothing in cancel or timeout mode
822   --
823   if (funcmode <> wf_engine.eng_run) then
824 
825       resultout := wf_engine.eng_null;
826       return;
827 
828   end if;
829 
830   -- Set the multi-org context
831   l_document_type := wf_engine.GetItemAttrText (itemtype => itemtype,
832                                          itemkey  => itemkey,
833                                          aname    => 'DOCUMENT_TYPE');
834   l_document_id := wf_engine.GetItemAttrNumber (itemtype => itemtype,
835                                          itemkey  => itemkey,
836                                          aname    => 'DOCUMENT_ID');
837 
838 --  PO_REQAPPROVAL_INIT1.get_multiorg_context (l_document_type, l_document_id, x_orgid);
839   l_orgid := wf_engine.GetItemAttrNumber (itemtype => itemtype,
840                                          itemkey  => itemkey,
841                                          aname    => 'ORG_ID');
842 
843   IF l_orgid is NOT NULL THEN
844 
845      po_moac_utils_pvt.set_org_context(l_orgid); --<R12 MOAC>
846 
847   END IF;
848 
849 
850   PO_REQAPPROVAL_FINDAPPRV1.GetApprovalPathId(itemtype,itemkey);
851 
852 
853      --
854      resultout := wf_engine.eng_completed || ':' ||  'ACTIVITY_PERFORMED';
855      --
856   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Get_approval_path_id: 02';
857   IF (g_po_wf_debug = 'Y') THEN
858      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
859   END IF;
860 
861 
862 EXCEPTION
863 
864   WHEN OTHERS THEN
865     l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey);
866     l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey);
867     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','Get_approval_path_id',x_progress);
868     PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name, l_doc_string, sqlerrm, 'PO_REQAPPROVAL_FINDAPPRV1.GET_APPROVAL_PATH_ID');
869     raise;
870 
871 END Get_approval_path_id;
872 
873 -- Get_Forward_mode
874 --   Get the requisition values on the doc header and assigns then to workflow attributes
875 --
876 procedure Get_Forward_mode(itemtype        in varchar2,
877                                 itemkey         in varchar2,
878                                 actid           in number,
879                                 funcmode        in varchar2,
880                                 resultout       out NOCOPY varchar2    ) is
881 
882 l_document_type varchar2(25);
883 l_document_id   number;
884 l_orgid         number;
885 l_forward_mode   varchar2(25);
886 x_progress              varchar2(100);
887 
888 l_doc_string varchar2(200);
889 l_preparer_user_name varchar2(100);
890 
891 BEGIN
892 
893   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Get_Forward_mode: 01';
894   IF (g_po_wf_debug = 'Y') THEN
895      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
896   END IF;
897 
898 
899   -- Do nothing in cancel or timeout mode
900   --
901   if (funcmode <> wf_engine.eng_run) then
902 
903       resultout := wf_engine.eng_null;
904       return;
905 
906   end if;
907 
908   -- Set the multi-org context
909   l_document_type := wf_engine.GetItemAttrText (itemtype => itemtype,
910                                          itemkey  => itemkey,
911                                          aname    => 'DOCUMENT_TYPE');
912   l_document_id := wf_engine.GetItemAttrNumber (itemtype => itemtype,
913                                          itemkey  => itemkey,
914                                          aname    => 'DOCUMENT_ID');
915 
916 --  PO_REQAPPROVAL_INIT1.get_multiorg_context (l_document_type, l_document_id,x_orgid);
917 
918   l_orgid := wf_engine.GetItemAttrNumber (itemtype => itemtype,
919                                          itemkey  => itemkey,
920                                          aname    => 'ORG_ID');
921 
922   IF l_orgid is NOT NULL THEN
923 
924     po_moac_utils_pvt.set_org_context(l_orgid); --<R12 MOAC>
925 
926   END IF;
927 
928 
929   l_forward_mode := PO_REQAPPROVAL_FINDAPPRV1.GetForwardMode(itemtype, itemkey);
930 
931   IF l_forward_mode = 'DIRECT' THEN
932 
933      resultout := wf_engine.eng_completed || ':' ||  'DIRECT';
934 
935   ELSIF l_forward_mode = 'HIERARCHY' THEN
936 
937      resultout := wf_engine.eng_completed || ':' ||  'HIERARCHY';
938 
939   END IF;
940 
941   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Get_Forward_mode: 02';
942   IF (g_po_wf_debug = 'Y') THEN
943      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
944   END IF;
945 
946 
947 EXCEPTION
948 
949   WHEN OTHERS THEN
950     l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey);
951     l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey);
952     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','Get_Forward_mode',x_progress);
953     PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name, l_doc_string, sqlerrm, 'PO_REQAPPROVAL_FINDAPPRV1.GET_FORWARD_MODE');
954     raise;
955 
956 
957 END Get_Forward_mode;
958 
959 --
960 procedure Use_Position_flag(itemtype        in varchar2,
961                                 itemkey         in varchar2,
962                                 actid           in number,
963                                 funcmode        in varchar2,
964                                 resultout       out NOCOPY varchar2    ) is
965 
966 l_document_type varchar2(25);
967 l_document_id   number;
968 l_orgid         number;
969 l_use_positions_flag    varchar2(1);
970 x_progress              varchar2(100);
971 
972 l_doc_string varchar2(200);
973 l_preparer_user_name varchar2(100);
974 
975 BEGIN
976 
977   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Use_Position_flag: 01';
978   IF (g_po_wf_debug = 'Y') THEN
979      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
980   END IF;
981 
982 
983   -- Do nothing in cancel or timeout mode
984   --
985   if (funcmode <> wf_engine.eng_run) then
986 
987       resultout := wf_engine.eng_null;
988       return;
989 
990   end if;
991 
992   -- Set the multi-org context
993   l_document_type := wf_engine.GetItemAttrText (itemtype => itemtype,
994                                          itemkey  => itemkey,
995                                          aname    => 'DOCUMENT_TYPE');
996   l_document_id := wf_engine.GetItemAttrNumber (itemtype => itemtype,
997                                          itemkey  => itemkey,
998                                          aname    => 'DOCUMENT_ID');
999 
1000 --  PO_REQAPPROVAL_INIT1.get_multiorg_context (l_document_type, l_document_id,x_orgid);
1001   l_orgid := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1002                                          itemkey  => itemkey,
1003                                          aname    => 'ORG_ID');
1004 
1005   IF l_orgid is NOT NULL THEN
1006 
1007     po_moac_utils_pvt.set_org_context(l_orgid); --<R12 MOAC>
1008 
1009   END IF;
1010 
1011 
1012   l_use_positions_flag := PO_REQAPPROVAL_FINDAPPRV1.UsePositionFlag;
1013 
1014   IF l_use_positions_flag = 'Y' THEN
1015 
1016      resultout := wf_engine.eng_completed || ':' ||  'Y';
1017 
1018   ELSIF l_use_positions_flag = 'N' THEN
1019 
1020      resultout := wf_engine.eng_completed || ':' ||  'N';
1021 
1022   END IF;
1023 
1024   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.Use_Position_flag: 02';
1025   IF (g_po_wf_debug = 'Y') THEN
1026      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1027   END IF;
1028 
1029 EXCEPTION
1030 
1031   WHEN OTHERS THEN
1032     l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey);
1033     l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey);
1034     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','Use_Position_flag',x_progress);
1035     PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name, l_doc_string, sqlerrm, 'PO_REQAPPROVAL_FINDAPPRV1.USE_POSITION_FLAG');
1036     raise;
1037 
1038 
1039 END Use_Position_flag;
1040 
1041 --
1042 -- GetMgr_hr_hier
1043 --   Get the requisition values on the doc header and assigns then to workflow attributes
1044 --
1045 procedure GetMgr_hr_hier(itemtype        in varchar2,
1046                                 itemkey         in varchar2,
1047                                 actid           in number,
1048                                 funcmode        in varchar2,
1049                                 resultout       out NOCOPY varchar2    ) is
1050 
1051 l_document_type   varchar2(25);
1052 l_document_id     number;
1053 l_orgid           number;
1054 l_found_manager   VARCHAR2(1);
1055 x_progress        varchar2(100);
1056 
1057 l_doc_string varchar2(200);
1058 l_preparer_user_name varchar2(100);
1059 
1060 BEGIN
1061 
1062   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.GetMgr_hr_hier: 01';
1063   IF (g_po_wf_debug = 'Y') THEN
1064      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1065   END IF;
1066 
1067 
1068   -- Do nothing in cancel or timeout mode
1069   --
1070   if (funcmode <> wf_engine.eng_run) then
1071 
1072       resultout := wf_engine.eng_null;
1073       return;
1074 
1075   end if;
1076 
1077   -- Set the multi-org context
1078   l_document_type := wf_engine.GetItemAttrText (itemtype => itemtype,
1079                                          itemkey  => itemkey,
1080                                          aname    => 'DOCUMENT_TYPE');
1081   l_document_id := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1082                                          itemkey  => itemkey,
1083                                          aname    => 'DOCUMENT_ID');
1084 
1085 --  PO_REQAPPROVAL_INIT1.get_multiorg_context (l_document_type, l_document_id,x_orgid);
1086 
1087   l_orgid := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1088                                          itemkey  => itemkey,
1089                                          aname    => 'ORG_ID');
1090 
1091   IF l_orgid is NOT NULL THEN
1092 
1093     po_moac_utils_pvt.set_org_context(l_orgid); --<R12 MOAC>
1094 
1095   END IF;
1096 
1097 
1098 
1099  l_found_manager := PO_REQAPPROVAL_FINDAPPRV1.GetMgrHRHier(itemtype, itemkey);
1100 
1101  IF l_found_manager = 'Y' THEN
1102 
1103      resultout := wf_engine.eng_completed || ':' ||  'Y';
1104      x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.GetMgr_hr_hier: RESULT=Y';
1105 
1106   ELSIF l_found_manager = 'N' THEN
1107 
1108      resultout := wf_engine.eng_completed || ':' ||  'N';
1109      x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.GetMgr_hr_hier: RESULT=N';
1110 
1111   END IF;
1112 
1113   IF (g_po_wf_debug = 'Y') THEN
1114      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1115   END IF;
1116 
1117 EXCEPTION
1118 
1119   WHEN OTHERS THEN
1120     l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey);
1121     l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey);
1122     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','GetMgr_hr_hier',x_progress);
1123     PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name, l_doc_string, sqlerrm, 'PO_REQAPPROVAL_FINDAPPRV1.GETMGR_HR_HIER');
1124     raise;
1125 
1126 END GetMgr_hr_hier;
1127 
1128 --
1129 
1130 --
1131 -- GetMgr_po_hier
1132 --   Get the requisition values on the doc header and assigns then to workflow attributes
1133 --
1134 procedure GetMgr_po_hier(itemtype        in varchar2,
1135                                 itemkey         in varchar2,
1136                                 actid           in number,
1137                                 funcmode        in varchar2,
1138                                 resultout       out NOCOPY varchar2    ) is
1139 
1140 l_document_type varchar2(25);
1141 l_document_id   number;
1142 l_orgid         number;
1143 l_found_manager   VARCHAR2(1);
1144 x_progress              varchar2(100);
1145 
1146 l_doc_string varchar2(200);
1147 l_preparer_user_name varchar2(100);
1148 
1149 BEGIN
1150 
1151   x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.GetMgr_po_hier: 01';
1152   IF (g_po_wf_debug = 'Y') THEN
1153      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1154   END IF;
1155 
1156 
1157   -- Do nothing in cancel or timeout mode
1158   --
1159   if (funcmode <> wf_engine.eng_run) then
1160 
1161       resultout := wf_engine.eng_null;
1162       return;
1163 
1164   end if;
1165 
1166   -- Set the multi-org context
1167   l_document_type := wf_engine.GetItemAttrText (itemtype => itemtype,
1168                                          itemkey  => itemkey,
1169                                          aname    => 'DOCUMENT_TYPE');
1170   l_document_id := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1171                                          itemkey  => itemkey,
1172                                          aname    => 'DOCUMENT_ID');
1173 
1174 --  PO_REQAPPROVAL_INIT1.get_multiorg_context (l_document_type, l_document_id, x_orgid);
1175   l_orgid := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1176                                          itemkey  => itemkey,
1177                                          aname    => 'ORG_ID');
1178 
1179   IF l_orgid is NOT NULL THEN
1180 
1181     po_moac_utils_pvt.set_org_context(l_orgid); --<R12 MOAC>
1182 
1183   END IF;
1184 
1185 
1186  l_found_manager := PO_REQAPPROVAL_FINDAPPRV1.GetMgrPOHier(itemtype, itemkey);
1187 
1188  IF l_found_manager = 'Y' THEN
1189 
1190      resultout := wf_engine.eng_completed || ':' ||  'Y';
1191      x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.GetMgr_po_hier: RESULT=Y';
1192 
1193   ELSIF l_found_manager = 'N' THEN
1194 
1195      resultout := wf_engine.eng_completed || ':' ||  'N';
1196      x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.GetMgr_po_hier: RESULT=N';
1197 
1198   END IF;
1199 
1200   IF (g_po_wf_debug = 'Y') THEN
1201      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1202   END IF;
1203 
1204 EXCEPTION
1205 
1206   WHEN OTHERS THEN
1207     l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey);
1208     l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey);
1209     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','GetMgr_po_hier',x_progress);
1210     PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name, l_doc_string, sqlerrm, 'PO_REQAPPROVAL_FINDAPPRV1.GETMGR_PO_HIER');
1211     raise;
1212 
1213 
1214 END GetMgr_po_hier;
1215 
1216 --
1217 
1218 /*********************************************************************************
1219 ** The following are the APIs that support the workflow procedures.
1220 *********************************************************************************/
1221 
1222 
1223 FUNCTION IsForwardToProvided(itemtype VARCHAR2, itemkey VARCHAR2) RETURN VARCHAR2 is
1224 
1225 l_forward_to_id     NUMBER := NULL;
1226 l_forward_to_id_old NUMBER := NULL;
1227 l_forward_to_username_response varchar2(60):= NULL;
1228 
1229 x_progress varchar2(100):='000';
1230 BEGIN
1231 
1232 /* DEBUG: This procedure needs to get the employee_id of the username
1233 **        provided by the person responding to the notification.
1234 **        If we are unable to get an employee_id (for example, the
1235 **        user is only a Web user, not in Per_people_F table),
1236 **        then we should raise some kind of execption (e.g. send a notification
1237 **        to the system administrator????).
1238 **        If we get an employee_id, then we need to compare it to the old
1239 **        value in the forward_to_id, to check if the user provided a new
1240 **        forward_to.
1241 */
1242 
1243   x_progress :='In IsForwardToProvided. x_progress= 001';
1244   IF (g_po_wf_debug = 'Y') THEN
1245      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1246   END IF;
1247 
1248   /* Get_employee_id(), should set the item attribute FORWARD_TO_ID
1249   ** to the id of the username supplied as a forward_to in the notification
1250   ** (It gets the username from item_attribute FORWARD_TO_USERNAME, which is
1251   **  referenced in the message attribute).
1252   ** It should also return that id.
1253   */
1254 
1255   l_forward_to_username_response := wf_engine.GetItemAttrText (itemtype => itemtype,
1256                                          itemkey  => itemkey,
1257                                          aname    => 'FORWARD_TO_USERNAME_RESPONSE');
1258 
1259   /* If there is no Forward-to provided in the notification, then the forward_to_id
1260   ** comes from the current value of the FORWARD_TO_ID.
1261   ** Otherwise, we get it from the username supplied in the notification.
1262   */
1263   IF l_forward_to_username_response is NOT NULL THEN
1264 
1265      x_progress :='In IsForwardToProvided. x_progress= 002';
1266      IF (g_po_wf_debug = 'Y') THEN
1267         /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1268      END IF;
1269 
1270 
1271      /* Set the forward_to username so they would get the notification */
1272      /* DEBUG: Only set the FORWARD_TO_USERNAME, if Get_employee_id() returned
1273      **        a valid employee.
1274      */
1275      PO_REQAPPROVAL_INIT1.Get_employee_id(l_forward_to_username_response,
1276                                              l_forward_to_id);
1277 
1278      IF l_forward_to_id is NOT NULL THEN
1279 
1280          x_progress := '003';
1281          x_progress :='In IsForwardToProvided. x_progress= 003';
1282          IF (g_po_wf_debug = 'Y') THEN
1283             /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1284          END IF;
1285 
1286          wf_engine.SetItemAttrText ( itemtype   => itemType,
1287                                    itemkey    => itemkey,
1288                                    aname      => 'FORWARD_TO_USERNAME',
1289                                    avalue     => l_forward_to_username_response);
1290 
1291          wf_engine.SetItemAttrNumber ( itemtype   => itemType,
1292                                    itemkey    => itemkey,
1293                                    aname      => 'FORWARD_TO_ID',
1294                                    avalue     => l_forward_to_id);
1295 
1296       ELSE
1297 
1298          x_progress :='In IsForwardToProvided. x_progress= 004';
1299          IF (g_po_wf_debug = 'Y') THEN
1300             /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1301          END IF;
1302 
1303          RETURN('N'); -- If no valid user provide, then return 'NO FORWARD-TO'
1304 
1305       END IF;
1306 
1307   ELSE
1308 
1309       x_progress :='In IsForwardToProvided. x_progress= 005';
1310       IF (g_po_wf_debug = 'Y') THEN
1311          /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1312       END IF;
1313 
1314       l_forward_to_id := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1315                                          itemkey  => itemkey,
1316                                          aname    => 'FORWARD_TO_ID');
1317   END IF;
1318 
1319   /* Reset the value of the forward_to RESPONSE attribute */
1320   wf_engine.SetItemAttrText ( itemtype   => itemType,
1321                                    itemkey    => itemkey,
1322                                    aname      => 'FORWARD_TO_USERNAME_RESPONSE',
1323                                    avalue     => NULL);
1324 
1325   l_forward_to_id_old := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1326                                          itemkey  => itemkey,
1327                                          aname    => 'FORWARD_TO_ID_OLD');
1328 
1329   IF ( NVL(l_forward_to_id,0) <> NVL(l_forward_to_id_old,0) ) THEN
1330 
1331      -- x_progress:= '006';
1332 
1333      /* Set the old value equal to the new value */
1334      wf_engine.SetItemAttrNumber ( itemtype   => itemType,
1335                                    itemkey    => itemkey,
1336                                    aname      => 'FORWARD_TO_ID_OLD',
1337                                    avalue     => l_forward_to_id);
1338 
1339      RETURN('Y');
1340 
1341   ELSE
1342 
1343      x_progress :='In IsForwardToProvided. x_progress= 007';
1344      IF (g_po_wf_debug = 'Y') THEN
1345         /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1346      END IF;
1347 
1348      RETURN('N');
1349   END IF;
1350 
1351 EXCEPTION
1352 
1353   WHEN OTHERS THEN
1354     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','IsForwardToProvided',x_progress);
1355         raise;
1356 
1357 END IsForwardToProvided;
1358 
1359 --
1360 FUNCTION CheckForwardTo( p_username varchar2,  x_user_id IN OUT NOCOPY number) RETURN VARCHAR2 is
1361 
1362 /* Bug# 1646614: kagarwal
1363 ** Desc: We need to remove the check for orig_system_id from wf_users in
1364 ** function CheckForwardTo() in POXWPA3B.pls as it is not required. Also it will
1365 ** improve performance.
1366 */
1367 
1368 /*
1369 Cursor C1(username varchar2) is
1370     Select ORIG_SYSTEM_ID
1371     from WF_USERS
1372     where name = username;
1373 */
1374 
1375 /* Bug# 1134100: kagarwal
1376 ** Desc: If the forward to user was not an employee the
1377 **       Notification would get forwarded to the user.
1378 **       A check has been added that the user is also a
1379 **       valid employee.
1380 */
1381 
1382 /* Bug# 1301432: kagarwal
1383 ** Desc: When validating the forward to username we need to verify that the
1384 ** user is a valid employee and also belongs to fnd_users
1385 **
1386 ** We need to change the Fix of Bug#1134100.
1387 ** The ORIG_SYSTEM_ID in wf_roles returns employee number for username
1388 ** associated with an employee and fnd_user.user_id for username not
1389 ** associated with an employee
1390 **
1391 ** We can do away with the check of wf_roles but it will help us
1392 ** identify if the users have setup issue. Also the check from
1393 ** PER_WORKFORCE_CURRENT_V makes sure that the employee is
1394 ** active on the current date.
1395 */
1396 
1397 cursor C2(username varchar2) is
1398 SELECT HR.PERSON_ID
1399 FROM   FND_USER FND, PO_WORKFORCE_CURRENT_X HR     --<BUG 6615913>
1400 WHERE  FND.USER_NAME = username
1401 AND    FND.EMPLOYEE_ID = HR.PERSON_ID
1402 AND    ROWNUM = 1;
1403 
1404 -- check_emp_id number;
1405 
1406 x_progress varchar2(3) := '000';
1407 
1408 BEGIN
1409 
1410   x_progress := '001';
1411 
1412     OPEN C2(p_username);
1413 
1414     FETCH C2 into x_user_id;
1415 
1416     x_progress := '003';
1417 
1418     IF C2%FOUND THEN
1419        x_progress := '004';
1420        CLOSE C2;
1421        RETURN('Y');
1422     ELSE
1423        x_progress := '005';
1424        CLOSE C2;
1425        RETURN('N');
1426     END IF;
1427 
1428   x_progress := '007';
1429 
1430 EXCEPTION
1431 
1432   WHEN OTHERS THEN
1433     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','CheckForwardTo',x_progress);
1434         raise;
1435 
1436 END CheckForwardTo;
1437 
1438 --
1439 PROCEDURE GetApprovalPathId(itemtype VARCHAR2, itemkey VARCHAR2) is
1440 
1441 l_approval_path_id NUMBER;
1442 l_document_type_code VARCHAR2(25);
1443 l_document_subtype   VARCHAR2(25);
1444 
1445 x_progress varchar2(200) := '000';
1446 BEGIN
1447 
1448   x_progress := '001';
1449   l_approval_path_id := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1450                                          itemkey  => itemkey,
1451                                          aname    => 'APPROVAL_PATH_ID');
1452 
1453   /* If No Approval Path was specified by the user, then get the default */
1454 
1455   IF l_approval_path_id is NULL THEN
1456 
1457     l_document_type_code := wf_engine.GetItemAttrText (itemtype => itemtype,
1458                                          itemkey  => itemkey,
1459                                          aname    => 'DOCUMENT_TYPE');
1460 
1461     l_document_subtype := wf_engine.GetItemAttrText (itemtype => itemtype,
1462                                          itemkey  => itemkey,
1463                                          aname    => 'DOCUMENT_SUBTYPE');
1464 
1465     x_progress := '002';
1466 
1467     Select default_approval_path_id into l_approval_path_id
1468     FROM   po_document_types podt
1469     WHERE  podt.document_type_code = l_document_type_code
1470     AND    podt.document_subtype = l_document_subtype;
1471 
1472     wf_engine.SetItemAttrNumber (itemtype => itemtype,
1473                                  itemkey  => itemkey,
1474                                  aname    => 'APPROVAL_PATH_ID',
1475                                  avalue   => l_approval_path_id);
1476 
1477   END IF;
1478 
1479   x_progress := 'Procedure GetApprovalPathId(). PATH_ID= ' || to_char(l_approval_path_id);
1480   IF (g_po_wf_debug = 'Y') THEN
1481      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1482   END IF;
1483 
1484 EXCEPTION
1485 
1486   WHEN OTHERS THEN
1487     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','GetApprovalPathId',x_progress);
1488         raise;
1489 
1490 
1491 END GetApprovalPathId;
1492 
1493 
1494 --
1495 FUNCTION GetForwardMode(itemtype varchar2, itemkey varchar2) RETURN VARCHAR2 is
1496 
1497 l_forward_mode  VARCHAR2(25);
1498 l_document_subtype VARCHAR2(25);
1499 l_document_type_code VARCHAR2(25);
1500 
1501 x_progress varchar2(3) := '000';
1502 BEGIN
1503 
1504   x_progress := '001';
1505   l_document_type_code := wf_engine.GetItemAttrText (itemtype => itemtype,
1506                                          itemkey  => itemkey,
1507                                          aname    => 'DOCUMENT_TYPE');
1508 
1509   l_document_subtype := wf_engine.GetItemAttrText (itemtype => itemtype,
1510                                          itemkey  => itemkey,
1511                                          aname    => 'DOCUMENT_SUBTYPE');
1512 
1513   SELECT FORWARDING_MODE_CODE into l_forward_mode
1514   from po_document_types
1515    where  document_subtype   = l_document_subtype
1516    and    document_type_code = l_document_type_code;
1517 
1518    RETURN(l_forward_mode);
1519 
1520   x_progress := '002';
1521 EXCEPTION
1522 
1523   WHEN OTHERS THEN
1524     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','GetForwardMode',x_progress);
1525         raise;
1526 
1527 END GetForwardMode;
1528 
1529 --
1530 FUNCTION UsePositionFlag RETURN VARCHAR2 is
1531 
1532 l_use_positions_flag VARCHAR2(1);
1533 
1534 x_progress varchar2(3) := '000';
1535 BEGIN
1536 
1537   x_progress := '001';
1538   SELECT  NVL(use_positions_flag, 'N') into l_use_positions_flag
1539   from financials_system_parameters;
1540 
1541   RETURN(l_use_positions_flag);
1542 
1543   x_progress := '002';
1544 EXCEPTION
1545 
1546   WHEN OTHERS THEN
1547     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','UsePositionFlag',x_progress);
1548         raise;
1549 
1550 END UsePositionFlag;
1551 
1552 --
1553 FUNCTION GetMgrHRHier(itemtype VARCHAR2, itemkey VARCHAR2) RETURN VARCHAR2 is
1554 
1555 /* Bug# 1169107: kagarwal
1556 ** Desc: Added the check that the supervisor is still
1557 **       active on the current date.
1558 **
1559 */
1560 
1561 /* Bug# 1350792: kagarwal
1562 ** Desc: In GetMgrHRHier() function the check that the supervisor is still
1563 ** active for bug fix 1169107 should also include that the system_person_type
1564 ** is an 'EMP'.
1565 */
1566 
1567 /* Bug#2278152: kagarwal
1568 ** Desc: When we retrieve the supervisor of an employee, we need
1569 ** to check for the person type of EMP_APL as well, in addition to EMP
1570 */
1571 
1572 /* Bug# 2479883: kagarwal
1573 ** Desc: When we get the supervisor of an employee, we should be choosing
1574 ** the supervisor from the currently active primary assignment.
1575 **
1576 ** Added condition pera.person_id = p_employee_id to SQL in cursor C1, C2
1577 */
1578 
1579 /*  Bug# 5556434:
1580 ** Modified the cursors C1 to include the
1581 ** check to select the supervisor if the  assignment type E.
1582 ** Also modified the SQLs slightly to ensure that no more inline
1583 ** SQLs to improve performance.
1584 ** Also added CWK assignment type
1585 */
1586 
1587 CURSOR c1 (p_empid NUMBER, p_business_group_id NUMBER) IS
1588 SELECT pafe.supervisor_id
1589 FROM   Per_All_Assignments_f pafe,  -- <BUG 6615913>
1590        Per_All_People_f ppfs,       -- <BUG 6615913>
1591        Per_All_Assignments_f pafs,  -- <BUG 6615913>
1592        Per_Person_Types ppts
1593 WHERE  pafe.business_group_id = p_business_group_id
1594        AND pafe.person_id = p_empid
1595        AND Trunc(SYSDATE) BETWEEN pafe.Effective_Start_Date
1596                               AND pafe.Effective_End_Date
1597        AND pafe.Primary_Flag = 'Y'
1598        AND pafe.Assignment_Type IN ('E','C')
1599        AND ppfs.Person_Id = pafe.Supervisor_Id
1600        AND Trunc(SYSDATE) BETWEEN ppfs.Effective_Start_Date
1601                               AND ppfs.Effective_End_Date
1602        AND pafs.Person_Id = ppfs.Person_Id
1603        AND Trunc(SYSDATE) BETWEEN pafs.Effective_Start_Date
1604                               AND pafs.Effective_End_Date
1605        AND pafs.Primary_Flag = 'Y'
1606        AND pafs.Assignment_Type IN ('E','C')
1607        AND ppts.Person_Type_Id = ppfs.Person_Type_Id
1608        AND ppts.System_Person_Type IN ('EMP','EMP_APL','CWK');   --<R12 CWK Enhancemment>
1609 
1610 /*  Bug# 5556434:
1611 ** Modified the cursors C2 to include the
1612 ** check to select the supervisor if the assignment type E.
1613 ** Also modified the SQLs slightly to ensure that no more inline
1614 ** SQLs to improve performance.
1615 ** Also added CWK assignment type
1616 */
1617 
1618 CURSOR C2 ( p_empid NUMBER ) IS
1619 SELECT Pafe.supervisor_id
1620 FROM   Per_All_Assignments_f pafe,  -- <BUG 6615913>
1621        Per_All_People_f ppfs,       -- <BUG 6615913>
1622        Per_All_Assignments_f pafs,  -- <BUG 6615913>
1623        Per_Person_Types ppts
1624 WHERE  pafe.person_id = p_empid
1625        AND Trunc(SYSDATE) BETWEEN pafe.Effective_Start_Date
1626                               AND pafe.Effective_End_Date
1627        AND pafe.Primary_Flag = 'Y'
1628        AND pafe.Assignment_Type IN ('E','C')
1629        AND ppfs.Person_Id = pafe.Supervisor_Id
1630        AND Trunc(SYSDATE) BETWEEN ppfs.Effective_Start_Date
1631                               AND ppfs.Effective_End_Date
1632        AND Pafs.Person_Id = ppfs.Person_Id
1633        AND Trunc(SYSDATE) BETWEEN pafs.Effective_Start_Date
1634                               AND pafs.Effective_End_Date
1635        AND pafs.Primary_Flag = 'Y'
1636        AND pafs.Assignment_Type IN ('E','C')
1637        AND ppts.Person_Type_Id = ppfs.Person_Type_Id
1638        AND ppts.System_Person_Type IN ('EMP','EMP_APL','CWK');   --<R12 CWK Enhancemment>
1639 
1640 l_superior_id number;
1641 l_empid       number;
1642 
1643 x_username            varchar2(100);
1644 x_user_display_name   varchar2(240);
1645 
1646 l_forward_from_id          number;
1647 l_forward_from_username    varchar2(100);
1648 l_forward_from_disp_name   varchar2(100);
1649 
1650 l_business_group_id  NUMBER;
1651 
1652 x_progress varchar2(200) := NULL;
1653 x_hr_profile varchar2(1) := hr_general.get_xbg_profile;
1654 
1655 BEGIN
1656 
1657  /* Get the employee whos manager we need to find. This is always
1658  ** kept in APPROVER_EMPID.
1659  */
1660 
1661  l_empid := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1662                                          itemkey  => itemkey,
1663                                          aname    => 'APPROVER_EMPID');
1664  SELECT business_group_id
1665  INTO   l_business_group_id
1666  FROM   FINANCIALS_SYSTEM_PARAMETERS;
1667 
1668  x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.GetMgrHRHier Business_group_id= ' ||
1669                 to_char(l_business_group_id);
1670 
1671  if x_hr_profile = 'Y' then
1672   OPEN C2(l_empid);
1673   FETCH C2 into l_superior_id;
1674  else
1675   OPEN C1(l_empid, l_business_group_id);
1676   FETCH C1 into l_superior_id;
1677  end if;
1678 
1679  x_progress := x_progress || ' employee_id=' || to_char(l_empid) ||
1680                              ' supervisor_id=' || to_char(l_superior_id);
1681 
1682   IF (g_po_wf_debug = 'Y') THEN
1683      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1684   END IF;
1685 
1686  IF l_superior_id IS NOT NULL THEN
1687 
1688     /* Bug #1278794: kagarwal
1689     ** Desc: When a Doc is submitted for approval and the approver does not have
1690     **   the authority to approve, the approval workflow looks for the superior
1691     **   of the approver to forward the document.
1692     **
1693     **   If the superior does not have a valid username, we will return the
1694     **   document to the preparer with Message 'No Approver found'.
1695     **
1696     **   Return 'N', if PO_REQAPPROVAL_INIT1.get_user_name returns
1697     **   x_username as NULL
1698     */
1699 
1700     PO_REQAPPROVAL_INIT1.get_user_name(l_superior_id, x_username,
1701                                       x_user_display_name);
1702 
1703     IF x_username IS NULL THEN
1704        if x_hr_profile = 'Y' then
1705         close C2;
1706        else
1707         close C1;
1708        end if;
1709 
1710        RETURN('N');
1711 
1712      END IF;
1713 
1714     /* If we found an approver, then we need a forward-from.
1715     ** If the Forward_from_id is NULL, then we need to set the forward_from_id
1716     ** to be that of the previous approver. This takes care of the following
1717     ** scenario:
1718     ** an approver gets a notification, they respond with APPROVE action.
1719     ** Since the approver did not provide a forward-to, we null out
1720     ** the forward-from and the forward-to (see activity
1721     ** "Set Forward-to/from Approve"). The flow then moves to activity
1722     ** "Verify Authority". If the user does not have authority, then flow
1723     ** moves to "Find Approver". Then we get here.
1724     ** At this point, we find an approver, so we need to set the forward-from
1725     ** to be the last person that took the APPROVE action.
1726     */
1727 
1728     l_forward_from_id := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1729                                          itemkey  => itemkey,
1730                                          aname    => 'FORWARD_FROM_ID');
1731 
1732     IF l_forward_from_id is NULL THEN
1733 
1734        /* Get the previous approver username and display name */
1735        l_forward_from_username := wf_engine.GetItemAttrText ( itemtype => itemType,
1736                                             itemkey    => itemkey,
1737                                             aname      => 'APPROVER_USER_NAME');
1738 
1739        l_forward_from_disp_name := wf_engine.GetItemAttrText ( itemtype   => itemType,
1740                               itemkey    => itemkey,
1741                               aname      => 'APPROVER_DISPLAY_NAME');
1742 
1743        /* Set the forward-from username and display name to that of the previous
1744        ** approver.
1745        */
1746        wf_engine.SetItemAttrText ( itemtype   => itemType,
1747                               itemkey    => itemkey,
1748                               aname      => 'FORWARD_FROM_ID' ,
1749                               avalue     => l_empid);
1750 
1751        wf_engine.SetItemAttrText ( itemtype   => itemType,
1752                               itemkey    => itemkey,
1753                               aname      => 'FORWARD_FROM_USER_NAME' ,
1754                               avalue     => l_forward_from_username);
1755 
1756        wf_engine.SetItemAttrText ( itemtype   => itemType,
1757                               itemkey    => itemkey,
1758                               aname      => 'FORWARD_FROM_DISP_NAME' ,
1759                               avalue     => l_forward_from_disp_name);
1760 
1761     END IF;
1762 
1763     /* Set the approver id to that of the superior. We do this in case this manager
1764     ** does not have the authority to approve. Therefore, we would loop back and call
1765     ** this routine again. But this time we want to find the manager of this manager
1766     ** not of the original submitter (Also, note that When we first come into the
1767     ** workflow, we set the APPROVER_EMPID to the preparer id).
1768     **
1769     ** NOTE: Activity "Verify Authority" always uses the APPROVER_EMPID attribute
1770     **       as the approver.
1771     */
1772     wf_engine.SetItemAttrNumber (itemtype => itemtype,
1773                                  itemkey  => itemkey,
1774                                  aname    => 'APPROVER_EMPID',
1775                                  avalue   => l_superior_id);
1776 
1777     /* Set the forward-to ID. This is the approver that will get the notification */
1778     wf_engine.SetItemAttrNumber (itemtype => itemtype,
1779                                  itemkey  => itemkey,
1780                                  aname    => 'FORWARD_TO_ID',
1781                                  avalue   => l_superior_id);
1782 
1783     /* Set the value of FORWARD_TO_ID_OLD. This is used to determine if the responder
1784     ** to the notification entered a different USERNAME to forward the doc to.
1785     */
1786      wf_engine.SetItemAttrNumber ( itemtype   => itemType,
1787                                    itemkey    => itemkey,
1788                                    aname      => 'FORWARD_TO_ID_OLD',
1789                                    avalue     => l_superior_id);
1790 
1791     /* Get the username of Forward-to employee. We need to assign it to the
1792     ** performer of the notification */
1793 	/* Commented out the call since we have already got the username */
1794     /*PO_REQAPPROVAL_INIT1.get_user_name(l_superior_id, x_username,
1795                                       x_user_display_name);*/
1796 
1797       wf_engine.SetItemAttrText ( itemtype   => itemType,
1798                               itemkey    => itemkey,
1799                               aname      => 'FORWARD_TO_USERNAME' ,
1800                               avalue     => x_username);
1801 
1802       wf_engine.SetItemAttrText ( itemtype   => itemType,
1803                               itemkey    => itemkey,
1804                               aname      => 'FORWARD_TO_DISPLAY_NAME' ,
1805                               avalue     => x_user_display_name);
1806 
1807       wf_engine.SetItemAttrText ( itemtype   => itemType,
1808                               itemkey    => itemkey,
1809                               aname      => 'APPROVER_USER_NAME' ,
1810                               avalue     => x_username);
1811 
1812       wf_engine.SetItemAttrText ( itemtype   => itemType,
1813                               itemkey    => itemkey,
1814                               aname      => 'APPROVER_DISPLAY_NAME' ,
1815                               avalue     => x_user_display_name);
1816 
1817     if x_hr_profile = 'Y' then
1818      close C2;
1819     else
1820      close C1;
1821     end if;
1822     RETURN('Y');
1823 
1824  ELSE
1825 
1826    if x_hr_profile = 'Y' then
1827      close C2;
1828     else
1829      close C1;
1830     end if;
1831 
1832    RETURN('N');
1833 
1834  END IF;
1835 
1836 
1837 EXCEPTION
1838 
1839   WHEN OTHERS THEN
1840     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','GetMgrHRHier',x_progress);
1841         raise;
1842 
1843 END GetMgrHRHier;
1844 
1845 --
1846 FUNCTION GetMgrPOHier(itemtype VARCHAR2, itemkey VARCHAR2) RETURN VARCHAR2 is
1847 
1848 -- Bug 762194: The superior_level needs to be > 0 instead of = 1.
1849 
1850  /* Bug 2437175
1851     Added the LEADING(POEH) hint to get better execution plan */
1852 
1853 Cursor C1(p_empid number, p_approval_path_id number) is
1854   SELECT /*+ LEADING(POEH) */POEH.superior_id, poeh.superior_level, HREC.full_name
1855   FROM   PO_EMPLOYEES_CURRENT_X HREC,   -- <BUG 6615913>
1856          PO_EMPLOYEE_HIERARCHIES POEH
1857   WHERE  POEH.position_structure_id = p_approval_path_id
1858   AND    POEH.employee_id = p_empid
1859   AND    HREC.employee_id = POEH.superior_id
1860   AND    POEH.superior_level > 0
1861   UNION ALL
1862   SELECT /*+ LEADING(POEH) */ poeh.superior_id, poeh.superior_level, cwk.full_name
1863   FROM   PO_WORKFORCE_CURRENT_X cwk,  -- <BUG 6615913>
1864          po_employee_hierarchies poeh
1865   WHERE  poeh.position_structure_id = p_approval_path_id
1866   AND    poeh.employee_id = p_empid
1867   AND    cwk.person_id = poeh.superior_id
1868   AND    poeh.superior_level > 0
1869   AND    nvl(fnd_profile.value('HR_TREAT_CWK_AS_EMP'),'N') = 'Y'
1870   ORDER BY superior_level, full_name;
1871 
1872 l_superior_id    NUMBER := NULL;
1873 l_superior_level NUMBER := NULL;
1874 l_full_name      VARCHAR2(240) := '000';
1875 
1876 l_empid       number;
1877 l_approval_path_id number;
1878 
1879 x_username            varchar2(100);
1880 x_user_display_name   varchar2(240);
1881 
1882 l_forward_from_id          number;
1883 l_forward_from_username    varchar2(100);
1884 l_forward_from_disp_name   varchar2(100);
1885 
1886 x_progress varchar2(200) := NULL;
1887 BEGIN
1888 
1889 
1890  l_empid := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1891                                          itemkey  => itemkey,
1892                                          aname    => 'APPROVER_EMPID');
1893 
1894  l_approval_path_id := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1895                                          itemkey  => itemkey,
1896                                          aname    => 'APPROVAL_PATH_ID');
1897 
1898  x_progress := '001';
1899 
1900  open C1(l_empid, l_approval_path_id);
1901  fetch C1 into l_superior_id, l_superior_level, l_full_name;
1902 
1903  x_progress := 'PO_REQAPPROVAL_FINDAPPRV1.GetMgrPOHier: approval_path_id= ' ||
1904                 to_char(l_approval_path_id) || ' employee_id=' ||
1905                 to_char(l_empid) || ' supervisor_id=' || to_char(l_superior_id);
1906   IF (g_po_wf_debug = 'Y') THEN
1907      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1908   END IF;
1909 
1910 
1911  IF C1%FOUND THEN
1912 
1913     /* Bug #1278794: kagarwal
1914     ** Desc: When a Doc is submitted for approval and the approver does not have
1915     **   the authority to approve, the approval workflow looks for the superior
1916     **   of the approver to forward the document.
1917     **
1918     **   If the superior does not have a valid username, we will return the
1919     **   document to the preparer with Message 'No Approver found'.
1920     **
1921     **   Return 'N', if PO_REQAPPROVAL_INIT1.get_user_name returns
1922     **   x_username as NULL
1923     */
1924 
1925     PO_REQAPPROVAL_INIT1.get_user_name(l_superior_id, x_username,
1926                                       x_user_display_name);
1927 
1928     IF x_username IS NULL THEN
1929        close C1;
1930        RETURN('N');
1931 
1932      END IF;
1933 
1934     /* If we found an approver, then we need a forward-from.
1935     ** If the Forward_from_id is NULL, then we need to set the forward_from_id
1936     ** to be that of the previous approver. This takes care of the following
1937     ** scenario:
1938     ** an approver gets a notification, they respond with APPROVE action.
1939     ** Since the approver did not provide a forward-to, we null out
1940     ** the forward-from and the forward-to (see activity
1941     ** "Set Forward-to/from Approve"). The flow then moves to activity
1942     ** "Verify Authority". If the user does not have authority, then flow
1943     ** moves to "Find Approver". Then we get here.
1944     ** At this point, we find an approver, so we need to set the forward-from
1945     ** to be the last person that took the APPROVE action.
1946     */
1947 
1948     l_forward_from_id := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1949                                          itemkey  => itemkey,
1950                                          aname    => 'FORWARD_FROM_ID');
1951 
1952     IF l_forward_from_id is NULL THEN
1953 
1954        /* Get the previous approver username and display name */
1955        l_forward_from_username := wf_engine.GetItemAttrText ( itemtype => itemType,
1956                                             itemkey    => itemkey,
1957                                             aname      => 'APPROVER_USER_NAME');
1958 
1959        l_forward_from_disp_name := wf_engine.GetItemAttrText ( itemtype   => itemType,
1960                               itemkey    => itemkey,
1961                               aname      => 'APPROVER_DISPLAY_NAME');
1962 
1963        /* Set the forward-from username and display name to that of the previous
1964        ** approver.
1965        */
1966        wf_engine.SetItemAttrText ( itemtype   => itemType,
1967                               itemkey    => itemkey,
1968                               aname      => 'FORWARD_FROM_ID' ,
1969                               avalue     => l_empid);
1970 
1971        wf_engine.SetItemAttrText ( itemtype   => itemType,
1972                               itemkey    => itemkey,
1973                               aname      => 'FORWARD_FROM_USER_NAME' ,
1974                               avalue     => l_forward_from_username);
1975 
1976        wf_engine.SetItemAttrText ( itemtype   => itemType,
1977                               itemkey    => itemkey,
1978                               aname      => 'FORWARD_FROM_DISP_NAME' ,
1979                               avalue     => l_forward_from_disp_name);
1980 
1981     END IF;
1982 
1983     /* Set the employee id to the manager. The reason, we do this is that this manager
1984     ** may not have the authority to approve. Therefore, we would loop back and call
1985     ** this routine again. But this time we want to find the manager of this manager
1986     ** not of the original submitter (Also, note that When we first come into the
1987     ** workflow, we set the APPROVER_EMPID to the submitter id).
1988     **
1989     ** NOTE: Activity "Verify Authority" always uses the APPROVER_EMPID attribute
1990     **       as the approver.
1991     */
1992     wf_engine.SetItemAttrNumber (itemtype => itemtype,
1993                                  itemkey  => itemkey,
1994                                  aname    => 'APPROVER_EMPID',
1995                                  avalue   => l_superior_id);
1996 
1997     /* Set the forward-to ID. This is the approver that will get the notification */
1998     wf_engine.SetItemAttrNumber (itemtype => itemtype,
1999                                  itemkey  => itemkey,
2000                                  aname    => 'FORWARD_TO_ID',
2001                                  avalue   => l_superior_id);
2002 
2003     /* Set the value of FORWARD_TO_ID_OLD. This is used to determine if the responder
2004     ** to the notification entered a different USERNAME to forward the doc to.
2005     */
2006      wf_engine.SetItemAttrNumber ( itemtype   => itemType,
2007                                    itemkey    => itemkey,
2008                                    aname      => 'FORWARD_TO_ID_OLD',
2009                                    avalue     => l_superior_id);
2010 
2011     /* Get the username of Forward-to employee. We need to assign it to the
2012     ** performer of the notification */
2013     /*PO_REQAPPROVAL_INIT1.get_user_name(l_superior_id, x_username,
2014                                       x_user_display_name);*/
2015 
2016       wf_engine.SetItemAttrText ( itemtype   => itemType,
2017                               itemkey    => itemkey,
2018                               aname      => 'FORWARD_TO_USERNAME' ,
2019                               avalue     => x_username);
2020 
2021       wf_engine.SetItemAttrText ( itemtype   => itemType,
2022                               itemkey    => itemkey,
2023                               aname      => 'FORWARD_TO_DISPLAY_NAME' ,
2024                               avalue     => x_user_display_name);
2025 
2026       wf_engine.SetItemAttrText ( itemtype   => itemType,
2027                               itemkey    => itemkey,
2028                               aname      => 'APPROVER_USER_NAME' ,
2029                               avalue     => x_username);
2030 
2031       wf_engine.SetItemAttrText ( itemtype   => itemType,
2032                               itemkey    => itemkey,
2033                               aname      => 'APPROVER_DISPLAY_NAME' ,
2034                               avalue     => x_user_display_name);
2035 
2036     close C1;
2037     RETURN('Y');
2038 
2039  ELSE
2040 
2041    close C1;
2042    RETURN('N');
2043 
2044  END IF;
2045 
2046 
2047 EXCEPTION
2048 
2049   WHEN OTHERS THEN
2050     wf_core.context('PO_REQAPPROVAL_FINDAPPRV1','GetMgrPOHier',x_progress);
2051         raise;
2052 
2053 END GetMgrPOHier;
2054 
2055 --
2056 
2057 /* Bug# 1496490
2058 ** New Procedure to check the owner can approve flag value
2059 */
2060 
2061 PROCEDURE CheckOwnerCanApprove (itemtype in VARCHAR2, itemkey in VARCHAR2,
2062 CanOwnerApprove out NOCOPY VARCHAR2)  is
2063 
2064 	Cursor C1(p_document_type_code VARCHAR2, p_document_subtype VARCHAR2) is
2065 	select NVL(can_preparer_approve_flag,'N')
2066 	from po_document_types
2067 	where document_type_code = p_document_type_code
2068 	and   document_subtype = p_document_subtype;
2069 
2070 l_document_type_code VARCHAR2(25);
2071 l_document_subtype   VARCHAR2(25);
2072 x_progress varchar2(3):= '000';
2073 
2074 BEGIN
2075 	x_progress := '001';
2076  	l_document_type_code := wf_engine.GetItemAttrText (itemtype => itemtype,
2077                                          itemkey  => itemkey,
2078                                          aname    => 'DOCUMENT_TYPE');
2079 
2080  	l_document_subtype := wf_engine.GetItemAttrText (itemtype => itemtype,
2081                                          itemkey  => itemkey,
2082                                          aname    => 'DOCUMENT_SUBTYPE');
2083 
2084 	open C1(l_document_type_code, l_document_subtype);
2085 	Fetch C1 into CanOwnerApprove;
2086 	close C1;
2087 
2088 EXCEPTION
2089   WHEN OTHERS THEN
2090     wf_core.context('PO_REQAPPROVAL_INIT1','CheckOwnerCanApprove',x_progress);
2091         raise;
2092 END CheckOwnerCanApprove;
2093 
2094 --
2095 
2096 end PO_REQAPPROVAL_FINDAPPRV1;