DBA Data[Home] [Help]

PACKAGE BODY: APPS.AME_POSITION_HANDLER

Source


1 package body ame_position_handler as
2 /* $Header: ameepoha.pkb 120.9 2011/05/17 11:40:51 nchinnam ship $ */
3  /* package variables */
4   approverCategories  ame_util.charList;
5   parameterIds        ame_util.idList;
6   parametersCount     integer;
7   parameters          ame_util.stringList;
8   ruleIds             ame_util.idList;
9   ruleSatisfiedYN     ame_util.charList;
10   isRequestor         boolean;
11   /* forward declarations */
12   procedure getParameterIds;
13   /*  Procedures */
14   /*
15     getCatSourceAndAuthority does not account for the ALLOW_REQUESTOR_APPROVAL attribute.
16     The handler procedure does that.
17   */
18   procedure getCatSourceAndAuthority(positionIdIn           in  integer,
19                                      categoryOut            out nocopy varchar2,
20                                      sourceOut              out nocopy varchar2,
21                                      hasFinalAuthorityYNOut out nocopy varchar2) as
22     category ame_util.charType;
23     hasFinalAuthorityYN ame_util.charType;
24     source ame_util.longStringType;
25     tempRuleRequiresApprover boolean;
26     tempRuleSatisfied boolean;
27     tempApprover1 ame_util.approverRecord2;
28     tempApprover2 ame_util.approverRecord2;
29     begin
30       /*
31         1.  An approver satisfies a rule when the rule's parameter number equals to
32             the approver's orig_system_id.
33         2.  An approver has final authority if the approver satisfies all the rules.
34         3.  The source value is a comma-delimited list of the IDs of the rules that
35             require an approver.  This procedure builds up the source value according
36             to the following logic:
37             A.  If a rule has not yet been satisfied, the rule requires the input
38                 approver.
39         4.  An approver's category is ame_util.approvalApproverCategory if any of the
40             rule usages requiring the approver is of that category; otherwise the
41             approver's category is ame_util.fyiApproverCategory.
42       */
43       category            := ame_util.fyiApproverCategory;
44       hasFinalAuthorityYN := ame_util.booleanTrue;
45       for i in 1 .. parametersCount loop
46         /* if the rule is satisfied already no need to process again. */
47         if(ruleSatisfiedYN(i) = ame_util.booleanFalse) then
48           --
49           -- Determine whether the approver satisfies the current rule.
50           --
51           tempRuleSatisfied := false;
52           tempApprover1.orig_system := 'POS';
53           tempApprover1.orig_system_id := positionIdIn;
54           tempApprover2.orig_system := 'POS';
55           tempApprover2.orig_system_id := parameterIds(i);
56           if(positionIdIn = parameterIds(i) or
57                (isRequestor and ame_approver_type_pkg.isASubordinate
58                                    (approverIn => tempApprover1,
59                                     possibleSubordApproverIn => tempApprover2))) then
60             tempRuleSatisfied := true;
61           end if;
62           --
63           -- Update hasFinalAuthorityYN as needed.
64           --
65           if(not tempRuleSatisfied and
66              hasFinalAuthorityYN = ame_util.booleanTrue) then
67             hasFinalAuthorityYN := ame_util.booleanFalse;
68           end if;
69           --
70           -- Mark the rule as satisfied as needed.
71           --
72           if(tempRuleSatisfied) then
73             ruleSatisfiedYN(i) := ame_util.booleanTrue;
74           end if;
75           --
76           -- Update source.
77           --
78           ame_util.appendRuleIdToSource(ruleIdIn => ruleIds(i),
79                                         sourceInOut => source);
80           --
81           -- Update category as needed.
82           --
83           if(category = ame_util.fyiApproverCategory and
84              approverCategories(i) = ame_util.approvalApproverCategory) then
85             category := ame_util.approvalApproverCategory;
86           end if;
87         end if;
88       end loop;
89       categoryOut            := category;
90       hasFinalAuthorityYNOut := hasFinalAuthorityYN;
91       sourceOut              := source;
92       exception
93         when others then
94           categoryOut            := null;
95           hasFinalAuthorityYNOut := null;
96           sourceOut              := null;
97           ame_util.runtimeException(packageNameIn     => 'ame_position_handler',
98                                     routineNameIn     => 'getCatSourceAndAuthority',
99                                     exceptionNumberIn => sqlcode,
100                                     exceptionStringIn => sqlerrm);
101           raise;
102     end getCatSourceAndAuthority;
103   procedure handler as
104     COAInsertee ame_util.approverRecord2;
105     errorCode integer;
106     errorMessage ame_util.longestStringType;
107     finalAuthorityFound boolean;
108     nullFirstIdException exception;
109     requestorId     integer;
110     startingPointId integer;
111     tempApprover ame_util.approverRecord2;
112     tempHasFinalAuthorityYN ame_util.charType;
113     tempMemberOrderNumber integer;
114     votingRegimeType ame_util.stringType;
115     firstApproverSource ame_util.longStringType;
116     firstAuthInsExists boolean := false;
117     coaInsAuthForward boolean := false;
118     l_error_code number;
119     begin
120       /*
121         The engine only calls a handler if a rule requiring it exists, so we can assume that
122         the package variables that ame_engine.getHandlerRules2 initializes are nonempty.
123         Fetch the rules and sort them in increasing parameter order. (Duplicate parameters
124         are harmless here.)
125       */
126       errorCode := -20242;
127       ame_engine.getHandlerRules2(ruleIdsOut            => ruleIds,
128                                   approverCategoriesOut => approverCategories,
129                                   parametersOut         => parameters);
130       /* Populate some of the package variables. */
131       parametersCount := parameters.count;
132       getParameterIds;
133       for i in 1 .. ruleIds.count loop
134         ruleSatisfiedYN(i) := ame_util.booleanFalse;
135       end loop;
136       /* Set the fields in tempApprover that are constant for the entire handler cycle. */
137       tempApprover.orig_system       := ame_util.posOrigSystem;
138       tempApprover.authority         := ame_util.authorityApprover;
139       tempApprover.action_type_id    := ame_engine.getHandlerActionTypeId;
140       tempApprover.item_class        := ame_engine.getHandlerItemClassName;
141       tempApprover.item_id           := ame_engine.getHandlerItemId;
142       tempApprover.group_or_chain_id := 1;
143       --
144       tempApprover.item_class_order_number     := ame_engine.getHandlerItemClassOrderNumber;
145       tempApprover.item_order_number           := ame_engine.getHandlerItemOrderNumber;
146       tempApprover.sub_list_order_number       := ame_engine.getHandlerSublistOrderNum;
147       tempApprover.action_type_order_number    := ame_engine.getHandlerActionTypeOrderNum;
148       tempApprover.group_or_chain_order_number := 1;
149       /* Fetch some of the required attributes. */
150       votingRegimeType := ame_engine.getActionTypeVotingRegime(actionTypeIdIn => tempApprover.action_type_id);
151       /* Check for COA Insertions */
152       ame_engine.getHandlerCOAFirstApprover(itemClassIn => tempApprover.item_class,
153                                             itemIdIn => tempApprover.item_id,
154                                             actionTypeIdIn => tempApprover.action_type_id,
155                                             groupOrChainIdIn => tempApprover.group_or_chain_id,
156                                             nameOut => COAInsertee.name,
157                                             origSystemOut => COAInsertee.orig_system,
158                                             origSystemIdOut => COAInsertee.orig_system_id,
159                                             displayNameOut => COAInsertee.display_name,
160                                             sourceOut => COAInsertee.source);
161       /* Start building the chain from the COA Insertee if defined otherwise from the
162          non-default starting point or the requestor's supervisor.  */
163       isRequestor := true;
164       if COAInsertee.name is  null then
165         /* Fetch some of the required attributes. */
166         startingPointId :=
167            to_number(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.nonDefStartingPointPosAttr));
168         if(startingPointId is null) then
169           requestorId :=
170             to_number(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.transactionReqPositionAttr));
171           if (requestorId is null) then
172             raise nullFirstIdException;
173           end if;
174           tempApprover.orig_system_id := requestorId;
175           /* Check if requestor can self approve. If so, insert the approver as the
176              only approver, with a status of approved, and return.*/
177           if(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.allowAutoApprovalAttribute)
178                  = ame_util.booleanAttributeTrue)
179             then
180             getCatSourceAndAuthority(positionIdIn           => requestorId,
181                                  categoryOut            => tempApprover.approver_category,
182                                  sourceOut              => tempApprover.source,
183                                  hasFinalAuthorityYNOut => tempHasFinalAuthorityYN);
184             if(tempHasFinalAuthorityYN = ame_util.booleanTrue) then
185               tempApprover.api_insertion := ame_util.oamGenerated;
186               ame_approver_type_pkg.getWfRolesNameAndDisplayName(
187                                  origSystemIn   => ame_util.posOrigSystem,
188                                  origSystemIdIn => requestorId,
189                                  nameOut        => tempApprover.name,
190                                  displayNameOut => tempApprover.display_name);
191               tempApprover.occurrence := ame_engine.getHandlerOccurrence(
192                                        nameIn =>  tempApprover.name,
193                                        itemClassIn => tempApprover.item_class,
194                                        itemIdIn => tempApprover.item_id,
195                                        actionTypeIdIn => tempApprover.action_type_id,
196                                        groupOrChainIdIn => tempApprover.group_or_chain_id);
197               tempApprover.member_order_number := 1;
198               tempApprover.approval_status     := ame_util.approvedStatus;
199               ame_engine.addApprover(approverIn => tempApprover);
200               return;
201             end if;
202             isRequestor := false;
203           end if;
204           /* The requestor could not self-approve, either because there was a non-default
205           starting point, or because the requestor lacked sufficient authority.  So,
206           start building the chain from the non-default starting point or the requestor's
207           parent position.  */
208           tempApprover.orig_system_id := ame_position_level_handler.getNextPosition(positionIdIn => requestorId);
209         else
210           tempApprover.orig_system_id := startingPointId;
211         end if;
212         tempApprover.api_insertion := ame_util.oamGenerated;
213         ame_approver_type_pkg.getWfRolesNameAndDisplayName(origSystemIn   => ame_util.posOrigSystem,
214                                                            origSystemIdIn => tempApprover.orig_system_id,
215                                                            nameOut        => tempApprover.name,
216                                                            displayNameOut => tempApprover.display_name);
217       else
218         tempApprover.name := COAInsertee.name;
219         tempApprover.orig_system := COAInsertee.orig_system;
220         tempApprover.orig_system_id := COAInsertee.orig_system_id;
221         tempApprover.display_name :=  COAInsertee.display_name;
222         firstApproverSource := COAInsertee.source;
223         tempApprover.api_insertion := ame_util.apiAuthorityInsertion;
224         firstAuthInsExists := true;
225       end if;
226       /* Build the chain. */
227       tempMemberOrderNumber := 0; /* pre-increment */
228       errorCode := -20243;
229       loop
230         getCatSourceAndAuthority(positionIdIn           => tempApprover.orig_system_id,
231                                  categoryOut            => tempApprover.approver_category,
232                                  sourceOut              => tempApprover.source,
233                                  hasFinalAuthorityYNOut => tempHasFinalAuthorityYN);
234         isRequestor := false;
235         if firstApproverSource is not null then
236           tempApprover.source := firstApproverSource;
237           firstApproverSource := null;
238         end if;
239         tempApprover.occurrence := ame_engine.getHandlerOccurrence(
240                                        nameIn =>  tempApprover.name,
241                                        itemClassIn => tempApprover.item_class,
242                                        itemIdIn => tempApprover.item_id,
243                                        actionTypeIdIn => tempApprover.action_type_id,
244                                        groupOrChainIdIn => tempApprover.group_or_chain_id);
245         tempMemberOrderNumber      := tempMemberOrderNumber + 1;
246         if(votingRegimeType = ame_util.serializedVoting) then
247           tempApprover.member_order_number := tempMemberOrderNumber;
248         else /* votingRegimeType in (ame_util.consensusVoting, ame_util.firstApproverVoting) */
249           tempApprover.member_order_number := 1;
250         end if;
251         tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn => tempApprover);
252         /* The engine will set tempApprover.approver_order_number; leave it null here. */
253         ame_engine.addApprover(approverIn => tempApprover);
254         /* check to see if there is a COA insertion after this approver. If a COA insertion is
255            found, keep checking till no more COA insertions. The check for final authority
256            will need to be done again.  */
257         loop
258           /* Initialize COAInsertee approverRecord2 */
259           COAInsertee := ame_util.emptyApproverRecord2;
260           /* Check if there are any COAInsertions */
261           ame_engine.getHandlerCOAInsertion(nameIn => tempApprover.name,
262                                             itemClassIn => tempApprover.item_class,
263                                             itemIdIn => tempApprover.item_id,
264                                             actionTypeIdIn => tempApprover.action_type_id,
265                                             groupOrChainIdIn => tempApprover.group_or_chain_id,
266                                             occurrenceIn => tempApprover.occurrence,
267                                             approvalStatusIn => tempApprover.approval_status,
268                                             nameOut => COAInsertee.name,
269                                             origSystemOut => COAInsertee.orig_system,
270                                             origSystemIdOut => COAInsertee.orig_system_id,
271                                             displayNameOut => COAInsertee.display_name,
272                                             sourceOut => COAInsertee.source);
273           if COAInsertee.name is null then
274             exit;
275           else
276             coaInsAuthForward := true;
277             tempApprover.name := COAInsertee.name;
278             tempApprover.orig_system := COAInsertee.orig_system;
279             tempApprover.orig_system_id := COAInsertee.orig_system_id;
280             tempApprover.display_name :=  COAInsertee.display_name;
281             getCatSourceAndAuthority(positionIdIn           => tempApprover.orig_system_id,
282                                  categoryOut            => tempApprover.approver_category,
283                                  sourceOut              => tempApprover.source,
284                                  hasFinalAuthorityYNOut => tempHasFinalAuthorityYN);
285             tempApprover.source := COAInsertee.source;
286             tempApprover.api_insertion := ame_util.apiAuthorityInsertion;
287             tempMemberOrderNumber := tempMemberOrderNumber + 1;
288             if(votingRegimeType = ame_util.serializedVoting) then
289               tempApprover.member_order_number := tempMemberOrderNumber;
290             else /* votingRegimeType in (ame_util.consensusVoting, ame_util.firstApproverVoting) */
291               tempApprover.member_order_number := 1;
292             end if;
293             tempApprover.occurrence := ame_engine.getHandlerOccurrence(nameIn =>  tempApprover.name,
294                                               itemClassIn => tempApprover.item_class,
295                                               itemIdIn => tempApprover.item_id,
296                                               actionTypeIdIn => tempApprover.action_type_id,
297                                               groupOrChainIdIn => tempApprover.group_or_chain_id);
298             tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn =>
299 tempApprover);
300             /* If approver has a status of ame_util.approve or ame_util.approveAndForwardStatus or
301                ame_util.nullStatus check to see if approver could have final authority */
302             if tempApprover.approval_status in (ame_util.approvedStatus, ame_util.approveAndForwardStatus,
303                                                 ame_util.nullStatus)
304               then
305               if(not finalAuthorityFound and
306                 tempHasFinalAuthorityYN = ame_util.booleanTrue) then
307                 finalAuthorityFound := true;
308               end if;
309             end if;
310             ame_engine.addApprover(approverIn => tempApprover);
311           end if;
312         end loop;
313         /* Decide whether to end the chain. */
314         if(tempHasFinalAuthorityYN  = ame_util.booleanTrue ) then
315           exit;
316         end if;
317         tempApprover.orig_system_id := ame_position_level_handler.getNextPosition(positionIdIn =>tempApprover.orig_system_id );
318         ame_approver_type_pkg.getWfRolesNameAndDisplayName(origSystemIn   => ame_util.posOrigSystem,
319                                                            origSystemIdIn => tempApprover.orig_system_id,
320                                                            nameOut        => tempApprover.name,
321                                                            displayNameOut => tempApprover.display_name);
322         if firstAuthInsExists then
323           ame_engine.setDeviationReasonDate(ame_approver_deviation_pkg.firstauthHandlerInsReason,null);
324         end if;
325         if coaInsAuthForward then
326           ame_engine.setDeviationReasonDate(ame_approver_deviation_pkg.forwarHandlerAuthInsReason,null);
327         end if;
328         tempApprover.api_insertion := ame_util.oamGenerated;
329       end loop;
330       exception
331         when nullFirstIdException then
332           errorCode := -20107;
333           errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
334                                               messageNameIn          => 'AME_400408_HAN_NO_TRANS_POS_ID');
335           ame_util.runtimeException(packageNameIn     => 'ame_position_handler',
336                                     routineNameIn     => 'handler',
337                                     exceptionNumberIn => errorCode,
338                                     exceptionStringIn => errorMessage);
339           raise_application_error(errorCode,
340                                   errorMessage);
341         when others then
342           ame_util.runtimeException(packageNameIn     => 'ame_position_handler',
343                                     routineNameIn     => 'handler',
344                                     exceptionNumberIn => sqlcode,
345                                     exceptionStringIn => sqlerrm);
346           l_error_code := sqlcode;
347           if l_error_code = -20213 then
348             errorMessage := ame_util.getMessage(applicationShortNameIn =>'PER',
349                                               messageNameIn => 'AME_400834_INV_HANDLR_APR',
350                                               tokenNameOneIn  => 'ACTION_TYPE_NAME',
351                                               tokenValueOneIn => ame_engine.getActionTypeName(tempApprover.action_type_id),
352                                               tokenNameTwoIn => 'ORIG_SYSTEM',
353                                               tokenValueTwoIn => ame_util.posOrigSystem,
354                                               tokenNameThreeIn => 'ORIG_SYSEM_ID',
355                                               tokenValueThreeIn => tempApprover.orig_system_id);
356            raise_application_error(errorCode,errorMessage);
357           end if;
358           raise;
359     end handler;
360   procedure getParameterIds as
361     errorCode integer;
362     begin
363       for i in 1..parametersCount loop
364         parameterIds(i) :=
365          ame_approver_type_pkg.getApproverOrigSystemId(nameIn => parameters(i));
366       end loop;
367       exception
368         when no_data_found then
369           errorCode := -20001;
370           ame_util.runtimeException(packageNameIn     => 'ame_position_handler',
371                                     routineNameIn     => 'getParameterIds',
372                                     exceptionNumberIn => errorCode,
373                                     exceptionStringIn => sqlerrm);
374           raise_application_error(errorCode,
375                                   sqlerrm);
376         when others then
377           ame_util.runtimeException(packageNameIn     => 'ame_position_handler',
378                                     routineNameIn     => 'getParameterIds',
379                                     exceptionNumberIn => sqlcode,
380                                     exceptionStringIn => sqlerrm);
381           raise;
382     end getParameterIds;
383  end ame_position_handler;