DBA Data[Home] [Help]

PACKAGE BODY: APPS.AME_LI_JOB_LEVEL_HANDLER

Source


1 package body ame_li_job_level_handler as
2 /* $Header: ameeliha.pkb 120.2 2007/12/20 20:02:56 prasashe noship $ */
3   /* package variables */
4   approverCategories ame_util.charList;
5   parametersCount integer;
6   parameterNumbers ame_util.idList;
7   parameters ame_util.stringList;
8   parameterSigns ame_util.charList;
9   ruleIds ame_util.idList;
10   ruleSatisfiedYN ame_util.charList;
11   threshholdJobLevel integer;
12   topDogFound boolean;
13   topDogPersonId integer;
14   /* forward declarations */
15   /*
16     getCatSourceAndAuthority does not account for the ALLOW_REQUESTOR_APPROVAL attribute.
17     The handler procedure does that.
18   */
19   procedure getCatSourceAndAuthority(personIdIn in integer,
20                                      jobLevelIn in integer,
21                                      supervisorIdIn in integer,
22                                      categoryOut out nocopy varchar2,
23                                      sourceOut out nocopy varchar2,
24                                      hasFinalAuthorityYNOut out nocopy varchar2,
25                                      supervisorJobLevelOut out nocopy integer,
26                                      nextSupervisorIdOut out nocopy integer);
27   /*
28     parseAndSortRules populates the parameterNumbers and parameterSigns tables in
29     ascending lexicographic order, first by numerical order, then with '+' dominating '-'.
30     Note that it does not sort the parameters proper.
31   */
32   procedure parseAndSortRules;
33   /* procedures */
34   procedure getCatSourceAndAuthority(personIdIn in integer,
35                                      jobLevelIn in integer,
36                                      supervisorIdIn in integer,
37                                      categoryOut out nocopy varchar2,
38                                      sourceOut out nocopy varchar2,
39                                      hasFinalAuthorityYNOut out nocopy varchar2,
40                                      supervisorJobLevelOut out nocopy integer,
41                                      nextSupervisorIdOut out nocopy integer) as
42     category ame_util.charType;
43     errorCode integer;
44     errorMessage ame_util.longestStringType;
45     hasFinalAuthorityYN ame_util.charType;
46     noSupervisorException exception;
47     personDisplayName ame_util.longStringType;
48     source ame_util.longStringType;
49     supervisorJobLevel integer;
50     tempRuleRequiresApprover boolean;
51     tempRuleSatisfied boolean;
52     begin
53       /* Initialize the two output arguments that might not otherwise get set. */
54      supervisorJobLevelOut := null;
55      nextSupervisorIdOut := null;
56       /*
57         1.  An approver satisfies a rule in any of three cases:
58             A.  The rule's parameter number does not exceed the approver's job level.
59             B.  The rule's parameter sign is '-', and the job level of the approver's
60                 supervisor exceeds the rule's parameter number.
61             C.  The approver is the top dog.
62         2.  An approver has final authority if the approver satisfies all the rules.
63             (The handler procedure proper takes care of adding subsequent approvers at
64             the same job level, if the relevant mandatory attribute so requires.)
65         3.  The source value is an ame-util.fieldDelimiter-delimited list of the IDs of
66             the rules that require an approver.  This procedure builds up the source
67             value according to the following logic:
68             A.  If a rule has not yet been satisfied, the rule requires the input
69                 approver.
70             B.  Otherwise, the rule requires the input approver only if the approver
71                 does <<not>> satisfy the rule.  (This would happen in the perverse case
72                 that an approver satisfies a rule, but their supervisor has a lower
73                 job level that does not satisfy the rule.)
74         4.  An approver's category is ame_util.approvalApproverCategory if any of the
75             rule usages requiring the approver is of that category; otherwise the
76             approver's category is ame_util.fyiApproverCategory.
77       */
78       category := ame_util.fyiApproverCategory;
79       hasFinalAuthorityYN := ame_util.booleanTrue;
80       for i in 1 .. parameterNumbers.count loop
81         /* Determine whether the approver satisfies the current rule. */
82         if(personIdIn = topDogPersonId) then
83           tempRuleSatisfied := true;
84           topDogFound := true;
85         else
86           tempRuleSatisfied := false;
87           topDogFound := false;
88           if(jobLevelIn >= parameterNumbers(i)) then
89             tempRuleSatisfied := true;
90           elsif(parameterSigns(i) = '-') then
91             if(supervisorJobLevel is null) then
92               if(supervisorIdIn is null) then
93                 raise noSupervisorException;
94               end if;
95               ame_absolute_job_level_handler.getJobLevelAndSupervisor(personIdIn => supervisorIdIn,
96                                        jobLevelOut => supervisorJobLevel,
97                                        supervisorIdOut => nextSupervisorIdOut);
98               supervisorJobLevelOut := supervisorJobLevel;
99             end if;
100             if(supervisorJobLevel > parameterNumbers(i)) then
101               tempRuleSatisfied := true;
102             end if;
103           end if;
104         end if;
105         /* Update hasFinalAuthorityYN as needed. */
106         if(not tempRuleSatisfied and
107            hasFinalAuthorityYN = ame_util.booleanTrue) then
108           hasFinalAuthorityYN := ame_util.booleanFalse;
109         end if;
110         /* Determine whether the current rule requires the approver. */
111         tempRuleRequiresApprover := false;
112         if(ruleSatisfiedYN(i) = ame_util.booleanTrue) then
113           if(not tempRuleSatisfied) then
114             tempRuleRequiresApprover := true;
115           end if;
116         else
117           tempRuleRequiresApprover := true;
118           if(tempRuleSatisfied) then
119             ruleSatisfiedYN(i) := ame_util.booleanTrue;
120           end if;
121         end if;
122         if(tempRuleRequiresApprover) then
123           /* Update source. */
124           ame_util.appendRuleIdToSource(ruleIdIn => ruleIds(i),
125                                         sourceInOut => source);
126           /* Update category as needed. */
127           if(category = ame_util.fyiApproverCategory and
128              approverCategories(i) = ame_util.approvalApproverCategory) then
129             category := ame_util.approvalApproverCategory;
130           end if;
131         end if;
132       end loop;
133       categoryOut := category;
134       hasFinalAuthorityYNOut := hasFinalAuthorityYN;
135       sourceOut := source;
136       exception
137         when noSupervisorException then
138           personDisplayName := ame_approver_type_pkg.getApproverDisplayName2(
139                                       origSystemIn => ame_util.perOrigSystem,
140                                       origSystemIdIn => personIdIn );
141           errorCode := -20001;
142           errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
143             messageNameIn     => 'AME_400297_HAN_LACK_SPVR',
144             tokenNameOneIn    => 'FIRST_NAME',
145             tokenValueOneIn   => personDisplayName,
146             tokenNameTwoIn    => 'LAST_NAME',
147             tokenValueTwoIn   => null ,
148             tokenNameThreeIn  => 'OTHER_NAME',
149             tokenValueThreeIn =>  null );
150           ame_util.runtimeException(packageNameIn => 'ame_li_job_level_handler',
151                                     routineNameIn => 'getCatSourceAndAuthority',
152                                     exceptionNumberIn => errorCode,
153                                     exceptionStringIn => errorMessage);
154           raise_application_error(errorCode,
155                                   errorMessage);
156         when others then
157           categoryOut := null;
158           hasFinalAuthorityYNOut := null;
159           sourceOut := null;
160           ame_util.runtimeException(packageNameIn => 'ame_li_job_level_handler',
161                                     routineNameIn => 'getCatSourceAndAuthority',
162                                     exceptionNumberIn => sqlcode,
163                                     exceptionStringIn => sqlerrm);
164           raise;
165     end getCatSourceAndAuthority;
166   procedure handler as
167     chainOrderMode ame_util.stringType;
168     COAInsertee ame_util.approverRecord2;
169     errorCode integer;
170     errorMessage ame_util.longestStringType;
171     finalAuthorityApproverCategory ame_util.charType;
172     finalAuthorityFound boolean;
173     finalAuthoritySource ame_util.longStringType;
174     includeAllJobLevelApprovers boolean;
175     itemClassId integer;
176     itemIds ame_util.stringList;
177     lineItemStartingPointPersonId integer;
178     noSupervisorException exception;
179     nullFirstIdException exception;
180     firstStartingPointId integer;
181     personDisplayName ame_util.longStringType;
182     secondStartingPointId integer;
183     tempApprover ame_util.approverRecord2;
184     tempHasFinalAuthorityYN ame_util.charType;
185     tempJobLevel integer;
186     tempMemberOrderNumber integer;
187     tempOldJobLevel integer;
188     tempSupervisorId integer;
189     tempSupervisorJobLevel integer;
190     tempNextSupervisorId integer;
191     votingRegimeType ame_util.stringType;
192     firstAuthInsExists boolean := false;
193     coaInsAuthForward boolean := false;
194     begin
195       includeAllJobLevelApprovers :=
196         ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.includeAllApproversAttribute) =
197         ame_util.booleanAttributeTrue;
198       /* Populate some of the package variables. */
199       topDogPersonId := to_number(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.topSupPersonIdAttribute));
200       /* Set the fields in tempApprover that are constant for the entire handler cycle. */
201       tempApprover.orig_system := ame_util.perOrigSystem;
202       tempApprover.authority := ame_util.authorityApprover;
203       tempApprover.action_type_id := ame_engine.getHandlerActionTypeId;
204       tempApprover.item_class := ame_engine.getHandlerItemClassName;
205       tempApprover.item_class_order_number := ame_engine.getHandlerItemClassOrderNumber;
206       tempApprover.item_order_number := ame_engine.getHandlerItemOrderNumber;
207       tempApprover.sub_list_order_number := ame_engine.getHandlerSublistOrderNum;
208       tempApprover.action_type_order_number := ame_engine.getHandlerActionTypeOrderNum;
209       votingRegimeType := ame_engine.getActionTypeVotingRegime(actionTypeIdIn => tempApprover.action_type_id);
210       chainOrderMode := ame_engine.getActionTypeChainOrderMode(actionTypeIdIn => tempApprover.action_type_id);
211       /*
212         The engine only calls a handler if a rule requiring it exists, so we can assume that
213         the package variables that ame_engine.getHandlerRules initializes are nonempty.
214         Fetch the rules and sort them in increasing parameter order.  (Duplicate parameters
215         are harmless here.)
216       */
217       ame_engine.getHandlerRules2(ruleIdsOut => ruleIds,
218                                   approverCategoriesOut => approverCategories,
219                                   parametersOut => parameters);
220       parametersCount := parameters.count;
221       /* get the Item class Id for Line Item Item class */
222       itemClassId := ame_engine.getItemClassId(itemClassNameIn => ame_util.lineItemItemClassName);
223       /* call ame_engine.getItemClassItemIds() to get the item Id list */
224       ame_engine.getItemClassItemIds(itemClassIdIn => itemClassId,
225                                      itemIdsOut => itemIds);
226       for chainCounter in 1..itemIds.count loop
227         firstAuthInsExists := false;
228         coaInsAuthForward := false;
229         finalAuthorityApproverCategory := null;
230         finalAuthoritySource := null;
231         /* Set the tempApprover variables for this line item cycle */
232         tempApprover.item_id := ame_engine.getHandlerItemId;
233         tempApprover.group_or_chain_id := chainCounter;
234         /* Check for COA 'firstAuthority' insertions */
235         ame_engine.getHandlerCOAFirstApprover(itemClassIn => tempApprover.item_class,
236                                               itemIdIn => tempApprover.item_id,
237                                               actionTypeIdIn =>tempApprover.action_type_id,
238                                               groupOrChainIdIn => chainCounter,
239                                               nameOut => COAInsertee.name,
240                                               origSystemOut => COAInsertee.orig_system,
241                                               origSystemIdOut =>COAInsertee.orig_system_id,
242                                               displayNameOut => COAInsertee.display_name,
243                                               sourceOut => COAInsertee.source);
244         if COAInsertee.name is  null then
245           /* call ame_engine.getItemAttValue2() inside the loop to get the line
246              item starting point person id  */
247           lineItemStartingPointPersonId := to_number(ame_engine.getItemAttValue2(
248                             attributeNameIn => ame_util.lineItemStartingPointAttribute,
249                                       itemIdIn => itemIds(chainCounter)));
250           if(lineItemStartingPointPersonId is null ) then
251             raise nullFirstIdException;
252           end if;
253           tempApprover.orig_system_id := lineItemStartingPointPersonId;
254           tempApprover.api_insertion := ame_util.oamGenerated;
255           ame_approver_type_pkg.getWfRolesNameAndDisplayName(
256                               origSystemIn => ame_util.perOrigSystem,
257                               origSystemIdIn => tempApprover.orig_system_id,
258                               nameOut => tempApprover.name,
259                               displayNameOut => tempApprover.display_name);
260         else
261           tempApprover.name := COAInsertee.name;
262           tempApprover.orig_system := COAInsertee.orig_system;
263           tempApprover.orig_system_id := COAInsertee.orig_system_id;
264           tempApprover.display_name :=  COAInsertee.display_name;
265           tempApprover.source := COAInsertee.source;
266           tempApprover.api_insertion := ame_util.apiAuthorityInsertion;
267           firstAuthInsExists := true;
268         end if;
269         /* Get the threshholdJobLevel to convert parameters to absolute values */
270         ame_absolute_job_level_handler.getJobLevelAndSupervisor(
271                                    personIdIn => tempApprover.orig_system_id,
272                                    jobLevelOut => threshholdJobLevel,
273                                    supervisorIdOut => tempSupervisorId);
274         tempJobLevel := threshholdJobLevel;
275         parseAndSortRules;
276         for i in 1 .. parameterNumbers.count loop
277           ruleSatisfiedYN(i) := ame_util.booleanFalse;
278         end loop;
279         if (chainOrderMode = ame_util.serialChainsMode) then
280             tempApprover.group_or_chain_order_number := chainCounter;
281         else /* chain Order Mode is parallel */
282             tempApprover.group_or_chain_order_number := 1;
283         end if;
284         /* In this case self approval can not be done so build the chain. */
285         finalAuthorityFound := false;
286         tempMemberOrderNumber := 0; /* pre-increment */
287         loop
288           getCatSourceAndAuthority(personIdIn => tempApprover.orig_system_id,
289                                    jobLevelIn => tempJobLevel,
290                                    supervisorIdIn => tempSupervisorId,
291                                    categoryOut => tempApprover.approver_category,
292                                    sourceOut => tempApprover.source,
293                                    hasFinalAuthorityYNOut => tempHasFinalAuthorityYN,
294                                    supervisorJobLevelOut => tempSupervisorJobLevel,
295                                    nextSupervisorIdOut => tempNextSupervisorId);
296           if(not finalAuthorityFound and
297              tempHasFinalAuthorityYN = ame_util.booleanTrue) then
298             finalAuthorityFound := true;
299             finalAuthorityApproverCategory := tempApprover.approver_category;
300             finalAuthoritySource := tempApprover.source;
301           end if;
302           if (tempApprover.source is null and
303              finalAuthoritySource is not null ) then
304             tempApprover.approver_category := finalAuthorityApproverCategory;
305             tempApprover.source := finalAuthoritySource;
306           end if;
307           tempApprover.api_insertion := ame_util.oamGenerated;
308           tempApprover.occurrence := ame_engine.getHandlerOccurrence(
309                                    nameIn=>tempApprover.name,
310                                    itemClassIn => tempApprover.item_class,
311                                    itemIdIn => tempApprover.item_id,
312                                    actionTypeIdIn => tempApprover.action_type_id,
313                                    groupOrChainIdIn => tempApprover.group_or_chain_id);
314           tempMemberOrderNumber := tempMemberOrderNumber + 1;
315           if(votingRegimeType = ame_util.serializedVoting) then
316             tempApprover.member_order_number := tempMemberOrderNumber;
317           else /* votingRegimeType in (ame_util.consensusVoting, ame_util.firstApproverVoting) */
318             tempApprover.member_order_number := 1;
319           end if;
320           tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn => tempApprover);
321           /* The engine will set tempApprover.approver_order_number; leave it null here. */
322           ame_engine.addApprover(approverIn => tempApprover);
323           /* check to see if there is a COA insertion after this approver. If a COA
324              insertion is found, keep checking till no more COA insertions. The check
325              for final authority will need to be done again.  */
326           loop
327             /* Initialize COAInsertee approverRecord2 */
328             COAInsertee := ame_util.emptyApproverRecord2;
329             /* Check if there are any COAInsertions */
330             ame_engine.getHandlerCOAInsertion(nameIn => tempApprover.name,
331                                             itemClassIn => tempApprover.item_class,
332                                             itemIdIn => tempApprover.item_id,
333                                             actionTypeIdIn => tempApprover.action_type_id,
334                                             groupOrChainIdIn => tempApprover.group_or_chain_id,
335                                             occurrenceIn => tempApprover.occurrence,
336                                             approvalStatusIn => tempApprover.approval_status,
337                                             nameOut => COAInsertee.name,
338                                             origSystemOut => COAInsertee.orig_system,
339                                             origSystemIdOut => COAInsertee.orig_system_id,
340                                             displayNameOut => COAInsertee.display_name,
341                                             sourceOut => COAInsertee.source);
342             if COAInsertee.name is null then
343               exit;
344             else
345               tempApprover.name := COAInsertee.name;
346               tempApprover.orig_system := COAInsertee.orig_system;
347               tempApprover.orig_system_id := COAInsertee.orig_system_id;
348               tempApprover.display_name :=  COAInsertee.display_name;
349               ame_absolute_job_level_handler.getJobLevelAndSupervisor(personIdIn => tempApprover.orig_system_id,
350                                        jobLevelOut => tempJobLevel,
351                                        supervisorIdOut => tempSupervisorId);
352               getCatSourceAndAuthority(personIdIn => tempApprover.orig_system_id,
353                                        jobLevelIn => tempJobLevel,
354                                        supervisorIdIn => tempSupervisorId,
355                                        categoryOut => tempApprover.approver_category,
356                                        sourceOut => tempApprover.source,
357                                        hasFinalAuthorityYNOut => tempHasFinalAuthorityYN,
358                                        supervisorJobLevelOut => tempSupervisorJobLevel,
359                                        nextSupervisorIdOut => tempNextSupervisorId);
360               tempApprover.source := COAInsertee.source;
361               tempApprover.approver_category := ame_util.approvalApproverCategory;
362               tempApprover.api_insertion := ame_util.apiAuthorityInsertion;
363               tempMemberOrderNumber := tempMemberOrderNumber + 1;
364               if(votingRegimeType = ame_util.serializedVoting) then
365                 tempApprover.member_order_number := tempMemberOrderNumber;
366               else /* votingRegimeType in (ame_util.consensusVoting, ame_util.firstApproverVoting) */
367                 tempApprover.member_order_number := 1;
368               end if;
369               tempApprover.occurrence := ame_engine.getHandlerOccurrence(nameIn =>  tempApprover.name,
370                                               itemClassIn => tempApprover.item_class,
371                                               itemIdIn => tempApprover.item_id,
372                                               actionTypeIdIn => tempApprover.action_type_id,
373                                               groupOrChainIdIn => tempApprover.group_or_chain_id);
374               tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn => tempApprover);
375               /* If approver has a status of ame_util.approve or ame_util.approveAndForwardStatus or
376                  ame_util.nullStatus check to see if approver could have final authority */
377               if ((tempApprover.approval_status is null) or
378                 (tempApprover.approval_status in
379                         (ame_util.approvedStatus, ame_util.approveAndForwardStatus,
380                          ame_util.repeatedStatus, ame_util.suppressedStatus,
381                          ame_util.beatByFirstResponderStatus, ame_util.nullStatus)) or
382                 (tempApprover.approver_category = ame_util.approvalApproverCategory and
383                  tempApprover.approval_status = ame_util.notifiedStatus) )
384                 then
385                 if(not finalAuthorityFound and
386                   tempHasFinalAuthorityYN = ame_util.booleanTrue) then
387                   finalAuthorityFound := true;
388                 end if;
389               end if;
390               ame_engine.addApprover(approverIn => tempApprover);
391               coaInsAuthForward := true;
392             end if;
393           end loop;
394           /* Decide whether to end the chain. */
395           if(topDogFound or
396              (finalAuthorityFound and
397              not includeAllJobLevelApprovers)) then
398             exit;
399           end if;
400           /* Check to make sure tempSupervisorId is not null, else raise noSupervisorException */
401           if tempSupervisorId is null then
402             raise noSupervisorException;
403           else
404             tempApprover.orig_system_id := tempSupervisorId;
405           end if;
406           tempOldJobLevel := tempJobLevel;
407           if(tempSupervisorJobLevel is null) then
408             ame_absolute_job_level_handler.getJobLevelAndSupervisor(personIdIn => tempApprover.orig_system_id,
409                                    jobLevelOut => tempJobLevel,
410                                    supervisorIdOut => tempSupervisorId);
411           else
412             tempJobLevel := tempSupervisorJobLevel;
413             tempSupervisorId := tempNextSupervisorId;
414           end if;
415           /* At this point finalAuthorityFound implies includeAllJobLevelApprovers, so
416           the following if doesn't need to check includeAllJobLevelApprovers.  But it's
417           implicit in the if statement.  */
418           if(finalAuthorityFound and
419              tempOldJobLevel <> tempJobLevel) then
420             exit;
421           end if;
422           ame_approver_type_pkg.getWfRolesNameAndDisplayName(
423                                    origSystemIn => ame_util.perOrigSystem,
424                                    origSystemIdIn => tempApprover.orig_system_id,
425                                    nameOut => tempApprover.name,
426                                    displayNameOut => tempApprover.display_name);
427           if firstAuthInsExists then
428             ame_engine.setDeviationReasonDate(ame_approver_deviation_pkg.firstauthHandlerInsReason,null);
429           end if;
430           if coaInsAuthForward then
431             ame_engine.setDeviationReasonDate(ame_approver_deviation_pkg.forwarHandlerAuthInsReason,null);
432           end if;
433         end loop;
434       end loop;
435       exception
436         when noSupervisorException then
437           if tempApprover.display_name is null then
438             personDisplayName := ame_approver_type_pkg.getApproverDisplayName2(
439                                       origSystemIn => ame_util.perOrigSystem,
440                                       origSystemIdIn => tempApprover.orig_system_id );
441           else
442             personDisplayName := tempApprover.display_name;
443           end if;
444           errorCode := -20001;
445           errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
446             messageNameIn     => 'AME_400297_HAN_LACK_SPVR',
447             tokenNameOneIn    => 'FIRST_NAME',
448             tokenValueOneIn   => personDisplayName,
449             tokenNameTwoIn    => 'LAST_NAME',
450             tokenValueTwoIn   => null ,
451             tokenNameThreeIn  => 'OTHER_NAME',
452             tokenValueThreeIn =>  null );
453           ame_util.runtimeException(packageNameIn => 'ame_li_job_level_handler',
454                                     routineNameIn => 'handler',
455                                     exceptionNumberIn => errorCode,
456                                     exceptionStringIn => errorMessage);
457           raise_application_error(errorCode,
458                                   errorMessage);
459         when nullFirstIdException then
460           errorCode := -20001;
461           errorMessage :=
462             ame_util.getMessage(applicationShortNameIn => 'PER',
463                                 messageNameIn => 'AME_400450_LIHA_NO_PER_ID');
464           ame_util.runtimeException(packageNameIn => 'ame_li_job_level_handler',
465                                     routineNameIn => 'handler',
466                                     exceptionNumberIn => errorCode,
467                                     exceptionStringIn => errorMessage);
468           raise_application_error(errorCode,
469                                   errorMessage);
470         when others then
471           ame_util.runtimeException(packageNameIn => 'ame_li_job_level_handler',
472                                     routineNameIn => 'handler',
473                                     exceptionNumberIn => sqlcode,
474                                     exceptionStringIn => sqlerrm);
475           raise;
476     end handler;
477   procedure parseAndSortRules  as
478     badParameterException exception;
479     errorCode integer;
480     errorMessage ame_util.longestStringType;
481     tempCategory ame_util.charType;
482     tempIndex integer;
483     tempLength integer;
484     tempNumber integer;
485     tempRuleId integer;
486     tempSign ame_util.charType;
487     upperLimit integer;
488     i   integer;
489     j integer;
490     begin
491       /* Parse. */
492       tempIndex := 0;
493       parameterNumbers.delete;
494       parameterSigns.delete;
495       for i in 1 .. parametersCount  loop
496         tempIndex := tempIndex + 1;
497         tempLength := lengthb(parameters(i));
498         parameterNumbers(tempIndex) := to_number(substrb(parameters(i),1,tempLength- 1));
499         parameterSigns(tempIndex) := substrb(parameters(i), -1, 1);
500         if(parameterSigns(tempIndex) <> '+' and
501            parameterSigns(tempIndex) <> '-') then
502           raise badParameterException;
503         end if;
504       end loop;
505       /* Sort. */
506       for i in 2 .. tempIndex loop
507         upperLimit := i - 1;
508         for j in 1 .. upperLimit loop
509           if(parameterNumbers(i) < parameterNumbers(j) or
510              (parameterNumbers(i) = parameterNumbers(j) and
511               parameterSigns(i) = '-' and parameterSigns(j) = '+')) then
512             tempRuleId := ruleIds(j);
513             tempCategory := approverCategories(j);
514             tempNumber := parameterNumbers(j);
515             tempSign := parameterSigns(j);
516             ruleIds(j) := ruleIds(i);
517             approverCategories(j) := approverCategories(i);
518             parameterNumbers(j) := parameterNumbers(i);
519             parameterSigns(j) := parameterSigns(i);
520             ruleIds(i) := tempRuleId;
521             approverCategories(i) := tempCategory;
522             parameterNumbers(i) := tempNumber;
523             parameterSigns(i) := tempSign;
524           end if;
525         end loop;
526       end loop;
527       exception
528         when badParameterException then
529           errorCode := -20001;
530           errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
531                                               messageNameIn => 'AME_400234_HAN_ACT_PAR_SIGN');
532           ame_util.runtimeException(packageNameIn => 'ame_li_job_level_handler',
533                                     routineNameIn => 'parseAndSortRules',
534                                     exceptionNumberIn => errorCode,
535                                     exceptionStringIn => errorMessage);
536           raise_application_error(errorCode,
537                                   errorMessage);
538         when others then
539           ame_util.runtimeException(packageNameIn => 'ame_li_job_level_handler',
540                                     routineNameIn => 'parseAndSortRules',
541                                     exceptionNumberIn => sqlcode,
542                                     exceptionStringIn => sqlerrm);
543           raise;
544     end parseAndSortRules;
545 end ame_li_job_level_handler;