DBA Data[Home] [Help]

PACKAGE BODY: APPS.FA_RX_FLEX_PKG

Source


1 package body fa_rx_flex_pkg as
2 /* $Header: FARXFLXB.pls 120.7.12010000.2 2008/07/31 06:52:03 sbhaskar ship $ */
3 
4 ---------------------------------------------
5 -- Some global types, constants and cursors
6 ---------------------------------------------
7 type seg_array is table of FND_FLEX_VALUES.PARENT_FLEX_VALUE_LOW%type index by binary_integer;
8 NEWLINE CONSTANT varchar2(3) := '';
9 
10 
11 --
12 -- The following cursor is used extensively and is the main logic of
13 -- most of the procedures provided by this package.
14 -- Givent the key flexfield and  qualifier/segment number,
15 -- this cursor will return the segment number(s), column name(s)
16 -- and the flex value set(s) for all of the segments that
17 -- match the criteria for this key flexfield
18 --
19 cursor cflex(p_application_id in varchar2,
20 		p_id_flex_code in varchar2,
21 		p_id_flex_num in number,
22 		p_qualifier in varchar2,
23 		p_segnum in number) is
24 	select s.segment_num, s.application_column_name, s.flex_value_set_id
25 	from 	fnd_id_flex_segments s
26 	where	s.application_id = p_application_id
27 	and	s.id_flex_code = p_id_flex_code
28 	and	s.id_flex_num = p_id_flex_num
29 	and	s.enabled_flag = 'Y'
30 	and	p_qualifier = 'ALL'
31 	and	p_segnum is null
32 	union all
33 	select s.segment_num, s.application_column_name, s.flex_value_set_id
34 	from 	fnd_id_flex_segments s,
35 		fnd_segment_attribute_values sav,
36 		fnd_segment_attribute_types sat
37 	where	s.application_id = p_application_id
38 	and	s.id_flex_code = p_id_flex_code
39 	and	s.id_flex_num = p_id_flex_num
40 	and	s.enabled_flag = 'Y'
41 	and	s.application_column_name = sav.application_column_name
42 	and	sav.application_id = p_application_id
43 	and	sav.id_flex_code = p_id_flex_code
44 	and	sav.id_flex_num = p_id_flex_num
45 	and	sav.attribute_value = 'Y'
46 	and	sav.segment_attribute_type = sat.segment_attribute_type
47 	and	sat.application_id = p_application_id
48 	and	sat.id_flex_code = p_id_flex_code
49 	and	sat.unique_flag = 'Y'
50 	and	sat.segment_attribute_type = p_qualifier
51 	and	p_qualifier <> 'ALL'
52 	and	p_segnum is null
53 	union all
54 	select s.segment_num, s.application_column_name, s.flex_value_set_id
55 	from 	fnd_id_flex_segments s
56 	where	s.application_id = p_application_id
57 	and	s.id_flex_code = p_id_flex_code
58 	and	s.id_flex_num = p_id_flex_num
59 	and	s.enabled_flag = 'Y'
60 	and	s.segment_num = p_segnum
61 	and	p_qualifier is null
62 	order by 1;
63 
64 cursor par_seg( p_application_id in number,
65 		p_id_flex_code in varchar2,
66 		p_id_flex_num in number,
67 		p_value_set_id in number)
68 Is
69 select  c.segment_num parent_seg_num
70 from	FND_FLEX_VALUE_SETS a, FND_ID_FLEX_SEGMENTS b, FND_ID_FLEX_SEGMENTS c
71 where	b.APPLICATION_ID = p_application_id
72 and	b.ID_FLEX_CODE = p_id_flex_code
73 and	b.ID_FLEX_NUM = p_id_flex_num
74 and	(b.FLEX_VALUE_SET_ID = a.FLEX_VALUE_SET_ID)
75 and	b.APPLICATION_ID = c.APPLICATION_ID
76 and	b.ID_FLEX_CODE = c.ID_FLEX_CODE
77 and	b.ID_FLEX_NUM = c.ID_FLEX_NUM
78 and	(a.PARENT_FLEX_VALUE_SET_ID = c.FLEX_VALUE_SET_ID)
79 and	a.FLEX_VALUE_SET_ID = p_value_set_id;
80 
81 ------------------------------------
82 -- Private Functions/Procedures
83 ------------------------------------
84 
85 g_print_debug boolean := fa_cache_pkg.fa_print_debug;
86 
87 -------------------------------------------------------------------------
88 --
89 -- PRIVATE FUNCTION Get_Parent_Value
90 --
91 -- Parameters
92 --		p_seg_array		Segment Array
93 --		p_application_id	Application id
94 --		p_id_flex_code		flex code
95 --		p_id_flex_num		Flex num default null
96 --		p_child_value_set_id	value set id , whose parent value value is to be found out.
97 --
98 -- Returns
99 --   the parent segment value
100 -- Description
101 --   This function returns the parent segments value for a depenant value set.
102 --   takes in application id,
103 --
104 --
105 -- Modification History
106 --  RRAVUNNY    Created Bug#2991482
107 --
108 -------------------------------------------------------------------------
109 Function Get_Parent_Value(	p_seg_array in seg_array,
110 				p_application_id in number,
111 				p_id_flex_code in varchar2,
112 				p_id_flex_num in number default NULL,
113 				p_child_value_set_id in number
114 			) return varchar2
115 Is
116 	Lvr_Parent_Value	FND_FLEX_VALUES.PARENT_FLEX_VALUE_LOW%type	Default Null;
117 	Lnu_array_counter	Number		Default Null;
118 	err_num			Number;
119 	Lnu_cache_index		Number		Default Null;
120 Begin
121 --*	dbms_output.put_line('Get_Parent_Value +');
122 --*	dbms_output.put_line(p_application_id||' - '||p_id_flex_code||' - '||p_id_flex_num||' - '||p_child_value_set_id);
123 	--* Check if the fa_rx_flex_parent_seg_t cache exists
124 	Lnu_cache_index := fa_rx_flex_par_seg_t.FIRST;
125 --*	dbms_output.put_line('for first , Lnu_cache_index = '||Lnu_cache_index||' total = '||fa_rx_flex_par_seg_t.count);
126 	WHILE Lnu_cache_index IS NOT NULL
127 	LOOP
128 --*		dbms_output.put_line('record content fa_rx_flex_parent_seg_t('||Lnu_cache_index||')');
129 --*		dbms_output.put_line('fa_rx_flex_parent_seg_t(Lnu_cache_index).fap_application_id = '||fa_rx_flex_par_seg_t(Lnu_cache_index).fap_application_id);
130 --*		dbms_output.put_line('fa_rx_flex_parent_seg_t(Lnu_cache_index).fap_id_flex_code = '||fa_rx_flex_par_seg_t(Lnu_cache_index).fap_id_flex_code);
131 --*		dbms_output.put_line('fa_rx_flex_parent_seg_t(Lnu_cache_index).fap_id_flex_num = '||fa_rx_flex_par_seg_t(Lnu_cache_index).fap_id_flex_num);
132 --*		dbms_output.put_line('fa_rx_flex_parent_seg_t(Lnu_cache_index).fap_flex_value_set_id = '||fa_rx_flex_par_seg_t(Lnu_cache_index).fap_flex_value_set_id);
133 --*		dbms_output.put_line('fa_rx_flex_parent_seg_t(Lnu_cache_index).fap_parent_segment_num = '||fa_rx_flex_par_seg_t(Lnu_cache_index).fap_parent_segment_num);
134 		--* Check if the record exists in cache.
135 		If (	fa_rx_flex_par_seg_t(Lnu_cache_index).fap_application_id = p_application_id and
136 			fa_rx_flex_par_seg_t(Lnu_cache_index).fap_id_flex_code = p_id_flex_code and
137 			fa_rx_flex_par_seg_t(Lnu_cache_index).fap_id_flex_num = p_id_flex_num and
138 			fa_rx_flex_par_seg_t(Lnu_cache_index).fap_flex_value_set_id = p_child_value_set_id
139 		    )
140 		Then
141 --*			dbms_output.put_line('present in cache');
142 			Lnu_array_counter := fa_rx_flex_par_seg_t(Lnu_cache_index).fap_parent_segment_num;
143 --*			dbms_output.put_line('Lnu_array_counter = '||Lnu_array_counter);
144 			Exit;
145 		End If;
146 
147 		Lnu_cache_index := fa_rx_flex_par_seg_t.NEXT(Lnu_cache_index);
148 	END LOOP;
149 
150 	If p_seg_array.FIRST Is Null Then
151 --*		dbms_output.put_line('Get_Parent_Value return' ||Lvr_Parent_Value);
152 --*		dbms_output.put_line('Get_Parent_Value -');
153 		Return(Lvr_Parent_Value);
154 	End If;
155 
156 	--* Not present in cache
157 	Lnu_cache_index := Nvl(fa_rx_flex_par_seg_t.count,0) + 1;
158 --*	dbms_output.put_line('Lnu_cache_index = '||Lnu_cache_index);
159 	fa_rx_flex_par_seg_t(Lnu_cache_index).fap_application_id := p_application_id;
160 	fa_rx_flex_par_seg_t(Lnu_cache_index).fap_id_flex_code := p_id_flex_code;
161 	fa_rx_flex_par_seg_t(Lnu_cache_index).fap_id_flex_num := p_id_flex_num ;
162 	fa_rx_flex_par_seg_t(Lnu_cache_index).fap_flex_value_set_id := p_child_value_set_id ;
163 
164 	If Lnu_array_counter Is Null Then
165 --*		dbms_output.put_line('Get_Parent_Value Lnu_array_counter is null');
166 		If par_seg%IsOpen Then
167 			Close par_seg;
168 		End If;
169 		Open par_seg(p_application_id,p_id_flex_code,p_id_flex_num,p_child_value_set_id);
170 		Fetch par_seg into Lnu_array_counter;
171 		Close par_seg;
172 --*		dbms_output.put_line('Get_Parent_Value copy into cache Lnu_array_counter = '||Lnu_array_counter);
173 		fa_rx_flex_par_seg_t(Lnu_cache_index).fap_parent_segment_num := Lnu_array_counter;
174 --*		dbms_output.put_line('216');
175 --*		dbms_output.put_line('218');
176 	End If;
177 
178 	If Lnu_array_counter Is Not Null Then
179 		Lvr_Parent_Value := p_seg_array(Lnu_array_counter);
180 	End If;
181 
182 --*	dbms_output.put_line('Get_Parent_Value return' ||Lvr_Parent_Value);
183 --*	dbms_output.put_line('Get_Parent_Value -');
184 	Return(Lvr_Parent_Value);
185 Exception
186 	When Others Then
187 		err_num := sqlcode;
188 		dbms_output.put_line('Get_Parent_Value exception '||err_num);
189 		dbms_output.put_line('Get_Parent_Value -');
190 		Return(Lvr_Parent_Value);
191 End Get_Parent_Value;
192 -------------------------------------------------------------------------
193 --
194 -- PRIVATE PROCEDURE separate_segments
195 --
196 -- Parameters
197 --		p_seg_array		Segment Array
198 --		p_values		Concatenated Segments
199 --		p_sep			Segment Delimiter
200 --
201 -- Description
202 --   This function takes the concatenated segments and splits them
203 --   up into individual segments (using the segment delimiter) and
204 --   places them into the segment array.
205 --
206 -- Modification History
207 --  KMIZUTA    02-APR-99	Created.
208 --
209 -------------------------------------------------------------------------
210 
211 procedure separate_segments(
212 	p_seg_array in out nocopy seg_array,
213 	p_values in varchar2,
214 	p_sep in varchar2)
215 is
216   i number;
217   next_sep number;
218   l_values varchar2(600);
219 begin
220   IF (g_print_debug) THEN
221   	fa_rx_util_pkg.debug('fa_rx_flex_pkg.separate_segments('||p_values||')+');
222   END IF;
223 
224   l_values := p_values;
225   i := 1;
226   while (l_values is not null) loop
227 	next_sep := instr(l_values, p_sep);
228 	if next_sep = 0 then
229 	  p_seg_array(i) := l_values;
230 	  l_values := null;
231 	else
232 	  p_seg_array(i) := substr(l_values, 1, next_sep-1);
233 	  l_values := substr(l_values, next_sep+1);
234 	end if;
235 
236 	i := i+1;
237   end loop;
238 
239   fa_rx_util_pkg.debug('fa_rx_flex_pkg.separate_segments('||to_char(i-1)||')-');
240 end separate_segments;
241 
242 
243 -------------------------------------------------------------------------
244 --
245 -- PRIVATE FUNCTION get_id_flex_num
246 --
247 -- Parameters
248 --		p_application_id	Application ID of key flexfield
249 --		p_id_flex_code		Flexfield code
250 --		p_id_flex_num		Flexfield structure num
251 --
252 -- Returns NUMBER
253 --   Returns the actual id_flex_num to be used
254 --
255 -- Description
256 --   This function takes the p_id_flex_num as input and returns
257 --   the actual id_flex_num to be used. If p_id_flex_num is not NULL,
258 --   it returns p_id_flex_num. If it is NULL, it returns the one structure
259 --   number that exists for this key flexfield. If there are more than
260 --   one, then this function will raise an exception.
261 --   This is to support key flexfield structures like the item flexfield
262 --   which uses a dataset.
263 --
264 -- Modification History
265 --  KMIZUTA    02-APR-99	Created.
266 --
267 -------------------------------------------------------------------------
268 function get_id_flex_num(
269 	p_application_id in number,
270 	p_id_flex_code in varchar2,
271 	p_id_flex_num in number) return number
272 is
273   l_id_flex_num number;
274 begin
275   if p_id_flex_num is not null then
276     return p_id_flex_num;
277   end if;
278 
279   select id_flex_num into l_id_flex_num
280   from fnd_id_flex_structures
281   where application_id = p_application_id
282   and   id_flex_code = p_id_flex_code;
283 
284   return l_id_flex_num;
285 exception
286 when too_many_rows then
287   IF (g_print_debug) THEN
288   	fa_rx_util_pkg.debug('get_id_flex_num: ' || 'EXCEPTION ==> Too many structures for APP_ID='||to_char(p_application_id)||', ID_FLEX_CODE='||p_id_flex_code);
289   END IF;
290   raise;
291 end get_id_flex_num;
292 
293 
294 -------------------------------------------------------------------------
295 --
296 -- PRIVATE FUNCTION get_segment_delimiter
297 --
298 -- Parameters
299 --		p_application_id	Application ID of key flexfield
300 --		p_id_flex_code		Flexfield code
301 --		p_id_flex_num		Flexfield structure num
302 --
303 -- Returns VARCHAR2
304 --   Returns the segment delimiter for the given key flexfield
305 --
306 -- Description
307 --   This function takes the concatenated segments and splits them
308 --   up into individual segments (using the segment delimiter) and
309 --   places them into the segment array.
310 --
311 -- Modification History
312 --  KMIZUTA    02-APR-99	Created.
313 --
314 -------------------------------------------------------------------------
315 function get_segment_delimiter(
316 	p_application_id in number,
317 	p_id_flex_code in varchar2,
318 	p_id_flex_num in number) return varchar2
319 is
320   sep fnd_id_flex_structures.concatenated_segment_delimiter%type;
321 begin
322   select concatenated_segment_delimiter into sep
323   from fnd_id_flex_structures
324   where	application_id = p_application_id
325   and	id_flex_code = p_id_flex_code
326   and	id_flex_num = p_id_flex_num;
327 
328   return sep;
329 
330 exception
331 when no_data_found then
332   IF (g_print_debug) THEN
333   	fa_rx_util_pkg.debug('get_segment_delimiter: ' || 'EXCEPTION ==> Unable to find segment delimiter!');
334   END IF;
335   raise;
336 end get_segment_delimiter;
337 
338 
339 
340 ------------------------------------
341 -- Public Functions/Procedures
342 ------------------------------------
343 
344 -------------------------------------------------------------------------
345 --
346 -- FUNCTION flex_sql
347 --
348 -- Parameters
349 --		p_application_id	Application ID of key flexfield
350 --		p_id_flex_code		Flexfield code
351 --		p_id_flex_num		Flexfield structure num
352 --		p_table_alias		Table Alias
353 --		p_mode			Output mode
354 --		p_qualifier		Flexfield qualifier or segment number
355 --		p_function		Operator
356 --		p_operand1,2		Operands
357 --
358 -- Returns VARCHAR2
359 --   Returns the required SQL clause
360 --
361 -- Description
362 --   This function mimics the functionality of the userexit FLEXSQL.
363 --   Given the parameters, this function is equivalent to:
364 --	FND FLEXSQL
365 --		CODE=":p_id_flex_code"
366 --		APPL_SHORT_NAME="Short name from :p_application_id"
367 --		OUTPUT=":This is the return value"
368 --		MODE=":p_mode"
369 --		DISPLAY=":p_qualifier"
370 --		NUM=":p_id_flex_num"
371 --		TABLEALIAS=":p_table_alias"
372 --		OPERATOR=":p_function"
373 --		OPERAND1=":p_operand1"
374 --		OPERAND2=":p_operand2"
375 --
376 -- Restrictions
377 --   No support for SHOWDEPSEG parameter
378 --   No support for MULTINUM parameter
379 --   p_qualifier must be 'ALL' or a valid qualifier name or segment number.
380 --   p_function does not support "QBE".
381 --
382 -- Modification History
383 --  KMIZUTA    02-APR-99	Created.
384 --
385 -------------------------------------------------------------------------
386 function flex_sql(
387 	p_application_id in number,
388 	p_id_flex_code in varchar2,
389 	p_id_flex_num in number default null,
390 	p_table_alias in varchar2,
391 	p_mode in varchar2,
392 	p_qualifier in varchar2,
393 	p_function in varchar2 default null,
394 	p_operand1 in varchar2 default null,
395 	p_operand2 in varchar2 default null)
396 return varchar2
397 is
398   segnum   fnd_id_flex_segments.segment_num%type;
399   colname  fnd_id_flex_segments.application_column_name%type;
400   seg_value_set_id fnd_flex_value_sets.flex_value_set_id%type;
401 
402   sep fnd_id_flex_structures.concatenated_segment_delimiter%type;
403   op1 seg_array;
404   op2 seg_array;
405 
406   i number;
407 
408   table_alias varchar2(40);
409   buffer varchar2(2000);
410 
411   l_qualifier	fnd_segment_attribute_types.segment_attribute_type%type;
412   l_segnum	fnd_id_flex_segments.segment_num%type;
413   l_id_flex_num number;
414 begin
415   IF (g_print_debug) THEN
416   	fa_rx_util_pkg.debug('fa_rx_flex_pkg.flex_sql()+');
417   END IF;
418 
419   --
420   -- Check the validity of some of the parameters
421   --
422   if 	p_mode not in ('SELECT', 'WHERE', 'HAVING', 'ORDER BY', 'GROUP BY') or
423 	p_function not in ('=', '<', '>', '<=', '>=', '!=', 'BETWEEN') then
424 		raise invalid_argument;
425   end if;
426 
427   l_id_flex_num := get_id_flex_num(p_application_id, p_id_flex_code, p_id_flex_num);
428 
429   -- Delimiter
430   sep := get_segment_delimiter(
431 		p_application_id,
432 		p_id_flex_code,
433 		l_id_flex_num);
434 
435   -- Actual table alias used in SQL statement
436   if p_table_alias is null then table_alias := null;
437   else table_alias := p_table_alias ||'.';
438   end if;
439 
440 
441   --
442   -- Initialize the op1 and op2 seg_arrays
443   --
444   if p_function in ('=', '<', '>', '<=', '>=', '!=') then
445     if p_qualifier = 'ALL' then
446 	separate_segments(op1, p_operand1, sep);
447     else
448 	op1(1) := p_operand1;
449     end if;
450   elsif p_function in ('BETWEEN') then
451     if p_qualifier = 'ALL' then
452 	separate_segments(op1, p_operand1, sep);
453 	separate_segments(op2, p_operand2, sep);
454     else
455 	op1(1) := p_operand1;
456 	op2(1) := p_operand2;
457     end if;
458   end if;
459 
460 
461   --
462   -- Finally ready for to compile
463   --
464   if cflex%isopen then close cflex;
465   end if;
466   begin
467     l_segnum := to_number(p_qualifier);
468     l_qualifier := null;
469   exception
470   when VALUE_ERROR then
471     l_segnum := null;
472     l_qualifier := p_qualifier;
473   end;
474   open cflex(p_application_id,
475 		p_id_flex_code,
476 		l_id_flex_num,
477 		l_qualifier,
478 		l_segnum);
479   i := 1;
480   loop
481 	--
482 	-- For each row fetched by cflex
483 	-- build up the SQL clause
484 	fetch cflex into segnum, colname, seg_value_set_id;
485 	exit when cflex%notfound;
486 
487 	if p_mode in ('SELECT', 'GROUP BY') then
488 	  if buffer is not null then buffer := buffer || '||''' ||sep|| '''||';
489 	  end if;
490 	  buffer := buffer||table_alias||colname;
491 	elsif p_mode = 'ORDER BY' then
492 	  if buffer is not null then buffer := buffer || ',';
493 	  end if;
494 	  buffer := buffer||table_alias||colname;
495 	elsif p_mode in ('WHERE', 'HAVING') then
496 	  if buffer is not null then buffer := buffer || ' and ';
497 	  end if;
498 	  buffer := buffer||table_alias||colname;
499 
500 	  if p_function in ('=', '<', '>', '<=', '>=', '!=') then
501 	    buffer := buffer || p_function || '''' || op1(i) || '''';
502 	  elsif p_function in ('BETWEEN') then
503 	    buffer := buffer || ' BETWEEN '''|| op1(i) || ''' AND '''|| op2(i) ||'''';
504 	  end if;
505 	end if;
506     	i := i + 1;
507   end loop;
508   close cflex;
509 
510   if buffer is null then
511 	--
512 	-- If the buffer is null then that means
513 	-- that cflex cursor returned no rows.
514 	-- One of the arguments MUST be incorrect
515 	-- Output the parameters and raise error
516 	--
517 	IF (g_print_debug) THEN
518 		fa_rx_util_pkg.debug('Error in fa_rx_flex_pkg.flex_sql()');
519 		fa_rx_util_pkg.debug('flex_sql: ' || 'Application ID = '||to_char(p_application_id));
520 		fa_rx_util_pkg.debug('flex_sql: ' || 'ID Flex Code   = '||p_id_flex_code);
521 		fa_rx_util_pkg.debug('flex_sql: ' || 'ID Flex Num    = '||to_char(l_id_flex_num));
522 		fa_rx_util_pkg.debug('flex_sql: ' || 'Qualifier      = '||p_qualifier);
523 		fa_rx_util_pkg.debug('flex_sql: ' || '  **** No rows returned ****  ');
524 		fa_rx_util_pkg.debug('fa_rx_flex_pkg.flex_sql(EXCEPTION)-');
525 	END IF;
526 	raise invalid_argument;
527   end if;
528 
529   IF (g_print_debug) THEN
530   	fa_rx_util_pkg.debug('fa_rx_flex_pkg.flex_sql('||buffer||')-');
531   END IF;
532   return buffer;
533 
534 exception
535 when others then
536   if cflex%isopen then
537 	close cflex;
538   end if;
539 
540   IF (g_print_debug) THEN
541   	fa_rx_util_pkg.debug('Exception in fa_rx_flex_pkg.flex_sql()');
542   	fa_rx_util_pkg.debug('flex_sql: ' || 'Application ID = '||to_char(p_application_id));
543   	fa_rx_util_pkg.debug('flex_sql: ' || 'ID Flex Code   = '||p_id_flex_code);
544   	fa_rx_util_pkg.debug('flex_sql: ' || 'ID Flex Num    = '||to_char(l_id_flex_num));
545   	fa_rx_util_pkg.debug('flex_sql: ' || 'Table Alias    = '||p_table_alias);
546   	fa_rx_util_pkg.debug('flex_sql: ' || 'Mode           = '||p_mode);
547   	fa_rx_util_pkg.debug('flex_sql: ' || 'Qualifier      = '||p_qualifier);
548   	fa_rx_util_pkg.debug('flex_sql: ' || 'Function       = '||p_function);
549   	fa_rx_util_pkg.debug('flex_sql: ' || 'Operand 1      = '||p_operand1);
550   	fa_rx_util_pkg.debug('flex_sql: ' || 'Operand 2      = '||p_operand2);
551   	fa_rx_util_pkg.debug('fa_rx_flex_pkg.flex_sql(EXCEPTION)-');
552   END IF;
553   raise;
554 end flex_sql;
555 
556 
557 
558 -------------------------------------------------------------------------
559 --
560 -- FUNCTION get_value
561 --
562 -- Parameters
563 --		p_application_id	Application ID of key flexfield
564 --		p_id_flex_code		Flexfield code
565 --		p_id_flex_num		Flexfield structure num
566 --		p_qualifier		Flexfield qualifier or segment number
567 --		p_ccid			Code combination ID
568 --
569 -- Returns VARCHAR2
570 --   Returns the concatenated segment values of the key flexfield
571 --
572 -- Description
573 --   There is no equivalent for this function. This function takes
574 --   the code combination id for the key flexfield and returns the
575 --   actual segment values. This function can be used within
576 --   the after fetch triggers for RXi reports to retrieve the value.
577 --
578 -- Modification History
579 --  KMIZUTA    02-APR-99	Created.
580 
581 --  Bug2951118 LGANDHI 25-MAY-2003 Modified to including Cacheing routine.
582 --
583 -------------------------------------------------------------------------
584 function get_value(
585 	p_application_id in number,
586 	p_id_flex_code in varchar2,
587 	p_id_flex_num in number default NULL,
588 	p_qualifier in varchar2,
589 	p_ccid in number) return varchar2
590 is
591   sqlstmt varchar2(2000);
592 
593   l_table_name varchar2(30);
594   l_unique_id_column_name varchar2(30);
595   l_sep fnd_id_flex_structures.concatenated_segment_delimiter%type;
596   c integer;
597   rows integer;
598   segnum   fnd_id_flex_segments.segment_num%type;
599   colname  fnd_id_flex_segments.application_column_name%type;
600   seg_value_set_id fnd_flex_value_sets.flex_value_set_id%type;
601   buffer varchar2(2000);
602 
603   l_qualifier	fnd_segment_attribute_types.segment_attribute_type%type;
604   l_segnum	fnd_id_flex_segments.segment_num%type;
605   l_id_flex_num number;
606   l_counter     number := 0;
607 begin
608   IF (g_print_debug) THEN
609   	fa_rx_util_pkg.debug('fa_rx_flex_pkg.get_value()+');
610   END IF;
611 
612   IF(p_application_id IS NOT NULL AND p_id_flex_code IS NOT NULL AND p_id_flex_num
613           IS NOT NULL AND p_qualifier IS NOT NULL AND 	p_ccid IS NOT NULL ) THEN
614 
615 LOOP
616 
617 	IF (fa_rx_flex_val_t.EXISTS(l_counter))   THEN
618 
619 
620 	  IF((fa_rx_flex_val_t(l_counter).application_id =  p_application_id)
621               AND (fa_rx_flex_val_t(l_counter).id_flex_code = p_id_flex_code)
622 	      AND (fa_rx_flex_val_t(l_counter).id_flex_num =  p_id_flex_num)
623               AND (fa_rx_flex_val_t(l_counter).qualifier =  p_qualifier)
624               AND (fa_rx_flex_val_t(l_counter).ccid =  p_ccid))
625           THEN
626 
627 
628 		RETURN fa_rx_flex_val_t(l_counter).buffer;
629 
630           ELSE
631 
632 		l_counter:=l_counter + 1;
633 
634 	  END IF;
635 
636 
637 	END IF;
638 
639 
640 EXIT WHEN  (NOT fa_rx_flex_val_t.EXISTS(l_counter));
641 
642 END LOOP;
643 
644 END IF;
645 
646 
647   l_id_flex_num := get_id_flex_num(p_application_id, p_id_flex_code, p_id_flex_num);
648 
649   --
650   -- Get the code combination table and the
651   -- Primary key for that table
652   --
653   select application_table_name , unique_id_column_name
654   into  l_table_name, l_unique_id_column_name
655   from  fnd_id_flexs
656   where application_id = p_application_id
657   and   id_flex_code = p_id_flex_code;
658 
659   -- Get the segment delimiter
660   l_sep := get_segment_delimiter(
661 		p_application_id,
662 		p_id_flex_code,
663 		l_id_flex_num);
664 
665 
666   --
667   -- We are going to build the select statment which
668   -- is going to get us the value we want.
669   --
670 
671   --
672   -- First build the select statment
673   --
674   sqlstmt := null;
675   if cflex%isopen then close cflex;
676   end if;
677   begin
678     l_segnum := to_number(p_qualifier);
679     l_qualifier := null;
680   exception
681   when VALUE_ERROR then
682     l_segnum := null;
683     l_qualifier := p_qualifier;
684   end;
685   open cflex(p_application_id,
686 		p_id_flex_code,
687 		l_id_flex_num,
688 		l_qualifier,
689 		l_segnum);
690 
691   loop
692 	--
693 	-- For each row, get the column name of the
694 	-- code combinations table which has the segment value.
695 	--
696 	fetch cflex into segnum, colname, seg_value_set_id;
697 	exit when cflex%notfound;
698 
699 	if sqlstmt is not null then
700 	  sqlstmt := sqlstmt || '||''' || l_sep || '''||' ||colname;
701 	else
702 	  sqlstmt := colname;
703 	end if;
704   end loop;
705   if sqlstmt is null then
706 	--
707 	-- If the sqlstmt is null then that means
708 	-- that cflex cursor returned no rows.
709 	-- One of the arguments MUST be incorrect
710 	-- Output the parameters and raise error
711 	--
712 	fa_rx_util_pkg.log('Error in fa_rx_flex_pkg.get_value()');
713 	fa_rx_util_pkg.log('Application ID = '||to_char(p_application_id));
714 	fa_rx_util_pkg.log('ID Flex Code   = '||p_id_flex_code);
715 	fa_rx_util_pkg.log('ID Flex Num    = '||to_char(l_id_flex_num));
716 	fa_rx_util_pkg.log('Qualifier      = '||p_qualifier);
717 	fa_rx_util_pkg.log('  **** No rows returned ****  ');
718 
719 	IF (g_print_debug) THEN
720 		fa_rx_util_pkg.debug('fa_rx_flex_pkg.get_value(EXCEPTION)-');
721 	END IF;
722 	raise invalid_argument;
723   end if;
724 
725   sqlstmt := 'SELECT '||sqlstmt||' FROM '||l_table_name||' WHERE '||l_unique_id_column_name||' = :ccid';
726   close cflex;
727   IF (g_print_debug) THEN
728   	fa_rx_util_pkg.debug('get_value: ' || 'Executing SELECT...');
729   	fa_rx_util_pkg.debug('get_value: ' || sqlstmt);
730   END IF;
731 
732   --
733   -- We have the SELECT statement.
734   -- Now execute it.
735   c := dbms_sql.open_cursor;
736   dbms_sql.parse(c, sqlstmt, dbms_sql.native);
737   dbms_sql.bind_variable(c, 'ccid', p_ccid);
738   dbms_sql.define_column(c, 1, buffer, 2000);
739   rows := dbms_sql.execute(c);
740   rows := dbms_sql.fetch_rows(c);
741   if rows <= 0 then
742 	IF (g_print_debug) THEN
743 		fa_rx_util_pkg.debug('Invalid CCID in fa_rx_flex_pkg.get_value()');
744 		fa_rx_util_pkg.debug('get_value: ' || 'CCID = '||to_char(p_ccid));
745 		fa_rx_util_pkg.debug('fa_rx_flex_pkg.get_value(NO_DATA_FOUND)-');
746 	END IF;
747 	raise no_data_found;
748   end if;
749   dbms_sql.column_value(c, 1, buffer);
750   dbms_sql.close_cursor(c);
751 
752   IF (g_print_debug) THEN
753   	fa_rx_util_pkg.debug('fa_rx_flex_pkg.get_value('||buffer||')-');
754   END IF;
755 
756 
757 	IF (p_application_id IS NOT NULL AND p_id_flex_code IS NOT NULL AND p_id_flex_num
758 	 IS NOT NULL AND p_qualifier IS NOT NULL AND p_ccid IS NOT NULL ) THEN
759 
760 
761 	      fa_rx_flex_val_t(l_counter).application_id :=  p_application_id ;
762               fa_rx_flex_val_t(l_counter).id_flex_code   := p_id_flex_code ;
763 	      fa_rx_flex_val_t(l_counter).id_flex_num    :=  p_id_flex_num ;
764               fa_rx_flex_val_t(l_counter).qualifier      :=  p_qualifier;
765               fa_rx_flex_val_t(l_counter).ccid           :=  p_ccid;
766 	      fa_rx_flex_val_t(l_counter).buffer	 :=  buffer;
767 
768 
769 		RETURN	fa_rx_flex_val_t(l_counter).buffer;
770 
771 	 ELSE
772 
773 		 RETURN	buffer ;
774 
775 	END IF;
776 
777 
778 
779 
780 exception
781 when others then
782   if cflex%isopen then
783 	close cflex;
784   end if;
785   if dbms_sql.is_open(c) then
786 	dbms_sql.close_cursor(c);
787   end if;
788 
789   fa_rx_util_pkg.log('Exception in fa_rx_flex_pkg.get_value()');
790   fa_rx_util_pkg.log('Application_ID = ' || to_char(p_Application_ID));
791   fa_rx_util_pkg.log('ID Flex Code   = ' || p_ID_Flex_Code);
792   fa_rx_util_pkg.log('ID Flex Num    = ' || to_char(l_id_flex_num));
793   fa_rx_util_pkg.log('Qualifier      = ' || p_qualifier);
794   fa_rx_util_pkg.log('CCID           = ' || to_char(p_ccid));
795 
796   IF (g_print_debug) THEN
797   	fa_rx_util_pkg.debug('fa_rx_flex_pkg.get_value(EXCEPTION)-');
798   END IF;
799   raise;
800 end get_value;
801 
802 
803 
804 -------------------------------------------------------------------------
805 --
806 -- FUNCTION get_description
807 --
808 -- Parameters
809 --		p_application_id	Application ID of key flexfield
810 --		p_id_flex_code		Flexfield code
811 --		p_id_flex_num		Flexfield structure num
812 --		p_qualifier		Flexfield qualifier or segment number
813 --		p_data			Flexfield Segments
814 --
815 -- Returns VARCHAR2
816 --   Returns the concatenated description of the key flexfield
817 --
818 -- Description
819 --   This function mimics the functionality of the userexit FLEXIDVAL.
820 --   Given the parameters, this function is equivalent to:
821 --	FND FLEXIDVAL
822 --		CODE=":p_id_flex_code"
823 --		APPL_SHORT_NAME="Short name from :p_application_id"
824 --		DATA=":p_data"
825 --		NUM=":p_id_flex_num"
826 --		DISPLAY=":p_qualifier"
827 --		IDISPLAY=":p_qualifier"
828 --		DESCRIPTION=":This is the return value"
829 --
830 -- Restrictions
831 --   No support for SHOWDEPSEG parameter
832 --   No support for VALUE, APROMPT, LPROMPT, PADDED_VALUE, SECURITY parameter
833 --   p_qualifier must be 'ALL' or a valid qualifier name or segment number.
834 --   DISPLAY and IDISPLAY are always the same p_qualifier value.
835 --
836 -- Modification History
837 --  KMIZUTA    02-APR-99	Created.
838 --
839 --  Bug2948619 LGANDHI 25-MAY-2003 Modified to including Cacheing routine.
840 --  Bug2991482 RRAVUNNY Modified the function to accomodate the parent value for
841 --   dependant value sets.
842 
843 -------------------------------------------------------------------------
844 function get_description(
845 	p_application_id in number,
846 	p_id_flex_code in varchar2,
847 	p_id_flex_num in number default NULL,
848 	p_qualifier in varchar2,
849 	p_data in varchar2) return varchar2
850 is
851   segments seg_array;
852   err_num number;
853   sep fnd_id_flex_structures.concatenated_segment_delimiter%type;
854 
855   segnum   fnd_id_flex_segments.segment_num%type;
856   colname  fnd_id_flex_segments.application_column_name%type;
857   seg_value_set_id fnd_flex_value_sets.flex_value_set_id%type;
858 
859   seg_value varchar2(50);
860   seg_desc fnd_flex_values_vl.description%type;
861   concatenated_description varchar2(2000);
862   seg_parent_value FND_FLEX_VALUES.PARENT_FLEX_VALUE_LOW%type;
863   i number;
864 
865   l_qualifier	fnd_segment_attribute_types.segment_attribute_type%type;
866   l_segnum	fnd_id_flex_segments.segment_num%type;
867   l_id_flex_num number;
868   l_counter     number := 0;
869   found         boolean;
870 begin
871 
872 --  Bug2948619 LGANDHI 25-MAY-2003 Modified to including Cacheing routine.
873 
874 IF (p_application_id IS NOT NULL  AND p_id_flex_code IS NOT NULL AND p_id_flex_num IS NOT NULL
875           AND 	p_qualifier IS NOT NULL AND p_data IS NOT NULL )  THEN
876 
877 
878 LOOP
879 
880 IF (fa_rx_flex_desc_t.EXISTS(l_counter))   THEN
881 	IF (   (fa_rx_flex_desc_t(l_counter).application_id =  p_application_id)
882               AND (fa_rx_flex_desc_t(l_counter).id_flex_code=p_id_flex_code)
883 	      AND (fa_rx_flex_desc_t(l_counter).id_flex_num =  p_id_flex_num)
884               AND (fa_rx_flex_desc_t(l_counter).qualifier =  p_qualifier)
885               AND (fa_rx_flex_desc_t(l_counter).data =  p_data)   )
886         THEN
887 		RETURN fa_rx_flex_desc_t(l_counter).concatenated_description;
888         ELSE
889 		l_counter := l_counter + 1;
890 	END IF;
891 END IF;
892 
893 EXIT WHEN  (NOT fa_rx_flex_desc_t.EXISTS(l_counter));
894 
895 END LOOP;
896 
897 END IF;
898 
899 
900 
901 l_id_flex_num := get_id_flex_num(p_application_id, p_id_flex_code, p_id_flex_num);
902   -- Get segment delimiter
903   sep := get_segment_delimiter(
904 		p_application_id,
905 		p_id_flex_code,
906 		l_id_flex_num);
907 
908 
909   -- Separate out the data
910   if p_qualifier = 'ALL' then
911 	separate_segments(segments, p_data, sep);
912   else
913 	segments(1) := p_data;
914   end if;
915 
916   i := 1;
917   if cflex%isopen then close cflex;
918   end if;
919   begin
920     l_segnum := to_number(p_qualifier);
921     l_qualifier := null;
922   exception
923    when others then
924 	err_num := sqlcode;
925 	seg_desc := null;
926 	l_segnum := null;
927 	l_qualifier := p_qualifier;
928   end;
929 
930   open cflex(p_application_id,
931 		p_id_flex_code,
932 		l_id_flex_num,
933 		l_qualifier,
934 		l_segnum);
935   loop
936 	--
937 	-- For each row, get its meaning
938 	--
939 
940 	fetch cflex into segnum, colname, seg_value_set_id;
941 	exit when cflex%notfound;
942 	seg_parent_value := Null;
943 	if p_qualifier = 'ALL' then
944 		seg_parent_value := Get_Parent_Value(segments,
945 				p_application_id ,
946 				p_id_flex_code   ,
947 				l_id_flex_num    ,
948 				seg_value_set_id);
949 	End If;
950 	seg_value := segments(i);
951 	begin
952 		seg_desc := fa_rx_shared_pkg.get_flex_val_meaning(seg_value_set_id, null, seg_value,seg_parent_value);
953 		dbms_output.put_line('seg_parent_value = '||seg_parent_value||' , seg_desc = '||seg_desc);
954 	exception
955 		when no_data_found then
956 			seg_desc := null;
957 		when value_error then
958 			seg_desc := null;
959 		when others then
960 			err_num := sqlcode;
961 			seg_desc := null;
962 	end;
963 
964 	if concatenated_description is not null then
965 	  concatenated_description := concatenated_description || sep;
966 	end if;
967 	concatenated_description := concatenated_description ||seg_desc;
968 
969 	i := i + 1;
970   end loop;
971   close cflex;
972 
973   if concatenated_description is null then
974 	--
975 	-- If the concatenated_description is null then that means
976 	-- that cflex cursor returned no rows.
977 	-- One of the arguments MUST be incorrect
978 	-- Output the parameters and raise error
979 	--
980 	raise invalid_argument;
981   end if;
982 
983 
984 
985 	IF (p_application_id IS NOT NULL  AND p_id_flex_code IS NOT NULL AND p_id_flex_num  IS NOT NULL
986           AND 	p_qualifier IS NOT NULL AND p_data IS NOT NULL )  THEN
987 
988 		fa_rx_flex_desc_t(l_counter).application_id := p_application_id;
989 		fa_rx_flex_desc_t(l_counter).id_flex_code   :=  p_id_flex_code;
990 		fa_rx_flex_desc_t(l_counter).id_flex_num    :=  p_id_flex_num;
991 		fa_rx_flex_desc_t(l_counter).qualifier      :=  p_qualifier;
992 		fa_rx_flex_desc_t(l_counter).data           :=  p_data;
993 		fa_rx_flex_desc_t(l_counter).concatenated_description :=concatenated_description;
994 
995 		RETURN	fa_rx_flex_desc_t(l_counter).concatenated_description ;
996 
997 	 ELSE
998 		 RETURN	concatenated_description ;
999 
1000 	END IF;
1001 
1002 exception
1003 when no_data_found then
1004 	if cflex%isopen then
1005 		close cflex;
1006 	end if;
1007 
1008 	raise;
1009 
1010 when others then
1011 	if cflex%isopen then
1012 		close cflex;
1013 	end if;
1014 
1015 	raise;
1016 
1017 end get_description;
1018 
1019 
1020 end fa_rx_flex_pkg;