DBA Data[Home] [Help]

PACKAGE BODY: APPS.AME_RELATIVE_JOB_LEVEL_HANDLER

Source


1 package body ame_relative_job_level_handler as
2 /* $Header: ameerjha.pkb 120.3 2007/12/20 20:04:11 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 a comma-delimited list of the IDs of the rules that
66             require an approver.  This procedure builds up the source value according
67             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 .. parametersCount loop
81         /* Determine whether the approver satisfies the current rule. */
82         if(personIdIn = topDogPersonId) then
83           topDogFound := true;
84           tempRuleSatisfied := true;
85         else
86           topDogFound := false;
87           tempRuleSatisfied := false;
88           if(jobLevelIn >= parameterNumbers(i)) then
89             tempRuleSatisfied := true;
90           elsif(parameterSigns(i) = '-') then
91             if supervisorIdIn is null then
92               supervisorJobLevel := 0;
93             else
94               if(supervisorJobLevel is null) then
95                 if(supervisorIdIn is null) then
96                   raise noSupervisorException;
97                 end if;
98                 ame_absolute_job_level_handler.getJobLevelAndSupervisor(personIdIn => supervisorIdIn,
99                                          jobLevelOut => supervisorJobLevel,
100                                          supervisorIdOut => nextSupervisorIdOut);
101                 supervisorJobLevelOut := supervisorJobLevel;
102               end if;
103               if(supervisorJobLevel > parameterNumbers(i)) then
104                 tempRuleSatisfied := true;
105               end if;
106             end if;
107           end if;
108         end if;
109         /* Update hasFinalAuthorityYN as needed. */
110         if(not tempRuleSatisfied and
111            hasFinalAuthorityYN = ame_util.booleanTrue) then
112           hasFinalAuthorityYN := ame_util.booleanFalse;
113         end if;
114         /* Determine whether the current rule requires the approver. */
115         tempRuleRequiresApprover := false;
116         if(ruleSatisfiedYN(i) = ame_util.booleanTrue) then
117           if(not tempRuleSatisfied) then
118             tempRuleRequiresApprover := true;
119           end if;
120         else
121           tempRuleRequiresApprover := true;
122           if(tempRuleSatisfied) then
123             ruleSatisfiedYN(i) := ame_util.booleanTrue;
124           end if;
125         end if;
126         if(tempRuleRequiresApprover) then
127           /* Update source. */
128           ame_util.appendRuleIdToSource(ruleIdIn => ruleIds(i),
129                                         sourceInOut => source);
130           /* Update category as needed. */
131           if(category = ame_util.fyiApproverCategory and
132              approverCategories(i) = ame_util.approvalApproverCategory) then
133             category := ame_util.approvalApproverCategory;
134           end if;
135         end if;
136       end loop;
137       categoryOut := category;
138       hasFinalAuthorityYNOut := hasFinalAuthorityYN;
139       sourceOut := source;
140       exception
141          when noSupervisorException then
142            personDisplayName := ame_approver_type_pkg.getApproverDisplayName2(
143                                       origSystemIn => ame_util.perOrigSystem,
144                                       origSystemIdIn => personIdIn );
145            errorCode := -20001;
146            errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
147              messageNameIn     => 'AME_400297_HAN_LACK_SPVR',
148              tokenNameOneIn    => 'FIRST_NAME',
149              tokenValueOneIn   => personDisplayName,
150              tokenNameTwoIn    => 'LAST_NAME',
151              tokenValueTwoIn   => null ,
152              tokenNameThreeIn  => 'OTHER_NAME',
153              tokenValueThreeIn =>  null );
154           ame_util.runtimeException(packageNameIn => 'ame_relative_job_level_handler',
155                                     routineNameIn => 'getCatSourceAndAuthority',
156                                     exceptionNumberIn => errorCode,
157                                     exceptionStringIn => errorMessage);
158           raise_application_error(errorCode,
159                                   errorMessage);
160         when others then
161           categoryOut := null;
162           hasFinalAuthorityYNOut := null;
163           sourceOut := null;
164           ame_util.runtimeException(packageNameIn => 'ame_relative_job_level_handler',
165                                     routineNameIn => 'getCatSourceAndAuthority',
166                                     exceptionNumberIn => sqlcode,
167                                     exceptionStringIn => sqlerrm);
168           raise;
169     end getCatSourceAndAuthority;
170   procedure handler as
171     COAInsertee ame_util.approverRecord2;
172     errorCode integer;
173     errorMessage ame_util.longestStringType;
174     finalAuthorityApproverCategory ame_util.charType;
175     finalAuthorityFound boolean;
176     finalAuthoritySource ame_util.longStringType;
177     firstApproverSource ame_util.longStringType;
178     includeAllJobLevelApprovers boolean;
179     personDisplayName ame_util.longStringType;
180     noSupervisorException exception;
181     nullFirstIdException exception;
182     requestorId integer;
183     startingPointId integer;
184     tempApprover ame_util.approverRecord2;
185     tempHasFinalAuthorityYN ame_util.charType;
186     tempJobLevel integer;
187     tempMemberOrderNumber integer;
188     tempOldJobLevel integer;
189     tempSupervisorId integer;
190     tempSupervisorJobLevel integer;
191     tempNextSupervisorId integer;
192     topDogRequestorException exception;
193     votingRegimeType ame_util.stringType;
194     firstAuthInsExists boolean := false;
195     coaInsAuthForward boolean := false;
196     begin
197       finalAuthorityApproverCategory := null;
198       finalAuthoritySource := null;
199       includeAllJobLevelApprovers :=
200         ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.includeAllApproversAttribute) =
201         ame_util.booleanAttributeTrue;
202       /* Populate some of the package variables. */
203       topDogPersonId := to_number(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.topSupPersonIdAttribute));
204       /*
205         The engine only calls a handler if a rule requiring it exists, so we can assume that
206         the package variables that ame_engine.getHandlerRules initializes are nonempty.
207         Fetch the rules and sort them in increasing parameter order.  (Duplicate parameters
208         are harmless here.)
209       */
210       ame_engine.getHandlerRules2(ruleIdsOut => ruleIds,
211                                   approverCategoriesOut => approverCategories,
212                                   parametersOut => parameters);
213       /* Set the fields in tempApprover that are constant for the entire handler cycle. */
214       tempApprover.orig_system := ame_util.perOrigSystem;
215       tempApprover.authority := ame_util.authorityApprover;
216       tempApprover.action_type_id := ame_engine.getHandlerActionTypeId;
217       tempApprover.item_class := ame_engine.getHandlerItemClassName;
218       tempApprover.item_id := ame_engine.getHandlerItemId;
219       tempApprover.item_class_order_number := ame_engine.getHandlerItemClassOrderNumber;
220       tempApprover.item_order_number := ame_engine.getHandlerItemOrderNumber;
221       tempApprover.sub_list_order_number := ame_engine.getHandlerSublistOrderNum;
222       tempApprover.action_type_order_number := ame_engine.getHandlerActionTypeOrderNum;
223       tempApprover.group_or_chain_order_number := 1;
224       tempApprover.group_or_chain_id := 1;
225       votingRegimeType := ame_engine.getActionTypeVotingRegime(actionTypeIdIn => tempApprover.action_type_id);
226       /* Check for COA 'firstAuthority' insertions */
227       ame_engine.getHandlerCOAFirstApprover(itemClassIn => tempApprover.item_class,
228                                             itemIdIn => tempApprover.item_id,
229                                             actionTypeIdIn => tempApprover.action_type_id,
230                                             groupOrChainIdIn => tempApprover.group_or_chain_id,
231                                             nameOut => COAInsertee.name,
232                                             origSystemOut => COAInsertee.orig_system,
233                                             origSystemIdOut => COAInsertee.orig_system_id,
234                                             displayNameOut => COAInsertee.display_name,
235                                             sourceOut => COAInsertee.source);
236       if COAInsertee.name is  null then
237         /* Fetch some of the required attributes. */
238         startingPointId :=
239             to_number(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.jobLevelStartingPointAttribute));
240         if(startingPointId is null) then
241           requestorId :=
242             to_number(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.transactionRequestorAttribute));
243           if (requestorId is  null) then
244             raise nullFirstIdException;
245           end if;
246           tempApprover.orig_system_id := requestorId;
247         else
248           tempApprover.orig_system_id := startingPointId;
249           ame_approver_type_pkg.getWfRolesNameAndDisplayName(
250                                                 origSystemIn => ame_util.perOrigSystem,
251                                                 origSystemIdIn =>tempApprover.orig_system_id,
252                                                 nameOut => tempApprover.name,
253                                                 displayNameOut => tempApprover.display_name);
254         end if;
255         tempApprover.api_insertion := ame_util.oamGenerated;
256       else
257         tempApprover.name := COAInsertee.name;
258         tempApprover.orig_system := COAInsertee.orig_system;
259         tempApprover.orig_system_id := COAInsertee.orig_system_id;
260         tempApprover.display_name :=  COAInsertee.display_name;
261         firstApproverSource := COAInsertee.source;
262         tempApprover.api_insertion := ame_util.apiAuthorityInsertion;
263         firstAuthInsExists := true;
264       end if;
265       /* The threshhold Job level is the job level of this tempApprover */
266       ame_absolute_job_level_handler.getJobLevelAndSupervisor(personIdIn => tempApprover.orig_system_id,
267                                                               jobLevelOut => tempJobLevel,
268                                                               supervisorIdOut => tempSupervisorId);
269       threshholdJobLevel := tempJobLevel;
270       parametersCount := parameters.count;
271       parseAndSortRules;
272       for i in 1 .. ruleIds.count loop
273         ruleSatisfiedYN(i) := ame_util.booleanFalse;
274       end loop;
275       /* Self Approval is only an option for this handler if requestor is the top dog. So only need to check for it in that case.
276          But in case of no COAInsertion and no startingPointId, the chain must start from requestor's manager. This could
277          not be set above as the threshhold has to be the requestor's approval authority. */
278       if(COAInsertee.name is null and
279          startingPointId is null )
280         then
281         /* Check to make sure requestor is not the topDogPersonId, if yes check for autoapproval */
282         if (requestorId = topDogPersonId ) then
283             if(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.allowAutoApprovalAttribute)
284                  = ame_util.booleanAttributeTrue) then
285               /* insert the requestor into the chain set the requestor's status to approved
286                  end the chain with the requestor */
287               tempApprover.orig_system_id := requestorId;
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               tempApprover.occurrence := ame_engine.getHandlerOccurrence(
297                                                 nameIn =>  tempApprover.name,
298                                                 itemClassIn => tempApprover.item_class,
299                                                 itemIdIn => tempApprover.item_id,
300                                                 actionTypeIdIn => tempApprover.action_type_id,
301                                                 groupOrChainIdIn => tempApprover.group_or_chain_id);
302               tempApprover.member_order_number := 1;
303               tempApprover.api_insertion := ame_util.oamGenerated;
304               tempApprover.approval_status := ame_util.approvedStatus;
305               ame_approver_type_pkg.getWfRolesNameAndDisplayName(origSystemIn => ame_util.perOrigSystem,
306                                                            origSystemIdIn => tempApprover.orig_system_id,
307                                                            nameOut => tempApprover.name,
308                                                            displayNameOut => tempApprover.display_name);
309               ame_engine.addApprover(approverIn => tempApprover);
310               return;
311             else
312                raise topDogRequestorException;
313             end if;
314         elsif (tempSupervisorId is null) then
315             raise noSupervisorException;
316         else
317           tempApprover.orig_system_id := tempSupervisorId ;
318         end if;
319         ame_absolute_job_level_handler.getJobLevelAndSupervisor(personIdIn => tempApprover.orig_system_id,
320                                                                 jobLevelOut => tempJobLevel,
321                                                                 supervisorIdOut => tempSupervisorId);
322         ame_approver_type_pkg.getWfRolesNameAndDisplayName(
323                                                 origSystemIn => ame_util.perOrigSystem,
324                                                 origSystemIdIn =>tempApprover.orig_system_id,
325                                                 nameOut => tempApprover.name,
326                                                 displayNameOut => tempApprover.display_name);
327       end if;
328       /* Build the chain. */
329       finalAuthorityFound := false;
330       tempMemberOrderNumber := 0; /* pre-increment */
331       loop
332         getCatSourceAndAuthority(personIdIn => tempApprover.orig_system_id,
333                                  jobLevelIn => tempJobLevel,
334                                  supervisorIdIn => tempSupervisorId,
335                                  categoryOut => tempApprover.approver_category,
336                                  sourceOut => tempApprover.source,
337                                  hasFinalAuthorityYNOut => tempHasFinalAuthorityYN,
338                                  supervisorJobLevelOut => tempSupervisorJobLevel,
339                                  nextSupervisorIdOut => tempNextSupervisorId);
340         /* reassign the value of source in case approver was a firstAuthority insertee */
341         if firstApproverSource is not null then
342           tempApprover.source := firstApproverSource;
343           firstApproverSource := null;
344         end if;
345         if(not finalAuthorityFound and
346            tempHasFinalAuthorityYN = ame_util.booleanTrue) then
347           finalAuthorityFound := true;
348           finalAuthorityApproverCategory := tempApprover.approver_category;
349           finalAuthoritySource := tempApprover.source;
350         end if;
351         if (tempApprover.source is null and
352            finalAuthoritySource is not null ) then
353           tempApprover.approver_category := finalAuthorityApproverCategory;
354           tempApprover.source := finalAuthoritySource;
355         end if;
356         tempApprover.api_insertion := ame_util.oamGenerated;
357         tempApprover.occurrence := 1;
358         tempMemberOrderNumber := tempMemberOrderNumber + 1;
359         if(votingRegimeType = ame_util.serializedVoting) then
360           tempApprover.member_order_number := tempMemberOrderNumber;
361         else /* votingRegimeType in (ame_util.consensusVoting, ame_util.firstApproverVoting) */
362           tempApprover.member_order_number := 1;
363         end if;
364         tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn => tempApprover);
365         /* The engine will set tempApprover.approver_order_number; leave it null here. */
366         ame_engine.addApprover(approverIn => tempApprover);
367         /* check to see if there is a COA insertion after this approver. If a COA insertion is
368            found, keep checking till no more COA insertions. The check for final authority will need to be
369            done again.
370         */
371         loop
372           /* Initialize COAInsertee approverRecord2 */
373           COAInsertee := ame_util.emptyApproverRecord2;
374           /* Check if there are any COAInsertions */
375           ame_engine.getHandlerCOAInsertion(nameIn => tempApprover.name,
376                                             itemClassIn => tempApprover.item_class,
377                                             itemIdIn => tempApprover.item_id,
378                                             actionTypeIdIn => tempApprover.action_type_id,
379                                             groupOrChainIdIn => tempApprover.group_or_chain_id,
380                                             occurrenceIn => tempApprover.occurrence,
381                                             approvalStatusIn => tempApprover.approval_status,
382                                             nameOut => COAInsertee.name,
383                                             origSystemOut => COAInsertee.orig_system,
384                                             origSystemIdOut => COAInsertee.orig_system_id,
385                                             displayNameOut => COAInsertee.display_name,
386                                             sourceOut => COAInsertee.source);
387           if COAInsertee.name is null then
388             exit;
389           else
390             tempApprover.name := COAInsertee.name;
391             tempApprover.orig_system := COAInsertee.orig_system;
392             tempApprover.orig_system_id := COAInsertee.orig_system_id;
393             tempApprover.display_name :=  COAInsertee.display_name;
394             ame_absolute_job_level_handler.getJobLevelAndSupervisor(
395                                      personIdIn => tempApprover.orig_system_id,
396                                      jobLevelOut => tempJobLevel,
397                                      supervisorIdOut => tempSupervisorId);
398             coaInsAuthForward := true;
399             getCatSourceAndAuthority(personIdIn => tempApprover.orig_system_id,
400                                      jobLevelIn => tempJobLevel,
401                                      supervisorIdIn => tempSupervisorId,
402                                      categoryOut => tempApprover.approver_category,
403                                      sourceOut => tempApprover.source,
404                                      hasFinalAuthorityYNOut => tempHasFinalAuthorityYN,
405                                      supervisorJobLevelOut => tempSupervisorJobLevel,
406                                      nextSupervisorIdOut => tempNextSupervisorId);
407             tempApprover.source := COAInsertee.source;
408             tempApprover.approver_category := ame_util.approvalApproverCategory;
409             tempApprover.api_insertion := ame_util.apiAuthorityInsertion;
410             tempMemberOrderNumber := tempMemberOrderNumber + 1;
411             if(votingRegimeType = ame_util.serializedVoting) then
412               tempApprover.member_order_number := tempMemberOrderNumber;
413             else /* votingRegimeType in (ame_util.consensusVoting, ame_util.firstApproverVoting) */
414               tempApprover.member_order_number := 1;
415             end if;
416             tempApprover.occurrence := ame_engine.getHandlerOccurrence(nameIn =>  tempApprover.name,
417                                               itemClassIn => tempApprover.item_class,
418                                               itemIdIn => tempApprover.item_id,
419                                               actionTypeIdIn => tempApprover.action_type_id,
420                                               groupOrChainIdIn => tempApprover.group_or_chain_id);
421             tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn => tempApprover);
422             /* If approver has a status of ame_util.approve or ame_util.approveAndForwardStatus or
423                ame_util.nullStatus check to see if approver could have final authority */
424             if ((tempApprover.approval_status is null) or
425                 (tempApprover.approval_status in
426                         (ame_util.approvedStatus, ame_util.approveAndForwardStatus,
427                          ame_util.repeatedStatus, ame_util.suppressedStatus,
428                          ame_util.beatByFirstResponderStatus, ame_util.nullStatus)) or
429                 (tempApprover.approver_category = ame_util.approvalApproverCategory and
430                  tempApprover.approval_status = ame_util.notifiedStatus) )
431               then
432               if(not finalAuthorityFound and
433                 tempHasFinalAuthorityYN = ame_util.booleanTrue) then
434                 finalAuthorityFound := true;
435               end if;
436             end if;
437             ame_engine.addApprover(approverIn => tempApprover);
438           end if;
439         end loop;
440         /* Decide whether to end the chain. */
441         if(topDogFound or
442            (finalAuthorityFound and
443            not includeAllJobLevelApprovers)) then
444           exit;
445         end if;
446         /* Check to make sure tempSupervisorId is not null, else raise noSupervisorException */
447         if tempSupervisorId is null then
448           raise noSupervisorException;
449         else
450           tempApprover.orig_system_id := tempSupervisorId;
451         end if;
452         tempOldJobLevel := tempJobLevel;
453         if(tempSupervisorJobLevel is null) then
454           ame_absolute_job_level_handler.getJobLevelAndSupervisor(personIdIn => tempApprover.orig_system_id,
455                                    jobLevelOut => tempJobLevel,
456                                    supervisorIdOut => tempSupervisorId);
457         else
458           tempJobLevel := tempSupervisorJobLevel;
459           tempSupervisorId := tempNextSupervisorId;
460         end if;
461         /*
462           At this point finalAuthorityFound implies includeAllJobLevelApprovers, so the following if
463           doesn't need to check includeAllJobLevelApprovers.  But it's implicit in the if statement.
464         */
465         if(finalAuthorityFound and
466            tempOldJobLevel <> tempJobLevel) then
467           exit;
468         end if;
469         ame_approver_type_pkg.getWfRolesNameAndDisplayName(
470                                                 origSystemIn => ame_util.perOrigSystem,
471                                                 origSystemIdIn =>tempApprover.orig_system_id,
472                                                 nameOut => tempApprover.name,
473                                                 displayNameOut => tempApprover.display_name);
474         if firstAuthInsExists then
475           ame_engine.setDeviationReasonDate(ame_approver_deviation_pkg.firstauthHandlerInsReason,null);
476         end if;
477         if coaInsAuthForward then
478           ame_engine.setDeviationReasonDate(ame_approver_deviation_pkg.forwarHandlerAuthInsReason,null);
479         end if;
480       end loop;
481       exception
482         when noSupervisorException then
483           if tempApprover.display_name is null then
484             personDisplayName := ame_approver_type_pkg.getApproverDisplayName2(
485                                       origSystemIn => ame_util.perOrigSystem,
486                                       origSystemIdIn => tempApprover.orig_system_id );
487           else
488             personDisplayName := tempApprover.display_name;
489           end if;
490           errorCode := -20001;
491           errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
492             messageNameIn     => 'AME_400297_HAN_LACK_SPVR',
493             tokenNameOneIn    => 'FIRST_NAME',
494             tokenValueOneIn   => personDisplayName,
495             tokenNameTwoIn    => 'LAST_NAME',
496             tokenValueTwoIn   => null ,
497             tokenNameThreeIn  => 'OTHER_NAME',
498             tokenValueThreeIn =>  null );
499           ame_util.runtimeException(packageNameIn => 'ame_relative_job_level_handler',
500                                     routineNameIn => 'handler',
501                                     exceptionNumberIn => errorCode,
502                                     exceptionStringIn => errorMessage);
503           raise_application_error(errorCode,
504                                   errorMessage);
505         when nullFirstIdException then
506           errorCode := -20001;
507           errorMessage :=
508           ame_util.getMessage(applicationShortNameIn => 'PER',
509                               messageNameIn => 'AME_400233_HAN_NO_TRANS_PER_ID');
510           ame_util.runtimeException(packageNameIn => 'ame_relative_job_level_handler',
511                                     routineNameIn => 'handler',
512                                     exceptionNumberIn => errorCode,
513                                     exceptionStringIn => errorMessage);
514           raise_application_error(errorCode,
515                                   errorMessage);
516         when topDogRequestorException then
517           errorCode := -20001;
518           errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
519                                     messageNameIn => 'AME_400421_REQ_CANNOT_APPROVE');
520           ame_util.runtimeException(packageNameIn => 'ame_relative_job_level_handler',
521                                     routineNameIn => 'handler',
522                                     exceptionNumberIn => errorCode,
523                                     exceptionStringIn => errorMessage);
524           raise_application_error(errorCode,
525                                   errorMessage);
526         when others then
527           ame_util.runtimeException(packageNameIn => 'ame_relative_job_level_handler',
528                                     routineNameIn => 'handler',
529                                     exceptionNumberIn => sqlcode,
530                                     exceptionStringIn => sqlerrm);
531           raise;
532     end handler;
533   procedure parseAndSortRules as
534     badParameterException exception;
535     errorCode integer;
536     errorMessage ame_util.longestStringType;
537     tempCategory ame_util.charType;
538     tempLength integer;
539     tempNumber integer;
540     tempRuleId integer;
541     tempSign ame_util.charType;
542     upperLimit integer;
543     begin
544       /* Parse. */
545       for i in 1 .. parametersCount loop
546         tempLength := lengthb(parameters(i));
547         parameterNumbers(i) := threshholdJobLevel + to_number(substrb(parameters(i), 1, tempLength - 1));
548         parameterSigns(i) := substrb(parameters(i), -1, 1);
549         if(parameterSigns(i) <> '+' and
550            parameterSigns(i) <> '-') then
551           raise badParameterException;
552         end if;
553       end loop;
554       /* Sort. */
555       for i in 2 .. parametersCount loop
556         upperLimit := i - 1;
557         for j in 1 .. upperLimit loop
558           if(parameterNumbers(i) < parameterNumbers(j) or
559              (parameterNumbers(i) = parameterNumbers(j) and
560               parameterSigns(i) = '-' and parameterSigns(j) = '+')) then
561             tempRuleId := ruleIds(j);
562             tempCategory := approverCategories(j);
563             tempNumber := parameterNumbers(j);
564             tempSign := parameterSigns(j);
565             ruleIds(j) := ruleIds(i);
566             approverCategories(j) := approverCategories(i);
567             parameterNumbers(j) := parameterNumbers(i);
568             parameterSigns(j) := parameterSigns(i);
569             ruleIds(i) := tempRuleId;
570             approverCategories(i) := tempCategory;
571             parameterNumbers(i) := tempNumber;
572             parameterSigns(i) := tempSign;
573           end if;
574         end loop;
575       end loop;
576       exception
577         when badParameterException then
578           errorCode := -20001;
579           errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
580                                               messageNameIn => 'AME_400234_HAN_ACT_PAR_SIGN');
581           ame_util.runtimeException(packageNameIn => 'ame_relative_job_level_handler',
582                                     routineNameIn => 'parseAndSortRules',
583                                     exceptionNumberIn => errorCode,
584                                     exceptionStringIn => errorMessage);
585           raise_application_error(errorCode,
586                                   errorMessage);
587         when others then
588           ame_util.runtimeException(packageNameIn => 'ame_relative_job_level_handler',
589                                     routineNameIn => 'parseAndSortRules',
590                                     exceptionNumberIn => sqlcode,
591                                     exceptionStringIn => sqlerrm);
592           raise;
593     end parseAndSortRules;
594 end ame_relative_job_level_handler;