DBA Data[Home] [Help]

PACKAGE BODY: APPS.AME_AG_CHAIN_HANDLER

Source


1 package body ame_ag_chain_handler as
2 /* $Header: ameegcha.pkb 120.4 2007/12/12 12:47:27 prasashe noship $ */
3  /* package variables */
4   approverCategories ame_util.charList;
5   groupIds ame_util.idList;
6   groupOrderNumbers ame_util.idList;
7   ruleIds ame_util.idList;
8   parameters ame_util.stringList;
9   parameterTwos ame_util.stringList;
10   sources ame_util.longStringList;
11   votingRegimes ame_util.charList;
12   /* forward declarations */
13   procedure eliminateDuplicates;
14    /*  Procedures */
15   procedure eliminateDuplicates as
16     begin
17       for i in 2 .. groupIds.count loop
18         if(groupIds(i) = groupIds(i - 1)) then
19           /*
20             Preserve the deleted rule's ID in the preserved rule's source field, if space permits.
21             In the very unlikely event otherwise, silently omit the extra source value(s).  (The
22             alternative would be to raise an exception that would require for its solution either
23             a code change or a change to the structure of the rules or transaction--none of which
24             would please the end user.)
25           */
26           if(lengthb(sources(i - 1)) + lengthb(sources(i)) + 1 <= ame_util.longStringTypeLength) then
27             sources(i) := sources(i) || ame_util.fieldDelimiter || sources(i - 1);
28           end if;
29           /* Make sure the dominant approver category is preserved. */
30           if(approverCategories(i) <> ame_util.approvalApproverCategory and
31              approverCategories(i - 1) = ame_util.approvalApproverCategory) then
32             approverCategories(i) := ame_util.approvalApproverCategory;
33           end if;
34           /* Delete the duplicate group. */
35           approverCategories.delete(i - 1);
36           groupIds.delete(i - 1);
37           groupOrderNumbers.delete(i - 1);
38           ruleIds.delete(i - 1);
39           parameters.delete(i - 1);
40           parameterTwos.delete(i - 1);
41           sources.delete(i - 1);
42           votingRegimes.delete(i - 1);
43         end if;
44       end loop;
45       exception
46         when others then
47           ame_util.runtimeException(packageNameIn => 'ame_ag_chain_handler',
48                                     routineNameIn => 'eliminateDuplicates',
49                                     exceptionNumberIn => sqlcode,
50                                     exceptionStringIn => sqlerrm);
51           raise;
52     end eliminateDuplicates;
53   procedure handler as
54     chainOrderMode ame_util.stringType;
55     COAInsertee ame_util.approverRecord2;
56     errorCode integer;
57     errorMessage ame_util.longestStringType;
58     finalAuthorityFound boolean;
59     groupOrderNumber integer;
60     nullFirstIdException exception;
61     requestorId integer;
62     startingPointId integer;
63     tempApprover ame_util.approverRecord2;
64     tempApproverNames ame_util.longStringList;
65     tempApproverOrderNumbers ame_util.idList;
66     tempApproverDisplayNames ame_util.longStringList;
67     tempOrigSystemIds ame_util.idList;
68     tempOrigSystems ame_util.stringList;
69     tempHasFinalAuthorityYN ame_util.charType;
70     tempIndex integer;
71     tempMemberOrderNumber integer := 1;
72     tempSupervisorId integer;
73     votingRegimeType ame_util.stringType;
74     allowEmptyGroups boolean;
75     currentApproverGrpMemberCount integer;
76     currentApproverGroupId integer;
77     emptyGroupException exception;
78     begin
79       /*
80         The engine only calls a handler if a rule requiring it exists, so we can assume that
81         the package variables that ame_engine.getHandlerRules initializes are nonempty.
82         Fetch the rules and sort them in increasing parameter order.  (Duplicate parameters
83         are harmless here.)
84       */
85       ame_engine.getHandlerRules(ruleIdsOut => ruleIds,
86                                  approverCategoriesOut => approverCategories,
87                                  parametersOut => parameters,
88                                  parameterTwosOut => parameterTwos);
89       /* Initialize the source list. */
90       for i in 1 .. ruleIds.count loop
91         sources(i) := to_char(ruleIds(i));
92       end loop;
93       /*
94         Convert the parameters to group IDs (integers), then fetch the groups' order numbers
95         and ordering modes.
96       */
97       ame_util.stringListToIdList(stringListIn => parameters,
98                                   idListOut => groupIds);
99       /* Bug:4491715 when get configs we sort group ids so corresponding sources and categories
100          must also be sorted */
101       ame_engine.getApprovalGroupConfigs(groupIdsInOut => groupIds,
102                                          sourcesInOut => sources,
103                                          approverCategoriesInOut => approverCategories,
104                                          orderNumbersOut => groupOrderNumbers,
105                                          votingRegimesOut => votingRegimes);
106       /* Eliminate duplicate group-ID entries, possibly leaving the package-variable lists sparse. */
107       eliminateDuplicates;
108       /* Find the transaction allows empty approval groups or not */
109       allowEmptyGroups :=
110          ame_engine.getHeaderAttValue2(attributeNameIn => ame_util.allowEmptyGroupAttribute)
111                        = ame_util.booleanAttributeTrue;
112       /* Set the fields in tempApprover that are constant for the entire handler cycle. */
113       tempApprover.orig_system := ame_util.perOrigSystem;
114       tempApprover.authority := ame_util.authorityApprover;
115       tempApprover.action_type_id := ame_engine.getHandlerActionTypeId;
116       tempApprover.group_or_chain_id := groupIds(groupIds.first);
117       tempApprover.api_insertion := ame_util.oamGenerated;
118       tempApprover.item_class := ame_engine.getHandlerItemClassName;
119       tempApprover.item_id := ame_engine.getHandlerItemId;
120       tempApprover.item_class_order_number := ame_engine.getHandlerItemClassOrderNumber;
121       tempApprover.item_order_number := ame_engine.getHandlerItemOrderNumber;
122       tempApprover.sub_list_order_number := ame_engine.getHandlerSublistOrderNum;
123       tempApprover.action_type_order_number := ame_engine.getHandlerActionTypeOrderNum;
124       votingRegimeType := ame_engine.getActionTypeVotingRegime(actionTypeIdIn => tempApprover.action_type_id);
125       chainOrderMode := ame_engine.getActionTypeChainOrderMode(actionTypeIdIn => tempApprover.action_type_id);
126       /* Check for COA First Authority Insertion */
127       ame_engine.getHandlerCOAFirstApprover(itemClassIn => tempApprover.item_class,
128                                             itemIdIn => tempApprover.item_id,
129                                             actionTypeIdIn => tempApprover.action_type_id,
130                                             groupOrChainIdIn => tempApprover.group_or_chain_id,
131                                             nameOut => COAInsertee.name,
132                                             origSystemOut => COAInsertee.orig_system,
133                                             origSystemIdOut => COAInsertee.orig_system_id,
134                                             displayNameOut => COAInsertee.display_name,
135                                             sourceOut => COAInsertee.source);
136       /* If COA Insertee exists add as first approver and then continue normal processing */
137       if COAInsertee.name is null then
138         tempApprover.api_insertion := ame_util.oamGenerated;
139         /* Bug fix 4468908 */
140         groupOrderNumber := 1;
141       else
142         /* Bug fix 4468908 */
143         groupOrderNumber := 2;
144         tempApprover.name := COAInsertee.name;
145         tempApprover.orig_system := COAInsertee.orig_system;
146         tempApprover.orig_system_id := COAInsertee.orig_system_id;
147         tempApprover.display_name :=  COAInsertee.display_name;
148         tempApprover.source := COAInsertee.source;
149         tempApprover.api_insertion := ame_util.apiAuthorityInsertion;
150         tempApprover.approver_category := ame_util.approvalApproverCategory;
151         tempApprover.group_or_chain_id := groupIds(groupIds.first);
152         tempApprover.occurrence := ame_engine.getHandlerOccurrence(nameIn=>tempApprover.name,
153                                                 itemClassIn => tempApprover.item_class,
154                                                 itemIdIn => tempApprover.item_id,
155                                                 actionTypeIdIn => tempApprover.action_type_id,
156                                                 groupOrChainIdIn => tempApprover.group_or_chain_id);
157         tempApprover.group_or_chain_order_number := 1;
158         tempApprover.member_order_number := 1;
159         tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn=>tempApprover);
160         /*
161           The engine will set tempApprover.approver_order_number; leave them null here.
162         */
163         ame_engine.addApprover(approverIn => tempApprover);
164       end if;
165       /*
166         Now iterate through the sorted groups, adding their membership to the engine's
167         approver list in the group-member order dictated by the group's voting regime
168         (and possibly its members' order numbers).
169       */
170       tempIndex := groupIds.first;
171       while(tempIndex is not null) loop
172         /* Clear the group-member buffers of any previous data. */
173         tempApproverNames.delete;
174         tempApproverOrderNumbers.delete;
175         tempApproverDisplayNames.delete;
176         tempOrigSystemIds.delete;
177         tempOrigSystems.delete;
178         /* Fetch the group's membership. */
179         ame_engine.getRuntimeGroupMembers(groupIdIn => groupIds(tempIndex),
180                                           approverNamesOut => tempApproverNames,
181                                           approverOrderNumbersOut => tempApproverOrderNumbers,
182                                           approverDisplayNamesOut => tempApproverDisplayNames,
183                                           origSystemIdsOut => tempOrigSystemIds,
184                                           origSystemsOut => tempOrigSystems);
185         currentApproverGrpMemberCount := tempApproverNames.count;
186         currentApproverGroupId := groupIds(tempIndex);
187         /* Throw error if the current group is empty and the transaction
188            doesnt accept empty groups */
189         if(not allowEmptyGroups and currentApproverGrpMemberCount = 0 ) then
190           raise emptyGroupException;
191         end if;
192         /* Add the group's members to the approver list. */
193         for j in 1 .. tempApproverNames.count loop
194           tempApprover.name := tempApproverNames(j);
195           tempApprover.orig_system := tempOrigSystems(j);
196           tempApprover.orig_system_id := tempOrigSystemIds(j);
197           tempApprover.display_name := tempApproverDisplayNames(j);
198           tempApprover.approver_category := approverCategories(tempIndex);
199           tempApprover.api_insertion := ame_util.oamGenerated;
200           tempApprover.group_or_chain_id := groupIds(tempIndex);
201           tempApprover.occurrence := ame_engine.getHandlerOccurrence(nameIn =>  tempApprover.name,
202                                                 itemClassIn => tempApprover.item_class,
203                                                 itemIdIn => tempApprover.item_id,
204                                                 actionTypeIdIn => tempApprover.action_type_id,
205                                                 groupOrChainIdIn => tempApprover.group_or_chain_id);
206           tempApprover.source := sources(tempIndex);
207           if (chainOrderMode = ame_util.serialChainsMode) then
208             tempApprover.group_or_chain_order_number := groupOrderNumber;
209           else /* chain Order Mode is parallel */
210             tempApprover.group_or_chain_order_number := 1;
211           end if;
212           if(votingRegimeType = ame_util.orderNumberVoting) then
213             tempApprover.member_order_number := tempApproverOrderNumbers(j);
214           elsif(votingRegimeType = ame_util.serializedVoting) then
215             tempApprover.member_order_number := tempMemberOrderNumber;
216           else /* votingRegimeType in (ame_util.consensusVoting, ame_util.firstApproverVoting) */
217             tempApprover.member_order_number := 1;
218           end if;
219           tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn  => tempApprover);
220           /*
221             The engine will set tempApprover.approver_order_number; leave them null here.
222           */
223           ame_engine.addApprover(approverIn => tempApprover);
224           /* Check if there is any COA Insertion after this approver. If a COA Insertee is
225              found keep checking till there are no more COA Insertee's */
226           loop
227             /* Initialize COAInsertee approver record 2 */
228             COAInsertee := ame_util.emptyApproverRecord2;
229             /* Check if there are any chain of authority insertions */
230             ame_engine.getHandlerCOAInsertion(nameIn => tempApprover.name,
231                                         itemClassIn => tempApprover.item_class,
232                                         itemIdIn => tempApprover.item_id,
233                                         actionTypeIdIn => tempApprover.action_type_id,
234                                         groupOrChainIdIn => tempApprover.group_or_chain_id,
235                                         occurrenceIn => tempApprover.occurrence,
236                                         approvalStatusIn => tempApprover.approval_status,
237                                         nameOut => COAInsertee.name,
238                                         origSystemOut => COAInsertee.orig_system,
239                                         origSystemIdOut => COAInsertee.orig_system_id,
240                                         displayNameOut => COAInsertee.display_name,
241                                         sourceOut => COAInsertee.source);
242             if COAInsertee.name is  null then
243               exit;
244             else
245               tempApprover.name := COAInsertee.name;
246               tempApprover.orig_system := COAInsertee.orig_system;
247               tempApprover.orig_system_id := COAInsertee.orig_system_id;
248               tempApprover.display_name :=  COAInsertee.display_name;
249               tempApprover.source := COAInsertee.source;
250               tempApprover.approver_category := ame_util.approvalApproverCategory;
251               tempApprover.api_insertion := ame_util.apiAuthorityInsertion;
252               tempApprover.group_or_chain_id := groupIds(tempIndex);
253               tempApprover.occurrence := ame_engine.getHandlerOccurrence(
254                                                 nameIn => tempApprover.name,
255                                                 itemClassIn => tempApprover.item_class,
256                                                 itemIdIn => tempApprover.item_id,
257                                                 actionTypeIdIn => tempApprover.action_type_id,
258                                                 groupOrChainIdIn => tempApprover.group_or_chain_id);
259               if (chainOrderMode = ame_util.serialChainsMode) then
260                 tempApprover.group_or_chain_order_number := groupOrderNumber;
261               else /* chain Order Mode is parallel */
262                 tempApprover.group_or_chain_order_number := 1;
263               end if;
264               if(votingRegimeType = ame_util.orderNumberVoting) then
265                 tempApprover.member_order_number := tempApproverOrderNumbers(j);
266               elsif(votingRegimeType = ame_util.serializedVoting) then
267                 tempMemberOrderNumber := tempMemberOrderNumber+1;
268                 tempApprover.member_order_number := tempMemberOrderNumber;
269               else /* votingRegimeType in (ame_util.consensusVoting, ame_util.firstApproverVoting) */
270                 tempApprover.member_order_number := 1;
271               end if;
272               tempApprover.approval_status := ame_engine.getHandlerApprovalStatus(approverIn  => tempApprover);
273               /*
274                 The engine will set tempApprover.approver_order_number; leave them null here.
275               */
276               ame_engine.addApprover(approverIn => tempApprover);
277             end if;
278           end loop;
279           if(votingRegimeType = ame_util.serializedVoting) then
280             tempMemberOrderNumber := tempMemberOrderNumber+1;
281           end if;
282         end loop;
283         tempIndex := groupIds.next(tempIndex);
284         groupOrderNumber := groupOrderNumber + 1;
285       end loop;
286       exception
287         when emptyGroupException then
288           errorCode := -20001;
289           errorMessage :=
290           ame_util.getMessage(applicationShortNameIn => 'PER',
291             messageNameIn     => 'AME_400229_HAN_APR_NO_MEM',
292             tokenNameOneIn    => 'APPROVAL_GROUP',
293             tokenValueOneIn   => ame_approval_group_pkg.getName(approvalGroupIdIn => currentApproverGroupId));
294           ame_util.runtimeException(packageNameIn => 'ame_ag_chain_handler',
295                                     routineNameIn => 'handler',
296                                     exceptionNumberIn => errorCode,
297                                     exceptionStringIn => errorMessage);
298           raise_application_error(errorCode,
299                                   errorMessage);
300         when others then
301           ame_util.runtimeException(packageNameIn => 'ame_ag_chain_handler',
302                                     routineNameIn => 'handler',
303                                     exceptionNumberIn => sqlcode,
304                                     exceptionStringIn => sqlerrm);
305           raise;
306     end handler;
307 end ame_ag_chain_handler;