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.6 2011/05/17 11:38:58 nchinnam ship $ */
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 := -20207;
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     l_error_code number;
195     begin
196       errorCode := -20236;
197       includeAllJobLevelApprovers :=
198         ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.includeAllApproversAttribute) =
199         ame_util.booleanAttributeTrue;
200       /* Populate some of the package variables. */
201       topDogPersonId := to_number(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.topSupPersonIdAttribute));
202       /* Set the fields in tempApprover that are constant for the entire handler cycle. */
203       tempApprover.orig_system := ame_util.perOrigSystem;
204       tempApprover.authority := ame_util.authorityApprover;
205       tempApprover.action_type_id := ame_engine.getHandlerActionTypeId;
206       tempApprover.item_class := ame_engine.getHandlerItemClassName;
207       tempApprover.item_class_order_number := ame_engine.getHandlerItemClassOrderNumber;
208       tempApprover.item_order_number := ame_engine.getHandlerItemOrderNumber;
209       tempApprover.sub_list_order_number := ame_engine.getHandlerSublistOrderNum;
210       tempApprover.action_type_order_number := ame_engine.getHandlerActionTypeOrderNum;
211       votingRegimeType := ame_engine.getActionTypeVotingRegime(actionTypeIdIn => tempApprover.action_type_id);
212       chainOrderMode := ame_engine.getActionTypeChainOrderMode(actionTypeIdIn => tempApprover.action_type_id);
213       /*
214         The engine only calls a handler if a rule requiring it exists, so we can assume that
215         the package variables that ame_engine.getHandlerRules initializes are nonempty.
216         Fetch the rules and sort them in increasing parameter order.  (Duplicate parameters
217         are harmless here.)
218       */
219       ame_engine.getHandlerRules2(ruleIdsOut => ruleIds,
220                                   approverCategoriesOut => approverCategories,
221                                   parametersOut => parameters);
222       parametersCount := parameters.count;
223       /* get the Item class Id for Line Item Item class */
224       itemClassId := ame_engine.getItemClassId(itemClassNameIn => ame_util.lineItemItemClassName);
225       /* call ame_engine.getItemClassItemIds() to get the item Id list */
226       ame_engine.getItemClassItemIds(itemClassIdIn => itemClassId,
227                                      itemIdsOut => itemIds);
228       for chainCounter in 1..itemIds.count loop
229         errorCode := -20236;
230         firstAuthInsExists := false;
231         coaInsAuthForward := false;
232         finalAuthorityApproverCategory := null;
233         finalAuthoritySource := null;
234         /* Set the tempApprover variables for this line item cycle */
235         tempApprover.item_id := ame_engine.getHandlerItemId;
236         tempApprover.group_or_chain_id := chainCounter;
237         /* Check for COA 'firstAuthority' insertions */
238         ame_engine.getHandlerCOAFirstApprover(itemClassIn => tempApprover.item_class,
239                                               itemIdIn => tempApprover.item_id,
240                                               actionTypeIdIn =>tempApprover.action_type_id,
241                                               groupOrChainIdIn => chainCounter,
242                                               nameOut => COAInsertee.name,
243                                               origSystemOut => COAInsertee.orig_system,
244                                               origSystemIdOut =>COAInsertee.orig_system_id,
245                                               displayNameOut => COAInsertee.display_name,
246                                               sourceOut => COAInsertee.source);
247         if COAInsertee.name is  null then
248           /* call ame_engine.getItemAttValue2() inside the loop to get the line
249              item starting point person id  */
250           lineItemStartingPointPersonId := to_number(ame_engine.getItemAttValue2(
251                             attributeNameIn => ame_util.lineItemStartingPointAttribute,
252                                       itemIdIn => itemIds(chainCounter)));
253           if(lineItemStartingPointPersonId is null ) then
254             raise nullFirstIdException;
255           end if;
256           tempApprover.orig_system_id := lineItemStartingPointPersonId;
257           tempApprover.api_insertion := ame_util.oamGenerated;
258           ame_approver_type_pkg.getWfRolesNameAndDisplayName(
259                               origSystemIn => ame_util.perOrigSystem,
260                               origSystemIdIn => tempApprover.orig_system_id,
261                               nameOut => tempApprover.name,
262                               displayNameOut => tempApprover.display_name);
263         else
264           tempApprover.name := COAInsertee.name;
265           tempApprover.orig_system := COAInsertee.orig_system;
266           tempApprover.orig_system_id := COAInsertee.orig_system_id;
267           tempApprover.display_name :=  COAInsertee.display_name;
268           tempApprover.source := COAInsertee.source;
269           tempApprover.api_insertion := ame_util.apiAuthorityInsertion;
270           firstAuthInsExists := true;
271         end if;
272         /* Get the threshholdJobLevel to convert parameters to absolute values */
273         ame_absolute_job_level_handler.getJobLevelAndSupervisor(
274                                    personIdIn => tempApprover.orig_system_id,
275                                    jobLevelOut => threshholdJobLevel,
276                                    supervisorIdOut => tempSupervisorId);
277         tempJobLevel := threshholdJobLevel;
278         parseAndSortRules;
279         for i in 1 .. parameterNumbers.count loop
280           ruleSatisfiedYN(i) := ame_util.booleanFalse;
281         end loop;
282         if (chainOrderMode = ame_util.serialChainsMode) then
283             tempApprover.group_or_chain_order_number := chainCounter;
284         else /* chain Order Mode is parallel */
285             tempApprover.group_or_chain_order_number := 1;
286         end if;
287         /* In this case self approval can not be done so build the chain. */
288         finalAuthorityFound := false;
289         tempMemberOrderNumber := 0; /* pre-increment */
290         errorCode := -20237;
291         loop
292           getCatSourceAndAuthority(personIdIn => tempApprover.orig_system_id,
293                                    jobLevelIn => tempJobLevel,
294                                    supervisorIdIn => tempSupervisorId,
295                                    categoryOut => tempApprover.approver_category,
296                                    sourceOut => tempApprover.source,
297                                    hasFinalAuthorityYNOut => tempHasFinalAuthorityYN,
298                                    supervisorJobLevelOut => tempSupervisorJobLevel,
299                                    nextSupervisorIdOut => tempNextSupervisorId);
300           if(not finalAuthorityFound and
301              tempHasFinalAuthorityYN = ame_util.booleanTrue) then
302             finalAuthorityFound := true;
303             finalAuthorityApproverCategory := tempApprover.approver_category;
304             finalAuthoritySource := tempApprover.source;
305           end if;
306           if (tempApprover.source is null and
307              finalAuthoritySource is not null ) then
308             tempApprover.approver_category := finalAuthorityApproverCategory;
309             tempApprover.source := finalAuthoritySource;
310           end if;
311           tempApprover.api_insertion := ame_util.oamGenerated;
312           tempApprover.occurrence := ame_engine.getHandlerOccurrence(
313                                    nameIn=>tempApprover.name,
314                                    itemClassIn => tempApprover.item_class,
315                                    itemIdIn => tempApprover.item_id,
316                                    actionTypeIdIn => tempApprover.action_type_id,
317                                    groupOrChainIdIn => tempApprover.group_or_chain_id);
318           tempMemberOrderNumber := tempMemberOrderNumber + 1;
319           if(votingRegimeType = ame_util.serializedVoting) then
320             tempApprover.member_order_number := tempMemberOrderNumber;
321           else /* votingRegimeType in (ame_util.consensusVoting, ame_util.firstApproverVoting) */
322             tempApprover.member_order_number := 1;
323           end if;
324           tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn => tempApprover);
325           /* The engine will set tempApprover.approver_order_number; leave it null here. */
326           ame_engine.addApprover(approverIn => tempApprover);
327           /* check to see if there is a COA insertion after this approver. If a COA
328              insertion is found, keep checking till no more COA insertions. The check
329              for final authority will need to be done again.  */
330           loop
331             /* Initialize COAInsertee approverRecord2 */
332             COAInsertee := ame_util.emptyApproverRecord2;
333             /* Check if there are any COAInsertions */
334             ame_engine.getHandlerCOAInsertion(nameIn => tempApprover.name,
335                                             itemClassIn => tempApprover.item_class,
336                                             itemIdIn => tempApprover.item_id,
337                                             actionTypeIdIn => tempApprover.action_type_id,
338                                             groupOrChainIdIn => tempApprover.group_or_chain_id,
339                                             occurrenceIn => tempApprover.occurrence,
340                                             approvalStatusIn => tempApprover.approval_status,
341                                             nameOut => COAInsertee.name,
342                                             origSystemOut => COAInsertee.orig_system,
343                                             origSystemIdOut => COAInsertee.orig_system_id,
344                                             displayNameOut => COAInsertee.display_name,
345                                             sourceOut => COAInsertee.source);
346             if COAInsertee.name is null then
347               exit;
348             else
349               tempApprover.name := COAInsertee.name;
350               tempApprover.orig_system := COAInsertee.orig_system;
351               tempApprover.orig_system_id := COAInsertee.orig_system_id;
352               tempApprover.display_name :=  COAInsertee.display_name;
353               ame_absolute_job_level_handler.getJobLevelAndSupervisor(personIdIn => tempApprover.orig_system_id,
354                                        jobLevelOut => tempJobLevel,
355                                        supervisorIdOut => tempSupervisorId);
356               getCatSourceAndAuthority(personIdIn => tempApprover.orig_system_id,
357                                        jobLevelIn => tempJobLevel,
358                                        supervisorIdIn => tempSupervisorId,
359                                        categoryOut => tempApprover.approver_category,
360                                        sourceOut => tempApprover.source,
361                                        hasFinalAuthorityYNOut => tempHasFinalAuthorityYN,
362                                        supervisorJobLevelOut => tempSupervisorJobLevel,
363                                        nextSupervisorIdOut => tempNextSupervisorId);
364               tempApprover.source := COAInsertee.source;
365               tempApprover.approver_category := ame_util.approvalApproverCategory;
366               tempApprover.api_insertion := ame_util.apiAuthorityInsertion;
367               tempMemberOrderNumber := tempMemberOrderNumber + 1;
368               if(votingRegimeType = ame_util.serializedVoting) then
369                 tempApprover.member_order_number := tempMemberOrderNumber;
370               else /* votingRegimeType in (ame_util.consensusVoting, ame_util.firstApproverVoting) */
371                 tempApprover.member_order_number := 1;
372               end if;
373               tempApprover.occurrence := ame_engine.getHandlerOccurrence(nameIn =>  tempApprover.name,
374                                               itemClassIn => tempApprover.item_class,
375                                               itemIdIn => tempApprover.item_id,
376                                               actionTypeIdIn => tempApprover.action_type_id,
377                                               groupOrChainIdIn => tempApprover.group_or_chain_id);
378               tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn => tempApprover);
379               /* If approver has a status of ame_util.approve or ame_util.approveAndForwardStatus or
380                  ame_util.nullStatus check to see if approver could have final authority */
381               if ((tempApprover.approval_status is null) or
382                 (tempApprover.approval_status in
383                         (ame_util.approvedStatus, ame_util.approveAndForwardStatus,
384                          ame_util.repeatedStatus, ame_util.suppressedStatus,
385                          ame_util.beatByFirstResponderStatus, ame_util.nullStatus)) or
386                 (tempApprover.approver_category = ame_util.approvalApproverCategory and
387                  tempApprover.approval_status = ame_util.notifiedStatus) )
388                 then
389                 if(not finalAuthorityFound and
390                   tempHasFinalAuthorityYN = ame_util.booleanTrue) then
391                   finalAuthorityFound := true;
392                 end if;
393               end if;
394               ame_engine.addApprover(approverIn => tempApprover);
395               coaInsAuthForward := true;
396             end if;
397           end loop;
398           /* Decide whether to end the chain. */
399           if(topDogFound or
400              (finalAuthorityFound and
401              not includeAllJobLevelApprovers)) then
402             exit;
403           end if;
404           /* Check to make sure tempSupervisorId is not null, else raise noSupervisorException */
405           if tempSupervisorId is null then
406             raise noSupervisorException;
407           else
408             tempApprover.orig_system_id := tempSupervisorId;
409           end if;
410           tempOldJobLevel := tempJobLevel;
411           if(tempSupervisorJobLevel is null) then
412             ame_absolute_job_level_handler.getJobLevelAndSupervisor(personIdIn => tempApprover.orig_system_id,
413                                    jobLevelOut => tempJobLevel,
414                                    supervisorIdOut => tempSupervisorId);
415           else
416             tempJobLevel := tempSupervisorJobLevel;
417             tempSupervisorId := tempNextSupervisorId;
418           end if;
419           /* At this point finalAuthorityFound implies includeAllJobLevelApprovers, so
420           the following if doesn't need to check includeAllJobLevelApprovers.  But it's
421           implicit in the if statement.  */
422           if(finalAuthorityFound and
423              tempOldJobLevel <> tempJobLevel) then
424             exit;
425           end if;
426           ame_approver_type_pkg.getWfRolesNameAndDisplayName(
427                                    origSystemIn => ame_util.perOrigSystem,
428                                    origSystemIdIn => tempApprover.orig_system_id,
429                                    nameOut => tempApprover.name,
430                                    displayNameOut => tempApprover.display_name);
431           if firstAuthInsExists then
432             ame_engine.setDeviationReasonDate(ame_approver_deviation_pkg.firstauthHandlerInsReason,null);
433           end if;
434           if coaInsAuthForward then
435             ame_engine.setDeviationReasonDate(ame_approver_deviation_pkg.forwarHandlerAuthInsReason,null);
436           end if;
437         end loop;
438       end loop;
439       exception
440         when noSupervisorException then
441           if tempApprover.display_name is null then
442             personDisplayName := ame_approver_type_pkg.getApproverDisplayName2(
443                                       origSystemIn => ame_util.perOrigSystem,
444                                       origSystemIdIn => tempApprover.orig_system_id );
445           else
446             personDisplayName := tempApprover.display_name;
447           end if;
448           errorCode := -20207;
449           errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
450             messageNameIn     => 'AME_400297_HAN_LACK_SPVR',
451             tokenNameOneIn    => 'FIRST_NAME',
452             tokenValueOneIn   => personDisplayName,
453             tokenNameTwoIn    => 'LAST_NAME',
454             tokenValueTwoIn   => null ,
455             tokenNameThreeIn  => 'OTHER_NAME',
456             tokenValueThreeIn =>  null );
457           ame_util.runtimeException(packageNameIn => 'ame_li_job_level_handler',
458                                     routineNameIn => 'handler',
459                                     exceptionNumberIn => errorCode,
460                                     exceptionStringIn => errorMessage);
461           raise_application_error(errorCode,
462                                   errorMessage);
463         when nullFirstIdException then
464           errorCode := -20001;
465           errorMessage :=
466             ame_util.getMessage(applicationShortNameIn => 'PER',
467                                 messageNameIn => 'AME_400450_LIHA_NO_PER_ID');
468           ame_util.runtimeException(packageNameIn => 'ame_li_job_level_handler',
469                                     routineNameIn => 'handler',
470                                     exceptionNumberIn => errorCode,
471                                     exceptionStringIn => errorMessage);
472           raise_application_error(errorCode,
473                                   errorMessage);
474         when others then
475           ame_util.runtimeException(packageNameIn => 'ame_li_job_level_handler',
476                                     routineNameIn => 'handler',
477                                     exceptionNumberIn => sqlcode,
478                                     exceptionStringIn => sqlerrm);
479           l_error_code := sqlcode;
480           if l_error_code = -20213 then
481             errorMessage := ame_util.getMessage(applicationShortNameIn =>'PER',
482                                               messageNameIn => 'AME_400834_INV_HANDLR_APR',
483                                               tokenNameOneIn  => 'ACTION_TYPE_NAME',
484                                               tokenValueOneIn => ame_engine.getActionTypeName(tempApprover.action_type_id),
485                                               tokenNameTwoIn => 'ORIG_SYSTEM',
486                                               tokenValueTwoIn => ame_util.perOrigSystem,
487                                               tokenNameThreeIn => 'ORIG_SYSEM_ID',
488                                               tokenValueThreeIn => tempApprover.orig_system_id);
489            raise_application_error(errorCode,errorMessage);
490           end if;
491           raise;
492     end handler;
493   procedure parseAndSortRules  as
494     badParameterException exception;
495     errorCode integer;
496     errorMessage ame_util.longestStringType;
497     tempCategory ame_util.charType;
498     tempIndex integer;
499     tempLength integer;
500     tempNumber integer;
501     tempRuleId integer;
502     tempSign ame_util.charType;
503     upperLimit integer;
504     i   integer;
505     j integer;
506     begin
507       /* Parse. */
508       tempIndex := 0;
509       parameterNumbers.delete;
510       parameterSigns.delete;
511       for i in 1 .. parametersCount  loop
512         tempIndex := tempIndex + 1;
513         tempLength := lengthb(parameters(i));
514         parameterNumbers(tempIndex) := to_number(substrb(parameters(i),1,tempLength- 1));
515         parameterSigns(tempIndex) := substrb(parameters(i), -1, 1);
516         if(parameterSigns(tempIndex) <> '+' and
517            parameterSigns(tempIndex) <> '-') then
518           raise badParameterException;
519         end if;
520       end loop;
521       /* Sort. */
522       for i in 2 .. tempIndex loop
523         upperLimit := i - 1;
524         for j in 1 .. upperLimit loop
525           if(parameterNumbers(i) < parameterNumbers(j) or
526              (parameterNumbers(i) = parameterNumbers(j) and
527               parameterSigns(i) = '-' and parameterSigns(j) = '+')) then
528             tempRuleId := ruleIds(j);
529             tempCategory := approverCategories(j);
530             tempNumber := parameterNumbers(j);
531             tempSign := parameterSigns(j);
532             ruleIds(j) := ruleIds(i);
533             approverCategories(j) := approverCategories(i);
534             parameterNumbers(j) := parameterNumbers(i);
535             parameterSigns(j) := parameterSigns(i);
536             ruleIds(i) := tempRuleId;
537             approverCategories(i) := tempCategory;
538             parameterNumbers(i) := tempNumber;
539             parameterSigns(i) := tempSign;
540           end if;
541         end loop;
542       end loop;
543       exception
544         when badParameterException then
545           errorCode := -20001;
546           errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
547                                               messageNameIn => 'AME_400234_HAN_ACT_PAR_SIGN');
548           ame_util.runtimeException(packageNameIn => 'ame_li_job_level_handler',
549                                     routineNameIn => 'parseAndSortRules',
550                                     exceptionNumberIn => errorCode,
551                                     exceptionStringIn => errorMessage);
552           raise_application_error(errorCode,
553                                   errorMessage);
554         when others then
555           ame_util.runtimeException(packageNameIn => 'ame_li_job_level_handler',
556                                     routineNameIn => 'parseAndSortRules',
557                                     exceptionNumberIn => sqlcode,
558                                     exceptionStringIn => sqlerrm);
559           raise;
560     end parseAndSortRules;
561 end ame_li_job_level_handler;