DBA Data[Home] [Help]

PACKAGE BODY: APPS.AME_NON_FINAL_HANDLER

Source


1 package body ame_non_final_handler as
2 /* $Header: ameenfha.pkb 120.1 2005/08/08 05:15:00 ubhat noship $ */
3   actionParameters ame_util.stringList;
4   allRuleIds ame_util.idList;
5   allRuleIndexes ame_util.idList;
6   currentRuleIdcount integer;
7   listModParameterOnes ame_util.stringList;
8   listModParameterTwos ame_util.longStringList;
9   parametersCount integer;
10   parameterNumbers ame_util.idList;
11   parameterSigns ame_util.charList;
12   parameters ame_util.stringList;
13   ruleIds ame_util.idList;
14   ruleIndexes ame_util.idList;
15   ruleSatisfiedYN ame_util.charList;
16   threshholdJobLevel integer;
17   topDogFound boolean;
18   topDogPersonId integer;
19   /* forward declaration */
20   procedure getSourceAndAuthority(personIdIn in integer,
21                                   jobLevelIn in integer,
22                                   supervisorIdIn in integer,
23                                   sourceOut out nocopy varchar2,
24                                   hasFinalAuthorityYNOut out nocopy varchar2,
25                                   supervisorJobLevelOut out nocopy integer,
26                                   nextSupervisorIdOut out nocopy integer) ;
27   /* getNextTargetApprover, will iterate thru the sorted listModParameterTwos and return
28      all the parameters for the next target approver */
29   procedure getNextTargetApprover;
30   /* This routine will group all the actionParameters, listModParameterTwos and  ruleIds
31      based on the listModParameterTwos values.i.e. based on the target approver*/
32   procedure groupRules;
33  procedure parseAndSortRules;
34   /* procedures */
35   /* getNextTargetApprover, will iterate thru the sorted listModParameterTwos and return
36      all the parameters for the next target approver */
37   procedure getNextTargetApprover is
38     rowCount integer;
39     tempInteger integer;
40     begin
41       rowCount := 1 ; /* post increment */
42       if currentRuleIdCount = actionParameters.count then
43         return;
44       end if;
45       currentRuleIdCount := currentRuleIdCount + 1;
46       parameters(rowCount) := actionParameters(currentRuleIdCount);
47       ruleIds(rowCount) := allRuleIds(currentRuleIdCount);
48       ruleIndexes(rowCount) := allRuleIndexes(currentRuleIdCount);
49       tempInteger := currentRuleIdCount + 1;
50       for i in tempInteger.. actionParameters.count loop
51         if listModParameterTwos(i) = listModParameterTwos(currentRuleIdCount) then
52           rowCount := rowCount + 1;
53           currentRuleIdCount := currentRuleIdCount + 1;
54           parameters(rowCount) := actionParameters(currentRuleIdCount);
55           ruleIds(rowCount) := allRuleIds(currentRuleIdCount);
56           ruleIndexes(rowCount) := allRuleIndexes(currentRuleIdCount);
57         else
58           exit;
59         end if;
60       end loop;
61     exception
62         when others then
63           ame_util.runtimeException(packageNameIn => 'ame_non_final_handler',
64                                     routineNameIn => 'getNextTargetApprover',
65                                     exceptionNumberIn => sqlcode,
66                                     exceptionStringIn => sqlerrm);
67           raise;
68     end getNextTargetApprover;
69   /*
70     getSourceAndAuthority does not account for the ALLOW_REQUESTOR_APPROVAL attribute.
71     The handler procedure does that.
72   */
73   procedure getSourceAndAuthority(personIdIn in integer,
74                                   jobLevelIn in integer,
75                                   supervisorIdIn in integer,
76                                   sourceOut out nocopy varchar2,
77                                   hasFinalAuthorityYNOut out nocopy varchar2,
78                                   supervisorJobLevelOut out nocopy integer,
79                                   nextSupervisorIdOut out nocopy integer) is
80     hasFinalAuthorityYN ame_util.charType;
81     source ame_util.longStringType;
82     supervisorJobLevel integer;
83     tempRuleRequiresApprover boolean;
84     tempRuleSatisfied boolean;
85     begin
86       /* Initialize the two output arguments that might not otherwise get set. */
87      supervisorJobLevelOut := null;
88      nextSupervisorIdOut := null;
89       /*
90         1.  An approver satisfies a rule in any of three cases:
91             A.  The rule's parameter number does not exceed the approver's job level.
92             B.  The rule's parameter sign is '-', and the job level of the approver's
93                 supervisor exceeds the rule's parameter number.
94             C.  The approver is the top dog.
95         2.  An approver has final authority if the approver satisfies all the rules.
96             (The handler procedure proper takes care of adding subsequent approvers at
97             the same job level, if the relevant mandatory attribute so requires.)
98       */
99       hasFinalAuthorityYN := ame_util.booleanTrue;
100       for i in 1 .. parametersCount loop
101         /* Determine whether the approver satisfies the current rule. */
102         if(personIdIn = topDogPersonId) then
103           tempRuleSatisfied := true;
104           topDogFound := true;
105         else
106           topDogFound := false;
107           tempRuleSatisfied := false;
108           if(jobLevelIn >= parameterNumbers(i)) then
109             tempRuleSatisfied := true;
110           elsif(parameterSigns(i) = '-') then
111             if supervisorIdIn is null then
112               supervisorJobLevel := 0;
113             else
114               if(supervisorJobLevel is null) then
115                 ame_absolute_job_level_handler.getJobLevelAndSupervisor(personIdIn => supervisorIdIn,
116                                     jobLevelOut => supervisorJobLevel,
117                                     supervisorIdOut => nextSupervisorIdOut);
118                 supervisorJobLevelOut := supervisorJobLevel;
119               end if;
120               if(supervisorJobLevel > parameterNumbers(i)) then
121                 tempRuleSatisfied := true;
122               end if;
123             end if;
124           end if;
125         end if;
126         /* Update hasFinalAuthorityYN as needed. */
127         if(not tempRuleSatisfied and
128            hasFinalAuthorityYN = ame_util.booleanTrue) then
129           hasFinalAuthorityYN := ame_util.booleanFalse;
130         end if;
131         /* Determine whether the current rule requires the approver. */
132         tempRuleRequiresApprover := false;
133         if(ruleSatisfiedYN(i) = ame_util.booleanTrue) then
134           if(not tempRuleSatisfied) then
135             tempRuleRequiresApprover := true;
136           end if;
137         else
138           tempRuleRequiresApprover := true;
139           if(tempRuleSatisfied) then
140             ruleSatisfiedYN(i) := ame_util.booleanTrue;
141           end if;
142         end if;
143         if(tempRuleRequiresApprover )
144           then
145           /* Update source. */
146           ame_util.appendRuleIdToSource(ruleIdIn => ruleIds(i),
147                                         sourceInOut => source);
148         end if;
149       end loop;
150       hasFinalAuthorityYNOut := hasFinalAuthorityYN;
151       sourceOut := source;
152       exception
153         when others then
154           hasFinalAuthorityYNOut := null;
155           sourceOut := null;
156           ame_util.runtimeException(packageNameIn => 'ame_non_final_handler',
157                                     routineNameIn => 'getSourceAndAuthority',
158                                     exceptionNumberIn => sqlcode,
159                                     exceptionStringIn => sqlerrm);
160           raise;
161     end getSourceAndAuthority;
162   procedure groupRules is
163     insertCount integer;
164     lowerLimit integer;
165     tempRuleId integer;
166     tempRuleIndex integer;
167     tempActionParameter ame_util.stringType;
168     tempListModParameterTwo ame_util.stringType;
169     tempListModParameterOne ame_util.stringType;
170     tempParameterCount integer;
171     begin
172       tempParameterCount := listModParameterTwos.count;
173       for i in 1 .. tempParameterCount loop
174         lowerLimit := i + 1;
175         insertCount := i ; /* Pre increment */
176         for j in lowerLimit .. tempParameterCount loop
177           if(listModParameterTwos(i) = listModParameterTwos(j) ) then
178             insertCount := insertCount + 1;
179             if j <> insertCount then
180               tempRuleId := allRuleIds(j);
181               tempRuleIndex := allRuleIndexes(j);
182               tempActionParameter := actionParameters(j);
183               tempListModParameterTwo := listModParameterTwos(j);
184               tempListModParameterOne := listModParameterOnes(j);
185               allRuleIds(j) := allRuleIds(insertCount);
186               allRuleIndexes(j) := allRuleIndexes(insertCount);
187               actionParameters(j) := actionParameters(insertCount);
188               listModParameterTwos(j) := listModParameterTwos(insertCount);
189               listModParameterOnes(j) := listModParameterOnes(insertCount);
190               allRuleIds(insertCount) := tempRuleId;
191               allRuleIndexes(insertCount) := tempRuleIndex;
192               actionParameters(insertCount) := tempActionParameter;
193               listModParameterTwos(insertCount) :=  tempListModParameterTwo;
194               listModParameterOnes(insertCount) := tempListModParameterOne;
195             end if;
196           end if;
197         end loop;
198       end loop;
199     exception
200       when others  then
201           ame_util.runtimeException(packageNameIn => 'ame_non_final_handler',
202                                     routineNameIn => 'groupRules',
203                                     exceptionNumberIn => sqlcode,
204                                     exceptionStringIn => sqlerrm);
205           raise;
206     end groupRules;
207   procedure handler as
208     badParameterException exception;
209     COAInsertee ame_util.approverRecord2;
210     errorCode integer;
211     errorMessage ame_util.longestStringType;
212     extensionApprovers ame_util.approversTable2;
213     extIndex integer;
214     finalAuthorityNotFound boolean;
215     finalAuthorityFound boolean;
216     finalAuthoritySource ame_util.longStringType;
217     includeAllJobLevelApprovers boolean;
218     insertionThreshhold integer;
219     lastForwardeeIndexes ame_util.idList;
220     noSupervisorException exception;
221     nullFirstIdException exception;
222     requestorId integer;
223     source ame_util.longStringType;
224     startingPointId integer;
225     tempApprovers ame_util.approversTable2;
226     tempApproverIndexes ame_util.idList;
227     tempHasFinalAuthorityYN ame_util.charType;
228     tempIndex integer;
229     tempJobLevel integer;
230     tempLength integer;
231     tempMemberOrderNumber integer;
232     tempOldJobLevel integer;
233     tempSupervisorId integer;
234     tempSupervisorJobLevel integer;
235     tempNextSupervisorId integer;
236     begin
237       /* Populate some of the package variables. */
238       includeAllJobLevelApprovers := null;
239       topDogPersonId := to_number(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.topSupPersonIdAttribute));
240       ame_engine.getHandlerRules3(ruleIdsOut => allRuleIds,
241                                   ruleIndexesOut => allRuleIndexes,
242                                   parametersOut => actionParameters,
243                                   listModParameterOnesOut => listModParameterOnes,
244                                   listModParameterTwosOut => listModParameterTwos);
245       /* sort all the rules so that they are grouped by listModParameterTwos. In all these
246          cases the listModParameterOnes should be final_approver, so, ignore this value */
247       groupRules;
248       /* Loop for each distinct listModParameterTwos */
249       currentRuleIdCount := 0; /* pre increment */
250       loop
251         /* initialize arrays */
252         parameters.delete;
253         getNextTargetApprover;
254         if parameters.count = 0 then
255           exit;
256         end if;
257         tempApproverIndexes.delete;
258         insertionThreshhold := 0;
259         ame_engine.getHandlerLMApprovers(listModParameterOneIn => listModParameterOnes(currentRuleIdCount),
260                                          listModParameterTwoIn => listModParameterTwos(currentRuleIdCount),
261                                          includeFyiApproversIn => false,
262                                          includeApprovalGroupsIn => false,
263                                          returnForwardeesIn => true,
264                                          approverIndexesOut => tempApproverIndexes,
265                                          lastForwardeeIndexesOut => lastForwardeeIndexes);
266         for j in 1 .. tempApproverIndexes.count loop
267           finalAuthorityNotFound := true;
268           finalAuthoritySource := null;
269           tempIndex := lastForwardeeIndexes(j) + insertionThreshhold;
270           /* Get the approver list. This should be inside the loop so that we get the latest list*/
271           ame_engine.getApprovers(approversOut => tempApprovers);
272           /* Check that the action type id of the target is based on job level handler */
273           if (tempApprovers(tempIndex).action_type_id =
274                   ame_engine.getActionTypeId(actionTypeNameIn => ame_util.absoluteJobLevelTypeName) or
275               tempApprovers(tempIndex).action_type_id =
276                   ame_engine.getActionTypeId(actionTypeNameIn => ame_util.relativeJobLevelTypeName) or
277               tempApprovers(tempIndex).action_type_id =
278                   ame_engine.getActionTypeId(actionTypeNameIn => ame_util.managerFinalApproverTypeName) or
279               tempApprovers(tempIndex).action_type_id =
280                   ame_engine.getActionTypeId(actionTypeNameIn => ame_util.finalApproverOnlyTypeName) or
281               tempApprovers(tempIndex).action_type_id =
282                   ame_engine.getActionTypeId(actionTypeNameIn => ame_util.lineItemJobLevelTypeName) or
283               tempApprovers(tempIndex).action_type_id =
284                   ame_engine.getActionTypeId(actionTypeNameIn => ame_util.dualChainsAuthorityTypeName) )
285           then
286             if(includeAllJobLevelApprovers is null) then
287               includeAllJobLevelApprovers :=
288                 ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.includeAllApproversAttribute) =
289                  ame_util.booleanAttributeTrue;
290             end if;
291             /* First, get the orig_system_id and job level of the target approver. */
292             if tempApprovers(tempIndex).orig_system_id is null then
293               ame_approver_type_pkg.getApproverOrigSystemAndId(nameIn =>tempApprovers(tempIndex).name,
294                                   origSystemOut => tempApprovers(tempIndex).orig_system,
295                                   origSystemIdOut => tempApprovers(tempIndex).orig_system_id);
296             end if;
297             ame_absolute_job_level_handler.getJobLevelAndSupervisor(
298                                   personIdIn => tempApprovers(tempIndex).orig_system_id,
299                                   jobLevelOut => tempJobLevel,
300                                   supervisorIdOut => tempSupervisorId);
301             threshholdJobLevel := tempJobLevel;
302             parseAndSortRules;
303             for i in 1 .. ruleIds.count loop
304               ruleSatisfiedYN(i) := ame_util.booleanFalse;
305               ame_engine.setRuleApplied(ruleIndexIn => ruleIndexes(i));
306             end loop;
307             /*
308               Third, walk the chain starting with the target and ending with the last forwardee,
309               checking for final authority.
310             */
311             for k in tempApproverIndexes(j) .. lastForwardeeIndexes(j) loop
312               /* no need to check that the approver is in the same chain as the target approver
313                  as this is done in the ame_engine.getHandlerLMApprovers() */
314               /* Check whether the approver has sufficient authority as per the
315                  actionParameter defined */
316               ame_absolute_job_level_handler.getJobLevelAndSupervisor(
317                                     personIdIn => tempApprovers(k).orig_system_id,
318                                     jobLevelOut => tempJobLevel,
319                                     supervisorIdOut => tempSupervisorId);
320               getSourceAndAuthority(personIdIn => tempApprovers(tempIndex).orig_system_id,
321                            jobLevelIn => tempJobLevel,
322                            supervisorIdIn => tempSupervisorId,
323                            sourceOut =>  source,
324                            hasFinalAuthorityYNOut => tempHasFinalAuthorityYN,
325                            supervisorJobLevelOut => tempSupervisorJobLevel,
326                            nextSupervisorIdOut => tempNextSupervisorId);
327               if(tempHasFinalAuthorityYN = ame_util.booleanTrue) then
328                 finalAuthorityNotFound := false;
329                 exit;
330               end if;
331             end loop;
332             /* If final authority was not found at the previous step, extend the chain,
333               starting from the last forwardee.
334               All the approvers inserted this way will have an approver category of 'A'.
335             */
336             if finalAuthorityNotFound then
337               extensionApprovers.delete;
338               extIndex := 1;
339               finalAuthorityFound := false;
340               tempMemberOrderNumber := tempApprovers(tempIndex).member_order_number; /* pre-increment */
341               ame_absolute_job_level_handler.getJobLevelAndSupervisor(
342                                     personIdIn => tempApprovers(tempIndex).orig_system_id,
343                                     jobLevelOut => tempJobLevel,
344                                     supervisorIdOut => tempSupervisorId);
345               extensionApprovers(extIndex).orig_system_id := tempSupervisorId;
346               while finalAuthorityNotFound loop
347                 /* get the next approver to be inserted */
348                 ame_absolute_job_level_handler.getJobLevelAndSupervisor(
349                                     personIdIn => extensionApprovers(extIndex).orig_system_id,
350                                     jobLevelOut => tempJobLevel,
351                                     supervisorIdOut => tempSupervisorId);
352                 extensionApprovers(extIndex).orig_system := ame_util.perOrigSystem;
353                 extensionApprovers(extIndex).authority := ame_util.authorityApprover;
354                 -- preserve the action_type_ID and action_type_order_number values of the original chains
355                 extensionApprovers(extIndex).action_type_id := tempApprovers(tempIndex).action_type_id;
356                 extensionApprovers(extIndex).item_class := tempApprovers(tempIndex).item_class;
357                 extensionApprovers(extIndex).item_id := tempApprovers(tempIndex).item_id;
358                 extensionApprovers(extIndex).item_class_order_number := tempApprovers(tempIndex).item_class_order_number;
359                 extensionApprovers(extIndex).item_order_number := tempApprovers(tempIndex).item_order_number;
360                 extensionApprovers(extIndex).sub_list_order_number := tempApprovers(tempIndex).sub_list_order_number;
361                 extensionApprovers(extIndex).action_type_order_number := tempApprovers(tempIndex).action_type_order_number;
362                 extensionApprovers(extIndex).group_or_chain_order_number := tempApprovers(tempIndex).group_or_chain_order_number;
363                 extensionApprovers(extIndex).group_or_chain_id := tempApprovers(tempIndex).group_or_chain_id;
364                 extensionApprovers(extIndex).approver_category := ame_util.approvalApproverCategory;
365                 extensionApprovers(extIndex).api_insertion := ame_util.oamGenerated;
366                 getSourceAndAuthority(personIdIn => extensionApprovers(extIndex).orig_system_id,
367                              jobLevelIn => tempJobLevel,
368                              supervisorIdIn => tempSupervisorId,
369                              sourceOut =>  extensionApprovers(extIndex).source,
370                              hasFinalAuthorityYNOut => tempHasFinalAuthorityYN,
371                              supervisorJobLevelOut => tempSupervisorJobLevel,
372                              nextSupervisorIdOut => tempNextSupervisorId);
373                 if(not finalAuthorityFound and
374                    tempHasFinalAuthorityYN = ame_util.booleanTrue) then
375                   finalAuthorityFound := true;
376                   finalAuthoritySource := extensionApprovers(extIndex).source;
377                 end if;
378                 if (extensionApprovers(extIndex).source is null and
379                    finalAuthoritySource is not null ) then
380                   extensionApprovers(extIndex).source := finalAuthoritySource;
381                 end if;
382                 ame_approver_type_pkg.getWfRolesNameAndDisplayName(origSystemIn => ame_util.perOrigSystem,
383                               origSystemIdIn => extensionApprovers(extIndex).orig_system_id,
384                               nameOut => extensionApprovers(extIndex).name,
385                               displayNameOut => extensionApprovers(extIndex).display_name);
386                 extensionApprovers(extIndex).occurrence := ame_engine.getHandlerOccurrence(
387                               nameIn =>extensionApprovers(extIndex).name,
388                               itemClassIn => extensionApprovers(extIndex).item_class,
389                               itemIdIn => extensionApprovers(extIndex).item_id,
390                               actionTypeIdIn => extensionApprovers(extIndex).action_type_id,
391                               groupOrChainIdIn => extensionApprovers(extIndex).group_or_chain_id);
392                 tempMemberOrderNumber := tempMemberOrderNumber + 1;
393                 extensionApprovers(extIndex).member_order_number := tempMemberOrderNumber;
394                 extensionApprovers(extIndex).approval_status := ame_engine.getHandlerApprovalStatus(
395                               approverIn => extensionApprovers(extIndex));
396                 /* The engine will set extensionApprovers(extIndex).approver_order_number; leave it null here. */
397                 /* check to see if there is a COA insertion after this approver. If a COA
398                    insertion is found, keep checking till no more COA insertions. The check
399                    for final authority will need to be done again.  */
400                 loop
401                   /* Initialize COAInsertee approverRecord2 */
402                   COAInsertee := ame_util.emptyApproverRecord2;
403                   /* Check if there are any COAInsertions */
404                   ame_engine.getHandlerCOAInsertion(nameIn => extensionApprovers(extIndex).name,
405                              itemClassIn => extensionApprovers(extIndex).item_class,
406                              itemIdIn => extensionApprovers(extIndex).item_id,
407                              actionTypeIdIn => extensionApprovers(extIndex).action_type_id,
408                              groupOrChainIdIn => extensionApprovers(extIndex).group_or_chain_id,
409                              occurrenceIn => extensionApprovers(extIndex).occurrence,
410                              approvalStatusIn => extensionApprovers(extIndex).approval_status,
411                              nameOut => COAInsertee.name,
412                              origSystemOut => COAInsertee.orig_system,
413                              origSystemIdOut => COAInsertee.orig_system_id,
414                              displayNameOut => COAInsertee.display_name,
415                              sourceOut => COAInsertee.source);
416                   if COAInsertee.name is null then
417                     exit;
418                   else
419                     extIndex := extIndex + 1;
420                     extensionApprovers(extIndex).name := COAInsertee.name;
421                     extensionApprovers(extIndex).orig_system := COAInsertee.orig_system;
422                     extensionApprovers(extIndex).orig_system_id := COAInsertee.orig_system_id;
423                     extensionApprovers(extIndex).display_name :=  COAInsertee.display_name;
424                     ame_absolute_job_level_handler.getJobLevelAndSupervisor(personIdIn => extensionApprovers(extIndex).orig_system_id,
425                                        jobLevelOut => tempJobLevel,
426                                        supervisorIdOut => tempSupervisorId);
427                     extensionApprovers(extIndex).orig_system_id := tempSupervisorId;
428                     extensionApprovers(extIndex).orig_system := ame_util.perOrigSystem;
429                     extensionApprovers(extIndex).authority := ame_util.authorityApprover;
430                     extensionApprovers(extIndex).action_type_id := ame_engine.getHandlerActionTypeId;
431                     extensionApprovers(extIndex).item_class := tempApprovers(tempIndex).item_class;
432                     extensionApprovers(extIndex).item_id := tempApprovers(tempIndex).item_id;
433                     extensionApprovers(extIndex).item_class_order_number := tempApprovers(tempIndex).item_class_order_number;
434                     extensionApprovers(extIndex).item_order_number := tempApprovers(tempIndex).item_order_number;
435                     extensionApprovers(extIndex).sub_list_order_number := tempApprovers(tempIndex).sub_list_order_number;
436                     extensionApprovers(extIndex).action_type_order_number := tempApprovers(tempIndex).action_type_order_number;
437                     extensionApprovers(extIndex).group_or_chain_order_number := tempApprovers(tempIndex).group_or_chain_order_number;
438                     extensionApprovers(extIndex).group_or_chain_id := tempApprovers(tempIndex).group_or_chain_id;
439                     getSourceAndAuthority(personIdIn => extensionApprovers(extIndex).orig_system_id,
440                                        jobLevelIn => tempJobLevel,
441                                        supervisorIdIn => tempSupervisorId,
442                                        sourceOut =>  extensionApprovers(extIndex).source,
443                                        hasFinalAuthorityYNOut => tempHasFinalAuthorityYN,
444                                        supervisorJobLevelOut => tempSupervisorJobLevel,
445                                        nextSupervisorIdOut => tempNextSupervisorId);
446                     extensionApprovers(extIndex).source := COAInsertee.source;
447                     extensionApprovers(extIndex).api_insertion := ame_util.apiAuthorityInsertion;
448                     tempMemberOrderNumber := tempMemberOrderNumber + 1;
449                     extensionApprovers(extIndex).member_order_number := tempMemberOrderNumber;
450                     extensionApprovers(extIndex).occurrence := ame_engine.getHandlerOccurrence(
451                                         nameIn =>  extensionApprovers(extIndex).name,
452                                         itemClassIn => extensionApprovers(extIndex).item_class,
453                                         itemIdIn => extensionApprovers(extIndex).item_id,
454                                         actionTypeIdIn => extensionApprovers(extIndex).action_type_id,
455                                         groupOrChainIdIn => extensionApprovers(extIndex).group_or_chain_id);
456                     extensionApprovers(extIndex).approval_status :=
457                           ame_engine.getHandlerApprovalStatus(approverIn => extensionApprovers(extIndex));
458                     /* If approver has a status of ame_util.approve or
459                        ame_util.approveAndForwardStatus or ame_util.nullStatus check to see
460                        if approver could have final authority */
461                     if extensionApprovers(extIndex).approval_status in (ame_util.approvedStatus, ame_util.approveAndForwardStatus,
462                                                   ame_util.nullStatus)
463                       then
464                       if(not finalAuthorityFound and
465                         tempHasFinalAuthorityYN = ame_util.booleanTrue) then
466                         finalAuthorityFound := true;
467                         tempOldJobLevel := tempJobLevel;
468                       end if;
469                     end if;
470                     extIndex := extIndex + 1;
471                   end if;
472                 end loop;
473                 /* Decide whether to end the chain. */
474                 if(topDogFound or
475                     (finalAuthorityFound and
476                      not includeAllJobLevelApprovers)) then
477                   finalAuthorityNotFound := false;
478                   exit;
479                 end if;
480                 tempOldJobLevel := tempJobLevel;
481                 /* Check to make sure tempSupervisorId is not null, else raise noSupervisorException */
482                 if tempSupervisorId is null then
483                   raise noSupervisorException;
484                 end if;
485                 if(tempSupervisorJobLevel is null) then
486                   ame_absolute_job_level_handler.getJobLevelAndSupervisor(personIdIn => tempSupervisorId,
487                                            jobLevelOut => tempSupervisorJobLevel,
488                                            supervisorIdOut => tempNextSupervisorId);
489                 end if;
490                 /*
491                   At this point finalAuthorityFound implies includeAllJobLevelApprovers, so the following if
492                   doesn't need to check includeAllJobLevelApprovers.  But it's implicit in the if statement.
493                 */
494                 if(finalAuthorityFound and
495                    tempOldJobLevel < tempSupervisorJobLevel) then
496                   finalAuthorityNotFound := false;
497                   exit;
498                 end if;
499                 extIndex := extIndex + 1;
500                 extensionApprovers(extIndex).orig_system_id := tempSupervisorId;
501                 tempJobLevel := tempSupervisorJobLevel;
502                 tempSupervisorId := tempNextSupervisorId;
503               end loop;
504               ame_engine.insertApprovers(firstIndexIn => lastForwardeeIndexes(j)+ insertionThreshhold + 1,
505                                          approversIn => extensionApprovers);
506               insertionThreshhold := insertionThreshhold + extensionApprovers.count;
507             end if;
508           end if;  /* This if corresponds to the check that action type id is valid */
509         end loop;
510       end loop;
511       exception
512         when badParameterException then
513           errorCode := -20001;
514           errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
515                                               messageNameIn => 'AME_400234_HAN_ACT_PAR_SIGN');
516           ame_util.runtimeException(packageNameIn => 'ame_non_final_handler',
517                                     routineNameIn => 'handler',
518                                     exceptionNumberIn => errorCode,
519                                     exceptionStringIn => errorMessage);
520           raise_application_error(errorCode,
521                                   errorMessage);
522         when noSupervisorException then
523           errorCode := -20001;
524           errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
525                                               messageNameIn => 'AME_400232_HAN_NO_SUPVSR_ID',
526                                               tokenNameOneIn => 'PERSON_ID',
527                                               tokenValueOneIn =>extensionApprovers(extIndex).orig_system_id);
528           ame_util.runtimeException(packageNameIn => 'ame_non_final_handler',
529                                     routineNameIn => 'handler',
530                                     exceptionNumberIn => errorCode,
531                                     exceptionStringIn => errorMessage);
532           raise_application_error(errorCode,
533                                   errorMessage);
534         when nullFirstIdException then
535           errorCode := -20001;
536           errorMessage :=
537           ame_util.getMessage(applicationShortNameIn => 'PER',
538                               messageNameIn => 'AME_400233_HAN_NO_TRANS_PER_ID');
539           ame_util.runtimeException(packageNameIn => 'ame_non_final_handler',
540                                     routineNameIn => 'handler',
541                                     exceptionNumberIn => errorCode,
542                                     exceptionStringIn => errorMessage);
543           raise_application_error(errorCode,
544                                   errorMessage);
545         when others then
546           ame_util.runtimeException(packageNameIn => 'ame_non_final_handler',
547                                     routineNameIn => 'handler',
548                                     exceptionNumberIn => sqlcode,
549                                     exceptionStringIn => sqlerrm);
550           raise;
551     end handler;
552  procedure parseAndSortRules is
553     badParameterException exception;
554     errorCode integer;
555     errorMessage ame_util.longestStringType;
556     tempCategory ame_util.charType;
557     tempLength integer;
558     tempNumber integer;
559     tempRuleId integer;
560     tempRuleIndex integer;
561     tempSign ame_util.charType;
562     upperLimit integer;
563    begin
564      parametersCount := parameters.count;
565      /* Parse. */
566      for i in 1 .. parametersCount loop
567        tempLength := lengthb(parameters(i));
568        if(substrb(parameters(i), 1, 1) = 'R') then
569          parameterNumbers(i) := to_number(substrb(parameters(i), 2, tempLength - 2)) +
570                                 threshholdJobLevel;
571          parameterSigns(i) := substrb(parameters(i), -1, 1);
572        else
573          parameterNumbers(i) := to_number(substrb(parameters(i), 2, tempLength - 2)) ;
574          parameterSigns(i) := substrb(parameters(i), -1, 1);
575        end if;
576        if(parameterSigns(i) <> '+' and
577           parameterSigns(i) <> '-') then
578          raise badParameterException;
579        end if;
580      end loop;
581      /* Sort. */
582      for i in 2 .. parametersCount loop
583        upperLimit := i - 1;
584        for j in 1 .. upperLimit loop
585          if(parameterNumbers(i) < parameterNumbers(j) or
586             (parameterNumbers(i) = parameterNumbers(j) and
587              parameterSigns(i) = '-' and parameterSigns(j) = '+')) then
588            tempRuleId := ruleIds(j);
589            tempRuleIndex := ruleIndexes(j);
590            tempNumber := parameterNumbers(j);
591            tempSign := parameterSigns(j);
592            ruleIds(j) := ruleIds(i);
593            ruleIndexes(j) := ruleIndexes(i);
594            parameterNumbers(j) := parameterNumbers(i);
595            parameterSigns(j) := parameterSigns(i);
596            ruleIds(i) := tempRuleId;
597            ruleIndexes(i) := tempRuleIndex;
598            parameterNumbers(i) := tempNumber;
599            parameterSigns(i) := tempSign;
600          end if;
601        end loop;
602      end loop;
603      exception
604        when badParameterException then
605          errorCode := -20001;
606          errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
607                                              messageNameIn => 'AME_400234_HAN_ACT_PAR_SIGN');
608          ame_util.runtimeException(packageNameIn => 'ame_non_final_handler',
609                                    routineNameIn => 'parseAndSortRules',
610                                    exceptionNumberIn => errorCode,
611                                    exceptionStringIn => errorMessage);
612          raise_application_error(errorCode,
613                                  errorMessage);
614        when others then
615          ame_util.runtimeException(packageNameIn => 'ame_non_final_handler',
616                                    routineNameIn => 'parseAndSortRules',
617                                    exceptionNumberIn => sqlcode,
618                                    exceptionStringIn => sqlerrm);
619          raise;
620    end parseAndSortRules ;
621 end ame_non_final_handler;