[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;