DBA Data[Home] [Help]

PACKAGE BODY: APPS.POR_AME_APPROVAL_LIST

Source


1 PACKAGE BODY por_ame_approval_list AS
2 /* $Header: POXAPL2B.pls 120.75.12020000.5 2013/03/19 07:20:45 aacai ship $ */
3 
4 
5 -- Read the profile option that enables/disables the debug log
6 g_po_wf_debug VARCHAR2(1) := NVL(FND_PROFILE.VALUE('PO_SET_DEBUG_WORKFLOW_ON'),'N');
7 g_module_prefix CONSTANT VARCHAR2(50) := 'po.plsql.' || g_pkg_name || '.';
8 g_fnd_debug VARCHAR2(1) := NVL(FND_PROFILE.VALUE('AFLOG_ENABLED'),'N');
9 
10 approvalListStr          VARCHAR2(32767) := NULL;
11 
12 /* private routines */
13 
14 --------------------------------------------------------------------------------
15 --Start of Comments
16 --Name: getAllApprovers
17 --Function:
18 --  Get the latest approval list from AME
19 --Parameters:
20 --IN:
21 --pReqHeaderId
22 --  Requisition Header ID
23 --pAmeTransactionType
24 --  AME transaction type
25 --OUT:
26 --pApprovalListStr
27 --  Approval List concatenated in a string
28 --pApprovalListCount
29 --  Number of Approvers.
30 --  It has a value of 0, if the document does not require approval.
31 --End of Comments
32 --------------------------------------------------------------------------------
33 procedure getAllApprovers(pReqHeaderId             IN  NUMBER,
34                             pAmeTransactionType    IN VARCHAR2,
35                             pApprovalListStr       OUT NOCOPY VARCHAR2,
36                             pApprovalListCount     OUT NOCOPY NUMBER);
37 
38 
39 --------------------------------------------------------------------------------
40 --Start of Comments
41 --Name: getAbsolutePosition
42 --Function:
43 --  Return the absolute position given an input position.
44 --  The absolute position is added with an offset by the number of past approvers.
45 --Parameters:
46 --IN:
47 --pReqHeaderId
48 --  Requisition Header ID
49 --pAmeTransactionType
50 --  AME transaction type
51 --pPosition
52 --  This position is a relative value after the last of the past approvers.
53 --OUT:
54 --  None
55 --End of Comments
56 --------------------------------------------------------------------------------
57 function getAbsolutePosition(pReqHeaderId             IN  NUMBER,
58                             pAmeTransactionType    IN VARCHAR2,
59                             pPosition IN NUMBER)
60 return number;
61 
62 --------------------------------------------------------------------------------
63 --Start of Comments
64 --Name: marshalField
65 --Function:
66 --  Append the input string into approval list string
67 --  Replace the input string if it contains either a quote or delimiter char.
68 --  Another quote char is added in front of a quote or delimiter char.
69 
70 --Parameters:
71 --IN:
72 --p_string
73 --  Input string
74 
75 --OUT:
76 --None
77 --End of Comments
78 --------------------------------------------------------------------------------
79 PROCEDURE marshalField(p_string     IN VARCHAR2,
80                        p_quote_char IN VARCHAR2,
81                        p_delimiter  IN VARCHAR2);
82 
83 --------------------------------------------------------------------------------
84 --Start of Comments
85 --Name: serializeApproversTable
86 --Function:
87 --  Serialize approver list table into a string representation
88 --Parameters:
89 --IN:
90 --approversTableIn
91 --  Approver list table
92 --pReqHeaderId
93 --  Requisition Header Id
94 --OUT:
95 --approverCount
96 --  Number of approvers
97 --hasApprovalAction
98 --  'Y' if there is approver taken action
99 --End of Comments
100 --------------------------------------------------------------------------------
101 
102 function serializeApproversTable(approversTableIn in ame_util.approversTable2,
103                                  reqHeaderId in NUMBER,
104                                  approverCount out nocopy number,
105                                  hasApprovalAction out nocopy varchar2)
106   return varchar2;
107 
108 --------------------------------------------------------------------------------
109 --Start of Comments
110 --Name: getAmeTxnType
111 --Function:
112 --  Get the ame txn type given the document type and subtype
113 --Parameters:
114 --IN:
115 -- p_doc_type
116 --  Document Type
117 -- p_doc_subtype
118 --  Document subtype
119 -- p_org_id
120 --  Corresponding org id
121 --OUT:
122 -- ameTxnType
123 -- the corresponding ame txn type
124 --End of Comments
125 --------------------------------------------------------------------------------
126 function getAmeTxnType (p_doc_type in VARCHAR2,
127                                       p_doc_subtype in VARCHAR2,
128 				      p_org_id in NUMBER)
129 return varchar2;
130 
131 
132 /* public API */
133 --------------------------------------------------------------------------------
134 --Start of Comments
135 --Name: change_first_approver
136 --Function:
137 --  Call AME API to get the new approval list for a requisition.
138 --  The new approval list is based on the person ID of a new first approver.
139 --Parameters:
140 --IN:
141 --    pReqHeaderId       Requisition Header ID
142 --    pPersonId          Person ID of a new first approver
143 --OUT:
144 --    pApprovalListStr   Approval List concatenated in a string
145 --    pApprovalListCount Number of Approvers.
146 --                       It has a value of 0, if the document does not require approval.
147 --    pQuoteChar         Quote Character, used for escaping purpose in tokenization
148 --    pFieldDelimiter    Field Delimiter, used for delimiting list string into elements.
149 --End of Comments
150 --------------------------------------------------------------------------------
151 procedure change_first_approver( pReqHeaderId        IN  NUMBER,
152                                  pPersonId           IN  NUMBER,
153                                  pApprovalListStr    OUT NOCOPY VARCHAR2,
154                                  pApprovalListCount  OUT NOCOPY NUMBER,
155                                  pQuoteChar          OUT NOCOPY VARCHAR2,
156                                  pFieldDelimiter     OUT NOCOPY VARCHAR2
157                                ) IS
158 
159   l_api_name varchar2(50):= 'change_first_approver';
160   tmpApprover ame_util.approverRecord2;
161   ameTransactionType po_document_types.ame_transaction_type%TYPE;
162 
163   approverList      ame_util.approversTable2;
164   l_process_out      VARCHAR2(10);
165   currentFirstApprover ame_util.approverRecord2;
166 
167 begin
168 
169   if g_fnd_debug = 'Y' then
170       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
171         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering change_first_approver...');
172       END IF;
173       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
174         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pReqHeaderId :' || pReqHeaderId );
175       END IF;
176       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
177         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pPersonId :' || pPersonId );
178       END IF;
179   end if;
180 
181   getAmeTransactionType(pReqHeaderId => pReqHeaderId,
182                     pAmeTransactionType => ameTransactionType);
183 
184   pQuoteChar :=quoteChar;
185   pFieldDelimiter :=fieldDelimiter;
186 
187   if g_fnd_debug = 'Y' then
188       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
189         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame api ame_api2.getAllApprovers7() to get the list of approvers from AME.');
190       END IF;
191   end if;
192 
193   -- get the current approvers list from AME.
194   ame_api2.getAllApprovers7( applicationIdIn=>applicationId,
195                              transactionIdIn=>pReqHeaderId,
196                              transactionTypeIn=>ameTransactionType,
197                              approvalProcessCompleteYNOut => l_process_out,
198                              approversOut=>approverList
199                            );
200 
201   if g_fnd_debug = 'Y' then
202       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
203         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Retrieved the list of approvers from AME using ame_api2.getAllApprovers7()');
204       END IF;
205   end if;
206 
207   -- Once we get the approvers list from AME, we iterate through the approvers list,
208   -- to find out the current first authority approver.
209   for i in 1 .. approverList.count loop
210     if( approverList(i).authority = ame_util.authorityApprover
211         and approverList(i).approval_status is null
212         and approverList(i).api_insertion = 'N'
213         and approverList(i).group_or_chain_id < 3 ) then
214           currentFirstApprover :=  approverList(i) ;
215           if g_fnd_debug = 'Y' then
216               IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
217                 FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Found the first authority approver...' || currentFirstApprover.name );
218               END IF;
219           end if;
220           exit;
221     end if;
222   end loop;
223 
224   -- Once we get the current first authority approver, we check for the current first authority approver's action type(POS/PER).
225   -- If the first approver record is of position hierarchy action type,
226   --    then we need to find out the position id of the given approver and frame the new approver record.
227   --    We also set the columns first_position_id and first_approver_id in po_requisition_headers_all
228   -- If the first approver record is of emp supervisor action type,
229   --    then we simply frame the new approver record from the input parameters.
230   -- FND users cannot be set as first authority approver. So no need to check for the value 'FND'
231 
232   if currentFirstApprover.orig_system = ame_util.posOrigSystem then
233 
234         if g_fnd_debug = 'Y' then
235             IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
236               FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'First record is of type Position Hierarchy...' );
237             END IF;
238         end if;
239         tmpApprover.orig_system := ame_util.posOrigSystem;
240         SELECT position_id into tmpApprover.orig_system_id FROM PER_ALL_ASSIGNMENTS_F pa
241                 WHERE pa.person_id = pPersonId and pa.primary_flag = 'Y' and pa.assignment_type in ('E','C')
242                 and pa.position_id is not null and pa.assignment_status_type_id not in (
243                 select assignment_status_type_id from per_assignment_status_types where per_system_status = 'TERM_ASSIGN')
244                 and TRUNC ( pa.effective_start_date )
245                 <=  TRUNC(SYSDATE) AND NVL(pa.effective_end_date, TRUNC( SYSDATE)) >= TRUNC(SYSDATE);
246 
247         if g_fnd_debug = 'Y' then
248             IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
249               FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Got users position_id :' || tmpApprover.orig_system_id );
250             END IF;
251         end if;
252 
253         UPDATE po_requisition_headers_all
254         SET first_position_id = tmpApprover.orig_system_id, first_approver_id = pPersonId
255         WHERE requisition_header_id = pReqHeaderId;
256 
257         if g_fnd_debug = 'Y' then
258             IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
259               FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' Inserted the first_position_id and first_approver_id columns.' );
260             END IF;
261         end if;
262 
263         IF tmpApprover.orig_system_id IS NULL THEN
264                raise_application_error(-20001, 'User is not associated to any position. ');
265         END IF;
266   else
267         if g_fnd_debug = 'Y' then
268             IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
269               FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' First record is of type Emp-Sup Hierarchy...' );
270             END IF;
271         end if;
272         tmpApprover.orig_system := ame_util.perOrigSystem;
273         tmpApprover.orig_system_id := pPersonId;
274   end if;
275 
276   -- set the mandatory default attributes for the first authority approver.
277   tmpApprover.authority := ame_util.authorityApprover;
278   tmpApprover.api_insertion := ame_util.apiAuthorityInsertion;
279   tmpApprover.approval_status := ame_util.nullStatus;
280   tmpApprover.approver_category := ame_util.approvalApproverCategory ;
281   tmpApprover.item_class := currentFirstApprover.item_class ;
282   tmpApprover.item_id := currentFirstApprover.item_id ;
283   tmpApprover.action_type_id := currentFirstApprover.action_type_id ;
284   tmpApprover.group_or_chain_id := currentFirstApprover.group_or_chain_id ;
285 
286   -- retrieve the name from wf_roles table for the given orig_system and orig_system_id values.
287   -- this name field does not refer to neither employee name nor position name
288   -- this name filed is the mandatory key field for the approverrecord2. We should pass this to ame. Otherwise ame will throw exception.
289 
290   -- bug 9395808
291   -- fix The problem of just picking up the first approver randomly when an approver is manually
292   -- inserted in the chain in iProc.
293   -- it should pick up the approver with earliest start date.
294   -- also validating the approver status
295   SELECT name into tmpApprover.name FROM (
296        SELECT name
297        FROM wf_roles
298        WHERE orig_system = tmpApprover.orig_system and orig_system_id = tmpApprover.orig_system_id
299        and status = 'ACTIVE' and trunc (nvl( expiration_date, sysdate)) >= trunc(sysdate)
300         ORDER BY start_date
301   )
302   WHERE rownum = 1;
303 
304   IF tmpApprover.name IS NULL THEN
305          raise_application_error(-20001, 'Record Not Found in WF_ROLES for the orig_system_id :' ||
306                                           tmpApprover.orig_system_id || ' -- orig_system :' || tmpApprover.orig_system );
307   END IF;
308 
309   -- call the ame api to set the first authority approver.
310   -- tmpApprover is the new first authority approver record.
311 
312   if g_fnd_debug = 'Y' then
313        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
314          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api2.setFirstAuthorityApprover()...' );
315        END IF;
316   end if;
317 
318   -- set a save point for failure rollback
319   SAVEPOINT CHANGE_FIRST_APPROVER;
320 
321   ame_api2.setFirstAuthorityApprover( applicationIdIn      => applicationId,
322                                       transactionIdIn      => pReqHeaderId,
323                                       approverIn           => tmpApprover,
324                                       transactionTypeIn    => ameTransactionType,
325                                       clearChainStatusYNIn => ame_util.booleanTrue
326                                     );
327   if g_fnd_debug = 'Y' then
328        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
329          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api2.setFirstAuthorityApprover()...' );
330        END IF;
331   end if;
332 
333   -- Once we change the first authority approver, then get the updated approvers list from ame.
334   getAllApprovers(pReqHeaderId, ameTransactionType, pApprovalListStr, pApprovalListCount);
335 
336   if g_fnd_debug = 'Y' then
337       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
338         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving change_first_approver...');
339       END IF;
340       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
341         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListStr :' || pApprovalListStr);
342       END IF;
343       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
344         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListCount :' || pApprovalListCount);
345       END IF;
346   end if;
347 
348 exception
349   when NO_DATA_FOUND then
350     pApprovalListCount := 0;
351     pApprovalListStr := 'NO_DATA_FOUND';
352     if g_fnd_debug = 'Y' then
353       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
354         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
355                       l_api_name || '.NO_DATA_FOUND', 'NO_DATA_FOUND');
356       END IF;
357     end if;
358   when others then
359     pApprovalListCount := 0;
360     pApprovalListStr := 'EXCEPTION:' || sqlerrm;
361     if g_fnd_debug = 'Y' then
362       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
363         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
364                       l_api_name || '.others_exception', sqlerrm);
365       END IF;
366     end if;
367     ROLLBACK TO CHANGE_FIRST_APPROVER;
368 end;
369 
370 --------------------------------------------------------------------------------
371 --Start of Comments
372 --Name: insert_approver
373 --Function:
374 --  Call AME API to insert an approver into a specific position.
375 --  The new approval list is retrieved after the insertion.
376 
377 --Parameters:
378 --IN:
379 --    pReqHeaderId       Requisition Header ID
380 --    pPersonId          Person ID of a new approver
381 --    pAuthority         AME Authority type of the new approver
382 --    pInsertionType     AME Insertion type of the new approver
383 --    pPosition          Position to be inserted
384 --    pApproverNumber    Exact insertion psition
385 --    pInsertionType     Where to insert, after or before
386 --    pApproverName      Username of the approver
387 --OUT:
388 --    pApprovalListStr   Approval List concatenated in a string
389 --    pApprovalListCount Number of Approvers.
390 --                       It has a value of 0, if the document does not require approval.
391 --    pQuoteChar         Quote Character, used for escaping purpose in tokenization
392 --    pFieldDelimiter    Field Delimiter, used for delimiting list string into elements.
393 --End of Comments
394 --------------------------------------------------------------------------------
395 procedure insert_approver(  pReqHeaderId        IN  NUMBER,
396                             pPersonId           IN NUMBER,
397                             pAuthority          IN VARCHAR2,
398                             pApproverCategory   IN VARCHAR2,
399                             pPosition           IN NUMBER,
400 			    pApproverNumber     IN NUMBER,
401                             pInsertionType      IN VARCHAR2,
402 			    pApproverName   IN VARCHAR2,
403                             pApprovalListStr    OUT NOCOPY VARCHAR2,
404                             pApprovalListCount  OUT NOCOPY NUMBER,
405                             pQuoteChar          OUT NOCOPY VARCHAR2,
406                             pFieldDelimiter     OUT NOCOPY VARCHAR2
407                           ) IS
408   l_api_name varchar2(50):= 'insert_approver';
409 
410   tmpApprover ame_util.approverRecord2;
411   insertOrder ame_util.insertionRecord2;
412   upperLimit number;
413   approverList      ame_util.approversTable2;
414   hasAvailableOrder boolean := false;
415   E_NO_AVAILABLE_INSERTION EXCEPTION;
416   ameTransactionType po_document_types.ame_transaction_type%TYPE;
417   absolutePosition number;
418   availableInsertionList ame_util.insertionsTable2;
419   l_process_out      VARCHAR2(10);
420   l_group_or_chain_id NUMBER := 0;
421   l_action_type_id NUMBER := 0;
422   l_counter NUMBER := 0;
423   l_approver_position NUMBER := 0;
424   hasHiddenApprovers boolean := false; -- Flag to check hidden approvers
425   l_insertion_type varchar2(1); -- To store insertion type
426 
427 begin
428 
429   if g_fnd_debug = 'Y' then
430       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
431         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering insert_approver...');
432       END IF;
433       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
434         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pReqHeaderId :' || pReqHeaderId );
435       END IF;
436       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
437         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pPersonId :' || pPersonId );
438       END IF;
439       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
440         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pAuthority :' || pAuthority );
441       END IF;
442       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
443         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pPosition :' || pPosition );
444       END IF;
445   end if;
446 
447   getAmeTransactionType(pReqHeaderId => pReqHeaderId,
448                     pAmeTransactionType => ameTransactionType);
449 
450   pQuoteChar :=quoteChar;
451   pFieldDelimiter :=fieldDelimiter;
452 
453   /*
454    past approvers are not in middle tier
455    so need to deduce the real position
456   */
457 
458 
459   -- Frame the approverRecord2 from the input parameters.
460   -- Set the default mandatory attributes also.
461   tmpApprover.orig_system := ame_util.perOrigSystem;
462   tmpApprover.orig_system_id := pPersonId;
463   tmpApprover.authority := pAuthority;
464   tmpApprover.api_insertion := ame_util.apiInsertion;
465   tmpApprover.approver_category := pApproverCategory;
466   tmpApprover.approval_status := ame_util.nullStatus;
467   ame_api2.getAllApprovers7( applicationIdIn => applicationId,
468                              transactionIdIn => pReqHeaderId,
469                              transactionTypeIn => ameTransactionType,
470                              approvalProcessCompleteYNOut => l_process_out,
471                              approversOut => approverList
472                            );
473 
474   /* Check if there is any supressed or repeated approver. As soon as we met any, set hasHiddenApprovers true and exit
475      Added extra statuses to check if there is any hidden approver in approver checkout flow */
476   For i In 1 .. approverList.count LOOP
477      IF (approverList(i).approval_status IN (ame_util.repeatedStatus,ame_util.suppressedStatus,
478                            ame_util.notifiedByRepeatedStatus, ame_util.approvedByRepeatedStatus,
479                            ame_util.rejectedByRepeatedStatus, ame_util.approvedStatus,
480                            ame_util.rejectStatus )) THEN
481        hasHiddenApprovers := true;
482        EXIT;
483     END IF;
484   END LOOP;
485 
486  /* If we  have any superessed approver then execute this code ,otherwise pass the pApproverNumber to absoluteposition
487      Approvers with Approval_status 'REPEATED' OR 'SUPPRESSED'is not considered in getAllApprovers procedure
488      Second condition will be used to avoid this code when we are inserting first approver */
489   IF ( hasHiddenApprovers = true AND pApproverName IS NOT NULL ) THEN
490      if g_fnd_debug = 'Y' then
491         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
492           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' Found Repeated/Skipped Approvers!'  );
493         END IF;
494      end if;
495 
496      for i in 1 .. approverList.count loop
497         /* Find approver with given name and status NULL or not REPEATED or not SUPPRESSED
498            Status XXXByRepeatedStatus is used because 'repeated' status gets modified to XXXByRepeatedStatus
499            status when other approvers in group or PCOA gets notified or approve or reject .Also group can have pending as well
500            as approved approvers */
501         IF ( pApproverName = approverList(i).name AND ( approverList(i).approval_status IS NULL
502              OR approverList(i).approval_status NOT IN (ame_util.repeatedStatus,ame_util.suppressedStatus,
503                 ame_util.notifiedByRepeatedStatus, ame_util.approvedByRepeatedStatus,
504                 ame_util.rejectedByRepeatedStatus, ame_util.approvedStatus,
505                 ame_util.rejectStatus))) THEN
506            l_approver_position := i;
507 	   /* Once we locate the approver terminate the loop */
508            EXIT;
509         END IF;
510      end loop;
511      l_group_or_chain_id := approverList(l_approver_position).group_or_chain_id;
512      l_action_type_id := approverList(l_approver_position).action_type_id;
513      l_insertion_type := approverList(l_approver_position).api_insertion; -- Set insertion type which will be used to identify adhoc approver
514 
515      /* Condition 1.1: If we are inserting after an approver who belongs to a group
516         Condition 1.2: If we are inserting after an approver who is either adhoc or belongs to COA
517         Condition 2.1: If we are inserting approver before an approver who belongs to a group
518         Condition 2.2: If we are inserting before an approver who is either adhoc or belongs to COA
519         In each case we have to take care of approvers who are repeated or deleted (suppressed)
520         And if there are approvers like this then either increment or decrement positionId depending upon whether
521         we are inserting after or before */
522      IF pInsertionType = 'A' THEN
523         l_counter := l_approver_position +1;
524         /* Check if the approver is adhoc or not. If adhoc then we need not to look for any repeated or supressed approver.
525            Checking it for 'after' case and not 'before' because insertion before adhoc is only possible if adhoc is inserted at
526            the left end of chain. And in that case action_type_id is enough to locate exact position of insertion
527            Requirement of these extra statuses have beed explained earlier. Not included condition check of 'approvedStatus'
528            for 'before' case, because we dont provide option to insert before approver who have approved */
529         IF l_insertion_type <> ame_util.apiInsertion THEN
530           if l_group_or_chain_id > 1  then
531              while( l_counter <= approverList.count AND approverList(l_counter).group_or_chain_id = l_group_or_chain_id
532 	           AND approverList(l_counter).approval_status IN (ame_util.repeatedStatus,ame_util.suppressedStatus,
533                        ame_util.notifiedByRepeatedStatus, ame_util.approvedByRepeatedStatus, ame_util.rejectedByRepeatedStatus,
534                        ame_util.approvedStatus) ) LOOP
535                l_counter := l_counter + 1;
536              END LOOP;
537 	  else
538 	      while( l_counter <= approverList.count AND approverList(l_counter).action_type_id = l_action_type_id
539 	            AND approverList(l_counter).approval_status IN (ame_util.repeatedStatus,ame_util.suppressedStatus,
540                         ame_util.notifiedByRepeatedStatus, ame_util.approvedByRepeatedStatus, ame_util.rejectedByRepeatedStatus,
541                        ame_util.approvedStatus) ) LOOP
542                 l_counter := l_counter + 1;
543               END LOOP;
544 	  end if;
545         END IF;
546         absolutePosition := l_counter;
547     ELSE
548         l_counter := l_approver_position - 1;
549         if l_group_or_chain_id > 1 then
550 	   while( l_counter > 0 AND approverList(l_counter).group_or_chain_id = l_group_or_chain_id
551 	          AND approverList(l_counter).approval_status IN (ame_util.repeatedStatus,ame_util.suppressedStatus,
552                       ame_util.notifiedByRepeatedStatus, ame_util.approvedByRepeatedStatus, ame_util.rejectedByRepeatedStatus)) LOOP
553                l_counter := l_counter - 1;
554             END LOOP;
555 	 else
556 	     while( l_counter > 0 AND approverList(l_counter).action_type_id = l_action_type_id
557 	            AND approverList(l_counter).approval_status IN (ame_util.repeatedStatus,ame_util.suppressedStatus,
558                         ame_util.notifiedByRepeatedStatus, ame_util.approvedByRepeatedStatus, ame_util.rejectedByRepeatedStatus	)) LOOP
559                 l_counter := l_counter - 1;
560              END LOOP;
561 	 end if;
562 	 absolutePosition := l_counter + 1;
563      END IF;
564 
565   /* If we dont have any repeated approver */
566   ELSE
567     absolutePosition := pApproverNumber;
568   END IF;
569 
570   -- Verify the available insertions list from ame by giving the position number
571   -- Ame will give the output available list if the insertion is possible.
572   if g_fnd_debug = 'Y' then
573       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
574         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' final absolutePosition :'  || absolutePosition  );
575         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api3.getAvailableInsertions()..');
576       END IF;
577   end if;
578 
579   ame_api3.getAvailableInsertions( applicationIdIn        => applicationId,
580                                    transactionIdIn        => pReqHeaderId,
581                                    positionIn             => absolutePosition,
582                                    transactionTypeIn      => ameTransactionType,
583                                    availableInsertionsOut => availableInsertionList
584                                  );
585 
586   if g_fnd_debug = 'Y' then
587       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
588         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api3.getAvailableInsertions()..');
589       END IF;
590   end if;
591 
592   -- Iterate through the available list and find out the authority approver insertion location.
593   -- Once we get the exact available location, then simply populate the approver record's mandatory fields.
594 
595   IF(approverList.count = 0) THEN
596     FOR i IN 1 .. availableInsertionList.COUNT LOOP
597     IF availableInsertionList(i).order_type IN
598         (ame_util.absoluteOrder,ame_util.afterApprover, ame_util.beforeApprover) AND
599        availableInsertionList(i).api_insertion = tmpApprover.api_insertion AND
600        availableInsertionList(i).authority = tmpApprover.authority THEN
601 
602       insertOrder := availableInsertionList(i);
603 
604       tmpApprover.item_class := insertOrder.item_class;
605       tmpApprover.item_id := insertOrder.item_id;
606       tmpApprover.action_type_id := insertOrder.action_type_id;
607       tmpApprover.group_or_chain_id := insertOrder.group_or_chain_id;
608       tmpApprover.api_insertion := insertOrder.api_insertion;
609       tmpApprover.authority := insertOrder.authority;
610 
611       -- retrieve the name from wf_roles table for the given orig_system and orig_system_id values.
612       -- this name field does not refer to neither employee name nor position name
613       -- this name filed is the mandatory key field for the approverrecord2. We should pass this to ame. Otherwise ame will throw exception.
614       -- bug 9395808
615       -- fix The problem of just picking up the first approver randomly when an approver is manually
616       -- inserted in the chain in iProc.
617       -- it should pick up the approver with earliest start date.
618       -- also validating the approver status
619       SELECT name into tmpApprover.name FROM (
620  	             SELECT name
621  	             FROM wf_roles
622  	             WHERE orig_system = tmpApprover.orig_system and orig_system_id = tmpApprover.orig_system_id
623  	                   and status = 'ACTIVE' and trunc (nvl( expiration_date, sysdate)) >= trunc(sysdate)
624  	             ORDER BY start_date
625  	             )
626  	    WHERE rownum = 1;
627 
628       IF tmpApprover.name IS NULL THEN
629               raise_application_error(-20001, 'Record Not Found in WF_ROLES for the orig_system_id :' ||
630                                                tmpApprover.orig_system_id || ' -- orig_system :' || tmpApprover.orig_system );
631       END IF;
632 
633       if g_fnd_debug = 'Y' then
634            IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
635              FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Found the available position also to insert..');
636            END IF;
637       end if;
638 
639       hasAvailableOrder := true;
640       EXIT;
641 
642     END IF;
643     END LOOP;
644  ELSE
645   FOR i IN 1 .. availableInsertionList.COUNT LOOP
646      /* We can insert after an approver if we have order_type in absoluteOrder,afterApprover or beforeApprover
647         And for insertion before an approver we should have order_type as beforeApprover */
648      IF ((pInsertionType = 'A' and availableInsertionList(i).order_type IN ( ame_util.absoluteOrder,ame_util.afterApprover, ame_util.beforeApprover))
649           OR (pInsertionType = 'B' and availableInsertionList(i).order_type = ame_util.beforeApprover)) AND
650        availableInsertionList(i).api_insertion = tmpApprover.api_insertion AND
651        availableInsertionList(i).authority = tmpApprover.authority THEN
652 
653       insertOrder := availableInsertionList(i);
654 
655       tmpApprover.item_class := insertOrder.item_class;
656       tmpApprover.item_id := insertOrder.item_id;
657       tmpApprover.action_type_id := insertOrder.action_type_id;
658       tmpApprover.group_or_chain_id := insertOrder.group_or_chain_id;
659       tmpApprover.api_insertion := insertOrder.api_insertion;
660       tmpApprover.authority := insertOrder.authority;
661 
662       -- retrieve the name from wf_roles table for the given orig_system and orig_system_id values.
663       -- this name field does not refer to neither employee name nor position name
664       -- this name filed is the mandatory key field for the approverrecord2. We should pass this to ame. Otherwise ame will throw exception.
665       -- bug 9395808
666       -- fix The problem of just picking up the first approver randomly when an approver is manually
667       -- inserted in the chain in iProc.
668       -- it should pick up the approver with earliest start date.
669       -- also validating the approver status
670       SELECT name into tmpApprover.name FROM (
671  	             SELECT name
672  	             FROM wf_roles
673  	             WHERE orig_system = tmpApprover.orig_system and orig_system_id = tmpApprover.orig_system_id
674  	                   and status = 'ACTIVE' and trunc (nvl( expiration_date, sysdate)) >= trunc(sysdate)
675  	             ORDER BY start_date
676  	             )
677  	    WHERE rownum = 1;
678 
679       IF tmpApprover.name IS NULL THEN
680               raise_application_error(-20001, 'Record Not Found in WF_ROLES for the orig_system_id :' ||
681                                                tmpApprover.orig_system_id || ' -- orig_system :' || tmpApprover.orig_system );
682       END IF;
683 
684       if g_fnd_debug = 'Y' then
685            IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
686              FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Found the available position also to insert..');
687            END IF;
688       end if;
689 
690       hasAvailableOrder := true;
691       EXIT;
692 
693     END IF;
694   END LOOP;
695  END IF;
696   -- Call ame api to insert an approver if the hasAvailableOrder = true
697   -- tmpApprover will be the new approver record and will be inserted in the absolutePosition.
698   if (hasAvailableOrder) then
699 
700      if g_fnd_debug = 'Y' then
701           IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
702             FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api3.insertApprover()..');
703           END IF;
704      end if;
705 
706      ame_api3.insertApprover( applicationIdIn   => applicationId,
707                               transactionIdIn   => pReqHeaderId,
708                               approverIn        => tmpApprover,
709                               positionIn        => absolutePosition,
710                               insertionIn       => insertOrder,
711                               transactionTypeIn => ameTransactionType
712                            );
713 
714      if g_fnd_debug = 'Y' then
715           IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
716             FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api3.insertApprover()..');
717           END IF;
718      end if;
719     -- Once we insert an approver to ame, get the updated list of approvers from ame.
720     getAllApprovers(pReqHeaderId, ameTransactionType, pApprovalListStr, pApprovalListCount);
721 
722     if g_fnd_debug = 'Y' then
723         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
724           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving insert_approver...');
725         END IF;
726         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
727           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListStr :' || pApprovalListStr);
728         END IF;
729         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
730           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListCount :' || pApprovalListCount);
731         END IF;
732     end if;
733 
734     return;
735   end if;
736 
737   raise E_NO_AVAILABLE_INSERTION;
738 
739 exception
740   when E_NO_AVAILABLE_INSERTION then
741     pApprovalListCount := 0;
742     pApprovalListStr := 'EXCEPTION-E_NO_AVAILABLE_INSERTION';
743     if g_fnd_debug = 'Y' then
744       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
745         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
746                       l_api_name || '.E_NO_AVAILABLE_INSERTION', 'No available insertion order');
747       END IF;
748     end if;
749   when NO_DATA_FOUND then
750     pApprovalListCount := 0;
751     pApprovalListStr := 'NO_DATA_FOUND';
752     if g_fnd_debug = 'Y' then
753       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
754         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
755                       l_api_name || '.NO_DATA_FOUND', 'NO_DATA_FOUND');
756       END IF;
757     end if;
758   when others then
759     pApprovalListCount := 0;
760     pApprovalListStr := 'EXCEPTION';
761     if g_fnd_debug = 'Y' then
762       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
763         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
764                       l_api_name || '.others_exception', sqlerrm);
765       END IF;
766     end if;
767 end;
768 
769 --------------------------------------------------------------------------------
770 --Start of Comments
771 --Name: delete_approver
772 --Function:
773 --  Call AME API to delete an approver from the current approver list.
774 --  The new approval list is retrieved after the deletion.
775 
776 --Parameters:
777 --IN:
778 --    pReqHeaderId       Requisition Header ID
779 --    pPersonId          Person ID of the approver to be deleted
780 --OUT:
781 --    pApprovalListStr   Approval List concatenated in a string
782 --    pApprovalListCount Number of Approvers.
783 --                       It has a value of 0, if the document does not require approval.
784 --    pQuoteChar         Quote Character, used for escaping purpose in tokenization
785 --    pFieldDelimiter    Field Delimiter, used for delimiting list string into elements.
786 --End of Comments
787 --------------------------------------------------------------------------------
788 procedure delete_approver(  pReqHeaderId        IN  NUMBER,
789                             pPersonId           IN  NUMBER,
790                             pOrigSystem         IN VARCHAR2,
791                             pOrigSystemId       IN NUMBER,
792                             pRecordName         IN VARCHAR2,
793                             pAuthority          IN VARCHAR2,
794                             pApprovalListStr    OUT NOCOPY VARCHAR2,
795                             pApprovalListCount  OUT NOCOPY NUMBER,
796                             pQuoteChar          OUT NOCOPY VARCHAR2,
797                             pFieldDelimiter     OUT NOCOPY VARCHAR2
798                           ) IS
799 
800   l_api_name varchar2(50):= 'delete_approver';
801   tmpApprover      ame_util.approverRecord2;
802   ameTransactionType po_document_types.ame_transaction_type%TYPE;
803 
804   approverList      ame_util.approversTable2;
805   l_process_out      VARCHAR2(10);
806   l_first_position_id NUMBER;
807 
808 begin
809 
810    if g_fnd_debug = 'Y' then
811        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
812          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering delete_approver...');
813        END IF;
814        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
815          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pReqHeaderId :' || pReqHeaderId );
816        END IF;
817        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
818          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pPersonId :' || pPersonId );
819        END IF;
820        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
821          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pOrigSystem :' || pOrigSystem );
822        END IF;
823        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
824          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pOrigSystemId :' || pOrigSystemId );
825        END IF;
826        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
827          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pRecordName :' || pRecordName );
828        END IF;
829        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
830          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pAuthority :' || pAuthority );
831        END IF;
832    end if;
833 
834   getAmeTransactionType(pReqHeaderId => pReqHeaderId,
835                     pAmeTransactionType => ameTransactionType);
836 
837   pQuoteChar :=quoteChar;
838   pFieldDelimiter :=fieldDelimiter;
839 
840   -- Frame the approverRecord2 from the input parameters.
841   tmpApprover.orig_system_id := pOrigSystemId;
842   tmpApprover.orig_system    := pOrigSystem;
843   tmpApprover.name           := pRecordName;
844   tmpApprover.authority      := pAuthority;
845 
846   if g_fnd_debug = 'Y' then
847        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
848          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api2.getAllApprovers7()..');
849        END IF;
850   end if;
851 
852   -- get the AME approvers list
853   ame_api2.getAllApprovers7( applicationIdIn => applicationId,
854                              transactionIdIn => pReqHeaderId,
855                              transactionTypeIn => ameTransactionType,
856                              approvalProcessCompleteYNOut => l_process_out,
857                              approversOut => approverList
858                            );
859 
860   if g_fnd_debug = 'Y' then
861        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
862          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api2.getAllApprovers7()..');
863        END IF;
864   end if;
865 
866   -- check for the given approver details in the approval list
867   -- the approver should be there in the approval list
868   -- once we get the approver details in the list, simply copy the record to tmpApprover approverRecord2.
869   for i in 1 .. approverList.count loop
870 
871     if g_fnd_debug = 'Y' then
872       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
873         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Searching through list of Approvers for match');
874         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  name: ' || tmpApprover.name || ' ? ' || approverList(i).name);
875         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  orig_system: ' || tmpApprover.orig_system || ' ? ' || approverList(i).orig_system);
876         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  orig_system_id: ' || tmpApprover.orig_system_id || ' ? ' || approverList(i).orig_system_id);
877         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  authority: ' || tmpApprover.authority || ' ? ' || approverList(i).authority);
878         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  status is NULL or NOT SUPPRESSED: ' || approverList(i).approval_status);
879       END IF;
880     end if;
881 
882     if( approverList(i).name = tmpApprover.name and
883         approverList(i).orig_system = tmpApprover.orig_system and
884         approverList(i).orig_system_id = tmpApprover.orig_system_id and
885         approverList(i).authority = tmpApprover.authority and
886         ( approverList(i).approval_status is null or
887           approverList(i).approval_status = ame_util.nullStatus or
888           approverList(i).approval_status <> ame_util.suppressedStatus) ) then
889 
890            if g_fnd_debug = 'Y' then
891                 IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
892                   FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Found the approver to be deleted also in the list...');
893                   FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Approver Name = ' || tmpApprover.name);
894                   FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Approver Action Type Id = ' || approverList(i).action_type_id);
895                   FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Approver Status = ' ||  approverList(i).approval_status);
896                 END IF;
897            end if;
898           tmpApprover :=  approverList(i) ;
899           exit;
900 
901     end if;
902   end loop;
903 
904   -- Call the ame api to delete the approver.
905   -- tmpApprover will be deleted from the approver list
906   if g_fnd_debug = 'Y' then
907        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
908          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api3.suppressApprover()..');
909        END IF;
910   end if;
911   ame_api3.suppressApprover( applicationIdIn   => applicationId,
912                              transactionIdIn   => pReqHeaderId,
913                              approverIn        => tmpApprover,
914                              transactionTypeIn => ameTransactionType
915                            );
916 
917   if g_fnd_debug = 'Y' then
918        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
919          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api3.suppressApprover()..');
920        END IF;
921   end if;
922 
923   if (tmpApprover.orig_system=ame_util.posOrigSystem) THEN
924 
925     SELECT FIRST_POSITION_ID
926     INTO l_first_position_id
927     FROM po_requisition_headers_all
928     WHERE requisition_header_id = pReqHeaderId;
929 
930     if g_fnd_debug = 'Y' then
931       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
932         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'POS Record is being suppressed.');
933       END IF;
934       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
935         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Stored FIRST_POSITION_ID = ' || l_first_position_id);
936       END IF;
937     end if;
938 
939     if (tmpApprover.orig_system_id=l_first_position_id) then
940     -- we are suppressing the First Position Approver;
941     -- thus, we need to clear the values from the req headers table.
942 
943         UPDATE po_requisition_headers_all
944         SET first_position_id = NULL, first_approver_id = NULL
945         WHERE requisition_header_id = pReqHeaderId;
946 
947         if g_fnd_debug = 'Y' then
948           IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
949             FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name,
950                  'Cleared first_position_id and first_approver_id from req_header table.');
951           END IF;
952         end if;
953 
954     END IF;
955   END IF;
956 
957   -- Once we delete an approver from the approval list, get the updated approval list from ame.
958   getAllApprovers(pReqHeaderId, ameTransactionType, pApprovalListStr, pApprovalListCount);
959 
960   if g_fnd_debug = 'Y' then
961       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
962         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving delete_approver...');
963       END IF;
964       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
965         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListStr :' || pApprovalListStr);
966       END IF;
967       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
968         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListCount :' || pApprovalListCount);
969       END IF;
970   end if;
971 
972 exception
973   when NO_DATA_FOUND then
974     pApprovalListCount := 0;
975     pApprovalListStr := 'NO_DATA_FOUND';
976     if g_fnd_debug = 'Y' then
977       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
978         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
979                       l_api_name || '.NO_DATA_FOUND', 'NO_DATA_FOUND');
980       END IF;
981     end if;
982   when others then
983     pApprovalListCount := 0;
984     pApprovalListStr := 'EXCEPTION:' || sqlerrm;
985     if g_fnd_debug = 'Y' then
986       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
987         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
988                       l_api_name || '.others_exception', sqlerrm);
989       END IF;
990     end if;
991 end;
992 
993 --------------------------------------------------------------------------------
994 --Start of Comments
995 --Name: get_ame_approval_list
996 --Function:
997 --  Call AME API to build the latest approver list.
998 --  If the approver list should be defaulted,
999 --  Then the history of the list will be cleared before building a list, except the following case:
1000 --    If the defaulting is for opening saved cart:
1001 --    (an incompleted requisition which did not have past approval action)
1002 
1003 --Parameters:
1004 --IN:
1005 --    pReqHeaderId       Requisition Header ID
1006 --    pDefaultFlag       Value 1 if approver list should be defaulted.
1007 --                       Value -1 if approver list is to be rebuilt for iP approver checkout
1008 --                       null value if the latest approver list is to be
1009 --                       retrieved in all other cases.
1010 
1011 --OUT:
1012 --    pApprovalListStr   Approval List concatenated in a string
1013 --    pApprovalListCount Number of Approvers.
1014 --                       It has a value of 0, if the document does not require approval.
1015 --    pQuoteChar         Quote Character, used for escaping purpose in tokenization
1016 --    pFieldDelimiter    Field Delimiter, used for delimiting list string into elements.
1017 --    pApprovalAction    'Y' if there were approvers taken action on the document.
1018 --                       Those approvers are not included in the list,
1019 --                       Only the future approvers are returned.
1020 --End of Comments
1021 --------------------------------------------------------------------------------
1022 procedure get_ame_approval_list(pReqHeaderId    IN  NUMBER,
1023                             pDefaultFlag        IN  NUMBER,
1024                             pApprovalListStr    OUT NOCOPY VARCHAR2,
1025                             pApprovalListCount  OUT NOCOPY NUMBER,
1026                             pQuoteChar              OUT NOCOPY VARCHAR2,
1027                             pFieldDelimiter         OUT NOCOPY VARCHAR2,
1028                             pApprovalAction OUT NOCOPY VARCHAR2
1029 ) IS
1030 
1031   l_api_name varchar2(50):= 'get_ame_approval_list';
1032   --approverList      ame_util.approversTable;
1033   clearListForSavedCart varchar2(1) := 'N';
1034   authorizationStatus po_requisition_headers.authorization_status%TYPE;
1035   preparerId po_requisition_headers.preparer_id%TYPE;
1036   ameTransactionType po_document_types.ame_transaction_type%TYPE;
1037 
1038   l_itemtype po_requisition_headers.wf_item_type%TYPE;
1039   l_itemkey po_requisition_headers.wf_item_key%TYPE;
1040 
1041   approverList      ame_util.approversTable2;
1042   l_process_out      VARCHAR2(10);
1043   l_progress      VARCHAR2(10);
1044   l_appr NUMBER;
1045 
1046 BEGIN
1047 
1048    if g_fnd_debug = 'Y' then
1049        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1050          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering get_ame_approval_list...');
1051        END IF;
1052        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1053          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pReqHeaderId :' || pReqHeaderId );
1054        END IF;
1055        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1056          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pDefaultFlag :' || pDefaultFlag );
1057        END IF;
1058    end if;
1059 
1060   -- pDefaultFlag:
1061   --    -1: Approver Checkout
1062   --     1: Possible Reset
1063   --     2: Force Reset
1064   --  null: Load Current List
1065 
1066   if (pDefaultFlag = -1) then
1067     SELECT wf_item_type, wf_item_key
1068     INTO l_itemtype, l_itemkey
1069     FROM po_requisition_headers_all
1070     WHERE requisition_header_id = pReqHeaderId;
1071     ameTransactionType := PO_WF_UTIL_PKG.GetItemAttrText( itemtype => l_itemtype,
1072                               itemkey    => l_itemkey,
1073                               aname      => 'AME_TRANSACTION_TYPE');
1074   else
1075     getAmeTransactionType(pReqHeaderId => pReqHeaderId,
1076                     pAmeTransactionType => ameTransactionType);
1077   end if;
1078 
1079   pQuoteChar :=quoteChar;
1080   pFieldDelimiter :=fieldDelimiter;
1081 
1082   if (pDefaultFlag=1 OR pDefaultFlag=2) then
1083     /* check to see it is not open saved cart */
1084     select authorization_status, preparer_id
1085     into authorizationStatus, preparerId
1086     from po_requisition_headers
1087     where requisition_header_id = pReqHeaderId;
1088 
1089     -- Get the approval list from ame.
1090     -- Based on our function design, we clear the approval list before calling the getAllApprovers7 call.
1091     -- If we call clearAllApprovals all the inserted/deleted approvers by the users will be ignored.
1092     -- AME will return the rule generated approvers if we call getAllApprovers after the clearAllApprovals call.
1093 
1094     if g_fnd_debug = 'Y' then
1095          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1096            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'authorizationStatus :' || authorizationStatus);
1097          END IF;
1098     end if;
1099 
1100     -- if INCOMPLETE and pDefaultFlag is 1 (non-force), then check to see if we should reset or not
1101     if (authorizationStatus = 'INCOMPLETE' AND pDefaultFlag=1) then
1102 
1103       if g_fnd_debug = 'Y' then
1104            IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1105              FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api2.getAllApprovers7()a...');
1106            END IF;
1107       end if;
1108 
1109       BEGIN
1110       l_progress := '000';
1111 
1112 /*Bug 6314864 and 10107113: commented in case of final approver times out*/
1113 
1114       ame_api2.getAllApprovers7( applicationIdIn   => applicationId,
1115                                  transactionIdIn   => pReqHeaderId,
1116                                  transactionTypeIn => ameTransactionType,
1117                                  approvalProcessCompleteYNOut => l_process_out,
1118                                  approversOut      => approverList
1119                                );
1120      l_progress := '001';
1121 
1122       if g_fnd_debug = 'Y' then
1123            IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1124              FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' Done with ame_api6.getApprovers...progress='|| l_progress );
1125            END IF;
1126       end if;
1127 
1128       for i in 1 .. approverList.count loop
1129         if(approverList(i).approval_status is not null
1130             and approverList(i).orig_system_id <> preparerId) then
1131           /* this is not a saved cart, need to clear the list */
1132           clearListForSavedCart := 'Y';
1133           l_progress := '005';
1134           exit;
1135         end if;
1136       end loop;
1137 
1138       EXCEPTION when others then
1139         SELECT Count(*) INTO  l_appr
1140         FROM po_action_history WHERE
1141         object_id =pReqHeaderId
1142         AND  OBJECT_TYPE_CODE =  'REQUISITION'
1143         AND  ACTION_CODE <> 'SUBMIT';
1144 
1145         if g_fnd_debug = 'Y' then
1146            IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1147              FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Exception in ame_api2.getAllApprovers7,l_appr= ' || l_appr||' progress='|| l_progress );
1148            END IF;
1149         end if;
1150         IF l_appr <> 0 THEN
1151            clearListForSavedCart := 'Y';
1152         END IF;
1153 
1154       END;
1155 
1156       if g_fnd_debug = 'Y' then
1157          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1158            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'clearListForSavedCart :' || clearListForSavedCart);
1159          END IF;
1160       end if;
1161 
1162       if (clearListForSavedCart = 'Y') then
1163 
1164          -- clear columns since we are rebuilding the approval list
1165          UPDATE po_requisition_headers_all
1166          SET first_position_id = NULL, first_approver_id = NULL
1167          WHERE requisition_header_id = pReqHeaderId;
1168 
1169          if g_fnd_debug = 'Y' then
1170              IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1171                FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name,
1172                  'Cleared first_position_id and first_approver_id from req_header table.');
1173                FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api2.clearAllApprovals()a...');
1174              END IF;
1175          end if;
1176 
1177          ame_api2.clearAllApprovals( applicationIdIn   => applicationId,
1178                                      transactionIdIn   => pReqHeaderId,
1179                                      transactionTypeIn => ameTransactionType
1180                                    );
1181 
1182          if g_fnd_debug = 'Y' then
1183              IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1184                FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api2.clearAllApprovals()a...');
1185              END IF;
1186              IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1187                FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api2.getAllApprovers7()b...');
1188              END IF;
1189          end if;
1190 
1191          ame_api2.getAllApprovers7( applicationIdIn   => applicationId,
1192                                     transactionIdIn   => pReqHeaderId,
1193                                     transactionTypeIn => ameTransactionType,
1194                                     approvalProcessCompleteYNOut => l_process_out,
1195                                     approversOut      => approverList
1196                                   );
1197         if g_fnd_debug = 'Y' then
1198              IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1199                FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api2.getAllApprovers7()b...');
1200              END IF;
1201          end if;
1202 
1203       end if; -- if(clearListForSavedCart = 'Y')
1204 
1205     else -- if (pDefaultFlag=2) or (pDefaultFlag=1 and not INCOMPLETE), this will force the reset
1206 
1207        -- clear columns since we are rebuilding the approval list
1208        UPDATE po_requisition_headers_all
1209        SET first_position_id = NULL, first_approver_id = NULL
1210        WHERE requisition_header_id = pReqHeaderId;
1211 
1212        if g_fnd_debug = 'Y' then
1213            IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1214              FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name,
1215                'Cleared first_position_id and first_approver_id from req_header table.');
1216              FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api2.clearAllApprovals()b...');
1217            END IF;
1218        end if;
1219 
1220        ame_api2.clearAllApprovals( applicationIdIn   => applicationId,
1221                                    transactionIdIn   => pReqHeaderId,
1222                                    transactionTypeIn => ameTransactionType
1223                                   );
1224 
1225        if g_fnd_debug = 'Y' then
1226              IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1227                FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api2.clearAllApprovals()b...');
1228              END IF;
1229              IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1230                FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api2.getAllApprovers7()c...');
1231              END IF;
1232        end if;
1233 
1234        ame_api2.getAllApprovers7( applicationIdIn   => applicationId,
1235                                   transactionIdIn   => pReqHeaderId,
1236                                   transactionTypeIn => ameTransactionType,
1237                                   approvalProcessCompleteYNOut => l_process_out,
1238                                   approversOut      => approverList
1239                                 );
1240       if g_fnd_debug = 'Y' then
1241            IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1242              FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api2.getAllApprovers7()c...');
1243            END IF;
1244       end if;
1245 
1246    end if; -- if ( authorizationStatus = 'INCOMPLETE')
1247 
1248   else -- if pDefaultFlag is null or -1
1249 
1250    if g_fnd_debug = 'Y' then
1251          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1252            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api2.getAllApprovers7()d...');
1253          END IF;
1254    end if;
1255 
1256    ame_api2.getAllApprovers7( applicationIdIn   => applicationId,
1257                               transactionIdIn   => pReqHeaderId,
1258                               transactionTypeIn => ameTransactionType,
1259                               approvalProcessCompleteYNOut => l_process_out,
1260                               approversOut      => approverList
1261                             );
1262 
1263    if g_fnd_debug = 'Y' then
1264         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1265           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api2.getAllApprovers7()d...');
1266         END IF;
1267    end if;
1268 
1269   end if; -- if(pDefaultFlag = 1)
1270 
1271   if(approverList.count > 0) then
1272     pApprovalListStr := serializeApproversTable( approverList, pReqHeaderId, pApprovalListCount, pApprovalAction );
1273   else
1274     pApprovalListCount:=0;
1275   end if;
1276   if g_fnd_debug = 'Y' then
1277       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1278         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving get_ame_approval_list...');
1279       END IF;
1280       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1281         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListStr :' || pApprovalListStr);
1282       END IF;
1283       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1284         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListCount :' || pApprovalListCount);
1285       END IF;
1286   end if;
1287 
1288 exception
1289   when NO_DATA_FOUND then
1290     pApprovalListCount := 0;
1291     pApprovalListStr := 'NO_DATA_FOUND';
1292     if g_fnd_debug = 'Y' then
1293       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
1294         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
1295                       l_api_name || '.NO_DATA_FOUND', 'NO_DATA_FOUND');
1296       END IF;
1297     end if;
1298   when others then
1299     pApprovalListCount := 0;
1300     pApprovalListStr := 'EXCEPTION:' || sqlerrm;
1301     if g_fnd_debug = 'Y' then
1302       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
1303         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
1304                       l_api_name || '.others_exception', sqlerrm);
1305       END IF;
1306     end if;
1307 END get_ame_approval_list;
1308 
1309 --------------------------------------------------------------------------------
1310 --Start of Comments
1311 --Name: is_ame_reqapprv_workflow
1312 --Function:
1313 --  Returns 'Y' if the requisition workflow uses AME for approval routing
1314 --  Returns 'N' if the requisition workflow does not AME for approval routing
1315 
1316 --Parameters:
1317 --IN:
1318 --    pReqHeaderId       Requisition Header ID
1319 --OUT:
1320 --    None
1321 --End of Comments
1322 --------------------------------------------------------------------------------
1323 function is_ame_reqapprv_workflow (pReqHeaderId    IN  NUMBER,
1324                                    pIsRcoApproval  IN BOOLEAN,
1325                                    xAmeTransactionType OUT NOCOPY VARCHAR2)
1326 return varchar2 IS
1327   isAmeApproval varchar2 (1);
1328   l_itemtype po_requisition_headers.wf_item_type%TYPE;
1329   l_itemkey po_requisition_headers.wf_item_key%TYPE;
1330 
1331 BEGIN
1332 
1333   if (pIsRcoApproval) then
1334     SELECT DISTINCT wf_item_type, wf_item_key
1335     INTO l_itemtype, l_itemkey
1336     FROM po_change_requests
1337     WHERE document_header_id= pReqHeaderId AND
1338           document_type = 'REQ' AND
1339           action_type IN ('MODIFICATION', 'CANCELLATION') AND
1340           creation_date = (select max(creation_date)
1341                           from PO_CHANGE_REQUESTS
1342                           where DOCUMENT_HEADER_ID = pReqHeaderId) AND
1343           request_status NOT IN ('ACCEPTED', 'REJECTED');
1344   else
1345     SELECT wf_item_type, wf_item_key
1346     INTO l_itemtype, l_itemkey
1347     FROM po_requisition_headers_all
1348     WHERE requisition_header_id = pReqHeaderId;
1349   end if;
1350 
1351   isAmeApproval := PO_WF_UTIL_PKG.GetItemAttrText( itemtype => l_itemtype,
1352                               itemkey    => l_itemkey,
1353                               aname      => 'IS_AME_APPROVAL');
1354 
1355   if (isAmeApproval = 'Y') then
1356    xAmeTransactionType := PO_WF_UTIL_PKG.GetItemAttrText( itemtype => l_itemtype,
1357                               itemkey    => l_itemkey,
1358                               aname      => 'AME_TRANSACTION_TYPE');
1359    return 'Y';
1360   else
1361    return 'N';
1362   end if;
1363 END;
1364 
1365 --------------------------------------------------------------------------------
1366 --Start of Comments
1367 --Name: get_old_approval_list
1368 --Function:
1369 --  Call AME API to get the existing approval list for a requisition.
1370 --  Only the future approval list is returned.
1371 
1372 --Parameters:
1373 --IN:
1374 --    pReqHeaderId       Requisition Header ID
1375 --OUT:
1376 --    pApprovalListStr   Furture Approval List concatenated in a string
1377 --    pApprovalListCount Number of Approvers. It has a value of 0,
1378 --                       if AME did not build approval list for this transaction.
1379 --    pQuoteChar         Quote Character, used for escaping purpose in tokenization
1380 --    pFieldDelimiter    Field Delimiter, used for delimiting list string into elements.
1381 --End of Comments
1382 --------------------------------------------------------------------------------
1383 procedure get_old_approval_list(pReqHeaderId    IN  NUMBER,
1384                             pApprovalListStr    OUT NOCOPY VARCHAR2,
1385                             pApprovalListCount  OUT NOCOPY NUMBER,
1386                             pQuoteChar          OUT NOCOPY VARCHAR2,
1387                             pFieldDelimiter     OUT NOCOPY VARCHAR2) IS
1388 
1389   l_api_name varchar2(50):= 'get_old_approval_list';
1390   hasApprovalAction varchar2(1);
1391   approverCount number;
1392   approverList      ame_util.approversTable2;
1393   ameTransactionType po_document_types.ame_transaction_type%TYPE;
1394   authorizationStatus po_requisition_headers_all.authorization_status%TYPE;
1395   isRcoApproval boolean := false;
1396   changeRequestExist number := 0;
1397   l_process_out VARCHAR2(10);
1398 
1399 BEGIN
1400 
1401    if g_fnd_debug = 'Y' then
1402        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1403          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering get_old_approval_list...');
1404        END IF;
1405        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1406          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pReqHeaderId :' || pReqHeaderId );
1407        END IF;
1408    end if;
1409 
1410   begin
1411     select authorization_status
1412     into authorizationStatus
1413     from po_requisition_headers_all
1414     where requisition_header_id = pReqHeaderId;
1415   exception
1416     when others then
1417     if g_fnd_debug = 'Y' then
1418       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
1419         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
1420                       l_api_name || '.others_exception', sqlerrm);
1421       END IF;
1422     end if;
1423     return;
1424   end;
1425 
1426   if g_fnd_debug = 'Y' then
1427        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1428          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'authorizationStatus :' || authorizationStatus);
1429        END IF;
1430   end if;
1431 
1432   if (authorizationStatus <> 'IN PROCESS' and authorizationStatus <> 'PRE-APPROVED') then
1433     -- if the requisition is approved, check if it is rco transaction
1434     if (authorizationStatus = 'APPROVED') then
1435       begin
1436         SELECT COUNT(1)
1437         INTO changeRequestExist
1438         FROM
1439           PO_CHANGE_REQUESTS pcr
1440         WHERE
1441           pcr.document_header_id = pReqHeaderId AND
1442           pcr.document_type = 'REQ' AND
1443           pcr.action_type IN ('MODIFICATION', 'CANCELLATION') AND
1444           pcr.approval_required_flag = 'Y' AND
1445           pcr.request_status NOT IN ('ACCEPTED', 'REJECTED');
1446       exception
1447         when others then
1448           null; -- assume not rco or the rco is approved/rejected.
1449       end;
1450       if (changeRequestExist>0) then
1451         isRcoApproval :=true;
1452       else
1453         return;
1454       end if;
1455     else
1456       return;
1457     end if;
1458   end if;
1459 
1460   if (is_ame_reqapprv_workflow (pReqHeaderId, isRcoApproval, ameTransactionType) <> 'Y') then
1461 
1462     pApprovalListCount := 0;
1463     if g_fnd_debug = 'Y' then
1464         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1465           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving get_old_approval_list due to the call is_ame_reqapprv_workflow()...');
1466         END IF;
1467         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1468           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListCount :' || pApprovalListCount);
1469         END IF;
1470     end if;
1471     return;
1472   end if;
1473 
1474   pQuoteChar :=quoteChar;
1475   pFieldDelimiter :=fieldDelimiter;
1476 
1477    if g_fnd_debug = 'Y' then
1478          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1479            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api3.getOldApprovers()...');
1480          END IF;
1481    end if;
1482 
1483   /*
1484   ame_api3.getOldApprovers(applicationIdIn=>applicationId,
1485                             transactionIdIn=>pReqHeaderId,
1486                             transactionTypeIn=>ameTransactionType,
1487                             oldApproversOut=>approverList);
1488   */
1489 
1490  /* ame_api2.getAllApprovers7( applicationIdIn => applicationId,
1491                              transactionIdIn => pReqHeaderId,
1492                              transactionTypeIn => ameTransactionType,
1493                              approvalProcessCompleteYNOut => l_process_out,
1494                              approversOut => approverList
1495                             );*/
1496 
1497  ame_api6.getApprovers2( applicationIdIn => applicationId,
1498 	   transactionTypeIn => ameTransactionType,
1499  	   transactionIdIn => pReqHeaderId,
1500                              approversOut => approverList
1501                             );
1502 
1503    if g_fnd_debug = 'Y' then
1504          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1505            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api3.getOldApprovers()...');
1506          END IF;
1507    end if;
1508 
1509   pApprovalListCount := approverList.count;
1510 
1511   if(approverList.count>0) then
1512     pApprovalListStr := serializeApproversTable(approverList, pReqHeaderId, approverCount, hasApprovalAction);
1513     pApprovalListCount := approverCount;
1514   end if;
1515 
1516   if g_fnd_debug = 'Y' then
1517       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1518         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving get_old_approval_list...');
1519       END IF;
1520       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1521         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListStr :' || pApprovalListStr);
1522       END IF;
1523       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1524         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListCount :' || pApprovalListCount);
1525       END IF;
1526   end if;
1527 
1528 exception
1529   when NO_DATA_FOUND then
1530     pApprovalListCount := 0;
1531     pApprovalListStr := 'NO_DATA_FOUND';
1532     if g_fnd_debug = 'Y' then
1533       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
1534         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
1535                       l_api_name || '.NO_DATA_FOUND', 'NO_DATA_FOUND');
1536       END IF;
1537     end if;
1538   when others then
1539     pApprovalListCount := 0;
1540     pApprovalListStr := 'EXCEPTION';
1541     if g_fnd_debug = 'Y' then
1542       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
1543         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
1544                       l_api_name || '.others_exception', sqlerrm);
1545       END IF;
1546     end if;
1547 END;
1548 
1549 --------------------------------------------------------------------------------
1550 --Start of Comments
1551 --Name: is_req_pre_approved
1552 --Function:
1553 --  Approval workflow PL/SQL handler
1554 --  Check AME approval list to determine if the document requires approval
1555 --  from a chain of authority approver
1556 --  Return 'Y' if yes
1557 --  Return 'N' if no
1558 
1559 --Parameters:
1560 --  Standard workflow in/out parameters
1561 
1562 --End of Comments
1563 --------------------------------------------------------------------------------
1564 procedure is_req_pre_approved(itemtype        in varchar2,
1565                                 itemkey       in varchar2,
1566                                 actid         in number,
1567                                 funcmode      in varchar2,
1568                                 resultout     out NOCOPY varchar2) is
1569 
1570   l_api_name varchar2(50):= 'is_req_pre_approved';
1571   x_progress  varchar2(100);
1572   x_resultout varchar2(30);
1573   l_document_id  number;
1574   l_return_val varchar2(1);
1575 
1576   l_doc_string varchar2(200);
1577   l_preparer_user_name varchar2(100);
1578 
1579   approverCount integer;
1580   approvers ame_util.approversTable2;
1581   ameTransactionType po_document_types.ame_transaction_type%TYPE;
1582   l_process_out VARCHAR2(10);
1583 
1584 BEGIN
1585 
1586   if g_fnd_debug = 'Y' then
1587       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1588         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering is_req_pre_approved...');
1589       END IF;
1590   end if;
1591 
1592   x_progress := 'POR_AME_APPROVAL_LIST.is_req_pre_approved: 01';
1593   IF (g_po_wf_debug = 'Y') THEN
1594      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1595   END IF;
1596 
1597   l_return_val := 'Y';
1598 
1599 
1600   -- Do nothing in cancel or timeout mode
1601   --
1602   if (funcmode <> wf_engine.eng_run) then
1603 
1604       resultout := wf_engine.eng_null;
1605       return;
1606 
1607   end if;
1608 
1609   l_document_id := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1610                                          itemkey  => itemkey,
1611                                          aname    => 'DOCUMENT_ID');
1612 
1613   getAmeTransactionType(pReqHeaderId => to_number(l_document_id),
1614                     pAmeTransactionType => ameTransactionType);
1615 
1616   x_progress := 'POR_AME_APPROVAL_LIST.is_req_pre_approved: 02' || ameTransactionType;
1617   IF (g_po_wf_debug = 'Y') THEN
1618      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1619   END IF;
1620 
1621   -- Get the list of approvers from ame.
1622   if g_fnd_debug = 'Y' then
1623       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1624         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api2.getAllApprovers7()...');
1625       END IF;
1626   end if;
1627 
1628   ame_api2.getAllApprovers7( applicationIdIn => applicationId,
1629                              transactionIdIn => l_document_id,
1630                              transactionTypeIn => ameTransactionType,
1631                              approvalProcessCompleteYNOut => l_process_out,
1632                              approversOut => approvers
1633                             );
1634   if g_fnd_debug = 'Y' then
1635       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1636         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api2.getAllApprovers7()...');
1637       END IF;
1638   end if;
1639   approverCount := approvers.count;
1640 
1641   -- Once we get the list of approvers from AME, check for the approval_status in all the record.
1642   for i in 1 .. approverCount loop
1643     if(approvers(i).authority = ame_util.authorityApprover and
1644            (approvers(i).api_insertion = ame_util.oamGenerated or
1645             approvers(i).api_insertion = ame_util.apiAuthorityInsertion) and
1646            (approvers(i).approval_status is null or
1647             approvers(i).approval_status = ame_util.nullStatus)) then
1648       l_return_val := 'N';
1649       exit;
1650     end if;
1651   end loop;
1652 
1653   resultout := wf_engine.eng_completed || ':' ||  l_return_val;
1654   x_resultout := l_return_val;
1655 
1656   x_progress := 'POR_AME_APPROVAL_LIST.is_req_pre_approved: 02. RESULT= ' || x_resultout;
1657   IF (g_po_wf_debug = 'Y') THEN
1658      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,x_progress);
1659   END IF;
1660 
1661   if g_fnd_debug = 'Y' then
1662       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1663         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving is_req_pre_approved...');
1664       END IF;
1665       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1666         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- x_resultout :' || x_resultout);
1667       END IF;
1668   end if;
1669 
1670 EXCEPTION
1671 
1672   WHEN OTHERS THEN
1673     l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey);
1674     l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey);
1675     WF_CORE.context('POR_AME_APPROVAL_LIST' , 'is_req_pre_approved', itemtype, itemkey, x_progress);
1676     PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name, l_doc_string, sqlerrm, 'POR_AME_APPROVAL_LIST.is_req_pre_approved');
1677     RAISE;
1678 
1679 END is_req_pre_approved;
1680 
1681 
1682 --------------------------------------------------------------------------------
1683 --Start of Comments
1684 --Name: get_first_authority_approver
1685 --Function:
1686 --  Call AME API to fetch the latest approval list
1687 --  Then walk through the list to find a first chain of authority approver
1688 --  for a requisition.
1689 --  The procedure raises any exception thrown by AME engine.
1690 
1691 --Parameters:
1692 --IN:
1693 --    pReqHeaderId       Requisition Header ID
1694 --OUT:
1695 --    xPersonId          The person ID of the chain of authority approver
1696 --                       This variable will have a null value,
1697 --                       if such an approver is not found.
1698 
1699 --End of Comments
1700 --------------------------------------------------------------------------------
1701 procedure get_first_authority_approver(pReqHeaderId    IN  NUMBER,
1702                                        xPersonId       OUT NOCOPY VARCHAR2) IS
1703 
1704   l_api_name varchar2(50):= 'get_first_authority_approver';
1705   approverCount number;
1706   approvers      ame_util.approversTable2;
1707   ameTransactionType po_document_types.ame_transaction_type%TYPE;
1708   l_process_out VARCHAR2(10);
1709 
1710 BEGIN
1711 
1712   if g_fnd_debug = 'Y' then
1713       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1714         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering get_first_authority_approver...');
1715       END IF;
1716       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1717         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param -- pReqHeaderId ' || pReqHeaderId );
1718       END IF;
1719   end if;
1720 
1721   xPersonId := null;
1722   getAmeTransactionType(pReqHeaderId => pReqHeaderId,
1723                     pAmeTransactionType => ameTransactionType);
1724 
1725   -- Get the approvers list from ame.
1726   if g_fnd_debug = 'Y' then
1727       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1728         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api2.getAllApprovers7()...');
1729       END IF;
1730   end if;
1731 
1732   ame_api2.getAllApprovers7( applicationIdIn => applicationId,
1733                              transactionIdIn => pReqHeaderId,
1734                              transactionTypeIn => ameTransactionType,
1735                              approvalProcessCompleteYNOut => l_process_out,
1736                              approversOut => approvers
1737                             );
1738 
1739   if g_fnd_debug = 'Y' then
1740       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1741         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api2.getAllApprovers7()...');
1742       END IF;
1743   end if;
1744 
1745   approverCount := approvers.count;
1746 
1747   -- Once we get the list of approvers from ame, check for the first authority approver record in the list.
1748   -- Check for the action type(POS/PER) in the first authority approver record.
1749   -- If the first record is of position hierarchy type, then find out the person_id from the position id and return that.
1750   -- Otherwise simply return the person_id from the orig_system_id value.
1751 
1752   for i in 1 .. approverCount loop
1753     if(approvers(i).authority = ame_util.authorityApprover and
1754            approvers(i).api_insertion = ame_util.oamGenerated and
1755            (approvers(i).approval_status is null or
1756             approvers(i).approval_status = ame_util.nullStatus)) then
1757 
1758               if approvers(i).orig_system = ame_util.posOrigSystem then
1759 
1760                    if g_fnd_debug = 'Y' then
1761                         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1762                           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'First record is Position Hierarchy action type...');
1763                         END IF;
1764                    end if;
1765 
1766                    begin
1767                        SELECT person_id into xPersonId FROM (
1768                           SELECT person.person_id FROM per_all_people_f person, per_all_assignments_f asg
1769                           WHERE asg.position_id = approvers(i).orig_system_id and trunc(sysdate) between person.effective_start_date
1770                           and nvl(person.effective_end_date, trunc(sysdate)) and person.person_id = asg.person_id
1771                           and asg.primary_flag = 'Y' and asg.assignment_type in ('E','C')
1772                           and ( person.current_employee_flag = 'Y' or person.current_npw_flag = 'Y' )
1773                           and asg.assignment_status_type_id not in (
1774                              SELECT assignment_status_type_id FROM per_assignment_status_types
1775                              WHERE per_system_status = 'TERM_ASSIGN'
1776                          ) and trunc(sysdate) between asg.effective_start_date and asg.effective_end_date order by person.last_name
1777                       ) where rownum = 1;
1778                    exception
1779                         WHEN NO_DATA_FOUND THEN
1780                         RAISE;
1781                    end;
1782               else
1783                   xPersonId := approvers(i).orig_system_id;
1784               end if;
1785       exit;
1786     end if;
1787   end loop;
1788 
1789   if g_fnd_debug = 'Y' then
1790       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1791         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving get_first_authority_approver...');
1792       END IF;
1793       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1794         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- xPersonId :' || xPersonId);
1795       END IF;
1796   end if;
1797 
1798 exception
1799   when others then
1800     if g_fnd_debug = 'Y' then
1801       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
1802         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
1803                       l_api_name || '.others_exception', sqlerrm);
1804       END IF;
1805     end if;
1806     raise;
1807 
1808 END;
1809 
1810 --------------------------------------------------------------------------------
1811 --Start of Comments
1812 --Name: can_delete_oam_approvers
1813 --Function:
1814 --  Call AME API to fetch the value of the
1815 --  ALLOW_DELETING_RULE_GENERATED_APPROVERS OAM attribute.
1816 --  This attribute specifies whether approvers generated by
1817 --  approval rules can be deleted from the approver list.
1818 
1819 --Parameters:
1820 --IN:
1821 --    pReqHeaderId       Requisition Header ID
1822 --OUT:
1823 --    xResult            'Y' or 'N'
1824 --End of Comments
1825 --------------------------------------------------------------------------------
1826 PROCEDURE can_delete_oam_approvers( pReqHeaderId  IN NUMBER,
1827                                     xResult       OUT NOCOPY VARCHAR2) IS
1828   l_api_name varchar2(50):= 'can_delete_oam_approvers';
1829   attributeValue1 VARCHAR2(10);
1830   attributeValue2 VARCHAR2(10);
1831   attributeValue3 VARCHAR2(10);
1832   ameTransactionType po_document_types.ame_transaction_type%TYPE;
1833 
1834 BEGIN
1835 
1836   if g_fnd_debug = 'Y' then
1837       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1838         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering can_delete_oam_approvers...');
1839       END IF;
1840       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1841         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param -- pReqHeaderId ' || pReqHeaderId );
1842       END IF;
1843   end if;
1844 
1845   getAmeTransactionType(pReqHeaderId => pReqHeaderId,
1846                     pAmeTransactionType => ameTransactionType);
1847 
1848   if g_fnd_debug = 'Y' then
1849       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1850         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api3.getAttributeValue()...');
1851       END IF;
1852   end if;
1853   ame_api3.getAttributeValue(applicationIdIn => applicationId,
1854                              transactionTypeIn => ameTransactionType,
1855                              transactionIdIn => pReqHeaderId,
1856                              attributeNameIn => ame_util.allowDeletingOamApprovers,
1857                              itemIdIn => NULL,
1858                              attributeValue1Out => attributeValue1,
1859                              attributeValue2Out => attributeValue2,
1860                              attributeValue3Out => attributeValue3);
1861 
1862   if g_fnd_debug = 'Y' then
1863       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1864         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api3.getAttributeValue()...');
1865       END IF;
1866   end if;
1867 
1868   IF attributeValue1 = 'true' THEN
1869     xResult := 'Y';
1870   ELSE
1871     xResult := 'N';
1872   END IF;
1873 
1874   if g_fnd_debug = 'Y' then
1875       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1876         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving can_delete_oam_approvers...');
1877       END IF;
1878       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1879         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- xResult :' || xResult);
1880       END IF;
1881   end if;
1882 
1883 EXCEPTION
1884   WHEN OTHERS THEN
1885     if g_fnd_debug = 'Y' then
1886       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
1887         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
1888                       l_api_name || '.others_exception', sqlerrm);
1889       END IF;
1890     end if;
1891     --raise;
1892     xResult := 'N';
1893 END can_delete_oam_approvers;
1894 
1895 
1896 /* private procedures */
1897 procedure getAmeTransactionType(pReqHeaderId          IN  NUMBER,
1898                             pAmeTransactionType OUT NOCOPY VARCHAR2
1899 ) IS
1900 
1901   l_api_name varchar2(50):= 'getAmeTransactionType';
1902   changeRequestExist number := 0;
1903   docType po_document_types.document_type_code%TYPE;
1904   docSubType po_document_types.document_subtype%TYPE;
1905   lookupCode po_requisition_headers.type_lookup_code%TYPE;
1906   orgId NUMBER;
1907 
1908 begin
1909 
1910   if g_fnd_debug = 'Y' then
1911     IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1912       FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'pReqHeaderId: ' || pReqHeaderId);
1913       FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'current org id: ' || PO_MOAC_UTILS_PVT.get_current_org_id);
1914     END IF;
1915   end if;
1916 
1917   -- check if is rco, alternative is to check authorization status
1918   begin
1919     SELECT COUNT(1)
1920     INTO changeRequestExist
1921     FROM
1922      PO_CHANGE_REQUESTS pcr
1923     WHERE
1924      pcr.document_header_id = pReqHeaderId AND
1925      pcr.document_type = 'REQ' AND
1926      pcr.action_type IN ('MODIFICATION', 'CANCELLATION') AND
1927      pcr.request_status NOT IN ('ACCEPTED', 'REJECTED');
1928   exception
1929     when others then
1930         if g_fnd_debug = 'Y' then
1931           IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1932             FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Not RCO');
1933           END IF;
1934         end if;
1935   end;
1936 
1937   if (changeRequestExist > 0) then
1938     docType := 'CHANGE_REQUEST';
1939     docSubType :='REQUISITION';
1940 
1941     SELECT org_id
1942       INTO orgId
1943       FROM po_requisition_headers_all
1944      WHERE requisition_header_id = pReqHeaderId;
1945 
1946   else
1947     docType := 'REQUISITION';
1948     begin
1949       SELECT type_lookup_code, org_id
1950       INTO lookupCode, orgId
1951       FROM po_requisition_headers_all
1952       WHERE requisition_header_id = pReqHeaderId;
1953 
1954     exception
1955       when others then
1956         if g_fnd_debug = 'Y' then
1957           IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1958             FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Req not found');
1959           END IF;
1960         end if;
1961         lookupCode := 'PURCHASE'; -- assume not internal
1962     end;
1963     docSubType := lookupCode;
1964   end if;
1965 
1966   -- Use the private function to fetch the ame txn type given the doc type and subtype
1967   pAmeTransactionType := getAmeTxnType(docType, docSubType, orgId);
1968 
1969   if g_fnd_debug = 'Y' then
1970     IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
1971       FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'pAmeTransactionType: ' || pAmeTransactionType);
1972     END IF;
1973   end if;
1974 
1975 end;
1976 
1977 function getAmeTxnType (p_doc_type IN VARCHAR2,
1978                                       p_doc_subtype IN VARCHAR2,
1979 				      p_org_id IN NUMBER)
1980 				      return VARCHAR2 is
1981  x_ame_txn_type po_document_types_all_b.ame_transaction_type%TYPE;
1982 BEGIN
1983 
1984     SELECT ame_transaction_type
1985     INTO x_ame_txn_type
1986     FROM po_document_types_all_b
1987     WHERE document_type_code = p_doc_type
1988     and document_subtype = p_doc_subtype
1989     and org_id = p_org_id;
1990 
1991     return x_ame_txn_type;
1992 
1993   EXCEPTION
1994     when others then
1995      return 'PURCHASE_REQ';
1996   END getAmeTxnType;
1997 
1998 PROCEDURE marshalField(p_string     IN VARCHAR2,
1999                        p_quote_char IN VARCHAR2,
2000                        p_delimiter  IN VARCHAR2) IS
2001   l_string VARCHAR2(32767) := NULL;
2002 BEGIN
2003   l_string := p_string;
2004   l_string := REPLACE(l_string, p_quote_char, p_quote_char || p_quote_char);
2005   l_string := REPLACE(l_string, p_delimiter, p_quote_char || p_delimiter);
2006   approvalListStr := approvalListStr ||l_string || p_delimiter;
2007 END marshalField;
2008 
2009 
2010 --------------------------------------------------------------------------------
2011 --Start of Comments
2012 --Name: serializeApproversTable
2013 --Function:
2014 -- This function will simply iterate thorugh the list
2015 -- of approvers and frame an approver string from each approver record
2016 -- and give the output.
2017 
2018 -- If the approver record is of position hierarchy action type, then
2019 -- the list of users associated to the position will be retrieved
2020 -- and will be sort by last_name. Then the first user will be selected from the sorted list
2021 -- and that user's person_id will be considered.
2022 
2023 -- approverRecord.orig_system can have 3 values like following.
2024 -- PER = Employee Supervisor action type --> approverRecord.orig_system_id will be person_id
2025 -- POS = Position Hierarchy              --> approverRecord.orig_system_id will be position_id
2026 -- FND = FND Users                       --> approverRecord.orig_system_id will be user_id
2027 
2028 --Parameters:
2029 --IN:
2030 --    approversTableIn       Approvers List
2031 --    reqHeaderId            ID of the requisition
2032 --OUT:
2033 --    approverCount          Total Number of approvers in the list.
2034 --    hasApprovalAction      'Y' or 'N'
2035 --End of Comments
2036 --------------------------------------------------------------------------------
2037 function serializeApproversTable( approversTableIn in ame_util.approversTable2,
2038                                   reqHeaderId in NUMBER,
2039                                   approverCount out nocopy number,
2040                                   hasApprovalAction out nocopy varchar2
2041                                 )
2042                                 return varchar2 as
2043 
2044   l_api_name varchar2(50):= 'serializeApproversTable';
2045   upperLimit integer;
2046 
2047   l_full_name per_all_people_f.full_name%TYPE;
2048   l_person_id per_all_people_f.person_id%TYPE;
2049   l_job_or_position VARCHAR2(2000);
2050   l_orig_system VARCHAR2(30);
2051   l_orig_system_id NUMBER;
2052 
2053   l_position_id NUMBER;
2054   l_job_id NUMBER;
2055   l_valid_approver VARCHAR2(1);
2056   l_preparer_id NUMBER;        --bug 14591082
2057   l_preparer_pos_id NUMBER;    --bug 14591082
2058 
2059 begin
2060 
2061   if g_fnd_debug = 'Y' then
2062       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2063         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering serializeApproversTable...');
2064       END IF;
2065   end if;
2066 
2067 -- bug 9559404: Commented the following code as l_preparer_id is no longer needed
2068 -- bug 14591082:uncommented this piece of code to get preparer id
2069   select PREPARER_ID
2070   into l_preparer_id
2071   from po_requisition_headers_all
2072   where reqHeaderId = requisition_header_id;
2073 
2074   if g_fnd_debug = 'Y' then
2075       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2076         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' l_preparer_id: ' || l_preparer_id);
2077       END IF;
2078   end if;
2079 
2080   approvalListStr := NULL;
2081   upperLimit := approversTableIn.count;
2082 
2083   approverCount := 0;
2084   hasApprovalAction := 'N';
2085 
2086   if g_fnd_debug = 'Y' then
2087       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2088         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' upperLimit :' || upperLimit );
2089       END IF;
2090   end if;
2091 
2092   -- Iterate through the list of approvers.
2093   for i in 1 .. upperLimit loop
2094 
2095     if g_fnd_debug = 'Y' then
2096         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2097           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' Processing the approver :' || i );
2098           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Orig_System :' || approversTableIn(i).orig_system);
2099           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Orig System Id :' || approversTableIn(i).orig_system_id);
2100           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Approval Status :' || approversTableIn(i).approval_status);
2101         END IF;
2102     end if;
2103 
2104     -- assume valid approver
2105     l_valid_approver := 'Y';
2106 
2107 -- bug 9559404 : Commented the following code so that if preparer is an approver, he is also shown in the approvals list
2108 -- bug 14591082: Uncommented this piece of code to handle preparer
2109     -- if we have a Emp-Sup approver, make sure the approverId
2110     -- is NOT the same as preparer's Id
2111     if (approversTableIn(i).orig_system = ame_util.perOrigSystem) then
2112       -- bug 14591082: added condition 'approversTableIn(i).approval_status = ame_util.approvedStatus'
2113       if (approversTableIn(i).orig_system_id = l_preparer_id AND approversTableIn(i).approval_status = ame_util.approvedStatus ) THEN
2114         l_valid_approver := 'N';
2115         if g_fnd_debug = 'Y' then
2116           IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2117             FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  ApproverID matches l_preparer_id... skipping!');
2118           END IF;
2119         end if;
2120       end if;
2121 
2122     -- else if we have a position approver, make sure the position
2123     -- is NOT the same as preparer's position
2124     elsif (approversTableIn(i).orig_system = ame_util.posOrigSystem) then
2125 
2126       SELECT POSITION_ID
2127       INTO l_preparer_pos_id
2128       FROM PER_ALL_ASSIGNMENTS_F
2129       WHERE PERSON_ID = l_preparer_id
2130         and primary_flag = 'Y'
2131         and assignment_type in ('E','C')
2132         and assignment_status_type_id not in ( select assignment_status_type_id from per_assignment_status_types where per_system_status = 'TERM_ASSIGN')
2133         and TRUNC ( effective_start_date ) <=  TRUNC(SYSDATE)
2134         and NVL(effective_end_date, TRUNC( SYSDATE)) >= TRUNC(SYSDATE)
2135         and rownum = 1;
2136       -- bug 14591082: added condition 'approversTableIn(i).approval_status = ame_util.approvedStatus'
2137       if (approversTableIn(i).orig_system_id = l_preparer_pos_id AND approversTableIn(i).approval_status = ame_util.approvedStatus ) then
2138         l_valid_approver := 'N';
2139         if g_fnd_debug = 'Y' then
2140           IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2141             FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Approvers Position matches preparers... skipping!');
2142           END IF;
2143         end if;
2144       end if;
2145 
2146     end if;  -- Checking PER and POS-based approver
2147 
2148 -- bug 9559404 : end
2149 
2150    -- If the approval_status is not null, then we can assume the following.
2151    --  1. The approver is deleted.
2152    --  2. The approver is notified or approved/rejected.
2153    -- So if the approval_status is not null,
2154    -- we need to additionally check if the status is not notified and not suppressed and not approved,
2155    -- then do not consider the record.
2156    -- (we want to consider notified, suppressed and approved records)
2157 
2158    if( approversTableIn(i).approval_status is not null  AND
2159        approversTableIn(i).approval_status<>ame_util.notifiedStatus AND
2160        approversTableIn(i).approval_status<>ame_util.suppressedStatus AND
2161        approversTableIn(i).approval_status<>ame_util.approvedStatus) then
2162 
2163      hasApprovalAction := 'Y';
2164      if g_fnd_debug = 'Y' then
2165          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2166            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Approval_status is ' || approversTableIn(i).approval_status);
2167            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '    ...so we do not consider this approver.');
2168          END IF;
2169      end if;
2170 
2171    elsif (l_valid_approver = 'Y') then
2172 
2173     l_orig_system    := approversTableIn(i).orig_system;
2174     l_orig_system_id := approversTableIn(i).orig_system_id;
2175     l_job_or_position := NULL;
2176 
2177     -- orig_system and orig_system_id should not be null.
2178     -- There is a bug 4403014 for the same. So this is a work-around to achieve the same.
2179     if l_orig_system is null and l_orig_system_id is null then
2180        SELECT orig_system, orig_system_id into l_orig_system, l_orig_system_id FROM wf_roles where name =  approversTableIn(i).name and rownum = 1;
2181     end if;
2182 
2183     if l_orig_system is null and l_orig_system_id is null then
2184          raise NO_DATA_FOUND;
2185     end if;
2186 
2187     if g_fnd_debug = 'Y' then
2188         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2189           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  l_orig_system :' || l_orig_system );
2190         END IF;
2191         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2192           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  l_orig_system_id :' || l_orig_system_id );
2193         END IF;
2194     end if;
2195 
2196     begin
2197         get_person_info( l_orig_system,
2198                          l_orig_system_id,
2199                          approversTableIn(i).display_name,
2200                          reqHeaderId,
2201                          g_fnd_debug,
2202                          l_person_id,
2203                          l_full_name);
2204 
2205     exception
2206          WHEN NO_DATA_FOUND THEN
2207                  -- No approvers found for this position. So we will skip this position.
2208                  l_valid_approver := 'N';
2209 
2210                  -- We raise the exception only for the last approver.
2211                  if i = upperLimit then
2212                      raise NO_DATA_FOUND;
2213                  end if;
2214     end;
2215 
2216     -- Find position | job name
2217     if ( l_orig_system = ame_util.posOrigSystem ) then
2218          l_job_or_position := approversTableIn(i).display_name;
2219     else
2220          l_job_or_position := null;
2221     end if;
2222 
2223     -- Verify the person_id is not null.
2224     if( l_valid_approver = 'Y' AND ( l_person_id is null or l_full_name is null ))then
2225 
2226         SELECT orig_system_id, display_name, description into l_person_id, l_full_name, l_job_or_position
2227         FROM wf_roles where name =  approversTableIn(i).name and rownum = 1;
2228 
2229         -- We raise the exception only for the last approver.
2230         --if l_person_id is null then
2231         if i = upperLimit then
2232             raise NO_DATA_FOUND;
2233         end if;
2234 
2235     end if;
2236 
2237     if g_fnd_debug = 'Y' then
2238         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2239           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  l_full_name :' || l_full_name );
2240         END IF;
2241         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2242           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  l_person_id :' || l_person_id );
2243         END IF;
2244     end if;
2245 
2246     -- Make sure position/job name is populated.
2247     if( l_job_or_position is null ) then
2248 
2249            -- retrieve the position name. if the position name is null check for the job name.
2250 
2251            SELECT position_id, job_id INTO l_position_id, l_job_id
2252            FROM per_all_assignments_f
2253            WHERE person_id = l_person_id
2254                 and primary_flag = 'Y' and assignment_type in ('E','C')
2255                 and assignment_status_type_id not in ( select assignment_status_type_id from per_assignment_status_types where per_system_status = 'TERM_ASSIGN')
2256                 and TRUNC ( effective_start_date ) <=  TRUNC(SYSDATE) AND NVL(effective_end_date, TRUNC( SYSDATE)) >= TRUNC(SYSDATE)
2257                 and rownum = 1;
2258 
2259            if l_position_id is not null then
2260                SELECT name INTO l_job_or_position FROM per_all_positions WHERE position_id = l_position_id;
2261            end if;
2262 
2263            if l_job_or_position is null and l_job_id is not null then
2264                SELECT name INTO l_job_or_position FROM per_jobs WHERE job_id = l_job_id;
2265            end if;
2266 
2267            if g_fnd_debug = 'Y' then
2268                  IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2269                    FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  l_job_or_position :' || l_job_or_position );
2270                  END IF;
2271            end if;
2272 
2273     end if;
2274 
2275     -- If the approver is valid, then only frame the approver string.
2276     if( l_valid_approver = 'Y' ) then
2277         marshalField(l_full_name, quoteChar, fieldDelimiter);
2278         marshalField( to_char(l_person_id), quoteChar, fieldDelimiter);
2279         marshalField(l_job_or_position, quoteChar, fieldDelimiter);
2280         marshalField(approversTableIn(i).name, quoteChar, fieldDelimiter);
2281 
2282         --marshalField(approversTableIn(i).orig_system, quoteChar, fieldDelimiter);
2283         --marshalField(to_char(approversTableIn(i).orig_system_id), quoteChar, fieldDelimiter);
2284 
2285         marshalField(l_orig_system, quoteChar, fieldDelimiter);
2286         marshalField(to_char(l_orig_system_id), quoteChar, fieldDelimiter);
2287 
2288         marshalField(approversTableIn(i).api_insertion, quoteChar, fieldDelimiter);
2289         marshalField(approversTableIn(i).authority, quoteChar, fieldDelimiter);
2290         marshalField(approversTableIn(i).approval_status, quoteChar, fieldDelimiter);
2291         marshalField(approversTableIn(i).approver_category, quoteChar, fieldDelimiter);
2292         marshalField(approversTableIn(i).approver_order_number, quoteChar, fieldDelimiter);
2293         marshalField(approversTableIn(i).action_type_id, quoteChar, fieldDelimiter);
2294         marshalField(approversTableIn(i).group_or_chain_id, quoteChar, fieldDelimiter);
2295         marshalField(approversTableIn(i).member_order_number, quoteChar, fieldDelimiter);
2296         --marshalField(to_char(i), quoteChar, fieldDelimiter);
2297         approverCount := approverCount +1;
2298         marshalField(to_char(approverCount), quoteChar, fieldDelimiter);
2299     end if;
2300 
2301   end if; -- if approval_status is not null.
2302   end loop;
2303 
2304   if g_fnd_debug = 'Y' then
2305       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2306         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving serializeApproversTable...');
2307       END IF;
2308       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2309         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- approvalListStr :' || approvalListStr );
2310       END IF;
2311   end if;
2312   return  approvalListStr;
2313 
2314 exception
2315   when others then
2316     if g_fnd_debug = 'Y' then
2317       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
2318         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
2319                       l_api_name || '.others_exception', sqlerrm);
2320       END IF;
2321     end if;
2322     raise;
2323     return(null);
2324 end serializeApproversTable;
2325 
2326 procedure getAllApprovers(  pReqHeaderId             IN  NUMBER,
2327                             pAmeTransactionType      IN VARCHAR2,
2328                             pApprovalListStr         OUT NOCOPY VARCHAR2,
2329                             pApprovalListCount       OUT NOCOPY NUMBER)  IS
2330 
2331   l_api_name varchar2(50):= 'getAllApprovers';
2332   hasApprovalAction varchar2(1);
2333   approverList      ame_util.approversTable2;
2334   l_process_out     VARCHAR2(10);
2335 
2336 begin
2337 
2338 
2339   if g_fnd_debug = 'Y' then
2340       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2341         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering getAllApprovers...');
2342       END IF;
2343       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2344         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param -- pReqHeaderId :' || pReqHeaderId);
2345       END IF;
2346       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2347         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame_api2.getAllApprovers7()...');
2348       END IF;
2349   end if;
2350 
2351   ame_api2.getAllApprovers7( applicationIdIn   => applicationId,
2352                              transactionIdIn   => pReqHeaderId,
2353                              transactionTypeIn => pAmeTransactionType,
2354                              approvalProcessCompleteYNOut => l_process_out,
2355                              approversOut      => approverList
2356                            );
2357 
2358   if g_fnd_debug = 'Y' then
2359       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2360         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Done with ame_api2.getAllApprovers7()...');
2361       END IF;
2362   end if;
2363 
2364   if(approverList.count > 0) then
2365     /* no approver required */
2366     pApprovalListStr := serializeApproversTable(approverList, pReqHeaderId, pApprovalListCount, hasApprovalAction);
2367   else
2368     pApprovalListCount:=0;
2369   end if;
2370 
2371   if g_fnd_debug = 'Y' then
2372       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2373         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving getAllApprovers...');
2374       END IF;
2375       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2376         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- approvalListStr :' || approvalListStr );
2377       END IF;
2378       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2379         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListCount :' || pApprovalListCount );
2380       END IF;
2381   end if;
2382 
2383 exception
2384   when others then
2385     if g_fnd_debug = 'Y' then
2386       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
2387         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
2388                       l_api_name || '.others_exception', sqlerrm);
2389       END IF;
2390     end if;
2391     raise;
2392 end getAllApprovers;
2393 
2394 function getAbsolutePosition(pReqHeaderId             IN  NUMBER,
2395                             pAmeTransactionType    IN VARCHAR2,
2396                             pPosition IN NUMBER)
2397 return number  IS
2398 
2399   l_api_name varchar2(50):= 'getAbsolutePosition';
2400   approverList      ame_util.approversTable2;
2401   absolutePosition number := pPosition;
2402   numOfNullStatus number := 0;
2403   l_process_out      VARCHAR2(10);
2404 
2405 begin
2406 
2407   ame_api2.getAllApprovers7( applicationIdIn=>applicationId,
2408                              transactionIdIn=>pReqHeaderId,
2409                              transactionTypeIn=>pAmeTransactionType,
2410                              approvalProcessCompleteYNOut => l_process_out,
2411                              approversOut=>approverList
2412                            );
2413 
2414   for i in 1 .. approverList.count loop
2415     if(approverList(i).approval_status is not null) then
2416       absolutePosition := absolutePosition + 1;
2417     else
2418       numOfNullStatus := numOfNullStatus + 1;
2419     end if;
2420     if(numOfNullStatus >= pPosition) then
2421       exit;
2422     end if;
2423   end loop;
2424   return absolutePosition;
2425 
2426 exception
2427   when others then
2428     if g_fnd_debug = 'Y' then
2429       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
2430         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
2431                       l_api_name || '.others_exception', sqlerrm);
2432       END IF;
2433     end if;
2434     raise;
2435 
2436 end getAbsolutePosition;
2437 
2438 --------------------------------------------------------------------------------
2439 --Start of Comments
2440 --Name: retrieve_approval_info
2441 --Function:
2442 --  This procedure checks which approval is used.
2443 --        -- whether AME is used for approval or PO Hierarchy approval.
2444 --Parameters:
2445 --IN:
2446 --    pReqHeaderId                Requisition Header ID
2447 --    pIsApprovalHistoryFlow   Flag indicating whether function is being
2448 --                                         called from approval history flow
2449 --OUT:
2450 --    x_is_ame_approval  'Y' if AME is used for approval.
2451 --    x_approval_status  Status of the req.
2452 --    pQuoteChar         Quote Character, used for escaping purpose in tokenization
2453 --    x_is_rco_approval  'Y' if RCO approval.
2454 --End of Comments
2455 --------------------------------------------------------------------------------
2456 procedure retrieve_approval_info( p_req_header_id in number,
2457                                   p_is_approval_history_flow in varchar2,
2458                                   x_is_ame_approval out NOCOPY varchar2,
2459                                   x_approval_status out NOCOPY varchar2,
2460                                   x_is_rco_approval out NOCOPY varchar2
2461                                 ) IS
2462 
2463   l_itemtype po_requisition_headers.wf_item_type%TYPE;
2464   l_itemkey po_requisition_headers.wf_item_key%TYPE;
2465   l_api_name varchar2(50):= 'retrieve_approval_info';
2466 
2467   l_change_request_group_id NUMBER;
2468 
2469   begin
2470 
2471    if g_fnd_debug = 'Y' then
2472        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2473          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering retrieve_approval_info...');
2474        END IF;
2475        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2476          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - p_req_header_id :' || p_req_header_id );
2477          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - p_is_approval_history_flow :' || p_is_approval_history_flow );
2478 
2479        END IF;
2480    end if;
2481 
2482    -- Initialize all the output params.
2483    x_is_rco_approval := 'N';
2484    x_is_ame_approval := 'N';
2485    x_approval_status := null;
2486 
2487 
2488    select authorization_status, wf_item_type, wf_item_key
2489       into x_approval_status, l_itemtype, l_itemkey
2490    from po_requisition_headers_all
2491          where requisition_header_id = p_req_header_id;
2492 
2493    if g_fnd_debug = 'Y' then
2494          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2495            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' x_approval_status :' || x_approval_status );
2496          END IF;
2497    end if;
2498 
2499    -- Check whether it is ame approval or not.
2500    x_is_ame_approval := PO_WF_UTIL_PKG.GetItemAttrText( itemtype => l_itemtype,
2501                                                         itemkey    => l_itemkey,
2502                                                         aname      => 'IS_AME_APPROVAL'
2503                                                       );
2504 
2505    -- If the code is not being called from the approval history flow, check for pending change requests
2506    if (p_is_approval_history_flow <> 'Y') then
2507 
2508      -- First check whether change request is there or not.
2509      BEGIN
2510           SELECT max(change_request_group_id) INTO l_change_request_group_id
2511           FROM po_change_requests
2512           WHERE document_header_id = p_req_header_id
2513               AND document_type = 'REQ';
2514      EXCEPTION
2515         WHEN OTHERS THEN
2516             l_change_request_group_id := null;
2517      END;
2518 
2519      -- l_change_request_group_id is not null, then change request is there for the req.
2520      -- retrieve the status , wf_item_type and wf_item_key.
2521      IF l_change_request_group_id IS NOT NULL THEN
2522 
2523         x_is_rco_approval := 'Y';
2524 
2525         SELECT wf_item_type, wf_item_key,
2526                decode( request_status, 'ACCEPTED', x_approval_status,
2527                        'MGR_APP', 'APPROVED',
2528                        'REJECTED','REJECTED',
2529                        'IN PROCESS' )
2530         INTO l_itemtype, l_itemkey, x_approval_status
2531         FROM po_change_requests
2532         WHERE document_header_id = p_req_header_id
2533               AND change_request_group_id = l_change_request_group_id
2534               AND document_type = 'REQ'
2535               AND action_type <> 'DERIVED'
2536               AND rownum = 1;
2537 
2538      END IF;
2539 
2540    end if; -- end of RCO check...
2541 
2542    -- get the authorization status meaning from fnd_loopup_values_vl
2543    SELECT distinct meaning into x_approval_status
2544    FROM fnd_lookup_values_vl
2545    WHERE lookup_code = x_approval_status and lookup_type = 'AUTHORIZATION STATUS';
2546 
2547    -- Check RCO approval type is ame approval or not.
2548    if( 'Y' =  x_is_rco_approval ) then
2549        if( l_itemtype is not null AND  l_itemkey is not null ) then
2550            x_is_ame_approval := PO_WF_UTIL_PKG.GetItemAttrText( itemtype => l_itemtype,
2551                                                                 itemkey    => l_itemkey,
2552                                                                 aname      => 'IS_AME_APPROVAL'
2553                                                               );
2554        end if;
2555    end if;
2556 
2557    if g_fnd_debug = 'Y' then
2558          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2559            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' x_is_ame_approval :' || x_is_ame_approval );
2560          END IF;
2561          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2562            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' x_is_rco_approval :' || x_is_rco_approval );
2563          END IF;
2564          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2565            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' x_approval_status :' || x_approval_status );
2566          END IF;
2567    end if;
2568 
2569 exception
2570     when others then
2571     if g_fnd_debug = 'Y' then
2572       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
2573         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
2574                       l_api_name || '.others_exception', sqlerrm);
2575       END IF;
2576     end if;
2577     raise;
2578 end RETRIEVE_APPROVAL_INFO;
2579 
2580 --------------------------------------------------------------------------------
2581 --Start of Comments
2582 --Name: retrieve_approver_info
2583 --Function:
2584 --  This procedure retrieves the approver's title and email.
2585 --Parameters:
2586 --IN:
2587 --    pReqHeaderId       Requisition Header ID
2588 --OUT:
2589 --    x_title - title of the approver.
2590 --    x_email - email of the approver.
2591 --End of Comments
2592 --------------------------------------------------------------------------------
2593 procedure retrieve_approver_info( p_approver_id in number,
2594                                   x_title out NOCOPY varchar2,
2595                                   x_email out NOCOPY varchar2
2596                                 ) IS
2597 
2598   l_api_name varchar2(50):= 'retrieve_approver_info';
2599   l_position_id number;
2600   l_job_id number;
2601 
2602   begin
2603 
2604    if g_fnd_debug = 'Y' then
2605        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2606          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering retrieve_approver_info...');
2607        END IF;
2608        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2609          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - p_approver_id :' || p_approver_id );
2610        END IF;
2611    end if;
2612 
2613    x_title := null;
2614    x_email := null;
2615 
2616    -- first get the email id.
2617    SELECT email_address INTO x_email FROM per_all_people_f
2618           WHERE person_id = p_approver_id
2619           AND TRUNC ( effective_start_date ) <=  TRUNC(SYSDATE) AND NVL(effective_end_date, TRUNC( SYSDATE)) >= TRUNC(SYSDATE)
2620           AND rownum = 1;
2621 
2622    if g_fnd_debug = 'Y' then
2623          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2624            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' x_email :' || x_email );
2625          END IF;
2626    end if;
2627 
2628    -- retrieve the position name. if the position name is null check for the job name.
2629    SELECT position_id, job_id INTO l_position_id, l_job_id
2630    FROM per_all_assignments_f
2631    WHERE person_id = p_approver_id
2632         and primary_flag = 'Y' and assignment_type in ('E','C')
2633         and assignment_status_type_id not in ( select assignment_status_type_id from per_assignment_status_types where per_system_status = 'TERM_ASSIGN')
2634         and TRUNC ( effective_start_date ) <=  TRUNC(SYSDATE) AND NVL(effective_end_date, TRUNC( SYSDATE)) >= TRUNC(SYSDATE)
2635         and rownum = 1;
2636 
2637    if l_position_id is not null then
2638        SELECT name INTO x_title FROM per_all_positions WHERE position_id = l_position_id;
2639    end if;
2640 
2641    if x_title is null and l_job_id is not null then
2642        SELECT name INTO x_title FROM per_jobs WHERE job_id = l_job_id;
2643    end if;
2644 
2645    if g_fnd_debug = 'Y' then
2646          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2647            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' x_title :' || x_title );
2648          END IF;
2649    end if;
2650 
2651 exception
2652     when others then
2653     if g_fnd_debug = 'Y' then
2654       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
2655         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
2656                       l_api_name || '.others_exception', sqlerrm);
2657       END IF;
2658     end if;
2659 end retrieve_approver_info;
2660 --------------------------------------------------------------------------------
2661 --Start of Comments
2662 --Name: get_approval_group_name
2663 --Function:
2664 --  This procedure retrieves the approval group name for the given group id.
2665 --Parameters:
2666 --IN:
2667 --    p_group_id       Group Id
2668 --OUT:
2669 --    x_group_name - Group name for the given group id.
2670 --End of Comments
2671 --------------------------------------------------------------------------------
2672 function get_approval_group_name( p_group_id in number ) return varchar2 IS
2673 
2674   l_api_name varchar2(50):= 'get_approval_group_name';
2675   l_group_name varchar2(1000);
2676 
2677   begin
2678 
2679    if p_group_id is null then
2680        return '';
2681    end if;
2682 
2683    if g_fnd_debug = 'Y' then
2684        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2685          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering get_approval_group_name...');
2686        END IF;
2687        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2688          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - p_group_id :' || p_group_id );
2689        END IF;
2690    end if;
2691 
2692    -- If the group id is less than 3, then it is not approval group.
2693    if p_group_id < 3 then
2694        return '';
2695    end if;
2696 
2697    l_group_name := 'Group:' || p_group_id;
2698 
2699    ame_api5.getApprovalGroupName( groupIdIn    => p_group_id,
2700                                   groupNameOut => l_group_name
2701                                 );
2702 
2703    if g_fnd_debug = 'Y' then
2704          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2705            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' l_group_name :' || l_group_name );
2706          END IF;
2707    end if;
2708 
2709    return l_group_name;
2710 
2711 exception
2712     when others then
2713     l_group_name := 'Group:' || p_group_id;
2714     if g_fnd_debug = 'Y' then
2715       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
2716         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
2717                       l_api_name || '.others_exception', sqlerrm);
2718       END IF;
2719     end if;
2720     return l_group_name;
2721 end get_approval_group_name;
2722 
2723 --------------------------------------------------------------------------------
2724 --Start of Comments
2725 --Name: get_ame_approval_list_history
2726 --Function:
2727 --  Call AME API to build the approver list history.
2728 --Parameters:
2729 --IN:
2730 --    pReqHeaderId       Requisition Header ID
2731 --    pCallingPage         The page from which the function is being called
2732 --OUT:
2733 --    pApprovalListStr   Approval List concatenated in a string
2734 --    pApprovalListCount Number of Approvers.
2735 --                       It has a value of 0, if the document does not require approval.
2736 --    pQuoteChar         Quote Character, used for escaping purpose in tokenization
2737 --    pFieldDelimiter    Field Delimiter, used for delimiting list string into elements.
2738 --End of Comments
2739 --------------------------------------------------------------------------------
2740 procedure get_ame_approval_list_history( pReqHeaderId        IN  NUMBER,
2741                                          pCallingPage IN VARCHAR2,
2742                                          pApprovalListStr    OUT NOCOPY VARCHAR2,
2743                                          pApprovalListCount  OUT NOCOPY NUMBER,
2744                                          pQuoteChar          OUT NOCOPY VARCHAR2,
2745                                          pFieldDelimiter     OUT NOCOPY VARCHAR2
2746                                         ) IS
2747 
2748   l_api_name varchar2(50):= 'get_ame_approval_list_history';
2749   ameTransactionType po_document_types.ame_transaction_type%TYPE;
2750 
2751   l_itemtype po_requisition_headers.wf_item_type%TYPE;
2752   l_itemkey po_requisition_headers.wf_item_key%TYPE;
2753 
2754   approverList       ame_util.approversTable2;
2755   l_process_out      VARCHAR2(10);
2756 
2757   l_full_name per_all_people_f.full_name%TYPE;
2758   l_person_id per_all_people_f.person_id%TYPE;
2759   l_job_or_position VARCHAR2(2000);
2760   l_orig_system VARCHAR2(30);
2761   l_orig_system_id NUMBER;
2762 
2763   l_job_id number;
2764   l_position_id number;
2765   l_valid_approver VARCHAR2(1);
2766 
2767   l_preparer_id NUMBER;
2768   l_first_approver_id NUMBER;
2769   l_first_position_id NUMBER;
2770   l_org_id NUMBER;
2771   p_doc_type po_document_types_all_b.document_type_code%type;
2772   p_doc_subtype po_document_types_all_b.document_subtype%type;
2773   l_authorizationStatus po_requisition_headers_all.AUTHORIZATION_STATUS%type;
2774   l_change_pending_flag po_requisition_headers_all.CHANGE_PENDING_FLAG%type;
2775   l_approval_reqd_flag PO_CHANGE_REQUESTS.APPROVAL_REQUIRED_FLAG%type;
2776 
2777 BEGIN
2778 
2779    if g_fnd_debug = 'Y' then
2780        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2781          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering get_ame_approval_list_history...');
2782          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pReqHeaderId :' || pReqHeaderId );
2783          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' current org Id: ' || PO_MOAC_UTILS_PVT.get_current_org_id);
2784        END IF;
2785    end if;
2786 
2787   select PREPARER_ID,
2788          first_position_id,
2789          first_approver_id,
2790          org_id,
2791          AUTHORIZATION_STATUS,
2792          CHANGE_PENDING_FLAG
2793   into   l_preparer_id,
2794          l_first_position_id,
2795          l_first_approver_id,
2796          l_org_id,
2797          l_authorizationStatus,
2798          l_change_pending_flag
2799   from   po_requisition_headers_all
2800   where  pReqHeaderId = requisition_header_id;
2801 
2802   --PO_MOAC_UTILS_PVT.set_org_context(l_org_id);
2803 
2804   if g_fnd_debug = 'Y' then
2805       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2806         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' PreparerID for this req :' || l_preparer_id );
2807         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' l_first_position_id: ' || l_first_position_id);
2808         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' l_first_approver_id: ' || l_first_approver_id);
2809         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' l_authorizationStatus: ' || l_authorizationStatus);
2810         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' l_change_pending_flag: ' || l_change_pending_flag);
2811       END IF;
2812   end if;
2813 
2814   pQuoteChar := quoteChar;
2815   pFieldDelimiter := fieldDelimiter;
2816 
2817   approvalListStr := NULL;
2818   pApprovalListCount := 0;
2819 
2820     /*
2821       If the function is being called from approval history page or the change history page
2822       Set the appropriate document type and subtype and then get the corresponding
2823       ame transaction type
2824     */
2825 
2826    if (pCallingPage = 'fromChangeHistoryPage' OR pCallingPage = 'fromRCONotificationPage') then
2827      -- We are in RCO Modes...
2828      -- need to check if approval is even required.
2829      -- If not, then no approval needed for this RCO
2830      -- Simply return and do NOT build AME list
2831     begin
2832      select DISTINCT  nvl(APPROVAL_REQUIRED_FLAG, 'N')
2833      into l_approval_reqd_flag
2834      from PO_CHANGE_REQUESTS
2835      where DOCUMENT_HEADER_ID = pReqHeaderId
2836      and action_type IN ('MODIFICATION', 'CANCELLATION')
2837      and creation_date = (select max(creation_date)
2838                           from PO_CHANGE_REQUESTS
2839                           where DOCUMENT_HEADER_ID = pReqHeaderId);
2840     exception
2841       when others then
2842         l_approval_reqd_flag := 'Y';
2843     end;
2844 
2845      if (l_approval_reqd_flag = 'N') then
2846 
2847        if g_fnd_debug = 'Y' then
2848          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2849            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  No Approval Required! RETURNING....');
2850            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving get_ame_approval_list...');
2851          END IF;
2852        end if;
2853 
2854        pApprovalListCount := 0;
2855        pApprovalListStr := '';
2856 
2857        RETURN;
2858      END IF;
2859 
2860      -- otherwise, AME required... continue with existing logic.
2861      p_doc_type := 'CHANGE_REQUEST';
2862      p_doc_subtype := 'REQUISITION';
2863    else
2864      p_doc_type := 'REQUISITION';
2865 
2866      begin
2867        SELECT type_lookup_code
2868        INTO p_doc_subtype
2869        FROM po_requisition_headers_all
2870        WHERE requisition_header_id = pReqHeaderId;
2871 
2872      exception
2873        when others then
2874          p_doc_subtype := 'PURCHASE';
2875      end;
2876 
2877    end if;
2878 
2879    ameTransactionType := getAmeTxnType(p_doc_type, p_doc_subtype, l_org_id);
2880 
2881   if g_fnd_debug = 'Y' then
2882       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2883         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'ameTransactionType: ' || ameTransactionType);
2884       END IF;
2885   end if;
2886 
2887   -- if called from RCO page or RCO notification, we use change_pending_flag to determine if txn is in process
2888   -- otherwise, we look at authorizationStatus
2889 
2890   if ( (pCallingPage <> 'fromRCONotificationPage' AND pCallingPage <> 'fromChangeHistoryPage' AND l_authorizationStatus = 'IN PROCESS') OR
2891        (pCallingPage = 'fromRCONotificationPage' AND l_change_pending_flag = 'Y') OR
2892        (pCallingPage = 'fromChangeHistoryPage' AND l_change_pending_flag = 'Y') ) then
2893 
2894     -- if req is in process, then use ame_api2 which will rebuild the approval list
2895     if g_fnd_debug = 'Y' then
2896       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2897         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Req is IN PROCESS: Using ame_api2 to REBUILD');
2898       END IF;
2899     end if;
2900 
2901     -- If we are going to use the flag approvalProcessCompleteYNOut,
2902     -- then we have to set the following flag.
2903     ame_util2.detailedApprovalStatusFlagYN := ame_util.booleanTrue;
2904 
2905     ame_api2.getAllApprovers7( applicationIdIn   => applicationId,
2906                                transactionIdIn   => pReqHeaderId,
2907                                transactionTypeIn => ameTransactionType,
2908                                approvalProcessCompleteYNOut => l_process_out,
2909                                approversOut      => approverList
2910                              );
2911 
2912     if g_fnd_debug = 'Y' then
2913       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2914         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'approvalProcessCompleteYNOut = ' || l_process_out);
2915         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'getAllApprovers7 Done');
2916       END IF;
2917     end if;
2918 
2919   else
2920     -- otherwise, req is completed... so use ame_api6 to get the stored history w/o rebuilding
2921 
2922     if g_fnd_debug = 'Y' then
2923       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2924         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Req is COMPLETED: Using ame_api6 - NO REBUILD');
2925       END IF;
2926     end if;
2927 
2928     ame_api6.getApprovers(applicationIdIn   => applicationId,
2929                           transactionTypeIn => ameTransactionType,
2930                           transactionIdIn   => pReqHeaderId,
2931                           approversOut      => approverList);
2932 
2933     -- process is completed.  Set flag.
2934     l_process_out := 'Y';
2935 
2936     if g_fnd_debug = 'Y' then
2937       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2938         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'getApprovers Done');
2939       END IF;
2940     end if;
2941 
2942   END IF;
2943 
2944   -- Iterate through the list of approvers.
2945   for i in 1 .. approverList.count loop
2946 
2947     l_valid_approver := 'Y';
2948     if g_fnd_debug = 'Y' then
2949         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2950           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' Processing the approver :' || i );
2951         END IF;
2952     end if;
2953 
2954     if (l_preparer_id=approverList(i).orig_system_id) THEN
2955       l_valid_approver := 'N';
2956       if g_fnd_debug = 'Y' then
2957         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2958           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' ApproverID matches PreparerID... invalid approver!');
2959         END IF;
2960       end if;
2961     end if;
2962 
2963     if( ( ( l_process_out = 'Y' OR l_process_out = 'N' ) AND
2964           ( approverList(i).approval_status is not null AND
2965              ( approverList(i).approval_status not in
2966                 ( ame_util.notifiedByRepeatedStatus,
2967                   ame_util.approvedByRepeatedStatus,
2968                   ame_util.rejectedByRepeatedStatus,
2969                   ame_util.repeatedStatus,
2970                   ame_util.noResponseStatus
2971                 )
2972              )
2973           )
2974         ) OR
2975         ( ( l_process_out = 'W' OR  l_process_out = 'P' )AND
2976           ( approverList(i).approval_status is null OR
2977              ( approverList(i).approval_status not in
2978                 ( ame_util.notifiedByRepeatedStatus,
2979                   ame_util.approvedByRepeatedStatus,
2980                   ame_util.rejectedByRepeatedStatus,
2981                   ame_util.repeatedStatus,
2982                   ame_util.noResponseStatus
2983                 )
2984              )
2985           )
2986         )
2987       ) then
2988 
2989       l_orig_system    := approverList(i).orig_system;
2990       l_orig_system_id := approverList(i).orig_system_id;
2991       l_job_or_position := NULL;
2992 
2993       if ( l_orig_system = ame_util.perOrigSystem) then
2994 
2995         -- Employee Supervisor Record.
2996         if g_fnd_debug = 'Y' then
2997             IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
2998               FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Emp - Sup Record ...');
2999             END IF;
3000         end if;
3001         l_full_name := approverList(i).display_name;
3002         l_person_id := l_orig_system_id;
3003 
3004       elsif ( l_orig_system = ame_util.posOrigSystem) then
3005 
3006         -- Position Hierarchy Record. The logic is mentioned in the comments section.
3007         if g_fnd_debug = 'Y' then
3008              IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3009                FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Position Hierarchy Record ...');
3010              END IF;
3011         end if;
3012 
3013         begin
3014 
3015           if (l_first_position_id is not NULL AND l_first_position_id=l_orig_system_id) then
3016 
3017             if g_fnd_debug = 'Y' then
3018               IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3019                 FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Approver position matches l_first_position_id.');
3020                 FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Using stored l_first_approver_id as person_id.');
3021               END IF;
3022             end if;
3023 
3024             l_person_id := l_first_approver_id;
3025 
3026             SELECT full_name
3027             INTO l_full_name
3028             FROM per_all_people_f
3029             WHERE person_id = l_first_approver_id
3030             AND TRUNC(sysdate) between effective_start_date and effective_end_date;
3031 
3032           else
3033               SELECT person_id, full_name into l_person_id,l_full_name FROM (
3034                        SELECT person.person_id, person.full_name FROM per_all_people_f person, per_all_assignments_f asg
3035                        WHERE asg.position_id = l_orig_system_id and trunc(sysdate) between person.effective_start_date
3036                        and nvl(person.effective_end_date, trunc(sysdate)) and person.person_id = asg.person_id
3037                        and asg.primary_flag = 'Y' and asg.assignment_type in ('E','C')
3038                        and ( person.current_employee_flag = 'Y' or person.current_npw_flag = 'Y' )
3039                        and asg.assignment_status_type_id not in (
3040                           SELECT assignment_status_type_id FROM per_assignment_status_types
3041                           WHERE per_system_status = 'TERM_ASSIGN'
3042                        ) and trunc(sysdate) between asg.effective_start_date and asg.effective_end_date order by person.last_name
3043                 ) where rownum = 1;
3044 
3045           end if;
3046 
3047        exception
3048              WHEN NO_DATA_FOUND THEN
3049                  --RAISE;
3050                  l_valid_approver := 'N';
3051       END;
3052 
3053       elsif (l_orig_system = ame_util.fndUserOrigSystem) then
3054 
3055         -- FND User Record.
3056         if g_fnd_debug = 'Y' then
3057            IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3058              FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'FND User Record ...');
3059            END IF;
3060         end if;
3061         SELECT employee_id into l_person_id
3062              FROM fnd_user
3063              WHERE user_id = l_orig_system_id
3064              and trunc(sysdate) between start_date and nvl(end_date, sysdate+1);
3065 
3066         l_full_name := approverList(i).display_name;
3067 
3068       end if;
3069 
3070       if g_fnd_debug = 'Y' then
3071           IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3072             FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' l_full_name :' || l_full_name );
3073           END IF;
3074          IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3075            FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' l_person_id :' || l_person_id );
3076          END IF;
3077       end if;
3078 
3079       -- Find position | job name
3080       if ( l_orig_system = ame_util.posOrigSystem ) then
3081          l_job_or_position := approverList(i).display_name;
3082       else
3083          l_job_or_position := null;
3084       end if;
3085 
3086       -- Make sure position/job name is populated.
3087       if( l_job_or_position is null ) then
3088 
3089            -- retrieve the position name. if the position name is null check for the job name.
3090 
3091            -- bug #15883770 relax the condition on employee assignment, that is
3092            -- to allow user to view the approval list regardless the current
3093            -- employee status (Employee, Ex-employee , etc..) for approved requisition
3094            SELECT position_id, job_id INTO l_position_id, l_job_id
3095            FROM per_all_assignments_f
3096            WHERE person_id = l_person_id
3097              and (l_authorizationStatus = 'APPROVED'
3098                  or (primary_flag = 'Y' and assignment_type in ('E','C')
3099                     and assignment_status_type_id not in ( select assignment_status_type_id from per_assignment_status_types where per_system_status = 'TERM_ASSIGN')
3100                     and TRUNC ( effective_start_date ) <=  TRUNC(SYSDATE) AND NVL(effective_end_date, TRUNC( SYSDATE)) >= TRUNC(SYSDATE)
3101                    )
3102                  )
3103              and rownum = 1;
3104 
3105            if l_position_id is not null then
3106                SELECT name INTO l_job_or_position FROM per_all_positions WHERE position_id = l_position_id;
3107            end if;
3108 
3109            if l_job_or_position is null and l_job_id is not null then
3110                SELECT name INTO l_job_or_position FROM per_jobs WHERE job_id = l_job_id;
3111            end if;
3112 
3113            if g_fnd_debug = 'Y' then
3114                  IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3115                    FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' l_job_or_position :' || l_job_or_position );
3116                  END IF;
3117            end if;
3118 
3119       end if;
3120 
3121       if( l_valid_approver = 'Y' ) then
3122           marshalField(l_full_name, quoteChar, fieldDelimiter);
3123           marshalField( to_char(l_person_id), quoteChar, fieldDelimiter);
3124           marshalField(l_job_or_position, quoteChar, fieldDelimiter);
3125           marshalField(approverList(i).name, quoteChar, fieldDelimiter);
3126 
3127           --marshalField(approversTableIn(i).orig_system, quoteChar, fieldDelimiter);
3128           --marshalField(to_char(approversTableIn(i).orig_system_id), quoteChar, fieldDelimiter);
3129 
3130           marshalField(l_orig_system, quoteChar, fieldDelimiter);
3131           marshalField(to_char(l_orig_system_id), quoteChar, fieldDelimiter);
3132 
3133           marshalField(approverList(i).api_insertion, quoteChar, fieldDelimiter);
3134           marshalField(approverList(i).authority, quoteChar, fieldDelimiter);
3135           marshalField(approverList(i).approval_status, quoteChar, fieldDelimiter);
3136           marshalField(approverList(i).approver_category, quoteChar, fieldDelimiter);
3137           marshalField(approverList(i).approver_order_number, quoteChar, fieldDelimiter);
3138           marshalField(approverList(i).action_type_id, quoteChar, fieldDelimiter);
3139           marshalField(approverList(i).group_or_chain_id, quoteChar, fieldDelimiter);
3140           marshalField(approverList(i).member_order_number, quoteChar, fieldDelimiter);
3141          --marshalField(to_char(i), quoteChar, fieldDelimiter);
3142           pApprovalListCount := pApprovalListCount +1;
3143          marshalField(to_char(pApprovalListCount), quoteChar, fieldDelimiter);
3144        end if;
3145 
3146     end if;
3147   end loop;
3148 
3149   pApprovalListStr := approvalListStr;
3150 
3151   if g_fnd_debug = 'Y' then
3152       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3153         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListStr :' || pApprovalListStr);
3154       END IF;
3155       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3156         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Output param -- pApprovalListCount :' || pApprovalListCount);
3157       END IF;
3158       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3159         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving get_ame_approval_list...');
3160       END IF;
3161   end if;
3162 
3163 exception
3164   when NO_DATA_FOUND then
3165     pApprovalListCount := 0;
3166     pApprovalListStr := 'NO_DATA_FOUND';
3167     if g_fnd_debug = 'Y' then
3168       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
3169         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
3170                       l_api_name || '.NO_DATA_FOUND', 'NO_DATA_FOUND');
3171       END IF;
3172     end if;
3173   when others then
3174     pApprovalListCount := 0;
3175     pApprovalListStr := 'EXCEPTION';
3176     if g_fnd_debug = 'Y' then
3177       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
3178         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
3179                       l_api_name || '.others_exception', sqlerrm);
3180       END IF;
3181     end if;
3182 END get_ame_approval_list_history;
3183 
3184 
3185 --------------------------------------------------------------------------------
3186 --Start of Comments
3187 --Name: get_next_approvers_info
3188 --Function:
3189 --  Call AME API to get approverId and approverName
3190 
3191 --Parameters:
3192 --IN:
3193 --    pReqHeaderId       Requisition Header ID
3194 
3195 --OUT:
3196 --    x_approverId   Approver's ID
3197 --    x_approverName Full name of the approver
3198 --End of Comments
3199 --------------------------------------------------------------------------------
3200 procedure get_next_approvers_info(pReqHeaderId    IN  NUMBER,
3201                                   x_approverId    OUT NOCOPY NUMBER,
3202                                   x_approverName  OUT NOCOPY VARCHAR2
3203 ) IS
3204 
3205 l_itemtype po_requisition_headers.wf_item_type%TYPE;
3206 l_itemkey po_requisition_headers.wf_item_key%TYPE;
3207 l_ameTransactionType po_document_types.ame_transaction_type%TYPE;
3208 l_completeYNO varchar2(100);
3209 
3210 l_approversList      ame_util.approversTable2;
3211 l_approver_index NUMBER;
3212 l_preparer_id number;
3213 l_approverId number;
3214 l_approverName VARCHAR2(240);
3215 l_next_app_count number  :=0;
3216 
3217 l_api_name varchar2(50):= 'get_next_approvers_info';
3218 x_progress varchar2(100);
3219 
3220 BEGIN
3221   if g_fnd_debug = 'Y' then
3222        IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3223          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering get_next_approvers_info...');
3224        END IF;
3225   end if;
3226 
3227   x_progress := '001';
3228   getAmeTransactionType(pReqHeaderId => pReqHeaderId,
3229                     pAmeTransactionType => l_ameTransactionType);
3230 
3231   x_progress := '002';
3232 
3233   ame_api2.getAllApprovers7( applicationIdIn   => applicationId,
3234                              transactionIdIn   => pReqHeaderId,
3235                              transactionTypeIn => l_ameTransactionType,
3236                              approvalProcessCompleteYNOut => l_completeYNO,
3237                              approversOut      => l_approversList
3238                              );
3239 
3240   x_progress := '003';
3241 
3242   select PREPARER_ID
3243   into l_preparer_id
3244   from po_requisition_headers_all
3245   where pReqHeaderId = requisition_header_id;
3246 
3247   x_progress := '004';
3248 
3249   for i in 1 .. l_approversList.count loop
3250     if ( l_approversList(i).approval_status= 'NOTIFIED'
3251      and l_approversList(i).approver_category = ame_util.approvalApproverCategory ) then
3252 
3253        get_person_info(   l_approversList(i).orig_system,
3254                           l_approversList(i).orig_system_id,
3255                           l_approversList(i).display_name,
3256                           pReqHeaderId,
3257                           g_fnd_debug,
3258                           l_approverId,
3259                           l_approverName);
3260 
3261        if (l_approverId <> l_preparer_id ) then
3262          l_next_app_count := l_next_app_count + 1;
3263          x_approverId := l_approverId;
3264          x_approverName := l_approverName;
3265        end if;
3266 
3267     end if;
3268   end loop;
3269 
3270   x_progress := '006';
3271 
3272   if (l_next_app_count > 1 ) then
3273 
3274     -- if more than 1 approvers, approver_name is shown as 'MULTIPLE'
3275     x_approverName := 'MULTIPLE';
3276     x_approverId := NULL;
3277 
3278   end if;
3279 
3280   x_progress := '007';
3281 
3282   if g_fnd_debug = 'Y' then
3283      IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3284          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'x_approverId :' || x_approverId );
3285          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, ' x_approverName:' || x_approverName);
3286          FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Leaving get_next_approvers_info...');
3287      END IF;
3288   end if;
3289 
3290 EXCEPTION
3291   when others then
3292     x_approverId := -999;
3293     x_approverName := null;
3294     if g_fnd_debug = 'Y' then
3295       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
3296         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
3297                       l_api_name || '.others_exception', sqlerrm);
3298       END IF;
3299     end if;
3300     raise;
3301 
3302 END get_next_approvers_info;
3303 
3304 
3305 procedure get_person_info( p_origSystem   IN VARCHAR2,
3306                            p_origSystemId IN NUMBER,
3307                            p_displayName  IN VARCHAR2,
3308                            p_reqHeaderId  IN NUMBER,
3309                            p_logFlag      IN VARCHAR2,
3310                            x_personId    OUT NOCOPY NUMBER,
3311                            x_fullName    OUT NOCOPY VARCHAR2
3312 ) IS
3313 
3314   l_first_approver_id NUMBER;
3315   l_first_position_id NUMBER;
3316 
3317   l_api_name varchar2(50):= 'get_person_info';
3318 
3319 BEGIN
3320 
3321   if p_logFlag = 'Y' then
3322     IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3323       FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'get_person_info(+)');
3324       FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  p_origSystem = ' || p_origSystem);
3325       FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  p_origSystemId = ' || p_origSystemId);
3326       FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  p_displayName = ' || p_displayName);
3327       FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  p_reqHeaderId = ' || p_reqHeaderId);
3328       FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  p_logFlag = ' || p_logFlag);
3329     END IF;
3330   end if;
3331 
3332   if ( p_origSystem = ame_util.perOrigSystem) then
3333 
3334     -- Employee Supervisor Record.
3335     if p_logFlag = 'Y' then
3336       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3337         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Employee Supervisor Record ...');
3338       END IF;
3339     end if;
3340 
3341     x_fullName := p_displayName;
3342     x_personId := p_origSystemId;
3343 
3344   elsif ( p_origSystem = ame_util.posOrigSystem) then
3345 
3346     -- Position Hierarchy Record.
3347     if p_logFlag = 'Y' then
3348       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3349         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Position Hierarchy Record ...');
3350       END IF;
3351     end if;
3352 
3353     select first_position_id, first_approver_id
3354     into l_first_position_id, l_first_approver_id
3355     from po_requisition_headers_all
3356     where p_reqHeaderId = requisition_header_id;
3357 
3358     if p_logFlag = 'Y' then
3359       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3360         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  l_first_position_id: ' || l_first_position_id);
3361         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  l_first_approver_id: ' || l_first_approver_id);
3362       END IF;
3363     end if;
3364 
3365     if (l_first_position_id is not NULL AND l_first_position_id = p_origSystemId) then
3366       -- use stored approver_id since position_id matches stored id
3367 
3368       if p_logFlag = 'Y' then
3369         IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3370           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Approver position matches l_first_position_id.');
3371           FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  Using stored l_first_approver_id as person_id.');
3372         END IF;
3373       end if;
3374 
3375       x_personId := l_first_approver_id;
3376 
3377       SELECT full_name
3378       INTO x_fullName
3379       FROM per_all_people_f
3380       WHERE person_id = l_first_approver_id
3381       AND trunc(sysdate) between effective_start_date and effective_end_date;
3382 
3383     else
3384       SELECT person_id, full_name
3385       into x_personId, x_fullName
3386       FROM (
3387               SELECT person.person_id, person.full_name
3388               FROM per_all_people_f person, per_all_assignments_f asg
3389               WHERE asg.position_id = p_origSystemId
3390               and trunc(sysdate) between person.effective_start_date
3391               and nvl(person.effective_end_date, trunc(sysdate)) and person.person_id = asg.person_id
3392               and asg.primary_flag = 'Y' and asg.assignment_type in ('E','C')
3393               and ( person.current_employee_flag = 'Y' or person.current_npw_flag = 'Y' )
3394               and asg.assignment_status_type_id not in (
3395                   SELECT assignment_status_type_id
3396                   FROM per_assignment_status_types
3397                   WHERE per_system_status = 'TERM_ASSIGN'
3398                   )
3399               and trunc(sysdate) between asg.effective_start_date and asg.effective_end_date
3400               order by person.last_name
3401               )
3402       WHERE rownum = 1;
3403 
3404     end if;
3405 
3406   elsif (p_origSystem = ame_util.fndUserOrigSystem) then
3407 
3408     -- FND User Record.
3409     if p_logFlag = 'Y' then
3410       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3411         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  FND User Record ...');
3412       END IF;
3413     end if;
3414 
3415     SELECT employee_id
3416     into x_personId
3417     FROM fnd_user
3418     WHERE user_id = p_origSystemId
3419     and trunc(sysdate) between start_date and nvl(end_date, sysdate+1);
3420 
3421     x_fullName := p_displayName;
3422 
3423   end if;
3424 
3425   if p_logFlag = 'Y' then
3426     IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3427       FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  x_fullName :' || x_fullName );
3428       FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, '  x_personId :' || x_personId );
3429       FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'get_person_info(-)');
3430     END IF;
3431   end if;
3432 
3433 end get_person_info;
3434 
3435 /* public API */
3436 --------------------------------------------------------------------------------
3437 --Start of Comments
3438 --Name: is_req_forward_valid
3439 --Function:
3440 --  Call AME API to check whether the requisition can be forwareded in case of AME approvals
3441 --Parameters:
3442 --IN:
3443 --    pReqHeaderId       Requisition Header ID
3444 --    pPersonId          Person ID of a new first approver
3445 --OUT:
3446 --    pApprovalListStr   Approval List concatenated in a string
3447 --    pApprovalListCount Number of Approvers.
3448 --                       It has a value of 0, if the document does not require approval.
3449 --    pQuoteChar         Quote Character, used for escaping purpose in tokenization
3450 --    pFieldDelimiter    Field Delimiter, used for delimiting list string into elements.
3451 --End of Comments
3452 --------------------------------------------------------------------------------
3453 FUNCTION  is_req_forward_valid( pReqHeaderId  IN NUMBER) RETURN VARCHAR2 IS
3454 
3455   l_api_name varchar2(50):= 'is_req_forward_valid';
3456   tmpApprover ame_util.approverRecord2;
3457   ameTransactionType po_document_types.ame_transaction_type%TYPE;
3458 
3459   approverList      ame_util.approversTable2;
3460   l_process_out      VARCHAR2(10);
3461   currentFirstApprover ame_util.approverRecord2;
3462   approvalList VARCHAR2(3000);
3463   apprCt NUMBER;
3464   appChar  VARCHAR2(3000);
3465   appDelim    VARCHAR2(3000);
3466   flag VARCHAR2(1) := 'Y';
3467 begin
3468   if g_fnd_debug = 'Y' then
3469       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3470         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Entering is_req_forward_valid...');
3471         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Input param - pReqHeaderId :' || pReqHeaderId );
3472       END IF;
3473   end if;
3474 
3475   getAmeTransactionType(pReqHeaderId => pReqHeaderId,
3476                     pAmeTransactionType => ameTransactionType);
3477 
3478 
3479   if g_fnd_debug = 'Y' then
3480       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3481         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Invoking ame api ame_api2.getAllApprovers7() to get the list of approvers from AME.' ||ameTransactionType );
3482       END IF;
3483   end if;
3484 
3485   IF ameTransactionType IS NOT NULL THEN
3486   -- get the current approvers list from AME.
3487   ame_api2.getAllApprovers7( applicationIdIn=>applicationId,
3488                              transactionIdIn=>pReqHeaderId,
3489                              transactionTypeIn=>ameTransactionType,
3490                              approvalProcessCompleteYNOut => l_process_out,
3491                              approversOut=>approverList
3492                            );
3493 
3494   if g_fnd_debug = 'Y' then
3495       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3496         FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Retrieved the list of approvers from AME using ame_api2.getAllApprovers7()');
3497       END IF;
3498   end if;
3499 
3500   -- Once we get the approvers list from AME, we iterate through the approvers list,
3501   -- to find out the current first authority approver.
3502   for i in 1 .. approverList.count loop
3503     if( approverList(i).authority = ame_util.authorityApprover
3504         and approverList(i).approval_status is null
3505         and approverList(i).api_insertion = 'N'
3506         and approverList(i).group_or_chain_id < 3 ) then
3507 
3508           if g_fnd_debug = 'Y' then
3509               IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3510                 FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Found the first authority approver...' || currentFirstApprover.name );
3511                 FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Returing can forward Y' );
3512 
3513               END IF;
3514           end if;
3515 
3516           RETURN 'Y';
3517     end if;
3518   end loop;
3519   ELSE
3520       RETURN 'Y';
3521 
3522 
3523   END IF;
3524       if g_fnd_debug = 'Y' then
3525               IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_STATEMENT) THEN
3526                 FND_LOG.string(FND_LOG.level_statement, g_module_prefix || l_api_name, 'Returing cannot forward N' );
3527 
3528               END IF;
3529           end if;
3530 
3531           RETURN 'N';
3532 
3533 exception
3534   when NO_DATA_FOUND then
3535 
3536 
3537     if g_fnd_debug = 'Y' then
3538       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
3539         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
3540                       l_api_name || '.NO_DATA_FOUND', 'NO_DATA_FOUND');
3541       END IF;
3542     end if;
3543      RETURN 'N';
3544 
3545   when others then
3546      if g_fnd_debug = 'Y' then
3547       IF (FND_LOG.G_CURRENT_RUNTIME_LEVEL <= FND_LOG.LEVEL_UNEXPECTED) THEN
3548         FND_LOG.string(FND_LOG.level_unexpected, g_module_prefix ||
3549                       l_api_name || '.others_exception', sqlerrm);
3550       END IF;
3551     end if;
3552     ROLLBACK TO is_req_forward_valid;
3553      RETURN 'N';
3554 
3555 end;
3556 
3557 /* For bug 16064617 :: adding following proc which will be used in a New WF EVENT
3558    created for clearing AME approval list when approver rejects the requisition
3559    and Reject action gets successful just before sending FYI notification to preparer
3560    about rejection of document. */
3561 
3562 procedure Clear_ame_apprv_list_reject(itemtype in varchar2,
3563                                 itemkey         in varchar2,
3564                                 actid           in number,
3565                                 funcmode        in varchar2,
3566                                 resultout       out NOCOPY varchar2) IS
3567 
3568 l_document_type         PO_DOCUMENT_TYPES_ALL.document_type_code%TYPE;
3569 l_document_subtype      PO_DOCUMENT_TYPES_ALL.document_subtype%TYPE;
3570 l_document_id           NUMBER;
3571 l_ame_Transaction_Type  PO_DOCUMENT_TYPES_ALL.ame_transaction_type%TYPE;
3572 l_progress  VARCHAR2(300) := '000';
3573 l_doc_string varchar2(200);
3574 l_preparer_user_name varchar2(100);
3575 l_orgid number;
3576 
3577 BEGIN
3578 
3579   -- Do nothing in cancel or timeout mode
3580   --
3581   if (funcmode <> wf_engine.eng_run) then
3582 
3583       resultout := wf_engine.eng_null;
3584       return;
3585 
3586   end if;
3587 
3588   l_progress := 'Get doc attributes: 001';
3589   IF (g_po_wf_debug = 'Y') THEN
3590      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
3591   END IF;
3592 
3593   l_document_type    :=  wf_engine.GetItemAttrText (itemtype => itemtype,
3594                                                     itemkey  => itemkey,
3595                                                     aname    => 'DOCUMENT_TYPE');
3596 
3597   l_document_subtype :=  wf_engine.GetItemAttrText (itemtype => itemtype,
3598                                                     itemkey  => itemkey,
3599                                                     aname    => 'DOCUMENT_SUBTYPE');
3600 
3601   l_document_id      :=  wf_engine.GetItemAttrNumber (itemtype => itemtype,
3602                                                       itemkey  => itemkey,
3603                                                       aname    => 'DOCUMENT_ID');
3604 
3605  l_progress := 'Get doc attributes: 002 l_document_type :: '||l_document_type||
3606                 'l_document_subtype :: '||l_document_subtype||'l_document_id :: '||l_document_id;
3607 
3608   IF (g_po_wf_debug = 'Y') THEN
3609      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
3610   END IF;
3611 
3612 /*
3613 ** Desc Need to set the org context
3614 */
3615 
3616   l_progress := 'Get org_id: 003';
3617   IF (g_po_wf_debug = 'Y') THEN
3618      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
3619   END IF;
3620 
3621   l_orgid := wf_engine.GetItemAttrNumber (itemtype => itemtype,
3622                                          itemkey  => itemkey,
3623                                          aname    => 'ORG_ID');
3624 
3625   l_progress := 'Get doc attributes: 004 l_orgid :: '||l_orgid;
3626 
3627   IF (g_po_wf_debug = 'Y') THEN
3628      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
3629   END IF;
3630 
3631   IF l_orgid is NOT NULL THEN
3632     PO_MOAC_UTILS_PVT.set_org_context(l_orgid) ;       -- <R12.MOAC>
3633   END IF;
3634 
3635   l_progress := 'Get ame transaction type: 005';
3636   IF (g_po_wf_debug = 'Y') THEN
3637      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
3638   END IF;
3639 
3640   IF l_document_type = 'REQUISITION' THEN
3641 
3642    BEGIN
3643 
3644     SELECT ame_transaction_type
3645       INTO l_ame_Transaction_Type
3646       FROM po_document_types
3647     WHERE document_type_code = l_document_type
3648       and document_subtype   = l_document_subtype;
3649 
3650    EXCEPTION
3651 
3652     WHEN OTHERS THEN
3653 
3654      l_ame_Transaction_Type := null;
3655 
3656    END;
3657 
3658   END IF;
3659 
3660   l_progress := 'Get ame transaction type: 006 l_ame_Transaction_Type :: '||l_ame_Transaction_Type;
3661   IF (g_po_wf_debug = 'Y') THEN
3662      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
3663   END IF;
3664 
3665 
3666   IF l_ame_Transaction_Type IS NOT NULL THEN
3667 
3668   l_progress := 'Ame Clear all approvals call: 007 ';
3669   IF (g_po_wf_debug = 'Y') THEN
3670      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
3671   END IF;
3672 
3673       ame_api2.clearAllApprovals(applicationIdIn=>201,
3674                   transactionIdIn=>l_document_id,
3675                   transactionTypeIn=>l_ame_Transaction_Type);
3676 
3677   END IF;
3678 
3679   l_progress := 'Get_req_preparer_msg_attribute End : 008 ';
3680   IF (g_po_wf_debug = 'Y') THEN
3681      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
3682   END IF;
3683 
3684   resultout := wf_engine.eng_completed || ':' ||  'ACTIVITY_PERFORMED';
3685 
3686 
3687 EXCEPTION
3688  WHEN OTHERS THEN
3689     l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey);
3690     l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey);
3691     WF_CORE.context('POR_AME_APPROVAL_LIST' , 'Clear_ame_apprv_list_reject', itemtype, itemkey,l_progress);
3692     PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name, l_doc_string, sqlerrm,
3693                                           'POR_AME_APPROVAL_LIST.CLEAR_AME_APPRV_LIST_REJECT');
3694     raise;
3695 
3696 END Clear_ame_apprv_list_reject;
3697 
3698 END por_ame_approval_list;