DBA Data[Home] [Help]

PACKAGE BODY: APPS.FTE_ACS_CACHE_PKG

Source


1 PACKAGE BODY FTE_ACS_CACHE_PKG AS
2 /* $Header: FTEACSCB.pls 120.5 2005/09/19 05:27:22 alksharm noship $ */
3 
4 -- -------------------------------------------------------------------------- --
5 --                                                                            --
6 -- NAME:        FTE_ACS_CACHE_PKG                                             --
7 -- TYPE:        PACKAGE BODY                                                  --
8 -- DESCRIPTION: Contains core procedures for searching the rule in the cache  --
9 --              In this package processing is done for a single entity.       --
10 --                                                                            --
11 -- CHANGE CONTROL LOG                                                         --
12 --                                                                            --
13 -- -------------------------------------------------------------------------- --
14 
15 --
16 --  Used to get rule data from the database for a particular group id
17 --
18 TYPE rules_record_type IS RECORD( rule_id			FTE_SEL_RULE_RESTRICTIONS.rule_id%type,
19 				  attribute_name		FTE_SEL_RULE_RESTRICTIONS.attribute_name%type,
20 				  attribute_value_from		FTE_SEL_RULE_RESTRICTIONS.attribute_value_from%type,
21 				  attribute_value_to		FTE_SEL_RULE_RESTRICTIONS.attribute_value_to%type,
22 				  attribute_value_from_number	FTE_SEL_RULE_RESTRICTIONS.attribute_value_from_number%type,
23 				  attribute_value_to_number	FTE_SEL_RULE_RESTRICTIONS.attribute_value_to_number%type,
24 				  overlap_flag			FTE_SEL_RULE_RESTRICTIONS.range_overlap_flag%type);
25 
26 TYPE rules_tab_type IS TABLE OF rules_record_type INDEX BY BINARY_INTEGER;
27 
28 --
29 --Limit is  a) 'L'  - Lower limit.
30 --          b) 'U'  - Upper limit
31 --	    c) 'N'  - Null (Added when range is not there)
32 
33 TYPE range_match_rule_rec IS RECORD( rule_id		FTE_SEL_RULE_RESTRICTIONS.rule_id%type,
34 				     overlap_flag	FTE_SEL_RULE_RESTRICTIONS.range_overlap_flag%type,
35 				     limit		VARCHAR2(1));
36 
37 TYPE range_match_tab   IS TABLE OF range_match_rule_rec INDEX BY BINARY_INTEGER;
38 
39 TYPE range_match_cache IS TABLE OF range_match_tab INDEX BY VARCHAR2(32767);
40 
41 --
42 -- To be used for FOB and Regions
43 --
44 
45 TYPE exact_match_tab   IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
46 
47 TYPE exact_match_cache IS TABLE OF exact_match_tab INDEX BY VARCHAR2(32767);
48 
49 TYPE priority_tab_type IS TABLE OF NUMBER;
50 
51 TYPE rule_match_tab    IS TABLE OF NUMBER;
52 
53 TYPE group_cache_rec   IS RECORD( attribute_tab		wsh_util_core.id_tab_type,
54 				  priority_tab		priority_tab_type,
55 				  weight_uom_code	VARCHAR2(30),
56 				  volume_uom_code	VARCHAR2(30));
57 
58 TYPE groups_cache_type IS TABLE OF group_cache_rec INDEX BY BINARY_INTEGER;
59 
60 TYPE from_to_region_cache_type	IS TABLE OF NUMBER INDEX BY VARCHAR2(32767);
61 
62 --
63 -- The data structure is used for storing RULE-RESULT association.
64 -- 1 rule can be associated with multiple results.
65 -- The results are indexed by rule_id.
66 --
67 TYPE result_id_tab	IS TABLE OF NUMBER		INDEX BY BINARY_INTEGER;
68 
69 TYPE rule_result_tab	IS TABLE OF result_id_tab	INDEX BY BINARY_INTEGER;
70 
71 --
72 -- Local data structure for querying the result attributes.
73 --
74 TYPE fte_attr_code_val_rec_type IS RECORD( attr_code VARCHAR2(30),
75 				           attr_val  VARCHAR2(240));
76 
77 TYPE fte_attr_code_val_tab_type IS TABLE OF fte_attr_code_val_rec_type INDEX BY BINARY_INTEGER;
78 
79 -- -------------------------------------------------------------------------- --
80 -- Global Package Constants                                                   --
81 -- ------------------------                                                   --
82 --                                                                            --
83 -- -------------------------------------------------------------------------- --
84 
85 	--
86 	G_PKG_NAME CONSTANT VARCHAR2(50) := 'FTE_ACS_CACHE_PKG';
87 	--
88     g_session_id        NUMBER;
89 	g_num_absent		NUMBER      := -9999 ;
90 	g_val_absent		VARCHAR2(25):= 'NULL';
91     g_max_cache_size	NUMBER      := 10;
92 	g_null_tab		WSH_UTIL_CORE.ID_TAB_TYPE;
93 
94 --
95 --	2^10 = 2 147 483 648 ,
96 --      Taking 11 characters in the index
97 --      g_int_mask is used for Integer Fields, Include Sign always otherwise negative length will be more
98 --      g__num_mask  is used for decimals
99 --
100 --	The three masks are different
101 --      Valid Combinations are - 1) g_int_mask - g_num_mask
102 --                               2) g_int_mask - char_mask
103 --
104 	g_int_mask		VARCHAR2(12) := 'S00000000000';
105 	g_num_mask		VARCHAR2(20) := '00000000000D00000000';
106     g_lpad_char		VARCHAR2(1)  := '0';
107 	g_lpad_length		NUMBER       := 25;
108 
109 	g_low_range_break	VARCHAR2(1)  := 'L';
110 	g_high_range_break	VARCHAR2(1)  := 'H';
111 	g_null_range		VARCHAR2(1)  := 'N';
112 	g_value_present		NUMBER	     := 1;
113 
114 	g_wt_idx		NUMBER	     := 0;
115 	g_vol_idx		NUMBER	     := 1;
116 	g_fr_reg_idx		NUMBER	     := 2;
117 	g_to_reg_idx		NUMBER	     := 3;
118 	g_fr_post_idx		NUMBER	     := 4;
119 	g_to_post_idx		NUMBER	     := 5;
120 	g_transit_time_idx	NUMBER	     := 6;
121 	g_fob_code_idx		NUMBER	     := 7;
122 
123 
124 -- -------------------------------------------------------------------------- --
125 -- Global Priority Tables                                                     --
126 -- ------------------------                                                   --
127 --                                                                            --
128 -- -------------------------------------------------------------------------- --
129 	g_to_postal_priority	priority_tab_type;
130     g_from_postal_priority	priority_tab_type;
131     g_to_region_priority	priority_tab_type;
132     g_from_region_priority	priority_tab_type;
133     g_all_priority		priority_tab_type;
134 	g_from_pzone_priority	priority_tab_type;
135 	g_to_pzone_priority	priority_tab_type;
136 
137 	g_table_initialized	BOOLEAN	     := FALSE;
138 
139 
140 -- -------------------------------------------------------------------------- --
141 -- Global Caches	                                                      --
142 -- ------------------------                                                   --
143 --                                                                            --
144 -- -------------------------------------------------------------------------- --
145 
146 	--
147 	--  Global Range Caches Used
148 	--
149 
150 	g_weight_cache		range_match_cache;
151 	g_volume_cache		range_match_cache;
152 	g_transit_cache		range_match_cache;
153 	g_from_postal_cache	range_match_cache;
154 	g_to_postal_cache	range_match_cache;
155 
156 	--
157 	--  Global Exact Caches Used
158 	--
159 
160 	g_fob_cache		exact_match_cache;
161 
162 	--
163 	-- Other caches
164 	--
165 	g_groups_cache		groups_cache_type;
166 	g_from_to_region_cache	from_to_region_cache_type;
167 
168 	-- Global caches for storing results for a particular rule.
169 	--
170 	-- Results are indexed by rule_id
171 	-- The order in which results are stored in cache is determined by rank or leg sequence
172 	-- For eg :
173 	--	 Rank(Index)	        Result
174 	--	  1			 501
175 	--	  2  			 509
176 	--        3 			 513
177 	--	Leg Destination(Index) Result
178 	--	 1			 539
179 	--	 2		         532
180 	g_rule_result_cache		rule_result_tab;
181 	g_result_attribute_cache	fte_cs_result_attr_tab;
182 
183 -- -------------------------------------------------------------------------- --
184 -- Procedures Definitions		                                      --
185 -- ------------------------                                                   --
186 --                                                                            --
187 -- -------------------------------------------------------------------------- --
188 
189 
190 --***************************************************************************--
191 --========================================================================
192 -- FUNCTION  : get_fixed_key      PRIVATE
193 --
194 -- PARAMETERS: p_group_id		Group id
195 --	       p_from_region_id         From Region Id
196 --  	       p_to_region_id           To Region Id
197 --
198 -- COMMENT   : Returns appended p_group_id, p_from_region_id, p_to_region_id after
199 --	       formatting them
200 --
201 --***************************************************************************--
202 FUNCTION get_fixed_key ( p_group_id          IN NUMBER,
203 			 p_from_region_id    IN NUMBER,
204 			 p_to_region_id      IN NUMBER) RETURN VARCHAR2
205 IS
206 
207     l_key		VARCHAR2(32767);
208     l_debug_on          CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
209     l_module_name       CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'get_fixed_key';
210 
211 BEGIN
212 
213         IF l_debug_on THEN
214 	      wsh_debug_sv.push (l_module_name);
215 	END IF;
216 
217 	l_key :=  TO_CHAR(p_group_id,      g_int_mask) || '-' ||
218 	          TO_CHAR(p_from_region_id,g_int_mask) || '-' ||
219 		  TO_CHAR(p_to_region_id  ,  g_int_mask);
220 
221         IF l_debug_on THEN
222           WSH_DEBUG_SV.log(l_module_name,'Fixed Key ',l_key);
223           WSH_DEBUG_SV.POP (l_module_name);
224 	END IF;
225 
226 	RETURN (l_key);
227 EXCEPTION
228 
229       WHEN others THEN
230       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.get_fixed_key');
231 
232       IF l_debug_on THEN
233         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
234         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
235       END IF;
236       --
237 END get_fixed_key;
238 
239 
240 --***************************************************************************--
241 --========================================================================
242 -- FUNCTION  : get_key_for_num      PRIVATE
243 --
244 -- PARAMETERS: p_fixed_key		Fixed  Key
245 --	       p_number			Number key
246 --
247 -- COMMENT   : Returns p_fixed_key appended with formated number key
248 --
249 --***************************************************************************--
250 FUNCTION get_key_for_num(  p_fixed_key  IN  VARCHAR2,
251 			   p_number     IN  NUMBER) RETURN VARCHAR2
252 IS
253      l_key		VARCHAR2(32767);
254      l_debug_on          CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
255      l_module_name       CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'get_key_for_num';
256 
257 BEGIN
258 
259 	IF l_debug_on THEN
260 	      wsh_debug_sv.push (l_module_name);
261 	END IF;
262 
263 
264 	l_key  :=    p_fixed_key|| '-' ||
265 	             TO_CHAR(p_number,g_num_mask);
266 
267         IF l_debug_on THEN
268           WSH_DEBUG_SV.log(l_module_name,'Number Key ',l_key);
269           WSH_DEBUG_SV.POP (l_module_name);
270 	END IF;
271 
272 	RETURN l_key;
273 
274 EXCEPTION
275       WHEN others THEN
276       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.get_key_for_num');
277 
278       IF l_debug_on THEN
279         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
280         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
281       END IF;
282       --
283 END get_key_for_num;
284 
285 --***************************************************************************--
286 --========================================================================
287 -- FUNCTION  : get_key_for_char         PRIVATE
288 --
289 -- PARAMETERS: p_fixed_key		Fixed Key
290 --	       p_char			Char key
291 --
292 -- COMMENT   : Returns p_fixed_key appended with padded p_char key
293 --
294 --***************************************************************************--
295 FUNCTION get_key_for_char(  p_fixed_key  IN VARCHAR2,
296                             p_char	 IN VARCHAR2) RETURN VARCHAR2
297 IS
298      l_key		 VARCHAR2(32767);
299      l_debug_on          CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
300      l_module_name       CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'get_key_for_char';
301 BEGIN
302 
303 	IF l_debug_on THEN
304 	      wsh_debug_sv.push (l_module_name);
305 	END IF;
306 
307 	l_key :=  p_fixed_key||'-' ||
308 	          LPAD(p_char,g_lpad_length,g_lpad_char);
309 
310 	IF l_debug_on THEN
311           WSH_DEBUG_SV.log(l_module_name,'Char Key ',l_key);
312           WSH_DEBUG_SV.POP (l_module_name);
313 	END IF;
314 
315 	RETURN l_key;
316 EXCEPTION
317       WHEN others THEN
318       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.get_key_for_char');
319 
320       IF l_debug_on THEN
321         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
322         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
323       END IF;
324       --
325 END  get_key_for_char;
326 
327 
328 --***************************************************************************--
329 --========================================================================
330 -- FUNCTION  : get_key_for_null         PRIVATE
331 --
332 -- PARAMETERS: p_fixed_key		Fixed Key
333 --
334 --
335 -- COMMENT   : Returns p_fixed_key appended with padded g_val_absent
336 --
337 --***************************************************************************--
338 FUNCTION get_key_for_null(  p_fixed_key	  IN VARCHAR2) RETURN VARCHAR2
339 IS
340      l_key		VARCHAR2(32767);
341      l_debug_on          CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
342      l_module_name       CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'get_key_for_null';
343 BEGIN
344 	IF l_debug_on THEN
345 	      wsh_debug_sv.push (l_module_name);
346 	END IF;
347 
348 	l_key := p_fixed_key||'-'||LPAD(g_val_absent,g_lpad_length,g_lpad_char);
349 
350 	IF l_debug_on THEN
351           WSH_DEBUG_SV.log(l_module_name,'NULL Key',l_key);
352           WSH_DEBUG_SV.POP (l_module_name);
353 	END IF;
354 
355 	RETURN l_key;
356 EXCEPTION
357       WHEN others THEN
361         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
358       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.get_key_for_null');
359       IF l_debug_on THEN
360         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
362       END IF;
363       --
364 
365 END get_key_for_null;
366 
367 --***************************************************************************--
368 --========================================================================
369 -- PROCEDURE : initialize_tables          PRIVATE
370 --
371 -- PARAMETERS:  x_return_status		  Return Status
372 --
373 -- COMMENT   : The API initializes priority tables .Following is priority list is followed.
374 --
375 --PRIORITY ATTRIBUTE TYPE	ATTRIBUTE TYPE		ATTRIBUTE TYPE	ATTRIBUTE TYPE
376 ----------------------------------------------------------------------------------
377 -- 1.	 TO_POSTAL	TO_REGION/ZONE_ID	FROM_POSTAL	FROM_REGION/ZONE_ID
378 -- 2.    TO_POSTAL	TO_REGION/ZONE_ID	FROM_POSTAL		-
379 -- 3.	 TO_POSTAL	TO_REGION_ID		FROM POSTAL ZONE	-
380 -- 4.	 TO_POSTAL	TO_REGION_ID		FROM_REGION_ID		-
381 -- 5.	 TO_POSTAL	TO_REGION_ID			-		-
382 -- 6.    TO_POSTAL		-		FROM_POSTAL	FROM_REGION_ID
383 -- 7.	 TO POSTAL ZONE	   	-		FROM_POSTAL	FROM_REGION_ID
384 -- 8.    TO_POSTAL		-		FROM_POSTAL		-
385 -- 9.	 TO_POSTAL		-		FROM_POSTAL_ZONE	-
386 -- 10.	 TO POSTAL ZONE	    	-		FROM POSTAL		-
387 -- 11.	 TO POSTAL ZONE	    	-		FROM POSTAL_ZONE	-
388 -- 12.   TO_POSTAL		-			-	FROM_REGION_ID
389 -- 13.   TO POSTAL ZONE		-			-	FROM_REGION_ID
390 -- 14.   TO_POSTAL		-			-		-
391 -- 15	 TO POSTAL ZONE	    	-			-		-
392 -- 16.	 TO_REGION_ID		-		FROM_POSTAL	FROM_REGION_ID
393 -- 17.   TO_REGION_ID		-		FROM_POSTAL		-
394 -- 18.	 TO_REGION_ID		-		FROM POSTAL ZONE	-
395 -- 19.	 TO_REGION_ID		-		FROM_REGION_ID		-
396 -- 20.	 TO_REGION_ID		-			-		-
397 -- 21.		-		-		FROM_POSTAL	FROM_REGION_ID
398 -- 22.		-		-		FROM_POSTAL		-
399 -- 23.		-		-		FROM POSTAL ZONE	-
400 -- 24.		-		-		FROM_REGION_ID		-
401 -- 25.		-		-			-		-
402 --***************************************************************************--
403 PROCEDURE initialize_tables (x_return_status OUT NOCOPY VARCHAR2)  IS
404 
405 l_debug_on     CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
406 l_module_name  CONSTANT VARCHAR2(100) := 'wsh.plsql.'||G_PKG_NAME||'.'||'initialize_tables';
407 
408 BEGIN
409 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
410 
411 	IF l_debug_on THEN
412 	   wsh_debug_sv.push (l_module_name);
413         END IF;
414 
415 	--All the priorites
416         g_all_priority		:= priority_tab_type(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25);
417 	--Priorities where to postal code has to be evaluated.
418 	g_to_postal_priority	:= priority_tab_type(1,2,3,4,5,6,8,9,12,14);
419         --Priorities where from postal code has to be evaluated.
420 	g_from_postal_priority	:= priority_tab_type(1,2,6,7,8,10,16,17,21,22);
421 	--Priorities where to region has to be evaluated.
422 	g_to_region_priority	:= priority_tab_type(1,2,3,4,5,16,17,18,19,20);
423         --Priorities where from region has to be evaluated.
424 	g_from_region_priority	:= priority_tab_type(1,4,6,7,12,13,16,19,21,24);
425         --Priorities where to postal zone has to be evaluated.
426 	g_to_pzone_priority	:= priority_tab_type(7,10,11,13,15);
427         --Priorities where from postal zone has to be evaluated
428 	g_from_pzone_priority	:= priority_tab_type(3,9,11,18,23);
429 
430 	--Used for NULL representation of region/zone.
431 	g_null_tab(1) := g_num_absent;
432 
433 	g_table_initialized	:= TRUE;
434 
435 	IF l_debug_on THEN
436 	    WSH_DEBUG_SV.POP(l_module_name);
437         END IF;
438 EXCEPTION
439 WHEN others THEN
440       g_table_initialized := FALSE;
441       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.INITIALIZE_TABLES');
442       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
443 
444       IF l_debug_on THEN
445         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
446         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
447       END IF;
448       --
449 END initialize_tables;
450 
451 
452 --***************************************************************************--
453 --========================================================================
454 -- PROCEDURE : Delete_Rule_Caches         PRIVATE
455 --
456 -- PARAMETERS: x_return_status		  Return Status
457 --
458 -- COMMENT   : Delete all the rule caches
459 --***************************************************************************--
460 
461 PROCEDURE delete_rule_caches( x_return_status OUT NOCOPY VARCHAR2)
462 IS
463 
464    l_debug_on          CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
465    l_module_name       CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'delete_rule_caches';
466 
467 BEGIN
468 
469    x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
470 
471    IF l_debug_on THEN
472        wsh_debug_sv.push (l_module_name);
473    END IF;
474 
475    g_groups_cache.DELETE;
476    g_weight_cache.DELETE;
477    g_volume_cache.DELETE;
478    g_transit_cache.DELETE;
479    g_from_postal_cache.DELETE;
480    g_to_postal_cache.DELETE;
481    g_fob_cache.DELETE;
482 
483    IF l_debug_on THEN
484         WSH_DEBUG_SV.logmsg(l_module_name,'CACHES DELETED');
485         WSH_DEBUG_SV.POP (l_module_name);
486    END IF;
487 
488 EXCEPTION
489       WHEN others THEN
490 
491       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.DELETE_RULE_CACHES');
492       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
493 
497       END IF;
494       IF l_debug_on THEN
495         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
496         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
498       --
499 END delete_rule_caches;
500 
501 
502 --========================================================================
503 -- PROCEDURE :  refresh_cache            PRIVATE
504 --
505 -- PARAMETERS: x_return_status           Return Status
506 -- COMMENT   :
507 --             Refreshes rules database caches
508 --             if middletier session (ICX session) is changed
509 --========================================================================
510 
511 PROCEDURE refresh_cache (
512              x_return_status    OUT  NOCOPY  VARCHAR2 )
513 IS
514 
515     l_session_id        NUMBER  := 0;
516     l_debug_on          CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
517     l_module_name       CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'refresh_cache';
518 
519 BEGIN
520     x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
521     --
522     IF l_debug_on THEN
523       wsh_debug_sv.push (l_module_name);
524     END IF;
525     --
526 
527     l_session_id := icx_sec.g_session_id;
528 
529     IF l_debug_on THEN
530        wsh_debug_sv.logmsg(l_module_name,'g_session_id : '||g_session_id||' Current session id : '||l_session_id);
531     END IF;
532 
533     IF g_session_id IS NULL OR l_session_id <> g_session_id THEN
534        delete_rule_caches(x_return_status => x_return_status);
535 
536        g_session_id := l_session_id;
537 
538        IF l_debug_on THEN
539 	   wsh_debug_sv.logmsg(l_module_name,'Rules Cache cleared');
540        END IF;
541 
542     END IF;
543 
544     --
545     IF l_debug_on THEN
546       wsh_debug_sv.pop (l_module_name);
547     END IF;
548     --
549 
550 EXCEPTION
551     WHEN others THEN
552       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.refresh_cache');
553       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
554       --
555       IF l_debug_on THEN
556         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
557         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
558       END IF;
559       --
560 END refresh_cache;
561 
562 
563 --***************************************************************************--
564 --========================================================================
565 -- PROCEDURE : sort_priority_tab     PRIVATE
566 --
567 -- PARAMETERS: p_priority_tab	     Priority tab to be sorted,
568 --	       x_return_status	     Return Status
569 --
570 -- COMMENT   : Sorts the priority table.
571 --
572 --***************************************************************************--
573 PROCEDURE sort_priority_tab(p_priority_tab  IN	OUT NOCOPY PRIORITY_TAB_TYPE,
574 			    x_return_status OUT NOCOPY	VARCHAR2)
575 IS
576 
577  i			NUMBER;
578  j			NUMBER;
579  temp			NUMBER;
580  more_sort		BOOLEAN := TRUE;
581 
582  l_debug_on     CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
583  l_module_name  CONSTANT VARCHAR2(100) := 'wsh.plsql.'||G_PKG_NAME||'.'||'sort_priority_tab';
584 
585 BEGIN
586 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
587 
588         IF l_debug_on THEN
589 	     wsh_debug_sv.push (l_module_name);
590 	END IF;
591 
592 	IF (p_priority_tab.COUNT<>1) THEN
593 
594 	   i:= p_priority_tab.FIRST;
595 
596 	   IF i IS NOT NULL THEN
597 	      LOOP
598 		  more_sort := FALSE;
599                   j := p_priority_tab.NEXT(i);
600 		  IF  j is NOT NULL THEN
601 		     LOOP
602 			IF (p_priority_tab(j) < p_priority_tab(i)) THEN
603 			    temp := p_priority_tab(j);
604 			    p_priority_tab(j) := p_priority_tab(i);
605 			    p_priority_tab(i) := temp;
606 			    more_sort := TRUE;
607 			END IF;
608 
609 			EXIT when j = p_priority_tab.LAST;
610 			j:= p_priority_tab.NEXT(j);
611  		     END LOOP;
612 		  END IF;
613 		  EXIT when NOT(more_sort) OR (i = p_priority_tab.LAST);
614 		  i:= p_priority_tab.NEXT(i);
615 	       END LOOP;
616 	   END IF;
617 
618 	END IF;
619 
620 	IF l_debug_on THEN
621 	        WSH_DEBUG_SV.POP (l_module_name);
622 	END IF;
623 EXCEPTION
624   WHEN others THEN
625 
626       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.SORT_PRIORITY_TAB');
627       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
628 
629       IF l_debug_on THEN
630         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
631         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
632       END IF;
633       --
634 END sort_priority_tab;
635 
636 
637 --***************************************************************************--
638 --========================================================================
639 -- PROCEDURE : get_sorted_priority_tab     PRIVATE
640 --
641 -- PARAMETERS: p_attribute_tab		Attributes present in the group.
642 --	       x_priority_tab		Table of priorities that should be validated for group.
643 --	       x_return_status		Return Status
644 --
645 -- COMMENT   : Returns sorted priority tab.
646 --
647 --
648 -- ALGORITHM :
649 --	       Uses except SET operation to find the priorities that need to be
650 --	       evaluated. The procees is not an additive process it is a subtractive process.
654 PROCEDURE get_sorted_priority_tab( p_attribute_tab      IN	   WSH_UTIL_CORE.ID_TAB_TYPE,
651 --             Remove all that need not be evaluated
652 --***************************************************************************--
653 
655 				   x_priority_tab	OUT NOCOPY PRIORITY_TAB_TYPE,
656 				   x_return_status	OUT NOCOPY VARCHAR2)
657 IS
658 
659  l_sort		BOOLEAN := FALSE;
660  l_priority_tab	PRIORITY_TAB_TYPE;
661 
662  l_debug_on	CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
663  l_module_name  CONSTANT VARCHAR2(100) := 'wsh.plsql.'||G_PKG_NAME||'.'||'get_sorted_priority_tab';
664 
665 BEGIN
666 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
667 
668         IF l_debug_on THEN
669 	     wsh_debug_sv.push (l_module_name);
670 	END IF;
671 
672 	l_priority_tab := g_all_priority;
673 
674 	IF NOT(p_attribute_tab.EXISTS(g_fr_post_idx)) THEN
675 		l_priority_tab := l_priority_tab MULTISET EXCEPT g_from_postal_priority;
676 		l_sort := TRUE;
677 	END IF;
678 
679 	IF NOT(p_attribute_tab.EXISTS(g_to_post_idx)) THEN
680 		l_priority_tab := l_priority_tab MULTISET EXCEPT g_to_postal_priority;
681 		l_sort := TRUE;
682 	END IF;
683 
684         -- We need to remove from pzone also.
685 	IF NOT(p_attribute_tab.EXISTS(g_fr_reg_idx)) THEN
686 		l_priority_tab := l_priority_tab MULTISET EXCEPT g_from_region_priority;
687 		l_priority_tab := l_priority_tab MULTISET EXCEPT g_from_pzone_priority;
688 		l_sort := TRUE;
689 	END IF;
690 
691 	IF NOT(p_attribute_tab.EXISTS(g_to_reg_idx)) THEN
692 		l_priority_tab := l_priority_tab MULTISET EXCEPT g_to_region_priority;
693 		l_priority_tab := l_priority_tab MULTISET EXCEPT g_to_pzone_priority;
694 		l_sort := TRUE;
695 	END IF;
696 
697 	-- Results of operations may not be sorted fashion
698 	-- Sort the priority tab
699 	-- Writing boolean sort
700 
701 	IF (l_priority_tab.COUNT<>1 and l_sort ) THEN
702 
703 		sort_priority_tab( p_priority_tab   => l_priority_tab,
704 				   x_return_status  => x_return_status);
705 
706 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
707 		       IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
708 		           raise FND_API.G_EXC_UNEXPECTED_ERROR;
709 		       END IF;
710 		END IF;
711     	END IF;
712 
713 	x_priority_tab := l_priority_tab;
714 
715 	IF l_debug_on THEN
716 	        WSH_DEBUG_SV.POP (l_module_name);
717 	END IF;
718 EXCEPTION
719   WHEN others THEN
720       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.GET_SORTED_PRIORITY_TAB');
721       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
722 
723       IF l_debug_on THEN
724         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
725         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
726       END IF;
727       --
728 END get_sorted_priority_tab;
729 
730 
731 --***************************************************************************--
732 --========================================================================
733 -- PROCEDURE : add_group_to_group_cache         PRIVATE
734 --
735 -- PARAMETERS: p_group_id		  Group id to be used
736 --	       x_return_status		  Return Status
737 --
738 -- COMMENT   : Adds a group and its attribute to the global cache.
739 --
740 --
741 -- ALGORITHM :
742 --	      1) Query for all group attributes.
743 --	      2) Add the group attributes and priority_tab to the cache
744 --***************************************************************************--
745 PROCEDURE add_group_to_group_cache( p_group_id      IN  NUMBER,
746 			            x_return_status OUT NOCOPY VARCHAR2)
747 IS
748 
749 --
750 --Check this query
751 --
752 CURSOR c_get_group_attributes IS
753 SELECT attribute_name,attribute_uom_code
754 FROM   fte_sel_group_attributes
755 WHERE  group_id = p_group_id;
756 
757 itr			NUMBER;
758 
759 l_attr_tab		FTE_ATTR_CODE_VAL_TAB_TYPE;
760 l_group_attr		WSH_UTIL_CORE.ID_TAB_TYPE;
761 
762 l_group_cache_rec	GROUP_CACHE_REC;
763 l_priority_tab		PRIORITY_TAB_TYPE;
764 l_priority_str		VARCHAR2(600);
765 
766 l_debug_on     CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
767 l_module_name  CONSTANT VARCHAR2(100) := 'wsh.plsql.'||G_PKG_NAME||'.'||'add_group_to_group_cache';
768 
769 BEGIN
770     x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
771 
772     IF l_debug_on THEN
773        wsh_debug_sv.push (l_module_name);
774        WSH_DEBUG_SV.log(l_module_name,'Adding group to Group Cache ',p_group_id);
775        WSH_DEBUG_SV.logmsg(l_module_name,'Attribtues to be checked ');
776     END IF;
777 
778     OPEN  c_get_group_attributes;
779     FETCH c_get_group_attributes BULK COLLECT INTO l_attr_tab;
780     CLOSE c_get_group_attributes;
781 
782     itr := l_attr_tab.FIRST;
783 
784     IF (itr IS NOT NULL) THEN
785 	LOOP
786 
787 	     IF ( l_attr_tab(itr).attr_code = 'WEIGHT') THEN
788 		l_group_attr(g_wt_idx) := g_value_present;
789 		l_group_cache_rec.weight_uom_code := l_attr_tab(itr).attr_val;
790 
791 		IF l_debug_on THEN
792 		   WSH_DEBUG_SV.logmsg(l_module_name,'Weight');
793 		END IF;
794 
795 	     ELSIF (l_attr_tab(itr).attr_code = 'VOLUME') THEN
796 		l_group_attr(g_vol_idx) := g_value_present;
797 		l_group_cache_rec.volume_uom_code := l_attr_tab(itr).attr_val;
798 
799 		IF l_debug_on THEN
800 		   WSH_DEBUG_SV.logmsg(l_module_name,'Volume');
801 		END IF;
802 
803  	     ELSIF (l_attr_tab(itr).attr_code = 'TRANSIT_TIME') THEN
804 		l_group_attr(g_transit_time_idx) := g_value_present;
805 
809 
806 		IF l_debug_on THEN
807 		   WSH_DEBUG_SV.logmsg(l_module_name,'Transit Time');
808 		END IF;
810 	     --
811 	     -- FTE_SEL_RULE_RESTICTIONS has FROM_REGION_ID
812 	     -- FTE_SEL_GROUP_ATTRIBUTES has 'FROM_REGION_COUNTRY'
813 	     --
814 	     ELSIF (l_attr_tab(itr).attr_code IN ('FROM_REGION_COUNTRY','FROM_REGION_STATE','FROM_REGION_CITY','FROM_ZONE','FROM_REGION')) THEN
815 
816 		 -- R12 UI enters 'FROM_REGION' for postal codes also.
817 		l_group_attr(g_fr_reg_idx) := g_value_present;
818 		IF (l_attr_tab(itr).attr_code = 'FROM_REGION') THEN
819 			l_group_attr(g_fr_post_idx) := g_value_present;
820 			IF l_debug_on THEN
821 			   WSH_DEBUG_SV.logmsg(l_module_name,'From Region Postal Code');
822 			END IF;
823 		END IF;
824 
825 		IF l_debug_on THEN
826 		   WSH_DEBUG_SV.logmsg(l_module_name,'From Region');
827 		END IF;
828 
829 	     --
830 	     -- FTE_SEL_RULE_RESTRICTIONS has TO_REGION_ID
831 	     -- FTE_SEL_GROUP_ATTRIBUTES has 'TO_REGION_COUNTRY'
832 	     --
833 	     ELSIF (l_attr_tab(itr).attr_code IN ('TO_REGION_COUNTRY','TO_REGION_STATE','TO_REGION_CITY','TO_ZONE','TO_REGION')) THEN
834 		l_group_attr(g_to_reg_idx) := g_value_present;
835 
836 	         -- R12 UI enters 'TO_REGION' for postal codes also.
837 		IF (l_attr_tab(itr).attr_code = 'TO_REGION') THEN
838 			l_group_attr(g_to_post_idx) := g_value_present;
839 			IF l_debug_on THEN
840 			   WSH_DEBUG_SV.logmsg(l_module_name,'To Region Postal Code');
841 			END IF;
842 		END IF;
843 
844 		IF l_debug_on THEN
845 		   WSH_DEBUG_SV.logmsg(l_module_name,'To Region');
846 		END IF;
847 
848 	     -- Prior to R12 , UI stores 'FROM_REGION_POSTAL_CODE' for from postal code.
849 	     ELSIF (l_attr_tab(itr).attr_code IN('FROM_REGION_POSTAL_CODE')) THEN
850 		l_group_attr(g_fr_post_idx) := g_value_present;
851 
852 		IF l_debug_on THEN
853 		   WSH_DEBUG_SV.logmsg(l_module_name,'From Region Postal Code');
854 		END IF;
855 
856   	     -- Prior to R12 , UI stores  'TO_REGION_POSTAL_CODE' for To postal codes.
857 	     ELSIF (l_attr_tab(itr).attr_code IN ('TO_REGION_POSTAL_CODE')) THEN
858   	        l_group_attr(g_to_post_idx) := g_value_present;
859 
860 		IF l_debug_on THEN
861 		   WSH_DEBUG_SV.logmsg(l_module_name,'To Region Postal Code');
862 		END IF;
863 
864 	     ELSIF (l_attr_tab(itr).attr_code = 'FOB_CODE') THEN
865 		l_group_attr(g_fob_code_idx) := g_value_present;
866 
867 		IF l_debug_on THEN
868 		   WSH_DEBUG_SV.logmsg(l_module_name,'Fob Code');
869 		END IF;
870 
871 	     END IF;
872 
873 	     EXIT WHEN itr = l_attr_tab.LAST;
874 	     itr := l_attr_tab.NEXT(itr);
875 	END LOOP;
876     END IF;
877 
878     get_sorted_priority_tab( p_attribute_tab   => l_group_attr,
879 			     x_priority_tab    => l_priority_tab,
880 			     x_return_status   => x_return_status);
881 
882     IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
883        IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
884            raise FND_API.G_EXC_UNEXPECTED_ERROR;
885         END IF;
886     END IF;
887 
888     l_group_cache_rec.attribute_tab := l_group_attr;
889     l_group_cache_rec.priority_tab  := l_priority_tab;
890 
891     g_groups_cache(p_group_id):=l_group_cache_rec;
892 
893     IF l_debug_on THEN
894 
895 	    itr := l_priority_tab.FIRST;
896 	    l_priority_str := l_priority_tab(itr);
897 
898 	    IF NOT (itr = l_priority_tab.LAST) THEN
899             LOOP
900 	    	itr := l_priority_tab.NEXT(itr);
901 		l_priority_str := l_priority_str ||'-'||l_priority_tab(itr);
902 		EXIT WHEN itr = l_priority_tab.LAST;
903             END LOOP;
904             END IF;
905 
906             WSH_DEBUG_SV.log(l_module_name,'Priorities To be checked',l_priority_str);
907             WSH_DEBUG_SV.POP (l_module_name);
908     END IF;
909 
910 EXCEPTION
911 WHEN OTHERS THEN
912 
913       IF c_get_group_attributes%ISOPEN THEN
914  	 CLOSE c_get_group_attributes;
915       END IF;
916 
917       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.add_group_to_cache');
918       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
919 
920       IF l_debug_on THEN
921         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
922         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
923       END IF;
924       --
925 END add_group_to_group_cache;
926 
927 
928 --***************************************************************************--
929 --========================================================================
930 -- PROCEDURE : add_to_non_range_cache         PRIVATE
931 --
932 -- PARAMETERS: p_cache			  Global cache to be modified
933 --             p_fixed_key                Key for the attribute value
934 --	       p_null_key		  Key used if attribute value is null.
935 --	       p_rule_id	          Rule id to be added
936 --	       x_return_status		  Return Status
937 --
938 -- COMMENT   : Adds a rule to Non Range Cache
939 --
940 --
941 -- ALGORITHM :
942 --	       1. IF NULL_KEY THEN index is NULL_KEY ELSE index is FIXED_KEY
943 --	       2. Insert the record at proper index
944 --***************************************************************************--
945 PROCEDURE add_to_non_range_cache ( p_cache		IN OUT NOCOPY EXACT_MATCH_CACHE,
946 			           p_fixed_key		IN VARCHAR2 DEFAULT NULL,
947 				   p_null_key		IN VARCHAR2 DEFAULT NULL,
948 				   p_rule_id		IN NUMBER,
949 				   x_return_status OUT NOCOPY VARCHAR2)
950 IS
951 
952   l_rule_tab 	exact_match_tab;
953   l_key		VARCHAR2(32767);
954 
958 BEGIN
955   l_debug_on          CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
956   l_module_name       CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'add_to_non_range_cache';
957 
959 
960      x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
961 
962      IF l_debug_on THEN
963        WSH_DEBUG_SV.push(l_module_name);
964        WSH_DEBUG_SV.log(l_module_name,'p_fixed_key',p_fixed_key);
965        WSH_DEBUG_SV.log(l_module_name,'p_null_key ', p_null_key);
966        WSH_DEBUG_SV.log(l_module_name,'p_rule_id  ',p_rule_id);
967      END IF;
968 
969      IF (p_fixed_key IS NOT NULL) THEN
970 	l_key := p_fixed_key;
971      ELSE
972 	l_key := p_null_key;
973      END IF;
974 
975      IF (p_cache.EXISTS(l_key)) THEN
976 	        -- Add new rule to table present
977 		l_rule_tab := p_cache(l_key);
978 		l_rule_tab(l_rule_tab.COUNT) := p_rule_id;
979      ELSE
980 	-- Add new table
981 	l_rule_tab(0) := p_rule_id;
982      END IF;
983 
984      p_cache(l_key) := l_rule_tab;
985 
986      IF l_debug_on THEN
987         WSH_DEBUG_SV.POP (l_module_name);
988      END IF;
989 
990 EXCEPTION
991 WHEN others THEN
992       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.ADD_TO_NON_RANGE_CACHE');
993       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
994 
995       IF l_debug_on THEN
996         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
997         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
998       END IF;
999      --
1000 END add_to_non_range_cache;
1001 
1002 --***************************************************************************--
1003 --========================================================================
1004 -- PROCEDURE : add_to_range_cache         PRIVATE
1005 --
1006 -- PARAMETERS: p_cache			  Global cache to be modified
1007 --             p_key_low                  Lower range break
1008 --	       p_key_high                 Higher range break
1009 --	       p_null_key		  Key used if attribute value is null.
1010 --	       p_overlap_flag            Indicates whether there is overlap in the range or not
1011 --	       p_rule_id	          Rule id to be added
1012 --	       x_return_status		  Return Status
1013 --
1014 -- COMMENT   : Adds a rule to Range Cache
1015 --
1016 --
1017 -- ALGORITHM :
1018 --	      1. If NULL_KEY then create null_key Records else Low/High Records.
1019 --	      2. Insert the record at proper index
1020 --***************************************************************************--
1021 PROCEDURE add_to_range_cache( p_cache	      IN OUT NOCOPY RANGE_MATCH_CACHE,
1022 			      p_key_low       IN VARCHAR2 DEFAULT NULL,
1023 			      p_key_high      IN VARCHAR2 DEFAULT NULL,
1024 			      p_null_key      IN VARCHAR2 DEFAULT NULL,
1025 			      p_overlap_flag  IN VARCHAR2 DEFAULT 'Y',
1026 			      p_rule_id	      IN NUMBER,
1027 			      x_return_status OUT NOCOPY VARCHAR2)
1028 IS
1029 
1030 l_rule_rec_low		range_match_rule_rec;
1031 l_rule_rec_high		range_match_rule_rec;
1032 l_rule_rec_null		range_match_rule_rec;
1033 
1034 l_rule_tab_low		range_match_tab;
1035 l_rule_tab_high		range_match_tab;
1036 l_rule_tab_null		range_match_tab;
1037 
1038 l_debug_on              CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
1039 l_module_name           CONSTANT VARCHAR2(100) := 'wsh.plsql.' ||G_PKG_NAME ||'.'||'add_to_range_cache';
1040 
1041 BEGIN
1042 
1043         x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
1044 
1045         IF l_debug_on THEN
1046 
1047 	     WSH_DEBUG_SV.push(l_module_name);
1048              WSH_DEBUG_SV.log(l_module_name,'p_key_low   ',p_key_low);
1049              WSH_DEBUG_SV.log(l_module_name,'p_key_high  ',p_key_high);
1050              WSH_DEBUG_SV.log(l_module_name,'p_null_key  ',p_null_key);
1051              WSH_DEBUG_SV.log(l_module_name,'p_overlap_flag',p_overlap_flag);
1052 	     WSH_DEBUG_SV.log(l_module_name,'p_rule_id    ',p_rule_id);
1053 
1054         END IF;
1055 
1056 	IF (p_null_key IS NULL) THEN
1057 
1058 	    --
1059 	    -- Create the records
1060 	    --
1061 
1062 	    l_rule_rec_low.rule_id       := p_rule_id;
1063 	    l_rule_rec_low.overlap_flag  := p_overlap_flag;
1064 	    l_rule_rec_low.limit         := g_low_range_break;
1065 
1066 	    l_rule_rec_high.rule_id      := p_rule_id;
1067 	    l_rule_rec_high.overlap_flag := p_overlap_flag;
1068 	    l_rule_rec_high.limit        := g_high_range_break;
1069 
1070     	    --
1071 	    -- Add the records to the cache
1072 	    --
1073 
1074 	    IF (p_cache.EXISTS(p_key_low)) THEN
1075 		l_rule_tab_low := p_cache(p_key_low);
1076 		l_rule_tab_low(l_rule_tab_low.COUNT) := l_rule_rec_low;
1077 	    ELSE
1078 	 	l_rule_tab_low(0) := l_rule_rec_low;
1079 	    END IF;
1080 
1081 	    p_cache(p_key_low) := l_rule_tab_low;
1082 
1083 	    IF (p_cache.EXISTS(p_key_high)) THEN
1084 		l_rule_tab_high := p_cache(p_key_high);
1085 		l_rule_tab_high(l_rule_tab_high.COUNT) := l_rule_rec_high;
1086 	    ELSE
1087 		l_rule_tab_high(0) := l_rule_rec_high;
1088 	    END IF;
1089 	    p_cache(p_key_high) := l_rule_tab_high;
1090 
1091 	 ELSE
1092 
1093 	    l_rule_rec_null.rule_id       := p_rule_id;
1094 	    l_rule_rec_null.overlap_flag  := p_overlap_flag;
1095 	    l_rule_rec_null.limit         := g_null_range;
1096 
1097 	    IF (p_cache.EXISTS(p_null_key)) THEN
1098 		l_rule_tab_null := p_cache(p_null_key);
1099 		l_rule_tab_null(l_rule_tab_null.COUNT) := l_rule_rec_null;
1100    	    ELSE
1101 		l_rule_tab_null(0) := l_rule_rec_null;
1102 	    END IF;
1103 
1104 	    p_cache(p_null_key) := l_rule_tab_null;
1105 
1106          END IF;
1110          END IF;
1107 
1108          IF l_debug_on THEN
1109             WSH_DEBUG_SV.POP (l_module_name);
1111 
1112 EXCEPTION
1113 WHEN others THEN
1114 
1115       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.ADD_TO_RANGE_CACHE');
1116       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
1117 
1118       IF l_debug_on THEN
1119         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
1120         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
1121       END IF;
1122 END add_to_range_cache;
1123 
1124 
1125 --***************************************************************************--
1126 --========================================================================
1127 -- PROCEDURE : build_cache                PRIVATE
1128 --
1129 -- PARAMETERS: p_group_id		  Group id to be used
1130 --	       x_return_status		  Return Status
1131 --
1132 -- COMMENT   : For a given group id creates the cache.
1133 --
1134 --
1135 -- ALGORITHM :
1136 --	      1, Drop the cache if number of groups is more than the limit.
1137 --	      2. Query for all the rules within a group.
1138 --            3. Check if overlap flag is set for a sample rule.
1139 --                 If flag is not set then call FTE_ACS_RULE_UTIL_PKG.SET_overlap_FLAG
1140 --	      4. For all Rules
1141 --			Get all the attributes for a rule.
1142 --			Put the respective attributes in respective caches.
1143 --
1144 --***************************************************************************--
1145 PROCEDURE build_cache(p_group_id	IN  NUMBER,
1146 		      x_return_status	OUT NOCOPY VARCHAR)
1147 
1148 IS
1149 
1150 CURSOR  C_GET_RULE_RESTRICTIONS IS
1151 SELECT  rule_id,
1152         attribute_name,
1153         attribute_value_From,
1154         attribute_value_to,
1155         attribute_value_from_number,
1156         attribute_value_to_number,
1157 	range_overlap_flag
1158 FROM    fte_sel_rule_restrictions
1159 WHERE   group_id = p_group_id
1160 ORDER BY rule_id;
1161 
1162 
1163 curr_rule_id        NUMBER;
1164 prev_rule_id	    NUMBER;
1165 
1166 from_weight		    NUMBER;
1167 to_weight		    NUMBER;
1168 weight_overlap	    VARCHAR2(1);
1169 
1170 from_volume		    NUMBER;
1171 to_volume		    NUMBER;
1172 volume_overlap      VARCHAR2(1);
1173 
1174 from_transit_time	NUMBER;
1175 to_transit_time 	NUMBER;
1176 transit_overlap     VARCHAR2(1);
1177 
1178 from_region		    NUMBER;
1179 to_region		    NUMBER;
1180 
1181 from_postal_low		VARCHAR2(240);
1182 from_postal_high	VARCHAR2(240);
1183 from_postal_overlap	VARCHAR2(1);
1184 
1185 to_postal_low		VARCHAR2(240);
1186 to_postal_high		VARCHAR2(240);
1187 to_postal_overlap	VARCHAR2(1);
1188 
1189 fob_code		    VARCHAR2(240);
1190 
1191 rule_tab		    RULES_TAB_TYPE;
1192 
1193 fixed_key		    VARCHAR2(32767);
1194 null_key		    VARCHAR2(32767);
1195 key_low			    VARCHAR2(32767);
1196 key_high		    VARCHAR2(32767);
1197 
1198 itr			        NUMBER;
1199 next_itr		    NUMBER;
1200 next_rule_id		NUMBER;
1201 
1202 l_group_attr		WSH_UTIL_CORE.ID_TAB_TYPE;
1203 
1204 l_debug_on          CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
1205 l_module_name       CONSTANT VARCHAR2(100) := 'wsh.plsql.'||G_PKG_NAME||'.'||'build_cache';
1206 
1207 --
1208 --Exceptions
1209 --
1210 FTE_CS_ERROR_INVALID_RANGE  EXCEPTION;
1211 
1212 BEGIN
1213 
1214     x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
1215 
1216     IF l_debug_on THEN
1217         WSH_DEBUG_SV.push(l_module_name);
1218         WSH_DEBUG_SV.log(l_module_name,'p_group_id   ',p_group_id);
1219     END IF;
1220 
1221     refresh_cache(x_return_status);
1222 
1223     -- We will not have greater than, because it means we first add and then drop
1224     -- the cache.
1225     IF ( g_groups_cache.COUNT = g_max_cache_size ) THEN
1226 	  DELETE_RULE_CACHES(x_return_status => x_return_status);
1227     END IF;
1228 
1229     --
1230     -- Add group to the group cache.
1231     --
1232     add_group_to_group_cache( p_group_id      => p_group_id,
1233    	                      x_return_status => x_return_status);
1234 
1235     l_group_attr:=  g_groups_cache(p_group_id).attribute_tab;
1236 
1237 
1238     OPEN  c_get_rule_restrictions;
1239     FETCH c_get_rule_restrictions BULK COLLECT INTO rule_tab;
1240     CLOSE c_get_rule_restrictions;
1241 
1242     itr := rule_tab.FIRST;
1243 
1244     IF (itr IS NOT NULL) THEN
1245 
1246 	--
1247 	-- overlap flag has to be either 'Y' or 'N'
1248 	--
1249 	IF (rule_tab(itr).overlap_flag IS NULL) THEN
1250 
1251 		--
1252 		-- overlap flag needs to be set
1253 		--
1254 
1255 		FTE_ACS_RULE_UTIL_PKG.SET_RANGE_OVERLAP_FLAG(p_group_id	 => p_group_id);
1256 
1257 		--
1258 		-- Delete Rule Tab and query again.
1259 		--
1260 		rule_tab.DELETE;
1261 
1262 		OPEN  c_get_rule_restrictions;
1263 		FETCH c_get_rule_restrictions BULK COLLECT INTO rule_tab;
1264 		CLOSE c_get_rule_restrictions;
1265 		itr := rule_tab.FIRST;
1266 	END IF;
1267     END IF;
1268 
1269 
1270     IF (itr IS NOT NULL) THEN
1271     LOOP
1272 	 --
1273 	 --Initialize the default Values;
1274 	 --
1275 	 curr_rule_id      := rule_tab(itr).rule_id;
1276      from_region       := g_num_absent;
1277   	 to_region         := g_num_absent;
1278 	 from_postal_low   := g_val_absent;
1279 	 from_postal_high  := g_val_absent;
1280 	 to_postal_low     := g_val_absent;
1281 	 to_postal_high    := g_val_absent;
1282 	 from_weight       := g_num_absent;
1286 	 from_transit_time := g_num_absent;
1283 	 to_weight         := g_num_absent;
1284 	 from_volume       := g_num_absent;
1285 	 to_volume         := g_num_absent;
1287 	 to_transit_time   := g_num_absent;
1288 	 fob_code          := g_val_absent;
1289 
1290   	 --
1291 	 -- Get the values for a rule.
1292 	 --
1293 	 LOOP
1294 
1295 	    -- For Weight Volume Conversions we use display weight and volume.
1296 	    IF ( rule_tab(itr).attribute_name = 'DISPLAY_WEIGHT') THEN
1297 
1298 		 from_weight     := rule_tab(itr).attribute_value_from_number;
1299 		 to_weight       := rule_tab(itr).attribute_value_to_number;
1300 	     weight_overlap  := rule_tab(itr).overlap_flag;
1301 
1302 	    ELSIF (rule_tab(itr).attribute_name = 'DISPLAY_VOLUME') THEN
1303 
1304 		 from_volume    := rule_tab(itr).attribute_value_from_number;
1305 		 to_volume      := rule_tab(itr).attribute_value_to_number;
1306          volume_overlap := rule_tab(itr).overlap_flag;
1307 
1308 	    ELSIF (rule_tab(itr).attribute_name = 'TRANSIT_TIME') THEN
1309 
1310 		 from_transit_time    := rule_tab(itr).attribute_value_from_number;
1311 	     to_transit_time      := rule_tab(itr).attribute_value_to_number;
1312 		 transit_overlap      := rule_tab(itr).overlap_flag;
1313 
1314    	    ELSIF (rule_tab(itr).attribute_name = 'FROM_REGION_POSTAL_CODE') THEN
1315 
1316 	 	 from_postal_low	 := rule_tab(itr).attribute_value_from;
1317     	 from_postal_high := rule_tab(itr).attribute_value_to;
1318 
1319   	    ELSIF (rule_tab(itr).attribute_name = 'TO_REGION_POSTAL_CODE') THEN
1320 
1321 	  	 to_postal_low	:= rule_tab(itr).attribute_value_from;
1322 		 to_postal_high := rule_tab(itr).attribute_value_to;
1323 
1324 	    ELSIF (rule_tab(itr).attribute_name = 'FROM_REGION_ID') THEN
1325 
1326 		 from_region  := rule_tab(itr).attribute_value_from_number;
1327 
1328   	    ELSIF (rule_tab(itr).attribute_name = 'TO_REGION_ID') THEN
1329 
1330 	 	 to_region    := rule_tab(itr).attribute_value_from_number;
1331 
1332   	    ELSIF (rule_tab(itr).attribute_name = 'FOB_CODE') THEN
1333 
1334 	 	 fob_code     := rule_tab(itr).attribute_value_from;
1335 
1336 	    END IF;
1337 
1338 	    IF ( itr = rule_tab.LAST ) THEN
1339 	         EXIT;
1340 	    ELSE
1341 	        next_itr     := rule_tab.NEXT(itr);
1342 	        next_rule_id := rule_tab(next_itr).rule_id;
1343 	        EXIT WHEN next_rule_id <> curr_rule_id;
1344 	        itr := next_itr;
1345 	    END IF;
1346 
1347         END LOOP;
1348 
1349 	    IF l_debug_on THEN
1350 
1351             WSH_DEBUG_SV.log(l_module_name,' Rule ID           ', curr_rule_id );
1352             WSH_DEBUG_SV.log(l_module_name,' From_region       ', from_region );
1353             WSH_DEBUG_SV.log(l_module_name,' To_region         ', to_region);
1354             WSH_DEBUG_SV.log(l_module_name,' From_postal_low   ', from_postal_low);
1355             WSH_DEBUG_SV.log(l_module_name,' From_postal_high  ', from_postal_high);
1356             WSH_DEBUG_SV.log(l_module_name,' To_postal_low     ', to_postal_low);
1357             WSH_DEBUG_SV.log(l_module_name,' To_postal_high    ', to_postal_high);
1358             WSH_DEBUG_SV.log(l_module_name,' From_weight       ', from_weight);
1359             WSH_DEBUG_SV.log(l_module_name,' To_weight         ', to_weight);
1360             WSH_DEBUG_SV.log(l_module_name,' From_volume       ', from_volume);
1361             WSH_DEBUG_SV.log(l_module_name,' To_volume         ', to_volume);
1362             WSH_DEBUG_SV.log(l_module_name,' From_transit_time ', from_transit_time);
1363             WSH_DEBUG_SV.log(l_module_name,' To_transit_time   ', to_transit_time);
1364             WSH_DEBUG_SV.log(l_module_name,' Fob_code          ', fob_code);
1365 
1366         END IF;
1367 
1368         fixed_key  := get_fixed_key(p_group_id        => p_group_id,
1369 			                        p_from_region_id  => from_region,
1370 	   			                    p_to_region_id    => to_region);
1371 
1372 
1373 	    null_key   := get_key_for_null(p_fixed_key    => fixed_key);
1374 
1375         --
1376         --Register From-To-Region combination in the  From-To-Region-Cache
1377         --Register using dummy value
1378         --
1379         g_from_to_region_cache(fixed_key) := g_value_present;
1380 
1381         --
1382         -- In range attributes either both from and to will be present
1383         -- or none will be present
1384         -- Only add value to the cache if the attribute is present in the group.
1385 
1386  	IF (l_group_attr.EXISTS(g_wt_idx)) THEN
1387 
1388 	   IF l_debug_on THEN
1389  		   WSH_DEBUG_SV.logmsg(l_module_name,'Adding to Weight Cache');
1390 	   END IF;
1391 
1392 	   IF (from_weight <> g_num_absent) AND (to_weight <> g_num_absent) THEN
1393 
1394        	    key_low  := get_key_for_num( p_fixed_key => fixed_key,
1395 		  		             p_number    => from_weight);
1396 
1397 	        key_high := get_key_for_num( p_fixed_key => fixed_key,
1398 		  		             p_number   => to_weight);
1399 
1400 
1401 		    add_to_range_cache( p_cache         => g_weight_cache,
1402 				    p_key_low       => key_low,
1403 				    p_key_high      => key_high,
1404 				    p_overlap_flag => weight_overlap,
1405 				    p_rule_id	    => curr_rule_id,
1406 				    x_return_status => x_return_status);
1407 
1408 		    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1409 		     IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1410 		         raise FND_API.G_EXC_UNEXPECTED_ERROR;
1411 		     END IF;
1412 	        END IF;
1413 
1414 	    ELSIF (from_weight = g_num_absent) AND (to_weight = g_num_absent) THEN
1415 
1416 
1417 		    add_to_range_cache( p_cache         => g_weight_cache,
1418 		   		    p_null_key      => null_key,
1419 				    p_rule_id       => curr_rule_id,
1420 				    x_return_status => x_return_status);
1421 
1425                 END IF;
1422 		    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1423                 IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1424                    raise FND_API.G_EXC_UNEXPECTED_ERROR;
1426 		    END IF;
1427 	    ELSE
1428 		    RAISE FTE_CS_ERROR_INVALID_RANGE;
1429 	    END IF;
1430 	END IF;
1431 
1432 	IF (l_group_attr.EXISTS(g_vol_idx)) THEN
1433 
1434 
1435 	  IF l_debug_on THEN
1436  		   WSH_DEBUG_SV.logmsg(l_module_name,'Adding to Volume Cache');
1437 	  END IF;
1438 
1439 	  IF (from_volume <> g_num_absent) AND (to_volume <> g_num_absent) THEN
1440 
1441 		key_low  := get_key_for_num( p_fixed_key  => fixed_key,
1442 		 	 		      p_number    => from_volume);
1443 
1444 		key_high := get_key_for_num( p_fixed_key => fixed_key,
1445 			 		      p_number   => to_volume);
1446 
1447 		add_to_range_cache( p_cache         => g_volume_cache,
1448 				    p_key_low       => key_low,
1449 				    p_key_high      => key_high,
1450 				    p_overlap_flag  => volume_overlap,
1451 				    p_rule_id       => curr_rule_id,
1452 				    x_return_status => x_return_status);
1453 
1454 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1455 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1456 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1457 			END IF;
1458 		END IF;
1459 
1460            ELSIF (from_volume = g_num_absent) AND (to_volume = g_num_absent) THEN
1461 
1462 		add_to_range_cache( p_cache         => g_volume_cache,
1463 		                    p_null_key      => null_key,
1464 			 	    p_rule_id       => curr_rule_id,
1465 				    x_return_status => x_return_status);
1466 
1467 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1468 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1469 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1470 			END IF;
1471 		END IF;
1472 	  ELSE
1473 		 RAISE FTE_CS_ERROR_INVALID_RANGE;
1474 	  END IF;
1475 
1476 	END IF;
1477 
1478 	IF (l_group_attr.EXISTS(g_transit_time_idx)) THEN
1479 
1480  	  IF l_debug_on THEN
1481  		   WSH_DEBUG_SV.logmsg(l_module_name,'Adding to Transit Time Cache');
1482 	  END IF;
1483 
1484 
1485 	  IF (from_transit_time <> g_num_absent) AND (to_transit_time <> g_num_absent) THEN
1486 
1487 		key_low  := get_key_for_num( p_fixed_key => fixed_key,
1488 		 	 		     p_number    => from_transit_time);
1489 
1490 		key_high := get_key_for_num( p_fixed_key => fixed_key,
1491 			 		     p_number    => to_transit_time);
1492 
1493 		add_to_range_cache( p_cache         => g_transit_cache,
1494 				    p_key_low       => key_low,
1495 				    p_key_high      => key_high,
1496 				    p_overlap_flag  => transit_overlap,
1497 				    p_rule_id       => curr_rule_id,
1498 				    x_return_status => x_return_status );
1499 
1500 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1501 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1502 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1503 			END IF;
1504 		END IF;
1505 
1506 	  ELSIF (from_transit_time = g_num_absent) AND (to_transit_time = g_num_absent) THEN
1507 
1508 		add_to_range_cache( p_cache        => g_transit_cache,
1509 		                    p_null_key      => null_key,
1510 				    p_rule_id       => curr_rule_id,
1511 				    x_return_status => x_return_status);
1512 
1513 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1514 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1515 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1516 			END IF;
1517 		END IF;
1518 
1519 	  ELSE
1520 		RAISE FTE_CS_ERROR_INVALID_RANGE;
1521 	  END IF;
1522 
1523 	END IF;
1524 
1525 	IF (l_group_attr.EXISTS(g_to_post_idx)) THEN
1526 
1527 	   IF l_debug_on THEN
1528  		   WSH_DEBUG_SV.logmsg(l_module_name,'Adding to To Postal Code Cache');
1529 	   END IF;
1530 
1531 	   IF (to_postal_low <> g_val_absent) AND (to_postal_high <> g_val_absent) THEN
1532 
1533  		key_low  := get_key_for_char(  p_fixed_key => fixed_key,
1534 			                       p_char      => to_postal_low);
1535 
1536 		key_high := get_key_for_char(  p_fixed_key => fixed_key,
1537 			                       p_char      => to_postal_high);
1538 
1539 
1540 		add_to_range_cache( p_cache         => g_to_postal_cache,
1541 				    p_key_low       => key_low,
1542 				    p_key_high      => key_high,
1543 				    p_overlap_flag  => to_postal_overlap,
1544 	       			    p_rule_id       => curr_rule_id,
1545 				    x_return_status => x_return_status );
1546 
1547 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1548 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1549 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1550 			END IF;
1551 		END IF;
1552 
1553 	  ELSIF (to_postal_low = g_val_absent) AND (to_postal_high = g_val_absent) THEN
1554 
1555 		add_to_range_cache( p_cache         => g_to_postal_cache,
1556 				    p_null_key      => null_key,
1557 	 		            p_rule_id       => curr_rule_id,
1558 				    x_return_status => x_return_status);
1559 
1560 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1561 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1562 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1563 			END IF;
1564 		END IF;
1565 
1566 	  --
1567 	  -- In case of postal code one limit can be null
1568           --
1569 
1570 	  ELSIF (to_postal_low = g_val_absent) AND (to_postal_high <> g_val_absent) THEN
1571 
1572 		IF l_debug_on THEN
1573  		   WSH_DEBUG_SV.logmsg(l_module_name,'Lower postal code is NULL');
1574 		END IF;
1575 
1576 		key_high := get_key_for_char(  p_fixed_key => fixed_key,
1577  					       p_char      => to_postal_high);
1578 
1582 				    p_overlap_flag  => to_postal_overlap,
1579 		add_to_range_cache( p_cache         => g_to_postal_cache,
1580 				    p_key_low       => key_high,
1581 				    p_key_high      => key_high,
1583 	       			    p_rule_id       => curr_rule_id,
1584 				    x_return_status => x_return_status );
1585 
1586 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1587 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1588 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1589 			END IF;
1590 		END IF;
1591 
1592 	  ELSE
1593 
1594 		IF l_debug_on THEN
1595  		   WSH_DEBUG_SV.logmsg(l_module_name,'Upper postal code is NULL');
1596 		END IF;
1597 
1598 		key_low := get_key_for_char(  p_fixed_key => fixed_key,
1599  					      p_char      => to_postal_low);
1600 
1601 		add_to_range_cache( p_cache         => g_to_postal_cache,
1602 				    p_key_low       => key_low,
1603 				    p_key_high      => key_low,
1604 				    p_overlap_flag  => to_postal_overlap,
1605 	       			    p_rule_id       => curr_rule_id,
1606 				    x_return_status => x_return_status );
1607 
1608 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1609 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1610 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1611 			END IF;
1612 		END IF;
1613 	    END IF;
1614 	END IF;
1615 
1616 	IF (l_group_attr.EXISTS(g_fr_post_idx)) THEN
1617 
1618  	    IF l_debug_on THEN
1619  		   WSH_DEBUG_SV.logmsg(l_module_name,'Adding to From Postal Code Cache');
1620     	    END IF;
1621 
1622 	    IF (from_postal_low <> g_val_absent) AND (from_postal_high <> g_val_absent) THEN
1623 
1624 		key_low  := get_key_for_char(  p_fixed_key => fixed_key,
1625 			                       p_char      => from_postal_low);
1626 
1627 		key_high := get_key_for_char(  p_fixed_key => fixed_key,
1628  					       p_char      => from_postal_high);
1629 
1630 		add_to_range_cache( p_cache         => g_from_postal_cache,
1631 				    p_key_low       => key_low,
1632 				    p_key_high      => key_high,
1633 				    p_overlap_flag  => from_postal_overlap,
1634 	       			    p_rule_id       => curr_rule_id,
1635 				    x_return_status => x_return_status );
1636 
1637 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1638 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1639 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1640 			END IF;
1641 		END IF;
1642 
1643 	    ELSIF (from_postal_low = g_val_absent) AND (from_postal_high = g_val_absent) THEN
1644 
1645 	        IF l_debug_on THEN
1646  		   WSH_DEBUG_SV.logmsg(l_module_name,'Both from and to Postal Codes are NULL');
1647 		END IF;
1648 
1649 		add_to_range_cache( p_cache         => g_from_postal_cache,
1650 		 		    p_null_key      => null_key,
1651 				    p_rule_id       => curr_rule_id,
1652 				    x_return_status => x_return_status);
1653 
1654 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1655 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1656 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1657 			END IF;
1658 		END IF;
1659 
1660 	    ELSIF (from_postal_low = g_val_absent) AND (from_postal_high <> g_val_absent) THEN
1661 
1662 		IF l_debug_on THEN
1663  		   WSH_DEBUG_SV.logmsg(l_module_name,'Lower postal code is NULL');
1664 		END IF;
1665 
1666 		key_high := get_key_for_char(  p_fixed_key => fixed_key,
1667  					       p_char      => from_postal_high);
1668 
1669 		add_to_range_cache( p_cache         => g_from_postal_cache,
1670 				    p_key_low       => key_high,
1671 				    p_key_high      => key_high,
1672 				    p_overlap_flag  => from_postal_overlap,
1673 	       			    p_rule_id       => curr_rule_id,
1674 				    x_return_status => x_return_status );
1675 
1676 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1677 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1678 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1679 			END IF;
1680 		END IF;
1681 
1682 	    ELSE
1683 
1684 		IF l_debug_on THEN
1685  		   WSH_DEBUG_SV.logmsg(l_module_name,'Upper postal code is NULL');
1686 		END IF;
1687 
1688 		key_low := get_key_for_char(  p_fixed_key => fixed_key,
1689  					      p_char      => from_postal_low);
1690 
1691 		add_to_range_cache( p_cache         => g_from_postal_cache,
1692 				    p_key_low       => key_low,
1693 				    p_key_high      => key_low,
1694 				    p_overlap_flag  => from_postal_overlap,
1695 	       			    p_rule_id       => curr_rule_id,
1696 				    x_return_status => x_return_status );
1697 
1698 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1699 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1700 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1701 			END IF;
1702 		END IF;
1703 
1704 	    END IF;
1705 
1706 	END IF;
1707 
1708 	IF (l_group_attr.EXISTS(g_fob_code_idx)) THEN
1709 
1710             IF l_debug_on THEN
1711  		   WSH_DEBUG_SV.logmsg(l_module_name,'Adding to FOB Cache');
1712    	    END IF;
1713 
1714 	    IF ( fob_code <> g_val_absent) THEN
1715 
1716 		key_low  := get_key_for_char(  p_fixed_key => fixed_key,
1717 			                       p_char      => fob_code);
1718 
1719 		add_to_non_range_cache( p_cache         => g_fob_cache,
1720 	  			        p_fixed_key     => key_low,
1721 	       			        p_rule_id       => curr_rule_id,
1722 				        x_return_status => x_return_status );
1723 
1724 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1725 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1726 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1727 			END IF;
1728 		END IF;
1729 
1730 	    ELSE
1731 		add_to_non_range_cache( p_cache         => g_fob_cache,
1732 			 	        p_null_key      => null_key,
1736 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1733  					p_rule_id       => curr_rule_id,
1734 				        x_return_status => x_return_status);
1735 
1737 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1738 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1739 			END IF;
1740 		END IF;
1741 	    END IF;
1742 	END IF;
1743 
1744 	EXIT WHEN itr = rule_tab.LAST;
1745         itr := rule_tab.NEXT(itr);
1746    END LOOP;
1747 
1748    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
1749       IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
1750 	   raise FND_API.G_EXC_UNEXPECTED_ERROR;
1751       END IF;
1752    END IF;
1753 
1754    END IF;
1755 
1756    IF l_debug_on THEN
1757       WSH_DEBUG_SV.POP (l_module_name);
1758    END IF;
1759 
1760 EXCEPTION
1761     WHEN FTE_CS_ERROR_INVALID_RANGE THEN
1762 
1763       IF c_get_rule_restrictions%ISOPEN THEN
1764          CLOSE c_get_rule_restrictions;
1765       END IF;
1766       --
1767       x_return_status := WSH_UTIL_CORE.G_RET_STS_ERROR;
1768       --
1769       IF l_debug_on THEN
1770         WSH_DEBUG_SV.pop(l_module_name,'Attribute Range has either FROM or TO Only (Range is Invalid');
1771       END IF;
1772 
1773     WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
1774 
1775       IF c_get_rule_restrictions%ISOPEN THEN
1776          CLOSE c_get_rule_restrictions;
1777       END IF;
1778 
1779       --
1780       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR ;
1781       --
1782       IF l_debug_on THEN
1783         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
1784         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
1785       END IF;
1786       --
1787 
1788     WHEN others THEN
1789 
1790       IF c_get_rule_restrictions%ISOPEN THEN
1791          CLOSE c_get_rule_restrictions;
1792       END IF;
1793 
1794       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.ADD_TO_RANGE_CACHE');
1795       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
1796       --
1797       IF l_debug_on THEN
1798         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
1799         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
1800       END IF;
1801 
1802 END build_cache;
1803 
1804 
1805 --***************************************************************************--
1806 --========================================================================
1807 -- PROCEDURE  : search_exact_cache_for_null     PRIVATE
1808 --
1809 -- PARAMETERS:  p_cache			EXACT_MATCH_CACHE to be searched
1810 --	        p_fixed_key		Fixed key to be used.
1811 --		x_result_tab		Matching Rules.
1812 --		x_return_status		Return Status
1813 --
1814 -- COMMENT   : This API returns all the rules which have null as matching attributes
1815 --
1816 --***************************************************************************--
1817 PROCEDURE search_exact_cache_for_null(	p_cache			IN		EXACT_MATCH_CACHE,
1818 					p_fixed_key		IN		VARCHAR2,
1819 					x_result_tab		OUT NOCOPY 	rule_match_tab,
1820 					x_return_status		OUT NOCOPY	VARCHAR2)
1821 IS
1822 	l_null_key	VARCHAR2(32767);
1823 	l_rule_tab      exact_match_tab;
1824 	itr		NUMBER;
1825 
1826 	l_debug_on          CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
1827 	l_module_name       CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'search_exact_cache_for_null';
1828 
1829 BEGIN
1830 
1831 	IF l_debug_on THEN
1832 	      wsh_debug_sv.push (l_module_name);
1833 	END IF;
1834 
1835 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
1836 
1837 	l_null_key := get_key_for_null ( p_fixed_key) ;
1838 
1839 	IF (p_cache.EXISTS(l_null_key)) THEN
1840 		l_rule_tab := p_cache(l_null_key);
1841 		itr := l_rule_tab.FIRST;
1842 
1843 		IF (itr IS NOT NULL) THEN
1844 		  LOOP
1845 			IF (x_result_tab IS NULL) THEN
1846 			    x_result_tab:= rule_match_tab(l_rule_tab(itr));
1847 			ELSE
1848 			    x_result_tab.EXTEND;
1849 			    x_result_tab(x_result_tab.COUNT):= l_rule_tab(itr);
1850 			END IF;
1851 			EXIT WHEN itr = l_rule_tab.LAST;
1852 			itr := l_rule_tab.NEXT(itr);
1853 		  END LOOP;
1854 		END IF;
1855 	END IF;
1856 
1857 	IF l_debug_on THEN
1858                   WSH_DEBUG_SV.POP (l_module_name);
1859 	END IF;
1860 
1861 EXCEPTION
1862       WHEN others THEN
1863 
1864       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.search_exact_cache_for_null');
1865       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
1866 
1867       IF l_debug_on THEN
1868         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
1869         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
1870       END IF;
1871       --
1872 END search_exact_cache_for_null;
1873 
1874 
1875 --***************************************************************************--
1876 --========================================================================
1877 -- PROCEDURE  : search_range_cache_for_null     PRIVATE
1878 --
1879 -- PARAMETERS:  p_cache			RANGE_MATCH_CACHE to be searched
1880 --	        p_fixed_key		Fixed key to be used.
1881 --		x_result_tab		Matching Rules (This will be a non index by variable)
1882 --		x_return_status		Return Status
1883 --
1884 -- COMMENT   : This API returns all the rules which have null as matching attributes
1885 --
1886 --***************************************************************************--
1890 				       x_return_status	OUT NOCOPY	VARCHAR2)
1887 PROCEDURE search_range_cache_for_null( p_cache		IN		RANGE_MATCH_CACHE,
1888 				       p_fixed_key	IN		VARCHAR2,
1889 				       x_result_tab	OUT NOCOPY 	rule_match_tab,
1891 IS
1892 
1893 	l_null_key	VARCHAR2(32767);
1894 	l_rule_tab      range_match_tab;
1895 	itr		NUMBER;
1896 
1897 	l_debug_on          CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
1898 	l_module_name       CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'search_range_cache_for_null';
1899 
1900 BEGIN
1901 
1902 	IF l_debug_on THEN
1903 	      wsh_debug_sv.push (l_module_name);
1904 	END IF;
1905 
1906 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
1907 
1908 	l_null_key := get_key_for_null(p_fixed_key);
1909 
1910 	IF (p_cache.EXISTS(l_null_key)) THEN
1911 
1912 		l_rule_tab := p_cache(l_null_key);
1913 
1914 		itr := l_rule_tab.FIRST;
1915 
1916 		IF (itr IS NOT NULL) THEN
1917 		  LOOP
1918 			-- Type casting needs to be done.
1919 			IF (x_result_tab IS NULL) THEN
1920 
1921 			    x_result_tab:= rule_match_tab(l_rule_tab(itr).rule_id);
1922 
1923 			ELSE
1924 			    x_result_tab.EXTEND;
1925 			    x_result_tab(x_result_tab.COUNT):= l_rule_tab(itr).rule_id;
1926 
1927 			END IF;
1928 			EXIT WHEN itr = l_rule_tab.LAST;
1929 			itr := l_rule_tab.NEXT(itr);
1930 		  END LOOP;
1931 		END IF;
1932 	END IF;
1933 
1934 	IF l_debug_on THEN
1935            WSH_DEBUG_SV.POP (l_module_name);
1936 	END IF;
1937 
1938 EXCEPTION
1939 WHEN others THEN
1940 
1941       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.search_range_cache_for_null');
1942       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
1943       IF l_debug_on THEN
1944 	  WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
1945 	  WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
1946       END IF;
1947       --
1948 END search_range_cache_for_null;
1949 
1950 
1951 --***************************************************************************--
1952 --========================================================================
1953 -- PROCEDURE  : get_higher_breaks     PRIVATE
1954 --
1955 -- PARAMETERS:  p_cache			Range Cache to be searched
1956 --		p_start_idx		Starting index for search.
1957 --	        p_fixed_key		Fixed key to be used.
1958 --		p_null_key		Null key.
1959 --		x_rule_tab		Rules having higher breaks.
1960 --		x_return_status		Return Status
1961 --
1962 -- COMMENT   : This API returns all the rules with have upper range break  more
1963 --	       than the attribute value.
1964 --***************************************************************************--
1965 PROCEDURE get_higher_breaks( p_cache		IN	RANGE_MATCH_CACHE,
1966 			     p_start_idx	IN	VARCHAR2,
1967 			     p_fixed_key	IN	VARCHAR2,
1968 			     p_null_key		IN	VARCHAR2,
1969 			     x_rule_tab		OUT NOCOPY RULE_MATCH_TAB,
1970 			     x_return_status    OUT NOCOPY VARCHAR2)
1971 IS
1972 	l_curr_idx	VARCHAR2(32767);
1973 	l_rule_tab	range_match_tab;
1974 	itr		NUMBER;
1975 	l_debug_on      CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
1976 	l_module_name  CONSTANT VARCHAR2(100) := 'wsh.plsql.'||G_PKG_NAME||'.'||'GET_HIGHER_BREAKS';
1977 BEGIN
1978 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
1979 
1980 	IF l_debug_on THEN
1981  	   wsh_debug_sv.push(l_module_name);
1982 	END IF;
1983 
1984 	l_curr_idx := p_cache.NEXT(p_start_idx);
1985 
1986 	--
1987 	-- All the rules to be searched should have the same fixed key.
1988 	-- Null key attributes should not be considered.
1989 	--
1990 
1991 	WHILE (l_curr_idx IS NOT NULL AND l_curr_idx <> p_null_key AND INSTR(l_curr_idx,p_fixed_key,1,1) = 1)
1992 	LOOP
1993 
1994 	     l_rule_tab := p_cache(l_curr_idx);
1995 	     itr := l_rule_tab.FIRST;
1996 
1997 	     IF (itr IS NOT NULL) THEN
1998 		LOOP
1999 		IF (l_rule_tab(itr).limit=g_high_range_break) THEN
2000 
2001 		     IF (x_rule_tab IS NULL) THEN
2002 		 	 x_rule_tab := rule_match_tab(l_rule_tab(itr).rule_id);
2003 		     ELSE
2004 			 x_rule_tab.EXTEND;
2005 			 x_rule_tab(x_rule_tab.COUNT) := l_rule_tab(itr).rule_id;
2006 		     END IF;
2007 		END IF;
2008 
2009 		EXIT WHEN itr = l_rule_tab.LAST;
2010 		itr := l_rule_tab.NEXT(itr);
2011 		END LOOP;
2012 
2013 	      END IF;
2014 
2015 	      l_curr_idx := p_cache.NEXT(l_curr_idx);
2016 	 END LOOP;
2017 
2018 	 IF l_debug_on THEN
2019              WSH_DEBUG_SV.POP(l_module_name);
2020 	 END IF;
2021 
2022 EXCEPTION
2023 WHEN others THEN
2024 
2025       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.get_higher_breaks');
2026       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
2027 
2028       IF l_debug_on THEN
2029         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
2030         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
2031       END IF;
2032       --
2033 END get_higher_breaks;
2034 
2035 
2036 --***************************************************************************--
2037 --========================================================================
2038 -- PROCEDURE  : get_lower_breaks     PRIVATE
2039 --
2040 -- PARAMETERS:  p_cache			Range Cache to be searched
2041 --		p_start_idx		Starting index for search.
2042 --	        p_fixed_key		Fixed key to be used.
2043 --		p_null_key		Null key.
2044 --		x_rule_tab		Rules with lower breaks.
2045 --		x_return_status		Return Status
2046 --
2047 -- COMMENT   : This API returns all the rules with have lower break less
2051 PROCEDURE get_lower_breaks( p_cache		IN	   RANGE_MATCH_CACHE,
2048 --	       than the attribute value.
2049 --
2050 --***************************************************************************--
2052 			    p_start_idx		IN	   VARCHAR2,
2053 			    p_null_key		IN	   VARCHAR2,
2054 			    p_fixed_key		IN	   VARCHAR2,
2055 			    x_rule_tab		OUT NOCOPY RULE_MATCH_TAB,
2056 			    x_return_status	OUT NOCOPY VARCHAR2)
2057 IS
2058 
2059   l_curr_idx	VARCHAR2(32767);
2060   l_rule_tab	range_match_tab;
2061   itr		NUMBER;
2062 
2063   l_debug_on     CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
2064   l_module_name  CONSTANT VARCHAR2(100) := 'wsh.plsql.'||G_PKG_NAME||'.'||'GET_LOWER_BREAKS';
2065 
2066 BEGIN
2067 
2068 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
2069 
2070 	IF l_debug_on THEN
2071  	   wsh_debug_sv.push (l_module_name);
2072 	END IF;
2073 
2074 	l_curr_idx := p_cache.PRIOR(p_start_idx);
2075 
2076 	WHILE (l_curr_idx IS NOT NULL AND l_curr_idx <> p_null_key AND INSTR(l_curr_idx,p_fixed_key,1,1) = 1)
2077 	LOOP
2078 	     l_rule_tab := p_cache(l_curr_idx);
2079 	     itr := l_rule_tab.FIRST;
2080 
2081 	     IF (itr IS NOT NULL) THEN
2082  	     LOOP
2083 
2084 		IF (l_rule_tab(itr).limit=g_low_range_break) THEN
2085 		     IF (x_rule_tab IS NULL) THEN
2086 			 x_rule_tab := rule_match_tab(l_rule_tab(itr).rule_id);
2087 		     ELSE
2088 			 x_rule_tab.EXTEND;
2089 			 x_rule_tab(x_rule_tab.COUNT) := l_rule_tab(itr).rule_id;
2090 		     END IF;
2091 		END IF;
2092 
2093 		EXIT WHEN itr = l_rule_tab.LAST;
2094 		itr := l_rule_tab.NEXT(itr);
2095 		END LOOP;
2096 	     END IF;
2097 
2098 	     -- Check this condition.
2099 	     l_curr_idx := p_cache.PRIOR(l_curr_idx);
2100 	END LOOP;
2101 
2102         IF l_debug_on THEN
2103             WSH_DEBUG_SV.POP (l_module_name);
2104 	END IF;
2105 EXCEPTION
2106 WHEN others THEN
2107       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.get_lower_breaks');
2108       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
2109 
2110       IF l_debug_on THEN
2111         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
2112         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
2113       END IF;
2114 
2115 END get_lower_breaks;
2116 
2117 --***************************************************************************--
2118 --========================================================================
2119 -- PROCEDURE  : search_exact_cache     PRIVATE
2120 --
2121 -- PARAMETERS:  p_cache			Exact Cache to be searched
2122 --	        p_fixed_key		Fixed key to be used.
2123 --		p_attribute		Attribute value
2124 --		p_search_null		This flag determines whether
2125 --					NULL values should be searched or not
2126 --		x_result_tab		Matching Rules
2127 --		x_return_status		Return Status
2128 --
2129 -- COMMENT   : This API returns all the rules which exactly match the attribute
2130 --
2131 --***************************************************************************--
2132 PROCEDURE search_exact_cache(	p_cache			IN		EXACT_MATCH_CACHE,
2133 				p_fixed_key		IN		VARCHAR2,
2134 				p_attribute_key		IN		VARCHAR2,
2135 				p_search_null		IN		BOOLEAN,
2136 				x_result_tab		OUT NOCOPY 	rule_match_tab,
2137 				x_return_status		OUT NOCOPY	VARCHAR2)
2138 
2139 IS
2140 	l_rule_tab	 EXACT_MATCH_TAB;
2141 	itr		 NUMBER;
2142 
2143 	l_debug_on       CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
2144 	l_module_name    CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'search_exact_cache';
2145 BEGIN
2146 
2147 	IF l_debug_on THEN
2148 	      wsh_debug_sv.push (l_module_name);
2149 	END IF;
2150 
2151 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
2152 
2153 	IF (p_search_null) THEN
2154 
2155 		search_exact_cache_for_null( p_cache	    => p_cache,
2156 					     p_fixed_key    => p_fixed_key,
2157 					     x_result_tab   => x_result_tab,
2158 					     x_return_status=> x_return_status);
2159 
2160 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
2161 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
2162 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
2163 			END IF;
2164 		END IF;
2165 	END IF;
2166 
2167 	IF (p_cache.EXISTS(p_attribute_key)) THEN
2168 	      l_rule_tab := p_cache(p_attribute_key);
2169 	      itr := l_rule_tab.FIRST;
2170 	      IF (itr is NOT NULL) THEN
2171 	         LOOP
2172 			IF (x_result_tab IS NULL) THEN
2173 			       x_result_tab:= rule_match_tab(l_rule_tab(itr));
2174 			ELSE
2175 			       x_result_tab.EXTEND;
2176 			       x_result_tab(x_result_tab.COUNT) :=l_rule_tab(itr);
2177 			END IF;
2178 			EXIT when itr = l_rule_tab.LAST;
2179 			itr := l_rule_tab.NEXT(itr);
2180 		 END LOOP;
2181 	      END IF;
2182 	 END IF;
2183 
2184 	 IF l_debug_on THEN
2185             WSH_DEBUG_SV.POP (l_module_name);
2186 	 END IF;
2187 
2188 EXCEPTION
2189 WHEN others THEN
2190 
2191       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.search_exact_cache');
2192       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
2193 
2194       IF l_debug_on THEN
2195         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
2196         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
2197       END IF;
2198       --
2199 END search_exact_cache;
2200 
2201 --***************************************************************************--
2202 --========================================================================
2203 -- PROCEDURE  : search_range_cache     PRIVATE
2204 --
2208 --		p_search_null		This flag determines whether
2205 -- PARAMETERS:  p_cache			Range Cache to be searched
2206 --	        p_fixed_key		Fixed key to be used.
2207 --		p_attribute		Attribute value
2209 --					NULL values should be searched or not
2210 --		x_result_tab		Matching Rules
2211 --		x_return_status		Return Status
2212 --
2213 -- COMMENT   : This API returns all the rules which match the attribute in the range
2214 --	       cache.
2215 --***************************************************************************--
2216 PROCEDURE search_range_cache(  p_cache			IN		RANGE_MATCH_CACHE,
2217 			       p_fixed_key		IN		VARCHAR2,
2218 			       p_attribute_key		IN		VARCHAR2,
2219 			       p_match_upper_limit	IN		BOOLEAN,
2220 			       p_search_null		IN		BOOLEAN,
2221 			       x_result_tab		OUT NOCOPY 	rule_match_tab,
2222 			       x_return_status		OUT NOCOPY	VARCHAR2)
2223 IS
2224 
2225 	check_overlap	        BOOLEAN := FALSE;
2226 
2227 	l_prev_idx		VARCHAR2(32767);
2228 	l_next_idx		VARCHAR2(32767);
2229     l_unique_rule   BOOLEAN;
2230     l_rule_id       FTE_SEL_RULE_RESTRICTIONS.rule_id%type;
2231 	l_rule_tab		range_match_tab;
2232 	l_prev_tab		range_match_tab;
2233 	l_next_tab		range_match_tab;
2234 	l_prev_rec		range_match_rule_rec;
2235 	l_next_rec		range_match_rule_rec;
2236 
2237 	itr			NUMBER;
2238     results_itr NUMBER;
2239 	l_null_key		VARCHAR2(32767);
2240 
2241 	lower_breaks		rule_match_tab;
2242 	higher_breaks		rule_match_tab;
2243 	match_rules		rule_match_tab;
2244 
2245 	l_debug_on		CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
2246 	l_module_name		CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'search_range_cache';
2247 
2248 BEGIN
2249 
2250 	IF l_debug_on THEN
2251 	      wsh_debug_sv.push (l_module_name);
2252 	END IF;
2253 
2254 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
2255     l_unique_rule := true;
2256 	IF (p_search_null) THEN
2257 
2258 	     search_range_cache_for_null( p_cache	=> p_cache,
2259 	  			          p_fixed_key	=> p_fixed_key,
2260 					  x_result_tab	=> x_result_tab,
2261 					  x_return_status=> x_return_status);
2262 
2263 	     --Done with search range cache for null
2264 
2265 	     IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
2266 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
2267 		   raise FND_API.G_EXC_UNEXPECTED_ERROR;
2268 		END IF;
2269 	     END IF;
2270 	END IF;
2271 
2272 	--
2273 	-- Checking the exact match. The exact match. In case of rules we have
2274 	-- Range defined >= and <
2275 	-- In case of exact match we should check for only >= . ie lower range.
2276 	--
2277 	-- For postal codes and transit time the range is defined as <= .
2278 	-- In case of .EXISTS we should check for higher range break.
2279 	--
2280 
2281 	IF (p_cache.EXISTS(p_attribute_key)) THEN
2282 	      l_rule_tab := p_cache(p_attribute_key);
2283 	      itr := l_rule_tab.FIRST;
2284 
2285 	      IF (itr is NOT NULL) THEN
2286 	        LOOP
2287 			IF (l_rule_tab(itr).limit = g_low_range_break)  OR
2288 			   (l_rule_tab(itr).limit = g_high_range_break AND p_match_upper_limit)
2289 			THEN
2290                 l_rule_id := l_rule_tab(itr).rule_id;
2291 				IF (x_result_tab IS NULL) THEN
2292                     x_result_tab:= rule_match_tab(l_rule_id);
2293 				ELSE
2294                     results_itr := x_result_tab.FIRST;
2295                     IF results_itr IS NOT NULL THEN
2296                        LOOP
2297                             IF x_result_tab(results_itr) = l_rule_id THEN
2298                                 l_unique_rule := false;
2299                                 EXIT;
2300                             END IF;
2301                             EXIT WHEN results_itr = x_result_tab.LAST;
2302                             results_itr := x_result_tab.NEXT(results_itr);
2303                        END LOOP;
2304                     END IF;
2305                     IF l_unique_rule THEN
2306                         x_result_tab.EXTEND;
2307                         x_result_tab(x_result_tab.COUNT) :=l_rule_tab(itr).rule_id;
2308                     END IF;
2309 				END IF;
2310 				--
2311 				--Even if for 1 record in table overlap flag is 'Y'.
2312 				--We need to check for overlaps
2313 			        IF (l_rule_tab(itr).overlap_flag = 'Y') THEN
2314 					check_overlap:= TRUE;
2315 				END IF;
2316 			END IF;
2317 			EXIT when itr = l_rule_tab.LAST;
2318 			itr := l_rule_tab.NEXT(itr);
2319 		    END LOOP;
2320 
2321 		    --
2322 		    -- If we are here,then above code has been executed atleast once.
2323 		    -- If check overlap flag is FALSE,we can return.
2324 		    -- Attributes exists and none of them has overlap.
2325 		    --
2326 
2327 		    IF (NOT check_overlap) THEN
2328 
2329 			IF l_debug_on THEN
2330 			   WSH_DEBUG_SV.POP (l_module_name);
2331 			END IF;
2332 			RETURN;
2333 
2334 		    END IF;
2335 	      END IF;
2336 	END IF;
2337 
2338 	l_prev_idx :=  p_cache.prior(p_attribute_key);
2339 	l_next_idx :=  p_cache.next(p_attribute_key);
2340 	l_null_key :=  get_key_for_null(p_fixed_key) ;
2341 
2342 	--
2343 	-- Previous and Next Index will be null
2344 	--
2345 
2346 	IF  l_prev_idx IS NULL OR  l_next_idx IS NULL
2347 	   OR (INSTR(l_prev_idx,p_fixed_key,1,1) <> 1) OR  (l_prev_idx = l_null_key)
2348 	   OR (INSTR(l_next_idx,p_fixed_key,1,1) <> 1) OR (l_next_idx = l_null_key)
2349 	THEN
2350 		IF l_debug_on THEN
2351 		   WSH_DEBUG_SV.POP (l_module_name);
2352 		END IF;
2353 		RETURN;
2354 	END IF;
2355 
2356 
2357         --
2358 	-- Get the previous and next tabs, We are sure that both of them are valid.
2359 	--  a) Null entries will not be made
2360 	--  b) The indexes are valid.
2364 	--  b) Next tab has 1 record.
2361 	--
2362 	-- Here handle the likely case when
2363 	--  a) The prev tab has 1 record.
2365 	--  c) Both are closed and overlap flag is 'N'
2366 	--     If such a case is found return back.
2367 
2368 	l_prev_tab  :=  p_cache(l_prev_idx);
2369 	l_next_tab  :=  p_cache(l_next_idx);
2370 
2371 	IF (l_prev_tab.COUNT = 1) AND (l_next_tab.COUNT = 1) THEN
2372 
2373 		l_prev_rec := l_prev_tab(l_prev_tab.FIRST);
2374 		l_next_rec := l_next_tab(l_next_tab.FIRST);
2375 
2376 		IF (l_prev_rec.rule_id = l_next_rec.rule_id) AND
2377 		   (l_prev_rec.limit = g_low_range_break) AND
2378 		   (l_next_rec.limit = g_high_range_break) THEN
2379 
2380 				IF (x_result_tab IS NULL) THEN
2381 				    x_result_tab:= rule_match_tab(l_prev_rec.rule_id);
2382 				ELSE
2383 				    x_result_tab.EXTEND;
2384 				    x_result_tab(x_result_tab.COUNT):=l_prev_rec.rule_id;
2385 				END IF;
2386 
2387 				--
2388 				-- If overlap flag at the next rec and the previous record is
2389 				-- 'N' we can exit.
2390 				--
2391 
2392 				IF (l_prev_rec.overlap_flag='N' AND l_next_rec.overlap_flag = 'N') THEN
2393 				  IF l_debug_on THEN
2394 				     WSH_DEBUG_SV.POP (l_module_name);
2395 				  END IF;
2396 				  RETURN;
2397 				END IF;
2398 		END IF;
2399 	 END IF;
2400 	 --
2401 	 -- If we reach here then it means that match has not been found or overlap flag is Y;
2402 	 --
2403 	 --
2404 	 -- Algorithm here is -
2405 	 --	1. Get all previous rules with limit = L
2406 	 --     2. Get all next rules with limit = U.
2407 	 --     3. Take intersection of rules returned in above tables.
2408 	 --     4. All the rules returned have to be sent back.
2409 	 --
2410 	 get_lower_breaks( p_cache		=> p_cache,
2411 			   p_start_idx		=> p_attribute_key,
2412 			   p_fixed_key		=> p_fixed_key,
2413 			   p_null_key		=> l_null_key,
2414 			   x_rule_tab		=> lower_breaks,
2415 			   x_return_status	=> x_return_status);
2416 
2417  	 IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
2418 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
2419 		   raise FND_API.G_EXC_UNEXPECTED_ERROR;
2420 		END IF;
2421 	 END IF;
2422 
2423 	 IF (lower_breaks IS NULL) THEN
2424 		 IF l_debug_on THEN
2425 		     WSH_DEBUG_SV.POP (l_module_name);
2426 		 END IF;
2427 		 RETURN;
2428 	 END IF;
2429 
2430 	 get_higher_breaks( p_cache		=> p_cache,
2431 			   p_start_idx		=> p_attribute_key,
2432 			   p_fixed_key		=> p_fixed_key,
2433 			   p_null_key		=> l_null_key,
2434 			   x_rule_tab		=> higher_breaks,
2435 			   x_return_status	=> x_return_status);
2436 
2437 	 IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
2438 		IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
2439 		   raise FND_API.G_EXC_UNEXPECTED_ERROR;
2440 		END IF;
2441 	 END IF;
2442 
2443 	 IF (higher_breaks IS NULL) THEN
2444 		IF l_debug_on THEN
2445 		     WSH_DEBUG_SV.POP (l_module_name);
2446 		END IF;
2447 		RETURN;
2448 	 END IF;
2449 
2450  	 match_rules := lower_breaks MULTISET INTERSECT higher_breaks;
2451 
2452 	 IF (match_rules IS NOT NULL) THEN
2453 
2454 		IF (x_result_tab IS NULL ) THEN
2455 		     x_result_tab := match_rules;
2456 		ELSE
2457 		     x_result_tab := x_result_tab MULTISET UNION DISTINCT match_rules;
2458 	 	END IF;
2459 	 END IF;
2460 
2461 	 IF l_debug_on THEN
2462             WSH_DEBUG_SV.POP (l_module_name);
2463 	 END IF;
2464 
2465 EXCEPTION
2466 WHEN others THEN
2467 
2468       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.search_range_cache');
2469       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
2470 
2471       IF l_debug_on THEN
2472         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
2473         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
2474       END IF;
2475       --
2476 END search_range_cache;
2477 
2478 --***************************************************************************--
2479 --========================================================================
2480 -- PROCEDURE  : get_all_rules_in_cache     PRIVATE
2481 --
2482 -- PARAMETERS:  p_cache			Range Cache to be searched
2483 --		x_result_tab		Matching Rules
2484 --		x_return_status		Return Status
2485 --
2486 -- COMMENT   : This API returns all the rules which match the attribute in the range
2487 --	       cache.
2488 --***************************************************************************--
2489 PROCEDURE get_all_rules_in_cache(  p_cache			IN		RANGE_MATCH_CACHE,
2490 			       x_result_tab		OUT NOCOPY 	rule_match_tab,
2491 			       x_return_status		OUT NOCOPY	VARCHAR2)
2492 IS
2493 
2494 	l_rule_tab		range_match_tab;
2495 	itr			    NUMBER;
2496     l_rule_tab_itr  VARCHAR2(32767);
2497 	match_rules		rule_match_tab;
2498 
2499 	l_debug_on		CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
2500 	l_module_name		CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'get_all_rules_in_cache';
2501 
2502 BEGIN
2503 
2504 	IF l_debug_on THEN
2505 	      wsh_debug_sv.push (l_module_name);
2506 	END IF;
2507 
2508 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
2509 
2510     l_rule_tab_itr := p_cache.FIRST;
2511 
2512     IF p_cache.FIRST IS NOT NULL THEN
2513         LOOP
2514             l_rule_tab := p_cache(l_rule_tab_itr);
2515             itr := l_rule_tab.FIRST;
2516 
2517             IF (itr is NOT NULL) THEN
2518                 LOOP
2519                     IF (x_result_tab IS NULL) THEN
2520                         x_result_tab:= rule_match_tab(l_rule_tab(itr).rule_id);
2521                     ELSE
2525 
2522                         x_result_tab.EXTEND;
2523                         x_result_tab(x_result_tab.COUNT) :=l_rule_tab(itr).rule_id;
2524                     END IF;
2526                     EXIT when itr = l_rule_tab.LAST;
2527                     itr := l_rule_tab.NEXT(itr);
2528                 END LOOP;
2529             END IF;
2530 
2531             EXIT when l_rule_tab_itr = p_cache.LAST;
2532             l_rule_tab_itr := p_cache.NEXT(l_rule_tab_itr);
2533 
2534         END LOOP;
2535     END IF;
2536 
2537     IF l_debug_on THEN
2538         WSH_DEBUG_SV.POP (l_module_name);
2539     END IF;
2540 
2541 EXCEPTION
2542 WHEN others THEN
2543 
2544       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.get_all_rules_in_cache');
2545       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
2546 
2547       IF l_debug_on THEN
2548         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
2549         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
2550       END IF;
2551       --
2552 END get_all_rules_in_cache;
2553 
2554 --***************************************************************************--
2555 --========================================================================
2556 -- PROCEDURE  : search_min_high_transit_time     PRIVATE
2557 --
2558 -- PARAMETERS:  p_result_tab		Rules to be evaluated to find the rule with minimum
2559 --					high transit time.
2560 --		x_rule_id		Rule with minimum maximum transit time
2561 --		x_return_status		Return Status
2562 --
2563 -- COMMENT   : This API returns the rule with the minimum high transit time from
2564 --	       a given set of rules
2565 --
2566 --***************************************************************************--
2567 PROCEDURE search_min_high_transit_time( p_result_tab	IN		RULE_MATCH_TAB,
2568 					x_rule_id	OUT NOCOPY	NUMBER,
2569 					x_return_status	OUT NOCOPY	VARCHAR2)
2570 IS
2571 	l_rule_str	 VARCHAR2(4000);
2572 	sql_string	 VARCHAR2(4000);
2573 	itr		 NUMBER;
2574 
2575 	l_debug_on       CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
2576 	l_module_name    CONSTANT VARCHAR2(100) := 'wsh.plsql.' || G_PKG_NAME || '.' || 'search_min_high_transit_time';
2577 
2578 BEGIN
2579 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
2580 	itr := p_result_tab.FIRST;
2581 
2582 	IF (itr IS NOT NULL) THEN
2583 		LOOP
2584 			IF (l_rule_str IS NULL) THEN
2585 				l_rule_str   := TO_CHAR(p_result_tab(itr));
2586 			ELSE
2587 				l_rule_str   := l_rule_str ||','||TO_CHAR(p_result_tab(itr));
2588 			END IF;
2589 
2590 			EXIT WHEN itr = p_result_tab.LAST;
2591 			itr := p_result_tab.NEXT(itr);
2592 		END LOOP;
2593 	END IF;
2594 
2595 	sql_string := 'SELECT rule_id FROM '
2596               || ' (SELECT rule_id'
2597 		      || ' FROM FTE_SEL_RULE_RESTRICTIONS '
2598 		      || ' WHERE attribute_name=''TRANSIT_TIME'' '--AND ROWNUM=1'
2599 		      || ' AND rule_id IN ('
2600 		      || l_rule_str
2601 		      || ')'
2602 		      || ' ORDER BY attribute_value_to_number)'
2603               || ' WHERE ROWNUM=1';
2604 
2605 	IF l_debug_on THEN
2606 		WSH_DEBUG_SV.logmsg(l_module_name,'Rule String is '||l_rule_str);
2607 		WSH_DEBUG_SV.logmsg(l_module_name,'SQL String is  '||sql_string);
2608 	END IF;
2609 
2610 	EXECUTE IMMEDIATE sql_string INTO x_rule_id;
2611 
2612 	IF l_debug_on THEN
2613 	      WSH_DEBUG_SV.logmsg(l_module_name,'Rule Id is '||x_rule_id);
2614 	      wsh_debug_sv.pop(l_module_name);
2615 	END IF;
2616 
2617 EXCEPTION
2618 WHEN others THEN
2619       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.search_min_high_transit_time');
2620       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
2621 
2622       IF l_debug_on THEN
2623         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
2624         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
2625       END IF;
2626 END search_min_high_transit_time;
2627 
2628 
2629 --***************************************************************************--
2630 --========================================================================
2631 -- PROCEDURE  : find_rule_for_key       PRIVATE
2632 --
2633 -- PARAMETERS:  p_fixed_key		Fixed key to be used for search
2634 --					Group_id-FromRegion-ToRegion Combination
2635 --
2636 --		p_group_id	        Group id
2637 --		p_from_postal_flag	From postal flag is true,if from postal code
2638 --					has to be searched
2639 --		p_to_postal_flag	To postal flag is true , if to postal code has to
2640 --					be searched.
2641 --		p_from_postal_code	From postal code of the entity.
2642 --		p_to_postal_code	To postal code of the entity
2643 --		p_weight		Weight of the entity.
2644 --		p_volume		Volume of the entity.
2645 --		p_transit_time		Transit time associated with the entity
2646 --		p_fob_code		FOB code
2647 --		x_rule_id		Matching rule id.
2648 --		x_return_status		Return status
2649 --
2650 -- COMMENT   : The API finds the rule that matches the attributes.
2651 --             g_rule_not_found is returned if no match is found.
2652 --***************************************************************************--
2653 PROCEDURE find_rule_for_key(	p_fixed_key		IN 		VARCHAR2,
2654 				p_group_id		IN		NUMBER,
2655 				p_from_postal_flag	IN 		BOOLEAN,
2656 				p_to_postal_flag	IN		BOOLEAN,
2657 				p_from_postal_code	IN		VARCHAR2,
2658 				p_to_postal_code	IN		VARCHAR2,
2659 				p_weight		IN		NUMBER,
2660 				p_volume		IN		NUMBER,
2661 				p_transit_time		IN		NUMBER,
2662 				p_fob_code		IN		VARCHAR2,
2663 				x_rule_id		OUT NOCOPY	NUMBER,
2664 				x_return_status		OUT NOCOPY	VARCHAR2)
2665 IS
2666 
2667 
2671 	WHERE  group_id = p_group_id;
2668 	CURSOR c_get_group_name IS
2669 	SELECT name
2670 	FROM   FTE_SEL_GROUPS
2672 
2673 	l_result_set		RULE_MATCH_TAB ;
2674 	l_temp_set		RULE_MATCH_TAB ;
2675 	l_attribute_tab		WSH_UTIL_CORE.ID_TAB_TYPE;
2676 	l_attribute_key		VARCHAR2(32767);
2677 	itr			NUMBER;
2678 
2679 	l_group_name		VARCHAR2(32767);
2680 
2681  	l_debug_on      CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
2682 	l_module_name  CONSTANT VARCHAR2(100) := 'wsh.plsql.'||G_PKG_NAME||'.'||'FIND_RULE_FOR_KEY';
2683 
2684 	OVERLAPPING_RULES_EXIST	EXCEPTION;
2685 BEGIN
2686 
2687 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
2688 
2689 	IF l_debug_on THEN
2690  	   wsh_debug_sv.push(l_module_name);
2691 	END IF;
2692 
2693 	x_rule_id := g_rule_not_found;
2694 
2695 	l_attribute_tab	  := g_groups_cache(p_group_id).attribute_tab;
2696 	--
2697 	--  Method     : Even if attribute is null,we need to get all the rules where the attribute is null.
2698 	--  Exceptions : Postal codes.In postal codes we need to check whether they are present or not.
2699 	--               Check for postal codes as Null has been taken care of before.
2700 	--
2701         IF (l_attribute_tab.EXISTS(g_fob_code_idx)) THEN
2702 
2703 	     IF (p_fob_code IS NOT NULL) THEN
2704 
2705 		--
2706 		--Compare with the old engine.
2707 		--
2708 
2709 		IF l_debug_on THEN
2710  		   wsh_debug_sv.logmsg(l_module_name,'Searching FOB (Not null) ');
2711 		END IF;
2712 
2713 
2714 		l_attribute_key := get_key_for_char(  p_fixed_key => p_fixed_key ,
2715 						      p_char	  => p_fob_code);
2716 
2717 		search_exact_cache( p_cache		=> g_fob_cache,
2718 				    p_fixed_key		=> p_fixed_key,
2719 				    p_attribute_key	=> l_attribute_key,
2720 				    p_search_null	=> TRUE,
2721 				    x_result_tab	=> l_temp_set,
2722 				    x_return_status	=> x_return_status);
2723 
2724 		    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
2725 			    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
2726 			        raise FND_API.G_EXC_UNEXPECTED_ERROR;
2727 		    	END IF;
2728 		    END IF;
2729 	     ELSE
2730 
2731             IF l_debug_on THEN
2732      		   wsh_debug_sv.logmsg(l_module_name,'Searching FOB (Null) ');
2733 	    	END IF;
2734 
2735 		    search_exact_cache_for_null( p_cache		=> g_fob_cache,
2736 					     p_fixed_key	=> p_fixed_key,
2737 					     x_result_tab	=> l_temp_set,
2738 					     x_return_status	=> x_return_status);
2739 
2740 		    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
2741 			    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
2742 			         raise FND_API.G_EXC_UNEXPECTED_ERROR;
2743 			    END IF;
2744 		    END IF;
2745 	    END IF;
2746 
2747 	    IF l_debug_on THEN
2748  		   IF l_temp_set IS NOT NULL THEN
2749 			itr := l_temp_set.FIRST;
2750 			LOOP
2751 			   wsh_debug_sv.log(l_module_name,'Temp Set Rule Matched',l_temp_set(itr));
2752 			   EXIT WHEN itr = l_temp_set.LAST;
2753 			   itr := l_temp_set.NEXT(itr);
2754 			END LOOP;
2755 		   END IF;
2756 	     END IF;
2757 
2758 	     IF (l_temp_set IS NULL) THEN
2759 		--No valid rule found
2760 		IF l_debug_on THEN
2761  			wsh_debug_sv.pop(l_module_name);
2762 		END IF;
2763 		RETURN;
2764 	     ELSE
2765 		-- This is the first attribute. Here no need to use intersect.
2766 		l_result_set := l_temp_set;
2767 	     END IF;
2768 
2769 	     IF l_debug_on THEN
2770  		   IF l_result_set IS NOT NULL THEN
2771 			itr := l_result_set.FIRST;
2772 			LOOP
2773 			   wsh_debug_sv.log(l_module_name,'Result Set Rule Matched',l_result_set(itr));
2774 			   EXIT WHEN itr = l_result_set.LAST;
2775 			   itr := l_result_set.NEXT(itr);
2776 			END LOOP;
2777 		   END IF;
2778 	     END IF;
2779 
2780 	END IF; -- IF (l_attribute_tab.EXISTS(g_fob_code_idx)) THEN
2781 
2782 	--
2783 	-- Only if weight exists in the group,we will be searching in the
2784 	-- cache.
2785 	--
2786 	IF (l_attribute_tab.EXISTS(g_wt_idx)) THEN
2787 
2788 		IF (p_weight IS NOT NULL) THEN
2789 
2790 
2791 			IF l_debug_on THEN
2792 	 		   wsh_debug_sv.logmsg(l_module_name,'Searching Weight (Not Null) ');
2793 			END IF;
2794 
2795 			l_attribute_key := get_key_for_num( p_fixed_key => p_fixed_key ,
2796 							    p_number	=> p_weight);
2797 
2798 			search_range_cache( p_cache		=> g_weight_cache,
2799 					    p_fixed_key		=> p_fixed_key,
2800 					    p_attribute_key	=> l_attribute_key,
2801 					    p_search_null	=> TRUE,
2802 					    p_match_upper_limit => FALSE,
2803 					    x_result_tab	=> l_temp_set,
2804 					    x_return_status	=> x_return_status);
2805 
2806 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
2807 				IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
2808 				   raise FND_API.G_EXC_UNEXPECTED_ERROR;
2809 				END IF;
2810 			END IF;
2811 
2812 		ELSE
2813 
2814 			IF l_debug_on THEN
2815 	 		   wsh_debug_sv.logmsg(l_module_name,'Searching Weight (Null) ');
2816 			END IF;
2817 
2818 			search_range_cache_for_null( p_cache		=> g_weight_cache,
2819 						     p_fixed_key	=> p_fixed_key,
2820 						     x_result_tab	=> l_temp_set,
2821 						     x_return_status	=> x_return_status);
2822 
2823 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
2824 				IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
2825 				   raise FND_API.G_EXC_UNEXPECTED_ERROR;
2826 				END IF;
2827 			END IF;
2828 
2829 		END IF;
2830 
2831 		IF l_debug_on THEN
2832  		   IF l_temp_set IS NOT NULL THEN
2833 			itr := l_temp_set.FIRST;
2834 			LOOP
2838 			END LOOP;
2835 			   wsh_debug_sv.log(l_module_name,'Temp Set Rule Matched',l_temp_set(itr));
2836 			   EXIT WHEN itr = l_temp_set.LAST;
2837 			   itr := l_temp_set.NEXT(itr);
2839 		   END IF;
2840 	    END IF;
2841 
2842 		IF (l_temp_set IS NULL) THEN
2843 			-- No valid rule is found.
2844 			IF l_debug_on THEN
2845  				wsh_debug_sv.pop(l_module_name);
2846 			END IF;
2847 			RETURN;
2848 		ELSE
2849 			IF (l_result_set IS NULL) THEN
2850 				l_result_set := l_temp_set;
2851 			ELSE
2852 				l_result_set := l_result_set MULTISET INTERSECT l_temp_set;
2853 
2854 				IF (l_result_set.COUNT = 0) THEN
2855 				     IF l_debug_on THEN
2856 					wsh_debug_sv.pop(l_module_name);
2857 				     END IF;
2858 				     RETURN;
2859 				END IF;
2860 			END IF;
2861 		END IF;
2862 
2863 		IF l_debug_on THEN
2864  		   IF l_result_set IS NOT NULL THEN
2865 			itr := l_result_set.FIRST;
2866 			LOOP
2867 			   wsh_debug_sv.log(l_module_name,'Result Set Rule Matched',l_result_set(itr));
2868 			   EXIT WHEN itr = l_result_set.LAST;
2869 			   itr := l_result_set.NEXT(itr);
2870 			END LOOP;
2871 		   END IF;
2872 	         END IF;
2873 
2874         END IF; -- IF (l_attribute_tab.EXISTS(g_wt_idx)) THEN
2875 
2876 	--
2877         -- Only if volume exists in the group we will be searching for it.
2878         --
2879         IF (l_attribute_tab.EXISTS(g_vol_idx)) THEN
2880 
2881 	       IF (p_volume IS NOT NULL) THEN
2882 
2883 			IF l_debug_on THEN
2884 	 		   wsh_debug_sv.logmsg(l_module_name,'Searching Volume (Not Null) ');
2885 			END IF;
2886 
2887 			l_attribute_key := get_key_for_num( p_fixed_key => p_fixed_key ,
2888 							    p_number	=> p_volume);
2889 
2890 			search_range_cache( p_cache		=> g_volume_cache,
2891 					    p_fixed_key		=> p_fixed_key,
2892 					    p_attribute_key	=> l_attribute_key,
2893 					    p_match_upper_limit => FALSE,
2894 					    p_search_null	=> TRUE,
2895 					    x_result_tab	=> l_temp_set,
2896 					    x_return_status	=> x_return_status);
2897 
2898 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
2899 				IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
2900 				   raise FND_API.G_EXC_UNEXPECTED_ERROR;
2901 				END IF;
2902 			END IF;
2903 	       ELSE
2904 
2905 			IF l_debug_on THEN
2906 	 		   wsh_debug_sv.logmsg(l_module_name,'Searching Volume (Null) ');
2907 			END IF;
2908 
2909 			search_range_cache_for_null( p_cache		=> g_volume_cache,
2910 						     p_fixed_key	=> p_fixed_key,
2911 						     x_result_tab	=> l_temp_set,
2912 						     x_return_status	=> x_return_status);
2913 
2914 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
2915 				IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
2916 				   raise FND_API.G_EXC_UNEXPECTED_ERROR;
2917 				END IF;
2918 			END IF;
2919 	       END IF;
2920 
2921 	       IF l_debug_on THEN
2922  		   IF l_temp_set IS NOT NULL THEN
2923 			itr := l_temp_set.FIRST;
2924 			LOOP
2925 			   wsh_debug_sv.log(l_module_name,'Temp Set Rule Matched',l_temp_set(itr));
2926 			   EXIT WHEN itr = l_temp_set.LAST;
2927 			   itr := l_temp_set.NEXT(itr);
2928 			END LOOP;
2929 		   END IF;
2930 	       END IF;
2931 
2932 	       IF (l_temp_set IS NULL) THEN
2933 			-- No valid rule is found.
2934 			IF l_debug_on THEN
2935 				wsh_debug_sv.pop(l_module_name);
2936 			END IF;
2937 			RETURN;
2938 	       ELSE
2939 			IF (l_result_set IS NULL) THEN
2940 				l_result_set := l_temp_set;
2941 			ELSE
2942 				l_result_set := l_result_set MULTISET INTERSECT l_temp_set;
2943 
2944 				IF (l_result_set.COUNT = 0 ) THEN
2945 					IF l_debug_on THEN
2946 						wsh_debug_sv.pop(l_module_name);
2947 					END IF;
2948 					RETURN;
2949 				END IF;
2950 			END IF;
2951 	       END IF;
2952 
2953 	       IF l_debug_on THEN
2954  		   IF l_result_set IS NOT NULL THEN
2955 			itr := l_result_set.FIRST;
2956 			LOOP
2957 			   wsh_debug_sv.log(l_module_name,'Result Set Rule Matched',l_result_set(itr));
2958 			   EXIT WHEN itr = l_result_set.LAST;
2959 			   itr := l_result_set.NEXT(itr);
2960 			END LOOP;
2961 		   END IF;
2962 	         END IF;
2963 
2964 	END IF; -- IF (l_attribute_tab.EXISTS(g_vol_idx)) THEN
2965 
2966 	IF (l_attribute_tab.EXISTS(g_fr_post_idx)) THEN
2967 
2968 		IF (p_from_postal_flag) AND (p_from_postal_code IS NOT NULL) THEN
2969    		--
2970 		-- Do not search for NULL postal codes as that is handled in a
2971 		-- different priority.
2972 		--
2973 			IF l_debug_on THEN
2974 	 		   wsh_debug_sv.logmsg(l_module_name,'Searching From Postal Code ');
2975 			END IF;
2976 
2977 
2978 			l_attribute_key := get_key_for_char( p_fixed_key => p_fixed_key,
2979 							     p_char	 => p_from_postal_code);
2980 
2981 			search_range_cache(  p_cache		=> g_from_postal_cache,
2982 					     p_fixed_key	=> p_fixed_key,
2983 					     p_attribute_key	=> l_attribute_key,
2984 	  				     p_match_upper_limit=> TRUE,
2985 					     p_search_null	=> FALSE,
2986 					     x_result_tab	=> l_temp_set,
2987 					     x_return_status	=> x_return_status);
2988 
2989 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
2990 			    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
2991 				  raise FND_API.G_EXC_UNEXPECTED_ERROR;
2992 			    END IF;
2993 			END IF;
2994 
2995 		ELSE
2996 		--
2997 		-- If postal code is null or flag is false then we will search the
2998 		-- cache only for null values.
2999 		--
3000 
3001 			IF l_debug_on THEN
3002 	 		   wsh_debug_sv.logmsg(l_module_name,'Searching From Postal Code(null) ');
3003 			END IF;
3004 
3005 
3009 					     x_return_status	=> x_return_status);
3006 			search_range_cache_for_null(p_cache	=> g_from_postal_cache,
3007 					     p_fixed_key	=> p_fixed_key,
3008 					     x_result_tab	=> l_temp_set,
3010 
3011 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3012 			    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3013 				  raise FND_API.G_EXC_UNEXPECTED_ERROR;
3014 			    END IF;
3015 			END IF;
3016 		END IF;
3017 
3018 		IF l_debug_on THEN
3019  		   IF l_temp_set IS NOT NULL THEN
3020 			itr := l_temp_set.FIRST;
3021 			LOOP
3022 			   wsh_debug_sv.log(l_module_name,'Temp Set Rule Matched',l_temp_set(itr));
3023 			   EXIT WHEN itr = l_temp_set.LAST;
3024 			   itr := l_temp_set.NEXT(itr);
3025 			END LOOP;
3026 		   END IF;
3027 	        END IF;
3028 		--
3029 		-- If no valid result set is retrieved we return back.
3030 		--
3031 		IF (l_temp_set IS NULL) THEN
3032 			--No valid rule found
3033 			IF l_debug_on THEN
3034  				wsh_debug_sv.pop (l_module_name);
3035 			END IF;
3036 			RETURN;
3037 		ELSE
3038 			IF (l_result_set IS NULL) THEN
3039 			   l_result_set := l_temp_set;
3040 			ELSE
3041 
3042 			   l_result_set := l_result_set MULTISET INTERSECT l_temp_set;
3043 			   IF (l_result_set.COUNT=0) THEN
3044 			      IF l_debug_on THEN
3045 	 			wsh_debug_sv.pop (l_module_name);
3046 		 	      END IF;
3047 			      RETURN;
3048 			   END IF;
3049 			END IF;
3050 		END IF;
3051 
3052 		IF l_debug_on THEN
3053  		   IF l_result_set IS NOT NULL THEN
3054 			itr := l_result_set.FIRST;
3055 			LOOP
3056 			   wsh_debug_sv.log(l_module_name,'Result Set Rule Matched',l_result_set(itr));
3057 			   EXIT WHEN itr = l_result_set.LAST;
3058 			   itr := l_result_set.NEXT(itr);
3059 			END LOOP;
3060 		   END IF;
3061 	         END IF;
3062 
3063 	 END IF;
3064 
3065 	 --
3066 	 --Checking for to postal Code
3067 	 --
3068 	 IF (l_attribute_tab.EXISTS(g_to_post_idx)) THEN
3069 
3070 		 IF (p_to_postal_flag) AND (p_to_postal_code IS NOT NULL) THEN
3071 
3072 			IF l_debug_on THEN
3073 	 		   wsh_debug_sv.logmsg(l_module_name,'Searching to Postal Code ');
3074 			END IF;
3075 
3076 
3077 			--
3078 			-- Do not search for NULL postal codes as that is handled in a
3079 			-- different priority.
3080 			--
3081 			l_attribute_key := get_key_for_char( p_fixed_key => p_fixed_key,
3082 							     p_char	 => p_to_postal_code);
3083 
3084 			search_range_cache(p_cache	=> g_to_postal_cache,
3085 				     p_fixed_key	=> p_fixed_key,
3086 				     p_attribute_key	=> l_attribute_key,
3087 	  			     p_match_upper_limit=> TRUE,
3088 				     p_search_null	=> FALSE,
3089 				     x_result_tab	=> l_temp_set,
3090 				     x_return_status	=> x_return_status);
3091 
3092 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3093 			    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3094 				  raise FND_API.G_EXC_UNEXPECTED_ERROR;
3095 			    END IF;
3096 			END IF;
3097 		 ELSE
3098 			--
3099 			-- If postal code is null or flag is false then we will search the
3100 			-- cache only for null values.
3101 			--
3102 			IF l_debug_on THEN
3103 	 		   wsh_debug_sv.logmsg(l_module_name,'Searching to Postal Code(null) ');
3104 			END IF;
3105 
3106 			search_range_cache_for_null( p_cache	=> g_to_postal_cache,
3107 					     p_fixed_key	=> p_fixed_key,
3108 					     x_result_tab	=> l_temp_set,
3109 					     x_return_status	=> x_return_status);
3110 
3111 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3112 			    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3113 				  raise FND_API.G_EXC_UNEXPECTED_ERROR;
3114 			    END IF;
3115 			END IF;
3116 		END IF;
3117 
3118 		IF l_debug_on THEN
3119  		   IF l_temp_set IS NOT NULL THEN
3120 			itr := l_temp_set.FIRST;
3121 			LOOP
3122 			   wsh_debug_sv.log(l_module_name,'Temp Set Rule Matched',l_temp_set(itr));
3123 			   EXIT WHEN itr = l_temp_set.LAST;
3124 			   itr := l_temp_set.NEXT(itr);
3125 			END LOOP;
3126 		   END IF;
3127 	        END IF;
3128 		 --
3129 		 -- If no valid result set is retrieved we return back.
3130 		 --
3131 		 IF (l_temp_set IS NULL) THEN
3132 			--No valid rule found
3133 			IF l_debug_on THEN
3134  				wsh_debug_sv.pop (l_module_name);
3135 			END IF;
3136 			RETURN;
3137 		 ELSE
3138 
3139 			IF (l_result_set IS NULL) THEN
3140 			   l_result_set := l_temp_set;
3141 			ELSE
3142 			   l_result_set := l_result_set MULTISET INTERSECT l_temp_set;
3143 			   IF (l_result_set.COUNT = 0) THEN
3144 			      IF l_debug_on THEN
3145 	 			wsh_debug_sv.pop (l_module_name);
3146 	 		      END IF;
3147 			      RETURN;
3148 			   END IF;
3149 			END IF;
3150 		 END IF;
3151 
3152 		 IF l_debug_on THEN
3153  		   IF l_result_set IS NOT NULL THEN
3154 			itr := l_result_set.FIRST;
3155 			LOOP
3156 			   wsh_debug_sv.log(l_module_name,'Result Set Rule Matched',l_result_set(itr));
3157 			   EXIT WHEN itr = l_result_set.LAST;
3158 			   itr := l_result_set.NEXT(itr);
3159 			END LOOP;
3160 		   END IF;
3161 	         END IF;
3162 
3163 	 END IF;
3164 	 --
3165 	 --  Search for transit time:
3166 	 --  If transit time is 0, null or less than 1, get the rule which has
3167 	 --  the minimum maximum transit time.
3168 	 --
3169 	 IF (l_attribute_tab.EXISTS(g_transit_time_idx)) THEN
3170 
3171 		IF (p_transit_time IS NOT NULL AND (p_transit_time >= 1)) THEN
3172 
3173 
3174 			IF l_debug_on THEN
3175 	 		   wsh_debug_sv.logmsg(l_module_name,'Searching Transit Time (Not Null)');
3176 			END IF;
3177 
3181 		        -- When we store 0-4, in database it actually stores (0-5).
3178 			l_attribute_key := get_key_for_num(  p_fixed_key => p_fixed_key,
3179 							     p_number    => p_transit_time);
3180 
3182 			-- Upper range break should be taken as < instead of <=.
3183 
3184 			search_range_cache( p_cache		=> g_transit_cache,
3185 					    p_fixed_key		=> p_fixed_key,
3186 					    p_attribute_key	=> l_attribute_key,
3187 					    -- Upper limit will NOT be seached
3188 					    p_match_upper_limit => FALSE,
3189 					    p_search_null	=> TRUE,
3190 					    x_result_tab	=> l_temp_set,
3191 					    x_return_status	=> x_return_status);
3192 
3193 
3194 			IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3195 			    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3196 				  raise FND_API.G_EXC_UNEXPECTED_ERROR;
3197 			    END IF;
3198 			END IF;
3199 
3200 			IF l_debug_on THEN
3201 	 		   IF l_temp_set IS NOT NULL THEN
3202 			   itr := l_temp_set.FIRST;
3203 			   LOOP
3204 			       wsh_debug_sv.log(l_module_name,'Temp Set Rule Matched',l_temp_set(itr));
3205 			       EXIT WHEN itr = l_temp_set.LAST;
3206 			       itr := l_temp_set.NEXT(itr);
3207  			   END LOOP;
3208 			   END IF;
3209 		        END IF;
3210 
3211 			IF (l_temp_set IS NULL) THEN
3212 				-- No valid rule is found.
3213 				IF l_debug_on THEN
3214 		 		   wsh_debug_sv.pop (l_module_name);
3215 				END IF;
3216 				RETURN;
3217 			ELSE
3218 				IF (l_result_set IS NULL) THEN
3219 					l_result_set := l_temp_set;
3220 				ELSE
3221 					l_result_set := l_result_set MULTISET INTERSECT l_temp_set;
3222 					IF (l_result_set.COUNT = 0 ) THEN
3223 						IF l_debug_on THEN
3224 		 				   wsh_debug_sv.pop (l_module_name);
3225 						END IF;
3226 						RETURN;
3227 					END IF;
3228 				END IF;
3229 			END IF;
3230 
3231 			IF l_debug_on THEN
3232 	 		   IF l_result_set IS NOT NULL THEN
3233 				itr := l_result_set.FIRST;
3234 				LOOP
3235 				   wsh_debug_sv.log(l_module_name,'Result Set Rule Matched',l_result_set(itr));
3236 				   EXIT WHEN itr = l_result_set.LAST;
3237 				   itr := l_result_set.NEXT(itr);
3238 				END LOOP;
3239 			   END IF;
3240 		        END IF;
3241 		ELSE
3242             IF (l_result_set IS NULL) THEN
3243                 get_all_rules_in_cache(p_cache		=> g_transit_cache,
3244                 x_result_tab	=> l_result_set,
3245                 x_return_status	=> x_return_status);
3246             END IF;
3247 
3248 			IF (l_result_set IS NOT NULL AND l_result_set.COUNT>1) THEN
3249 				--
3250 				-- In all the selected rules, find the rule that has minimum maximum transit time
3251 				-- (If only 1 rule then do nothing)
3252 				--
3253 
3254 				IF l_debug_on THEN
3255 		 		   wsh_debug_sv.logmsg(l_module_name,'Searching min high transit time ');
3256 				END IF;
3257 
3258 				search_min_high_Transit_Time( p_result_tab	=> l_result_set,
3259 							      x_rule_id		=> x_rule_id,
3260 							      x_return_status	=> x_return_status);
3261 
3262 				IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3263 				    IF x_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3264 					  raise FND_API.G_EXC_UNEXPECTED_ERROR;
3265 				    END IF;
3266 				END IF;
3267 
3268 				IF l_debug_on THEN
3269 		 			wsh_debug_sv.pop (l_module_name);
3270 				END IF;
3271 				RETURN;
3272 			END IF;
3273 		END IF;
3274 	END IF;
3275 
3276 	--
3277 	--if result_set is NOT NULL then get the value
3278 	--
3279 
3280 	IF (l_result_set IS NOT NULL) THEN
3281 
3282 		IF (l_result_set.COUNT=1) THEN
3283 			x_rule_id := l_result_set(l_result_set.FIRST);
3284 		ELSE
3285 			RAISE OVERLAPPING_RULES_EXIST;
3286 		END IF;
3287 	END IF;
3288 
3289 EXCEPTION
3290 
3291 WHEN OVERLAPPING_RULES_EXIST THEN
3292 
3293 	OPEN  c_get_group_name;
3294 	FETCH c_get_group_name INTO l_group_name;
3295 	CLOSE c_get_group_name;
3296 
3297 	FND_MESSAGE.SET_NAME('FTE','FTE_POSTAL_CODE_OVERLAP');
3298 	FND_MESSAGE.SET_TOKEN('RULE_NAME',l_group_name);
3299 	x_return_status := WSH_UTIL_CORE.G_RET_STS_ERROR;
3300         WSH_UTIL_CORE.add_message(x_return_status);
3301 
3302 	IF l_debug_on THEN
3303 	   WSH_DEBUG_SV.logmsg(l_module_name,'Overlapping Rules Exist for Group'||l_group_name);
3304 	   WSH_DEBUG_SV.pop(l_module_name);
3305         END IF;
3306 
3307 WHEN others THEN
3308       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.find_rule_for_key');
3309       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
3310 
3311       IF l_debug_on THEN
3312         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
3313         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
3314       END IF;
3315 
3316 END find_rule_for_key;
3317 
3318 
3319 --***************************************************************************--
3320 --========================================================================
3321 -- PROCEDURE : get_matching_rule            PRIVATE
3322 --
3323 -- PARAMETERS: p_info		          Attributes of the entity to be searched for
3324 --	       x_rule_id		  Matching Rule
3325 --	       x_return_status		  Return Status
3326 --
3327 -- COMMENT   : The API returns the rule which matches attribute values passed in p_info.
3328 --	       If no rule is found matching it returns  g_rule_not_found
3329 --
3330 --***************************************************************************--
3331 PROCEDURE get_matching_rule(  p_info		IN  FTE_ACS_CACHE_PKG.fte_cs_entity_attr_rec,
3332 			      x_rule_id		OUT NOCOPY NUMBER,
3333 			      x_return_status	OUT NOCOPY VARCHAR2)
3334 
3335 IS
3336 
3340 
3337 l_group_cache_rec		GROUP_CACHE_REC;
3338 l_attribute_tab			WSH_UTIL_CORE.ID_TAB_TYPE;
3339 l_priority_tab			PRIORITY_TAB_TYPE;
3341 from_pregion_tab		WSH_UTIL_CORE.ID_TAB_TYPE;
3342 from_all_region_tab		WSH_UTIL_CORE.ID_TAB_TYPE;
3343 from_postal_zone_tab		WSH_UTIL_CORE.ID_TAB_TYPE;
3344 
3345 
3346 to_pregion_tab			WSH_UTIL_CORE.ID_TAB_TYPE;
3347 to_all_region_tab		WSH_UTIL_CORE.ID_TAB_TYPE;
3348 to_postal_zone_tab		WSH_UTIL_CORE.ID_TAB_TYPE;
3349 
3350 from_postal_code		WSH_LOCATIONS.POSTAL_CODE%TYPE;
3351 to_postal_code			WSH_LOCATIONS.POSTAL_CODE%TYPE;
3352 
3353 p_itr				NUMBER;
3354 priority			NUMBER;
3355 
3356 l_fixed_key			VARCHAR2(32767);
3357 
3358 from_tab			WSH_UTIL_CORE.ID_TAB_TYPE;
3359 to_tab				WSH_UTIL_CORE.ID_TAB_TYPE;
3360 from_postal_flag		BOOLEAN;
3361 to_postal_flag			BOOLEAN;
3362 
3363 from_itr			NUMBER;
3364 to_itr				NUMBER;
3365 
3366 from_region			NUMBER;
3367 to_region			NUMBER;
3368 
3369 l_sort_flag			BOOLEAN := FALSE;
3370 
3371 l_rule_id			NUMBER;
3372 l_weight_val			NUMBER;
3373 l_volume_val			NUMBER;
3374 
3375 l_return_status			VARCHAR2(1);
3376 
3377 FTE_CS_WGHT_CONV_ERR		EXCEPTION;
3378 FTE_CS_VOL_CONV_ERR		EXCEPTION;
3379 
3380 l_debug_on     CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
3381 l_module_name  CONSTANT VARCHAR2(100) := 'wsh.plsql.'||G_PKG_NAME||'.'||'get_matching_rule';
3382 
3383 
3384 BEGIN
3385 
3386 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
3387 
3388 	IF l_debug_on THEN
3389 	   wsh_debug_sv.push (l_module_name);
3390 	   WSH_DEBUG_SV.log(l_module_name,'Group Id     ',p_info.group_id);
3391 	   WSH_DEBUG_SV.log(l_module_name,'Delivery Id  ',p_info.delivery_id);
3392 	   WSH_DEBUG_SV.log(l_module_name,'Trip Id      ',p_info.trip_id);
3393 	   WSH_DEBUG_SV.log(l_module_name,'Weight       ',p_info.weight);
3394 	   WSH_DEBUG_SV.log(l_module_name,'Weight UOM   ',p_info.weight_uom_code);
3395    	   WSH_DEBUG_SV.log(l_module_name,'Volume       ',p_info.volume);
3396 	   WSH_DEBUG_SV.log(l_module_name,'Volume UOM   ',p_info.volume_uom_code);
3397 	   WSH_DEBUG_SV.log(l_module_name,'Transit Time ',p_info.transit_time);
3398 	   WSH_DEBUG_SV.log(l_module_name,'Ship From Id ',p_info.ship_from_location_id);
3399    	   WSH_DEBUG_SV.log(l_module_name,'Ship To Id   ',p_info.ship_to_location_id);
3400 	   WSH_DEBUG_SV.log(l_module_name,'Fob Code     ',p_info.fob_code);
3401 	END IF;
3402 
3403 	IF NOT (g_table_initialized) THEN
3404 
3405         initialize_tables(x_return_status => l_return_status);
3406 
3407 		IF l_debug_on THEN
3408 		      WSH_DEBUG_SV.log(l_module_name,'l_return Status ',l_return_status);
3409 	        END IF;
3410 
3411 		IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3412 			IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3413 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
3414 			END IF;
3415 		END IF;
3416 	END IF;
3417 
3418 	IF NOT(g_groups_cache.EXISTS(p_info.group_id)) THEN
3419 
3420 		build_cache( p_group_id      => p_info.group_id,
3421 			     x_return_status => l_return_status);
3422 
3423 		IF l_debug_on THEN
3424 		      WSH_DEBUG_SV.log(l_module_name,'l_return Status ',l_return_status);
3425 	        END IF;
3426 
3427 		IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3428 			IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3429 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
3430 			END IF;
3431 		END IF;
3432 
3433 	END IF;
3434 
3435 	l_group_cache_rec := g_groups_cache(p_info.group_id);
3436 
3437 	l_attribute_tab	  := l_group_cache_rec.attribute_tab;
3438 	l_priority_tab    := l_group_cache_rec.priority_tab;
3439 
3440 	--
3441 	-- Do weight-volume Conversions;
3442 	--
3443 	IF (l_attribute_tab.EXISTS(g_wt_idx)) THEN
3444 		-- Change weight
3445 		IF (l_group_cache_rec.weight_uom_code <> p_info.weight_uom_code) THEN
3446 
3447 			 IF l_debug_on THEN
3448 			        WSH_DEBUG_SV.logmsg(l_module_name,'Calling program unit FTE_ACS_RULE_UTIL_PKG.CONV_TO_BASE_UOM');
3449 		         END IF;
3450 			  --
3451 		         l_weight_val:=FTE_ACS_RULE_UTIL_PKG.CONV_TO_BASE_UOM(p_input_value => p_info.weight,
3452                                                         p_from_uom    => p_info.weight_uom_code,
3453                                                         p_to_uom      => l_group_cache_rec.weight_uom_code);
3454 
3455 			 IF (l_weight_val < 0 ) THEN
3456 				  RAISE FTE_CS_WGHT_CONV_ERR;
3457 			 END IF;
3458 		ELSE
3459 			l_weight_val :=  p_info.weight;
3460 		END IF;
3461 
3462 		IF l_debug_on THEN
3463 			WSH_DEBUG_SV.logmsg(l_module_name,'Weight  '||l_weight_val||'Weight UOM '||l_group_cache_rec.weight_uom_code);
3464 		END IF;
3465 
3466 	END IF;
3467 
3468 
3469 
3470 	IF (l_attribute_tab.EXISTS(g_vol_idx)) THEN
3471 		-- Change volume
3472 		IF (l_group_cache_rec.volume_uom_code <> p_info.volume_uom_code) THEN
3473 
3474 			 IF l_debug_on THEN
3475 			        WSH_DEBUG_SV.logmsg(l_module_name,'Calling program unit FTE_ACS_RULE_UTIL_PKG.CONV_TO_BASE_UOM');
3476 		         END IF;
3477 			  --
3478 		         l_volume_val:=FTE_ACS_RULE_UTIL_PKG.CONV_TO_BASE_UOM(p_input_value => p_info.volume,
3479 									      p_from_uom    => p_info.volume_uom_code,
3480 					                                      p_to_uom      => l_group_cache_rec.volume_uom_code);
3481 
3482 			 IF (l_volume_val < 0 ) THEN
3483 				  RAISE FTE_CS_VOL_CONV_ERR;
3484 			 END IF;
3485 		ELSE
3486 			l_volume_val :=  p_info.volume;
3487 		END IF;
3488 
3489 		IF l_debug_on THEN
3490 			WSH_DEBUG_SV.logmsg(l_module_name,'Volume '||l_volume_val||'Volume UOM '||l_group_cache_rec.volume_uom_code);
3491 		END IF;
3492 	END IF;
3493 
3494 	IF (l_attribute_tab.EXISTS(g_fr_reg_idx)) THEN
3498 
3495 
3496 	      -- We encapsulate region type 3 as
3497 	      -- pregion(Region type 2,1,0) + postal code
3499 	        FTE_ACS_RULE_UTIL_PKG.get_formated_regions(
3500 				  p_location_id		=> p_info.ship_from_location_id,
3501 				  x_region_tab		=> from_pregion_tab,
3502 			          x_all_region_tab	=> from_all_region_tab,
3503 				  x_postal_zone_tab	=> from_postal_zone_tab,
3504 				  x_return_status	=> l_return_status);
3505 
3506 		IF l_debug_on THEN
3507 		      WSH_DEBUG_SV.log(l_module_name,'l_return Status ',l_return_status);
3508 	        END IF;
3509 
3510 		IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3511 			IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3512 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
3513 			END IF;
3514 		END IF;
3515 		--
3516 		-- Depending on results obtained above we can remove certain priorities from the list.
3517 		-- There is always a possibility that the location is not associated with some regions.
3518 
3519 		IF (from_all_region_tab.count = 0 ) THEN
3520 
3521 			IF l_debug_on THEN
3522 			   WSH_DEBUG_SV.logmsg(l_module_name,'No From Region Associated with the entity');
3523 			END IF;
3524 
3525 			l_priority_tab		  := l_priority_tab MULTISET EXCEPT g_from_region_priority;
3526 			l_sort_flag		  := TRUE;
3527 
3528 		END IF;
3529 
3530 		--
3531 		-- IF (from_pregion_tab.count=0) is NOT NEEDED here.We will check it after checking postal codes.
3532 		-- Above check is not needed because because all the regions of type 2,1,0 are already present
3533 		-- in from_all_region_tab.
3534 		--
3535 		-- Following can never happen
3536 		--  a) Location is associated to a zones and not to a region
3537 		--  b) Location is associated to a region of type 3 and not to a region of type 0
3538 		--
3539 
3540 		IF (from_postal_zone_tab.count = 0) THEN
3541 
3542 			IF l_debug_on THEN
3543 			   WSH_DEBUG_SV.logmsg(l_module_name,'No From Postal Zone Associated with the entity');
3544 			END IF;
3545 
3546 			l_priority_tab := l_priority_tab MULTISET EXCEPT g_from_pzone_priority;
3547 			l_sort_flag    := TRUE;
3548 		END IF;
3549 	END IF;
3550 
3551 
3552 	IF (l_attribute_tab.EXISTS(g_to_reg_idx)) THEN
3553 
3554 	        FTE_ACS_RULE_UTIL_PKG.get_formated_regions(
3555 				  p_location_id		=> p_info.ship_to_location_id,
3556 				  x_region_tab		=> to_pregion_tab,
3557 			          x_all_region_tab	=> to_all_region_tab,
3558 				  x_postal_zone_tab	=> to_postal_zone_tab,
3559 				  x_return_status	=> l_return_status);
3560 
3561 		IF l_debug_on THEN
3562 		      WSH_DEBUG_SV.log(l_module_name,'l_return Status ',l_return_status);
3563 	        END IF;
3564 
3565 		IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3566 			IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3567 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
3568 			END IF;
3569 		END IF;
3570 
3571 		--
3572 		-- Depending on results obtained above we can remove certain priorities from the list.
3573 		-- There is always a possibility that the location is not associated with some regions.
3574 		--
3575 
3576 		IF (to_all_region_tab.count = 0 ) THEN
3577 
3578 			IF l_debug_on THEN
3579 			   WSH_DEBUG_SV.logmsg(l_module_name,'No To Region Associated with the entity');
3580 			END IF;
3581 			l_priority_tab		  := l_priority_tab MULTISET EXCEPT g_to_region_priority;
3582 			l_sort_flag		  := TRUE;
3583 		END IF;
3584 
3585 		IF (to_postal_zone_tab.count = 0) THEN
3586 
3587 			IF l_debug_on THEN
3588 			   WSH_DEBUG_SV.logmsg(l_module_name,'No To Postal Zone Associated with the entity');
3589 			END IF;
3590 			l_priority_tab := l_priority_tab MULTISET EXCEPT g_to_pzone_priority;
3591 			l_sort_flag    := TRUE;
3592 		END IF;
3593 	END IF;
3594 
3595 
3596 	IF (l_attribute_tab.EXISTS(g_fr_post_idx)) THEN
3597 
3598 	       FTE_ACS_RULE_UTIL_PKG.get_postal_code(p_location_id   => p_info.ship_from_location_id,
3599 			 x_postal_code   => from_postal_code,
3600 			 x_return_status => l_return_status);
3601 
3602 		IF l_debug_on THEN
3603 		      WSH_DEBUG_SV.log(l_module_name,'l_return Status ',l_return_status);
3604 	        END IF;
3605 
3606 		IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3607 			IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3608 			   raise FND_API.G_EXC_UNEXPECTED_ERROR;
3609 			END IF;
3610 		END IF;
3611 
3612 		    --
3613 		    -- We cannot remove postal codes from the prioirity logic here.
3614 		    -- If postal code is null then we will search only the null cache.
3615 		    -- If postal code is present then we will search the cache without null.
3616 		    -- The case of prioirty checking with and without postal codes has been taken
3617 		    -- care in  priority logic.
3618 		    --
3619 		    -- Input has   	Group		What to do		How do we handle
3620 		    -- Postal code	Attribute
3621 		    --   Yes		Yes		Search			None of the priorites are removed.
3622 		    --   Yes		No		Do not search		Priorities are removed
3623 		    --    No		Yes		Search for null match	If parameter is null then check only for null cache.
3624 		    --    No.		No		Do not search		The priority will be removed.
3625 		    --
3626 	END IF;
3627 
3628 
3629 	IF (l_attribute_tab.EXISTS(g_to_post_idx)) THEN
3630 
3631 	   FTE_ACS_RULE_UTIL_PKG.get_postal_code(p_location_id   => p_info.ship_to_location_id,
3632 			    x_postal_code   => to_postal_code,
3633 			    x_return_status => l_return_status);
3634 
3635 	    IF l_debug_on THEN
3636 	         WSH_DEBUG_SV.log(l_module_name,'l_return Status ',l_return_status);
3637 	    END IF;
3638 
3639 	    IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3640 		IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3641 		   raise FND_API.G_EXC_UNEXPECTED_ERROR;
3642 		END IF;
3646 	IF (l_priority_tab.COUNT <> 1 and l_sort_flag) THEN
3643 	    END IF;
3644 	END IF;
3645 
3647 
3648 		sort_priority_tab( p_priority_tab   => l_priority_tab,
3649 				   x_return_status  => l_return_status);
3650 
3651 		IF l_debug_on THEN
3652 	                WSH_DEBUG_SV.log(l_module_name,'l_return Status ',l_return_status);
3653 	        END IF;
3654 
3655 		IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3656 		       IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3657 		           raise FND_API.G_EXC_UNEXPECTED_ERROR;
3658 		       END IF;
3659 		END IF;
3660 	END IF;
3661 
3662 	p_itr := l_priority_tab.FIRST;
3663 
3664 	IF (p_itr) IS NOT NULL THEN
3665 	LOOP
3666 		priority := l_priority_tab(p_itr);
3667 
3668 		IF l_debug_on THEN
3669 	                WSH_DEBUG_SV.log(l_module_name,'Current Priority ',priority);
3670 	        END IF;
3671 
3672 
3673 		IF (priority = 1 ) THEN
3674   			-- * TO_POSTAL * TO_REGION/ZONE_ID * FROM_POSTAL * FROM_REGION/ZONE_ID *
3675 			to_postal_flag   := TRUE;
3676 			from_postal_flag := TRUE;
3677 			to_tab		 := to_pregion_tab;
3678 			from_tab	 := from_pregion_tab;
3679 
3680 		ELSIF (priority = 2) THEN
3681 			--*  TO_POSTAL * TO_REGION/ZONE_ID * FROM_POSTAL * - *
3682 			to_postal_flag   := TRUE;
3683 			from_postal_flag := TRUE;
3684 			to_tab		 := to_pregion_tab;
3685 			from_tab	 := g_null_tab;
3686 
3687 		ELSIF (priority = 3 ) THEN
3688 			-- * TO_POSTAL * TO_REGION_ID  * FROM POSTAL ZONE * -  *
3689  			to_postal_flag   := TRUE;
3690 			from_postal_flag := FALSE;
3691 			to_tab		 := to_pregion_tab;
3692 			from_tab	 := from_postal_zone_tab;
3693 
3694 		ELSIF (priority = 4 ) THEN
3695 			-- * TO_POSTAL *TO_REGION_ID *	FROM_REGION_ID	* - *
3696 			to_postal_flag   := TRUE;
3697  			from_postal_flag := FALSE;
3698 			to_tab		 := to_pregion_tab;
3699 			from_tab	 := from_all_region_tab;
3700 
3701 		ELSIF (priority = 5 ) THEN
3702 			-- * TO_POSTAL * TO_REGION_ID *  -  *  -  *
3703 			to_postal_flag   := TRUE;
3704 			from_postal_flag := FALSE;
3705 			to_tab		 := to_pregion_tab;
3706 			from_tab	 := g_null_tab;
3707 
3708 		ELSIF (priority = 6 ) THEN
3709 			-- * TO_POSTAL * - * FROM_POSTAL * FROM_REGION_ID *
3710 			to_postal_flag   := TRUE;
3711 			from_postal_flag := TRUE;
3712 			to_tab		 := g_null_tab;
3713 			from_tab	 := to_pregion_tab;
3714 
3715 		ELSIF (priority = 7 ) THEN
3716 			-- * TO POSTAL ZONE * - *  FROM_POSTAL * FROM_REGION_ID *
3717 			to_postal_flag   := FALSE;
3718 			from_postal_flag := TRUE;
3719 			to_tab		 := to_postal_zone_tab;
3720 			from_tab	 := from_pregion_tab;
3721 
3722 		ELSIF (priority = 8 ) THEN
3723 			-- * TO_POSTAL * - * FROM_POSTAL * - *
3724 			to_postal_flag   := TRUE;
3725 			from_postal_flag := TRUE;
3726 			to_tab		 := g_null_tab;
3727 			from_tab	 := g_null_tab;
3728 
3729 		ELSIF (priority = 9 ) THEN
3730 			-- * TO_POSTAL * - * FROM_POSTAL_ZONE *	- *
3731 			to_postal_flag   := TRUE;
3732 			from_postal_flag := FALSE;
3733 			to_tab		 := g_null_tab;
3734 			from_tab	 := from_postal_zone_tab;
3735 
3736 		ELSIF (priority = 10 ) THEN
3737 			-- * TO_POSTAL_ZONE * - * FROM_POSTAL *	- *
3738 			to_postal_flag   := FALSE;
3739 			from_postal_flag := TRUE;
3740 			to_tab		 := to_postal_zone_tab;
3741 			from_tab	 := g_null_tab;
3742 
3743 		ELSIF (priority = 11 ) THEN
3744 			-- * TO POSTAL ZONE * - *	FROM POSTAL ZONE * -  *
3745 			to_postal_flag   := FALSE;
3746 			from_postal_flag := FALSE;
3747 			to_tab		 := to_postal_zone_tab;
3748 			from_tab	 := from_postal_zone_tab;
3749 
3750 		ELSIF (priority = 12) THEN
3751 			-- * TO POSTAL  * - *	FROM REGION * -  *
3752 			to_postal_flag   := TRUE;
3753 			from_postal_flag := FALSE;
3754 			to_tab		 := g_null_tab;
3755 			from_tab	 := from_all_region_tab;
3756 
3757 		ELSIF (priority = 13 ) THEN
3758 			-- * TO POSTAL ZONE * - *	FROM_REGION_ID	* -  *
3759 			to_postal_flag   := FALSE;
3760 			from_postal_flag := FALSE;
3761 			to_tab		 := to_postal_zone_tab;
3762 			from_tab	 := from_all_region_tab;
3763 
3764 		ELSIF (priority = 14 ) THEN
3765 			-- * TO POSTAL  * - *	- * -  *
3766 			to_postal_flag   := TRUE;
3767 			from_postal_flag := FALSE;
3768 			to_tab		 := g_null_tab;
3769 			from_tab	 := g_null_tab;
3770 
3771 		ELSIF (priority = 15 ) THEN
3772 			-- * TO POSTAL ZONE * - *  - * - *
3773 			to_postal_flag   := FALSE;
3774 			from_postal_flag := FALSE;
3775 			to_tab		 := to_postal_zone_tab;
3776 			from_tab	 := g_null_tab;
3777 
3778 		ELSIF (priority = 16 ) THEN
3779 			-- * TO_REGION_ID  * - * FROM_POSTAL * FROM_REGION_ID *
3780 			to_postal_flag   := FALSE;
3781 			from_postal_flag := TRUE;
3782 			to_tab		 := to_all_region_tab;
3783 			from_tab	 := from_pregion_tab;
3784 
3785 		ELSIF (priority = 17 ) THEN
3786 			-- * TO_REGION_ID  * - * FROM_POSTAL * - *
3787 			to_postal_flag   := FALSE;
3788 			from_postal_flag := TRUE;
3789 			to_tab		 := to_all_region_tab;
3790 			from_tab	 := g_null_tab;
3791 
3792 		ELSIF (priority = 18 ) THEN
3793 			-- * TO_REGION_ID * - *  FROM POSTAL ZONE * -  *
3794 			to_postal_flag   := FALSE;
3795 			from_postal_flag := FALSE;
3796 			to_tab		 := to_all_region_tab;
3797 			from_tab	 := from_postal_zone_tab;
3798 
3799 		ELSIF (priority = 19 ) THEN
3800 			-- * TO_REGION_ID * -  *  FROM_REGION_ID *  -  *
3801 			to_postal_flag   := FALSE;
3802 			from_postal_flag := FALSE;
3803 			to_tab		 := to_all_region_tab;
3804 			from_tab	 := from_all_region_tab;
3805 
3806 		ELSIF (priority = 20 ) THEN
3807 			-- * TO_REGION_ID * -  *  -  *  - *
3808 			to_postal_flag   := FALSE;
3809 			from_postal_flag := FALSE;
3813 		ELSIF (priority = 21 ) THEN
3810 			to_tab		 := to_all_region_tab;
3811 			from_tab	 := g_null_tab;
3812 
3814 			-- * - *  -  * FROM_POSTAL *  FROM_REGION_ID *
3815 			to_postal_flag   := FALSE;
3816 			from_postal_flag := TRUE;
3817 			to_tab		 := g_null_tab;
3818 			from_tab	 := from_pregion_tab;
3819 
3820 		ELSIF (priority = 22 ) THEN
3821 			-- * - *  -  * FROM_POSTAL * - *
3822 			to_postal_flag   := FALSE;
3823 			from_postal_flag := TRUE;
3824 			to_tab		 := g_null_tab;
3825 			from_tab	 := g_null_tab;
3826 
3827 		ELSIF (priority = 23 ) THEN
3828 			--* - * - * - * FROM POSTAL ZONE *
3829 			to_postal_flag   := FALSE;
3830 			from_postal_flag := FALSE;
3831 			to_tab		 := g_null_tab;
3832 			from_tab	 := from_postal_zone_tab;
3833 
3834 		ELSIF (priority = 24 ) THEN
3835 			--* - *  - * FROM_REGION_ID * -  *
3836 			to_postal_flag   := FALSE;
3837 			from_postal_flag := FALSE;
3838 			to_tab		 := g_null_tab;
3839 			from_tab	 := from_all_region_tab;
3840 
3841 		ELSIF (priority = 25) THEN
3842 			--* - * - *  - * - *
3843 			to_postal_flag   := FALSE;
3844 			from_postal_flag := FALSE;
3845 			to_tab		 := g_null_tab;
3846 			from_tab	 := g_null_tab;
3847 
3848 		END IF;
3849 
3850 		--
3851 		-- Here we should be sure that from table and to table are not empty table.
3852 		-- In case they are null we have some extra priorities in our table.
3853 		-- These should have not been evaluated;
3854                 --
3855 		-- In cases where from and to table is null we are using table g_null_tab.
3856 		-- g_null_tab has 1 entry ie g_num_absent
3857 		--
3858 
3859 		IF (from_tab.COUNT<>0 AND to_tab.COUNT<>0) THEN
3860 
3861 			IF l_debug_on THEN
3862 				WSH_DEBUG_SV.log(l_module_name,'Calling Find Rule for key for Priority',priority);
3863 		        END IF;
3864 
3865 			-- Loop over the tables here only.
3866 
3867 			to_itr := to_tab.FIRST;
3868 			IF (to_itr IS NOT NULL) THEN
3869 			LOOP
3870 
3871 			    to_region := to_tab(to_itr);
3872 			    from_itr  := from_tab.FIRST;
3873 
3874 			    IF (from_itr IS NOT NULL) THEN
3875 			    LOOP
3876 
3877 				from_region := from_tab(from_itr);
3878 				l_fixed_key := get_fixed_key ( p_group_id	=> p_info.group_id,
3879 							       p_from_region_id => from_region,
3880 							       p_to_region_id   => to_region);
3881 
3882 				--
3883 				-- If we put a from_region - to_region cache here we can
3884 				-- control when we should call the API and when we should not.
3885 				--
3886 				--
3887 				-- Only if From To region has rules registered we will proceed for search
3888 				--
3889 
3890 			        IF (g_from_to_region_cache.EXISTS(l_fixed_key)) THEN
3891 
3892 					find_rule_for_key( p_fixed_key		=> l_fixed_key,
3893 							   p_group_id		=> p_info.group_id,
3894 							   p_from_postal_flag	=> from_postal_flag,
3895 							   p_to_postal_flag	=> to_postal_flag,
3896                                p_from_postal_code	=> from_postal_code,
3897                                p_to_postal_code	=> to_postal_code,
3898 							   p_weight		=> l_weight_val,
3899 							   p_volume		=> l_volume_val,
3900 							   p_transit_time	=> p_info.transit_time,
3901 							   p_fob_code		=> p_info.fob_code,
3902 							   x_rule_id		=> l_rule_id,
3903 							   x_return_status	=> l_return_status);
3904 
3905 					IF l_debug_on THEN
3906 					      WSH_DEBUG_SV.log(l_module_name,'l_rule_id ', l_rule_id);
3907 						  WSH_DEBUG_SV.log(l_module_name,'l_return Status ',l_return_status);
3908 					END IF;
3909 
3910 					IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
3911 						IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
3912 						   raise FND_API.G_EXC_UNEXPECTED_ERROR;
3913 						END IF;
3914 					END IF;
3915 
3916 					IF (l_rule_id <> g_rule_not_found) THEN
3917 
3918 						x_rule_id := l_rule_id ;
3919 
3920 						IF l_debug_on THEN
3921 							  WSH_DEBUG_SV.log(l_module_name,'x_rule_id',x_rule_id);
3922 							  WSH_DEBUG_SV.POP (l_module_name);
3923 						END IF;
3924 						RETURN;
3925 					END IF;
3926 				END IF;
3927 
3928 				EXIT WHEN from_itr = from_tab.LAST;
3929 				from_itr := from_tab.NEXT(from_itr);
3930 
3931 			     END LOOP;
3932 			     END IF;
3933 
3934 			     EXIT WHEN to_itr = to_tab.LAST;
3935 			     to_itr := to_tab.NEXT(to_itr);
3936 
3937 			END LOOP;
3938 			END IF;
3939 
3940 		END IF;
3941 		EXIT WHEN p_itr = l_priority_tab.LAST;
3942 		p_itr := l_priority_tab.NEXT(p_itr);
3943 
3944 	END LOOP;
3945 	END IF;
3946 
3947 	-- If we reach here then no rule was found for the delivery
3948 	x_rule_id := g_rule_not_found;
3949 
3950 	IF l_debug_on THEN
3951 	     WSH_DEBUG_SV.POP (l_module_name);
3952 	END IF;
3953 
3954 EXCEPTION
3955 
3956 WHEN FTE_CS_VOL_CONV_ERR THEN
3957 
3958       FND_MESSAGE.SET_NAME('FTE','FTE_CS_VOL_CONV_ERR');
3959       x_return_status  := WSH_UTIL_CORE.G_RET_STS_ERROR;
3960       WSH_UTIL_CORE.add_message(x_return_status);
3961 
3962       IF l_debug_on THEN
3963         WSH_DEBUG_SV.pop(l_module_name,'Volume UOM Conversion Error');
3964       END IF;
3965 
3966 WHEN FTE_CS_WGHT_CONV_ERR THEN
3967 
3968       FND_MESSAGE.SET_NAME('FTE','FTE_CS_WGHT_CONV_ERR');
3969       x_return_status  := WSH_UTIL_CORE.G_RET_STS_ERROR;
3970       WSH_UTIL_CORE.add_message(x_return_status);
3971 
3972       IF l_debug_on THEN
3973         WSH_DEBUG_SV.pop(l_module_name,'Volume UOM Conversion Error');
3974       END IF;
3975 
3976 WHEN others THEN
3977 
3978       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.get_matching_rule');
3982         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
3979       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
3980 
3981       IF l_debug_on THEN
3983         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
3984       END IF;
3985       --
3986 END  get_matching_rule;
3987 
3988 --***************************************************************************
3989 --===========================================================================
3990 -- PROCEDURE : build_rule_result_cache    RRIVATE
3991 --
3992 -- PARAMETERS: p_rule_id	          Rule Id
3993 --	       x_return_status		  Return Status
3994 --
3995 -- COMMENT   : The API builds Rules Result Cache.
3996 --             a) The Rule Result store the results associated with a rule in order of
3997 --		  increasing leg sequence/ rank .
3998 --             b) Result Attribute Cache stores the result attributites and there values.
3999 --***************************************************************************--
4000 
4001 PROCEDURE build_rule_result_cache( p_rule_id		IN NUMBER,
4002 				   x_return_status 	OUT NOCOPY VARCHAR2)
4003 
4004 IS
4005 
4006 -- -----------------------------------------------------------------
4007 -- get results for a rule
4008 -- -----------------------------------------------------------------
4009 cursor c_get_result_id  IS
4010 select fsras.result_id
4011 from   fte_sel_result_assignments fsras
4012 where  fsras.rule_id = p_rule_id;
4013 
4014 -- -----------------------------------------------------------------
4015 -- get result attributes names and values
4016 -- -----------------------------------------------------------------
4017 cursor c_get_result_attributes(p_result_id NUMBER) IS
4018 select fsra.attribute_code,
4019        fsra.attribute_value
4020 from   fte_sel_result_attributes fsra
4021 where  fsra.result_id = p_result_id;
4022 
4023 
4024 l_result_id_tab		result_id_tab;
4025 l_attr_tab		fte_attr_code_val_tab_type;
4026 l_cs_result_rec		fte_cs_result_attr_rec;
4027 l_sorted_result_tab	result_id_tab;
4028 
4029 l_result_id			NUMBER;
4030 
4031 itr				NUMBER;
4032 l_itr				NUMBER;
4033 l_seq				NUMBER;
4034 
4035 INVALID_RESULT_ATTRIBUTE	EXCEPTION;
4036 NO_RESULTS_FOR_RULE		EXCEPTION;
4037 
4038 l_debug_on		CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
4039 l_module_name		CONSTANT VARCHAR2(100) := 'wsh.plsql.'||G_PKG_NAME||'.'||'build_rule_result_cache';
4040 
4041 BEGIN
4042 
4043 	--
4044 	-- Values are not in cache.
4045 	-- Query the database tables to return results;
4046 	--
4047 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
4048 
4049 	IF l_debug_on THEN
4050 	       WSH_DEBUG_SV.push(l_module_name);
4051 	       WSH_DEBUG_SV.log(l_module_name,'p_rule_id',p_rule_id);
4052         END IF;
4053 
4054 
4055 	OPEN  c_get_result_id;
4056 	FETCH c_get_result_id BULK COLLECT INTO l_result_id_tab;
4057 	CLOSE c_get_result_id;
4058 
4059 	itr := l_result_id_tab.FIRST;
4060 
4061 	IF (itr IS NOT NULL) THEN
4062 	LOOP
4063 		l_result_id := l_result_id_tab(itr);
4064 
4065 		IF l_debug_on THEN
4066 		       WSH_DEBUG_SV.log(l_module_name,'Result id to be queried',l_result_id);
4067 		END IF;
4068 
4069 		IF NOT(g_result_attribute_cache.EXISTS(l_result_id)) THEN
4070 
4071 			l_attr_tab.DELETE;
4072 			l_cs_result_rec	:= NULL;
4073 
4074 			OPEN  c_get_result_attributes(l_result_id);
4075 			FETCH c_get_result_attributes BULK COLLECT INTO l_attr_tab;
4076 			CLOSE c_get_result_attributes;
4077 
4078 			l_itr :=l_attr_tab.FIRST;
4079 
4080 			IF (l_itr IS NOT NULL) THEN
4081 
4082 			--
4083 			-- Setting the default values(If Rank is NULL , it should be considered 1)
4084 			-- Defaulting it to 1, otherwise it will be overwritten
4085 			-- Converting the attribute values to record type.
4086 			-- Default type is 'RANK'
4087 
4088 			l_cs_result_rec.rank		:= 1;
4089 			l_cs_result_rec.result_type	:= 'RANK';
4090 
4091 			LOOP
4092 
4093 				IF (l_attr_tab(l_itr).attr_code = 'RANK') THEN
4094 					l_cs_result_rec.rank := l_attr_tab(l_itr).attr_val;
4095 					l_cs_result_rec.result_type	:= 'RANK';
4096 
4097 				ELSIF (l_attr_tab(l_itr).attr_code = 'LEG_SEQUENCE') THEN
4098 -- LEG_SEQUENCE attribute code INDICATES we result_type is MULTILEG
4099 					l_cs_result_rec.leg_sequence := l_attr_tab(l_itr).attr_val;
4100 					l_cs_result_rec.result_type  := 'MULTILEG';
4101 
4102 				ELSIF (l_attr_tab(l_itr).attr_code = 'LEG_DESTINATION') THEN
4103 					l_cs_result_rec.leg_destination	   := l_attr_tab(l_itr).attr_val;
4104 
4105 --				ELSIF (l_attr_tab(l_itr).attr_code = 'ITINERARY') THEN
4106 --					l_cs_result_rec.itinerary_id := l_attr_tab(l_itr).attr_val;
4107 
4108 				ELSIF (l_attr_tab(l_itr).attr_code = 'CARRIER') THEN
4109 					l_cs_result_rec.carrier_id := l_attr_tab(l_itr).attr_val;
4110 
4111 				ELSIF (l_attr_tab(l_itr).attr_code = 'MODE_OF_TRANSPORT') THEN
4112 					l_cs_result_rec.mode_of_transport:= l_attr_tab(l_itr).attr_val;
4113 
4114 				ELSIF (l_attr_tab(l_itr).attr_code = 'SERVICE_LEVEL') THEN
4115 					l_cs_result_rec.service_level := l_attr_tab(l_itr).attr_val;
4116 
4117 				ELSIF (l_attr_tab(l_itr).attr_code = 'FREIGHT_TERMS') THEN
4118 					l_cs_result_rec.freight_terms_code := l_attr_tab(l_itr).attr_val;
4119 
4120 				ELSIF (l_attr_tab(l_itr).attr_code = 'CONSIGNEE_CAR_ACNO') THEN
4121 					l_cs_result_rec.consignee_carrier_ac_no := l_attr_tab(l_itr).attr_val;
4122 
4123 --				ELSIF (l_attr_tab(l_itr).attr_code = 'TRACK_ONLY_FLAG') THEN
4124 --					l_cs_result_rec.track_only_flag	:= l_attr_tab(l_itr).attr_val;
4125 				ELSE
4126 						RAISE INVALID_RESULT_ATTRIBUTE;
4127 				END IF;
4128 
4132 			END LOOP;
4129 				EXIT WHEN l_itr = l_attr_tab.LAST;
4130 				l_itr := l_attr_tab.NEXT(l_itr);
4131 
4133 
4134 			END IF;
4135 
4136 			--
4137 			-- Now store the result attributes in the cache;
4138 			--
4139 			g_result_attribute_cache(l_result_id) := l_cs_result_rec;
4140 	       END IF;
4141 
4142 		--
4143 		-- Either we will have multileg or Rank : Calculate the temp sequence
4144 		-- At this stage we have result attributes stored in the cache.
4145 		--
4146 
4147 		IF (g_result_attribute_cache(l_result_id).result_type = 'MULTILEG') THEN
4148 			l_seq	:= g_result_attribute_cache(l_result_id).leg_sequence;
4149 		ELSIF (g_result_attribute_cache(l_result_id).result_type = 'RANK')  THEN
4150 			l_seq   := g_result_attribute_cache(l_result_id).rank;
4151 		END IF;
4152 
4153 		--
4154 		l_sorted_result_tab(l_seq) := l_result_id;
4155 		--
4156 
4157 		EXIT WHEN itr = l_result_id_tab.LAST;
4158 		itr := l_result_id_tab.NEXT(itr);
4159 
4160 	END LOOP;
4161 
4162 	g_rule_result_cache(p_rule_id) := l_sorted_result_tab;
4163 
4164 	ELSE
4165 		RAISE NO_RESULTS_FOR_RULE;
4166 	END IF;
4167 
4168 	IF l_debug_on THEN
4169 	     WSH_DEBUG_SV.POP(l_module_name);
4170 	END IF;
4171 
4172 
4173 EXCEPTION
4174 WHEN INVALID_RESULT_ATTRIBUTE THEN
4175       x_return_status := WSH_UTIL_CORE.G_RET_STS_ERROR;
4176       --
4177       IF l_debug_on THEN
4178         WSH_DEBUG_SV.pop(l_module_name,'Invalid Attribute associated with Rule'||p_rule_id);
4179       END IF;
4180 
4181 WHEN NO_RESULTS_FOR_RULE THEN
4182 
4183       x_return_status := WSH_UTIL_CORE.G_RET_STS_ERROR;
4184       --
4185       IF l_debug_on THEN
4186         WSH_DEBUG_SV.pop(l_module_name,'No Results Associated with Rule'||p_rule_id);
4187       END IF;
4188 
4189 WHEN OTHERS THEN
4190       --
4191       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.BUILD_RULE_RESULT_CACHE');
4192       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
4193       --
4194 
4195       IF l_debug_on THEN
4196         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
4197         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
4198       END IF;
4199 
4200 END build_rule_result_cache;
4201 
4202 
4203 --***************************************************************************--
4204 --===========================================================================
4205 -- PROCEDURE : get_results_for_rule      PRIVATE
4206 --
4207 -- PARAMETERS: p_rule_id		 Rule Id.
4208 --	       x_result_tab		 Results Attributes associated with the rule.
4209 --	       x_return_status		 Return Status
4210 --
4211 -- COMMENT   : For a given rule id queries FTE_SEL_RESULT_ASSIGNMENTS and FTE_SEL_RESULT_ATTRIBUTES
4212 --             to return the result.Caching is used in this procedure.
4213 --
4214 --
4215 -- ALGORITHM :
4216 --	      1. Check global cache to see if associated results exist.
4217 --	      2. If NOT , build the cache .
4218 --            3. Return attributes from the cache.
4219 --***************************************************************************--
4220 PROCEDURE get_results_for_rule( p_rule_id	 IN		NUMBER,
4221 		 	        x_result_tab	 OUT NOCOPY	FTE_ACS_CACHE_PKG.fte_cs_result_attr_tab,
4222 				x_return_status  OUT NOCOPY     VARCHAR2)
4223 
4224 IS
4225 
4226 	l_tab			RESULT_ID_TAB;
4227 	itr			NUMBER;
4228 	l_cnt			NUMBER := 0;
4229         l_return_status         VARCHAR2(1);
4230 	l_itr			NUMBER;
4231 
4232 	l_debug_on		CONSTANT BOOLEAN := WSH_DEBUG_SV.is_debug_enabled;
4233 	l_module_name		CONSTANT VARCHAR2(100) := 'wsh.plsql.'||G_PKG_NAME||'.'||'get_results_for_rule';
4234 
4235 	NO_RESULTS_FOR_RULE	EXCEPTION;
4236 
4237 BEGIN
4238 
4239 	x_return_status := WSH_UTIL_CORE.G_RET_STS_SUCCESS;
4240 
4241 	IF l_debug_on THEN
4242 	       WSH_DEBUG_SV.push(l_module_name);
4243 	       WSH_DEBUG_SV.log(l_module_name,'p_rule_id',p_rule_id);
4244         END IF;
4245 
4246 	IF NOT(g_rule_result_cache.EXISTS(p_rule_id)) THEN
4247 
4248 		BUILD_RULE_RESULT_CACHE( p_rule_id	  => p_rule_id,
4249 					 x_return_status  => l_return_status);
4250 
4251 		IF l_debug_on THEN
4252 	            WSH_DEBUG_SV.log(l_module_name,'l_return Status ',l_return_status);
4253 		END IF;
4254 
4255 		IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_SUCCESS THEN
4256 		     IF l_return_status <> WSH_UTIL_CORE.G_RET_STS_WARNING THEN
4257 		         raise FND_API.G_EXC_UNEXPECTED_ERROR;
4258 		     END IF;
4259 	        END IF;
4260 	END IF;
4261 
4262 	l_tab := g_rule_result_cache(p_rule_id);
4263 
4264 	IF l_debug_on THEN
4265 
4266 		IF (l_tab.COUNT>0) THEN
4267 			itr := l_tab.FIRST;
4268 			LOOP
4269 			    WSH_DEBUG_SV.log(l_module_name,'Result id',l_tab(itr));
4270 			    EXIT WHEN itr = l_tab.LAST;
4271 			    itr := l_tab.NEXT(itr);
4272 			END LOOP;
4273 		END IF;
4274 	END IF;
4275 
4276 	itr   := l_tab.FIRST;
4277 	IF (itr IS NOT NULL) THEN
4278 	LOOP
4279 		x_result_tab(l_cnt) := g_result_attribute_cache(l_tab(itr));
4280 		EXIT WHEN itr = l_tab.LAST;
4281 		itr := l_tab.NEXT(itr);
4282 		l_cnt:= l_cnt+1;
4283 		END LOOP;
4284 	ELSE
4285 		RAISE NO_RESULTS_FOR_RULE;
4286 	END IF;
4287 
4288 	IF l_debug_on THEN
4289 
4290 	      l_itr := x_result_tab.FIRST;
4291 
4292 	      IF (l_itr IS NOT NULL) THEN
4293 	      LOOP
4294 		  	 WSH_DEBUG_SV.logmsg(l_module_name,'Output Record for result');
4295 			 WSH_DEBUG_SV.logmsg(l_module_name,'result_type '||x_result_tab(l_itr).result_type);
4296 			 WSH_DEBUG_SV.logmsg(l_module_name,'rank '||x_result_tab(l_itr).rank);
4297 			 WSH_DEBUG_SV.logmsg(l_module_name,'leg_destination '||x_result_tab(l_itr).leg_destination);
4298 			 WSH_DEBUG_SV.logmsg(l_module_name,'leg_sequence '||x_result_tab(l_itr).leg_sequence);
4299 			 WSH_DEBUG_SV.logmsg(l_module_name,'carrier_id '||x_result_tab(l_itr).carrier_id);
4300 			 WSH_DEBUG_SV.logmsg(l_module_name,'mode_of_transport '||x_result_tab(l_itr).mode_of_transport);
4301 			 WSH_DEBUG_SV.logmsg(l_module_name,'service_level '||x_result_tab(l_itr).service_level);
4302 			 WSH_DEBUG_SV.logmsg(l_module_name,'freight_terms_code '||x_result_tab(l_itr).freight_terms_code);
4303 			 WSH_DEBUG_SV.logmsg(l_module_name,'consignee_carrier_ac_no '||x_result_tab(l_itr).consignee_carrier_ac_no);
4304 			 WSH_DEBUG_SV.logmsg(l_module_name,'result_level '||x_result_tab(l_itr).result_level);
4305 
4306 			 EXIT WHEN l_itr = x_result_tab.LAST;
4307 			 l_itr := x_result_tab.NEXT(l_itr);
4308 		END LOOP;
4309 	      END IF;
4310 	      WSH_DEBUG_SV.POP (l_module_name);
4311 	END IF;
4312 
4313 EXCEPTION
4314 
4315  WHEN NO_RESULTS_FOR_RULE THEN
4316 
4317       x_return_status := WSH_UTIL_CORE.G_RET_STS_ERROR;
4318       --
4319       IF l_debug_on THEN
4320         WSH_DEBUG_SV.pop(l_module_name,'No Results Associated with Rule'||p_rule_id);
4321       END IF;
4322 
4323  WHEN OTHERS THEN
4324 
4325       WSH_UTIL_CORE.default_handler('FTE_ACS_CACHE_PKG.GET_RESULTS_FOR_RULE');
4326       x_return_status := WSH_UTIL_CORE.G_RET_STS_UNEXP_ERROR;
4327       --
4328       IF l_debug_on THEN
4329         WSH_DEBUG_SV.logmsg(l_module_name,'Unexpected error has occured. Oracle error message is '|| SQLERRM,WSH_DEBUG_SV.C_UNEXPEC_ERR_LEVEL);
4330         WSH_DEBUG_SV.pop(l_module_name,'EXCEPTION:FND_API.G_EXC_UNEXPECTED_ERROR');
4331       END IF;
4332 
4333 END get_results_for_rule;
4334 
4335 END FTE_ACS_CACHE_PKG;