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