DBA Data[Home] [Help]

PACKAGE BODY: APPS.AME_POSITION_HANDLER

Source


1 package body ame_position_handler as
2 /* $Header: ameepoha.pkb 120.5 2007/12/20 20:03:55 prasashe noship $ */
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     begin
119       /*
120         The engine only calls a handler if a rule requiring it exists, so we can assume that
121         the package variables that ame_engine.getHandlerRules2 initializes are nonempty.
122         Fetch the rules and sort them in increasing parameter order. (Duplicate parameters
123         are harmless here.)
124       */
125       ame_engine.getHandlerRules2(ruleIdsOut            => ruleIds,
126                                   approverCategoriesOut => approverCategories,
127                                   parametersOut         => parameters);
128       /* Populate some of the package variables. */
129       parametersCount := parameters.count;
130       getParameterIds;
131       for i in 1 .. ruleIds.count loop
132         ruleSatisfiedYN(i) := ame_util.booleanFalse;
133       end loop;
134       /* Set the fields in tempApprover that are constant for the entire handler cycle. */
135       tempApprover.orig_system       := ame_util.posOrigSystem;
136       tempApprover.authority         := ame_util.authorityApprover;
137       tempApprover.action_type_id    := ame_engine.getHandlerActionTypeId;
138       tempApprover.item_class        := ame_engine.getHandlerItemClassName;
139       tempApprover.item_id           := ame_engine.getHandlerItemId;
140       tempApprover.group_or_chain_id := 1;
141       --
142       tempApprover.item_class_order_number     := ame_engine.getHandlerItemClassOrderNumber;
143       tempApprover.item_order_number           := ame_engine.getHandlerItemOrderNumber;
144       tempApprover.sub_list_order_number       := ame_engine.getHandlerSublistOrderNum;
145       tempApprover.action_type_order_number    := ame_engine.getHandlerActionTypeOrderNum;
146       tempApprover.group_or_chain_order_number := 1;
147       /* Fetch some of the required attributes. */
148       votingRegimeType := ame_engine.getActionTypeVotingRegime(actionTypeIdIn => tempApprover.action_type_id);
149       /* Check for COA Insertions */
150       ame_engine.getHandlerCOAFirstApprover(itemClassIn => tempApprover.item_class,
151                                             itemIdIn => tempApprover.item_id,
152                                             actionTypeIdIn => tempApprover.action_type_id,
153                                             groupOrChainIdIn => tempApprover.group_or_chain_id,
154                                             nameOut => COAInsertee.name,
155                                             origSystemOut => COAInsertee.orig_system,
156                                             origSystemIdOut => COAInsertee.orig_system_id,
157                                             displayNameOut => COAInsertee.display_name,
158                                             sourceOut => COAInsertee.source);
159       /* Start building the chain from the COA Insertee if defined otherwise from the
160          non-default starting point or the requestor's supervisor.  */
161       isRequestor := true;
162       if COAInsertee.name is  null then
163         /* Fetch some of the required attributes. */
164         startingPointId :=
165            to_number(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.nonDefStartingPointPosAttr));
166         if(startingPointId is null) then
167           requestorId :=
168             to_number(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.transactionReqPositionAttr));
169           if (requestorId is null) then
170             raise nullFirstIdException;
171           end if;
172           tempApprover.orig_system_id := requestorId;
173           /* Check if requestor can self approve. If so, insert the approver as the
174              only approver, with a status of approved, and return.*/
175           if(ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.allowAutoApprovalAttribute)
176                  = ame_util.booleanAttributeTrue)
177             then
178             getCatSourceAndAuthority(positionIdIn           => requestorId,
179                                  categoryOut            => tempApprover.approver_category,
180                                  sourceOut              => tempApprover.source,
181                                  hasFinalAuthorityYNOut => tempHasFinalAuthorityYN);
182             if(tempHasFinalAuthorityYN = ame_util.booleanTrue) then
183               tempApprover.api_insertion := ame_util.oamGenerated;
184               ame_approver_type_pkg.getWfRolesNameAndDisplayName(
185                                  origSystemIn   => ame_util.posOrigSystem,
186                                  origSystemIdIn => requestorId,
187                                  nameOut        => tempApprover.name,
188                                  displayNameOut => tempApprover.display_name);
189               tempApprover.occurrence := ame_engine.getHandlerOccurrence(
190                                        nameIn =>  tempApprover.name,
191                                        itemClassIn => tempApprover.item_class,
192                                        itemIdIn => tempApprover.item_id,
193                                        actionTypeIdIn => tempApprover.action_type_id,
194                                        groupOrChainIdIn => tempApprover.group_or_chain_id);
195               tempApprover.member_order_number := 1;
196               tempApprover.approval_status     := ame_util.approvedStatus;
197               ame_engine.addApprover(approverIn => tempApprover);
198               return;
199             end if;
200             isRequestor := false;
201           end if;
202           /* The requestor could not self-approve, either because there was a non-default
203           starting point, or because the requestor lacked sufficient authority.  So,
204           start building the chain from the non-default starting point or the requestor's
205           parent position.  */
206           tempApprover.orig_system_id := ame_position_level_handler.getNextPosition(positionIdIn => requestorId);
207         else
208           tempApprover.orig_system_id := startingPointId;
209         end if;
210         tempApprover.api_insertion := ame_util.oamGenerated;
211         ame_approver_type_pkg.getWfRolesNameAndDisplayName(origSystemIn   => ame_util.posOrigSystem,
212                                                            origSystemIdIn => tempApprover.orig_system_id,
213                                                            nameOut        => tempApprover.name,
214                                                            displayNameOut => tempApprover.display_name);
215       else
216         tempApprover.name := COAInsertee.name;
217         tempApprover.orig_system := COAInsertee.orig_system;
218         tempApprover.orig_system_id := COAInsertee.orig_system_id;
219         tempApprover.display_name :=  COAInsertee.display_name;
220         firstApproverSource := COAInsertee.source;
221         tempApprover.api_insertion := ame_util.apiAuthorityInsertion;
222         firstAuthInsExists := true;
223       end if;
224       /* Build the chain. */
225       tempMemberOrderNumber := 0; /* pre-increment */
226       loop
227         getCatSourceAndAuthority(positionIdIn           => tempApprover.orig_system_id,
228                                  categoryOut            => tempApprover.approver_category,
229                                  sourceOut              => tempApprover.source,
230                                  hasFinalAuthorityYNOut => tempHasFinalAuthorityYN);
231         isRequestor := false;
232         if firstApproverSource is not null then
233           tempApprover.source := firstApproverSource;
234           firstApproverSource := null;
235         end if;
236         tempApprover.occurrence := ame_engine.getHandlerOccurrence(
237                                        nameIn =>  tempApprover.name,
238                                        itemClassIn => tempApprover.item_class,
239                                        itemIdIn => tempApprover.item_id,
240                                        actionTypeIdIn => tempApprover.action_type_id,
241                                        groupOrChainIdIn => tempApprover.group_or_chain_id);
242         tempMemberOrderNumber      := tempMemberOrderNumber + 1;
243         if(votingRegimeType = ame_util.serializedVoting) then
244           tempApprover.member_order_number := tempMemberOrderNumber;
245         else /* votingRegimeType in (ame_util.consensusVoting, ame_util.firstApproverVoting) */
246           tempApprover.member_order_number := 1;
247         end if;
248         tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn => tempApprover);
249         /* The engine will set tempApprover.approver_order_number; leave it null here. */
250         ame_engine.addApprover(approverIn => tempApprover);
251         /* check to see if there is a COA insertion after this approver. If a COA insertion is
252            found, keep checking till no more COA insertions. The check for final authority
253            will need to be done again.  */
254         loop
255           /* Initialize COAInsertee approverRecord2 */
256           COAInsertee := ame_util.emptyApproverRecord2;
257           /* Check if there are any COAInsertions */
258           ame_engine.getHandlerCOAInsertion(nameIn => tempApprover.name,
259                                             itemClassIn => tempApprover.item_class,
260                                             itemIdIn => tempApprover.item_id,
261                                             actionTypeIdIn => tempApprover.action_type_id,
262                                             groupOrChainIdIn => tempApprover.group_or_chain_id,
263                                             occurrenceIn => tempApprover.occurrence,
264                                             approvalStatusIn => tempApprover.approval_status,
265                                             nameOut => COAInsertee.name,
266                                             origSystemOut => COAInsertee.orig_system,
267                                             origSystemIdOut => COAInsertee.orig_system_id,
268                                             displayNameOut => COAInsertee.display_name,
269                                             sourceOut => COAInsertee.source);
270           if COAInsertee.name is null then
271             exit;
272           else
273             coaInsAuthForward := true;
274             tempApprover.name := COAInsertee.name;
275             tempApprover.orig_system := COAInsertee.orig_system;
276             tempApprover.orig_system_id := COAInsertee.orig_system_id;
277             tempApprover.display_name :=  COAInsertee.display_name;
278             getCatSourceAndAuthority(positionIdIn           => tempApprover.orig_system_id,
279                                  categoryOut            => tempApprover.approver_category,
280                                  sourceOut              => tempApprover.source,
281                                  hasFinalAuthorityYNOut => tempHasFinalAuthorityYN);
282             tempApprover.source := COAInsertee.source;
283             tempApprover.api_insertion := ame_util.apiAuthorityInsertion;
284             tempMemberOrderNumber := tempMemberOrderNumber + 1;
285             if(votingRegimeType = ame_util.serializedVoting) then
286               tempApprover.member_order_number := tempMemberOrderNumber;
287             else /* votingRegimeType in (ame_util.consensusVoting, ame_util.firstApproverVoting) */
288               tempApprover.member_order_number := 1;
289             end if;
290             tempApprover.occurrence := ame_engine.getHandlerOccurrence(nameIn =>  tempApprover.name,
291                                               itemClassIn => tempApprover.item_class,
292                                               itemIdIn => tempApprover.item_id,
293                                               actionTypeIdIn => tempApprover.action_type_id,
294                                               groupOrChainIdIn => tempApprover.group_or_chain_id);
295             tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn =>
296 tempApprover);
297             /* If approver has a status of ame_util.approve or ame_util.approveAndForwardStatus or
298                ame_util.nullStatus check to see if approver could have final authority */
299             if tempApprover.approval_status in (ame_util.approvedStatus, ame_util.approveAndForwardStatus,
300                                                 ame_util.nullStatus)
301               then
302               if(not finalAuthorityFound and
303                 tempHasFinalAuthorityYN = ame_util.booleanTrue) then
304                 finalAuthorityFound := true;
305               end if;
306             end if;
307             ame_engine.addApprover(approverIn => tempApprover);
308           end if;
309         end loop;
310         /* Decide whether to end the chain. */
311         if(tempHasFinalAuthorityYN  = ame_util.booleanTrue ) then
312           exit;
313         end if;
314         tempApprover.orig_system_id := ame_position_level_handler.getNextPosition(positionIdIn =>tempApprover.orig_system_id );
315         ame_approver_type_pkg.getWfRolesNameAndDisplayName(origSystemIn   => ame_util.posOrigSystem,
316                                                            origSystemIdIn => tempApprover.orig_system_id,
317                                                            nameOut        => tempApprover.name,
318                                                            displayNameOut => tempApprover.display_name);
319         if firstAuthInsExists then
320           ame_engine.setDeviationReasonDate(ame_approver_deviation_pkg.firstauthHandlerInsReason,null);
321         end if;
322         if coaInsAuthForward then
323           ame_engine.setDeviationReasonDate(ame_approver_deviation_pkg.forwarHandlerAuthInsReason,null);
324         end if;
325         tempApprover.api_insertion := ame_util.oamGenerated;
326       end loop;
327       exception
328         when nullFirstIdException then
329           errorCode := -20001;
330           errorMessage := ame_util.getMessage(applicationShortNameIn => 'PER',
331                                               messageNameIn          => 'AME_400408_HAN_NO_TRANS_POS_ID');
332           ame_util.runtimeException(packageNameIn     => 'ame_position_handler',
333                                     routineNameIn     => 'handler',
334                                     exceptionNumberIn => errorCode,
335                                     exceptionStringIn => errorMessage);
336           raise_application_error(errorCode,
337                                   errorMessage);
338         when others then
339           ame_util.runtimeException(packageNameIn     => 'ame_position_handler',
340                                     routineNameIn     => 'handler',
341                                     exceptionNumberIn => sqlcode,
342                                     exceptionStringIn => sqlerrm);
343           raise;
344     end handler;
345   procedure getParameterIds as
346     errorCode integer;
347     begin
348       for i in 1..parametersCount loop
349         parameterIds(i) :=
350          ame_approver_type_pkg.getApproverOrigSystemId(nameIn => parameters(i));
351       end loop;
352       exception
353         when no_data_found then
354           errorCode := -20001;
355           ame_util.runtimeException(packageNameIn     => 'ame_position_handler',
356                                     routineNameIn     => 'getParameterIds',
357                                     exceptionNumberIn => errorCode,
358                                     exceptionStringIn => sqlerrm);
359           raise_application_error(errorCode,
360                                   sqlerrm);
361         when others then
362           ame_util.runtimeException(packageNameIn     => 'ame_position_handler',
363                                     routineNameIn     => 'getParameterIds',
364                                     exceptionNumberIn => sqlcode,
365                                     exceptionStringIn => sqlerrm);
366           raise;
367     end getParameterIds;
368  end ame_position_handler;