DBA Data[Home] [Help]

PACKAGE BODY: APPS.IEM_ROUTE_CLASS_PUB

Source


1 PACKAGE BODY IEM_ROUTE_CLASS_PUB AS
2 /* $Header: iempclsb.pls 120.2 2005/06/23 13:04:09 appldev ship $ */
3 --
4 --
5 -- Purpose: Mantain route classification related operations
6 --
7 -- MODIFICATION HISTORY
8 -- Person      Date         Comments
9 --  Liang Xia   01/10/2002   fix bug that if the number of rules for a classification is less than
10 --                          that of classification with higher priority, this classification
11 --                          is never satisfied. ( No bug logged, shipped with FP-M )
12 --  Liang Xia   11/18/2002   Added dynamic classification. Shipped in MP-Q ( 11.5.9 )
13 --  Liang Xia   12/06/2004  Changed for 115.11 schema complaince
14 --  Liang Xia   06/24/2005  Fixed GSCC sql.46 ( bug 4452895 )
15 -- ---------   ------  ------------------------------------------
16 
17 /*GLOBAL VARIABLES FOR PRIVATE USE
18   ==================================*/
19   G_PKG_NAME    VARCHAR2(100):= 'IEM_ROUTE_CLASS_PUB';
20 
21   --The record type for passing rules
22   TYPE Rules_rec_type is RECORD (
23     key      iem_route_rules.key_type_code%type,
24     operator iem_route_rules.operator_type_code%type,
25     value    iem_route_rules.value%type);
26 
27   --The table type for passing rules
28   TYPE Rules_tbl_type IS table of Rules_rec_type INDEX BY BINARY_INTEGER;
29 
30 
31 
32   /* PRIVATE PROCEDURES NOT AVAILABLE TO THE PUBLIC
33   ================================================*/
34 
35   /* Evaluate And conditions */
36   PROCEDURE evaluateAnd(keyVals IN iem_route_pub.keyVals_tbl_type, rules IN Rules_tbl_type, fireClass OUT NOCOPY Boolean)
37     IS
38 
39   x number := 1;
40   y number := 1;
41 
42   keyToFind iem_route_class_rules.key_type_code%type;
43   operator iem_route_class_rules.operator_type_code%type;
44   valueToFind iem_route_class_rules.value%type;
45 
46   foundKey Boolean;
47   foundKeyValue Boolean;
48 
49   numberOfKeys  Number;
50   numberOfRules Number;
51 
52   errorMessage varchar2(2000);
53 
54   Begin
55 
56 
57        numberOfKeys := keyVals.count;
58        numberofRules := rules.count;
59 
60        --Evaluate each rule one at a time
61        while x <= numberOfRules loop
62 
63         --Copy the rule into temp variables to save repetitive calls to the UDT
64         keyToFind := rules(x).key;
65         valueToFind := rules(x).value;
66         operator := rules(x).operator;
67 
68         y := 1;
69         foundKey := false;
70         foundKeyValue := false;
71 
72         --Search through all the keys that got passed in
73         while y <= numberOfKeys loop
74 
75           --Make the key comparison
76           if keyToFind = keyVals(y).key then
77                 foundKey := true;
78 
79                 --If the key is found then see if the value matches up based on the operator
80                 if iem_operators_pvt.satisfied(keyVals(y).value, operator, valueToFind, keyVals(y).datatype) then
81                     foundKeyValue := true;
82                 end if;
83                 --Exit since we found what we wanted
84                 EXIT;
85            end if;
86 
87          y := y + 1;
88          end loop;
89 
90         --If we were unable to find the key or the value then exit since this is AND chaining
91         if (foundKey = false or foundKeyValue = false) then
92             fireClass := false;
93             EXIT;
94         else
95             fireClass := true;
96         end if;
97 
98        x := x + 1;
99        end loop;
100 
101     EXCEPTION
102         When others then
103 
104 		if( FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL ) then
105            errorMessage := '[' || sqlcode || sqlerrm || ']' || ' Others';
106 	       FND_LOG.STRING(FND_LOG.LEVEL_EXCEPTION, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.EVALUATEAND.OTHERS', errorMessage);
107 		end if;
108 
109   End evaluateAnd;
110 
111 
112   /* Evaluate OR conditions */
113   PROCEDURE evaluateOr(keyVals IN iem_route_pub.keyVals_tbl_type, rules IN Rules_tbl_type, fireClass OUT NOCOPY Boolean)
114     IS
115 
116   x number := 1;
117   y number := 1;
118 
119   keyToFind iem_route_class_rules.key_type_code%type;
120   operator iem_route_class_rules.operator_type_code%type;
121   valueToFind iem_route_class_rules.value%type;
122 
123   foundKeyValue Boolean;
124 
125   numberOfKeys  Number;
126   numberOfRules Number;
127 
128   errorMessage varchar2(2000);
129 
130   Begin
131 
132        numberOfKeys := keyVals.count;
133        numberofRules := rules.count;
134 
135        --Evaluate each rule one at a time
136        while x <= numberOfRules loop
137 
138        --Copy the rule into temp variables to save repetitive calls to the UDT
139         keyToFind := rules(x).key;
140         valueToFind := rules(x).value;
141         operator := rules(x).operator;
142 
143         y := 1;
144         foundKeyValue := false;
145 
146         --Search through all the keys that got passed in
147         while y <= numberOfKeys loop
148 
149           --Make the key comparison case insensitive
150           if upper(keyToFind) = upper(keyVals(y).key) then
151                 --If the key is found then see if the value matches up based on the operator
152                 if iem_operators_pvt.satisfied(keyVals(y).value, operator, valueToFind, keyVals(y).datatype) then
153                     foundKeyValue := true;
154                 end if;
155                 --Exit since we found what we wanted
156                 EXIT;
157            end if;
158 
159          y := y + 1;
160          end loop;
161 
162         --If we found a key value pair then exit since this is OR chaining
163         if foundKeyValue then
164             fireClass := true;
165             EXIT;
166         else
167             fireClass := false;
168         end if;
169 
170        x := x + 1;
171        end loop;
172 
173     EXCEPTION
174         When others then
175 		if( FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL ) then
176         	errorMessage := '[' || sqlcode || sqlerrm || ']' || ' Others';
177 	    	FND_LOG.STRING(FND_LOG.LEVEL_EXCEPTION, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.EVALUATEOR.OTHERS', errorMessage);
178 		end if;
179   End evaluateOr;
180 
181 PROCEDURE classify(
182   p_api_version_number  IN Number,
183   p_init_msg_list       IN VARCHAR2 := NULL,
184   p_commit              IN VARCHAR2 := NULL,
185   p_keyVals_tbl         IN IEM_ROUTE_PUB.keyVals_tbl_type,
186   p_accountId           IN Number,
187   x_classificationId    OUT NOCOPY Number,
188   x_return_status       OUT NOCOPY VARCHAR2,
189   x_msg_count           OUT NOCOPY NUMBER,
190   x_msg_data            OUT NOCOPY VARCHAR2)
191 
192 IS
193   l_api_version_number      CONSTANT    NUMBER:= 1.0;
194   l_api_name                CONSTANT    VARCHAR2(30):= 'Classify';
195 
196 
197   --The active classifications in the system
198   cursor c_classifications (p_enabled_flag iem_account_route_class.enabled_flag%type,
199    p_account_id iem_mstemail_accounts.email_account_id%type)
200   is
201   select
202     a.route_classification_id,
203     a.procedure_name,
204     a.boolean_type_code
205   from
206     iem_route_classifications a,
207     iem_account_route_class b
208   where
209     a.route_classification_id = b.route_classification_id
210   and
211     b.enabled_flag = p_enabled_flag
212   and
213     b.email_account_id = p_account_id
214   and
215     a.route_classification_id <> 0
216   order by b.priority;
217 
218   --All the rules for a classification
219   cursor c_rules (p_route_classification_id iem_route_classifications.route_classification_id%type)
220    is
221   select
222     key_type_code,
223     operator_type_code,
224     value
225   from
226     iem_route_class_rules
227   where
228     route_classification_id = p_route_classification_id;
229 
230 
231   x number:= 1;
232   ruleHold Rules_tbl_type;
233   classSatisfied Boolean := false;
234   enabledFlag varchar(1):= 'Y';
235   booleanTypeCode iem_route_classifications.boolean_type_code%type;
236 
237   runTimekeyVals_tbl IEM_ROUTE_PUB.keyVals_tbl_type;
238   procedureName   iem_route_classifications.procedure_name%type;
239   returnParamType   iem_route_class_rules.key_type_code%type;
240   runTimeSuccess    Boolean := true;
241 
242   l_result          VARCHAR2(256);
243   l_return_status         VARCHAR2(20) := FND_API.G_RET_STS_SUCCESS;
244   l_msg_count             NUMBER := 0;
245   l_msg_data              VARCHAR2(2000);
246 
247   l_log_enabled  BOOLEAN := false;
248   l_exception_log BOOLEAN := false;
249   logMessage varchar2(2000);
250   errorMessage varchar2(2000);
251 
252    BEGIN
253 
254    --Standard begin of API savepoint
255    SAVEPOINT    Classify_PUB;
256 
257    -- Standard call to check for call compatibility.
258    IF NOT FND_API.Compatible_API_Call(
259                     l_api_version_number,
260 				    p_api_version_number,
261 				    l_api_name,
262 				    G_PKG_NAME)
263    THEN
264         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
265    END IF;
266 
267    -- Initialize message list if p_init_msg_list is set to TRUE.
268    IF FND_API.to_Boolean( p_init_msg_list ) THEN
269      FND_MSG_PUB.initialize;
270    END IF;
271 
272    -- Initialize API return status to SUCCESS
273    x_return_status := FND_API.G_RET_STS_SUCCESS;
274 
275    --=================--
276    -- Begining of API --
277    --=================--
278     FND_LOG_REPOSITORY.init(null,null);
279 
280 
281 	l_log_enabled := FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL ;
282 
283 	l_exception_log :=  FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL ;
284 
285     if l_log_enabled then
286         logMessage := '[p_account_id=' || to_char(p_accountid) || ']';
287         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.ROUTE.START', logMessage);
288     end if;
289 
290 
291    --Initialize group to 0
292    x_classificationId := 0;
293 
294    --Iniitalize the Rule data structure
295    --ruleHold.delete;
296 
297    --Check to see if the passed in PL/SQL table has valid key-vals
298    If p_keyVals_tbl.count > 0 then
299 
300     if l_log_enabled then
301         logMessage := '[p_keyValsCount=' || to_char(p_keyVals_tbl.count) || ']';
302         FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.ROUTE.KEY_VALS_MORE_THAN_0', logMessage);
303     end if;
304 
305 
306        --Get all the active routes in the system
307        For v_classifications in c_classifications (enabledFlag, p_accountId) Loop
308 
309              --The boolean operator for the rule chaining
310              booleanTypeCode := v_classifications.boolean_type_code;
311              procedureName := v_classifications.procedure_name;
312 
313              --Iniitalize the Rule data structure
314              ruleHold.delete;
315 	         x := 1;
316              -- Identify classification type
317              IF ( booleanTypeCode = 'DYNAMIC' ) THEN
318                     if l_log_enabled then
319             		logMessage := '[DYNAMIC procedure_name='||procedureName|| ']';
320     		        FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.DYNAMIC_CLASS', logMessage);
321     		        end if;
322 
323                  runTimekeyVals_tbl.delete;
324                  runTimeSuccess := true;
325 
326                  --Get rules for the dynamic route and load it into the data structure
327                  For v_rules in c_rules(v_classifications.route_classification_id) Loop
328                     returnParamType:= v_rules.key_type_code;
329 
330                     -- begin PROCEDURE processing
331                     BEGIN
332                         IEM_ROUTE_RUN_PROC_PVT.run_Procedure(
333                                     p_api_version_number    =>P_Api_Version_Number,
334                                     p_init_msg_list         => FND_API.G_FALSE,
335                                     p_commit                => FND_API.G_FALSE,--P_Commit,
336                                     p_procedure_name        => procedureName,
337                                     p_key_value             => p_keyVals_tbl,
338                                     p_param_type            => returnParamType,
339                                     x_result                => l_result,
340                                     x_return_status         => l_return_status,
341                                     x_msg_count             => l_msg_count,
342                                     x_msg_data              => l_msg_data);
343 
344                         if (l_return_status <> FND_API.G_RET_STS_SUCCESS) then
345                             if l_log_enabled then
346                                 logMessage := '[ERROR when execute procedure for RouteID: '||v_classifications.route_classification_id ||']';
347                                 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.DYNAMIC_CLASS', logMessage);
348                             end if;
349                             runTimeSuccess := false;
350                         else
351                             -- Insert data in key-value pair table
352                             if returnParamType = 'IEMNNUMBER' then
353                                 runTimekeyVals_tbl(x).key := 'IEMNDYNROUTERETURNVAL';
354                                 runTimekeyVals_tbl(x).value := l_result;
355                                 runTimekeyVals_tbl(x).datatype := 'N';
356                             elsif  returnParamType = 'IEMSVARCHAR2' then
357                                 runTimekeyVals_tbl(x).key := 'IEMSDYNROUTERETURNVAL';
358                                 runTimekeyVals_tbl(x).value := l_result;
359                                 runTimekeyVals_tbl(x).datatype := 'S';
360                             end if;
361 
362                             if l_log_enabled then
363             		          logMessage := '[DYNAMIC ROUTE RETURNED VALUE =' || l_result || ']';
364     		                  FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.DYNAMIC_CLASS', logMessage);
365     		                end if;
366                         end if;
367                      EXCEPTION
368                   	     WHEN OTHERS THEN
369                             runTimeSuccess := false;
370                             if l_log_enabled then
371                                 logMessage := '[ERROR (Others) when execute procedure for keyId: '||v_classifications.route_classification_id ||'. error:'||sqlerrm||']';
372                                 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.DYNAMIC_CLASS', logMessage);
373                             end if;
374                      END; -- end of PROCEDURE processing
375 
376                     -- Exit when run procedure failed
377                     if runTimeSuccess then
378                       if returnParamType = 'IEMNNUMBER' then
379                           ruleHold(x).key := 'IEMNDYNROUTERETURNVAL';
380                       elsif  returnParamType = 'IEMSVARCHAR2' then
381                           ruleHold(x).key := 'IEMSDYNROUTERETURNVAL';
382                       end if;
383 
384 
385                       ruleHold(x).operator := v_rules.operator_type_code;
386                       ruleHold(x).value := v_rules.value;
387 
388                       if l_log_enabled then
389               		    logMessage := '[DYNAMIC ROUTE' || ruleHold(x).key || ruleHold(x).operator || ruleHold(x).value || ']';
390       		            FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.DYNAMIC_CLASS', logMessage);
391       		          end if;
392                     else
393                         exit;
394                     end if;
395 
396                     x := x + 1;
397                  End Loop;
398 
399                  --Depending on the operator call different evaluation functions
400                  if runTimeSuccess then
401                     evaluateAnd(runTimekeyVals_tbl, ruleHold, classSatisfied);
402                  else
403                     classSatisfied := false;
404                  end if;
405 
406                 if classSatisfied then
407                     x_classificationId := v_classifications.route_classification_id;
408                     EXIT;
409                 end if;
410 
411 
412              ELSIF ( booleanTypeCode = 'AND' ) or ( booleanTypeCode = 'OR') THEN
413              --Get all the rules for the route and load it into the data structure
414              For v_rules in c_rules(v_classifications.route_classification_id) Loop
415                 ruleHold(x).key := v_rules.key_type_code;
416                 ruleHold(x).operator := v_rules.operator_type_code;
417                 ruleHold(x).value := v_rules.value;
418 
419                 if l_log_enabled then
420         		  logMessage := '[' || ruleHold(x).key || ruleHold(x).operator || ruleHold(x).value || ']';
421 		          FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.CLASSIFY.RULES', logMessage);
422 		        end if;
423 
424 
425                 x := x + 1;
426              End Loop;
427 
428 
429              --Depending on the operator call different evaluation functions
430              if booleanTypeCode = 'AND' then
431                  evaluateAnd(p_keyVals_tbl, ruleHold, classSatisfied);
432              elsif booleanTypeCode = 'OR' then
433                  evaluateOr(p_keyVals_tbl, ruleHold, classSatisfied);
434              end if;
435 
436 
437               --If the rules got satisfied then check if group is valid
438               if classSatisfied then
439                     x_classificationId := v_classifications.route_classification_id;
440                     EXIT;
441               end if;
442             END IF; -- end if boolean_type is Dynamic
443        End Loop;
444 
445    End if;
446    --==========--
447    --End of API--
448    --==========--
449 
450    --Standard check of p_commit
451    If FND_API.To_Boolean(p_commit) then
452         COMMIT WORK;
453    End if;
454 
455    --Standard call to get message count and if count is 1 then get message info
456    FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
457 
458    EXCEPTION
459       WHEN FND_API.G_EXC_ERROR THEN
460           Rollback to Classify_PUB;
461           x_return_status := FND_API.G_RET_STS_ERROR;
462           FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
463 		  if l_exception_log then
464           	 errorMessage := '[' || sqlcode || sqlerrm || ']' || ' Execution Error';
465 	      	 FND_LOG.STRING(FND_LOG.LEVEL_EXCEPTION, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.ROUTE.EXEC_ERROR', errorMessage);
466 		  end if;
467      WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
468           Rollback to Classify_PUB;
469           x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
470           FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
471 		  if l_exception_log then
472           	 errorMessage := '[' || sqlcode || sqlerrm || ']' || ' Unexpected Execution Error';
473 			 FND_LOG.STRING(FND_LOG.LEVEL_EXCEPTION, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.ROUTE.UNEXP_EXEC_ERROR', errorMessage);
474 		  end if;
475      WHEN OTHERS THEN
476           Rollback to Classify_PUB;
477           x_return_status := FND_API.G_RET_STS_ERROR;
478           IF fnd_msg_pub.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
479             FND_MSG_PUB.Add_Exc_Msg(G_PKG_NAME, l_api_name);
480           END IF;
481           FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
482 
483 		  if l_exception_log then
484           	 errorMessage := '[' || sqlcode || sqlerrm || ']' || ' Others';
485 	      	 FND_LOG.STRING(FND_LOG.LEVEL_EXCEPTION, 'IEM.PLSQL.IEM_ROUTE_CLASS_PUB.ROUTE.OTHERS', errorMessage);
486 		  end if;
487 
488 
489 
490 END;
491 
492 END IEM_ROUTE_CLASS_PUB;