DBA Data[Home] [Help]

PACKAGE BODY: APPS.EGO_USER_ATTRS_DATA_PVT

Source


1 PACKAGE BODY EGO_USER_ATTRS_DATA_PVT AS
2 /* $Header: EGOPEFDB.pls 120.111.12020000.9 2013/03/26 03:06:30 evwang ship $ */
3 
4                       ------------------------
5                       -- Private Data Types --
6                       ------------------------
7 
8 
9     TYPE LOCAL_NUMBER_TABLE IS TABLE OF NUMBER
10       INDEX BY BINARY_INTEGER;
11 
12     TYPE LOCAL_VARCHAR_TABLE IS TABLE OF VARCHAR2(30)
13       INDEX BY BINARY_INTEGER;
14 
15     TYPE LOCAL_MEDIUM_VARCHAR_TABLE IS TABLE OF VARCHAR2(300)
16       INDEX BY BINARY_INTEGER;
17 
18     TYPE LOCAL_BIG_VARCHAR_TABLE IS TABLE OF VARCHAR2(5000)
19       INDEX BY BINARY_INTEGER;
20 
21     TYPE LOCAL_COL_NV_PAIR_TABLE IS TABLE OF EGO_COL_NAME_VALUE_PAIR_OBJ
22       INDEX BY BINARY_INTEGER;
23 
24     TYPE LOCAL_USER_ATTR_DATA_TABLE IS TABLE OF EGO_USER_ATTR_DATA_OBJ
25       INDEX BY BINARY_INTEGER;
26 
27     TYPE LOCAL_USER_ATTR_ROW_TABLE IS TABLE OF EGO_USER_ATTR_ROW_OBJ
28       INDEX BY BINARY_INTEGER;
29 
30     TYPE VARCHAR2_TBL_TYPE         IS VARRAY(100) OF VARCHAR2(4000);	-- Bug 8757354
31     TYPE DATE_TBL_TYPE             IS VARRAY(100) OF DATE;
32     TYPE NUMBER_TBL_TYPE           IS VARRAY(100) OF NUMBER;
33 
34     ----------------------------------------------------------------------
35     -- Type for tracking Attr Data for Get_User_Attrs_Data, including a --
36     -- field for DATABASE_COLUMN so we can match up columns from query  --
37     ----------------------------------------------------------------------
38     TYPE LOCAL_USER_ATTR_DATA_REC IS RECORD
39     (
40         ATTR_GROUP_ID                        NUMBER
41        ,APPLICATION_ID                       NUMBER
42        ,ATTR_GROUP_TYPE                      VARCHAR2(40)
43        ,ATTR_GROUP_NAME                      VARCHAR2(30)
44        ,ATTR_NAME                            VARCHAR2(30)
45        ,ATTR_DISP_NAME                       VARCHAR2(80)
46        ,ATTR_DISP_VALUE                      VARCHAR2(4000)	-- Bug 8757354
47        ,ATTR_UNIT_OF_MEASURE                 VARCHAR2(3)
48        ,DATABASE_COLUMN                      VARCHAR2(30)
49        --To pass the internal Value along with the display value
50        ,ATTR_VALUE_STR                      VARCHAR(4000)	-- Bug 8757354
51        ,ATTR_VALUE_NUM                      NUMBER
52        ,ATTR_VALUE_DATE                     DATE
53        ,DATA_TYPE_CODE                      VARCHAR2(8)
54 
55 
56     );
57 
58     TYPE LOCAL_AUGMENTED_DATA_TABLE IS TABLE OF LOCAL_USER_ATTR_DATA_REC
59       INDEX BY BINARY_INTEGER;
60 
61     TYPE LOCAL_HIERARCHY_REC IS RECORD
62     (
63         ATTR_GROUP_TYPE    VARCHAR2(40)
64       , IS_ROOT_NODE       VARCHAR2(1)
65       , IS_LEAF_NODE       VARCHAR2(1)
66     );
67 
68     TYPE LOCAL_HIERARCHY_REC_TABLE IS TABLE OF LOCAL_HIERARCHY_REC
69       INDEX BY BINARY_INTEGER;
70 
71     -- 13719629
72     TYPE VARCHAR2_CACHE_TABTYPE IS TABLE OF VARCHAR2(32767) INDEX BY VARCHAR2(300);
73     TYPE VARTABLE_CACHE_TABTYPE IS TABLE OF LOCAL_MEDIUM_VARCHAR_TABLE INDEX BY VARCHAR2(300);
74 
75                    ------------------------------
76                    -- Private Global Variables --
77                    ------------------------------
78 
79     G_PKG_NAME           CONSTANT   VARCHAR2(30) := 'EGO_USER_ATTRS_DATA_PVT';
80     G_CURRENT_USER_PRIVILEGES       EGO_VARCHAR_TBL_TYPE;
81 
82     G_BULK_PROCESSING_FLAG          BOOLEAN := FALSE;
83     G_DEFAULT_ON_INSERT_FLAG        BOOLEAN := FALSE;
84     G_NEED_TO_RESET_AG_CACHE        BOOLEAN := TRUE;
85 
86     G_OBJECT_NAME_TO_ID_CACHE       LOCAL_VARCHAR_TABLE;
87     G_ASSOCIATION_DATA_LEVEL_CACHE  LOCAL_BIG_VARCHAR_TABLE;
88 
89     --
90     -- Bug 13719629. Performance issue in get table column list
91     -- due to high number of executions. Adding a new PLSQL level
92     -- caching infrastructure to cache metadata.
93     -- sreharih. Fri Feb 17 11:08:31 PST 2012
94     --
95 
96     G_VARCHAR2_CACHE_STORE          VARCHAR2_CACHE_TABTYPE;
97     G_VARTABLE_CACHE_STORE          VARTABLE_CACHE_TABTYPE;
98 
99 
100     G_DEBUG_OUTPUT_LEVEL            NUMBER := 0;
101     G_ADD_ERRORS_TO_FND_STACK       VARCHAR2(1) := 'N';
102     G_USER_ROW_IDENTIFIER           NUMBER := 0;
103 
104     G_B_TABLE_DML                   VARCHAR2(32767);
105     G_TL_TABLE_DML                  VARCHAR2(32767);
106 
107     G_BIND_INDEX                    NUMBER := 0;
108     G_BIND_DATATYPE_TBL             VARCHAR2_TBL_TYPE;
109     G_BIND_TEXT_TBL                 VARCHAR2_TBL_TYPE;
110     G_BIND_DATE_TBL                 DATE_TBL_TYPE;
111     G_BIND_NUMBER_TBL               NUMBER_TBL_TYPE;
112     G_BIND_IDENTIFIER_TBL           VARCHAR2_TBL_TYPE;
113     G_B_BIND_IDENTIFIER_TBL         VARCHAR2_TBL_TYPE;
114     G_TL_BIND_IDENTIFIER_TBL        VARCHAR2_TBL_TYPE;
115 
116     G_B_BIND_INDEX                  NUMBER := 0;
117     G_B_BIND_DATATYPE_TBL           VARCHAR2_TBL_TYPE;
118     G_B_BIND_TEXT_TBL               VARCHAR2_TBL_TYPE;
119     G_B_BIND_DATE_TBL               DATE_TBL_TYPE;
120     G_B_BIND_NUMBER_TBL             NUMBER_TBL_TYPE;
121 
122     G_TL_BIND_INDEX                 NUMBER := 0;
123     G_TL_BIND_DATATYPE_TBL          VARCHAR2_TBL_TYPE;
124     G_TL_BIND_TEXT_TBL              VARCHAR2_TBL_TYPE;
125     G_TL_BIND_DATE_TBL              DATE_TBL_TYPE;
126     G_TL_BIND_NUMBER_TBL            NUMBER_TBL_TYPE;
127 
128     G_DATA_LEVEL_NAME               VARCHAR2(30);
129     G_DATA_LEVEL_ID                 NUMBER;
130     -----------------------------------------------------
131     -- This is a private additional mode for use in    --
132     -- calls to Process_Row from Implement_Change_Line --
133     -----------------------------------------------------
134     G_IMPLEMENT_CREATE_MODE  CONSTANT VARCHAR2(10) := 'IMP_CREATE';
135 
136     G_HIERARCHY_CACHE                 LOCAL_HIERARCHY_REC_TABLE;
137     --in GTIN while creating a row 'SYNC' is passed which changes to 'UPDATE' or 'CREATE'
138     G_SYNC_TO_UPDATE                  VARCHAR2(1) := 'N';
139 
140     G_RET_STS_SUCCESS       VARCHAR2(1) := 'S';
141     G_RET_STS_ERROR         VARCHAR2(1) := 'E';
142     G_RET_STS_UNEXP_ERROR   VARCHAR2(1) := 'U';
143 
144 		----Bug 9277377
145     g_tab_name                               VARCHAR2(30) := NULL;
146     g_owner                                  VARCHAR2(30) := NULL;
147 
148 -- for development user to enable and disable debug
149 G_ENABLE_DEBUG BOOLEAN := FALSE;
150 --Added by geguo for 9373845
151 G_WHO_CREATION_DATE       DATE := NULL;
152 G_WHO_LAST_UPDATE_DATE    DATE := NULL;
153 
154                  ---------------------------------
155                  -- Private Debugging Procedure --
156                  ---------------------------------
157 
158 ----------------------------------------------------------------------
159 /*
160  * The following procedure is for debugging purposes.  Its functionality is
161  * controlled by the global variable G_DEBUG_OUTPUT_LEVEL, whose values are:
162  *
163  * 3: LONG debug messages
164  * 2: MEDIUM debug messages
165  * 1: SHORT debug messages
166  * 0: NO debug messages
167  *
168  * The procedure will only print messages at the specified level or lower.
169  * When logging messages, specify their debug level or let it default to 3.
170  *(You will also have to call "set serveroutput on" to see the output.)
171  */
172 
173 PROCEDURE Debug_Msg(
174         p_message                       IN   VARCHAR2
175        ,p_level_of_debug                IN   NUMBER       DEFAULT 3
176 )
177 IS
178 
179 -- PRAGMA AUTONOMOUS_TRANSACTION;  --- commented bug 9231200
180 
181 BEGIN
182 -- IF G_ENABLE_DEBUG THEN
183 --    sri_debug('EGOPEFDB ' ||p_message);
184 -- END IF;
185  IF (LENGTH(p_message) > 200) THEN
186    Debug_Msg(SUBSTR(p_message, 1, 200), p_level_of_debug);
187    Debug_Msg(SUBSTR(p_message, 201), p_level_of_debug);
188  ELSIF (LENGTH(p_message) > 0) THEN
189    ERROR_HANDLER.Write_Debug('['||TO_CHAR(SYSDATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT)||'] '||p_message);
190 --   dbms_output.put_line(p_message);
191  END IF;
192 END Debug_Msg;
193 
194 ----------------------------------------------------------------------
195 
196 /*
197  * For debugging of SQL strings whose length exceeds the 2000 byte
198  * buffer limit on DBMS_OUTPUT.PUT_LINE.  This procedure handles
199  * strings of any length up to the VARCHAR2 PL/SQL limit of 32767
200  * bytes by making recursive calls as necessary.
201  * (Debug_Msg is defined at the end of this package body.)
202  */
203 
204 PROCEDURE Debug_SQL (
205         p_long_message                  IN   VARCHAR2
206        ,p_level_of_debug                IN   NUMBER := 3
207 )
208 IS
209 
210   BEGIN
211 NULL;
212 /***
213     IF (p_level_of_debug <= G_DEBUG_OUTPUT_LEVEL) THEN
214       IF (LENGTH(p_long_message) > 5000) THEN
215         Debug_SQL(SUBSTR(p_long_message, 1, 5000), p_level_of_debug);
216         Debug_SQL(SUBSTR(p_long_message, 5001), p_level_of_debug);
217       ELSE
218         Debug_Msg(SUBSTR(p_long_message, 1, 200), p_level_of_debug);
219         Debug_Msg(SUBSTR(p_long_message, 201, 200), p_level_of_debug);
220         Debug_Msg(SUBSTR(p_long_message, 401, 200), p_level_of_debug);
221         Debug_Msg(SUBSTR(p_long_message, 601, 200), p_level_of_debug);
222         Debug_Msg(SUBSTR(p_long_message, 801, 200), p_level_of_debug);
223         Debug_Msg(SUBSTR(p_long_message, 1001, 200), p_level_of_debug);
224         Debug_Msg(SUBSTR(p_long_message, 1201, 200), p_level_of_debug);
225         Debug_Msg(SUBSTR(p_long_message, 1401, 200), p_level_of_debug);
226         Debug_Msg(SUBSTR(p_long_message, 1601, 200), p_level_of_debug);
227         Debug_Msg(SUBSTR(p_long_message, 1801, 200), p_level_of_debug);
228         Debug_Msg(SUBSTR(p_long_message, 2001, 200), p_level_of_debug);
229         Debug_Msg(SUBSTR(p_long_message, 2201, 200), p_level_of_debug);
230         Debug_Msg(SUBSTR(p_long_message, 2401, 200), p_level_of_debug);
231         Debug_Msg(SUBSTR(p_long_message, 2601, 200), p_level_of_debug);
232         Debug_Msg(SUBSTR(p_long_message, 2801, 200), p_level_of_debug);
233         Debug_Msg(SUBSTR(p_long_message, 3001, 200), p_level_of_debug);
234         Debug_Msg(SUBSTR(p_long_message, 3201, 200), p_level_of_debug);
235         Debug_Msg(SUBSTR(p_long_message, 3401, 200), p_level_of_debug);
236         Debug_Msg(SUBSTR(p_long_message, 3601, 200), p_level_of_debug);
237         Debug_Msg(SUBSTR(p_long_message, 3801, 200), p_level_of_debug);
238         Debug_Msg(SUBSTR(p_long_message, 4001, 200), p_level_of_debug);
239         Debug_Msg(SUBSTR(p_long_message, 4201, 200), p_level_of_debug);
240         Debug_Msg(SUBSTR(p_long_message, 4401, 200), p_level_of_debug);
241         Debug_Msg(SUBSTR(p_long_message, 4601, 200), p_level_of_debug);
242         Debug_Msg(SUBSTR(p_long_message, 4801, 200), p_level_of_debug);
243       END IF;
244     END IF;
245 ***/
246 END Debug_SQL;
247     --
248     -- Bug 13719629. Performance issue in get table column list
249     -- due to high number of executions. Adding a new PLSQL level
250     -- caching infrastructure to cache metadata.
251     -- sreharih. Fri Feb 17 11:08:31 PST 2012
252     --
253 --
254 -- Preprocess and build key
255 --
256 FUNCTION build_key(p_key IN VARCHAR2) RETURN VARCHAR2 IS
257 
258 BEGIN
259  RETURN substr(p_key, 1, 300);
260 END build_key;
261 
262 --
263 -- Get cached varchar2 value
264 --
265 FUNCTION get_cached_varchar(p_key IN VARCHAR2) RETURN VARCHAR2 IS
266 
267 BEGIN
268   IF(G_VARCHAR2_CACHE_STORE.EXISTS(p_key)) THEN
269      Debug_Msg('Cache hit for ' || p_key || ' : returning ' || G_VARCHAR2_CACHE_STORE(p_key));
270      RETURN G_VARCHAR2_CACHE_STORE(p_key);
271   END IF;
272     Debug_Msg('Cache miss for ' || p_key || ' : returning NULL');
273   RETURN NULL;
274 
275 END get_cached_varchar;
276 
277 --
278 -- Cache varchar2 value
279 --
280 PROCEDURE cache_varchar(p_key   IN VARCHAR2,
281                         p_value IN VARCHAR2) IS
282 
283 
284 BEGIN
285 
286   G_VARCHAR2_CACHE_STORE(p_key) := p_value;
287 
288 END cache_varchar;
289 
290 --
291 -- Get cached varchar2 TABLE
292 --
293 FUNCTION get_cached_vartable(p_key IN VARCHAR2) RETURN LOCAL_MEDIUM_VARCHAR_TABLE IS
294   l_ret LOCAL_MEDIUM_VARCHAR_TABLE;
295 BEGIN
296   IF(G_VARTABLE_CACHE_STORE.EXISTS(p_key)) THEN
297      Debug_Msg('Cache hit for ' || p_key );
298      l_ret := G_VARTABLE_CACHE_STORE(p_key);
299   ELSE
300      Debug_Msg('Cache miss for ' || p_key || ' : returning NULL');
301   END IF;
302 
303   RETURN l_ret;
304 
305 END get_cached_vartable;
306 
307 --
308 -- Cache varchar2 TABLE
309 --
310 
311 PROCEDURE cache_vartable(p_key   IN VARCHAR2,
312                          p_value IN LOCAL_MEDIUM_VARCHAR_TABLE) IS
313 
314 
315 BEGIN
316 
317   G_VARTABLE_CACHE_STORE(p_key) := p_value;
318 
319 END cache_vartable;
320 
321 -- End 13719629
322 
323 ----------------------------------------------------------------------
324 
325 
326 
327            ---------------------------------------------
328            -- Private Helper Procedures and Functions --
329            ---------------------------------------------
330 
331 ----------------------------------------------------------------------
332 --
333 -- Private
334 --
335 ----------------------------------
336 -- Covert data level name to Id --
337 ----------------------------------
338 FUNCTION Get_Data_Level_Id ( p_application_id    IN VARCHAR2
339                             ,p_attr_group_type   IN VARCHAR2
340                             ,p_data_level_name   IN VARCHAR2
341 )
342 RETURN NUMBER
343 IS
344    l_data_level_id   NUMBER;
345 BEGIN
346 
347    IF(p_data_level_name IS NULL) THEN
348      RETURN NULL;
349    END IF;
350 
351    IF(p_data_level_name = G_DATA_LEVEL_NAME) THEN
352      RETURN G_DATA_LEVEL_ID;
353    END IF;
354 
355    SELECT DATA_LEVEL_ID
356      INTO l_data_level_id
357      FROM EGO_DATA_LEVEL_B
358     WHERE APPLICATION_ID = p_application_id
359       AND ATTR_GROUP_TYPE = p_attr_group_type
360       AND DATA_LEVEL_NAME = p_data_level_name;
361 
362    IF(l_data_level_id IS NOT NULL) THEN
363      G_DATA_LEVEL_ID := l_data_level_id;
364      G_DATA_LEVEL_NAME := p_data_level_name;
365    END IF;
366 
367    RETURN l_data_level_id;
368 EXCEPTION
369    WHEN OTHERS THEN
370    Debug_Msg('Failed Get_Data_Level_Id-'||SQLERRM,0);
371    RAISE FND_API.G_EXC_ERROR;
372 END Get_Data_Level_Id;
373 ---------------------------------------------------------------------
374 
375 --
376 -- Private
377 --
378 --------------------------------
379 -- Is name value pairs valid  --
380 --------------------------------
381 PROCEDURE Is_Name_Value_Pairs_Valid
382    ( p_attr_group_id               IN NUMBER
383     ,p_data_level_name             IN VARCHAR2
384     ,p_class_code_hierarchy        IN VARCHAR2
385     ,p_data_level_name_value_pairs IN EGO_COL_NAME_VALUE_PAIR_ARRAY
386     ,x_data_level_id               OUT NOCOPY NUMBER
387     ,x_name_value_pair_valid       OUT NOCOPY VARCHAR2
388    ) IS
389 
390   l_api_name               VARCHAR2(30) := 'Is_Name_Value_Pairs_Valid';
391   l_dynamic_sql            VARCHAR2(5000);
392   l_name_value_pair_valid  BOOLEAN := FALSE;
393   l_dl_metadata_obj        EGO_DATA_LEVEL_METADATA_OBJ;
394 
395 BEGIN
396   Debug_Msg(l_api_name || '  cannot find an unique data level using  ag_ID, DATA_LEVEL, CLASS_CODE '||
397              p_attr_group_id ||', '||p_data_level_name||', '||p_class_code_hierarchy,1);
398   --
399   -- if the passed in pk values satisfy the data level, call perform_dml_on_temlate_row
400   -- old code will return only one record
401   -- new code will have p_data_level and must return only one record
402   --
403   BEGIN
404     l_dynamic_sql := 'SELECT DISTINCT(assoc.data_level_id) ' ||
405                       ' FROM ego_data_level_b dl, ego_obj_ag_assocs_b assoc, ego_fnd_dsc_flx_ctx_ext ag '||
406                      ' WHERE ag.attr_group_id = '||p_attr_group_id ||
407                        ' AND dl.attr_group_type = ag.descriptive_flexfield_name '||
408                        ' AND dl.application_id = ag.application_id ';
409     IF p_data_level_name IS NOT NULL THEN
410       l_dynamic_sql := l_dynamic_sql ||
411                        ' AND dl.data_level_name = '''||p_data_level_name||'''';
412     END IF;
413    l_dynamic_sql := l_dynamic_sql ||
414                        ' AND dl.data_level_id = assoc.data_level_id ' ||
415                        ' AND assoc.attr_group_id = ag.attr_group_id '||
416                        ' AND assoc.classification_code IN ('||p_class_code_hierarchy ||')';
417     Debug_Msg(l_api_name || '   complete query '|| l_dynamic_sql,1);
418     EXECUTE IMMEDIATE l_dynamic_sql
419     INTO x_data_level_id;
420   EXCEPTION
421     WHEN OTHERS THEN
422      Debug_Msg(l_api_name || '   EXCEPTION '||SQLERRM,1);
423      x_data_level_id := NULL;
424      x_name_value_pair_valid := FND_API.G_FALSE;
425   END;
426   l_name_value_pair_valid := FALSE;
427   IF x_data_level_id IS NOT NULL THEN
428     -- if the pk's passed satisfy this data_level, call Perform_DML_On_Template_Row
429     Debug_Msg(l_api_name || '  we have valid data_level_id as  '|| x_data_level_id,1);
430     l_dl_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Metadata(x_data_level_id);
431     IF l_dl_metadata_obj IS NULL THEN
432       Debug_Msg(l_api_name || '  in invalid as we cannot have dl metadata object '|| x_data_level_id,1);
433       l_name_value_pair_valid := FALSE;
434     ELSE
435       IF (p_data_level_name_value_pairs IS NULL OR p_data_level_name_value_pairs.COUNT = 0) THEN
436         Debug_Msg(l_api_name || '  101 ',1);
437         IF l_dl_metadata_obj.pk_column_name1 IS NULL AND
438            l_dl_metadata_obj.pk_column_name2 IS NULL AND
439            l_dl_metadata_obj.pk_column_name3 IS NULL AND
440            l_dl_metadata_obj.pk_column_name4 IS NULL AND
441            l_dl_metadata_obj.pk_column_name5 IS NULL THEN
442         Debug_Msg(l_api_name || '  102 ',1);
443           l_name_value_pair_valid := TRUE;
444         END IF;
445       ELSE
446         FOR i IN p_data_level_name_value_pairs.FIRST .. p_data_level_name_value_pairs.LAST LOOP
447         Debug_Msg(l_api_name || '  103 ',1);
448           IF (p_data_level_name_value_pairs(i).name IS NOT NULL
449               AND
450               (
451                 (p_data_level_name_value_pairs(i).name = l_dl_metadata_obj.pk_column_name1 OR l_dl_metadata_obj.pk_column_name1 IS NULL)
452                 OR
453                 (p_data_level_name_value_pairs(i).name = l_dl_metadata_obj.pk_column_name2 OR l_dl_metadata_obj.pk_column_name2 IS NULL)
454                 OR
455                 (p_data_level_name_value_pairs(i).name = l_dl_metadata_obj.pk_column_name3 OR l_dl_metadata_obj.pk_column_name3 IS NULL)
456                 OR
457                 (p_data_level_name_value_pairs(i).name = l_dl_metadata_obj.pk_column_name4 OR l_dl_metadata_obj.pk_column_name4 IS NULL)
458                 OR
459                 (p_data_level_name_value_pairs(i).name = l_dl_metadata_obj.pk_column_name5 OR l_dl_metadata_obj.pk_column_name5 IS NULL)
460               )
461              ) THEN
462         Debug_Msg(l_api_name || '  104 ',1);
463             l_name_value_pair_valid := TRUE;
464           ELSE
465         Debug_Msg(l_api_name || '  105 ',1);
466             l_name_value_pair_valid := FALSE;
467             EXIT; -- exit the loop
468           END IF;
469         END LOOP;
470       END IF;
471     END IF;
472   END IF;
473 
474         Debug_Msg(l_api_name || '  106 ',1);
475   IF l_name_value_pair_valid THEN
476         Debug_Msg(l_api_name || '  107 ',1);
477     x_name_value_pair_valid := FND_API.G_TRUE;
478   ELSE
479         Debug_Msg(l_api_name || '  108 ',1);
480     x_name_value_pair_valid := FND_API.G_FALSE;
481   END IF;
482 
483 END Is_Name_Value_Pairs_Valid;
484 
485 --
486 -- Private
487 -- To Check whether the attribute is null or not
488 --
489 FUNCTION All_Attr_Values_Are_Null (
490         p_attr_name_value_pairs    IN   EGO_USER_ATTR_DATA_TABLE
491 )
492 RETURN BOOLEAN
493 IS
494 
495     l_attr_count      NUMBER;
496     l_all_are_null    BOOLEAN := TRUE;
497 
498   BEGIN
499 
500     Debug_Msg('In All_Attr_Values_Are_Null, starting', 2);
501 
502     IF (p_attr_name_value_pairs IS NOT NULL AND p_attr_name_value_pairs.COUNT > 0) THEN
503 
504       l_attr_count := p_attr_name_value_pairs.FIRST;
505 
506       WHILE (l_attr_count <= p_attr_name_value_pairs.LAST)
507       LOOP
508         EXIT WHEN (NOT l_all_are_null);
509 
510           IF (p_attr_name_value_pairs(l_attr_count).ATTR_VALUE_STR IS NOT NULL OR
511               p_attr_name_value_pairs(l_attr_count).ATTR_VALUE_NUM IS NOT NULL OR
512               p_attr_name_value_pairs(l_attr_count).ATTR_VALUE_DATE IS NOT NULL OR
513               p_attr_name_value_pairs(l_attr_count).ATTR_DISP_VALUE IS NOT NULL) THEN
514             l_all_are_null := FALSE;
515           END IF;
516 
517         l_attr_count := p_attr_name_value_pairs.NEXT(l_attr_count);
518       END LOOP;
519     END IF;
520 
521     Debug_Msg('In All_Attr_Values_Are_Null, done', 2);
522 
523     RETURN l_all_are_null;
524 
525 END All_Attr_Values_Are_Null;
526 
527 ----------------------------------------------------------------------
528 
529 --
530 -- Private
531 --
532 FUNCTION Get_Hierarchy_For_AG_Type (
533         p_ag_type                       IN   VARCHAR2
534        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
535 )
536 RETURN LOCAL_HIERARCHY_REC
537 IS
538 
539     l_hierarchy_cache_index NUMBER;
540     l_hierarchy_row_index   NUMBER;
541     l_dynamic_sql           VARCHAR2(200);
542     l_hierarchy_query       VARCHAR2(4000);
543     l_pk_column_index       NUMBER;
544     l_pk_value1             VARCHAR2(150);
545     l_pk_value2             VARCHAR2(150);
546     l_pk_value3             VARCHAR2(150);
547     l_pk_value4             VARCHAR2(150);
548     l_pk_value5             VARCHAR2(150);
549 
550     TYPE LOCAL_RESULT_PAIR IS RECORD
551     (
552         IS_ROOT_NODE        VARCHAR2(1)
553       , IS_LEAF_NODE        VARCHAR2(1)
554     );
555 
556     l_result                LOCAL_RESULT_PAIR;
557     l_return_value          LOCAL_HIERARCHY_REC;
558 
559     --Variables for Dynamic Cursor execution
560     TYPE cur_typ IS REF CURSOR;
561 
562     c_cursor              cur_typ;
563     l_hier_res_found      BOOLEAN := FALSE;
564 
565   BEGIN
566 
567     Debug_Msg('In Get_Hierarchy_From_AG_Type, starting for p_ag_type '||p_ag_type, 2);
568 
569     IF (G_HIERARCHY_CACHE.FIRST IS NOT NULL) THEN
570 
571       l_hierarchy_cache_index := G_HIERARCHY_CACHE.FIRST;
572       WHILE (l_hierarchy_cache_index <= G_HIERARCHY_CACHE.LAST)
573       LOOP
574         EXIT WHEN (l_hierarchy_row_index IS NOT NULL);
575         IF (G_HIERARCHY_CACHE(l_hierarchy_cache_index).ATTR_GROUP_TYPE = p_ag_type) THEN
576           l_hierarchy_row_index := l_hierarchy_cache_index;
577         END IF;
578         l_hierarchy_cache_index := G_HIERARCHY_CACHE.NEXT(l_hierarchy_cache_index);
579       END LOOP;
580     ELSE
581        Debug_Msg(' G_HIERARCHY_CACHE IS NULL ');
582        l_hierarchy_cache_index := 1;
583     END IF;
584 
585     IF (l_hierarchy_row_index IS NULL) THEN
586 
587       -- get hierarchy query for this object and run it
588       l_dynamic_sql := 'SELECT HIERARCHY_NODE_QUERY FROM EGO_FND_DESC_FLEXS_EXT '||
589                        'WHERE DESCRIPTIVE_FLEXFIELD_NAME = :1';
590 
591       EXECUTE IMMEDIATE l_dynamic_sql INTO l_hierarchy_query USING p_ag_type;
592 
593       Debug_Msg('In Get_Hierarchy_From_AG_Type,  l_hierarchy_query = '||l_hierarchy_query);
594 
595       IF (l_hierarchy_query IS NOT NULL) THEN
596 
597         -- prepare the hierarchy query binds and run it
598         IF (p_pk_column_name_value_pairs IS NOT NULL AND p_pk_column_name_value_pairs.COUNT > 0) THEN
599 
600           l_pk_column_index := p_pk_column_name_value_pairs.FIRST;
601           WHILE (l_pk_column_index <= p_pk_column_name_value_pairs.LAST)
602           LOOP
603 
604             IF (p_pk_column_name_value_pairs(l_pk_column_index).VALUE IS NOT NULL AND
605                 LENGTH(p_pk_column_name_value_pairs(l_pk_column_index).VALUE) > 0) THEN
606 
607               IF (l_pk_column_index = p_pk_column_name_value_pairs.FIRST) THEN
608                 l_pk_value1 := p_pk_column_name_value_pairs(l_pk_column_index).VALUE;
609               ELSIF (l_pk_column_index = p_pk_column_name_value_pairs.FIRST+1) THEN
610                 l_pk_value2 := p_pk_column_name_value_pairs(l_pk_column_index).VALUE;
611               ELSIF (l_pk_column_index = p_pk_column_name_value_pairs.FIRST+2) THEN
612                 l_pk_value3 := p_pk_column_name_value_pairs(l_pk_column_index).VALUE;
613               ELSIF (l_pk_column_index = p_pk_column_name_value_pairs.FIRST+3) THEN
614                 l_pk_value4 := p_pk_column_name_value_pairs(l_pk_column_index).VALUE;
615               ELSIF (l_pk_column_index = p_pk_column_name_value_pairs.FIRST+4) THEN
616                 l_pk_value5 := p_pk_column_name_value_pairs(l_pk_column_index).VALUE;
617               END IF;
618 
619           Debug_Msg('In Get_Hierarchy_From_AG_Type, Debug [p_pk_column_name_value_pairs(l_pk_column_index).VALUE] = '||p_pk_column_name_value_pairs(l_pk_column_index).VALUE);
620 
621             END IF;
622 
623             l_pk_column_index := p_pk_column_name_value_pairs.NEXT(l_pk_column_index);
624           END LOOP;
625 
626         END IF;
627 
628         -- assuming that if pk_value3 is defined, pk_value1 and 2 are defined as well
629         IF (l_pk_value5 IS NOT NULL) THEN
630           OPEN c_cursor FOR l_hierarchy_query USING l_pk_value1, l_pk_value2, l_pk_value3, l_pk_value4, l_pk_value5;
631           FETCH c_cursor INTO l_result;
632           IF c_cursor%FOUND THEN
633             l_hier_res_found := TRUE;
634           END IF;
635           CLOSE c_cursor;
636 
637         ELSIF (l_pk_value4 IS NOT NULL) THEN
638           OPEN c_cursor FOR l_hierarchy_query USING l_pk_value1, l_pk_value2, l_pk_value3, l_pk_value4;
639           FETCH c_cursor INTO l_result;
640           IF c_cursor%FOUND THEN
641             l_hier_res_found := TRUE;
642           END IF;
643           CLOSE c_cursor;
644 
645         ELSIF (l_pk_value3 IS NOT NULL) THEN
646           OPEN c_cursor FOR l_hierarchy_query USING l_pk_value1, l_pk_value2, l_pk_value3;
647           FETCH c_cursor INTO l_result;
648           IF c_cursor%FOUND THEN
649             l_hier_res_found := TRUE;
650           END IF;
651           CLOSE c_cursor;
652 
653         ELSIF (l_pk_value2 IS NOT NULL) THEN
654 
655           OPEN c_cursor FOR l_hierarchy_query USING l_pk_value1, l_pk_value2;
656           FETCH c_cursor INTO l_result;
657           IF c_cursor%FOUND THEN
658             l_hier_res_found := TRUE;
659           END IF;
660           CLOSE c_cursor;
661 
662         ELSIF (l_pk_value1 IS NOT NULL) THEN
663           OPEN c_cursor FOR l_hierarchy_query USING l_pk_value1;
664           FETCH c_cursor INTO l_result;
665           IF c_cursor%FOUND THEN
666             l_hier_res_found := TRUE;
667           END IF;
668           CLOSE c_cursor;
669 
670         ELSE
671           OPEN c_cursor FOR l_hierarchy_query;
672           FETCH c_cursor INTO l_result;
673           IF c_cursor%FOUND THEN
674             l_hier_res_found := TRUE;
675           END IF;
676           CLOSE c_cursor;
677 
678         END IF;
679 
680         -- cache the results
681         IF l_hier_res_found THEN
682           l_return_value.IS_ROOT_NODE := l_result.IS_ROOT_NODE;
683           l_return_value.IS_LEAF_NODE := l_result.IS_LEAF_NODE;
684         ELSE
685           -- default values if query returned no results
686           l_return_value.IS_ROOT_NODE := 'N';
687           l_return_value.IS_LEAF_NODE := 'N';
688         END IF;
689 
690       ELSE
691        -- if no query was found, return default values
692         l_return_value.IS_ROOT_NODE := 'N';
693         l_return_value.IS_LEAF_NODE := 'N';
694       END IF;
695 
696       l_return_value.ATTR_GROUP_TYPE := p_ag_type;
697       Debug_Msg('In Get_Hierarchy_From_AG_Type, l_hierarchy_cache_index = '||To_Char(l_hierarchy_cache_index));
698       Debug_Msg('l_return_value.IS_ROOT_NODE = '||l_return_value.IS_ROOT_NODE||' and l_return_value.IS_LEAF_NODE = '||l_return_value.IS_LEAF_NODE);
699       IF(l_hierarchy_cache_index IS NULL) THEN
700         l_hierarchy_cache_index := G_HIERARCHY_CACHE.LAST + 1;
701       END IF;
702       G_HIERARCHY_CACHE(l_hierarchy_cache_index) := l_return_value;
703 
704     ELSE
705       l_return_value := G_HIERARCHY_CACHE(l_hierarchy_row_index);
706     END IF;
707 
708     RETURN l_return_value;
709 
710   EXCEPTION
711     WHEN NO_DATA_FOUND THEN
712       Debug_Msg('In Get_Hierarchy_From_AG_Type, EXCEPTION  NO_DATA_FOUND ');
713       RETURN NULL;
714 
715 END Get_Hierarchy_For_AG_Type;
716 
717 ----------------------------------------------------------------------
718 
719 --
720 -- Private
721 --  Get_Changed_Attributes - returns an attribute diff table that lists
722 --  the old and new attribute values for the given DML operation
723 --
724 PROCEDURE Get_Changed_Attributes (
725      p_dml_operation                IN  VARCHAR2
726     ,p_object_name                  IN  VARCHAR2
727     ,p_pk_column_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
728     ,p_attr_group_metadata_obj      IN  EGO_ATTR_GROUP_METADATA_OBJ
729     ,p_ext_table_metadata_obj       IN  EGO_EXT_TABLE_METADATA_OBJ
730     ,p_data_level                   IN  VARCHAR2   DEFAULT NULL --R12C
731     ,p_data_level_name_value_pairs  IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
732     ,p_attr_name_value_pairs        IN  EGO_USER_ATTR_DATA_TABLE
733     ,p_extension_id                 IN  NUMBER     DEFAULT NULL
734     ,p_entity_id                    IN  NUMBER     DEFAULT NULL
735     ,p_entity_index                 IN  NUMBER     DEFAULT NULL
736     ,p_entity_code                  IN  VARCHAR2   DEFAULT NULL
737     ,px_attr_diffs                  IN  OUT NOCOPY EGO_USER_ATTR_DIFF_TABLE
738                                  )
739   IS
740 
741     l_api_name                      VARCHAR2(30) := 'Get_Changed_Attributes';
742     l_attrs_index                   NUMBER;
743     l_dynamic_sql                   VARCHAR2(32767);
744 
745     l_data_level_string             VARCHAR2(1000);
746     l_ag_predicate_list             VARCHAR2(20000);
747     l_db_column_query_table         LOCAL_BIG_VARCHAR_TABLE;
748     l_curr_ag_request_obj           EGO_ATTR_GROUP_REQUEST_OBJ;
749     l_curr_attr_metadata_obj        EGO_ATTR_METADATA_OBJ;
750     l_curr_augmented_attr_rec       LOCAL_USER_ATTR_DATA_REC;
751     l_curr_aug_table_index          NUMBER;
752     l_augmented_data_table          LOCAL_AUGMENTED_DATA_TABLE;
753     l_table_of_high_ind_for_AG_ID   LOCAL_NUMBER_TABLE;
754     l_curr_db_column_name           VARCHAR2(30);
755     l_db_column_list                VARCHAR2(10000);
756     l_to_char_db_col_expression     VARCHAR2(90);
757     l_db_column_tables_index        NUMBER;
758     l_int_to_disp_val_string        VARCHAR2(32767);
759     l_db_column_name_table          LOCAL_VARCHAR_TABLE;
760     l_start_index                   NUMBER;
761     l_substring_length              NUMBER;
762     l_temp_db_query_string          VARCHAR2(32767);
763     l_pk_col_string                 VARCHAR2(1000);
764     l_cursor_id                     NUMBER;
765     l_extension_id                  NUMBER;
766     l_dummy                         NUMBER;
767 
768     l_attr_name_value_rec           EGO_USER_ATTR_DATA_OBJ;
769     l_retrieved_value               VARCHAR2(4000); --bug 12979914
770     l_data_type_codes_table         LOCAL_VARCHAR_TABLE;
771     l_attr_diffs_last               NUMBER;
772     l_data_level_id                 NUMBER;
773     l_dl_col_mdata_array            EGO_COL_METADATA_ARRAY;
774 
775   BEGIN
776 
777     Debug_Msg(l_api_name||' starting', 1);
778 
779     IF (p_dml_operation = 'INSERT') THEN
780 
781       -----------------------------------------------------------------------
782       -- For the INSERT case, just record the new attribute values         --
783       -----------------------------------------------------------------------
784       Debug_Msg(l_api_name||' insert', 1);
785 
786       px_attr_diffs := EGO_USER_ATTR_DIFF_TABLE();
787       l_attrs_index := p_attr_name_value_pairs.FIRST;
788       WHILE (l_attrs_index <= p_attr_name_value_pairs.LAST)
789       LOOP
790 
791         l_attr_name_value_rec := p_attr_name_value_pairs(l_attrs_index);
792 
793         l_curr_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
794                                       p_attr_group_metadata_obj.attr_metadata_table
795                                      ,l_attr_name_value_rec.ATTR_NAME
796                                     );
797 
798         px_attr_diffs.EXTEND();
799         px_attr_diffs(px_attr_diffs.LAST) :=
800           EGO_USER_ATTR_DIFF_OBJ(l_curr_attr_metadata_obj.ATTR_ID            --  attr_id
801                                 ,l_curr_attr_metadata_obj.ATTR_NAME          --  attr_name
802                                 ,null                                        --  old_attr_value_str
803                                 ,null                                        --  old_attr_value_num
804                                 ,null                                        --  old_attr_value_date
805                                 ,null                                        --  old_attr_uom
806                                 ,l_attr_name_value_rec.ATTR_VALUE_STR        --  new_attr_value_str
807                                 ,l_attr_name_value_rec.ATTR_VALUE_NUM        --  new_attr_value_num
808                                 ,l_attr_name_value_rec.ATTR_VALUE_DATE       --  new_attr_value_date
809                                 ,l_attr_name_value_rec.ATTR_UNIT_OF_MEASURE  --  new_attr_uom
810                                 ,l_curr_attr_metadata_obj.UNIQUE_KEY_FLAG    --  unique_key_flag
811                                 ,null                                        --  extension_id
812                                 );
813 
814         l_attrs_index := p_attr_name_value_pairs.NEXT(l_attrs_index);
815 
816         Debug_Msg(l_api_name||' attr('||to_char(l_attrs_index)||
817                   '):'||l_attr_name_value_rec.ATTR_NAME||
818                   ' str:'||l_attr_name_value_rec.ATTR_VALUE_STR||
819                   ' num:'||l_attr_name_value_rec.ATTR_VALUE_NUM||
820                   ' date:'||l_attr_name_value_rec.ATTR_VALUE_DATE||
821                   ' uom:'||l_attr_name_value_rec.ATTR_UNIT_OF_MEASURE);
822 
823       END LOOP;
824 
825     ELSIF (p_dml_operation = 'UPDATE' ) THEN
826 
827       -----------------------------------------------------------------------
828       -- For the UPDATE case, record the new attribute values, then query  --
829       -- for the old values, and pack both into the attr diffs table       --
830       -----------------------------------------------------------------------
831       Debug_Msg(l_api_name||' update', 1);
832 
833       -----------------------------------------------------------------------
834       -- For every Attribute in our table of Attribute names, we find its  --
835       -- metadata and build an augmented version of a Data record for it,  --
836       -- which we then add to a table for later use in correlating a given --
837       -- Database Column to the appropriate Attribute and then building an --
838       -- Attr Data object for that Attr and its value.                     --
839       -----------------------------------------------------------------------
840       px_attr_diffs := EGO_USER_ATTR_DIFF_TABLE();
841       l_attrs_index := p_attr_name_value_pairs.FIRST;
842       WHILE (l_attrs_index <= p_attr_name_value_pairs.LAST)
843       LOOP
844 
845         l_attr_name_value_rec := p_attr_name_value_pairs(l_attrs_index);
846         l_curr_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
847                                       p_attr_group_metadata_obj.attr_metadata_table
848                                      ,l_attr_name_value_rec.ATTR_NAME
849                                     );
850         l_curr_augmented_attr_rec.ATTR_GROUP_ID := p_attr_group_metadata_obj.ATTR_GROUP_ID;
851         l_curr_augmented_attr_rec.APPLICATION_ID := p_attr_group_metadata_obj.APPLICATION_ID;
852         l_curr_augmented_attr_rec.ATTR_GROUP_TYPE := p_attr_group_metadata_obj.ATTR_GROUP_TYPE;
853         l_curr_augmented_attr_rec.ATTR_GROUP_NAME := p_attr_group_metadata_obj.ATTR_GROUP_NAME;
854         l_curr_augmented_attr_rec.ATTR_NAME := l_curr_attr_metadata_obj.ATTR_NAME;
855         l_curr_augmented_attr_rec.ATTR_DISP_NAME := l_curr_attr_metadata_obj.ATTR_DISP_NAME;
856         l_curr_augmented_attr_rec.DATABASE_COLUMN := l_curr_attr_metadata_obj.DATABASE_COLUMN;
857 
858         -----------------------------------------------------------------------
859         -- Store data type codes in a local table so we don't have to call   --
860         -- Find_Metadata_For_Attr again for each attribute                   --
861         -----------------------------------------------------------------------
862         l_data_type_codes_table(l_data_type_codes_table.COUNT+1) := l_curr_attr_metadata_obj.DATA_TYPE_CODE;
863 
864         Debug_Msg(l_api_name||' attr '||to_char(l_attrs_index)||':'||l_curr_attr_metadata_obj.ATTR_NAME, 1);
865 
866         -----------------------------------------------------------------------
867         -- For now, store the new values in the diff table. Later we'll get  --
868         -- the old values                                                    --
869         -----------------------------------------------------------------------
870         px_attr_diffs.EXTEND();
871         px_attr_diffs(px_attr_diffs.LAST) :=
872           EGO_USER_ATTR_DIFF_OBJ(l_curr_attr_metadata_obj.ATTR_ID           --  attr_id
873                                 ,l_curr_attr_metadata_obj.ATTR_NAME         --  attr_name
874                                 ,null                                       --  old_attr_value_str
875                                 ,null                                       --  old_attr_value_num
876                                 ,null                                       --  old_attr_value_date
877                                 ,null                                       --  old_attr_uom
878                                 ,l_attr_name_value_rec.ATTR_VALUE_STR       --  new_attr_value_str
879                                 ,l_attr_name_value_rec.ATTR_VALUE_NUM       --  new_attr_value_num
880                                 ,l_attr_name_value_rec.ATTR_VALUE_DATE      --  new_attr_value_date
881                                 ,l_attr_name_value_rec.ATTR_UNIT_OF_MEASURE --  new_attr_uom
882                                 ,l_curr_attr_metadata_obj.UNIQUE_KEY_FLAG   --  unique_key_flag
883                                 ,null                                       --  extension_id
884                                 );
885 
886         ----------------------------------------------------
887         -- Record the index at which we store this record --
888         ----------------------------------------------------
889         l_curr_aug_table_index := l_augmented_data_table.COUNT+1;
890         l_augmented_data_table(l_curr_aug_table_index) := l_curr_augmented_attr_rec;
891 
892         -----------------------------------------------------------------------------
893         -- If the Database Column for this Attribute is one that has not yet been  --
894         -- processed, put it into the l_db_column_name_table and put its name and  --
895         -- its l_db_column_name_table index into the l_db_column_list. If this has --
896         -- already been done for this column, get the index from l_db_column_list. --
897         -----------------------------------------------------------------------------
898         l_curr_db_column_name := l_curr_augmented_attr_rec.DATABASE_COLUMN;
899 
900         IF (l_db_column_list IS NULL OR
901             INSTR(l_db_column_list, l_curr_db_column_name||':') = 0) THEN
902 
903           l_db_column_tables_index := l_db_column_name_table.COUNT+1;
904           l_db_column_name_table(l_db_column_tables_index) := l_curr_db_column_name;
905           l_db_column_list := l_db_column_list || l_curr_db_column_name || ':'||l_db_column_tables_index||', ';
906 
907         ELSE
908 
909           l_start_index := INSTR(l_db_column_list, l_curr_db_column_name||':') + LENGTH(l_curr_db_column_name||':');
910           l_substring_length := INSTR(l_db_column_list, ',', l_start_index) - l_start_index;
911           l_db_column_tables_index := TO_NUMBER(SUBSTR(l_db_column_list, l_start_index, l_substring_length));
912 
913         END IF;
914 
915         l_to_char_db_col_expression := EGO_USER_ATTRS_COMMON_PVT.Create_DB_Col_Alias_If_Needed(l_curr_attr_metadata_obj);
916 
917         ----------------------------------------------------------------------
918         -- If this Attribute does not have a Value Set that distinguishes   --
919         -- between Internal and Display Values, we just make sure that a    --
920         -- query for this Database Column name (as determined by the index) --
921         -- is in the l_db_column_query_table (we don't want to overwrite a  --
922         -- possibly more complicated query with our simple formatted one,   --
923         -- which is why we only add it if one doesn't already exist).       --
924         ----------------------------------------------------------------------
925         IF (NOT l_db_column_query_table.EXISTS(l_db_column_tables_index)) THEN
926           l_db_column_query_table(l_db_column_tables_index) := l_to_char_db_col_expression;
927         END IF;
928 
929         ------------------------------------------------------------
930         -- We now have the formatted database column name and the --
931         -- Int -> Disp value conversion query; now we see whether --
932         -- there is yet a DECODE query for this database column,  --
933         -- and either create one or add to the existing one       --
934         ------------------------------------------------------------
935         IF ((NOT l_db_column_query_table.EXISTS(l_db_column_tables_index)) OR
936             l_db_column_query_table(l_db_column_tables_index) = l_to_char_db_col_expression) THEN
937 
938           IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG = 'Y') THEN
939             l_db_column_query_table(l_db_column_tables_index) := '' ||
940             'DECODE(ATTR_GROUP_ID,'||l_curr_attr_metadata_obj.ATTR_GROUP_ID||',('||
941             l_int_to_disp_val_string||l_to_char_db_col_expression||'),'||
942             l_to_char_db_col_expression||') '||l_curr_db_column_name;
943           ELSE
944             l_db_column_query_table(l_db_column_tables_index) := '' ||
945               l_to_char_db_col_expression||' '||l_curr_db_column_name;
946           END IF;
947 
948         ELSE
949 
950           ---------------------------------------------------
951           -- Otherwise, we get the current DECODE query... --
952           ---------------------------------------------------
953           l_temp_db_query_string := l_db_column_query_table(l_db_column_tables_index);
954 
955           ---------------------------------------------
956           -- ...insert our new portion at index 22   --
957           -- (i.e., after 'DECODE(ATTR_GROUP_ID,'... --
958           ---------------------------------------------
959           l_temp_db_query_string := SUBSTR(l_temp_db_query_string, 1, 21) ||
960                                       l_curr_attr_metadata_obj.ATTR_GROUP_ID||',('||
961                                       l_int_to_disp_val_string||
962                                       l_to_char_db_col_expression||'),'||
963                                       SUBSTR(l_temp_db_query_string, 22);
964 
965           -------------------------------------------------------------------------
966           -- ...and put the updated query back into the l_db_column_query_table. --
967           -------------------------------------------------------------------------
968           l_db_column_query_table(l_db_column_tables_index) := l_temp_db_query_string;
969 
970         END IF;
971 
972         l_attrs_index := p_attr_name_value_pairs.NEXT(l_attrs_index);
973       END LOOP;
974 
975       --------------------------------------------------------------------------------
976       -- Now we build a query list with all of our Database Column query components --
977       --------------------------------------------------------------------------------
978       l_db_column_list := '';
979       FOR i IN l_db_column_query_table.FIRST .. l_db_column_query_table.LAST
980       LOOP
981 
982         l_db_column_list := l_db_column_list || l_db_column_query_table(i) || ',';
983 
984       END LOOP;
985 
986       -----------------------------------------------------
987       -- Trim the trailing bits from the DB Column lists --
988       -----------------------------------------------------
989       l_db_column_list := RTRIM(l_db_column_list, ',');
990 
991       Debug_Msg(l_api_name||' pk cols '||l_pk_col_string);
992 
993       Init();
994       FND_DSQL.Add_Text('SELECT EXTENSION_ID, ' ||l_db_column_list||
995                          ' FROM ' ||NVL(p_attr_group_metadata_obj.EXT_TABLE_VL_NAME
996                                        ,p_attr_group_metadata_obj.EXT_TABLE_B_NAME)||
997                         ' WHERE ');
998 
999       ----------------------------------------------------------------------
1000       -- We know this call will succeed because we checked the PK columns --
1001       -- against the metadata in Perform_Preliminary_Checks, above        --
1002       ----------------------------------------------------------------------
1003       l_pk_col_string := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
1004                            p_ext_table_metadata_obj.pk_column_metadata
1005                           ,p_pk_column_name_value_pairs
1006                           ,'EQUALS'
1007                           ,TRUE);
1008 
1009       -----------------------------------------------------------------------
1010       -- If extension ID info is available, select on it.                  --
1011       -----------------------------------------------------------------------
1012       IF (p_extension_id IS NOT NULL) THEN
1013         FND_DSQL.Add_Text(' AND EXTENSION_ID = ');
1014         Add_Bind(p_value => p_extension_id);
1015       END IF;
1016 
1017       ----------------------------------------------------------------------------
1018       --We add the data_level_id to the where clause, it would be passed in
1019       --by the implementing team if the R12C changes for enhanced data level
1020       --support have been taken up.
1021       ----------------------------------------------------------------------------
1022       IF(p_data_level IS NOT NULL
1023          AND
1024          FND_API.TO_BOOLEAN(
1025               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => p_attr_group_metadata_obj.ext_table_vl_name
1026                                                            ,p_column_name => 'DATA_LEVEL_ID'
1027                                                            )
1028                            )
1029          ) THEN
1030 
1031         l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
1032                                              ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
1033                                              ,p_data_level);
1034 
1035         FND_DSQL.Add_Text(' AND DATA_LEVEL_ID = ');
1036         Add_Bind (p_bind_identifier => 'DATA_LEVEL_ID'
1037                  ,p_value           =>  l_data_level_id);
1038 
1039       END IF;
1040 
1041 --AMAY TODO: just use EXT ID here and nothing else!!!
1042 -- check with dylan: can we assume we have ext id at perform dml on row pvt
1043       Debug_Msg(l_api_name||' dyn_sql '||l_dynamic_sql);
1044 
1045       IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG = 'Y') THEN
1046 
1047         ------------------------------------------------
1048         -- Build a predicate for each Attribute Group --
1049         -- and concatenate it into a master predicate --
1050         ------------------------------------------------
1051         FND_DSQL.Add_Text(' AND (ATTR_GROUP_ID = ');
1052         Add_Bind(p_value => p_attr_group_metadata_obj.ATTR_GROUP_ID);
1053 
1054         ---------------------------------------------------------------
1055         -- Make a string to use in the query; it will be of the form --
1056         -- 'DATA_LEVEL_1 = <value> AND ... DATA_LEVEL_N = <value>';  --
1057         -- we know this call will succeed because we built the array --
1058         -- of data level name/value pairs ourselves using metadata.  --
1059         ---------------------------------------------------------------
1060 
1061         l_dl_col_mdata_array:= EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Col_Array(p_attr_group_metadata_obj.APPLICATION_ID,
1062                                                                                   p_attr_group_metadata_obj.ATTR_GROUP_TYPE);
1063 
1064         l_data_level_string := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
1065                                  l_dl_col_mdata_array
1066                                 ,p_data_level_name_value_pairs
1067                                 ,'EQUALS'
1068                                 ,TRUE
1069                                 ,' AND '
1070                                );
1071         FND_DSQL.Add_Text(')');
1072 
1073       END IF;
1074 
1075       Debug_SQL(l_dynamic_sql);
1076 
1077       ----------------------------------
1078       -- Open a cursor for processing --
1079       ----------------------------------
1080       l_cursor_id := DBMS_SQL.OPEN_CURSOR;
1081       FND_DSQL.Set_Cursor(l_cursor_id);
1082 
1083       -------------------------------------
1084       -- Parse our dynamic SQL statement --
1085       -------------------------------------
1086       DBMS_SQL.PARSE(l_cursor_id, FND_DSQL.Get_Text(), DBMS_SQL.NATIVE);
1087 
1088       ------------------------
1089       -- Bind our variables --
1090       ------------------------
1091       FND_DSQL.Do_Binds();
1092 
1093       --------------------------------------------------------------------------
1094       -- Register the data types of the columns we are selecting in our query --
1095       -- (in the VARCHAR2 case, that includes stating the maximum size that a --
1096       -- value in the column might be; to be safe we will use 1000 bytes).    --
1097       -- First we register the EXTENSION_ID and ATTR_GROUP_ID...              --
1098       --------------------------------------------------------------------------
1099       DBMS_SQL.Define_Column(l_cursor_id, 1, l_extension_id);
1100 
1101       -----------------------------------
1102       -- ...then the Database Columns. --
1103       -----------------------------------
1104       FOR i IN l_db_column_name_table.FIRST .. l_db_column_name_table.LAST
1105       LOOP
1106 
1107         --------------------------------------------------------------------
1108         -- We cast everything to string for assignment to ATTR_DISP_VALUE --
1109         --------------------------------------------------------------------
1110         DBMS_SQL.Define_Column(l_cursor_id, i+1, l_retrieved_value, 4000); --bug 12979914
1111 
1112       END LOOP;
1113 
1114       -------------------------------
1115       -- Execute our dynamic query --
1116       -------------------------------
1117       l_dummy := DBMS_SQL.Execute(l_cursor_id);
1118 
1119       Debug_Msg(l_api_name||' executed the query', 3);
1120 
1121       -----------------------------------------------------------------------
1122       -- Loop through the result set rows and decode the results into the  --
1123       -- appropriate fields of the attr diff object based on data type     --
1124       -----------------------------------------------------------------------
1125 
1126       l_attr_diffs_last := px_attr_diffs.LAST;
1127       WHILE (DBMS_SQL.FETCH_ROWS(l_cursor_id) > 0)
1128       LOOP
1129 
1130         FOR i IN l_db_column_name_table.FIRST .. l_db_column_name_table.LAST
1131         LOOP
1132 
1133           ----------------------------------------------------------------------
1134           -- Update the correct record in attr diffs.  Use l_attr_diffs_last  --
1135           -- so that insertions do not affect loop iteration                  --
1136           ----------------------------------------------------------------------
1137           FOR j IN px_attr_diffs.FIRST .. l_attr_diffs_last
1138           LOOP
1139 
1140             IF (l_db_column_name_table(i) = l_augmented_data_table(j).DATABASE_COLUMN) THEN
1141 
1142               DBMS_SQL.COLUMN_VALUE(l_cursor_id, 1, l_extension_id);
1143 
1144               ------------------------------------------------
1145               -- We use i+1 because of the offset caused by --
1146               -- requesting EXTENSION_ID                    --
1147               ------------------------------------------------
1148               DBMS_SQL.COLUMN_VALUE(l_cursor_id, i+1, l_retrieved_value);
1149 
1150               Debug_Msg(l_api_name||' db col: '||l_db_column_name_table(i)||' val: '||l_retrieved_value, 1);
1151 
1152               IF (px_attr_diffs(j).OLD_ATTR_VALUE_NUM IS NULL AND
1153                   px_attr_diffs(j).OLD_ATTR_VALUE_DATE IS NULL AND
1154                   px_attr_diffs(j).OLD_ATTR_VALUE_STR IS NULL) THEN
1155 
1156                 ---------------------------------------------------
1157                 -- No entry exists in diff table for this column --
1158                 ---------------------------------------------------
1159                 px_attr_diffs(j).EXTENSION_ID := l_extension_id;
1160 
1161                 IF (l_data_type_codes_table(j) = 'N') THEN
1162                   px_attr_diffs(j).OLD_ATTR_VALUE_NUM :=
1163                     TO_NUMBER(l_retrieved_value);
1164                 ELSIF (l_data_type_codes_table(j) = 'X') THEN
1165                   px_attr_diffs(j).OLD_ATTR_VALUE_DATE :=
1166                     TRUNC(TO_DATE(l_retrieved_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
1167                 ELSIF (l_data_type_codes_table(j) = 'Y') THEN
1168                   px_attr_diffs(j).OLD_ATTR_VALUE_DATE :=
1169                     TO_DATE(l_retrieved_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
1170                 ELSE
1171                   px_attr_diffs(j).OLD_ATTR_VALUE_STR := l_retrieved_value;
1172                 END IF;
1173 
1174               ELSE
1175 
1176                 ---------------------------------------------------
1177                 -- An entry already exists in diff table for     --
1178                 -- this column, so add a new record at the end   --
1179                 ---------------------------------------------------
1180                 px_attr_diffs.EXTEND();
1181                 px_attr_diffs(px_attr_diffs.LAST) :=
1182                        EGO_USER_ATTR_DIFF_OBJ(px_attr_diffs(j).ATTR_ID         --  attr_id
1183                                              ,px_attr_diffs(j).ATTR_NAME       --  attr_name
1184                                              ,null                             --  old_attr_value_str
1185                                              ,null                             --  old_attr_value_num
1186                                              ,null                             --  old_attr_value_date
1187                                              ,null                             --  old_attr_uom
1188                                              ,null                             --  new_attr_value_str
1189                                              ,null                             --  new_attr_value_num
1190                                              ,null                             --  new_attr_value_date
1191                                              ,null                             --  new_attr_uom
1192                                              ,px_attr_diffs(j).UNIQUE_KEY_FLAG --  unique_key_flag
1193                                              ,l_extension_id                   --  extension_id
1194                                              );
1195                 IF (l_data_type_codes_table(j) = 'N') THEN
1196                   px_attr_diffs(px_attr_diffs.LAST).OLD_ATTR_VALUE_NUM :=
1197                     TO_NUMBER(l_retrieved_value);
1198                 ELSIF (l_data_type_codes_table(j) = 'X') THEN
1199                   px_attr_diffs(px_attr_diffs.LAST).OLD_ATTR_VALUE_DATE :=
1200                     TRUNC(TO_DATE(l_retrieved_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
1201                 ELSIF (l_data_type_codes_table(j) = 'Y') THEN
1202                   px_attr_diffs(px_attr_diffs.LAST).OLD_ATTR_VALUE_DATE :=
1203                     TO_DATE(l_retrieved_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
1204                 ELSE
1205                   px_attr_diffs(px_attr_diffs.LAST).OLD_ATTR_VALUE_STR := l_retrieved_value;
1206                 END IF;
1207 
1208               END IF;
1209 
1210             END IF;
1211           END LOOP;
1212         END LOOP;
1213       END LOOP;
1214 
1215       -----------------------------------------
1216       -- Close the cursor when we're through --
1217       -----------------------------------------
1218       IF (l_cursor_id IS NOT NULL) THEN
1219         DBMS_SQL.Close_Cursor(l_cursor_id);
1220         l_cursor_id := NULL;
1221       END IF;
1222     -- Start ssingal -For Ucc Net Attribute Propagation
1223     ELSIF (p_dml_operation = 'DELETE' ) THEN
1224       Debug_Msg(l_api_name||' Transaction Type is Delete ', 1);
1225 
1226       px_attr_diffs    :=      EGO_USER_ATTR_DIFF_TABLE();
1227       l_attrs_index    :=      p_attr_name_value_pairs.FIRST;
1228 
1229       WHILE (l_attrs_index <= p_attr_name_value_pairs.LAST)
1230       LOOP
1231         l_attr_name_value_rec :=  p_attr_name_value_pairs(l_attrs_index);
1232         l_curr_attr_metadata_obj :=   EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr
1233                                       (
1234                                         p_attr_group_metadata_obj.attr_metadata_table,
1235                                         l_attr_name_value_rec.ATTR_NAME
1236                                       );
1237          px_attr_diffs.EXTEND();
1238          -- For Transaction Type Delete
1239          -- Pass the old Attribute Data
1240          -- in the Diff Object
1241          px_attr_diffs(px_attr_diffs.LAST) :=
1242                        EGO_USER_ATTR_DIFF_OBJ(l_curr_attr_metadata_obj.ATTR_ID            --  attr_id
1243                                              ,l_curr_attr_metadata_obj.ATTR_NAME          --  attr_name
1244                                              ,l_attr_name_value_rec.ATTR_VALUE_STR        --  old_attr_value_str
1245                                              ,l_attr_name_value_rec.ATTR_VALUE_NUM        --  old_attr_value_num
1246                                              ,l_attr_name_value_rec.ATTR_VALUE_DATE       --  old_attr_value_date
1247                                              ,l_attr_name_value_rec.ATTR_UNIT_OF_MEASURE  --  old_attr_uom
1248                                              ,null                                        --  new_attr_value_str
1249                                              ,null                                        --  new_attr_value_num
1250                                              ,null                                        --  new_attr_value_date
1251                                              ,null                                        --  new_attr_uom
1252                                              ,l_curr_attr_metadata_obj.UNIQUE_KEY_FLAG    --  unique_key_flag
1253                                              ,null                                        --  extension_id
1254                                              );
1255         l_attrs_index         :=      p_attr_name_value_pairs.NEXT(l_attrs_index);
1256 
1257       END LOOP;
1258     END IF;
1259     -- End ssingal -For Ucc Net Attribute Propagation
1260 
1261     -----------------------------------------
1262     -- Display what's in the diff object   --
1263     -----------------------------------------
1264     FOR a IN px_attr_diffs.FIRST .. px_attr_diffs.LAST
1265     LOOP
1266 
1267       Debug_Msg(l_api_name||' diff '||a||':'||
1268                 px_attr_diffs(a).ATTR_ID||','||px_attr_diffs(a).OLD_ATTR_VALUE_STR||','||
1269                 px_attr_diffs(a).OLD_ATTR_VALUE_NUM||','||px_attr_diffs(a).OLD_ATTR_VALUE_DATE||','||
1270                 px_attr_diffs(a).OLD_ATTR_UOM||','||px_attr_diffs(a).NEW_ATTR_VALUE_STR||','||
1271                 px_attr_diffs(a).NEW_ATTR_VALUE_NUM||','||px_attr_diffs(a).NEW_ATTR_VALUE_DATE||','||
1272                 px_attr_diffs(a).NEW_ATTR_UOM||','||px_attr_diffs(a).UNIQUE_KEY_FLAG||','||
1273                 px_attr_diffs(a).EXTENSION_ID);
1274 
1275     END LOOP;
1276 
1277     Debug_Msg(l_api_name||' done', 1);
1278 
1279   EXCEPTION
1280   WHEN OTHERS THEN
1281     Debug_Msg(l_api_name||' API failed: '||SQLERRM, 1);
1282     RETURN;
1283 
1284 END Get_Changed_Attributes;
1285 
1286 ----------------------------------------------------------------------
1287 
1288 --
1289 -- Private
1290 --
1291 PROCEDURE Propagate_Attributes (
1292           p_pk_column_name_value_pairs    IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
1293         , p_class_code_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
1294         , p_data_level_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
1295         , p_attr_diffs                    IN  EGO_USER_ATTR_DIFF_TABLE
1296         , p_transaction_type              IN  VARCHAR2
1297         , p_attr_group_metadata_obj       IN  EGO_ATTR_GROUP_METADATA_OBJ
1298         , x_return_status                 OUT NOCOPY VARCHAR2
1299         , x_error_message                 OUT NOCOPY VARCHAR2
1300         )
1301   IS
1302     l_dynamic_sql           VARCHAR2(4000);
1303   BEGIN
1304 
1305     Debug_Msg('In Propagate_Attributes, starting', 1);
1306 
1307     IF (p_attr_group_metadata_obj.HIERARCHY_PROPAGATION_API IS NOT NULL) THEN
1308 
1309       Debug_Msg('In Propagate_Attributes, executing API: '||p_attr_group_metadata_obj.HIERARCHY_PROPAGATION_API, 1);
1310 
1311       BEGIN
1312 
1313         EXECUTE IMMEDIATE 'BEGIN '||p_attr_group_metadata_obj.HIERARCHY_PROPAGATION_API||'(:1, :2, :3, :4, :5, :6, :7); END;'
1314         USING  IN  p_pk_column_name_value_pairs
1315        , IN  p_class_code_name_value_pairs
1316        , IN  p_data_level_name_value_pairs
1317              , IN  p_attr_diffs
1318              , IN  p_transaction_type
1319              , IN  p_attr_group_metadata_obj.ATTR_GROUP_ID
1320              , OUT x_error_message;
1321 
1322       EXCEPTION
1323         WHEN OTHERS THEN
1324           Debug_Msg('In Propagate_Attributes, API failed: '||SQLERRM, 1);
1325           x_return_status := G_RET_STS_UNEXP_ERROR;
1326           x_error_message := SQLERRM;
1327           RETURN;
1328       END;
1329 
1330     END IF;
1331     IF x_error_message IS NULL THEN
1332       x_return_status := G_RET_STS_SUCCESS;
1333       Debug_Msg('In Propagate_Attributes, returned successfully ', 1);
1334     ELSE
1335       x_return_status := G_RET_STS_ERROR;
1336       Debug_Msg('In Propagate_Attributes, returned with error: '||x_error_message, 1);
1337     END IF;
1338 
1339     Debug_Msg('In Propagate_Attributes, done', 1);
1340 
1341 END Propagate_Attributes;
1342 
1343 ----------------------------------------------------------------------
1344 
1345 --
1346 -- Private
1347 --
1348 PROCEDURE Convert_Attr_Diff_To_Data (
1349           p_attr_diff_tbl                 IN EGO_USER_ATTR_DIFF_TABLE
1350         , px_attr_data_tbl                IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
1351         , p_true_if_new                   IN BOOLEAN := TRUE
1352         -- px_is_delete returns true if this diff object contains a delete operation
1353         , px_is_delete                    OUT NOCOPY BOOLEAN
1354         , x_error_message                 OUT NOCOPY VARCHAR2
1355         )
1356   IS
1357     l_dynamic_sql           VARCHAR2(4000);
1358     l_row_identifier        NUMBER;
1359     l_debug_msg             VARCHAR2(10);
1360   BEGIN
1361 
1362     Debug_Msg('In Convert_Attr_Diff_To_data, starting', 1);
1363     px_is_delete := TRUE;
1364 
1365     IF p_attr_diff_tbl IS NOT NULL THEN
1366 
1367       FOR i IN p_attr_diff_tbl.FIRST..p_attr_diff_tbl.LAST LOOP
1368 
1369         IF px_attr_data_tbl IS NULL THEN
1370           Debug_Msg('In Convert_Attr_Diff_To_Data, px_attr_data_tbl is NULL', 1);
1371           px_attr_data_tbl := EGO_USER_ATTR_DATA_TABLE();
1372         END IF;
1373 
1374         -- Set row identifier based on previous contents of diff table
1375         l_row_identifier := 1;
1376         FOR j IN p_attr_diff_tbl.FIRST..i-1 LOOP
1377 
1378           IF (p_attr_diff_tbl(i).ATTR_NAME = p_attr_diff_tbl(j).ATTR_NAME) THEN
1379 
1380             l_row_identifier := l_row_identifier + 1;
1381 
1382           END IF;
1383 
1384         END LOOP;
1385 
1386         px_attr_data_tbl.EXTEND;
1387 
1388         IF (p_true_if_new) THEN
1389           px_attr_data_tbl(i) :=
1390             EGO_USER_ATTR_DATA_OBJ
1391       ( l_row_identifier
1392       , p_attr_diff_tbl(i).ATTR_NAME
1393       , p_attr_diff_tbl(i).NEW_ATTR_VALUE_STR
1394       , p_attr_diff_tbl(i).NEW_ATTR_VALUE_NUM
1395       , p_attr_diff_tbl(i).NEW_ATTR_VALUE_DATE
1396       , NULL--p_attr_diff_tbl(i).ATTR_DISP_VALUE
1397       , p_attr_diff_tbl(i).NEW_ATTR_UOM
1398       , NULL--p_attr_diff_tbl(i).USER_ROW_IDENTIFIER
1399       );
1400         ELSE
1401           px_attr_data_tbl(i) :=
1402             EGO_USER_ATTR_DATA_OBJ
1403       ( l_row_identifier
1404       , p_attr_diff_tbl(i).ATTR_NAME
1405       , p_attr_diff_tbl(i).OLD_ATTR_VALUE_STR
1406       , p_attr_diff_tbl(i).OLD_ATTR_VALUE_NUM
1407       , p_attr_diff_tbl(i).OLD_ATTR_VALUE_DATE
1408       , NULL--p_attr_diff_tbl(i).ATTR_DISP_VALUE
1409       , p_attr_diff_tbl(i).OLD_ATTR_UOM
1410       , NULL--p_attr_diff_tbl(i).USER_ROW_IDENTIFIER
1411       );
1412         END IF;
1413 
1414         -- turn px_is_delete off/false if we find a new attribute value
1415         IF px_is_delete AND
1416            (p_attr_diff_tbl(i).NEW_ATTR_VALUE_STR IS NOT NULL OR
1417             p_attr_diff_tbl(i).NEW_ATTR_VALUE_NUM IS NOT NULL OR
1418             p_attr_diff_tbl(i).NEW_ATTR_VALUE_DATE IS NOT NULL OR
1419             p_attr_diff_tbl(i).NEW_ATTR_UOM IS NOT NULL)
1420         THEN
1421 
1422           px_is_delete := FALSE;
1423 
1424         END IF;
1425 
1426       END LOOP;
1427 
1428     END IF;
1429 
1430     if px_is_delete
1431     then
1432       l_debug_msg := 'True' ;
1433     else
1434       l_debug_msg := 'False' ;
1435     end if;
1436 
1437     Debug_Msg('In Convert_Attr_Diff_To_Data, done, px_is_delete = '||l_debug_msg);
1438 
1439 END Convert_Attr_Diff_To_Data;
1440 
1441 
1442 ----------------------------------------------------------------------
1443 --
1444 -- Private
1445 --
1446 FUNCTION Build_Sorted_Data_Table (
1447         p_attributes_data_table         IN   EGO_USER_ATTR_DATA_TABLE
1448 )
1449 RETURN LOCAL_USER_ATTR_DATA_TABLE
1450 IS
1451 
1452 
1453     l_attr_data_table_index  NUMBER;
1454     l_current_data_element   EGO_USER_ATTR_DATA_OBJ;
1455     l_current_row_id         NUMBER;
1456     l_row_id_ordinality_table LOCAL_NUMBER_TABLE;
1457     l_row_id_ordinality      NUMBER;
1458     l_sorted_data_index_table LOCAL_NUMBER_TABLE;
1459     l_s_a_d_table_index      NUMBER;
1460     l_sorted_attr_data_table LOCAL_USER_ATTR_DATA_TABLE;
1461     l_sorted_row_id_table    LOCAL_NUMBER_TABLE;
1462  	  l_sorted_data_element    EGO_USER_ATTR_DATA_TABLE;
1463  	  temp                     EGO_USER_ATTR_DATA_OBJ;
1464 
1465   BEGIN
1466 
1467     Debug_Msg('In Build_Sorted_Data_Table, starting', 2);
1468 
1469     ----------------------------------------------------------------------
1470     -- This function sorts the elements of p_attributes_data_table by   --
1471     -- ROW_IDENTIFIER.  It works by putting all elements for each       --
1472     -- distinct ROW_IDENTIFIER into their own "region" of an index-by   --
1473     -- table, l_sorted_attr_data_table.  To keep track of the correct   --
1474     -- index in each region at which we will insert the next element,   --
1475     -- we use two "helper tables": l_row_id_ordinality_table, the first --
1476     -- helper table, stores the ordinal number of each ROW_IDENTIFIER,  --
1477     -- and l_sorted_data_index_table, the second helper table, stores   --
1478     -- the next available index in the ROW_IDENTIFIER region for the    --
1479     -- ordinal number we fetched from l_row_id_ordinality_table.  This  --
1480     -- solution will allow us to process 1000 rows of data in each call --
1481     -- with 1000 elements for each row of data.                         --
1482     --                                                                  --
1483     -- EXAMPLE: we have two ROW_IDENTIFIERs: 1678 and 239330, and each  --
1484     -- of these ROW_IDENTIFIERs has five elements.  So this function    --
1485     -- loops through all ten passed-in elements and sorts them by       --
1486     -- ROW_IDENTIFIER, as follows (for three of the ten elements).      --
1487     -- First element ROW_IDENTIFIER is 239330.  Since there's nothing   --
1488     -- in l_row_id_ordinality_table for 239330, we add an entry with    --
1489     -- 239330 as the key and 1 (l_row_id_ordinality_table's current     --
1490     -- count + 1) as the value.  That value, 1, is now the ordinal      --
1491     -- number of 239330 (because 239330 is the *1*st ROW_IDENTIFIER     --
1492     -- we processed).  We use this ordinality to determine that the     --
1493     -- region in l_sorted_attr_data_table for 239330 is the region      --
1494     -- starting at (1 * 1000) = 1000.  Since this is the first element  --
1495     -- for this region, the first available index will be 1000, which   --
1496     -- we store in l_sorted_data_index_table.  Then, when we fetch      --
1497     -- the index, we increment the next available index to 1001.        --
1498     -- We use 1000 to add the first element to l_sorted_data_table.     --
1499     -- Second element ROW_IDENTIFIER is 1678.  Since there's nothing    --
1500     -- in l_row_id_ordinality_table for 1678, we add an entry with      --
1501     -- 1678 as the key and 2 (l_row_id_ordinality_table's current       --
1502     -- count + 1) as the value.  That value, 2, is now the ordinal      --
1503     -- number of 1678 (because 1678 is the *2*nd ROW_IDENTIFIER         --
1504     -- we processed).  We use this ordinality to determine that the     --
1505     -- region in l_sorted_attr_data_table for 1678 is the region        --
1506     -- starting at (2 * 1000) = 2000.  Since this is the first element  --
1507     -- for this region, the first available index will be 2000, which   --
1508     -- we store in l_sorted_data_index_table.  Then, when we fetch      --
1509     -- the index, we increment the next available index to 2001.        --
1510     -- We use 2000 to add the second element to l_sorted_data_table.    --
1511     -- Third element ROW_IDENTIFIER is 239330.  We find the ordinality  --
1512     -- for 239330 from l_row_id_ordinality_table as 1, and we use that  --
1513     -- to find the next available index from l_sorted_data_index_table  --
1514     -- as 1001.  Then we increment the next available index to 1002,    --
1515     -- and we use 1001 to add the third element to l_sorted_data_table. --
1516     ----------------------------------------------------------------------
1517     /*l_attr_data_table_index := p_attributes_data_table.FIRST;
1518     WHILE (l_attr_data_table_index <= p_attributes_data_table.LAST)
1519     LOOP
1520 
1521       l_current_data_element := p_attributes_data_table(l_attr_data_table_index);
1522       l_current_row_id := l_current_data_element.ROW_IDENTIFIER;
1523 
1524       IF (NOT l_row_id_ordinality_table.EXISTS(l_current_row_id)) THEN
1525         l_row_id_ordinality_table(l_current_row_id) := l_row_id_ordinality_table.COUNT + 1;
1526       END IF;
1527       l_row_id_ordinality := l_row_id_ordinality_table(l_current_row_id);
1528 
1529       IF (NOT l_sorted_data_index_table.EXISTS(l_row_id_ordinality)) THEN
1530         l_sorted_data_index_table(l_row_id_ordinality) := l_row_id_ordinality * 1000;
1531       END IF;
1532       l_s_a_d_table_index := l_sorted_data_index_table(l_row_id_ordinality);
1533       l_sorted_data_index_table(l_row_id_ordinality) :=
1534         l_sorted_data_index_table(l_row_id_ordinality) + 1;
1535 
1536       l_sorted_attr_data_table(l_s_a_d_table_index) := l_current_data_element;
1537 
1538       l_attr_data_table_index := p_attributes_data_table.NEXT(l_attr_data_table_index);
1539     END LOOP;
1540 
1541     Debug_Msg('In Build_Sorted_Data_Table, p_attributes_data_table.COUNT is '||
1542               p_attributes_data_table.COUNT||' and l_sorted_attr_data_table.COUNT is '||
1543               l_sorted_attr_data_table.COUNT);
1544     Debug_Msg('In Build_Sorted_Data_Table, done', 2);*/
1545 
1546 		--bug 7711838 commented the above as this will not sort the data table records based on row identifier
1547  	     --Simply it will group all the records with the same Row Identifier according to the order in which they are
1548  	     --in Data table. Actual sorting will not take place
1549  	     --7711838 begin
1550 
1551 
1552              --
1553              -- Bug 12626471. PLSQL numeric or value error is thrown
1554              -- if p_attributes_data_table is passed NULL. It can be
1555              -- passed null for DELETE mode. Adding a NULL check.
1556              -- sreharih. Tue Aug  2 12:14:29 PDT 2011
1557              --
1558           IF  p_attributes_data_table IS NOT NULL AND p_attributes_data_table.COUNT > 0 THEN
1559  	     l_attr_data_table_index := p_attributes_data_table.FIRST;
1560  	     l_sorted_data_element:=  p_attributes_data_table;
1561  	     FOR i IN  l_sorted_data_element.FIRST .. l_sorted_data_element.LAST
1562  	     LOOP
1563  	        FOR j IN i+1 .. l_sorted_data_element.LAST
1564  	        LOOP
1565  	             IF(l_sorted_data_element(i).ROW_IDENTIFIER >= l_sorted_data_element(j).ROW_IDENTIFIER) THEN
1566  	                  temp := l_sorted_data_element(i);
1567  	                  l_sorted_data_element(i):=l_sorted_data_element(j);
1568  	                  l_sorted_data_element(j):=temp;
1569  	             END IF;
1570  	        END LOOP ;
1571  	     END LOOP;
1572 
1573  	     l_attr_data_table_index := l_sorted_data_element.FIRST;
1574 
1575  	     WHILE (l_attr_data_table_index <= l_sorted_data_element.LAST)
1576  	     LOOP
1577  	       l_current_data_element := l_sorted_data_element(l_attr_data_table_index);
1578  	       l_current_row_id := l_current_data_element.ROW_IDENTIFIER;
1579  	       l_sorted_attr_data_table(l_attr_data_table_index) := l_current_data_element;
1580  	       l_attr_data_table_index := l_sorted_data_element.NEXT(l_attr_data_table_index);
1581  	     END LOOP;
1582 
1583           END IF;
1584  	    -- 7711838 end
1585 
1586     RETURN l_sorted_attr_data_table;
1587 
1588 END Build_Sorted_Data_Table;
1589 
1590 ----------------------------------------------------------------------
1591 
1592 --
1593 -- Private
1594 --
1595 FUNCTION Build_Sorted_Row_Table (
1596         p_attributes_row_table          IN   EGO_USER_ATTR_ROW_TABLE
1597 ) RETURN LOCAL_USER_ATTR_ROW_TABLE IS
1598 
1599     l_sorted_attr_row_table  LOCAL_USER_ATTR_ROW_TABLE;
1600     l_attr_row_table_index   NUMBER;
1601     l_current_row_element    EGO_USER_ATTR_ROW_OBJ;
1602     l_current_row_id         NUMBER;
1603     l_row_id_index_table     LOCAL_NUMBER_TABLE;
1604 
1605   BEGIN
1606 
1607     Debug_Msg('In Build_Sorted_Row_Table, starting', 2);
1608 
1609     l_attr_row_table_index := p_attributes_row_table.FIRST;
1610     WHILE (l_attr_row_table_index <= p_attributes_row_table.LAST)
1611     LOOP
1612 
1613       l_current_row_element := p_attributes_row_table(l_attr_row_table_index);
1614       l_current_row_id := l_current_row_element.ROW_IDENTIFIER;
1615       l_sorted_attr_row_table(l_current_row_id) := l_current_row_element;
1616 
1617       l_attr_row_table_index := p_attributes_row_table.NEXT(l_attr_row_table_index);
1618     END LOOP;
1619 
1620     Debug_Msg('In Build_Sorted_Row_Table, done', 2);
1621 
1622     RETURN l_sorted_attr_row_table;
1623 
1624 END Build_Sorted_Row_Table;
1625 
1626 ----------------------------------------------------------------------
1627 
1628 --
1629 -- Private
1630 --
1631 FUNCTION Get_Object_Id_From_Name (
1632         p_object_name                   IN   VARCHAR2
1633 )
1634 RETURN NUMBER
1635 IS
1636 
1637     l_object_name_table_index NUMBER;
1638     l_object_id              NUMBER;
1639 
1640   BEGIN
1641 
1642     Debug_Msg('In Get_Object_Id_From_Name, starting for p_object_name '||p_object_name, 2);
1643 
1644     IF (G_OBJECT_NAME_TO_ID_CACHE.FIRST IS NOT NULL) THEN
1645       l_object_name_table_index := G_OBJECT_NAME_TO_ID_CACHE.FIRST;
1646       WHILE (l_object_name_table_index <= G_OBJECT_NAME_TO_ID_CACHE.LAST)
1647       LOOP
1648         EXIT WHEN (l_object_id IS NOT NULL);
1649 
1650         IF (G_OBJECT_NAME_TO_ID_CACHE(l_object_name_table_index) = p_object_name) THEN
1651           l_object_id := l_object_name_table_index;
1652         END IF;
1653 
1654         l_object_name_table_index := G_OBJECT_NAME_TO_ID_CACHE.NEXT(l_object_name_table_index);
1655       END LOOP;
1656     END IF;
1657 
1658     IF (l_object_id IS NULL) THEN
1659 
1660       SELECT OBJECT_ID
1661         INTO l_object_id
1662         FROM FND_OBJECTS
1663        WHERE OBJ_NAME = p_object_name;
1664 
1665       G_OBJECT_NAME_TO_ID_CACHE(l_object_id) := p_object_name;
1666 
1667     END IF;
1668 
1669     Debug_Msg('In Get_Object_Id_From_Name, done: returning l_object_id as '||l_object_id, 2);
1670 
1671     RETURN l_object_id;
1672 
1673   EXCEPTION
1674     WHEN NO_DATA_FOUND THEN
1675       Debug_Msg('In Get_Object_Id_From_Name, EXCEPTION NO_DATA_FOUND', 1);
1676       RETURN NULL;
1677 
1678 END Get_Object_Id_From_Name;
1679 
1680 ----------------------------------------------------------------------
1681 
1682 --
1683 -- Private
1684 --
1685 FUNCTION Build_Data_Level_Array (
1686         p_object_name       IN  VARCHAR2
1687        ,p_data_level_id     IN  NUMBER DEFAULT NULL
1688        ,p_data_level_1      IN  VARCHAR2
1689        ,p_data_level_2      IN  VARCHAR2
1690        ,p_data_level_3      IN  VARCHAR2
1691        ,p_data_level_4      IN  VARCHAR2
1692        ,p_data_level_5      IN  VARCHAR2
1693 )
1694 RETURN EGO_COL_NAME_VALUE_PAIR_ARRAY
1695 IS
1696 
1697     l_object_id                     NUMBER;
1698     l_ext_table_metadata_obj        EGO_EXT_TABLE_METADATA_OBJ;
1699     l_data_level_metadata_array     EGO_COL_METADATA_ARRAY;
1700     l_data_level_1_name_value_pair  EGO_COL_NAME_VALUE_PAIR_OBJ;
1701     l_data_level_2_name_value_pair  EGO_COL_NAME_VALUE_PAIR_OBJ;
1702     l_data_level_3_name_value_pair  EGO_COL_NAME_VALUE_PAIR_OBJ;
1703     l_data_level_4_name_value_pair  EGO_COL_NAME_VALUE_PAIR_OBJ;
1704     l_data_level_5_name_value_pair  EGO_COL_NAME_VALUE_PAIR_OBJ;
1705     l_data_level_name_value_pairs   EGO_COL_NAME_VALUE_PAIR_ARRAY;
1706     l_data_level_metadata           EGO_DATA_LEVEL_METADATA_OBJ;
1707   BEGIN
1708 
1709     Debug_Msg('In Build_Data_Level_Array, starting', 2);
1710 
1711     -----------------------------------------------------------------
1712     -- Added for R12C, in case the data_level_id is passed we need --
1713     -- to process it accordingly.                                  --
1714     -----------------------------------------------------------------
1715     IF(p_data_level_id IS NOT NULL) THEN
1716 
1717       l_data_level_metadata := EGO_USER_ATTRS_COMMON_PVT.get_data_level_metadata(p_data_level_id);
1718       IF(l_data_level_metadata.PK_COLUMN_NAME1 IS NOT NULL) THEN
1719          l_data_level_1_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(l_data_level_metadata.PK_COLUMN_NAME1,p_data_level_1);
1720       END IF;
1721 
1722       IF(l_data_level_metadata.PK_COLUMN_NAME2 IS NOT NULL) THEN
1723          l_data_level_2_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(l_data_level_metadata.PK_COLUMN_NAME2,p_data_level_2);
1724       END IF;
1725 
1726       IF(l_data_level_metadata.PK_COLUMN_NAME3 IS NOT NULL) THEN
1727          l_data_level_3_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(l_data_level_metadata.PK_COLUMN_NAME3,p_data_level_3);
1728       END IF;
1729 
1730       IF(l_data_level_metadata.PK_COLUMN_NAME4 IS NOT NULL) THEN
1731          l_data_level_4_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(l_data_level_metadata.PK_COLUMN_NAME4,p_data_level_4);
1732       END IF;
1733 
1734       IF(l_data_level_metadata.PK_COLUMN_NAME5 IS NOT NULL) THEN
1735          l_data_level_5_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(l_data_level_metadata.PK_COLUMN_NAME5,p_data_level_5);
1736       END IF;
1737 
1738       IF (l_data_level_5_name_value_pair IS NOT NULL) THEN
1739         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1740                                            l_data_level_1_name_value_pair
1741                                           ,l_data_level_2_name_value_pair
1742                                           ,l_data_level_3_name_value_pair
1743                                           ,l_data_level_4_name_value_pair
1744                                           ,l_data_level_5_name_value_pair
1745                                          );
1746       ELSIF (l_data_level_4_name_value_pair IS NOT NULL) THEN
1747         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1748                                            l_data_level_1_name_value_pair
1749                                           ,l_data_level_2_name_value_pair
1750                                           ,l_data_level_3_name_value_pair
1751                                           ,l_data_level_4_name_value_pair
1752                                          );
1753       ELSIF (l_data_level_3_name_value_pair IS NOT NULL) THEN
1754         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1755                                            l_data_level_1_name_value_pair
1756                                           ,l_data_level_2_name_value_pair
1757                                           ,l_data_level_3_name_value_pair
1758                                          );
1759       ELSIF (l_data_level_2_name_value_pair IS NOT NULL) THEN
1760         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1761                                            l_data_level_1_name_value_pair
1762                                           ,l_data_level_2_name_value_pair
1763                                          );
1764       ELSIF (l_data_level_1_name_value_pair IS NOT NULL) THEN
1765         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1766                                            l_data_level_1_name_value_pair
1767                                          );
1768       ELSE
1769         l_data_level_name_value_pairs := NULL;
1770       END IF;
1771     IF (l_data_level_name_value_pairs IS NOT NULL AND l_data_level_name_value_pairs.COUNT IS NOT NULL) THEN
1772       Debug_Msg('In Build_Data_Level_Array, l_data_level_name_value_pairs.COUNT is ' ||l_data_level_name_value_pairs.COUNT);
1773     ELSE
1774       Debug_Msg('In Build_Data_Level_Array, l_data_level_name_value_pairs is NULL or empty');
1775     END IF;
1776       RETURN l_data_level_name_value_pairs;
1777 
1778     END IF;
1779     -----------------------------------------------------------------------------R12C end
1780     l_object_id := Get_Object_Id_From_Name(p_object_name);
1781     l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
1782     l_data_level_metadata_array := l_ext_table_metadata_obj.data_level_metadata;
1783 
1784     IF (l_data_level_metadata_array IS NOT NULL AND l_data_level_metadata_array(1) IS NOT NULL) THEN
1785       l_data_level_1_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(
1786                                           l_data_level_metadata_array(1).COL_NAME
1787                                          ,p_data_level_1
1788                                         );
1789       IF (l_data_level_metadata_array.EXISTS(2) AND l_data_level_metadata_array(2) IS NOT NULL) THEN
1790         l_data_level_2_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(
1791                                             l_data_level_metadata_array(2).COL_NAME
1792                                            ,p_data_level_2
1793                                           );
1794         IF (l_data_level_metadata_array.EXISTS(3) AND l_data_level_metadata_array(3) IS NOT NULL) THEN
1795           l_data_level_3_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(
1796                                             l_data_level_metadata_array(3).COL_NAME
1797                                            ,p_data_level_3
1798                                           );
1799         END IF;
1800       END IF;
1801 
1802       IF (l_data_level_3_name_value_pair IS NOT NULL) THEN
1803         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1804                                            l_data_level_1_name_value_pair
1805                                           ,l_data_level_2_name_value_pair
1806                                           ,l_data_level_3_name_value_pair
1807                                          );
1808       ELSIF (l_data_level_2_name_value_pair IS NOT NULL) THEN
1809         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1810                                            l_data_level_1_name_value_pair
1811                                           ,l_data_level_2_name_value_pair
1812                                          );
1813       ELSE
1814         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1815                                            l_data_level_1_name_value_pair
1816                                          );
1817 
1818       END IF;
1819     END IF;
1820 
1821     IF (l_data_level_name_value_pairs IS NOT NULL AND l_data_level_name_value_pairs.COUNT IS NOT NULL) THEN
1822       Debug_Msg('In Build_Data_Level_Array, l_data_level_name_value_pairs.COUNT is ' ||l_data_level_name_value_pairs.COUNT);
1823     ELSE
1824       Debug_Msg('In Build_Data_Level_Array, l_data_level_name_value_pairs is NULL or empty');
1825     END IF;
1826     Debug_Msg('In Build_Data_Level_Array, done', 2);
1827 
1828     RETURN l_data_level_name_value_pairs;
1829 
1830 END Build_Data_Level_Array;
1831 
1832 ----------------------------------------------------------------------
1833 
1834 --
1835 -- Private
1836 --
1837 FUNCTION Format_Sysdate_Expression (
1838         p_sysdate_expression    IN   VARCHAR2
1839 )
1840 RETURN VARCHAR2
1841 IS
1842     l_dynamic_sql         VARCHAR2(200);
1843     l_formatted_string    VARCHAR2(150);
1844 
1845   BEGIN
1846 
1847     --------------------------------------------------------------
1848     -- We need to remove any '$' chars used to tokenize Sysdate --
1849     -- (these are used when the Value Set bounds are defined).  --
1850     --------------------------------------------------------------
1851     l_formatted_string := TRIM(REPLACE(p_sysdate_expression, '$'));
1852 
1853     ----------------------------------------------------------------
1854     -- Now we rely on dynamic SQL to treat the bound string as an --
1855     -- expression for a Date object, and we call TO_CHAR on it to --
1856     -- turn it into a string version of that Date, formatted into --
1857     -- our standard format.                                       --
1858     ----------------------------------------------------------------
1859     l_dynamic_sql := 'SELECT TO_CHAR('||l_formatted_string||', '''||
1860                      EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT||''') FROM DUAL';
1861     Debug_Msg('In Format_Sysdate_Expression, l_dynamic_sql is as follows:', 3);
1862     Debug_SQL(l_dynamic_sql);
1863     EXECUTE IMMEDIATE l_dynamic_sql INTO l_formatted_string;
1864 
1865     RETURN l_formatted_string;
1866 
1867 END Format_Sysdate_Expression;
1868 
1869 ----------------------------------------------------------------------
1870 
1871 --
1872 -- Private
1873 --
1874 FUNCTION Find_Name_Value_Pair_For_Attr (
1875         p_attr_name_value_pairs   IN  EGO_USER_ATTR_DATA_TABLE
1876        ,p_attr_name               IN  VARCHAR2
1877 )
1878 RETURN EGO_USER_ATTR_DATA_OBJ
1879 IS
1880 
1881     l_table_index     NUMBER;
1882     l_attr_data_obj   EGO_USER_ATTR_DATA_OBJ;
1883 
1884   BEGIN
1885 
1886     Debug_Msg('In Find_Name_Value_Pair_For_Attr, starting for p_attr_name '||p_attr_name, 2);
1887 
1888     IF (p_attr_name_value_pairs IS NOT NULL AND
1889         p_attr_name_value_pairs.COUNT > 0) THEN
1890 
1891       l_table_index := p_attr_name_value_pairs.FIRST;
1892 
1893       IF (p_attr_name IS NOT NULL) THEN
1894 
1895         WHILE (l_table_index <= p_attr_name_value_pairs.LAST)
1896         LOOP
1897           EXIT WHEN (p_attr_name_value_pairs(l_table_index).ATTR_NAME = p_attr_name);
1898 
1899           l_table_index := p_attr_name_value_pairs.NEXT(l_table_index);
1900         END LOOP;
1901 
1902         -----------------------------------------------
1903         -- Make sure we have the correct table index --
1904         -----------------------------------------------
1905         IF (l_table_index IS NOT NULL AND
1906             p_attr_name_value_pairs(l_table_index).ATTR_NAME = p_attr_name) THEN
1907           l_attr_data_obj := p_attr_name_value_pairs(l_table_index);
1908         END IF;
1909       END IF;
1910     END IF;
1911 
1912     Debug_Msg('In Find_Name_Value_Pair_For_Attr, done', 2);
1913 
1914     RETURN l_attr_data_obj;
1915 
1916 END Find_Name_Value_Pair_For_Attr;
1917 
1918 ----------------------------------------------------------------------
1919 
1920 --
1921 -- Private
1922 --
1923 FUNCTION Find_Metadata_For_Col (
1924         p_ext_table_col_metadata  IN  EGO_COL_METADATA_ARRAY
1925        ,p_col_name                IN  VARCHAR2
1926 )
1927 RETURN EGO_COL_METADATA_OBJ
1928 IS
1929 
1930     l_col_metadata_index  NUMBER;
1931     l_col_metadata_obj    EGO_COL_METADATA_OBJ;
1932 
1933   BEGIN
1934 
1935     l_col_metadata_index := p_ext_table_col_metadata.FIRST;
1936     WHILE (l_col_metadata_index <= p_ext_table_col_metadata.LAST)
1937     LOOP
1938       EXIT WHEN (l_col_metadata_obj IS NOT NULL);
1939 
1940       IF (UPPER(p_col_name) = UPPER(p_ext_table_col_metadata(l_col_metadata_index).COL_NAME)) THEN
1941         l_col_metadata_obj := p_ext_table_col_metadata(l_col_metadata_index);
1942       END IF;
1943 
1944 
1945       Debug_Msg('In Find_Metadata_For_Col, next metadata column found - ' ||
1946                 UPPER(p_ext_table_col_metadata(l_col_metadata_index).COL_NAME), 5);
1947 
1948       l_col_metadata_index := p_ext_table_col_metadata.NEXT(l_col_metadata_index);
1949     END LOOP;
1950 
1951     RETURN l_col_metadata_obj;
1952 
1953   EXCEPTION
1954     WHEN OTHERS THEN
1955       Debug_Msg('In Find_Metadata_For_Col, EXCEPTION OTHERS', 1);
1956       RETURN NULL;
1957 
1958 END Find_Metadata_For_Col;
1959 
1960 ----------------------------------------------------------------------
1961 
1962 --
1963 -- Private
1964 --
1965 -- This procedure adds text and/or bind variables, as appropriate, to a dynamic SQL
1966 -- statement being constructed using the FND_DSQL package.  We assume that we are
1967 -- in the midst of building a statement, so we do not call Init().
1968 -- The procedure appends a final p_separator value onto the FND_DSQL list
1969 --
1970 -- The procedure's allowable p_mode values are:
1971 -- 'VALUES': adds bind variables for Attr values, separated appropriately, to FND_DSQL
1972 -- 'VALUES_DEF': special case of VALUES that uses DEFAULT_VALUE for any NULL Attributes
1973 -- 'COLUMNS': adds a comma-delimited list of ext table column names and no bind variables
1974 -- 'COLUMNS_DEF': special case of COLUMNS to match with VALUES_DEF
1975 -- 'EQUALS': adds a list of elements of the form 'ColumnN = :N', where N is a number;
1976 --           the bind variables are added by calls to Add_Bind(), passing the
1977 --           relevant Attribute data values
1978 --
1979 -- The parameter p_which_attrs determines which Attributes are considered in processing
1980 -- NOTE: if p_mode is 'VALUES_DEF' or 'COLUMNS_DEF', *ALL* Attributes will be considered,
1981 -- but the rest of the constraints below will still apply for the p_which_attrs values:
1982 -- 'ALL': processes all Attributes in p_attr_metadata_table
1983 -- 'TRANS': processes passed-in Attributes of data type Translatable Text
1984 -- 'NONTRANS': processes passed-in Attributes that are *not* Translatable Text
1985 -- 'UNIQUE_KEY': processes passed-in Attributes whose UNIQUE_KEY flag is 'Y'
1986 
1987 PROCEDURE Add_Attr_Info_To_Statement (
1988         p_attr_metadata_table     IN  EGO_ATTR_METADATA_TABLE
1989        ,p_attr_name_value_pairs   IN  EGO_USER_ATTR_DATA_TABLE
1990        ,p_separator               IN  VARCHAR2
1991        ,p_mode                    IN  VARCHAR2
1992        ,p_which_attrs             IN  VARCHAR2
1993 ) IS
1994 
1995     l_metadata_driven     BOOLEAN;
1996     l_for_loop_index      NUMBER;
1997     l_for_loop_last       NUMBER;
1998     l_attr_metadata_obj   EGO_ATTR_METADATA_OBJ;
1999     l_attr_data_obj       EGO_USER_ATTR_DATA_OBJ;
2000     l_unique_key_flag     VARCHAR2(1);
2001     l_data_type           VARCHAR2(1);
2002     l_column_name         VARCHAR2(30);
2003     l_default_value       EGO_ATTRS_V.DEFAULT_VALUE%TYPE;
2004     l_candidate_value     VARCHAR2(4000); -- Bug 8757354
2005     l_uom_column          VARCHAR2(30);
2006     l_uom_value           VARCHAR2(10);
2007 
2008   BEGIN
2009 
2010     Debug_Msg('In Add_Attr_Info_To_Statement, starting', 2);
2011     Debug_Msg('In Add_Attr_Info_To_Statement, mode is '||p_mode||' and p_which_attrs is '|| p_which_attrs);
2012     ----------------------------------------------------------------------------
2013     -- If l_metadata_driven is TRUE, we loop through all metadata objects,    --
2014     -- because we want to process every Attribute in the Attribute Group even --
2015     -- if the caller didn't pass in an Attr Data object for each of them.     --
2016     -- Otherwise, we loop through all name/value pairs, ignoring Attributes   --
2017     -- that are in the Attribute Group but aren't mentioned by the caller.    --
2018     ----------------------------------------------------------------------------
2019     l_metadata_driven := (p_which_attrs = 'ALL' OR
2020                           p_mode = 'VALUES_DEF' OR
2021                           p_mode = 'COLUMNS_DEF');
2022 
2023     IF (l_metadata_driven OR
2024         (p_attr_name_value_pairs IS NOT NULL AND
2025          p_attr_name_value_pairs.COUNT > 0)) THEN
2026 
2027       IF (l_metadata_driven) THEN
2028         l_for_loop_index := p_attr_metadata_table.FIRST;
2029         l_for_loop_last := p_attr_metadata_table.LAST;
2030       ELSE
2031         l_for_loop_index := p_attr_name_value_pairs.FIRST;
2032         l_for_loop_last := p_attr_name_value_pairs.LAST;
2033       END IF;
2034 
2035       WHILE (l_for_loop_index <= l_for_loop_last)
2036       LOOP
2037 
2038         ----------------------------------------------------------------
2039         -- 1). Find the metadata and data objects for this Attribute; --
2040         -- if l_metadata_driven is TRUE, then l_attr_data_obj may be  --
2041         -- null, because the caller may not have passed in an Attr    --
2042         -- Data object for that Attribute.                            --
2043         ----------------------------------------------------------------
2044         IF (l_metadata_driven) THEN
2045           l_attr_metadata_obj := p_attr_metadata_table(l_for_loop_index);
2046           l_attr_data_obj := Find_Name_Value_Pair_For_Attr(
2047                                p_attr_name_value_pairs
2048                               ,l_attr_metadata_obj.ATTR_NAME
2049                              );
2050         ELSE
2051           l_attr_data_obj := p_attr_name_value_pairs(l_for_loop_index);
2052           l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
2053                                    p_attr_metadata_table => p_attr_metadata_table
2054                                   ,p_attr_name           => l_attr_data_obj.ATTR_NAME
2055                                  );
2056         END IF;
2057 
2058         ------------------------------------------------------------
2059         -- 2). Find the UNIQUE_KEY_FLAG and DATA_TYPE_CODE values --
2060         ------------------------------------------------------------
2061         l_unique_key_flag := l_attr_metadata_obj.UNIQUE_KEY_FLAG;
2062         l_data_type := l_attr_metadata_obj.DATA_TYPE_CODE;
2063 
2064         -----------------------------------------------------------------
2065         -- 3). If this Attribute should be processed (according to the --
2066         -- p_which_attrs value and relevant metadata), find the value  --
2067         -- (either passed in, Default, or NULL) and also the Database  --
2068         -- Column.  We use these two pieces of information as well as  --
2069         -- things like Data Type to build our list as specified by the --
2070         -- value of p_mode (e.g., 'COLUMNS', 'VALUES_DEF', etc.).      --
2071         -- Note that if the Attribute has a Value Set, we should have  --
2072         -- replaced the passed-in Value (which may have either been    --
2073         -- the Display Value or the Internal Value) with the Internal  --
2074         -- Value in Validate_Row.                                      --
2075         -----------------------------------------------------------------
2076         IF ((UPPER(p_which_attrs) = 'ALL') OR
2077             (UPPER(p_which_attrs) = 'UNIQUE_KEY' AND l_unique_key_flag = 'Y') OR
2078             (UPPER(p_which_attrs) = 'TRANS' AND
2079              l_data_type = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) OR
2080             (UPPER(p_which_attrs) = 'NONTRANS' AND
2081              l_data_type <> EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE)) THEN
2082 
2083           ---------------------------------------------------------------------------
2084           -- Reset UOM, column name, default and value variables each time through --
2085           ---------------------------------------------------------------------------
2086           l_uom_column := NULL;
2087           l_uom_value := NULL;
2088           l_candidate_value := NULL;
2089 
2090           l_column_name := l_attr_metadata_obj.DATABASE_COLUMN;
2091 
2092           IF (UPPER(p_mode) = 'VALUES_DEF') THEN
2093             l_default_value := l_attr_metadata_obj.DEFAULT_VALUE;
2094           ELSE
2095             l_default_value := NULL;
2096           END IF;
2097 
2098           ---------------------------------------------------------------
2099           -- First, try to use the value appropriate for the data type --
2100           ---------------------------------------------------------------
2101           IF (l_data_type IS NULL OR
2102               l_data_type = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
2103               l_data_type = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
2104 
2105             l_candidate_value := l_attr_data_obj.ATTR_VALUE_STR;
2106             Debug_Msg('Candidate value:'||l_candidate_value);
2107 
2108           ELSIF (l_data_type = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
2109 
2110             l_candidate_value := TO_CHAR(l_attr_data_obj.ATTR_VALUE_NUM);
2111 
2112             --------------------------------------------------------------------
2113             -- For all Number Attributes with UOM info, get the data/metadata --
2114             --------------------------------------------------------------------
2115             IF (l_attr_data_obj.ATTR_UNIT_OF_MEASURE IS NOT NULL) THEN
2116 
2117               IF (INSTR(l_column_name, 'N_EXT_ATTR') = 1) THEN
2118                 l_uom_column := 'UOM_' || SUBSTR(l_column_name, 3);
2119               ELSE
2120                 l_uom_column := 'UOM_' || l_column_name;
2121               END IF;
2122               l_uom_value := '''' || l_attr_data_obj.ATTR_UNIT_OF_MEASURE || '''';
2123 
2124             END IF;
2125 
2126           ELSIF (l_data_type = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) THEN
2127 
2128             l_candidate_value := TO_CHAR(TRUNC(l_attr_data_obj.ATTR_VALUE_DATE),
2129                                          EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
2130 
2131           ELSIF (l_data_type = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
2132 
2133             l_candidate_value := TO_CHAR(l_attr_data_obj.ATTR_VALUE_DATE,
2134                                          EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
2135 
2136           END IF;
2137 
2138           ----------------------------------------------------------
2139           -- If what we got is null, try to use the default value --
2140           ----------------------------------------------------------
2141           IF (l_candidate_value IS NULL AND
2142               l_default_value IS NOT NULL) THEN
2143 
2144             ---------------------------------------
2145             -- Format default value if necessary --
2146             ---------------------------------------
2147             IF ((l_data_type = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
2148                  l_data_type = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) AND
2149                 INSTR(UPPER(l_default_value), 'SYSDATE') > 0) THEN
2150               l_default_value := Format_Sysdate_Expression(l_default_value);
2151             END IF;
2152 
2153 /***
2154 ASSUMPTIONS:
2155 1). the UI validates that Number default values with UOM are in the UOM base
2156 2). the UI validates that Date default values are in
2157     EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT and that
2158     Standard Date default values are truncated appropriately
2159 ***/
2160 
2161             l_candidate_value := l_default_value;
2162 
2163           END IF;
2164 
2165           ----------------------------------------------
2166           -- Add column info to the list if necessary --
2167           ----------------------------------------------
2168           IF (UPPER(p_mode) = 'EQUALS' OR
2169               UPPER(p_mode) = 'COLUMNS' OR
2170               UPPER(p_mode) = 'COLUMNS_DEF') THEN
2171 
2172             FND_DSQL.Add_Text(l_column_name);
2173 
2174             IF (UPPER(p_mode) = 'EQUALS') THEN
2175 
2176               IF (l_candidate_value IS NULL AND p_separator = ' AND ') THEN
2177 
2178                 FND_DSQL.Add_Text(' IS ');
2179 
2180               ELSE
2181 
2182                 FND_DSQL.Add_Text(' = ');
2183 
2184               END IF;
2185 
2186             ELSE
2187 
2188               FND_DSQL.Add_Text(p_separator);
2189 
2190             END IF;
2191           END IF;
2192 
2193           ---------------------------------------------
2194           -- Add value info to the list if necessary --
2195           ---------------------------------------------
2196           IF (UPPER(p_mode) = 'EQUALS' OR
2197               UPPER(p_mode) = 'VALUES' OR
2198               UPPER(p_mode) = 'VALUES_DEF') THEN
2199 
2200             IF (l_candidate_value IS NULL) THEN
2201 
2202               FND_DSQL.Add_Text(' NULL ');
2203 
2204             ELSIF (l_data_type IS NULL OR
2205                    l_data_type = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
2206                    l_data_type = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
2207 
2208               /* Bug 9204753. RTRIM() the Attribute Value, for Char and Translatable Text Data Types,
2209                  before adding it to SQL statement, so that spaces at the end will be truncated. */
2210 	      Add_Bind(p_bind_identifier => l_attr_metadata_obj.ATTR_GROUP_NAME||'$$'||l_attr_metadata_obj.ATTR_NAME
2211                       ,p_value           =>  RTRIM(l_candidate_value));
2212 
2213             ELSIF (l_data_type = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
2214 
2215               Add_Bind(p_bind_identifier => l_attr_metadata_obj.ATTR_GROUP_NAME||'$$'||l_attr_metadata_obj.ATTR_NAME
2216                       ,p_value           => TO_NUMBER(l_candidate_value));
2217 
2218             ELSIF (l_data_type = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
2219                    l_data_type = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
2220 
2221               Add_Bind(p_bind_identifier => l_attr_metadata_obj.ATTR_GROUP_NAME||'$$'||l_attr_metadata_obj.ATTR_NAME
2222                       ,p_value           => TO_DATE(l_candidate_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
2223 
2224             END IF;
2225 
2226             FND_DSQL.Add_Text(p_separator);
2227 
2228           END IF;
2229 
2230           -------------------------------------------
2231           -- Add UOM info to the list if necessary --
2232           -------------------------------------------
2233           IF (l_uom_column IS NOT NULL) THEN
2234 
2235             IF (UPPER(p_mode) = 'EQUALS' OR
2236                 UPPER(p_mode) = 'COLUMNS' OR
2237                 UPPER(p_mode) = 'COLUMNS_DEF') THEN
2238 
2239               FND_DSQL.Add_Text(l_uom_column);
2240 
2241               IF (UPPER(p_mode) = 'EQUALS') THEN
2242 
2243                 IF (l_uom_value IS NULL AND p_separator = ' AND ') THEN
2244 
2245                   FND_DSQL.Add_Text(' IS ');
2246 
2247                 ELSE
2248 
2249                   FND_DSQL.Add_Text(' = ');
2250 
2251                 END IF;
2252 
2253               ELSE
2254 
2255                 FND_DSQL.Add_Text(p_separator);
2256 
2257               END IF;
2258             END IF;
2259 
2260             IF (UPPER(p_mode) = 'EQUALS' OR
2261                 UPPER(p_mode) = 'VALUES' OR
2262                 UPPER(p_mode) = 'VALUES_DEF') THEN
2263 
2264               IF (l_uom_value IS NULL) THEN
2265 
2266                 FND_DSQL.Add_Text(' NULL ');
2267 
2268               ELSE
2269 
2270                 FND_DSQL.Add_Text(l_uom_value);
2271 
2272               END IF;
2273 
2274               FND_DSQL.Add_Text(p_separator);
2275 
2276             END IF;
2277           END IF;
2278         END IF;
2279 
2280         IF (l_metadata_driven) THEN
2281           l_for_loop_index := p_attr_metadata_table.NEXT(l_for_loop_index);
2282         ELSE
2283           l_for_loop_index := p_attr_name_value_pairs.NEXT(l_for_loop_index);
2284         END IF;
2285       END LOOP;
2286     END IF;
2287 
2288     Debug_Msg('In Add_Attr_Info_To_Statement, done', 2);
2289 
2290 END Add_Attr_Info_To_Statement;
2291 
2292 ----------------------------------------------------------------------
2293   --
2294   -- Private
2295   --
2296   ----------------------------------------------------------------------
2297 
2298 PROCEDURE Remove_OrderBy_Clause(
2299         px_where_clause                 IN OUT NOCOPY VARCHAR2
2300 ) IS
2301 
2302   l_search_ordby_clause      LONG;
2303   l_ord_index                NUMBER;
2304   l_by_index                 NUMBER;
2305   l_last_ord_index           NUMBER;
2306   --bug 5119374
2307   l_has_order_by             BOOLEAN := FALSE;
2308 
2309   BEGIN
2310     -- initialize variables
2311 
2312     l_search_ordby_clause := UPPER(px_where_clause);
2313     l_ord_index := INSTR(l_search_ordby_clause, 'ORDER ');
2314 
2315     IF l_ord_index <> 0 THEN
2316       l_last_ord_index := l_ord_index;
2317       --bug 5119374
2318       l_has_order_by :=TRUE;
2319     ELSE
2320       l_last_ord_index := length(px_where_clause);
2321     END IF;
2322 
2323     -- find the index of the last 'ORDER BY' clause
2324 
2325     WHILE (l_ord_index <> 0) LOOP
2326       l_by_index := INSTR(SUBSTR(l_search_ordby_clause, l_ord_index + 5), 'BY ');
2327       IF l_by_index <> 0 THEN
2328         l_search_ordby_clause := SUBSTR(l_search_ordby_clause, l_ord_index + 5 + l_by_index + 2);
2329         l_ord_index := INSTR(l_search_ordby_clause, 'ORDER ');
2330 
2331         -- if there are more 'ORDER BY' clauses, increment index:
2332         -- l_last_ord_index  += 5 letters for 'ORDER' +
2333         --                   +  index of 'BY' + 2 letters for 'BY'
2334         --                   +  (index of the next 'ORDER BY' - 1)
2335 
2336         IF l_ord_index <> 0 THEN
2337           l_last_ord_index := l_last_ord_index + 5 + l_by_index + 2 + l_ord_index - 1;
2338         END IF;
2339       ELSE
2340         l_ord_index := 0;
2341       END IF;
2342     END LOOP;
2343 
2344     -- if there is a close bracket: 'ORDER BY' clause is nested -> do nothing
2345     -- if no close bracket, remove 'ORDER BY' clause
2346     -- if after ORDER BY both '(' and also ')' exist then is not a subquery if and only if there is again no ')' after the previous
2347     -- checks. e.g. "ORDER BY TO_NUMBER()" or "ORDER BY TO_NUMBER(X) ) "
2348     --                                                                                                       ^ for closing the subquery
2349     IF (l_has_order_by
2350          AND ( INSTR(l_search_ordby_clause, ')') = 0
2351                    OR ( INSTR(l_search_ordby_clause, '(') <> 0
2352                           AND INSTR(l_search_ordby_clause, ')') <> 0
2353                           AND (
2354                                 INSTR(l_search_ordby_clause,')')= length(l_search_ordby_clause)  --bug 12630681
2355                              OR INSTR(SUBSTR(l_search_ordby_clause, INSTR(l_search_ordby_clause,')') + 1 ), ')' ) = 0 )
2356                         )
2357                 )
2358          ) THEN --bug 5119374
2359       px_where_clause := RTRIM(SUBSTR(px_where_clause, 0, l_last_ord_index - 1));
2360     END IF;
2361 
2362 END Remove_OrderBy_Clause;
2363 
2364 ----------------------------------------------------------------------
2365 
2366 -- This procedure builds a WHERE clause, which it adds to a SQL statement being
2367 -- built using the FND_DSQL package.  This procedure neither initializes nor
2368 -- executes that statement; it just adds text and bind variables through calls
2369 -- to FND_DSQL procedures.
2370 
2371 PROCEDURE Build_Where_Clause (
2372         p_attr_group_metadata_obj       IN  EGO_ATTR_GROUP_METADATA_OBJ
2373        ,p_ext_table_metadata_obj        IN  EGO_EXT_TABLE_METADATA_OBJ
2374        ,p_pk_column_name_value_pairs    IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
2375        ,p_data_level                    IN  VARCHAR2   DEFAULT NULL --R12C
2376        ,p_data_level_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
2377        ,p_attr_name_value_pairs         IN  EGO_USER_ATTR_DATA_TABLE DEFAULT NULL
2378 ) IS
2379 
2380     l_api_name               VARCHAR2(30) := 'Build_Where_Clause';
2381     l_pk_col_string          VARCHAR2(1000) := '';
2382     l_data_level_string      VARCHAR2(1000) := '';
2383     l_data_level_id          NUMBER;
2384     l_dl_col_mdata_array     EGO_COL_METADATA_ARRAY;
2385   BEGIN
2386 
2387     Debug_Msg(l_api_name || ' starting, p_data_level='||p_data_level, 2);
2388     ---------------------------------------------------------------
2389     -- We add the Unique Key portion of the clause first because --
2390     -- Add_Attr_Info_To_Statement appends a trailing separator   --
2391     -- to the list if it adds anything to it; this also means we --
2392     -- don't need to add an ' AND ' after we add the Unique Key  --
2393     -- info, because Add_Attr_Info_To_Statement does that for us --
2394     ---------------------------------------------------------------
2395     IF (p_attr_name_value_pairs IS NOT NULL AND
2396         p_attr_name_value_pairs.COUNT > 0 AND
2397         p_attr_group_metadata_obj.MULTI_ROW_CODE = 'Y') THEN
2398 
2399       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
2400                                 ,p_attr_name_value_pairs
2401                                 ,' AND '
2402                                 ,'EQUALS'
2403                                 ,'UNIQUE_KEY');
2404 
2405     END IF;
2406 
2407     IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG ='Y') THEN
2408       FND_DSQL.Add_Text(' ATTR_GROUP_ID = ');
2409       Add_Bind(p_value => p_attr_group_metadata_obj.ATTR_GROUP_ID);
2410     ELSE
2411       FND_DSQL.Add_Text(' 1 = 1 ');
2412     END IF;
2413 
2414     --------------------------------------------------------------
2415     -- Added in R12C, for implementations uptaking the enhanced --
2416     -- support for data level p_data_level would be passed in.  --
2417     --------------------------------------------------------------
2418       IF(p_data_level IS NOT NULL
2419          AND
2420          FND_API.TO_BOOLEAN(
2421               has_column_in_table_view(p_object_name  => p_attr_group_metadata_obj.ext_table_vl_name
2422                                                            ,p_column_name => 'DATA_LEVEL_ID'
2423                                                            )
2424                            )
2425          ) THEN
2426       -- CONVERTING THE DATA_LEVEL_NAME TO ID --
2427       l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
2428                                            ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
2429                                            ,p_data_level);
2430 
2431       FND_DSQL.Add_Text(' AND DATA_LEVEL_ID = ');
2432       Add_Bind(p_value => l_data_level_id);
2433     END IF;
2434 
2435 Debug_Msg(l_api_name ||' calling EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for pk ');
2436     l_pk_col_string := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
2437                          p_ext_table_metadata_obj.pk_column_metadata
2438                         ,p_pk_column_name_value_pairs
2439                         ,'EQUALS'
2440                         ,TRUE
2441                         ,' AND '
2442                        );
2443 
2444 Debug_Msg(l_api_name ||' calling EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Col_Array ');
2445     l_dl_col_mdata_array:= EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Col_Array(p_attr_group_metadata_obj.APPLICATION_ID,
2446                                                                              p_attr_group_metadata_obj.ATTR_GROUP_TYPE);
2447 
2448 Debug_Msg(l_api_name ||' calling EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for data level ');
2449     l_data_level_string := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
2450                              l_dl_col_mdata_array
2451                             ,p_data_level_name_value_pairs
2452                             ,'EQUALS'
2453                             ,TRUE
2454                             ,' AND '
2455                            );
2456 Debug_Msg(l_api_name ||' after the l_data_level_string :=  ... l_data_level_string='||l_data_level_string);
2457     -------------------------------------------------------------------------
2458     -- Since we will be querying on the extension table's VL, we no longer --
2459     -- need to constrain our queries by language (the VL does that for us) --
2460     -------------------------------------------------------------------------
2461 
2462     Debug_Msg(l_api_name || ' done', 2);
2463 
2464 END Build_Where_Clause;
2465 
2466 ----------------------------------------------------------------------
2467 
2468 PROCEDURE Sort_Attr_Values_Table (
2469         p_attr_group_metadata_obj   IN EGO_ATTR_GROUP_METADATA_OBJ
2470        ,px_attr_name_value_pairs    IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
2471 ) IS
2472 
2473     l_sorted_attr_data_table   LOCAL_USER_ATTR_DATA_TABLE;
2474     l_sorted_data_table_index  NUMBER;
2475     l_attr_data_index          NUMBER;
2476     l_attr_metadata_obj        EGO_ATTR_METADATA_OBJ;
2477 
2478   BEGIN
2479 
2480     Debug_Msg('In Sort_Attr_Values_Table, starting', 2);
2481 
2482     -----------------------------------------------------------------------
2483     -- First, put the Attributes into a temp table according to SEQUENCE --
2484     -----------------------------------------------------------------------
2485     IF (px_attr_name_value_pairs IS NOT NULL AND
2486         px_attr_name_value_pairs.COUNT > 0) THEN
2487       l_attr_data_index := px_attr_name_value_pairs.FIRST;
2488       WHILE (l_attr_data_index <= px_attr_name_value_pairs.LAST)
2489       LOOP
2490 
2491         l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
2492                                  p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table
2493                                 ,p_attr_name           => px_attr_name_value_pairs(l_attr_data_index).ATTR_NAME
2494                                );
2495 
2496         l_sorted_attr_data_table(l_attr_metadata_obj.SEQUENCE) := px_attr_name_value_pairs(l_attr_data_index);
2497 
2498         l_attr_data_index := px_attr_name_value_pairs.NEXT(l_attr_data_index);
2499       END LOOP;
2500 
2501       ------------------------------------------------
2502       -- Next, clear out the name/value pairs table --
2503       -- to make room for the sorted Attributes     --
2504       ------------------------------------------------
2505       px_attr_name_value_pairs.DELETE();
2506 
2507       ---------------------------------------------------------------------------
2508       -- Finally, return the Attributes to the name/value pairs table in order --
2509       ---------------------------------------------------------------------------
2510       l_sorted_data_table_index := l_sorted_attr_data_table.FIRST;
2511       WHILE (l_sorted_data_table_index <= l_sorted_attr_data_table.LAST)
2512       LOOP
2513         px_attr_name_value_pairs.EXTEND();
2514         px_attr_name_value_pairs(px_attr_name_value_pairs.LAST) := l_sorted_attr_data_table(l_sorted_data_table_index);
2515         l_sorted_data_table_index := l_sorted_attr_data_table.NEXT(l_sorted_data_table_index);
2516       END LOOP;
2517     END IF;
2518 
2519     Debug_Msg('In Sort_Attr_Values_Table, done', 2);
2520 
2521 END Sort_Attr_Values_Table;
2522 
2523 ----------------------------------------------------------------------
2524 
2525 -- This function has two basic modes: if p_return_bound_sql is FALSE, then we
2526 -- initialize FND_DSQL to constuct/bind/execute the query and return the result.
2527 -- If TRUE, we build and return the query itself.  In this case, we don't pass
2528 -- p_final_bind_value or p_attr_name_value_pairs, and when replacing Attr Group
2529 -- tokens we construct a nested query to get the value required by the token.
2530 FUNCTION Tokenized_Val_Set_Query (
2531         p_attr_metadata_obj             IN  EGO_ATTR_METADATA_OBJ
2532        ,p_attr_group_metadata_obj       IN  EGO_ATTR_GROUP_METADATA_OBJ
2533        ,p_ext_table_metadata_obj        IN  EGO_EXT_TABLE_METADATA_OBJ
2534        ,p_pk_column_name_value_pairs    IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
2535        ,p_data_level_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
2536        ,p_entity_id                     IN  VARCHAR2
2537        ,p_entity_index                  IN  NUMBER
2538        ,p_entity_code                   IN  VARCHAR2
2539        ,p_add_errors_to_fnd_stack       IN  VARCHAR2   DEFAULT FND_API.G_FALSE
2540        ,p_attr_name_value_pairs         IN  EGO_USER_ATTR_DATA_TABLE
2541        ,p_is_disp_to_int_query          IN  BOOLEAN
2542        ,p_final_bind_value              IN  VARCHAR2
2543        ,p_return_bound_sql              IN  BOOLEAN DEFAULT FALSE
2544 )
2545 RETURN VARCHAR2
2546 IS
2547 
2548     l_head_of_query              VARCHAR2(32767);
2549     l_tail_of_query              VARCHAR2(32767);
2550     l_has_tokens_left            BOOLEAN;
2551     l_token_start_index          NUMBER;
2552     l_token_end_index            NUMBER;
2553     l_token                      VARCHAR2(50);
2554     l_source_of_replacement      VARCHAR2(30);
2555     l_token_replacement          VARCHAR2(4000);	-- Bug 8757354
2556     l_token_data_type            VARCHAR2(1);
2557     l_pk_array_index             NUMBER;
2558     l_replacement_attr_metadata  EGO_ATTR_METADATA_OBJ;
2559     l_replacement_attr_data      EGO_USER_ATTR_DATA_OBJ;
2560     l_retrieved_value            VARCHAR2(4000); --bug 12979914
2561     l_error_message_name         VARCHAR2(30);
2562     l_token_table                ERROR_HANDLER.Token_Tbl_Type;
2563     l_cursor_id                  NUMBER;
2564     l_dynamic_sql                VARCHAR2(32767);
2565     l_number_of_rows             NUMBER;
2566 
2567   BEGIN
2568 
2569     Debug_Msg('In Tokenized_Val_Set_Query, starting', 2);
2570 
2571     --------------------------------------------------------------------------
2572     -- If this function is being called from another package, then we won't --
2573     -- have initialized G_USER_ROW_IDENTIFIER yet; we try to use the row    --
2574     -- identifier from p_attr_name_value_pairs, but if it is NULL or empty  --
2575     -- we use the value 1 instead                                           --
2576     --------------------------------------------------------------------------
2577     IF (G_USER_ROW_IDENTIFIER = 0) THEN
2578       IF (p_attr_name_value_pairs IS NOT NULL AND
2579           p_attr_name_value_pairs.COUNT > 0) THEN
2580         G_USER_ROW_IDENTIFIER := p_attr_name_value_pairs(p_attr_name_value_pairs.FIRST).USER_ROW_IDENTIFIER;
2581       ELSE
2582         G_USER_ROW_IDENTIFIER := 1;
2583       END IF;
2584     END IF;
2585 
2586     IF (p_is_disp_to_int_query) THEN
2587       l_tail_of_query := p_attr_metadata_obj.DISP_TO_INT_VAL_QUERY;
2588     ELSE
2589       l_tail_of_query := p_attr_metadata_obj.INT_TO_DISP_VAL_QUERY;
2590     END IF;
2591 
2592     Debug_Msg('In Tokenized_Val_Set_Query, query starts as follows:');
2593     Debug_Sql(l_tail_of_query);
2594 
2595     --------------------------------------------------------------------------------
2596     -- We only process the query if the Attribute has a Value Set of type "Table" --
2597     -- (because that's the only case in which there may be tokens to replace)     --
2598     --------------------------------------------------------------------------------
2599     IF (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE) THEN
2600 
2601       l_has_tokens_left := (INSTR(UPPER(l_tail_of_query), ':$OBJECT$.') > 0 OR
2602                             INSTR(UPPER(l_tail_of_query), ':$ATTRIBUTEGROUP$.') > 0);
2603 
2604       IF (l_has_tokens_left) THEN
2605         Debug_Msg('In Tokenized_Val_Set_Query, query has tokens to process');
2606 
2607         IF (NOT p_return_bound_sql) THEN
2608           Init();
2609         END IF;
2610 
2611       ELSE
2612         Debug_Msg('In Tokenized_Val_Set_Query, query has no tokens');
2613       END IF;
2614 
2615       WHILE (l_has_tokens_left)
2616       LOOP
2617 
2618         -------------------------------------------------------------------------
2619         -- Get the token (even in the case where it's at the end of the query) --
2620         -------------------------------------------------------------------------
2621         l_token_start_index := INSTR(l_tail_of_query, ':$');
2622         l_token_end_index := INSTR(l_tail_of_query, ' ', l_token_start_index);
2623 /***
2624 Assumption: here we assume a space after the bind variable; perhaps we shouldn't
2625 ***/
2626         IF (l_token_end_index = 0) THEN
2627           l_token_end_index := LENGTH(l_tail_of_query) + 1;
2628         END IF;
2629         l_token := SUBSTR(l_tail_of_query, l_token_start_index, (l_token_end_index - l_token_start_index));
2630 
2631         ----------------------------------------------------------------
2632         -- Ensure we have a legitimate token and not a false positive --
2633         ----------------------------------------------------------------
2634         IF ((INSTR(UPPER(l_token), ':$OBJECT$.') = 1) OR
2635             (INSTR(UPPER(l_token), ':$ATTRIBUTEGROUP$.') = 1)) THEN
2636 
2637           l_source_of_replacement := SUBSTR(l_token, INSTR(l_token, '.') + 1);
2638 
2639           ------------------------------
2640           -- If we have a PK token... --
2641           ------------------------------
2642           IF (INSTR(UPPER(l_token), ':$OBJECT$.') = 1) THEN
2643 
2644             -----------------------------------------------------------
2645             -- ...find the appropriate PK value to replace the token --
2646             -----------------------------------------------------------
2647             l_pk_array_index := p_pk_column_name_value_pairs.FIRST;
2648             WHILE (l_pk_array_index <= p_pk_column_name_value_pairs.LAST)
2649             LOOP
2650               EXIT WHEN (l_token_replacement IS NOT NULL);
2651 
2652               --------------------------------------------------------------
2653               -- Case insensitive comparison for Primary Key column names --
2654               --------------------------------------------------------------
2655               IF (UPPER(l_source_of_replacement) =
2656                   UPPER(p_pk_column_name_value_pairs(l_pk_array_index).NAME)) THEN
2657                 l_token_replacement := p_pk_column_name_value_pairs(l_pk_array_index).VALUE;
2658               END IF;
2659 
2660               l_pk_array_index := p_pk_column_name_value_pairs.NEXT(l_pk_array_index);
2661             END LOOP;
2662 
2663             --------------------------------------------------------------------
2664             -- If we couldn't find a token replacement, the token must be bad --
2665             --------------------------------------------------------------------
2666             IF (l_token_replacement IS NULL) THEN
2667 
2668               l_error_message_name := 'EGO_EF_TOKEN_ERR_PK';
2669 
2670               l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
2671               l_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
2672               l_token_table(2).TOKEN_NAME := 'AG_NAME';
2673               l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
2674               l_token_table(3).TOKEN_NAME := 'BAD_PK_NAME';
2675               l_token_table(3).TOKEN_VALUE := l_source_of_replacement;
2676               l_token_table(4).TOKEN_NAME := 'OBJ_NAME';
2677               l_token_table(4).TOKEN_VALUE := p_ext_table_metadata_obj.OBJ_NAME;
2678 
2679               ERROR_HANDLER.Add_Error_Message(
2680                 p_message_name      => l_error_message_name
2681                ,p_application_id    => 'EGO'
2682                ,p_token_tbl         => l_token_table
2683                ,p_message_type      => FND_API.G_RET_STS_ERROR
2684                ,p_row_identifier    => G_USER_ROW_IDENTIFIER
2685                ,p_entity_id         => p_entity_id
2686                ,p_entity_index      => p_entity_index
2687                ,p_entity_code       => p_entity_code
2688                ,p_addto_fnd_stack   => p_add_errors_to_fnd_stack
2689               );
2690 
2691               RAISE FND_API.G_EXC_ERROR;
2692             END IF;
2693 
2694           ------------------------------------
2695           -- Otherwise, we have an AG token --
2696           ------------------------------------
2697           ELSIF (INSTR(UPPER(l_token), ':$ATTRIBUTEGROUP$.') = 1) THEN
2698 
2699             -----------------------------------------
2700             -- Find the metadata for the Attribute --
2701             -- whose value will replace the token  --
2702             -----------------------------------------
2703             l_replacement_attr_metadata := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
2704                                              p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table
2705                                             ,p_attr_name           => l_source_of_replacement
2706                                            );
2707 
2708             IF (l_replacement_attr_metadata IS NULL OR
2709                 l_replacement_attr_metadata.ATTR_NAME IS NULL) THEN
2710 
2711               ----------------------------------------------------------------------
2712               -- If the Attribute Group token yielded no metadata, it must be bad --
2713               ----------------------------------------------------------------------
2714               l_error_message_name := 'EGO_EF_TOKEN_ERR_AG';
2715 
2716               l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
2717               l_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
2718               l_token_table(2).TOKEN_NAME := 'AG_NAME';
2719               l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
2720               l_token_table(3).TOKEN_NAME := 'BAD_ATTR_NAME';
2721               l_token_table(3).TOKEN_VALUE := l_source_of_replacement;
2722 
2723               ERROR_HANDLER.Add_Error_Message(
2724                 p_message_name      => l_error_message_name
2725                ,p_application_id    => 'EGO'
2726                ,p_token_tbl         => l_token_table
2727                ,p_message_type      => FND_API.G_RET_STS_ERROR
2728                ,p_row_identifier    => G_USER_ROW_IDENTIFIER
2729                ,p_entity_id         => p_entity_id
2730                ,p_entity_index      => p_entity_index
2731                ,p_entity_code       => p_entity_code
2732                ,p_addto_fnd_stack   => p_add_errors_to_fnd_stack
2733               );
2734 
2735               RAISE FND_API.G_EXC_ERROR;
2736 
2737             ELSE
2738 
2739               IF (p_return_bound_sql) THEN
2740 
2741                 ----------------------------------------------------------
2742                 -- If we are constructing and returning the query, then --
2743                 -- we don't have p_attr_name_value_pairs, so we'll have --
2744                 -- to use the replacement's database column name        --
2745                 ----------------------------------------------------------
2746                 l_token_replacement := l_replacement_attr_metadata.DATABASE_COLUMN;
2747 
2748               ELSIF (p_attr_name_value_pairs IS NOT NULL) THEN
2749 
2750                 --------------------------------------------------------------------------------
2751                 -- If we have Attr values, try replacing the token with the appropriate value --
2752                 --------------------------------------------------------------------------------
2753                 l_replacement_attr_data := Find_Name_Value_Pair_For_Attr(p_attr_name_value_pairs
2754                                                                         ,l_replacement_attr_metadata.ATTR_NAME);
2755 
2756                 IF (l_replacement_attr_data IS NOT NULL) THEN
2757 
2758                   IF (l_replacement_attr_metadata.DATA_TYPE_CODE IS NULL OR
2759                       l_replacement_attr_metadata.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
2760                       l_replacement_attr_metadata.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
2761 
2762                     /* FP bug 8499883 with base bug 8215594
2763                     l_token_replacement := l_replacement_attr_data.ATTR_VALUE_STR; */
2764                     l_token_replacement := nvl(l_replacement_attr_data.ATTR_VALUE_STR,l_replacement_attr_data.ATTR_DISP_VALUE);
2765 
2766                   ELSIF (l_replacement_attr_metadata.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
2767 
2768                     l_token_replacement := TO_CHAR(l_replacement_attr_data.ATTR_VALUE_NUM);
2769 
2770                   ELSIF (l_replacement_attr_metadata.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
2771                          l_replacement_attr_metadata.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
2772 
2773                     l_token_replacement := TO_CHAR(l_replacement_attr_data.ATTR_VALUE_DATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
2774 
2775                   END IF;
2776 
2777                   -----------------------------------------------------------------------
2778                   -- If we don't have an internal value for this Attr but we do have a --
2779                   -- display value AND if the Attr does not have a bind value VS query --
2780                   -- (i.e., if we can guarantee it won't need Tokenized_Val_Set_Query) --
2781                   -- then we can try to get its internal value for our query           --
2782                   -- NOTE: we have to be careful here, because we're flirting with a   --
2783                   -- possibly tricky pseudo-recursion                                  --
2784                   -----------------------------------------------------------------------
2785 				  --for bug 10428782, if l_token_replacement is still a display value from a value set, we need get internal value for it.
2786                   IF ((l_token_replacement IS NULL or
2787 				      (l_replacement_attr_metadata.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE OR
2788 				       l_replacement_attr_metadata.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE OR
2789 					   l_replacement_attr_metadata.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE)) AND
2790                       l_replacement_attr_data.ATTR_DISP_VALUE IS NOT NULL AND
2791                       (l_replacement_attr_metadata.VS_BIND_VALUES_CODE IS NULL OR
2792                        l_replacement_attr_metadata.VS_BIND_VALUES_CODE = 'N' OR
2793                        l_replacement_attr_metadata.VS_BIND_VALUES_CODE = 'O')) THEN --bug 13478195
2794 
2795                     Debug_Msg('In Tokenized_Val_Set_Query, trying to get int value for bind value Attr '||l_replacement_attr_data.ATTR_NAME);
2796 
2797 /***
2798 ASSUMPTION:
2799 We assume that all UK Attrs for the query have their int values already
2800 We sort by sequence, which should ensure that bind value Attrs are processed, but
2801 it won't guarantee that UK Attrs are processed...
2802 ***/
2803 
2804                     l_token_replacement := Get_Int_Val_For_Disp_Val(
2805                                              p_attr_metadata_obj             => l_replacement_attr_metadata
2806                                             ,p_attr_value_obj                => l_replacement_attr_data
2807                                             ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
2808                                             ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
2809                                             ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
2810                                             ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
2811                                             ,p_entity_id                     => p_entity_id
2812                                             ,p_entity_index                  => p_entity_index
2813                                             ,p_entity_code                   => p_entity_code
2814                                             ,p_attr_name_value_pairs         => p_attr_name_value_pairs
2815                                            );
2816 
2817                     Debug_Msg('In Tokenized_Val_Set_Query, got int value for bind value Attr '||l_replacement_attr_data.ATTR_NAME||' as '||l_token_replacement);
2818                   END IF;
2819                 END IF;
2820               END IF;
2821             END IF;
2822           END IF;
2823 
2824           -----------------------------------------------------------------------------
2825           -- By this point we have either a replacement value or NULL (which we just --
2826           -- pass and let things break); now we paste what we have into the query    --
2827           -----------------------------------------------------------------------------
2828           IF (p_return_bound_sql) THEN
2829             l_head_of_query := l_head_of_query ||
2830                                SUBSTR(l_tail_of_query, 1, (l_token_start_index - 1)) ||
2831                                l_token_replacement;
2832           ELSE
2833             FND_DSQL.Add_Text(SUBSTR(l_tail_of_query, 1, (l_token_start_index - 1)));
2834             Add_Bind(p_value => l_token_replacement);
2835           END IF;
2836 
2837         ELSE
2838 
2839           ---------------------------------------------------------------------
2840           -- In case of a false positive, we put what we thought was a token --
2841           -- back into the query, and we move forward past the end of it     --
2842           ---------------------------------------------------------------------
2843           IF (p_return_bound_sql) THEN
2844             l_head_of_query := l_head_of_query ||
2845                                SUBSTR(l_tail_of_query, 1, (l_token_end_index - 1));
2846           ELSE
2847             FND_DSQL.Add_Text(SUBSTR(l_tail_of_query, 1, (l_token_end_index - 1)));
2848           END IF;
2849 
2850         END IF;
2851 
2852         ------------------------------------------------------------------------------
2853         -- Clip the part of the query we just processed (even if it wasn't a token) --
2854         ------------------------------------------------------------------------------
2855         l_tail_of_query := SUBSTR(l_tail_of_query, l_token_end_index);
2856 
2857         l_has_tokens_left := (INSTR(UPPER(l_tail_of_query), ':$OBJECT$') > 0 OR
2858                               INSTR(UPPER(l_tail_of_query), ':$ATTRIBUTEGROUP$') > 0);
2859         l_token_replacement := NULL;
2860         l_replacement_attr_metadata := NULL;
2861 
2862       END LOOP;
2863     END IF;
2864 
2865     -------------------------------------------------------------------
2866     -- After processing all tokens (or if we didn't process at all), --
2867     -- we get the remainder of the query, bind the passed-in value,  --
2868     -- execute the query, and return our results                     --
2869     -------------------------------------------------------------------
2870     IF (p_return_bound_sql) THEN
2871       l_dynamic_sql := l_head_of_query || l_tail_of_query;
2872 
2873       Debug_Msg('In Tokenized_Val_Set_Query, l_dynamic_sql to be returned is as follows:', 3);
2874       Debug_SQL(l_dynamic_sql);
2875       Debug_Msg('In Tokenized_Val_Set_Query, done', 2);
2876       RETURN l_dynamic_sql;
2877 
2878     ELSE
2879       FND_DSQL.Add_Text(l_tail_of_query);
2880       Add_Bind(p_value => p_final_bind_value);
2881 
2882       l_dynamic_sql := FND_DSQL.Get_Text(FALSE);
2883 
2884       Debug_Msg('In Tokenized_Val_Set_Query, l_dynamic_sql to be executed is as follows:', 3);
2885       Debug_SQL(FND_DSQL.Get_Text(TRUE));
2886 
2887       l_cursor_id := DBMS_SQL.Open_Cursor;
2888 
2889       DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
2890       FND_DSQL.Set_Cursor(l_cursor_id);
2891       FND_DSQL.Do_Binds();
2892       DBMS_SQL.Define_Column(l_cursor_id, 1, l_retrieved_value, 4000); --bug 12979914
2893 
2894       l_number_of_rows := DBMS_SQL.Execute_And_Fetch(l_cursor_id);
2895 
2896       IF (l_number_of_rows > 0) THEN
2897 
2898         DBMS_SQL.Column_Value(l_cursor_id, 1, l_retrieved_value);
2899 
2900       END IF;
2901 
2902       DBMS_SQL.Close_Cursor(l_cursor_id);
2903       fnd_dsql.init(); --bug 13478195
2904 
2905       Debug_Msg('In Tokenized_Val_Set_Query, l_retrieved_value is as follows: '||
2906                 l_retrieved_value);
2907       Debug_Msg('In Tokenized_Val_Set_Query, done', 2);
2908       RETURN l_retrieved_value;
2909 
2910     END IF;
2911 
2912 END Tokenized_Val_Set_Query;
2913 
2914 ----------------------------------------------------------------------
2915 
2916 FUNCTION Get_Int_Val_For_Disp_Val (
2917         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
2918        ,p_attr_value_obj                IN   EGO_USER_ATTR_DATA_OBJ
2919        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
2920        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
2921        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
2922        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
2923        ,p_entity_id                     IN   VARCHAR2
2924        ,p_entity_index                  IN   NUMBER
2925        ,p_entity_code                   IN   VARCHAR2
2926        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
2927 )
2928 RETURN VARCHAR2
2929 IS
2930 
2931     l_dynamic_sql            VARCHAR2(32767);
2932     l_disp_value             VARCHAR2(4000);	-- Bug 8757354
2933     l_int_value              VARCHAR2(4000);	-- Bug 8757354
2934 
2935   BEGIN
2936 
2937     ----------------------------------------------------------------------
2938     -- For Attributes with either "Independent" or "Table" Value Sets,  --
2939     -- there are Display Values and Internal Values that are different; --
2940     -- we store the Internal Values, but since the caller may only know --
2941     -- the Display Value we have this procedure to convert a given Disp --
2942     -- Value to its corresponding Int Value.  We treat Int Value and    --
2943     -- Disp Value as strings, but either may represent a Number or Date --
2944     ----------------------------------------------------------------------
2945     l_disp_value := p_attr_value_obj.ATTR_DISP_VALUE;
2946 
2947     Debug_Msg('In Get_Int_Val_For_Disp_Val, starting for l_disp_value '||l_disp_value, 2);
2948 
2949     IF (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE  OR
2950         p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE ) THEN
2951 --PERF TUNING 4957648
2952       l_dynamic_sql := 'SELECT DISTINCT FLEX_VALUE '||
2953                          ' FROM FND_FLEX_VALUES_VL '||
2954                         ' WHERE FLEX_VALUE_SET_ID = :1 '||
2955                           ' AND ENABLED_FLAG = ''Y'' '||
2956                           ' AND (NVL(START_DATE_ACTIVE, SYSDATE - 1) < SYSDATE) '||
2957                           ' AND (NVL(END_DATE_ACTIVE, SYSDATE + 1) > SYSDATE) '||
2958                           ' AND FLEX_VALUE_MEANING = :2 ';
2959 
2960       EXECUTE IMMEDIATE l_dynamic_sql
2961          INTO l_int_value
2962         USING p_attr_metadata_obj.VALUE_SET_ID, l_disp_value;
2963 
2964     ELSIF (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE) THEN
2965 
2966       ---------------------------------------------------------------------
2967       -- If the Table Value Set doesn't have an Additional Where Clause  --
2968       -- with bind values, we can go ahead and execute the query without --
2969       -- tokenizing at all                                               --
2970       ---------------------------------------------------------------------
2971       IF (p_attr_metadata_obj.VS_BIND_VALUES_CODE IS NULL OR
2972           p_attr_metadata_obj.VS_BIND_VALUES_CODE = 'N') THEN
2973 
2974         EXECUTE IMMEDIATE p_attr_metadata_obj.DISP_TO_INT_VAL_QUERY||' :1 AND ROWNUM < 2'
2975            INTO l_int_value
2976           USING l_disp_value;
2977 
2978       ELSE
2979 
2980         --------------------------------------------------------------------
2981         -- This is the hard case; it's a Table Value Set whose Additional --
2982         -- Where Clause has bind values, which means we'll have to call   --
2983         -- Tokenized_Val_Set_Query to execute the query on our behalf     --
2984         --------------------------------------------------------------------
2985         l_int_value := Tokenized_Val_Set_Query(
2986                          p_attr_metadata_obj           => p_attr_metadata_obj
2987                         ,p_attr_group_metadata_obj     => p_attr_group_metadata_obj
2988                         ,p_ext_table_metadata_obj      => p_ext_table_metadata_obj
2989                         ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
2990                         ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
2991                         ,p_entity_id                   => p_entity_id
2992                         ,p_entity_index                => p_entity_index
2993                         ,p_entity_code                 => p_entity_code
2994                         ,p_attr_name_value_pairs       => p_attr_name_value_pairs
2995                         ,p_is_disp_to_int_query        => TRUE
2996                         ,p_final_bind_value            => l_disp_value
2997                        );
2998 
2999         Debug_Msg('In Get_Int_Val_For_Disp_Val, Tokenized_Val_Set_Query returned '||l_int_value, 3);
3000 
3001       END IF;
3002     END IF;
3003 
3004     Debug_Msg('In Get_Int_Val_For_Disp_Val, disp val of '||l_disp_value||' got int val as '||l_int_value);
3005     Debug_Msg('In Get_Int_Val_For_Disp_Val, done', 2);
3006 
3007     RETURN l_int_value;
3008 
3009   ------------------------------------------------------------------
3010   -- In cases where the Attribute value is not in the Value Set,  --
3011   -- we may get the ORA-01403 "NO_DATA_FOUND" error, and in cases --
3012   -- where we failed to substitute the bind values, we raise an   --
3013   -- error; so our EXCEPTION block catches those and returns NULL --
3014   ------------------------------------------------------------------
3015   EXCEPTION
3016     WHEN OTHERS THEN
3017       Debug_Msg('In Get_Int_Val_For_Disp_Val, EXCEPTION OTHERS', 1);
3018       RETURN NULL;
3019 
3020 END Get_Int_Val_For_Disp_Val;
3021 
3022 ----------------------------------------------------------------------
3023 
3024 FUNCTION Get_Disp_Val_For_Int_Val (
3025         p_attr_int_value                IN   VARCHAR2   DEFAULT NULL
3026        ,p_attr_value_obj                IN   EGO_USER_ATTR_DATA_OBJ DEFAULT NULL
3027        ,p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
3028        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
3029        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
3030        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
3031        ,p_entity_id                     IN   VARCHAR2   DEFAULT NULL
3032        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
3033        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
3034        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE DEFAULT NULL
3035        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ DEFAULT NULL
3036        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
3037 )
3038 RETURN VARCHAR2
3039 IS
3040 
3041     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
3042     l_val_set_query          VARCHAR2(32767);
3043     l_attr_int_value         VARCHAR2(4000);	-- Bug 8757354
3044     l_attr_disp_value        VARCHAR2(4000);	-- Bug 8757354
3045 
3046   BEGIN
3047 
3048     Debug_Msg('In Get_Disp_Val_For_Int_Val, starting', 2);
3049 
3050     -------------------------------------------------------------------------------
3051     -- We get the Internal Value for the Attribute, either passed in directly or --
3052     -- passed in as a field in a data object; in the latter case, we assume that --
3053     -- the data type is correct because this was checked in Validate_Row already --
3054     -------------------------------------------------------------------------------
3055     IF (p_attr_int_value IS NOT NULL) THEN
3056 
3057       l_attr_int_value := p_attr_int_value;
3058 
3059     ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
3060            p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
3061            p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
3062 
3063       l_attr_int_value := p_attr_value_obj.ATTR_VALUE_STR;
3064 
3065     ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
3066 
3067       l_attr_int_value := TO_CHAR(p_attr_value_obj.ATTR_VALUE_NUM);
3068 
3069     ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
3070            p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
3071 
3072       l_attr_int_value := TO_CHAR(p_attr_value_obj.ATTR_VALUE_DATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
3073 
3074     END IF;
3075 
3076     l_attr_int_value := TRIM(l_attr_int_value);
3077 
3078     -------------------------------------------------------------------
3079     -- Next we handle the simple cases (i.e., all queries without an --
3080     -- Additional Where Clause containing user-defined bind values)  --
3081     -------------------------------------------------------------------
3082     -- fix for bug 4543638 included translatable independent validation code to get disp value
3083     IF (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE OR
3084         p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE
3085         ) THEN
3086 
3087       ---------------------------------------------------------------
3088       -- Even though our Attribute metadata object has this query  --
3089       -- stored, we use this version because our stored version    --
3090       -- has the Value Set ID hard-coded, whereas this version has --
3091       -- it as a bind value (which is more efficient); the stored  --
3092       -- version is only for use in Get_User_Attrs_Data            --
3093       ---------------------------------------------------------------
3094 --PERF TUNING 4957648
3095 
3096       IF(p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN --bug 14268474
3097 
3098         l_val_set_query := 'SELECT DISTINCT FLEX_VALUE_MEANING '||
3099                            ' FROM FND_FLEX_VALUES_VL '||
3100                           ' WHERE FLEX_VALUE_SET_ID = :1 '||
3101                             ' AND ENABLED_FLAG = ''Y'' '||
3102                             ' AND (NVL(START_DATE_ACTIVE, SYSDATE - 1) < SYSDATE) '||
3103                             ' AND (NVL(END_DATE_ACTIVE, SYSDATE + 1) > SYSDATE) '||
3104                             ' AND TO_NUMBER(FLEX_VALUE) = :2 ';
3105 
3106       ELSE
3107         l_val_set_query := 'SELECT DISTINCT FLEX_VALUE_MEANING '||
3108                            ' FROM FND_FLEX_VALUES_VL '||
3109                           ' WHERE FLEX_VALUE_SET_ID = :1 '||
3110                             ' AND ENABLED_FLAG = ''Y'' '||
3111                             ' AND (NVL(START_DATE_ACTIVE, SYSDATE - 1) < SYSDATE) '||
3112                             ' AND (NVL(END_DATE_ACTIVE, SYSDATE + 1) > SYSDATE) '||
3113                             ' AND FLEX_VALUE = :2 ';
3114 
3115       END IF;
3116 
3117       EXECUTE IMMEDIATE l_val_set_query
3118          INTO l_attr_disp_value
3119         USING p_attr_metadata_obj.VALUE_SET_ID, l_attr_int_value;
3120 
3121     ELSIF (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE AND
3122            (p_attr_metadata_obj.VS_BIND_VALUES_CODE IS NULL OR
3123             p_attr_metadata_obj.VS_BIND_VALUES_CODE = 'N')) THEN
3124 
3125       EXECUTE IMMEDIATE p_attr_metadata_obj.INT_TO_DISP_VAL_QUERY||' :1 AND ROWNUM < 2'
3126          INTO l_attr_disp_value
3127         USING l_attr_int_value;
3128 
3129     ELSE
3130 
3131       --------------------------------------------------------------------
3132       -- This is the hard case; it's a Table Value Set whose Additional --
3133       -- Where Clause has bind values, which means we'll have to call   --
3134       -- Tokenized_Val_Set_Query to execute the query on our behalf     --
3135       --------------------------------------------------------------------
3136       IF (p_ext_table_metadata_obj IS NOT NULL) THEN
3137         l_ext_table_metadata_obj := p_ext_table_metadata_obj;
3138       ELSE
3139         l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(Get_Object_Id_From_Name(p_object_name));
3140       END IF;
3141 
3142       l_attr_disp_value := Tokenized_Val_Set_Query(
3143                              p_attr_metadata_obj           => p_attr_metadata_obj
3144                             ,p_attr_group_metadata_obj     => p_attr_group_metadata_obj
3145                             ,p_ext_table_metadata_obj      => l_ext_table_metadata_obj
3146                             ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
3147                             ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
3148                             ,p_entity_id                   => p_entity_id
3149                             ,p_entity_index                => p_entity_index
3150                             ,p_entity_code                 => p_entity_code
3151                             ,p_attr_name_value_pairs       => p_attr_name_value_pairs
3152                             ,p_is_disp_to_int_query        => FALSE
3153                             ,p_final_bind_value            => l_attr_int_value
3154                            );
3155 
3156     END IF;
3157 
3158     Debug_Msg('In Get_Disp_Val_For_Int_Val, done; returning '||l_attr_disp_value, 2);
3159 
3160     RETURN l_attr_disp_value;
3161 
3162   EXCEPTION
3163     WHEN OTHERS THEN
3164       Debug_Msg('In Get_Disp_Val_For_Int_Val, got exception '||SQLERRM, 3);
3165       RETURN NULL;
3166 
3167 END Get_Disp_Val_For_Int_Val;
3168 
3169 ----------------------------------------------------------------------
3170 
3171 FUNCTION Get_Extension_Id_For_Row (
3172         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
3173        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
3174        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
3175        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
3176        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
3177        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
3178        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
3179        ,p_extra_pk_col_name_val_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
3180        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
3181        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT NULL
3182 )
3183 RETURN NUMBER
3184 IS
3185 
3186     l_api_name               VARCHAR2(30)  := 'Get_Extension_Id_For_Row';
3187     l_vl_name                VARCHAR2(30);
3188     l_change_where_clause    VARCHAR2(1000);
3189     l_extra_where_clause     VARCHAR2(5000);
3190     l_cursor_id              NUMBER;
3191     l_dynamic_sql            VARCHAR2(15000);
3192     l_data_level_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
3193     l_number_of_rows         NUMBER;
3194     l_extension_id           NUMBER;
3195     l_index                  NUMBER;
3196 
3197   BEGIN
3198 
3199     Debug_Msg(l_api_name || ' starting with p_data_level='||p_data_level, 2);
3200 
3201     --------------------------------------------------------------------------
3202     -- Determine whether we're in Change mode and set variables accordingly --
3203     --------------------------------------------------------------------------
3204     IF (p_change_obj IS NOT NULL
3205         AND
3206        (p_pending_vl_name IS NOT NULL OR p_pending_b_table_name IS NOT NULL)) THEN
3207 
3208       IF (p_pending_vl_name IS NOT NULL) THEN
3209         l_vl_name := p_pending_vl_name;
3210       ELSE
3211         l_vl_name := p_pending_b_table_name;
3212       END IF;
3213 
3214       IF (p_change_obj.CHANGE_ID IS NOT NULL) THEN
3215         l_change_where_clause := ' CHANGE_ID = '||p_change_obj.CHANGE_ID||' AND ';
3216       ELSE
3217         l_change_where_clause := ' AND CHANGE_ID IS NULL AND ';
3218       END IF;
3219 
3220       IF (p_change_obj.CHANGE_LINE_ID IS NOT NULL) THEN
3221         l_change_where_clause := l_change_where_clause||'CHANGE_LINE_ID = '||p_change_obj.CHANGE_LINE_ID||' AND ';
3222       ELSE
3223         l_change_where_clause := l_change_where_clause||'CHANGE_LINE_ID IS NULL AND ';
3224       END IF;
3225 
3226       --------------------------------------------------------------
3227       -- If querying from the pending table, we ignore Data Level --
3228       --------------------------------------------------------------
3229       l_data_level_name_value_pairs := NULL;
3230 
3231     ELSE
3232 
3233       IF (p_attr_group_metadata_obj.EXT_TABLE_VL_NAME IS NOT NULL) THEN
3234         l_vl_name := p_attr_group_metadata_obj.EXT_TABLE_VL_NAME;
3235       ELSE
3236         l_vl_name := p_attr_group_metadata_obj.EXT_TABLE_B_NAME;
3237       END IF;
3238 
3239       l_change_where_clause := '';
3240 
3241       l_data_level_name_value_pairs := p_data_level_name_value_pairs;
3242 
3243     END IF;
3244 
3245 
3246 
3247     --------------------------------------------------------------------------
3248     -- Include the extra pk's in the query if provided --
3249     --------------------------------------------------------------------------
3250     l_extra_where_clause := ' 1=1 ';
3251 
3252     IF (p_extra_pk_col_name_val_pairs IS NOT NULL AND
3253         (p_pending_vl_name IS NOT NULL OR p_pending_b_table_name IS NOT NULL)) THEN
3254 
3255       IF (p_pending_vl_name IS NOT NULL) THEN
3256         l_vl_name := p_pending_vl_name;
3257       ELSE
3258         l_vl_name := p_pending_b_table_name;
3259       END IF;
3260 
3261       IF (p_extra_pk_col_name_val_pairs IS NOT NULL AND p_extra_pk_col_name_val_pairs.COUNT > 0) THEN
3262         l_index := p_extra_pk_col_name_val_pairs.FIRST;
3263         WHILE (l_index IS NOT NULL)
3264         LOOP
3265           IF (p_extra_pk_col_name_val_pairs(l_index).NAME IS NOT NULL) THEN
3266 
3267                 l_extra_where_clause := l_extra_where_clause || ' AND ';
3268 
3269             IF (p_extra_pk_col_name_val_pairs(l_index).VALUE IS NOT NULL) THEN
3270                 l_extra_where_clause := l_extra_where_clause || p_extra_pk_col_name_val_pairs(l_index).NAME || ' = '
3271                                                              || p_extra_pk_col_name_val_pairs(l_index).VALUE || '  '  ;
3272             ELSE
3273                 l_extra_where_clause := l_extra_where_clause || p_extra_pk_col_name_val_pairs(l_index).NAME || ' IS NULL  ';
3274             END IF;
3275           END IF;
3276           l_index := p_extra_pk_col_name_val_pairs.NEXT(l_index);
3277         END LOOP;
3278       END IF;
3279     END IF;
3280 
3281     -----------------------------------------------
3282     -- We clear FND_DSQL and start our new query --
3283     -----------------------------------------------
3284     Init();
3285     FND_DSQL.Add_Text('SELECT EXTENSION_ID FROM ' || l_vl_name ||
3286                       ' WHERE 1=1 AND ' || l_change_where_clause||l_extra_where_clause||' AND ');
3287 
3288     Debug_Msg(l_api_name ||' calling  Build_Where_Clause', 3);
3289     Build_Where_Clause(p_attr_group_metadata_obj
3290                       ,p_ext_table_metadata_obj
3291                       ,p_pk_column_name_value_pairs
3292                       ,p_data_level
3293                       ,l_data_level_name_value_pairs -- NULL if we're in Change mode
3294                       ,p_attr_name_value_pairs);
3295     Debug_Msg(l_api_name ||' returning  Build_Where_Clause', 3);
3296 
3297     l_dynamic_sql := FND_DSQL.Get_Text(FALSE);
3298 
3299     Debug_Msg(l_api_name ||' l_dynamic_sql is as follows: '||l_dynamic_sql, 3);
3300     Debug_SQL(FND_DSQL.Get_Text(TRUE));
3301     ----------------------------------------
3302     -- Now we open a cursor for our query --
3303     ----------------------------------------
3304     l_cursor_id := DBMS_SQL.Open_Cursor;
3305 
3306     --------------------------------------------------
3307     -- Next we parse the query, bind our variables, --
3308     -- and tell DBMS_SQL what we want it to return  --
3309     --------------------------------------------------
3310     DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
3311     FND_DSQL.Set_Cursor(l_cursor_id);
3312     FND_DSQL.Do_Binds();
3313     DBMS_SQL.Define_Column(l_cursor_id, 1, l_extension_id);
3314     ---------------------------------------------------------------------
3315     -- We execute the query and see how many rows we get; if we get no --
3316     -- rows, we return NULL, and if we get too many rows, we return -1 --
3317     ---------------------------------------------------------------------
3318     l_number_of_rows := DBMS_SQL.Execute_And_Fetch(l_cursor_id);
3319     IF (l_number_of_rows = 1) THEN
3320       DBMS_SQL.Column_Value(l_cursor_id, 1, l_extension_id);
3321     ELSIF (l_number_of_rows > 1) THEN
3322       l_extension_id := -1;
3323     END IF;
3324 
3325     ---------------------------------------------------------
3326     -- Finally, we close the cursor and return our results --
3327     ---------------------------------------------------------
3328     DBMS_SQL.Close_Cursor(l_cursor_id);
3329     Debug_Msg('In Get_Extension_Id_For_Row, done; l_extension_id is '||l_extension_id, 2);
3330 
3331     RETURN l_extension_id;
3332 EXCEPTION
3333   WHEN OTHERS THEN
3334      Debug_Msg(' Get_Extension_Id_For_Row EXCEPTION - '||SQLERRM);
3335 
3336 END Get_Extension_Id_For_Row;
3337 
3338 ----------------------------------------------------------------------
3339 
3340 FUNCTION Fetch_UK_Attr_Names_Table (
3341         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
3342 )
3343 RETURN LOCAL_MEDIUM_VARCHAR_TABLE
3344 IS
3345 
3346     l_uk_attr_names_table    LOCAL_MEDIUM_VARCHAR_TABLE;
3347     l_uk_attr_names_table_index NUMBER := 1;
3348     l_uk_attrs_count         NUMBER;
3349     l_table_index            NUMBER;
3350     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
3351 
3352   BEGIN
3353 
3354     ----------------------------------------------------------------
3355     -- We find out how many UK Attrs there are in the Attr Group, --
3356     -- so we don't waste time looping after we've found them all  --
3357     ----------------------------------------------------------------
3358     l_uk_attrs_count := p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT;
3359 
3360     l_table_index := p_attr_group_metadata_obj.attr_metadata_table.FIRST;
3361     WHILE (l_table_index <= p_attr_group_metadata_obj.attr_metadata_table.LAST)
3362     LOOP
3363       EXIT WHEN (l_uk_attr_names_table.COUNT = l_uk_attrs_count);
3364 
3365       -----------------------------------------------------
3366       -- If we find a UK Attr, add its name to our table --
3367       -----------------------------------------------------
3368       IF (p_attr_group_metadata_obj.attr_metadata_table(l_table_index).UNIQUE_KEY_FLAG = 'Y') THEN
3369 
3370         l_uk_attr_names_table(l_uk_attr_names_table_index) := p_attr_group_metadata_obj.attr_metadata_table(l_table_index).ATTR_DISP_NAME;
3371         l_uk_attr_names_table_index := l_uk_attr_names_table_index + 1;
3372 
3373       END IF;
3374 
3375       l_table_index := p_attr_group_metadata_obj.attr_metadata_table.NEXT(l_table_index);
3376     END LOOP;
3377 
3378     RETURN l_uk_attr_names_table;
3379 
3380 END Fetch_UK_Attr_Names_Table;
3381 
3382 -------------------------------------------------------------------------------
3383 -- Added for Bug 9137842
3384 -- Function Fetch_UK_Attr_Display_Values will populate the
3385 -- p_attr_group_metadata_obj.ATTR_DISP_VALUE with either ATTR_VALUE_STR
3386 -- or ATTR_VALUE_NUM or ATTR_VALUE_DATE based on the call.
3387 -------------------------------------------------------------------------------
3388 
3389   FUNCTION Fetch_UK_Attr_Display_Values(p_attr_group_metadata_obj     IN EGO_ATTR_GROUP_METADATA_OBJ,
3390                                         p_ext_table_metadata_obj      IN EGO_EXT_TABLE_METADATA_OBJ DEFAULT NULL,
3391                                         p_pk_column_name_value_pairs  IN EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL,
3392                                         p_data_level_name_value_pairs IN EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL,
3393                                         p_entity_id                   IN VARCHAR2 DEFAULT NULL,
3394                                         p_entity_index                IN NUMBER DEFAULT NULL,
3395                                         p_entity_code                 IN VARCHAR2 DEFAULT NULL,
3396                                         p_attr_name_value_pairs       IN EGO_USER_ATTR_DATA_TABLE,
3397                                         p_attr_name_value             IN VARCHAR2,
3398                                         l_table_index                 IN NUMBER
3399 )
3400 RETURN varchar2
3401 IS
3402     l_vs_table_name             EGO_VALIDATION_TABLE_INFO_V.application_table_name%type;  -- bug 14619994
3403     l_vs_value_column           EGO_VALIDATION_TABLE_INFO_V.value_column_name%type;  -- bug 14619994
3404     l_vs_id_column              EGO_VALIDATION_TABLE_INFO_V.id_column_name%type; -- bug 14619994
3405     l_dynamic_query             VARCHAR2(2000);
3406     l_disp_value                LOCAL_BIG_VARCHAR_TABLE;
3407     l_attr_value_date           VARCHAR2(50);
3408     l_validation_type           VARCHAR2(10):= 'NULL';
3409     l_vs_where_clause           VARCHAR2(1000);
3410     l_attr_metadata_obj EGO_ATTR_METADATA_OBJ;
3411     l_display_value     VARCHAR2(4000);
3412 BEGIN
3413       SELECT validation_type INTO l_validation_type
3414       FROM FND_FLEX_VALUE_SETS WHERE
3415       flex_value_set_id= p_attr_group_metadata_obj.attr_metadata_table(l_table_index).VALUE_SET_ID ;
3416 
3417       IF l_validation_type='F' THEN --  TABLE Validation type
3418          SELECT
3419                application_table_name,
3420                value_column_name,
3421                id_column_name,
3422                additional_where_clause
3423           INTO
3424                l_vs_table_name,
3425                l_vs_value_column,
3426                l_vs_id_column,
3427                l_vs_where_clause
3428           FROM EGO_VALIDATION_TABLE_INFO_V
3429           WHERE id_column_name IS NOT NULL
3430           AND   flex_value_set_id=p_attr_group_metadata_obj.attr_metadata_table(l_table_index).VALUE_SET_ID;
3431 
3432  ----bug 16073812
3433   ---------------------------------
3434       -- Trim off any leading spaces --
3435       ---------------------------------
3436           l_vs_where_clause := LTRIM(l_vs_where_clause);
3437            ---------------------------------------------
3438       -- Check whether the trimmed string starts --
3439       -- with 'WHERE'; if so, trim the 'WHERE'   --
3440       ---------------------------------------------
3441       IF (INSTR(UPPER(SUBSTR(l_vs_where_clause, 1, 6)), 'WHERE') <> 0) THEN
3442         l_vs_where_clause := SUBSTR(l_vs_where_clause, 6);
3443       END IF;
3444       Remove_OrderBy_Clause(l_vs_where_clause);
3445       -----------------------------------------------------
3446       -- Now, if where clause is non-empty, add an 'AND' --
3447       -- so that we can append our own where criteria    --
3448       -----------------------------------------------------
3449 
3450       IF (LENGTH(l_vs_where_clause) > 0) THEN
3451 
3452         ------------------------------------------------------
3453         -- In case the where clause has new line or tabs    --
3454         -- we need to remove it BugFix:4101091              --
3455         ------------------------------------------------------
3456         SELECT REPLACE(l_vs_where_clause,FND_GLOBAL.LOCAL_CHR(10),FND_GLOBAL.LOCAL_CHR(32)) INTO l_vs_where_clause FROM dual; --replacing new line character
3457         SELECT REPLACE(l_vs_where_clause,FND_GLOBAL.LOCAL_CHR(13),FND_GLOBAL.LOCAL_CHR(32)) INTO l_vs_where_clause FROM dual; --removing carriage return
3458         -------------------------------------------------------------------------
3459         -- well if there is still some special character left we cant help it. --
3460         -------------------------------------------------------------------------
3461 
3462         ------------------------------------------------------
3463         -- In case the where clause starts with an Order By --
3464         -- we need to add a 1=1 before the order by         --
3465         ------------------------------------------------------
3466   IF ( INSTR(LTRIM(UPPER(l_vs_where_clause)),'ORDER ') = 1 ) THEN
3467            IF (INSTR(UPPER(
3468                            SUBSTR(LTRIM(l_vs_where_clause),INSTR(LTRIM(UPPER(l_vs_where_clause)),'ORDER ')+6 )
3469                           ),'BY ') <> 0) THEN
3470             l_vs_where_clause := ' 1=1   ' || l_vs_where_clause ;
3471             END IF;
3472         END IF;
3473 
3474           l_dynamic_query :='SELECT '|| l_vs_value_column ||' FROM '||l_vs_table_name||' WHERE to_char('|| l_vs_id_column || ') = to_char('''||p_attr_name_value||''')'||' AND '||l_vs_where_clause;
3475       ELSE
3476 
3477           l_dynamic_query := 'SELECT ' || l_vs_value_column || ' FROM ' ||
3478                            l_vs_table_name || ' WHERE to_char(' ||
3479                            l_vs_id_column || ') = to_char(''' ||
3480                            p_attr_name_value || ''')';
3481       END IF;
3482 
3483 
3484 
3485 		      IF (INSTR(UPPER(l_dynamic_query), ':$') > 0) THEN
3486 		        l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table,
3487 		                                                                                p_attr_name           => p_attr_name_value_pairs(l_table_index)
3488 		                                                                                                        .ATTR_NAME);
3489 
3490 		        l_display_value := Tokenized_Val_Set_Query(p_attr_metadata_obj           => l_attr_metadata_obj,
3491 		                                                   p_attr_group_metadata_obj     => p_attr_group_metadata_obj,
3492 		                                                   p_ext_table_metadata_obj      => p_ext_table_metadata_obj,
3493 		                                                   p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs,
3494 		                                                   p_data_level_name_value_pairs => p_data_level_name_value_pairs,
3495 		                                                   p_entity_id                   => p_entity_id,
3496 		                                                   p_entity_index                => p_entity_index,
3497 		                                                   p_entity_code                 => p_entity_code,
3498 		                                                   p_attr_name_value_pairs       => p_attr_name_value_pairs,
3499 		                                                   p_is_disp_to_int_query        => FALSE,
3500 		                                                   p_final_bind_value            => p_attr_name_value,
3501 		                                                   p_return_bound_sql            => FALSE);
3502 		        l_disp_value(l_table_index) := l_display_value;
3503 
3504 		      ELSE
3505 		        EXECUTE IMMEDIATE l_dynamic_query
3506 		          INTO l_disp_value(l_table_index);
3507 		        Debug_Msg('in Fetch_UK_Attr_Display_Values, error is here ', 1);
3508 		      END IF;
3509         ELSE -- Translatable Independent Validation Type
3510             IF p_attr_name_value_pairs(l_table_index).ATTR_VALUE_DATE IS NOT NULL THEN
3511 
3512                 l_attr_value_date :=To_char(p_attr_name_value_pairs(l_table_index).ATTR_VALUE_DATE,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
3513 
3514                 SELECT
3515                         display_name INTO l_disp_value(l_table_index)
3516                   FROM ego_value_set_values_v
3517                   WHERE value_set_id=p_attr_group_metadata_obj.attr_metadata_table(l_table_index).VALUE_SET_ID
3518                   AND internal_name= trim(l_attr_value_date);
3519 
3520             ELSE
3521                   SELECT
3522                         display_name INTO l_disp_value(l_table_index)
3523                   FROM ego_value_set_values_v
3524                   WHERE value_set_id=p_attr_group_metadata_obj.attr_metadata_table(l_table_index).VALUE_SET_ID
3525                   AND To_Char(internal_name)= p_attr_name_value;
3526             END IF;
3527          END IF;
3528 
3529           RETURN  l_disp_value(l_table_index) ;
3530 
3531       EXCEPTION
3532            WHEN NO_DATA_FOUND THEN
3533            l_disp_value(l_table_index) := p_attr_name_value ;
3534            RETURN  l_disp_value(l_table_index) ;
3535 
3536 
3537 END Fetch_UK_Attr_Display_Values;
3538 ----------------------------------------------------------------------
3539 
3540  FUNCTION Fetch_UK_Attr_Values_Table(p_attr_group_metadata_obj     IN EGO_ATTR_GROUP_METADATA_OBJ,
3541                                       p_ext_table_metadata_obj      IN EGO_EXT_TABLE_METADATA_OBJ DEFAULT NULL,
3542                                       p_pk_column_name_value_pairs  IN EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL,
3543                                       p_data_level_name_value_pairs IN EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL,
3544                                       p_entity_id                   IN VARCHAR2 DEFAULT NULL,
3545                                       p_entity_index                IN NUMBER DEFAULT NULL,
3546                                       p_entity_code                 IN VARCHAR2 DEFAULT NULL,
3547                                       p_attr_name_value_pairs       IN EGO_USER_ATTR_DATA_TABLE)
3548 RETURN LOCAL_BIG_VARCHAR_TABLE
3549 IS
3550 
3551     l_uk_attr_values_table   LOCAL_BIG_VARCHAR_TABLE;
3552     l_uk_attr_values_table_index NUMBER := 1;
3553     l_uk_attrs_count         NUMBER;
3554     l_table_index            NUMBER;
3555     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
3556 
3557   BEGIN
3558 
3559     ----------------------------------------------------------------
3560     -- We find out how many UK Attrs there are in the Attr Group, --
3561     -- so we don't waste time looping after we've found them all  --
3562     ----------------------------------------------------------------
3563     l_uk_attrs_count := p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT;
3564 
3565     IF (p_attr_name_value_pairs IS NULL OR
3566         p_attr_name_value_pairs.COUNT = 0) THEN
3567 
3568       --------------------------------------------------------
3569       -- If there were no values passed in, we need to show --
3570       -- 'NULL' in our error message for each UK value      --
3571       --------------------------------------------------------
3572       FOR i IN 1 .. l_uk_attrs_count
3573       LOOP
3574         l_uk_attr_values_table(i) := 'NULL';
3575       END LOOP;
3576 
3577     ELSE
3578 
3579       l_table_index := p_attr_name_value_pairs.FIRST;
3580       WHILE (l_table_index <= p_attr_name_value_pairs.LAST)
3581       LOOP
3582         EXIT WHEN (l_uk_attr_values_table.COUNT = l_uk_attrs_count);
3583 
3584         l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
3585                                  p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table
3586                                 ,p_attr_name           => p_attr_name_value_pairs(l_table_index).ATTR_NAME
3587                                );
3588 
3589         -----------------------------------------------------
3590         -- If we find a UK Attr value, add it to our table --
3591         -----------------------------------------------------
3592         IF (l_attr_metadata_obj.UNIQUE_KEY_FLAG = 'Y') THEN
3593 
3594           IF (l_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
3595               l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
3596               l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
3597 
3598             l_uk_attr_values_table(l_uk_attr_values_table_index) := Fetch_UK_Attr_Display_Values(p_attr_group_metadata_obj,
3599                                                                                                  p_ext_table_metadata_obj,
3600                                                                                                  p_pk_column_name_value_pairs,
3601                                                                                                  p_data_level_name_value_pairs,
3602                                                                                                  p_entity_id,
3603                                                                                                  p_entity_index,
3604                                                                                                  p_entity_code,
3605                                                                                                  p_attr_name_value_pairs,
3606                                                                                                  p_attr_name_value_pairs(l_table_index)
3607                                                                                                  .ATTR_VALUE_STR,
3608                                                                                                  l_table_index);
3609           ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
3610 
3611            l_uk_attr_values_table(l_uk_attr_values_table_index) := Fetch_UK_Attr_Display_Values(p_attr_group_metadata_obj,
3612                                                                                                  p_ext_table_metadata_obj,
3613                                                                                                  p_pk_column_name_value_pairs,
3614                                                                                                  p_data_level_name_value_pairs,
3615                                                                                                  p_entity_id,
3616                                                                                                  p_entity_index,
3617                                                                                                  p_entity_code,
3618                                                                                                  p_attr_name_value_pairs,
3619                                                                                                  p_attr_name_value_pairs(l_table_index)
3620                                                                                                  .ATTR_VALUE_NUM,
3621                                                                                                  l_table_index);
3622 
3623           ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
3624                  l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
3625 
3626              l_uk_attr_values_table(l_uk_attr_values_table_index) := Fetch_UK_Attr_Display_Values(p_attr_group_metadata_obj,
3627                                                                                                  p_ext_table_metadata_obj,
3628                                                                                                  p_pk_column_name_value_pairs,
3629                                                                                                  p_data_level_name_value_pairs,
3630                                                                                                  p_entity_id,
3631                                                                                                  p_entity_index,
3632                                                                                                  p_entity_code,
3633                                                                                                  p_attr_name_value_pairs,
3634                                                                                                  p_attr_name_value_pairs(l_table_index)
3635                                                                                                  .ATTR_VALUE_DATE,
3636                                                                                                  l_table_index);
3637 
3638           END IF;
3639 
3640           l_uk_attr_values_table_index := l_uk_attr_values_table_index + 1;
3641         END IF;
3642 
3643         l_table_index := p_attr_name_value_pairs.NEXT(l_table_index);
3644       END LOOP;
3645     END IF;
3646 
3647     RETURN l_uk_attr_values_table;
3648 
3649 END Fetch_UK_Attr_Values_Table;
3650 
3651 ----------------------------------------------------------------------
3652 
3653 FUNCTION Fetch_UK_Attr_Names_List (
3654         p_uk_attr_names_table           IN   LOCAL_MEDIUM_VARCHAR_TABLE
3655 )
3656 RETURN VARCHAR2
3657 IS
3658 
3659     l_uk_attr_names_table_index NUMBER;
3660     l_uk_attr_names_list       VARCHAR2(100) := ''; -- tokens can only be 100 bytes long
3661 
3662   BEGIN
3663 
3664     --------------------------------------------------------------
3665     -- If there are more than 5 Unique Key Attributes, we try   --
3666     -- to make a list of them all; however, since ERROR_HANDLER --
3667     -- tokens can only be 100 bytes, we may well not be able    --
3668     -- to provide a complete list.  In that case, we tokenize   --
3669     -- the message with another message that basically says,    --
3670     -- "(the list is too long to display here)"                 --
3671     --------------------------------------------------------------
3672     l_uk_attr_names_table_index := p_uk_attr_names_table.FIRST;
3673     WHILE (l_uk_attr_names_table_index <= p_uk_attr_names_table.LAST)
3674     LOOP
3675       l_uk_attr_names_list := l_uk_attr_names_list ||
3676                               p_uk_attr_names_table(l_uk_attr_names_table_index) ||
3677                               ', ';
3678       l_uk_attr_names_table_index := p_uk_attr_names_table.NEXT(l_uk_attr_names_table_index);
3679     END LOOP;
3680 
3681     RETURN l_uk_attr_names_list;
3682 
3683   EXCEPTION
3684     WHEN OTHERS THEN
3685       Debug_Msg(' Fetch_UK_Attr_Names_List EXCEPTION OTHERS - '||SQLERRM);
3686       RETURN ERROR_HANDLER.Translate_Message('EGO', 'EGO_UK_TOO_LONG_TO_LIST');
3687 
3688 END Fetch_UK_Attr_Names_List;
3689 
3690 ----------------------------------------------------------------------
3691 
3692 PROCEDURE Get_Err_Info_For_UK_Not_Resp (
3693         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
3694        ,p_is_err_in_production_table    IN   BOOLEAN
3695        ,x_unique_key_err_msg            OUT NOCOPY VARCHAR2
3696        ,x_token_table                   OUT NOCOPY ERROR_HANDLER.Token_Tbl_Type
3697 ) IS
3698 
3699     l_uk_attr_names_table   LOCAL_MEDIUM_VARCHAR_TABLE;
3700 
3701   BEGIN
3702 
3703     l_uk_attr_names_table := Fetch_UK_Attr_Names_Table(p_attr_group_metadata_obj);
3704 
3705     IF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 1) THEN
3706 
3707       x_unique_key_err_msg := 'EGO_EF_UK1_NOT_RESP';
3708 
3709       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3710       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3711       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3712       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3713 
3714     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 2) THEN
3715 
3716       x_unique_key_err_msg := 'EGO_EF_UK2_NOT_RESP';
3717 
3718       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3719       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3720       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3721       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3722       x_token_table(3).TOKEN_NAME := 'UK2_NAME';
3723       x_token_table(3).TOKEN_VALUE := l_uk_attr_names_table(2);
3724 
3725     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 3) THEN
3726 
3727       x_unique_key_err_msg := 'EGO_EF_UK3_NOT_RESP';
3728 
3729       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3730       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3731       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3732       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3733       x_token_table(3).TOKEN_NAME := 'UK2_NAME';
3734       x_token_table(3).TOKEN_VALUE := l_uk_attr_names_table(2);
3735       x_token_table(4).TOKEN_NAME := 'UK3_NAME';
3736       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(3);
3737 
3738     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 4) THEN
3739 
3740       x_unique_key_err_msg := 'EGO_EF_UK4_NOT_RESP';
3741 
3742       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3743       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3744       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3745       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3746       x_token_table(3).TOKEN_NAME := 'UK2_NAME';
3747       x_token_table(3).TOKEN_VALUE := l_uk_attr_names_table(2);
3748       x_token_table(4).TOKEN_NAME := 'UK3_NAME';
3749       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(3);
3750       x_token_table(5).TOKEN_NAME := 'UK4_NAME';
3751       x_token_table(5).TOKEN_VALUE := l_uk_attr_names_table(4);
3752 
3753     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 5) THEN
3754 
3755       x_unique_key_err_msg := 'EGO_EF_UK5_NOT_RESP';
3756 
3757       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3758       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3759       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3760       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3761       x_token_table(3).TOKEN_NAME := 'UK2_NAME';
3762       x_token_table(3).TOKEN_VALUE := l_uk_attr_names_table(2);
3763       x_token_table(4).TOKEN_NAME := 'UK3_NAME';
3764       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(3);
3765       x_token_table(5).TOKEN_NAME := 'UK4_NAME';
3766       x_token_table(5).TOKEN_VALUE := l_uk_attr_names_table(4);
3767       x_token_table(6).TOKEN_NAME := 'UK5_NAME';
3768       x_token_table(6).TOKEN_VALUE := l_uk_attr_names_table(5);
3769 
3770     ELSE
3771 
3772       x_unique_key_err_msg := 'EGO_EF_LONG_UK_NOT_RESP';
3773 
3774       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3775       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3776       x_token_table(2).TOKEN_NAME := 'UK_NAME_LIST';
3777       x_token_table(2).TOKEN_VALUE := Fetch_UK_Attr_Names_List(l_uk_attr_names_table);
3778 
3779     END IF;
3780 
3781 END Get_Err_Info_For_UK_Not_Resp;
3782 
3783 ----------------------------------------------------------------------
3784 
3785   PROCEDURE Get_Err_Info_For_UK_Violation(p_attr_group_metadata_obj     IN EGO_ATTR_GROUP_METADATA_OBJ,
3786                                           p_ext_table_metadata_obj      IN EGO_EXT_TABLE_METADATA_OBJ DEFAULT NULL,
3787                                           p_pk_column_name_value_pairs  IN EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL,
3788                                           p_data_level_name_value_pairs IN EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL,
3789                                           p_entity_id                   IN VARCHAR2 DEFAULT NULL,
3790                                           p_entity_index                IN NUMBER DEFAULT NULL,
3791                                           p_entity_code                 IN VARCHAR2 DEFAULT NULL,
3792                                           p_attr_name_value_pairs       IN EGO_USER_ATTR_DATA_TABLE,
3793                                           p_is_err_in_production_table  IN BOOLEAN,
3794                                           x_unique_key_err_msg          OUT NOCOPY VARCHAR2,
3795                                           x_token_table                 OUT NOCOPY ERROR_HANDLER.Token_Tbl_Type) IS
3796 
3797     l_uk_attr_names_table   LOCAL_MEDIUM_VARCHAR_TABLE;
3798     l_uk_attr_values_table   LOCAL_BIG_VARCHAR_TABLE;
3799 
3800   BEGIN
3801 
3802     l_uk_attr_names_table := Fetch_UK_Attr_Names_Table(p_attr_group_metadata_obj);
3803     l_uk_attr_values_table := Fetch_UK_Attr_Values_Table(p_attr_group_metadata_obj,
3804                                                          p_ext_table_metadata_obj,
3805                                                          p_pk_column_name_value_pairs,
3806                                                          p_data_level_name_value_pairs,
3807                                                          p_entity_id,
3808                                                          p_entity_index,
3809                                                          p_entity_code,
3810                                                          p_attr_name_value_pairs);
3811 
3812     IF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 1) THEN
3813 
3814       x_unique_key_err_msg := 'EGO_EF_UK1_VIOLATION';
3815 
3816       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3817       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3818       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3819       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3820       x_token_table(3).TOKEN_NAME := 'ATTR1_VALUE';
3821       x_token_table(3).TOKEN_VALUE := l_uk_attr_values_table(1);
3822 
3823     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 2) THEN
3824 
3825       x_unique_key_err_msg := 'EGO_EF_UK2_VIOLATION';
3826 
3827       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3828       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3829       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3830       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3831       x_token_table(3).TOKEN_NAME := 'ATTR1_VALUE';
3832       x_token_table(3).TOKEN_VALUE := l_uk_attr_values_table(1);
3833       x_token_table(4).TOKEN_NAME := 'UK2_NAME';
3834       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(2);
3835       x_token_table(5).TOKEN_NAME := 'ATTR2_VALUE';
3836       x_token_table(5).TOKEN_VALUE := l_uk_attr_values_table(2);
3837 
3838     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 3) THEN
3839 
3840       x_unique_key_err_msg := 'EGO_EF_UK3_VIOLATION';
3841 
3842       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3843       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3844       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3845       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3846       x_token_table(3).TOKEN_NAME := 'ATTR1_VALUE';
3847       x_token_table(3).TOKEN_VALUE := l_uk_attr_values_table(1);
3848       x_token_table(4).TOKEN_NAME := 'UK2_NAME';
3849       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(2);
3850       x_token_table(5).TOKEN_NAME := 'ATTR2_VALUE';
3851       x_token_table(5).TOKEN_VALUE := l_uk_attr_values_table(2);
3852       x_token_table(6).TOKEN_NAME := 'UK3_NAME';
3853       x_token_table(6).TOKEN_VALUE := l_uk_attr_names_table(3);
3854       x_token_table(7).TOKEN_NAME := 'ATTR3_VALUE';
3855       x_token_table(7).TOKEN_VALUE := l_uk_attr_values_table(3);
3856 
3857     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 4) THEN
3858 
3859       x_unique_key_err_msg := 'EGO_EF_UK4_VIOLATION';
3860 
3861       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3862       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3863       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3864       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3865       x_token_table(3).TOKEN_NAME := 'ATTR1_VALUE';
3866       x_token_table(3).TOKEN_VALUE := l_uk_attr_values_table(1);
3867       x_token_table(4).TOKEN_NAME := 'UK2_NAME';
3868       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(2);
3869       x_token_table(5).TOKEN_NAME := 'ATTR2_VALUE';
3870       x_token_table(5).TOKEN_VALUE := l_uk_attr_values_table(2);
3871       x_token_table(6).TOKEN_NAME := 'UK3_NAME';
3872       x_token_table(6).TOKEN_VALUE := l_uk_attr_names_table(3);
3873       x_token_table(7).TOKEN_NAME := 'ATTR3_VALUE';
3874       x_token_table(7).TOKEN_VALUE := l_uk_attr_values_table(3);
3875       x_token_table(8).TOKEN_NAME := 'UK4_NAME';
3876       x_token_table(8).TOKEN_VALUE := l_uk_attr_names_table(4);
3877       x_token_table(9).TOKEN_NAME := 'ATTR4_VALUE';
3878       x_token_table(9).TOKEN_VALUE := l_uk_attr_values_table(4);
3879 
3880     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 5) THEN
3881 
3882       x_unique_key_err_msg := 'EGO_EF_UK4_VIOLATION';
3883 
3884       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3885       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3886       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3887       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3888       x_token_table(3).TOKEN_NAME := 'ATTR1_VALUE';
3889       x_token_table(3).TOKEN_VALUE := l_uk_attr_values_table(1);
3890       x_token_table(4).TOKEN_NAME := 'UK2_NAME';
3891       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(2);
3892       x_token_table(5).TOKEN_NAME := 'ATTR2_VALUE';
3893       x_token_table(5).TOKEN_VALUE := l_uk_attr_values_table(2);
3894       x_token_table(6).TOKEN_NAME := 'UK3_NAME';
3895       x_token_table(6).TOKEN_VALUE := l_uk_attr_names_table(3);
3896       x_token_table(7).TOKEN_NAME := 'ATTR3_VALUE';
3897       x_token_table(7).TOKEN_VALUE := l_uk_attr_values_table(3);
3898       x_token_table(8).TOKEN_NAME := 'UK4_NAME';
3899       x_token_table(8).TOKEN_VALUE := l_uk_attr_names_table(4);
3900       x_token_table(9).TOKEN_NAME := 'ATTR4_VALUE';
3901       x_token_table(9).TOKEN_VALUE := l_uk_attr_values_table(4);
3902       x_token_table(10).TOKEN_NAME := 'UK5_NAME';
3903       x_token_table(10).TOKEN_VALUE := l_uk_attr_names_table(5);
3904       x_token_table(11).TOKEN_NAME := 'ATTR5_VALUE';
3905       x_token_table(11).TOKEN_VALUE := l_uk_attr_values_table(5);
3906 
3907     ELSE
3908 
3909       x_unique_key_err_msg := 'EGO_EF_LONG_UK_VIOLATION';
3910 
3911       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3912       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3913       x_token_table(2).TOKEN_NAME := 'UK_NAME_LIST';
3914       x_token_table(2).TOKEN_VALUE := Fetch_UK_Attr_Names_List(l_uk_attr_names_table);
3915 
3916     END IF;
3917 
3918 END Get_Err_Info_For_UK_Violation;
3919 
3920 ----------------------------------------------------------------------
3921 
3922 PROCEDURE Get_Extension_Id_And_Mode (
3923         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
3924        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
3925        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
3926        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
3927        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
3928        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
3929        ,p_extension_id                  IN   NUMBER     DEFAULT NULL
3930        ,p_mode                          IN   VARCHAR2   DEFAULT NULL
3931        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
3932        ,p_extra_pk_col_name_val_pairs IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
3933        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
3934        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT NULL
3935        ,p_entity_id                     IN   VARCHAR2   DEFAULT NULL
3936        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
3937        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
3938        ,x_extension_id                  OUT NOCOPY NUMBER
3939        ,x_mode                          OUT NOCOPY VARCHAR2
3940        ,x_return_status                 OUT NOCOPY VARCHAR2
3941 ) IS
3942 
3943     l_api_name               CONSTANT VARCHAR2(30) := 'Get_Extension_Id_And_Mode';
3944 
3945     l_is_change_case         BOOLEAN;
3946     l_extra_pk_present       BOOLEAN;
3947     l_production_ext_id      NUMBER;
3948     l_pending_ext_id         NUMBER;
3949     l_error_message_name     VARCHAR2(30);
3950     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
3951 
3952   BEGIN
3953 
3954     Debug_Msg('In Get_Extension_Id_And_Mode, starting with p_mode as '||p_mode||' and p_extension_id as '||p_extension_id, 2);
3955 
3956 Debug_Msg('In Get_Extension_Id_And_Mode,  p_data_level='||p_data_level);
3957 
3958     --------------------------------------------------------------
3959     -- In this section we try to find extension IDs for the row --
3960     -- whose data we have in both the production table and, if  --
3961     -- appropriate, in the pending table; this effort serves as --
3962     -- the Unique Key check for multi-row Attribute Groups and  --
3963     -- will also allow us to determine (or validate) the mode.  --
3964     --------------------------------------------------------------
3965     l_is_change_case := (p_change_obj IS NOT NULL);
3966 
3967     l_production_ext_id := Get_Extension_Id_For_Row(
3968                              p_attr_group_metadata_obj     => p_attr_group_metadata_obj
3969                             ,p_ext_table_metadata_obj      => p_ext_table_metadata_obj
3970                             ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
3971                             ,p_data_level                  => p_data_level
3972                             ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
3973                             ,p_attr_name_value_pairs       => p_attr_name_value_pairs
3974                            );
3975 
3976     IF (l_is_change_case) THEN
3977 
3978       l_pending_ext_id := Get_Extension_Id_For_Row(
3979                             p_attr_group_metadata_obj     => p_attr_group_metadata_obj
3980                            ,p_ext_table_metadata_obj      => p_ext_table_metadata_obj
3981                            ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
3982                            ,p_data_level                  => p_data_level
3983                            ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
3984                            ,p_attr_name_value_pairs       => p_attr_name_value_pairs
3985                            ,p_change_obj                  => p_change_obj
3986                            ,p_pending_b_table_name        => p_pending_b_table_name
3987                            ,p_pending_vl_name             => p_pending_vl_name
3988                           );
3989 
3990     END IF;
3991 
3992     l_extra_pk_present := (p_extra_pk_col_name_val_pairs IS NOT NULL);
3993 
3994 
3995     IF (l_extra_pk_present) THEN
3996 
3997       l_pending_ext_id := Get_Extension_Id_For_Row(
3998                             p_attr_group_metadata_obj     => p_attr_group_metadata_obj
3999                            ,p_ext_table_metadata_obj      => p_ext_table_metadata_obj
4000                            ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
4001                            ,p_data_level                  => p_data_level
4002                            ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
4003                            ,p_attr_name_value_pairs       => p_attr_name_value_pairs
4004                            ,p_change_obj                  => p_change_obj
4005                            ,p_extra_pk_col_name_val_pairs => p_extra_pk_col_name_val_pairs
4006                            ,p_pending_b_table_name        => p_pending_b_table_name
4007                            ,p_pending_vl_name             => p_pending_vl_name
4008                           );
4009 
4010       -- Here we are assuming that the extension_id passed is the correct one even though
4011       -- we cannot find it in the pending table. This was a specific requirement raised by
4012       -- CM where they do not save the UK's which are not changed in the pending table and
4013       -- hence they want this check to be overlooked.
4014       -- GNANDA
4015       IF (p_attr_group_metadata_obj.MULTI_ROW_CODE = 'Y' AND
4016           l_pending_ext_id IS NULL AND
4017           p_extension_id IS NOT NULL) THEN
4018           l_pending_ext_id := p_extension_id;
4019       END IF;
4020 
4021 
4022 
4023     END IF;
4024 
4025     Debug_Msg('In Get_Extension_Id_And_Mode, l_production_ext_id is '||l_production_ext_id||' and l_pending_ext_id is '||l_pending_ext_id, 3);
4026 
4027     IF (p_attr_group_metadata_obj.MULTI_ROW_CODE = 'N') THEN
4028       IF (p_extension_id IS NOT NULL) THEN
4029 
4030         x_extension_id := p_extension_id;
4031 
4032       ELSE
4033 
4034         -----------------------------------------------------
4035         -- If we're inserting into the pending table a row --
4036         -- that comes from a production row, we'll want to --
4037         -- preserve the production row's extension ID      --
4038         -----------------------------------------------------
4039         IF (l_is_change_case AND
4040             p_mode = G_CREATE_MODE AND
4041             p_change_obj.ACD_TYPE <> 'ADD') THEN
4042 
4043           x_extension_id := l_production_ext_id;
4044 
4045         END IF;
4046       END IF;
4047     ELSIF (p_attr_group_metadata_obj.MULTI_ROW_CODE = 'Y') THEN
4048       IF (p_extension_id IS NOT NULL) THEN
4049 
4050         IF (p_mode = G_DELETE_MODE OR
4051             (l_is_change_case AND p_change_obj.ACD_TYPE = 'DELETE')) THEN
4052 
4053           ------------------------------------------------------------
4054           -- If user is trying to delete from the UI, we don't want --
4055           -- to worry about Unique Key violations; we just want to  --
4056           -- delete whatever row the user tells us to delete        --
4057           ------------------------------------------------------------
4058           x_extension_id := p_extension_id;
4059 
4060         ELSE
4061 
4062           ----------------------------------------------------------------------------
4063           -- If the extension ID is passed in and the Attribute Group is multi-row, --
4064           -- then we have to ensure that the values we'll be updating won't result  --
4065           -- in a Unique Key violation.  So we check to ensure that a row like the  --
4066           -- passed-in row doesn't exist in the production table (and, if we're in  --
4067           -- change case, we check the pending table as well).  If we get an ext ID --
4068           -- for either table that's not the same as the passed-in ext ID, we raise --
4069           -- an error.  If, on the other hand, whatever ext IDs we find match the   --
4070           -- passed-in ext ID, that just means we found the row that the user wants --
4071           -- to update, so we have no problem.  Likewise, if we don't find any ext  --
4072           -- IDs, that means the user is changing Unique Key values to some new and --
4073           -- still-unique combination, in which case we accept the passed-in ext ID --
4074           ----------------------------------------------------------------------------
4075           IF ((l_production_ext_id IS NOT NULL AND
4076                l_production_ext_id <> p_extension_id) OR
4077               (l_pending_ext_id IS NOT NULL AND
4078                l_pending_ext_id <> p_extension_id)) THEN
4079 
4080             IF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT > 0) THEN
4081 
4082               -----------------------------------------------
4083               -- If we found more than one row, the Unique --
4084               -- Key is not respected in the current data  --
4085               -----------------------------------------------
4086               IF (l_production_ext_id = -1 OR
4087                   l_pending_ext_id = -1) THEN
4088 
4089                 Get_Err_Info_For_UK_Not_Resp(p_attr_group_metadata_obj
4090                                             ,(l_production_ext_id = -1)
4091                                             ,l_error_message_name
4092                                             ,l_token_table);
4093 
4094               -----------------------------------------------------------------
4095               -- If, on the other hand, we found exactly one row, the Unique --
4096               -- Key is respected but the current row would violate it       --
4097               -----------------------------------------------------------------
4098               ELSE
4099 
4100                Get_Err_Info_For_UK_Violation(p_attr_group_metadata_obj,
4101                                               p_ext_table_metadata_obj,
4102                                               p_pk_column_name_value_pairs,
4103                                               p_data_level_name_value_pairs,
4104                                               p_entity_id,
4105                                               p_entity_index,
4106                                               p_entity_code,
4107                                               p_attr_name_value_pairs,
4108                                               (l_production_ext_id IS NOT NULL),
4109                                               l_error_message_name,
4110                                               l_token_table);
4111 
4112               END IF;
4113 
4114             ELSE
4115 
4116               l_error_message_name := 'EGO_EF_NO_UNIQUE_KEY';
4117 
4118               l_token_table(1).TOKEN_NAME := 'AG_NAME';
4119               l_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
4120 
4121             END IF;
4122 
4123           ----------------------------------------------------------
4124           -- As mentioned above, if both are null then we assume  --
4125           -- that we're changing UK values and that the passed-in --
4126           -- ext ID must be the correct ext ID to do so           --
4127           ----------------------------------------------------------
4128           ELSIF (l_production_ext_id IS NULL AND
4129                  l_pending_ext_id IS NULL) THEN
4130 
4131             x_extension_id := p_extension_id;
4132 
4133           END IF;
4134         END IF;
4135       ELSE
4136 
4137         -------------------------------------------------------------------------
4138         -- In this case the extension IDs we fetched will determine whether we --
4139         -- are inserting or updating--and, if the latter, which row we update. --
4140         -------------------------------------------------------------------------
4141         IF (l_production_ext_id IS NOT NULL OR
4142             l_pending_ext_id IS NOT NULL) THEN
4143 
4144           -------------------------------------------------------------------------
4145           -- If we found more than one row in either table (signaled by the -1)  --
4146           -- then we either have no Unique Key or one that's not respected       --
4147           -------------------------------------------------------------------------
4148           IF (l_production_ext_id = -1 OR
4149               l_pending_ext_id = -1) THEN
4150 
4151             IF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT > 0) THEN
4152 
4153               ----------------------------------------------------------
4154               -- If we found more than one row, the Unique Key is not --
4155               -- respected in the current data in at least one table  --
4156               ----------------------------------------------------------
4157               Get_Err_Info_For_UK_Not_Resp(p_attr_group_metadata_obj
4158                                           ,(l_production_ext_id = -1)
4159                                           ,l_error_message_name
4160                                           ,l_token_table);
4161 
4162 
4163             ELSE
4164 
4165               l_error_message_name := 'EGO_EF_NO_UNIQUE_KEY';
4166 
4167               l_token_table(1).TOKEN_NAME := 'AG_NAME';
4168               l_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
4169 
4170             END IF;
4171 
4172           ---------------------------------------------------------
4173           -- If the mode is 'CREATE', then the current row would --
4174           -- violate the UK if any of the following applies:     --
4175           -- * user is inserting into the pending table and      --
4176           --   + there's already a row in the pending table, or  --
4177           --   + the ACD type is also 'CREATE', and there's      --
4178           --     already a row in the production table           --
4179           -- * user is inserting into the production table and   --
4180           --   there's already a row in the production table     --
4181           ---------------------------------------------------------
4182           ELSIF (p_mode = G_CREATE_MODE AND
4183                  ((l_is_change_case AND
4184                    (l_pending_ext_id IS NOT NULL OR
4185                     (p_change_obj.ACD_TYPE = 'ADD' AND
4186                      l_production_ext_id IS NOT NULL))) OR
4187                   ((NOT l_is_change_case AND NOT l_extra_pk_present) AND
4188                    l_production_ext_id IS NOT NULL))) THEN
4189 
4190             IF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT > 0) THEN
4191 
4192               -------------------------------------------------------
4193               -- If we found an ext ID for at least one table, the --
4194               -- Unique Key would be violated by adding this row   --
4195               -------------------------------------------------------
4196  			Get_Err_Info_For_UK_Violation(p_attr_group_metadata_obj,
4197                                               p_ext_table_metadata_obj,
4198                                               p_pk_column_name_value_pairs,
4199                                               p_data_level_name_value_pairs,
4200                                               p_entity_id,
4201                                               p_entity_index,
4202                                               p_entity_code,
4203                                               p_attr_name_value_pairs,
4204                                               (l_production_ext_id IS NOT NULL),
4205                                               l_error_message_name,
4206                                               l_token_table);
4207             ELSE
4208 
4209               l_error_message_name := 'EGO_EF_NO_UK_FOR_CREATE';
4210 
4211               l_token_table(1).TOKEN_NAME := 'AG_NAME';
4212               l_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
4213 
4214             END IF;
4215           END IF;
4216         END IF;
4217       END IF;
4218     END IF;
4219 
4220     ------------------------------------------------------------------------
4221     -- Whatever error message we built in the preceding lines, we now log --
4222     ------------------------------------------------------------------------
4223     IF (l_error_message_name IS NOT NULL) THEN
4224 
4225       ERROR_HANDLER.Add_Error_Message(
4226         p_message_name      => l_error_message_name
4227        ,p_application_id    => 'EGO'
4228        ,p_token_tbl         => l_token_table
4229        ,p_message_type      => FND_API.G_RET_STS_ERROR
4230        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
4231        ,p_entity_id         => p_entity_id
4232        ,p_entity_index      => p_entity_index
4233        ,p_entity_code       => p_entity_code
4234        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
4235       );
4236 
4237       RAISE FND_API.G_EXC_ERROR;
4238     ELSIF (x_extension_id IS NULL) THEN
4239       --------------------------------------------------------------------
4240       -- If there was no error and we don't yet have the ext ID, set it --
4241       -- based on the table on which the user is trying to perform DML  --
4242       --------------------------------------------------------------------
4243       IF (l_is_change_case OR l_extra_pk_present) THEN
4244         x_extension_id := l_pending_ext_id;
4245       ELSE
4246         x_extension_id := l_production_ext_id;
4247       END IF;
4248     END IF;
4249 
4250     --------------------------------------------------------------------------
4251     -- If the caller didn't pass a mode, we behave as if we're in SYNC mode --
4252     --------------------------------------------------------------------------
4253     IF (p_mode IS NOT NULL AND
4254         UPPER(p_mode) <> G_SYNC_MODE) THEN
4255       x_mode := UPPER(p_mode);
4256     ELSE
4257       IF (x_extension_id IS NULL) THEN
4258         x_mode := G_CREATE_MODE;
4259       ELSE
4260         x_mode := G_UPDATE_MODE;
4261       END IF;
4262     END IF;
4263 
4264     ------------------------------------------------------------------
4265     -- If we don't have an extension ID at this point, then either  --
4266     -- we are in CREATE mode or there's an error somewhere.  If, on --
4267     -- the other hand, we *do* have an extension ID and the mode is --
4268     -- CREATE, that's also an error (unless we're in Change mode,   --
4269     -- in which case we sometimes take in an extension ID)          --
4270     ------------------------------------------------------------------
4271     IF (x_extension_id IS NULL AND x_mode <> G_CREATE_MODE) THEN
4272 
4273       l_error_message_name := 'EGO_EF_ROW_NOT_FOUND';
4274 
4275       l_token_table(1).TOKEN_NAME := 'AG_NAME';
4276       l_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
4277 
4278       ERROR_HANDLER.Add_Error_Message(
4279         p_message_name      => l_error_message_name
4280        ,p_application_id    => 'EGO'
4281        ,p_token_tbl         => l_token_table
4282        ,p_message_type      => FND_API.G_RET_STS_ERROR
4283        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
4284        ,p_entity_id         => p_entity_id
4285        ,p_entity_index      => p_entity_index
4286        ,p_entity_code       => p_entity_code
4287        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
4288       );
4289 
4290       RAISE FND_API.G_EXC_ERROR;
4291 
4292     ELSIF (x_extension_id IS NOT NULL AND
4293            x_mode = G_CREATE_MODE AND
4294            (NOT l_is_change_case OR p_change_obj.ACD_TYPE = 'ADD')) THEN
4295 
4296       l_error_message_name := 'EGO_EF_ROW_ALREADY_EXISTS';
4297 
4298       l_token_table(1).TOKEN_NAME := 'AG_NAME';
4299       l_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
4300 
4301       ERROR_HANDLER.Add_Error_Message(
4302         p_message_name      => l_error_message_name
4303        ,p_application_id    => 'EGO'
4304        ,p_token_tbl         => l_token_table
4305        ,p_message_type      => FND_API.G_RET_STS_ERROR
4306        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
4307        ,p_entity_id         => p_entity_id
4308        ,p_entity_index      => p_entity_index
4309        ,p_entity_code       => p_entity_code
4310        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
4311       );
4312 
4313       RAISE FND_API.G_EXC_ERROR;
4314 
4315     END IF;
4316 
4317     ----------------------------------------------------------------------
4318     -- There is one circumstance (coming from Implement_Change_Line) in --
4319     -- which we take in an extension ID but want to operate in CREATE   --
4320     -- mode; to pass our error checks, we use G_IMPLEMENT_CREATE_MODE   --
4321     ----------------------------------------------------------------------
4322     IF (x_mode = G_IMPLEMENT_CREATE_MODE) THEN
4323       x_mode := G_CREATE_MODE;
4324     END IF;
4325 
4326     ----------------------------------------------------------------------
4327     -- If we're bulkloading, we don't accept empty rows in CREATE mode; --
4328     -- from the UI we do, because there are cases (e.g., seeded AGs) in --
4329     -- which other teams' code always assumes that a join to our tables --
4330     -- will succeed (even if there's no data in our tables)             --
4331     ----------------------------------------------------------------------
4332     IF (x_mode = G_CREATE_MODE AND
4333         All_Attr_Values_Are_Null(p_attr_name_value_pairs) AND
4334         G_BULK_PROCESSING_FLAG) THEN
4335 
4336       l_error_message_name := 'EGO_EF_NO_ATTR_VALS_TO_INSERT';
4337 
4338       l_token_table(1).TOKEN_NAME := 'AG_NAME';
4339       l_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
4340 
4341       ERROR_HANDLER.Add_Error_Message(
4342         p_message_name      => l_error_message_name
4343        ,p_application_id    => 'EGO'
4344        ,p_token_tbl         => l_token_table
4345        ,p_message_type      => FND_API.G_RET_STS_ERROR
4346        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
4347        ,p_entity_id         => p_entity_id
4348        ,p_entity_index      => p_entity_index
4349        ,p_entity_code       => p_entity_code
4350        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
4351       );
4352 
4353       RAISE FND_API.G_EXC_ERROR;
4354 
4355     END IF;
4356     Debug_Msg('In Get_Extension_Id_And_Mode, done', 2);
4357 
4358   EXCEPTION
4359     WHEN FND_API.G_EXC_ERROR THEN
4360       Debug_Msg(' Get_Extension_Id_And_Mode EXCEPTION FND_API.G_EXC_ERROR ');
4361       x_return_status := FND_API.G_RET_STS_ERROR;
4362 
4363     WHEN OTHERS THEN
4364 
4365       Debug_Msg(' Get_Extension_Id_And_Mode EXCEPTION OTHERS '||SQLERRM);
4366       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4367 
4368       l_token_table.DELETE();
4369       l_token_table(1).TOKEN_NAME := 'PKG_NAME';
4370       l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
4371       l_token_table(2).TOKEN_NAME := 'API_NAME';
4372       l_token_table(2).TOKEN_VALUE := l_api_name;
4373       l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
4374       l_token_table(3).TOKEN_VALUE := SQLERRM;
4375 
4376       ERROR_HANDLER.Add_Error_Message(
4377         p_message_name      => 'EGO_PLSQL_ERR'
4378        ,p_application_id    => 'EGO'
4379        ,p_token_tbl         => l_token_table
4380        ,p_message_type      => FND_API.G_RET_STS_ERROR
4381        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
4382        ,p_entity_id         => p_entity_id
4383        ,p_entity_index      => p_entity_index
4384        ,p_entity_code       => p_entity_code
4385        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
4386       );
4387 
4388 END Get_Extension_Id_And_Mode;
4389 
4390 ----------------------------------------------------------------------
4391 
4392 FUNCTION Do_All_Attrs_Exist (
4393         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
4394        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
4395        ,p_entity_id                     IN   VARCHAR2
4396        ,p_entity_index                  IN   NUMBER
4397        ,p_entity_code                   IN   VARCHAR2
4398 )
4399 RETURN BOOLEAN
4400 IS
4401 
4402     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
4403     l_attr_count             NUMBER;
4404     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
4405     l_all_exist              BOOLEAN := TRUE;
4406 
4407   BEGIN
4408 
4409     Debug_Msg('In Do_All_Attrs_Exist, starting', 2);
4410 
4411     l_token_table(1).TOKEN_NAME := 'BAD_ATTR_NAME';
4412     -- the token value will be set every time we find a missing Attr
4413     l_token_table(2).TOKEN_NAME := 'AG_NAME';
4414     l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_NAME;
4415 
4416     IF (p_attr_name_value_pairs IS NOT NULL AND
4417         p_attr_name_value_pairs.COUNT > 0) THEN
4418       l_attr_count := p_attr_name_value_pairs.FIRST;
4419       WHILE (l_attr_count <= p_attr_name_value_pairs.LAST)
4420       LOOP
4421 
4422         l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
4423                                  p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table
4424                                 ,p_attr_name           => p_attr_name_value_pairs(l_attr_count).ATTR_NAME
4425                                );
4426         IF (l_attr_metadata_obj IS NULL OR
4427             l_attr_metadata_obj.ATTR_NAME IS NULL) THEN
4428 
4429           --------------------------------------------------------------------
4430           -- If we can't find metadata for this Attribute, report the error --
4431           --------------------------------------------------------------------
4432           l_all_exist := FALSE;
4433 
4434           l_token_table(1).TOKEN_VALUE := p_attr_name_value_pairs(l_attr_count).ATTR_NAME;
4435 
4436           ERROR_HANDLER.Add_Error_Message(
4437             p_message_name      => 'EGO_EF_ATTR_DOES_NOT_EXIST'
4438            ,p_application_id    => 'EGO'
4439            ,p_token_tbl         => l_token_table
4440            ,p_message_type      => FND_API.G_RET_STS_ERROR
4441            ,p_row_identifier    => G_USER_ROW_IDENTIFIER
4442            ,p_entity_id         => p_entity_id
4443            ,p_entity_index      => p_entity_index
4444            ,p_entity_code       => p_entity_code
4445            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
4446           );
4447 
4448         END IF;
4449 
4450         l_attr_count := p_attr_name_value_pairs.NEXT(l_attr_count);
4451       END LOOP;
4452     END IF;
4453 
4454     Debug_Msg('In Do_All_Attrs_Exist, done', 2);
4455 
4456     RETURN l_all_exist;
4457 
4458 END Do_All_Attrs_Exist;
4459 
4460 ----------------------------------------------------------------------
4461 
4462 
4463 FUNCTION Are_These_Col_Names_Right (
4464         p_ext_table_col_metadata        IN   EGO_COL_METADATA_ARRAY
4465        ,p_col_name_value_pairs          IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
4466 )
4467 RETURN BOOLEAN
4468 IS
4469 
4470     l_name_value_pair_index  NUMBER;
4471     l_col_metadata_obj       EGO_COL_METADATA_OBJ;
4472     l_col_name_candidate     VARCHAR2(30);
4473     l_are_names_right        BOOLEAN := TRUE;
4474     l_found_this_col_name    BOOLEAN := FALSE;
4475 
4476   BEGIN
4477 
4478     Debug_Msg('In Are_These_Col_Names_Right, starting');
4479 
4480     --------------------------------------------------------------
4481     -- Loop through the name/value pair array: for every column --
4482     -- name, look in the extension table metadata column list   --
4483     -- to find a match.  If we don't find a match, we return    --
4484     -- FALSE; if we find matches for all the columns in the     --
4485     -- name/value pair list, we return TRUE.  If the name/value --
4486     -- pair array is null or empty, it passes.                  --
4487     --------------------------------------------------------------
4488     IF (p_col_name_value_pairs IS NOT NULL AND
4489         p_col_name_value_pairs.COUNT > 0) THEN
4490 
4491       l_name_value_pair_index := p_col_name_value_pairs.FIRST;
4492       WHILE (l_name_value_pair_index <= p_col_name_value_pairs.LAST)
4493       LOOP
4494         EXIT WHEN (NOT l_are_names_right);
4495 
4496         l_col_name_candidate := p_col_name_value_pairs(l_name_value_pair_index).NAME;
4497         l_found_this_col_name := FALSE;
4498 
4499         -----------------------------------------------------
4500         -- If we can find this candidate or if it's a list --
4501         -- of related classification codes, we pass it     --
4502         -----------------------------------------------------
4503         IF (INSTR(UPPER(l_col_name_candidate), 'RELATED_CLASS_CODE_LIST') <> 0) THEN
4504 
4505           l_found_this_col_name := TRUE;
4506 
4507         ELSE
4508 
4509           l_col_metadata_obj := Find_Metadata_For_Col(p_ext_table_col_metadata
4510                                                      ,l_col_name_candidate);
4511           l_found_this_col_name := (l_col_metadata_obj IS NOT NULL);
4512 
4513         END IF;
4514 
4515         l_are_names_right := l_found_this_col_name;
4516 
4517         IF (NOT l_are_names_right) THEN
4518           Debug_Msg('In Are_These_Col_Names_Right, unidentified column name is: '||l_col_name_candidate);
4519         END IF;
4520 
4521         l_name_value_pair_index := p_col_name_value_pairs.NEXT(l_name_value_pair_index);
4522       END LOOP;
4523     END IF;
4524 
4525     IF (l_are_names_right) THEN
4526       Debug_Msg('In Are_These_Col_Names_Right, returning TRUE');
4527     ELSE
4528       Debug_Msg('In Are_These_Col_Names_Right, returning FALSE');
4529     END IF;
4530 
4531     RETURN l_are_names_right;
4532 
4533 END Are_These_Col_Names_Right;
4534 
4535 ----------------------------------------------------------------------
4536 
4537 FUNCTION Are_Ext_Table_Col_Names_Right (
4538         p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
4539        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
4540        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
4541 )
4542 RETURN BOOLEAN
4543 IS
4544 
4545     l_are_names_right        BOOLEAN := TRUE;
4546 
4547   BEGIN
4548 
4549     Debug_Msg('In Are_Ext_Table_Col_Names_Right, starting', 2);
4550 
4551     l_are_names_right := Are_These_Col_Names_Right(p_ext_table_metadata_obj.pk_column_metadata
4552                                                   ,p_pk_column_name_value_pairs);
4553 
4554     IF (l_are_names_right AND
4555         p_class_code_name_value_pairs IS NOT NULL) THEN
4556       l_are_names_right := Are_These_Col_Names_Right(p_ext_table_metadata_obj.class_code_metadata
4557                                                     ,p_class_code_name_value_pairs);
4558     END IF;
4559 
4560     IF (l_are_names_right) THEN
4561       Debug_Msg('In Are_Ext_Table_Col_Names_Right, done; returning TRUE', 2);
4562     ELSE
4563       Debug_Msg('In Are_Ext_Table_Col_Names_Right, done; returning FALSE', 2);
4564     END IF;
4565 
4566     RETURN l_are_names_right;
4567 
4568   EXCEPTION
4569     WHEN OTHERS THEN
4570       Debug_Msg(' Are_Ext_Table_Col_Names_Right EXCEPTION OTHERS '||SQLERRM);
4571       RETURN FALSE;
4572 
4573 END Are_Ext_Table_Col_Names_Right;
4574 
4575 ----------------------------------------------------------------------
4576 
4577 FUNCTION Is_Data_Level_Correct (
4578         p_object_id                     IN   NUMBER
4579        ,p_attr_group_id                 IN   NUMBER
4580        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
4581        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
4582        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
4583        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
4584        ,p_attr_group_disp_name          IN   VARCHAR2
4585        ,x_err_msg_name                  OUT NOCOPY VARCHAR2
4586        ,x_token_table                   OUT NOCOPY ERROR_HANDLER.Token_Tbl_Type
4587 )
4588 RETURN BOOLEAN IS
4589 
4590     l_api_name                VARCHAR2(50) := 'Is_Data_Level_Correct';
4591     l_cursor_id               NUMBER;
4592     l_dummy                   NUMBER;
4593     l_obj_and_class           VARCHAR2(1100);
4594     l_data_level              EGO_OBJ_AG_ASSOCS_B.DATA_LEVEL%TYPE;
4595     l_data_level_id           NUMBER;
4596     l_is_data_level_correct   BOOLEAN := TRUE;
4597     l_cc_value_list           VARCHAR2(1000);
4598     l_dynamic_sql             VARCHAR2(5500);
4599     l_data_level_index        NUMBER;
4600     l_data_level_progress_point VARCHAR2(10);
4601     l_wrong_data_level        VARCHAR2(80);
4602     l_item_ag_count          INT;
4603     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
4604     l_enabled_data_level_table EGO_DATA_LEVEL_TABLE;
4605     l_data_level_metadata      EGO_DATA_LEVEL_METADATA_OBJ;
4606     l_column_matched           BOOLEAN;
4607     l_data_level_matched       BOOLEAN;
4608     l_dl_pk_col_list           VARCHAR2(200);
4609 
4610     l_data_level_list    VARCHAR2(5000);
4611     l_start_index        NUMBER;
4612     l_end_index          NUMBER;
4613 
4614   BEGIN
4615     --bug 7701752 : if AG is EGO_ITEMMGMT_GROUP and ItemDetailImage,ItemDetailDesc, exclude it, because it is associated by default, added by chris.zhao at 2009-01-19
4616     SELECT COUNT (*)
4617       INTO l_item_ag_count
4618       FROM ego_attr_groups_v
4619      WHERE attr_group_type = 'EGO_ITEMMGMT_GROUP' AND (attr_group_id = 1 OR attr_group_id = 2) AND attr_group_id = p_attr_group_id ;
4620 
4621     IF (l_item_ag_count > 0)
4622     THEN
4623       debug_msg (' For pseudo association, exclude ItemDetailImage,ItemDetailDesc for ITEM AG', 2);
4624       RETURN TRUE;
4625     END IF;
4626 
4627     Debug_Msg(l_api_name || ' starting with p_data_level '||p_data_level, 2);
4628 
4629     -----------------------------------------------------------------
4630     -- If data level has been provided we need to verify it from   --
4631     -- the metadata.                                               --
4632     -----------------------------------------------------------------
4633     IF (p_data_level IS NOT NULL) THEN
4634 
4635       l_data_level_matched := FALSE;
4636       l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata
4637                                           (p_attr_group_id  =>  p_attr_group_id);
4638       l_enabled_data_level_table := l_attr_group_metadata_obj.ENABLED_DATA_LEVELS;
4639 
4640       FOR i IN l_enabled_data_level_table.FIRST .. l_enabled_data_level_table.LAST
4641       LOOP
4642         IF(l_enabled_data_level_table(i).DATA_LEVEL_NAME = p_data_level) THEN
4643           l_data_level_metadata := EGO_USER_ATTRS_COMMON_PVT.get_data_level_metadata(
4644                                        p_data_level_id => l_enabled_data_level_table(i).DATA_LEVEL_ID
4645                                                                                     );
4646           l_data_level_matched := TRUE;
4647           l_column_matched := TRUE;
4648           l_dl_pk_col_list := '';
4649           IF p_data_level_name_value_pairs IS NOT NULL AND p_data_level_name_value_pairs.COUNT > 0 THEN
4650             FOR j IN p_data_level_name_value_pairs.FIRST .. p_data_level_name_value_pairs.LAST
4651             LOOP
4652                --Each col in the provided dl pk col list should be valid
4653                IF(    p_data_level_name_value_pairs(j).NAME <> l_data_level_metadata.PK_COLUMN_NAME1
4654                   AND p_data_level_name_value_pairs(j).NAME <> l_data_level_metadata.PK_COLUMN_NAME2
4655                   AND p_data_level_name_value_pairs(j).NAME <> l_data_level_metadata.PK_COLUMN_NAME3
4656                   AND p_data_level_name_value_pairs(j).NAME <> l_data_level_metadata.PK_COLUMN_NAME4
4657                   AND p_data_level_name_value_pairs(j).NAME <> l_data_level_metadata.PK_COLUMN_NAME5) THEN
4658                  l_column_matched:= FALSE;
4659                END IF;
4660                l_dl_pk_col_list := l_dl_pk_col_list||' '||p_data_level_name_value_pairs(j).NAME;
4661             END LOOP;
4662 
4663             -- All the pk columns should be present in the provided DL columns list.
4664             IF(    (l_data_level_metadata.PK_COLUMN_NAME1 IS NOT NULL AND INSTR(l_dl_pk_col_list,l_data_level_metadata.PK_COLUMN_NAME1) = 0)
4665                AND (l_data_level_metadata.PK_COLUMN_NAME2 IS NOT NULL AND INSTR(l_dl_pk_col_list,l_data_level_metadata.PK_COLUMN_NAME2) = 0)
4666                AND (l_data_level_metadata.PK_COLUMN_NAME3 IS NOT NULL AND INSTR(l_dl_pk_col_list,l_data_level_metadata.PK_COLUMN_NAME3) = 0)
4667                AND (l_data_level_metadata.PK_COLUMN_NAME4 IS NOT NULL AND INSTR(l_dl_pk_col_list,l_data_level_metadata.PK_COLUMN_NAME4) = 0)
4668                AND (l_data_level_metadata.PK_COLUMN_NAME5 IS NOT NULL AND INSTR(l_dl_pk_col_list,l_data_level_metadata.PK_COLUMN_NAME5) = 0)
4669               ) THEN
4670                  l_column_matched:= FALSE;
4671             END IF;
4672           END IF;
4673 
4674           IF(NOT l_column_matched) THEN
4675             RETURN FALSE;
4676           END IF;
4677         END IF;   --l_enabled_data_level_table(i).DATA_LEVEL_NAME = p_data_level
4678       END LOOP;
4679 
4680       IF(l_data_level_matched AND l_column_matched) THEN
4681       --If the passed in data level is fine we check the association of the data level with the classification
4682         Init();
4683         FND_DSQL.Add_Text(' SELECT DATA_LEVEL FROM EGO_OBJ_AG_ASSOCS_B'||
4684                           '  WHERE OBJECT_ID =  ');
4685         Add_Bind(p_value => p_object_id);
4686         FND_DSQL.Add_Text('    AND ATTR_GROUP_ID = ');
4687         Add_Bind(p_value => p_attr_group_id);
4688         FND_DSQL.Add_Text('    AND ROWNUM = 1');
4689         FND_DSQL.Add_Text('    AND CLASSIFICATION_CODE IN (');
4690         l_cc_value_list := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
4691                              p_ext_table_metadata_obj.class_code_metadata
4692                             ,p_class_code_name_value_pairs
4693                             ,'VALUES_ALL_CC'
4694                             ,TRUE
4695                            );
4696         FND_DSQL.Add_Text(')');
4697         l_cursor_id := DBMS_SQL.Open_Cursor;
4698         DBMS_SQL.Parse(l_cursor_id, FND_DSQL.Get_Text(), DBMS_SQL.Native);
4699         FND_DSQL.Set_Cursor(l_cursor_id);
4700         FND_DSQL.Do_Binds();
4701         DBMS_SQL.Define_Column(l_cursor_id, 1, l_data_level, 30);
4702         l_dummy := DBMS_SQL.Execute(l_cursor_id);
4703         l_dummy := DBMS_SQL.Fetch_Rows(l_cursor_id);
4704 
4705         IF (l_dummy = 0) THEN
4706            RAISE NO_DATA_FOUND;
4707         END IF;
4708 
4709         --bug 9170700
4710         DBMS_SQL.Close_Cursor(l_cursor_id);
4711 
4712         l_is_data_level_correct := TRUE;
4713       ELSE
4714         l_is_data_level_correct := FALSE;
4715       END IF;
4716 
4717     ELSE  -- p_data_level IS NULL
4718       --
4719       -- R12 code
4720       --
4721       l_cc_value_list := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
4722                            p_ext_table_metadata_obj.class_code_metadata
4723                           ,p_class_code_name_value_pairs
4724                           ,'VALUES_ALL_CC'
4725                           ,FALSE
4726                          );
4727 
4728       Debug_Msg('In Is_Data_Level_Correct, got l_cc_value_list as '||l_cc_value_list);
4729 
4730       l_obj_and_class := '$'||TO_CHAR(p_object_id)||':'||l_cc_value_list||':';
4731 
4732       Debug_Msg('In Is_Data_Level_Correct, got l_obj_and_class as '||l_obj_and_class);
4733 
4734       IF (G_ASSOCIATION_DATA_LEVEL_CACHE.EXISTS(p_attr_group_id) AND
4735           INSTR(G_ASSOCIATION_DATA_LEVEL_CACHE(p_attr_group_id), l_obj_and_class) > 0) THEN
4736 
4737         Debug_Msg('In Is_Data_Level_Correct, found association '||l_obj_and_class||' in the cache');
4738          l_data_level_list := G_ASSOCIATION_DATA_LEVEL_CACHE(p_attr_group_id);
4739          l_start_index := INSTR(l_data_level_list, l_obj_and_class) + LENGTH(l_obj_and_class);
4740          l_end_index := INSTR(l_data_level_list, '$', l_start_index);
4741          l_data_level := SUBSTR(l_data_level_list, l_start_index, (l_end_index - l_start_index));
4742       ELSE
4743 
4744         Init();
4745         FND_DSQL.Add_Text(' SELECT DECODE(ATTRIBUTE2, 1, ATTRIBUTE3,'||
4746                                                     ' 2, ATTRIBUTE5,'||
4747                                                     ' 3, ATTRIBUTE7,'||
4748                                                        ' ''NONE'')'||
4749                             ' FROM FND_LOOKUP_VALUES'||
4750                            ' WHERE LOOKUP_TYPE = ''EGO_EF_DATA_LEVEL'''||
4751                  ' AND LANGUAGE = USERENV(''LANG'')'||
4752                              ' AND LOOKUP_CODE = (SELECT DATA_LEVEL'||
4753                                                   ' FROM EGO_OBJ_AG_ASSOCS_B'||
4754                                                  ' WHERE OBJECT_ID = ');
4755         Add_Bind(p_value => p_object_id);
4756         FND_DSQL.Add_Text(' AND ATTR_GROUP_ID = ');
4757         Add_Bind(p_value => p_attr_group_id);
4758         FND_DSQL.Add_Text(' AND ROWNUM = 1');
4759 
4760         IF (LENGTH(l_cc_value_list) > 0) THEN
4761           FND_DSQL.Add_Text(' AND CLASSIFICATION_CODE IN (');
4762           l_cc_value_list := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
4763                                p_ext_table_metadata_obj.class_code_metadata
4764                               ,p_class_code_name_value_pairs
4765                               ,'VALUES_ALL_CC'
4766                               ,TRUE
4767                              );
4768           FND_DSQL.Add_Text(')');
4769         END IF;
4770 
4771         FND_DSQL.Add_Text(') ');
4772 
4773         Debug_Msg('Bind params for the preceding SQL: '||p_object_id||' and '||p_attr_group_id, 3);
4774 
4775         l_cursor_id := DBMS_SQL.Open_Cursor;
4776         DBMS_SQL.Parse(l_cursor_id, FND_DSQL.Get_Text(), DBMS_SQL.Native);
4777         FND_DSQL.Set_Cursor(l_cursor_id);
4778         FND_DSQL.Do_Binds();
4779         DBMS_SQL.Define_Column(l_cursor_id, 1, l_data_level, 30);
4780         l_dummy := DBMS_SQL.Execute(l_cursor_id);
4781         l_dummy := DBMS_SQL.Fetch_Rows(l_cursor_id);
4782 
4783         IF (l_dummy = 0) THEN
4784           RAISE NO_DATA_FOUND;
4785         END IF;
4786 
4787         DBMS_SQL.Column_Value(l_cursor_id, 1, l_data_level);
4788         DBMS_SQL.Close_Cursor(l_cursor_id);
4789 
4790         IF (G_ASSOCIATION_DATA_LEVEL_CACHE.EXISTS(p_attr_group_id)) THEN
4791 
4792           G_ASSOCIATION_DATA_LEVEL_CACHE(p_attr_group_id) := l_obj_and_class||
4793                                                              l_data_level||'$ '||
4794                                                              G_ASSOCIATION_DATA_LEVEL_CACHE(p_attr_group_id);
4795           Debug_Msg('In Is_Data_Level_Correct, added association '||l_obj_and_class||' to the cached list');
4796 
4797         ELSE
4798 
4799           G_ASSOCIATION_DATA_LEVEL_CACHE(p_attr_group_id) := l_obj_and_class||
4800                                                              l_data_level||'$ ';
4801 
4802           Debug_Msg('In Is_Data_Level_Correct, started cached list with association '||l_obj_and_class);
4803 
4804         END IF;
4805       END IF;
4806 
4807       Debug_Msg('In Is_Data_Level_Correct, the data level for this association is '||l_data_level);
4808 
4809       ------------------------------------------------------------------------
4810       -- At this point we have the Data Level at which this Attribute Group --
4811       -- is associated to this Object; now we need to make sure that we     --
4812       -- have values for all Data Levels up to and including this one and   --
4813       -- that we don't have values for any Data Levels past this one.       --
4814       ------------------------------------------------------------------------
4815       IF (l_data_level = 'NONE') THEN
4816         l_data_level_progress_point := 'AFTER';
4817       ELSE
4818         l_data_level_progress_point := 'BEFORE';
4819       END IF;
4820 
4821       ------------------------------------------------------------------
4822       -- If user hasn't passed in a data level array or has passed in --
4823       -- an array with a NULL first value, then NONE is the only      --
4824       -- correct value for the data level of this association         --
4825       ------------------------------------------------------------------
4826       IF (p_data_level_name_value_pairs IS NULL OR
4827           p_data_level_name_value_pairs.COUNT = 0 OR
4828           p_data_level_name_value_pairs(p_data_level_name_value_pairs.FIRST).VALUE IS NULL) THEN
4829 
4830         l_is_data_level_correct := (l_data_level = 'NONE');
4831 
4832       ELSE
4833 
4834         l_data_level_index := p_data_level_name_value_pairs.FIRST;
4835 
4836         WHILE (l_data_level_index <= p_data_level_name_value_pairs.LAST)
4837         LOOP
4838           EXIT WHEN (NOT l_is_data_level_correct);
4839 
4840           IF (p_data_level_name_value_pairs(l_data_level_index).NAME = l_data_level) THEN
4841             l_data_level_progress_point := 'AT';
4842             Debug_Msg('In Is_Data_Level_Correct, found the data level for this association at index '||
4843                       l_data_level_index||' in the passed-in DL array');
4844           END IF;
4845 
4846           IF ((l_data_level_progress_point = 'BEFORE' OR
4847                l_data_level_progress_point = 'AT') AND
4848               p_data_level_name_value_pairs(l_data_level_index).VALUE IS NULL) THEN
4849 
4850             --------------------------------------------------------------------
4851             -- If the user didn't pass a value for the current data level and --
4852             -- should have, then he/she must have been trying to process the  --
4853             -- Attr data for the data level above the current one (e.g., Item --
4854             -- instead of Item Revision, Structure instead of Component, or   --
4855             -- Project instead of Task), so we report that this is incorrect  --
4856             -- NOTE: The data level index will never be 1, because we checked --
4857             -- that case just before we entered the loop                      --
4858             --------------------------------------------------------------------
4859             IF (l_data_level_index = 2) THEN
4860               l_wrong_data_level := p_ext_table_metadata_obj.DATA_LEVEL_MEANING_1;
4861             ELSIF (l_data_level_index = 3) THEN
4862               l_wrong_data_level := p_ext_table_metadata_obj.DATA_LEVEL_MEANING_2;
4863             END IF;
4864 
4865             l_is_data_level_correct := FALSE;
4866 
4867           ELSIF (l_data_level_progress_point = 'AFTER' AND
4868                  p_data_level_name_value_pairs(l_data_level_index).VALUE IS NOT NULL) THEN
4869 
4870             ----------------------------------------------------------------------
4871             -- If, on the other hand, the user passed a data level value for    --
4872             -- some data level beyond the correct one (e.g., Item Revision when --
4873             -- trying to process Attr data for an Attr Group associated at the  --
4874             -- Item level), we report this mistake as well                      --
4875             ----------------------------------------------------------------------
4876             IF (l_data_level_index = 1) THEN
4877               l_wrong_data_level := p_ext_table_metadata_obj.DATA_LEVEL_MEANING_2;
4878             ELSIF (l_data_level_index = 2) THEN
4879               l_wrong_data_level := p_ext_table_metadata_obj.DATA_LEVEL_MEANING_3;
4880             END IF;
4881 
4882             l_is_data_level_correct := FALSE;
4883 
4884           END IF;
4885 
4886           ---------------------------------------------------------
4887           -- Once we've processed the correct data level we will --
4888           -- need to process all subsequent data levels as well, --
4889           -- noting that they are AFTER the correct data level   --
4890           ---------------------------------------------------------
4891           IF (l_data_level_progress_point = 'AT') THEN
4892             l_data_level_progress_point := 'AFTER';
4893           END IF;
4894 
4895           ------------------------------------------------------------
4896           -- If we're going to do another loop, increment the index --
4897           ------------------------------------------------------------
4898           IF (l_is_data_level_correct) THEN
4899             l_data_level_index := p_data_level_name_value_pairs.NEXT(l_data_level_index);
4900           END IF;
4901         END LOOP;
4902       END IF;
4903     END IF;
4904 
4905     IF (NOT l_is_data_level_correct) THEN
4906       x_err_msg_name := 'EGO_EF_DATA_LEVEL_INCORRECT';
4907       x_token_table(1).TOKEN_NAME := 'AG_NAME';
4908       x_token_table(1).TOKEN_VALUE := p_attr_group_disp_name;
4909       x_token_table(2).TOKEN_NAME := 'DATA_LEVEL';
4910       x_token_table(2).TOKEN_VALUE := NVL(l_wrong_data_level,p_data_level);
4911       Debug_Msg('In Is_Data_Level_Correct, returning FALSE because l_data_level is '||
4912                 l_data_level ||
4913                 ', l_data_level_progress_point is '||
4914                 l_data_level_progress_point||
4915                 ' and l_wrong_data_level is '||l_wrong_data_level);
4916     END IF;
4917 
4918     Debug_Msg('In Is_Data_Level_Correct, done', 2);
4919     RETURN l_is_data_level_correct;
4920 
4921   EXCEPTION
4922     WHEN NO_DATA_FOUND THEN
4923       Debug_Msg('In Is_Data_Level_Correct, got NO_DATA_FOUND exception so returning FALSE');
4924       IF (l_cursor_id IS NOT NULL) THEN
4925         DBMS_SQL.Close_Cursor(l_cursor_id);
4926       END IF;
4927       --------------------------------------------------------------------
4928       -- In this case, the Attribute Group isn't even associated to the --
4929       -- passed-in Classification Code, so we try to query up the       --
4930       -- Classification Meaning to make a user-friendly error message   --
4931       --------------------------------------------------------------------
4932       x_err_msg_name := 'EGO_EF_AG_NOT_ASSOCIATED';
4933       x_token_table(1).TOKEN_NAME := 'AG_NAME';
4934       x_token_table(1).TOKEN_VALUE := p_attr_group_disp_name;
4935       x_token_table(2).TOKEN_NAME := 'CLASS_MEANING';
4936       BEGIN
4937         SELECT EGO_EXT_FWK_PUB.Get_Class_Meaning(p_object_id, p_class_code_name_value_pairs(1).VALUE)
4938           INTO x_token_table(2).TOKEN_VALUE
4939           FROM DUAL;
4940       EXCEPTION
4941         WHEN OTHERS THEN
4942           x_token_table(2).TOKEN_VALUE := p_class_code_name_value_pairs(1).VALUE;
4943       END;
4944       RETURN FALSE;
4945 
4946 END Is_Data_Level_Correct;
4947 
4948 ----------------------------------------------------------------------
4949 
4950 FUNCTION Disp_Val_Replacement_Is_Bad (
4951         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
4952        ,px_attr_value_obj               IN OUT NOCOPY EGO_USER_ATTR_DATA_OBJ
4953 )
4954 RETURN BOOLEAN
4955 IS
4956 l_conv_rate              NUMBER; -- Bug 16502567
4957   BEGIN
4958 
4959     Debug_Msg('In Disp_Val_Replacement_Is_Bad, starting', 2);
4960 
4961     IF (p_attr_metadata_obj.VALIDATION_CODE IS NULL OR
4962         NOT (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE OR
4963              p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE)) THEN
4964 
4965       IF (px_attr_value_obj.ATTR_DISP_VALUE IS NOT NULL) THEN
4966 
4967         IF ((p_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
4968              p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
4969              p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) AND
4970             px_attr_value_obj.ATTR_VALUE_STR IS NULL) THEN
4971 
4972           Debug_Msg('In Disp_Val_Replacement_Is_Bad, putting '||
4973                     px_attr_value_obj.ATTR_DISP_VALUE||
4974                     ' into ATTR_VALUE_STR column', 3);
4975           px_attr_value_obj.ATTR_VALUE_STR := px_attr_value_obj.ATTR_DISP_VALUE;
4976 
4977         ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE AND
4978                px_attr_value_obj.ATTR_VALUE_NUM IS NULL) THEN
4979 
4980           Debug_Msg('In Disp_Val_Replacement_Is_Bad, putting '||
4981                     px_attr_value_obj.ATTR_DISP_VALUE||
4982                     ' into ATTR_VALUE_NUM column', 3);
4983           -- Bug 16502567 Start
4984           -- Note: ATTR_DISP_VALUE on ATTR_UNIT_OF_MEASURE while ATTR_VALUE_NUM on UNIT_OF_MEASURE_BASE
4985  	  l_conv_rate := 1;
4986  	  IF ( px_attr_value_obj.ATTR_UNIT_OF_MEASURE IS NOT NULL AND p_attr_metadata_obj.UNIT_OF_MEASURE_BASE IS NOT NULL
4987  	       AND  px_attr_value_obj.ATTR_UNIT_OF_MEASURE <> p_attr_metadata_obj.UNIT_OF_MEASURE_BASE ) THEN
4988  	      BEGIN
4989                 SELECT CONVERSION_RATE
4990                 INTO l_conv_rate
4991                 FROM MTL_UOM_CONVERSIONS
4992                 WHERE UOM_CLASS = p_attr_metadata_obj.UNIT_OF_MEASURE_CLASS
4993                 AND UOM_CODE = px_attr_value_obj.ATTR_UNIT_OF_MEASURE
4994                 AND ROWNUM = 1;
4995                 Debug_Msg('In Disp_Val_Replacement_Is_Bad UOM conversion rate is ' || to_char(l_conv_rate));
4996               EXCEPTION
4997                 WHEN OTHERS THEN
4998                 Debug_Msg('In Disp_Val_Replacement_Is_Bad UOM conversion Exception ');
4999                 l_conv_rate := 1;
5000               END;
5001           END IF;
5002           px_attr_value_obj.ATTR_VALUE_NUM := l_conv_rate * TO_NUMBER(px_attr_value_obj.ATTR_DISP_VALUE);
5003           -- Bug 16502567 End
5004 
5005         ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE AND
5006                px_attr_value_obj.ATTR_VALUE_DATE IS NULL) THEN
5007 
5008           Debug_Msg('In Disp_Val_Replacement_Is_Bad, putting '||
5009                     px_attr_value_obj.ATTR_DISP_VALUE||
5010                     ' into ATTR_VALUE_DATE column', 3);
5011           px_attr_value_obj.ATTR_VALUE_DATE := TRUNC(TO_DATE(px_attr_value_obj.ATTR_DISP_VALUE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
5012 
5013         ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE AND
5014                px_attr_value_obj.ATTR_VALUE_DATE IS NULL) THEN
5015 
5016           Debug_Msg('In Disp_Val_Replacement_Is_Bad, putting '||
5017                     px_attr_value_obj.ATTR_DISP_VALUE||
5018                     ' into ATTR_VALUE_DATE column', 3);
5019           px_attr_value_obj.ATTR_VALUE_DATE := TO_DATE(px_attr_value_obj.ATTR_DISP_VALUE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
5020 
5021         END IF;
5022       END IF;
5023     END IF;
5024 
5025     ----------------------------------------------------
5026     -- If we've gotten here, either we didn't replace --
5027     -- or else the replacement was a valid one        --
5028     ----------------------------------------------------
5029     Debug_Msg('In Disp_Val_Replacement_Is_Bad, returning FALSE', 2);
5030     RETURN FALSE;
5031 
5032   EXCEPTION
5033     WHEN OTHERS THEN
5034       Debug_Msg('In Disp_Val_Replacement_Is_Bad, returning TRUE', 2);
5035       ------------------------------------------------------------------------
5036       -- We assume this means we tried to replace and got a data type clash --
5037       ------------------------------------------------------------------------
5038       RETURN TRUE;
5039 
5040 END Disp_Val_Replacement_Is_Bad;
5041 
5042 ----------------------------------------------------------------------
5043 
5044 FUNCTION Is_Required_Flag_Respected (
5045         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
5046        ,p_mode                          IN   VARCHAR2
5047        ,p_attr_value_obj                IN   EGO_USER_ATTR_DATA_OBJ
5048        ,p_attr_group_disp_name          IN   VARCHAR2
5049        ,x_err_msg_name                  OUT NOCOPY VARCHAR2
5050        ,x_token_table                   OUT NOCOPY ERROR_HANDLER.Token_Tbl_Type
5051 )
5052 RETURN BOOLEAN
5053 IS
5054 
5055     l_value                  VARCHAR2(4000);	-- Bug 8757354
5056     l_is_req_flag_resp       BOOLEAN := TRUE;
5057 
5058   BEGIN
5059 
5060     Debug_Msg('In Is_Required_Flag_Respected, starting', 2);
5061 
5062     IF (p_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
5063         p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
5064         p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
5065       l_value := p_attr_value_obj.ATTR_VALUE_STR;
5066     ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
5067       l_value := p_attr_value_obj.ATTR_VALUE_NUM;
5068     ELSE
5069       l_value := p_attr_value_obj.ATTR_VALUE_DATE;
5070     END IF;
5071 
5072     ------------------------------------------------------------------
5073     -- If they didn't pass a value of the correct data type AND the --
5074     -- Attribute has a Value Set of type Independent or Table, then --
5075     -- we give them one last chance by assuming that they passed a  --
5076     -- Display Value (which we will later convert to an Internal    --
5077     -- Value in Is_Value_Set_Respected)                             --
5078     ------------------------------------------------------------------
5079     IF (l_value IS NULL AND
5080         (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE OR
5081          p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE OR
5082          p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE)) THEN
5083       l_value := p_attr_value_obj.ATTR_DISP_VALUE;
5084     END IF;
5085 
5086     --------------------------------------------------------------
5087     -- If the Attribute is required, we're in CREATE mode, no   --
5088     -- value was passed, and no Default Value is defined (or we --
5089     -- aren't using the Default Value), then we raise an error  --
5090     --------------------------------------------------------------
5091     IF (p_attr_metadata_obj.REQUIRED_FLAG = 'Y' AND
5092         (UPPER(p_mode) = G_CREATE_MODE OR UPPER(p_mode) = G_UPDATE_MODE) AND --gnanda:BugFix:4640128
5093         l_value IS NULL AND
5094         (p_attr_metadata_obj.DEFAULT_VALUE IS NULL OR
5095         NOT G_DEFAULT_ON_INSERT_FLAG)) THEN
5096       Debug_Msg('In Is_Required_Flag_Respected, required Attr '||p_attr_value_obj.ATTR_NAME||' has no value in '||p_mode||' mode');
5097 
5098       l_is_req_flag_resp := FALSE;
5099 
5100       x_err_msg_name := 'EGO_EF_NO_VAL_FOR_REQ_ATTR';
5101 
5102       x_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5103       x_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5104       x_token_table(2).TOKEN_NAME := 'AG_NAME';
5105       x_token_table(2).TOKEN_VALUE := p_attr_group_disp_name;
5106 
5107     END IF;
5108 
5109     Debug_Msg('In Is_Required_Flag_Respected, done', 2);
5110 
5111   RETURN l_is_req_flag_resp;
5112 
5113 END Is_Required_Flag_Respected;
5114 
5115 ----------------------------------------------------------------------
5116 
5117 FUNCTION Is_Data_Type_Correct (
5118         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
5119        ,p_attr_value_obj                IN   EGO_USER_ATTR_DATA_OBJ
5120        ,p_attr_group_disp_name          IN   VARCHAR2
5121        ,x_err_msg_name                  OUT NOCOPY VARCHAR2
5122        ,x_token_table                   OUT NOCOPY ERROR_HANDLER.Token_Tbl_Type
5123 )
5124 RETURN BOOLEAN
5125 IS
5126 
5127     l_value                  VARCHAR2(4000); -- Bug 8757354
5128     l_is_data_type_correct   BOOLEAN := TRUE;
5129 
5130   BEGIN
5131 
5132     Debug_Msg('In Is_Data_Type_Correct, starting', 2);
5133 
5134     IF
5135        (
5136          (
5137            p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
5138            p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE
5139          ) AND
5140          (
5141            p_attr_value_obj.ATTR_VALUE_STR IS NULL AND
5142            (
5143              p_attr_value_obj.ATTR_VALUE_NUM IS NOT NULL OR
5144              p_attr_value_obj.ATTR_VALUE_DATE IS NOT NULL
5145            )
5146          )
5147        ) THEN
5148 
5149       l_value := NVL(TO_CHAR(p_attr_value_obj.ATTR_VALUE_NUM),
5150                      TO_CHAR(p_attr_value_obj.ATTR_VALUE_DATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
5151 
5152     ELSIF (
5153             (
5154               p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE
5155             ) AND
5156             (
5157               p_attr_value_obj.ATTR_VALUE_NUM IS NULL AND
5158               (
5159                 p_attr_value_obj.ATTR_VALUE_STR IS NOT NULL OR
5160                 p_attr_value_obj.ATTR_VALUE_DATE IS NOT NULL
5161               )
5162             )
5163           ) THEN
5164 
5165       l_value := NVL(p_attr_value_obj.ATTR_VALUE_STR,
5166                      TO_CHAR(p_attr_value_obj.ATTR_VALUE_DATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
5167 
5168     ELSIF (
5169             (
5170               p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
5171               p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE
5172             ) AND
5173             (
5174               p_attr_value_obj.ATTR_VALUE_DATE IS NULL AND
5175               (
5176                 p_attr_value_obj.ATTR_VALUE_STR IS NOT NULL OR
5177                 p_attr_value_obj.ATTR_VALUE_NUM IS NOT NULL
5178               )
5179             )
5180           ) THEN
5181 
5182       l_value := NVL(p_attr_value_obj.ATTR_VALUE_STR,
5183                      TO_CHAR(p_attr_value_obj.ATTR_VALUE_NUM));
5184 
5185     END IF;
5186 
5187     IF (l_value IS NOT NULL) THEN
5188 
5189       Debug_Msg('In Is_Data_Type_Correct, Attr '||p_attr_value_obj.ATTR_NAME||
5190                 ' has no value of the correct data type, '||p_attr_metadata_obj.DATA_TYPE_MEANING);
5191 
5192       l_is_data_type_correct := FALSE;
5193 
5194       x_err_msg_name := 'EGO_EF_DATA_TYPE_INCORRECT';
5195 
5196       x_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5197       x_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5198       x_token_table(2).TOKEN_NAME := 'AG_NAME';
5199       x_token_table(2).TOKEN_VALUE := p_attr_group_disp_name;
5200       x_token_table(3).TOKEN_NAME := 'DATA_TYPE';
5201       x_token_table(3).TOKEN_VALUE := p_attr_metadata_obj.DATA_TYPE_MEANING;
5202       x_token_table(4).TOKEN_NAME := 'VALUE';
5203       x_token_table(4).TOKEN_VALUE := p_attr_value_obj.ATTR_DISP_VALUE;
5204 
5205     END IF;
5206 
5207     Debug_Msg('In Is_Data_Type_Correct, done', 2);
5208 
5209   RETURN l_is_data_type_correct;
5210 
5211 END Is_Data_Type_Correct;
5212 
5213 ----------------------------------------------------------------------
5214 
5215 FUNCTION Is_Min_Or_Max_Value_Respected (
5216         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
5217        ,p_attr_value_obj                IN   EGO_USER_ATTR_DATA_OBJ
5218        ,p_min_or_max                    IN   VARCHAR2
5219 )
5220 RETURN BOOLEAN
5221 IS
5222 
5223     l_is_range_respected     BOOLEAN := TRUE;
5224     l_value_bound_string     VARCHAR2(150);
5225 
5226   BEGIN
5227 
5228     Debug_Msg('In Is_Min_Or_Max_Value_Respected, starting', 2);
5229 
5230     IF (p_min_or_max = 'MIN') THEN
5231       l_value_bound_string := p_attr_metadata_obj.MINIMUM_VALUE;
5232     ELSIF (p_min_or_max = 'MAX') THEN
5233       l_value_bound_string := p_attr_metadata_obj.MAXIMUM_VALUE;
5234     END IF;
5235 
5236     IF (l_value_bound_string IS NOT NULL) THEN
5237 
5238       Debug_Msg('In Is_Min_Or_Max_Value_Respected, '||p_attr_value_obj.ATTR_NAME||
5239                 ' has a '||p_min_or_max||' value of '||l_value_bound_string);
5240 
5241       -----------------
5242       -- Number case --
5243       -----------------
5244       IF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
5245 
5246         IF ((p_min_or_max = 'MIN' AND
5247              p_attr_value_obj.ATTR_VALUE_NUM < TO_NUMBER(l_value_bound_string)) OR
5248             (p_min_or_max = 'MAX' AND
5249              p_attr_value_obj.ATTR_VALUE_NUM > TO_NUMBER(l_value_bound_string))) THEN
5250           l_is_range_respected := FALSE;
5251         END IF;
5252 
5253       ---------------
5254       -- Date case --
5255       ---------------
5256       ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
5257              p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
5258 
5259         -----------------------------------------------------------------
5260         -- We store Min/Max Values in Timestamp format, which includes --
5261         -- a decimal millisecond component; but since the TO_DATE      --
5262         -- function doesn't allow for milliseconds, we have to trim    --
5263         -- that part of the string in order to compare the value.      --
5264         -- We also allow Min/Max Values to be expressions of the form  --
5265         -- "$SYSDATE$ [+/- {integer}]"; if this value bound string is  --
5266         -- in such a form, we turn it into a string in                 --
5267         -- EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT.                    --
5268         -----------------------------------------------------------------
5269         IF (INSTR(l_value_bound_string, '.', -1) > 0) THEN
5270           l_value_bound_string := SUBSTR(l_value_bound_string, 1, INSTR(l_value_bound_string, '.') - 1);
5271         ELSIF (INSTR(UPPER(l_value_bound_string), 'SYSDATE') > 0) THEN
5272 
5273           l_value_bound_string := Format_Sysdate_Expression(l_value_bound_string);
5274 
5275         END IF;
5276 
5277         IF (
5278              (
5279                (
5280                  p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE AND
5281                  (
5282                    p_min_or_max = 'MIN' AND
5283                    p_attr_value_obj.ATTR_VALUE_DATE < TRUNC(TO_DATE(l_value_bound_string, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT))
5284                  )
5285                )
5286                OR
5287                (
5288                  p_min_or_max = 'MAX' AND
5289                  TRUNC(p_attr_value_obj.ATTR_VALUE_DATE) > TO_DATE(l_value_bound_string, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT)
5290                )
5291              )
5292              OR
5293              (
5294                (
5295                  p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE AND
5296                  (
5297                    p_min_or_max = 'MIN' AND
5298                    p_attr_value_obj.ATTR_VALUE_DATE < TO_DATE(l_value_bound_string, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT)
5299                  )
5300                )
5301                OR
5302                (
5303                  p_min_or_max = 'MAX' AND
5304                  p_attr_value_obj.ATTR_VALUE_DATE > TO_DATE(l_value_bound_string, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT)
5305                )
5306              )
5307            ) THEN
5308 
5309           l_is_range_respected := FALSE;
5310 
5311         END IF;
5312       END IF;
5313     END IF;
5314 
5315     IF (l_is_range_respected) THEN
5316       Debug_Msg('In Is_Min_Or_Max_Value_Respected, returning TRUE');
5317     ELSE
5318       Debug_Msg('In Is_Min_Or_Max_Value_Respected, returning FALSE');
5319     END IF;
5320     Debug_Msg('In Is_Min_Or_Max_Value_Respected, done', 2);
5321 
5322     RETURN l_is_range_respected;
5323 
5324 EXCEPTION
5325   WHEN OTHERS THEN
5326     Debug_Msg('In Is_Min_Or_Max_Value_Respected, EXCEPTION OTHERS '||SQLERRM);
5327     RETURN FALSE;
5328 
5329 END Is_Min_Or_Max_Value_Respected;
5330 
5331 ----------------------------------------------------------------------
5332 
5333 FUNCTION Is_Max_Size_Respected (
5334         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
5335        ,p_attr_value_obj                IN   EGO_USER_ATTR_DATA_OBJ
5336        ,p_attr_group_disp_name          IN   VARCHAR2
5337        ,x_err_msg_name                  OUT NOCOPY VARCHAR2
5338        ,x_token_table                   OUT NOCOPY ERROR_HANDLER.Token_Tbl_Type
5339 )
5340 RETURN BOOLEAN
5341 IS
5342 
5343     l_is_max_size_respected  BOOLEAN := TRUE;
5344     l_value                  VARCHAR2(4000);	-- Bug 8757354
5345 
5346   BEGIN
5347 
5348     Debug_Msg('In Is_Max_Size_Respected, starting', 2);
5349 
5350     ---------------------------------------------------------------
5351     -- NOTE: We don't enforce maximum size with Date Attributes, --
5352     -- because the size depends on the format of the Date, which --
5353     -- we can't know at this point.                              --
5354     -- Also, we use LENGTH rather than LENGTH for these checks  --
5355     -- because we want to know the number of characters rather   --
5356     -- than the number of bytes (for multi-byte support).        --
5357     ---------------------------------------------------------------
5358 
5359     IF (p_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
5360         p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
5361         p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
5362 
5363       IF (p_attr_metadata_obj.MAXIMUM_SIZE > 0 AND
5364           p_attr_metadata_obj.MAXIMUM_SIZE <
5365           LENGTHB(p_attr_value_obj.ATTR_VALUE_STR)) THEN  --for bug 9748517, use byte size to determin size for multi-byte language
5366         l_is_max_size_respected := FALSE;
5367         l_value := p_attr_value_obj.ATTR_VALUE_STR;
5368       END IF;
5369 
5370     ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
5371 
5372       IF (p_attr_metadata_obj.MAXIMUM_SIZE > 0 AND
5373           p_attr_metadata_obj.MAXIMUM_SIZE <
5374           LENGTH(TO_CHAR(p_attr_value_obj.ATTR_VALUE_NUM))) THEN
5375         l_is_max_size_respected := FALSE;
5376         l_value := TO_CHAR(p_attr_value_obj.ATTR_VALUE_NUM);
5377       END IF;
5378 
5379     END IF;
5380 
5381     IF (NOT l_is_max_size_respected) THEN
5382 
5383       x_err_msg_name := 'EGO_EF_MAX_SIZE_VIOLATED';
5384 
5385       x_token_table(1).TOKEN_NAME := 'VALUE';
5386       x_token_table(1).TOKEN_VALUE := l_value;
5387       x_token_table(2).TOKEN_NAME := 'ATTR_NAME';
5388       x_token_table(2).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5389       x_token_table(3).TOKEN_NAME := 'AG_NAME';
5390       x_token_table(3).TOKEN_VALUE := p_attr_group_disp_name;
5391 
5392     END IF;
5393 
5394     Debug_Msg('In Is_Max_Size_Respected, done', 2);
5395 
5396     RETURN l_is_max_size_respected;
5397 
5398 END Is_Max_Size_Respected;
5399 
5400 ----------------------------------------------------------------------
5401 
5402 FUNCTION Is_UOM_Valid (
5403         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
5404        ,px_attr_value_obj               IN OUT NOCOPY EGO_USER_ATTR_DATA_OBJ
5405 )
5406 RETURN BOOLEAN
5407 IS
5408 
5409     l_is_uom_valid           BOOLEAN := TRUE;
5410     l_dummy                  VARCHAR2(1);
5411 
5412   BEGIN
5413 
5414     Debug_Msg('In Is_UOM_Valid, starting', 2);
5415 
5416     ------------------------------------------------------------------------------
5417     -- If there is a UOM, we see whether it's a member of the correct UOM class --
5418     -- (we query against MTL_UNITS_OF_MEASURE_TL because there is no _B table)  --
5419     ------------------------------------------------------------------------------
5420     IF (px_attr_value_obj.ATTR_UNIT_OF_MEASURE IS NOT NULL) THEN
5421 
5422       BEGIN
5423         SELECT 'X'
5424           INTO l_dummy
5425           FROM MTL_UNITS_OF_MEASURE_TL
5426          WHERE UOM_CLASS = p_attr_metadata_obj.UNIT_OF_MEASURE_CLASS
5427            AND UOM_CODE = px_attr_value_obj.ATTR_UNIT_OF_MEASURE
5428            AND ROWNUM = 1;
5429       EXCEPTION
5430         WHEN NO_DATA_FOUND THEN
5431           l_is_uom_valid := FALSE;
5432       END;
5433 
5434     -- BUG 8632453
5435     ELSE IF (px_attr_value_obj.ATTR_UNIT_OF_MEASURE IS NULL AND
5436              p_attr_metadata_obj.UNIT_OF_MEASURE_CLASS IS NOT NULL) THEN
5437           l_is_uom_valid := FALSE;
5438 
5439     END IF;
5440     --END OF BUG 8632453
5441 
5442 
5443     END IF;
5444 
5445     IF (l_is_uom_valid) THEN
5446       Debug_Msg('In Is_UOM_Valid, returning TRUE');
5447     ELSE
5448       Debug_Msg('In Is_UOM_Valid, returning FALSE');
5449     END IF;
5450 
5451     Debug_Msg('In Is_UOM_Valid, done', 2);
5452 
5453   RETURN l_is_uom_valid;
5454 
5455 END Is_UOM_Valid;
5456 
5457 ----------------------------------------------------------------------
5458 
5459 FUNCTION Is_Value_Set_Respected (
5460         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
5461        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
5462        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
5463        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
5464        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
5465        ,p_entity_id                     IN   VARCHAR2
5466        ,p_entity_index                  IN   NUMBER
5467        ,p_entity_code                   IN   VARCHAR2
5468        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
5469        ,px_attr_value_obj               IN OUT NOCOPY EGO_USER_ATTR_DATA_OBJ
5470 )
5471 RETURN BOOLEAN
5472 IS
5473 
5474     l_int_value              VARCHAR2(4000);	-- Bug 8757354
5475     l_disp_value             VARCHAR2(4000);	-- Bug 8757354
5476     l_is_val_set_respected   BOOLEAN := TRUE;
5477     l_err_msg_name           VARCHAR2(30);
5478     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
5479 
5480   BEGIN
5481 
5482     Debug_Msg('In Is_Value_Set_Respected, starting', 2);
5483 
5484     IF (p_attr_metadata_obj.VALUE_SET_ID IS NOT NULL) THEN
5485 
5486       Debug_Msg('In Is_Value_Set_Respected, '||px_attr_value_obj.ATTR_NAME||
5487                 ' has Value Set of validation type '||p_attr_metadata_obj.VALIDATION_CODE);
5488 
5489       IF (p_attr_metadata_obj.VALIDATION_CODE = 'N') THEN
5490 
5491         l_is_val_set_respected := Is_Min_Or_Max_Value_Respected(p_attr_metadata_obj
5492                                                                ,px_attr_value_obj
5493                                                                ,'MIN');
5494 
5495         IF (NOT l_is_val_set_respected) THEN
5496 
5497           IF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
5498 
5499             l_err_msg_name := 'EGO_EF_MIN_VAL_NUM_VIOLATED';
5500 
5501             l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5502             l_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5503             l_token_table(2).TOKEN_NAME := 'AG_NAME';
5504             l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5505             l_token_table(3).TOKEN_NAME := 'MIN_NUM_VALUE';
5506             l_token_table(3).TOKEN_VALUE := p_attr_metadata_obj.MINIMUM_VALUE;
5507 
5508           ELSE
5509 
5510             l_err_msg_name := 'EGO_EF_MIN_VAL_DATE_VIOLATED';
5511 
5512             l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5513             l_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5514             l_token_table(2).TOKEN_NAME := 'AG_NAME';
5515             l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5516             l_token_table(3).TOKEN_NAME := 'MIN_DATE_VALUE';
5517             l_token_table(3).TOKEN_VALUE := p_attr_metadata_obj.MINIMUM_VALUE;
5518 
5519           END IF;
5520 
5521         ELSE
5522 
5523           l_is_val_set_respected := Is_Min_Or_Max_Value_Respected(p_attr_metadata_obj
5524                                                                  ,px_attr_value_obj
5525                                                                  ,'MAX');
5526 
5527           IF (NOT l_is_val_set_respected) THEN
5528 
5529             IF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
5530 
5531               l_err_msg_name := 'EGO_EF_MAX_VAL_NUM_VIOLATED';
5532 
5533               l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5534               l_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5535               l_token_table(2).TOKEN_NAME := 'AG_NAME';
5536               l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5537               l_token_table(3).TOKEN_NAME := 'MAX_NUM_VALUE';
5538               l_token_table(3).TOKEN_VALUE := p_attr_metadata_obj.MAXIMUM_VALUE;
5539 
5540             ELSE
5541 
5542               l_err_msg_name := 'EGO_EF_MAX_VAL_DATE_VIOLATED';
5543 
5544               l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5545               l_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5546               l_token_table(2).TOKEN_NAME := 'AG_NAME';
5547               l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5548               l_token_table(3).TOKEN_NAME := 'MAX_DATE_VALUE';
5549               l_token_table(3).TOKEN_VALUE := p_attr_metadata_obj.MAXIMUM_VALUE;
5550 
5551             END IF;
5552           END IF;
5553         END IF;
5554 
5555       ----------------------------------------------------------------------------
5556       -- If the Attribute has a Value Set whose Values have different Internal  --
5557       -- and Display Values, we need to validate the passed-in value (which has --
5558       -- to be either an Internal Value or a Display Value for the Value Set)   --
5559       ----------------------------------------------------------------------------
5560       ELSIF (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE OR
5561              p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE OR
5562              p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE) THEN
5563 
5564         -------------------------------------------
5565         -- If the user passed the Display Value, --
5566         -- we will try to get the Internal Value --
5567         -------------------------------------------
5568         IF (px_attr_value_obj.ATTR_DISP_VALUE IS NOT NULL AND
5569             px_attr_value_obj.ATTR_VALUE_STR IS NULL AND
5570             px_attr_value_obj.ATTR_VALUE_NUM IS NULL AND
5571             px_attr_value_obj.ATTR_VALUE_DATE IS NULL) THEN
5572 
5573           l_int_value := Get_Int_Val_For_Disp_Val(
5574                            p_attr_metadata_obj             => p_attr_metadata_obj
5575                           ,p_attr_value_obj                => px_attr_value_obj
5576                           ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
5577                           ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
5578                           ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
5579                           ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
5580                           ,p_entity_id                     => p_entity_id
5581                           ,p_entity_index                  => p_entity_index
5582                           ,p_entity_code                   => p_entity_code
5583                           ,p_attr_name_value_pairs         => p_attr_name_value_pairs
5584                          );
5585 
5586           IF (l_int_value IS NOT NULL) THEN
5587             IF (p_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
5588                 p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
5589                 p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
5590 
5591               px_attr_value_obj.ATTR_VALUE_STR := l_int_value;
5592 
5593             ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
5594 
5595               px_attr_value_obj.ATTR_VALUE_NUM := TO_NUMBER(l_int_value);
5596 
5597             ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) THEN
5598 
5599               px_attr_value_obj.ATTR_VALUE_DATE := TRUNC(TO_DATE(l_int_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
5600 
5601             ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
5602 
5603               px_attr_value_obj.ATTR_VALUE_DATE := TO_DATE(l_int_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
5604 
5605             END IF;
5606           ELSE
5607 
5608             l_is_val_set_respected := FALSE;
5609 
5610             l_err_msg_name := 'EGO_EF_INDEPENDENT_VS_VIOLATED';
5611 
5612             l_token_table(1).TOKEN_NAME := 'VALUE';
5613             l_token_table(1).TOKEN_VALUE := px_attr_value_obj.ATTR_DISP_VALUE;
5614             l_token_table(2).TOKEN_NAME := 'ATTR_NAME';
5615             l_token_table(2).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5616             l_token_table(3).TOKEN_NAME := 'AG_NAME';
5617             l_token_table(3).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5618 
5619             Debug_Msg('In Is_Value_Set_Respected, disp value passed was bad; VS is violated');
5620           END IF;
5621 
5622         ---------------------------------------------------------------
5623         -- If, on the other hand, the user passed the Interal Value, --
5624         -- we verify it by trying to get the Display Value           --
5625         ---------------------------------------------------------------
5626         ELSIF (px_attr_value_obj.ATTR_VALUE_STR IS NOT NULL OR
5627                px_attr_value_obj.ATTR_VALUE_NUM IS NOT NULL OR
5628                px_attr_value_obj.ATTR_VALUE_DATE IS NOT NULL) THEN
5629 
5630           l_disp_value := Get_Disp_Val_For_Int_Val(
5631                             p_attr_value_obj                => px_attr_value_obj
5632                            ,p_attr_metadata_obj             => p_attr_metadata_obj
5633                            ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
5634                            ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
5635                            ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
5636                            ,p_entity_id                     => p_entity_id
5637                            ,p_entity_index                  => p_entity_index
5638                            ,p_entity_code                   => p_entity_code
5639                            ,p_attr_name_value_pairs         => p_attr_name_value_pairs
5640                            ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
5641                           );
5642 
5643           IF (l_disp_value IS NULL) THEN
5644 
5645             l_is_val_set_respected := FALSE;
5646 
5647             l_err_msg_name := 'EGO_EF_INDEPENDENT_VS_VIOLATED';
5648 
5649             IF (px_attr_value_obj.ATTR_VALUE_STR IS NOT NULL) THEN
5650               l_int_value := px_attr_value_obj.ATTR_VALUE_STR;
5651             ELSIF (px_attr_value_obj.ATTR_VALUE_NUM IS NOT NULL) THEN
5652               l_int_value := px_attr_value_obj.ATTR_VALUE_NUM;
5653             ELSE
5654               l_int_value := px_attr_value_obj.ATTR_VALUE_DATE;
5655             END IF;
5656 
5657             l_token_table(1).TOKEN_NAME := 'VALUE';
5658             l_token_table(1).TOKEN_VALUE := l_int_value;
5659             l_token_table(2).TOKEN_NAME := 'ATTR_NAME';
5660             l_token_table(2).TOKEN_VALUE :=p_attr_metadata_obj.ATTR_DISP_NAME;
5661             l_token_table(3).TOKEN_NAME := 'AG_NAME';
5662             l_token_table(3).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5663 
5664             Debug_Msg('In Is_Value_Set_Respected, int value passed was bad; VS is violated');
5665           END IF;
5666         END IF;
5667       END IF;
5668     END IF;
5669 
5670     ----------------------------------------------------------
5671     -- If we found an error and didn't log it in one of the --
5672     -- functions we called, then we need to log it now      --
5673     ----------------------------------------------------------
5674     IF (NOT l_is_val_set_respected AND l_err_msg_name IS NOT NULL) THEN
5675 
5676       ERROR_HANDLER.Add_Error_Message(
5677         p_message_name      => l_err_msg_name
5678        ,p_application_id    => 'EGO'
5679        ,p_token_tbl         => l_token_table
5680        ,p_message_type      => FND_API.G_RET_STS_ERROR
5681        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
5682        ,p_entity_id         => p_entity_id
5683        ,p_entity_index      => p_entity_index
5684        ,p_entity_code       => p_entity_code
5685        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
5686       );
5687 
5688     END IF;
5689 
5690     IF (l_is_val_set_respected) THEN
5691       Debug_Msg('In Is_Value_Set_Respected, returning TRUE');
5692     ELSE
5693       Debug_Msg('In Is_Value_Set_Respected, returning FALSE');
5694     END IF;
5695 
5696     Debug_Msg('In Is_Value_Set_Respected, done', 2);
5697 
5698     RETURN l_is_val_set_respected;
5699 
5700   EXCEPTION
5701     WHEN OTHERS THEN
5702       Debug_Msg('In Is_Min_Or_Max_Value_Respected, EXCEPTION OTHERS '||SQLERRM);
5703       RETURN FALSE;
5704 
5705 END Is_Value_Set_Respected;
5706 
5707 ----------------------------------------------------------------------
5708 
5709 FUNCTION Verify_All_Required_Attrs (
5710         p_passed_attr_names_table       IN   LOCAL_VARCHAR_TABLE
5711        ,p_attr_metadata_table           IN   EGO_ATTR_METADATA_TABLE
5712        ,p_entity_id                     IN   VARCHAR2
5713        ,p_entity_index                  IN   NUMBER
5714        ,p_entity_code                   IN   VARCHAR2
5715        ,p_attr_group_disp_name          IN   VARCHAR2
5716        ,px_attr_name_value_pairs        IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
5717 )
5718 RETURN BOOLEAN
5719 IS
5720 
5721     l_has_all_required_attrs BOOLEAN := TRUE;
5722     l_metadata_table_index   NUMBER;
5723     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
5724     l_passed_attrs_table_index NUMBER;
5725     l_already_processed      BOOLEAN;
5726     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
5727 
5728   BEGIN
5729 
5730     l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5731     -- the token value will be supplied in the loop itself
5732     l_token_table(2).TOKEN_NAME := 'AG_NAME';
5733     l_token_table(2).TOKEN_VALUE := p_attr_group_disp_name;
5734 
5735     Debug_Msg('In Verify_All_Required_Attrs, starting', 2);
5736 
5737     -----------------------------------------------------
5738     -- We loop through all Attributes in the Attribute --
5739     -- Group, looking for required Attributes          --
5740     -----------------------------------------------------
5741     l_metadata_table_index := p_attr_metadata_table.FIRST;
5742     WHILE (l_metadata_table_index <= p_attr_metadata_table.LAST)
5743     LOOP
5744 
5745       l_already_processed := FALSE;
5746       l_attr_metadata_obj := p_attr_metadata_table(l_metadata_table_index);
5747       IF (l_attr_metadata_obj.REQUIRED_FLAG = 'Y') THEN
5748 
5749         --------------------------------------------
5750         -- For every required Attribute, we check --
5751         -- whether or not we already processed it --
5752         --------------------------------------------
5753         l_passed_attrs_table_index := p_passed_attr_names_table.FIRST;
5754         WHILE (l_passed_attrs_table_index <= p_passed_attr_names_table.LAST)
5755         LOOP
5756           EXIT WHEN (l_already_processed);
5757 
5758           IF (p_passed_attr_names_table(l_passed_attrs_table_index) = l_attr_metadata_obj.ATTR_NAME) THEN
5759 
5760             l_already_processed := TRUE;
5761 
5762           END IF;
5763 
5764           l_passed_attrs_table_index := p_passed_attr_names_table.NEXT(l_passed_attrs_table_index);
5765         END LOOP;
5766 
5767         -------------------------------------------------------------------------
5768         -- If the required Attribute wasn't passed but has a default value, we --
5769         -- create a data object for it and put it into our name/value pairs    --
5770         -- table (trusting Get_List_For_Attrs to default it as necessary); if  --
5771         -- there is no default value, we add the Attribute's name to the list  --
5772         -- of missing Attributes                                               --
5773         -------------------------------------------------------------------------
5774         IF (NOT l_already_processed) THEN
5775 
5776           IF (l_attr_metadata_obj.DEFAULT_VALUE IS NOT NULL) THEN
5777 
5778             Debug_Msg('In Verify_All_Required_Attrs, non-passed required Attribute '||l_attr_metadata_obj.ATTR_DISP_NAME||' has a default value');
5779 
5780             DECLARE
5781 
5782               l_attr_data_obj           EGO_USER_ATTR_DATA_OBJ;
5783 
5784             BEGIN
5785 
5786               l_attr_data_obj := EGO_USER_ATTR_DATA_OBJ(
5787                                    px_attr_name_value_pairs(px_attr_name_value_pairs.FIRST).ROW_IDENTIFIER
5788                                   ,l_attr_metadata_obj.ATTR_NAME
5789                                   ,null -- ATTR_VALUE_STR
5790                                   ,null -- ATTR_VALUE_NUM
5791                                   ,null -- ATTR_VALUE_DATE
5792                                   ,null -- ATTR_DISP_VALUE
5793                                   ,l_attr_metadata_obj.UNIT_OF_MEASURE_BASE
5794                                   ,-1   -- USER_ROW_IDENTIFIER
5795                                  );
5796 
5797               px_attr_name_value_pairs.EXTEND();
5798 --
5799 -- ASSUMPTION: this table does not need to be re-sorted by sequence, because we've
5800 -- passed the only place where sequence matters (i.e., Tokenized_Val_Set_Query)
5801 --
5802               px_attr_name_value_pairs(px_attr_name_value_pairs.LAST) := l_attr_data_obj;
5803             END;
5804           ELSE
5805 
5806             Debug_Msg('In Verify_All_Required_Attrs, non-passed required Attribute '||l_attr_metadata_obj.ATTR_DISP_NAME||' has no default value');
5807 
5808             l_token_table(1).TOKEN_VALUE := l_attr_metadata_obj.ATTR_DISP_NAME;
5809 
5810             ERROR_HANDLER.Add_Error_Message(
5811               p_message_name      => 'EGO_EF_NO_VAL_FOR_REQ_ATTR'
5812              ,p_application_id    => 'EGO'
5813              ,p_token_tbl         => l_token_table
5814              ,p_message_type      => FND_API.G_RET_STS_ERROR
5815              ,p_row_identifier    => G_USER_ROW_IDENTIFIER
5816              ,p_entity_id         => p_entity_id
5817              ,p_entity_index      => p_entity_index
5818              ,p_entity_code       => p_entity_code
5819              ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
5820             );
5821 
5822             l_has_all_required_attrs := FALSE;
5823 
5824           END IF;
5825         END IF;
5826       END IF;
5827 
5828       l_metadata_table_index := p_attr_metadata_table.NEXT(l_metadata_table_index);
5829     END LOOP;
5830 
5831     Debug_Msg('In Verify_All_Required_Attrs, done', 2);
5832 
5833     RETURN l_has_all_required_attrs;
5834 
5835 END Verify_All_Required_Attrs;
5836 
5837 ----------------------------------------------------------------------
5838 
5839 FUNCTION Get_Requested_Attr_Names (
5840         p_row_identifier                IN   NUMBER
5841        ,p_attr_group_disp_name          IN   VARCHAR2
5842        ,p_attr_name_list                IN   VARCHAR2
5843        ,p_attr_metadata_table           IN   EGO_ATTR_METADATA_TABLE
5844        ,p_entity_id                     IN   VARCHAR2
5845        ,p_entity_index                  IN   NUMBER
5846        ,p_entity_code                   IN   VARCHAR2
5847 )
5848 RETURN LOCAL_VARCHAR_TABLE
5849 IS
5850 
5851     l_attr_name_list         VARCHAR2(3000) := p_attr_name_list;
5852     l_attr_name_table        LOCAL_VARCHAR_TABLE;
5853     l_next_attr_name         VARCHAR2(30);
5854     l_candidate_attr         EGO_ATTR_METADATA_OBJ;
5855     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
5856     l_metadata_table_index   NUMBER;
5857     l_found_bad_names        BOOLEAN := FALSE;
5858 
5859   BEGIN
5860 
5861     Debug_Msg('In Get_Requested_Attr_Names, starting', 2);
5862 
5863     IF (LENGTH(l_attr_name_list) > 0) THEN
5864       WHILE (LENGTH(l_attr_name_list) > 0)
5865       LOOP
5866 
5867         IF (INSTR(l_attr_name_list, ',') > 0) THEN
5868 
5869           l_next_attr_name := SUBSTR(l_attr_name_list, 1, INSTR(l_attr_name_list, ',') - 1);
5870           l_attr_name_list := SUBSTR(l_attr_name_list, INSTR(l_attr_name_list, ',') + 1);
5871 
5872         ELSE
5873 
5874           l_next_attr_name := l_attr_name_list;
5875           l_attr_name_list := '';
5876 
5877         END IF;
5878 
5879         l_next_attr_name := TRIM(l_next_attr_name);
5880 
5881         Debug_Msg('In Get_Requested_Attr_Names, trying to add '||l_next_attr_name||' to table', 3);
5882 
5883         l_candidate_attr := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
5884                               p_attr_metadata_table => p_attr_metadata_table
5885                              ,p_attr_name           => l_next_attr_name
5886                             );
5887 
5888         IF (l_candidate_attr IS NOT NULL AND
5889             l_candidate_attr.ATTR_NAME IS NOT NULL) THEN
5890 
5891           l_attr_name_table(l_attr_name_table.COUNT+1) := l_next_attr_name;
5892 
5893         ELSE
5894 
5895           l_found_bad_names := TRUE;
5896 
5897           l_token_table(1).TOKEN_NAME := 'BAD_ATTR_NAME';
5898           l_token_table(1).TOKEN_VALUE := l_next_attr_name;
5899           l_token_table(2).TOKEN_NAME := 'AG_NAME';
5900           l_token_table(2).TOKEN_VALUE := p_attr_group_disp_name;
5901 
5902           ERROR_HANDLER.Add_Error_Message(
5903             p_message_name      => 'EGO_EF_ATTR_DOES_NOT_EXIST'
5904            ,p_application_id    => 'EGO'
5905            ,p_token_tbl         => l_token_table
5906            ,p_message_type      => FND_API.G_RET_STS_ERROR
5907            ,p_row_identifier    => p_row_identifier
5908            ,p_entity_id         => p_entity_id
5909            ,p_entity_index      => p_entity_index
5910            ,p_entity_code       => p_entity_code
5911            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
5912           );
5913 
5914         END IF;
5915 
5916       END LOOP;
5917     ELSE -- if the list is empty, we return all Attributes in the Attribute Group
5918      --bug 5494760 the p_attr_metadata_table can be null, if no attribute
5919      -- is created under the attribute group.
5920      IF p_attr_metadata_table IS NOT NULL THEN
5921       l_metadata_table_index := p_attr_metadata_table.FIRST;
5922       WHILE (l_metadata_table_index <= p_attr_metadata_table.LAST)
5923       LOOP
5924         l_attr_name_table(l_attr_name_table.COUNT+1) := p_attr_metadata_table(l_metadata_table_index).ATTR_NAME;
5925         l_metadata_table_index := p_attr_metadata_table.NEXT(l_metadata_table_index);
5926       END LOOP;
5927      END IF;--p_attr_metadata_table IS NOT NULL
5928     END IF;
5929 
5930     -- If we fail, we need to pass something back to indicate that failure
5931     IF (l_found_bad_names) THEN
5932       l_attr_name_table(-1) := 'FAILED';
5933     END IF;
5934 
5935     Debug_Msg('In Get_Requested_Attr_Names, done', 2);
5936 
5937     RETURN l_attr_name_table;
5938 
5939 END Get_Requested_Attr_Names;
5940 
5941 ----------------------------------------------------------------------
5942 
5943 PROCEDURE Generate_Attr_Int_Values (
5944         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
5945        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
5946        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
5947        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
5948        ,p_entity_id                     IN   VARCHAR2   DEFAULT NULL
5949        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
5950        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
5951        ,px_attr_name_value_pairs        IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
5952        ,x_return_status                 OUT NOCOPY VARCHAR2
5953 ) IS
5954 
5955     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
5956     l_attr_value_index       NUMBER;
5957     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
5958     l_int_value              VARCHAR2(4000);	-- Bug 8757354
5959     l_err_msg_name           VARCHAR2(30);
5960 
5961   BEGIN
5962 
5963     Debug_Msg('In Generate_Attr_Int_Values, starting', 2);
5964 
5965     IF (px_attr_name_value_pairs IS NOT NULL AND
5966         px_attr_name_value_pairs.COUNT > 0) THEN
5967       l_attr_value_index := px_attr_name_value_pairs.FIRST;
5968       WHILE (l_attr_value_index <= px_attr_name_value_pairs.LAST)
5969       LOOP
5970 
5971         l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
5972                                  p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table
5973                                 ,p_attr_name           => px_attr_name_value_pairs(l_attr_value_index).ATTR_NAME
5974                                );
5975 
5976         ----------------------------------------------------------------------------
5977         -- If the Attribute has a Value Set of a type that has different internal --
5978         -- and display values, we only want to try getting the internal value if  --
5979         -- the caller has passed in the display value and nothing else; otherwise --
5980         -- we want to use the passed-in internal value and thus avoid a query.    --
5981         ----------------------------------------------------------------------------
5982         IF ((l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE OR
5983              l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE OR
5984              l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE) AND
5985             (px_attr_name_value_pairs(l_attr_value_index).ATTR_DISP_VALUE IS NOT NULL) AND
5986             (px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_STR IS NULL AND
5987              px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_NUM IS NULL AND
5988              px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_DATE IS NULL)) THEN
5989 
5990           l_int_value := Get_Int_Val_For_Disp_Val(
5991                            p_attr_metadata_obj             => l_attr_metadata_obj
5992                           ,p_attr_value_obj                => px_attr_name_value_pairs(l_attr_value_index)
5993                           ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
5994                           ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
5995                           ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
5996                           ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
5997                           ,p_entity_id                     => p_entity_id
5998                           ,p_entity_index                  => p_entity_index
5999                           ,p_entity_code                   => p_entity_code
6000                           ,p_attr_name_value_pairs         => px_attr_name_value_pairs
6001                          );
6002 
6003           IF (l_int_value IS NOT NULL) THEN
6004             IF (l_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
6005                 l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
6006                 l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
6007               px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_STR := l_int_value;
6008             ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
6009               px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_NUM := TO_NUMBER(l_int_value);
6010             ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) THEN
6011               px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_DATE := TRUNC(TO_DATE(l_int_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
6012             ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
6013               px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_DATE := TO_DATE(l_int_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
6014             END IF;
6015           ELSE
6016 
6017             l_err_msg_name := 'EGO_EF_INDEPENDENT_VS_VIOLATED';
6018 
6019             l_token_table(1).TOKEN_NAME := 'VALUE';
6020             l_token_table(1).TOKEN_VALUE := px_attr_name_value_pairs(l_attr_value_index).ATTR_DISP_VALUE;
6021             l_token_table(2).TOKEN_NAME := 'ATTR_NAME';
6022             l_token_table(2).TOKEN_VALUE := l_attr_metadata_obj.ATTR_DISP_NAME;
6023             l_token_table(3).TOKEN_NAME := 'AG_NAME';
6024             l_token_table(3).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
6025 
6026             x_return_status := FND_API.G_RET_STS_ERROR;
6027 
6028           END IF;
6029 
6030         -----------------------------------------------------------------------------------
6031         -- We also check for the (common) case where the Attribute doesn't have distinct --
6032         -- internal and display values but the user passed the value as ATTR_DISP_VALUE  --
6033         -- anyway, just for convenience; in this case, we try to interpret the passed-in --
6034         -- value as being of the appropriate data type.  If we cannot do so, we report   --
6035         -- the problem,                                                                  --
6036         -----------------------------------------------------------------------------------
6037         ELSIF (Disp_Val_Replacement_Is_Bad(l_attr_metadata_obj
6038                                           ,px_attr_name_value_pairs(l_attr_value_index))) THEN
6039 
6040           l_err_msg_name := 'EGO_EF_DATA_TYPE_INCORRECT';
6041 
6042           l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
6043           l_token_table(1).TOKEN_VALUE := l_attr_metadata_obj.ATTR_DISP_NAME;
6044           l_token_table(2).TOKEN_NAME := 'AG_NAME';
6045           l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
6046           l_token_table(3).TOKEN_NAME := 'DATA_TYPE';
6047           l_token_table(3).TOKEN_VALUE := l_attr_metadata_obj.DATA_TYPE_MEANING;
6048           l_token_table(4).TOKEN_NAME := 'VALUE';
6049           l_token_table(4).TOKEN_VALUE := px_attr_name_value_pairs(l_attr_value_index).ATTR_DISP_VALUE;
6050 
6051           x_return_status := FND_API.G_RET_STS_ERROR;
6052 
6053 
6054         ------------------------------------------------------------------------------
6055         -- Finally, we check for the much less common case where the Attribute is a --
6056         -- Date, but the value passed in is a $SYSDATE$ expression of some sort; in --
6057         -- such a case, we want to replace the expression with the appropriate Date --
6058         ------------------------------------------------------------------------------
6059         ELSIF ((l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
6060                 l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE)
6061                 AND
6062                (px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_STR IS NOT NULL AND
6063                 px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_DATE IS NULL)) THEN
6064 
6065           DECLARE
6066             l_formatted_expression   VARCHAR2(150);
6067           BEGIN
6068             l_formatted_expression := Format_Sysdate_Expression(px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_STR);
6069 
6070             IF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) THEN
6071               px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_DATE := TRUNC(TO_DATE(l_formatted_expression, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
6072             ELSE
6073               px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_DATE := TO_DATE(l_formatted_expression, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
6074             END IF;
6075 
6076           EXCEPTION
6077             WHEN OTHERS THEN
6078               l_err_msg_name := 'EGO_EF_DATA_TYPE_INCORRECT';
6079               l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
6080               l_token_table(1).TOKEN_VALUE := l_attr_metadata_obj.ATTR_DISP_NAME;
6081               l_token_table(2).TOKEN_NAME := 'AG_NAME';
6082               l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
6083               l_token_table(3).TOKEN_NAME := 'DATA_TYPE';
6084               l_token_table(3).TOKEN_VALUE := l_attr_metadata_obj.DATA_TYPE_MEANING;
6085               l_token_table(4).TOKEN_NAME := 'VALUE';
6086               l_token_table(4).TOKEN_VALUE := px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_STR;
6087               x_return_status := FND_API.G_RET_STS_ERROR;
6088           END;
6089         END IF;
6090 
6091         ----------------------------------------------------------------------------
6092         -- If processing for this Attribute failed, we log the error but continue --
6093         -- to process remaining Attributes (so we can report all errors at once)  --
6094         ----------------------------------------------------------------------------
6095         IF (l_err_msg_name IS NOT NULL) THEN
6096 
6097           Debug_Msg('Adding '||l_err_msg_name||' to error table for row '||px_attr_name_value_pairs(px_attr_name_value_pairs.FIRST).ROW_IDENTIFIER);
6098 
6099           ERROR_HANDLER.Add_Error_Message(
6100             p_message_name      => l_err_msg_name
6101            ,p_application_id    => 'EGO'
6102            ,p_token_tbl         => l_token_table
6103            ,p_message_type      => FND_API.G_RET_STS_ERROR
6104            ,p_row_identifier    => G_USER_ROW_IDENTIFIER
6105            ,p_entity_id         => p_entity_id
6106            ,p_entity_index      => p_entity_index
6107            ,p_entity_code       => p_entity_code
6108            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
6109           );
6110         END IF;
6111 
6112         l_err_msg_name := NULL;
6113         l_token_table.DELETE();
6114         l_attr_value_index := px_attr_name_value_pairs.NEXT(l_attr_value_index);
6115       END LOOP;
6116     END IF;
6117 
6118     Debug_Msg('In Generate_Attr_Int_Values, done', 2);
6119 
6120 END Generate_Attr_Int_Values;
6121 
6122 ----------------------------------------------------------------------
6123 PROCEDURE Raise_WF_Event_If_Enabled (
6124         p_dml_type                      IN   VARCHAR2
6125        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
6126        ,p_extension_id                  IN   NUMBER
6127        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
6128        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
6129        ,p_entity_id                     IN   VARCHAR2
6130        ,p_entity_index                  IN   NUMBER
6131        ,p_entity_code                   IN   VARCHAR2
6132        ,p_pre_event_flag                IN   VARCHAR2 DEFAULT NULL  --4105841
6133        ,p_data_level_id                 IN   VARCHAR2 DEFAULT NULL
6134        ,px_attr_diffs                   IN   EGO_USER_ATTR_DIFF_TABLE
6135 ) IS
6136 
6137     l_api_name               CONSTANT VARCHAR2(30) := 'Raise_WF_Event_If_Enabled';
6138     l_event_name             VARCHAR2(240);
6139     l_is_event_enabled_flag  VARCHAR2(1);
6140     l_primary_key_1_col_name VARCHAR2(30);
6141     l_primary_key_1_value    VARCHAR2(150);
6142     l_primary_key_2_col_name VARCHAR2(30);
6143     l_primary_key_2_value    VARCHAR2(150);
6144     l_primary_key_3_col_name VARCHAR2(30);
6145     l_primary_key_3_value    VARCHAR2(150);
6146     l_primary_key_4_col_name VARCHAR2(30);
6147     l_primary_key_4_value    VARCHAR2(150);
6148     l_primary_key_5_col_name VARCHAR2(30);
6149     l_primary_key_5_value    VARCHAR2(150);
6150     l_data_level_1_col_name  VARCHAR2(30);
6151     l_data_level_1_value     VARCHAR2(150);
6152     l_data_level_2_col_name  VARCHAR2(30);
6153     l_data_level_2_value     VARCHAR2(150);
6154     l_data_level_3_col_name  VARCHAR2(30);
6155     l_data_level_3_value     VARCHAR2(150);
6156     l_data_level_4_col_name  VARCHAR2(30);
6157     l_data_level_4_value     VARCHAR2(150);
6158     l_data_level_5_col_name  VARCHAR2(30);
6159     l_data_level_5_value     VARCHAR2(150);
6160 
6161     l_event_key              VARCHAR2(240);
6162     l_attr_name              VARCHAR2(240);
6163     --Start 4105841 Business Event Enh
6164     l_attr_name_val_index    NUMBER;
6165     l_attrs_index            NUMBER;
6166     l_attr_rec               EGO_ATTR_REC;
6167     l_attr_name_val          EGO_ATTR_TABLE;
6168     l_dml_type               VARCHAR2(10);
6169     l_dummy                  NUMBER;
6170     --End 4105841
6171     l_curr_attr_metadata_obj        EGO_ATTR_METADATA_OBJ; -- abedajna, Bug 6134504
6172   BEGIN
6173 
6174 
6175     ----------------------------------------------------------------------
6176     -- If there is a Business Event defined for this Attr Group Type... --
6177     ----------------------------------------------------------------------
6178     Debug_Msg( l_api_name ||' started');
6179     IF p_pre_event_flag IS NULL THEN
6180       BEGIN
6181         SELECT BUSINESS_EVENT_NAME
6182           INTO l_event_name
6183           FROM EGO_FND_DESC_FLEXS_EXT
6184          WHERE APPLICATION_ID = p_attr_group_metadata_obj.APPLICATION_ID
6185            AND DESCRIPTIVE_FLEXFIELD_NAME = p_attr_group_metadata_obj.ATTR_GROUP_TYPE;
6186       EXCEPTION
6187         WHEN NO_DATA_FOUND THEN
6188           NULL;
6189       END;
6190     ELSE
6191       BEGIN --Added for 4105841
6192         SELECT PRE_BUSINESS_EVENT_NAME
6193           INTO l_event_name
6194           FROM EGO_FND_DESC_FLEXS_EXT
6195          WHERE APPLICATION_ID = p_attr_group_metadata_obj.APPLICATION_ID
6196            AND DESCRIPTIVE_FLEXFIELD_NAME = p_attr_group_metadata_obj.ATTR_GROUP_TYPE;
6197       EXCEPTION
6198         WHEN NO_DATA_FOUND THEN
6199           NULL;
6200       END;
6201     END IF;
6202 
6203     IF (l_event_name IS NOT NULL) THEN
6204       -----------------------------------------------------------
6205       -- ...and if this Attr Group is enabled for the Event... --
6206       -----------------------------------------------------------
6207 
6208 
6209       IF p_pre_event_flag IS NULL THEN
6210         /*
6211   SELECT BUSINESS_EVENT_FLAG
6212           INTO l_is_event_enabled_flag
6213           FROM EGO_FND_DSC_FLX_CTX_EXT
6214          WHERE ATTR_GROUP_ID = p_attr_group_metadata_obj.ATTR_GROUP_ID;*/
6215         SELECT COUNT(*)
6216           INTO l_dummy
6217           FROM EGO_ATTR_GROUP_DL
6218          WHERE ATTR_GROUP_ID = p_attr_group_metadata_obj.ATTR_GROUP_ID
6219            AND DATA_LEVEL_ID = NVL(p_data_level_id,DATA_LEVEL_ID)
6220            AND RAISE_POST_EVENT = 'Y'; -- abedajna 6137035
6221         IF (l_dummy > 0) THEN
6222           l_is_event_enabled_flag := 'Y';
6223         ELSE
6224           l_is_event_enabled_flag := 'N';
6225         END IF;
6226 
6227       ELSE  --Added for 4105841
6228       /*
6229         SELECT PRE_BUSINESS_EVENT_FLAG
6230           INTO l_is_event_enabled_flag
6231           FROM EGO_FND_DSC_FLX_CTX_EXT
6232          WHERE ATTR_GROUP_ID = p_attr_group_metadata_obj.ATTR_GROUP_ID;*/
6233         SELECT COUNT(*)
6234           INTO l_dummy
6235           FROM EGO_ATTR_GROUP_DL
6236          WHERE ATTR_GROUP_ID = p_attr_group_metadata_obj.ATTR_GROUP_ID
6237            AND DATA_LEVEL_ID = NVL(p_data_level_id,DATA_LEVEL_ID)
6238            AND RAISE_PRE_EVENT = 'Y';  --abedajna 6137035
6239         IF (l_dummy > 0) THEN
6240           l_is_event_enabled_flag := 'Y';
6241         ELSE
6242           l_is_event_enabled_flag := 'N';
6243         END IF;
6244       END IF;
6245 
6246     END IF;
6247 
6248     IF (l_is_event_enabled_flag = 'Y') THEN
6249 
6250         ------------------------------------------------------------
6251         -- ...then we gather PKs and data levels in order to call --
6252         -- our wrapper to the WF code to raise the Business Event --
6253         ------------------------------------------------------------
6254       l_primary_key_1_col_name := p_pk_column_name_value_pairs(1).NAME;
6255       l_primary_key_1_value := p_pk_column_name_value_pairs(1).VALUE;
6256 
6257       IF (p_pk_column_name_value_pairs.COUNT > 1 AND
6258           p_pk_column_name_value_pairs(2) IS NOT NULL) THEN
6259 
6260         l_primary_key_2_col_name := p_pk_column_name_value_pairs(2).NAME;
6261         l_primary_key_2_value := p_pk_column_name_value_pairs(2).VALUE;
6262 
6263         IF (p_pk_column_name_value_pairs.COUNT > 2 AND
6264             p_pk_column_name_value_pairs(3) IS NOT NULL) THEN
6265 
6266           l_primary_key_3_col_name := p_pk_column_name_value_pairs(3).NAME;
6267           l_primary_key_3_value := p_pk_column_name_value_pairs(3).VALUE;
6268 
6269           IF (p_pk_column_name_value_pairs.COUNT > 3 AND
6270               p_pk_column_name_value_pairs(4) IS NOT NULL) THEN
6271 
6272             l_primary_key_4_col_name := p_pk_column_name_value_pairs(4).NAME;
6273             l_primary_key_4_value := p_pk_column_name_value_pairs(4).VALUE;
6274 
6275             IF (p_pk_column_name_value_pairs.COUNT > 4 AND
6276                 p_pk_column_name_value_pairs(5) IS NOT NULL) THEN
6277 
6278               l_primary_key_5_col_name := p_pk_column_name_value_pairs(5).NAME;
6279               l_primary_key_5_value := p_pk_column_name_value_pairs(5).VALUE;
6280 
6281             END IF;
6282           END IF;
6283         END IF;
6284       END IF;
6285 
6286       IF (p_data_level_name_value_pairs IS NOT NULL AND
6287           p_data_level_name_value_pairs.COUNT > 0 AND
6288           p_data_level_name_value_pairs(1) IS NOT NULL) THEN
6289 
6290         l_data_level_1_col_name := p_data_level_name_value_pairs(1).NAME;
6291         l_data_level_1_value := p_data_level_name_value_pairs(1).VALUE;
6292 
6293         IF (p_data_level_name_value_pairs.COUNT > 1 AND
6294             p_data_level_name_value_pairs(2) IS NOT NULL) THEN
6295 
6296           l_data_level_2_col_name := p_data_level_name_value_pairs(2).NAME;
6297           l_data_level_2_value := p_data_level_name_value_pairs(2).VALUE;
6298 
6299           IF (p_data_level_name_value_pairs.COUNT > 2 AND
6300               p_data_level_name_value_pairs(3) IS NOT NULL) THEN
6301 
6302             l_data_level_3_col_name := p_data_level_name_value_pairs(3).NAME;
6303             l_data_level_3_value := p_data_level_name_value_pairs(3).VALUE;
6304 
6305               IF (p_data_level_name_value_pairs.COUNT > 3 AND
6306                   p_data_level_name_value_pairs(4) IS NOT NULL) THEN
6307 
6308                 l_data_level_4_col_name := p_data_level_name_value_pairs(4).NAME;
6309                 l_data_level_4_value := p_data_level_name_value_pairs(4).VALUE;
6310 
6311                  IF (p_data_level_name_value_pairs.COUNT > 4 AND
6312                      p_data_level_name_value_pairs(5) IS NOT NULL) THEN
6313 
6314                    l_data_level_5_col_name := p_data_level_name_value_pairs(5).NAME;
6315                    l_data_level_5_value := p_data_level_name_value_pairs(5).VALUE;
6316                  END IF;
6317               END IF;
6318           END IF;
6319         END IF;
6320       END IF;
6321 
6322       --------------------------------------------------------------------
6323       -- To generate a unique instance key, we take the first 225 chars --
6324       -- of the Event name and append a timestamp of the current time   --
6325       --------------------------------------------------------------------
6326       l_event_key := SUBSTRB(l_event_name, 1, 225) || '-' || TO_CHAR(SYSDATE, 'J.SSSSS') || TO_CHAR(dbms_random.value(1,100));
6327 
6328       Debug_Msg('In Raise_WF_Event_If_Enabled, raising event with key '||l_event_key||' and DML_TYPE '||p_dml_type, 3);
6329       -- Start 4105841
6330 
6331       l_attrs_index    := px_attr_diffs.FIRST;
6332       l_attr_name_val  := EGO_ATTR_TABLE();
6333       l_attr_rec       := EGO_ATTR_REC('','');
6334       ---  In case of update compare and add...the changed ones....
6335       l_dml_type := p_dml_type;
6336       IF l_dml_type = 'UPDATE' AND G_SYNC_TO_UPDATE = 'Y' THEN
6337         l_dml_type := 'CREATE';
6338 /*        IF p_pre_event_flag IS NULL THEN --modify it after raising post event.
6339           G_SYNC_TO_UPDATE := 'N';
6340         END IF;     */
6341       END IF;
6342 
6343       IF(l_dml_type = 'UPDATE') THEN
6344         WHILE (l_attrs_index <= px_attr_diffs.LAST) LOOP
6345           l_attr_rec.attr_name := px_attr_diffs(l_attrs_index).attr_name;
6346 -- abedajna Bug 6134504 begin
6347             l_curr_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
6348                                       p_attr_group_metadata_obj.attr_metadata_table
6349                                      ,l_attr_rec.attr_name );
6350 -- abedajna Bug 6134504 end
6351           IF(NVL(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_STR,FND_API.G_MISS_CHAR)<>
6352              NVL(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_STR,FND_API.G_MISS_CHAR)) THEN
6353             l_attr_name_val.EXTEND();
6354             l_attr_rec.attr_value := px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_STR;
6355             l_attr_name_val(l_attr_name_val.LAST) := l_attr_rec;
6356           ELSIF ( NVL(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_NUM,FND_API.G_MISS_NUM)<>
6357                   NVL(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_NUM,FND_API.G_MISS_NUM))THEN
6358             l_attr_name_val.EXTEND();
6359             l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_NUM);
6360             l_attr_name_val(l_attr_name_val.LAST) :=l_attr_rec;
6361           ELSIF (NVL(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_DATE,FND_API.G_MISS_DATE)<>
6362                  NVL(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE,FND_API.G_MISS_DATE))THEN
6363             l_attr_name_val.EXTEND();
6364 --          l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE);
6365 -- abedajna Bug 6134504 begin
6366             if ( l_curr_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE ) then -- timestamp
6367                 l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
6368             elsif ( l_curr_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) then -- date
6369                 l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE);
6370             end if;
6371 -- abedajna Bug 6134504 end
6372             l_attr_name_val(l_attr_name_val.LAST) :=  l_attr_rec;
6373           END IF;
6374           l_attrs_index := px_attr_diffs.NEXT(l_attrs_index);
6375         END LOOP;
6376 
6377       ---for create add all attributes
6378       ELSIF(l_dml_type = 'CREATE') then
6379         WHILE (l_attrs_index <= px_attr_diffs.LAST) LOOP
6380           l_attr_rec.attr_name := px_attr_diffs(l_attrs_index).attr_name;
6381 -- abedajna Bug 6134504 begin
6382             l_curr_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
6383                                       p_attr_group_metadata_obj.attr_metadata_table
6384                                      ,l_attr_rec.attr_name );
6385 -- abedajna Bug 6134504 end
6386           IF px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_STR IS NOT NULL  THEN
6387             l_attr_rec.attr_value := px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_STR;
6388           ELSIF px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_NUM IS NOT NULL THEN
6389             l_attr_rec.attr_value := TO_CHAR(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_num);
6390           ELSIF px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE IS NOT NULL THEN
6391 --            l_attr_rec.attr_value := TO_CHAR(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE);
6392 -- abedajna Bug 6134504 begin
6393             if ( l_curr_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE ) then -- timestamp
6394                 l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
6395             elsif ( l_curr_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) then -- date
6396                 l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE);
6397             end if;
6398 -- abedajna Bug 6134504 end
6399           ELSE
6400             l_attr_rec.attr_value := null;
6401           END IF;
6402 
6403           l_attr_name_val.EXTEND();
6404           l_attr_name_val(l_attr_name_val.LAST) :=  l_attr_rec;
6405           l_attrs_index := px_attr_diffs.NEXT(l_attrs_index);
6406         END LOOP;
6407 
6408      ---for delete add all 'old' attributes
6409      ELSIF(l_dml_type = 'DELETE') then
6410         WHILE (l_attrs_index <= px_attr_diffs.LAST) LOOP
6411           l_attr_rec.attr_name := px_attr_diffs(l_attrs_index).attr_name;
6412 -- abedajna Bug 6134504 begin
6413             l_curr_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
6414                                       p_attr_group_metadata_obj.attr_metadata_table
6415                                      ,l_attr_rec.attr_name );
6416 -- abedajna Bug 6134504 end
6417           IF px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_STR IS NOT NULL  THEN
6418             l_attr_rec.attr_value := px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_STR;
6419           ELSIF px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_NUM IS NOT NULL THEN
6420             l_attr_rec.attr_value := TO_CHAR(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_num);
6421           ELSIF px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_DATE IS NOT NULL THEN
6422 --            l_attr_rec.attr_value := TO_CHAR(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_DATE);
6423 -- abedajna Bug 6134504 begin
6424             if ( l_curr_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) then -- timestamp
6425                 l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_DATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
6426             elsif ( l_curr_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) then -- date
6427                 l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_DATE);
6428             end if;
6429 -- abedajna Bug 6134504 end
6430           ELSE
6431             l_attr_rec.attr_value := null;
6432           END IF;
6433 
6434           l_attr_name_val.EXTEND();
6435           l_attr_name_val(l_attr_name_val.LAST) :=  l_attr_rec;
6436           l_attrs_index := px_attr_diffs.NEXT(l_attrs_index);
6437         END LOOP;
6438       END IF;
6439 
6440       ---Raise the event
6441       IF l_attr_name_val.count() > 0 THEN --if attributes are there raise it,
6442         IF p_pre_event_flag IS NULL THEN --Raise post Event
6443            EGO_WF_WRAPPER_PVT.Raise_WF_Business_Event(
6444             p_event_name                  => l_event_name
6445            ,p_event_key                   => l_event_key
6446            ,p_dml_type                    => l_dml_type
6447            ,p_attr_group_name             => p_attr_group_metadata_obj.ATTR_GROUP_NAME
6448            ,p_extension_id                => p_extension_id
6449            ,p_primary_key_1_col_name      => l_primary_key_1_col_name
6450            ,p_primary_key_1_value         => l_primary_key_1_value
6451            ,p_primary_key_2_col_name      => l_primary_key_2_col_name
6452            ,p_primary_key_2_value         => l_primary_key_2_value
6453            ,p_primary_key_3_col_name      => l_primary_key_3_col_name
6454            ,p_primary_key_3_value         => l_primary_key_3_value
6455            ,p_primary_key_4_col_name      => l_primary_key_4_col_name
6456            ,p_primary_key_4_value         => l_primary_key_4_value
6457            ,p_primary_key_5_col_name      => l_primary_key_5_col_name
6458            ,p_primary_key_5_value         => l_primary_key_5_value
6459            ,p_data_level_id               => p_data_level_id
6460            ,p_data_level_1_col_name       => l_data_level_1_col_name
6461            ,p_data_level_1_value          => l_data_level_1_value
6462            ,p_data_level_2_col_name       => l_data_level_2_col_name
6463            ,p_data_level_2_value          => l_data_level_2_value
6464            ,p_data_level_3_col_name       => l_data_level_3_col_name
6465            ,p_data_level_3_value          => l_data_level_3_value
6466            ,p_data_level_4_col_name       => l_data_level_4_col_name
6467            ,p_data_level_4_value          => l_data_level_4_value
6468            ,p_data_level_5_col_name       => l_data_level_5_col_name
6469            ,p_data_level_5_value          => l_data_level_5_value
6470            ,p_user_row_identifier         => G_USER_ROW_IDENTIFIER
6471            ,p_entity_id                   => p_entity_id
6472            ,p_entity_index                => p_entity_index
6473            ,p_entity_code                 => p_entity_code
6474            ,p_add_errors_to_fnd_stack     => G_ADD_ERRORS_TO_FND_STACK
6475           );
6476         ELSE --raise PreEvent
6477           EGO_WF_WRAPPER_PVT.Raise_WF_Business_Event(
6478             p_event_name                  => l_event_name
6479            ,p_event_key                   => l_event_key
6480            ,p_pre_event_flag              => 'T'
6481            ,p_dml_type                    => l_dml_type
6482            ,p_attr_group_name             => p_attr_group_metadata_obj.ATTR_GROUP_NAME
6483            ,p_extension_id                => p_extension_id
6484            ,p_primary_key_1_col_name      => l_primary_key_1_col_name
6485            ,p_primary_key_1_value         => l_primary_key_1_value
6486            ,p_primary_key_2_col_name      => l_primary_key_2_col_name
6487            ,p_primary_key_2_value         => l_primary_key_2_value
6488            ,p_primary_key_3_col_name      => l_primary_key_3_col_name
6489            ,p_primary_key_3_value         => l_primary_key_3_value
6490            ,p_primary_key_4_col_name      => l_primary_key_4_col_name
6491            ,p_primary_key_4_value         => l_primary_key_4_value
6492            ,p_primary_key_5_col_name      => l_primary_key_5_col_name
6493            ,p_primary_key_5_value         => l_primary_key_5_value
6494            ,p_data_level_id               => p_data_level_id
6495            ,p_data_level_1_col_name       => l_data_level_1_col_name
6496            ,p_data_level_1_value          => l_data_level_1_value
6497            ,p_data_level_2_col_name       => l_data_level_2_col_name
6498            ,p_data_level_2_value          => l_data_level_2_value
6499            ,p_data_level_3_col_name       => l_data_level_3_col_name
6500            ,p_data_level_3_value          => l_data_level_3_value
6501            ,p_data_level_4_col_name       => l_data_level_4_col_name
6502            ,p_data_level_4_value          => l_data_level_4_value
6503            ,p_data_level_5_col_name       => l_data_level_5_col_name
6504            ,p_data_level_5_value          => l_data_level_5_value
6505            ,p_user_row_identifier         => G_USER_ROW_IDENTIFIER
6506            ,p_attr_name_val_tbl           => l_attr_name_val
6507            ,p_entity_id                   => p_entity_id
6508            ,p_entity_index                => p_entity_index
6509            ,p_entity_code                 => p_entity_code
6510            ,p_add_errors_to_fnd_stack     => G_ADD_ERRORS_TO_FND_STACK
6511           );
6512         END IF;--end pre event flag.
6513       END IF; ---end count attributes.
6514     END IF;--end if if flag enabled
6515     Debug_Msg( l_api_name ||' done ');
6516   EXCEPTION
6517     --- If subscription fails...don't add to the stack, already added in EGO_WF_WRAPPER_PVT
6518     WHEN EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC THEN
6519         raise EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC;
6520 
6521     WHEN OTHERS THEN
6522       DECLARE
6523         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
6524       BEGIN
6525         Debug_Msg('GOT EXCEPTION' || SQLERRM);
6526         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
6527         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
6528         l_token_table(2).TOKEN_NAME := 'API_NAME';
6529         l_token_table(2).TOKEN_VALUE := l_api_name;
6530         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
6531         l_token_table(3).TOKEN_VALUE := SQLERRM;
6532 
6533         ERROR_HANDLER.Add_Error_Message(
6534           p_message_name      => 'EGO_PLSQL_ERR'
6535          ,p_application_id    => 'EGO'
6536          ,p_token_tbl         => l_token_table
6537          ,p_message_type      => FND_API.G_RET_STS_ERROR
6538          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
6539          ,p_entity_id         => p_entity_id
6540          ,p_entity_index      => p_entity_index
6541          ,p_entity_code       => p_entity_code
6542          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
6543         );
6544       END;
6545 END Raise_WF_Event_If_Enabled;
6546 
6547 
6548 ----------------------------------------------------------------------
6549 
6550 
6551                   -------------------------------
6552                   -- Private Set-up Procedures --
6553                   -------------------------------
6554 
6555 ----------------------------------------------------------------------
6556 
6557 PROCEDURE Perform_Preliminary_Checks (
6558         p_object_name                   IN   VARCHAR2
6559        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
6560        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
6561        ,p_entity_id                     IN   VARCHAR2
6562        ,p_entity_index                  IN   NUMBER
6563        ,p_entity_code                   IN   VARCHAR2
6564        ,x_return_status                 OUT NOCOPY VARCHAR2
6565 ) IS
6566 
6567     l_object_id              NUMBER;
6568     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
6569     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
6570     l_err_msg_name           VARCHAR2(30);
6571 
6572   BEGIN
6573 
6574     Debug_Msg('In Perform_Preliminary_Checks, starting', 2);
6575 
6576     ---------------------------------------------------------------------------------
6577     -- The first thing we do is make sure the passed-in Object Name is a valid one --
6578     -- (the procedure we call caches Object ID, so the call is not a wasted query) --
6579     ---------------------------------------------------------------------------------
6580     l_object_id := Get_Object_Id_From_Name(p_object_name);
6581     IF (l_object_id IS NULL) THEN
6582 
6583       l_token_table(1).TOKEN_NAME := 'OBJ_NAME';
6584       l_token_table(1).TOKEN_VALUE := p_object_name;
6585 
6586       l_err_msg_name := 'EGO_EF_NO_OBJ_ID_FOR_NAME';
6587       ERROR_HANDLER.Add_Error_Message(
6588         p_message_name      => l_err_msg_name
6589        ,p_application_id    => 'EGO'
6590        ,p_token_tbl         => l_token_table
6591        ,p_message_type      => FND_API.G_RET_STS_ERROR
6592        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
6593        ,p_entity_id         => p_entity_id
6594        ,p_entity_index      => p_entity_index
6595        ,p_entity_code       => p_entity_code
6596        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
6597       );
6598 
6599       RAISE FND_API.G_EXC_ERROR;
6600 
6601     END IF;
6602 
6603     ---------------------------------------------------------------
6604     -- Next, we make sure the column names passed in by as part  --
6605     -- of the name/value pair arrays match up with the extension --
6606     -- table metadata (again, the Ext Table object we find will  --
6607     -- be cached for later use, so asking for it now is OK).     --
6608     ---------------------------------------------------------------
6609     l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
6610 
6611     Debug_Msg('In Perform_Preliminary_Checks, getting ext table metadata for object ' || l_object_id, 2);
6612 
6613     IF (l_ext_table_metadata_obj IS NULL) THEN
6614       l_token_table(1).TOKEN_NAME := 'OBJECT_NAME';
6615       l_token_table(1).TOKEN_VALUE := p_object_name;
6616       ERROR_HANDLER.Add_Error_Message(
6617         p_message_name      => 'EGO_EF_EXT_TABLE_METADATA_ERR'
6618        ,p_application_id    => 'EGO'
6619        ,p_token_tbl         => l_token_table
6620        ,p_message_type      => FND_API.G_RET_STS_ERROR
6621        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
6622        ,p_entity_id         => p_entity_id
6623        ,p_entity_index      => p_entity_index
6624        ,p_entity_code       => p_entity_code
6625        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
6626       );
6627       RAISE FND_API.G_EXC_ERROR;
6628     END IF;
6629 
6630     IF (NOT Are_Ext_Table_Col_Names_Right(l_ext_table_metadata_obj
6631                                          ,p_pk_column_name_value_pairs
6632                                          ,p_class_code_name_value_pairs)) THEN
6633       l_token_table(1).TOKEN_NAME := 'OBJ_NAME';
6634       l_token_table(1).TOKEN_VALUE := p_object_name;
6635       l_err_msg_name := 'EGO_EF_EXT_TBL_COL_NAME_ERR';
6636       ERROR_HANDLER.Add_Error_Message(
6637         p_message_name      => l_err_msg_name
6638        ,p_application_id    => 'EGO'
6639        ,p_token_tbl         => l_token_table
6640        ,p_message_type      => FND_API.G_RET_STS_ERROR
6641        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
6642        ,p_entity_id         => p_entity_id
6643        ,p_entity_index      => p_entity_index
6644        ,p_entity_code       => p_entity_code
6645        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
6646       );
6647       RAISE FND_API.G_EXC_ERROR;
6648     END IF;
6649 
6650     -----------------------------------------------------------------------------
6651     -- Next, we check that the Primary Key column array has at least one value --
6652     -----------------------------------------------------------------------------
6653     IF (p_pk_column_name_value_pairs IS NULL OR
6654         p_pk_column_name_value_pairs(p_pk_column_name_value_pairs.FIRST) IS NULL OR
6655         p_pk_column_name_value_pairs(p_pk_column_name_value_pairs.FIRST).VALUE IS NULL) THEN
6656 
6657       IF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 1) THEN
6658         l_err_msg_name := 'EGO_EF_NO_PK_VALUES_1';
6659         l_token_table(1).TOKEN_NAME := 'PK1_COL_NAME';
6660         l_token_table(1).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME;
6661         l_token_table(2).TOKEN_NAME := 'OBJ_NAME';
6662         l_token_table(2).TOKEN_VALUE := p_object_name;
6663       ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 2) THEN
6664         l_err_msg_name := 'EGO_EF_NO_PK_VALUES_2';
6665         l_token_table(1).TOKEN_NAME := 'PK1_COL_NAME';
6666         l_token_table(1).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME;
6667         l_token_table(2).TOKEN_NAME := 'PK2_COL_NAME';
6668         l_token_table(2).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME;
6669         l_token_table(3).TOKEN_NAME := 'OBJ_NAME';
6670         l_token_table(3).TOKEN_VALUE := p_object_name;
6671       ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 3) THEN
6672         l_err_msg_name := 'EGO_EF_NO_PK_VALUES_3';
6673         l_token_table(1).TOKEN_NAME := 'PK1_COL_NAME';
6674         l_token_table(1).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME;
6675         l_token_table(2).TOKEN_NAME := 'PK2_COL_NAME';
6676         l_token_table(2).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME;
6677         l_token_table(3).TOKEN_NAME := 'PK3_COL_NAME';
6678         l_token_table(3).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME;
6679         l_token_table(4).TOKEN_NAME := 'OBJ_NAME';
6680         l_token_table(4).TOKEN_VALUE := p_object_name;
6681       ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 4) THEN
6682         l_err_msg_name := 'EGO_EF_NO_PK_VALUES_4';
6683         l_token_table(1).TOKEN_NAME := 'PK1_COL_NAME';
6684         l_token_table(1).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME;
6685         l_token_table(2).TOKEN_NAME := 'PK2_COL_NAME';
6686         l_token_table(2).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME;
6687         l_token_table(3).TOKEN_NAME := 'PK3_COL_NAME';
6688         l_token_table(3).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME;
6689         l_token_table(4).TOKEN_NAME := 'PK4_COL_NAME';
6690         l_token_table(4).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME;
6691         l_token_table(5).TOKEN_NAME := 'OBJ_NAME';
6692         l_token_table(5).TOKEN_VALUE := p_object_name;
6693       ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 5) THEN
6694         l_err_msg_name := 'EGO_EF_NO_PK_VALUES_5';
6695         l_token_table(1).TOKEN_NAME := 'PK1_COL_NAME';
6696         l_token_table(1).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME;
6697         l_token_table(2).TOKEN_NAME := 'PK2_COL_NAME';
6698         l_token_table(2).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME;
6699         l_token_table(3).TOKEN_NAME := 'PK3_COL_NAME';
6700         l_token_table(3).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME;
6701         l_token_table(4).TOKEN_NAME := 'PK4_COL_NAME';
6702         l_token_table(4).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME;
6703         l_token_table(5).TOKEN_NAME := 'PK5_COL_NAME';
6704         l_token_table(5).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(5).COL_NAME;
6705         l_token_table(6).TOKEN_NAME := 'OBJ_NAME';
6706         l_token_table(6).TOKEN_VALUE := p_object_name;
6707       END IF;
6708       ERROR_HANDLER.Add_Error_Message(
6709         p_message_name      => l_err_msg_name
6710        ,p_application_id    => 'EGO'
6711        ,p_token_tbl         => l_token_table
6712        ,p_message_type      => FND_API.G_RET_STS_ERROR
6713        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
6714        ,p_entity_id         => p_entity_id
6715        ,p_entity_index      => p_entity_index
6716        ,p_entity_code       => p_entity_code
6717        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
6718       );
6719       RAISE FND_API.G_EXC_ERROR;
6720     END IF;
6721 
6722     x_return_status := FND_API.G_RET_STS_SUCCESS;
6723     Debug_Msg('In Perform_Preliminary_Checks, done', 2);
6724 
6725   EXCEPTION
6726     WHEN FND_API.G_EXC_ERROR THEN
6727       Debug_Msg('In Perform_Preliminary_Checks, EXCEPTION FND_API.G_EXC_ERROR', 2);
6728       x_return_status := FND_API.G_RET_STS_ERROR;
6729 
6730 END Perform_Preliminary_Checks;
6731 
6732 ----------------------------------------------------------------------
6733 -- if p_data_level_row_obj is sent,
6734 -- the privilege will be taken from data_level_row_obj
6735 -- else it is taken from p_attr_group_metadata_obj
6736 ----------------------------------------------------------------------
6737 PROCEDURE Check_Privileges (
6738         p_attr_group_metadata_obj  IN   EGO_ATTR_GROUP_METADATA_OBJ
6739        ,p_data_level_row_obj       IN   EGO_DATA_LEVEL_ROW_OBJ  DEFAULT NULL
6740        ,p_ignore_edit_privilege    IN   BOOLEAN    DEFAULT FALSE
6741        ,p_entity_id                IN   NUMBER     DEFAULT NULL
6742        ,p_entity_index             IN   NUMBER     DEFAULT NULL
6743        ,p_entity_code              IN   VARCHAR2   DEFAULT NULL
6744        ,x_return_status            OUT  NOCOPY VARCHAR2
6745 ) IS
6746 
6747     l_privilege_table_index  NUMBER;
6748     l_has_view_privilege     BOOLEAN := FALSE;
6749     l_has_edit_privilege     BOOLEAN := FALSE;
6750     l_error_message_name     VARCHAR2(30);
6751     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
6752     l_view_privilege         fnd_form_functions.function_name%TYPE;
6753     l_edit_privilege         fnd_form_functions.function_name%TYPE;
6754 
6755   BEGIN
6756 
6757     Debug_Msg('In Check_Privileges, starting', 2);
6758 IF (p_data_level_row_obj IS NULL) THEN
6759 Debug_Msg(' Check_Privileges  view priv: '|| p_data_level_row_obj.view_privilege_id ||' edit priv: '||p_data_level_row_obj.edit_privilege_id);
6760 ELSE
6761 Debug_Msg(' Check_Privileges  view priv: '|| p_attr_group_metadata_obj.VIEW_PRIVILEGE ||' edit priv: '||p_attr_group_metadata_obj.EDIT_PRIVILEGE);
6762 END IF;
6763 
6764     ---------------------------------------------------------------
6765     -- First check for View privilege; if there is one, the user --
6766     -- must have it to even see the AG, let alone modify it      --
6767     ---------------------------------------------------------------
6768     IF (p_data_level_row_obj IS NULL AND p_attr_group_metadata_obj.VIEW_PRIVILEGE IS NULL)
6769        OR
6770        (p_data_level_row_obj IS NOT NULL and p_data_level_row_obj.view_privilege_id IS NULL) THEN
6771 
6772       l_has_view_privilege := TRUE;
6773 
6774     ELSE
6775 
6776       IF p_data_level_row_obj IS NOT NULL THEN
6777         SELECT function_name
6778         INTO l_view_privilege
6779         FROM fnd_form_functions
6780         WHERE function_id = p_data_level_row_obj.view_privilege_id;
6781       ELSE
6782         l_view_privilege  := p_attr_group_metadata_obj.VIEW_PRIVILEGE;
6783       END IF;
6784 Debug_Msg(' Check_Privileges  view priv: '|| l_view_privilege );
6785       --------------------------------------------------------
6786       -- NOTE: We assume that this procedure is only called --
6787       -- when G_CURRENT_USER_PRIVILEGES is not NULL         --
6788       --------------------------------------------------------
6789       IF (G_CURRENT_USER_PRIVILEGES IS NOT NULL AND G_CURRENT_USER_PRIVILEGES.COUNT > 0) THEN
6790         l_privilege_table_index := G_CURRENT_USER_PRIVILEGES.FIRST;
6791         WHILE (l_privilege_table_index <= G_CURRENT_USER_PRIVILEGES.LAST)
6792         LOOP
6793           EXIT WHEN l_has_view_privilege;
6794 
6795           IF (G_CURRENT_USER_PRIVILEGES(l_privilege_table_index) = l_view_privilege) THEN
6796             l_has_view_privilege := TRUE;
6797           END IF;
6798 
6799           l_privilege_table_index := G_CURRENT_USER_PRIVILEGES.NEXT(l_privilege_table_index);
6800         END LOOP;
6801       END IF;
6802     END IF;
6803 
6804     ----------------------------------------------------------------------
6805     -- If the user has View privilege (or if there is none defined), we --
6806     -- check for Edit privilege (assuming that p_ignore_edit_privilege  --
6807     -- is FALSE); if there is an Edit privilege, the user must have it  --
6808     ----------------------------------------------------------------------
6809     IF (NOT l_has_view_privilege) THEN
6810       l_error_message_name := 'EGO_EF_AG_USER_VIEW_PRIV_ERR';
6811     ELSE
6812 
6813       IF ( p_ignore_edit_privilege
6814           OR
6815           (p_data_level_row_obj IS NULL AND p_attr_group_metadata_obj.EDIT_PRIVILEGE IS NULL)
6816           OR
6817           (p_data_level_row_obj IS NOT NULL and p_data_level_row_obj.edit_privilege_id IS NULL) ) THEN
6818 
6819         l_has_edit_privilege := TRUE;
6820 
6821       ELSE
6822         IF p_data_level_row_obj IS NOT NULL THEN
6823           IF p_data_level_row_obj.edit_privilege_id IS NOT NULL THEN
6824             SELECT function_name
6825             INTO l_edit_privilege
6826             FROM fnd_form_functions
6827             WHERE function_id = p_data_level_row_obj.edit_privilege_id;
6828           ELSE
6829             l_edit_privilege := NULL;
6830           END IF;
6831         ELSE
6832           l_edit_privilege := p_attr_group_metadata_obj.EDIT_PRIVILEGE;
6833         END IF;
6834 Debug_Msg(' Check_Privileges  edit priv: '|| l_edit_privilege );
6835 
6836         IF (G_CURRENT_USER_PRIVILEGES.COUNT > 0) THEN
6837           l_privilege_table_index := G_CURRENT_USER_PRIVILEGES.FIRST;
6838           WHILE (l_privilege_table_index <= G_CURRENT_USER_PRIVILEGES.LAST)
6839           LOOP
6840             EXIT WHEN l_has_edit_privilege;
6841 
6842             IF (G_CURRENT_USER_PRIVILEGES(l_privilege_table_index) = l_edit_privilege) THEN
6843               l_has_edit_privilege := TRUE;
6844             END IF;
6845 
6846             l_privilege_table_index := G_CURRENT_USER_PRIVILEGES.NEXT(l_privilege_table_index);
6847           END LOOP;
6848         END IF;
6849       END IF;
6850     END IF;
6851 
6852     IF (l_has_edit_privilege) THEN
6853       x_return_status := FND_API.G_RET_STS_SUCCESS;
6854     ELSIF (l_error_message_name IS NULL) THEN
6855       l_error_message_name := 'EGO_EF_AG_USER_PRIV_ERR';
6856     END IF;
6857 
6858     -----------------------------------------------------------------------
6859     -- If the user is missing a necessary privilege, we report the error --
6860     -----------------------------------------------------------------------
6861     IF (l_error_message_name IS NOT NULL) THEN
6862 
6863       l_token_table(1).TOKEN_NAME := 'USER_NAME';
6864       l_token_table(1).TOKEN_VALUE := FND_GLOBAL.USER_NAME;
6865       l_token_table(2).TOKEN_NAME := 'AG_NAME';
6866       l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
6867 
6868       ERROR_HANDLER.Add_Error_Message(
6869         p_message_name                  => l_error_message_name
6870        ,p_application_id                => 'EGO'
6871        ,p_token_tbl                     => l_token_table
6872        ,p_message_type                  => FND_API.G_RET_STS_ERROR
6873        ,p_row_identifier                => G_USER_ROW_IDENTIFIER
6874        ,p_entity_id                     => p_entity_id
6875        ,p_entity_index                  => p_entity_index
6876        ,p_entity_code                   => p_entity_code
6877        ,p_addto_fnd_stack               => G_ADD_ERRORS_TO_FND_STACK
6878       );
6879 
6880       x_return_status := FND_API.G_RET_STS_ERROR;
6881     END IF;
6882 
6883     Debug_Msg('In Check_Privileges, done; x_return_status is '||x_return_status, 2);
6884 
6885 END Check_Privileges;
6886 
6887 ----------------------------------------------------------------------
6888 
6889 PROCEDURE Set_Up_Business_Object_Session (
6890         p_bulkload_flag                 IN   BOOLEAN
6891        ,p_user_privileges_on_object     IN   EGO_VARCHAR_TBL_TYPE DEFAULT NULL
6892        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
6893        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
6894        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
6895        ,p_debug_level                   IN   NUMBER
6896        ,p_init_error_handler_flag       IN   BOOLEAN
6897        ,p_object_name                   IN   VARCHAR2
6898        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
6899        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
6900        ,p_init_fnd_msg_list             IN   VARCHAR2
6901        ,p_add_errors_to_fnd_stack       IN   VARCHAR2
6902        ,p_default_user_row_identifier   IN   NUMBER     DEFAULT NULL
6903        ,p_use_def_vals_on_insert_flag   IN   BOOLEAN    DEFAULT FALSE
6904        ,x_return_status                 OUT NOCOPY VARCHAR2
6905 ) IS
6906 
6907     l_err_msg_name           VARCHAR2(30);
6908     l_api_name               VARCHAR2(50) := 'Set_Up_Business_Object_Session(): ';
6909 
6910   BEGIN
6911 Debug_Msg(l_api_name || 'starting', 3);
6912     ------------------------------------------------------------------
6913     -- This flag determines when certain validations are performed, --
6914     -- how error-handling proceeds, how caching is handled, etc.    --
6915     ------------------------------------------------------------------
6916     G_BULK_PROCESSING_FLAG := p_bulkload_flag;
6917 
6918     ---------------------------------------------------------------
6919     -- This flag determines whether calls to Insert_Row will use --
6920     -- Default Values for Attributes that are NULL or not passed --
6921     ---------------------------------------------------------------
6922     G_DEFAULT_ON_INSERT_FLAG := p_use_def_vals_on_insert_flag OR p_bulkload_flag;
6923 
6924     ---------------------------------------------------------------------------
6925     -- This table holds the current user's privileges on the current object; --
6926     -- if it is non-null and non-empty, we will use it to perform data       --
6927     -- security checks for all Attribute Groups that have privileges defined --
6928     ---------------------------------------------------------------------------
6929     G_CURRENT_USER_PRIVILEGES := p_user_privileges_on_object;
6930 
6931     ---------------------------------------------------------------------
6932     -- If non-null, this is the number we should use for logging error --
6933     -- messages that are outside of the context of any particular row  --
6934     ---------------------------------------------------------------------
6935     IF (p_default_user_row_identifier IS NOT NULL) THEN
6936       G_USER_ROW_IDENTIFIER := p_default_user_row_identifier;
6937     END IF;
6938 
6939     --------------------------------------------------------------------------
6940     -- Reset our cache of metadata so we pick up the latest state of things --
6941     -- (we only want to do this once per bulkload and once per UI call)     --
6942     --------------------------------------------------------------------------
6943     IF (G_NEED_TO_RESET_AG_CACHE) THEN
6944 
6945       EGO_USER_ATTRS_COMMON_PVT.Reset_Cache_And_Globals();
6946       G_ASSOCIATION_DATA_LEVEL_CACHE.DELETE();
6947       G_HIERARCHY_CACHE.DELETE();
6948 
6949       IF (G_BULK_PROCESSING_FLAG) THEN
6950 
6951         G_NEED_TO_RESET_AG_CACHE := FALSE;
6952 
6953       END IF;
6954     END IF;
6955 
6956     ---------------------------------------
6957     -- This global holds the debug level --
6958     ---------------------------------------
6959     G_DEBUG_OUTPUT_LEVEL := p_debug_level;
6960 
6961     -----------------------------------------
6962     -- Initialize FND_MSG_PUB if necessary --
6963     -----------------------------------------
6964     IF (FND_API.To_Boolean(p_init_fnd_msg_list)) THEN
6965 
6966       FND_MSG_PUB.Initialize;
6967 
6968     END IF;
6969 
6970     ---------------------------------------
6971     -- Set up ERROR_HANDLER if necessary --
6972     ---------------------------------------
6973     IF (p_init_error_handler_flag) THEN
6974 
6975       ERROR_HANDLER.Initialize();
6976 
6977       ----------------------------------------------------------
6978       -- If we're debugging we have to set up a Debug session --
6979       ----------------------------------------------------------
6980       IF (p_debug_level > 0) THEN
6981 
6982         Set_Up_Debug_Session(p_entity_id, p_entity_code, p_debug_level);
6983 
6984       END IF;
6985     END IF;
6986 
6987     IF (FND_API.To_Boolean(p_add_errors_to_fnd_stack)) THEN
6988       G_ADD_ERRORS_TO_FND_STACK := 'Y';
6989     ELSE
6990       G_ADD_ERRORS_TO_FND_STACK := 'N';
6991     END IF;
6992 
6993     ---------------------------------------------------
6994     -- Before we begin processing rows, we make sure --
6995     -- the basic information passed in is correct    --
6996     ---------------------------------------------------
6997     Perform_Preliminary_Checks(
6998         p_object_name                   => p_object_name
6999        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
7000        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
7001        ,p_entity_id                     => p_entity_id
7002        ,p_entity_index                  => p_entity_index
7003        ,p_entity_code                   => p_entity_code
7004        ,x_return_status                 => x_return_status
7005     );
7006 Debug_Msg(l_api_name || 'done', 3);
7007 
7008 END Set_Up_Business_Object_Session;
7009 
7010 ----------------------------------------------------------------------
7011 
7012 PROCEDURE Close_Business_Object_Session (
7013         p_init_error_handler_flag       IN   BOOLEAN
7014        ,p_log_errors                    IN   BOOLEAN
7015        ,p_write_to_concurrent_log       IN   BOOLEAN
7016 ) IS
7017 
7018   BEGIN
7019 
7020     --------------------------------------------
7021     -- We log errors if we were told to do so --
7022     --------------------------------------------
7023     IF (p_log_errors) THEN
7024       IF (p_write_to_concurrent_log) THEN
7025         ERROR_HANDLER.Log_Error(
7026           p_write_err_to_inttable       => 'Y'
7027          ,p_write_err_to_conclog        => 'Y'
7028          ,p_write_err_to_debugfile      => ERROR_HANDLER.Get_Debug()
7029         );
7030       ELSE
7031         ERROR_HANDLER.Log_Error(
7032           p_write_err_to_inttable       => 'Y'
7033          ,p_write_err_to_debugfile      => ERROR_HANDLER.Get_Debug()
7034         );
7035       END IF;
7036     END IF;
7037 
7038     --------------------------------------------------------
7039     -- Set our various flags back to their initial values --
7040     --------------------------------------------------------
7041     -- FP Bug:6266004 (Base Bug:6086581)
7042     -- Start Reverting the fix done as a part of bug 3713278
7043 
7044     G_BULK_PROCESSING_FLAG := FALSE;
7045     G_DEFAULT_ON_INSERT_FLAG := FALSE;
7046     G_NEED_TO_RESET_AG_CACHE := TRUE;
7047     G_ADD_ERRORS_TO_FND_STACK := 'N';
7048 
7049     --Bug Fix 3713728
7050     --------------------------------------------------------
7051     -- We conditionally clear the user cache , only if it
7052     -- is not in Bulk Load Session
7053     --------------------------------------------------------
7054 
7055 --    IF(G_BULK_PROCESSING_FLAG = FALSE) THEN
7056 --      G_NEED_TO_RESET_AG_CACHE := TRUE;
7057 --    END IF;
7058 --    G_BULK_PROCESSING_FLAG := FALSE;
7059     --Bug Fix 3713728
7060 
7061     -- FP Bug:6266004 (Base Bug:6086581)
7062     -- End Reverting the fix done as a part of bug 3713278
7063 
7064     --------------------------------------------------------------
7065     -- If we were debugging, we have to close the debug session --
7066     --------------------------------------------------------------
7067     IF (p_init_error_handler_flag AND
7068         G_DEBUG_OUTPUT_LEVEL > 0 AND
7069         ERROR_HANDLER.Get_Debug() = 'Y') THEN
7070 
7071       ERROR_HANDLER.Close_Debug_Session();
7072       G_DEBUG_OUTPUT_LEVEL := 0;
7073 
7074     END IF;
7075 
7076   EXCEPTION
7077     WHEN OTHERS THEN
7078 
7079       ----------------------------------------------------------
7080       -- The ERROR_HANDLER call may fail for various reasons, --
7081       -- but we don't want that to halt our processing        --
7082       ----------------------------------------------------------
7083       NULL;
7084 
7085 END Close_Business_Object_Session;
7086 
7087 ----------------------------------------------------------------------
7088 
7089 
7090 -- As a part of the Bug 8939034, Removed the hint BYPASS_UJVC.
7091 -- p_to_table_name is not passed in any call to the below function, So the currently update expression
7092 -- having the hint BYPASS_UJVC will not execute at all, as result removing the hint BYPASS_UJVC.
7093 -- If any future use is planned to use the below function by passing the p_to_table_name,
7094 -- we have to re-evaluate the hint in update expression.
7095 FUNCTION Get_Table_Columns_List (
7096         p_application_id                IN   NUMBER
7097        ,p_from_table_name               IN   VARCHAR2
7098        ,p_from_cols_to_exclude_list     IN   VARCHAR2   DEFAULT NULL
7099        ,p_from_table_alias_prefix       IN   VARCHAR2   DEFAULT NULL
7100        ,p_to_table_name                 IN   VARCHAR2   DEFAULT NULL
7101        ,p_to_table_alias_prefix         IN   VARCHAR2   DEFAULT NULL
7102        ,p_in_line_view_where_clause     IN   VARCHAR2   DEFAULT NULL
7103        ,p_cast_date_cols_to_char        IN   BOOLEAN    DEFAULT FALSE
7104 )
7105 RETURN VARCHAR2
7106 IS
7107 
7108     l_dynamic_sql             VARCHAR2(20000);
7109     l_table_column_names_list VARCHAR2(32767);
7110     l_in_update_mode          BOOLEAN;
7111     l_update_expression       VARCHAR2(32767);
7112     l_column_name             VARCHAR2(30);
7113     l_column_type             VARCHAR2(1);
7114 
7115     TYPE DYNAMIC_CUR IS REF CURSOR;
7116     l_dynamic_cursor         DYNAMIC_CUR;
7117 
7118   BEGIN
7119 
7120     -------------------------------------------------------------------
7121     -- Build a query to fetch names of all columns we want to append --
7122     -------------------------------------------------------------------
7123 /***
7124   -- fix for 12.2 OLP compatible
7125 
7126     l_dynamic_sql := ' SELECT COLUMN_NAME, Decode(DATA_TYPE,''NUMBER'',''N'', ''DATE'',''D'',''VARCHAR2'',''V'',NULL) COLUMN_TYPE '|| --BugFix:5503749 (FND_COLUMNS has the TL columns registered for the B table also hence cannot FND_COLUMNS now)
7127                        ' FROM SYS.ALL_TAB_COLUMNS ' ||
7128                       ' WHERE TABLE_NAME = :1 ';
7129 ***/
7130 
7131     -- bug#15835530  fix for 12.2 OLP compatible
7132     l_dynamic_sql := ' SELECT COLUMN_NAME, Decode(DATA_TYPE,''NUMBER'',''N'', ''DATE'',''D'',''VARCHAR2'',''V'',NULL) COLUMN_TYPE '|| --BugFix:5503749 (FND_COLUMNS has the TL columns registered for the B table also hence cannot FND_COLUMNS now)
7133                        ' FROM user_synonyms syn, dba_tab_columns col ' ||
7134                       ' WHERE syn.synonym_name = :1 AND col.owner = syn.table_owner AND col.table_name = syn.table_name ';
7135 
7136     --Bug No:5346472
7137     -- We can't use a bind as :3 which is replaced by
7138     -- p_from_cols_to_exclude_list below.Since it is of type VARCHAR2
7139     -- and mainly it contains a long string with comma seperated values.
7140     -- Using :3 in this case will fetch wrong results.
7141     IF (p_from_cols_to_exclude_list IS NOT NULL) THEN
7142       --Bug no:5346472
7143       --l_dynamic_sql := l_dynamic_sql||' AND C.COLUMN_NAME NOT IN ( :3 )';
7144       l_dynamic_sql := l_dynamic_sql||' AND COLUMN_NAME NOT IN ( '||p_from_cols_to_exclude_list||' )';
7145     END IF;
7146     l_dynamic_sql := l_dynamic_sql||' ORDER BY COLUMN_NAME';
7147 
7148     -----------------------------------------------------------------------
7149     -- Determine whether we're in update mode (in which, instead of just --
7150     -- making a list of column names, we make an update expression using --
7151     -- the two table names (and possibly aliases) passed in)             --
7152     -----------------------------------------------------------------------
7153     l_in_update_mode := (p_to_table_name IS NOT NULL);
7154 
7155     ----------------------------------------------------
7156     -- Fetch all the table column names, prefixing or --
7157     -- building an update expression as appropriate   --
7158     ----------------------------------------------------
7159     IF (p_from_cols_to_exclude_list IS NOT NULL) THEN
7160       OPEN l_dynamic_cursor FOR l_dynamic_sql
7161       USING p_from_table_name;--Bug No:5346472 --, p_from_cols_to_exclude_list;
7162     ELSE
7163       OPEN l_dynamic_cursor FOR l_dynamic_sql
7164       USING p_from_table_name;
7165     END IF;
7166     LOOP
7167       FETCH l_dynamic_cursor INTO l_column_name, l_column_type;
7168       EXIT WHEN l_dynamic_cursor%NOTFOUND;
7169 
7170       -------------------------------------------
7171       -- If we're casting Dates to char, do so --
7172       -------------------------------------------
7173       IF (p_cast_date_cols_to_char AND l_column_type = 'D') THEN
7174         l_table_column_names_list := l_table_column_names_list||' TO_CHAR(';
7175       END IF;
7176 
7177       -------------------------------------------
7178       -- If there's a from table alias, add it --
7179       -------------------------------------------
7180       IF (p_from_table_alias_prefix IS NOT NULL) THEN
7181         l_table_column_names_list := l_table_column_names_list||p_from_table_alias_prefix||'.';
7182       END IF;
7183 
7184       ------------------------------------------------------------------
7185       -- Whether or not there's an alias, add the current column name --
7186       ------------------------------------------------------------------
7187       l_table_column_names_list := l_table_column_names_list || l_column_name || ' ';
7188 
7189       -----------------------------------------------------------
7190       -- If we're in update mode, add a from column alias, the --
7191       -- to column and its alias (we assume table aliases in   --
7192       -- update mode), and append to our update expression     --
7193       -----------------------------------------------------------
7194       IF (l_in_update_mode) THEN
7195         l_table_column_names_list := l_table_column_names_list ||
7196                                      p_from_table_alias_prefix || '_' ||
7197                                      l_column_name || ',' ||
7198                                      p_to_table_alias_prefix || '.' ||
7199                                      l_column_name || ' ' ||
7200                                      p_to_table_alias_prefix || '_' ||
7201                                      l_column_name;
7202 
7203         l_update_expression := l_update_expression ||
7204                                p_to_table_alias_prefix || '_' ||
7205                                l_column_name || '=' ||
7206                                p_from_table_alias_prefix || '_' ||
7207                                l_column_name || ',';
7208 
7209       END IF;
7210 
7211       ---------------------------------------------------------------------
7212       -- If we're casting Dates to char, close the parentheses correctly --
7213       ---------------------------------------------------------------------
7214       IF (p_cast_date_cols_to_char) THEN
7215         IF (l_column_type = 'D') THEN
7216           l_table_column_names_list := l_table_column_names_list||','''||
7217                                        EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT||''') '||
7218                                        l_column_name;
7219         END IF;
7220       END IF;
7221 
7222       ---------------------------------------------------------
7223       -- Add a comma to end each loop regardless of the mode --
7224       ---------------------------------------------------------
7225       l_table_column_names_list := l_table_column_names_list || ',';
7226 
7227     END LOOP;
7228     CLOSE l_dynamic_cursor;
7229 
7230     -----------------------------------------------------------------------
7231     -- Trim the trailing ',' from l_table_column_names_list if necessary --
7232     -----------------------------------------------------------------------
7233     IF (LENGTH(l_table_column_names_list) > 0) THEN
7234       l_table_column_names_list := RTRIM(l_table_column_names_list, ',');
7235     END IF;
7236 
7237     -----------------------------------------------------------------
7238     -- Trim the trailing ',' from l_update_expression if necessary --
7239     -----------------------------------------------------------------
7240     IF (LENGTH(l_update_expression) > 0) THEN
7241       l_update_expression := RTRIM(l_update_expression, ',');
7242     END IF;
7243 
7244     ----------------------------------------------------------------------
7245     -- If we're in update mode, assemble the complete update expression --
7246     ----------------------------------------------------------------------
7247     IF (l_in_update_mode) THEN
7248      -- Bug 8939034 : Start - Removed the hint BYPASS_UJVC
7249      -- l_table_column_names_list := 'UPDATE /*+ BYPASS_UJVC */ (SELECT '||l_table_column_names_list||
7250       l_table_column_names_list := 'UPDATE (SELECT '||l_table_column_names_list||
7251      -- Bug 8939034 : End
7252                                    ' FROM '||p_from_table_name||' '||p_from_table_alias_prefix||
7253                                    ','||p_to_table_name||' '||p_to_table_alias_prefix||' '||
7254                                    p_in_line_view_where_clause||') SET '||l_update_expression;
7255     END IF;
7256 
7257     RETURN l_table_column_names_list;
7258 
7259 END Get_Table_Columns_List;
7260 
7261 ----------------------------------------------------------------------
7262 
7263 
7264 
7265                     ----------------------------
7266                     -- Private Procedure APIs --
7267                     ----------------------------
7268 
7269 ----------------------------------------------------------------------
7270 
7271 PROCEDURE Insert_Row (
7272         p_api_version                   IN   NUMBER
7273        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
7274        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
7275        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
7276        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
7277        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
7278        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
7279        ,p_extension_id                  IN   NUMBER
7280        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
7281        ,p_language_to_process           IN   VARCHAR2
7282        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ
7283        ,p_extra_pk_col_name_val_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
7284        ,p_extra_attr_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
7285        ,p_pending_b_table_name          IN   VARCHAR2
7286        ,p_pending_tl_table_name         IN   VARCHAR2
7287        ,p_execute_dml                   IN   VARCHAR2   DEFAULT FND_API.G_TRUE
7288        ,p_entity_id                     IN   VARCHAR2
7289        ,p_entity_index                  IN   NUMBER
7290        ,p_entity_code                   IN   VARCHAR2
7291        ,p_commit                        IN   VARCHAR2
7292        ,p_bulkload_flag                 IN   BOOLEAN    DEFAULT FALSE
7293        ,px_attr_diffs                   IN OUT NOCOPY EGO_USER_ATTR_DIFF_TABLE
7294        ,p_raise_business_event          IN   BOOLEAN DEFAULT TRUE
7295        ,x_extension_id                  OUT NOCOPY NUMBER
7296        ,x_return_status                 OUT NOCOPY VARCHAR2
7297 ) IS
7298 
7299     l_api_name               CONSTANT VARCHAR2(30) := 'Insert_Row';
7300 
7301     --we don't use l_api_version yet, but eventually we might:
7302     --if we change required parameters, version goes FROM n.x to (n+1).x
7303     --if we change optional parameters, version goes FROM x.n to x.(n+1)
7304     l_api_version            CONSTANT NUMBER := 1.0;
7305 
7306     l_b_table_name           VARCHAR2(30);
7307     l_tl_table_name          VARCHAR2(30);
7308     l_pk_col_names           VARCHAR2(175);
7309     l_dl_col_names           VARCHAR2(200);
7310     l_cc_col_names           VARCHAR2(50);
7311     l_change_col_names       VARCHAR2(50);
7312     l_all_col_names          VARCHAR2(425);
7313     l_pk_col_values          VARCHAR2(775);
7314     l_dl_col_values          VARCHAR2(100);
7315     l_cc_col_values          VARCHAR2(300);
7316     l_change_col_values      VARCHAR2(50);
7317     l_all_col_values         VARCHAR2(1175);
7318     l_default_values_or_not  VARCHAR2(10);
7319     l_default_columns_or_not VARCHAR2(11);
7320     l_new_extension_id       NUMBER;
7321     l_dynamic_sql            VARCHAR2(32767); --the largest a VARCHAR2 can be
7322     l_cursor_id              NUMBER;
7323     l_number_of_rows         NUMBER;
7324     l_dummy                  VARCHAR2(1175);
7325     l_error_message          VARCHAR2(4000);
7326     l_event_name             VARCHAR2(240);
7327     l_is_event_enabled_flag  VARCHAR2(1);
7328     l_event_key              VARCHAR2(240);
7329     l_parameter_list         WF_PARAMETER_LIST_T := WF_PARAMETER_LIST_T();
7330     l_parameter_t            WF_PARAMETER_T:= WF_PARAMETER_T(null, null);
7331 
7332     l_propagate_hierarchy    BOOLEAN := TRUE;
7333     l_attr_diffs_event       EGO_USER_ATTR_DIFF_TABLE;
7334     l_pre_raise_flag         VARCHAR2(1);  --4105841
7335 
7336     l_extra_col_names        VARCHAR2(10000);
7337     l_extra_col_values       VARCHAR2(10000);
7338     l_index                  NUMBER;
7339 
7340     l_current_user_id        NUMBER := FND_GLOBAL.User_Id;
7341     l_current_login_id       NUMBER := FND_GLOBAL.Login_Id;
7342     l_data_level_id          NUMBER;
7343     l_dl_col_mdata_array     EGO_COL_METADATA_ARRAY;
7344 
7345     l_column_exists          VARCHAR2(1);  -- Bug 10097738
7346   BEGIN
7347 
7348     Debug_Msg('In Insert_Row, starting', 1);
7349 
7350     IF FND_API.To_Boolean(p_commit) THEN
7351       SAVEPOINT Insert_Row;
7352     END IF;
7353 
7354     l_pre_raise_flag := 'F';
7355     -- Check for call compatibility
7356     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
7357                                         l_api_name, G_PKG_NAME)
7358     THEN
7359       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7360     END IF;
7361 
7362     IF (p_bulkload_flag) THEN
7363       l_propagate_hierarchy := FALSE;
7364     END IF;
7365 
7366     ----------------------------------------------------------------------
7367     -- We take in p_extension_id for the case where the caller wants to --
7368     -- add a row to the pending changes table based on a production row --
7369     -- for a Multi-Row Attr Group but with changed values for unique    --
7370     -- key Attrs; in such a case, we won't be able to find the current  --
7371     -- Extension ID from the production row (since we rely on UK values --
7372     -- our Get_Extension_Id_For_Row query), so it must be passed in.    --
7373     -- We also take in p_extension_id from Implement_Change_Line.       --
7374     ----------------------------------------------------------------------
7375     IF (p_extension_id IS NOT NULL) THEN
7376       l_new_extension_id := p_extension_id;
7377     END IF;
7378 
7379     ----------------------------
7380     -- Add the extra columns .--
7381     ----------------------------
7382     l_extra_col_names := '';
7383     l_extra_col_values := '';
7384 
7385     IF(p_extra_pk_col_name_val_pairs IS NOT NULL) THEN
7386 
7387       l_index := p_extra_pk_col_name_val_pairs.FIRST;
7388       WHILE (l_index IS NOT NULL)
7389       LOOP
7390 
7391          IF (p_extra_pk_col_name_val_pairs(l_index).NAME IS NOT NULL) THEN
7392            l_extra_col_names := l_extra_col_names || p_extra_pk_col_name_val_pairs(l_index).NAME || ' , ';
7393            IF (p_extra_pk_col_name_val_pairs(l_index).VALUE IS NOT NULL) THEN
7394              l_extra_col_values := l_extra_col_values || p_extra_pk_col_name_val_pairs(l_index).VALUE || ' , ';
7395            ELSE
7396              l_extra_col_values := l_extra_col_values || ' NULL , ';
7397            END IF;
7398          END IF;
7399       l_index := p_extra_pk_col_name_val_pairs.NEXT(l_index);
7400 
7401       END LOOP;
7402     END IF;
7403 
7404 
7405     IF(p_extra_attr_name_value_pairs IS NOT NULL) THEN
7406       l_index := p_extra_attr_name_value_pairs.FIRST;
7407 
7408       WHILE (l_index IS NOT NULL)
7409       LOOP
7410          IF (p_extra_attr_name_value_pairs(l_index).NAME IS NOT NULL) THEN
7411 
7412            l_extra_col_names := l_extra_col_names || p_extra_attr_name_value_pairs(l_index).NAME || ' , ';
7413            IF (p_extra_attr_name_value_pairs(l_index).VALUE IS NOT NULL) THEN
7414              l_extra_col_values := l_extra_col_values || p_extra_attr_name_value_pairs(l_index).VALUE || ' , ';
7415            ELSE
7416              l_extra_col_values := l_extra_col_values || ' NULL , ';
7417            END IF;
7418 
7419          END IF;
7420          l_index := p_extra_attr_name_value_pairs.NEXT(l_index);
7421       END LOOP;
7422     END IF;
7423 
7424     --------------------------------------------------------------------------
7425     -- Determine whether we're in Change mode and set variables accordingly --
7426     --------------------------------------------------------------------------
7427     IF (p_change_obj IS NOT NULL AND
7428         p_pending_b_table_name IS NOT NULL AND
7429         p_pending_tl_table_name IS NOT NULL) THEN
7430 
7431       IF (p_extension_id IS NULL) THEN
7432         IF (p_change_obj.ACD_TYPE <> 'ADD') THEN
7433 
7434           l_new_extension_id := Get_Extension_Id_For_Row(
7435                                   p_attr_group_metadata_obj     => p_attr_group_metadata_obj
7436                                  ,p_ext_table_metadata_obj      => p_ext_table_metadata_obj
7437                                  ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
7438                                  ,p_data_level                  => p_data_level
7439                                  ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
7440                                  ,p_attr_name_value_pairs       => p_attr_name_value_pairs
7441                                 );
7442 
7443         END IF;
7444       END IF;
7445 
7446       l_b_table_name := p_pending_b_table_name;
7447       l_tl_table_name := p_pending_tl_table_name;
7448       l_change_col_names := ' CHANGE_ID, CHANGE_LINE_ID, ACD_TYPE, ';
7449       IF (p_change_obj.CHANGE_ID IS NOT NULL) THEN
7450         l_change_col_values := p_change_obj.CHANGE_ID||', ';
7451       ELSE
7452         l_change_col_values := 'NULL, ';
7453       END IF;
7454       IF (p_change_obj.CHANGE_LINE_ID IS NOT NULL) THEN
7455         l_change_col_values := l_change_col_values||
7456                                p_change_obj.CHANGE_LINE_ID||', ';
7457       ELSE
7458         l_change_col_values := l_change_col_values||'NULL, ';
7459       END IF;
7460       IF (p_change_obj.ACD_TYPE IS NOT NULL) THEN
7461         l_change_col_values := l_change_col_values || '''' || p_change_obj.ACD_TYPE || ''', ';
7462       ELSE
7463         l_change_col_values := l_change_col_values || '''NULL'', ';
7464       END IF;
7465 
7466     ELSE
7467 
7468       l_b_table_name := p_attr_group_metadata_obj.EXT_TABLE_B_NAME;
7469       l_tl_table_name := p_attr_group_metadata_obj.EXT_TABLE_TL_NAME;
7470       l_change_col_names := '';
7471       l_change_col_values := '';
7472 
7473     END IF;
7474 
7475     ---------------------------------
7476     -- we need to construct the    --
7477     -- DML for the provided tables --
7478     ---------------------------------
7479 
7480    IF (p_pending_b_table_name IS NOT NULL) THEN
7481       l_b_table_name := p_pending_b_table_name;
7482    END IF;
7483 
7484    IF (p_pending_b_table_name IS NOT NULL) THEN
7485       l_tl_table_name := p_pending_tl_table_name;
7486    END IF;
7487 
7488     ------------------------------------------------------------------
7489     -- If we haven't set it yet, get a sequence-generated extension --
7490     -- ID to use for insertion into both the base and TL tables     --
7491     ------------------------------------------------------------------
7492     IF (l_new_extension_id IS NULL) THEN
7493       SELECT EGO_EXTFWK_S.NEXTVAL INTO l_new_extension_id FROM DUAL;
7494     END IF;
7495 
7496     --Start 4105841
7497     Get_Changed_Attributes(
7498           p_dml_operation                 => 'INSERT'
7499         , p_object_name                   => null
7500         , p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
7501         , p_attr_group_metadata_obj       => p_attr_group_metadata_obj
7502         , p_ext_table_metadata_obj        => p_ext_table_metadata_obj
7503         , p_data_level                    => p_data_level
7504         , p_data_level_name_value_pairs   => p_data_level_name_value_pairs
7505         , p_attr_name_value_pairs         => p_attr_name_value_pairs
7506         , p_extension_id                  => null
7507         , p_entity_id                     => p_entity_id
7508         , p_entity_index                  => p_entity_index
7509         , p_entity_code                   => p_entity_code
7510         , px_attr_diffs                   => l_attr_diffs_event);
7511     --End 4105841
7512 
7513     -- Only propagate if at least one attribute has EIH code = LP/AP
7514     IF (l_propagate_hierarchy AND
7515         p_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG = 'Y') THEN
7516     --4105841 : Removing call to Get_Changed_Attributes as it's called before this check
7517       px_attr_diffs := l_attr_diffs_event;
7518     END IF;
7519 
7520     -----------------------------------------------
7521     -- Now we open a cursor for the statement(s) --
7522     -- and initialize FND_DSQL for our DMLs      --
7523     -----------------------------------------------
7524     l_cursor_id := DBMS_SQL.Open_Cursor;
7525     Init();
7526 
7527     --------------------------------------------------------------------------------
7528     -- If we're bulkloading, we want to default any values the user left blank,   --
7529     -- but if we're coming from the UI, then the user explicitly set them to NULL --
7530     --------------------------------------------------------------------------------
7531     IF (G_DEFAULT_ON_INSERT_FLAG) THEN
7532 
7533       l_default_values_or_not := 'VALUES_DEF';
7534       l_default_columns_or_not := 'COLUMNS_DEF';
7535 
7536     ELSE
7537 
7538       l_default_values_or_not := 'VALUES';
7539       l_default_columns_or_not := 'COLUMNS';
7540 
7541     END IF;
7542 
7543     ------------------------------------------------------------------
7544     -- We pass p_language_to_process from Implement_Change_Line; if --
7545     -- we have it, then we only insert if the passed-in language is --
7546     -- equal to USERENV('LANG'); otherwise we behave normally       --
7547     ------------------------------------------------------------------
7548     IF (p_language_to_process IS NULL OR
7549         p_language_to_process = USERENV('LANG')) THEN
7550 
7551       ------------------------------------------------------
7552       -- FND_DSQL and start our first DML statement       --
7553       -- NOTE: we insert into both tables regardless of   --
7554       -- whether there are any Attr values for each table --
7555       -- so that the VL doesn't have to outer join        --
7556       ------------------------------------------------------
7557 
7558       -- CM expects extension Id to be the first bind
7559       -- in the generated DML
7560       FND_DSQL.Add_Text('INSERT INTO '||l_b_table_name||
7561                         ' ('||
7562                         'EXTENSION_ID, ');
7563 
7564       -----------------------------------------------------
7565       -- Add attr_group_id only if table has this column --
7566       -----------------------------------------------------
7567       IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG ='Y') THEN
7568         FND_DSQL.Add_Text('ATTR_GROUP_ID, ');
7569       END IF;
7570 
7571       -----------------------------------------------------
7572       -- Add data_level_id only if it has been provided  --
7573       -----------------------------------------------------
7574       IF(p_data_level IS NOT NULL
7575          AND
7576          FND_API.TO_BOOLEAN(
7577               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => l_b_table_name
7578                                                            ,p_column_name => 'DATA_LEVEL_ID'
7579                                                            )
7580                            )
7581          ) THEN
7582         FND_DSQL.Add_Text('DATA_LEVEL_ID, ');
7583       END IF;
7584 
7585       --------------------------------------------------------------------------
7586       -- We trust that the names and values (fetched separately) will match   --
7587       -- up, because we checked this in Validate_Row.  If the caller bypassed --
7588       -- Validate_Row and went straight to Perform_DML_On_Row, then our       --
7589       -- assumption that names and values will match up could cause an error. --
7590       --------------------------------------------------------------------------
7591 
7592 Debug_Msg(l_api_name || ' calling  EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for PK ');
7593       l_pk_col_names := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7594                                                     p_ext_table_metadata_obj.pk_column_metadata
7595                                                    ,p_pk_column_name_value_pairs
7596                                                    ,'NAMES'
7597                                                    ,TRUE
7598                                                   );
7599 Debug_Msg(l_api_name || ' calling  EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for CC ');
7600       l_cc_col_names := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7601                                                     p_ext_table_metadata_obj.class_code_metadata
7602                                                    ,p_class_code_name_value_pairs
7603                                                    ,'NAMES'
7604                                                    ,TRUE
7605                                                    ,', '
7606                                                   );
7607       --------------------------------------------
7608       -- NOTE: if inserting into the pending    --
7609       -- table, we don't insert Data Level info --
7610       --------------------------------------------
7611 
7612       l_dl_col_mdata_array := EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Col_Array(p_attr_group_metadata_obj.APPLICATION_ID,
7613                                                                                  p_attr_group_metadata_obj.ATTR_GROUP_TYPE);
7614 /***
7615         FOR i IN l_dl_col_mdata_array.FIRST .. l_dl_col_mdata_array.LAST
7616         LOOP
7617            Debug_Msg('dl col--'||l_dl_col_mdata_array(i).COL_NAME);
7618         END LOOP;
7619 ***/
7620       IF (p_data_level_name_value_pairs IS NOT NULL AND
7621           p_data_level_name_value_pairs.COUNT > 0 AND
7622           p_change_obj IS NULL) THEN
7623 Debug_Msg(l_api_name || ' calling  EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for DL ');
7624         l_dl_col_names := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7625                                                       l_dl_col_mdata_array
7626                                                      ,p_data_level_name_value_pairs
7627                                                      ,'NAMES'
7628                                                      ,TRUE
7629                                                      ,', '
7630                                                     );
7631       END IF;
7632 
7633 Debug_Msg('  l_dl_col_names-'||l_dl_col_names);
7634 
7635       FND_DSQL.Add_Text(', ' || l_change_col_names || l_extra_col_names);
7636 
7637       -----------------------------------------------
7638       -- Add the Attr column info to the statement --
7639       -----------------------------------------------
7640 Debug_Msg(l_api_name || ' calling  Add_Attr_Info_To_Statement ');
7641       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
7642                                 ,p_attr_name_value_pairs
7643                                 ,', '
7644                                 ,l_default_columns_or_not
7645                                 ,'NONTRANS');
7646 
7647       ----------------------------------------------------------------------
7648       -- (No need to add a comma here, because Add_Attr_Info_To_Statement --
7649       -- adds a trailing separator to the list if it adds anything to it) --
7650       ----------------------------------------------------------------------
7651 			 -- Bug 10097738 : Start
7652  	       IF (p_attr_group_metadata_obj.MULTI_ROW_CODE = 'Y') THEN
7653  	         -- check if the column UNIQUE_VALUE exists in the _b table
7654 
7655  	         -- The below function returns 'T' or 'F'
7656 					 l_column_exists:= HAS_COLUMN_IN_TABLE_VIEW(l_b_table_name,'UNIQUE_VALUE');
7657 
7658  	         -- Add UNIQUE_VALUE only if table has this column for multi row UDAs only
7659  	         IF (FND_API.TO_BOOLEAN(l_column_exists)) THEN
7660  	           FND_DSQL.Add_Text('UNIQUE_VALUE, ');
7661  	         END IF;
7662  	       END IF;
7663  	       -- Bug 10097738 : End
7664 
7665       -------------------------------------
7666       -- Add the rest of the column info --
7667       -------------------------------------
7668       FND_DSQL.Add_Text('CREATED_BY, '||
7669                         'CREATION_DATE, '||
7670                         'LAST_UPDATED_BY, '||
7671                         'LAST_UPDATE_DATE, '||
7672                         'LAST_UPDATE_LOGIN'||
7673                         ') VALUES ( ');
7674 
7675       ------------------------------------------------
7676       -- Now bind the values, including Attr values --
7677       ------------------------------------------------
7678       Add_Bind(p_bind_identifier => 'EXTENSION_ID'
7679               ,p_value           => l_new_extension_id);
7680 
7681       -----------------------------------------------------
7682       -- Add attr_group_id only if table has this column --
7683       -----------------------------------------------------
7684       IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG ='Y') THEN
7685         FND_DSQL.Add_Text(', ');
7686         Add_Bind(p_bind_identifier => 'ATTR_GROUP_ID'
7687                  ,p_value          => p_attr_group_metadata_obj.ATTR_GROUP_ID);
7688       END IF;
7689 
7690       -----------------------------------------------------
7691       -- Add data_level_id only if it has been provided  --
7692       -----------------------------------------------------
7693       Debug_Msg(' in insert_row -- p_data_level-'||p_data_level);
7694       IF(p_data_level IS NOT NULL
7695          AND
7696          FND_API.TO_BOOLEAN(
7697               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => l_b_table_name
7698                                                            ,p_column_name => 'DATA_LEVEL_ID'
7699                                                            )
7700                            )
7701          ) THEN
7702         l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
7703                                              ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
7704                                              ,p_data_level);
7705         FND_DSQL.Add_Text(', ');
7706         Add_Bind(p_bind_identifier => 'DATA_LEVEL_ID'
7707                 ,p_value           => l_data_level_id);
7708       Debug_Msg(' in insert_row -- l_data_level_id-'||l_data_level_id);
7709       END IF;
7710 
7711 
7712       FND_DSQL.Add_Text(', ');
7713 Debug_Msg(l_api_name || ' calling  EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for PK 2 ');
7714       l_pk_col_values := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7715                                                      p_ext_table_metadata_obj.pk_column_metadata
7716                                                     ,p_pk_column_name_value_pairs
7717                                                     ,'VALUES'
7718                                                     ,TRUE
7719                                                    );
7720 Debug_Msg(l_api_name || ' calling  EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for CC 2 ');
7721       l_cc_col_values := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7722                                                      p_ext_table_metadata_obj.class_code_metadata
7723                                                     ,p_class_code_name_value_pairs
7724                                                     ,'VALUES'
7725                                                     ,TRUE
7726                                                     ,', '
7727                                                    );
7728       --------------------------------------------
7729       -- NOTE: if inserting into the pending    --
7730       -- table, we don't insert Data Level info --
7731       --------------------------------------------
7732       IF (p_data_level_name_value_pairs IS NOT NULL AND
7733           p_data_level_name_value_pairs.COUNT > 0 AND
7734           p_change_obj IS NULL) THEN
7735 Debug_Msg(l_api_name || ' calling  EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for DL 2 ');
7736         l_dl_col_values := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7737                                                        l_dl_col_mdata_array
7738                                                       ,p_data_level_name_value_pairs
7739                                                       ,'VALUES'
7740                                                       ,TRUE
7741                                                       ,', '
7742                                                      );
7743       END IF;
7744 
7745       FND_DSQL.Add_Text(', '||l_change_col_values|| l_extra_col_values);
7746 
7747       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
7748                                 ,p_attr_name_value_pairs
7749                                 ,', '
7750                                 ,l_default_values_or_not
7751                                 ,'NONTRANS');
7752 
7753       ----------------------------------------------------------------------
7754       -- (No need to add a comma here, because Add_Attr_Info_To_Statement --
7755       -- adds a trailing separator to the list if it adds anything to it) --
7756       ----------------------------------------------------------------------
7757 
7758       -- Bug 10097738 : Start
7759       IF (p_attr_group_metadata_obj.MULTI_ROW_CODE = 'Y' AND FND_API.TO_BOOLEAN(l_column_exists)) THEN
7760         FND_DSQL.Add_Bind(l_new_extension_id);    -- inserting the ext id value in UNIQUE_VALUE column for MR UDAs
7761         FND_DSQL.Add_Text(', ');
7762       END IF;
7763       -- Bug 10097738 : End
7764 
7765       Add_Bind(p_bind_identifier => 'CREATED_BY'
7766               ,p_value           => l_current_user_id);
7767       FND_DSQL.Add_Text(', ');
7768       --Added by geguo for 9373845
7769       SELECT NVL(G_WHO_CREATION_DATE, SYSDATE),
7770              NVL(G_WHO_LAST_UPDATE_DATE, SYSDATE)
7771         INTO G_WHO_CREATION_DATE, G_WHO_LAST_UPDATE_DATE
7772         FROM DUAL;
7773 
7774       Add_Bind(p_bind_identifier => 'CREATION_DATE'
7775               ,p_value           => G_WHO_CREATION_DATE);
7776       FND_DSQL.Add_Text(', ');
7777       Add_Bind(p_bind_identifier => 'LAST_UPDATED_BY'
7778               ,p_value           => l_current_user_id);
7779       FND_DSQL.Add_Text(', ');
7780 
7781       --Added by geguo for 9373845
7782       Add_Bind(p_bind_identifier => 'LAST_UPDATE_DATE'
7783               ,p_value           => G_WHO_LAST_UPDATE_DATE);
7784       FND_DSQL.Add_Text(', ');
7785       Add_Bind(p_bind_identifier => 'LAST_UPDATE_LOGIN'
7786               ,p_value           => l_current_login_id);
7787       FND_DSQL.Add_Text(')');
7788 
7789       l_dynamic_sql := FND_DSQL.Get_Text(FALSE);
7790 
7791       Debug_Msg('In Insert_Row, l_dynamic_sql for base table is as follows:', 3);
7792       Debug_Msg(l_dynamic_sql,3);
7793       Debug_SQL(FND_DSQL.Get_Text(TRUE));
7794       Set_Binds_And_Dml(l_dynamic_sql,'B');
7795 
7796       ---------------------------------------------------------------------
7797       -- Next we parse the statement, bind our variables, and execute it --
7798       ---------------------------------------------------------------------
7799 
7800       IF (p_execute_dml = FND_API.G_TRUE) THEN
7801         DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
7802         FND_DSQL.Set_Cursor(l_cursor_id);
7803         FND_DSQL.Do_Binds();
7804       END IF;
7805 
7806       --
7807       -- Bug 12603968. Resetting the global variables.
7808       -- See bugdb for details.
7809       -- sreharih. Tue May 31 14:54:01 PDT 2011.
7810       --
7811       G_WHO_CREATION_DATE := NULL;
7812       G_WHO_LAST_UPDATE_DATE := NULL;
7813       --Bug 12603968 End
7814 
7815       --Start 4105841 Raise pre event
7816       IF (p_change_obj IS  NULL) THEN
7817         IF(p_raise_business_event) THEN
7818           Raise_WF_Event_If_Enabled(
7819                 p_dml_type                      => 'CREATE'
7820                ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
7821                ,p_extension_id                  => l_new_extension_id
7822                ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
7823                ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
7824                ,p_entity_id                     => p_entity_id
7825                ,p_entity_index                  => p_entity_index
7826                ,p_entity_code                   => p_entity_code
7827                ,p_pre_event_flag                => 'T'
7828                ,p_data_level_id                 => l_data_level_id
7829                ,px_attr_diffs                   => l_attr_diffs_event
7830               );
7831           l_pre_raise_flag := 'T';
7832         END IF;
7833       END IF;
7834       --End 4105841
7835 
7836       IF (p_execute_dml = FND_API.G_TRUE) THEN
7837         l_number_of_rows := DBMS_SQL.Execute(l_cursor_id);
7838       END IF;
7839 
7840     END IF;
7841 
7842 
7843     ----------------------------------------------------------------
7844     -- Now we do basically the same thing except for the TL table --
7845     -- NOTE: again, we insert into the TL table regardless of     --
7846     -- whether there are any translatable Attr values so that the --
7847     -- VL doesn't have to outer join                              --
7848     ----------------------------------------------------------------
7849     IF (p_attr_group_metadata_obj.EXT_TABLE_TL_NAME IS NOT NULL) THEN
7850 
7851       Init();
7852       -- CM expects extension Id to be the first bind
7853       -- in the generated DML
7854       FND_DSQL.Add_Text('INSERT INTO '||l_tl_table_name||
7855                         ' ('||
7856                         'EXTENSION_ID, ');
7857 
7858       -----------------------------------------------------
7859       -- Add attr_group_id only if table has this column --
7860       -----------------------------------------------------
7861       IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG ='Y') THEN
7862         FND_DSQL.Add_Text('ATTR_GROUP_ID, ');
7863       END IF;
7864 
7865       -----------------------------------------------------
7866       -- Add data_level_id only if it has been provided  --
7867       -----------------------------------------------------
7868       IF(p_data_level IS NOT NULL
7869          AND
7870          FND_API.TO_BOOLEAN(
7871               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => l_tl_table_name
7872                                                            ,p_column_name => 'DATA_LEVEL_ID'
7873                                                            )
7874                            )
7875          ) THEN
7876         FND_DSQL.Add_Text('DATA_LEVEL_ID, ');
7877       END IF;
7878 
7879       l_pk_col_names := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7880                                                     p_ext_table_metadata_obj.pk_column_metadata
7881                                                    ,p_pk_column_name_value_pairs
7882                                                    ,'NAMES'
7883                                                    ,TRUE
7884                                                   );
7885       l_cc_col_names := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7886                                                     p_ext_table_metadata_obj.class_code_metadata
7887                                                    ,p_class_code_name_value_pairs
7888                                                    ,'NAMES'
7889                                                    ,TRUE
7890                                                    ,', '
7891                                                   );
7892       IF (p_data_level_name_value_pairs IS NOT NULL AND
7893           p_data_level_name_value_pairs.COUNT > 0 AND
7894           p_change_obj IS NULL) THEN
7895         l_dl_col_names := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7896                                                       l_dl_col_mdata_array
7897                                                      ,p_data_level_name_value_pairs
7898                                                      ,'NAMES'
7899                                                      ,TRUE
7900                                                      ,', '
7901                                                     );
7902       END IF;
7903 
7904       FND_DSQL.Add_Text(', ' || l_change_col_names||l_extra_col_names);
7905 
7906       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
7907                                 ,p_attr_name_value_pairs
7908                                 ,', '
7909                                 ,l_default_columns_or_not
7910                                 ,'TRANS');
7911 
7912       ----------------------------------------------------------------------
7913       -- (No need to add a comma here, because Add_Attr_Info_To_Statement --
7914       -- adds a trailing separator to the list if it adds anything to it) --
7915       ----------------------------------------------------------------------
7916 
7917       FND_DSQL.Add_Text('CREATED_BY, '||
7918                         'CREATION_DATE, '||
7919                         'LAST_UPDATED_BY, '||
7920                         'LAST_UPDATE_DATE, '||
7921                         'LAST_UPDATE_LOGIN, '||
7922                         'SOURCE_LANG, '||
7923                         'LANGUAGE) '||
7924                         'SELECT ');
7925 
7926       Add_Bind(p_bind_identifier => 'EXTENSION_ID'
7927               ,p_value           => l_new_extension_id);
7928 
7929       -----------------------------------------------------
7930       -- Add attr_group_id only if table has this column --
7931       -----------------------------------------------------
7932       IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG ='Y') THEN
7933         FND_DSQL.Add_Text(', ');
7934         Add_Bind(p_bind_identifier => 'ATTR_GROUP_ID'
7935                 ,p_value           => p_attr_group_metadata_obj.ATTR_GROUP_ID);
7936       END IF;
7937 
7938       -----------------------------------------------------
7939       -- Add data_level_id only if it has been provided  --
7940       -----------------------------------------------------
7941       IF(p_data_level IS NOT NULL
7942          AND
7943          FND_API.TO_BOOLEAN(
7944               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => l_tl_table_name
7945                                                            ,p_column_name => 'DATA_LEVEL_ID'
7946                                                            )
7947                            )
7948          ) THEN
7949         l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
7950                                              ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
7951                                              ,p_data_level);
7952         FND_DSQL.Add_Text(', ');
7953         Add_Bind(p_bind_identifier => 'DATA_LEVEL_ID'
7954                 ,p_value           => l_data_level_id);
7955       END IF;
7956 
7957       FND_DSQL.Add_Text(', ');
7958       l_pk_col_values := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7959                                                      p_ext_table_metadata_obj.pk_column_metadata
7960                                                     ,p_pk_column_name_value_pairs
7961                                                     ,'VALUES'
7962                                                     ,TRUE
7963                                                    );
7964       l_cc_col_values := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7965                                                      p_ext_table_metadata_obj.class_code_metadata
7966                                                     ,p_class_code_name_value_pairs
7967                                                     ,'VALUES'
7968                                                     ,TRUE
7969                                                     ,', '
7970                                                    );
7971       IF (p_data_level_name_value_pairs IS NOT NULL AND
7972           p_data_level_name_value_pairs.COUNT > 0 AND
7973           p_change_obj IS NULL) THEN
7974         l_dl_col_values := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7975                                                        l_dl_col_mdata_array
7976                                                       ,p_data_level_name_value_pairs
7977                                                       ,'VALUES'
7978                                                       ,TRUE
7979                                                       ,', '
7980                                                      );
7981       END IF;
7982 
7983       FND_DSQL.Add_Text(', '||l_change_col_values||l_extra_col_values);
7984 
7985       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
7986                                 ,p_attr_name_value_pairs
7987                                 ,', '
7988                                 ,l_default_values_or_not
7989                                 ,'TRANS');
7990 
7991       ----------------------------------------------------------------------
7992       -- (No need to add a comma here, because Add_Attr_Info_To_Statement --
7993       -- adds a trailing separator to the list if it adds anything to it) --
7994       ----------------------------------------------------------------------
7995 
7996       Add_Bind(p_bind_identifier => 'CREATED_BY'
7997               ,p_value           => l_current_user_id);
7998       FND_DSQL.Add_Text(', ');
7999       Add_Bind(p_bind_identifier => 'CREATION_DATE'
8000               ,p_value           => SYSDATE);
8001       FND_DSQL.Add_Text(', ');
8002       Add_Bind(p_bind_identifier => 'LAST_UPDATED_BY'
8003               ,p_value           => l_current_user_id);
8004       FND_DSQL.Add_Text(', ');
8005       Add_Bind(p_bind_identifier => 'LAST_UPDATE_DATE'
8006               ,p_value           => SYSDATE);
8007       FND_DSQL.Add_Text(', ');
8008       Add_Bind(p_bind_identifier => 'LAST_UPDATE_LOGIN'
8009               ,p_value           => l_current_login_id);
8010       FND_DSQL.Add_Text(', ');
8011       Add_Bind(p_bind_identifier => 'SOURCE_LANG'
8012               ,p_value           => USERENV('LANG'));
8013       FND_DSQL.Add_Text(', L.LANGUAGE_CODE '||
8014                         'FROM '||
8015                         'FND_LANGUAGES L '||
8016                         'WHERE L.INSTALLED_FLAG IN (''I'', ''B'')');
8017 
8018       -----------------------------------------------------------------
8019       -- We pass p_language_to_process from Implement_Change_Line so --
8020       -- that each pending TL row only inserts one production row    --
8021       -----------------------------------------------------------------
8022       IF (p_language_to_process IS NOT NULL) THEN
8023         FND_DSQL.Add_Text(' AND L.LANGUAGE_CODE = ');
8024         Add_Bind(p_bind_identifier => 'LANGUAGE'
8025                 ,p_value           => p_language_to_process);
8026       END IF;
8027 
8028       l_dynamic_sql := FND_DSQL.Get_Text(FALSE);
8029 
8030       Set_Binds_And_Dml(l_dynamic_sql,'TL');
8031 
8032       Debug_Msg('In Insert_Row, l_dynamic_sql for TL table is as follows:', 3);
8033       Debug_SQL(FND_DSQL.Get_Text(TRUE));
8034 
8035       ---------------------------------------------------
8036       -- We re-use our cursor from the first statement --
8037       ---------------------------------------------------
8038       IF (p_execute_dml = FND_API.G_TRUE) THEN
8039         DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
8040         FND_DSQL.Set_Cursor(l_cursor_id);
8041        FND_DSQL.Do_Binds();
8042       END IF;
8043 
8044       ---Start 4105841
8045       --raise the event if it has not been raised
8046 
8047       IF  (p_change_obj IS NULL) AND (l_pre_raise_flag = 'F') THEN
8048         IF(p_raise_business_event) THEN
8049           Raise_WF_Event_If_Enabled(
8050                 p_dml_type                      => 'CREATE'
8051                ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
8052                ,p_extension_id                  => l_new_extension_id
8053                ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
8054                ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
8055                ,p_entity_id                     => p_entity_id
8056                ,p_entity_index                  => p_entity_index
8057                ,p_entity_code                   => p_entity_code
8058                ,p_pre_event_flag                => 'T'
8059                ,p_data_level_id                 => l_data_level_id
8060                ,px_attr_diffs                   => l_attr_diffs_event
8061                );
8062           l_pre_raise_flag := 'T';
8063         END IF;
8064       END IF;
8065       --End 4105841
8066 
8067       IF (p_execute_dml = FND_API.G_TRUE) THEN
8068         l_number_of_rows := DBMS_SQL.Execute(l_cursor_id);
8069       END IF;
8070 
8071     END IF;
8072 
8073     ----------------------------------
8074     -- Finally, we close our cursor --
8075     ----------------------------------
8076     DBMS_SQL.Close_Cursor(l_cursor_id);
8077 
8078     IF (l_propagate_hierarchy
8079         AND p_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG = 'Y'
8080         AND px_attr_diffs.COUNT > 0 AND p_execute_dml = FND_API.G_TRUE) THEN --Bug fix 5220020
8081       Propagate_Attributes( p_pk_column_name_value_pairs
8082                           , p_class_code_name_value_pairs
8083                           , p_data_level_name_value_pairs
8084                           , px_attr_diffs
8085                           , G_CREATE_MODE
8086                           , p_attr_group_metadata_obj
8087                           , x_return_status
8088                           , l_error_message);
8089     END IF;
8090     IF (x_return_status IN (G_RET_STS_ERROR, G_RET_STS_UNEXP_ERROR )) THEN
8091       fnd_message.set_name('EGO','EGO_GENERIC_MSG_TEXT');
8092       fnd_message.set_token('MESSAGE',l_error_message);
8093       fnd_msg_pub.Add;
8094       RETURN;
8095     END IF;
8096 
8097     --------------------------------------------------
8098     -- If we inserted into the production tables... --
8099     -- we see about raising a Business Event      --
8100     --------------------------------------------------
8101     IF (p_change_obj IS NULL) THEN
8102       IF(p_raise_business_event) THEN
8103       Raise_WF_Event_If_Enabled(
8104         p_dml_type                      => 'CREATE'
8105        ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
8106        ,p_extension_id                  => l_new_extension_id
8107        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
8108        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
8109        ,p_entity_id                     => p_entity_id
8110        ,p_entity_index                  => p_entity_index
8111        ,p_entity_code                   => p_entity_code
8112        ,p_data_level_id                 => l_data_level_id
8113        ,px_attr_diffs                   => l_attr_diffs_event
8114       );
8115       END IF;
8116     END IF;
8117 
8118     x_extension_id := l_new_extension_id;
8119 
8120     Debug_Msg('In Insert_Row, done', 1);
8121 
8122     IF FND_API.To_Boolean(p_commit) THEN
8123       COMMIT WORK;
8124     END IF;
8125 
8126     x_return_status := FND_API.G_RET_STS_SUCCESS;
8127 
8128   EXCEPTION
8129     -----------------------------------------------------------
8130     -- There are no expected errors in this procedure, so... --
8131     -----------------------------------------------------------
8132     --Start 4105841
8133     --Checking for Exception raised by preAttribute Change Event
8134     --don't put to the stack already added in EGO_WF_WRAPPER_PVT
8135     WHEN EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC THEN
8136       Debug_Msg('Insert_Row EXCEPTION  EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC ');
8137       IF FND_API.To_Boolean(p_commit) THEN
8138         ROLLBACK TO insert_row;
8139       END IF;
8140       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
8141     --End 4105841
8142 
8143     WHEN OTHERS THEN
8144 
8145       Debug_Msg('Insert_Row EXCEPTION  others '||SQLERRM);
8146       IF FND_API.To_Boolean(p_commit) THEN
8147         ROLLBACK TO insert_row;
8148       END IF;
8149       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
8150 
8151       DECLARE
8152         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
8153       BEGIN
8154         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
8155         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
8156         l_token_table(2).TOKEN_NAME := 'API_NAME';
8157         l_token_table(2).TOKEN_VALUE := l_api_name;
8158         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
8159         l_token_table(3).TOKEN_VALUE := SQLERRM;
8160 
8161         ERROR_HANDLER.Add_Error_Message(
8162           p_message_name      => 'EGO_PLSQL_ERR'
8163          ,p_application_id    => 'EGO'
8164          ,p_token_tbl         => l_token_table
8165          ,p_message_type      => FND_API.G_RET_STS_ERROR
8166          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
8167          ,p_entity_id         => p_entity_id
8168          ,p_entity_index      => p_entity_index
8169          ,p_entity_code       => p_entity_code
8170          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
8171         );
8172       END;
8173 
8174 END Insert_Row;
8175 
8176 ----------------------------------------------------------------------
8177 
8178 PROCEDURE Update_Row (
8179         p_api_version                   IN   NUMBER
8180        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
8181        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
8182        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
8183        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
8184        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
8185        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
8186        ,p_extension_id                  IN   NUMBER
8187        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
8188        ,p_language_to_process           IN   VARCHAR2
8189        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ
8190        ,p_extra_attr_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
8191        ,p_extra_pk_col_name_val_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
8192        ,p_pending_b_table_name          IN   VARCHAR2
8193        ,p_pending_tl_table_name         IN   VARCHAR2
8194        ,p_execute_dml                   IN   VARCHAR2   DEFAULT FND_API.G_TRUE
8195        ,p_entity_id                     IN   VARCHAR2
8196        ,p_entity_index                  IN   NUMBER
8197        ,p_entity_code                   IN   VARCHAR2
8198        ,p_commit                        IN   VARCHAR2
8199        ,p_bulkload_flag                 IN   BOOLEAN    DEFAULT FALSE
8200        ,px_attr_diffs                   IN OUT NOCOPY EGO_USER_ATTR_DIFF_TABLE
8201        ,p_raise_business_event          IN   BOOLEAN DEFAULT TRUE
8202        ,x_return_status                 OUT NOCOPY VARCHAR2
8203 ) IS
8204 
8205     l_api_name               CONSTANT VARCHAR2(30) := 'Update_Row';
8206 
8207     --we don't use l_api_version yet, but eventually we might:
8208     --if we change required parameters, version goes FROM n.x to (n+1).x
8209     --if we change optional parameters, version goes FROM x.n to x.(n+1)
8210     l_api_version            CONSTANT NUMBER := 1.0;
8211 
8212     l_b_table_name           VARCHAR2(30);
8213     l_tl_table_name          VARCHAR2(30);
8214     l_which_attrs_to_update  VARCHAR2(10);
8215     l_attr_value_string      VARCHAR2(10000);
8216     l_change_col_where_string VARCHAR2(100);
8217     l_change_col_value_string VARCHAR2(50);
8218     l_extra_col_value_string VARCHAR2(10000);
8219     l_extra_col_where_string VARCHAR2(10000);
8220     l_dynamic_sql            VARCHAR2(32767); --the largest a VARCHAR2 can be
8221     l_cursor_id              NUMBER;
8222     l_number_of_rows         NUMBER;
8223 
8224     l_event_name             VARCHAR2(240);
8225     l_is_event_enabled_flag  VARCHAR2(1);
8226     l_event_key              VARCHAR2(240);
8227     l_parameter_list         WF_PARAMETER_LIST_T := WF_PARAMETER_LIST_T();
8228     l_parameter_t            WF_PARAMETER_T:= WF_PARAMETER_T(null, null);
8229     l_error_message          VARCHAR2(4000);
8230     l_propagate_hierarchy    BOOLEAN := TRUE;
8231     --Start 4105841
8232     l_attr_diffs_event       EGO_USER_ATTR_DIFF_TABLE;
8233     l_pre_event_flag         VARCHAR2(1);
8234     --End 4105841
8235     ctr                      NUMBER;
8236     l_index                  NUMBER;
8237 
8238     l_current_user_id        NUMBER := FND_GLOBAL.User_Id;
8239     l_current_login_id       NUMBER := FND_GLOBAL.Login_Id;
8240     --Start Bug 5211171
8241      l_col_value             VARCHAR2(1000);
8242      l_col_name              VARCHAR2(1000);
8243      l_col_values_index      NUMBER;
8244     --End Bug 5211171
8245     l_data_level_id          NUMBER;
8246 
8247   BEGIN
8248 
8249     Debug_Msg('In Update_Row, starting', 1);
8250 
8251     IF FND_API.To_Boolean(p_commit) THEN
8252       SAVEPOINT update_row;
8253     END IF;
8254 
8255     l_pre_event_flag := 'F';
8256     -- Check for call compatibility
8257     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
8258                                         l_api_name, G_PKG_NAME)
8259     THEN
8260       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8261     END IF;
8262 
8263     IF (p_bulkload_flag) THEN
8264       l_propagate_hierarchy := FALSE;
8265     END IF;
8266 
8267     -----------------------------------------------------------------------------------
8268     -- In case the extra columns are passed to be updated we push them into the dml
8269     -----------------------------------------------------------------------------------
8270     l_extra_col_value_string := null;
8271     ctr := 0;
8272     IF (p_extra_attr_name_value_pairs IS NOT NULL AND
8273         p_extra_attr_name_value_pairs.COUNT > 0) THEN
8274 
8275       l_index := p_extra_attr_name_value_pairs.FIRST;
8276       WHILE (l_index IS NOT NULL)
8277       LOOP
8278         IF (p_extra_attr_name_value_pairs(l_index).NAME IS NOT NULL) THEN
8279            ctr := ctr+1;
8280            IF ( ctr >1 ) THEN
8281              l_extra_col_value_string := l_extra_col_value_string||' , ';
8282            END IF;
8283            IF (p_extra_attr_name_value_pairs(l_index).VALUE IS NOT NULL) THEN
8284               l_extra_col_value_string := l_extra_col_value_string || p_extra_attr_name_value_pairs(l_index).NAME || ' = '
8285                                                                    ||  p_extra_attr_name_value_pairs(l_index).VALUE ;
8286            ELSE
8287               l_extra_col_value_string := l_extra_col_value_string || p_extra_attr_name_value_pairs(l_index).NAME || ' =  NULL ';
8288            END IF;
8289         END IF;
8290         l_index := p_extra_attr_name_value_pairs.NEXT(l_index);
8291       END LOOP;
8292 
8293     END IF;
8294 
8295     ------------------------------------------------------------------------------------------
8296     -- In case the extra pk columns values are passed we add them into the dml where clause
8297     ------------------------------------------------------------------------------------------
8298 
8299     l_extra_col_where_string := ' ';
8300 
8301     IF (p_extra_pk_col_name_val_pairs IS NOT NULL AND
8302         p_extra_pk_col_name_val_pairs.COUNT > 0) THEN
8303 
8304       l_index := p_extra_pk_col_name_val_pairs.FIRST;
8305       WHILE (l_index IS NOT NULL)
8306       LOOP
8307 
8308         IF (p_extra_pk_col_name_val_pairs(l_index).NAME IS NOT NULL) THEN
8309            l_extra_col_where_string := l_extra_col_where_string || ' AND ';
8310            IF (p_extra_pk_col_name_val_pairs(l_index).VALUE IS NOT NULL) THEN
8311               l_extra_col_where_string := l_extra_col_where_string || p_extra_pk_col_name_val_pairs(l_index).NAME || ' = '
8312                                                                    ||  p_extra_pk_col_name_val_pairs(l_index).VALUE ;
8313            ELSE
8314               l_extra_col_where_string := l_extra_col_where_string || p_extra_pk_col_name_val_pairs(l_index).NAME || ' IS  NULL ';
8315            END IF;
8316         END IF;
8317         l_index := p_extra_pk_col_name_val_pairs.NEXT(l_index);
8318 
8319       END LOOP;
8320 
8321     END IF;
8322 
8323    --------------------------------------------------------------------------
8324     -- Determine whether we're in Change mode and set variables accordingly --
8325     --------------------------------------------------------------------------
8326     IF (p_change_obj IS NOT NULL AND
8327         p_pending_b_table_name IS NOT NULL AND
8328         p_pending_tl_table_name IS NOT NULL) THEN
8329 
8330       l_b_table_name := p_pending_b_table_name;
8331       l_tl_table_name := p_pending_tl_table_name;
8332       IF (p_change_obj.CHANGE_ID IS NOT NULL) THEN
8333         l_change_col_where_string := ' AND CHANGE_ID = '||p_change_obj.CHANGE_ID||' AND ';
8334       ELSE
8335         l_change_col_where_string := ' AND CHANGE_ID IS NULL AND ';
8336       END IF;
8337       IF (p_change_obj.CHANGE_LINE_ID IS NOT NULL) THEN
8338         l_change_col_where_string := l_change_col_where_string||
8339                                      'CHANGE_LINE_ID = '||
8340                                      p_change_obj.CHANGE_LINE_ID||' ';
8341       ELSE
8342         l_change_col_where_string := l_change_col_where_string||
8343                                      'CHANGE_LINE_ID IS NULL ';
8344       END IF;
8345 
8346       -------------------------
8347       -- Update the ACD Type --
8348       -------------------------
8349       l_change_col_value_string := 'ACD_TYPE = '''||
8350                                    NVL(p_change_obj.ACD_TYPE, 'NULL')||''', ';
8351     ELSE
8352 
8353       l_b_table_name := p_attr_group_metadata_obj.EXT_TABLE_B_NAME;
8354       l_tl_table_name := p_attr_group_metadata_obj.EXT_TABLE_TL_NAME;
8355       l_change_col_where_string := '';
8356       l_change_col_value_string := '';
8357 
8358     END IF;
8359 
8360     -------------------------------------------------------------------------------
8361     -- In case the p_pending_b_table_name and p_pending_tl_table_name are passed
8362     -- we will use them.
8363     -------------------------------------------------------------------------------
8364     IF (p_pending_b_table_name IS NOT NULL) THEN
8365         l_b_table_name := p_pending_b_table_name;
8366         l_tl_table_name := p_pending_tl_table_name;
8367     END IF;
8368 
8369      -- Start 4105841
8370      Get_Changed_Attributes(
8371             p_dml_operation                 => 'UPDATE'
8372           , p_object_name                   =>  null
8373           , p_pk_column_name_value_pairs    =>  p_pk_column_name_value_pairs
8374           , p_attr_group_metadata_obj       =>  p_attr_group_metadata_obj
8375           , p_ext_table_metadata_obj        =>  p_ext_table_metadata_obj
8376           , p_data_level                    =>  p_data_level
8377           , p_data_level_name_value_pairs   =>  p_data_level_name_value_pairs
8378           , p_attr_name_value_pairs         =>  p_attr_name_value_pairs
8379           , p_extension_id                  =>  p_extension_id
8380           , p_entity_id                     =>  p_entity_id
8381           , p_entity_index                  =>  p_entity_index
8382           , p_entity_code                   =>  p_entity_code
8383           , px_attr_diffs                   =>  l_attr_diffs_event);
8384     -- End 4105841
8385     -- Only propagate if at least one attribute has EIH code = LP/AP
8386     IF (l_propagate_hierarchy AND
8387         p_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG = 'Y') THEN
8388     --4105841 : Removing call to Get_Changed_Attributes as it's called before this check
8389       px_attr_diffs := l_attr_diffs_event;
8390     END IF;
8391     --------------------------------------------------------------
8392     -- First we open a cursor for use in one or both statements --
8393     --------------------------------------------------------------
8394     l_cursor_id := DBMS_SQL.Open_Cursor;
8395 
8396     ------------------------------------------------------------------
8397     -- We pass p_language_to_process from Implement_Change_Line; if --
8398     -- we have it, then we only insert if the passed-in language is --
8399     -- equal to USERENV('LANG').  Otherwise we update the base      --
8400     -- table if there are any non-translatable Attributes.          --
8401     ------------------------------------------------------------------
8402     IF (p_attr_group_metadata_obj.TRANS_ATTRS_COUNT <
8403         p_attr_group_metadata_obj.attr_metadata_table.COUNT AND
8404         (p_language_to_process IS NULL OR
8405          p_language_to_process = USERENV('LANG'))) THEN
8406 
8407       Init();
8408       FND_DSQL.Add_Text('UPDATE '||l_b_table_name||
8409                         ' SET '||l_extra_col_value_string||l_change_col_value_string);
8410 
8411       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
8412                                 ,p_attr_name_value_pairs
8413                                 ,', '
8414                                 ,'EQUALS'
8415                                 ,'NONTRANS');
8416 
8417       ----------------------------------------------------------------------
8418       -- (No need to add a comma here, because Add_Attr_Info_To_Statement --
8419       -- adds a trailing separator to the list if it adds anything to it) --
8420       ----------------------------------------------------------------------
8421 
8422       FND_DSQL.Add_Text('LAST_UPDATED_BY = ');
8423       Add_Bind(p_bind_identifier => 'LAST_UPDATED_BY'
8424               ,p_value           => l_current_user_id);
8425       FND_DSQL.Add_Text(', ');
8426       FND_DSQL.Add_Text('LAST_UPDATE_DATE = ');
8427       --Added by geguo for 9373845
8428       SELECT NVL(G_WHO_LAST_UPDATE_DATE, SYSDATE) INTO G_WHO_LAST_UPDATE_DATE FROM DUAL;
8429       Add_Bind(p_bind_identifier => 'LAST_UPDATE_DATE'
8430               ,p_value           => G_WHO_LAST_UPDATE_DATE);
8431       FND_DSQL.Add_Text(', ');
8432       FND_DSQL.Add_Text('LAST_UPDATE_LOGIN = ');
8433       Add_Bind(p_bind_identifier => 'LAST_UPDATE_LOGIN'
8434               ,p_value           => l_current_login_id);
8435 
8436       FND_DSQL.Add_Text(' WHERE EXTENSION_ID = ');
8437       Add_Bind(p_bind_identifier => 'EXTENSION_ID'
8438               ,p_value           => p_extension_id);
8439 
8440       ----------------------------------------------------------------------------
8441       --We add the data_level_id to the where clause, it would be passed in
8442       --by the implementing team if the R12C changes for enhanced data level
8443       --support have been taken up.
8444       ----------------------------------------------------------------------------
8445       IF(p_data_level IS NOT NULL
8446          AND
8447          FND_API.TO_BOOLEAN(
8448               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => l_b_table_name
8449                                                            ,p_column_name => 'DATA_LEVEL_ID'
8450                                                            )
8451                            )
8452          ) THEN
8453 
8454         l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
8455                                              ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
8456                                              ,p_data_level);
8457 
8458       FND_DSQL.Add_Text(' AND DATA_LEVEL_ID = ');
8459       Add_Bind(p_bind_identifier => 'DATA_LEVEL_ID'
8460               ,p_value           => l_data_level_id);
8461 
8462       END IF;
8463 
8464       --Start Bug 5211171
8465       IF (p_data_level_name_value_pairs IS NOT NULL
8466          AND p_data_level_name_value_pairs.COUNT <> 0
8467          AND p_data_level_name_value_pairs(p_data_level_name_value_pairs.FIRST).VALUE IS NOT NULL) THEN
8468            l_col_values_index := p_data_level_name_value_pairs.FIRST;
8469            WHILE (l_col_values_index <= p_data_level_name_value_pairs.LAST)
8470            LOOP
8471 
8472              l_col_name := p_data_level_name_value_pairs(l_col_values_index).NAME;
8473              l_col_value := p_data_level_name_value_pairs(l_col_values_index).VALUE;
8474              IF (l_col_value is not NULL) THEN
8475                FND_DSQL.Add_Text(' AND '||l_col_name||' = ');
8476                Add_Bind(p_bind_identifier => l_col_name
8477                        ,p_value           => l_col_value);
8478              END IF;
8479              l_col_values_index := p_data_level_name_value_pairs.NEXT(l_col_values_index);
8480            END LOOP;
8481       END IF;--p_data_level_name_value_pairs IS NOT NULL
8482       --End Bug 5211171
8483 
8484       FND_DSQL.Add_Text(l_change_col_where_string);
8485       FND_DSQL.Add_Text(l_extra_col_where_string);
8486 
8487 
8488 
8489       l_dynamic_sql := FND_DSQL.Get_Text(FALSE);
8490 
8491       Debug_Msg('In Update_Row, l_dynamic_sql for base table is as follows:', 3);
8492       Debug_Msg('In Update_Row, l_dynamic_sql:'||l_dynamic_sql, 3);
8493       Debug_SQL(FND_DSQL.Get_Text(TRUE));
8494       Set_Binds_And_Dml(l_dynamic_sql ,'B');
8495 
8496       IF (p_execute_dml = FND_API.G_TRUE) THEN
8497         DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
8498         FND_DSQL.Set_Cursor(l_cursor_id);
8499         FND_DSQL.Do_Binds();
8500       END IF;
8501 
8502       --
8503       -- Bug 12603968. Resetting the global variables.
8504       -- See bugdb for details.
8505       -- sreharih. Tue May 31 14:54:01 PDT 2011.
8506       --
8507       G_WHO_CREATION_DATE := NULL;
8508       G_WHO_LAST_UPDATE_DATE := NULL;
8509       --Bug 12603968 End
8510 
8511       --Start 4105841 Raise Pre Event
8512       IF (p_change_obj IS NULL) THEN
8513         IF(p_raise_business_event) THEN
8514         Raise_WF_Event_If_Enabled(
8515             p_dml_type                      => 'UPDATE'
8516            ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
8517            ,p_extension_id                  => p_extension_id
8518            ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
8519            ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
8520            ,p_entity_id                     => p_entity_id
8521            ,p_entity_index                  => p_entity_index
8522            ,p_entity_code                   => p_entity_code
8523            ,p_pre_event_flag                => 'T'
8524            ,p_data_level_id                 => l_data_level_id
8525            ,px_attr_diffs                   => l_attr_diffs_event
8526           );
8527         l_pre_event_flag := 'T';
8528         END IF;
8529        END IF;
8530        --End 4105841
8531 
8532       IF (p_execute_dml =  FND_API.G_TRUE) THEN
8533         l_number_of_rows := DBMS_SQL.Execute(l_cursor_id);
8534       END IF;
8535 
8536     END IF;
8537 
8538     -------------------------------------------
8539     -- If there are translatable Attributes, --
8540     -- we will need to update the TL table   --
8541     -------------------------------------------
8542     IF (p_attr_group_metadata_obj.TRANS_ATTRS_COUNT > 0 AND
8543         p_attr_group_metadata_obj.EXT_TABLE_TL_NAME IS NOT NULL) THEN
8544 
8545       Init();
8546       FND_DSQL.Add_Text('UPDATE '||l_tl_table_name||
8547                         ' SET '||l_change_col_value_string);
8548 
8549       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
8550                                 ,p_attr_name_value_pairs
8551                                 ,', '
8552                                 ,'EQUALS'
8553                                 ,'TRANS');
8554 
8555       ----------------------------------------------------------------------
8556       -- (No need to add a comma here, because Add_Attr_Info_To_Statement --
8557       -- adds a trailing separator to the list if it adds anything to it) --
8558       ----------------------------------------------------------------------
8559 
8560       FND_DSQL.Add_Text('LAST_UPDATED_BY = ');
8561       Add_Bind(p_bind_identifier => 'LAST_UPDATED_BY'
8562               ,p_value           => l_current_user_id);
8563       FND_DSQL.Add_Text(', ');
8564       FND_DSQL.Add_Text('LAST_UPDATE_DATE = ');
8565       Add_Bind(p_bind_identifier => 'LAST_UPDATE_DATE'
8566               ,p_value           => SYSDATE);
8567       FND_DSQL.Add_Text(', ');
8568       FND_DSQL.Add_Text('LAST_UPDATE_LOGIN = ');
8569       Add_Bind(p_bind_identifier => 'LAST_UPDATE_LOGIN'
8570               ,p_value           => l_current_login_id);
8571        --Bug 10065435
8572       FND_DSQL.Add_Text(', ');
8573       IF (p_language_to_process IS NOT NULL and p_language_to_process <> USERENV('LANG')) THEN
8574            FND_DSQL.Add_Text('SOURCE_LANG = DECODE(SOURCE_LANG, LANGUAGE,''' || p_language_to_process || ''', SOURCE_LANG)');
8575       else
8576         FND_DSQL.Add_Text('SOURCE_LANG = ');
8577       	Add_Bind(p_bind_identifier => 'SOURCE_LANG'
8578               ,p_value           => USERENV('LANG'));
8579       end if;       -- end Bug 10065435
8580 
8581       FND_DSQL.Add_Text(' WHERE EXTENSION_ID = ');
8582       Add_Bind(p_bind_identifier => 'EXTENSION_ID'
8583               ,p_value           => p_extension_id);
8584 
8585       ----------------------------------------------------------------------------
8586       --We add the data_level_id to the where clause, it would be passed in
8587       --by the implementing team if the R12C changes for enhanced data level
8588       --support have been taken up.
8589       ----------------------------------------------------------------------------
8590       IF(p_data_level IS NOT NULL
8591          AND
8592          FND_API.TO_BOOLEAN(
8593               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => l_tl_table_name
8594                                                            ,p_column_name => 'DATA_LEVEL_ID'
8595                                                            )
8596                            )
8597          ) THEN
8598 
8599         l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
8600                                              ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
8601                                              ,p_data_level);
8602 
8603       FND_DSQL.Add_Text(' AND DATA_LEVEL_ID = ');
8604       Add_Bind(p_bind_identifier => 'DATA_LEVEL_ID'
8605               ,p_value           => l_data_level_id);
8606 
8607       END IF;
8608 
8609 
8610        --Start Bug 5211171
8611       IF (p_data_level_name_value_pairs IS NOT NULL
8612          AND p_data_level_name_value_pairs.COUNT <> 0
8613          AND p_data_level_name_value_pairs(p_data_level_name_value_pairs.FIRST).VALUE IS NOT NULL) THEN
8614            l_col_values_index := p_data_level_name_value_pairs.FIRST;
8615            Debug_Msg('In UPDATE_ROW ,p_data_level_name_value_pairs IS NOT NULL');
8616            WHILE (l_col_values_index <= p_data_level_name_value_pairs.LAST)
8617            LOOP
8618              l_col_name := p_data_level_name_value_pairs(l_col_values_index).NAME;
8619              l_col_value := p_data_level_name_value_pairs(l_col_values_index).VALUE;
8620              IF (l_col_value is not NULL) THEN
8621                FND_DSQL.Add_Text(' AND '||l_col_name||' = ');
8622                Add_Bind(p_bind_identifier => l_col_name
8623                        ,p_value           => l_col_value);
8624              END IF;
8625              l_col_values_index := p_class_code_name_value_pairs.NEXT(l_col_values_index);
8626            END LOOP;
8627       END IF;--p_data_level_name_value_pairs IS NOT NULL
8628       --End Bug 5211171
8629 
8630       FND_DSQL.Add_Text(l_change_col_where_string);
8631       FND_DSQL.Add_Text(l_extra_col_where_string); -- bug 8349515
8632 
8633       -----------------------------------------------------------------
8634       -- We pass p_language_to_process from Implement_Change_Line so --
8635       -- that each pending TL row only updates one production row    --
8636       -----------------------------------------------------------------
8637       IF (p_language_to_process IS NOT NULL) THEN
8638         FND_DSQL.Add_Text(' AND ((SOURCE_LANG = ');
8639         Add_Bind(p_bind_identifier => 'SOURCE_LANG'
8640                 ,p_value           => USERENV('LANG'));
8641         FND_DSQL.Add_Text(' AND LANGUAGE = ');
8642         Add_Bind(p_bind_identifier => 'LANGUAGE'
8643                 ,p_value           => p_language_to_process);
8644         FND_DSQL.Add_Text(') OR (SOURCE_LANG <> ');
8645         Add_Bind(p_bind_identifier => 'SOURCE_LANG'
8646                 ,p_value           => USERENV('LANG'));
8647         FND_DSQL.Add_Text(' AND LANGUAGE = ');
8648         Add_Bind(p_bind_identifier => 'LANGUAGE'
8649                 ,p_value           => USERENV('LANG'));
8650         --added for bug 10065435
8651         FND_DSQL.Add_Text(') OR (SOURCE_LANG = ');
8652         Add_Bind(p_bind_identifier => 'SOURCE_LANG'
8653                 ,p_value           => p_language_to_process);
8654         FND_DSQL.Add_Text(' AND LANGUAGE = ');
8655         Add_Bind(p_bind_identifier => 'LANGUAGE'
8656                 ,p_value           => p_language_to_process);
8657         --end for bug 10065435
8658         FND_DSQL.Add_Text('))');
8659       ELSE
8660         ----------------------------------------------------------
8661         -- In all other flows, we want to update all rows whose --
8662         -- language or source language is the current language  --
8663         ----------------------------------------------------------
8664         FND_DSQL.Add_Text(' AND (LANGUAGE = ');
8665         Add_Bind(p_bind_identifier => 'LANGUAGE'
8666                 ,p_value           => USERENV('LANG'));
8667         FND_DSQL.Add_Text(' OR SOURCE_LANG = ');
8668         Add_Bind(p_bind_identifier => 'SOURCE_LANG'
8669                 ,p_value           => USERENV('LANG'));
8670         FND_DSQL.Add_Text(')');
8671       END IF;
8672 
8673 
8674       l_dynamic_sql := FND_DSQL.Get_Text(FALSE);
8675       Set_Binds_And_Dml(l_dynamic_sql ,'TL');
8676 
8677       Debug_Msg('In Update_Row, l_dynamic_sql for TL table is as follows:', 3);
8678       Debug_SQL(FND_DSQL.Get_Text(TRUE));
8679 
8680       IF (p_execute_dml = FND_API.G_TRUE) THEN
8681         DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
8682         FND_DSQL.Set_Cursor(l_cursor_id);
8683         FND_DSQL.Do_Binds();
8684       END IF;
8685 
8686       --Start 4105841
8687       --Raise pre Event if not already raised
8688       IF (p_change_obj IS NULL) AND (l_pre_event_flag = 'F') THEN
8689         IF(p_raise_business_event) THEN
8690         Raise_WF_Event_If_Enabled(
8691             p_dml_type                      => 'UPDATE'
8692            ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
8693            ,p_extension_id                  => p_extension_id
8694            ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
8695            ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
8696            ,p_entity_id                     => p_entity_id
8697            ,p_entity_index                  => p_entity_index
8698            ,p_entity_code                   => p_entity_code
8699            ,p_pre_event_flag                => 'T'
8700            ,p_data_level_id                 => l_data_level_id
8701            ,px_attr_diffs                   => l_attr_diffs_event
8702           );
8703         l_pre_event_flag := 'T';
8704         END IF;
8705       END IF;
8706       --End 4105841
8707 
8708       IF (p_execute_dml = FND_API.G_TRUE) THEN
8709         l_number_of_rows := DBMS_SQL.Execute(l_cursor_id);
8710       END IF;
8711 
8712 
8713     END IF;
8714 
8715 
8716     ----------------------------------
8717     -- Finally, we close our cursor --
8718     ----------------------------------
8719     DBMS_SQL.Close_Cursor(l_cursor_id);
8720 
8721     --
8722     -- If caller passes multiple rows with same UK values, what should I do?
8723     -- Currently, I think they'll be treated as multiple instances of the same row,
8724     -- so the data for the last-loaded one will overwrite all previous data.
8725     -- I think that's OK.
8726     --
8727 
8728     IF (l_propagate_hierarchy
8729         AND p_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG = 'Y'
8730         AND px_attr_diffs.COUNT > 0 AND p_execute_dml = FND_API.G_TRUE) THEN --Bug fix 5220020
8731       Propagate_Attributes( p_pk_column_name_value_pairs
8732                           , p_class_code_name_value_pairs
8733                           , p_data_level_name_value_pairs
8734                           , px_attr_diffs
8735                           , G_UPDATE_MODE
8736                           , p_attr_group_metadata_obj
8737                           , x_return_status
8738                           , l_error_message);
8739     END IF;
8740     IF (x_return_status IN (G_RET_STS_ERROR, G_RET_STS_UNEXP_ERROR )) THEN
8741       fnd_message.set_name('EGO','EGO_GENERIC_MSG_TEXT');
8742       fnd_message.set_token('MESSAGE',l_error_message);
8743       fnd_msg_pub.Add;
8744       RETURN;
8745     END IF;
8746 
8747     --------------------------------------------------
8748     -- If we inserted into the production tables... --
8749     -- we see about raising a Business Event      --
8750     --------------------------------------------------
8751     IF (p_change_obj IS NULL) THEN
8752      IF(p_raise_business_event) THEN
8753       Raise_WF_Event_If_Enabled(
8754         p_dml_type                      => 'UPDATE'
8755        ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
8756        ,p_extension_id                  => p_extension_id
8757        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
8758        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
8759        ,p_entity_id                     => p_entity_id
8760        ,p_entity_index                  => p_entity_index
8761        ,p_entity_code                   => p_entity_code
8762        ,p_data_level_id                 => l_data_level_id
8763        ,px_attr_diffs                   => l_attr_diffs_event
8764       );
8765       END IF;
8766     END IF;
8767 
8768     Debug_Msg('In Update_Row, done', 1);
8769 
8770     IF FND_API.To_Boolean(p_commit) THEN
8771       COMMIT WORK;
8772     END IF;
8773 
8774     x_return_status := FND_API.G_RET_STS_SUCCESS;
8775 
8776   EXCEPTION
8777     -----------------------------------------------------------
8778     -- There are no expected errors in this procedure, so... --
8779     -----------------------------------------------------------
8780     --Start 4105841
8781     --Checking for Exception raised by preAttribute Change Event
8782     --don't put to the stack already added in EGO_WF_WRAPPER_PVT
8783     WHEN EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC THEN
8784       Debug_Msg('Update_Row EXCEPTION  EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC ');
8785 
8786       IF FND_API.To_Boolean(p_commit) THEN
8787         ROLLBACK TO update_row;
8788       END IF;
8789       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
8790     --End 4105841
8791 
8792     WHEN OTHERS THEN
8793       Debug_Msg('Update_Row EXCEPTION  others '||SQLERRM);
8794       IF FND_API.To_Boolean(p_commit) THEN
8795         ROLLBACK TO update_row;
8796       END IF;
8797       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
8798 
8799       DECLARE
8800         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
8801       BEGIN
8802         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
8803         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
8804         l_token_table(2).TOKEN_NAME := 'API_NAME';
8805         l_token_table(2).TOKEN_VALUE := l_api_name;
8806         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
8807         l_token_table(3).TOKEN_VALUE := SQLERRM;
8808 
8809         ERROR_HANDLER.Add_Error_Message(
8810           p_message_name      => 'EGO_PLSQL_ERR'
8811          ,p_application_id    => 'EGO'
8812          ,p_token_tbl         => l_token_table
8813          ,p_message_type      => FND_API.G_RET_STS_ERROR
8814          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
8815          ,p_entity_id         => p_entity_id
8816          ,p_entity_index      => p_entity_index
8817          ,p_entity_code       => p_entity_code
8818          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
8819         );
8820       END;
8821 
8822 END Update_Row;
8823 
8824 ----------------------------------------------------------------------
8825 PROCEDURE Delete_Row (
8826         p_api_version                   IN   NUMBER
8827        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
8828        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
8829        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
8830        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
8831        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
8832        ,p_extension_id                  IN   NUMBER
8833         -- Start ssingal -For Ucc Net Attribute Propagation
8834        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
8835        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
8836         -- End ssingal
8837        ,p_language_to_process           IN   VARCHAR2
8838        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ
8839        ,p_extra_pk_col_name_val_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
8840        ,p_pending_b_table_name          IN   VARCHAR2
8841        ,p_pending_tl_table_name         IN   VARCHAR2
8842        ,p_execute_dml                   IN   VARCHAR2   DEFAULT FND_API.G_TRUE
8843         -- Start ssingal -For Ucc Net Attribute Propagation
8844        ,p_bulkload_flag                 IN   BOOLEAN DEFAULT FALSE
8845        ,px_attr_diffs                   IN   OUT NOCOPY EGO_USER_ATTR_DIFF_TABLE
8846         -- End ssingal -For Ucc Net Attribute Propagation
8847        ,p_entity_id                     IN   VARCHAR2
8848        ,p_entity_index                  IN   NUMBER
8849        ,p_entity_code                   IN   VARCHAR2
8850        ,p_commit                        IN   VARCHAR2
8851        ,p_raise_business_event          IN   BOOLEAN DEFAULT TRUE
8852        ,x_return_status                 OUT  NOCOPY VARCHAR2
8853 ) IS
8854 
8855     l_api_name               CONSTANT VARCHAR2(30) := 'Delete_Row';
8856 
8857     --we don't use l_api_version yet, but eventually we might:
8858     --if we change required parameters, version goes FROM n.x to (n+1).x
8859     --if we change optional parameters, version goes FROM x.n to x.(n+1)
8860     l_api_version            CONSTANT NUMBER := 1.0;
8861 
8862     l_b_table_name           VARCHAR2(30);
8863     l_tl_table_name          VARCHAR2(30);
8864     l_change_col_where_string VARCHAR2(1000);
8865     l_dynamic_sql            VARCHAR2(1000);
8866     l_error_message          VARCHAR2(4000);
8867     l_event_name             VARCHAR2(240);
8868     l_is_event_enabled_flag  VARCHAR2(1);
8869     l_event_key              VARCHAR2(240);
8870     l_parameter_list         WF_PARAMETER_LIST_T := WF_PARAMETER_LIST_T();
8871     l_parameter_t            WF_PARAMETER_T:= WF_PARAMETER_T(null, null);
8872     -- Start ssingal -For Ucc Net Attribute Propagation
8873     l_propagate_hierarchy    BOOLEAN :=TRUE;
8874     -- End ssingal -For Ucc Net Attribute Propagation
8875     --Start 4105841
8876     l_attr_diffs_event       EGO_USER_ATTR_DIFF_TABLE;
8877     l_extra_col_where_string VARCHAR2(1000);
8878     l_index                  NUMBER;
8879     l_data_level_id          NUMBER;
8880 
8881   BEGIN
8882 
8883     Debug_Msg('In Delete_Row, starting', 1);
8884 
8885     IF FND_API.To_Boolean(p_commit) THEN
8886       SAVEPOINT delete_row;
8887     END IF;
8888 
8889     -- Check for call compatibility
8890     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
8891                                         l_api_name, G_PKG_NAME)
8892     THEN
8893       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8894     END IF;
8895 
8896     IF (p_extension_id IS NULL) THEN
8897       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8898     END IF;
8899     -- Start ssingal -For Ucc Net Attribute Propagation
8900     IF  p_bulkload_flag THEN
8901       l_propagate_hierarchy := FALSE;
8902     END IF;
8903 
8904     --Start 4105841
8905     Get_Changed_Attributes(
8906            p_dml_operation                 => 'DELETE'
8907          , p_object_name                   =>  null
8908          , p_pk_column_name_value_pairs    =>  p_pk_column_name_value_pairs
8909          , p_attr_group_metadata_obj       =>  p_attr_group_metadata_obj
8910          , p_ext_table_metadata_obj        =>  p_ext_table_metadata_obj
8911          , p_data_level                    =>  p_data_level
8912          , p_data_level_name_value_pairs   =>  p_data_level_name_value_pairs
8913          , p_attr_name_value_pairs         =>  p_attr_name_value_pairs
8914          , p_extension_id                  =>  p_extension_id
8915          , p_entity_id                     =>  p_entity_id
8916          , p_entity_index                  =>  p_entity_index
8917          , p_entity_code                   =>  p_entity_code
8918          , px_attr_diffs                   =>  l_attr_diffs_event);
8919     --End 4105841
8920 
8921    IF (l_propagate_hierarchy AND
8922         p_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG = 'Y'
8923        ) THEN
8924     --4105841 : Removing call to Get_Changed_Attributes as it's called before this check
8925        px_attr_diffs :=  l_attr_diffs_event;
8926      END IF;
8927 
8928     -- End ssingal -For Ucc Net Attribute Propagation
8929 
8930     --------------------------------------------------------------------------
8931     -- Determine whether we're in Change mode and set variables accordingly --
8932     --------------------------------------------------------------------------
8933 
8934     IF (p_change_obj IS NOT NULL AND
8935         p_pending_b_table_name IS NOT NULL AND
8936         p_pending_tl_table_name IS NOT NULL) THEN
8937 
8938       l_b_table_name := p_pending_b_table_name;
8939       l_tl_table_name := p_pending_tl_table_name;
8940       IF (p_change_obj.CHANGE_ID IS NOT NULL) THEN
8941         l_change_col_where_string := ' AND CHANGE_ID = '||p_change_obj.CHANGE_ID||' AND ';
8942       ELSE
8943         l_change_col_where_string := ' AND CHANGE_ID IS NULL AND ';
8944       END IF;
8945       IF (p_change_obj.CHANGE_LINE_ID IS NOT NULL) THEN
8946         l_change_col_where_string := l_change_col_where_string||
8947                                      'CHANGE_LINE_ID = '||
8948                                      p_change_obj.CHANGE_LINE_ID||' ';
8949       ELSE
8950         l_change_col_where_string := l_change_col_where_string||
8951                                      'CHANGE_LINE_ID IS NULL ';
8952       END IF;
8953     ELSE
8954 
8955       l_b_table_name := p_attr_group_metadata_obj.EXT_TABLE_B_NAME;
8956       l_tl_table_name := p_attr_group_metadata_obj.EXT_TABLE_TL_NAME;
8957       l_change_col_where_string := '';
8958 
8959     END IF;
8960 
8961     ------------------------------------------------------------------------------------------
8962     -- In case the extra pk columns values are passed we add them into the dml where clause
8963     ------------------------------------------------------------------------------------------
8964 
8965     l_extra_col_where_string := ' ';
8966 
8967     IF (p_extra_pk_col_name_val_pairs IS NOT NULL AND
8968         p_extra_pk_col_name_val_pairs.COUNT > 0) THEN
8969 
8970       l_index := p_extra_pk_col_name_val_pairs.FIRST;
8971       WHILE (l_index IS NOT NULL)
8972       LOOP
8973 
8974         IF (p_extra_pk_col_name_val_pairs(l_index).NAME IS NOT NULL) THEN
8975            l_extra_col_where_string := l_extra_col_where_string || ' AND ';
8976            IF (p_extra_pk_col_name_val_pairs(l_index).VALUE IS NOT NULL) THEN
8977               l_extra_col_where_string := l_extra_col_where_string || p_extra_pk_col_name_val_pairs(l_index).NAME || ' = '
8978                                                                    ||  p_extra_pk_col_name_val_pairs(l_index).VALUE ;
8979            ELSE
8980               l_extra_col_where_string := l_extra_col_where_string || p_extra_pk_col_name_val_pairs(l_index).NAME || ' IS  NULL ';
8981            END IF;
8982         END IF;
8983         l_index := p_extra_pk_col_name_val_pairs.NEXT(l_index);
8984 
8985       END LOOP;
8986 
8987     END IF;
8988 
8989     -------------------------------------------------------------------------------
8990     -- In case the p_pending_b_table_name and p_pending_tl_table_name are passed
8991     -- we will use them.
8992     -------------------------------------------------------------------------------
8993     IF (p_pending_b_table_name IS NOT NULL) THEN
8994         l_b_table_name := p_pending_b_table_name;
8995         l_tl_table_name := p_pending_tl_table_name;
8996     END IF;
8997 
8998     l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
8999                                          ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
9000                                          ,p_data_level);
9001 
9002     ---------------------------------------------------------------
9003     -- We pass p_language_to_process from Implement_Change_Line; --
9004     -- if we have it, then we only delete from the base table if --
9005     -- the passed-in language is equal to USERENV('LANG') and we --
9006     -- only delete the TL row for that language.                 --
9007     -- Otherwise we delete from both tables normally.            --
9008     ---------------------------------------------------------------
9009     IF (p_language_to_process IS NULL OR
9010         p_language_to_process = USERENV('LANG')) THEN
9011       l_dynamic_sql := 'DELETE FROM '||l_b_table_name||
9012                        ' WHERE EXTENSION_ID = '||p_extension_id||l_change_col_where_string||l_extra_col_where_string;
9013 
9014       Debug_SQL(l_dynamic_sql);
9015       --Start 4105841 Raise Pre event
9016       IF (p_change_obj IS NULL) THEN
9017        IF(p_raise_business_event) THEN
9018         Raise_WF_Event_If_Enabled(
9019           p_dml_type                      => 'DELETE'
9020          ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9021          ,p_extension_id                  => p_extension_id
9022          ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9023          ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9024          ,p_entity_id                     => p_entity_id
9025          ,p_entity_index                  => p_entity_index
9026          ,p_entity_code                   => p_entity_code
9027          ,p_pre_event_flag                => 'T'
9028          ,p_data_level_id                 => l_data_level_id
9029          ,px_attr_diffs                   => l_attr_diffs_event
9030         );
9031         END IF;
9032       END IF;
9033       --End 4105841
9034 
9035       Set_Binds_And_Dml(l_dynamic_sql ,'B');
9036 
9037       IF (p_execute_dml = FND_API.G_TRUE) THEN
9038         EXECUTE IMMEDIATE l_dynamic_sql;
9039       END IF;
9040     END IF;
9041 
9042     IF (l_tl_table_name IS NOT NULL) THEN
9043 
9044       l_dynamic_sql := 'DELETE FROM '||l_tl_table_name||
9045                        ' WHERE EXTENSION_ID = '||p_extension_id||l_change_col_where_string||l_extra_col_where_string;
9046 
9047       -----------------------------------------------------------------
9048       -- We pass p_language_to_process from Implement_Change_Line so --
9049       -- that each pending TL row only deletes one production row    --
9050       -----------------------------------------------------------------
9051       IF (p_language_to_process IS NOT NULL) THEN
9052         FND_DSQL.Add_Text(' AND LANGUAGE = ');
9053         Add_Bind(p_value => p_language_to_process);
9054       END IF;
9055     END IF;
9056 
9057     Debug_SQL(l_dynamic_sql);
9058 
9059     Set_Binds_And_Dml(l_dynamic_sql ,'TL');
9060 
9061     IF (p_execute_dml = FND_API.G_TRUE) THEN
9062       EXECUTE IMMEDIATE l_dynamic_sql;
9063     END IF;
9064     -- Start ssingal -For Ucc Net Attribute Propagation
9065 
9066     -- Only propagate if at least one attribute has EIH code = LP/AP
9067     IF (l_propagate_hierarchy AND
9068         p_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG = 'Y'
9069         AND px_attr_diffs.COUNT > 0  AND p_execute_dml = FND_API.G_TRUE) THEN --Bug fix 5220020
9070 
9071       Propagate_Attributes( p_pk_column_name_value_pairs
9072                           , p_class_code_name_value_pairs
9073                           , p_data_level_name_value_pairs
9074                           , px_attr_diffs
9075                           , G_DELETE_MODE
9076                           , p_attr_group_metadata_obj
9077                           , x_return_status
9078                           , l_error_message);
9079     END IF;
9080     -- End ssingal -For Ucc Net Attribute Propagation
9081     IF (x_return_status IN (G_RET_STS_ERROR, G_RET_STS_UNEXP_ERROR )) THEN
9082       fnd_message.set_name('EGO','EGO_GENERIC_MSG_TEXT');
9083       fnd_message.set_token('MESSAGE',l_error_message);
9084       fnd_msg_pub.Add;
9085       RETURN;
9086     END IF;
9087 
9088     -------------------------------------------------
9089     -- If we deleted from the production tables... --
9090     -- we see about raising a Business Event      --
9091     -------------------------------------------------
9092     IF (p_change_obj IS NULL) THEN
9093       IF(p_raise_business_event) THEN
9094       Raise_WF_Event_If_Enabled(
9095         p_dml_type                      => 'DELETE'
9096        ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9097        ,p_extension_id                  => p_extension_id
9098        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9099        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9100        ,p_entity_id                     => p_entity_id
9101        ,p_entity_index                  => p_entity_index
9102        ,p_entity_code                   => p_entity_code
9103        ,p_data_level_id                 => l_data_level_id
9104        ,px_attr_diffs                   => l_attr_diffs_event
9105       );
9106       END IF;
9107     END IF;
9108 
9109     Debug_Msg('In Delete_Row, done', 1);
9110 
9111     IF FND_API.To_Boolean(p_commit) THEN
9112       COMMIT WORK;
9113     END IF;
9114 
9115     x_return_status := FND_API.G_RET_STS_SUCCESS;
9116 
9117   EXCEPTION
9118     -----------------------------------------------------------
9119     -- There are no expected errors in this procedure, so... --
9120     -----------------------------------------------------------
9121     --Start 4105841
9122     --Checking for Exception raised by preAttribute Change Event
9123     --don't put to the stack already added in EGO_WF_WRAPPER_PVT
9124     WHEN EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC THEN
9125       Debug_Msg('Delete_Row EXCEPTION  EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC ');
9126 
9127       IF FND_API.To_Boolean(p_commit) THEN
9128         ROLLBACK TO delete_row;
9129       END IF;
9130       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
9131     --End 4105841
9132     WHEN OTHERS THEN
9133       Debug_Msg('Delete_Row EXCEPTION  others '||SQLERRM);
9134       IF FND_API.To_Boolean(p_commit) THEN
9135         ROLLBACK TO delete_row;
9136       END IF;
9137       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
9138 
9139       DECLARE
9140         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
9141       BEGIN
9142         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
9143         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
9144         l_token_table(2).TOKEN_NAME := 'API_NAME';
9145         l_token_table(2).TOKEN_VALUE := l_api_name;
9146         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
9147         l_token_table(3).TOKEN_VALUE := SQLERRM;
9148 
9149         ERROR_HANDLER.Add_Error_Message(
9150           p_message_name      => 'EGO_PLSQL_ERR'
9151          ,p_application_id    => 'EGO'
9152          ,p_token_tbl         => l_token_table
9153          ,p_message_type      => FND_API.G_RET_STS_ERROR
9154          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9155          ,p_entity_id         => p_entity_id
9156          ,p_entity_index      => p_entity_index
9157          ,p_entity_code       => p_entity_code
9158          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9159         );
9160       END;
9161 
9162 END Delete_Row;
9163 
9164 ----------------------------------------------------------------------
9165 
9166 PROCEDURE Validate_Row_Pvt (
9167         p_api_version                   IN   NUMBER
9168        ,p_object_id                     IN   NUMBER
9169        ,p_validate_hierarchy            IN   VARCHAR2   DEFAULT FND_API.G_TRUE --Added for bugFix:5275391
9170        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
9171        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
9172        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9173        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9174        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
9175        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9176        ,p_extension_id                  IN   NUMBER
9177        ,p_mode                          IN   VARCHAR2
9178        ,p_entity_id                     IN   VARCHAR2   DEFAULT NULL
9179        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
9180        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
9181        ,px_attr_name_value_pairs        IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
9182        ,x_return_status                 OUT NOCOPY VARCHAR2
9183 ) IS
9184 
9185     l_api_name               CONSTANT VARCHAR2(30) := 'Validate_Row_Pvt';
9186 
9187     --we don't use l_api_version yet, but eventually we might:
9188     --if we change required parameters, version goes FROM n.x to (n+1).x
9189     --if we change optional parameters, version goes FROM x.n to x.(n+1)
9190     l_api_version            CONSTANT NUMBER := 1.0;
9191 
9192     l_is_valid_row           BOOLEAN := TRUE;
9193     l_err_msg_name           VARCHAR2(30);
9194     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
9195     l_is_duplicate_attr      BOOLEAN;
9196     l_duplicate_attr_index   NUMBER;
9197     l_attr_value_index       NUMBER;
9198     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
9199     l_attr_name_table        LOCAL_VARCHAR_TABLE;
9200     l_hierarchy_results      LOCAL_HIERARCHY_REC;
9201 
9202   BEGIN
9203 
9204     Debug_Msg(l_api_name || ' starting', 1);
9205 
9206     -- Check for call compatibility
9207     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
9208                                         l_api_name, G_PKG_NAME)
9209     THEN
9210       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9211     END IF;
9212 
9213     Debug_Msg(l_api_name || ' calling Is_Data_Level_Correct ', 1);
9214     IF (NOT Is_Data_Level_Correct(
9215               p_object_id                     => p_object_id
9216              ,p_attr_group_id                 => p_attr_group_metadata_obj.ATTR_GROUP_ID
9217              ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9218              ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9219              ,p_data_level                    => p_data_level
9220              ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9221              ,p_attr_group_disp_name          => p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME
9222              ,x_err_msg_name                  => l_err_msg_name
9223              ,x_token_table                   => l_token_table)
9224        ) THEN
9225 
9226       ERROR_HANDLER.Add_Error_Message(
9227         p_message_name      => l_err_msg_name
9228        ,p_application_id    => 'EGO'
9229        ,p_token_tbl         => l_token_table
9230        ,p_message_type      => FND_API.G_RET_STS_ERROR
9231        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9232        ,p_entity_id         => p_entity_id
9233        ,p_entity_index      => p_entity_index
9234        ,p_entity_code       => p_entity_code
9235        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9236       );
9237 
9238       l_token_table.DELETE();
9239 
9240       l_is_valid_row := FALSE;
9241 
9242       Debug_Msg(l_api_name || ' l_is_valid_row is now FALSE ', 1);
9243 
9244     END IF;
9245     Debug_Msg(l_api_name || ' returned Is_Data_Level_Correct ', 1);
9246 
9247 IF px_attr_name_value_pairs.COUNT > 0 THEN
9248     Debug_Msg(l_api_name || ' px_attr_name_value_pairs has values', 1);
9249 ELSE
9250     Debug_Msg(l_api_name || ' px_attr_name_value_pairs IS NULL!! ', 1);
9251 END IF;
9252     l_attr_value_index := px_attr_name_value_pairs.FIRST;
9253     WHILE (l_attr_value_index <= px_attr_name_value_pairs.LAST)
9254     LOOP
9255 
9256       l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
9257                                p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table
9258                               ,p_attr_name           => px_attr_name_value_pairs(l_attr_value_index).ATTR_NAME
9259                              );
9260 
9261       ---------------------------------------------------------------------------
9262       -- First we check whether we have already processed this Attribute.  The --
9263       -- caller may have passed multiple values for the same Attribute, which  --
9264       -- is an error, and we also don't want to spend time validating the same --
9265       -- Attribute more than once.                                             --
9266       ---------------------------------------------------------------------------
9267       l_is_duplicate_attr := FALSE;
9268       IF (l_attr_name_table.COUNT > 0) THEN
9269         l_duplicate_attr_index := l_attr_name_table.FIRST;
9270         WHILE (l_duplicate_attr_index <= l_attr_name_table.LAST)
9271         LOOP
9272           EXIT WHEN (l_is_duplicate_attr);
9273           IF (l_attr_metadata_obj.ATTR_NAME = l_attr_name_table(l_duplicate_attr_index)) THEN
9274             l_is_duplicate_attr := TRUE;
9275           END IF;
9276           l_duplicate_attr_index := l_attr_name_table.NEXT(l_duplicate_attr_index);
9277         END LOOP;
9278       END IF;
9279 
9280       IF (l_is_duplicate_attr) THEN
9281 
9282         l_err_msg_name := 'EGO_EF_MULT_VALUES_FOR_ATTR';
9283 
9284         l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
9285         l_token_table(1).TOKEN_VALUE := l_attr_metadata_obj.ATTR_DISP_NAME;
9286         l_token_table(2).TOKEN_NAME := 'AG_NAME';
9287         l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
9288 
9289             Debug_Msg(l_api_name ||'Adding '||l_err_msg_name||' to error table for row '||px_attr_name_value_pairs(px_attr_name_value_pairs.FIRST).ROW_IDENTIFIER);
9290 
9291         ERROR_HANDLER.Add_Error_Message(
9292           p_message_name      => l_err_msg_name
9293          ,p_application_id    => 'EGO'
9294          ,p_token_tbl         => l_token_table
9295          ,p_message_type      => FND_API.G_RET_STS_ERROR
9296          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9297          ,p_entity_id         => p_entity_id
9298          ,p_entity_index      => p_entity_index
9299          ,p_entity_code       => p_entity_code
9300          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9301         );
9302 
9303         l_token_table.DELETE();
9304 
9305         l_is_valid_row := FALSE;
9306 
9307             Debug_Msg(l_api_name ||'l_is_valid_row is now FALSE', 1);
9308 
9309       ELSE
9310 
9311         ----------------------------------------------------------------------
9312         -- Add the Internal Name for checking against subsequent Attributes --
9313         ----------------------------------------------------------------------
9314         l_attr_name_table(l_attr_name_table.COUNT+1) := l_attr_metadata_obj.ATTR_NAME;
9315 
9316         ---------------------------------------------------------------------------
9317         -- If the Attribute is marked as Required and the mode is G_CREATE_MODE, --
9318         -- then the user must pass a value for the Attribute                     --
9319         ---------------------------------------------------------------------------
9320             Debug_Msg(l_api_name ||' loop '||l_attr_value_index||', checking required flag');
9321 
9322         IF (NOT Is_Required_Flag_Respected(l_attr_metadata_obj
9323                                           ,p_mode
9324                                           ,px_attr_name_value_pairs(l_attr_value_index)
9325                                           ,p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME
9326                                           ,l_err_msg_name
9327                                           ,l_token_table)) THEN
9328 
9329           Debug_Msg(l_api_name ||'Adding '||l_err_msg_name||' to error table for row '||px_attr_name_value_pairs(px_attr_name_value_pairs.FIRST).ROW_IDENTIFIER);
9330 
9331           ERROR_HANDLER.Add_Error_Message(
9332             p_message_name      => l_err_msg_name
9333            ,p_application_id    => 'EGO'
9334            ,p_token_tbl         => l_token_table
9335            ,p_message_type      => FND_API.G_RET_STS_ERROR
9336            ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9337            ,p_entity_id         => p_entity_id
9338            ,p_entity_index      => p_entity_index
9339            ,p_entity_code       => p_entity_code
9340            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9341           );
9342 
9343           l_token_table.DELETE();
9344 
9345           l_is_valid_row := FALSE;
9346 
9347           Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
9348 
9349         END IF;
9350 
9351         ---------------------------------------------------------------------------
9352         -- The user must pass a value of the correct data type for the Attribute --
9353         ---------------------------------------------------------------------------
9354             Debug_Msg(l_api_name ||' loop '||l_attr_value_index||', checking data type');
9355 
9356         IF (NOT Is_Data_Type_Correct(l_attr_metadata_obj
9357                                     ,px_attr_name_value_pairs(l_attr_value_index)
9358                                     ,p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME
9359                                     ,l_err_msg_name
9360                                     ,l_token_table)) THEN
9361 
9362           Debug_Msg(l_api_name ||'Adding '||l_err_msg_name||' to error table for row '||px_attr_name_value_pairs(px_attr_name_value_pairs.FIRST).ROW_IDENTIFIER);
9363 
9364           ERROR_HANDLER.Add_Error_Message(
9365             p_message_name      => l_err_msg_name
9366            ,p_application_id    => 'EGO'
9367            ,p_token_tbl         => l_token_table
9368            ,p_message_type      => FND_API.G_RET_STS_ERROR
9369            ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9370            ,p_entity_id         => p_entity_id
9371            ,p_entity_index      => p_entity_index
9372            ,p_entity_code       => p_entity_code
9373            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9374           );
9375 
9376           l_token_table.DELETE();
9377 
9378           l_is_valid_row := FALSE;
9379 
9380           Debug_Msg(l_api_name ||'l_is_valid_row is now FALSE', 1);
9381 
9382         END IF;
9383 
9384         -------------------------------------------------------------------------
9385         -- Some Attributes have a maximum allowable size; we enforce that here --
9386         -------------------------------------------------------------------------
9387             Debug_Msg(l_api_name ||' loop '||l_attr_value_index||', checking max size');
9388 
9389         IF (NOT Is_Max_Size_Respected(l_attr_metadata_obj
9390                                      ,px_attr_name_value_pairs(l_attr_value_index)
9391                                      ,p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME
9392                                      ,l_err_msg_name
9393                                      ,l_token_table)) THEN
9394 
9395           Debug_Msg(l_api_name ||'Adding '||l_err_msg_name||' to error table for row '||px_attr_name_value_pairs(px_attr_name_value_pairs.FIRST).ROW_IDENTIFIER);
9396 
9397           ERROR_HANDLER.Add_Error_Message(
9398             p_message_name      => l_err_msg_name
9399            ,p_application_id    => 'EGO'
9400            ,p_token_tbl         => l_token_table
9401            ,p_message_type      => FND_API.G_RET_STS_ERROR
9402            ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9403            ,p_entity_id         => p_entity_id
9404            ,p_entity_index      => p_entity_index
9405            ,p_entity_code       => p_entity_code
9406            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9407           );
9408 
9409           l_token_table.DELETE();
9410 
9411           l_is_valid_row := FALSE;
9412 
9413           Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
9414 
9415         END IF;
9416 
9417         -------------------------------------------------------------------
9418         -- If the Attribute has a Unit Of Measure, we need to process it --
9419         -------------------------------------------------------------------
9420             Debug_Msg(l_api_name ||' loop '||l_attr_value_index||', processing UOM');
9421 
9422         IF (NOT Is_UOM_Valid(l_attr_metadata_obj
9423                             ,px_attr_name_value_pairs(l_attr_value_index))) THEN
9424 
9425           l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
9426           l_token_table(1).TOKEN_VALUE := l_attr_metadata_obj.ATTR_DISP_NAME;
9427 
9428           l_token_table(2).TOKEN_NAME := 'UOM_CLASS';
9429           l_token_table(2).TOKEN_VALUE := l_attr_metadata_obj.UNIT_OF_MEASURE_CLASS;
9430 
9431           l_err_msg_name := 'EGO_EF_UOM_NOT_IN_UOM_CLASS';
9432 
9433           Debug_Msg(l_api_name ||'Adding '||l_err_msg_name||' to error table for row '||px_attr_name_value_pairs(px_attr_name_value_pairs.FIRST).ROW_IDENTIFIER);
9434 
9435           ERROR_HANDLER.Add_Error_Message(
9436             p_message_name      => l_err_msg_name
9437            ,p_application_id    => 'EGO'
9438            ,p_token_tbl         => l_token_table
9439            ,p_message_type      => FND_API.G_RET_STS_ERROR
9440            ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9441            ,p_entity_id         => p_entity_id
9442            ,p_entity_index      => p_entity_index
9443            ,p_entity_code       => p_entity_code
9444            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9445           );
9446 
9447           l_token_table.DELETE();
9448 
9449           l_is_valid_row := FALSE;
9450 
9451               Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
9452 
9453         END IF;
9454 
9455         --------------------------------------------------------------
9456         -- Finally, we check all user-defined Value Set constraints --
9457         -- (We log errors in this function itself rather than here) --
9458         --------------------------------------------------------------
9459         Debug_Msg(l_api_name ||' loop '||l_attr_value_index||', checking Value Set');
9460 
9461         IF (NOT Is_Value_Set_Respected(l_attr_metadata_obj
9462                                       ,p_attr_group_metadata_obj
9463                                       ,p_ext_table_metadata_obj
9464                                       ,p_pk_column_name_value_pairs
9465                                       ,p_data_level_name_value_pairs
9466                                       ,p_entity_id
9467                                       ,p_entity_index
9468                                       ,p_entity_code
9469                                       ,px_attr_name_value_pairs
9470                                       ,px_attr_name_value_pairs(l_attr_value_index))) THEN
9471 
9472           l_is_valid_row := FALSE;
9473 
9474           Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
9475 
9476         END IF;
9477 
9478         -------------------------------------------------------------------------
9479         -- Check if hierarchy security flags prevent the current changes from
9480         -- being made.
9481         -------------------------------------------------------------------------
9482 
9483         IF (FND_API.To_Boolean(p_validate_hierarchy) AND--Added for bugFix:5275391
9484             NOT (l_attr_metadata_obj.EDIT_IN_HIERARCHY_CODE = 'A' OR
9485                  l_attr_metadata_obj.EDIT_IN_HIERARCHY_CODE = 'AP')
9486            ) THEN
9487           -- Get is_root/is_leaf
9488           l_hierarchy_results :=
9489             Get_Hierarchy_For_AG_Type(p_attr_group_metadata_obj.ATTR_GROUP_TYPE
9490                                      ,p_pk_column_name_value_pairs);
9491 
9492           -- Compare results of hierarchy query to vih/eih modes
9493           IF (l_attr_metadata_obj.EDIT_IN_HIERARCHY_CODE = 'R' OR
9494               l_attr_metadata_obj.EDIT_IN_HIERARCHY_CODE = 'RP') THEN
9495 
9496             IF (l_hierarchy_results.IS_ROOT_NODE <> 'Y') THEN
9497 
9498               -- ERROR!  TODO: handle this correctly
9499               l_err_msg_name := 'HIERARCHY SECURITY VALIDATION';
9500               Debug_Msg(l_api_name ||'Adding '||l_err_msg_name||' to error table for row '||px_attr_name_value_pairs(px_attr_name_value_pairs.FIRST).ROW_IDENTIFIER);
9501 
9502               ERROR_HANDLER.Add_Error_Message(
9503                 p_message_name      => l_err_msg_name
9504                ,p_application_id    => 'EGO'
9505                ,p_token_tbl         => l_token_table
9506                ,p_message_type      => FND_API.G_RET_STS_ERROR
9507                ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9508                ,p_entity_id         => p_entity_id
9509                ,p_entity_index      => p_entity_index
9510                ,p_entity_code       => p_entity_code
9511                ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9512               );
9513 
9514               l_token_table.DELETE();
9515               l_is_valid_row := FALSE;
9516               Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
9517 
9518             END IF;
9519 
9520           ELSIF (l_attr_metadata_obj.EDIT_IN_HIERARCHY_CODE = 'L' OR
9521                  l_attr_metadata_obj.EDIT_IN_HIERARCHY_CODE = 'LP') THEN
9522 
9523             IF (l_hierarchy_results.IS_LEAF_NODE <> 'Y') THEN
9524 
9525               -- ERROR!  TODO: handle this correctly
9526               l_err_msg_name := 'HIERARCHY SECURITY VALIDATION';
9527               Debug_Msg(l_api_name ||'Adding '||l_err_msg_name||' to error table for row '||px_attr_name_value_pairs(px_attr_name_value_pairs.FIRST).ROW_IDENTIFIER);
9528 
9529               ERROR_HANDLER.Add_Error_Message(
9530                 p_message_name      => l_err_msg_name
9531                ,p_application_id    => 'EGO'
9532                ,p_token_tbl         => l_token_table
9533                ,p_message_type      => FND_API.G_RET_STS_ERROR
9534                ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9535                ,p_entity_id         => p_entity_id
9536                ,p_entity_index      => p_entity_index
9537                ,p_entity_code       => p_entity_code
9538                ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9539               );
9540 
9541               l_token_table.DELETE();
9542 
9543               l_is_valid_row := FALSE;
9544 
9545               Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
9546 
9547             END IF;
9548 
9549           END IF;
9550 
9551         END IF;
9552 
9553       END IF;
9554 
9555       l_attr_value_index := px_attr_name_value_pairs.NEXT(l_attr_value_index);
9556     END LOOP;
9557 
9558     -------------------------------------------------------------------------
9559     -- Finally, if the mode is 'CREATE', we want to check whether the user --
9560     -- failed to pass any required Attributes.  If we find a non-passed    --
9561     -- required Attribute, we check whether it has a default value: if so, --
9562     -- we build an Attribute data object for it and add it to our list of  --
9563     -- Attr values, but if not we raise an error for each missing required --
9564     -- Attribute (these errors are logged in the function itself).         --
9565     -------------------------------------------------------------------------
9566     IF (p_mode = G_CREATE_MODE AND
9567         NOT Verify_All_Required_Attrs(l_attr_name_table
9568                                      ,p_attr_group_metadata_obj.attr_metadata_table
9569                                      ,p_entity_id
9570                                      ,p_entity_index
9571                                      ,p_entity_code
9572                                      ,p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME
9573                                      ,px_attr_name_value_pairs)) THEN
9574 
9575       l_is_valid_row := FALSE;
9576 
9577       Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
9578 
9579     END IF;
9580 
9581     Debug_Msg(l_api_name ||' done', 1);
9582 
9583     IF (NOT l_is_valid_row) THEN
9584 
9585       RAISE FND_API.G_EXC_ERROR;
9586 
9587     END IF;
9588 
9589 -----------------------------------
9590 
9591     x_return_status := FND_API.G_RET_STS_SUCCESS;
9592 
9593   EXCEPTION
9594     WHEN FND_API.G_EXC_ERROR THEN
9595       Debug_Msg(l_api_name ||' EXCEPTION FND_API.G_EXC_ERROR  raised ', 1);
9596       x_return_status := FND_API.G_RET_STS_ERROR;
9597 
9598     WHEN OTHERS THEN
9599       Debug_Msg(l_api_name ||' EXCEPTION OTHERS  raised '||SQLERRM, 1);
9600       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
9601 
9602       l_token_table.DELETE();
9603       l_token_table(1).TOKEN_NAME := 'PKG_NAME';
9604       l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
9605       l_token_table(2).TOKEN_NAME := 'API_NAME';
9606       l_token_table(2).TOKEN_VALUE := l_api_name;
9607       l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
9608       l_token_table(3).TOKEN_VALUE := SQLERRM;
9609 
9610       ERROR_HANDLER.Add_Error_Message(
9611         p_message_name      => 'EGO_PLSQL_ERR'
9612        ,p_application_id    => 'EGO'
9613        ,p_token_tbl         => l_token_table
9614        ,p_message_type      => FND_API.G_RET_STS_ERROR
9615        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9616        ,p_entity_id         => p_entity_id
9617        ,p_entity_index      => p_entity_index
9618        ,p_entity_code       => p_entity_code
9619        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9620       );
9621 
9622 END Validate_Row_Pvt;
9623 
9624 ----------------------------------------------------------------------
9625 
9626 PROCEDURE Perform_DML_On_Row_Pvt (
9627         p_api_version                   IN   NUMBER
9628        ,p_object_id                     IN   NUMBER
9629        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
9630        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
9631        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9632        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9633        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
9634        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9635        ,p_extension_id                  IN   NUMBER
9636        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
9637        ,p_language_to_process           IN   VARCHAR2   DEFAULT NULL
9638        ,p_mode                          IN   VARCHAR2
9639        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
9640        ,p_extra_pk_col_name_val_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
9641        ,p_extra_attr_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
9642        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
9643        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT NULL
9644        ,p_execute_dml                   IN   VARCHAR2   DEFAULT FND_API.G_TRUE
9645        ,p_entity_id                     IN   VARCHAR2   DEFAULT NULL
9646        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
9647        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
9648        ,p_commit                        IN   VARCHAR2
9649        ,p_bulkload_flag                 IN   BOOLEAN    DEFAULT FALSE
9650        ,p_raise_business_event          IN   BOOLEAN    DEFAULT TRUE
9651        ,x_extension_id                  OUT NOCOPY NUMBER
9652        ,x_return_status                 OUT NOCOPY VARCHAR2
9653 ) IS
9654 
9655     l_api_name               CONSTANT VARCHAR2(30) := 'Perform_DML_On_Row_Pvt';
9656 
9657     --we don't use l_api_version yet, but eventually we might:
9658     --if we change required parameters, version goes FROM n.x to (n+1).x
9659     --if we change optional parameters, version goes FROM x.n to x.(n+1)
9660     l_api_version            CONSTANT NUMBER := 1.0;
9661     l_attr_diffs             EGO_USER_ATTR_DIFF_TABLE := EGO_USER_ATTR_DIFF_TABLE();
9662 
9663   BEGIN
9664 
9665     Debug_Msg(l_api_name || ' starting with p_data_level '||p_data_level, 1);
9666 
9667     IF FND_API.To_Boolean(p_commit) THEN
9668       SAVEPOINT Perform_DML_On_Row_PVT;
9669     END IF;
9670 
9671     -- Check for call compatibility
9672     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
9673                                         l_api_name, G_PKG_NAME)
9674     THEN
9675       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9676     END IF;
9677 
9678     IF (p_mode = G_CREATE_MODE) THEN
9679       Insert_Row(
9680         p_api_version                   => p_api_version
9681        ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9682        ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9683        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9684        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9685        ,p_data_level                    => p_data_level
9686        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9687        ,p_extension_id                  => p_extension_id
9688        ,p_attr_name_value_pairs         => p_attr_name_value_pairs
9689        ,p_language_to_process           => p_language_to_process
9690        ,p_change_obj                    => p_change_obj
9691        ,p_extra_pk_col_name_val_pairs   => p_extra_pk_col_name_val_pairs
9692        ,p_extra_attr_name_value_pairs   => p_extra_attr_name_value_pairs
9693        ,p_pending_b_table_name          => p_pending_b_table_name
9694        ,p_pending_tl_table_name         => p_pending_tl_table_name
9695        ,p_execute_dml                   => p_execute_dml
9696        ,p_entity_id                     => p_entity_id
9697        ,p_entity_index                  => p_entity_index
9698        ,p_entity_code                   => p_entity_code
9699        ,p_commit                        => FND_API.G_FALSE
9700        ,p_bulkload_flag                 => p_bulkload_flag
9701        ,px_attr_diffs                   => l_attr_diffs
9702        ,p_raise_business_event          => p_raise_business_event
9703        ,x_extension_id                  => x_extension_id
9704        ,x_return_status                 => x_return_status
9705       );
9706     ELSIF (p_mode = G_UPDATE_MODE) THEN
9707       Update_Row(
9708         p_api_version                   => p_api_version
9709        ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9710        ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9711        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9712        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9713        ,p_data_level                    => p_data_level
9714        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9715        ,p_extension_id                  => p_extension_id
9716        ,p_attr_name_value_pairs         => p_attr_name_value_pairs
9717        ,p_language_to_process           => p_language_to_process
9718        ,p_change_obj                    => p_change_obj
9719        ,p_extra_pk_col_name_val_pairs   => p_extra_pk_col_name_val_pairs
9720        ,p_extra_attr_name_value_pairs   => p_extra_attr_name_value_pairs
9721        ,p_pending_b_table_name          => p_pending_b_table_name
9722        ,p_pending_tl_table_name         => p_pending_tl_table_name
9723        ,p_execute_dml                   => p_execute_dml
9724        ,p_entity_id                     => p_entity_id
9725        ,p_entity_index                  => p_entity_index
9726        ,p_entity_code                   => p_entity_code
9727        ,p_commit                        => FND_API.G_FALSE
9728        ,p_bulkload_flag                 => p_bulkload_flag
9729        ,px_attr_diffs                   => l_attr_diffs
9730        ,p_raise_business_event          => p_raise_business_event
9731        ,x_return_status                 => x_return_status
9732       );
9733     ELSIF (p_mode = G_DELETE_MODE) THEN -- mode must be G_DELETE_MODE
9734       Delete_Row(
9735         p_api_version                   => p_api_version
9736        ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9737        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9738        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9739        ,p_data_level                    => p_data_level
9740        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9741        ,p_extension_id                  => p_extension_id
9742        ,p_attr_name_value_pairs         => p_attr_name_value_pairs
9743        ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9744        ,p_language_to_process           => p_language_to_process
9745        ,p_change_obj                    => p_change_obj
9746        ,p_extra_pk_col_name_val_pairs   => p_extra_pk_col_name_val_pairs
9747        ,p_pending_b_table_name          => p_pending_b_table_name
9748        ,p_pending_tl_table_name         => p_pending_tl_table_name
9749        ,p_execute_dml                   => p_execute_dml
9750        ,p_bulkload_flag                 => p_bulkload_flag
9751        ,px_attr_diffs                   => l_attr_diffs
9752        ,p_entity_id                     => p_entity_id
9753        ,p_entity_index                  => p_entity_index
9754        ,p_entity_code                   => p_entity_code
9755        ,p_commit                        => FND_API.G_FALSE
9756        ,p_raise_business_event          => p_raise_business_event
9757        ,x_return_status                 => x_return_status
9758       );
9759     ELSE
9760       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9761 
9762     END IF;
9763 
9764     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9765       RAISE FND_API.G_EXC_ERROR;
9766     END IF;
9767 
9768     IF(x_extension_id IS NULL AND p_extension_id IS NOT NULL ) THEN
9769        x_extension_id := p_extension_id;
9770     END IF;
9771 
9772     IF FND_API.To_Boolean(p_commit) THEN
9773       COMMIT WORK;
9774     END IF;
9775 
9776     x_return_status := FND_API.G_RET_STS_SUCCESS;
9777     Debug_Msg( l_api_name || ' ending ', 1);
9778 
9779   EXCEPTION
9780     WHEN FND_API.G_EXC_ERROR THEN
9781       Debug_Msg( l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR ', 1);
9782       IF FND_API.To_Boolean(p_commit) THEN
9783         ROLLBACK TO Perform_DML_On_Row_PVT;
9784       END IF;
9785       -----------------------------------------------------------
9786       -- If we get here, then the nested API call (whichever   --
9787       -- it was) must have failed; that call will have already --
9788       -- initialized the relevant out parameters.              --
9789       -----------------------------------------------------------
9790 
9791     WHEN OTHERS THEN
9792       Debug_Msg( l_api_name || ' EXCEPTION OTHERS '||SQLERRM, 1);
9793       IF FND_API.To_Boolean(p_commit) THEN
9794         ROLLBACK TO Perform_DML_On_Row_PVT;
9795       END IF;
9796       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
9797 
9798       DECLARE
9799         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
9800       BEGIN
9801         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
9802         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
9803         l_token_table(2).TOKEN_NAME := 'API_NAME';
9804         l_token_table(2).TOKEN_VALUE := l_api_name;
9805         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
9806         l_token_table(3).TOKEN_VALUE := SQLERRM;
9807 
9808         ERROR_HANDLER.Add_Error_Message(
9809           p_message_name      => 'EGO_PLSQL_ERR'
9810          ,p_application_id    => 'EGO'
9811          ,p_token_tbl         => l_token_table
9812          ,p_message_type      => FND_API.G_RET_STS_ERROR
9813          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9814          ,p_entity_id         => p_entity_id
9815          ,p_entity_index      => p_entity_index
9816          ,p_entity_code       => p_entity_code
9817          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9818         );
9819       END;
9820 
9821 END Perform_DML_On_Row_Pvt;
9822 
9823 ----------------------------------------------------------------------
9824 -- private procedure
9825 ----------------------------------------------------------------------
9826 PROCEDURE Perform_DML_On_Template_Row (
9827         p_object_id                     IN   NUMBER
9828        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
9829        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
9830        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9831        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9832        ,p_data_level                    IN   VARCHAR2
9833        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9834        ,p_commit                        IN   VARCHAR2
9835        ,px_attr_name_value_pairs        IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
9836 ) IS
9837 
9838     l_api_name               VARCHAR2(50) := 'Perform_DML_On_Template_Row';
9839     l_extension_id           NUMBER;
9840     l_dummy_ext_id           NUMBER;
9841     l_mode                   VARCHAR2(10);
9842     l_return_status          VARCHAR2(1);
9843 
9844   BEGIN
9845     Debug_Msg(l_api_name || ' starting ',1);
9846     -------------------------------------------------------------------------------
9847     -- If an Attribute in this Attribute Group has a "Table" Value Set that uses --
9848     -- bind values, we will have to sort the name/value pairs table so that the  --
9849     -- upcoming calls to Get_Int_Val_For_Disp_Val all behave as they should      --
9850     -------------------------------------------------------------------------------
9851     IF (p_attr_group_metadata_obj.SORT_ATTR_VALUES_FLAG = 'Y') THEN
9852       Sort_Attr_Values_Table(p_attr_group_metadata_obj
9853                             ,px_attr_name_value_pairs);
9854     END IF;
9855 
9856     -----------------------------------------------------------------------
9857     -- We now make sure we are dealing with only the internal values for --
9858     -- all Attributes (this is important to do before looking for the    --
9859     -- extension ID because we may need Unique Key Attribute internal    --
9860     -- values to perform the extension ID search)                        --
9861     -----------------------------------------------------------------------
9862     Debug_Msg(l_api_name || ' calling Generate_Attr_Int_Values ',1);
9863     Generate_Attr_Int_Values(
9864       p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9865      ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9866      ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9867      ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9868      ,px_attr_name_value_pairs        => px_attr_name_value_pairs
9869      ,x_return_status                 => l_return_status
9870                             );
9871     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9872       RAISE FND_API.G_EXC_ERROR;
9873     END IF;
9874 
9875     --------------------------------------------------
9876     -- Find out whether we're inserting or updating --
9877     -- (and check for Unique Key violations)        --
9878     --------------------------------------------------
9879     Debug_Msg(l_api_name || ' calling Get_Extension_Id_And_Mode ',1);
9880     Get_Extension_Id_And_Mode(
9881       p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9882      ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9883      ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9884      ,p_data_level                    => p_data_level
9885      ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9886      ,p_attr_name_value_pairs         => px_attr_name_value_pairs
9887      ,x_extension_id                  => l_extension_id
9888      ,x_mode                          => l_mode
9889      ,x_return_status                 => l_return_status
9890                              );
9891     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9892       RAISE FND_API.G_EXC_ERROR;
9893     END IF;
9894 
9895     ----------------------------------------------------------------------
9896     -- Validate the current collection of Attribute values prior to DML --
9897     ----------------------------------------------------------------------
9898     Debug_Msg(l_api_name || ' calling Validate_Row_Pvt ',1);
9899     Validate_Row_Pvt(
9900       p_api_version                   => 1.0
9901      ,p_object_id                     => p_object_id
9902      ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9903      ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9904      ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9905      ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9906      ,p_data_level                    => p_data_level
9907      ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9908      ,p_extension_id                  => l_extension_id
9909      ,p_mode                          => l_mode
9910      ,px_attr_name_value_pairs        => px_attr_name_value_pairs
9911      ,x_return_status                 => l_return_status
9912                     );
9913     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9914       RAISE FND_API.G_EXC_ERROR;
9915     END IF;
9916 
9917     -----------------------------------------------------
9918     -- If the row is valid, either insert or update it --
9919     -----------------------------------------------------
9920     Debug_Msg(l_api_name || ' calling Perform_DML_On_Row_Pvt ',1);
9921     Perform_DML_On_Row_Pvt(
9922       p_api_version                   => 1.0
9923      ,p_object_id                     => p_object_id
9924      ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9925      ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9926      ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9927      ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9928      ,p_data_level                    => p_data_level
9929      ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9930      ,p_extension_id                  => l_extension_id
9931      ,p_attr_name_value_pairs         => px_attr_name_value_pairs
9932      ,p_mode                          => l_mode
9933      ,p_commit                        => p_commit
9934      ,x_extension_id                  => l_dummy_ext_id
9935      ,x_return_status                 => l_return_status
9936                           );
9937     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9938       RAISE FND_API.G_EXC_ERROR;
9939     END IF;
9940     Debug_Msg(l_api_name || ' ending ',1);
9941 
9942 END Perform_DML_On_Template_Row;
9943 
9944 ----------------------------------------------------------------------
9945 
9946 PROCEDURE Perform_Setup_Operations (
9947         p_object_name                   IN  VARCHAR2
9948        ,p_attr_group_id                 IN  NUMBER
9949        ,p_application_id                IN  NUMBER
9950        ,p_attr_group_type               IN  VARCHAR2
9951        ,p_attr_group_name               IN  VARCHAR2
9952        ,p_pk_column_name_value_pairs    IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
9953        ,p_class_code_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
9954        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
9955        ,p_data_level_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
9956        ,p_extension_id                  IN  NUMBER
9957        ,p_entity_id                     IN  VARCHAR2
9958        ,p_entity_index                  IN  NUMBER
9959        ,p_entity_code                   IN  VARCHAR2
9960        ,p_debug_level                   IN  NUMBER     DEFAULT 0
9961        ,p_add_errors_to_fnd_stack       IN  VARCHAR2
9962        ,p_use_def_vals_on_insert_flag   IN  BOOLEAN    DEFAULT FALSE
9963        ,p_init_fnd_msg_list             IN  VARCHAR2
9964        ,p_mode                          IN  VARCHAR2
9965        ,p_change_obj                    IN  EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
9966        ,p_extra_pk_col_name_val_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
9967        ,p_pending_b_table_name          IN  VARCHAR2   DEFAULT NULL
9968        ,p_pending_vl_name               IN  VARCHAR2   DEFAULT NULL
9969        ,p_bulkload_flag                 IN  BOOLEAN    DEFAULT FALSE
9970        ,px_object_id                    IN OUT NOCOPY NUMBER
9971        ,px_attr_name_value_pairs        IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
9972        ,x_attr_group_metadata_obj       OUT NOCOPY EGO_ATTR_GROUP_METADATA_OBJ
9973        ,x_ext_table_metadata_obj        OUT NOCOPY EGO_EXT_TABLE_METADATA_OBJ
9974        ,x_extension_id                  OUT NOCOPY NUMBER
9975        ,x_mode                          OUT NOCOPY VARCHAR2
9976        ,x_return_status                 OUT NOCOPY VARCHAR2
9977 ) IS
9978 
9979     l_api_name               CONSTANT VARCHAR2(30) := 'Perform_Setup_Operations';
9980     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
9981     l_err_msg_name           VARCHAR2(30);
9982 
9983   BEGIN
9984 
9985     Debug_Msg(l_api_name || ' starting', 2);
9986 
9987     ------------------------------------------------------------------------
9988     -- We need to record which row number we are processing so we can log --
9989     -- error messages appropriately.  We need to use a global variable to --
9990     -- handle the case where p_attr_name_value_pairs is NULL or empty     --
9991     ------------------------------------------------------------------------
9992     IF (px_attr_name_value_pairs IS NULL OR px_attr_name_value_pairs.COUNT = 0) THEN
9993       G_USER_ROW_IDENTIFIER := 1;
9994     ELSE
9995       G_USER_ROW_IDENTIFIER := px_attr_name_value_pairs(px_attr_name_value_pairs.FIRST).USER_ROW_IDENTIFIER;
9996     END IF;
9997 
9998     ---------------------------------------------------------------------------
9999     -- If G_BULK_PROCESSING_FLAG has not been set to true, then we're coming --
10000     -- from the UI and we haven't yet set up our Business Object session     --
10001     ---------------------------------------------------------------------------
10002     IF (NOT G_BULK_PROCESSING_FLAG) THEN
10003 
10004       Debug_Msg(l_api_name || ' before Set_Up_Business_Object_Session ', 2);
10005       Set_Up_Business_Object_Session(
10006           p_bulkload_flag                 => p_bulkload_flag
10007          ,p_entity_id                     => p_entity_id
10008          ,p_entity_index                  => p_entity_index
10009          ,p_entity_code                   => p_entity_code
10010          ,p_debug_level                   => p_debug_level
10011          ,p_init_error_handler_flag       => (p_debug_level > 0)
10012          ,p_object_name                   => p_object_name
10013          ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
10014          ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
10015          ,p_init_fnd_msg_list             => p_init_fnd_msg_list
10016          ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
10017          ,p_use_def_vals_on_insert_flag   => p_use_def_vals_on_insert_flag
10018          ,x_return_status                 => x_return_status
10019       );
10020       Debug_Msg(l_api_name || ' done Set_Up_Business_Object_Session: '||x_return_status, 2);
10021       ----------------------------------------------------------------------
10022       -- If an error was found, we've already added it to the error stack --
10023       ----------------------------------------------------------------------
10024       IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
10025 
10026         RAISE FND_API.G_EXC_ERROR;
10027 
10028       END IF;
10029     END IF;
10030 
10031     IF (px_object_id IS NULL) THEN
10032       px_object_id := Get_Object_Id_From_Name(p_object_name);
10033     END IF;
10034 
10035     x_attr_group_metadata_obj :=
10036       EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(p_attr_group_id
10037                                                        ,p_application_id
10038                                                        ,p_attr_group_type
10039                                                        ,p_attr_group_name);
10040     Debug_Msg(l_api_name || ' before validations:  p_attr_group_id-'||p_attr_group_id||
10041                             ' p_application_id-'||p_application_id ||
10042                             ' p_attr_group_type-'||p_attr_group_type||
10043                             ' p_attr_group_name-'||p_attr_group_name);
10044 
10045     ------------------------------------------------------
10046     -- We check for the possibility that we didn't find --
10047     -- the metadata to correctly process this row       --
10048     ------------------------------------------------------
10049     IF (x_attr_group_metadata_obj IS NULL) THEN
10050 
10051       IF (p_application_id IS NOT NULL AND
10052           p_attr_group_type IS NOT NULL AND
10053           p_attr_group_name IS NOT NULL) THEN
10054 
10055         l_err_msg_name := 'EGO_EF_ATTR_GROUP_PK_NOT_FOUND';
10056 
10057         l_token_table(1).TOKEN_NAME := 'APP_ID';
10058         l_token_table(1).TOKEN_VALUE := p_application_id;
10059         l_token_table(2).TOKEN_NAME := 'AG_TYPE';
10060         l_token_table(2).TOKEN_VALUE := p_attr_group_type;
10061         l_token_table(3).TOKEN_NAME := 'AG_NAME';
10062         l_token_table(3).TOKEN_VALUE := p_attr_group_name;
10063 
10064       ELSE
10065 
10066         l_err_msg_name := 'EGO_EF_ATTR_GROUP_ID_NOT_FOUND';
10067 
10068         l_token_table(1).TOKEN_NAME := 'AG_ID';
10069         l_token_table(1).TOKEN_VALUE := p_attr_group_id;
10070 
10071       END IF;
10072 
10073       ERROR_HANDLER.Add_Error_Message(
10074         p_message_name      => l_err_msg_name
10075        ,p_application_id    => 'EGO'
10076        ,p_token_tbl         => l_token_table
10077        ,p_message_type      => FND_API.G_RET_STS_ERROR
10078        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
10079        ,p_entity_id         => p_entity_id
10080        ,p_entity_index      => p_entity_index
10081        ,p_entity_code       => p_entity_code
10082        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
10083       );
10084      Debug_Msg(l_api_name || 'before raising exception 0 ');
10085       RAISE FND_API.G_EXC_ERROR;
10086 
10087     ELSIF (NOT Do_All_Attrs_Exist(x_attr_group_metadata_obj
10088                                  ,px_attr_name_value_pairs
10089                                  ,p_entity_id
10090                                  ,p_entity_index
10091                                  ,p_entity_code)) THEN
10092 
10093       ----------------------------------------------------------------
10094       -- We've logged an error for every Attr that we couldn't find --
10095       ----------------------------------------------------------------
10096      Debug_Msg(l_api_name || 'before raising exception 1 ');
10097       RAISE FND_API.G_EXC_ERROR;
10098 
10099     END IF;
10100 
10101     x_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(px_object_id);
10102     IF (x_ext_table_metadata_obj IS NULL) THEN
10103 
10104       l_token_table.DELETE();
10105       l_token_table(1).TOKEN_NAME := 'OBJECT_NAME';
10106       l_token_table(1).TOKEN_VALUE := p_object_name;
10107 
10108       ERROR_HANDLER.Add_Error_Message(
10109         p_message_name      => 'EGO_EF_EXT_TABLE_METADATA_ERR'
10110        ,p_application_id    => 'EGO'
10111        ,p_token_tbl         => l_token_table
10112        ,p_message_type      => FND_API.G_RET_STS_ERROR
10113        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
10114        ,p_entity_id         => p_entity_id
10115        ,p_entity_index      => p_entity_index
10116        ,p_entity_code       => p_entity_code
10117        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
10118       );
10119      Debug_Msg(l_api_name || 'before raising exception 2 ');
10120 
10121       RAISE FND_API.G_EXC_ERROR;
10122 
10123     END IF;
10124 
10125     -------------------------------------------------------------------------------
10126     -- If an Attribute in this Attribute Group has a "Table" Value Set that uses --
10127     -- bind values, we will have to sort the name/value pairs table so that the  --
10128     -- upcoming calls to Get_Int_Val_For_Disp_Val all behave as they should      --
10129     -------------------------------------------------------------------------------
10130     IF (x_attr_group_metadata_obj.SORT_ATTR_VALUES_FLAG = 'Y') THEN
10131 
10132       Sort_Attr_Values_Table(x_attr_group_metadata_obj
10133                             ,px_attr_name_value_pairs);
10134 
10135     END IF;
10136 Debug_Msg(l_api_name || 'before Generate_Attr_Int_Values ');
10137     --------------------------------------------------------------------------------------
10138     -- We now make sure we are dealing with only the internal values for all Attributes --
10139     -- (this is important to do before looking for the extension ID because we may need --
10140     -- Unique Key Attribute internal values to perform the extension ID search)         --
10141     --------------------------------------------------------------------------------------
10142     Generate_Attr_Int_Values(
10143         p_attr_group_metadata_obj      => x_attr_group_metadata_obj
10144        ,p_ext_table_metadata_obj       => x_ext_table_metadata_obj
10145        ,p_pk_column_name_value_pairs   => p_pk_column_name_value_pairs
10146        ,p_data_level_name_value_pairs  => p_data_level_name_value_pairs
10147        ,p_entity_id                    => p_entity_id
10148        ,p_entity_index                 => p_entity_index
10149        ,p_entity_code                  => p_entity_code
10150        ,px_attr_name_value_pairs       => px_attr_name_value_pairs
10151        ,x_return_status                => x_return_status);
10152 
10153 Debug_Msg(l_api_name || 'done Generate_Attr_Int_Values: '||x_return_status);
10154     ------------------------------------------------------------
10155     -- If errors were found in processing the display values, --
10156     -- we've already added them to the error stack            --
10157     ------------------------------------------------------------
10158     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
10159       RAISE FND_API.G_EXC_ERROR;
10160     END IF;
10161 
10162     --------------------------------------------------------------------
10163     -- Now we determine whether we're creating, updating or deleting, --
10164     -- what the Extension ID is in the latter two cases, and whether  --
10165     -- our data violates any Unique Key constraints                   --
10166     --------------------------------------------------------------------
10167     Get_Extension_Id_And_Mode(
10168       p_attr_group_metadata_obj       => x_attr_group_metadata_obj
10169      ,p_ext_table_metadata_obj        => x_ext_table_metadata_obj
10170      ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
10171      ,p_data_level                    => p_data_level
10172      ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
10173      ,p_attr_name_value_pairs         => px_attr_name_value_pairs
10174      ,p_extension_id                  => p_extension_id
10175      ,p_mode                          => p_mode
10176      ,p_change_obj                    => p_change_obj
10177      ,p_extra_pk_col_name_val_pairs   => p_extra_pk_col_name_val_pairs
10178      ,p_pending_b_table_name          => p_pending_b_table_name
10179      ,p_pending_vl_name               => p_pending_vl_name
10180      ,p_entity_id                     => p_entity_id
10181      ,p_entity_index                  => p_entity_index
10182      ,p_entity_code                   => p_entity_code
10183      ,x_extension_id                  => x_extension_id
10184      ,x_mode                          => x_mode
10185      ,x_return_status                 => x_return_status
10186     );
10187     -----------------------------------------------------
10188     -- If errors were found in the previous procedure, --
10189     -- we've already added them to the error stack     --
10190     -----------------------------------------------------
10191     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
10192       RAISE FND_API.G_EXC_ERROR;
10193     END IF;
10194 
10195     Debug_Msg(l_api_name || ' after checking, x_mode is '||x_mode);
10196     IF (UPPER(x_mode) = G_UPDATE_MODE OR UPPER(x_mode) = G_DELETE_MODE) THEN
10197       Debug_Msg(l_api_name || ' after checking, x_extension_id is '||x_extension_id);
10198     END IF;
10199 
10200     Debug_Msg(l_api_name || ' done', 2);
10201 
10202   EXCEPTION
10203     WHEN FND_API.G_EXC_ERROR THEN
10204       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR', 1);
10205       x_return_status := FND_API.G_RET_STS_ERROR;
10206 
10207     WHEN OTHERS THEN
10208       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM, 1);
10209       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
10210       l_token_table.DELETE();
10211       l_token_table(1).TOKEN_NAME := 'PKG_NAME';
10212       l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
10213       l_token_table(2).TOKEN_NAME := 'API_NAME';
10214       l_token_table(2).TOKEN_VALUE := l_api_name;
10215       l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
10216       l_token_table(3).TOKEN_VALUE := SQLERRM;
10217 
10218       ERROR_HANDLER.Add_Error_Message(
10219         p_message_name      => 'EGO_PLSQL_ERR'
10220        ,p_application_id    => 'EGO'
10221        ,p_token_tbl         => l_token_table
10222        ,p_message_type      => FND_API.G_RET_STS_ERROR
10223        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
10224        ,p_entity_id         => p_entity_id
10225        ,p_entity_index      => p_entity_index
10226        ,p_entity_code       => p_entity_code
10227        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
10228       );
10229 
10230 END Perform_Setup_Operations;
10231 
10232 ----------------------------------------------------------------------
10233 
10234 
10235 
10236                       -----------------------
10237                       -- Public Procedures --
10238                       -----------------------
10239 
10240 ----------------------------------------------------------------------
10241 
10242 PROCEDURE Process_User_Attrs_Data (
10243         p_api_version                   IN   NUMBER
10244        ,p_object_name                   IN   VARCHAR2
10245        ,p_attributes_row_table          IN   EGO_USER_ATTR_ROW_TABLE
10246        ,p_attributes_data_table         IN   EGO_USER_ATTR_DATA_TABLE
10247        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
10248        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
10249        ,p_user_privileges_on_object     IN   EGO_VARCHAR_TBL_TYPE DEFAULT NULL
10250        ,p_change_info_table             IN   EGO_USER_ATTR_CHANGE_TABLE DEFAULT NULL
10251        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT  NULL
10252        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT  NULL
10253        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT  NULL
10254        ,p_entity_id                     IN   NUMBER     DEFAULT  NULL
10255        ,p_entity_index                  IN   NUMBER     DEFAULT  NULL
10256        ,p_entity_code                   IN   VARCHAR2   DEFAULT  NULL
10257        ,p_debug_level                   IN   NUMBER     DEFAULT  0
10258        ,p_validate_only                 IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10259        ,p_validate_hierarchy            IN   VARCHAR2   DEFAULT  FND_API.G_TRUE
10260        ,p_init_error_handler            IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10261        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10262        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10263        ,p_log_errors                    IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10264        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10265        ,p_commit                        IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10266        ,p_raise_business_event          IN   BOOLEAN    DEFAULT  TRUE
10267        ,x_failed_row_id_list            OUT NOCOPY VARCHAR2
10268        ,x_return_status                 OUT NOCOPY VARCHAR2
10269        ,x_errorcode                     OUT NOCOPY NUMBER
10270        ,x_msg_count                     OUT NOCOPY NUMBER
10271        ,x_msg_data                      OUT NOCOPY VARCHAR2
10272 ) IS
10273     l_extension_id           NUMBER;
10274     l_mode                   VARCHAR2(10);
10275 
10276 BEGIN
10277 
10278     Process_User_Attrs_Data
10279     (
10280         p_api_version                   => p_api_version
10281        ,p_object_name                   => p_object_name
10282        ,p_attributes_row_table          => p_attributes_row_table
10283        ,p_attributes_data_table         => p_attributes_data_table
10284        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
10285        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
10286        ,p_user_privileges_on_object     => p_user_privileges_on_object
10287        ,p_entity_id                     => p_entity_id
10288        ,p_entity_index                  => p_entity_index
10289        ,p_entity_code                   => p_entity_code
10290        ,p_debug_level                   => p_debug_level
10291        ,p_validate_only                 => p_validate_only  --bug 5122295
10292        ,p_validate_hierarchy            => p_validate_hierarchy
10293        ,p_init_error_handler            => p_init_error_handler
10294        ,p_write_to_concurrent_log       => p_write_to_concurrent_log
10295        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
10296        ,p_log_errors                    => p_log_errors
10297        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
10298        ,p_commit                        => p_commit
10299        ,p_raise_business_event          => p_raise_business_event
10300        ,x_extension_id                  => l_extension_id
10301        ,x_mode                          => l_mode
10302        ,x_failed_row_id_list            => x_failed_row_id_list
10303        ,x_return_status                 => x_return_status
10304        ,x_errorcode                     => x_errorcode
10305        ,x_msg_count                     => x_msg_count
10306        ,x_msg_data                      => x_msg_data
10307     );
10308 
10309 END;
10310 -------------------------------------------------------------------------------
10311 
10312 PROCEDURE Process_User_Attrs_Data (
10313         p_api_version                   IN   NUMBER
10314        ,p_object_name                   IN   VARCHAR2
10315        ,p_attributes_row_table          IN   EGO_USER_ATTR_ROW_TABLE
10316        ,p_attributes_data_table         IN   EGO_USER_ATTR_DATA_TABLE
10317        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
10318        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
10319        ,p_user_privileges_on_object     IN   EGO_VARCHAR_TBL_TYPE DEFAULT NULL
10320        ,p_change_info_table             IN   EGO_USER_ATTR_CHANGE_TABLE DEFAULT NULL
10321        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT  NULL
10322        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT  NULL
10323        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT  NULL
10324        ,p_entity_id                     IN   NUMBER     DEFAULT  NULL
10325        ,p_entity_index                  IN   NUMBER     DEFAULT  NULL
10326        ,p_entity_code                   IN   VARCHAR2   DEFAULT  NULL
10327        ,p_debug_level                   IN   NUMBER     DEFAULT  0
10328        ,p_validate_only                 IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10329        ,p_validate_hierarchy            IN   VARCHAR2   DEFAULT  FND_API.G_TRUE
10330        ,p_init_error_handler            IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10331        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10332        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10333        ,p_log_errors                    IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10334        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10335        ,p_commit                        IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
10336        ,p_raise_business_event          IN   BOOLEAN    DEFAULT  TRUE
10337        ,x_extension_id                  OUT NOCOPY NUMBER
10338        ,x_mode                          OUT NOCOPY VARCHAR2
10339        ,x_failed_row_id_list            OUT NOCOPY VARCHAR2
10340        ,x_return_status                 OUT NOCOPY VARCHAR2
10341        ,x_errorcode                     OUT NOCOPY NUMBER
10342        ,x_msg_count                     OUT NOCOPY NUMBER
10343        ,x_msg_data                      OUT NOCOPY VARCHAR2
10344 ) IS
10345 
10346     l_api_name               CONSTANT VARCHAR2(30) := 'Process_User_Attrs_Data';
10347 
10348     --we don't use l_api_version yet, but eventually we might:
10349     --if we change required parameters, version goes FROM n.x to (n+1).x
10350     --if we change optional parameters, version goes FROM x.n to x.(n+1)
10351     l_api_version            CONSTANT NUMBER := 1.0;
10352 
10353     l_default_user_row_id    NUMBER;
10354     l_sorted_attr_data_table LOCAL_USER_ATTR_DATA_TABLE;
10355     l_sorted_attr_row_table  LOCAL_USER_ATTR_ROW_TABLE;
10356     l_sorted_row_table_index NUMBER;
10357     l_current_row_element    EGO_USER_ATTR_ROW_OBJ;
10358     l_mode                   VARCHAR2(10);
10359     l_sorted_data_table_index NUMBER;
10360     l_got_all_attrs_for_this_row BOOLEAN := FALSE;
10361     l_current_data_element   EGO_USER_ATTR_DATA_OBJ;
10362     l_next_row_id            NUMBER;
10363     l_row_attrs_table        EGO_USER_ATTR_DATA_TABLE;
10364     l_data_level_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
10365     l_current_row_change_obj EGO_USER_ATTR_CHANGE_OBJ;
10366     l_return_status          VARCHAR2(1);
10367     l_errorcode              NUMBER;
10368     l_msg_count              NUMBER;
10369     l_msg_data               VARCHAR2(1000);
10370     l_data_level_id          NUMBER;
10371     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
10372 
10373 l_dummy_row       EGO_USER_ATTR_ROW_OBJ;
10374   BEGIN
10375 
10376     Debug_Msg(l_api_name || ' starting', 1);
10377 
10378     -- Check for call compatibility
10379     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
10380                                         l_api_name, G_PKG_NAME)
10381     THEN
10382       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
10383     END IF;
10384 
10385     --------------------------------------------------------------------------------
10386     -- Start by dealing with caching, error-handling, and preliminary validations --
10387     --------------------------------------------------------------------------------
10388     IF (p_attributes_data_table IS NOT NULL AND
10389         p_attributes_data_table.COUNT > 0) THEN
10390       l_default_user_row_id := p_attributes_data_table(p_attributes_data_table.FIRST).USER_ROW_IDENTIFIER;
10391     ELSE
10392       l_default_user_row_id := 0;
10393     END IF;
10394 
10395     Set_Up_Business_Object_Session(
10396         p_bulkload_flag                 => TRUE
10397        ,p_user_privileges_on_object     => p_user_privileges_on_object
10398        ,p_entity_id                     => p_entity_id
10399        ,p_entity_index                  => p_entity_index
10400        ,p_entity_code                   => p_entity_code
10401        ,p_debug_level                   => p_debug_level
10402        ,p_init_error_handler_flag       => FND_API.To_Boolean(p_init_error_handler)
10403        ,p_object_name                   => p_object_name
10404        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
10405        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
10406        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
10407        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
10408        ,p_default_user_row_identifier   => l_default_user_row_id
10409        ,x_return_status                 => x_return_status
10410     );
10411 
10412     ----------------------------------------------------------------------
10413     -- If an error was found, we've already added it to the error stack --
10414     ----------------------------------------------------------------------
10415     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
10416 
10417       --------------------------------------------------
10418       -- Mark every row in this instance as a failure --
10419       --------------------------------------------------
10420       FOR r IN p_attributes_row_table.FIRST .. p_attributes_row_table.LAST
10421       LOOP
10422 
10423         x_failed_row_id_list := x_failed_row_id_list ||
10424                                 p_attributes_row_table(r).ROW_IDENTIFIER || ',';
10425 
10426       END LOOP;
10427 
10428       ------------------------------------------------------------------
10429       -- Trim the trailing ',' from x_failed_row_id_list if necessary --
10430       ------------------------------------------------------------------
10431       x_failed_row_id_list := RTRIM(x_failed_row_id_list, ',');
10432 
10433       RAISE FND_API.G_EXC_ERROR;
10434     END IF;
10435 
10436     ---------------------------------------------------------------
10437     -- If we pass the preliminary tests, we can process the data --
10438     ---------------------------------------------------------------
10439     l_sorted_attr_data_table := Build_Sorted_Data_Table(p_attributes_data_table);
10440     l_sorted_attr_row_table := Build_Sorted_Row_Table(p_attributes_row_table);
10441 
10442     l_sorted_row_table_index := l_sorted_attr_row_table.FIRST;
10443     WHILE (l_sorted_row_table_index <= l_sorted_attr_row_table.LAST)
10444     LOOP
10445 Debug_Msg('1 in the loop ');
10446 
10447       ----------------------------------------------
10448       -- Initialize local variables for each loop --
10449       ----------------------------------------------
10450       l_got_all_attrs_for_this_row := FALSE;
10451       l_return_status := NULL;
10452       l_errorcode := NULL;
10453       l_msg_count := 0;
10454       l_msg_data := NULL;
10455       l_current_row_element := l_sorted_attr_row_table(l_sorted_row_table_index);
10456       l_mode := UPPER(l_current_row_element.TRANSACTION_TYPE);
10457 
10458       -----------------------------------------------------------
10459       -- Either make a new table or clear out the existing one --
10460       -----------------------------------------------------------
10461       IF (l_row_attrs_table IS NULL) THEN
10462         l_row_attrs_table := EGO_USER_ATTR_DATA_TABLE();
10463       ELSE
10464         l_row_attrs_table.DELETE();
10465       END IF;
10466 
10467       --------------------------------------------------------------------------
10468       -- If it's our first time through, initialize l_sorted_data_table_index --
10469       -- (for subsequent loops we want it to retain its current value so we   --
10470       -- can continue to step through the data table bit by bit in each loop) --
10471       --------------------------------------------------------------------------
10472       IF (l_sorted_data_table_index IS NULL) THEN
10473         l_sorted_data_table_index := l_sorted_attr_data_table.FIRST;
10474       END IF;
10475 
10476       --------------------------------------------------------------------------
10477       -- Step through the table collecting all Attr Data objects for this row --
10478       --------------------------------------------------------------------------
10479       WHILE (l_sorted_data_table_index <= l_sorted_attr_data_table.LAST)
10480       LOOP
10481         EXIT WHEN (l_got_all_attrs_for_this_row);
10482 
10483         l_current_data_element := l_sorted_attr_data_table(l_sorted_data_table_index);
10484         IF (l_current_data_element.ROW_IDENTIFIER = l_current_row_element.ROW_IDENTIFIER) THEN
10485 
10486           ---------------------------------------------------
10487           -- Add the current Attr Data object to the table --
10488           ---------------------------------------------------
10489           l_row_attrs_table.EXTEND();
10490           l_row_attrs_table(l_row_attrs_table.LAST()) := l_current_data_element;
10491 
10492           ---------------------------------------
10493           -- Update the index for another loop --
10494           ---------------------------------------
10495           l_sorted_data_table_index := l_sorted_attr_data_table.NEXT(l_sorted_data_table_index);
10496 
10497         ELSE
10498 
10499           ------------------------------------------------------------
10500           -- In this case we don't want to update the index because --
10501           -- the current index already belongs to the next row      --
10502           ------------------------------------------------------------
10503           l_got_all_attrs_for_this_row := TRUE;
10504 
10505         END IF;
10506       END LOOP;
10507 
10508       ---------------------------------------------------------------
10509       -- Try to get the change info for this row (if there is any) --
10510       ---------------------------------------------------------------
10511       IF (p_change_info_table IS NOT NULL AND
10512           p_change_info_table.EXISTS(l_current_row_element.ROW_IDENTIFIER)) THEN
10513         l_current_row_change_obj := p_change_info_table(l_current_row_element.ROW_IDENTIFIER);
10514       ELSE
10515         l_current_row_change_obj := NULL;
10516       END IF;
10517 Debug_Msg('10 AGID-'||l_current_row_element.ATTR_GROUP_ID);
10518       ---------------------------------------------------------
10519       -- At this point we have all the Attr Data objects for --
10520       -- this row, and we'll be ready to call Process_Row as --
10521       -- soon as we create a Data Level array for the row    --
10522       ---------------------------------------------------------
10523 
10524       l_data_level_id := Get_Data_Level_Id( l_current_row_element.ATTR_GROUP_APP_ID
10525                                            ,l_current_row_element.ATTR_GROUP_TYPE
10526                                            ,l_current_row_element.DATA_LEVEL);
10527 Debug_Msg('11 ');
10528 
10529       l_data_level_name_value_pairs :=
10530              Build_Data_Level_Array(p_object_name    => p_object_name
10531                                    ,p_data_level_id  => l_data_level_id
10532                                    ,p_data_level_1   => l_current_row_element.DATA_LEVEL_1
10533                                    ,p_data_level_2   => l_current_row_element.DATA_LEVEL_2
10534                                    ,p_data_level_3   => l_current_row_element.DATA_LEVEL_3
10535                                    ,p_data_level_4   => l_current_row_element.DATA_LEVEL_4
10536                                    ,p_data_level_5   => l_current_row_element.DATA_LEVEL_5
10537                                     );
10538 Debug_Msg('12 ');
10539 
10540 
10541     Debug_Msg(l_api_name || ' calling Process_Row ', 1);
10542 Debug_Msg(l_api_name ||  ' l_current_row_element.ATTR_GROUP_ID '||l_current_row_element.ATTR_GROUP_ID);
10543 Debug_Msg(l_api_name ||  ' l_current_row_element.DATA_LEVEL '||l_current_row_element.DATA_LEVEL );
10544 IF l_data_level_name_value_pairs IS NOT NULL THEN
10545   FOR i IN l_data_level_name_value_pairs.FIRST .. l_data_level_name_value_pairs.LAST
10546   LOOP
10547      Debug_Msg(l_api_name || ' NAME: '|| l_data_level_name_value_pairs(i).NAME || ' VALUE: '||l_data_level_name_value_pairs(i).VALUE) ;
10548   END LOOP;
10549 END IF;
10550 IF l_row_attrs_table IS NOT NULL AND l_row_attrs_table.COUNT > 0 THEN
10551   FOR i in l_row_attrs_table.FIRST .. l_row_attrs_table.LAST
10552   LOOP
10553     Debug_Msg(l_api_name || ' DATA_LEVEL: '|| i);
10554 --    Debug_Msg(l_api_name || ' ATTR_GROUP_NAME: '|| l_row_attrs_table(i).ATTR_GROUP_NAME || ' DATA_LEVEL: '||l_row_attrs_table(i).DATA_LEVEL);
10555   END LOOP;
10556 END IF;
10557 
10558       Process_Row(
10559         p_api_version                   => 1.0
10560        ,p_object_name                   => p_object_name
10561        ,p_attr_group_id                 => l_current_row_element.ATTR_GROUP_ID
10562        ,p_application_id                => l_current_row_element.ATTR_GROUP_APP_ID
10563        ,p_attr_group_type               => l_current_row_element.ATTR_GROUP_TYPE
10564        ,p_attr_group_name               => l_current_row_element.ATTR_GROUP_NAME
10565        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
10566        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
10567        ,p_data_level                    => l_current_row_element.DATA_LEVEL
10568        ,p_data_level_name_value_pairs   => l_data_level_name_value_pairs
10569        ,p_attr_name_value_pairs         => l_row_attrs_table
10570        ,p_validate_only                 => p_validate_only
10571        ,p_validate_hierarchy            => p_validate_hierarchy
10572        ,p_mode                          => l_mode
10573        ,p_change_obj                    => l_current_row_change_obj
10574        ,p_pending_b_table_name          => p_pending_b_table_name
10575        ,p_pending_tl_table_name         => p_pending_tl_table_name
10576        ,p_pending_vl_name               => p_pending_vl_name
10577        ,p_entity_id                     => p_entity_id
10578        ,p_entity_index                  => p_entity_index
10579        ,p_entity_code                   => p_entity_code
10580        ,p_raise_business_event          => p_raise_business_event
10581        ,x_extension_id                  => x_extension_id
10582        ,x_mode                          => x_mode
10583        ,x_return_status                 => l_return_status
10584        ,x_errorcode                     => l_errorcode
10585        ,x_msg_count                     => l_msg_count
10586        ,x_msg_data                      => l_msg_data
10587       );
10588 
10589       Debug_Msg(l_api_name || ' after processing row '||
10590                 l_current_row_element.ROW_IDENTIFIER||' in mode '||l_mode||
10591                 ', l_msg_data is '||l_msg_data||', l_return_status is '||
10592                 l_return_status||' and l_msg_count is '||l_msg_count, 1);
10593 
10594       -------------------------------------------------------
10595       -- Check whether this row was successfully processed --
10596       -------------------------------------------------------
10597       IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
10598 
10599         ----------------------------------------------------------------------------
10600         -- Since this row failed, put its ROW_IDENTIFIER into the failed row list --
10601         ----------------------------------------------------------------------------
10602         x_failed_row_id_list := x_failed_row_id_list ||
10603                                 l_current_row_element.ROW_IDENTIFIER || ',';
10604 
10605         ------------------------------------------------
10606         -- We keep x_return_status updated to reflect --
10607         -- the most serious error we come across      --
10608         ------------------------------------------------
10609         IF (x_return_status IS NULL OR
10610             x_return_status = FND_API.G_RET_STS_SUCCESS OR
10611             (x_return_status = FND_API.G_RET_STS_ERROR AND
10612              l_return_status = FND_API.G_RET_STS_UNEXP_ERROR)) THEN
10613 
10614           x_return_status := l_return_status;
10615 
10616         END IF;
10617       END IF;
10618 
10619       l_sorted_row_table_index := l_sorted_attr_row_table.NEXT(l_sorted_row_table_index);
10620     END LOOP;
10621 
10622     ------------------------------------------------------------------
10623     -- Trim the trailing ',' from x_failed_row_id_list if necessary --
10624     ------------------------------------------------------------------
10625     x_failed_row_id_list := RTRIM(x_failed_row_id_list, ',');
10626 
10627     x_msg_count := ERROR_HANDLER.Get_Message_Count();
10628 
10629     IF (x_msg_count > 0) THEN
10630 
10631       RAISE FND_API.G_EXC_ERROR;
10632 
10633     END IF;
10634 
10635     Debug_Msg('In Process_User_Attrs_Data, done', 1);
10636 
10637     Close_Business_Object_Session(
10638       p_init_error_handler_flag     => FND_API.To_Boolean(p_init_error_handler)
10639      ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
10640      ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
10641     );
10642 
10643     IF FND_API.To_Boolean(p_commit) THEN
10644       COMMIT WORK;
10645     END IF;
10646 
10647     IF (x_return_status IS NULL) THEN
10648       x_return_status := FND_API.G_RET_STS_SUCCESS;
10649     END IF;
10650 
10651   EXCEPTION
10652 
10653     ----------------------------------------------------------------------------
10654     -- We do not ROLLBACK in this procedure: standard behavior for Business   --
10655     -- Objects is for each row being processed to succeed or fail independent --
10656     -- of the status of other rows, so we let Process_Row ROLLBACK any errors --
10657     -- it encounters.  If callers want different behavior, they can establish --
10658     -- a SAVEPOINT prior to calling this procedure and ROLLBACK if we report  --
10659     -- any errors.                                                            --
10660     ----------------------------------------------------------------------------
10661     WHEN FND_API.G_EXC_ERROR THEN
10662       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR ', 1);
10663 
10664       -----------------------------------------------------------------------------
10665       -- Since we want to commit all successful rows, we will always call commit --
10666       -----------------------------------------------------------------------------
10667       IF FND_API.To_Boolean(p_commit) THEN
10668         COMMIT WORK;
10669       END IF;
10670 
10671       --bug 9559993
10672       x_return_status := FND_API.G_RET_STS_ERROR;
10673 
10674       Close_Business_Object_Session(
10675         p_init_error_handler_flag     => FND_API.To_Boolean(p_init_error_handler)
10676        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
10677        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
10678       );
10679 
10680       x_msg_count := ERROR_HANDLER.Get_Message_Count();
10681 
10682       IF (x_msg_count = 1) THEN
10683         DECLARE
10684           message_list  ERROR_HANDLER.Error_Tbl_Type;
10685         BEGIN
10686           ERROR_HANDLER.Get_Message_List(message_list);
10687           x_msg_data := message_list(message_list.FIRST).message_text;
10688         END;
10689       ELSE
10690         x_msg_data := NULL;
10691       END IF;
10692 
10693     WHEN OTHERS THEN
10694 
10695       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM, 1);
10696       -----------------------------------------------------------------------------
10697       -- Since we want to commit all successful rows, we will always call commit --
10698       -----------------------------------------------------------------------------
10699       IF FND_API.To_Boolean(p_commit) THEN
10700         COMMIT WORK;
10701       END IF;
10702 
10703       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
10704 
10705       DECLARE
10706         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
10707       BEGIN
10708         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
10709         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
10710         l_token_table(2).TOKEN_NAME := 'API_NAME';
10711         l_token_table(2).TOKEN_VALUE := l_api_name;
10712         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
10713         l_token_table(3).TOKEN_VALUE := SQLERRM;
10714 
10715         ERROR_HANDLER.Add_Error_Message(
10716           p_message_name      => 'EGO_PLSQL_ERR'
10717          ,p_application_id    => 'EGO'
10718          ,p_token_tbl         => l_token_table
10719          ,p_message_type      => FND_API.G_RET_STS_ERROR
10720          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
10721          ,p_entity_id         => p_entity_id
10722          ,p_entity_index      => p_entity_index
10723          ,p_entity_code       => p_entity_code
10724          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
10725         );
10726       END;
10727 
10728       Close_Business_Object_Session(
10729         p_init_error_handler_flag     => FND_API.To_Boolean(p_init_error_handler)
10730        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
10731        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
10732       );
10733 
10734       x_msg_count := ERROR_HANDLER.Get_Message_Count();
10735 
10736       IF (x_msg_count = 1) THEN
10737         DECLARE
10738           message_list  ERROR_HANDLER.Error_Tbl_Type;
10739         BEGIN
10740           ERROR_HANDLER.Get_Message_List(message_list);
10741           x_msg_data := message_list(message_list.FIRST).message_text;
10742         END;
10743       ELSE
10744         x_msg_data := NULL;
10745       END IF;
10746 
10747 END Process_User_Attrs_Data;
10748 
10749 
10750 
10751 --
10752 -- Bug 1276239. Performance issue in Get_User_Attrs_Data.
10753 -- Added below supporting methods to build the dynamic SQL
10754 -- predicate using fnd_dsql methods.
10755 -- sreharih. Thu Aug 25 12:44:00 PDT 2011
10756 --
10757 
10758 
10759 --
10760 -- Simple procedure to add AND operator.
10761 --
10762 PROCEDURE add_and IS
10763 
10764 BEGIN
10765  fnd_dsql.add_text(' AND ');
10766 END add_and;
10767 
10768 
10769 --
10770 -- Add predicate based on column metadata and name value
10771 -- pairs.
10772 -- params
10773 -- p_col_meta_data    - Column metadata array
10774 -- p_nameval_pairs    - Name-Value pair array. Name should be
10775 --                      same as p_col_meta_data.col_name
10776 -- p_add_and          - Pass true if "AND" string must be added
10777 --                      in the begining.
10778 -- x_predicate_added  - Returns true if a predicate is added by
10779 --                      this method.
10780 --
10781 PROCEDURE add_nameval_predicate (
10782                               p_col_metadata    IN EGO_COL_METADATA_ARRAY,
10783                               p_nameval_pairs   IN EGO_COL_NAME_VALUE_PAIR_ARRAY,
10784                               p_add_and         IN BOOLEAN,
10785                               x_predicate_added OUT NOCOPY boolean) IS
10786 
10787  l_predicate VARCHAR2(32767);
10788  l_add_and   BOOLEAN := false;
10789 
10790 BEGIN
10791 
10792   Debug_msg('add_nameval_predicate: ' || 'Entering method');
10793 
10794   IF p_col_metadata IS NULL OR p_col_metadata.COUNT <= 0 OR
10795      p_nameval_pairs IS NULL OR p_nameval_pairs.COUNT <= 0 THEN
10796 
10797      Debug_msg('add_nameval_predicate: ' || ' name value pair or col metadata is null. So returning');
10798      x_predicate_added := FALSE;
10799      RETURN;
10800   END IF;
10801 
10802   l_add_and := p_add_and;
10803   FOR i IN p_col_metadata.FIRST .. p_col_metadata.LAST LOOP
10804     IF p_col_metadata(i).col_name IS NOT NULL THEN
10805       Debug_msg('add_nameval_predicate: ' || ' processing ' || p_col_metadata(i).col_name);
10806 
10807       FOR j IN p_nameval_pairs.FIRST .. p_nameval_pairs.LAST LOOP
10808         IF p_nameval_pairs(j).name = p_col_metadata(i).col_name THEN
10809 
10810            IF l_add_and THEN
10811              add_and;
10812            END IF;
10813           Debug_msg('add_nameval_predicate: ' || ' adding predicate for ' || p_col_metadata(i).col_name || ' value ' || p_nameval_pairs(j).value);
10814 
10815            IF p_nameval_pairs(j).value IS NULL THEN
10816              l_predicate  := p_col_metadata(i).col_name || ' IS NULL ';
10817              fnd_dsql.add_text(l_predicate);
10818            ELSE
10819              l_predicate  := p_col_metadata(i).col_name || ' = ';
10820              fnd_dsql.add_text(l_predicate);
10821              fnd_dsql.add_bind(p_nameval_pairs(j).value);
10822            END IF;
10823            x_predicate_added := TRUE;
10824            l_add_and := TRUE;
10825         END IF;
10826       END LOOP;
10827 
10828     END IF;
10829   END LOOP;
10830   Debug_msg('add_nameval_predicate: ' || 'Returning');
10831 
10832 END add_nameval_predicate;
10833 
10834 --
10835 -- 12765239. Incorporating review comment.
10836 -- Added new method to convert data level object
10837 -- to col metadata array.
10838 --
10839 FUNCTION to_col_metadata_array (p_in IN EGO_DATA_LEVEL_METADATA_OBJ)
10840                                                  RETURN EGO_COL_METADATA_ARRAY IS
10841 
10842  l_out EGO_COL_METADATA_ARRAY;
10843  l_count NUMBER;
10844 BEGIN
10845   Debug_msg('to_col_metadata_array : ' || 'Entering');
10846   l_out := EGO_COL_METADATA_ARRAY();
10847   l_count := 1;
10848 
10849   -- There is a mismatch in column_type VARCHAR size.
10850   -- since we dont know what to do with it, its better
10851   -- to make it raise runtime exception.
10852   IF p_in IS NOT NULL THEN
10853     IF p_in.pk_column_name1 IS NOT NULL THEN
10854       Debug_msg('to_col_metadata_array : ' || 'Adding pk_column_name1 ' || p_in.pk_column_name1 || '-' || p_in.pk_column_type1);
10855       l_out.EXTEND;
10856       l_out(l_count) := EGO_COL_METADATA_OBJ(p_in.pk_column_name1,p_in.pk_column_type1);
10857       l_count := l_count + 1;
10858     END IF;
10859 
10860     IF p_in.pk_column_name2 IS NOT NULL THEN
10861       Debug_msg('to_col_metadata_array : ' || 'Adding pk_column_name2 ' || p_in.pk_column_name2 || '-' || p_in.pk_column_type2);
10862       l_out.EXTEND;
10863       l_out(l_count)  := EGO_COL_METADATA_OBJ(p_in.pk_column_name2,p_in.pk_column_type2);
10864       l_count := l_count + 1;
10865     END IF;
10866 
10867     IF p_in.pk_column_name3 IS NOT NULL THEN
10868       Debug_msg('to_col_metadata_array : ' || 'Adding pk_column_name3 ' || p_in.pk_column_name3 || '-' || p_in.pk_column_type3);
10869       l_out.EXTEND;
10870       l_out(l_count)  := EGO_COL_METADATA_OBJ(p_in.pk_column_name3,p_in.pk_column_type3);
10871       l_count := l_count + 1;
10872     END IF;
10873 
10874     IF p_in.pk_column_name4 IS NOT NULL THEN
10875       Debug_msg('to_col_metadata_array : ' || 'Adding pk_column_name4 ' || p_in.pk_column_name4 || '-' || p_in.pk_column_type4);
10876       l_out.EXTEND;
10877       l_out(l_count)  := EGO_COL_METADATA_OBJ(p_in.pk_column_name4,p_in.pk_column_type4);
10878       l_count := l_count + 1;
10879     END IF;
10880 
10881     IF p_in.pk_column_name5 IS NOT NULL THEN
10882       Debug_msg('to_col_metadata_array : ' || 'Adding pk_column_name5 ' || p_in.pk_column_name5 || '-' || p_in.pk_column_type5);
10883       l_out.EXTEND;
10884       l_out(l_count)  := EGO_COL_METADATA_OBJ(p_in.pk_column_name5,p_in.pk_column_type5);
10885       l_count := l_count + 1;
10886     END IF;
10887 
10888  END IF;
10889  RETURN l_out;
10890 END to_col_metadata_array;
10891 --
10892 -- Add data level predicate.
10893 -- params
10894 -- p_data_level_id          - Data level ID
10895 -- p_has_data_level_col     - Pass "true" if the table has data level
10896 --                            ID column
10897 -- p_data_level_metadata    - Data level metadata
10898 -- p_data_level_value_pairs - Data level name value pairs.
10899 -- p_add_and                - Pass true if "AND" string must be added
10900 --                            in the begining.
10901 -- x_predicate_added        - Returns true if a predicate is added by
10902 --                            this method.
10903 --
10904 PROCEDURE add_datalevel_predicate (
10905                               p_data_level_id             IN NUMBER,
10906                               p_has_data_level_col        IN BOOLEAN,
10907                               p_ext_data_level_metadata   IN EGO_COL_METADATA_ARRAY,
10908                               p_data_level_metadata       IN EGO_DATA_LEVEL_METADATA_OBJ,
10909                               p_data_level_value_pairs    IN EGO_COL_NAME_VALUE_PAIR_ARRAY,
10910                               p_add_and                   IN BOOLEAN,
10911                               x_predicate_added           OUT NOCOPY BOOLEAN) IS
10912 
10913  l_ret             BOOLEAN;
10914  l_predicate_added BOOLEAN;
10915 BEGIN
10916   Debug_msg('add_datalevel_predicate: ' || 'Entering');
10917 
10918   l_ret := FALSE;
10919   IF p_data_level_id IS NOT NULL AND p_has_data_level_col THEN
10920     IF p_add_and THEN
10921       add_and;
10922     END IF;
10923     Debug_msg('add_datalevel_predicate: ' || 'Added data_level_id condition DATA_LEVEL_ID = ' || p_data_level_id);
10924     fnd_dsql.add_text(' DATA_LEVEL_ID = ');
10925     fnd_dsql.add_bind(p_data_level_id);
10926     l_ret := TRUE;
10927   END IF;
10928 
10929   Debug_msg('add_datalevel_predicate: ' || 'Adding ext table prediacate');
10930   -- we are passing old data level meta data for backward compatibility.
10931   -- R12.C onwards we use data level meta data only from ego_data_level_b.
10932   add_nameval_predicate(p_col_metadata    => p_ext_data_level_metadata,
10933                         p_nameval_pairs   => p_data_level_value_pairs,
10934                         p_add_and         => l_ret OR p_add_and,
10935                         x_predicate_added => l_predicate_added);
10936 
10937   Debug_msg('add_datalevel_predicate: ' || 'Adding data level pkcol predicates ');
10938   add_nameval_predicate(p_col_metadata    => to_col_metadata_array(p_data_level_metadata),
10939                         p_nameval_pairs   => p_data_level_value_pairs,
10940                         p_add_and         => l_ret OR l_predicate_added,
10941                         x_predicate_added => l_predicate_added);
10942 
10943   Debug_msg('add_datalevel_predicate: ' || 'Returning');
10944   x_predicate_added := l_ret OR l_predicate_added;
10945 
10946 END add_datalevel_predicate;
10947 
10948 --
10949 -- Add AG predicate.
10950 -- params
10951 -- p_attr_group_id          - Attribute Group ID.
10952 -- p_add_and                - Pass true if "AND" string must be added
10953 --                            in the begining.
10954 -- x_predicate_added        - Returns true if a predicate is added by
10955 --                            this method.
10956 --
10957 
10958 PROCEDURE add_ag_predicate ( p_attr_group_id   IN NUMBER,
10959                              p_add_and         IN BOOLEAN,
10960                              x_predicate_added OUT NOCOPY BOOLEAN) IS
10961 
10962 BEGIN
10963     IF p_add_and THEN
10964      add_and;
10965     END IF;
10966     fnd_dsql.add_text(' ATTR_GROUP_ID = ');
10967     fnd_dsql.add_bind(p_attr_group_id);
10968     x_predicate_added := TRUE;
10969 END add_ag_predicate;
10970 
10971 --
10972 -- Return Attribute Group Defaulting property value.
10973 --
10974 FUNCTION get_ag_defaulting (p_attr_group_id IN NUMBER,
10975                             p_data_level    IN VARCHAR2) RETURN VARCHAR2 IS
10976 
10977  CURSOR c IS
10978    SELECT agdl.defaulting
10979      FROM ego_attr_group_dl agdl,
10980           ego_data_level_b dl
10981     WHERE agdl.attr_group_id = p_attr_group_id
10982       AND agdl.data_level_id = dl.data_level_id
10983       AND dl.data_level_name = p_data_level;
10984 
10985  l_temp ego_attr_group_dl.defaulting%TYPE;
10986 
10987 BEGIN
10988  OPEN c;
10989  FETCH c INTO l_temp;
10990  CLOSE c;
10991 
10992  RETURN l_temp;
10993 END get_ag_defaulting;
10994 
10995 --
10996 -- Return style item detail.
10997 --
10998 PROCEDURE get_style_item_details (p_organization_id   IN NUMBER,
10999                                   p_inventory_item_id IN NUMBER,
11000                                   x_style_flag        OUT NOCOPY VARCHAR2,
11001                                   x_style_item_id     OUT NOCOPY NUMBER) IS
11002 
11003  CURSOR c IS
11004   SELECT msib.style_item_flag, msib.style_item_id
11005     FROM mtl_system_items_b msib
11006    WHERE msib.organization_id = p_organization_id
11007      AND msib.inventory_item_id = p_inventory_item_id;
11008 
11009 
11010 BEGIN
11011 
11012  OPEN c;
11013  FETCH c INTO x_style_flag, x_style_item_id;
11014  CLOSE c;
11015 
11016 END get_style_item_details;
11017 
11018 --
11019 -- Process primary key col value pair for EGO_ITEMMGMT_GROUP.
11020 --
11021 --
11022 FUNCTION get_itmmgmt_pkcol(p_attr_group_id     IN NUMBER,
11023                            p_data_level        IN VARCHAR2,
11024                            p_pkcol_value_pairs IN EGO_COL_NAME_VALUE_PAIR_ARRAY)
11025                                                       RETURN EGO_COL_NAME_VALUE_PAIR_ARRAY IS
11026 
11027  l_pk_column_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
11028  l_inventory_item_id          mtl_system_items_b.inventory_item_id%TYPE;
11029  l_organization_id            mtl_system_items_b.organization_id%TYPE;
11030  l_style_item_flag            mtl_system_items_b.style_item_flag%TYPE;
11031  l_style_item_id              mtl_system_items_b.style_item_id%TYPE;
11032  l_defaulting                 ego_attr_group_dl.defaulting%TYPE;
11033 
11034 BEGIN
11035     Debug_msg('get_itmmgmt_pkcol: ' || ' Entering method');
11036     l_pk_column_name_value_pairs := p_pkcol_value_pairs;
11037 
11038     IF (l_pk_column_name_value_pairs IS NOT NULL AND
11039         l_pk_column_name_value_pairs.COUNT > 0) THEN
11040 
11041          FOR i IN l_pk_column_name_value_pairs.FIRST .. l_pk_column_name_value_pairs.LAST LOOP
11042               IF (l_pk_column_name_value_pairs(i).NAME = 'INVENTORY_ITEM_ID') THEN
11043                     l_inventory_item_id := l_pk_column_name_value_pairs(i).VALUE;
11044                     Debug_msg('get_itmmgmt_pkcol: ' || ' l_inventory_item_id =  ' || l_inventory_item_id);
11045               ELSIF (l_pk_column_name_value_pairs(i).NAME = 'ORGANIZATION_ID') THEN
11046                      l_organization_id := l_pk_column_name_value_pairs(i).VALUE;
11047                     Debug_msg('get_itmmgmt_pkcol: ' || ' l_organization_id =  ' || l_organization_id);
11048               END IF;
11049          END LOOP;
11050 
11051 
11052           -- 'I' for Inheritance, 'D'for defaulting
11053           l_defaulting := get_ag_defaulting(p_attr_group_id => p_attr_group_id,
11054                                             p_data_level    => p_data_level);
11055 
11056           Debug_msg('get_itmmgmt_pkcol: ' || ' l_defaulting = ' || l_defaulting);
11057 
11058           --
11059           -- For Inherited-AG SKUs get the value from parent Style Item
11060           --
11061 
11062           IF (l_defaulting = 'I') THEN
11063 
11064                    get_style_item_details(p_organization_id   => l_organization_id,
11065                                           p_inventory_item_id => l_inventory_item_id,
11066                                           x_style_flag        => l_style_item_flag,
11067                                           x_style_item_id     => l_style_item_id);
11068 
11069                   Debug_msg('get_itmmgmt_pkcol: ' || ' l_style_item_flag = ' || l_style_item_flag ||
11070                                                      ' l_style_item_id = '   || l_style_item_id);
11071 
11072                   -- style flag is N for SKUs
11073                   IF (l_style_item_flag = 'N') THEN
11074 
11075                      l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY
11076                                          (EGO_COL_NAME_VALUE_PAIR_OBJ( 'INVENTORY_ITEM_ID' , to_char(l_style_item_id))
11077                                           ,EGO_COL_NAME_VALUE_PAIR_OBJ( 'ORGANIZATION_ID' , to_char(l_organization_id))
11078                                          );
11079 
11080                   END IF; --END IF FOR STYLE_ITEM_FLAG
11081           END IF; -- defaulting
11082 
11083      END IF; -- null check
11084 
11085      RETURN l_pk_column_name_value_pairs;
11086 
11087 END get_itmmgmt_pkcol;
11088 
11089 --
11090 -- Add Primary Key predicates.
11091 -- params
11092 -- p_attr_group_type        - Attribute Group Type
11093 -- p_attr_group_id          - Attribute Group ID.
11094 -- p_data_level             - Data level
11095 -- p_pkcol_value_pairs      - Primary key column-value pairs
11096 -- p_pk_column_metadata     - Primary key column metadata.
11097 -- p_add_and                - Pass true if "AND" string must be added
11098 --                            in the begining.
11099 -- x_predicate_added        - Returns true if a predicate is added by
11100 --                            this method.
11101 --
11102 
11103 PROCEDURE add_pkcol_predicate (p_attr_group_type    IN VARCHAR2,
11104                                p_attr_group_id      IN NUMBER,
11105                                p_data_level         IN VARCHAR2,
11106                                p_pkcol_value_pairs  IN EGO_COL_NAME_VALUE_PAIR_ARRAY,
11107                                p_pk_column_metadata IN EGO_COL_METADATA_ARRAY,
11108                                p_add_and            IN BOOLEAN,
11109                                x_predicate_added    OUT NOCOPY BOOLEAN) IS
11110 
11111  l_pk_column_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
11112 BEGIN
11113   l_pk_column_name_value_pairs := p_pkcol_value_pairs;
11114   IF (p_attr_group_type = 'EGO_ITEMMGMT_GROUP') THEN
11115        l_pk_column_name_value_pairs :=  get_itmmgmt_pkcol(p_attr_group_id     => p_attr_group_id,
11116                                                           p_data_level        => p_data_level,
11117                                                           p_pkcol_value_pairs => l_pk_column_name_value_pairs);
11118   END IF;
11119 
11120   add_nameval_predicate(p_col_metadata    => p_pk_column_metadata,
11121                         p_nameval_pairs   => l_pk_column_name_value_pairs,
11122                         p_add_and         => p_add_and,
11123                         x_predicate_added => x_predicate_added);
11124 
11125 END add_pkcol_predicate;
11126 
11127 
11128 FUNCTION get_uom_value (p_uom_db_column_name IN VARCHAR2,
11129                         p_table_name         IN VARCHAR2,
11130                         p_extension_id       IN NUMBER) RETURN VARCHAR2 IS
11131 
11132     l_dynamic_sql      VARCHAR2(32767);
11133     l_uom_value        VARCHAR2(30);
11134     l_cursor_id        NUMBER;
11135     l_dummy            NUMBER;
11136 BEGIN
11137     Debug_msg('get_uom_value: ' || 'Entering method');
11138 
11139     fnd_dsql.init();
11140     fnd_dsql.add_text (' SELECT ' || p_uom_db_column_name ||
11141                        ' FROM ' || p_table_name  ||
11142                        ' WHERE EXTENSION_ID = ');
11143     fnd_dsql.add_bind(p_extension_id);
11144     l_cursor_id := DBMS_SQL.OPEN_CURSOR;
11145     l_dynamic_sql := fnd_dsql.get_text;
11146 
11147     Debug_msg('get_uom_value: ' || ' Query ' || l_dynamic_sql);
11148 
11149     DBMS_SQL.PARSE(l_cursor_id, l_dynamic_sql, DBMS_SQL.NATIVE);
11150     fnd_dsql.set_cursor(l_cursor_id);
11151     fnd_dsql.do_binds;
11152 
11153     dbms_sql.define_column(l_cursor_id, 1, l_uom_value, 3);
11154     l_dummy := DBMS_SQL.Execute(l_cursor_id);
11155 
11156     Debug_msg('get_uom_value: ' || 'Executed the query');
11157 
11158    WHILE (DBMS_SQL.FETCH_ROWS(l_cursor_id) > 0)
11159    LOOP
11160       dbms_sql.column_value(l_cursor_id, 1, l_uom_value);
11161    END LOOP;
11162 
11163    IF (l_cursor_id IS NOT NULL) THEN
11164       DBMS_SQL.Close_Cursor(l_cursor_id);
11165    END IF;
11166 
11167    Debug_msg('uom value = ' || l_uom_value);
11168    RETURN l_uom_value;
11169 
11170 END get_uom_value;
11171 
11172 --
11173 -- Bug 1276239. End of new supporting methods.
11174 -- sreharih. Thu Aug 25 12:44:00 PDT 2011
11175 --
11176 
11177 
11178 --
11179 -- Bug 1276239. Performance issue in Get_User_Attrs_Data.
11180 -- Following changes made.
11181 --  a. Removed redundant code(logic) like
11182 --       i. Usage of DECODE in SELECT. It was required based on old
11183 --          logic when we had only one SQL for all requested AGs.
11184 --          The current logic builds one SQL per AG.
11185 --      ii. We were buidling data level primary key prediactes twice.
11186 --  b. Replaced literal logic with binds. Using FND_DSQL and newly
11187 --     created encapsulated methods.
11188 --  c. Replaced literal logic for UOM value query with binds. Also
11189 --     we are using only EXTENSION_ID predicate for it as other
11190 --     conditions are not necessary.
11191 --
11192 -- sreharih. Thu Aug 25 12:44:00 PDT 2011
11193 --
11194 
11195 ----------------------------------------------------------------------
11196 
11197 PROCEDURE Get_User_Attrs_Data (
11198         p_api_version                   IN   NUMBER
11199        ,p_object_name                   IN   VARCHAR2
11200        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11201        ,p_attr_group_request_table      IN   EGO_ATTR_GROUP_REQUEST_TABLE
11202        ,p_user_privileges_on_object     IN   EGO_VARCHAR_TBL_TYPE DEFAULT NULL
11203        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
11204        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
11205        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
11206        ,p_debug_level                   IN   NUMBER     DEFAULT 0
11207        ,p_init_error_handler            IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11208        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11209        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11210        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11211        ,x_attributes_row_table          OUT NOCOPY EGO_USER_ATTR_ROW_TABLE
11212        ,x_attributes_data_table         OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
11213        ,x_return_status                 OUT NOCOPY VARCHAR2
11214        ,x_errorcode                     OUT NOCOPY NUMBER
11215        ,x_msg_count                     OUT NOCOPY NUMBER
11216        ,x_msg_data                      OUT NOCOPY VARCHAR2
11217 ) IS
11218 
11219     l_api_name               CONSTANT VARCHAR2(30) := 'Get_User_Attrs_Data';
11220 
11221     --we don't use l_api_version yet, but eventually we might:
11222     --if we change required parameters, version goes FROM n.x to (n+1).x
11223     --if we change optional parameters, version goes FROM x.n to x.(n+1)
11224     l_api_version            CONSTANT NUMBER := 1.0;
11225 
11226     l_object_id                   NUMBER;
11227     l_ext_table_metadata_obj      EGO_EXT_TABLE_METADATA_OBJ;
11228     l_request_table_index         NUMBER;
11229     l_curr_ag_request_obj         EGO_ATTR_GROUP_REQUEST_OBJ;
11230     l_curr_ag_metadata_obj        EGO_ATTR_GROUP_METADATA_OBJ;
11231     l_can_view_this_attr_group    BOOLEAN;
11232     l_augmented_data_table        LOCAL_AUGMENTED_DATA_TABLE;
11233     l_requested_attr_names_table  LOCAL_VARCHAR_TABLE;
11234     l_attr_list_index             NUMBER;
11235     l_curr_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
11236     l_new_attr_metadata_obj       EGO_ATTR_METADATA_OBJ;
11237     l_curr_augmented_attr_rec     LOCAL_USER_ATTR_DATA_REC;
11238     l_curr_aug_table_index        NUMBER;
11239     l_table_of_low_ind_for_AG_ID  LOCAL_NUMBER_TABLE;
11240     l_table_of_high_ind_for_AG_ID LOCAL_NUMBER_TABLE;
11241     l_ag_predicate_list           VARCHAR2(20000);
11242     l_curr_db_column_name         VARCHAR2(30);
11243     l_to_char_db_col_expression   VARCHAR2(90);
11244     l_db_column_list              VARCHAR2(32767);
11245     l_db_column_tables_index      NUMBER;
11246     l_db_column_name_table        LOCAL_VARCHAR_TABLE;
11247     l_db_column_query_table       LOCAL_BIG_VARCHAR_TABLE;
11248     l_start_index                 NUMBER;
11249     l_substring_length            NUMBER;
11250     l_temp_db_query_string        VARCHAR2(32767);
11251     l_int_to_disp_val_string      VARCHAR2(32767);
11252     l_data_level_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
11253     l_pk_col_string               VARCHAR2(1000);
11254     l_data_level_string           VARCHAR2(1000);
11255     l_dynamic_sql                 VARCHAR2(32767);
11256     l_cursor_id                   NUMBER;
11257     l_dummy                       NUMBER;
11258     l_varchar_example             VARCHAR2(1000);
11259     l_number_example              NUMBER;
11260     l_date_example                DATE;
11261     l_curr_AG_ID                  NUMBER;
11262     l_low_aug_tab_ind_for_AG_ID   NUMBER;
11263     l_high_aug_tab_ind_for_AG_ID  NUMBER;
11264     l_need_to_build_a_row_obj     BOOLEAN := TRUE;
11265     l_extension_id                NUMBER;
11266     --ENHR12:added for passing the internal value of an
11267     --attribute along with the display value.
11268     l_dbcol_cntr                  NUMBER:=0;
11269     l_char_value                  VARCHAR2(100);
11270     --bug 5494760
11271     l_has_attrs                   VARCHAR2(1) :='N';
11272     l_curr_ag_vl_name             VARCHAR2(30);
11273     l_curr_ag_table_name          VARCHAR2(30);
11274 
11275 l_token_table               ERROR_HANDLER.Token_Tbl_Type;
11276 l_curr_data_level_metadata  EGO_DATA_LEVEL_METADATA_OBJ;
11277 l_curr_data_level_row_obj   EGO_DATA_LEVEL_ROW_OBJ;
11278 l_has_data_level_col            BOOLEAN  := FALSE;    -- TRUE is for R12C
11279 l_dl_view_privilege  fnd_form_functions.function_name%TYPE;
11280 
11281     --bug 8218727
11282     l_dynamic_sql2                 VARCHAR2(32767);
11283     l_uom_value                    VARCHAR2(3);
11284     l_cursor_id2                   NUMBER;
11285     l_conv_rate                    NUMBER;
11286 
11287     --start bug 8588077
11288     l_current_attr_group_id       NUMBER;
11289     l_col_values_index            NUMBER;
11290     l_col_value_item_id           VARCHAR2(1000);
11291     l_col_value_org_id            VARCHAR2(30);
11292     l_col_name                    VARCHAR2(30);
11293     l_ag_inherited_query          VARCHAR2(3000);
11294     l_defaulting                  VARCHAR2(5);
11295     l_style_item_flag_query       VARCHAR2(3000);
11296     l_style_item_flag             VARCHAR2(5);
11297     l_style_item_id               NUMBER;
11298     l_input_data_level_id         NUMBER;
11299     l_pk_column_name_value_pairs  EGO_COL_NAME_VALUE_PAIR_ARRAY;
11300     -- Bug 12765239.
11301     l_add_and                     BOOLEAN := false;
11302     l_predicate_added             BOOLEAN := false;
11303   BEGIN
11304 
11305     Debug_Msg(l_api_name||'  starting', 1);
11306     -- Check for call compatibility
11307     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
11308                                         l_api_name, G_PKG_NAME)
11309     THEN
11310       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
11311     END IF;
11312 
11313 Debug_Msg(l_api_name||'  call compatible', 3);
11314 
11315 
11316 Debug_Msg(l_api_name||' Set_Up_Business_Object_Session(', 3);
11317 Debug_Msg(l_api_name||'   p_bulkload_flag                 => TRUE', 3);
11318 Debug_Msg(l_api_name||'   p_user_privileges_on_object     => <unprintable>', 3);
11319 Debug_Msg(l_api_name||'   p_entity_id                     => ' || p_entity_id, 3);
11320 Debug_Msg(l_api_name||'   p_entity_index                  => ' || p_entity_index, 3);
11321 Debug_Msg(l_api_name||'   p_entity_code                   => ' || p_entity_code, 3);
11322 Debug_Msg(l_api_name||'   p_debug_level                   => ' || p_debug_level, 3);
11323 Debug_Msg(l_api_name||'   p_init_error_handler_flag       => ' || p_init_error_handler, 3);
11324 Debug_Msg(l_api_name||'   p_object_name                   => ' || p_object_name, 3);
11325 Debug_Msg(l_api_name||'   p_pk_column_name_value_pairs    => <unprintable>', 3);
11326 Debug_Msg(l_api_name||'   p_class_code_name_value_pairs   => NULL', 3);
11327 Debug_Msg(l_api_name||'   p_init_fnd_msg_list             => ' || p_init_fnd_msg_list, 3);
11328 Debug_Msg(l_api_name||'   p_add_errors_to_fnd_stack       => ' || p_add_errors_to_fnd_stack, 3);
11329 Debug_Msg(l_api_name||'   x_return_status                 => ' || x_return_status, 3);
11330 Debug_Msg(l_api_name||' );', 3);
11331     --------------------------------------------------------------------------------
11332     -- Start by dealing with caching, error-handling, and preliminary validations --
11333     --------------------------------------------------------------------------------
11334 
11335     Set_Up_Business_Object_Session(
11336         p_bulkload_flag                 => TRUE
11337        ,p_user_privileges_on_object     => p_user_privileges_on_object
11338        ,p_entity_id                     => p_entity_id
11339        ,p_entity_index                  => p_entity_index
11340        ,p_entity_code                   => p_entity_code
11341        ,p_debug_level                   => p_debug_level
11342        ,p_init_error_handler_flag       => FND_API.To_Boolean(p_init_error_handler)
11343        ,p_object_name                   => p_object_name
11344        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
11345        ,p_class_code_name_value_pairs   => NULL -- SSARNOBA - I'm not sure if this should be null
11346        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
11347        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
11348        ,x_return_status                 => x_return_status
11349     );
11350 Debug_Msg(l_api_name || ' after Set_Up_Business_Object_Session ', 3);
11351 
11352     ----------------------------------------------------------------------
11353     -- If an error was found, we've already added it to the error stack --
11354     ----------------------------------------------------------------------
11355     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
11356       RAISE FND_API.G_EXC_ERROR;
11357     END IF;
11358 
11359     -------------------------------------------------
11360     -- We could have a batch metadata retrieval procedure for the *_User_Attrs_Data calls;
11361     -- it would batch fetch all the metadata for the relevent AGs and then store them in
11362     -- the cache (well, at least fifty of them; if more than fifty, it would still work well)
11363     -------------------------------------------------
11364 
11365 Debug_Msg(l_api_name || ' p_attr_group_request_table.count = '||p_attr_group_request_table.count);
11366     IF (p_attr_group_request_table IS NOT NULL AND
11367         p_attr_group_request_table.COUNT > 0) THEN
11368 
11369       -------------------------------------------------------------
11370       -- First, get metadata for later use in building the query --
11371       -- (we know both of these calls will succeed because they  --
11372       -- were tested in Perform_Preliminary_Checks, above)       --
11373       -------------------------------------------------------------
11374       l_object_id := Get_Object_Id_From_Name(p_object_name);
11375       l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
11376 
11377       --=======================================================================--
11378       -- Because there might be hundreds of Attribute Groups for which we need --
11379       -- to get data, we can't assume that we could store metadata for each of --
11380       -- them; so we do all processing that requires metadata at one time for  --
11381       -- each Attribute Group to avoid possibly having to refetch metadata for --
11382       -- any Attribute Group.                                                  --
11383       --=======================================================================--
11384       l_request_table_index := p_attr_group_request_table.FIRST;
11385       <<GUAD_ag_requests_loop>>
11386       WHILE (l_request_table_index <= p_attr_group_request_table.LAST)
11387       LOOP
11388         l_curr_ag_request_obj := p_attr_group_request_table(l_request_table_index);
11389 
11390 Debug_Msg(l_api_name || ' ');
11391 Debug_Msg(l_api_name || ' Attribute Group Request (       -- ' || l_request_table_index || '.');
11392 Debug_Msg(l_api_name || '   ATTR_GROUP_ID   =  ' || l_curr_ag_request_obj.ATTR_GROUP_ID);
11393 Debug_Msg(l_api_name || '   APPLICATION_ID  =  ' || l_curr_ag_request_obj.APPLICATION_ID);
11394 Debug_Msg(l_api_name || '   ATTR_GROUP_TYPE =  ' || l_curr_ag_request_obj.ATTR_GROUP_TYPE);
11395 Debug_Msg(l_api_name || '   ATTR_GROUP_NAME =  ' || l_curr_ag_request_obj.ATTR_GROUP_NAME);
11396 Debug_Msg(l_api_name || '   DATA_LEVEL      =  ' || l_curr_ag_request_obj.DATA_LEVEL);
11397 Debug_Msg(l_api_name || '   DATA_LEVEL_1    =  ' || l_curr_ag_request_obj.DATA_LEVEL_1);
11398 Debug_Msg(l_api_name || '   DATA_LEVEL_2    =  ' || l_curr_ag_request_obj.DATA_LEVEL_2);
11399 Debug_Msg(l_api_name || '   DATA_LEVEL_3    =  ' || l_curr_ag_request_obj.DATA_LEVEL_3);
11400 Debug_Msg(l_api_name || '   DATA_LEVEL_4    =  ' || l_curr_ag_request_obj.DATA_LEVEL_4);
11401 Debug_Msg(l_api_name || '   DATA_LEVEL_5    =  ' || l_curr_ag_request_obj.DATA_LEVEL_5);
11402 Debug_Msg(l_api_name || '   ATTR_NAME_LIST  =  ' || l_curr_ag_request_obj.ATTR_NAME_LIST);
11403 Debug_Msg(l_api_name || ' )  ');
11404 
11405         -- Get the metadata for this attribute group
11406         l_curr_ag_metadata_obj :=
11407           EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(l_curr_ag_request_obj.ATTR_GROUP_ID
11408                                                            ,l_curr_ag_request_obj.APPLICATION_ID
11409                                                            ,l_curr_ag_request_obj.ATTR_GROUP_TYPE
11410                                                            ,l_curr_ag_request_obj.ATTR_GROUP_NAME);
11411 
11412         -- Determine if the EXT table has a data level column
11413         l_has_data_level_col := FND_API.TO_BOOLEAN(EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(l_curr_ag_metadata_obj.EXT_TABLE_B_NAME, 'DATA_LEVEL_ID'));
11414 
11415 
11416         ----------------------------------------------------------------------
11417         -- Scan the list of enabled data levels, and see if the data level  --
11418         -- of the current attribute group is in this list                   --
11419         ----------------------------------------------------------------------
11420 
11421         l_curr_data_level_row_obj := NULL;
11422 
11423         IF l_has_data_level_col THEN
11424 
11425           IF (l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS IS NOT NULL AND
11426               l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS.COUNT <> 0) THEN
11427 
11428 Debug_Msg(l_api_name || ' passed data level name '|| l_curr_ag_request_obj.data_level);
11429 Debug_Msg(l_api_name || ' ' || l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS.COUNT || ' data level(s) enabled for AG ' || l_curr_ag_request_obj.ATTR_GROUP_ID);
11430 
11431             -- Loop 1.1
11432             FOR dl_index IN l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS.FIRST ..
11433                             l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS.LAST
11434             LOOP
11435 
11436 Debug_Msg(l_api_name ||' Enabled data level - '|| l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_name || ' (' || l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_id || ')');
11437 
11438               IF l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_name = l_curr_ag_request_obj.data_level THEN
11439 
11440 Debug_Msg(l_api_name||' Creating data level row obj ');
11441 
11442                 l_curr_data_level_row_obj := l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS(dl_index);
11443 
11444                 IF l_curr_data_level_row_obj IS NOT NULL THEN
11445 Debug_Msg(l_api_name || 'Data level metadata found');
11446                   l_curr_data_level_metadata := EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Metadata(l_curr_data_level_row_obj.data_level_id);
11447                   EXIT; -- exit the loop as we found the DL metadata
11448                 END IF;
11449               END IF;
11450             END LOOP;
11451 
11452 Debug_Msg(l_api_name || ' ');
11453 Debug_Msg(l_api_name || ', Data Level Metadata (');
11454 Debug_Msg(l_api_name || ',   DATA_LEVEL_ID        = ' || l_curr_data_level_metadata.DATA_LEVEL_ID);
11455 Debug_Msg(l_api_name || ',   DATA_LEVEL_NAME      = ' || l_curr_data_level_metadata.DATA_LEVEL_NAME);
11456 Debug_Msg(l_api_name || ',   USER_DATA_LEVEL_NAME = ' || l_curr_data_level_metadata.USER_DATA_LEVEL_NAME);
11457 Debug_Msg(l_api_name || ',   PK1_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME1);
11458 Debug_Msg(l_api_name || ',   PK2_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME2);
11459 Debug_Msg(l_api_name || ',   PK3_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME3);
11460 Debug_Msg(l_api_name || ',   PK4_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME4);
11461 Debug_Msg(l_api_name || ',   PK5_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME5);
11462 Debug_Msg(l_api_name || ',   PK1_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE1);
11463 Debug_Msg(l_api_name || ',   PK2_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE2);
11464 Debug_Msg(l_api_name || ',   PK3_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE3);
11465 Debug_Msg(l_api_name || ',   PK4_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE4);
11466 Debug_Msg(l_api_name || ',   PK5_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE5);
11467 Debug_Msg(l_api_name || ',   DL_PROD_TABLE_NAME   = ' || l_curr_data_level_metadata.DL_PROD_TABLE_NAME);
11468 Debug_Msg(l_api_name || ', )');
11469 Debug_Msg(l_api_name || ' ');
11470           IF l_curr_data_level_row_obj IS NULL THEN
11471             -- the data level is not correct, flash error message.
11472 
11473 Debug_Msg(l_api_name || ' Data level not in list of enabled data levels');
11474 
11475             l_token_table(1).TOKEN_NAME := 'DL_NAME';
11476             l_token_table(1).TOKEN_VALUE := '';
11477             l_token_table(2).TOKEN_NAME := 'AG_NAME';
11478             l_token_table(2).TOKEN_VALUE := l_curr_ag_metadata_obj.attr_group_disp_name;
11479 
11480             -- The data level XXX is not associated with the attribute
11481             -- group XXX
11482             ERROR_HANDLER.Add_Error_Message(
11483               p_message_name      => 'EGO_EF_DL_AG_INVALID'
11484              ,p_application_id    => 'EGO'
11485              ,p_token_tbl         => l_token_table
11486              ,p_message_type      => FND_API.G_RET_STS_ERROR
11487              ,p_row_identifier    => G_USER_ROW_IDENTIFIER
11488              ,p_entity_id         => p_entity_id
11489              ,p_entity_index      => p_entity_index
11490              ,p_entity_code       => p_entity_code
11491              ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
11492             );
11493             l_token_table.DELETE();
11494             RAISE FND_API.G_EXC_ERROR;
11495           END IF;
11496 
11497           -- We've found the metadata for the data level of this attribute group
11498 
11499 Debug_Msg(l_api_name || ' ');
11500 Debug_Msg(l_api_name || ', Data Level Metadata (');
11501 Debug_Msg(l_api_name || ',   DATA_LEVEL_ID        = ' || l_curr_data_level_metadata.DATA_LEVEL_ID);
11502 Debug_Msg(l_api_name || ',   DATA_LEVEL_NAME      = ' || l_curr_data_level_metadata.DATA_LEVEL_NAME);
11503 Debug_Msg(l_api_name || ',   USER_DATA_LEVEL_NAME = ' || l_curr_data_level_metadata.USER_DATA_LEVEL_NAME);
11504 Debug_Msg(l_api_name || ',   PK1_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME1);
11505 Debug_Msg(l_api_name || ',   PK2_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME2);
11506 Debug_Msg(l_api_name || ',   PK3_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME3);
11507 Debug_Msg(l_api_name || ',   PK4_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME4);
11508 Debug_Msg(l_api_name || ',   PK5_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME5);
11509 Debug_Msg(l_api_name || ',   PK1_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE1);
11510 Debug_Msg(l_api_name || ',   PK2_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE2);
11511 Debug_Msg(l_api_name || ',   PK3_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE3);
11512 Debug_Msg(l_api_name || ',   PK4_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE4);
11513 Debug_Msg(l_api_name || ',   PK5_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE5);
11514 Debug_Msg(l_api_name || ',   DL_PROD_TABLE_NAME   = ' || l_curr_data_level_metadata.DL_PROD_TABLE_NAME);
11515 Debug_Msg(l_api_name || ', )');
11516 Debug_Msg(l_api_name || ' ');
11517           END IF;
11518         END IF;  -- has_data_level
11519 Debug_Msg(l_api_name || ' level 1 done ');
11520 
11521         -- bug 5494760.  Go ahead for processing the Attribute Group only if the
11522         -- attribute group has got some attibutes in it.we return ATTR_METADATA_TABLE
11523         -- as a null if there are no attributes in the attribute group that is passed in.
11524         IF  (l_curr_ag_metadata_obj.ATTR_METADATA_TABLE IS NOT NULL AND l_curr_ag_metadata_obj.ATTR_METADATA_TABLE.COUNT <> 0 ) THEN
11525           -- set the flag to 'Y' even if  there is atleast one attribute group
11526           -- which has attributes in it.
11527           l_has_attrs := 'Y';
11528           -- get the view name
11529           l_curr_ag_vl_name := l_curr_ag_metadata_obj.EXT_TABLE_VL_NAME;
11530           -- get the table name also
11531           l_curr_ag_table_name := l_curr_ag_metadata_obj.EXT_TABLE_B_NAME;
11532           --
11533           -- Here we use l_curr_ag_metadata_obj.ATTR_GROUP_ID as our row identifier for
11534           -- error-reporting purposes; make sure it's known and that it's consistent!
11535           --
11536           G_USER_ROW_IDENTIFIER := l_curr_ag_metadata_obj.ATTR_GROUP_ID;
11537 
11538           l_can_view_this_attr_group := TRUE;
11539 
11540           -----------------------------------------------------------
11541           -- If the Attr Group is secured (either explicitly or by --
11542           -- a default privilege for this Object) AND the caller   --
11543           -- passed a table of privileges, then we ensure that the --
11544           -- user has the required View privilege for this AG      --
11545           -----------------------------------------------------------
11546           IF (G_CURRENT_USER_PRIVILEGES IS NOT NULL) THEN
11547 
11548             Check_Privileges(
11549               p_attr_group_metadata_obj  => l_curr_ag_metadata_obj
11550              ,p_data_level_row_obj       => l_curr_data_level_row_obj
11551              ,p_ignore_edit_privilege    => TRUE
11552              ,p_entity_id                => p_entity_id
11553              ,p_entity_index             => p_entity_index
11554              ,p_entity_code              => p_entity_code
11555              ,x_return_status            => x_return_status
11556             );
11557 
11558             IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
11559               l_can_view_this_attr_group := FALSE;
11560             END IF;
11561           END IF;
11562 
11563         IF (l_can_view_this_attr_group) THEN
11564 Debug_Msg(l_api_name || ' user can view the AG ');
11565           -------------------------------------------------------
11566           -- Build a Data Level array for this Attribute Group --
11567           -------------------------------------------------------
11568           IF l_curr_data_level_row_obj IS NULL THEN
11569 Debug_Msg(l_api_name || ' 100 ');
11570             -- r12 code
11571             l_data_level_name_value_pairs :=
11572                Build_Data_Level_Array(p_object_name    => p_object_name
11573                                      ,p_data_level_id  => NULL
11574                                      ,p_data_level_1   => l_curr_ag_request_obj.DATA_LEVEL_1
11575                                      ,p_data_level_2   => l_curr_ag_request_obj.DATA_LEVEL_2
11576                                      ,p_data_level_3   => l_curr_ag_request_obj.DATA_LEVEL_3
11577                                      ,p_data_level_4   => NULL
11578                                      ,p_data_level_5   => NULL
11579                                      );
11580           ELSE
11581 Debug_Msg(l_api_name || ' 200 ');
11582 Debug_Msg('Data level id ' || l_curr_data_level_row_obj.data_level_id);
11583             -- r12C code
11584             l_data_level_name_value_pairs :=
11585                Build_Data_Level_Array(p_object_name    => p_object_name
11586                                      ,p_data_level_id  => l_curr_data_level_row_obj.data_level_id
11587                                      ,p_data_level_1   => l_curr_ag_request_obj.DATA_LEVEL_1
11588                                      ,p_data_level_2   => l_curr_ag_request_obj.DATA_LEVEL_2
11589                                      ,p_data_level_3   => l_curr_ag_request_obj.DATA_LEVEL_3
11590                                      ,p_data_level_4   => l_curr_ag_request_obj.DATA_LEVEL_4
11591                                      ,p_data_level_5   => l_curr_ag_request_obj.DATA_LEVEL_5
11592                                      );
11593 Debug_Msg(l_api_name || ', data level key values = (' || l_curr_ag_request_obj.DATA_LEVEL_1 || ',' ||
11594                                                          l_curr_ag_request_obj.DATA_LEVEL_2 || ',' ||
11595                                                          l_curr_ag_request_obj.DATA_LEVEL_3 || ',' ||
11596                                                          l_curr_ag_request_obj.DATA_LEVEL_4 || ',' ||
11597                                                          l_curr_ag_request_obj.DATA_LEVEL_5 || ')', 5);
11598 
11599 
11600           END IF;
11601 
11602 Debug_Msg(l_api_name || ' data level name value pairs built ');
11603 
11604 
11605           ----------------------------------------------------------------------------------
11606           -- Get a list of the names of all requested Attributes for this Attribute Group --
11607           -- (this procedure also checks to be sure each name exists in the metadata)     --
11608           ----------------------------------------------------------------------------------
11609           l_requested_attr_names_table := Get_Requested_Attr_Names(l_curr_ag_metadata_obj.ATTR_GROUP_ID
11610                                                                   ,l_curr_ag_request_obj.ATTR_GROUP_NAME
11611                                                                   ,l_curr_ag_request_obj.ATTR_NAME_LIST
11612                                                                   ,l_curr_ag_metadata_obj.attr_metadata_table
11613                                                                   ,p_entity_id
11614                                                                   ,p_entity_index
11615                                                                   ,p_entity_code);
11616 
11617 Debug_Msg(l_api_name || ' requested attr names table built ');
11618           ---------------------------------------------------------------------------
11619           -- See whether we put error messages onto the stack in the previous call --
11620           ---------------------------------------------------------------------------
11621           IF (l_requested_attr_names_table.EXISTS(-1)) THEN
11622             RAISE FND_API.G_EXC_ERROR;
11623           END IF;
11624           --===================================================================--
11625           -- Loop 1.2
11626           -- For every Attribute in our table of Attribute names, we find its  --
11627           -- metadata and build an augmented version of a Data record for it,  --
11628           -- which we then add to a table for later use in correlating a given --
11629           -- Database Column to the appropriate Attribute and then building an --
11630           -- Attr Data object for that Attr and its value.  We also record the --
11631           -- index bounds in the data table for any given AG ID in order to    --
11632           -- limit the search for the correct augmented data record given the  --
11633           -- current AG ID and Database Column that we are processing.         --
11634           --===================================================================--
11635           l_attr_list_index := l_requested_attr_names_table.FIRST;
11636 
11637           <<GUAD_attributes_loop>>
11638           WHILE (l_attr_list_index <= l_requested_attr_names_table.LAST)
11639           LOOP
11640 Debug_Msg(l_api_name || ' processing attr at  '||l_attr_list_index);
11641 
11642             ---------------------------------------------------
11643             -- We know this call will succeed because it was --
11644             -- tested in Get_Requested_Attr_Names, above     --
11645             ---------------------------------------------------
11646             l_curr_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
11647                                           p_attr_metadata_table => l_curr_ag_metadata_obj.attr_metadata_table
11648                                          ,p_attr_name           => l_requested_attr_names_table(l_attr_list_index)
11649                                         );
11650 Debug_Msg(l_api_name || ' processing attr '|| l_attr_list_index || ' - ' ||l_curr_augmented_attr_rec.ATTR_NAME);
11651             l_curr_augmented_attr_rec.ATTR_GROUP_ID := l_curr_ag_metadata_obj.ATTR_GROUP_ID;
11652             l_curr_augmented_attr_rec.APPLICATION_ID := l_curr_ag_metadata_obj.APPLICATION_ID;
11653             l_curr_augmented_attr_rec.ATTR_GROUP_TYPE := l_curr_ag_metadata_obj.ATTR_GROUP_TYPE;
11654             l_curr_augmented_attr_rec.ATTR_GROUP_NAME := l_curr_ag_metadata_obj.ATTR_GROUP_NAME;
11655             l_curr_augmented_attr_rec.ATTR_NAME := l_curr_attr_metadata_obj.ATTR_NAME;
11656             l_curr_augmented_attr_rec.ATTR_DISP_NAME := l_curr_attr_metadata_obj.ATTR_DISP_NAME;
11657             l_curr_augmented_attr_rec.DATABASE_COLUMN := l_curr_attr_metadata_obj.DATABASE_COLUMN;
11658             l_curr_augmented_attr_rec.ATTR_UNIT_OF_MEASURE := l_curr_attr_metadata_obj.UNIT_OF_MEASURE_BASE; --Bug#7662816
11659             --ENHR12:added for passing the internal value of an
11660             --attribute along with the display value.
11661             l_curr_augmented_attr_rec.DATA_TYPE_CODE:=l_curr_attr_metadata_obj.DATA_TYPE_CODE;
11662             ----------------------------------------------------
11663             -- Record the index at which we store this record --
11664             ----------------------------------------------------
11665             l_curr_aug_table_index := l_augmented_data_table.COUNT+1;
11666             l_augmented_data_table(l_curr_aug_table_index) := l_curr_augmented_attr_rec;
11667 
11668             -----------------------------------------------------------------
11669             -- If it's the first index for this AG ID, store it as such... --
11670             -----------------------------------------------------------------
11671             IF (NOT l_table_of_low_ind_for_AG_ID.EXISTS(l_curr_augmented_attr_rec.ATTR_GROUP_ID)) THEN
11672               l_table_of_low_ind_for_AG_ID(l_curr_augmented_attr_rec.ATTR_GROUP_ID) := l_curr_aug_table_index;
11673             END IF;
11674 
11675             ------------------------------------------------------
11676             -- ...and since it's always the last index (so far) --
11677             -- for this AG ID, store it as that as well.        --
11678             ------------------------------------------------------
11679             l_table_of_high_ind_for_AG_ID(l_curr_augmented_attr_rec.ATTR_GROUP_ID) := l_curr_aug_table_index;
11680 
11681             -----------------------------------------------------------------------------
11682             -- If the Database Column for this Attribute is one that has not yet been  --
11683             -- processed, put it into the l_db_column_name_table and put its name and  --
11684             -- its l_db_column_name_table index into the l_db_column_list. If this has --
11685             -- already been done for this column, get the index from l_db_column_list. --
11686             -----------------------------------------------------------------------------
11687             l_curr_db_column_name := l_curr_augmented_attr_rec.DATABASE_COLUMN;
11688 
11689             IF (l_db_column_list IS NULL OR
11690                 INSTR(l_db_column_list, l_curr_db_column_name||':') = 0) THEN
11691 
11692               l_db_column_tables_index := l_db_column_name_table.COUNT+1;
11693               l_db_column_name_table(l_db_column_tables_index) := l_curr_db_column_name;
11694               l_db_column_list := l_db_column_list || l_curr_db_column_name || ':'||l_db_column_tables_index||', ';
11695 
11696             ELSE
11697 
11698               l_start_index := INSTR(l_db_column_list, l_curr_db_column_name||':') + LENGTH(l_curr_db_column_name||':');
11699               l_substring_length := INSTR(l_db_column_list, ',', l_start_index) - l_start_index;
11700               l_db_column_tables_index := TO_NUMBER(SUBSTR(l_db_column_list, l_start_index, l_substring_length));
11701 
11702             END IF;
11703 
11704             ---------------------------------------------------------------
11705             -- By default we want to cast the database column values we  --
11706             -- retrieve to strings (for assignment in ATTR_DISP_VALUE);  --
11707             -- the exception to this is if an Attr has a Table Value Set --
11708             -- (in which case the Int -> Disp value query may assume the --
11709             -- data type of the database column to be a Date or Number)  --
11710             ---------------------------------------------------------------
11711             l_to_char_db_col_expression := EGO_USER_ATTRS_COMMON_PVT.Create_DB_Col_Alias_If_Needed(l_curr_attr_metadata_obj,'EMSI');
11712 
11713             IF (l_curr_attr_metadata_obj.INT_TO_DISP_VAL_QUERY IS NULL) THEN
11714 
11715               ----------------------------------------------------------------------
11716               -- If this Attribute does not have a Value Set that distinguishes   --
11717               -- between Internal and Display Values, we just make sure that a    --
11718               -- query for this Database Column name (as determined by the index) --
11719               -- is in the l_db_column_query_table (we don't want to overwrite a  --
11720               -- possibly more complicated query with our simple formatted one,   --
11721               -- which is why we only add it if one doesn't already exist).       --
11722               ----------------------------------------------------------------------
11723               IF (NOT l_db_column_query_table.EXISTS(l_db_column_tables_index)) THEN
11724 
11725                 --ENHR12:changed for passing the internal value of an
11726                 --attribute along with the display value.
11727                 --------------------------------------------------------------------------
11728                 -- Syalaman - Following If condition is added as part of fix for bug 5859465.
11729                 -- If l_to_char_db_col_expression has coloumn name starting with TO_CHAR,
11730                 -- i.e., for ex., TO_CHAR(N_EXT_ATTR1), then add N_EXT_ATTR1 as alias name
11731                 -- to the column.
11732                 --------------------------------------------------------------------------
11733                 IF (InStr(l_to_char_db_col_expression,'TO_CHAR') = 1) THEN
11734                   l_db_column_query_table(l_db_column_tables_index) := l_to_char_db_col_expression|| ' ' ||
11735                                                                       l_curr_db_column_name|| ','||
11736                                                                       l_to_char_db_col_expression||'  INTERNAL_NAME';
11737                 ELSE
11738                   l_db_column_query_table(l_db_column_tables_index) := l_to_char_db_col_expression|| ','||
11739                                                                       l_to_char_db_col_expression||'  INTERNAL_NAME';
11740                 END IF;
11741                 -- end of fix for bug 5859465.
11742 
11743               END IF;
11744 
11745             ELSE
11746 
11747               --------------------------------------------------------------------
11748               -- Since the Attribute has different Internal and Display Values, --
11749               -- we build or update a DECODE query for the Database Column (so  --
11750               -- that each AG's use of the column gets the correct Disp value)  --
11751               --------------------------------------------------------------------
11752               IF (l_curr_attr_metadata_obj.VALIDATION_CODE IN (
11753                   EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE,
11754                   EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE)
11755                  ) THEN
11756 
11757                 l_int_to_disp_val_string := l_curr_attr_metadata_obj.INT_TO_DISP_VAL_QUERY;
11758 
11759               ELSIF (l_curr_attr_metadata_obj.VALIDATION_CODE =
11760                      EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE) THEN
11761 
11762                 ----------------------------------------------------------------
11763                 -- In this case we DON'T want to cast the result to a string, --
11764                 -- so we revert our expression to being the database column   --
11765                 ----------------------------------------------------------------
11766                 l_to_char_db_col_expression := 'EMSI.'||l_curr_db_column_name;
11767 
11768                 ------------------------------------------------------------------
11769                 -- This call will tokenize the query if (and only if) necessary --
11770                 ------------------------------------------------------------------
11771                 l_int_to_disp_val_string := Tokenized_Val_Set_Query(
11772                        p_attr_metadata_obj             => l_curr_attr_metadata_obj
11773                       ,p_attr_group_metadata_obj       => l_curr_ag_metadata_obj
11774                       ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
11775                       ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
11776                       ,p_data_level_name_value_pairs   => l_data_level_name_value_pairs
11777                       ,p_entity_id                     => p_entity_id
11778                       ,p_entity_index                  => p_entity_index
11779                       ,p_entity_code                   => p_entity_code
11780                       ,p_attr_name_value_pairs         => NULL
11781                       ,p_is_disp_to_int_query          => FALSE
11782                       ,p_final_bind_value              => NULL
11783                       ,p_return_bound_sql              => TRUE
11784                      );
11785 
11786               END IF;
11787 
11788               --
11789               -- Bug 1276239. Removed old logic of DECODE(attr_group_id).
11790               -- In old logic we used to build one single SQL for all AGs.
11791               -- So we needed DECODE(attr_group_id). However after version 120.48
11792               -- logic got changed to build one SQL per AG. So we dont need
11793               -- DECODE statements.
11794               -- sreharih. Thu Aug 25 12:44:00 PDT 2011
11795               --
11796 
11797               l_db_column_query_table(l_db_column_tables_index) := '' ||
11798                 '( ' || l_int_to_disp_val_string || ' ' || l_to_char_db_col_expression || ' ) '||l_curr_db_column_name||','||l_to_char_db_col_expression||'  INTERNAL_NAME ';
11799 
11800 
11801             END IF;
11802 
11803             l_attr_list_index := l_requested_attr_names_table.NEXT(l_attr_list_index);
11804           END LOOP attributes_loop;
11805 
11806           --Bug Fix - 3828505
11807         ELSE
11808           Debug_Msg(l_api_name || ' user can NOT view the AG ');
11809         END IF; -- the if check for l_can_view_this_attr_group
11810        END IF;--l_curr_ag_metadata_obj.ATTR_METADATA_TABLE IS NOT NULL--bug 5494760
11811 
11812        --bug 5494760
11813        --if there isn't a single attribute group which has attributes in it, return from
11814        --here itself instead of framing the query and executing it.
11815        IF (l_has_attrs <> 'Y') THEN
11816          Debug_Msg(l_api_name||'  there are no attribute groups in the list that has attributes in it.', 1);
11817          ------------------------------------------------------
11818          -- We log all errors we got as we close our session --
11819          ------------------------------------------------------
11820          Close_Business_Object_Session(
11821           p_init_error_handler_flag    => FND_API.To_Boolean(p_init_error_handler)
11822          ,p_log_errors                 => TRUE
11823          ,p_write_to_concurrent_log    => FALSE
11824          );
11825 
11826          x_return_status := FND_API.G_RET_STS_SUCCESS;
11827          RETURN ;
11828        END IF;
11829 
11830         --------------------------------------------------------------------
11831         -- It's possible that the user did not have sufficient privileges --
11832         -- to view even one of the requested Attr Groups; we need to see  --
11833         -- whether we built any Database Column query components at all   --
11834         --------------------------------------------------------------------
11835         IF (l_db_column_query_table.COUNT > 0) THEN
11836 
11837           --------------------------------------------------------------------------------
11838           -- Loop 1.3                                                                   --
11839           -- Now we build a query list with all of our Database Column query components --
11840           --------------------------------------------------------------------------------
11841           l_db_column_list := '';
11842           FOR i IN l_db_column_query_table.FIRST .. l_db_column_query_table.LAST
11843           LOOP
11844             l_db_column_list := l_db_column_list || l_db_column_query_table(i) || ',';
11845           END LOOP;
11846 
11847           -----------------------------------------------------------------------
11848           -- Trim the trailing bits from the Attr Group ID and DB Column lists --
11849           -----------------------------------------------------------------------
11850           l_db_column_list := RTRIM(l_db_column_list, ',');
11851 
11852           --
11853           -- Bug 1276239. Logic to use fnd_dsql.
11854           -- Encapsulated logic to build pkcol, data level and ag
11855           -- predicates in simple method and calling it from
11856           -- here.
11857           -- sreharih. Thu Aug 25 12:44:00 PDT 2011
11858           --
11859 
11860           fnd_dsql.init();
11861           fnd_dsql.add_text(' SELECT EXTENSION_ID, ATTR_GROUP_ID, '||l_db_column_list||
11862                              ' FROM ' ||NVL(l_curr_ag_vl_name,l_curr_ag_table_name)||' EMSI'||
11863                             ' WHERE ' );
11864           l_add_and := FALSE;
11865 
11866           add_pkcol_predicate (
11867                     p_attr_group_type    => l_curr_ag_metadata_obj.ATTR_GROUP_TYPE,
11868                     p_attr_group_id      => l_curr_ag_metadata_obj.ATTR_GROUP_ID,
11869                     p_data_level         => l_curr_ag_request_obj.DATA_LEVEL,
11870                     p_pkcol_value_pairs  => p_pk_column_name_value_pairs,
11871                     p_pk_column_metadata => l_ext_table_metadata_obj.pk_column_metadata,
11872                     p_add_and            => l_add_and,
11873                     x_predicate_added    => l_predicate_added);
11874 
11875           l_add_and := l_add_and OR l_predicate_added;
11876 
11877           add_datalevel_predicate (
11878                     p_data_level_id            => l_curr_data_level_row_obj.data_level_id,
11879                     p_has_data_level_col       => l_has_data_level_col,
11880                     p_ext_data_level_metadata  => l_ext_table_metadata_obj.data_level_metadata,
11881                     p_data_level_metadata      => l_curr_data_level_metadata,
11882                     p_data_level_value_pairs   => l_data_level_name_value_pairs,
11883                     p_add_and                  => l_add_and,
11884                     x_predicate_added          => l_predicate_added);
11885 
11886           l_add_and := l_add_and OR l_predicate_added;
11887 
11888           add_ag_predicate(
11889                    p_attr_group_id   => l_curr_ag_metadata_obj.attr_group_id,
11890                    p_add_and         => l_add_and,
11891                    x_predicate_added => l_predicate_added);
11892 
11893 
11894           l_dynamic_sql := fnd_dsql.get_text;
11895 
11896 
11897           Debug_Msg(l_dynamic_sql);
11898 
11899           ----------------------------------
11900           -- Open a cursor for processing --
11901           ----------------------------------
11902           l_cursor_id := DBMS_SQL.OPEN_CURSOR;
11903           -------------------------------------
11904           -- Parse our dynamic SQL statement --
11905           -------------------------------------
11906           DBMS_SQL.PARSE(l_cursor_id, l_dynamic_sql, DBMS_SQL.NATIVE);
11907           fnd_dsql.set_cursor(l_cursor_id);
11908           fnd_dsql.do_binds;
11909           --------------------------------------------------------------------------
11910           -- Register the data types of the columns we are selecting in our query --
11911           -- (in the VARCHAR2 case, that includes stating the maximum size that a --
11912           -- value in the column might be; to be safe we will use 1000 bytes).    --
11913           -- First we register the EXTENSION_ID and ATTR_GROUP_ID...              --
11914           --------------------------------------------------------------------------
11915           DBMS_SQL.Define_Column(l_cursor_id, 1, l_extension_id);
11916           DBMS_SQL.Define_Column(l_cursor_id, 2, l_curr_AG_ID);
11917 
11918           -----------------------------------
11919           -- Loop 1.4
11920           -- ...then the Database Columns. --
11921           -----------------------------------
11922           FOR i IN l_db_column_name_table.FIRST .. l_db_column_name_table.LAST
11923           LOOP
11924 
11925 -- Assumption: TVS values will be castable to string (I know all else will be)
11926 
11927             --------------------------------------------------------------------
11928             -- We cast everything to string for assignment to ATTR_DISP_VALUE --
11929             --------------------------------------------------------------------
11930             -- Syalaman - Fix for bug 5859465
11931             DBMS_SQL.Define_Column(l_cursor_id, (i*2)+1, l_varchar_example, 4000); --bug 12979914
11932 
11933             --ENHR12:changed for passing the internal value of the attribute
11934             --along with the display value.
11935             -- Syalaman - Fix for bug 5859465
11936             DBMS_SQL.Define_Column(l_cursor_id, (i*2)+2, l_varchar_example, 4000); --bug 12979914
11937           END LOOP;
11938 
11939           -------------------------------
11940           -- Execute our dynamic query --
11941           -------------------------------
11942           l_dummy := DBMS_SQL.Execute(l_cursor_id);
11943           Debug_Msg(l_api_name||'  executed the query', 3);
11944 
11945           --===============================================================================--
11946           -- Loop 1.5                                                                      --
11947           -- As we loop through the result set rows (which are ordered by ATTR_GROUP_ID),  --
11948           -- we search through l_augmented_data_table (which is also ordered by AG ID).    --
11949           -- Since all augmented data elements for a given AG ID are in a certain index    --
11950           -- range in l_augmented_data_table, we can save time by searching for the record --
11951           -- for a particular AG ID and Database Column only in the subset of the data     --
11952           -- table holding records for that AG ID.  Earlier we recorded the lowest and     --
11953           -- highest index in the data table whose elements corresponded to a given AG ID; --
11954           -- we use those numbers to limit our search to the relevent subsets of the data  --
11955           -- table.  The variables we use for this search bounding are:                    --
11956           -- 1). l_curr_AG_ID, which holds the AG ID for the current result set row,       --
11957           -- 2). l_low_aug_tab_ind_for_AG_ID, which holds the lowest index in the data     --
11958           -- table for an Attribute record belonging to the current AG ID, and             --
11959           -- 3). l_high_aug_tab_ind_for_AG_ID, which holds the highest such index.         --
11960           --===============================================================================--
11961           <<GUAD_all_attributes_loop>>
11962           WHILE (DBMS_SQL.FETCH_ROWS(l_cursor_id) > 0)
11963           LOOP
11964 
11965             ----------------------------------------------------------------
11966             -- Get the EXTENSION_ID and ATTR_GROUP_ID for the current row --
11967             ----------------------------------------------------------------
11968             DBMS_SQL.COLUMN_VALUE(l_cursor_id, 1, l_extension_id);
11969             DBMS_SQL.COLUMN_VALUE(l_cursor_id, 2, l_curr_AG_ID);
11970 
11971             -----------------------------------------------------------------
11972             -- Reset the variable that tells us whether we need to build a --
11973             -- new row object for the out parameter x_attributes_row_table --
11974             -----------------------------------------------------------------
11975             l_need_to_build_a_row_obj := TRUE;
11976 
11977             -- Update the search bounds (they will only change with a new AG ID) --
11978 
11979             l_low_aug_tab_ind_for_AG_ID := l_table_of_low_ind_for_AG_ID(l_curr_AG_ID);
11980             l_high_aug_tab_ind_for_AG_ID := l_table_of_high_ind_for_AG_ID(l_curr_AG_ID);
11981 
11982             --==============================================================--
11983             -- Loop 1.5.1                                                   --
11984             --==============================================================--
11985 
11986             <<GUAD_column_name_loop>>
11987             FOR i IN l_db_column_name_table.FIRST .. l_db_column_name_table.LAST
11988             LOOP
11989               --checking this in case none of the column  for a given i and j match
11990               --and always the l_dbcol_cntr follows the pattern that it will be 1
11991               --less than the i here.
11992               IF(l_dbcol_cntr <i-1) THEN
11993                 l_dbcol_cntr:=i-1;
11994               END IF;
11995               ------------------------------------------------------
11996               -- Clear the record for a fresh start to every loop --
11997               ------------------------------------------------------
11998               l_curr_augmented_attr_rec.ATTR_GROUP_ID := NULL;
11999               l_curr_augmented_attr_rec.APPLICATION_ID := NULL;
12000               l_curr_augmented_attr_rec.ATTR_GROUP_TYPE := NULL;
12001               l_curr_augmented_attr_rec.ATTR_GROUP_NAME := NULL;
12002               l_curr_augmented_attr_rec.ATTR_NAME := NULL;
12003               l_curr_augmented_attr_rec.ATTR_DISP_NAME := NULL;
12004               l_curr_augmented_attr_rec.ATTR_DISP_VALUE := NULL;
12005               l_curr_augmented_attr_rec.ATTR_UNIT_OF_MEASURE := NULL;
12006               l_curr_augmented_attr_rec.DATABASE_COLUMN := NULL;
12007               --ENHR12:added for passing the internal value of the attribute
12008               --along with the display value.
12009               l_curr_augmented_attr_rec.ATTR_VALUE_STR := NULL;
12010               l_curr_augmented_attr_rec.ATTR_VALUE_DATE := NULL;
12011               l_curr_augmented_attr_rec.ATTR_VALUE_NUM := NULL;
12012               l_curr_augmented_attr_rec.DATA_TYPE_CODE := NULL;
12013 
12014 --
12015 --  TO DO: include ATTR_UNIT_OF_MEASURE in the data you pull from the extension table
12016 --
12017 
12018               --============================================================--
12019               -- Loop 1.5.1.1                                               --
12020               -- Search within the range of augmented Data records for this --
12021               -- AG ID                                                      --
12022               --============================================================--
12023               <<GUAD_augmented_data_recs_loop>>
12024               FOR j IN l_low_aug_tab_ind_for_AG_ID .. l_high_aug_tab_ind_for_AG_ID
12025               LOOP
12026                 EXIT WHEN (l_curr_augmented_attr_rec.ATTR_GROUP_ID IS NOT NULL);
12027                 --------------------------------------------------------
12028                 -- If the current Data record is associated with the  --
12029                 -- current Database Column, store the column's value  --
12030                 -- temporarily (we will build an Attr Data object for --
12031                 -- it in a few more lines).                           --
12032                 --------------------------------------------------------
12033                 IF (l_db_column_name_table(i) = l_augmented_data_table(j).DATABASE_COLUMN) THEN
12034                   l_curr_augmented_attr_rec := l_augmented_data_table(j);
12035 
12036                   --ENHR12:added for passing the internal value of the attribute
12037                   --along with the display value.
12038                   --setting the Display Value.
12039                   DBMS_SQL.COLUMN_VALUE(l_cursor_id, (i*2)+1, l_curr_augmented_attr_rec.ATTR_DISP_VALUE); -- Fix for bug 5859465
12040 
12041                   --setting the intrnal value of the Attribute depending on the DATA_TYPE_CODE
12042                   --if the attribute is of type Translatable(A) or Char(C)
12043                   IF ('C'=l_curr_augmented_attr_rec.DATA_TYPE_CODE OR 'A'=l_curr_augmented_attr_rec.DATA_TYPE_CODE) THEN
12044                      DBMS_SQL.COLUMN_VALUE(l_cursor_id, (i*2)+2, l_curr_augmented_attr_rec.ATTR_VALUE_STR); -- Fix for bug 5859465
12045                      l_curr_augmented_attr_rec.ATTR_VALUE_DATE:=null;
12046                      l_curr_augmented_attr_rec.ATTR_VALUE_NUM:=null;
12047                       --if the attribute is of type Date(X) or DateTime(Y)
12048                   ELSIF('X'=l_curr_augmented_attr_rec.DATA_TYPE_CODE OR 'Y'=l_curr_augmented_attr_rec.DATA_TYPE_CODE) THEN
12049                      DBMS_SQL.COLUMN_VALUE(l_cursor_id, (i*2)+2,l_char_value);  -- Fix for bug 5859465
12050                      l_curr_augmented_attr_rec.ATTR_VALUE_STR:=null;
12051                      l_curr_augmented_attr_rec.ATTR_VALUE_NUM:=null;
12052                      l_curr_augmented_attr_rec.ATTR_VALUE_DATE:=TO_DATE(l_char_value,'yyyy/mm/dd HH24:MI:SS');
12053                       --if the attribute is of type NUMBER(N)
12054                   ELSIF('N'=l_curr_augmented_attr_rec.DATA_TYPE_CODE) THEN
12055                     DBMS_SQL.COLUMN_VALUE(l_cursor_id, (i*2)+2, l_char_value);  -- Fix for bug 5859465
12056                     l_curr_augmented_attr_rec.ATTR_VALUE_STR:=null;
12057                     l_curr_augmented_attr_rec.ATTR_VALUE_DATE:=null;
12058                     l_curr_augmented_attr_rec.ATTR_VALUE_NUM:=TO_NUMBER(l_char_value);
12059                     --bug 8218727
12060                     /*FP bug 8547119 with base bug 8545032, remove the IF clause
12061                     IF(l_curr_attr_metadata_obj.UNIT_OF_MEASURE_CLASS IS NOT NULL) THEN*/
12062 
12063                     /*FP bug 8547119 with base bug 8545032, remove the IF clause
12064                     END IF;--end if for l_curr_attr_metadata_obj.UNIT_OF_MEASURE_CLASS IS NOT NULL*/
12065 
12066                     l_attr_list_index := l_requested_attr_names_table.FIRST;
12067                     WHILE (l_attr_list_index <= l_requested_attr_names_table.LAST)
12068                     LOOP
12069 
12070                       IF (l_curr_augmented_attr_rec.ATTR_NAME = l_requested_attr_names_table(l_attr_list_index)) THEN
12071                         l_new_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
12072                                           p_attr_metadata_table => l_curr_ag_metadata_obj.attr_metadata_table
12073                                          ,p_attr_name           => l_requested_attr_names_table(l_attr_list_index)
12074                                         );
12075                         exit;
12076                       END IF;
12077                       l_attr_list_index := l_requested_attr_names_table.NEXT(l_attr_list_index);
12078                     END LOOP;
12079                    IF(l_new_attr_metadata_obj.UNIT_OF_MEASURE_CLASS IS NOT NULL) THEN
12080 
12081                         --
12082                         -- Bug 1276239. Encapsulated logic to find
12083                         -- uom value in get_uom_value method which
12084                         -- will use fnd_dsql to build and execute
12085                         -- query.
12086                         -- sreharih. Thu Aug 25 12:44:00 PDT 2011
12087                         --
12088 
12089                      l_uom_value := get_uom_value (
12090                                         p_uom_db_column_name => 'UOM'||substr(l_augmented_data_table(j).DATABASE_COLUMN,2),
12091                                         p_table_name         => NVL(l_curr_ag_vl_name,l_curr_ag_table_name),
12092                                         p_extension_id       => l_extension_id);
12093 
12094                      l_curr_augmented_attr_rec.ATTR_UNIT_OF_MEASURE := l_uom_value;
12095 
12096                      l_conv_rate := 1;
12097 
12098                      SELECT CONVERSION_RATE
12099                        INTO l_conv_rate
12100                        FROM MTL_UOM_CONVERSIONS
12101                       WHERE UOM_CLASS = l_new_attr_metadata_obj.UNIT_OF_MEASURE_CLASS
12102                         AND UOM_CODE = NVL(l_uom_value, l_new_attr_metadata_obj.UNIT_OF_MEASURE_BASE)
12103                         AND ROWNUM = 1;
12104 
12105                      IF(l_conv_rate = 0) THEN l_conv_rate := 1; END IF;
12106                      l_curr_augmented_attr_rec.ATTR_VALUE_NUM := l_curr_augmented_attr_rec.ATTR_VALUE_NUM/l_conv_rate;
12107                      l_curr_augmented_attr_rec.ATTR_DISP_VALUE := l_curr_augmented_attr_rec.ATTR_VALUE_NUM;
12108                    END IF;
12109                    -- end of fixing bug 8218727
12110                   END IF;
12111 
12112                   -----------------------------------------------------------
12113                   -- If this is the first Data record for the current row, --
12114                   -- we build a Row object and put it into the row table.  --
12115                   -----------------------------------------------------------
12116                   IF (l_need_to_build_a_row_obj) THEN
12117                     IF (x_attributes_row_table IS NULL) THEN
12118                       x_attributes_row_table := EGO_USER_ATTR_ROW_TABLE();
12119                     END IF;
12120                     x_attributes_row_table.EXTEND();
12121                     IF l_has_data_level_col THEN
12122                       x_attributes_row_table(x_attributes_row_table.LAST) :=
12123                         EGO_USER_ATTR_ROW_OBJ(
12124                           l_extension_id
12125                          ,l_curr_augmented_attr_rec.ATTR_GROUP_ID
12126                          ,l_curr_augmented_attr_rec.APPLICATION_ID
12127                          ,l_curr_augmented_attr_rec.ATTR_GROUP_TYPE
12128                          ,l_curr_augmented_attr_rec.ATTR_GROUP_NAME
12129                          ,l_curr_ag_request_obj.data_level        -- DATA_LEVEL
12130                          ,l_curr_ag_request_obj.data_level_1    -- DATA_LEVEL_1
12131                          ,l_curr_ag_request_obj.data_level_2    -- DATA_LEVEL_2
12132                          ,l_curr_ag_request_obj.data_level_3    -- DATA_LEVEL_3
12133                          ,l_curr_ag_request_obj.data_level_4    -- DATA_LEVEL_4
12134                          ,l_curr_ag_request_obj.data_level_5    -- DATA_LEVEL_5
12135                          ,null                              -- TRANSACTION_TYPE
12136                         );
12137                     ELSE
12138                       x_attributes_row_table(x_attributes_row_table.LAST) :=
12139                         EGO_USER_ATTR_ROW_OBJ(
12140                           l_extension_id
12141                          ,l_curr_augmented_attr_rec.ATTR_GROUP_ID
12142                          ,l_curr_augmented_attr_rec.APPLICATION_ID
12143                          ,l_curr_augmented_attr_rec.ATTR_GROUP_TYPE
12144                          ,l_curr_augmented_attr_rec.ATTR_GROUP_NAME
12145                          ,NULL                                    -- DATA_LEVEL
12146                          ,NULL                                  -- DATA_LEVEL_1
12147                          ,NULL                                  -- DATA_LEVEL_2
12148                          ,NULL                                  -- DATA_LEVEL_3
12149                          ,NULL                                  -- DATA_LEVEL_4
12150                          ,NULL                                  -- DATA_LEVEL_5
12151                          ,NULL                              -- TRANSACTION_TYPE
12152                         );
12153                     END IF;
12154                     l_need_to_build_a_row_obj := FALSE;
12155                   END IF;
12156 
12157                   -----------------------------------------------------
12158                   -- Once we have the value for this Data record, we --
12159                   -- put a Data object for it into the result table; --
12160                   -- the caller will later use ROW_IDENTIFIER (which --
12161                   -- in our case is l_extension_id) to find a row    --
12162                   -- object for any data object.                     --
12163                   -----------------------------------------------------
12164                   IF (x_attributes_data_table IS NULL) THEN
12165                     x_attributes_data_table := EGO_USER_ATTR_DATA_TABLE();
12166                   END IF;
12167 
12168                   x_attributes_data_table.EXTEND();
12169                   x_attributes_data_table(x_attributes_data_table.LAST) :=
12170                   --changed as a part of
12171                   --ENHR12:for passing the internal value of the attribute along
12172                   --with the display value.
12173                     EGO_USER_ATTR_DATA_OBJ(
12174                       l_extension_id
12175                      ,l_curr_augmented_attr_rec.ATTR_NAME
12176                      ,l_curr_augmented_attr_rec.ATTR_VALUE_STR-- ATTR_VALUE_STR
12177                      ,l_curr_augmented_attr_rec.ATTR_VALUE_NUM-- ATTR_VALUE_NUM
12178                      ,l_curr_augmented_attr_rec.ATTR_VALUE_DATE
12179                                                              -- ATTR_VALUE_DATE
12180                      ,l_curr_augmented_attr_rec.ATTR_DISP_VALUE
12181                      ,l_curr_augmented_attr_rec.ATTR_UNIT_OF_MEASURE    -- ATTR_UNIT_OF_MEASURE --Bug#7662816
12182                      ,null                               -- USER_ROW_IDENTIFIER
12183                     );
12184 
12185 Debug_Msg(l_api_name || l_curr_augmented_attr_rec.ATTR_NAME || ' = ' || l_curr_augmented_attr_rec.ATTR_VALUE_STR   );
12186 
12187                 END IF;
12188               END LOOP GUAD_augmented_data_recs_loop;
12189             END LOOP GUAD_column_name_loop;
12190           END LOOP GUAD_all_attributes_loop;
12191 
12192           -----------------------------------------
12193           -- Close the cursor when we're through --
12194           -----------------------------------------
12195           IF (l_cursor_id IS NOT NULL) THEN
12196             DBMS_SQL.Close_Cursor(l_cursor_id);
12197             l_cursor_id := NULL;
12198           END IF;
12199         ELSE
12200 Debug_Msg(l_api_name||' l_db_column_query_table.COUNT = ' || l_db_column_query_table.COUNT, 1);
12201         END IF;  -- l_db_column_query_table.COUNT
12202 
12203         l_dbcol_cntr := 0;
12204         l_db_column_name_table.DELETE;
12205         l_db_column_query_table.DELETE;
12206         l_request_table_index := p_attr_group_request_table.NEXT(l_request_table_index);
12207       END LOOP GUAD_ag_requests_loop;
12208 
12209     END IF;
12210 
12211     Debug_Msg(l_api_name||'  done', 1);
12212 
12213     ------------------------------------------------------
12214     -- We log all errors we got as we close our session --
12215     ------------------------------------------------------
12216     Close_Business_Object_Session(
12217       p_init_error_handler_flag       => FND_API.To_Boolean(p_init_error_handler)
12218      ,p_log_errors                    => TRUE
12219      ,p_write_to_concurrent_log       => FALSE
12220     );
12221 
12222     x_return_status := FND_API.G_RET_STS_SUCCESS;
12223 
12224   EXCEPTION
12225 
12226     WHEN FND_API.G_EXC_ERROR THEN
12227       Debug_Msg(l_api_name || ' FND_API.G_EXC_ERROR '||SQLERRM);
12228       -----------------------------------------
12229       -- Close the cursor if it's still open --
12230       -----------------------------------------
12231       IF (l_cursor_id IS NOT NULL) THEN
12232         DBMS_SQL.Close_Cursor(l_cursor_id);
12233         l_cursor_id := NULL;
12234       END IF;
12235 
12236       ------------------------------------------------------
12237       -- We log all errors we got as we close our session --
12238       ------------------------------------------------------
12239       Close_Business_Object_Session(
12240         p_init_error_handler_flag       => FND_API.To_Boolean(p_init_error_handler)
12241        ,p_log_errors                    => TRUE
12242        ,p_write_to_concurrent_log       => FALSE
12243       );
12244 
12245       x_return_status := FND_API.G_RET_STS_ERROR;
12246 
12247       x_msg_count := ERROR_HANDLER.Get_Message_Count();
12248       IF (x_msg_count = 1) THEN
12249         DECLARE
12250           message_list  ERROR_HANDLER.Error_Tbl_Type;
12251         BEGIN
12252           ERROR_HANDLER.Get_Message_List(message_list);
12253           x_msg_data := message_list(message_list.FIRST).message_text;
12254         END;
12255       ELSE
12256         x_msg_data := NULL;
12257       END IF;
12258 
12259     WHEN OTHERS THEN
12260 
12261       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM);
12262       -----------------------------------------
12263       -- Close the cursor if it's still open --
12264       -----------------------------------------
12265       IF (l_cursor_id IS NOT NULL) THEN
12266         DBMS_SQL.Close_Cursor(l_cursor_id);
12267         l_cursor_id := NULL;
12268       END IF;
12269       ------------------------------------------------------
12270       -- We log all errors we got as we close our session --
12271       ------------------------------------------------------
12272       Close_Business_Object_Session(
12273         p_init_error_handler_flag       => FND_API.To_Boolean(p_init_error_handler)
12274        ,p_log_errors                    => TRUE
12275        ,p_write_to_concurrent_log       => FALSE
12276       );
12277 
12278       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
12279       l_token_table(1).TOKEN_NAME := 'PKG_NAME';
12280       l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
12281       l_token_table(2).TOKEN_NAME := 'API_NAME';
12282       l_token_table(2).TOKEN_VALUE := l_api_name;
12283       l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
12284       l_token_table(3).TOKEN_VALUE := SQLERRM;
12285 
12286       ERROR_HANDLER.Add_Error_Message(
12287         p_message_name              => 'EGO_PLSQL_ERR'
12288        ,p_application_id            => 'EGO'
12289        ,p_token_tbl                 => l_token_table
12290        ,p_message_type              => FND_API.G_RET_STS_ERROR
12291        ,p_row_identifier            => G_USER_ROW_IDENTIFIER
12292        ,p_entity_id                 => p_entity_id
12293        ,p_entity_index              => p_entity_index
12294        ,p_entity_code               => p_entity_code
12295        ,p_addto_fnd_stack           => G_ADD_ERRORS_TO_FND_STACK
12296       );
12297       l_token_table.DELETE();
12298       x_msg_count := ERROR_HANDLER.Get_Message_Count();
12299 
12300       IF (x_msg_count = 1) THEN
12301         DECLARE
12302           message_list  ERROR_HANDLER.Error_Tbl_Type;
12303         BEGIN
12304           ERROR_HANDLER.Get_Message_List(message_list);
12305           IF message_list IS NOT NULL AND message_list.count > 0 THEN
12306             x_msg_data := message_list(message_list.FIRST).message_text;
12307           ELSE
12308             x_msg_data := 'Where from did I come here?? ';
12309           END IF;
12310         END;
12311       ELSE
12312         x_msg_data := NULL;
12313       END IF;
12314 
12315 END Get_User_Attrs_Data;
12316 
12317 ----------------------------------------------------------------------
12318 
12319 PROCEDURE Process_Row (
12320         p_api_version                   IN   NUMBER
12321        ,p_object_id                     IN   NUMBER     DEFAULT NULL
12322        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
12323        ,p_attr_group_id                 IN   NUMBER     DEFAULT NULL
12324        ,p_application_id                IN   NUMBER     DEFAULT NULL
12325        ,p_attr_group_type               IN   VARCHAR2   DEFAULT NULL
12326        ,p_attr_group_name               IN   VARCHAR2   DEFAULT NULL
12327        ,p_validate_hierarchy            IN   VARCHAR2   DEFAULT FND_API.G_TRUE--Added for bugFix:5275391
12328        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12329        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12330        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
12331        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12332        ,p_extension_id                  IN   NUMBER     DEFAULT NULL
12333        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
12334        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
12335        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
12336        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
12337        ,p_validate_only                 IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12338        ,p_language_to_process           IN   VARCHAR2   DEFAULT NULL
12339        ,p_mode                          IN   VARCHAR2   DEFAULT G_SYNC_MODE
12340        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
12341        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
12342        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT NULL
12343        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT NULL
12344        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12345        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12346        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12347        ,p_raise_business_event          IN   BOOLEAN DEFAULT TRUE
12348        ,x_return_status                 OUT NOCOPY VARCHAR2
12349        ,x_errorcode                     OUT NOCOPY NUMBER
12350        ,x_msg_count                     OUT NOCOPY NUMBER
12351        ,x_msg_data                      OUT NOCOPY VARCHAR2
12352 ) IS
12353     l_extension_id           NUMBER;
12354     l_mode                   VARCHAR2(10);
12355 
12356   BEGIN
12357 
12358       Process_Row(
12359         p_api_version                   => p_api_version
12360        ,p_object_name                   => p_object_name
12361        ,p_attr_group_id                 => p_attr_group_id
12362        ,p_application_id                => p_application_id
12363        ,p_attr_group_type               => p_attr_group_type
12364        ,p_attr_group_name               => p_attr_group_name
12365        ,p_validate_hierarchy            => p_validate_hierarchy
12366        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
12367        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
12368        ,p_data_level                    => p_data_level
12369        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
12370        ,p_extension_id                  => p_extension_id
12371        ,p_attr_name_value_pairs         => p_attr_name_value_pairs
12372        ,p_validate_only                 => p_validate_only
12373        ,p_language_to_process           => p_language_to_process --bug 	10065435
12374        ,p_mode                          => p_mode
12375        ,p_change_obj                    => p_change_obj
12376        ,p_pending_b_table_name          => p_pending_b_table_name
12377        ,p_pending_tl_table_name         => p_pending_tl_table_name
12378        ,p_pending_vl_name               => p_pending_vl_name
12379        ,p_entity_id                     => p_entity_id
12380        ,p_entity_index                  => p_entity_index
12381        ,p_entity_code                   => p_entity_code
12382        ,p_raise_business_event                   => p_raise_business_event
12383        ,x_extension_id                  => l_extension_id
12384        ,x_mode                          => l_mode
12385        ,x_return_status                 => x_return_status
12386        ,x_errorcode                     => x_errorcode
12387        ,x_msg_count                     => x_msg_count
12388        ,x_msg_data                      => x_msg_data
12389       );
12390 
12391 END Process_Row;
12392 
12393 ------------------------------------------------------------------------------------------
12394 
12395 PROCEDURE Process_Row (
12396         p_api_version                   IN   NUMBER
12397        ,p_object_id                     IN   NUMBER     DEFAULT NULL
12398        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
12399        ,p_attr_group_id                 IN   NUMBER     DEFAULT NULL
12400        ,p_application_id                IN   NUMBER     DEFAULT NULL
12401        ,p_attr_group_type               IN   VARCHAR2   DEFAULT NULL
12402        ,p_attr_group_name               IN   VARCHAR2   DEFAULT NULL
12403        ,p_validate_hierarchy            IN   VARCHAR2   DEFAULT FND_API.G_TRUE--Added for bugFix:5275391
12404        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12405        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12406        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
12407        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12408        ,p_extension_id                  IN   NUMBER     DEFAULT NULL
12409        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
12410        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
12411        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
12412        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
12413        ,p_validate_only                 IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12414        ,p_language_to_process           IN   VARCHAR2   DEFAULT NULL
12415        ,p_mode                          IN   VARCHAR2   DEFAULT G_SYNC_MODE
12416        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
12417        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
12418        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT NULL
12419        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT NULL
12420        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12421        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12422        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12423        ,p_raise_business_event          IN   BOOLEAN DEFAULT TRUE
12424        ,x_extension_id                  OUT NOCOPY NUMBER
12425        ,x_mode                          OUT NOCOPY VARCHAR2
12426        ,x_return_status                 OUT NOCOPY VARCHAR2
12427        ,x_errorcode                     OUT NOCOPY NUMBER
12428        ,x_msg_count                     OUT NOCOPY NUMBER
12429        ,x_msg_data                      OUT NOCOPY VARCHAR2
12430 ) IS
12431 
12432     l_api_name               CONSTANT VARCHAR2(30) := 'Process_Row';
12433 
12434     --we don't use l_api_version yet, but eventually we might:
12435     --if we change required parameters, version goes FROM n.x to (n+1).x
12436     --if we change optional parameters, version goes FROM x.n to x.(n+1)
12437     l_api_version            CONSTANT NUMBER := 1.0;
12438 
12439     l_object_id              NUMBER;
12440     l_attr_name_value_pairs   EGO_USER_ATTR_DATA_TABLE;
12441     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
12442     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
12443     l_extension_id           NUMBER;
12444     l_mode                   VARCHAR2(10);
12445 
12446 
12447   BEGIN
12448 
12449     Debug_Msg(l_api_name || ' starting ',1);
12450 
12451     -- SAVEPOINT Process_Row_PUB;
12452     -- (See EXCEPTION notes for why this is commented out)
12453 
12454     -- Check for call compatibility
12455     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
12456                                         l_api_name, G_PKG_NAME)
12457     THEN
12458       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
12459     END IF;
12460 
12461     l_object_id := p_object_id;
12462     l_attr_name_value_pairs := p_attr_name_value_pairs;
12463 
12464     Debug_Msg(l_api_name || ' calling  Perform_Setup_Operations ',1);
12465     Perform_Setup_Operations(
12466         p_object_name                   => p_object_name
12467        ,p_attr_group_id                 => p_attr_group_id
12468        ,p_application_id                => p_application_id
12469        ,p_attr_group_type               => p_attr_group_type
12470        ,p_attr_group_name               => p_attr_group_name
12471        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
12472        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
12473        ,p_data_level                    => p_data_level
12474        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
12475        ,p_extension_id                  => p_extension_id
12476        ,p_entity_id                     => p_entity_id
12477        ,p_entity_index                  => p_entity_index
12478        ,p_entity_code                   => p_entity_code
12479        ,p_mode                          => p_mode
12480        ,p_change_obj                    => p_change_obj
12481        ,p_pending_b_table_name          => p_pending_b_table_name
12482        ,p_pending_vl_name               => p_pending_vl_name
12483        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
12484        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
12485        ,px_object_id                    => l_object_id
12486        ,px_attr_name_value_pairs        => l_attr_name_value_pairs
12487        ,x_attr_group_metadata_obj       => l_attr_group_metadata_obj
12488        ,x_ext_table_metadata_obj        => l_ext_table_metadata_obj
12489        ,x_extension_id                  => l_extension_id
12490        ,x_mode                          => l_mode
12491        ,x_return_status                 => x_return_status
12492     );
12493     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12494       RAISE FND_API.G_EXC_ERROR;
12495     END IF;
12496 
12497     IF l_extension_id IS NOT NULL THEN
12498       x_extension_id := l_extension_id;
12499     END IF;
12500 
12501     IF l_mode IS NOT NULL THEN
12502       x_mode := l_mode;
12503     END IF;
12504 
12505     ------------------------------------------------------------
12506     -- If the Attr Group is secured (either explicitly or by  --
12507     -- default privileges for this Object) AND the caller has --
12508     -- passed a table of privileges, then we ensure that the  --
12509     -- user has the required privileges for this Attr Group   --
12510     ------------------------------------------------------------
12511     IF ((l_attr_group_metadata_obj.VIEW_PRIVILEGE IS NOT NULL OR
12512          l_attr_group_metadata_obj.EDIT_PRIVILEGE IS NOT NULL) AND
12513         G_CURRENT_USER_PRIVILEGES IS NOT NULL) THEN
12514 
12515     Debug_Msg(l_api_name || ' calling Check_Privileges ',1);
12516       Check_Privileges(
12517         p_attr_group_metadata_obj  => l_attr_group_metadata_obj
12518        ,p_data_level_row_obj       => NULL
12519        ,p_entity_id                => p_entity_id
12520        ,p_entity_index             => p_entity_index
12521        ,p_entity_code              => p_entity_code
12522        ,x_return_status            => x_return_status
12523       );
12524 
12525       IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12526         RAISE FND_API.G_EXC_ERROR;
12527       END IF;
12528     END IF;
12529 
12530     IF (l_mode IS NULL OR
12531         l_mode <> G_DELETE_MODE) THEN
12532 
12533     Debug_Msg(l_api_name || ' calling Validate_Row_Pvt ',1);
12534       Validate_Row_Pvt(
12535         p_api_version                   => p_api_version
12536        ,p_object_id                     => l_object_id
12537        ,p_validate_hierarchy            => p_validate_hierarchy
12538        ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
12539        ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
12540        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
12541        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
12542        ,p_data_level                    => p_data_level
12543        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
12544        ,p_extension_id                  => l_extension_id
12545        ,p_entity_id                     => p_entity_id
12546        ,p_entity_index                  => p_entity_index
12547        ,p_entity_code                   => p_entity_code
12548        ,p_mode                          => l_mode
12549        ,px_attr_name_value_pairs        => l_attr_name_value_pairs
12550        ,x_return_status                 => x_return_status
12551       );
12552       IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12553         RAISE FND_API.G_EXC_ERROR;
12554       END IF;
12555     END IF;
12556 
12557 
12558     IF( p_validate_only = FND_API.G_FALSE) THEN
12559 
12560       Debug_Msg(l_api_name||' done with Validate_Row_Pvt and about to call Perform_DML_On_Row_Pvt', 2);
12561 
12562       Perform_DML_On_Row_Pvt(
12563           p_api_version                   => p_api_version
12564          ,p_object_id                     => l_object_id
12565          ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
12566          ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
12567          ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
12568          ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
12569          ,p_data_level                    => p_data_level
12570          ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
12571          ,p_extension_id                  => l_extension_id
12572          ,p_attr_name_value_pairs         => l_attr_name_value_pairs
12573          ,p_language_to_process           => p_language_to_process
12574          ,p_mode                          => l_mode
12575          ,p_change_obj                    => p_change_obj
12576          ,p_pending_b_table_name          => p_pending_b_table_name
12577          ,p_pending_tl_table_name         => p_pending_tl_table_name
12578          ,p_entity_id                     => p_entity_id
12579          ,p_entity_index                  => p_entity_index
12580          ,p_entity_code                   => p_entity_code
12581          ,p_commit                        => FND_API.G_FALSE
12582          ,p_raise_business_event          => p_raise_business_event
12583          ,x_extension_id                  => x_extension_id
12584          ,x_return_status                 => x_return_status
12585       );
12586       IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12587         RAISE FND_API.G_EXC_ERROR;
12588       END IF;
12589 
12590       Debug_Msg('In Process_Row, done', 1);
12591 
12592     END IF;
12593 
12594     IF FND_API.To_Boolean(p_commit) THEN
12595       COMMIT WORK;
12596     END IF;
12597 
12598     x_return_status := FND_API.G_RET_STS_SUCCESS;
12599 
12600   EXCEPTION
12601     ----------------------------------------------------------------------------
12602     -- We don't do a ROLLBACK in this exception block; all exceptions will    --
12603     -- be either from nested API calls failing, in which case those APIs      --
12604     -- will have done ROLLBACKs already, or from some errors in this API      --
12605     -- itself, which doesn't do any DML operations and so has nothing to      --
12606     -- roll back.  (Also, when I was building this package and had a ROLLBACK --
12607     -- call in this exception block, I kept getting the following error:      --
12608     --                                                                        --
12609     --       'ORA-01086: savepoint 'PROCESS_ROW_PUB' never established'       --
12610     --                                                                        --
12611     -- so I took out the ROLLBACK call, which wasn't necessary anyway.)       --
12612     ----------------------------------------------------------------------------
12613 
12614     WHEN FND_API.G_EXC_ERROR THEN
12615       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR');
12616 
12617       IF FND_API.To_Boolean(p_commit) THEN
12618         COMMIT WORK;
12619       END IF;
12620       x_msg_count := ERROR_HANDLER.Get_Message_Count();
12621       IF (x_msg_count = 1) THEN
12622         DECLARE
12623           message_list  ERROR_HANDLER.Error_Tbl_Type;
12624         BEGIN
12625           ERROR_HANDLER.Get_Message_List(message_list);
12626           x_msg_data := message_list(message_list.FIRST).message_text;
12627         END;
12628       ELSE
12629         x_msg_data := NULL;
12630       END IF;
12631 
12632     WHEN OTHERS THEN
12633       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM);
12634       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
12635       DECLARE
12636         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
12637       BEGIN
12638         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
12639         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
12640         l_token_table(2).TOKEN_NAME := 'API_NAME';
12641         l_token_table(2).TOKEN_VALUE := l_api_name;
12642         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
12643         l_token_table(3).TOKEN_VALUE := SQLERRM;
12644 
12645         ERROR_HANDLER.Add_Error_Message(
12646           p_message_name      => 'EGO_PLSQL_ERR'
12647          ,p_application_id    => 'EGO'
12648          ,p_token_tbl         => l_token_table
12649          ,p_message_type      => FND_API.G_RET_STS_ERROR
12650          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
12651          ,p_entity_id         => p_entity_id
12652          ,p_entity_index      => p_entity_index
12653          ,p_entity_code       => p_entity_code
12654          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
12655         );
12656       END;
12657 
12658       x_msg_count := ERROR_HANDLER.Get_Message_Count();
12659 
12660       IF (x_msg_count = 1) THEN
12661         DECLARE
12662           message_list  ERROR_HANDLER.Error_Tbl_Type;
12663         BEGIN
12664           ERROR_HANDLER.Get_Message_List(message_list);
12665           x_msg_data := message_list(message_list.FIRST).message_text;
12666         END;
12667       ELSE
12668         x_msg_data := NULL;
12669       END IF;
12670 
12671 END Process_Row;
12672 
12673 ----------------------------------------------------------------------
12674 
12675 -- This version just performs some preliminary setup operations and
12676 -- and then calls the "private" signature, Validate_Row_Pvt
12677 
12678 PROCEDURE Validate_Row (
12679         p_api_version                   IN   NUMBER
12680        ,p_object_id                     IN   NUMBER     DEFAULT NULL
12681        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
12682        ,p_attr_group_id                 IN   NUMBER     DEFAULT NULL
12683        ,p_application_id                IN   NUMBER     DEFAULT NULL
12684        ,p_attr_group_type               IN   VARCHAR2   DEFAULT NULL
12685        ,p_attr_group_name               IN   VARCHAR2   DEFAULT NULL
12686        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12687        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12688        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
12689        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12690        ,p_extension_id                  IN   NUMBER     DEFAULT NULL
12691        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
12692        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
12693        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
12694        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
12695        ,p_mode                          IN   VARCHAR2   DEFAULT G_SYNC_MODE
12696        ,p_log_errors                    IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12697        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12698        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12699        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12700        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12701        ,x_return_status                 OUT NOCOPY VARCHAR2
12702        ,x_errorcode                     OUT NOCOPY NUMBER
12703        ,x_msg_count                     OUT NOCOPY NUMBER
12704        ,x_msg_data                      OUT NOCOPY VARCHAR2
12705 ) IS
12706 
12707     l_api_name               CONSTANT VARCHAR2(30) := 'Validate_Row';
12708 
12709     --we don't use l_api_version yet, but eventually we might:
12710     --if we change required parameters, version goes FROM n.x to (n+1).x
12711     --if we change optional parameters, version goes FROM x.n to x.(n+1)
12712     l_api_version            CONSTANT NUMBER := 1.0;
12713 
12714     l_object_id              NUMBER;
12715     l_attr_name_value_pairs   EGO_USER_ATTR_DATA_TABLE;
12716     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
12717     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
12718     l_extension_id           NUMBER;
12719     l_mode                   VARCHAR2(10);
12720 
12721   BEGIN
12722 
12723     Debug_Msg(l_api_name||' starting ', 1);
12724 
12725     IF FND_API.To_Boolean(p_commit) THEN
12726       SAVEPOINT Validate_Row_PUB;
12727     END IF;
12728 
12729     -- Check for call compatibility
12730     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
12731                                         l_api_name, G_PKG_NAME)
12732     THEN
12733       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
12734     END IF;
12735 
12736 -----------------------------------
12737 
12738     l_object_id := p_object_id;
12739     l_attr_name_value_pairs := p_attr_name_value_pairs;
12740 
12741     Perform_Setup_Operations(
12742         p_object_name                   => p_object_name
12743        ,p_attr_group_id                 => p_attr_group_id
12744        ,p_application_id                => p_application_id
12745        ,p_attr_group_type               => p_attr_group_type
12746        ,p_attr_group_name               => p_attr_group_name
12747        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
12748        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
12749        ,p_data_level                    => p_data_level
12750        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
12751        ,p_extension_id                  => p_extension_id
12752        ,p_entity_id                     => p_entity_id
12753        ,p_entity_index                  => p_entity_index
12754        ,p_entity_code                   => p_entity_code
12755        ,p_mode                          => p_mode
12756        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
12757        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
12758        ,px_object_id                    => l_object_id
12759        ,px_attr_name_value_pairs        => l_attr_name_value_pairs
12760        ,x_attr_group_metadata_obj       => l_attr_group_metadata_obj
12761        ,x_ext_table_metadata_obj        => l_ext_table_metadata_obj
12762        ,x_extension_id                  => l_extension_id
12763        ,x_mode                          => l_mode
12764        ,x_return_status                 => x_return_status
12765     );
12766     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12767       RAISE FND_API.G_EXC_ERROR;
12768     END IF;
12769 
12770     Debug_Msg(l_api_name||' calling Validate_Row_Pvt ', 1);
12771     Validate_Row_Pvt(
12772         p_api_version                   => p_api_version
12773        ,p_object_id                     => l_object_id
12774        ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
12775        ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
12776        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
12777        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
12778        ,p_data_level                    => p_data_level
12779        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
12780        ,p_extension_id                  => l_extension_id
12781        ,p_entity_id                     => p_entity_id
12782        ,p_entity_index                  => p_entity_index
12783        ,p_entity_code                   => p_entity_code
12784        ,p_mode                          => l_mode
12785        ,px_attr_name_value_pairs        => l_attr_name_value_pairs
12786        ,x_return_status                 => x_return_status
12787     );
12788     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12789       RAISE FND_API.G_EXC_ERROR;
12790     END IF;
12791 
12792     Close_Business_Object_Session(
12793       p_init_error_handler_flag       => FALSE
12794      ,p_log_errors                    => FND_API.To_Boolean(p_log_errors)
12795      ,p_write_to_concurrent_log       => FND_API.To_Boolean(p_write_to_concurrent_log)
12796     );
12797 
12798     IF FND_API.To_Boolean(p_commit) THEN
12799       COMMIT WORK;
12800     END IF;
12801 
12802     x_return_status := FND_API.G_RET_STS_SUCCESS;
12803     Debug_Msg(l_api_name||' ending ', 1);
12804 
12805   EXCEPTION
12806     WHEN FND_API.G_EXC_ERROR THEN
12807       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR');
12808       IF FND_API.To_Boolean(p_commit) THEN
12809         ROLLBACK TO Validate_Row_PUB;
12810       END IF;
12811       Close_Business_Object_Session(
12812         p_init_error_handler_flag     => FALSE
12813        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
12814        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
12815       );
12816 
12817       x_msg_count := ERROR_HANDLER.Get_Message_Count();
12818       IF (x_msg_count = 1) THEN
12819         DECLARE
12820           message_list  ERROR_HANDLER.Error_Tbl_Type;
12821         BEGIN
12822           ERROR_HANDLER.Get_Message_List(message_list);
12823           x_msg_data := message_list(message_list.FIRST).message_text;
12824         END;
12825       ELSE
12826         x_msg_data := NULL;
12827       END IF;
12828 
12829     WHEN OTHERS THEN
12830       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM);
12831       IF FND_API.To_Boolean(p_commit) THEN
12832         ROLLBACK TO Validate_Row_PUB;
12833       END IF;
12834       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
12835 
12836       DECLARE
12837         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
12838       BEGIN
12839         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
12840         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
12841         l_token_table(2).TOKEN_NAME := 'API_NAME';
12842         l_token_table(2).TOKEN_VALUE := l_api_name;
12843         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
12844         l_token_table(3).TOKEN_VALUE := SQLERRM;
12845 
12846         ERROR_HANDLER.Add_Error_Message(
12847           p_message_name      => 'EGO_PLSQL_ERR'
12848          ,p_application_id    => 'EGO'
12849          ,p_token_tbl         => l_token_table
12850          ,p_message_type      => FND_API.G_RET_STS_ERROR
12851          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
12852          ,p_entity_id         => p_entity_id
12853          ,p_entity_index      => p_entity_index
12854          ,p_entity_code       => p_entity_code
12855          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
12856         );
12857       END;
12858 
12859       Close_Business_Object_Session(
12860         p_init_error_handler_flag     => FALSE
12861        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
12862        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
12863       );
12864 
12865       x_msg_count := ERROR_HANDLER.Get_Message_Count();
12866 
12867       IF (x_msg_count = 1) THEN
12868         DECLARE
12869           message_list  ERROR_HANDLER.Error_Tbl_Type;
12870         BEGIN
12871           ERROR_HANDLER.Get_Message_List(message_list);
12872           x_msg_data := message_list(message_list.FIRST).message_text;
12873         END;
12874       ELSE
12875         x_msg_data := NULL;
12876       END IF;
12877 
12878 END Validate_Row;
12879 
12880 
12881 ----------------------------------------------------------------------
12882 
12883 -- The API returns the complete DML for a given attribute group
12884 -- with the corresponding binds. In case the DML is to be done
12885 -- on a table other than the one seeded for the given attr group
12886 -- type the table names can be passed as p_alternate_ext_*_table_name
12887 ----------------------------------------------------------------------
12888 
12889 PROCEDURE Generate_DML_For_Row (
12890         p_api_version                      IN   NUMBER
12891        ,p_object_id                        IN   NUMBER     DEFAULT NULL
12892        ,p_object_name                      IN   VARCHAR2   DEFAULT NULL
12893        ,p_attr_group_id                    IN   NUMBER     DEFAULT NULL
12894        ,p_application_id                   IN   NUMBER     DEFAULT NULL
12895        ,p_attr_group_type                  IN   VARCHAR2   DEFAULT NULL
12896        ,p_attr_group_name                  IN   VARCHAR2   DEFAULT NULL
12897        ,p_pk_column_name_value_pairs       IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12898        ,p_class_code_name_value_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12899        ,p_data_level                       IN   VARCHAR2   DEFAULT NULL --R12C
12900        ,p_data_level_name_value_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12901        ,p_extension_id                     IN   NUMBER     DEFAULT NULL
12902        ,p_attr_name_value_pairs            IN   EGO_USER_ATTR_DATA_TABLE
12903        ,p_mode                             IN   VARCHAR2   DEFAULT G_SYNC_MODE
12904        ,p_extra_pk_col_name_val_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
12905        ,p_extra_attr_name_value_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
12906        ,p_alternate_ext_b_table_name       IN   VARCHAR2   DEFAULT NULL
12907        ,p_alternate_ext_tl_table_name      IN   VARCHAR2   DEFAULT NULL
12908        ,p_alternate_ext_vl_name            IN   VARCHAR2   DEFAULT NULL
12909        ,p_execute_dml                      IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12910        ,p_entity_id                        IN   NUMBER     DEFAULT NULL
12911        ,p_entity_index                     IN   NUMBER     DEFAULT NULL
12912        ,p_entity_code                      IN   VARCHAR2   DEFAULT NULL
12913        ,p_debug_level                      IN   NUMBER     DEFAULT 0
12914        ,p_use_def_vals_on_insert           IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12915        ,p_log_errors                       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12916        ,p_init_fnd_msg_list                IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12917        ,p_write_to_concurrent_log          IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12918        ,p_add_errors_to_fnd_stack          IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12919        ,p_commit                           IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12920        ,p_bulkload_flag                    IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12921        ,p_raise_business_event             IN   BOOLEAN DEFAULT TRUE
12922        ,x_return_status                    OUT NOCOPY VARCHAR2
12923        ,x_errorcode                        OUT NOCOPY NUMBER
12924        ,x_msg_count                        OUT NOCOPY NUMBER
12925        ,x_msg_data                         OUT NOCOPY VARCHAR2
12926        ,x_b_dml_for_ag                     OUT NOCOPY VARCHAR2
12927        ,x_tl_dml_for_ag                    OUT NOCOPY VARCHAR2
12928        ,x_b_bind_count                     OUT NOCOPY NUMBER
12929        ,x_tl_bind_count                    OUT NOCOPY NUMBER
12930        ,x_b_bind_attr_table                OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
12931        ,x_tl_bind_attr_table               OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
12932  ) IS
12933 
12934     l_api_name               CONSTANT VARCHAR2(30) := 'Generate_DML_For_Row';
12935 
12936     --we don't use l_api_version yet, but eventually we might:
12937     --if we change required parameters, version goes FROM n.x to (n+1).x
12938     --if we change optional parameters, version goes FROM x.n to x.(n+1)
12939     l_api_version            CONSTANT NUMBER := 1.0;
12940 
12941     l_object_id              NUMBER;
12942     l_attr_name_value_pairs   EGO_USER_ATTR_DATA_TABLE;
12943     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
12944     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
12945     l_extension_id           NUMBER;
12946     l_mode                   VARCHAR2(10);
12947     l_dml                    VARCHAR2(32767);
12948     l_b_dml_bind_list        EGO_USER_ATTR_DATA_TABLE;
12949     l_tl_dml_bind_list       EGO_USER_ATTR_DATA_TABLE;
12950     l_bind_name              VARCHAR2(100);
12951 
12952   BEGIN
12953 
12954     Debug_Msg(l_api_name||' starting ', 1);
12955     -- Check for call compatibility
12956     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
12957                                         l_api_name, G_PKG_NAME)
12958     THEN
12959       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
12960     END IF;
12961 
12962     IF (FND_API.To_Boolean(p_init_fnd_msg_list)) THEN
12963       ERROR_HANDLER.Initialize();
12964     END IF;
12965 
12966     G_B_TABLE_DML   := '';
12967     G_TL_TABLE_DML  := '';
12968     G_BIND_INDEX    := 0;
12969     G_TL_BIND_INDEX := 0;
12970     G_B_BIND_INDEX  := 0;
12971 
12972    FOR i IN 1 .. 100 LOOP
12973 
12974     G_BIND_IDENTIFIER_TBL(i) := NULL;
12975     G_BIND_DATATYPE_TBL(i) := NULL;
12976     G_BIND_TEXT_TBL(i) := NULL;
12977     G_BIND_DATE_TBL(i) := NULL;
12978     G_BIND_NUMBER_TBL(i) := NULL;
12979 
12980     G_B_BIND_IDENTIFIER_TBL(i) := NULL;
12981     G_B_BIND_DATATYPE_TBL(i) := NULL;
12982     G_B_BIND_TEXT_TBL(i) := NULL;
12983     G_B_BIND_DATE_TBL(i) := NULL;
12984     G_B_BIND_NUMBER_TBL(i) := NULL;
12985 
12986     G_TL_BIND_IDENTIFIER_TBL(i) := NULL;
12987     G_TL_BIND_DATATYPE_TBL(i) := NULL;
12988     G_TL_BIND_TEXT_TBL(i) := NULL;
12989     G_TL_BIND_DATE_TBL(i) := NULL;
12990     G_TL_BIND_NUMBER_TBL(i) := NULL;
12991 
12992    END LOOP;
12993 
12994     G_SYNC_TO_UPDATE := 'N';
12995     l_object_id := p_object_id;
12996     l_attr_name_value_pairs := p_attr_name_value_pairs;
12997 
12998     Perform_Setup_Operations(
12999         p_object_name                   => p_object_name
13000        ,p_attr_group_id                 => p_attr_group_id
13001        ,p_application_id                => p_application_id
13002        ,p_attr_group_type               => p_attr_group_type
13003        ,p_attr_group_name               => p_attr_group_name
13004        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
13005        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
13006        ,p_data_level                    => p_data_level
13007        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
13008        ,p_extension_id                  => p_extension_id
13009        ,p_entity_id                     => p_entity_id
13010        ,p_entity_index                  => p_entity_index
13011        ,p_entity_code                   => p_entity_code
13012        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
13013        ,p_mode                          => p_mode
13014        ,p_extra_pk_col_name_val_pairs   => p_extra_pk_col_name_val_pairs
13015        ,p_pending_b_table_name          => p_alternate_ext_b_table_name
13016        ,p_pending_vl_name               => p_alternate_ext_vl_name
13017        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
13018        ,p_use_def_vals_on_insert_flag   => FND_API.To_Boolean(p_use_def_vals_on_insert)
13019        ,p_debug_level                   => p_debug_level
13020        ,p_bulkload_flag                 => FND_API.To_Boolean(p_bulkload_flag)
13021        ,px_object_id                    => l_object_id
13022        ,px_attr_name_value_pairs        => l_attr_name_value_pairs
13023        ,x_attr_group_metadata_obj       => l_attr_group_metadata_obj
13024        ,x_ext_table_metadata_obj        => l_ext_table_metadata_obj
13025        ,x_extension_id                  => l_extension_id
13026        ,x_mode                          => l_mode
13027        ,x_return_status                 => x_return_status
13028     );
13029 
13030     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
13031       RAISE FND_API.G_EXC_ERROR;
13032     END IF;
13033 
13034     Debug_Msg(l_api_name||' calling  Perform_DML_On_Row_Pvt', 1);
13035     Perform_DML_On_Row_Pvt(
13036         p_api_version                   => p_api_version
13037        ,p_object_id                     => l_object_id
13038        ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
13039        ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
13040        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
13041        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
13042        ,p_data_level                    => p_data_level
13043        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
13044        ,p_extension_id                  => p_extension_id
13045        ,p_attr_name_value_pairs         => l_attr_name_value_pairs
13046        ,p_mode                          => l_mode
13047        ,p_extra_pk_col_name_val_pairs   => p_extra_pk_col_name_val_pairs
13048        ,p_extra_attr_name_value_pairs   => p_extra_attr_name_value_pairs
13049        ,p_pending_b_table_name          => p_alternate_ext_b_table_name
13050        ,p_pending_tl_table_name         => p_alternate_ext_tl_table_name
13051        ,p_execute_dml                   => p_execute_dml
13052        ,p_entity_id                     => p_entity_id
13053        ,p_entity_index                  => p_entity_index
13054        ,p_entity_code                   => p_entity_code
13055        ,p_commit                        => FND_API.G_FALSE
13056        ,p_raise_business_event          => p_raise_business_event
13057        ,p_bulkload_flag                 => FND_API.To_Boolean(p_bulkload_flag)
13058        ,x_extension_id                  => l_extension_id
13059        ,x_return_status                 => x_return_status
13060     );
13061     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
13062       RAISE FND_API.G_EXC_ERROR;
13063     END IF;
13064 
13065     x_b_dml_for_ag      := G_B_TABLE_DML;
13066     x_tl_dml_for_ag     := G_TL_TABLE_DML;
13067     x_b_bind_count      := G_B_BIND_INDEX;
13068     x_tl_bind_count     := G_TL_BIND_INDEX;
13069 
13070     l_b_dml_bind_list   := EGO_USER_ATTR_DATA_TABLE();
13071     l_tl_dml_bind_list  := EGO_USER_ATTR_DATA_TABLE();
13072 
13073     FOR i in 1 .. G_B_BIND_INDEX
13074     LOOP
13075 
13076       l_bind_name := ':FND_BIND'||TO_CHAR(i);
13077       l_b_dml_bind_list.EXTEND();
13078       IF(G_B_BIND_DATATYPE_TBL(i) = 'D') THEN
13079         l_b_dml_bind_list(i) := EGO_USER_ATTR_DATA_OBJ(NULL,l_bind_name,NULL,NULL,G_B_BIND_DATE_TBL(i),G_B_BIND_IDENTIFIER_TBL(i),NULL,NULL);
13080       ELSIF (G_B_BIND_DATATYPE_TBL(i) = 'N') THEN
13081         l_b_dml_bind_list(i) := EGO_USER_ATTR_DATA_OBJ(NULL,l_bind_name,NULL,G_B_BIND_NUMBER_TBL(i),NULL,G_B_BIND_IDENTIFIER_TBL(i),NULL,NULL);
13082       ELSE
13083         l_b_dml_bind_list(i) := EGO_USER_ATTR_DATA_OBJ(NULL,l_bind_name,G_B_BIND_TEXT_TBL(i),NULL,NULL,G_B_BIND_IDENTIFIER_TBL(i),NULL,NULL);
13084       END IF;
13085     END LOOP;
13086 
13087 
13088     FOR j in 1 .. G_TL_BIND_INDEX
13089     LOOP
13090 
13091       l_bind_name := ':FND_BIND'||TO_CHAR(j);
13092       l_tl_dml_bind_list.EXTEND();
13093       IF(G_TL_BIND_DATATYPE_TBL(j) = 'D') THEN
13094         l_tl_dml_bind_list(j) := EGO_USER_ATTR_DATA_OBJ(NULL,l_bind_name,NULL,NULL,G_TL_BIND_DATE_TBL(j),G_TL_BIND_IDENTIFIER_TBL(j),NULL,NULL);
13095       ELSIF (G_TL_BIND_DATATYPE_TBL(j) = 'N') THEN
13096         l_tl_dml_bind_list(j) := EGO_USER_ATTR_DATA_OBJ(NULL,l_bind_name,NULL,G_TL_BIND_NUMBER_TBL(j),NULL,G_TL_BIND_IDENTIFIER_TBL(j),NULL,NULL);
13097       ELSE
13098         l_tl_dml_bind_list(j) := EGO_USER_ATTR_DATA_OBJ(NULL,l_bind_name,G_TL_BIND_TEXT_TBL(j),NULL,NULL,G_TL_BIND_IDENTIFIER_TBL(j),NULL,NULL);
13099       END IF;
13100     END LOOP;
13101 
13102     x_b_bind_attr_table  := l_b_dml_bind_list;
13103     x_tl_bind_attr_table := l_tl_dml_bind_list;
13104 
13105     Close_Business_Object_Session(
13106       p_init_error_handler_flag       => (p_debug_level > 0)
13107      ,p_log_errors                    => FND_API.To_Boolean(p_log_errors)
13108      ,p_write_to_concurrent_log       => FND_API.To_Boolean(p_write_to_concurrent_log)
13109     );
13110 
13111     IF FND_API.To_Boolean(p_commit) THEN
13112       COMMIT WORK;
13113     END IF;
13114 
13115     x_return_status := FND_API.G_RET_STS_SUCCESS;
13116 
13117     Debug_Msg(l_api_name||' ending ', 1);
13118 
13119   EXCEPTION
13120 
13121     WHEN FND_API.G_EXC_ERROR THEN
13122       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR');
13123 
13124       Close_Business_Object_Session(
13125         p_init_error_handler_flag     => (p_debug_level > 0)
13126        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
13127        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
13128       );
13129 
13130       x_msg_count := ERROR_HANDLER.Get_Message_Count();
13131       IF (x_msg_count = 1) THEN
13132         DECLARE
13133           message_list  ERROR_HANDLER.Error_Tbl_Type;
13134         BEGIN
13135           ERROR_HANDLER.Get_Message_List(message_list);
13136           x_msg_data := message_list(message_list.FIRST).message_text;
13137         END;
13138       ELSE
13139         x_msg_data := NULL;
13140       END IF;
13141 
13142     WHEN OTHERS THEN
13143       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM);
13144       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
13145       DECLARE
13146         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
13147       BEGIN
13148         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
13149         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
13150         l_token_table(2).TOKEN_NAME := 'API_NAME';
13151         l_token_table(2).TOKEN_VALUE := l_api_name;
13152         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
13153         l_token_table(3).TOKEN_VALUE := SQLERRM;
13154 
13155         ERROR_HANDLER.Add_Error_Message(
13156           p_message_name      => 'EGO_PLSQL_ERR'
13157          ,p_application_id    => 'EGO'
13158          ,p_token_tbl         => l_token_table
13159          ,p_message_type      => FND_API.G_RET_STS_ERROR
13160          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
13161          ,p_entity_id         => p_entity_id
13162          ,p_entity_index      => p_entity_index
13163          ,p_entity_code       => p_entity_code
13164          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
13165         );
13166       END;
13167 
13168       Close_Business_Object_Session(
13169         p_init_error_handler_flag     => (p_debug_level > 0)
13170        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
13171        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
13172       );
13173 
13174       x_msg_count := ERROR_HANDLER.Get_Message_Count();
13175 
13176       IF (x_msg_count = 1) THEN
13177         DECLARE
13178           message_list  ERROR_HANDLER.Error_Tbl_Type;
13179         BEGIN
13180           ERROR_HANDLER.Get_Message_List(message_list);
13181           x_msg_data := message_list(message_list.FIRST).message_text;
13182         END;
13183       ELSE
13184         x_msg_data := NULL;
13185       END IF;
13186 
13187 END Generate_DML_For_Row;
13188 
13189 ----------------------------------------------------------------------
13190 
13191 
13192 
13193 ----------------------------------------------------------------------
13194 -- This API returns the extension id of the attr group row          --
13195 ----------------------------------------------------------------------
13196 
13197 FUNCTION Get_Extension_Id (
13198         p_object_name                      IN   VARCHAR2
13199        ,p_attr_group_id                    IN   NUMBER     DEFAULT NULL
13200        ,p_application_id                   IN   NUMBER
13201        ,p_attr_group_type                  IN   VARCHAR2
13202        ,p_attr_group_name                  IN   VARCHAR2   DEFAULT NULL
13203        ,p_pk_column_name_value_pairs       IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
13204        ,p_data_level                       IN   VARCHAR2   DEFAULT NULL --R12C
13205        ,p_data_level_name_value_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
13206        ,p_attr_name_value_pairs            IN   EGO_USER_ATTR_DATA_TABLE
13207        ,p_extra_pk_col_name_val_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
13208        ,p_extra_attr_name_value_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
13209        ,p_alternate_ext_b_table_name       IN   VARCHAR2   DEFAULT NULL
13210        ,p_alternate_ext_tl_table_name      IN   VARCHAR2   DEFAULT NULL
13211        ,p_alternate_ext_vl_name            IN   VARCHAR2   DEFAULT NULL
13212        ) RETURN NUMBER
13213  IS
13214 
13215     l_attr_name_value_pairs   EGO_USER_ATTR_DATA_TABLE;
13216     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
13217     l_ext_table_metadata_obj  EGO_EXT_TABLE_METADATA_OBJ;
13218     l_ext_id                  NUMBER;
13219     l_object_id               NUMBER;
13220 
13221  BEGIN
13222 
13223     l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(p_attr_group_id
13224                                                                                   ,p_application_id
13225                                                                                   ,p_attr_group_type
13226                                                                                   ,p_attr_group_name);
13227     BEGIN
13228       SELECT OBJECT_ID INTO l_object_id
13229         FROM FND_OBJECTS
13230        WHERE OBJ_NAME = p_object_name;
13231     EXCEPTION
13232       WHEN OTHERS THEN
13233        NULL;
13234     END;
13235 
13236     l_ext_table_metadata_obj :=  EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
13237 
13238     l_ext_id := Get_Extension_Id_For_Row(
13239                                           p_attr_group_metadata_obj     => l_attr_group_metadata_obj
13240                                          ,p_ext_table_metadata_obj      => l_ext_table_metadata_obj
13241                                          ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
13242                                          ,p_data_level                  => p_data_level
13243                                          ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
13244                                          ,p_attr_name_value_pairs       => p_attr_name_value_pairs
13245                                          ,p_extra_pk_col_name_val_pairs => p_extra_pk_col_name_val_pairs
13246                                          ,p_pending_b_table_name        => p_alternate_ext_b_table_name
13247                                          ,p_pending_vl_name             => p_alternate_ext_vl_name
13248                                         );
13249     RETURN l_ext_id;
13250 
13251  END Get_Extension_Id;
13252 
13253 
13254 
13255 --gnanda end
13256 
13257 
13258 
13259 
13260 
13261 
13262 ----------------------------------------------------------------------
13263 
13264 -- This version just performs some preliminary setup operations and
13265 -- and then calls the "private" signature, Perform_DML_On_Row_Pvt
13266 
13267 PROCEDURE Perform_DML_On_Row (
13268         p_api_version                   IN   NUMBER
13269        ,p_object_id                     IN   NUMBER     DEFAULT NULL
13270        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
13271        ,p_attr_group_id                 IN   NUMBER     DEFAULT NULL
13272        ,p_application_id                IN   NUMBER     DEFAULT NULL
13273        ,p_attr_group_type               IN   VARCHAR2   DEFAULT NULL
13274        ,p_attr_group_name               IN   VARCHAR2   DEFAULT NULL
13275        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
13276        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
13277        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
13278        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
13279        ,p_extension_id                  IN   NUMBER     DEFAULT NULL
13280        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
13281        ,p_mode                          IN   VARCHAR2   DEFAULT G_SYNC_MODE
13282        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
13283        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
13284        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT NULL
13285        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT NULL
13286        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
13287        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
13288        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
13289        ,p_debug_level                   IN   NUMBER     DEFAULT 0
13290        ,p_use_def_vals_on_insert        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13291        ,p_log_errors                    IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13292        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13293        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13294        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13295        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13296        ,p_bulkload_flag                 IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13297        ,x_return_status                 OUT NOCOPY VARCHAR2
13298        ,x_errorcode                     OUT NOCOPY NUMBER
13299        ,x_msg_count                     OUT NOCOPY NUMBER
13300        ,x_msg_data                      OUT NOCOPY VARCHAR2
13301 ) IS
13302     l_extension_id           NUMBER;
13303     l_mode                   VARCHAR2(10);
13304   BEGIN
13305 
13306     Perform_DML_On_Row(
13307         p_api_version                   => p_api_version
13308        ,p_object_id                     => p_object_id
13309        ,p_object_name                   => p_object_name
13310        ,p_attr_group_id                 => p_attr_group_id
13311        ,p_application_id                => p_application_id
13312        ,p_attr_group_type               => p_attr_group_type
13313        ,p_attr_group_name               => p_attr_group_name
13314        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
13315        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
13316        ,p_data_level                    => p_data_level --R12C
13317        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
13318        ,p_extension_id                  => p_extension_id
13319        ,p_attr_name_value_pairs         => p_attr_name_value_pairs
13320        ,p_mode                          => p_mode
13321        ,p_change_obj                    => p_change_obj
13322        ,p_pending_b_table_name          => p_pending_b_table_name
13323        ,p_pending_tl_table_name         => p_pending_tl_table_name
13324        ,p_pending_vl_name               => p_pending_vl_name
13325        ,p_entity_id                     => p_entity_id
13326        ,p_entity_index                  => p_entity_index
13327        ,p_entity_code                   => p_entity_code
13328        ,p_debug_level                   => p_debug_level
13329        ,p_use_def_vals_on_insert        => p_use_def_vals_on_insert
13330        ,p_log_errors                    => p_log_errors
13331        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
13332        ,p_write_to_concurrent_log       => p_write_to_concurrent_log
13333        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
13334        ,p_commit                        => p_commit
13335        ,p_bulkload_flag                 => p_bulkload_flag
13336        ,x_extension_id                  => l_extension_id
13337        ,x_mode                          => l_mode
13338        ,x_return_status                 => x_return_status
13339        ,x_errorcode                     => x_errorcode
13340        ,x_msg_count                     => x_msg_count
13341        ,x_msg_data                      => x_msg_data
13342     );
13343 
13344 END Perform_DML_On_Row;
13345 
13346 ----------------------------------------------------------------------
13347 
13348 /* Overload method with additional parameters x_extension_id, x_mode */
13349 
13350 PROCEDURE Perform_DML_On_Row (
13351         p_api_version                   IN   NUMBER
13352        ,p_object_id                     IN   NUMBER     DEFAULT NULL
13353        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
13354        ,p_attr_group_id                 IN   NUMBER     DEFAULT NULL
13355        ,p_application_id                IN   NUMBER     DEFAULT NULL
13356        ,p_attr_group_type               IN   VARCHAR2   DEFAULT NULL
13357        ,p_attr_group_name               IN   VARCHAR2   DEFAULT NULL
13358        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
13359        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
13360        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
13361        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
13362        ,p_extension_id                  IN   NUMBER     DEFAULT NULL
13363        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
13364        ,p_mode                          IN   VARCHAR2   DEFAULT G_SYNC_MODE
13365        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
13366        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
13367        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT NULL
13368        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT NULL
13369        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
13370        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
13371        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
13372        ,p_debug_level                   IN   NUMBER     DEFAULT 0
13373        ,p_use_def_vals_on_insert        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13374        ,p_log_errors                    IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13375        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13376        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13377        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13378        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13379        ,p_bulkload_flag                 IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13380        --Added by geguo for 9373845 begin
13381        ,p_creation_date                 IN   DATE       DEFAULT NULL
13382        ,p_last_update_date              IN   DATE       DEFAULT NULL
13383        --Added by geguo 9373845 end
13384        ,x_extension_id                  OUT NOCOPY NUMBER
13385        ,x_mode                          OUT NOCOPY VARCHAR2
13386        ,x_return_status                 OUT NOCOPY VARCHAR2
13387        ,x_errorcode                     OUT NOCOPY NUMBER
13388        ,x_msg_count                     OUT NOCOPY NUMBER
13389        ,x_msg_data                      OUT NOCOPY VARCHAR2
13390 ) IS
13391 
13392     l_api_name               CONSTANT VARCHAR2(30) := 'Perform_DML_On_Row';
13393 
13394     --we don't use l_api_version yet, but eventually we might:
13395     --if we change required parameters, version goes FROM n.x to (n+1).x
13396     --if we change optional parameters, version goes FROM x.n to x.(n+1)
13397     l_api_version            CONSTANT NUMBER := 1.0;
13398 
13399     l_object_id              NUMBER;
13400     l_attr_name_value_pairs   EGO_USER_ATTR_DATA_TABLE;
13401     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
13402     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
13403     l_extension_id           NUMBER;
13404     l_mode                   VARCHAR2(10);
13405 
13406 
13407   BEGIN
13408     --Added by geguo for 9373845
13409     G_WHO_CREATION_DATE      := p_creation_date;
13410     G_WHO_LAST_UPDATE_DATE   := p_last_update_date;
13411     Debug_Msg(l_api_name||' starting with data_level = '||p_data_level, 1);
13412 
13413     IF FND_API.To_Boolean(p_commit) THEN
13414       SAVEPOINT Perform_DML_On_Row_PUB;
13415     END IF;
13416 
13417     -- Check for call compatibility
13418     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
13419                                         l_api_name, G_PKG_NAME)
13420     THEN
13421       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
13422     END IF;
13423 
13424     IF (FND_API.To_Boolean(p_init_fnd_msg_list)) THEN
13425       ERROR_HANDLER.Initialize();
13426     END IF;
13427     G_SYNC_TO_UPDATE := 'N';
13428     l_object_id := p_object_id;
13429     l_attr_name_value_pairs := p_attr_name_value_pairs;
13430 
13431     Perform_Setup_Operations(
13432         p_object_name                   => p_object_name
13433        ,p_attr_group_id                 => p_attr_group_id
13434        ,p_application_id                => p_application_id
13435        ,p_attr_group_type               => p_attr_group_type
13436        ,p_attr_group_name               => p_attr_group_name
13437        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
13438        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
13439        ,p_data_level                    => p_data_level
13440        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
13441        ,p_extension_id                  => p_extension_id
13442        ,p_entity_id                     => p_entity_id
13443        ,p_entity_index                  => p_entity_index
13444        ,p_entity_code                   => p_entity_code
13445        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
13446        ,p_mode                          => p_mode
13447        ,p_change_obj                    => p_change_obj
13448        ,p_pending_b_table_name          => p_pending_b_table_name
13449        ,p_pending_vl_name               => p_pending_vl_name
13450        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
13451        ,p_use_def_vals_on_insert_flag   => FND_API.To_Boolean(p_use_def_vals_on_insert)
13452        ,p_debug_level                   => p_debug_level
13453        ,p_bulkload_flag                 => FND_API.To_Boolean(p_bulkload_flag)
13454        ,px_object_id                    => l_object_id
13455        ,px_attr_name_value_pairs        => l_attr_name_value_pairs
13456        ,x_attr_group_metadata_obj       => l_attr_group_metadata_obj
13457        ,x_ext_table_metadata_obj        => l_ext_table_metadata_obj
13458        ,x_extension_id                  => x_extension_id
13459        ,x_mode                          => x_mode
13460        ,x_return_status                 => x_return_status
13461     );
13462     IF p_mode = 'SYNC'  --doing it for GTIN Attribute Group
13463        AND (l_mode = 'UPDATE'
13464             AND p_attr_group_type in ('EGO_ITEM_GTIN_ATTRS','EGO_ITEM_GTIN_MULTI_ATTRS'))
13465     THEN
13466       G_SYNC_TO_UPDATE := 'Y' ;
13467     END IF;
13468     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
13469       RAISE FND_API.G_EXC_ERROR;
13470     END IF;
13471 
13472     l_extension_id := x_extension_id;
13473     l_mode         := x_mode;
13474 
13475     Debug_Msg(l_api_name||' calling Perform_DML_On_Row_Pvt', 1);
13476 
13477     Perform_DML_On_Row_Pvt(
13478         p_api_version                   => p_api_version
13479        ,p_object_id                     => l_object_id
13480        ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
13481        ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
13482        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
13483        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
13484        ,p_data_level                    => p_data_level
13485        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
13486        ,p_extension_id                  => l_extension_id
13487        ,p_attr_name_value_pairs         => l_attr_name_value_pairs
13488        ,p_mode                          => l_mode
13489        ,p_change_obj                    => p_change_obj
13490        ,p_pending_b_table_name          => p_pending_b_table_name
13491        ,p_pending_tl_table_name         => p_pending_tl_table_name
13492        ,p_entity_id                     => p_entity_id
13493        ,p_entity_index                  => p_entity_index
13494        ,p_entity_code                   => p_entity_code
13495        ,p_commit                        => FND_API.G_FALSE
13496        ,p_bulkload_flag                 => FND_API.To_Boolean(p_bulkload_flag)
13497        ,x_extension_id                  => x_extension_id
13498        ,x_return_status                 => x_return_status
13499     );
13500     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
13501       RAISE FND_API.G_EXC_ERROR;
13502     END IF;
13503 
13504     Close_Business_Object_Session(
13505       p_init_error_handler_flag       => (p_debug_level > 0)
13506      ,p_log_errors                    => FND_API.To_Boolean(p_log_errors)
13507      ,p_write_to_concurrent_log       => FND_API.To_Boolean(p_write_to_concurrent_log)
13508     );
13509 
13510     IF FND_API.To_Boolean(p_commit) THEN
13511       COMMIT WORK;
13512     END IF;
13513 
13514     x_return_status := FND_API.G_RET_STS_SUCCESS;
13515 
13516   EXCEPTION
13517     WHEN FND_API.G_EXC_ERROR THEN
13518       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR');
13519       IF FND_API.To_Boolean(p_commit) THEN
13520         ROLLBACK TO Perform_DML_On_Row_PUB;
13521       END IF;
13522       Close_Business_Object_Session(
13523         p_init_error_handler_flag     => (p_debug_level > 0)
13524        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
13525        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
13526       );
13527 
13528       x_msg_count := ERROR_HANDLER.Get_Message_Count();
13529       IF (x_msg_count = 1) THEN
13530         DECLARE
13531           message_list  ERROR_HANDLER.Error_Tbl_Type;
13532         BEGIN
13533           ERROR_HANDLER.Get_Message_List(message_list);
13534           x_msg_data := message_list(message_list.FIRST).message_text;
13535         END;
13536       ELSE
13537         x_msg_data := NULL;
13538       END IF;
13539 
13540     WHEN OTHERS THEN
13541       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM);
13542       IF FND_API.To_Boolean(p_commit) THEN
13543         ROLLBACK TO Perform_DML_On_Row_PUB;
13544       END IF;
13545       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
13546 
13547       DECLARE
13548         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
13549       BEGIN
13550         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
13551         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
13552         l_token_table(2).TOKEN_NAME := 'API_NAME';
13553         l_token_table(2).TOKEN_VALUE := l_api_name;
13554         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
13555         l_token_table(3).TOKEN_VALUE := SQLERRM;
13556 
13557         ERROR_HANDLER.Add_Error_Message(
13558           p_message_name      => 'EGO_PLSQL_ERR'
13559          ,p_application_id    => 'EGO'
13560          ,p_token_tbl         => l_token_table
13561          ,p_message_type      => FND_API.G_RET_STS_ERROR
13562          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
13563          ,p_entity_id         => p_entity_id
13564          ,p_entity_index      => p_entity_index
13565          ,p_entity_code       => p_entity_code
13566          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
13567         );
13568       END;
13569 
13570       Close_Business_Object_Session(
13571         p_init_error_handler_flag     => (p_debug_level > 0)
13572        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
13573        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
13574       );
13575 
13576       x_msg_count := ERROR_HANDLER.Get_Message_Count();
13577 
13578       IF (x_msg_count = 1) THEN
13579         DECLARE
13580           message_list  ERROR_HANDLER.Error_Tbl_Type;
13581         BEGIN
13582           ERROR_HANDLER.Get_Message_List(message_list);
13583           x_msg_data := message_list(message_list.FIRST).message_text;
13584         END;
13585       ELSE
13586         x_msg_data := NULL;
13587       END IF;
13588 
13589 END Perform_DML_On_Row;
13590 
13591 ----------------------------------------------------------------------
13592 -- Public
13593 ----------------------------------------------------------------------
13594 
13595 PROCEDURE Perform_DML_From_Template (
13596         p_api_version                   IN   NUMBER
13597        ,p_template_id                   IN   NUMBER
13598        ,p_object_name                   IN   VARCHAR2
13599        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
13600        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
13601        ,p_data_level                    IN   VARCHAR2 DEFAULT NULL
13602        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
13603        ,p_attr_group_ids_to_exclude     IN   EGO_NUMBER_TBL_TYPE           DEFAULT NULL
13604        ,p_debug_level                   IN   NUMBER     DEFAULT 0
13605        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13606        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13607        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13608        ,x_return_status                 OUT NOCOPY VARCHAR2
13609        ,x_errorcode                     OUT NOCOPY NUMBER
13610        ,x_msg_count                     OUT NOCOPY NUMBER
13611        ,x_msg_data                      OUT NOCOPY VARCHAR2
13612 ) IS
13613 
13614     l_api_name               CONSTANT VARCHAR2(30) := 'Perform_DML_From_Template';
13615 
13616     --we don't use l_api_version yet, but eventually we might:
13617     --if we change required parameters, version goes FROM n.x to (n+1).x
13618     --if we change optional parameters, version goes FROM x.n to x.(n+1)
13619     l_api_version            CONSTANT NUMBER := 1.0;
13620 
13621     l_object_id              NUMBER;
13622     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
13623     l_class_code_hierarchy   VARCHAR2(16000);
13624     l_last_loop_index        NUMBER;
13625     l_this_loop_index        NUMBER;
13626     l_decode_index           NUMBER;
13627     l_cc_hierarchy_for_decode VARCHAR2(16100);
13628     l_dynamic_sql            VARCHAR2(30000);
13629     l_prev_loop_ag_id        NUMBER;
13630     l_prev_loop_row_number   NUMBER;
13631     l_at_start_of_ag         BOOLEAN;
13632     l_at_start_of_row        BOOLEAN;
13633     l_row_index              NUMBER := 0;
13634     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
13635     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
13636     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
13637     l_attr_name_value_pairs  EGO_USER_ATTR_DATA_TABLE;
13638     l_extension_id           NUMBER;
13639     l_mode                   VARCHAR2(10);
13640     l_attr_group_ids_to_exclude VARCHAR2(16000);
13641     l_attr_group_id          NUMBER;
13642     l_cursor_id              NUMBER;
13643     l_rows_fetched           NUMBER;
13644     l_cc_data_type           VARCHAR2(8);
13645     l_next_cc                VARCHAR2(150);
13646     l_cc_begin_pos           NUMBER;
13647     l_is_last_cc             BOOLEAN;
13648     --Start Bug 5211171
13649     l_rev_level              VARCHAR2(1000);
13650     l_decode_query           VARCHAR2(32767);
13651     --End Bug 5211171
13652     l_data_level_id          NUMBER;
13653     l_Perform_DML_On_Template_Row     VARCHAR2(1);
13654 
13655     TYPE TEMPL_ATTR_REC IS RECORD (
13656         ATTRIBUTE_GROUP_ID          EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_GROUP_ID%TYPE
13657        ,ATTRIBUTE_ID                EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_ID%TYPE
13658        ,ROW_NUMBER                  EGO_TEMPL_ATTRIBUTES.ROW_NUMBER%TYPE
13659        ,ATTRIBUTE_STRING_VALUE      EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_STRING_VALUE%TYPE
13660        ,ATTRIBUTE_NUMBER_VALUE      EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_NUMBER_VALUE%TYPE
13661        ,ATTRIBUTE_UOM_CODE          EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_UOM_CODE%TYPE
13662        ,ATTRIBUTE_DATE_VALUE        EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_DATE_VALUE%TYPE
13663        ,ATTRIBUTE_TRANSLATED_VALUE  EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_TRANSLATED_VALUE%TYPE
13664                                   );
13665     l_templ_attr_rec         TEMPL_ATTR_REC;
13666 
13667   BEGIN
13668     Debug_Msg(l_api_name||' starting ', 1);
13669 
13670     IF FND_API.To_Boolean(p_commit) THEN
13671       SAVEPOINT Perform_DML_From_Template;
13672     END IF;
13673 
13674     -- Check for call compatibility
13675     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
13676                                         l_api_name, G_PKG_NAME)
13677     THEN
13678       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
13679     END IF;
13680 
13681     ------------------------------------------------------------------
13682     -- Initialize the Business Object (flags, error-handling, etc.) --
13683     ------------------------------------------------------------------
13684     Set_Up_Business_Object_Session(
13685         p_bulkload_flag                => FALSE
13686        ,p_debug_level                  => p_debug_level
13687        ,p_init_error_handler_flag      => TRUE
13688        ,p_object_name                  => p_object_name
13689        ,p_pk_column_name_value_pairs   => p_pk_column_name_value_pairs
13690        ,p_class_code_name_value_pairs  => p_class_code_name_value_pairs
13691        ,p_init_fnd_msg_list            => p_init_fnd_msg_list
13692        ,p_add_errors_to_fnd_stack      => p_add_errors_to_fnd_stack
13693        ,p_default_user_row_identifier  => l_row_index
13694        ,x_return_status                => x_return_status
13695     );
13696     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
13697       RAISE FND_API.G_EXC_ERROR;
13698     END IF;
13699 
13700     ----------------------------------------------
13701     -- Get the Object ID and Ext Table metadata --
13702     ----------------------------------------------
13703     l_object_id := Get_Object_Id_From_Name(p_object_name);
13704 
13705     l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
13706 
13707     -----------------------------------------------------------------
13708     -- Build a DECODE string for the Classification Code Hierarchy --
13709     -----------------------------------------------------------------
13710     WHILE (INSTR(l_class_code_hierarchy, ',', (l_last_loop_index + 1)) > 0)
13711     LOOP
13712 
13713       l_this_loop_index := INSTR(l_class_code_hierarchy, ',', (l_last_loop_index + 1));
13714       l_cc_hierarchy_for_decode := l_cc_hierarchy_for_decode ||
13715                                    SUBSTR(l_class_code_hierarchy
13716                                          ,l_last_loop_index
13717                                          ,(l_this_loop_index - l_last_loop_index)) ||
13718                                    ', ' || l_decode_index;
13719 
13720       l_decode_index := l_decode_index + 1;
13721       l_last_loop_index := l_this_loop_index;
13722 
13723     END LOOP;
13724 
13725     l_cc_hierarchy_for_decode := l_cc_hierarchy_for_decode ||
13726           SUBSTR(l_class_code_hierarchy,l_last_loop_index) ||
13727           ', ' || l_decode_index;
13728 
13729     Debug_Msg(l_api_name||' l_cc_hierarchy_for_decode '|| l_cc_hierarchy_for_decode, 1);
13730     -----------------------------------------------------------------
13731     -- Build a list of attribute group ids to exclude from the     --
13732     -- query useful for applying a template while ignoring         --
13733     -- attribute groups under change control (part of bug 3781216) --
13734     -----------------------------------------------------------------
13735     l_attr_group_ids_to_exclude := '';
13736     IF (p_attr_group_ids_to_exclude IS NOT NULL AND
13737         p_attr_group_ids_to_exclude.COUNT > 0) THEN
13738 
13739       l_attr_group_ids_to_exclude := ' AND ETA_OUTER.ATTRIBUTE_GROUP_ID NOT IN ( ';
13740 
13741       FOR i IN p_attr_group_ids_to_exclude.FIRST .. p_attr_group_ids_to_exclude.LAST
13742       LOOP
13743         l_attr_group_id := p_attr_group_ids_to_exclude(i);
13744         l_attr_group_ids_to_exclude := l_attr_group_ids_to_exclude || l_attr_group_id || ',';
13745       END LOOP;
13746 
13747       -- Get rid of trailing comma
13748       l_attr_group_ids_to_exclude := RTRIM(l_attr_group_ids_to_exclude, ',') || ' ) ';
13749 
13750     END IF;
13751 
13752     -----------------------------------------------------------------
13753     -- Build a Dynamic SQL query to get all Attributes for which   --
13754     -- the passed-in Template has enabled values in the current    --
13755     -- Classification Code hierarchy (the query returns the lowest --
13756     -- level values, thus implementing Template value inheritance  --
13757     -- and overriding)                                             --
13758     -----------------------------------------------------------------
13759     l_cursor_id := DBMS_SQL.Open_Cursor;
13760     Init();
13761     FND_DSQL.Add_Text(
13762       'SELECT ETA_OUTER.ATTRIBUTE_GROUP_ID,' ||
13763             ' ETA_OUTER.ATTRIBUTE_ID,' ||
13764             ' ETA_OUTER.ROW_NUMBER,' ||
13765             ' ETA_OUTER.ATTRIBUTE_STRING_VALUE,' ||
13766             ' ETA_OUTER.ATTRIBUTE_NUMBER_VALUE,' ||
13767             ' ETA_OUTER.ATTRIBUTE_UOM_CODE,' ||
13768             ' ETA_OUTER.ATTRIBUTE_DATE_VALUE,' ||
13769             ' ETA_OUTER.ATTRIBUTE_TRANSLATED_VALUE' ||
13770        ' FROM EGO_TEMPL_ATTRIBUTES   ETA_OUTER'
13771                      );
13772     IF p_data_level IS NOT NULL THEN
13773       FND_DSQL.Add_Text(
13774            ' , EGO_DATA_LEVEL_B DL ' ||
13775       ' WHERE DL.data_level_name = '
13776                        );
13777       Add_Bind(p_value => p_data_level);
13778       FND_DSQL.Add_Text(
13779         ' AND DL.data_level_id = ETA_OUTER.data_level_id '
13780                        );
13781     ELSE
13782       FND_DSQL.Add_Text(' WHERE 1 = 1');
13783     END IF;
13784     FND_DSQL.Add_Text(' AND ETA_OUTER.TEMPLATE_ID = ');
13785     Add_Bind(p_value => p_template_id);
13786     FND_DSQL.Add_Text(' AND ETA_OUTER.CLASSIFICATION_CODE IN (');
13787 
13788     -- we assume here that the calling procedure has passed in some class codes
13789     l_class_code_hierarchy := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
13790                                 l_ext_table_metadata_obj.class_code_metadata
13791                                ,p_class_code_name_value_pairs
13792                                ,'VALUES_ALL_CC'
13793                                ,TRUE
13794                               );
13795     Debug_Msg(l_api_name||' l_class_code_hierarchy '|| l_class_code_hierarchy, 1);
13796 
13797     FND_DSQL.Add_Text(')' ||
13798         ' AND ETA_OUTER.ENABLED_FLAG = ''Y''' ||
13799         l_attr_group_ids_to_exclude||
13800         ' AND (ETA_OUTER.TEMPLATE_ID' ||
13801             ' ,ETA_OUTER.ATTRIBUTE_GROUP_ID' ||
13802             ' ,ETA_OUTER.ATTRIBUTE_ID' ||
13803             ' ,ETA_OUTER.ROW_NUMBER' ||
13804             ' ,DECODE(ETA_OUTER.CLASSIFICATION_CODE, ');
13805 
13806     l_cc_data_type := l_ext_table_metadata_obj.class_code_metadata(l_ext_table_metadata_obj.class_code_metadata.FIRST).DATA_TYPE;
13807     -----------------------------------------------------------------
13808     -- Build a DECODE string for the Classification Code Hierarchy --
13809     -----------------------------------------------------------------
13810     l_last_loop_index := 1;
13811     l_decode_index := 0;
13812     l_is_last_cc := FALSE;
13813     LOOP
13814 
13815       l_this_loop_index := INSTR(l_class_code_hierarchy, ',', l_last_loop_index);
13816 
13817       IF (l_this_loop_index = 0) THEN
13818         l_this_loop_index := LENGTH(l_class_code_hierarchy) + 1;
13819         l_is_last_cc := TRUE;
13820       END IF;
13821       l_next_cc := SUBSTR(l_class_code_hierarchy
13822                               ,l_last_loop_index
13823                               ,(l_this_loop_index - l_last_loop_index));
13824       IF (l_cc_data_type = 'NUMBER' OR l_cc_data_type = 'INTEGER') THEN
13825         Add_Bind(p_value => TO_NUMBER(l_next_cc));
13826       ELSIF (l_cc_data_type = 'VARCHAR' OR l_cc_data_type = 'VARCHAR2') THEN
13827         l_cc_begin_pos := INSTR(l_next_cc, '''') + 1;
13828         Add_Bind(p_value => SUBSTR(l_next_cc,
13829                                  l_cc_begin_pos,
13830                                  INSTR(l_next_cc, '''', -1) - l_cc_begin_pos));
13831       END IF;
13832       FND_DSQL.Add_Text(', ' || l_decode_index);
13833 
13834       EXIT WHEN (l_is_last_cc);
13835 
13836       FND_DSQL.Add_Text(', ');
13837       l_decode_index := l_decode_index + 1;
13838       l_last_loop_index := l_this_loop_index + 1;
13839 
13840     END LOOP;
13841 
13842     FND_DSQL.Add_Text('))' ||
13843             ' IN (SELECT ETA.TEMPLATE_ID' ||
13844                       ' ,ETA.ATTRIBUTE_GROUP_ID' ||
13845                       ' ,ETA.ATTRIBUTE_ID' ||
13846                       ' ,ETA.ROW_NUMBER' ||
13847                       ' ,MIN(DECODE(ETA.CLASSIFICATION_CODE, ');
13848 
13849     -----------------------------------------------------------------
13850     -- Build a DECODE string for the Classification Code Hierarchy --
13851     -----------------------------------------------------------------
13852     l_last_loop_index := 1;
13853     l_decode_index := 0;
13854     l_is_last_cc := FALSE;
13855     LOOP
13856 
13857       l_this_loop_index := INSTR(l_class_code_hierarchy, ',', l_last_loop_index);
13858 
13859       IF(l_this_loop_index = 0) THEN
13860         l_this_loop_index := LENGTH(l_class_code_hierarchy) + 1;
13861         l_is_last_cc := TRUE;
13862       END IF;
13863       l_next_cc := SUBSTR(l_class_code_hierarchy
13864                          ,l_last_loop_index
13865                          ,(l_this_loop_index - l_last_loop_index)
13866                          );
13867       IF (l_cc_data_type = 'NUMBER' OR l_cc_data_type = 'INTEGER') THEN
13868         Add_Bind(p_value => TO_NUMBER(l_next_cc));
13869       ELSIF (l_cc_data_type = 'VARCHAR' OR l_cc_data_type = 'VARCHAR2') THEN
13870         l_cc_begin_pos := INSTR(l_next_cc, '''') + 1;
13871         Add_Bind(p_value => SUBSTR(l_next_cc,
13872                                    l_cc_begin_pos,
13873                                    INSTR(l_next_cc, '''', -1) - l_cc_begin_pos));
13874       END IF;
13875       FND_DSQL.Add_Text(', ' || l_decode_index);
13876 
13877       EXIT WHEN (l_is_last_cc);
13878 
13879       FND_DSQL.Add_Text(', ');
13880       l_decode_index := l_decode_index + 1;
13881       l_last_loop_index := l_this_loop_index + 1;
13882 
13883     END LOOP;
13884 
13885     FND_DSQL.Add_Text(')) STEPS_ABOVE_CURR' ||
13886                   ' FROM EGO_TEMPL_ATTRIBUTES ETA' ||
13887                  ' WHERE ETA.TEMPLATE_ID = ');
13888     Add_Bind(p_value => p_template_id);
13889     FND_DSQL.Add_Text(
13890                    ' AND ETA.CLASSIFICATION_CODE IN (');
13891 
13892     l_class_code_hierarchy := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
13893                                     l_ext_table_metadata_obj.class_code_metadata
13894                                    ,p_class_code_name_value_pairs
13895                                    ,'VALUES_ALL_CC'
13896                                    ,TRUE
13897                               );
13898 
13899     FND_DSQL.Add_Text(')' ||
13900                  ' GROUP BY ETA.TEMPLATE_ID, ETA.ATTRIBUTE_GROUP_ID, ETA.ATTRIBUTE_ID, ETA.ROW_NUMBER)' ||
13901       ' ORDER BY ETA_OUTER.ATTRIBUTE_GROUP_ID, ETA_OUTER.ROW_NUMBER');
13902 
13903     -----------------------------------------------------------------------------------
13904     -- Parse and execute the query, and associate the output columns with our record --
13905     -----------------------------------------------------------------------------------
13906     Debug_Msg(l_api_name||' complete query '|| FND_DSQL.Get_Text(), 1);
13907     Debug_Msg(l_api_name||' using binds template_id: '||p_template_id||' , '||
13908               ' class code: '||l_class_code_hierarchy
13909               , 1);
13910 
13911     DBMS_SQL.Parse(l_cursor_id, FND_DSQL.Get_Text(), DBMS_SQL.Native);
13912     FND_DSQL.Set_Cursor(l_cursor_id);
13913     FND_DSQL.Do_Binds();
13914     DBMS_SQL.Define_Column(l_cursor_id, 1, l_templ_attr_rec.ATTRIBUTE_GROUP_ID);
13915     DBMS_SQL.Define_Column(l_cursor_id, 2, l_templ_attr_rec.ATTRIBUTE_ID);
13916     DBMS_SQL.Define_Column(l_cursor_id, 3, l_templ_attr_rec.ROW_NUMBER);
13917     DBMS_SQL.Define_Column(l_cursor_id, 4, l_templ_attr_rec.ATTRIBUTE_STRING_VALUE, 150);
13918     DBMS_SQL.Define_Column(l_cursor_id, 5, l_templ_attr_rec.ATTRIBUTE_NUMBER_VALUE);
13919     DBMS_SQL.Define_Column(l_cursor_id, 6, l_templ_attr_rec.ATTRIBUTE_UOM_CODE, 3);
13920     DBMS_SQL.Define_Column(l_cursor_id, 7, l_templ_attr_rec.ATTRIBUTE_DATE_VALUE);
13921     DBMS_SQL.Define_Column(l_cursor_id, 8, l_templ_attr_rec.ATTRIBUTE_TRANSLATED_VALUE, 1000);
13922     l_rows_fetched := DBMS_SQL.Execute(l_cursor_id);
13923 
13924     WHILE (DBMS_SQL.Fetch_Rows(l_cursor_id) > 0)
13925     LOOP
13926 
13927       DBMS_SQL.Column_Value(l_cursor_id, 1, l_templ_attr_rec.ATTRIBUTE_GROUP_ID);
13928       DBMS_SQL.Column_Value(l_cursor_id, 2, l_templ_attr_rec.ATTRIBUTE_ID);
13929       DBMS_SQL.Column_Value(l_cursor_id, 3, l_templ_attr_rec.ROW_NUMBER);
13930       DBMS_SQL.Column_Value(l_cursor_id, 4, l_templ_attr_rec.ATTRIBUTE_STRING_VALUE);
13931       DBMS_SQL.Column_Value(l_cursor_id, 5, l_templ_attr_rec.ATTRIBUTE_NUMBER_VALUE);
13932       DBMS_SQL.Column_Value(l_cursor_id, 6, l_templ_attr_rec.ATTRIBUTE_UOM_CODE);
13933       DBMS_SQL.Column_Value(l_cursor_id, 7, l_templ_attr_rec.ATTRIBUTE_DATE_VALUE);
13934       DBMS_SQL.Column_Value(l_cursor_id, 8, l_templ_attr_rec.ATTRIBUTE_TRANSLATED_VALUE);
13935 
13936       Debug_Msg(l_api_name ||' processing AG '||l_templ_attr_rec.ATTRIBUTE_GROUP_ID,1);
13937       -----------------------------------------------------------------------
13938       -- Find out whether we're at the beginning of an Attr Group or a row --
13939       -----------------------------------------------------------------------
13940       l_at_start_of_ag := (l_prev_loop_ag_id IS NULL OR
13941                            l_templ_attr_rec.ATTRIBUTE_GROUP_ID <> l_prev_loop_ag_id);
13942 
13943       ----------------------------------------------------------
13944       -- If we switched Attr Groups, we switched rows as well --
13945       ----------------------------------------------------------
13946       l_at_start_of_row := (l_at_start_of_ag OR
13947                             l_prev_loop_row_number IS NULL OR
13948                             l_templ_attr_rec.ROW_NUMBER <> l_prev_loop_row_number);
13949 
13950       -------------------------------------------------------------
13951       -- If we are at the start of the first row, initialize our --
13952       -- name/value pair array.  Otherwise, we want to process   --
13953       -- the data we've collected over the previous few loops    --
13954       -------------------------------------------------------------
13955       IF (l_at_start_of_row) THEN
13956 
13957         l_row_index := l_row_index + 1;
13958 
13959         IF (l_prev_loop_row_number IS NULL) THEN
13960           l_attr_name_value_pairs := EGO_USER_ATTR_DATA_TABLE();
13961         ELSE
13962 
13963           --Start Bug 5211171
13964 /***
13965 
13966           Debug_Msg(l_api_name||' ATTR_GROUP_ID '||l_attr_group_metadata_obj.ATTR_GROUP_ID, 1);
13967           Debug_Msg(l_api_name||' CLASS_CODE_HIERARCHY OBTAINED '||l_class_code_hierarchy, 1);
13968           Debug_Msg(l_api_name||' OBJECT_NAME '||p_object_name, 1);
13969           Debug_Msg(l_api_name||' OBJECT_ID '||l_object_id, 1);
13970 
13971           l_decode_query := 'SELECT DECODE(ATTRIBUTE2, 1, ATTRIBUTE3, 2, ATTRIBUTE5,3, ATTRIBUTE7,''NONE'') ';
13972           l_decode_query := l_decode_query||' FROM FND_LOOKUP_VALUES ';
13973           l_decode_query := l_decode_query||' WHERE LOOKUP_TYPE = ''EGO_EF_DATA_LEVEL'' ';
13974           l_decode_query := l_decode_query||' AND LANGUAGE = USERENV(''LANG'') ';
13975           l_decode_query := l_decode_query||' AND LOOKUP_CODE = (SELECT DATA_LEVEL ';
13976           l_decode_query := l_decode_query||' FROM EGO_OBJ_AG_ASSOCS_B ';
13977           l_decode_query := l_decode_query||' WHERE OBJECT_ID  = '||l_object_id;
13978           l_decode_query := l_decode_query||' AND ATTR_GROUP_ID = '||l_attr_group_metadata_obj.ATTR_GROUP_ID;
13979           l_decode_query := l_decode_query||' AND ROWNUM = 1 ';
13980           l_decode_query := l_decode_query||' AND CLASSIFICATION_CODE IN ('||l_class_code_hierarchy;
13981           l_decode_query := l_decode_query||'))';
13982 
13983           EXECUTE IMMEDIATE l_decode_query INTO l_rev_level;
13984           Debug_Msg(l_api_name||' DECODE QUERY  :'||l_decode_query, 1);
13985 
13986           Debug_Msg(l_api_name||' OBTAINED REVISION LEVEL,'||l_rev_level, 1);
13987 
13988           IF ( (l_rev_level = 'NONE' AND p_data_level_name_value_pairs IS NULL)
13989                OR
13990                (l_rev_level <> 'NONE' AND p_data_level_name_value_pairs IS NOT NULL )
13991              ) THEN
13992 
13993 ***/
13994 
13995           Is_Name_Value_Pairs_Valid
13996              ( p_attr_group_id               => l_attr_group_metadata_obj.attr_group_id
13997               ,p_data_level_name             => p_data_level
13998               ,p_class_code_hierarchy        => l_class_code_hierarchy
13999               ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
14000               ,x_data_level_id               => l_data_level_id
14001               ,x_name_value_pair_valid       => l_Perform_DML_On_Template_Row
14002              );
14003 
14004           IF FND_API.TO_BOOLEAN(l_Perform_DML_On_Template_Row) THEN
14005             Debug_Msg(l_api_name ||' CALLING Perform_DML_On_Template_Row in the loop ',1);
14006             Perform_DML_On_Template_Row(
14007                   p_object_id                    => l_object_id
14008                   ,p_attr_group_metadata_obj     => l_attr_group_metadata_obj
14009                   ,p_ext_table_metadata_obj      => l_ext_table_metadata_obj
14010                   ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
14011                   ,p_class_code_name_value_pairs => p_class_code_name_value_pairs
14012                   ,p_data_level                  => p_data_level
14013                   ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
14014                   ,px_attr_name_value_pairs      => l_attr_name_value_pairs
14015                   ,p_commit                      => FND_API.G_FALSE -- we don't commit until the end
14016                   );
14017           ELSE
14018             Debug_Msg(l_api_name ||' no need to call Perform_DML_On_Template_Row in the loop ',1);
14019           END IF;
14020          --End Bug 5211171
14021 
14022           ----------------------------------------------
14023           -- After processing this row, clear out the --
14024           -- name/value pairs array for the next row  --
14025           ----------------------------------------------
14026           l_attr_name_value_pairs.DELETE();
14027         END IF;
14028 
14029         ----------------------------------------------------------
14030         -- If we switched Attr Groups as well as rows, we fetch --
14031         -- l_attr_group_metadata_obj for the new Attr Group     --
14032         ----------------------------------------------------------
14033         IF (l_at_start_of_ag) THEN
14034 
14035           l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(
14036                                          p_attr_group_id => l_templ_attr_rec.ATTRIBUTE_GROUP_ID
14037                                        );
14038 
14039           IF (l_attr_group_metadata_obj IS NULL) THEN
14040 
14041             l_token_table(1).TOKEN_NAME := 'AG_ID';
14042             l_token_table(1).TOKEN_VALUE := l_templ_attr_rec.ATTRIBUTE_GROUP_ID;
14043 
14044             ERROR_HANDLER.Add_Error_Message(
14045               p_message_name      => 'EGO_EF_ATTR_GROUP_ID_NOT_FOUND'
14046              ,p_application_id    => 'EGO'
14047              ,p_token_tbl         => l_token_table
14048              ,p_message_type      => FND_API.G_RET_STS_ERROR
14049              ,p_row_identifier    => l_row_index + 1 --we haven't incremented yet
14050              ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
14051             );
14052 
14053             RAISE FND_API.G_EXC_ERROR;
14054           END IF;
14055         END IF;
14056       END IF;
14057 
14058       l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
14059                                p_attr_metadata_table => l_attr_group_metadata_obj.attr_metadata_table
14060                               ,p_attr_id             => l_templ_attr_rec.ATTRIBUTE_ID
14061                              );
14062 
14063       IF (l_attr_metadata_obj IS NULL OR
14064           l_attr_metadata_obj.ATTR_NAME IS NULL) THEN
14065 
14066         l_token_table(1).TOKEN_NAME := 'ATTR_ID';
14067         l_token_table(1).TOKEN_VALUE := l_templ_attr_rec.ATTRIBUTE_ID;
14068 
14069         ERROR_HANDLER.Add_Error_Message(
14070           p_message_name      => 'EGO_EF_ATTR_ID_NOT_FOUND'
14071          ,p_application_id    => 'EGO'
14072          ,p_token_tbl         => l_token_table
14073          ,p_message_type      => FND_API.G_RET_STS_ERROR
14074          ,p_row_identifier    => l_row_index + 1 --we haven't incremented yet
14075          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
14076         );
14077 
14078         RAISE FND_API.G_EXC_ERROR;
14079       END IF;
14080 
14081       ------------------------------------------------------------------
14082       -- Whether or not we're at the start of a row, we've fetched a  --
14083       -- record, so we load its values into the name/value pair array --
14084       -- NOTE: we will have display values instead of internal values --
14085       -- for Attributes with Value Sets that use bind values, in such --
14086       -- cases, we store the Template record value in ATTR_DISP_VALUE --
14087       -- instead of ATTR_VALUE_STR, and we will later convert it into --
14088       -- its corresponding internal value before validating the row   --
14089       ------------------------------------------------------------------
14090       l_attr_name_value_pairs.EXTEND();
14091       IF (l_attr_metadata_obj.VS_BIND_VALUES_CODE IS NOT NULL AND
14092           l_attr_metadata_obj.VS_BIND_VALUES_CODE <> 'N') THEN
14093 
14094         l_attr_name_value_pairs(l_attr_name_value_pairs.LAST) :=
14095           EGO_USER_ATTR_DATA_OBJ(
14096             l_row_index
14097            ,l_attr_metadata_obj.ATTR_NAME
14098            ,null -- ATTR_VALUE_STR
14099            ,l_templ_attr_rec.ATTRIBUTE_NUMBER_VALUE
14100            ,l_templ_attr_rec.ATTRIBUTE_DATE_VALUE
14101            ,NVL(l_templ_attr_rec.ATTRIBUTE_STRING_VALUE,l_templ_attr_rec.ATTRIBUTE_TRANSLATED_VALUE)
14102            ,l_templ_attr_rec.ATTRIBUTE_UOM_CODE
14103            ,l_row_index
14104           );
14105 
14106       ELSE
14107 
14108         l_attr_name_value_pairs(l_attr_name_value_pairs.LAST) :=
14109           EGO_USER_ATTR_DATA_OBJ(
14110             l_row_index
14111            ,l_attr_metadata_obj.ATTR_NAME
14112            ,NVL(l_templ_attr_rec.ATTRIBUTE_STRING_VALUE,l_templ_attr_rec.ATTRIBUTE_TRANSLATED_VALUE)
14113            ,l_templ_attr_rec.ATTRIBUTE_NUMBER_VALUE
14114            ,l_templ_attr_rec.ATTRIBUTE_DATE_VALUE
14115            ,null -- ATTR_DISP_VALUE
14116            ,l_templ_attr_rec.ATTRIBUTE_UOM_CODE
14117            ,l_row_index
14118           );
14119 
14120       END IF;
14121 
14122       --------------------------------------------------
14123       -- Now we update these values for the next loop --
14124       --------------------------------------------------
14125       l_prev_loop_ag_id := l_templ_attr_rec.ATTRIBUTE_GROUP_ID;
14126       l_prev_loop_row_number := l_templ_attr_rec.ROW_NUMBER;
14127 
14128     END LOOP;
14129 
14130     --bug 9170700
14131     DBMS_SQL.Close_Cursor(l_cursor_id);
14132 
14133     ------------------------------------------------------------------------
14134     -- Now we process the last row (i.e., the row whose values we've been --
14135     -- collecting in the last few loops but that we've not yet processed) --
14136     ------------------------------------------------------------------------
14137     l_row_index := l_row_index + 1;
14138 
14139     IF (l_prev_loop_row_number IS NOT NULL) THEN
14140       --Start Bug 5211171
14141 /***
14142       l_decode_query := 'SELECT DECODE(ATTRIBUTE2, 1, ATTRIBUTE3, 2, ATTRIBUTE5,3, ATTRIBUTE7,''NONE'') ';
14143       l_decode_query := l_decode_query||' FROM FND_LOOKUP_VALUES ';
14144       l_decode_query := l_decode_query||' WHERE LOOKUP_TYPE = ''EGO_EF_DATA_LEVEL'' ';
14145       l_decode_query := l_decode_query||' AND LANGUAGE = USERENV(''LANG'') ';
14146       l_decode_query := l_decode_query||' AND LOOKUP_CODE = (SELECT DATA_LEVEL ';
14147       l_decode_query := l_decode_query||' FROM EGO_OBJ_AG_ASSOCS_B ';
14148       l_decode_query := l_decode_query||' WHERE OBJECT_ID  = '||l_object_id;
14149       l_decode_query := l_decode_query||' AND ATTR_GROUP_ID = '||l_prev_loop_ag_id;
14150       l_decode_query := l_decode_query||' AND ROWNUM = 1 ';
14151       l_decode_query := l_decode_query||' AND CLASSIFICATION_CODE IN ('||l_class_code_hierarchy;
14152       l_decode_query := l_decode_query||'))';
14153 
14154       EXECUTE IMMEDIATE l_decode_query INTO l_rev_level;
14155 
14156       Debug_Msg(l_api_name||' OUT OF LOOP REVISION_LEVEL OBTAINED :'||l_rev_level,1);
14157 ***/
14158       Is_Name_Value_Pairs_Valid
14159          ( p_attr_group_id               => l_prev_loop_ag_id
14160           ,p_data_level_name             => p_data_level
14161           ,p_class_code_hierarchy        => l_class_code_hierarchy
14162           ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
14163           ,x_data_level_id               => l_data_level_id
14164           ,x_name_value_pair_valid       => l_Perform_DML_On_Template_Row
14165          );
14166 
14167       IF FND_API.TO_BOOLEAN(l_Perform_DML_On_Template_Row) THEN
14168         Debug_Msg(l_api_name || ' CALLING Perform_DML_On_Template_Row for data level out of loop',1);
14169         Perform_DML_On_Template_Row(
14170             p_object_id                     => l_object_id
14171            ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
14172            ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
14173            ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
14174            ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
14175            ,p_data_level                    => p_data_level
14176            ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
14177            ,px_attr_name_value_pairs        => l_attr_name_value_pairs
14178            ,p_commit                        => FND_API.G_FALSE -- we don't commit until the end
14179           );
14180       ELSE
14181         Debug_Msg(l_api_name || ' no need to call Perform_DML_On_Template_Row for data level out of loop',1);
14182       END IF;
14183       --End Bug 5211171
14184 
14185     END IF;
14186 
14187     IF FND_API.To_Boolean(p_commit) THEN
14188       COMMIT WORK;
14189     END IF;
14190 
14191     x_return_status := FND_API.G_RET_STS_SUCCESS;
14192     Debug_Msg(l_api_name||' done ',1);
14193     G_ENABLE_DEBUG := FALSE;
14194 
14195   EXCEPTION
14196     WHEN FND_API.G_EXC_ERROR THEN
14197       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR');
14198       IF FND_API.To_Boolean(p_commit) THEN
14199         ROLLBACK TO Perform_DML_From_Template;
14200       END IF;
14201       x_return_status := FND_API.G_RET_STS_ERROR;
14202 
14203       x_msg_count := ERROR_HANDLER.Get_Message_Count();
14204 
14205       IF (x_msg_count > 0) THEN
14206 
14207         ------------------------------------------------------
14208         -- We log all errors we got as we close our session --
14209         ------------------------------------------------------
14210         Close_Business_Object_Session(
14211           p_init_error_handler_flag       => FALSE
14212          ,p_log_errors                    => TRUE
14213          ,p_write_to_concurrent_log       => FALSE
14214         );
14215 
14216         IF (x_msg_count = 1) THEN
14217           DECLARE
14218             message_list  ERROR_HANDLER.Error_Tbl_Type;
14219           BEGIN
14220             ERROR_HANDLER.Get_Message_List(message_list);
14221             x_msg_data := message_list(message_list.FIRST).message_text;
14222           END;
14223         ELSE
14224           x_msg_data := NULL;
14225         END IF;
14226       END IF;
14227 
14228     WHEN OTHERS THEN
14229       Debug_Msg(l_api_name || ' EXCEPTION OTHERS'||SQLERRM);
14230       IF FND_API.To_Boolean(p_commit) THEN
14231         ROLLBACK TO Perform_DML_From_Template;
14232       END IF;
14233       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
14234 
14235       l_token_table(1).TOKEN_NAME := 'PKG_NAME';
14236       l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
14237       l_token_table(2).TOKEN_NAME := 'API_NAME';
14238       l_token_table(2).TOKEN_VALUE := l_api_name;
14239       l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
14240       l_token_table(3).TOKEN_VALUE := SQLERRM;
14241 
14242       ERROR_HANDLER.Add_Error_Message(
14243         p_message_name        => 'EGO_PLSQL_ERR'
14244        ,p_application_id      => 'EGO'
14245        ,p_token_tbl           => l_token_table
14246        ,p_message_type        => FND_API.G_RET_STS_ERROR
14247        ,p_row_identifier      => l_row_index
14248        ,p_addto_fnd_stack     => G_ADD_ERRORS_TO_FND_STACK
14249       );
14250 
14251       x_msg_count := ERROR_HANDLER.Get_Message_Count();
14252 
14253       ------------------------------------------------------
14254       -- We log all errors we got as we close our session --
14255       ------------------------------------------------------
14256       Close_Business_Object_Session(
14257         p_init_error_handler_flag       => FALSE
14258        ,p_log_errors                    => TRUE
14259        ,p_write_to_concurrent_log       => FALSE
14260       );
14261 
14262       IF (x_msg_count = 1) THEN
14263         DECLARE
14264           message_list  ERROR_HANDLER.Error_Tbl_Type;
14265         BEGIN
14266           ERROR_HANDLER.Get_Message_List(message_list);
14267           x_msg_data := message_list(message_list.FIRST).message_text;
14268         END;
14269       ELSE
14270         x_msg_data := NULL;
14271       END IF;
14272 
14273 END Perform_DML_From_Template;
14274 
14275 ----------------------------------------------------------------------
14276 
14277 PROCEDURE Copy_User_Attrs_Data (
14278         p_api_version                   IN   NUMBER
14279        ,p_application_id                IN   NUMBER
14280        ,p_object_id                     IN   NUMBER     DEFAULT NULL
14281        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
14282        ,p_old_pk_col_value_pairs        IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
14283        ,p_old_data_level_id             IN   NUMBER   DEFAULT  NULL
14284        ,p_old_dtlevel_col_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
14285        ,p_new_pk_col_value_pairs        IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
14286        ,p_new_data_level_id             IN   NUMBER   DEFAULT  NULL
14287        ,p_new_dtlevel_col_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
14288        ,p_new_cc_col_value_pairs        IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
14289        ,p_attr_group_list               IN   VARCHAR2   DEFAULT  NULL
14290        ,p_init_error_handler            IN   VARCHAR2   DEFAULT FND_API.G_FALSE
14291        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
14292        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
14293        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
14294        ,x_return_status                 OUT NOCOPY VARCHAR2
14295        ,x_errorcode                     OUT NOCOPY NUMBER
14296        ,x_msg_count                     OUT NOCOPY NUMBER
14297        ,x_msg_data                      OUT NOCOPY VARCHAR2
14298 ) IS
14299 
14300     l_api_name               CONSTANT VARCHAR2(30) := 'Copy_User_Attrs_Data';
14301 
14302     --we don't use l_api_version yet, but eventually we might:
14303     --if we change required parameters, version goes FROM n.x to (n+1).x
14304     --if we change optional parameters, version goes FROM x.n to x.(n+1)
14305     l_api_version            CONSTANT NUMBER := 1.0;
14306 
14307     l_object_id                NUMBER;
14308     l_b_table_name             VARCHAR2(30);
14309     l_tl_table_name            VARCHAR2(30);
14310     l_vl_name                  VARCHAR2(30);
14311     l_ext_table_metadata_obj     EGO_EXT_TABLE_METADATA_OBJ;
14312     l_pk_col_metadata_array      EGO_COL_METADATA_ARRAY;
14313     l_data_level_metadata_array  EGO_COL_METADATA_ARRAY;
14314     l_class_code_metadata_array  EGO_COL_METADATA_ARRAY;
14315     l_pk_index                 NUMBER;
14316     l_dtlevel_index            NUMBER;
14317     l_cc_col_index             NUMBER;
14318     l_cc_value_index           NUMBER;
14319     l_found_value_for_this_col BOOLEAN;
14320     l_insert_pk_sql            VARCHAR2(500);
14321     l_insert_dtlevel_sql       VARCHAR2(500) := '';
14322     l_insert_class_code_sql    VARCHAR2(100) := '';
14323     l_select_pk_sql            VARCHAR2(2000);
14324     l_select_dtlevel_sql       VARCHAR2(2000) := '';
14325     l_select_class_code_sql    VARCHAR2(500) := '';
14326     l_where_pk_sql             VARCHAR2(2000);
14327     l_where_dtlevel_sql        VARCHAR2(2000) := '';
14328     l_where_not_in_sql         VARCHAR2(1000);
14329     l_column_name_to_copy      VARCHAR2(30);
14330     l_base_table_copy_dml      VARCHAR2(10000) := '';
14331     l_tl_table_copy_dml        VARCHAR2(10000) := '';
14332     l_copy_from_ext_id         NUMBER;
14333     l_copy_to_ext_id           NUMBER;
14334     l_dynamic_sql              VARCHAR2(500);
14335     l_b_table_col_names_list   VARCHAR2(3000);
14336     l_tl_table_col_names_list  VARCHAR2(3000);
14337 
14338     l_current_user_id        NUMBER := FND_GLOBAL.User_Id;
14339     l_current_login_id       NUMBER := FND_GLOBAL.Login_Id;
14340     l_dummy                  INTEGER;
14341     l_pk_cursor              INTEGER;
14342     l_pk_array               dbms_sql.Varchar2_Table;
14343     l_dt_array               dbms_sql.Varchar2_Table;
14344     l_pk_array_index         NUMBER := 0;
14345     l_dt_array_index         NUMBER := 0;
14346 
14347 l_has_data_level_id   BOOLEAN  := FALSE;    -- TRUE is for R12C
14348 l_all_dl_cols      VARCHAR2(500);
14349 l_dummy_string     VARCHAR2(32767);
14350 l_delimator_loc    NUMBER;
14351 l_pk_name          VARCHAR2(30);
14352 l_attr_group_type  VARCHAR2(40);
14353 
14354     TYPE DYNAMIC_CUR IS REF CURSOR;
14355     l_dynamic_cursor         DYNAMIC_CUR;
14356 
14357     CURSOR group_types_cursor (cp_application_id NUMBER, cp_object_id NUMBER)
14358     IS
14359     SELECT DISTINCT FDF.DESCRIPTIVE_FLEXFIELD_NAME  ATTR_GROUP_TYPE
14360       FROM EGO_OBJECT_EXT_TABLES_B                  EOET
14361           ,FND_DESCRIPTIVE_FLEXS                    FDF
14362      WHERE EOET.APPLICATION_ID = cp_application_id
14363        AND EOET.OBJECT_ID = cp_object_id
14364        AND FDF.APPLICATION_ID = cp_application_id
14365        AND EOET.APPLICATION_ID = FDF.APPLICATION_ID
14366        AND EOET.EXT_TABLE_NAME = FDF.APPLICATION_TABLE_NAME;
14367 
14368   l_key               VARCHAR2(300);               -- bug 13719629
14369   l_key2              VARCHAR2(300);               -- bug 13719629
14370   l_attr_group_types  LOCAL_MEDIUM_VARCHAR_TABLE;  -- bug 13719629
14371   l_cached_not_in_sql VARCHAR2(1000);              -- bug 13719629
14372 
14373 
14374   BEGIN
14375 
14376     Debug_Msg(l_api_name || ' Starting ');
14377 
14378     IF FND_API.To_Boolean(p_commit) THEN
14379       SAVEPOINT Copy_User_Attrs_Data_PUB;
14380     END IF;
14381 
14382     -- Initialize FND_MSG_PUB if necessary
14383     IF (FND_API.To_Boolean(p_init_fnd_msg_list)) THEN
14384       FND_MSG_PUB.Initialize;
14385     END IF;
14386 
14387     -- Initialize ERROR_HANDLER if necessary
14388     IF (FND_API.To_Boolean(p_init_error_handler)) THEN
14389       ERROR_HANDLER.Initialize();
14390     END IF;
14391 
14392     -- Check for call compatibility
14393     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
14394                                         l_api_name, G_PKG_NAME)
14395     THEN
14396       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
14397     END IF;
14398 
14399     IF (FND_API.To_Boolean(p_add_errors_to_fnd_stack)) THEN
14400       G_ADD_ERRORS_TO_FND_STACK := 'Y';
14401     ELSE
14402       G_ADD_ERRORS_TO_FND_STACK := 'N';
14403     END IF;
14404 
14405     IF (p_object_id IS NULL) THEN
14406       l_object_id := Get_Object_Id_From_Name(p_object_name);
14407     ELSE
14408       l_object_id := p_object_id;
14409     END IF;
14410 
14411     --------------------------------------------------------------------
14412     -- The metadata for all extension tables (though not their names) --
14413     -- will be the same for all group types, so we only query it once --
14414     --------------------------------------------------------------------
14415     l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
14416 
14417     ---------------------------------------------------------------------
14418     -- Now we build strings that will be necessary for the rest of the --
14419     -- processing and, like l_ext_table_metadata_obj, won't change     --
14420     ---------------------------------------------------------------------
14421     l_pk_col_metadata_array := l_ext_table_metadata_obj.pk_column_metadata;
14422     l_data_level_metadata_array := l_ext_table_metadata_obj.data_level_metadata;
14423     l_class_code_metadata_array := l_ext_table_metadata_obj.class_code_metadata;
14424 
14425     IF p_old_data_level_id IS NOT NULL OR p_new_data_level_id IS NOT NULL THEN
14426       l_has_data_level_id := TRUE;
14427     ELSE
14428       l_has_data_level_id := FALSE;
14429     END IF;
14430     -- processing the pk cols
14431     IF (p_old_pk_col_value_pairs.COUNT <> p_new_pk_col_value_pairs.COUNT) THEN
14432       x_msg_data := 'EGO_EF_CP_PK_COL_COUNT_ERR';
14433       RAISE FND_API.G_EXC_ERROR;
14434     END IF;
14435 
14436     l_pk_index := p_old_pk_col_value_pairs.FIRST;
14437     WHILE (l_pk_index <= p_old_pk_col_value_pairs.LAST)
14438     LOOP
14439       -- assuming that the l_pk_col_metadata_array will be greater than or equal to p_old_pk_col_value_pairs
14440       IF (p_old_pk_col_value_pairs(l_pk_index).NAME = p_new_pk_col_value_pairs(l_pk_index).NAME AND
14441           p_old_pk_col_value_pairs(l_pk_index).NAME = l_pk_col_metadata_array(l_pk_index).COL_NAME) THEN
14442 
14443         IF (p_old_pk_col_value_pairs(l_pk_index).VALUE IS NOT NULL AND
14444             p_new_pk_col_value_pairs(l_pk_index).VALUE IS NOT NULL) THEN
14445           l_select_pk_sql := l_select_pk_sql ||'''' ||p_new_pk_col_value_pairs(l_pk_index).VALUE ||''', ';
14446           l_pk_array_index := l_pk_array_index +1 ;
14447           l_pk_array(l_pk_array_index) := p_old_pk_col_value_pairs(l_pk_index).VALUE;
14448           l_where_pk_sql  := l_where_pk_sql ||p_old_pk_col_value_pairs(l_pk_index).NAME ||' = :PK' ||l_pk_array_index ||' AND ';
14449           l_insert_pk_sql := l_insert_pk_sql ||p_old_pk_col_value_pairs(l_pk_index).NAME ||', ';
14450         END IF;
14451         l_where_not_in_sql := l_where_not_in_sql ||'''' ||l_pk_col_metadata_array(l_pk_index).COL_NAME ||''', ' ;
14452       ELSE
14453         x_msg_data := 'EGO_EF_CP_PK_COL_NAME_ERR';
14454         RAISE FND_API.G_EXC_ERROR;
14455       END IF;
14456 
14457       l_pk_index := p_old_pk_col_value_pairs.NEXT(l_pk_index);
14458     END LOOP;
14459 
14460     Debug_Msg(l_api_name || ' After PK loop l_insert_pk_sql: '||l_insert_pk_sql);
14461     Debug_Msg(l_api_name || ' After PK loop l_select_pk_sql: '||l_select_pk_sql);
14462     Debug_Msg(l_api_name || ' After PK loop l_where_pk_sql: '||l_where_pk_sql);
14463 
14464     --processing data levels
14465     IF p_old_data_level_id IS NOT NULL OR p_new_data_level_id IS NOT NULL THEN
14466 
14467       -- R12C code changes is this based on data_level_id or an assumption!!
14468       -- preparing where clause from the data levels
14469       IF p_old_dtlevel_col_value_pairs IS NOT NULL AND p_old_dtlevel_col_value_pairs.COUNT > 0 THEN
14470         l_dtlevel_index := p_old_dtlevel_col_value_pairs.FIRST;
14471         WHILE (l_dtlevel_index <= p_old_dtlevel_col_value_pairs.LAST)
14472         LOOP
14473           IF (p_old_dtlevel_col_value_pairs(l_dtlevel_index).VALUE IS NOT NULL) THEN
14474             l_dt_array_index := l_dt_array_index +1 ;
14475             l_dt_array(l_dt_array_index) := p_old_dtlevel_col_value_pairs(l_dtlevel_index).VALUE;
14476             l_where_dtlevel_sql := l_where_dtlevel_sql ||p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||' = :DT' ||l_dt_array_index || ' AND ';
14477           ELSE
14478             l_where_dtlevel_sql := l_where_dtlevel_sql ||p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||' IS NULL AND ';
14479           END IF;  -- if null
14480           l_dtlevel_index := p_old_dtlevel_col_value_pairs.NEXT(l_dtlevel_index);
14481         END LOOP;
14482       END IF;
14483 
14484       -- preparing select and insert statement for new data levels
14485       IF p_new_dtlevel_col_value_pairs IS NOT NULL AND p_new_dtlevel_col_value_pairs.COUNT > 0 THEN
14486         l_dtlevel_index := p_new_dtlevel_col_value_pairs.FIRST;
14487         WHILE (l_dtlevel_index <= p_new_dtlevel_col_value_pairs.LAST)
14488         LOOP
14489           IF (p_new_dtlevel_col_value_pairs(l_dtlevel_index).VALUE IS NOT NULL) THEN
14490             l_select_dtlevel_sql := l_select_dtlevel_sql ||'''' ||p_new_dtlevel_col_value_pairs(l_dtlevel_index).VALUE ||''', ';
14491           ELSE
14492             l_select_dtlevel_sql := l_select_dtlevel_sql || ' NULL, ';
14493           END IF;  -- if null
14494           l_insert_dtlevel_sql := l_insert_dtlevel_sql ||p_new_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||', ';
14495           l_dtlevel_index := p_new_dtlevel_col_value_pairs.NEXT(l_dtlevel_index);
14496         END LOOP;
14497       END IF;
14498 
14499   ELSE  --  p_old_data_level_id IS NOT NULL OR p_new_data_level_id IS NOT NULL
14500 
14501      -- existing code
14502       -- need to process data level only if it's not null
14503       IF (p_old_dtlevel_col_value_pairs IS NULL AND
14504           p_new_dtlevel_col_value_pairs IS NULL AND
14505           l_data_level_metadata_array IS NOT NULL) THEN
14506         x_msg_data := 'EGO_EF_CP_DL_NOT_PASSED_ERR';
14507         RAISE FND_API.G_EXC_ERROR;
14508       ELSIF (p_old_dtlevel_col_value_pairs IS NOT NULL AND
14509              p_new_dtlevel_col_value_pairs  IS NOT NULL) THEN
14510         IF (p_old_dtlevel_col_value_pairs.COUNT <> p_new_dtlevel_col_value_pairs.COUNT)  THEN
14511           x_msg_data := 'EGO_EF_CP_DL_COUNT_ERR';
14512           RAISE FND_API.G_EXC_ERROR;
14513         END IF;
14514         l_dtlevel_index := p_old_dtlevel_col_value_pairs.FIRST;
14515         WHILE (l_dtlevel_index <= p_old_dtlevel_col_value_pairs.LAST)
14516         LOOP
14517           -- need to check if the names are correct.
14518           IF (p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME = p_new_dtlevel_col_value_pairs(l_dtlevel_index).NAME AND
14519               p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME = l_data_level_metadata_array(l_dtlevel_index).COL_NAME) THEN
14520 
14521             IF (p_old_dtlevel_col_value_pairs(l_dtlevel_index).VALUE IS NOT NULL AND
14522                 p_new_dtlevel_col_value_pairs(l_dtlevel_index).VALUE IS NOT NULL) THEN
14523               l_select_dtlevel_sql := l_select_dtlevel_sql ||'''' ||p_new_dtlevel_col_value_pairs(l_dtlevel_index).VALUE ||''', ';
14524               l_dt_array_index := l_dt_array_index +1 ;
14525               l_dt_array(l_dt_array_index) := p_old_dtlevel_col_value_pairs(l_dtlevel_index).VALUE;
14526               l_where_dtlevel_sql := l_where_dtlevel_sql ||p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||' = :DT' ||l_dt_array_index || ' AND ';
14527             ELSE
14528               l_select_dtlevel_sql := l_select_dtlevel_sql || ' NULL, ';
14529               l_where_dtlevel_sql := l_where_dtlevel_sql ||p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||' IS NULL AND ';
14530             END IF;  -- if null
14531             l_insert_dtlevel_sql := l_insert_dtlevel_sql ||p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||', ';
14532             l_where_not_in_sql := l_where_not_in_sql ||'''' ||l_data_level_metadata_array(l_dtlevel_index).COL_NAME ||''', ';
14533           ELSE
14534             x_msg_data := 'EGO_EF_CP_DL_NAME_ERR';
14535             RAISE FND_API.G_EXC_ERROR;
14536           END IF;
14537           l_dtlevel_index := p_old_dtlevel_col_value_pairs.NEXT(l_dtlevel_index);
14538         END LOOP;
14539       END IF; -- if data level IS NOT NULL
14540     END IF;  -- p_old_data_level_id IS NOT NULL OR p_new_data_level_id IS NOT NULL
14541 
14542     Debug_Msg(l_api_name || ' After DL loop l_insert_dtlevel_sql: '||l_insert_dtlevel_sql);
14543     Debug_Msg(l_api_name || ' After DL loop l_select_dtlevel_sql: '||l_select_dtlevel_sql);
14544     Debug_Msg(l_api_name || ' After DL loop l_where_dtlevel_sql: '||l_where_dtlevel_sql);
14545     Debug_Msg(l_api_name || ' After DL loop l_where_not_in_sql: '||l_where_not_in_sql);
14546 
14547     --processing classification codes
14548     l_cc_col_index := l_class_code_metadata_array.FIRST;
14549     WHILE (l_cc_col_index <= l_class_code_metadata_array.LAST)
14550     LOOP
14551       EXIT WHEN l_class_code_metadata_array(l_cc_col_index).COL_NAME IS NULL;
14552 
14553       l_insert_class_code_sql := l_insert_class_code_sql ||
14554                                  l_class_code_metadata_array(l_cc_col_index).COL_NAME ||
14555                                  ', ';
14556       l_where_not_in_sql := l_where_not_in_sql ||
14557                             '''' ||
14558                             l_class_code_metadata_array(l_cc_col_index).COL_NAME ||
14559                             ''', ' ;
14560 
14561       l_found_value_for_this_col := FALSE;
14562       IF (p_new_cc_col_value_pairs IS NOT NULL AND
14563           p_new_cc_col_value_pairs.COUNT > 0) THEN
14564 
14565         -- loop through the passed-in name value pair array to find the right value for selecting
14566         l_cc_value_index := p_new_cc_col_value_pairs.FIRST;
14567         WHILE (l_cc_value_index <= p_new_cc_col_value_pairs.LAST)
14568         LOOP
14569           EXIT WHEN (l_found_value_for_this_col);
14570 
14571           IF (l_class_code_metadata_array(l_cc_col_index).COL_NAME =
14572               p_new_cc_col_value_pairs(l_cc_value_index).NAME) THEN
14573 
14574             l_select_class_code_sql := l_select_class_code_sql || '''' ||
14575                                        p_new_cc_col_value_pairs(l_cc_value_index).VALUE ||
14576                                        ''', ';
14577             l_found_value_for_this_col := TRUE;
14578           END IF;
14579 
14580           l_cc_value_index := p_new_cc_col_value_pairs.NEXT(l_cc_value_index);
14581         END LOOP;
14582       END IF;
14583 
14584       -- if we didn't find a value for the new classification code, we just copy the old one
14585       IF (NOT l_found_value_for_this_col) THEN
14586         l_select_class_code_sql := l_select_class_code_sql ||
14587                                    l_class_code_metadata_array(l_cc_col_index).COL_NAME ||
14588                                    ', ';
14589       END IF;
14590 
14591       l_cc_col_index := l_class_code_metadata_array.NEXT(l_cc_col_index);
14592     END LOOP;
14593     Debug_Msg(l_api_name || ' After CC loop l_select_class_code_sql: '||l_select_class_code_sql);
14594 
14595     -- appending the rest of columns to where not in sql
14596     l_where_not_in_sql := l_where_not_in_sql ||
14597                           '''EXTENSION_ID'', '||
14598                           '''DATA_LEVEL_ID'', '||
14599                           '''CREATED_BY'', '||
14600                           '''CREATION_DATE'', '||
14601                           '''LAST_UPDATED_BY'', '||
14602                           '''LAST_UPDATE_DATE'', '||
14603                           '''LAST_UPDATE_LOGIN''';
14604 
14605     -----------------------------------------------------------------
14606     -- we loop through all ATTR_GROUP_TYPE values for this object, --
14607     -- inserting rows into the B and TL tables for each group type --
14608     -----------------------------------------------------------------
14609 
14610 
14611     --
14612     -- Bug 13719629. Performance issue in get table column list
14613     -- due to high number of executions. Added PLSQL caching
14614     -- logic for attr group type.
14615     -- sreharih. Fri Feb 17 11:08:31 PST 2012
14616     --
14617     l_key := build_key('COPY_UDA_AGT_' || to_char(p_application_id) || '-' || to_char(l_object_id));
14618     l_attr_group_types := get_cached_vartable(p_key => l_key);
14619 
14620     IF l_attr_group_types IS NULL OR l_attr_group_types.COUNT = 0 THEN
14621        OPEN group_types_cursor(p_application_id, l_object_id);
14622        FETCH group_types_cursor BULK COLLECT INTO l_attr_group_types;
14623        CLOSE group_types_cursor;
14624        cache_vartable(p_key   => l_key,
14625                       p_value => l_attr_group_types);
14626     END IF;
14627 
14628     IF l_attr_group_types IS NOT NULL AND l_attr_group_types.COUNT > 0 THEN
14629       FOR agt_itr IN l_attr_group_types.FIRST..l_attr_group_types.LAST
14630       LOOP
14631 
14632       Debug_Msg(l_api_name || ' In Group Rec Loop : '|| l_attr_group_types(agt_itr));
14633       SELECT EXT_TABLE_NAME, EXT_TL_TABLE_NAME, EXT_VL_NAME, ATTR_GROUP_TYPE
14634         INTO l_b_table_name, l_tl_table_name, l_vl_name, l_attr_group_type
14635         FROM EGO_ATTR_GROUP_TYPES_V
14636        WHERE APPLICATION_ID = p_application_id
14637          AND ATTR_GROUP_TYPE = l_attr_group_types(agt_itr);
14638 
14639       l_has_data_level_id := FND_API.TO_BOOLEAN(EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(
14640                                     p_table_name  => l_b_table_name
14641                                    ,p_column_name => 'DATA_LEVEL_ID')
14642                                              );
14643       IF l_has_data_level_id THEN
14644         l_all_dl_cols := EGO_USER_ATTRS_COMMON_PVT.Get_All_Data_Level_PK_Names
14645                                        (p_application_id  => p_application_id
14646                                        ,p_attr_group_type => l_attr_group_type);
14647         -- l_all_dl_cols are in the format a,b,c
14648         -- this need to be changed as 'a','b','c'
14649 		if(l_all_dl_cols is not null) then --for bug 12636760, check if l_all_dl_cols is null
14650         l_where_not_in_sql := l_where_not_in_sql || ', '||REPLACE(''''||l_all_dl_cols||'''',', ',''', ''');
14651         l_all_dl_cols := l_all_dl_cols ||', ';
14652 		end if;
14653         --
14654         -- l_select_dtlevel_sql
14655         -- must be the given new dt level cols + null for the remaining columns in l_all_cols
14656         -- in the same order as in l_all_cols
14657         --
14658         l_select_dtlevel_sql := '';
14659         l_dummy_string := l_all_dl_cols;
14660         WHILE l_dummy_string IS NOT NULL LOOP
14661           l_delimator_loc := INSTR(l_dummy_string,',');
14662           IF l_delimator_loc = 0 THEN
14663             l_pk_name := l_dummy_string;
14664             l_dummy_string := NULL;
14665           ELSE
14666             l_pk_name := SUBSTR(l_dummy_string,0,l_delimator_loc);
14667             l_dummy_string := SUBSTR(l_dummy_string,l_delimator_loc+1);
14668           END IF;
14669           l_pk_name :=  TRIM(SUBSTR(TRIM(l_pk_name),1,LENGTH(TRIM(l_pk_name))-1));
14670           IF INSTR(l_insert_dtlevel_sql,l_pk_name) = 0 THEN
14671             l_select_dtlevel_sql := l_select_dtlevel_sql || ' NULL, ';
14672           ELSE
14673             IF p_new_dtlevel_col_value_pairs IS NOT NULL AND p_new_dtlevel_col_value_pairs.COUNT > 0 THEN
14674               l_dtlevel_index := p_new_dtlevel_col_value_pairs.FIRST;
14675               WHILE (l_dtlevel_index <= p_new_dtlevel_col_value_pairs.LAST)
14676               LOOP
14677                 IF (p_new_dtlevel_col_value_pairs(l_dtlevel_index).NAME = l_pk_name) THEN
14678                   l_select_dtlevel_sql := l_select_dtlevel_sql ||'''' ||p_new_dtlevel_col_value_pairs(l_dtlevel_index).VALUE ||''', ';
14679                   EXIT;
14680                 END IF;  -- if null
14681                 l_insert_dtlevel_sql := l_insert_dtlevel_sql ||p_new_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||', ';
14682                 l_dtlevel_index := p_new_dtlevel_col_value_pairs.NEXT(l_dtlevel_index);
14683               END LOOP;
14684             END IF;
14685           END IF;
14686         END LOOP;
14687       END IF; -- l_has_data_level
14688       ----------------------------------------------
14689       -- Fetch all the base table column names... --
14690       ----------------------------------------------
14691 
14692     --
14693     -- Bug 13719629. Performance issue in get table column list
14694     -- due to high number of executions. Added PLSQL caching
14695     -- logic for column list.
14696     -- l_where_not_in_sql may not be same for combination of l_b_table_name
14697     -- and p_application_id. Hence we are caching it seperately and
14698     -- re-evaulating column list if it is different.
14699     -- sreharih. Fri Feb 17 11:08:31 PST 2012
14700     --
14701     l_key := build_key('COPYUDA_B_' || to_char(p_application_id) || '-' || l_b_table_name);
14702     l_b_table_col_names_list := get_cached_varchar(p_key => l_key);
14703 
14704     l_key2 := build_key('COPYUDA_NOTINSQL_' || to_char(p_application_id) || '-' || l_b_table_name);
14705     l_cached_not_in_sql := get_cached_varchar(p_key => l_key2);
14706     Debug_msg(' l_cached_not_in_sql = ' || l_cached_not_in_sql);
14707     Debug_msg(' l_where_not_in_sql = ' || l_where_not_in_sql);
14708 
14709     IF l_cached_not_in_sql IS NULL OR l_cached_not_in_sql <> l_where_not_in_sql THEN
14710        Debug_msg('l_cached_not_in_sql is null or is not equal to ');
14711        cache_varchar(p_key   => l_key2,
14712                      p_value => l_where_not_in_sql);
14713     END IF;
14714 
14715     IF l_b_table_col_names_list IS NULL OR l_cached_not_in_sql <> l_where_not_in_sql THEN
14716       Debug_Msg(l_api_name || ' before Get_Table_Columns_List '||l_where_not_in_sql );
14717       l_b_table_col_names_list := Get_Table_Columns_List(
14718                                     p_application_id            => p_application_id
14719                                    ,p_from_table_name           => l_b_table_name
14720                                    ,p_from_cols_to_exclude_list => l_where_not_in_sql
14721                                   );
14722       Debug_Msg(l_api_name || ' after Get_Table_Columns_List '|| l_b_table_col_names_list);
14723       cache_varchar(p_key   => l_key,
14724                     p_value => l_b_table_col_names_list);
14725     END IF;
14726 
14727 
14728       -------------------------------------- -----------------------
14729       -- ...and all the TL table column names (if there are any) --
14730       -------------------------------------------------------------
14731       IF (l_tl_table_name IS NOT NULL) THEN
14732 
14733               --
14734               -- Bug 13719629. Performance issue in get table column list
14735               -- due to high number of executions. Added PLSQL caching
14736               -- logic for column list.
14737               -- sreharih. Fri Feb 17 11:08:31 PST 2012
14738               --
14739               l_key := build_key('COPYUDA_TL_' || to_char(p_application_id) || '-' || l_tl_table_name);
14740               l_tl_table_col_names_list := get_cached_varchar(p_key => l_key);
14741 
14742               IF l_tl_table_col_names_list IS NULL OR l_cached_not_in_sql <> l_where_not_in_sql THEN
14743                 l_tl_table_col_names_list := Get_Table_Columns_List(
14744                                        p_application_id            => p_application_id
14745                                       ,p_from_table_name           => l_tl_table_name
14746                                       ,p_from_cols_to_exclude_list => l_where_not_in_sql
14747                                      );
14748                 cache_varchar(p_key   => l_key,
14749                               p_value => l_tl_table_col_names_list);
14750 
14751               END IF;
14752 
14753       END IF;
14754 
14755       -----------------------------------------
14756       -- Build DML statements to use in each --
14757       -- iteration of our extension ID loop  --
14758       -----------------------------------------
14759 
14760       -- Bug 4071472
14761       -- Appending a comma in the end
14762       IF( l_b_table_col_names_list IS NOT NULL )
14763       THEN
14764         l_b_table_col_names_list := l_b_table_col_names_list||',';
14765       END IF;
14766 
14767       IF( l_tl_table_col_names_list IS NOT NULL )
14768       THEN
14769         l_tl_table_col_names_list := l_tl_table_col_names_list||',';
14770       END IF;
14771       Debug_Msg(l_api_name || ' Before Query l_insert_pk_sql: '||l_insert_pk_sql);
14772       Debug_Msg(l_api_name || ' Before Query l_all_dl_cols: '|| l_all_dl_cols );
14773       Debug_Msg(l_api_name || ' Before Query l_insert_class_code_sql: '||l_insert_class_code_sql );
14774       Debug_Msg(l_api_name || ' Before Query l_b_table_col_names_list: '|| l_b_table_col_names_list);
14775       Debug_Msg(l_api_name || ' Before Query l_select_pk_sql: '|| l_select_pk_sql);
14776       Debug_Msg(l_api_name || ' Before Query l_select_dtlevel_sql: '|| l_select_dtlevel_sql);
14777       Debug_Msg(l_api_name || ' Before Query l_select_class_code_sql: '|| l_select_class_code_sql );
14778       Debug_Msg(l_api_name || ' Before Query l_b_table_col_names_list: '|| l_b_table_col_names_list);
14779       Debug_Msg(l_api_name || ' Before Query l_tl_table_col_names_list: '|| l_tl_table_col_names_list);
14780 
14781       IF l_has_data_level_id THEN
14782         l_base_table_copy_dml := ' INSERT INTO '||l_b_table_name||
14783                                  ' (EXTENSION_ID, '||
14784                                     l_insert_pk_sql ||' '||
14785                                   ' DATA_LEVEL_ID, '||
14786                                     l_all_dl_cols ||' '||
14787                                     l_insert_class_code_sql ||' '||
14788                                     l_b_table_col_names_list||' '||
14789                                    'CREATED_BY, '||
14790                                    'CREATION_DATE, '||
14791                                    'LAST_UPDATED_BY, '||
14792                                    'LAST_UPDATE_DATE, '||
14793                                    'LAST_UPDATE_LOGIN)'||
14794                                  ' SELECT '||
14795                                     ':1, '||
14796                                     l_select_pk_sql ||' '||
14797                                     p_new_data_level_id ||', '||
14798                                     l_select_dtlevel_sql ||' '||
14799                                     l_select_class_code_sql ||' '||
14800                                     l_b_table_col_names_list||' '||
14801                                     l_current_user_id||', '||
14802                                    'SYSDATE, '||
14803                                     l_current_user_id||', '||
14804                                    'SYSDATE, '||
14805                                     l_current_login_id||
14806                                  ' FROM '||l_b_table_name||
14807                                 ' WHERE EXTENSION_ID = :2';
14808         IF (l_tl_table_name IS NOT NULL) THEN
14809           l_tl_table_copy_dml := ' INSERT INTO '||l_tl_table_name||
14810                                  ' (EXTENSION_ID, '||
14811                                     l_insert_pk_sql ||' '||
14812                                   ' DATA_LEVEL_ID, '||
14813                                     l_all_dl_cols ||' '||
14814                                     l_insert_class_code_sql ||' '||
14815                                     l_tl_table_col_names_list||' '||
14816                                    'CREATED_BY, '||
14817                                    'CREATION_DATE, '||
14818                                    'LAST_UPDATED_BY, '||
14819                                    'LAST_UPDATE_DATE, '||
14820                                    'LAST_UPDATE_LOGIN)'||
14821                                  ' SELECT '||
14822                                     ':1, '||
14823                                     l_select_pk_sql ||' '||
14824                                     p_new_data_level_id ||', '||
14825                                     l_select_dtlevel_sql ||' '||
14826                                     l_select_class_code_sql ||' '||
14827                                     l_tl_table_col_names_list||' '||
14828                                     l_current_user_id||', '||
14829                                    'SYSDATE, '||
14830                                     l_current_user_id||', '||
14831                                    'SYSDATE, '||
14832                                     l_current_login_id||
14833                                  ' FROM '||l_tl_table_name||
14834                                 ' WHERE EXTENSION_ID = :2';
14835         END IF;
14836       ELSE
14837         l_base_table_copy_dml := ' INSERT INTO '||l_b_table_name||
14838                                  ' (EXTENSION_ID, '||
14839                                     l_insert_pk_sql ||' '||
14840                                     l_insert_dtlevel_sql ||' '||
14841                                     l_insert_class_code_sql ||' '||
14842                                     l_b_table_col_names_list||' '||
14843                                    'CREATED_BY, '||
14844                                    'CREATION_DATE, '||
14845                                    'LAST_UPDATED_BY, '||
14846                                    'LAST_UPDATE_DATE, '||
14847                                    'LAST_UPDATE_LOGIN)'||
14848                                  ' SELECT '||
14849                                     ':1, '||
14850                                     l_select_pk_sql ||' '||
14851                                     l_select_dtlevel_sql ||' '||
14852                                     l_select_class_code_sql ||' '||
14853                                     l_b_table_col_names_list||' '||
14854                                     l_current_user_id||', '||
14855                                    'SYSDATE, '||
14856                                     l_current_user_id||', '||
14857                                    'SYSDATE, '||
14858                                     l_current_login_id||
14859                                  ' FROM '||l_b_table_name||
14860                                 ' WHERE EXTENSION_ID = :2';
14861 
14862         IF (l_tl_table_name IS NOT NULL) THEN
14863           l_tl_table_copy_dml := ' INSERT INTO '||l_tl_table_name||
14864                                  ' (EXTENSION_ID, '||
14865                                     l_insert_pk_sql ||' '||
14866                                     l_insert_dtlevel_sql ||' '||
14867                                     l_insert_class_code_sql ||' '||
14868                                     l_tl_table_col_names_list||' '||
14869                                    'CREATED_BY, '||
14870                                    'CREATION_DATE, '||
14871                                    'LAST_UPDATED_BY, '||
14872                                    'LAST_UPDATE_DATE, '||
14873                                    'LAST_UPDATE_LOGIN)'||
14874                                  ' SELECT '||
14875                                     ':1, '||
14876                                     l_select_pk_sql ||' '||
14877                                     l_select_dtlevel_sql ||' '||
14878                                     l_select_class_code_sql ||' '||
14879                                     l_tl_table_col_names_list||' '||
14880                                     l_current_user_id||', '||
14881                                    'SYSDATE, '||
14882                                     l_current_user_id||', '||
14883                                    'SYSDATE, '||
14884                                     l_current_login_id||
14885                                  ' FROM '||l_tl_table_name||
14886                                 ' WHERE EXTENSION_ID = :2';
14887         END IF;
14888       END IF;  -- l_has_data_level
14889       Debug_Msg(l_api_name || ' l_base_table_copy_dml: '||l_base_table_copy_dml);
14890       Debug_Msg(l_api_name || ' l_tl_table_copy_dml: '||l_tl_table_copy_dml);
14891       ------------------------------------------------------------------------
14892       -- We build a cursor to query extension IDs from the copy-from object --
14893       -- and to generate extension IDs for the copy-to object; then we loop --
14894       -- through that cursor inserting rows for the copy-to object into the --
14895       -- B and TL tables, using the copy-from object's values.              --
14896       ------------------------------------------------------------------------
14897       --bug 8655864 start
14898       Debug_msg(l_api_name || ' l_where_dtlevel_sql: ' || l_where_dtlevel_sql);
14899       IF (p_attr_group_list IS NOT NULL) THEN
14900 
14901         l_dynamic_sql := ' SELECT EXTENSION_ID, EGO_EXTFWK_S.NEXTVAL '||
14902                          ' FROM '||NVL(l_vl_name, l_b_table_name)||
14903                          ' WHERE '||l_where_pk_sql||l_where_dtlevel_sql||
14904                          ' ATTR_GROUP_ID IN ('||p_attr_group_list||')';
14905 
14906       ELSE
14907         l_dynamic_sql := ' SELECT EXTENSION_ID, EGO_EXTFWK_S.NEXTVAL '||
14908                          ' FROM '||NVL(l_vl_name, l_b_table_name)||
14909                          ' WHERE '||l_where_pk_sql||l_where_dtlevel_sql;
14910 
14911       -------------------------------------------------------------
14912       -- Trim the last 'AND' that is left on l_where_dtlevel_sql --
14913       -------------------------------------------------------------
14914        l_dynamic_sql := SUBSTR(l_dynamic_sql, 1, LENGTH(l_dynamic_sql) - LENGTH(' AND'));
14915       END IF;
14916 
14917       --13871278 using binding in l_dynamic_sql
14918       l_pk_cursor := dbms_sql.open_cursor;
14919       DBMS_SQL.PARSE(l_pk_cursor, l_dynamic_sql, DBMS_SQL.native);
14920       DBMS_SQL.DEFINE_COLUMN(l_pk_cursor, 1, l_copy_from_ext_id);
14921       DBMS_SQL.DEFINE_COLUMN(l_pk_cursor, 2, l_copy_to_ext_id);
14922       FOR l_pk_index IN 1 .. l_pk_array.count
14923       LOOP
14924           DBMS_SQL.BIND_VARIABLE(l_pk_cursor, ':PK'||(l_pk_index), l_pk_array(l_pk_index));
14925       END LOOP;
14926       FOR l_dtlevel_index IN 1 .. l_dt_array.count
14927       LOOP
14928           DBMS_SQL.BIND_VARIABLE(l_pk_cursor, ':DT'||(l_dtlevel_index), l_dt_array(l_dtlevel_index));
14929       END LOOP;
14930       l_dummy := DBMS_SQL.EXECUTE(l_pk_cursor);
14931       --bug 8655864 end
14932       --OPEN l_dynamic_cursor FOR l_dynamic_sql;
14933       LOOP
14934         --FETCH l_dynamic_cursor INTO l_copy_from_ext_id, l_copy_to_ext_id;
14935         IF DBMS_SQL.FETCH_ROWS(l_pk_cursor)>0 THEN
14936           DBMS_SQL.COLUMN_VALUE(l_pk_cursor, 1, l_copy_from_ext_id);
14937           DBMS_SQL.COLUMN_VALUE(l_pk_cursor, 2, l_copy_to_ext_id);
14938 
14939         --EXIT WHEN l_dynamic_cursor%NOTFOUND;
14940 
14941           EXECUTE IMMEDIATE l_base_table_copy_dml USING l_copy_to_ext_id, l_copy_from_ext_id;
14942 
14943           IF (l_tl_table_name IS NOT NULL) THEN
14944             EXECUTE IMMEDIATE l_tl_table_copy_dml USING l_copy_to_ext_id, l_copy_from_ext_id;
14945 
14946           END IF;
14947         ELSE
14948           Debug_Msg(l_api_name || ' NO RECORDS in l_pk_cursor');
14949           EXIT;
14950         END IF;
14951       END LOOP;
14952       DBMS_SQL.CLOSE_CURSOR(l_pk_cursor);
14953       --CLOSE l_dynamic_cursor;
14954      END LOOP;
14955     END IF; -- l_attr_group_types
14956 
14957     IF FND_API.To_Boolean(p_commit) THEN
14958       COMMIT WORK;
14959     END IF;
14960 
14961     x_return_status := FND_API.G_RET_STS_SUCCESS;
14962 
14963   EXCEPTION
14964     WHEN FND_API.G_EXC_ERROR THEN
14965       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR');
14966       IF FND_API.To_Boolean(p_commit) THEN
14967         ROLLBACK TO Copy_User_Attrs_Data_PUB;
14968       END IF;
14969       x_return_status := FND_API.G_RET_STS_ERROR;
14970 
14971       ERROR_HANDLER.Add_Error_Message(
14972         p_message_name      => x_msg_data
14973        ,p_application_id    => 'EGO'
14974        ,p_message_type      => FND_API.G_RET_STS_ERROR
14975        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
14976       );
14977 
14978     WHEN OTHERS THEN
14979       IF DBMS_SQL.IS_OPEN(l_pk_cursor) then
14980          DBMS_SQL.CLOSE_CURSOR(l_pk_cursor);
14981       END IF;
14982       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM);
14983       IF FND_API.To_Boolean(p_commit) THEN
14984         ROLLBACK TO Copy_User_Attrs_Data_PUB;
14985       END IF;
14986       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
14987 
14988       DECLARE
14989         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
14990       BEGIN
14991         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
14992         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
14993         l_token_table(2).TOKEN_NAME := 'API_NAME';
14994         l_token_table(2).TOKEN_VALUE := l_api_name;
14995         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
14996         l_token_table(3).TOKEN_VALUE := SQLERRM;
14997 
14998         ERROR_HANDLER.Add_Error_Message(
14999           p_message_name      => 'EGO_PLSQL_ERR'
15000          ,p_application_id    => 'EGO'
15001          ,p_token_tbl         => l_token_table
15002          ,p_message_type      => FND_API.G_RET_STS_ERROR
15003          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
15004         );
15005       END;
15006 
15007 END Copy_User_Attrs_Data;
15008 
15009 ---------------------------------------------------------------------------
15010 
15011 PROCEDURE Implement_Change_Line (
15012         p_api_version                   IN   NUMBER
15013        ,p_object_name                   IN   VARCHAR2
15014        ,p_production_b_table_name       IN   VARCHAR2
15015        ,p_production_tl_table_name      IN   VARCHAR2
15016        ,p_change_b_table_name           IN   VARCHAR2
15017        ,p_change_tl_table_name          IN   VARCHAR2
15018        ,p_tables_application_id         IN   NUMBER
15019        ,p_change_line_id                IN   NUMBER
15020        ,p_old_data_level_nv_pairs       IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
15021        ,p_new_data_level_nv_pairs       IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
15022        ,p_related_class_code_function   IN   VARCHAR2
15023        ,p_init_msg_list                 IN   VARCHAR2   DEFAULT FND_API.G_FALSE
15024        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
15025        ,x_return_status                 OUT NOCOPY VARCHAR2
15026        ,x_errorcode                     OUT NOCOPY NUMBER
15027        ,x_msg_count                     OUT NOCOPY NUMBER
15028        ,x_msg_data                      OUT NOCOPY VARCHAR2
15029 ) IS
15030 
15031     l_api_name               CONSTANT VARCHAR2(30) := 'Implement_Change_Line';
15032 
15033     --we don't use l_api_version yet, but eventually we might:
15034     --if we change required parameters, version goes FROM n.x to (n+1).x
15035     --if we change optional parameters, version goes FROM x.n to x.(n+1)
15036     l_api_version            CONSTANT NUMBER := 1.0;
15037 
15038     l_object_id              NUMBER;
15039     l_data_level_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
15040     l_current_dl_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
15041     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
15042     l_chng_col_names_list    VARCHAR2(20000);
15043     l_cols_to_exclude_list   VARCHAR2(2000);
15044     l_pk_column_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
15045     l_class_code_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
15046     l_b_chng_cols_list       VARCHAR2(10000);
15047     l_tl_chng_cols_list      VARCHAR2(10000);
15048     l_history_b_chng_cols_list VARCHAR2(10000);
15049     l_history_tl_chng_cols_list VARCHAR2(10000);
15050     l_history_b_prod_cols_list VARCHAR2(10000);
15051     l_history_tl_prod_cols_list VARCHAR2(10000);
15052     l_dynamic_sql            VARCHAR2(32767); --the largest a VARCHAR2 can be
15053     l_cursor_id              NUMBER;
15054     l_column_count           NUMBER;
15055     l_desc_table             DBMS_SQL.Desc_Tab;
15056     l_retrieved_value        VARCHAR2(1000);
15057     l_dummy                  NUMBER;
15058     l_current_column_index   NUMBER;
15059     l_current_row_language   VARCHAR2(30);
15060     l_current_row_source_lang VARCHAR2(30);
15061     l_current_acd_type       VARCHAR2(30);
15062     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
15063     l_current_pending_ext_id NUMBER;
15064     l_current_column_name    VARCHAR2(30);
15065     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
15066     l_dummy_err_msg_name     VARCHAR2(30);
15067     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
15068     l_attr_name_value_pairs  EGO_USER_ATTR_DATA_TABLE := EGO_USER_ATTR_DATA_TABLE();
15069     l_uom_column_nv_pairs    LOCAL_COL_NV_PAIR_TABLE;
15070     l_uom_nv_pairs_index     NUMBER := 0;
15071     l_current_uom_col_nv_obj EGO_COL_NAME_VALUE_PAIR_OBJ;
15072     l_attr_col_name_for_uom_col VARCHAR2(30);
15073     l_current_production_ext_id NUMBER;
15074     l_mode_for_current_row   VARCHAR2(10);
15075     l_ext_id_for_current_row NUMBER;
15076     l_utility_dynamic_sql    VARCHAR2(32767); --the largest a VARCHAR2 can be
15077     l_return_status          VARCHAR2(1);
15078     l_errorcode              NUMBER;
15079     l_msg_count              NUMBER;
15080     l_msg_data               VARCHAR2(1000);
15081 
15082   BEGIN
15083 
15084     Debug_Msg('In Implement_Change_Line, starting', 1);
15085 
15086     IF FND_API.To_Boolean(p_commit) THEN
15087       SAVEPOINT Implement_Change_Line_PUB;
15088     END IF;
15089 
15090     -- Initialize FND_MSG_PUB and ERROR_HANDLER if necessary
15091     IF (FND_API.To_Boolean(p_init_msg_list)) THEN
15092       FND_MSG_PUB.Initialize;
15093       ERROR_HANDLER.Initialize;
15094     END IF;
15095 
15096     -- Check for call compatibility
15097     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
15098                                         l_api_name, G_PKG_NAME)
15099     THEN
15100       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
15101     END IF;
15102 
15103     -----------------------------------------------
15104     -- First, we get the Object ID for our calls --
15105     -----------------------------------------------
15106     l_object_id := Get_Object_Id_From_Name(p_object_name);
15107 
15108     ----------------------------------------------------
15109     -- Determine whether we got new Data Level values --
15110     ----------------------------------------------------
15111     IF (p_new_data_level_nv_pairs IS NOT NULL) THEN
15112       l_data_level_name_value_pairs := p_new_data_level_nv_pairs;
15113     ELSE
15114       l_data_level_name_value_pairs := p_old_data_level_nv_pairs;
15115     END IF;
15116 
15117     ---------------------------------------------------------
15118     -- Get the necessary metadata for our production table --
15119     ---------------------------------------------------------
15120     l_ext_table_metadata_obj :=
15121       EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
15122 
15123     ----------------------------------------------------------
15124     -- Build a PK name/value pair array and begin the lists --
15125     -- of column names to fetch explicitly instead of from  --
15126     -- our constructed table columns list                   --
15127     ----------------------------------------------------------
15128 
15129     --
15130     -- ASSUMPTION: no PKs will ever be DATE objects
15131     --
15132     IF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 5) THEN
15133       l_pk_column_name_value_pairs :=
15134         EGO_COL_NAME_VALUE_PAIR_ARRAY(
15135           EGO_COL_NAME_VALUE_PAIR_OBJ(
15136             l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME, NULL
15137           )
15138          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
15139             l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME, NULL
15140           )
15141          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
15142             l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME, NULL
15143           )
15144          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
15145             l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME, NULL
15146           )
15147          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
15148             l_ext_table_metadata_obj.pk_column_metadata(5).COL_NAME, NULL
15149           )
15150         );
15151       l_chng_col_names_list := 'B.'||
15152                                l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
15153                                ',B.'||
15154                                l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
15155                                ',B.'||
15156                                l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME||
15157                                ',B.'||
15158                                l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME||
15159                                ',B.'||
15160                                l_ext_table_metadata_obj.pk_column_metadata(5).COL_NAME;
15161       l_cols_to_exclude_list := ''''||
15162                                 l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
15163                                 ''','''||
15164                                 l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
15165                                 ''','''||
15166                                 l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME||
15167                                 ''','''||
15168                                 l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME||
15169                                 ''','''||
15170                                 l_ext_table_metadata_obj.pk_column_metadata(5).COL_NAME||
15171                                 '''';
15172     ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 4) THEN
15173       l_pk_column_name_value_pairs :=
15174         EGO_COL_NAME_VALUE_PAIR_ARRAY(
15175           EGO_COL_NAME_VALUE_PAIR_OBJ(
15176             l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME, NULL
15177           )
15178          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
15179             l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME, NULL
15180           )
15181          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
15182             l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME, NULL
15183           )
15184          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
15185             l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME, NULL
15186           )
15187         );
15188       l_chng_col_names_list := 'B.'||
15189                                l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
15190                                ',B.'||
15191                                l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
15192                                ',B.'||
15193                                l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME||
15194                                ',B.'||
15195                                l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME;
15196       l_cols_to_exclude_list := ''''||
15197                                 l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
15198                                 ''','''||
15199                                 l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
15200                                 ''','''||
15201                                 l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME||
15202                                 ''','''||
15203                                 l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME||
15204                                 '''';
15205     ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 3) THEN
15206       l_pk_column_name_value_pairs :=
15207         EGO_COL_NAME_VALUE_PAIR_ARRAY(
15208           EGO_COL_NAME_VALUE_PAIR_OBJ(
15209             l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME, NULL
15210           )
15211          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
15212             l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME, NULL
15213           )
15214          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
15215             l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME, NULL
15216           )
15217         );
15218       l_chng_col_names_list := 'B.'||
15219                                l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
15220                                ',B.'||
15221                                l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
15222                                ',B.'||
15223                                l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME;
15224       l_cols_to_exclude_list := ''''||
15225                                 l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
15226                                 ''','''||
15227                                 l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
15228                                 ''','''||
15229                                 l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME||
15230                                 '''';
15231     ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 2) THEN
15232       l_pk_column_name_value_pairs :=
15233         EGO_COL_NAME_VALUE_PAIR_ARRAY(
15234           EGO_COL_NAME_VALUE_PAIR_OBJ(
15235             l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME, NULL
15236           )
15237          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
15238             l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME, NULL
15239           )
15240         );
15241       l_chng_col_names_list := 'B.'||
15242                                l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
15243                                ',B.'||
15244                                l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME;
15245       l_cols_to_exclude_list := ''''||
15246                                 l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
15247                                 ''','''||
15248                                 l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
15249                                 '''';
15250     ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 1) THEN
15251       l_pk_column_name_value_pairs :=
15252         EGO_COL_NAME_VALUE_PAIR_ARRAY(
15253           EGO_COL_NAME_VALUE_PAIR_OBJ(
15254             l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME, NULL
15255           )
15256         );
15257       l_chng_col_names_list := 'B.'||
15258                                l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME;
15259       l_cols_to_exclude_list := ''''||
15260                                 l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
15261                                 '''';
15262     END IF;
15263 
15264     ----------------------------------------------------------
15265     -- Now we add Classification Code columns to the lists, --
15266     -- if necessary; this includes room for a list of Class --
15267     -- Codes that are related to the current Class Code     --
15268     ----------------------------------------------------------
15269     IF (l_ext_table_metadata_obj.class_code_metadata IS NOT NULL AND
15270         l_ext_table_metadata_obj.class_code_metadata.COUNT > 0 AND
15271         l_ext_table_metadata_obj.class_code_metadata(1).COL_NAME IS NOT NULL) THEN
15272       l_class_code_name_value_pairs :=
15273         EGO_COL_NAME_VALUE_PAIR_ARRAY(
15274           EGO_COL_NAME_VALUE_PAIR_OBJ(
15275             l_ext_table_metadata_obj.class_code_metadata(1).COL_NAME, NULL
15276           ),
15277           EGO_COL_NAME_VALUE_PAIR_OBJ(
15278             'RELATED_CLASS_CODE_LIST_1', NULL
15279           )
15280         );
15281 
15282       l_chng_col_names_list := l_chng_col_names_list||',B.'||
15283                                l_ext_table_metadata_obj.class_code_metadata(1).COL_NAME;
15284 
15285       l_cols_to_exclude_list := l_cols_to_exclude_list||','''||
15286                                 l_ext_table_metadata_obj.class_code_metadata(1).COL_NAME||
15287                                 '''';
15288     END IF;
15289 
15290     -----------------------------------------------------------------
15291     -- For Data Level, we exclude the columns but don't explicitly --
15292     -- include them, because we already have the values we want    --
15293     -----------------------------------------------------------------
15294     IF (l_ext_table_metadata_obj.data_level_metadata IS NOT NULL) THEN
15295       IF (l_ext_table_metadata_obj.data_level_metadata.COUNT > 0) THEN
15296         l_cols_to_exclude_list :=
15297           l_cols_to_exclude_list||','''||
15298           l_ext_table_metadata_obj.data_level_metadata(1).COL_NAME||
15299           '''';
15300       END IF;
15301       IF (l_ext_table_metadata_obj.data_level_metadata.COUNT > 1) THEN
15302         l_cols_to_exclude_list :=
15303           l_cols_to_exclude_list||','''||
15304           l_ext_table_metadata_obj.data_level_metadata(2).COL_NAME||
15305           '''';
15306       END IF;
15307       IF (l_ext_table_metadata_obj.data_level_metadata.COUNT > 2) THEN
15308         l_cols_to_exclude_list :=
15309           l_cols_to_exclude_list||','''||
15310           l_ext_table_metadata_obj.data_level_metadata(3).COL_NAME||
15311           '''';
15312       END IF;
15313     END IF;
15314 
15315     ---------------------------------------------------------------
15316     -- Next, we add to the lists the rest of the columns that we --
15317     -- either want to get explicitly or don't want to get at all --
15318     ---------------------------------------------------------------
15319     l_chng_col_names_list := l_chng_col_names_list||
15320                              ',B.ACD_TYPE,B.ATTR_GROUP_ID,B.EXTENSION_ID';
15321     l_cols_to_exclude_list := l_cols_to_exclude_list||
15322                               ',''ACD_TYPE'',''ATTR_GROUP_ID'',''EXTENSION_ID'','||
15323                               '''CHANGE_ID'',''CHANGE_LINE_ID'','||
15324                               '''IMPLEMENTATION_DATE'',''CREATED_BY'','||
15325                               '''CREATION_DATE'',''LAST_UPDATED_BY'','||
15326                               '''LAST_UPDATE_DATE'',''LAST_UPDATE_LOGIN''';
15327 
15328     ----------------------------------------------------------
15329     -- Get lists of columns for the B and TL pending tables --
15330     -- (i.e., all Attr cols and the language cols from TL)  --
15331     ----------------------------------------------------------
15332     l_b_chng_cols_list := Get_Table_Columns_List(
15333                             p_application_id            => p_tables_application_id
15334                            ,p_from_table_name           => p_change_b_table_name
15335                            ,p_from_cols_to_exclude_list => l_cols_to_exclude_list
15336                            ,p_cast_date_cols_to_char    => TRUE
15337                           );
15338     l_tl_chng_cols_list := Get_Table_Columns_List(
15339                              p_application_id            => p_tables_application_id
15340                             ,p_from_table_name           => p_change_tl_table_name
15341                             ,p_from_cols_to_exclude_list => l_cols_to_exclude_list
15342                             ,p_cast_date_cols_to_char    => TRUE
15343                            );
15344 
15345     --------------------------------------------------------
15346     -- While we're getting lists of columns, we also get  --
15347     -- lists for later use in copying old production rows --
15348     -- into the pending tables as HISTORY rows            --
15349     --------------------------------------------------------
15350     l_cols_to_exclude_list := '''CHANGE_ID'', ''CHANGE_LINE_ID'', ''ACD_TYPE'', ''IMPLEMENTATION_DATE'', ''EXTENSION_ID'' , ''PROGRAM_ID'', ''PROGRAM_UPDATE_DATE'' , ''REQUEST_ID'' ,''PROGRAM_APPLICATION_ID'' ';
15351 
15352     l_history_b_chng_cols_list := Get_Table_Columns_List(
15353                                     p_application_id            => p_tables_application_id
15354                                    ,p_from_table_name           => p_change_b_table_name
15355                                    ,p_from_table_alias_prefix   => 'CT'
15356                                    ,p_from_cols_to_exclude_list => l_cols_to_exclude_list
15357                                   );
15358     l_history_tl_chng_cols_list := Get_Table_Columns_List(
15359                                      p_application_id            => p_tables_application_id
15360                                     ,p_from_table_name           => p_change_tl_table_name
15361                                     ,p_from_table_alias_prefix   => 'CT'
15362                                     ,p_from_cols_to_exclude_list => l_cols_to_exclude_list
15363                                    );
15364     l_history_b_prod_cols_list := Get_Table_Columns_List(
15365                                     p_application_id            => p_tables_application_id
15366                                    ,p_from_table_name           => p_production_b_table_name
15367                                    ,p_from_table_alias_prefix   => 'PT'
15368                                    ,p_from_cols_to_exclude_list => l_cols_to_exclude_list
15369                                   );
15370     l_history_tl_prod_cols_list := Get_Table_Columns_List(
15371                                      p_application_id            => p_tables_application_id
15372                                     ,p_from_table_name           => p_production_tl_table_name
15373                                     ,p_from_table_alias_prefix   => 'PT'
15374                                     ,p_from_cols_to_exclude_list => l_cols_to_exclude_list
15375                                    );
15376 
15377     -------------------------------------------------
15378     -- Now we build the SQL for our dynamic cursor --
15379     -------------------------------------------------
15380     l_dynamic_sql := 'SELECT '||l_chng_col_names_list||','||
15381                                 l_b_chng_cols_list||','||
15382                                 l_tl_chng_cols_list||
15383                       ' FROM '||p_change_b_table_name||' B,'||
15384                                 p_change_tl_table_name||' TL'||
15385                      ' WHERE B.ACD_TYPE <> ''HISTORY'' AND B.IMPLEMENTATION_DATE IS NULL'||
15386                        ' AND B.EXTENSION_ID = TL.EXTENSION_ID'||
15387                        ' AND B.ACD_TYPE = TL.ACD_TYPE'||
15388                        ' AND B.CHANGE_LINE_ID = TL.CHANGE_LINE_ID'||
15389                        ' AND B.CHANGE_LINE_ID = :1';
15390 
15391     l_cursor_id := DBMS_SQL.Open_Cursor;
15392     DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
15393     DBMS_SQL.Bind_Variable(l_cursor_id, ':1', p_change_line_id);
15394     DBMS_SQL.Describe_Columns(l_cursor_id, l_column_count, l_desc_table);
15395 
15396     FOR i IN 1 .. l_column_count
15397     LOOP
15398       -------------------------------------------------------------
15399       -- We define all columns as VARCHAR2(1000) for convenience --
15400        -- ASSUMPTION: no PKs will ever be DATE objects           --
15401       -------------------------------------------------------------
15402       DBMS_SQL.Define_Column(l_cursor_id, i, l_retrieved_value, 1000);
15403     END LOOP;
15404 
15405     ----------------------------------
15406     -- Execute our dynamic query... --
15407     ----------------------------------
15408     l_dummy := DBMS_SQL.Execute(l_cursor_id);
15409 
15410     ----------------------------------------------------
15411     -- ...then loop through the result set, gathering --
15412     -- the column values and then calling Process_Row --
15413     ----------------------------------------------------
15414     WHILE (DBMS_SQL.Fetch_Rows(l_cursor_id) > 0)
15415     LOOP
15416 
15417       l_current_column_index := 1;
15418       l_attr_name_value_pairs.DELETE();
15419 
15420       ------------------------------------
15421       -- Get the PK values for this row --
15422       ------------------------------------
15423       IF (l_pk_column_name_value_pairs.COUNT > 0) THEN
15424         DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
15425         l_current_column_index := l_current_column_index + 1;
15426         l_pk_column_name_value_pairs(1).VALUE := SUBSTRB(l_retrieved_value, 1, 150);
15427       END IF;
15428       IF (l_pk_column_name_value_pairs.COUNT > 1) THEN
15429         DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
15430         l_current_column_index := l_current_column_index + 1;
15431         l_pk_column_name_value_pairs(2).VALUE := SUBSTRB(l_retrieved_value, 1, 150);
15432       END IF;
15433       IF (l_pk_column_name_value_pairs.COUNT > 2) THEN
15434         DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
15435         l_current_column_index := l_current_column_index + 1;
15436         l_pk_column_name_value_pairs(3).VALUE := SUBSTRB(l_retrieved_value, 1, 150);
15437       END IF;
15438       IF (l_pk_column_name_value_pairs.COUNT > 3) THEN
15439         DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
15440         l_current_column_index := l_current_column_index + 1;
15441         l_pk_column_name_value_pairs(4).VALUE := SUBSTRB(l_retrieved_value, 1, 150);
15442       END IF;
15443       IF (l_pk_column_name_value_pairs.COUNT > 4) THEN
15444         DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
15445         l_current_column_index := l_current_column_index + 1;
15446         l_pk_column_name_value_pairs(5).VALUE := SUBSTRB(l_retrieved_value, 1, 150);
15447       END IF;
15448 
15449       ------------------------------------------------
15450       -- Get the Class Code value, if there is one, --
15451       -- and try to get related Class Codes as well --
15452       ------------------------------------------------
15453       IF (l_class_code_name_value_pairs IS NOT NULL AND
15454           l_class_code_name_value_pairs.COUNT > 0) THEN
15455         DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
15456         l_current_column_index := l_current_column_index + 1;
15457         l_class_code_name_value_pairs(1).VALUE := SUBSTRB(l_retrieved_value, 1, 150);
15458 
15459         EXECUTE IMMEDIATE 'BEGIN '||p_related_class_code_function||'(:1, :2); END;'
15460         USING IN  l_class_code_name_value_pairs(1).VALUE,
15461               OUT l_class_code_name_value_pairs(2).VALUE;
15462       END IF;
15463 
15464       ----------------------------
15465       -- Determine the ACD Type --
15466       ----------------------------
15467       DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
15468       l_current_column_index := l_current_column_index + 1;
15469       l_current_acd_type := l_retrieved_value;
15470 
15471       ---------------------------------------------------------
15472       -- Find the Attr Group metadata from the Attr Group ID --
15473       ---------------------------------------------------------
15474       DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
15475       l_current_column_index := l_current_column_index + 1;
15476       l_attr_group_metadata_obj :=
15477         EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(
15478           p_attr_group_id => TO_NUMBER(l_retrieved_value)
15479         );
15480 
15481       ---------------------------------------------------------------
15482       -- Determine whether this Attr Group needs Data Level values --
15483       ---------------------------------------------------------------
15484       IF (Is_Data_Level_Correct
15485              (p_object_id                     => l_object_id
15486              ,p_attr_group_id                 => l_attr_group_metadata_obj.ATTR_GROUP_ID
15487              ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
15488              ,p_class_code_name_value_pairs   => l_class_code_name_value_pairs
15489              ,p_data_level                    => NULL
15490              ,p_data_level_name_value_pairs   => l_data_level_name_value_pairs
15491              ,p_attr_group_disp_name          => l_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME
15492              ,x_err_msg_name                  => l_dummy_err_msg_name
15493              ,x_token_table                   => l_token_table)
15494          ) THEN
15495         l_current_dl_name_value_pairs := l_data_level_name_value_pairs;
15496       ELSE
15497         --------------------------------------------------------------------
15498         -- If the passed-in Data Levels are incorrect (e.g., they include --
15499         -- Revision ID for an Attr Group associated at the Item level),   --
15500         -- we will try to pass NULL and hope it works.  NOTE: this is an  --
15501         -- imperfect fix; it'll work for Items, but maybe not in general  --
15502         --------------------------------------------------------------------
15503 /***
15504 TO DO: make this logic more robust; right now it assumes that either
15505 we use all the passed-in Data Levels or none of them, but what about
15506 someday if there's a multi-DL implementation (i.e., one in which there's
15507 more than a binary situation of "passing DL" or "not passing DL"--e.g.,
15508 "passing some but not all DL")?
15509 ***/
15510         l_token_table.DELETE();
15511         l_current_dl_name_value_pairs := NULL;
15512       END IF;
15513 
15514       --------------------------
15515       -- Get the extension ID --
15516       --------------------------
15517       DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
15518       l_current_column_index := l_current_column_index + 1;
15519       l_current_pending_ext_id := TO_NUMBER(l_retrieved_value);
15520 
15521       -------------------------------------------------------------------
15522       -- Now we loop through the rest of the columns assigning values  --
15523       -- to Attr data objects, which we add to a table of such objects --
15524       -------------------------------------------------------------------
15525       FOR i IN l_current_column_index .. l_column_count
15526       LOOP
15527 
15528         -----------------------------------------------
15529         -- Get the current column name and its value --
15530         -----------------------------------------------
15531         l_current_column_name := l_desc_table(i).COL_NAME;
15532         DBMS_SQL.Column_Value(l_cursor_id, i, l_retrieved_value);
15533 
15534         ------------------------------------------------------------------------
15535         -- See whether the current column belongs to a User-Defined Attribute --
15536         ------------------------------------------------------------------------
15537         l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
15538                                  p_attr_metadata_table => l_attr_group_metadata_obj.attr_metadata_table
15539                                 ,p_db_column_name      => l_current_column_name
15540                                );
15541 
15542         ------------------------------------------------
15543         -- If the current column is an Attr column... --
15544         ------------------------------------------------
15545         IF (l_attr_metadata_obj IS NOT NULL AND
15546             l_attr_metadata_obj.ATTR_NAME IS NOT NULL) THEN
15547 
15548           -----------------------------------------------------
15549           -- ...then we add its value to our Attr data table --
15550           -----------------------------------------------------
15551           l_attr_name_value_pairs.EXTEND();
15552           l_attr_name_value_pairs(l_attr_name_value_pairs.LAST) :=
15553             EGO_USER_ATTR_DATA_OBJ(
15554               1
15555              ,l_attr_metadata_obj.ATTR_NAME
15556              ,null -- ATTR_VALUE_STR
15557              ,null -- ATTR_VALUE_NUM
15558              ,null -- ATTR_VALUE_DATE
15559              ,null -- ATTR_DISP_VALUE
15560              ,null -- ATTR_UNIT_OF_MEASURE (will be set below if necessary)
15561              ,-1
15562             );
15563 
15564           --------------------------------------------------------
15565           -- We assign l_retrieved_value according to data type --
15566           --------------------------------------------------------
15567           IF (l_attr_metadata_obj.DATA_TYPE_CODE = 'N') THEN
15568             -----------------------------
15569             -- We deal with UOMs below --
15570             -----------------------------
15571             l_attr_name_value_pairs(l_attr_name_value_pairs.LAST).ATTR_VALUE_NUM :=
15572               TO_NUMBER(l_retrieved_value);
15573           ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = 'X') THEN
15574             l_attr_name_value_pairs(l_attr_name_value_pairs.LAST).ATTR_VALUE_DATE :=
15575               TRUNC(TO_DATE(l_retrieved_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
15576           ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = 'Y') THEN
15577             l_attr_name_value_pairs(l_attr_name_value_pairs.LAST).ATTR_VALUE_DATE :=
15578               TO_DATE(l_retrieved_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
15579           ELSE
15580             l_attr_name_value_pairs(l_attr_name_value_pairs.LAST).ATTR_VALUE_STR :=
15581               l_retrieved_value;
15582           END IF;
15583         ELSIF (INSTR(l_current_column_name, 'UOM_') = 1) THEN
15584 
15585           --------------------------------------------
15586           -- Store the UOM column's name and value  --
15587           -- in a PL/SQL table for assignment below --
15588           --------------------------------------------
15589           l_uom_nv_pairs_index := l_uom_nv_pairs_index + 1;
15590           l_uom_column_nv_pairs(l_uom_nv_pairs_index) :=
15591             EGO_COL_NAME_VALUE_PAIR_OBJ(l_current_column_name, l_retrieved_value);
15592 
15593         ELSIF (l_current_column_name = 'LANGUAGE') THEN
15594 
15595           -------------------------------------------------------
15596           -- Determine the Language for passing to Process_Row --
15597           -------------------------------------------------------
15598           l_current_row_language := l_retrieved_value;
15599 
15600         ELSIF (l_current_column_name = 'SOURCE_LANG') THEN
15601 
15602           ------------------------------------------------
15603           -- Determine the Source Lang for knowing when --
15604           -- to insert a History row into the B table   --
15605           ------------------------------------------------
15606           l_current_row_source_lang := l_retrieved_value;
15607 
15608         END IF;
15609       END LOOP;
15610 
15611       ---------------------------------------------------------
15612       -- If we gathered any UOM data, we assign all gathered --
15613       -- UOM values to the appropriate Attr data object      --
15614       ---------------------------------------------------------
15615       IF (l_uom_nv_pairs_index > 0) THEN
15616 
15617         FOR i IN 1 .. l_uom_nv_pairs_index
15618         LOOP
15619 
15620           l_current_uom_col_nv_obj := l_uom_column_nv_pairs(i);
15621 
15622           ----------------------------------------------
15623           -- We derive the Attr's DB column name from --
15624           -- the UOM column name in one of two ways   --
15625           ----------------------------------------------
15626           IF (INSTR(l_current_uom_col_nv_obj.NAME, 'UOM_EXT_ATTR') = 1) THEN
15627             l_attr_col_name_for_uom_col := 'N_'||SUBSTR(l_current_uom_col_nv_obj.NAME, 5);
15628           ELSE
15629             l_attr_col_name_for_uom_col := SUBSTR(l_current_uom_col_nv_obj.NAME, 5);
15630           END IF;
15631 
15632           -------------------------------------------------------------
15633           -- Now we find the Attr from the column name we've derived --
15634           -- and set its Attr data object's UOM field with our value --
15635           -------------------------------------------------------------
15636           IF (l_attr_name_value_pairs IS NOT NULL AND
15637               l_attr_name_value_pairs.COUNT > 0) THEN
15638 
15639             l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
15640                                      p_attr_metadata_table => l_attr_group_metadata_obj.attr_metadata_table
15641                                     ,p_db_column_name      => l_attr_col_name_for_uom_col
15642                                    );
15643 
15644             ------------------------------------------------------------------
15645             -- If we found the metadata object, we look for the data object --
15646             ------------------------------------------------------------------
15647             IF (l_attr_metadata_obj IS NOT NULL AND
15648                 l_attr_metadata_obj.ATTR_NAME IS NOT NULL) THEN
15649 
15650               FOR j IN l_attr_name_value_pairs.FIRST .. l_attr_name_value_pairs.LAST
15651               LOOP
15652                 IF (l_attr_name_value_pairs(j).ATTR_NAME =
15653                     l_attr_metadata_obj.ATTR_NAME) THEN
15654 
15655                   -----------------------------------------------------------
15656                   -- When we find the data object, we set its UOM and exit --
15657                   -----------------------------------------------------------
15658                   l_attr_name_value_pairs(j).ATTR_UNIT_OF_MEASURE :=
15659                     l_current_uom_col_nv_obj.VALUE;
15660                   EXIT;
15661 
15662                 END IF;
15663               END LOOP;
15664             END IF;
15665           END IF;
15666         END LOOP;
15667       END IF;
15668 
15669       -------------------------------------------------------------------
15670       -- Now that we've got all necessary data and metadata, we try to --
15671       -- find a corresponding production row for this pending row; we  --
15672       -- use the new data level values if we have them, because we are --
15673       -- trying to see whether or not the row we're about to move into --
15674       -- the production table already exists there                     --
15675       -------------------------------------------------------------------
15676       l_current_production_ext_id :=
15677         Get_Extension_Id_For_Row(
15678           p_attr_group_metadata_obj     => l_attr_group_metadata_obj
15679          ,p_ext_table_metadata_obj      => l_ext_table_metadata_obj
15680          ,p_pk_column_name_value_pairs  => l_pk_column_name_value_pairs
15681          ,p_data_level_name_value_pairs => l_current_dl_name_value_pairs
15682          ,p_attr_name_value_pairs       => l_attr_name_value_pairs
15683         );
15684 
15685       ---------------------------------------------------------------------
15686       -- The mode and extension ID we pass to Process_Row are determined --
15687       -- by the existence of a production row, the ACD Type, and in some --
15688       -- cases by whether the Attr Group is single-row or multi-row      --
15689       ---------------------------------------------------------------------
15690       IF (l_current_acd_type = 'ADD') THEN
15691         IF (l_current_production_ext_id IS NULL) THEN
15692           ---------------------------------------
15693           -- If ACD Type is CREATE and there's --
15694           -- no production row, we create one  --
15695           ---------------------------------------
15696           l_mode_for_current_row := G_IMPLEMENT_CREATE_MODE;
15697           l_ext_id_for_current_row := l_current_pending_ext_id;
15698         ELSE
15699           IF (l_attr_group_metadata_obj.MULTI_ROW_CODE = 'N') THEN
15700             ------------------------------------------------------
15701             -- If ACD Type is CREATE, there's a production row, --
15702             -- and it's a single-row Attr Group, then someone   --
15703             -- created the row after this change was proposed,  --
15704             -- so we'll update the production row; we'll also   --
15705             -- copy the production Ext ID into the pending row  --
15706             -- to record the fact that this pending row updated --
15707             -- this production row                              --
15708             ------------------------------------------------------
15709             l_mode_for_current_row := G_UPDATE_MODE;
15710             l_ext_id_for_current_row := l_current_production_ext_id;
15711 
15712             ------------------------------------------------------------
15713             -- Process_Row will only process our pending B table row  --
15714             -- in the loop when LANGUAGE is NULL or when LANGUAGE =   --
15715             -- SOURCE_LANG, so we change the pending row in that loop --
15716             ------------------------------------------------------------
15717             IF (l_current_row_language IS NULL OR
15718                 l_current_row_language = l_current_row_source_lang) THEN
15719 
15720               l_utility_dynamic_sql := 'UPDATE '||p_change_b_table_name||
15721                                          ' SET EXTENSION_ID = :1'||
15722                                        ' WHERE EXTENSION_ID = :2'||
15723                                          ' AND ACD_TYPE = ''ADD'''||
15724                                          ' AND CHANGE_LINE_ID = :3';
15725               EXECUTE IMMEDIATE l_utility_dynamic_sql
15726               USING l_current_production_ext_id
15727                    ,l_current_pending_ext_id
15728                    ,p_change_line_id;
15729 
15730             END IF;
15731 
15732             l_utility_dynamic_sql := 'UPDATE '||p_change_tl_table_name||
15733                                        ' SET EXTENSION_ID = :1'||
15734                                      ' WHERE EXTENSION_ID = :2'||
15735                                        ' AND ACD_TYPE = ''ADD'''||
15736                                        ' AND CHANGE_LINE_ID = :3'||
15737                                        ' AND LANGUAGE = :4';
15738             EXECUTE IMMEDIATE l_utility_dynamic_sql
15739             USING l_current_production_ext_id
15740                  ,l_current_pending_ext_id
15741                  ,p_change_line_id
15742                  ,l_current_row_language;
15743 
15744           ELSE
15745             ---------------------------------------------------------------
15746             -- We let the ADD + multi-row + existing production row case --
15747             -- through so Get_Extension_Id_And_Mode can throw the error  --
15748             ---------------------------------------------------------------
15749             l_mode_for_current_row := G_IMPLEMENT_CREATE_MODE;
15750             l_ext_id_for_current_row := l_current_pending_ext_id;
15751           END IF;
15752         END IF;
15753       ELSIF (l_current_acd_type = 'CHANGE') THEN
15754         IF (l_current_production_ext_id IS NULL) THEN
15755           -------------------------------------------------------------
15756           -- In every case below, we'll use the pending extension ID --
15757           -------------------------------------------------------------
15758           l_ext_id_for_current_row := l_current_pending_ext_id;
15759 
15760           --
15761           -- TO DO: check if pendingExtID is in prod; if so, error
15762           --
15763 
15764           IF (l_attr_group_metadata_obj.MULTI_ROW_CODE = 'N') THEN
15765             -------------------------------------------------------
15766             -- If ACD Type is CHANGE, there's no production row, --
15767             -- and it's a single-row Attr Group, that means that --
15768             -- the row was somehow deleted since this change was --
15769             -- proposed, so we'll need to re-insert the row.     --
15770             -------------------------------------------------------
15771             l_mode_for_current_row := G_IMPLEMENT_CREATE_MODE;
15772           ELSE
15773             -------------------------------------------------------
15774             -- If ACD Type is CHANGE, there's no production row, --
15775             -- and it's a multi-row Attr Group, there are two    --
15776             -- possibilities: either the row was deleted since   --
15777             -- this change was proposed (in which case we will   --
15778             -- re-insert the row) or else this change involves   --
15779             -- changing Unique Key values (in which case the     --
15780             -- production row really does still exist, and we    --
15781             -- really do want to change it); we look for the     --
15782             -- production row using the pending extension ID to  --
15783             -- see which of these two possibilities we face now  --
15784             -------------------------------------------------------
15785             EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM '||p_change_b_table_name||
15786                               ' WHERE EXTENSION_ID = :1'
15787             INTO l_dummy
15788             USING l_current_pending_ext_id;
15789 
15790             IF (l_dummy > 0) THEN
15791               l_mode_for_current_row := G_UPDATE_MODE;
15792             ELSE
15793               l_mode_for_current_row := G_IMPLEMENT_CREATE_MODE;
15794             END IF;
15795           END IF;
15796         ELSE
15797           ---------------------------------------
15798           -- If ACD Type is CHANGE and there's --
15799           -- a production row, we change it    --
15800           ---------------------------------------
15801           l_mode_for_current_row := G_UPDATE_MODE;
15802           l_ext_id_for_current_row := l_current_production_ext_id;
15803         END IF;
15804       ELSIF (l_current_acd_type = 'DELETE') THEN
15805         IF (l_current_production_ext_id IS NULL) THEN
15806           ---------------------------------------
15807           -- If ACD Type is DELETE and there's --
15808           -- no production row, we do nothing  --
15809           ---------------------------------------
15810           l_mode_for_current_row := 'SKIP';
15811         ELSE
15812           ---------------------------------------
15813           -- If ACD Type is DELETE and there's --
15814           -- a production row, we delete it    --
15815           ---------------------------------------
15816           l_mode_for_current_row := G_DELETE_MODE;
15817           l_ext_id_for_current_row := l_current_production_ext_id;
15818         END IF;
15819       END IF;
15820 
15821       IF (l_mode_for_current_row <> 'SKIP') THEN
15822 
15823         -----------------------------------------------------------
15824         -- If we're altering a production row, we first copy the --
15825         -- row into the pending tables with the ACD Type HISTORY --
15826         -----------------------------------------------------------
15827         IF (l_mode_for_current_row = G_DELETE_MODE OR
15828             l_mode_for_current_row = G_UPDATE_MODE) THEN
15829 
15830           -----------------------------------------------------------
15831           -- Process_Row will only process our pending B table row --
15832           -- in the loop when LANGUAGE is NULL or when LANGUAGE =  --
15833           -- SOURCE_LANG, so we insert a History row in that loop  --
15834           -----------------------------------------------------------
15835           IF (l_current_row_language IS NULL OR
15836               l_current_row_language = l_current_row_source_lang) THEN
15837             l_utility_dynamic_sql := ' INSERT INTO '||p_change_b_table_name||' CT ('||
15838                                      l_history_b_chng_cols_list||
15839                                      ', CT.CHANGE_ID, CT.CHANGE_LINE_ID, CT.ACD_TYPE'||
15840                                      ', CT.EXTENSION_ID) SELECT '||
15841                                      l_history_b_prod_cols_list||
15842                                      ', CT.CHANGE_ID, CT.CHANGE_LINE_ID, ''HISTORY'''||
15843                                      ', PT.EXTENSION_ID FROM '||
15844                                      p_production_b_table_name||' PT, '||
15845                                      p_change_b_table_name||
15846                                      ' CT WHERE PT.EXTENSION_ID = :1'||
15847                                      ' AND CT.EXTENSION_ID = :2'||
15848                                      ' AND CT.CHANGE_LINE_ID = :3'||
15849                                      ' AND CT.ACD_TYPE = :4';
15850 
15851             EXECUTE IMMEDIATE l_utility_dynamic_sql
15852             USING l_ext_id_for_current_row, l_current_pending_ext_id,
15853                   p_change_line_id, l_current_acd_type;
15854 
15855           END IF;
15856 
15857           ------------------------------------------------------------
15858           -- Process_Row will only process the pending TL table row --
15859           -- whose language matches LANGUAGE, so we only insert a   --
15860           -- History row for that row                               --
15861           ------------------------------------------------------------
15862           l_utility_dynamic_sql := ' INSERT INTO '||p_change_tl_table_name||' CT ('||
15863                                    l_history_tl_chng_cols_list||
15864                                    ', CT.CHANGE_ID, CT.CHANGE_LINE_ID, CT.ACD_TYPE'||
15865                                    ', CT.EXTENSION_ID) SELECT '||
15866                                    l_history_tl_prod_cols_list||
15867                                    ', CT.CHANGE_ID, CT.CHANGE_LINE_ID, ''HISTORY'''||
15868                                    ', PT.EXTENSION_ID FROM '||
15869                                    p_production_tl_table_name||' PT, '||
15870                                    p_change_tl_table_name||
15871                                    ' CT WHERE PT.EXTENSION_ID = :1'||
15872                                    ' AND CT.EXTENSION_ID = :2'||
15873                                    ' AND CT.CHANGE_LINE_ID = :3'||
15874                                    ' AND CT.ACD_TYPE = :4'||
15875                                    ' AND CT.LANGUAGE = PT.LANGUAGE AND CT.LANGUAGE = :5';
15876 
15877           EXECUTE IMMEDIATE l_utility_dynamic_sql
15878           USING l_ext_id_for_current_row, l_current_pending_ext_id,
15879                 p_change_line_id, l_current_acd_type, l_current_row_language;
15880 
15881         END IF;
15882 
15883         ---------------------------------------------------------------------
15884         -- Now at last we're ready to call Process_Row on this pending row --
15885         ---------------------------------------------------------------------
15886 
15887         Process_Row(
15888           p_api_version                   => 1.0
15889          ,p_object_name                   => p_object_name
15890          ,p_attr_group_id                 => l_attr_group_metadata_obj.ATTR_GROUP_ID
15891          ,p_application_id                => l_attr_group_metadata_obj.APPLICATION_ID
15892          ,p_attr_group_type               => l_attr_group_metadata_obj.ATTR_GROUP_TYPE
15893          ,p_attr_group_name               => l_attr_group_metadata_obj.ATTR_GROUP_NAME
15894          ,p_pk_column_name_value_pairs    => l_pk_column_name_value_pairs
15895          ,p_class_code_name_value_pairs   => l_class_code_name_value_pairs
15896          ,p_data_level_name_value_pairs   => l_current_dl_name_value_pairs
15897          ,p_extension_id                  => l_ext_id_for_current_row
15898          ,p_attr_name_value_pairs         => l_attr_name_value_pairs
15899          ,p_language_to_process           => l_current_row_language
15900          ,p_mode                          => l_mode_for_current_row
15901          ,p_add_errors_to_fnd_stack       => FND_API.G_TRUE
15902          ,x_return_status                 => x_return_status
15903          ,x_errorcode                     => x_errorcode
15904          ,x_msg_count                     => x_msg_count
15905          ,x_msg_data                      => x_msg_data
15906         );
15907 
15908         IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
15909           RAISE FND_API.G_EXC_ERROR;
15910         END IF;
15911       END IF;
15912     END LOOP;
15913     DBMS_SQL.Close_Cursor(l_cursor_id);
15914 
15915     ---------------------------------------------------------------------------
15916     -- Finally, set the IMPLEMENTATION_DATE for all rows we just implemented --
15917     ---------------------------------------------------------------------------
15918     EXECUTE IMMEDIATE ' UPDATE '||p_change_b_table_name||
15919                          ' SET IMPLEMENTATION_DATE = :1'||
15920                        ' WHERE CHANGE_LINE_ID = :2'
15921     USING SYSDATE, p_change_line_id;
15922     EXECUTE IMMEDIATE ' UPDATE '||p_change_tl_table_name||
15923                          ' SET IMPLEMENTATION_DATE = :1'||
15924                        ' WHERE CHANGE_LINE_ID = :2'
15925     USING SYSDATE, p_change_line_id;
15926 
15927     IF FND_API.To_Boolean(p_commit) THEN
15928       COMMIT WORK;
15929     END IF;
15930 
15931     x_return_status := FND_API.G_RET_STS_SUCCESS;
15932 
15933     Debug_Msg('In Implement_Change_Line, done', 1);
15934 
15935   EXCEPTION
15936     WHEN FND_API.G_EXC_ERROR THEN
15937       Debug_Msg('In Implement_Change_Line, EXCEPTION FND_API.G_EXC_ERROR ', 1);
15938       IF FND_API.To_Boolean(p_commit) THEN
15939         ROLLBACK TO Implement_Change_Line_PUB;
15940       END IF;
15941       x_return_status := FND_API.G_RET_STS_ERROR;
15942 
15943       -----------------------------------------------------------------
15944       -- If Process_Row didn't return any errors, make one ourselves --
15945       -----------------------------------------------------------------
15946       IF (x_msg_data IS NULL AND x_msg_count = 0) THEN
15947         ERROR_HANDLER.Add_Error_Message(
15948           p_message_name              => 'EGO_EF_IMPLEMENT_ERR'
15949          ,p_application_id            => 'EGO'
15950          ,p_message_type              => FND_API.G_RET_STS_ERROR
15951          ,p_addto_fnd_stack           => 'Y'
15952         );
15953       END IF;
15954 
15955       -------------------------------------------------------------------
15956       -- If Process_Row had more than one error, return the first one  --
15957       -- (or else return the one we just added to ERROR_HANDLER above) --
15958       -------------------------------------------------------------------
15959       IF (x_msg_data IS NULL AND x_msg_count > 0) THEN
15960         DECLARE
15961           message_list  ERROR_HANDLER.Error_Tbl_Type;
15962         BEGIN
15963           ERROR_HANDLER.Get_Message_List(message_list);
15964           x_msg_data := message_list(message_list.FIRST).message_text;
15965         END;
15966       END IF;
15967 
15968     Debug_Msg('In Implement_Change_Line, got expected error: x_msg_data is '||x_msg_data, 3);
15969 
15970     WHEN OTHERS THEN
15971       Debug_Msg('In Implement_Change_Line, EXCEPTION OTHERS ', 1);
15972       IF FND_API.To_Boolean(p_commit) THEN
15973         ROLLBACK TO Implement_Change_Line_PUB;
15974       END IF;
15975       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
15976 
15977       DECLARE
15978         l_dummy_entity_index     NUMBER;
15979         l_dummy_entity_id        VARCHAR2(60);
15980         l_dummy_message_type     VARCHAR2(1);
15981       BEGIN
15982         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
15983         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
15984         l_token_table(2).TOKEN_NAME := 'API_NAME';
15985         l_token_table(2).TOKEN_VALUE := l_api_name;
15986         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
15987         l_token_table(3).TOKEN_VALUE := SQLERRM;
15988 
15989         ERROR_HANDLER.Add_Error_Message(
15990           p_message_name                  => 'EGO_PLSQL_ERR'
15991          ,p_application_id                => 'EGO'
15992          ,p_token_tbl                     => l_token_table
15993          ,p_message_type                  => FND_API.G_RET_STS_ERROR
15994          ,p_addto_fnd_stack               => 'Y'
15995         );
15996 
15997         ERROR_HANDLER.Get_Message(x_message_text => x_msg_data
15998                                  ,x_entity_index => l_dummy_entity_index
15999                                  ,x_entity_id    => l_dummy_entity_id
16000                                  ,x_message_type => l_dummy_message_type);
16001       END;
16002 
16003     Debug_Msg('In Implement_Change_Line, got unexpected error: x_msg_data is '||x_msg_data, 3);
16004 
16005 END Implement_Change_Line;
16006 
16007 ----------------------------------------------------------------------
16008 
16009 --------------------------------------------------------------------
16010 -- This procedure retrieves directly from the extension table the --
16011 -- internal value for an attribute.                               --
16012 --------------------------------------------------------------------
16013 
16014 PROCEDURE Get_Ext_Data (
16015         p_attr_group_metadata_obj   IN   EGO_ATTR_GROUP_METADATA_OBJ
16016        ,p_attr_metadata_obj         IN   EGO_ATTR_METADATA_OBJ
16017        ,p_pk_col1                   IN   VARCHAR2
16018        ,p_pk_col2                   IN   VARCHAR2   DEFAULT NULL
16019        ,p_pk_col3                   IN   VARCHAR2   DEFAULT NULL
16020        ,p_pk_col4                   IN   VARCHAR2   DEFAULT NULL
16021        ,p_pk_col5                   IN   VARCHAR2   DEFAULT NULL
16022        ,p_pk_value1                 IN   VARCHAR2
16023        ,p_pk_value2                 IN   VARCHAR2   DEFAULT NULL
16024        ,p_pk_value3                 IN   VARCHAR2   DEFAULT NULL
16025        ,p_pk_value4                 IN   VARCHAR2   DEFAULT NULL
16026        ,p_pk_value5                 IN   VARCHAR2   DEFAULT NULL
16027        ,p_data_level                IN   VARCHAR2   DEFAULT NULL
16028        ,p_dl_pk_values              IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
16029        ,p_dl_metadata_obj           IN   EGO_DATA_LEVEL_METADATA_OBJ   DEFAULT NULL
16030        ,x_str_val                   OUT  NOCOPY     VARCHAR2
16031        ,x_num_val                   OUT  NOCOPY     NUMBER
16032        ,x_date_val                  OUT  NOCOPY     DATE
16033 )
16034 IS
16035 
16036     l_api_name               CONSTANT VARCHAR2(30) := 'Get_Ext_Data';
16037     l_db_column_alias        VARCHAR2(90);
16038     l_dynamic_sql            VARCHAR2(7000);
16039     l_bind_index             NUMBER;
16040     l_cursor                 NUMBER;
16041     l_row_count              NUMBER;
16042     l_str                    VARCHAR2(200);
16043 
16044 l_token_table          ERROR_HANDLER.Token_Tbl_Type;
16045 l_has_data_level_id    BOOLEAN  := FALSE;                   -- TRUE is for R12C
16046 
16047 -- In EGOBETRU.sql, we have the following type declaration:
16048 --   TYPE LOCAL_VARCHAR_TABLE        IS TABLE OF VARCHAR2(80)
16049 l_bind_value_table     LOCAL_VARCHAR_TABLE;
16050 l_bind_var_name        VARCHAR2(80);
16051 l_bind_var_value       VARCHAR2(80);
16052 l_bind_var_value_num       NUMBER;
16053 
16054 l_dl_pk_index          NUMBER;
16055 l_dl_metadata_obj      EGO_DATA_LEVEL_METADATA_OBJ;
16056 
16057 BEGIN
16058 
16059 Debug_Msg(l_api_name || '' );
16060 Debug_Msg(l_api_name || ' Get_Ext_Data (' );
16061 Debug_Msg(l_api_name || '   p_attr_group_metadata_obj => <not printed>');
16062 Debug_Msg(l_api_name || '   p_attr_metadata_obj       => <not printed>');
16063 Debug_Msg(l_api_name || '   p_pk_col1                 => ' || p_pk_col1);
16064 Debug_Msg(l_api_name || '   p_pk_col2                 => ' || p_pk_col2);
16065 Debug_Msg(l_api_name || '   p_pk_col3                 => ' || p_pk_col3);
16066 Debug_Msg(l_api_name || '   p_pk_col4                 => ' || p_pk_col4);
16067 Debug_Msg(l_api_name || '   p_pk_col5                 => ' || p_pk_col5);
16068 Debug_Msg(l_api_name || '   p_pk_value1               => ' || p_pk_value1);
16069 Debug_Msg(l_api_name || '   p_pk_value2               => ' || p_pk_value2);
16070 Debug_Msg(l_api_name || '   p_pk_value3               => ' || p_pk_value3);
16071 Debug_Msg(l_api_name || '   p_pk_value4               => ' || p_pk_value4);
16072 Debug_Msg(l_api_name || '   p_pk_value5               => ' || p_pk_value5);
16073 Debug_Msg(l_api_name || '   p_data_level              => ' || p_data_level);
16074 Debug_Msg(l_api_name || '   p_dl_pk_values            => <not printed>');
16075 Debug_Msg(l_api_name || '   p_dl_metadata_obj         => <not printed>');
16076 Debug_Msg(l_api_name || ' )' );
16077 
16078     --======================================================================--
16079     --                       1. Build the query                             --
16080     --======================================================================--
16081 
16082     x_str_val         := NULL;
16083     x_num_val         := NULL;
16084     x_date_val        := NULL;
16085 
16086     l_db_column_alias := EGO_USER_ATTRS_COMMON_PVT.Create_DB_Col_Alias_If_Needed(p_attr_metadata_obj);
16087 
16088     l_cursor          := DBMS_SQL.OPEN_CURSOR;
16089     l_bind_index      := 0;
16090 
16091     --------------------------
16092     -- SELECT, FROM clauses --
16093     --------------------------
16094 
16095     l_dynamic_sql := 'SELECT ' || l_db_column_alias ||
16096                      ' FROM ' || NVL(p_attr_group_metadata_obj.EXT_TABLE_VL_NAME
16097                                      ,p_attr_group_metadata_obj.EXT_TABLE_B_NAME) ||
16098                      ' WHERE ';
16099 
16100     ------------------------------------------
16101     -- WHERE conditions: Attribute Group ID --
16102     ------------------------------------------
16103 
16104     IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG ='Y') THEN
16105       l_bind_value_table(l_bind_index) := p_attr_group_metadata_obj.ATTR_GROUP_ID;
16106 Debug_Msg(l_api_name || ' Bind value :' || (l_bind_index + 1) || ' has value ' || l_bind_value_table(l_bind_index) || ' (ATTR_GROUP_ID)');
16107       l_bind_index := l_bind_index + 1;
16108       l_dynamic_sql := l_dynamic_sql ||  ' ATTR_GROUP_ID = :1 AND ';
16109     END IF;
16110 
16111     -----------------------------------
16112     -- WHERE conditions: Primary key --
16113     -----------------------------------
16114 
16115     l_bind_value_table(l_bind_index) := p_pk_value1;
16116 Debug_Msg(l_api_name || ' Bind value :' || (l_bind_index + 1) || ' has value ' || l_bind_value_table(l_bind_index) || ' (' || p_pk_col1 || ')');
16117     l_bind_index := l_bind_index + 1;
16118     l_dynamic_sql := l_dynamic_sql || p_pk_col1 || ' = :' || l_bind_index;
16119 
16120 
16121     IF (p_pk_col2 IS NOT NULL) THEN
16122       l_bind_value_table(l_bind_index) := p_pk_value2;
16123 Debug_Msg(l_api_name || ' Bind value :' || (l_bind_index + 1) || ' has value ' || l_bind_value_table(l_bind_index) || ' (' || p_pk_col2 || ')');
16124       l_bind_index := l_bind_index + 1;
16125       l_dynamic_sql := l_dynamic_sql || ' AND ' || p_pk_col2 || ' = :' || l_bind_index;
16126 
16127       IF (p_pk_col3 IS NOT NULL) THEN
16128         l_bind_value_table(l_bind_index) := p_pk_value3;
16129 Debug_Msg(l_api_name || ' Bind value :' || (l_bind_index + 1) || ' has value ' || l_bind_value_table(l_bind_index) || ' (' || p_pk_col3 || ')');
16130         l_bind_index := l_bind_index + 1;
16131         l_dynamic_sql := l_dynamic_sql || ' AND ' || p_pk_col3 || ' = :' || l_bind_index;
16132 
16133         IF (p_pk_col4 IS NOT NULL) THEN
16134           l_bind_value_table(l_bind_index) := p_pk_value4;
16135           l_bind_index := l_bind_index + 1;
16136           l_dynamic_sql := l_dynamic_sql || ' AND ' || p_pk_col4 || ' = :' || l_bind_index;
16137 
16138           IF (p_pk_col5 IS NOT NULL) THEN
16139             l_bind_value_table(l_bind_index) := p_pk_value5;
16140             l_bind_index := l_bind_index + 1;
16141             l_dynamic_sql := l_dynamic_sql || ' AND ' || p_pk_col5 || ' = :' || l_bind_index;
16142           END IF;
16143         END IF;
16144       END IF;
16145     END IF;
16146 
16147     --------------------------------------------------------------
16148     -- WHERE conditions: Data Level ID, Data Level Primary Keys --
16149     --------------------------------------------------------------
16150 
16151     l_has_data_level_id := FND_API.TO_BOOLEAN(
16152                  EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name => p_attr_group_metadata_obj.EXT_TABLE_B_NAME
16153                                                               ,p_column_name => 'DATA_LEVEL_ID')
16154                                              );
16155 
16156     IF p_data_level IS NOT NULL AND l_has_data_level_id THEN
16157       IF p_dl_metadata_obj IS NULL THEN
16158           l_dl_metadata_obj := NULL;
16159           IF (p_attr_group_metadata_obj.ENABLED_DATA_LEVELS IS NOT NULL AND p_attr_group_metadata_obj.ENABLED_DATA_LEVELS.COUNT <> 0) THEN
16160 
16161             FOR dl_index IN p_attr_group_metadata_obj.ENABLED_DATA_LEVELS.FIRST .. p_attr_group_metadata_obj.ENABLED_DATA_LEVELS.LAST
16162             LOOP
16163 
16164               IF p_attr_group_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_name = p_data_level THEN
16165                 l_dl_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Metadata(p_attr_group_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_id);
16166 Debug_Msg(l_api_name || ' Data level found, exiting loop.');
16167                 -- exit the loop as we found the DL
16168                 EXIT;
16169               END IF;
16170 
16171             END LOOP;
16172 
16173             IF l_dl_metadata_obj IS NULL THEN
16174               -- the data level is not correct, flash error message.
16175               l_token_table(1).TOKEN_NAME := 'DL_NAME';
16176               l_token_table(1).TOKEN_VALUE := p_data_level;
16177               l_token_table(2).TOKEN_NAME := 'AG_NAME';
16178               l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.attr_group_disp_name;
16179               ERROR_HANDLER.Add_Error_Message(
16180                   p_message_name      => 'EGO_EF_DL_AG_INVALID'
16181                  ,p_application_id    => 'EGO'
16182                  ,p_token_tbl         => l_token_table
16183                  ,p_message_type      => FND_API.G_RET_STS_ERROR
16184                  ,p_row_identifier    => G_USER_ROW_IDENTIFIER
16185                  ,p_entity_id         => NULL
16186                  ,p_entity_index      => NULL
16187                  ,p_entity_code       => NULL
16188                  ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
16189                 );
16190               l_token_table.DELETE();
16191               RAISE FND_API.G_EXC_ERROR;
16192             END IF;
16193 
16194           END IF;
16195       ELSE
16196         l_dl_metadata_obj := p_dl_metadata_obj;
16197       END IF;
16198 
16199       IF l_dl_metadata_obj IS NOT NULL THEN
16200         l_bind_value_table(l_bind_index) := l_dl_metadata_obj.data_level_id;
16201         l_bind_index := l_bind_index + 1;
16202         l_dynamic_sql := l_dynamic_sql || ' AND DATA_LEVEL_ID = :' || l_bind_index;
16203         IF p_dl_pk_values IS NOT NULL AND p_dl_pk_values.COUNT > 0 THEN
16204           l_dl_pk_index := p_dl_pk_values.FIRST;
16205 
16206           WHILE (l_dl_pk_index <= p_dl_pk_values.LAST)
16207           LOOP
16208             IF p_dl_pk_values(l_dl_pk_index).NAME IS NOT NULL AND
16209                p_dl_pk_values(l_dl_pk_index).NAME IN
16210                      (l_dl_metadata_obj.pk_column_name1
16211                      ,l_dl_metadata_obj.pk_column_name2
16212                      ,l_dl_metadata_obj.pk_column_name3
16213                      ,l_dl_metadata_obj.pk_column_name4
16214                      ,l_dl_metadata_obj.pk_column_name5 ) THEN
16215               l_bind_value_table(l_bind_index) := p_dl_pk_values(l_dl_pk_index).NAME;
16216               l_bind_index := l_bind_index + 1;
16217               l_dynamic_sql := l_dynamic_sql || ' AND ' || p_dl_pk_values(l_dl_pk_index).NAME || ' = :' || l_bind_index;
16218             END IF;
16219             l_dl_pk_index := p_dl_pk_values.NEXT(l_dl_pk_index);
16220           END LOOP;
16221 
16222         END IF;
16223       END IF;
16224     END IF; -- p_data_level IS NOT NULL
16225 Debug_Msg(l_api_name || ' Query is:' );
16226 Debug_Msg(l_api_name || '   ' || l_dynamic_sql );
16227 Debug_Msg(l_api_name || ' ' );
16228 
16229     --======================================================================--
16230     --         2. Parse the query and bind the input variables              --
16231     --======================================================================--
16232 
16233     DBMS_SQL.PARSE(l_cursor, l_dynamic_sql, DBMS_SQL.NATIVE);
16234 
16235 Debug_Msg('Get_Ext_Data(): Bind value table has ' || l_bind_value_table.COUNT || ' elements');
16236 
16237     -- Bind the attribute group ID value, and the primary key values for the object
16238     FOR i IN l_bind_value_table.FIRST .. l_bind_value_table.LAST
16239     LOOP
16240        l_bind_var_name  := ':' || (i + 1);
16241        l_bind_var_value := l_bind_value_table(i);
16242        l_bind_var_value_num    := to_number(l_bind_var_value);
16243 Debug_Msg(l_api_name || ' Binding '|| l_bind_var_name || ' to value ' || l_bind_var_value_num);
16244 
16245       DBMS_SQL.BIND_VARIABLE(
16246         c      => l_cursor,                                        -- SQL query
16247         name   => l_bind_var_name,                        -- bind variable name
16248         value  => l_bind_var_value                 -- bind value (VARCHAR2(80))
16249       );
16250     END LOOP;
16251 
16252     ------------------------
16253     -- Define the outputs --
16254     ------------------------
16255     IF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
16256       DBMS_SQL.DEFINE_COLUMN(l_cursor, 1, x_num_val);
16257     ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = 'X' OR p_attr_metadata_obj.DATA_TYPE_CODE = 'Y') THEN
16258       DBMS_SQL.DEFINE_COLUMN(l_cursor, 1, l_str,150);
16259     ELSE
16260       DBMS_SQL.DEFINE_COLUMN(l_cursor, 1, x_str_val, 150);
16261     END IF;
16262 
16263     --======================================================================--
16264     --    3. Execute the query and fetch the attribute internal value       --
16265     --======================================================================--
16266 
16267     l_row_count := DBMS_SQL.EXECUTE_AND_FETCH(l_cursor, FALSE);
16268     IF (l_row_count > 0) THEN
16269 
16270       IF (p_attr_metadata_obj.DATA_TYPE_CODE = 'N') THEN
16271         DBMS_SQL.COLUMN_VALUE(l_cursor, 1, x_num_val);
16272       ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = 'X' OR p_attr_metadata_obj.DATA_TYPE_CODE = 'Y') THEN
16273         DBMS_SQL.COLUMN_VALUE(l_cursor, 1, l_str);
16274         x_date_val := TO_DATE(l_str,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
16275       ELSE
16276         DBMS_SQL.COLUMN_VALUE(l_cursor, 1, x_str_val);
16277       END IF;
16278     END IF;
16279 
16280     DBMS_SQL.CLOSE_CURSOR(l_cursor);
16281 
16282 Debug_Msg(l_api_name || ' Done.' );
16283 
16284 END Get_Ext_Data;
16285 
16286 ----------------------------------------------------------------------
16287 
16288 /*
16289  * Get_User_Attr_Val
16290  * -----------------
16291  */
16292 FUNCTION Get_User_Attr_Val (
16293         p_appl_id           IN   NUMBER
16294        ,p_attr_grp_type     IN   VARCHAR2
16295        ,p_attr_grp_name     IN   VARCHAR2               -- Attribute Group Name
16296        ,p_attr_name         IN   VARCHAR2                     -- Attribute Name
16297        ,p_object_name       IN   VARCHAR2
16298        ,p_pk_col1           IN   VARCHAR2
16299        ,p_pk_col2           IN   VARCHAR2   DEFAULT NULL
16300        ,p_pk_col3           IN   VARCHAR2   DEFAULT NULL
16301        ,p_pk_col4           IN   VARCHAR2   DEFAULT NULL
16302        ,p_pk_col5           IN   VARCHAR2   DEFAULT NULL
16303        ,p_pk_value1         IN   VARCHAR2
16304        ,p_pk_value2         IN   VARCHAR2   DEFAULT NULL
16305        ,p_pk_value3         IN   VARCHAR2   DEFAULT NULL
16306        ,p_pk_value4         IN   VARCHAR2   DEFAULT NULL
16307        ,p_pk_value5         IN   VARCHAR2   DEFAULT NULL
16308        ,p_data_level        IN   VARCHAR2   DEFAULT NULL
16309        ,p_dl_pk_values      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
16310 )
16311 RETURN VARCHAR2
16312 IS
16313 
16314     l_api_name VARCHAR2(30) := 'Get_User_Attr_Val():';
16315     l_attr_group_metadata_obj      EGO_ATTR_GROUP_METADATA_OBJ;
16316                                                     -- declared in EGOSEFD2.sql
16317     l_attr_metadata_obj            EGO_ATTR_METADATA_OBJ;
16318     l_pk_column_name_value_pairs   EGO_COL_NAME_VALUE_PAIR_ARRAY;
16319     l_attr_int_value         VARCHAR2(4000);	-- Bug 8757354
16320     l_attr_disp_value        VARCHAR2(4000);	-- Bug 8757354
16321 
16322     l_attr_metadata_table    EGO_ATTR_METADATA_TABLE;
16323     l_attr_name_value_pairs  EGO_USER_ATTR_DATA_TABLE;
16324     l_attr_counter           NUMBER;
16325     l_temp_attr_metadata     EGO_ATTR_METADATA_OBJ;
16326     l_temp_str               VARCHAR2(150);
16327     l_temp_num               NUMBER;
16328     l_temp_date              DATE;
16329     --bug 5094087
16330     l_return_status          VARCHAR2(1);
16331     l_msg_count              NUMBER;
16332     l_msg_data               VARCHAR2(1000);
16333 
16334 l_token_table                 ERROR_HANDLER.Token_Tbl_Type;
16335 l_has_data_level_id           BOOLEAN  := TRUE;    -- TRUE is for R12C
16336 l_curr_data_level_metadata    EGO_DATA_LEVEL_METADATA_OBJ := NULL;
16337 l_curr_data_level_row_obj     EGO_DATA_LEVEL_ROW_OBJ;
16338 
16339   BEGIN
16340 
16341 Debug_Msg(l_api_name || '(');
16342 Debug_Msg(l_api_name || '    p_appl_id                 => ' || p_appl_id);
16343 Debug_Msg(l_api_name || '    p_attr_grp_type           => ' || p_attr_grp_type);
16344 Debug_Msg(l_api_name || '    p_attr_grp_name           => ' || p_attr_grp_name);
16345 Debug_Msg(l_api_name || '    p_attr_name               => ' || p_attr_name);
16346 Debug_Msg(l_api_name || '    p_object_name             => ' || p_object_name);
16347 Debug_Msg(l_api_name || '    p_pk_col1                 => ' || p_pk_col1);
16348 Debug_Msg(l_api_name || '    p_pk_col2                 => ' || p_pk_col2);
16349 Debug_Msg(l_api_name || '    p_pk_col3                 => ' || p_pk_col3);
16350 Debug_Msg(l_api_name || '    p_pk_col4                 => ' || p_pk_col4);
16351 Debug_Msg(l_api_name || '    p_pk_col5                 => ' || p_pk_col5);
16352 Debug_Msg(l_api_name || '    p_pk_value1               => ' || p_pk_value1);
16353 Debug_Msg(l_api_name || '    p_pk_value2               => ' || p_pk_value2);
16354 Debug_Msg(l_api_name || '    p_pk_value3               => ' || p_pk_value3);
16355 Debug_Msg(l_api_name || '    p_pk_value4               => ' || p_pk_value4);
16356 Debug_Msg(l_api_name || '    p_pk_value5               => ' || p_pk_value5);
16357 Debug_Msg(l_api_name || '    p_data_level              => ' || p_data_level);
16358 Debug_Msg(l_api_name || '    p_dl_pk_values            => <not printed>');
16359 Debug_Msg(l_api_name || ' )' );
16360 
16361     l_attr_int_value := NULL;
16362 
16363     -----------------------------------------
16364     -- Get or build the necessary metadata --
16365     -----------------------------------------
16366     l_attr_group_metadata_obj :=
16367       EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(
16368                                  p_application_id  => p_appl_id
16369                                 ,p_attr_group_type => p_attr_grp_type
16370                                 ,p_attr_group_name => p_attr_grp_name
16371                                );
16372 
16373     l_attr_metadata_table := l_attr_group_metadata_obj.attr_metadata_table;
16374     l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
16375                              p_attr_metadata_table => l_attr_group_metadata_obj.attr_metadata_table
16376                             ,p_attr_name           => p_attr_name
16377                            );
16378 
16379 Debug_Msg(l_api_name || ' Found attribute group metadata ');
16380 Debug_Msg(l_api_name || ' l_attr_metadata_obj (');
16381 Debug_Msg(l_api_name || '   ATTR_GROUP_ID              = ' || l_attr_group_metadata_obj.ATTR_GROUP_ID);
16382 Debug_Msg(l_api_name || '   APPLICATION_ID             = ' || l_attr_group_metadata_obj.APPLICATION_ID);
16383 Debug_Msg(l_api_name || '   ATTR_GROUP_TYPE            = ' || l_attr_group_metadata_obj.ATTR_GROUP_TYPE);
16384 Debug_Msg(l_api_name || '   ATTR_GROUP_NAME            = ' || l_attr_group_metadata_obj.ATTR_GROUP_NAME);
16385 Debug_Msg(l_api_name || '   ATTR_GROUP_DISP_NAME       = ' || l_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME);
16386 Debug_Msg(l_api_name || '   AGV_NAME                   = ' || l_attr_group_metadata_obj.AGV_NAME);
16387 Debug_Msg(l_api_name || '   MULTI_ROW_CODE             = ' || l_attr_group_metadata_obj.MULTI_ROW_CODE);
16388 Debug_Msg(l_api_name || '   VIEW_PRIVILEGE             = ' || l_attr_group_metadata_obj.VIEW_PRIVILEGE);
16389 Debug_Msg(l_api_name || '   EDIT_PRIVILEGE             = ' || l_attr_group_metadata_obj.EDIT_PRIVILEGE);
16390 Debug_Msg(l_api_name || '   EXT_TABLE_B_NAME           = ' || l_attr_group_metadata_obj.EXT_TABLE_B_NAME);
16391 Debug_Msg(l_api_name || '   EXT_TABLE_TL_NAME          = ' || l_attr_group_metadata_obj.EXT_TABLE_TL_NAME);
16392 Debug_Msg(l_api_name || '   EXT_TABLE_VL_NAME          = ' || l_attr_group_metadata_obj.EXT_TABLE_VL_NAME);
16393 Debug_Msg(l_api_name || '   SORT_ATTR_VALUES_FLAG      = ' || l_attr_group_metadata_obj.SORT_ATTR_VALUES_FLAG);
16394 Debug_Msg(l_api_name || '   UNIQUE_KEY_ATTRS_COUNT     = ' || l_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT);
16395 Debug_Msg(l_api_name || '   TRANS_ATTRS_COUNT          = ' || l_attr_group_metadata_obj.TRANS_ATTRS_COUNT);
16396 Debug_Msg(l_api_name || '   ATTR_METADATA_TABLE        = <not displayed>');
16397 Debug_Msg(l_api_name || '   ATTR_GROUP_ID_FLAG         = ' || l_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG);
16398 Debug_Msg(l_api_name || '   HIERARCHY_NODE_QUERY       = ' || l_attr_group_metadata_obj.HIERARCHY_NODE_QUERY);
16399 Debug_Msg(l_api_name || '   HIERARCHY_PROPAGATION_API  = ' || l_attr_group_metadata_obj.HIERARCHY_PROPAGATION_API);
16400 Debug_Msg(l_api_name || '   HIERARCHY_PROPAGATE_FLAG   = ' || l_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG);
16401 Debug_Msg(l_api_name || '   ENABLED_DATA_LEVELS        =  <not displayed>');
16402 Debug_Msg(l_api_name || '   VARIANT                    = ' || l_attr_group_metadata_obj.VARIANT);
16403 Debug_Msg(l_api_name || ' )');
16404 
16405 
16406     -- Get data level metadata, if applicable
16407     IF p_data_level IS NOT NULL THEN
16408       -- check if the passed in data level is valid for this attribute group.
16409         Debug_Msg(l_api_name || ' Non-null data level');
16410         l_has_data_level_id := FND_API.TO_BOOLEAN(
16411                  EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name => l_attr_group_metadata_obj.EXT_TABLE_B_NAME
16412                                                               ,p_column_name => 'DATA_LEVEL_ID')
16413                                                  );
16414         IF l_has_data_level_id THEN
16415           l_curr_data_level_row_obj := NULL;
16416           Debug_Msg(l_api_name || ' Has Data Level');
16417           IF (l_attr_group_metadata_obj.ENABLED_DATA_LEVELS IS NOT NULL AND
16418               l_attr_group_metadata_obj.ENABLED_DATA_LEVELS.COUNT <> 0) THEN
16419 
16420             Debug_Msg(l_api_name || ' ' || l_attr_group_metadata_obj.ENABLED_DATA_LEVELS.COUNT || ' data level(s) enabled');
16421 
16422             ------------------------------------------------------------------
16423             -- See if the supplied data level is in the list of enabled     --
16424             -- data levels for this attribute group.                        --
16425             ------------------------------------------------------------------
16426             FOR dl_index IN l_attr_group_metadata_obj.ENABLED_DATA_LEVELS.FIRST ..
16427                             l_attr_group_metadata_obj.ENABLED_DATA_LEVELS.LAST
16428             LOOP
16429               Debug_Msg(l_api_name || ' enabled data level: ' ||
16430                         l_attr_group_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_name || '(' ||
16431                         l_attr_group_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_id || ')');
16432               IF l_attr_group_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_name = p_data_level THEN
16433                 l_curr_data_level_metadata := EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Metadata(l_attr_group_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_id);
16434                 Debug_Msg(l_api_name || ' Found Data Level, finished searching.');
16435                 EXIT;
16436               END IF;
16437             END LOOP;
16438 
16439             ------------------------------------------------------------------
16440             -- If the specified data level was not in the list of enabled   --
16441             -- data levels flash error message.                             --
16442             ------------------------------------------------------------------
16443             IF l_curr_data_level_metadata IS NULL THEN
16444               Debug_Msg(l_api_name || ' Couldn''t find data level.');
16445               l_token_table(1).TOKEN_NAME  := 'DL_NAME';
16446               l_token_table(1).TOKEN_VALUE := p_data_level;
16447               l_token_table(2).TOKEN_NAME  := 'AG_NAME';
16448               l_token_table(2).TOKEN_VALUE := l_attr_group_metadata_obj.attr_group_name;
16449               ERROR_HANDLER.Add_Error_Message(
16450                   p_message_name      => 'EGO_EF_DL_AG_INVALID'
16451                  ,p_application_id    => 'EGO'
16452                  ,p_token_tbl         => l_token_table
16453                  ,p_message_type      => FND_API.G_RET_STS_ERROR
16454                  ,p_row_identifier    => G_USER_ROW_IDENTIFIER
16455                  ,p_entity_id         => NULL
16456                  ,p_entity_index      => NULL
16457                  ,p_entity_code       => NULL
16458                  ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
16459                 );
16460               l_token_table.DELETE();
16461               RAISE FND_API.G_EXC_ERROR;
16462             END IF;
16463 
16464           END IF;
16465         END IF;  -- has_data_level
16466 
16467     END IF;
16468 
16469     IF (p_pk_col2 IS NOT NULL AND
16470         p_pk_col3 IS NOT NULL AND
16471         p_pk_col4 IS NOT NULL AND
16472         p_pk_col5 IS NOT NULL) THEN
16473 
16474       l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
16475                                         EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col1, p_pk_value1)
16476                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col2, p_pk_value2)
16477                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col3, p_pk_value3)
16478                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col4, p_pk_value4)
16479                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col5, p_pk_value5)
16480                                       );
16481 
16482     ------------------------------------------------------------------
16483     -- We build a name/value pair array for our Primary Keys to use --
16484     -- in tokenizing our query; NOTE: We assume (and require) that  --
16485     -- at least one Primary Key name/value pair is passed           --
16486     ------------------------------------------------------------------
16487     ELSIF (p_pk_col2 IS NOT NULL AND
16488            p_pk_col3 IS NOT NULL AND
16489            p_pk_col4 IS NOT NULL) THEN
16490 
16491       l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
16492                                         EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col1, p_pk_value1)
16493                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col2, p_pk_value2)
16494                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col3, p_pk_value3)
16495                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col4, p_pk_value4)
16496                                       );
16497 
16498     ELSIF (p_pk_col2 IS NOT NULL AND
16499            p_pk_col3 IS NOT NULL) THEN
16500 
16501       l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
16502                                         EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col1, p_pk_value1)
16503                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col2, p_pk_value2)
16504                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col3, p_pk_value3)
16505                                       );
16506 
16507     ELSIF (p_pk_col2 IS NOT NULL) THEN
16508 
16509       l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
16510                                         EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col1, p_pk_value1)
16511                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col2, p_pk_value2)
16512                                       );
16513 
16514     ELSE
16515 
16516       l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
16517                                         EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col1, p_pk_value1)
16518                                       );
16519 
16520     END IF;
16521 
16522     Debug_Msg('In Find_Metadata_For_Attr, about to get attribute''s internal value', 5);
16523 
16524     --------------------------------------------------------------------
16525     -- Build a query to get the Attribute's internal (database) value --
16526     -- NOTE: We assume an association at the top data level           --
16527     --------------------------------------------------------------------
16528     Get_Ext_Data(
16529         p_attr_group_metadata_obj  =>  l_attr_group_metadata_obj
16530        ,p_attr_metadata_obj        =>  l_attr_metadata_obj
16531        ,p_pk_col1                  =>  p_pk_col1
16532        ,p_pk_col2                  =>  p_pk_col2
16533        ,p_pk_col3                  =>  p_pk_col3
16534        ,p_pk_col4                  =>  p_pk_col4
16535        ,p_pk_col5                  =>  p_pk_col5
16536        ,p_pk_value1                =>  p_pk_value1
16537        ,p_pk_value2                =>  p_pk_value2
16538        ,p_pk_value3                =>  p_pk_value3
16539        ,p_pk_value4                =>  p_pk_value4
16540        ,p_pk_value5                =>  p_pk_value5
16541        ,p_data_level               =>  p_data_level
16542        ,p_dl_pk_values             =>  p_dl_pk_values
16543        ,p_dl_metadata_obj          =>  l_curr_data_level_metadata
16544        ,x_str_val                  =>  l_temp_str
16545        ,x_num_val                  =>  l_temp_num
16546        ,x_date_val                 =>  l_temp_date
16547     );
16548 
16549     Debug_Msg('In Find_Metadata_For_Attr, attribute''s internal value = ' || l_temp_str || l_temp_num || l_temp_date, 5);
16550 
16551     IF (l_temp_str IS NOT NULL) THEN
16552       l_attr_int_value := l_temp_str;
16553 /*Added for Bug#8354072 - Begins here * :  TO_CHAR function truncate the 0 before '.', adding it for UI display*/
16554        ELSIF (l_temp_num IS NOT NULL AND 0 < l_temp_num AND l_temp_num< 1) THEN
16555          l_attr_int_value := '0' || TO_CHAR(l_temp_num);
16556        ELSIF (l_temp_num IS NOT NULL AND -1 < l_temp_num AND l_temp_num < 0) THEN
16557          l_attr_int_value := '-0' || substr(TO_CHAR(l_temp_num), 2);
16558 /*Added for Bug#8354072 - Ends here */
16559     ELSIF (l_temp_num IS NOT NULL) THEN
16560       l_attr_int_value := TO_CHAR(l_temp_num);
16561     ELSIF (l_temp_date IS NOT NULL) THEN
16562     --bug 5094087
16563       l_attr_int_value := TO_CHAR(l_temp_date,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
16564     END IF;
16565 
16566     ----------------------------------------------------------
16567     -- At this point I have the internal value; if the Attr --
16568     -- has a display value, I need to try to get it instead --
16569     ----------------------------------------------------------
16570     -- fix for bug 4543638 included translatable independent validation code to get disp value
16571     IF (l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE OR
16572         l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE OR
16573         l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE) THEN
16574 
16575       ------------------------------------------------------------
16576       -- We must query up the rest of the attribute data in the --
16577       -- same group in case there are binds                     --
16578       ------------------------------------------------------------
16579       l_attr_name_value_pairs := EGO_USER_ATTR_DATA_TABLE();
16580 
16581       l_attr_counter := l_attr_metadata_table.FIRST();
16582       WHILE (l_attr_counter IS NOT NULL)
16583       LOOP
16584 
16585         l_temp_attr_metadata := l_attr_metadata_table(l_attr_counter);
16586         Get_Ext_Data(
16587             p_attr_group_metadata_obj  =>  l_attr_group_metadata_obj
16588            ,p_attr_metadata_obj        =>  l_temp_attr_metadata
16589            ,p_pk_col1                  =>  p_pk_col1
16590            ,p_pk_col2                  =>  p_pk_col2
16591            ,p_pk_col3                  =>  p_pk_col3
16592            ,p_pk_col4                  =>  p_pk_col4
16593            ,p_pk_col5                  =>  p_pk_col5
16594            ,p_pk_value1                =>  p_pk_value1
16595            ,p_pk_value2                =>  p_pk_value2
16596            ,p_pk_value3                =>  p_pk_value3
16597            ,p_pk_value4                =>  p_pk_value4
16598            ,p_pk_value5                =>  p_pk_value5
16599            ,p_data_level               =>  p_data_level
16600            ,p_dl_pk_values             =>  p_dl_pk_values
16601            ,p_dl_metadata_obj          =>  l_curr_data_level_metadata
16602            ,x_str_val                  =>  l_temp_str
16603            ,x_num_val                  =>  l_temp_num
16604            ,x_date_val                 =>  l_temp_date
16605         );
16606 
16607         l_attr_name_value_pairs.EXTEND();
16608         l_attr_name_value_pairs(l_attr_name_value_pairs.LAST) :=
16609           EGO_USER_ATTR_DATA_OBJ (
16610             1
16611            ,l_temp_attr_metadata.ATTR_NAME
16612            ,l_temp_str                                        -- ATTR_VALUE_STR
16613            ,l_temp_num                                        -- ATTR_VALUE_NUM
16614            ,l_temp_date                                      -- ATTR_VALUE_DATE
16615            ,NULL                                             -- ATTR_DISP_VALUE
16616            ,NULL                                        -- ATTR_UNIT_OF_MEASURE
16617            ,1
16618           );
16619 
16620         l_attr_counter := l_attr_metadata_table.NEXT(l_attr_counter);
16621 
16622       END LOOP;
16623 
16624       l_attr_disp_value := Get_Disp_Val_For_Int_Val(
16625                              p_attr_int_value                => l_attr_int_value
16626                             ,p_attr_metadata_obj             => l_attr_metadata_obj
16627                             ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
16628                             ,p_pk_column_name_value_pairs    => l_pk_column_name_value_pairs
16629                             ,p_object_name                   => p_object_name
16630                             ,p_attr_name_value_pairs         => l_attr_name_value_pairs
16631                            );
16632 
16633     END IF;
16634 
16635     -----------------------------------------------------
16636     -- If the Attr has no display value or we couldn't --
16637     -- find it, we simply return the internal value    --
16638     -----------------------------------------------------
16639     IF (l_attr_disp_value IS NULL) THEN
16640      --bug 5094087
16641       --------------------------------------------------------------
16642         -- If the Attribute is of Date or DateTime then we        --
16643         -- change the format to user preferences, else we return  --
16644         -- the obtained String as it is.                          --
16645         ------------------------------------------------------------
16646       IF ( l_attr_metadata_obj.DATA_TYPE_CODE IN
16647              (EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE,
16648               EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) )
16649       THEN
16650         l_attr_disp_value := EGO_USER_ATTRS_COMMON_PVT.Get_User_Pref_Date_Time_Val(
16651                                        p_date => TO_DATE(l_attr_int_value,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT)
16652                                       ,p_attr_type => l_attr_metadata_obj.DATA_TYPE_CODE
16653                                       ,x_return_status =>l_return_status
16654                                       ,x_msg_count     =>l_msg_count
16655                                       ,x_msg_data      =>l_msg_data
16656                                       );
16657       ELSE
16658          l_attr_disp_value := l_attr_int_value;
16659       END IF;
16660     END IF;
16661      --bug 5094087
16662      ------------------------------------------------------------
16663      -- If the Display value is NOT NULL and Attribute is of Date
16664      -- or DateTime and is coming from a Independent Type
16665      -- of Valueset then we change the format to user preferences,
16666      -- else we return the obtained String as it is.
16667      ------------------------------------------------------------
16668        IF ((l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE )
16669            AND (l_attr_metadata_obj.DATA_TYPE_CODE IN
16670                  (EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE,
16671                   EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE)))
16672        THEN
16673         l_attr_disp_value := EGO_USER_ATTRS_COMMON_PVT.Get_User_Pref_Date_Time_Val(
16674                                      p_date => TO_DATE(l_attr_disp_value,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT)
16675                                     ,p_attr_type => l_attr_metadata_obj.DATA_TYPE_CODE
16676                                     ,x_return_status =>l_return_status
16677                                     ,x_msg_count     =>l_msg_count
16678                                     ,x_msg_data      =>l_msg_data
16679                                     );
16680       END IF;
16681     RETURN l_attr_disp_value;
16682   ---------------------------------------------------------------------------------
16683   -- In case of any error, we try to return l_attr_int_value (which may be NULL) --
16684   ---------------------------------------------------------------------------------
16685   EXCEPTION
16686     WHEN OTHERS THEN
16687       Debug_Msg(' Get_User_Attr_Val EXCEPTION OTHERS '||SQLERRM);
16688       RETURN l_attr_int_value;
16689 
16690 END Get_User_Attr_Val;
16691 
16692 ----------------------------------------------------------------------
16693 
16694 PROCEDURE Set_Up_Debug_Session (
16695         p_entity_id                     IN   NUMBER
16696        ,p_entity_code                   IN   VARCHAR2
16697        ,p_debug_level                   IN   NUMBER DEFAULT 0
16698 ) IS
16699 
16700   --local variables
16701    --bug 12868802 UTL_FILE_DIR length defined in ORA.init can be longer than 512 in 10g or later,
16702      --so it may cause ORA-06502, replace with v$parameter.value%TYPE; which work in all cases.
16703 
16704 
16705     l_output_dir             v$parameter.value%TYPE;
16706     l_return_status          VARCHAR2(1);
16707     l_error_mesg             VARCHAR2(512);
16708 
16709   BEGIN
16710 
16711     IF (ERROR_HANDLER.Get_Debug() = 'N') THEN
16712 
16713       IF (p_debug_level > 0) THEN
16714 
16715         SELECT VALUE
16716           INTO l_output_dir
16717           FROM V$PARAMETER
16718          WHERE NAME = 'utl_file_dir';
16719 
16720         ---------------------------------------
16721         -- This global holds the debug level --
16722         ---------------------------------------
16723         G_DEBUG_OUTPUT_LEVEL := p_debug_level;
16724 
16725         ------------------------------------------------------
16726         -- Trim to get only the first directory in the list --
16727         ------------------------------------------------------
16728         IF (INSTR(l_output_dir, ',') > 0) THEN
16729           l_output_dir := SUBSTR(l_output_dir, 1, INSTR(l_output_dir, ',') - 1);
16730         END IF;
16731 
16732         ERROR_HANDLER.Open_Debug_Session(
16733           p_debug_filename   => 'EGO_USER_ATTRS_DATA_PVT-'||TO_CHAR(SYSDATE, 'J.SSSSS')||'.log'
16734          ,p_output_dir       => l_output_dir
16735          ,x_return_status    => l_return_status
16736          ,x_error_mesg       => l_error_mesg
16737         );
16738 
16739         IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
16740 
16741           ERROR_HANDLER.Add_Error_Message(
16742             p_message_text      => l_error_mesg
16743            ,p_message_type      => 'E'
16744            ,p_entity_code       => p_entity_code
16745            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
16746           );
16747 
16748         END IF;
16749       END IF;
16750     END IF;
16751 
16752 END Set_Up_Debug_Session;
16753 
16754 ----------------------------------------------------------------------
16755 
16756 PROCEDURE Update_Attributes (
16757           p_pk_column_name_value_pairs    IN EGO_COL_NAME_VALUE_PAIR_ARRAY
16758         , p_class_code_name_value_pairs   IN EGO_COL_NAME_VALUE_PAIR_ARRAY
16759         , p_data_level                    IN VARCHAR2  DEFAULT NULL
16760         , p_data_level_name_value_pairs   IN EGO_COL_NAME_VALUE_PAIR_ARRAY
16761         , p_attr_diffs                    IN EGO_USER_ATTR_DIFF_TABLE
16762         , p_transaction_type              IN VARCHAR2
16763         , p_attr_group_id                 IN NUMBER DEFAULT NULL
16764         , x_error_message                 OUT NOCOPY VARCHAR2
16765         )
16766   IS
16767 
16768     l_object_id                 NUMBER;
16769     l_attr_group_metadata_obj   EGO_ATTR_GROUP_METADATA_OBJ;
16770     l_ext_table_metadata_obj    EGO_EXT_TABLE_METADATA_OBJ;
16771     l_extension_id              NUMBER;
16772     l_old_attr_name_value_pairs EGO_USER_ATTR_DATA_TABLE;
16773     l_new_attr_name_value_pairs EGO_USER_ATTR_DATA_TABLE;
16774     l_mode                      VARCHAR2(10);
16775     l_return_status             VARCHAR2(1);
16776     l_row_identifier            NUMBER;
16777     l_max_row_identifier        NUMBER;
16778     l_perform_dml               BOOLEAN := TRUE;
16779     l_is_delete                 BOOLEAN;
16780 
16781 
16782   BEGIN
16783 
16784     -- get object id
16785     Debug_Msg('In Update_Attributes, called with transaction type '||p_transaction_type);
16786 
16787     l_object_id := Get_Object_Id_From_Name('EGO_ITEM');
16788 
16789     Debug_Msg('In Update_Attributes, retrieved l_object_id as '||l_object_id, 2);
16790     Debug_Msg('In Update_Attributes, getting AG metadata for '||p_attr_group_id, 2);
16791 
16792     l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata
16793                                    ( p_attr_group_id => p_attr_group_id );
16794 
16795     Debug_Msg('In Update_Attributes, got AG metadata: '||
16796       l_attr_group_metadata_obj.attr_group_id||','||
16797       l_attr_group_metadata_obj.application_id||','||
16798       l_attr_group_metadata_obj.attr_group_type||','||
16799       l_attr_group_metadata_obj.attr_group_name||','||
16800       l_attr_group_metadata_obj.attr_group_disp_name
16801       , 2);
16802 
16803     l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
16804     Convert_Attr_Diff_To_Data(p_attr_diffs, l_old_attr_name_value_pairs, FALSE, l_is_delete, x_error_message);
16805     Convert_Attr_Diff_To_Data(p_attr_diffs, l_new_attr_name_value_pairs, TRUE, l_is_delete, x_error_message);
16806 
16807     Debug_Msg('In Update_Attributes, got AG and ext table objs, getting ext id ');
16808 
16809     if l_old_attr_name_value_pairs is not null then
16810       for i in l_old_attr_name_value_pairs.FIRST .. l_old_attr_name_value_pairs.LAST loop
16811         Debug_Msg('In Update_Attributes, old('||i||') '
16812           ||l_old_attr_name_value_pairs(i).ROW_IDENTIFIER||','
16813           ||l_old_attr_name_value_pairs(i).ATTR_NAME||','
16814           ||l_old_attr_name_value_pairs(i).ATTR_VALUE_STR||','
16815           ||l_old_attr_name_value_pairs(i).ATTR_VALUE_NUM);
16816       end loop;
16817     end if;
16818     if l_new_attr_name_value_pairs is not null then
16819       for i in l_new_attr_name_value_pairs.FIRST .. l_new_attr_name_value_pairs.LAST loop
16820         Debug_Msg('In Update_Attributes, new('||i||') '
16821           ||l_new_attr_name_value_pairs(i).ROW_IDENTIFIER||','
16822           ||l_new_attr_name_value_pairs(i).ATTR_NAME||','
16823           ||l_new_attr_name_value_pairs(i).ATTR_VALUE_STR||','
16824           ||l_new_attr_name_value_pairs(i).ATTR_VALUE_NUM);
16825       end loop;
16826     end if;
16827 
16828     -- try to find an extension id, which tells us whether to CREATE/UPDATE/DELETE
16829     l_extension_id := Get_Extension_Id_For_Row
16830                           ( p_attr_group_metadata_obj     => l_attr_group_metadata_obj
16831                           , p_ext_table_metadata_obj      => l_ext_table_metadata_obj
16832                           , p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
16833                           , p_data_level                  => p_data_level
16834                           , p_data_level_name_value_pairs => p_data_level_name_value_pairs
16835                           , p_attr_name_value_pairs       => l_old_attr_name_value_pairs
16836                           );
16837 
16838     IF (l_extension_id IS NULL) THEN
16839 
16840       -- fallback on new values (to handle case where update_attrs is called
16841       -- redundantly on the each, which has already been updated)
16842 
16843       l_extension_id := Get_Extension_Id_For_Row
16844                           ( p_attr_group_metadata_obj     => l_attr_group_metadata_obj
16845                           , p_ext_table_metadata_obj      => l_ext_table_metadata_obj
16846                           , p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
16847                           , p_data_level                  => p_data_level
16848                           , p_data_level_name_value_pairs => p_data_level_name_value_pairs
16849                           , p_attr_name_value_pairs       => l_new_attr_name_value_pairs
16850                           );
16851 
16852     END IF;
16853 
16854     Debug_Msg('In Update_Attributes, using ext id '||l_extension_id);
16855 
16856     IF p_transaction_type = 'SYNC' THEN
16857       -- are we updating or deleting this row?
16858       --  uses data contained in diff object to find out
16859       IF (l_is_delete) THEN
16860         l_mode := G_DELETE_MODE;
16861       ELSE
16862         IF (l_extension_id IS NOT NULL) THEN
16863           l_mode := G_UPDATE_MODE;
16864         ELSE
16865           l_mode := G_CREATE_MODE;
16866         END IF;
16867       END IF;
16868     ELSE -- transaction type is DELETE
16869       l_mode := p_transaction_type;
16870       IF (l_extension_id IS NULL) THEN
16871         l_perform_dml := FALSE;
16872       END IF;
16873     END IF;   -- p_transaction_type = 'SYNC'
16874 
16875     IF l_perform_dml THEN
16876 
16877       Debug_Msg('In Update_Attributes, calling perform_dml_on_row_pvt with mode '||l_mode, 2);
16878 
16879       Perform_DML_On_Row_Pvt(
16880         p_api_version                   => 1.0
16881        ,p_object_id                     => l_object_id
16882        ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
16883        ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
16884        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
16885        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
16886        ,p_data_level                    => p_data_level
16887        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
16888        ,p_extension_id                  => l_extension_id
16889        ,p_attr_name_value_pairs         => l_new_attr_name_value_pairs
16890        ,p_mode                          => l_mode
16891        ,p_commit                        => FND_API.G_FALSE
16892        ,p_bulkload_flag                 => TRUE
16893        ,x_extension_id                  => l_extension_id
16894        ,x_return_status                 => l_return_status
16895       );
16896       Debug_Msg('In Update_Attributes, Perform_DML_On_Row_Pvt returned with status '||l_return_status, 2);
16897     ELSE
16898       Debug_Msg('In Update_Attributes, skipped perform_dml');
16899     END IF;
16900 
16901     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
16902       Debug_Msg('In Update_Attributes, ERROR ret status: '||l_return_status, 2);
16903       RAISE FND_API.G_EXC_ERROR;
16904     END IF;
16905 
16906   EXCEPTION
16907     WHEN FND_API.G_EXC_ERROR THEN
16908       Debug_Msg('In Update_Attributes, EXCEPTION FND_API.G_EXC_ERROR');
16909       x_error_message := FND_API.G_RET_STS_ERROR;
16910 
16911 END Update_Attributes;
16912 
16913 ----------------------------------------------------------------------
16914 
16915 -- Either pass in attr_group_id or attr_group_name
16916 PROCEDURE Get_Attr_Diffs (
16917           p_object_name                   IN VARCHAR2
16918         , p_pk_column_name_value_pairs    IN EGO_COL_NAME_VALUE_PAIR_ARRAY
16919         , p_class_code_name_value_pairs   IN EGO_COL_NAME_VALUE_PAIR_ARRAY
16920         , p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
16921         , p_data_level_name_value_pairs   IN EGO_COL_NAME_VALUE_PAIR_ARRAY
16922         , p_attr_group_id                 IN NUMBER DEFAULT NULL
16923         , p_application_id                IN NUMBER DEFAULT NULL
16924         , p_attr_group_type               IN VARCHAR2 DEFAULT NULL
16925         , p_attr_group_name               IN VARCHAR2 DEFAULT NULL
16926         , px_attr_diffs                   IN OUT NOCOPY EGO_USER_ATTR_DIFF_TABLE
16927         , x_error_message                 OUT NOCOPY VARCHAR2
16928         )
16929   IS
16930     l_attr_name_value_pairs               EGO_USER_ATTR_DATA_TABLE;
16931     l_attr_name_value_rec                 EGO_USER_ATTR_DATA_OBJ;
16932     l_attr_metadata_obj                   EGO_ATTR_METADATA_OBJ;
16933     l_ext_table_metadata_obj              EGO_EXT_TABLE_METADATA_OBJ;
16934     l_attr_group_metadata_obj             EGO_ATTR_GROUP_METADATA_OBJ;
16935     l_object_id                           NUMBER;
16936     l_attr_diffs                          EGO_USER_ATTR_DIFF_TABLE;
16937 
16938   BEGIN
16939 
16940     Debug_Msg('In Get_Attr_Diffs, starting');
16941 
16942     -- get list of attributes in this group
16943     l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata
16944                                    ( p_attr_group_id
16945                                    , p_application_id
16946                                    , p_attr_group_type
16947                                    , p_attr_group_name
16948                                    );
16949 
16950     FOR i IN  l_attr_group_metadata_obj.attr_metadata_table.FIRST .. l_attr_group_metadata_obj.attr_metadata_table.LAST
16951     LOOP
16952 
16953       l_attr_metadata_obj := l_attr_group_metadata_obj.attr_metadata_table(i);
16954 
16955       IF (l_attr_name_value_pairs IS NULL) THEN
16956         l_attr_name_value_pairs := EGO_USER_ATTR_DATA_TABLE();
16957       END IF;
16958 
16959       -- add all attributes to the name_value pairs table, to pass into Get_Change_Attrs
16960       l_attr_name_value_pairs.EXTEND();
16961       l_attr_name_value_pairs(l_attr_name_value_pairs.LAST) :=
16962         EGO_USER_ATTR_DATA_OBJ(1
16963                               ,l_attr_metadata_obj.ATTR_NAME
16964                               ,null
16965                               ,null
16966                               ,null
16967                               ,null
16968                               ,null
16969                               ,1
16970                               );
16971 
16972     END LOOP;
16973 
16974     -- get other objects necessary for Get_Change_Attrs call
16975     l_object_id := Get_Object_Id_From_Name(p_object_name);
16976     l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
16977 
16978     -- call Get_Changed_Attrs to get diffs as output
16979     Get_Changed_Attributes(
16980            p_dml_operation                 => 'UPDATE'
16981          , p_object_name                   =>  p_object_name
16982          , p_pk_column_name_value_pairs    =>  p_pk_column_name_value_pairs
16983          , p_attr_group_metadata_obj       =>  l_attr_group_metadata_obj
16984          , p_ext_table_metadata_obj        =>  l_ext_table_metadata_obj
16985          , p_data_level                    =>  p_data_level
16986          , p_data_level_name_value_pairs   =>  p_data_level_name_value_pairs
16987          , p_attr_name_value_pairs         =>  l_attr_name_value_pairs
16988          , p_extension_id                  =>  null
16989          , p_entity_id                     =>  null
16990          , p_entity_index                  =>  null
16991          , p_entity_code                   =>  null
16992          , px_attr_diffs                   =>  l_attr_diffs);
16993 
16994     -- Bug 4029064: need to remove diff object if both new and old values are null
16995     FOR i IN l_attr_diffs.FIRST .. l_attr_diffs.LAST
16996     LOOP
16997 
16998       IF (l_attr_diffs(i).old_attr_value_str IS NOT NULL OR
16999           l_attr_diffs(i).new_attr_value_str IS NOT NULL OR
17000           l_attr_diffs(i).old_attr_value_num IS NOT NULL OR
17001           l_attr_diffs(i).new_attr_value_num IS NOT NULL OR
17002           l_attr_diffs(i).old_attr_value_date IS NOT NULL OR
17003           l_attr_diffs(i).new_attr_value_date IS NOT NULL OR
17004           l_attr_diffs(i).old_attr_uom IS NOT NULL OR
17005           l_attr_diffs(i).new_attr_uom IS NOT NULL) THEN
17006 
17007         IF px_attr_diffs IS NULL THEN
17008           px_attr_diffs := EGO_USER_ATTR_DIFF_TABLE();
17009         END IF;
17010 
17011         px_attr_diffs.EXTEND();
17012         px_attr_diffs(px_attr_diffs.LAST) := l_attr_diffs(i);
17013 
17014       END IF;
17015 
17016     END LOOP;
17017 
17018     Debug_Msg('In Get_Attr_Diffs, finished');
17019 
17020   EXCEPTION
17021     WHEN OTHERS THEN
17022       Debug_Msg('In Get_Attr_Diffs, EXCEPTION FND_API.G_EXC_ERROR');
17023       RAISE FND_API.G_EXC_ERROR;
17024 
17025 END Get_Attr_Diffs;
17026 
17027 ---------------------------------------------------------------------------------
17028 /*
17029  * Get_Attr_Disp_Val_From_ValueSet
17030  * -------------------------------
17031  * Function returns the display value
17032  * of the attribute for a given internal value.
17033  */
17034  --gnanda api created for bug  4038065
17035 FUNCTION Get_Attr_Disp_Val_From_VSet (
17036          p_application_id               IN   NUMBER
17037         ,p_attr_internal_date_value     IN   DATE     DEFAULT NULL
17038         ,p_attr_internal_str_value      IN   VARCHAR2 DEFAULT NULL
17039         ,p_attr_internal_num_value      IN   NUMBER   DEFAULT NULL
17040         ,p_attr_internal_name           IN   VARCHAR2
17041         ,p_attr_group_type              IN   VARCHAR2
17042         ,p_attr_group_int_name          IN   VARCHAR2
17043         ,p_attr_id                      IN   NUMBER
17044         ,p_object_name                  IN   VARCHAR2
17045         ,p_pk1_column_name              IN   VARCHAR2
17046         ,p_pk1_value                    IN   VARCHAR2
17047         ,p_pk2_column_name              IN   VARCHAR2 DEFAULT NULL
17048         ,p_pk2_value                    IN   VARCHAR2 DEFAULT NULL
17049         ,p_pk3_column_name              IN   VARCHAR2 DEFAULT NULL
17050         ,p_pk3_value                    IN   VARCHAR2 DEFAULT NULL
17051         ,p_pk4_column_name              IN   VARCHAR2 DEFAULT NULL
17052         ,p_pk4_value                    IN   VARCHAR2 DEFAULT NULL
17053         ,p_pk5_column_name              IN   VARCHAR2 DEFAULT NULL
17054         ,p_pk5_value                    IN   VARCHAR2 DEFAULT NULL
17055         ,p_data_level1_column_name      IN   VARCHAR2 DEFAULT NULL
17056         ,p_data_level1_value            IN   VARCHAR2 DEFAULT NULL
17057         ,p_data_level2_column_name      IN   VARCHAR2 DEFAULT NULL
17058         ,p_data_level2_value            IN   VARCHAR2 DEFAULT NULL
17059         ,p_data_level3_column_name      IN   VARCHAR2 DEFAULT NULL
17060         ,p_data_level3_value            IN   VARCHAR2 DEFAULT NULL
17061 )
17062 RETURN VARCHAR2
17063 IS
17064        l_attr_value_obj                EGO_USER_ATTR_DATA_OBJ;
17065        l_attr_metadata_obj             EGO_ATTR_METADATA_OBJ;
17066        l_attr_metadata_obj_table       EGO_ATTR_METADATA_TABLE;
17067        l_attr_group_metadata_obj       EGO_ATTR_GROUP_METADATA_OBJ;
17068        l_pk_column_name_value_pairs    EGO_COL_NAME_VALUE_PAIR_ARRAY;
17069        l_data_level_name_value_pairs   EGO_COL_NAME_VALUE_PAIR_ARRAY;
17070        l_attr_disp_value               VARCHAR2(5000);
17071   BEGIN
17072        l_attr_value_obj :=  EGO_USER_ATTR_DATA_OBJ (null
17073                                                    ,p_attr_internal_name
17074                                                    ,p_attr_internal_str_value
17075                                                    ,p_attr_internal_num_value
17076                                                    ,p_attr_internal_date_value
17077                                                    ,null
17078                                                    ,null
17079                                                    ,null
17080                                                    );
17081 
17082        l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(
17083                                                     p_attr_group_id   => NULL
17084                                                    ,p_application_id  => p_application_id
17085                                                    ,p_attr_group_type => p_attr_group_type
17086                                                    ,p_attr_group_name => p_attr_group_int_name
17087                                                    );
17088 
17089 --todo:  why is this  here?
17090        IF FND_API.TO_BOOLEAN(EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(l_attr_group_metadata_obj.EXT_TABLE_B_NAME, 'DATA_LEVEL_ID')) THEN
17091          -- data level exists
17092 NULL;
17093        END IF;
17094 
17095        l_attr_metadata_obj_table := l_attr_group_metadata_obj.ATTR_METADATA_TABLE;
17096        IF l_attr_metadata_obj_table.count > 0 THEN
17097         FOR i IN l_attr_metadata_obj_table.FIRST .. l_attr_metadata_obj_table.LAST LOOP
17098          IF l_attr_metadata_obj_table(i).attr_name = p_attr_internal_name THEN
17099            l_attr_metadata_obj := l_attr_metadata_obj_table(i);
17100          END IF;
17101         END LOOP;
17102        END IF;
17103 
17104        l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
17105                                                     EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk1_column_name,p_pk1_value)
17106                                                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk2_column_name,p_pk2_value)
17107                                                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk3_column_name,p_pk3_value)
17108                                                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk4_column_name,p_pk4_value)
17109                                                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk5_column_name,p_pk5_value)
17110                                                    );
17111        l_data_level_name_value_pairs :=  EGO_COL_NAME_VALUE_PAIR_ARRAY(
17112                                                     EGO_COL_NAME_VALUE_PAIR_OBJ(p_data_level1_column_name,p_data_level1_value)
17113                                                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_data_level2_column_name,p_data_level2_value)
17114                                                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_data_level3_column_name,p_data_level3_value)
17115                                                    );
17116        l_attr_disp_value := Get_Disp_Val_For_Int_Val(
17117                                                    p_attr_value_obj                => l_attr_value_obj
17118                                                   ,p_attr_metadata_obj             => l_attr_metadata_obj
17119                                                   ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
17120                                                   ,p_pk_column_name_value_pairs    => l_pk_column_name_value_pairs
17121                                                   ,p_data_level_name_value_pairs   => l_data_level_name_value_pairs
17122                                                   ,p_object_name                   => p_object_name
17123                                                   );
17124 
17125        RETURN l_attr_disp_value;
17126 
17127   EXCEPTION
17128     WHEN OTHERS THEN
17129       Debug_Msg('In Get_Attr_Disp_Val_From_ValueSet, got exception '||SQLERRM, 3);
17130       RETURN NULL;
17131 
17132 END Get_Attr_Disp_Val_From_VSet;
17133 
17134 
17135 
17136 
17137 /*
17138  * Get_Attr_Int_Val_From_VSet
17139  * -------------------------------
17140  * Function returns the internal value for a given display
17141  * value of the value set. In case the attribute does not have
17142  * a value set attached the display value privded to the api is
17143  * returned back.
17144  */
17145 
17146 ---------------------------------------------------------------------------
17147 FUNCTION Get_Attr_Int_Val_From_VSet (
17148          p_application_id               IN   NUMBER
17149         ,p_attr_disp_value              IN   VARCHAR2
17150         ,p_attr_internal_name           IN   VARCHAR2
17151         ,p_attr_group_type              IN   VARCHAR2
17152         ,p_attr_group_int_name          IN   VARCHAR2
17153         ,p_attr_group_id                IN   NUMBER
17154         ,p_attr_id                      IN   NUMBER
17155         ,p_return_intf_col              IN   VARCHAR2
17156         ,p_object_name                  IN   VARCHAR2
17157         ,p_ext_table_metadata_obj       IN   EGO_EXT_TABLE_METADATA_OBJ
17158         ,p_pk1_column_name              IN   VARCHAR2
17159         ,p_pk1_value                    IN   VARCHAR2
17160         ,p_pk2_column_name              IN   VARCHAR2
17161         ,p_pk2_value                    IN   VARCHAR2
17162         ,p_pk3_column_name              IN   VARCHAR2
17163         ,p_pk3_value                    IN   VARCHAR2
17164         ,p_pk4_column_name              IN   VARCHAR2
17165         ,p_pk4_value                    IN   VARCHAR2
17166         ,p_pk5_column_name              IN   VARCHAR2
17167         ,p_pk5_value                    IN   VARCHAR2
17168         ,p_data_level1_column_name      IN   VARCHAR2
17169         ,p_data_level1_value            IN   VARCHAR2
17170         ,p_data_level2_column_name      IN   VARCHAR2
17171         ,p_data_level2_value            IN   VARCHAR2
17172         ,p_data_level3_column_name      IN   VARCHAR2
17173         ,p_data_level3_value            IN   VARCHAR2
17174         ,p_entity_id                    IN   VARCHAR2
17175         ,p_entity_index                 IN   NUMBER
17176         ,p_entity_code                  IN   VARCHAR2
17177 )
17178 RETURN VARCHAR2
17179 IS
17180        l_attr_value_obj                EGO_USER_ATTR_DATA_OBJ;
17181        l_attr_metadata_obj             EGO_ATTR_METADATA_OBJ;
17182        l_attr_metadata_obj_table       EGO_ATTR_METADATA_TABLE;
17183        l_attr_group_metadata_obj       EGO_ATTR_GROUP_METADATA_OBJ;
17184        l_pk_column_name_value_pairs    EGO_COL_NAME_VALUE_PAIR_ARRAY;
17185        l_data_level_name_value_pairs   EGO_COL_NAME_VALUE_PAIR_ARRAY;
17186        l_attr_internal_value           VARCHAR2(4000);
17187        l_ext_table_metadata_obj        EGO_EXT_TABLE_METADATA_OBJ;
17188   BEGIN
17189        l_attr_value_obj :=  EGO_USER_ATTR_DATA_OBJ (null
17190                                                    ,p_attr_internal_name
17191                                                    ,null
17192                                                    ,null
17193                                                    ,null
17194                                                    ,p_attr_disp_value
17195                                                    ,null
17196                                                    ,null
17197                                                    );
17198        l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(
17199                                                     p_attr_group_id   => NULL
17200                                                    ,p_application_id  => p_application_id
17201                                                    ,p_attr_group_type => p_attr_group_type
17202                                                    ,p_attr_group_name => p_attr_group_int_name
17203                                                    );
17204 
17205        IF l_attr_group_metadata_obj IS NULL THEN
17206          RETURN NULL;
17207        END IF;
17208 
17209        l_attr_metadata_obj_table := l_attr_group_metadata_obj.ATTR_METADATA_TABLE;
17210        IF l_attr_metadata_obj_table.count > 0 THEN
17211         FOR i IN l_attr_metadata_obj_table.FIRST .. l_attr_metadata_obj_table.LAST LOOP
17212          IF l_attr_metadata_obj_table(i).attr_name = p_attr_internal_name THEN
17213            l_attr_metadata_obj := l_attr_metadata_obj_table(i);
17214          END IF;
17215         END LOOP;
17216        END IF;
17217 
17218       -- If the value
17219        BEGIN
17220           IF l_attr_metadata_obj IS NULL THEN
17221             RETURN NULL;
17222           ELSE
17223             IF l_attr_metadata_obj.VALUE_SET_ID IS NULL THEN
17224                -- if the data is coming from intf table we have a possibility that its not
17225                -- valid in terms of datatype. We return a null in such a case.
17226                IF p_return_intf_col IS NOT NULL THEN
17227                   IF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE)
17228                      AND (p_return_intf_col = 'ATTR_VALUE_NUM') THEN
17229                     RETURN TO_CHAR(TO_NUMBER(p_attr_disp_value));
17230                   ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE
17231                          OR l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE)
17232                         AND (p_return_intf_col = 'ATTR_VALUE_DATE') THEN
17233                     RETURN TO_CHAR(TO_DATE(p_attr_disp_value,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT),EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
17234                   ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE
17235                          OR l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE)
17236                      AND (p_return_intf_col = 'ATTR_VALUE_STR') THEN
17237                     RETURN p_attr_disp_value;
17238                   ELSE
17239                     RETURN NULL;
17240                   END IF;
17241                ELSE
17242                  RETURN p_attr_disp_value;
17243                END IF;
17244             END IF;
17245           END IF;
17246        EXCEPTION
17247          WHEN OTHERS THEN
17248           RETURN NULL;
17249        END;
17250 
17251 
17252        -- This api can be used as a part of the VO query to fetch the internal values for
17253        -- an attribute in the interface table. In this case we will return a value only for
17254        -- the appropriate column.
17255        IF p_return_intf_col IS NOT NULL THEN
17256 
17257          IF p_return_intf_col = 'ATTR_VALUE_STR' THEN
17258             IF (l_attr_metadata_obj.DATA_TYPE_CODE <> EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE
17259                 AND l_attr_metadata_obj.DATA_TYPE_CODE <> EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE)  THEN
17260                  RETURN NULL;
17261             END IF;
17262 
17263          ELSIF p_return_intf_col = 'ATTR_VALUE_NUM' THEN
17264             IF l_attr_metadata_obj.DATA_TYPE_CODE <> EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE THEN
17265                  RETURN NULL;
17266             END IF;
17267 
17268          ELSIF p_return_intf_col = 'ATTR_VALUE_DATE' THEN
17269             IF (l_attr_metadata_obj.DATA_TYPE_CODE <> EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE
17270                 AND l_attr_metadata_obj.DATA_TYPE_CODE <> EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE)  THEN
17271                  RETURN NULL;
17272             END IF;
17273 
17274          END IF;
17275 
17276        END IF;
17277 
17278        l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
17279                     EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk1_column_name,p_pk1_value)
17280                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk2_column_name,p_pk2_value)
17281                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk3_column_name,p_pk3_value)
17282                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk4_column_name,p_pk4_value)
17283                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk5_column_name,p_pk5_value)
17284                    );
17285 
17286        l_data_level_name_value_pairs :=  EGO_COL_NAME_VALUE_PAIR_ARRAY(
17287                     EGO_COL_NAME_VALUE_PAIR_OBJ(p_data_level1_column_name,p_data_level1_value)
17288                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_data_level2_column_name,p_data_level2_value)
17289                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_data_level3_column_name,p_data_level3_value)
17290                    );
17291 
17292 
17293       IF (p_ext_table_metadata_obj IS NOT NULL) THEN
17294         l_ext_table_metadata_obj := p_ext_table_metadata_obj;
17295       ELSE
17296         l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(Get_Object_Id_From_Name(p_object_name));
17297       END IF;
17298 
17299 
17300       l_attr_internal_value := Get_Int_Val_For_Disp_Val(
17301                     p_attr_metadata_obj           =>l_attr_metadata_obj
17302                    ,p_attr_value_obj              =>l_attr_value_obj
17303                    ,p_attr_group_metadata_obj     =>l_attr_group_metadata_obj
17304                    ,p_ext_table_metadata_obj      =>l_ext_table_metadata_obj
17305                    ,p_pk_column_name_value_pairs  =>l_pk_column_name_value_pairs
17306                    ,p_data_level_name_value_pairs =>l_data_level_name_value_pairs
17307                    ,p_entity_id                   =>p_entity_id
17308                    ,p_entity_index                =>p_entity_index
17309                    ,p_entity_code                 =>p_entity_code
17310                    ,p_attr_name_value_pairs       =>null
17311                    );
17312 
17313 
17314       BEGIN
17315         IF p_return_intf_col IS NOT NULL THEN
17316            IF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE)
17317                AND (p_return_intf_col = 'ATTR_VALUE_NUM') THEN
17318                   l_attr_internal_value := TO_CHAR(TO_NUMBER(l_attr_internal_value));
17319            ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE
17320                   OR l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE)
17321                   AND (p_return_intf_col = 'ATTR_VALUE_DATE') THEN
17322                      l_attr_internal_value := TO_CHAR(TO_DATE(l_attr_internal_value,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT),EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
17323            ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE
17324                   OR l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE)
17325                   AND (p_return_intf_col = 'ATTR_VALUE_STR') THEN
17326                     l_attr_internal_value := l_attr_internal_value;
17327            END IF;
17328         END IF;
17329       EXCEPTION
17330          WHEN OTHERS THEN
17331           l_attr_internal_value := NULL;
17332       END;
17333 
17334 
17335       RETURN l_attr_internal_value;
17336 
17337 END Get_Attr_Int_Val_From_VSet;
17338 
17339 ---------------------------------------------------------------------------
17340 
17341 PROCEDURE Process_Data_Level_Nvp(
17342         p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
17343        ,x_data_level_obj                OUT NOCOPY  EGO_COL_NAME_VALUE_PAIR_OBJ
17344        ,x_data_level_index              OUT NOCOPY  NUMBER
17345 ) IS
17346     l_api_name VARCHAR2(30) := 'Process_data_level_nvp';
17347   BEGIN
17348 
17349 Debug_Msg(l_api_name||' starting', 2);
17350 
17351     IF p_data_level_name_value_pairs IS NULL THEN
17352 Debug_Msg(l_api_name||' p_data_level_name_value_pairs IS NULL. Returning.', 2);
17353       RETURN;
17354     END IF;
17355 
17356 
17357     IF p_data_level_name_value_pairs.COUNT > 0 THEN
17358       FOR i IN p_data_level_name_value_pairs.FIRST .. p_data_level_name_value_pairs.LAST
17359       LOOP
17360 
17361 Debug_Msg(l_api_name||' pair ' || i, 2);
17362 
17363         IF (i = p_data_level_name_value_pairs.FIRST AND
17364             p_data_level_name_value_pairs(i).NAME IS NOT NULL)
17365            OR
17366            (p_data_level_name_value_pairs(i).VALUE IS NOT NULL AND
17367             p_data_level_name_value_pairs(i).NAME IS NOT NULL)
17368         THEN
17369 
17370            x_data_level_obj   := p_data_level_name_value_pairs(i);
17371            x_data_level_index := i;
17372 
17373         END IF;
17374       END LOOP;
17375     ELSE
17376 Debug_Msg(l_api_name||' p_data_level_name_value_pairs.COUNT = ' || p_data_level_name_value_pairs.COUNT, 2);
17377     END IF;                       -- IF p_data_level_name_value_pairs.COUNT > 0
17378 
17379 
17380     IF x_data_level_obj IS NULL THEN
17381 Debug_Msg(l_api_name||' x_data_level_obj IS NULL', 2);
17382     ELSE
17383 Debug_Msg(l_api_name||' chosen data level pair = (' || x_data_level_obj.NAME || ', ' || x_data_level_obj.VALUE || ')', 2);
17384     END IF;
17385 Debug_Msg(l_api_name||' done', 2);
17386 
17387 END Process_Data_Level_Nvp;
17388 
17389 ---------------------------------------------------------------------------
17390 
17391 PROCEDURE Process_Class_Code_Nvp(
17392         p_class_code_name_value_pairs   IN         EGO_COL_NAME_VALUE_PAIR_ARRAY
17393        ,x_base_class_obj                OUT NOCOPY EGO_COL_NAME_VALUE_PAIR_OBJ
17394        ,x_related_class_obj             OUT NOCOPY EGO_COL_NAME_VALUE_PAIR_OBJ
17395 ) IS
17396     l_api_name  VARCHAR2(30) := 'Process_Class_Code_Nvp';
17397   BEGIN
17398 
17399     Debug_Msg(l_api_name||' starting', 2);
17400 
17401     IF p_class_code_name_value_pairs IS NULL THEN
17402       RETURN;
17403     END IF;
17404 
17405     FOR i IN p_class_code_name_value_pairs.FIRST .. p_class_code_name_value_pairs.LAST
17406     LOOP
17407 
17408       IF i = p_class_code_name_value_pairs.FIRST AND
17409          p_class_code_name_value_pairs(i).VALUE IS NOT NULL AND
17410          p_class_code_name_value_pairs(i).NAME IS NOT NULL
17411       THEN
17412 
17413          x_base_class_obj := p_class_code_name_value_pairs(i);
17414 
17415       ELSIF i = p_class_code_name_value_pairs.FIRST + 1 AND
17416             p_class_code_name_value_pairs(i).VALUE IS NOT NULL AND
17417             p_class_code_name_value_pairs(i).NAME IS NOT NULL
17418 
17419       THEN
17420 
17421          x_related_class_obj := p_class_code_name_value_pairs(i);
17422          exit;
17423 
17424       END IF;
17425     END LOOP;
17426 
17427     Debug_Msg(l_api_name||' base class code pair = (' ||
17428               x_base_class_obj.NAME || ', ' || x_base_class_obj.VALUE || ')', 3);
17429 
17430     Debug_Msg(l_api_name||' related class code pair = (' ||
17431               x_related_class_obj.NAME || ', ' || x_related_class_obj.VALUE || ')', 3);
17432 
17433     Debug_Msg(l_api_name||' done', 2);
17434 
17435 END Process_Class_Code_Nvp;
17436 
17437 ---------------------------------------------------------------------------
17438 
17439 PROCEDURE Build_Class_Code_Table(
17440         p_class_code_name_value_pairs   IN         EGO_COL_NAME_VALUE_PAIR_ARRAY
17441        ,x_class_code_table              OUT NOCOPY LOCAL_MEDIUM_VARCHAR_TABLE
17442 ) IS
17443     l_base_class_obj    EGO_COL_NAME_VALUE_PAIR_OBJ;
17444     l_related_class_obj EGO_COL_NAME_VALUE_PAIR_OBJ;
17445     l_remaining         VARCHAR2(300);
17446     l_current_val       VARCHAR2(300); --EGO_COL_NAME_VALUE_PAIR_OBJ.VALUE%TYPE;
17447     l_index             NUMBER;
17448   BEGIN
17449 
17450     Debug_Msg('In Build_Class_Code_Table, starting', 2);
17451 
17452     Process_Class_Code_Nvp(
17453         p_class_code_name_value_pairs  => p_class_code_name_value_pairs
17454        ,x_base_class_obj               => l_base_class_obj
17455        ,x_related_class_obj            => l_related_class_obj
17456     );
17457 
17458     IF l_base_class_obj IS NULL THEN
17459       RETURN;
17460     END IF;
17461 
17462     x_class_code_table(1) := l_base_class_obj.VALUE;
17463 
17464     IF l_related_class_obj IS NULL OR
17465        l_related_class_obj.VALUE IS NULL OR
17466        LENGTH(l_related_class_obj.VALUE) = 0
17467     THEN
17468       RETURN;
17469     END IF;
17470 
17471     l_remaining := l_related_class_obj.VALUE;
17472     l_index     := INSTR(l_remaining, ',');
17473 
17474     WHILE (l_index >  0) LOOP
17475        l_current_val := SUBSTR(l_remaining, 1, l_index - 1);
17476        l_remaining   := SUBSTR(l_remaining, l_index + 1, LENGTH(l_remaining));
17477 
17478        x_class_code_table(x_class_code_table.COUNT+1) := LTRIM(RTRIM(l_current_val));
17479 
17480        l_index := INSTR(l_remaining, ',');
17481     END LOOP;
17482 
17483     -- take care of the last value
17484     x_class_code_table(x_class_code_table.COUNT+1) := LTRIM(RTRIM(l_remaining));
17485 
17486     Debug_Msg('In Build_Class_Code_Table, done', 2);
17487 
17488 END Build_Class_Code_Table;
17489 
17490 /*----------------------------------------------------------------------------
17491 
17492   DESCRIPTION
17493     Extracts the values from the (column name, value) pairs in the
17494     data level pairs array and sets them as out parameters
17495 
17496   AUTHOR
17497     ssarnoba
17498 
17499   RELEASE
17500     R12C
17501 
17502   NOTES
17503     (-) If duplicate column names are specified, the last one's value is
17504         set to the out parameter
17505 
17506 ----------------------------------------------------------------------------*/
17507 PROCEDURE Extract_Data_Level_Values(
17508    p_data_level_name               IN   EGO_DATA_LEVEL_VL.DATA_LEVEL_NAME%TYPE
17509   ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
17510   ,x_data_level_1                  OUT  NOCOPY VARCHAR2
17511   ,x_data_level_2                  OUT  NOCOPY VARCHAR2
17512   ,x_data_level_3                  OUT  NOCOPY VARCHAR2
17513 )
17514 IS
17515    l_api_name              CONSTANT VARCHAR2(30) := 'Extract_Data_Level_Values';
17516    p_dl1_column                     VARCHAR2(20);
17517    p_dl2_column                     VARCHAR2(20);
17518    p_dl3_column                     VARCHAR2(20);
17519    iter_col_name                    VARCHAR2(150);
17520    iter_value                       VARCHAR2(150);
17521 
17522    CURSOR get_data_levek_col_names (cp_data_level_name EGO_DATA_LEVEL_B.DATA_LEVEL_NAME%TYPE)
17523    IS
17524    SELECT pk1_column_name, pk2_column_name, pk3_column_name
17525    FROM   ego_data_level_vl
17526    WHERE  data_level_name = cp_data_level_name;
17527 
17528 BEGIN
17529 
17530   Debug_Msg(l_api_name || '  Begin', 2);
17531   Debug_Msg(l_api_name || '  p_data_level_name - ' || p_data_level_name, 2);
17532 
17533   ----------------------------------------------------------------------------
17534   -- Determine which array element value will populate which OUT            --
17535   -- parameter                                                              --
17536   ----------------------------------------------------------------------------
17537 
17538   -- e.g.
17539   --
17540   --   (-) x_data_level_1 gets populated with the value from
17541   --       (PK2_VALUE, value)
17542   --   (-) x_data_level_2 gets populated with the value from
17543   --       (PK1_VALUE, value)00
17544 
17545   -- We can't use SELECT INTO because the WHERE clause contains a parameter,
17546   -- not a literal. The SQL engine cannot determine that only one row
17547   -- will be returned. So instead we have to use a cursor.
17548 
17549   OPEN get_data_levek_col_names (p_data_level_name);
17550   FETCH get_data_levek_col_names INTO p_dl1_column, p_dl2_column, p_dl3_column;
17551 
17552   Debug_Msg(l_api_name || '  PK Columns determined', 2);
17553   Debug_Msg(l_api_name || '    p_dl1_column: ' || p_dl1_column, 2);
17554   Debug_Msg(l_api_name || '    p_dl2_column: ' || p_dl2_column, 2);
17555   Debug_Msg(l_api_name || '    p_dl3_column: ' || p_dl3_column, 2);
17556 
17557   Debug_Msg(l_api_name || '  Number of data level pairs: ' || p_data_level_name_value_pairs.COUNT, 2);
17558 
17559   ----------------------------------------------------------------------------
17560   -- Iterate over the list and extract each value in the pair, placing it   --
17561   -- in one of the OUT parameters                                           --
17562   ----------------------------------------------------------------------------
17563 
17564   IF (p_data_level_name_value_pairs.COUNT > 0) THEN
17565 
17566     FOR i IN p_data_level_name_value_pairs.FIRST ..
17567              p_data_level_name_value_pairs.LAST
17568     LOOP
17569       Debug_Msg(l_api_name || '  data level pair ' || i, 2);
17570 
17571       -- Get the column name and value
17572       iter_col_name := p_data_level_name_value_pairs(i).NAME;
17573       iter_value    := p_data_level_name_value_pairs(i).VALUE;
17574 
17575       -- Put the value in the correct OUT parameter
17576       IF    (iter_col_name = p_dl1_column) THEN
17577         x_data_level_1 := iter_value;
17578       ELSIF (iter_col_name = p_dl2_column) THEN
17579         x_data_level_2 := iter_value;
17580       ELSIF (iter_col_name = p_dl3_column) THEN
17581         x_data_level_3 := iter_value;
17582       END IF;
17583 
17584     END LOOP;
17585 
17586   END IF;
17587 
17588   Debug_Msg(l_api_name || '  End', 2);
17589 
17590 END Extract_Data_Level_Values;
17591 
17592 
17593 ----------------------------------------------------------------------------
17594 
17595 
17596 PROCEDURE Process_Data_Level_Values(
17597         p_data_level_obj  IN         EGO_COL_NAME_VALUE_PAIR_OBJ
17598        ,p_data_level_ind  IN         NUMBER
17599        ,x_data_level_1    OUT NOCOPY VARCHAR2
17600        ,x_data_level_2    OUT NOCOPY VARCHAR2
17601        ,x_data_level_3    OUT NOCOPY VARCHAR2
17602 ) IS
17603 
17604   BEGIN
17605 
17606     Debug_Msg('In Process_Data_Level_Values, starting', 2);
17607 
17608     -- reset values
17609     x_data_level_1 := null;
17610     x_data_level_2 := null;
17611     x_data_level_3 := null;
17612 
17613     IF p_data_level_obj.VALUE IS NULL THEN
17614        RETURN;
17615     END IF;
17616 
17617     -- data level is 1 below the index, since index = 1
17618     -- corresponds to the top data level (data level 0)
17619     IF p_data_level_ind = 2 THEN
17620       x_data_level_1 := p_data_level_obj.VALUE;
17621     ELSIF p_data_level_ind = 3 THEN
17622       x_data_level_2 := p_data_level_obj.VALUE;
17623     ELSIF p_data_level_ind = 4 THEN
17624       x_data_level_3 := p_data_level_obj.VALUE;
17625     END IF;
17626 
17627     Debug_Msg('In Process_Data_Level_Values, done', 2);
17628 
17629 END Process_Data_Level_Values;
17630 
17631 
17632 /*----------------------------------------------------------------------------
17633   DESCRIPTION
17634     Builds a request table to validate attribute groups of an object
17635 
17636   NOTES
17637     (-) Only the attribute groups at the specified data level are added
17638         to the request object.
17639     (-) The object type EGO_ATTR_GROUP_REQUEST_OBJ is declared in
17640         EGOSEFD2.sql
17641 
17642 ----------------------------------------------------------------------------*/
17643 PROCEDURE Build_Request_Table_For_Obj(
17644         p_object_name                   IN   VARCHAR2
17645        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
17646        ,p_data_level_name               IN   EGO_DATA_LEVEL_VL.DATA_LEVEL_NAME%TYPE
17647        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
17648                                                    -- the data level key values
17649        ,p_attr_group_type_table         IN   EGO_VARCHAR_TBL_TYPE
17650        ,x_attr_group_request_table      OUT NOCOPY EGO_ATTR_GROUP_REQUEST_TABLE
17651 ) IS
17652 
17653     l_api_name              VARCHAR2(30) := 'Build_Request_Table_For_Obj';
17654     l_attributes_row_table  EGO_USER_ATTR_ROW_TABLE;
17655     l_attributes_data_table EGO_USER_ATTR_DATA_TABLE;
17656     l_data_level_obj        EGO_COL_NAME_VALUE_PAIR_OBJ;
17657     l_data_level_index      NUMBER;
17658     l_class_code_table      LOCAL_MEDIUM_VARCHAR_TABLE;
17659     l_attr_group_id         ego_obj_ag_assocs_b.attr_group_id%TYPE;
17660     l_data_level_1          VARCHAR2(150);
17661     l_data_level_2          VARCHAR2(150);
17662     l_data_level_3          VARCHAR2(150);
17663 
17664     CURSOR relevant_ag_w_data_level(
17665               p_data_level ego_obj_ag_assocs_b.data_level%TYPE
17666              ,p_class_code ego_obj_ag_assocs_b.classification_code%TYPE
17667              ,p_obj_name   fnd_objects.obj_name%TYPE
17668              ,p_ag_type    ego_fnd_dsc_flx_ctx_ext.descriptive_flexfield_name%TYPE)
17669     IS
17670      SELECT assoc.attr_group_id
17671        FROM ego_obj_ag_assocs_b assoc,
17672             fnd_objects object,
17673             ego_fnd_dsc_flx_ctx_ext ag
17674       WHERE assoc.classification_code     = p_class_code
17675         AND assoc.object_id               = object.object_id
17676         AND object.obj_name               = p_obj_name
17677         AND ag.descriptive_flexfield_name = p_ag_type
17678         AND ag.attr_group_id              = assoc.attr_group_id
17679         AND assoc.data_level              = p_data_level;
17680 
17681     CURSOR relevant_ag_wo_data_level(
17682               p_class_code ego_obj_ag_assocs_b.classification_code%TYPE
17683              ,p_obj_name   fnd_objects.obj_name%TYPE
17684              ,p_ag_type    ego_fnd_dsc_flx_ctx_ext.descriptive_flexfield_name%TYPE)
17685     IS
17686      SELECT assoc.attr_group_id
17687        FROM ego_obj_ag_assocs_b assoc,
17688             fnd_objects object,
17689             ego_fnd_dsc_flx_ctx_ext ag
17690       WHERE assoc.classification_code     = p_class_code
17691         AND assoc.object_id               = object.object_id
17692         AND object.obj_name               = p_obj_name
17693         AND ag.descriptive_flexfield_name = p_ag_type
17694         AND ag.attr_group_id              = assoc.attr_group_id;
17695 
17696   BEGIN
17697 
17698     Debug_Msg(l_api_name||' starting', 2);
17699 
17700     Debug_msg(l_api_name||' will request attribute group at ' ||
17701               p_data_level_name || ' for object ' || p_object_name ||
17702               ' to be validated');
17703 
17704     ---------------------------------------------------------
17705     -- Put the (class code name, value) pairs into a table --
17706     ---------------------------------------------------------
17707 
17708     Build_Class_Code_Table(
17709         p_class_code_name_value_pairs => p_class_code_name_value_pairs
17710        ,x_class_code_table            => l_class_code_table
17711     );
17712 
17713     Debug_Msg(l_api_name || ' finished building class code table', 2);
17714 
17715     --------------------------------------------------------------------
17716     -- Extract the values from the (column name, value) pairs in the  --
17717     -- data level pairs array                                         --
17718     --------------------------------------------------------------------
17719 
17720     Extract_Data_Level_Values(
17721         p_data_level_name               => p_data_level_name
17722        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
17723        ,x_data_level_1                  => l_data_level_1
17724        ,x_data_level_2                  => l_data_level_2
17725        ,x_data_level_3                  => l_data_level_3
17726     );
17727 
17728     Debug_Msg(l_api_name||' extracted data level values', 2);
17729 
17730     --------------------------
17731     -- Build Request Table  --
17732     --------------------------
17733 
17734     IF x_attr_group_request_table IS NULL THEN
17735        x_attr_group_request_table := EGO_ATTR_GROUP_REQUEST_TABLE();
17736     END IF;
17737 
17738     IF p_attr_group_type_table.COUNT = 0 THEN
17739 Debug_Msg(l_api_name||' Attribute Group Type Table is empty', 2);
17740     END IF;
17741 
17742     IF l_class_code_table.COUNT = 0 THEN
17743 Debug_Msg(l_api_name||' Class Code Table is empty', 2);
17744     END IF;
17745 
17746     <<ag_types_loop>>
17747     FOR i IN 1 .. p_attr_group_type_table.COUNT LOOP
17748 
17749 Debug_Msg(l_api_name||' type table (' || i || ') = ' || p_attr_group_type_table(i), 2);
17750 
17751        <<class_code_loop>>
17752        FOR j IN 1 .. l_class_code_table.COUNT LOOP
17753 
17754 Debug_Msg(l_api_name||' class code (' || j || ') = ' || l_class_code_table(j), 2);
17755 Debug_Msg(l_api_name||' l_data_level_obj.NAME = ' || l_data_level_obj.NAME, 2);
17756 Debug_Msg(l_api_name||' p_object_name = ' || p_object_name, 2);
17757 
17758 
17759           IF p_data_level_name IS NOT NULL AND
17760              LENGTH(p_data_level_name) > 0
17761           THEN
17762 Debug_Msg(l_api_name||' p_data_level => ' || p_data_level_name , 3);
17763 Debug_Msg(l_api_name||' p_ag_type    => ' || p_attr_group_type_table(i), 3);
17764              OPEN relevant_ag_w_data_level(
17765                     p_data_level => p_data_level_name
17766                    ,p_class_code => l_class_code_table(j)
17767                    ,p_obj_name   => p_object_name
17768                    ,p_ag_type    => p_attr_group_type_table(i));
17769 
17770           ELSE
17771 Debug_Msg(l_api_name||' getting attribute groups not associated to any data level', 3);
17772              OPEN relevant_ag_wo_data_level(
17773                     p_class_code => l_class_code_table(j)
17774                    ,p_obj_name   => p_object_name
17775                    ,p_ag_type    => p_attr_group_type_table(i)
17776                    );
17777 
17778           END IF;
17779 
17780 Debug_Msg(l_api_name||' i = ' || i || ', j = ' || j, 2);
17781 
17782           --------------------------------------------------------------------
17783           -- Create a request object for eatch attribute group which        --
17784           -- eixsts at the specified data level                             --
17785           --------------------------------------------------------------------
17786 
17787           <<attr_groups_loop>>
17788           LOOP
17789 
17790 
17791              ---------------------------------
17792              -- Get the attribute group ID  --
17793              ---------------------------------
17794 
17795              IF relevant_ag_w_data_level%ISOPEN THEN
17796 Debug_Msg(l_api_name || ' fetching next AG ' || l_attr_group_id || ' with data level...', 2);
17797                 FETCH relevant_ag_w_data_level INTO l_attr_group_id;
17798                 EXIT WHEN relevant_ag_w_data_level%NOTFOUND;
17799              ELSE
17800                 FETCH relevant_ag_wo_data_level INTO l_attr_group_id;
17801 Debug_Msg(l_api_name || ' fetching next AG ' || l_attr_group_id || '  without data level...', 2);
17802                 EXIT WHEN relevant_ag_wo_data_level%NOTFOUND;
17803              END IF;
17804 
17805              Debug_Msg(l_api_name||' attribute group ID is ' || l_attr_group_id, 2);
17806 
17807              ------------------------------------------------------
17808              -- Append a request object for this attribute group --
17809              ------------------------------------------------------
17810 
17811              x_attr_group_request_table.EXTEND();
17812              x_attr_group_request_table(x_attr_group_request_table.LAST) :=
17813               EGO_ATTR_GROUP_REQUEST_OBJ(
17814                   l_attr_group_id                              -- ATTR_GROUP_ID
17815                  ,NULL                                        -- APPLICATION_ID
17816                  ,NULL                                       -- ATTR_GROUP_TYPE
17817                  ,NULL                                       -- ATTR_GROUP_NAME
17818                  ,p_data_level_name                               -- DATA_LEVEL
17819                  ,l_data_level_1                                -- DATA_LEVEL_1
17820                  ,l_data_level_2                                -- DATA_LEVEL_2
17821                  ,l_data_level_3                                -- DATA_LEVEL_3
17822                  ,NULL                                          -- DATA_LEVEL_4
17823                  ,NULL                                          -- DATA_LEVEL_5
17824                  ,NULL                                        -- ATTR_NAME_LIST
17825               );
17826 Debug_Msg(l_api_name || ' appended validation request for AG ' || l_attr_group_id, 2);
17827 
17828           END LOOP attr_groups_loop;
17829 Debug_Msg(l_api_name || ' exited attr_groups_loop', 3);
17830 
17831           IF relevant_ag_w_data_level%ISOPEN THEN
17832              CLOSE relevant_ag_w_data_level;
17833           ELSE
17834              CLOSE relevant_ag_wo_data_level;
17835          END IF;
17836 
17837        END LOOP class_code_loop;
17838 Debug_Msg(l_api_name || ' exited class_code_loop', 3);
17839     END LOOP ag_types_loop;
17840 
17841     Debug_Msg(l_api_name||' done', 2);
17842 
17843 END Build_Request_Table_For_Obj;
17844 
17845 ----------------------------------------------------------------------
17846 
17847 PROCEDURE Process_Req_Attr_Results(
17848         p_request_table          IN EGO_ATTR_GROUP_REQUEST_TABLE
17849        ,p_attributes_row_table   IN EGO_USER_ATTR_ROW_TABLE
17850        ,p_attributes_data_table  IN EGO_USER_ATTR_DATA_TABLE
17851        ,px_attributes_req_table  IN OUT NOCOPY EGO_USER_ATTR_TABLE
17852 ) IS
17853     l_has_value BOOLEAN;
17854     l_ix        NUMBER;
17855     l_api_name   VARCHAR2(30) := 'Process_Req_Attr_Results';
17856 
17857     CURSOR fetch_required_attr(
17858              p_ag_id    IN ego_attr_groups_v.attr_group_id%TYPE)
17859     IS
17860      SELECT attr.attr_name,
17861             attr.attr_display_name,
17862             ag.attr_group_id,
17863             ag.attr_group_name,
17864             ag.attr_group_disp_name,
17865             ag.attr_group_type,
17866             ag.application_id
17867        FROM ego_attrs_v attr ,
17868             ego_attr_groups_v ag
17869       WHERE ag.application_id = attr.application_id
17870         AND ag.attr_group_type = attr.attr_group_type
17871         AND ag.attr_group_name = attr.attr_group_name
17872         AND ag.attr_group_id = p_ag_id
17873         AND attr.required_flag = 'Y'
17874         AND attr.enabled_flag = 'Y';
17875 
17876   BEGIN
17877 
17878 Debug_Msg(l_api_name||' starting ', 2);
17879 
17880     IF p_request_table IS NULL THEN
17881 Debug_Msg(l_api_name||' returning as request table is NULL ', 2);
17882        RETURN;
17883     END IF;
17884 
17885 Debug_Msg(l_api_name||' request table size: ' || p_request_table.COUNT, 2);
17886 
17887     ------------------------------
17888     -- For each attribute group --
17889     ------------------------------
17890     FOR i IN 1 .. p_request_table.COUNT LOOP
17891 
17892        -------------------------------------
17893        -- Get all the required attributes --
17894        -------------------------------------
17895        FOR req_attr_rec IN fetch_required_attr(p_request_table(i).ATTR_GROUP_ID) LOOP
17896 
17897           l_has_value := FALSE;
17898 
17899           ------------------------------------------------
17900           -- Check to see if the attribute has any data --
17901           ------------------------------------------------
17902 
17903           IF p_attributes_row_table IS NOT NULL AND
17904              p_attributes_data_table IS NOT NULL
17905           THEN
17906 
17907 Debug_Msg(l_api_name||' p_attributes_data_table size: ' || p_attributes_data_table.COUNT, 2);
17908 
17909              FOR j IN 1 .. p_attributes_data_table.COUNT LOOP
17910 
17911               -- find the corresponding row object index
17912               l_ix := -1;
17913 
17914               FOR k IN 1 .. p_attributes_row_table.COUNT LOOP
17915                  IF p_attributes_row_table(k).ROW_IDENTIFIER =
17916                     p_attributes_data_table(j).ROW_IDENTIFIER
17917                  THEN
17918                    l_ix := k;
17919                    exit;
17920                  END IF;
17921               END LOOP;
17922 
17923               IF l_ix = -1 THEN
17924                  RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
17925               END IF;
17926 
17927               IF p_attributes_data_table(j).ATTR_NAME        = req_attr_rec.attr_name
17928                  AND
17929                  (p_attributes_row_table(l_ix).ATTR_GROUP_ID     = req_attr_rec.attr_group_id
17930                    OR
17931                   (p_attributes_row_table(l_ix).ATTR_GROUP_APP_ID = req_attr_rec.application_id AND
17932                    p_attributes_row_table(l_ix).ATTR_GROUP_TYPE   = req_attr_rec.attr_group_type AND
17933                    p_attributes_row_table(l_ix).ATTR_GROUP_NAME   = req_attr_rec.attr_group_name)
17934                  )
17935                  AND
17936                  (p_attributes_data_table(j).ATTR_VALUE_STR IS NOT NULL OR
17937                   p_attributes_data_table(j).ATTR_VALUE_NUM IS NOT NULL OR
17938                   p_attributes_data_table(j).ATTR_VALUE_DATE IS NOT NULL OR
17939                   p_attributes_data_table(j).ATTR_DISP_VALUE IS NOT NULL)
17940                THEN
17941                   l_has_value := TRUE;
17942 Debug_Msg(l_api_name|| p_attributes_data_table(j).ATTR_NAME || p_attributes_data_table(j).ATTR_VALUE_STR ||
17943           p_attributes_data_table(j).ATTR_VALUE_NUM || p_attributes_data_table(j).ATTR_VALUE_DATE || '(' ||
17944           p_attributes_data_table(j).ATTR_DISP_VALUE || ')', 2);
17945 
17946                   exit;
17947                END IF; -- if value exist for attr group
17948              END LOOP; -- p_attributes_data_table
17949           END IF; -- attr row and data NOT NULL
17950 
17951           --------------------------------------------------------------------
17952           -- If the attribute doesn't have a value, create an attribute     --
17953           -- descriptor object and add it to the results table, which       --
17954           -- contains the attribute descriptors of all required attributes  --
17955           -- that have violated the required property.                      --
17956           --------------------------------------------------------------------
17957 
17958           IF NOT l_has_value THEN
17959 
17960              IF px_attributes_req_table IS NULL THEN
17961                 px_attributes_req_table := EGO_USER_ATTR_TABLE();
17962              END IF;
17963 
17964              px_attributes_req_table.EXTEND();
17965              px_attributes_req_table(px_attributes_req_table.LAST) :=
17966                 EGO_USER_ATTR_OBJ(
17967                    req_attr_rec.application_id                -- APPLICATION_ID
17968                   ,req_attr_rec.attr_group_type              -- ATTR_GROUP_TYPE
17969                   ,req_attr_rec.attr_group_name              -- ATTR_GROUP_NAME
17970                   ,req_attr_rec.attr_group_disp_name    -- ATTR_GROUP_DISP_NAME
17971                   ,req_attr_rec.attr_name                          -- ATTR_NAME
17972                   ,req_attr_rec.attr_display_name             -- ATTR_DISP_NAME
17973                 );
17974 
17975 Debug_Msg(l_api_name|| req_attr_rec.attr_name || ' does not have a value', 2);
17976           ELSE
17977 Debug_Msg(l_api_name|| req_attr_rec.attr_name || ' has a value', 2);
17978           END IF; -- NOT l_has_value
17979        END LOOP; --fetch_required_attr
17980     END LOOP; --p_request_table
17981 
17982 Debug_Msg('Process_Req_Attr_Results, done', 2);
17983 
17984 END Process_Req_Attr_Results;
17985 
17986 ----------------------------------------------------------------------
17987 
17988 --
17989 -- NOTES
17990 --   (-) When an attribute that is required has no value, that attribute's
17991 --       details gets added to the output collection 'x_attributes_req_table'.
17992 --       The caller can read the entries in this table to find out which
17993 --       attributes violate their madatory property.
17994 --
17995 PROCEDURE Validate_Required_Attrs (
17996         p_api_version                   IN   NUMBER
17997        ,p_object_name                   IN   VARCHAR2
17998        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
17999        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
18000        ,p_data_level_name               IN   EGO_DATA_LEVEL_B.DATA_LEVEL_NAME%TYPE := NULL
18001        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
18002        ,p_attr_group_type_table         IN   EGO_VARCHAR_TBL_TYPE
18003        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
18004        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
18005        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
18006        ,p_debug_level                   IN   NUMBER     DEFAULT 0
18007        ,p_init_error_handler            IN   VARCHAR2   DEFAULT FND_API.G_TRUE
18008        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
18009        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
18010        ,p_log_errors                    IN   VARCHAR2   DEFAULT FND_API.G_FALSE
18011        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
18012        ,x_attributes_req_table          OUT NOCOPY EGO_USER_ATTR_TABLE
18013        ,x_return_status                 OUT NOCOPY VARCHAR2
18014        ,x_errorcode                     OUT NOCOPY NUMBER
18015        ,x_msg_count                     OUT NOCOPY NUMBER
18016        ,x_msg_data                      OUT NOCOPY VARCHAR2
18017 )IS
18018     l_api_name              CONSTANT VARCHAR2(30) := 'Validate_Required_Attrs';
18019     l_batch_size            CONSTANT NUMBER := 5;
18020     l_attributes_row_table  EGO_USER_ATTR_ROW_TABLE;
18021     l_attributes_data_table EGO_USER_ATTR_DATA_TABLE;
18022     l_request_table         EGO_ATTR_GROUP_REQUEST_TABLE;
18023                         -- request table for ALL attribute groups of the object
18024     l_request_table_batch_iter    EGO_ATTR_GROUP_REQUEST_TABLE;
18025                              -- request table for one batch of attribute groups
18026     l_attributes_req_table  EGO_USER_ATTR_TABLE;
18027     l_token_table           ERROR_HANDLER.Token_Tbl_Type;
18028 
18029   BEGIN
18030 
18031     Debug_Msg(l_api_name ||' starting', 2);
18032 
18033     --------------------------------------------------------------------------
18034     -- Build a Request Table for all attribute groups of the object to be   --
18035     -- validated.                                                           --
18036     --------------------------------------------------------------------------
18037 
18038     Build_Request_Table_For_Obj(
18039         p_object_name                   => p_object_name
18040        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
18041        ,p_data_level_name               => p_data_level_name
18042        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
18043        ,p_attr_group_type_table         => p_attr_group_type_table
18044        ,x_attr_group_request_table      => l_request_table
18045     );
18046 
18047     Debug_Msg(l_api_name||' Request Table for object has been built.', 2);
18048 
18049     IF l_request_table IS NULL THEN
18050        Debug_Msg(l_api_name||' Request Table for object is null so Returning.', 2);
18051        RETURN;
18052     END IF;
18053 
18054     --------------------------------------------------------------------------
18055     -- Build a Request Table which will contain the requests for just one   --
18056     -- batch of attribute groups per iteration                              --
18057     --------------------------------------------------------------------------
18058 
18059     l_request_table_batch_iter   := EGO_ATTR_GROUP_REQUEST_TABLE();
18060 
18061     IF l_request_table.COUNT = 0 THEN
18062        Debug_Msg(l_api_name||' Request Table for attribute group is empty so Returning', 2);
18063        RETURN;
18064     END IF;
18065 
18066     --------------------------------------------------------------------------
18067     -- Iterate through the request objects, and validate the attributes at  --
18068     -- the data level that particular request object specifies              --
18069     --------------------------------------------------------------------------
18070 
18071     FOR i IN 1 .. l_request_table.COUNT
18072     LOOP
18073 
18074        -----------------------------------------------------------------------
18075        -- Collect the request rows that belong to a single attribute group  --
18076        -----------------------------------------------------------------------
18077 
18078        l_request_table_batch_iter.EXTEND();
18079 
18080        IF mod(i, l_batch_size) = 0 THEN
18081           -- Start a new batch
18082           l_request_table_batch_iter(l_batch_size) := l_request_table(i);
18083        ELSE
18084           -- Append this request row to the current batch
18085           l_request_table_batch_iter(mod(i, l_batch_size)) := l_request_table(i);
18086        END IF;
18087 
18088        IF mod(i, l_batch_size) = 0 OR
18089           i = l_request_table.COUNT
18090        THEN
18091 
18092           --------------------------------------------------------------------
18093           -- Fetch the attribute values in this batch of attribute groups   --
18094           --------------------------------------------------------------------
18095           Get_User_Attrs_Data (
18096               p_api_version                   => p_api_version
18097              ,p_object_name                   => p_object_name
18098              ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
18099              ,p_attr_group_request_table      => l_request_table_batch_iter
18100              ,p_user_privileges_on_object     => NULL
18101              ,p_entity_id                     => p_entity_id
18102              ,p_entity_index                  => p_entity_index
18103              ,p_entity_code                   => p_entity_code
18104              ,p_debug_level                   => p_debug_level
18105              ,p_init_error_handler            => p_init_error_handler
18106              ,p_init_fnd_msg_list             => p_init_fnd_msg_list
18107              ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
18108              ,x_attributes_row_table          => l_attributes_row_table
18109              ,x_attributes_data_table         => l_attributes_data_table
18110              ,x_return_status                 => x_return_status
18111              ,x_errorcode                     => x_errorcode
18112              ,x_msg_count                     => x_msg_count
18113              ,x_msg_data                      => x_msg_data
18114           );
18115 
18116           IF l_attributes_data_table IS NULL THEN
18117 Debug_Msg(l_api_name||' l_attributes_data_table = NULL', 3);
18118           ELSE
18119 Debug_Msg(l_api_name||' l_attributes_data_table.COUNT = ' || l_attributes_data_table.COUNT, 3);
18120           END IF;
18121 
18122           -------------------------------------
18123           -- Populate result data structure  --
18124           -------------------------------------
18125           Process_Req_Attr_Results(
18126              p_request_table          => l_request_table_batch_iter
18127             ,p_attributes_row_table   => l_attributes_row_table
18128             ,p_attributes_data_table  => l_attributes_data_table
18129             ,px_attributes_req_table  => l_attributes_req_table
18130           );
18131 
18132           x_attributes_req_table := l_attributes_req_table;
18133 
18134           --reset transient variables
18135           l_request_table_batch_iter.DELETE;
18136 
18137           IF l_attributes_row_table IS NOT NULL THEN
18138              l_attributes_row_table.DELETE;
18139           END IF;
18140 
18141           IF l_attributes_data_table IS NOT NULL THEN
18142              l_attributes_data_table.DELETE;
18143           END IF;
18144 
18145        END IF;
18146 
18147     END LOOP;
18148 
18149     Debug_Msg(l_api_name||' done', 2);
18150 
18151   EXCEPTION
18152     WHEN FND_API.G_EXC_ERROR THEN
18153       x_return_status := FND_API.G_RET_STS_ERROR;
18154 
18155     WHEN OTHERS THEN
18156       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
18157       l_token_table.DELETE();
18158       l_token_table(1).TOKEN_NAME := 'PKG_NAME';
18159       l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
18160       l_token_table(2).TOKEN_NAME := 'API_NAME';
18161       l_token_table(2).TOKEN_VALUE := l_api_name;
18162       l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
18163       l_token_table(3).TOKEN_VALUE := SQLERRM;
18164 
18165       ERROR_HANDLER.Add_Error_Message(
18166         p_message_name              => 'EGO_PLSQL_ERR'
18167        ,p_application_id            => 'EGO'
18168        ,p_token_tbl                 => l_token_table
18169        ,p_message_type              => FND_API.G_RET_STS_ERROR
18170        ,p_row_identifier            => G_USER_ROW_IDENTIFIER
18171        ,p_entity_id                 => p_entity_id
18172        ,p_entity_index              => p_entity_index
18173        ,p_entity_code               => p_entity_code
18174        ,p_addto_fnd_stack           => G_ADD_ERRORS_TO_FND_STACK
18175       );
18176 
18177 END Validate_Required_Attrs;
18178 
18179 
18180 -----------------------------------------------
18181 -- Wrappers for Add_Bind and Init
18182 -----------------------------------------------
18183 
18184 PROCEDURE Add_Bind ( p_bind_identifier   IN VARCHAR2 DEFAULT NULL
18185                     ,p_value             IN VARCHAR2)
18186   IS
18187 BEGIN
18188    G_BIND_INDEX := G_BIND_INDEX + 1;
18189    G_BIND_IDENTIFIER_TBL(G_BIND_INDEX) := p_bind_identifier;
18190    G_BIND_DATATYPE_TBL(G_BIND_INDEX) := 'C';
18191    G_BIND_TEXT_TBL(G_BIND_INDEX) := p_value;
18192    FND_DSQL.Add_Bind(p_value);
18193 END Add_Bind; --VARCHAR2
18194 
18195 ----------------------------------------------------------------------
18196 
18197 PROCEDURE Add_Bind ( p_bind_identifier   IN VARCHAR2 DEFAULT NULL
18198                     ,p_value             IN DATE)
18199   IS
18200 BEGIN
18201    G_BIND_INDEX := G_BIND_INDEX + 1;
18202    G_BIND_IDENTIFIER_TBL(G_BIND_INDEX) := p_bind_identifier;
18203    G_BIND_DATATYPE_TBL(G_BIND_INDEX) := 'D';
18204    G_BIND_DATE_TBL(G_BIND_INDEX) := p_value;
18205    FND_DSQL.Add_Bind(p_value);
18206 END Add_Bind; --DATE
18207 
18208 ----------------------------------------------------------------------
18209 
18210 PROCEDURE Add_Bind ( p_bind_identifier   IN VARCHAR2 DEFAULT NULL
18211                     ,p_value             IN NUMBER)
18212   IS
18213 BEGIN
18214    G_BIND_INDEX := G_BIND_INDEX + 1;
18215    G_BIND_IDENTIFIER_TBL(G_BIND_INDEX) := p_bind_identifier;
18216    G_BIND_DATATYPE_TBL(G_BIND_INDEX) := 'N';
18217    G_BIND_NUMBER_TBL(G_BIND_INDEX) := p_value;
18218    FND_DSQL.Add_Bind(p_value);
18219 END Add_Bind; --NUMBER
18220 
18221 ----------------------------------------------------------------------
18222 
18223 PROCEDURE Set_Binds_And_Dml (p_sql IN VARCHAR2
18224                             ,p_mode IN VARCHAR2)
18225  IS
18226 BEGIN
18227 
18228  IF(p_mode = 'B') THEN
18229    G_B_TABLE_DML           := p_sql;
18230    G_B_BIND_INDEX          := G_BIND_INDEX;
18231    G_B_BIND_IDENTIFIER_TBL   := G_BIND_IDENTIFIER_TBL;
18232    G_B_BIND_DATATYPE_TBL   := G_BIND_DATATYPE_TBL;
18233    G_B_BIND_TEXT_TBL       := G_BIND_TEXT_TBL;
18234    G_B_BIND_DATE_TBL       := G_BIND_DATE_TBL;
18235    G_B_BIND_NUMBER_TBL     := G_BIND_NUMBER_TBL;
18236  ELSIF (p_mode='TL') THEN
18237    G_TL_TABLE_DML          := p_sql;
18238    G_TL_BIND_INDEX         := G_BIND_INDEX;
18239    G_TL_BIND_IDENTIFIER_TBL   := G_BIND_IDENTIFIER_TBL;
18240    G_TL_BIND_DATATYPE_TBL  := G_BIND_DATATYPE_TBL;
18241    G_TL_BIND_TEXT_TBL      := G_BIND_TEXT_TBL;
18242    G_TL_BIND_DATE_TBL      := G_BIND_DATE_TBL;
18243    G_TL_BIND_NUMBER_TBL    := G_BIND_NUMBER_TBL;
18244  END IF;
18245 
18246 END Set_Binds_And_Dml;
18247 
18248 ----------------------------------------------------------------------
18249 
18250 PROCEDURE Init
18251   IS
18252 BEGIN
18253    G_BIND_INDEX   := 0;
18254    FND_DSQL.Init();
18255 
18256    FOR i IN 1 .. 100 LOOP
18257 
18258     G_BIND_IDENTIFIER_TBL(i) := NULL;
18259     G_BIND_DATATYPE_TBL(i) := NULL;
18260     G_BIND_TEXT_TBL(i) := NULL;
18261     G_BIND_DATE_TBL(i) := NULL;
18262     G_BIND_NUMBER_TBL(i) := NULL;
18263 
18264    END LOOP;
18265 
18266 END init;
18267 
18268 ---------------------------------------------------------------
18269 
18270 /*
18271  * Apply_Default_Vals_For_Entity
18272  * -----------------------------
18273  * Apply_Default_Vals_For_Entity : This API should be called after the entity creation
18274  * is successfuly done. This API would set the default values for attributes in the all
18275  * the single row attribute groups not having a required attribute for the given entity.
18276  */
18277 
18278 PROCEDURE Apply_Default_Vals_For_Entity (
18279         p_object_name                   IN   VARCHAR2
18280        ,p_application_id                IN   NUMBER
18281        ,p_attr_group_type               IN   VARCHAR2
18282        ,p_attr_groups_to_exclude        IN   VARCHAR2   DEFAULT NULL
18283        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
18284        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
18285        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL
18286        ,p_data_level_values             IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
18287        ,p_additional_class_Code_list    IN   VARCHAR2   DEFAULT NULL
18288        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
18289        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
18290        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
18291        ,p_debug_level                   IN   NUMBER     DEFAULT 0
18292        ,p_init_error_handler            IN   VARCHAR2   DEFAULT FND_API.G_FALSE
18293        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
18294        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
18295        ,p_log_errors                    IN   VARCHAR2   DEFAULT FND_API.G_FALSE
18296        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
18297        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
18298        ,x_failed_row_id_list            OUT NOCOPY VARCHAR2
18299        ,x_return_status                 OUT NOCOPY VARCHAR2
18300        ,x_errorcode                     OUT NOCOPY NUMBER
18301        ,x_msg_count                     OUT NOCOPY NUMBER
18302        ,x_msg_data                      OUT NOCOPY VARCHAR2
18303        )
18304   IS
18305     l_api_name                    VARCHAR2(30) := 'Apply_Default_Vals_For_Entity';
18306     l_object_id                   NUMBER;
18307     l_ext_b_table_name            VARCHAR2(30);
18308     l_ext_vl_name                 VARCHAR2(30);
18309     l_ext_where_clause            VARCHAR2(600);
18310     l_ag_id_col_exists            BOOLEAN;
18311     l_dynamic_sql                 VARCHAR2(10000);
18312     l_related_class_Code_list     VARCHAR2(5000);
18313     l_excluded_ag_list            VARCHAR2(1000);
18314     l_previous_ag_id              NUMBER;
18315     l_counter1                    NUMBER;
18316     l_counter2                    NUMBER;
18317     l_dummy_number                NUMBER;
18318     l_ext_row_exists              BOOLEAN;
18319     l_base_data_level             VARCHAR2(30);
18320     l_data_level_1                VARCHAR2(150);
18321     l_data_level_2                VARCHAR2(150);
18322     l_data_level_3                VARCHAR2(150);
18323     l_data_level_4                VARCHAR2(150);
18324     l_data_level_5                VARCHAR2(150);
18325     l_number_val                  NUMBER;
18326     l_str_val                     VARCHAR2(4000);	-- Bug 8757354
18327     l_date_val                    DATE;
18328     l_attr_row_table              EGO_USER_ATTR_ROW_TABLE;
18329     l_attr_data_table             EGO_USER_ATTR_DATA_TABLE;
18330     l_transaction_type            VARCHAR2(10);
18331     l_temp_date_str               VARCHAR2(200);
18332     l_temp_attr_row_table         EGO_USER_ATTR_ROW_TABLE;
18333     l_temp_attr_data_table        EGO_USER_ATTR_DATA_TABLE;
18334     l_cc_name_value_pairs         EGO_COL_NAME_VALUE_PAIR_ARRAY;
18335     l_has_data_level_id           BOOLEAN;
18336     l_data_level_id               NUMBER;
18337 
18338     TYPE DYNAMIC_CUR              IS REF CURSOR;
18339     attr_rec_cursor               DYNAMIC_CUR;
18340 
18341     TYPE LOCAL_USER_ATTR_DATA_REC IS RECORD
18342     (
18343         ATTR_GROUP_ID             NUMBER
18344        ,ATTR_GROUP_NAME           VARCHAR2(30)
18345        ,ATTR_NAME                 VARCHAR2(30)
18346        ,REQUIRED_FLAG             VARCHAR2(1)
18347        ,DEFAULT_VALUE             VARCHAR2(4000)	-- Bug 8757354
18348        ,DATA_LEVEL                VARCHAR2(30)
18349        ,DATA_TYPE                 VARCHAR2(1)
18350     );
18351 
18352     l_attr_record                 LOCAL_USER_ATTR_DATA_REC;
18353 
18354   BEGIN
18355 
18356     Debug_Msg(l_api_name ||' Starting with params ',1);
18357     Debug_Msg(l_api_name ||' object_name: '||p_object_name||' application id: '||p_application_id);
18358     Debug_Msg(l_api_name ||' attr group type: '||p_attr_group_type||' attr grp to exclude '||p_attr_groups_to_exclude);
18359     IF p_pk_column_name_value_pairs IS NULL THEN
18360       Debug_Msg(l_api_name ||' p_pk_column_name_value_pairs is NULL ');
18361     ELSIF p_pk_column_name_value_pairs.COUNT = 0 THEN
18362       Debug_Msg(l_api_name ||' p_pk_column_name_value_pairs count is 0 ');
18363     ELSE
18364       FOR i IN 1 .. p_pk_column_name_value_pairs.COUNT LOOP
18365         debug_msg(l_api_name||' name('||i||'): '||p_pk_column_name_value_pairs(i).NAME ||' value('||i||'): '||p_pk_column_name_value_pairs(i).value);
18366       END LOOP;
18367     END IF;
18368     IF p_class_code_name_value_pairs IS NULL THEN
18369       Debug_Msg(l_api_name ||' p_class_code_name_value_pairs is NULL ');
18370     ELSIF p_class_code_name_value_pairs.COUNT = 0 THEN
18371       Debug_Msg(l_api_name ||' p_class_code_name_value_pairs count is 0 ');
18372     ELSE
18373       FOR i IN 1 .. p_class_code_name_value_pairs.COUNT LOOP
18374         debug_msg(l_api_name||' name('||i||'): '||p_class_code_name_value_pairs(i).NAME ||' value('||i||'): '||p_class_code_name_value_pairs(i).value);
18375       END LOOP;
18376     END IF;
18377     Debug_Msg(l_api_name ||' data level: '||p_data_level);
18378     IF p_data_level_values IS NULL THEN
18379       Debug_Msg(l_api_name ||' p_data_level_values is NULL ');
18380     ELSIF p_data_level_values.COUNT = 0 THEN
18381       Debug_Msg(l_api_name ||' p_data_level_values count is 0 ');
18382     ELSE
18383       FOR i IN 1 .. p_data_level_values.COUNT LOOP
18384         debug_msg(l_api_name||' name('||i||'): '||p_data_level_values(i).NAME ||' value('||i||'): '||p_data_level_values(i).value);
18385       END LOOP;
18386     END IF;
18387     Debug_Msg(l_api_name ||' addl class codes: '||p_additional_class_Code_list);
18388     Debug_Msg(l_api_name ||' entity id: '||p_entity_id||' entity index: '||p_entity_index);
18389     Debug_Msg(l_api_name ||' entity code: '||p_entity_code||' debug level: '||p_debug_level);
18390     Debug_Msg(l_api_name ||' init error handler: '||p_init_error_handler||' write conc log: '||p_write_to_concurrent_log);
18391     Debug_Msg(l_api_name ||' init msg list: '||p_init_fnd_msg_list||' log errors: '||p_log_errors);
18392     Debug_Msg(l_api_name ||' add error to stack: '||p_add_errors_to_fnd_stack||' commit flag: '||p_commit);
18393 
18394     SELECT FLEX.APPLICATION_TABLE_NAME        EXT_TABLE_NAME,
18395            FLEX_EXT.APPLICATION_VL_NAME       EXT_VL_NAME
18396       INTO l_ext_b_table_name,
18397            l_ext_vl_name
18398       FROM FND_DESCRIPTIVE_FLEXS              FLEX,
18399            EGO_FND_DESC_FLEXS_EXT             FLEX_EXT
18400      WHERE FLEX.APPLICATION_ID = FLEX_EXT.APPLICATION_ID(+)
18401        AND FLEX.DESCRIPTIVE_FLEXFIELD_NAME = FLEX_EXT.DESCRIPTIVE_FLEXFIELD_NAME(+)
18402        AND FLEX.APPLICATION_ID = p_application_id
18403        AND FLEX.DESCRIPTIVE_FLEXFIELD_NAME = p_attr_group_type;
18404 
18405     IF( l_ext_vl_name IS NULL ) THEN
18406       l_ext_vl_name := l_ext_b_table_name;
18407     END IF;
18408     Debug_Msg(l_api_name ||' b table: '||l_ext_b_table_name||' tl table: '||l_ext_vl_name);
18409 
18410     l_object_id := Get_Object_Id_From_Name(p_object_name);
18411 
18412     -------------------------------------------------------------
18413     -- Find out weather the ATTR_GROUP_ID column exists in the --
18414     -- table where attribute data is to be uploaded or not     --
18415     -------------------------------------------------------------
18416     l_ag_id_col_exists := FND_API.TO_BOOLEAN(EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(
18417                                     p_table_name  => l_ext_b_table_name
18418                                    ,p_column_name => 'ATTR_GROUP_ID')
18419                                              );
18420 
18421     l_has_data_level_id := FND_API.TO_BOOLEAN(EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(
18422                                     p_table_name  => l_ext_b_table_name
18423                                    ,p_column_name => 'DATA_LEVEL_ID')
18424                                              );
18425 
18426     IF l_has_data_level_id THEN
18427       SELECT data_level_id
18428         INTO l_data_level_id
18429         FROM ego_data_level_b
18430        WHERE application_id = p_application_id
18431          AND attr_group_type = p_attr_group_type
18432          AND data_level_name = p_data_level;
18433     END IF;
18434 
18435     l_ext_where_clause := p_class_code_name_value_pairs(1).NAME ||' = '||p_class_code_name_value_pairs(1).VALUE||' ';
18436     IF (l_ag_id_col_exists) THEN
18437       l_ext_where_clause := l_ext_where_clause || ' AND EXT.ATTR_GROUP_ID = :ag_id ';
18438     END IF;
18439 
18440     FOR i IN p_pk_column_name_value_pairs.FIRST .. p_pk_column_name_value_pairs.LAST
18441     LOOP
18442       l_ext_where_clause := l_ext_where_clause||' AND '||p_pk_column_name_value_pairs(i).NAME || ' = '||p_pk_column_name_value_pairs(i).VALUE ;
18443     END LOOP;
18444 
18445     IF l_has_data_level_id THEN
18446       l_ext_where_clause := l_ext_where_clause || ' AND data_level_id = '||l_data_level_id;
18447       IF p_data_level_values IS NOT NULL AND p_data_level_values.COUNT <> 0 THEN
18448         FOR i IN 1 .. p_data_level_values.COUNT LOOP
18449           l_ext_where_clause := l_ext_where_clause || ' AND '||p_data_level_values(i).name ||' = '||p_data_level_values(i).value;
18450         END LOOP;
18451       END IF;
18452     END IF;
18453 
18454     IF (p_additional_class_Code_list IS NULL) THEN
18455       l_related_class_Code_list := ' -2910 '; --any random negative number since cc wont be negative.
18456     ELSE
18457       l_related_class_Code_list := p_additional_class_Code_list;
18458     END IF;
18459 
18460     ----------------------
18461     -- Building the SQL --
18462     ----------------------
18463     --bug 8904892 change driving table to assoc_tbl;
18464 
18465     l_dynamic_sql := ' SELECT  /*+ LEADING( assoc_tbl) */ ATTR_GROUP_TBL.ATTR_GROUP_ID, ATTR_TBL.DESCRIPTIVE_FLEX_CONTEXT_CODE ATTR_GROUP_NAME,'||
18466                             ' ATTR_TBL.END_USER_COLUMN_NAME ATTR_NAME, REQUIRED_FLAG, DEFAULT_VALUE , ASSOC_TBL.DATA_LEVEL,'||
18467                             ' ATTR_EXT_TBL.DATA_TYPE'||
18468                        ' FROM FND_DESCR_FLEX_COLUMN_USAGES ATTR_TBL,'||
18469                             ' EGO_FND_DSC_FLX_CTX_EXT ATTR_GROUP_TBL,'||
18470                             ' EGO_OBJ_AG_ASSOCS_B ASSOC_TBL,'||
18471                             ' EGO_FND_DF_COL_USGS_EXT ATTR_EXT_TBL'||
18472                       ' WHERE ATTR_TBL.APPLICATION_ID = ATTR_GROUP_TBL.APPLICATION_ID ';
18473 
18474     IF (p_attr_groups_to_exclude IS NOT NULL) THEN
18475        l_dynamic_sql := l_dynamic_sql||
18476                         ' AND ATTR_GROUP_TBL.ATTR_GROUP_ID NOT IN ('||p_attr_groups_to_exclude||') ';
18477     END IF;
18478 
18479     l_dynamic_sql := l_dynamic_sql||
18480                         ' AND ATTR_TBL.DESCRIPTIVE_FLEXFIELD_NAME = ATTR_GROUP_TBL.DESCRIPTIVE_FLEXFIELD_NAME'||
18481                         ' AND ATTR_TBL.DESCRIPTIVE_FLEX_CONTEXT_CODE = ATTR_GROUP_TBL.DESCRIPTIVE_FLEX_CONTEXT_CODE '||
18482                         ' AND (ATTR_TBL.DEFAULT_VALUE IS NOT NULL OR ATTR_TBL.REQUIRED_FLAG = ''Y'')'||
18483                         ' AND ATTR_TBL.ENABLED_FLAG = ''Y'''||
18484                         ' AND ATTR_EXT_TBL.APPLICATION_ID = :app_id '||
18485                         ' AND ATTR_EXT_TBL.DESCRIPTIVE_FLEXFIELD_NAME = :attr_group_type '||
18486                         ' AND ATTR_EXT_TBL.DESCRIPTIVE_FLEX_CONTEXT_CODE = ATTR_TBL.DESCRIPTIVE_FLEX_CONTEXT_CODE'||
18487                         ' AND ATTR_EXT_TBL.APPLICATION_COLUMN_NAME = ATTR_TBL.APPLICATION_COLUMN_NAME'||
18488                         ' AND ATTR_GROUP_TBL.DESCRIPTIVE_FLEXFIELD_NAME = :attr_group_type '||
18489                         ' AND ATTR_GROUP_TBL.APPLICATION_ID = :app_id '||
18490                         ' AND ATTR_GROUP_TBL.ATTR_GROUP_ID = ASSOC_TBL.ATTR_GROUP_ID'||
18491                         ' AND ASSOC_TBL.OBJECT_ID = :object_id '||
18492                         ' AND ATTR_GROUP_TBL.MULTI_ROW = ''N'''||
18493                         ' AND (    ASSOC_TBL.CLASSIFICATION_CODE IN ('||l_related_class_Code_list||')'||
18494                         '       OR ASSOC_TBL.CLASSIFICATION_CODE = :class_Code  )';
18495     IF l_has_data_level_id THEN
18496       l_dynamic_sql := l_dynamic_sql||
18497                         ' AND ASSOC_TBL.data_level_id = '||l_data_level_id;
18498     END IF;
18499       l_dynamic_sql := l_dynamic_sql||
18500                         ' ORDER BY ATTR_GROUP_TBL.ATTR_GROUP_ID';
18501 
18502    IF l_has_data_level_id THEN
18503      l_base_data_level := p_data_level;
18504    ELSE
18505      -----------------------------------------------
18506      -- Getting the base data level for the entity
18507      -----------------------------------------------
18508      SELECT data_level_name
18509        INTO l_base_data_level
18510        FROM ( SELECT MIN(data_level_id) data_level_id
18511                 FROM ego_data_level_b
18512                WHERE application_id = p_application_id
18513                  AND attr_group_type = p_attr_group_type
18514             ) min_dl, ego_data_level_b dl
18515       WHERE dl.data_level_id = min_dl.data_level_id;
18516    END IF;
18517 
18518    IF p_data_level_values IS NOT NULL THEN
18519      l_dummy_number := p_data_level_values.COUNT;
18520    ELSE
18521      l_dummy_number := 0;
18522    END IF;
18523 
18524    IF l_dummy_number > 4 THEN
18525      l_data_level_5 := p_data_level_values(5).VALUE;
18526    ELSE
18527      l_data_level_5 := NULL;
18528    END IF;
18529 
18530    IF l_dummy_number > 3 THEN
18531      l_data_level_4 := p_data_level_values(4).VALUE;
18532    ELSE
18533      l_data_level_4 := NULL;
18534    END IF;
18535 
18536    IF l_dummy_number > 2 THEN
18537      l_data_level_3 := p_data_level_values(3).VALUE;
18538    ELSE
18539      l_data_level_3 := NULL;
18540    END IF;
18541 
18542    IF l_dummy_number > 1 THEN
18543      l_data_level_2 := p_data_level_values(2).VALUE;
18544    ELSE
18545      l_data_level_2 := NULL;
18546    END IF;
18547 
18548    IF l_dummy_number > 0 THEN
18549      l_data_level_1 := p_data_level_values(1).VALUE;
18550    ELSE
18551      l_data_level_1 := NULL;
18552    END IF;
18553 
18554    -------------------------------------
18555    -- Looping through the attr records
18556    -- for building the attr data object
18557    -------------------------------------
18558     -- initializing all the variables...
18559     l_excluded_ag_list := ' ';
18560     l_previous_ag_id := -1;
18561     l_counter1 := 0;
18562     l_counter2 := 0;
18563 
18564     l_attr_row_table := EGO_USER_ATTR_ROW_TABLE();
18565     l_attr_data_table := EGO_USER_ATTR_DATA_TABLE();
18566     l_temp_attr_row_table := EGO_USER_ATTR_ROW_TABLE();
18567     l_temp_attr_data_table := EGO_USER_ATTR_DATA_TABLE();
18568 
18569     Debug_Msg(l_api_name ||' attr rec cursor: '||l_dynamic_sql);
18570     Debug_Msg(l_api_name ||' binds are 1: '|| p_application_id ||' 2: '|| p_attr_group_type||
18571               ' 3: '||p_attr_group_type ||' 4: '||p_application_id ||' 5: '||l_object_id ||
18572               ' 6: '||p_class_code_name_value_pairs(1).VALUE);
18573 
18574      OPEN attr_rec_cursor
18575       FOR  l_dynamic_sql
18576     USING  p_application_id,
18577            p_attr_group_type,
18578            p_attr_group_type,
18579            p_application_id,
18580            l_object_id,
18581            p_class_code_name_value_pairs(1).VALUE;
18582 
18583     ------------------------------------------------------------------------------------------
18584     --Looping through the cursor fetched records to get the attributes with default values  --
18585     --and no corresponding AG row in the ext data table.                                    --
18586     ------------------------------------------------------------------------------------------
18587     LOOP
18588     FETCH attr_rec_cursor INTO l_attr_record;
18589     EXIT WHEN attr_rec_cursor%NOTFOUND;
18590 
18591       IF(l_attr_record.DATA_TYPE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE)THEN
18592          l_number_val := TO_NUMBER(l_attr_record.DEFAULT_VALUE);
18593          l_str_val    := NULL;
18594          l_date_val   := NULL;
18595       ELSIF (l_attr_record.DATA_TYPE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE OR
18596              l_attr_record.DATA_TYPE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE) THEN
18597          l_number_val := NULL;
18598          l_str_val    := l_attr_record.DEFAULT_VALUE;
18599          l_date_val   := NULL;
18600       ELSIF(l_attr_record.DATA_TYPE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
18601              l_attr_record.DATA_TYPE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
18602          l_number_val := NULL;
18603          l_str_val    := NULL;
18604          IF(INSTR(UPPER(l_attr_record.DEFAULT_VALUE),'$SYSDATE$') <> 0) THEN
18605            l_temp_date_str := REPLACE(UPPER(l_attr_record.DEFAULT_VALUE),'$'); --bugfix:5228308
18606            EXECUTE IMMEDIATE 'SELECT '||l_temp_date_str||' FROM DUAL '
18607            INTO l_date_val;
18608          ELSE
18609            l_date_val := TO_DATE(l_attr_record.DEFAULT_VALUE,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
18610          END IF;
18611       END IF;
18612 
18613       IF (l_attr_record.REQUIRED_FLAG = 'Y' AND l_attr_record.DEFAULT_VALUE IS NULL) THEN
18614          l_excluded_ag_list := l_excluded_ag_list || '   '||l_attr_record.ATTR_GROUP_ID||'   ';
18615       END IF;
18616 
18617       IF (l_previous_ag_id = -1 OR l_previous_ag_id <> l_attr_record.ATTR_GROUP_ID) THEN
18618 
18619         l_temp_attr_row_table.EXTEND();
18620         l_counter1 := l_counter1+1;
18621 
18622         IF (l_ag_id_col_exists) THEN
18623            l_transaction_type := 'CREATE';
18624         ELSE
18625            l_transaction_type := 'SYNC';
18626         END IF;
18627 
18628         IF l_has_data_level_id THEN -- R12C code
18629           Debug_Msg(l_api_name ||' creating attr row object for R12C ');
18630           l_temp_attr_row_table(l_counter1) :=
18631                      EGO_USER_ATTR_ROW_OBJ( l_attr_record.ATTR_GROUP_ID,      --ROW_IDENTIFIER
18632                                             l_attr_record.ATTR_GROUP_ID,      --ATTR_GROUP_ID
18633                                             p_application_id,                 --ATTR_GROUP_APP_ID
18634                                             p_attr_group_type,                --ATTR_GROUP_TYPE
18635                                             l_attr_record.ATTR_GROUP_NAME,    --ATTR_GROUP_NAME
18636                                             p_data_level,                     --DATA_LEVEL
18637                                             l_data_level_1,                   --DATA_LEVEL_1
18638                                             l_data_level_2,                   --DATA_LEVEL_2
18639                                             l_data_level_3,                   --DATA_LEVEL_3
18640                                             l_data_level_4,                   --DATA_LEVEL_4
18641                                             l_data_level_5,                   --DATA_LEVEL_5
18642                                             l_transaction_type                --TRANSACTION_TYPE
18643                                            );
18644         ELSE -- R12 code
18645           IF(l_base_data_level = l_attr_record.DATA_LEVEL) THEN
18646             Debug_Msg(l_api_name ||' creating attr row object for R12 base data level ');
18647             l_temp_attr_row_table(l_counter1) :=
18648                      EGO_USER_ATTR_ROW_OBJ( l_attr_record.ATTR_GROUP_ID,      --ROW_IDENTIFIER
18649                                             l_attr_record.ATTR_GROUP_ID,      --ATTR_GROUP_ID
18650                                             p_application_id,                 --ATTR_GROUP_APP_ID
18651                                             p_attr_group_type,                --ATTR_GROUP_TYPE
18652                                             l_attr_record.ATTR_GROUP_NAME,    --ATTR_GROUP_NAME
18653                                             null,                             --DATA_LEVEL
18654                                             null,                             --DATA_LEVEL_1
18655                                             null,                             --DATA_LEVEL_2
18656                                             null,                             --DATA_LEVEL_3
18657                                             null,                             --DATA_LEVEL_4
18658                                             null,                             --DATA_LEVEL_5
18659                                             l_transaction_type                --TRANSACTION_TYPE
18660                                            );
18661           ELSE
18662             Debug_Msg(l_api_name ||' creating attr row object for R12 NON base data level ');
18663             l_temp_attr_row_table(l_counter1) :=
18664                      EGO_USER_ATTR_ROW_OBJ( l_attr_record.ATTR_GROUP_ID,      --ROW_IDENTIFIER
18665                                             l_attr_record.ATTR_GROUP_ID,      --ATTR_GROUP_ID
18666                                             p_application_id,                 --ATTR_GROUP_APP_ID
18667                                             p_attr_group_type,                --ATTR_GROUP_TYPE
18668                                             l_attr_record.ATTR_GROUP_NAME,    --ATTR_GROUP_NAME
18669                                             null,                             --DATA_LEVEL
18670                                             l_data_level_1,                   --DATA_LEVEL_1
18671                                             l_data_level_2,                   --DATA_LEVEL_2
18672                                             l_data_level_3,                   --DATA_LEVEL_3
18673                                             null,                             --DATA_LEVEL_4
18674                                             null,                             --DATA_LEVEL_5
18675                                             l_transaction_type                --TRANSACTION_TYPE
18676                                            );
18677 
18678           END IF;
18679         END IF;
18680         l_previous_ag_id := l_attr_record.ATTR_GROUP_ID;
18681       END IF;
18682 
18683       l_temp_attr_data_table.EXTEND();
18684       l_counter2 := l_counter2 + 1;
18685       l_temp_attr_data_table(l_counter2) :=
18686                  EGO_USER_ATTR_DATA_OBJ( l_attr_record.ATTR_GROUP_ID,   --ROW_IDENTIFIER
18687                                          l_attr_record.ATTR_NAME,       --ATTR_NAME
18688                                          l_str_val,                     --ATTR_VALUE_STR
18689                                          l_number_val,                  --ATTR_VALUE_NUM
18690                                          l_date_val,                    --ATTR_VALUE_DATE
18691                                          l_attr_record.DEFAULT_VALUE,   --ATTR_DISP_VALUE
18692                                          null,                          --ATTR_UNIT_OF_MEASURE
18693                                          null                           --USER_ROW_IDENTIFIER
18694                                         );
18695     END LOOP;
18696     Debug_Msg(l_api_name ||' completed data for AG cursor ');
18697     ------------------------------------------------------------------------------------
18698     --Here we clean up the attr group defination table to filter out the ag's with
18699     --required attributes or having a record in the ext data table.
18700     ------------------------------------------------------------------------------------
18701 
18702     l_dynamic_sql := 'SELECT 1 FROM '||l_ext_vl_name||' EXT WHERE '||l_ext_where_clause;
18703     Debug_Msg(l_api_name ||' dynamic sql for ext row check: '||l_dynamic_sql);
18704 
18705     IF(l_temp_attr_row_table.COUNT > 0 AND l_temp_attr_row_table.COUNT > 0) THEN
18706 
18707        FOR i in l_temp_attr_row_table.FIRST .. l_temp_attr_row_table.LAST
18708        LOOP
18709 
18710          IF ( INSTR(l_excluded_ag_list,l_temp_attr_row_table(i).ATTR_GROUP_ID) = 0 ) THEN
18711 
18712            l_ext_row_exists := TRUE;
18713            BEGIN
18714              IF (l_ag_id_col_exists) THEN
18715                Debug_Msg(l_api_name ||' exec dyn sql for '||l_temp_attr_row_table(i).ATTR_GROUP_ID);
18716                EXECUTE IMMEDIATE l_dynamic_sql
18717                INTO l_dummy_number
18718                USING l_temp_attr_row_table(i).ATTR_GROUP_ID;
18719              ELSE
18720                EXECUTE IMMEDIATE l_dynamic_sql
18721                INTO l_dummy_number;
18722              END IF;
18723            EXCEPTION
18724              WHEN NO_DATA_FOUND THEN
18725                l_ext_row_exists:=FALSE;
18726            END;
18727 
18728            IF (NOT l_ext_row_exists ) THEN
18729              l_attr_row_table.EXTEND();
18730              l_attr_row_table(l_attr_row_table.LAST) :=
18731                   EGO_USER_ATTR_ROW_OBJ (  l_temp_attr_row_table(i).ROW_IDENTIFIER
18732                                           ,l_temp_attr_row_table(i).ATTR_GROUP_ID
18733                                           ,l_temp_attr_row_table(i).ATTR_GROUP_APP_ID
18734                                           ,l_temp_attr_row_table(i).ATTR_GROUP_TYPE
18735                                           ,l_temp_attr_row_table(i).ATTR_GROUP_NAME
18736                                           ,l_temp_attr_row_table(i).DATA_LEVEL
18737                                           ,l_temp_attr_row_table(i).DATA_LEVEL_1
18738                                           ,l_temp_attr_row_table(i).DATA_LEVEL_2
18739                                           ,l_temp_attr_row_table(i).DATA_LEVEL_3
18740                                           ,l_temp_attr_row_table(i).DATA_LEVEL_4
18741                                           ,l_temp_attr_row_table(i).DATA_LEVEL_5
18742                                           ,l_temp_attr_row_table(i).TRANSACTION_TYPE
18743                                          );
18744            ELSE
18745              l_excluded_ag_list := l_excluded_ag_list||'  '||l_temp_attr_row_table(i).ATTR_GROUP_ID||'   ';
18746            END IF;
18747          END IF;
18748        END LOOP;
18749        Debug_Msg(l_api_name ||' 1st level of filtering ');
18750        ----------------------------------------------------------------------------
18751        --Here we filter out the attributes belonging to attr groups which have
18752        --required attributes or have a row in the ext table for the given item.
18753        ----------------------------------------------------------------------------
18754 
18755        l_counter1 := 0;
18756        FOR i in l_temp_attr_data_table.FIRST .. l_temp_attr_data_table.LAST
18757        LOOP
18758          IF ( INSTR(l_excluded_ag_list,l_temp_attr_data_table(i).ROW_IDENTIFIER) = 0 ) THEN
18759 
18760            l_counter1 := l_counter1+1;
18761            l_attr_data_table.EXTEND();
18762            l_attr_data_table(l_counter1) :=
18763                 EGO_USER_ATTR_DATA_OBJ (  l_temp_attr_data_table(i).ROW_IDENTIFIER
18764                                          ,l_temp_attr_data_table(i).ATTR_NAME
18765                                          ,l_temp_attr_data_table(i).ATTR_VALUE_STR
18766                                          ,l_temp_attr_data_table(i).ATTR_VALUE_NUM
18767                                          ,l_temp_attr_data_table(i).ATTR_VALUE_DATE
18768                                          ,l_temp_attr_data_table(i).ATTR_DISP_VALUE
18769                                          ,l_temp_attr_data_table(i).ATTR_UNIT_OF_MEASURE
18770                                          ,l_temp_attr_data_table(i).USER_ROW_IDENTIFIER
18771                                         );
18772          END IF;
18773        END LOOP;
18774        Debug_Msg(l_api_name ||' 2nd level of filtering ');
18775 
18776     END IF; --if the generated tables are not null
18777     ------------------------------------------------------------
18778     -- Now we call Process_user_attrs_data for processing the
18779     -- data we have extracted above ...
18780     ------------------------------------------------------------
18781 
18782     x_failed_row_id_list := NULL;
18783     x_return_status := 'S';
18784     x_errorcode := NULL;
18785     x_msg_count := 0;
18786     x_msg_data := NULL;
18787 
18788 
18789     IF(l_attr_data_table.COUNT > 0 AND l_attr_row_table.COUNT > 0 ) THEN
18790 
18791       l_cc_name_value_pairs := p_class_code_name_value_pairs;
18792       l_cc_name_value_pairs.EXTEND();
18793       l_cc_name_value_pairs(2) := EGO_COL_NAME_VALUE_PAIR_OBJ('RELATED_CLASS_CODE_LIST',l_related_class_Code_list);
18794       Debug_Msg(l_api_name ||' Calling Process_User_Attrs_Data ');
18795       Process_User_Attrs_Data(
18796           p_api_version                   => 1.0
18797          ,p_object_name                   => p_object_name
18798          ,p_attributes_row_table          => l_attr_row_table
18799          ,p_attributes_data_table         => l_attr_data_table
18800          ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
18801          ,p_class_code_name_value_pairs   => l_cc_name_value_pairs
18802          ,p_entity_id                     => p_entity_id
18803          ,p_entity_index                  => p_entity_index
18804          ,p_entity_code                   => p_entity_code
18805          ,p_debug_level                   => p_debug_level
18806          ,p_init_error_handler            => p_init_error_handler
18807          ,p_write_to_concurrent_log       => p_write_to_concurrent_log
18808          ,p_init_fnd_msg_list             => p_init_fnd_msg_list
18809          ,p_log_errors                    => p_log_errors
18810          ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
18811          ,p_commit                        => p_commit
18812          ,x_failed_row_id_list            => x_failed_row_id_list
18813          ,x_return_status                 => x_return_status
18814          ,x_errorcode                     => x_errorcode
18815          ,x_msg_count                     => x_msg_count
18816          ,x_msg_data                      => x_msg_data
18817        );
18818       Debug_Msg(l_api_name ||' returned Process_User_Attrs_Data with status: '||x_return_status);
18819       Debug_Msg(l_api_name ||' returned Process_User_Attrs_Data with msg: '||x_msg_data);
18820     END IF;
18821     Debug_Msg(l_api_name ||' Exit ');
18822 EXCEPTION
18823   WHEN OTHERS THEN
18824     Debug_Msg(l_api_name ||' EXCEPTION: '||SQLERRM);
18825     x_return_status := G_RET_STS_UNEXP_ERROR;
18826     x_msg_count := 1;
18827     x_msg_data := SQLERRM;
18828 
18829 END Apply_Default_Vals_For_Entity;
18830 
18831 /*
18832 *Bug:9277377
18833 *Add the function to check column for both table and view oject
18834 */
18835 FUNCTION HAS_COLUMN_IN_TABLE_VIEW (p_object_name  IN  VARCHAR2
18836                              ,p_column_name IN  VARCHAR2
18837                              )
18838 RETURN VARCHAR2 IS
18839   l_dummy_number  NUMBER;
18840 BEGIN
18841    -- Add owner to the all_tab_columns query for better performance.
18842    -- Also cache the owner and table names to try to avoid doing the
18843    -- same query over and over.
18844 
18845      IF (g_tab_name = p_object_name) THEN
18846        NULL;  -- A hit in the cache, no need to query.
18847      ELSE
18848        -- Execute the following either if g_tab_name
18849        -- is not equal to p_object_name or if it is
18850        -- NULL (i.e. the first usage).
18851        --
18852          SELECT owner
18853          INTO   g_owner
18854          FROM   sys.all_objects
18855          WHERE  object_type IN ('TABLE','VIEW')
18856          AND object_name = p_object_name;
18857       -- update cache
18858          g_tab_name := p_object_name;
18859      END IF;
18860 
18861 /***
18862   -- fix for 12.2 OLP compatible
18863 
18864   SELECT 1
18865   INTO l_dummy_number
18866   FROM SYS.all_tab_columns
18867   WHERE table_name = p_object_name
18868   AND column_name = p_column_name;
18869 ***/
18870 
18871   -- bug#15835530  fix for 12.2 OLP compatible
18872   SELECT 1
18873   INTO l_dummy_number
18874   FROM user_synonyms syn, dba_tab_columns col
18875   WHERE syn.synonym_name = p_object_name
18876   AND col.owner = syn.table_owner
18877   AND col.table_name = syn.table_name
18878   AND col.column_name = p_column_name;
18879 
18880   RETURN FND_API.G_TRUE;
18881 EXCEPTION
18882   WHEN OTHERS THEN
18883     RETURN FND_API.G_FALSE;
18884 END HAS_COLUMN_IN_TABLE_VIEW;
18885 
18886 
18887 
18888 ----------------------------
18889 -- Package Initialization --
18890 ----------------------------
18891 BEGIN
18892 
18893     G_BIND_DATATYPE_TBL := VARCHAR2_TBL_TYPE();
18894     G_BIND_TEXT_TBL := VARCHAR2_TBL_TYPE();
18895     G_BIND_DATE_TBL := DATE_TBL_TYPE();
18896     G_BIND_NUMBER_TBL := NUMBER_TBL_TYPE();
18897     G_BIND_IDENTIFIER_TBL := VARCHAR2_TBL_TYPE();
18898 
18899 
18900     G_B_BIND_DATATYPE_TBL := VARCHAR2_TBL_TYPE();
18901     G_B_BIND_TEXT_TBL := VARCHAR2_TBL_TYPE();
18902     G_B_BIND_DATE_TBL := DATE_TBL_TYPE();
18903     G_B_BIND_NUMBER_TBL := NUMBER_TBL_TYPE();
18904     G_B_BIND_IDENTIFIER_TBL := VARCHAR2_TBL_TYPE();
18905 
18906 
18907     G_TL_BIND_DATATYPE_TBL := VARCHAR2_TBL_TYPE();
18908     G_TL_BIND_TEXT_TBL := VARCHAR2_TBL_TYPE();
18909     G_TL_BIND_DATE_TBL := DATE_TBL_TYPE();
18910     G_TL_BIND_NUMBER_TBL := NUMBER_TBL_TYPE();
18911     G_TL_BIND_IDENTIFIER_TBL := VARCHAR2_TBL_TYPE();
18912 
18913 
18914     G_BIND_IDENTIFIER_TBL.EXTEND(100);
18915     G_BIND_DATATYPE_TBL.EXTEND(100);
18916     G_BIND_TEXT_TBL.EXTEND(100);
18917     G_BIND_DATE_TBL.EXTEND(100);
18918     G_BIND_NUMBER_TBL.EXTEND(100);
18919 
18920     G_B_BIND_IDENTIFIER_TBL.EXTEND(100);
18921     G_B_BIND_DATATYPE_TBL.EXTEND(100);
18922     G_B_BIND_TEXT_TBL.EXTEND(100);
18923     G_B_BIND_DATE_TBL.EXTEND(100);
18924     G_B_BIND_NUMBER_TBL.EXTEND(100);
18925 
18926     G_TL_BIND_IDENTIFIER_TBL.EXTEND(100);
18927     G_TL_BIND_DATATYPE_TBL.EXTEND(100);
18928     G_TL_BIND_TEXT_TBL.EXTEND(100);
18929     G_TL_BIND_DATE_TBL.EXTEND(100);
18930     G_TL_BIND_NUMBER_TBL.EXTEND(100);
18931 
18932 END EGO_USER_ATTRS_DATA_PVT;